prostgles-server 4.2.576 → 4.2.577
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DboBuilder/DboBuilder.d.ts +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.js +1 -1
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.d.ts +1 -2
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js +2 -2
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js.map +1 -1
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js +58 -40
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js.map +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.d.ts +4 -7
- package/dist/DboBuilder/TableHandler/updateFile.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.js +7 -6
- package/dist/DboBuilder/TableHandler/updateFile.js.map +1 -1
- package/dist/DboBuilder/TableHandler/uploadFile.d.ts +31 -0
- package/dist/DboBuilder/TableHandler/uploadFile.d.ts.map +1 -0
- package/dist/DboBuilder/{uploadFile.js → TableHandler/uploadFile.js} +26 -14
- package/dist/DboBuilder/TableHandler/uploadFile.js.map +1 -0
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +1 -0
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.js +2 -0
- package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
- package/dist/DboBuilder/runSql/runSqlUtils.d.ts +1 -1
- package/dist/StorageClient/getFileTableConfig.d.ts +12 -10
- package/dist/StorageClient/getFileTableConfig.d.ts.map +1 -1
- package/dist/StorageClient/getFileTableConfig.js +17 -13
- package/dist/StorageClient/getFileTableConfig.js.map +1 -1
- package/dist/StorageClient/setupFileServeHandler.d.ts.map +1 -1
- package/dist/StorageClient/setupFileServeHandler.js +5 -7
- package/dist/StorageClient/setupFileServeHandler.js.map +1 -1
- package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +1 -1
- package/lib/DboBuilder/TableHandler/onDeleteFromFileTable.ts +3 -3
- package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +72 -47
- package/lib/DboBuilder/TableHandler/updateFile.ts +12 -10
- package/lib/DboBuilder/{uploadFile.ts → TableHandler/uploadFile.ts} +43 -22
- package/lib/DboBuilder/ViewHandler/ViewHandler.ts +2 -0
- package/lib/StorageClient/getFileTableConfig.ts +26 -13
- package/lib/StorageClient/setupFileServeHandler.ts +6 -7
- package/package.json +2 -2
- package/dist/DboBuilder/uploadFile.d.ts +0 -26
- package/dist/DboBuilder/uploadFile.d.ts.map +0 -1
- package/dist/DboBuilder/uploadFile.js.map +0 -1
|
@@ -3,25 +3,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getFileTableConfig = void 0;
|
|
4
4
|
const prostgles_types_1 = require("prostgles-types");
|
|
5
5
|
const updateFile_1 = require("../DboBuilder/TableHandler/updateFile");
|
|
6
|
-
const uploadFile_1 = require("../DboBuilder/uploadFile");
|
|
6
|
+
const uploadFile_1 = require("../DboBuilder/TableHandler/uploadFile");
|
|
7
7
|
const setupFileServeHandler_1 = require("./setupFileServeHandler");
|
|
8
8
|
const onDeleteFromFileTable_1 = require("../DboBuilder/TableHandler/onDeleteFromFileTable");
|
|
9
9
|
const FILE_TABLE_COLUMN_DEFINITIONS = {
|
|
10
|
-
name: `TEXT NOT NULL UNIQUE`,
|
|
11
|
-
extension: `TEXT NOT NULL`,
|
|
12
|
-
content_type: `TEXT NOT NULL`,
|
|
13
|
-
content_length: `BIGINT NOT NULL DEFAULT 0`,
|
|
14
|
-
added: `TIMESTAMP NOT NULL DEFAULT NOW()`,
|
|
15
|
-
url: `TEXT NOT NULL`,
|
|
16
10
|
id: `UUID PRIMARY KEY DEFAULT gen_random_uuid()`,
|
|
11
|
+
extension: `TEXT NOT NULL DEFAULT ''`,
|
|
12
|
+
content_type: `TEXT NOT NULL DEFAULT ''`,
|
|
13
|
+
content_length: `BIGINT NOT NULL DEFAULT 0`,
|
|
14
|
+
etag: `TEXT NOT NULL DEFAULT ''`,
|
|
17
15
|
original_name: `TEXT NOT NULL`,
|
|
16
|
+
original_last_modified: `TIMESTAMPTZ`,
|
|
18
17
|
description: `TEXT`,
|
|
18
|
+
url: `TEXT NOT NULL DEFAULT ''`,
|
|
19
19
|
cloud_url: `TEXT`,
|
|
20
20
|
signed_url: `TEXT`,
|
|
21
21
|
signed_url_expires: `BIGINT`,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
added: `TIMESTAMP NOT NULL DEFAULT NOW()`,
|
|
23
|
+
updated: `TIMESTAMP NOT NULL DEFAULT NOW()`,
|
|
24
|
+
deleted: `TIMESTAMPTZ`,
|
|
25
|
+
deleted_from_storage: `TIMESTAMPTZ`,
|
|
26
|
+
data: `BYTEA NOT NULL CHECK (data = decode('01', 'hex'))`, // Used as a placeholder to ensure insert types are correct. Actual data is uploaded to storageClient and not stored in the DB
|
|
25
27
|
};
|
|
26
28
|
const getFileTableConfig = (prg) => {
|
|
27
29
|
const { fileTable, tableConfig } = prg.opts;
|
|
@@ -74,14 +76,15 @@ const getFileTableConfig = (prg) => {
|
|
|
74
76
|
if (!tableHandler)
|
|
75
77
|
throw "Storage tableHandler not found";
|
|
76
78
|
(0, uploadFile_1.assertFileObjectValid)(insertData);
|
|
77
|
-
const { data: dataBlob,
|
|
79
|
+
const { data: dataBlob, original_name, id, original_last_modified = null, } = insertData;
|
|
78
80
|
const data = dataBlob;
|
|
79
81
|
if (command === "update") {
|
|
80
82
|
const { newData } = await (0, updateFile_1.updateFile)(tableHandler, fileTable, {
|
|
81
83
|
filter: filter ?? {},
|
|
82
84
|
localParams,
|
|
83
85
|
data,
|
|
84
|
-
|
|
86
|
+
original_name,
|
|
87
|
+
original_last_modified,
|
|
85
88
|
});
|
|
86
89
|
return {
|
|
87
90
|
row: newData,
|
|
@@ -92,9 +95,10 @@ const getFileTableConfig = (prg) => {
|
|
|
92
95
|
}
|
|
93
96
|
const media = await (0, uploadFile_1.uploadFile)(fileTable, {
|
|
94
97
|
data,
|
|
95
|
-
|
|
98
|
+
original_name,
|
|
96
99
|
localParams,
|
|
97
100
|
mediaId: id,
|
|
101
|
+
original_last_modified,
|
|
98
102
|
});
|
|
99
103
|
return {
|
|
100
104
|
row: media,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileTableConfig.js","sourceRoot":"","sources":["../../lib/StorageClient/getFileTableConfig.ts"],"names":[],"mappings":";;;AAAA,qDAA2C;AAC3C,sEAAmE;AACnE,
|
|
1
|
+
{"version":3,"file":"getFileTableConfig.js","sourceRoot":"","sources":["../../lib/StorageClient/getFileTableConfig.ts"],"names":[],"mappings":";;;AAAA,qDAA2C;AAC3C,sEAAmE;AACnE,sEAA0F;AAG1F,mEAAgE;AAChE,4FAAyF;AAGzF,MAAM,6BAA6B,GAAG;IACpC,EAAE,EAAE,4CAA4C;IAChD,SAAS,EAAE,0BAA0B;IACrC,YAAY,EAAE,0BAA0B;IACxC,cAAc,EAAE,2BAA2B;IAC3C,IAAI,EAAE,0BAA0B;IAChC,aAAa,EAAE,eAAe;IAC9B,sBAAsB,EAAE,aAAa;IACrC,WAAW,EAAE,MAAM;IACnB,GAAG,EAAE,0BAA0B;IAC/B,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,MAAM;IAClB,kBAAkB,EAAE,QAAQ;IAC5B,KAAK,EAAE,kCAAkC;IACzC,OAAO,EAAE,kCAAkC;IAC3C,OAAO,EAAE,aAAa;IACtB,oBAAoB,EAAE,aAAa;IACnC,IAAI,EAAE,mDAAmD,EAAE,8HAA8H;CACjL,CAAC;AAgBJ,MAAM,kBAAkB,GAAG,CAAC,GAAc,EAA2B,EAAE;IAC5E,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;IAC5C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,GAAG,SAAS,CAAC;IAEjC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,SAAS,CAAC;IAE9D,MAAM,mBAAmB,GAAG,WAAW,EAAE,CAAC,aAAa,CAAC,CAAC;IACzD,IAAI,mBAAmB,EAAE,CAAC;QACxB,IAAI,eAAe,IAAI,mBAAmB,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CACb,2BAA2B,aAAa,gDAAgD,CACzF,CAAC;QACJ,CAAC;QACD,IAAI,mBAAmB,CAAC,YAAY,IAAI,mBAAmB,CAAC,mBAAmB,EAAE,CAAC;YAChF,MAAM,IAAI,KAAK,CACb,2BAA2B,aAAa,sEAAsE,CAC/G,CAAC;QACJ,CAAC;QACD,IAAI,SAAS,IAAI,mBAAmB,IAAI,mBAAmB,CAAC,OAAO,EAAE,CAAC;YACpE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;YACnE,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAChF,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAClB,CAAC;YACF,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CACb,2BAA2B,aAAa,+CAA+C,eAAe,EAAE,CACzG,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,CAAC,aAAa,CAAC,EAAE;YACf,GAAG,mBAAmB;YACtB,OAAO,EAAE;gBACP,GAAG,6BAA6B;gBAChC,GAAG,mBAAmB,EAAE,OAAO;aAChC;YACD,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;gBACnB,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,6CAAqB,EAAC,GAAG,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;gBAE1F,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC;gBAC9E,OAAO,CAAC,GAAG,CACT,6DAA6D,WAAW,uGAAuG,CAChL,CAAC;gBACF,OAAO;oBACL,SAAS,EAAE,OAAO;iBACnB,CAAC;YACJ,CAAC;YACD,KAAK,EAAE;gBACL,GAAG,mBAAmB,EAAE,KAAK;gBAC7B,UAAU,EAAE;oBACV;wBACE,QAAQ,EAAE;4BACR,MAAM,EAAE,CAAC;4BACT,MAAM,EAAE,CAAC;yBACV;wBACD,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;4BACrE,MAAM,YAAY,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;4BAC9D,IAAI,CAAC,YAAY;gCAAE,MAAM,gCAAgC,CAAC;4BAC1D,IAAA,kCAAqB,EAAC,UAAU,CAAC,CAAC;4BAElC,MAAM,EACJ,IAAI,EAAE,QAAQ,EACd,aAAa,EACb,EAAE,EACF,sBAAsB,GAAG,IAAI,GAC9B,GAAG,UAAU,CAAC;4BACf,MAAM,IAAI,GAAG,QAA6B,CAAC;4BAC3C,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;gCACzB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAA,uBAAU,EAAC,YAAY,EAAE,SAAS,EAAE;oCAC5D,MAAM,EAAE,MAAM,IAAI,EAAE;oCACpB,WAAW;oCACX,IAAI;oCACJ,aAAa;oCACb,sBAAsB;iCACvB,CAAC,CAAC;gCACH,OAAO;oCACL,GAAG,EAAE,OAAO;oCACZ,WAAW,EAAE;wCACX,IAAI;qCACL;iCACF,CAAC;4BACJ,CAAC;4BAED,MAAM,KAAK,GAAG,MAAM,IAAA,uBAAU,EAAC,SAAS,EAAE;gCACxC,IAAI;gCACJ,aAAa;gCACb,WAAW;gCACX,OAAO,EAAE,EAAE;gCACX,sBAAsB;6BACvB,CAAC,CAAC;4BAEH,OAAO;gCACL,GAAG,EAAE,KAAK;gCACV,WAAW,EAAE;oCACX,IAAI;iCACL;6BACF,CAAC;wBACJ,CAAC;qBAC8C;oBACjD,GAAG,CAAC,mBAAmB,EAAE,KAAK,EAAE,UAAU,IAAI,EAAE,CAAC;iBAClD;gBACD,iBAAiB,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,EAAE;oBAChF,OAAO,IAAA,6CAAqB,EAAC,SAAS,EAAE;wBACtC,IAAI,EAAE,GAAG;wBACT,CAAC,EAAE,EAAE;wBACL,cAAc;wBACd,WAAW;wBACX,UAAU;qBACX,CAAC,CAAC;gBACL,CAAC;aACF;SACF;QACD,GAAG,IAAA,0BAAQ,EAAC,WAAW,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;KAChD,CAAC;AACJ,CAAC,CAAC;AAxHW,QAAA,kBAAkB,sBAwH7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupFileServeHandler.d.ts","sourceRoot":"","sources":["../../lib/StorageClient/setupFileServeHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAI7B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D,eAAO,MAAM,iBAAiB,GAAI,QAAQ,eAAe,WAOxD,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,IAAI,EAAE,EACN,QAAQ,eAAe,EACvB,eAAe,aAAa,EAC5B,KAAK,CAAC,CAAC,OAAO,EACd,KAAK,SAAS;;
|
|
1
|
+
{"version":3,"file":"setupFileServeHandler.d.ts","sourceRoot":"","sources":["../../lib/StorageClient/setupFileServeHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAI7B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D,eAAO,MAAM,iBAAiB,GAAI,QAAQ,eAAe,WAOxD,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,IAAI,EAAE,EACN,QAAQ,eAAe,EACvB,eAAe,aAAa,EAC5B,KAAK,CAAC,CAAC,OAAO,EACd,KAAK,SAAS;;CAiFf,CAAC"}
|
|
@@ -50,18 +50,16 @@ exports.getFileServeRoute = getFileServeRoute;
|
|
|
50
50
|
const setupFileServeHandler = (db, config, storageClient, app, prg) => {
|
|
51
51
|
const fileTableName = config.tableName;
|
|
52
52
|
const fileServeRoute = (0, exports.getFileServeRoute)(config);
|
|
53
|
-
const fileRouteExpress = fileServeRoute + "/:
|
|
53
|
+
const fileRouteExpress = fileServeRoute + "/:id";
|
|
54
54
|
app.get(fileRouteExpress, async (req, res) => {
|
|
55
55
|
try {
|
|
56
|
-
const {
|
|
57
|
-
if (typeof
|
|
56
|
+
const { id } = req.params;
|
|
57
|
+
if (typeof id !== "string" || !id) {
|
|
58
58
|
throw "Invalid media name";
|
|
59
59
|
}
|
|
60
|
-
const id = name.slice(0, 36);
|
|
61
60
|
const selectParams = {
|
|
62
61
|
select: {
|
|
63
62
|
id: 1,
|
|
64
|
-
name: 1,
|
|
65
63
|
signed_url: 1,
|
|
66
64
|
signed_url_expires: 1,
|
|
67
65
|
content_type: 1,
|
|
@@ -87,7 +85,7 @@ const setupFileServeHandler = (db, config, storageClient, app, prg) => {
|
|
|
87
85
|
const HOUR = 3600 * 1000;
|
|
88
86
|
const EXPIRES = Date.now() + HOUR;
|
|
89
87
|
if (!url || expires < EXPIRES) {
|
|
90
|
-
url = await storageClient.getSignedUrlForDownload(file.
|
|
88
|
+
url = await storageClient.getSignedUrlForDownload(file.id, 60 * 60);
|
|
91
89
|
await db.any("UPDATE ${fileTableName:name} SET signed_url = ${signed_url}, signed_url_expires = ${signed_url_expires} WHERE id = ${id}", {
|
|
92
90
|
fileTableName,
|
|
93
91
|
id: file.id,
|
|
@@ -98,7 +96,7 @@ const setupFileServeHandler = (db, config, storageClient, app, prg) => {
|
|
|
98
96
|
res.redirect(url);
|
|
99
97
|
}
|
|
100
98
|
else {
|
|
101
|
-
const localFilePath = (0, path_1.join)(storageClient.localFolderPath, file.
|
|
99
|
+
const localFilePath = (0, path_1.join)(storageClient.localFolderPath, file.id);
|
|
102
100
|
if (!fs.existsSync(localFilePath)) {
|
|
103
101
|
throw new Error("File not found");
|
|
104
102
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupFileServeHandler.js","sourceRoot":"","sources":["../../lib/StorageClient/setupFileServeHandler.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,uCAAyB;AACzB,+BAA4B;AAC5B,qDAA0E;AAI1E,0DAAuD;AAIhD,MAAM,iBAAiB,GAAG,CAAC,MAAuB,EAAE,EAAE;IAC3D,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC;IACvC,MAAM,cAAc,GAAG,MAAM,CAAC,aAAa,IAAI,IAAI,aAAa,EAAE,CAAC;IACnE,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,MAAM,wCAAwC,CAAC;IACjD,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC;AAPW,QAAA,iBAAiB,qBAO5B;AAEK,MAAM,qBAAqB,GAAG,CACnC,EAAM,EACN,MAAuB,EACvB,aAA4B,EAC5B,GAAc,EACd,GAAc,EACd,EAAE;IACF,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC;IACvC,MAAM,cAAc,GAAG,IAAA,yBAAiB,EAAC,MAAM,CAAC,CAAC;IACjD,MAAM,gBAAgB,GAAG,cAAc,GAAG,
|
|
1
|
+
{"version":3,"file":"setupFileServeHandler.js","sourceRoot":"","sources":["../../lib/StorageClient/setupFileServeHandler.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,uCAAyB;AACzB,+BAA4B;AAC5B,qDAA0E;AAI1E,0DAAuD;AAIhD,MAAM,iBAAiB,GAAG,CAAC,MAAuB,EAAE,EAAE;IAC3D,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC;IACvC,MAAM,cAAc,GAAG,MAAM,CAAC,aAAa,IAAI,IAAI,aAAa,EAAE,CAAC;IACnE,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,MAAM,wCAAwC,CAAC;IACjD,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC;AAPW,QAAA,iBAAiB,qBAO5B;AAEK,MAAM,qBAAqB,GAAG,CACnC,EAAM,EACN,MAAuB,EACvB,aAA4B,EAC5B,GAAc,EACd,GAAc,EACd,EAAE;IACF,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC;IACvC,MAAM,cAAc,GAAG,IAAA,yBAAiB,EAAC,MAAM,CAAC,CAAC;IACjD,MAAM,gBAAgB,GAAG,cAAc,GAAG,MAAM,CAAC;IAEjD,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAC3C,IAAI,CAAC;YACH,MAAM,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;YAC1B,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,EAAE,EAAE,CAAC;gBAClC,MAAM,oBAAoB,CAAC;YAC7B,CAAC;YAED,MAAM,YAAY,GAAG;gBACnB,MAAM,EAAE;oBACN,EAAE,EAAE,CAAC;oBACL,UAAU,EAAE,CAAC;oBACb,kBAAkB,EAAE,CAAC;oBACrB,YAAY,EAAE,CAAC;iBAChB;aACF,CAAC;YACF,MAAM,IAAI,GAAG,CAAC,MAAM,mCAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAC5C;gBACE,OAAO,EAAE,SAAS;gBAClB,SAAS,EAAE,aAAa;gBACxB,MAAM,EAAE,EAAE,EAAE,EAAE;gBACd,MAAM,EAAE,YAAY;gBACpB,MAAM,EAAE,SAAS;aAClB,EACD;gBACE,GAAG;gBACH,OAAO,EAAE,GAAG;aACb,EACD,SAAS,CACV,CAA6B,CAAC;YAE/B,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,GAAG,CAAC,MAAM,CAAC,6BAAe,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;gBAC5E,OAAO;YACT,CAAC;YAED,IAAI,aAAa,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACnC,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC;gBAC1B,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,CAAC,CAAC;gBAEhD,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;gBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;gBAClC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;oBAC9B,GAAG,GAAG,MAAM,aAAa,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;oBAEpE,MAAM,EAAE,CAAC,GAAG,CACV,0HAA0H,EAC1H;wBACE,aAAa;wBACb,EAAE,EAAE,IAAI,CAAC,EAAE;wBACX,UAAU,EAAE,GAAG;wBACf,kBAAkB,EAAE,OAAO;qBAC5B,CACF,CAAC;gBACJ,CAAC;gBAED,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,MAAM,aAAa,GAAG,IAAA,WAAI,EAAC,aAAa,CAAC,eAAe,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBACnE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;oBAClC,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;gBACpC,CAAC;gBACD,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBACnC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,6BAAe,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,IAAA,gCAAkB,EAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC,CAAC;AAtFW,QAAA,qBAAqB,yBAsFhC"}
|
|
@@ -31,7 +31,7 @@ export const onDeleteFromFileTable = async (
|
|
|
31
31
|
return (isOneOrNone ? result[0] : result) as undefined | AnyObject[];
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
let files: { id: string
|
|
34
|
+
let files: { id: string }[] = [];
|
|
35
35
|
const totalFiles = await tableHandler.count(filterOpts.filter);
|
|
36
36
|
do {
|
|
37
37
|
const batch = (await tableHandler.find(filterOpts.filter, {
|
|
@@ -46,11 +46,11 @@ export const onDeleteFromFileTable = async (
|
|
|
46
46
|
}
|
|
47
47
|
/** If any table delete fails then do not delete files */
|
|
48
48
|
for (const file of files) {
|
|
49
|
-
await storageClient.delete(file.
|
|
49
|
+
await storageClient.delete(file.id);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
if (returningQuery) {
|
|
53
|
-
return files.map((f) => pickKeys(f, ["id"
|
|
53
|
+
return files.map((f) => pickKeys(f, ["id"]));
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
return undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AnyObject, FieldFilter, InsertParams, UpdateParams } from "prostgles-types";
|
|
2
|
-
import { asName } from "prostgles-types";
|
|
2
|
+
import { asName, isDefined } from "prostgles-types";
|
|
3
3
|
import type { InsertRule, UpdateRule } from "../../PublishParser/PublishParser";
|
|
4
4
|
import type { LocalParams } from "../DboBuilder";
|
|
5
5
|
import { rejectWithPGClientError, withUserRLS } from "../DboBuilder";
|
|
@@ -51,7 +51,8 @@ export const runInsertUpdateQuery = async (args: RunInsertUpdateQueryArgs) => {
|
|
|
51
51
|
tableHandler.parseFieldFilter(returningFields),
|
|
52
52
|
);
|
|
53
53
|
const { checkFilter } = rule ?? {};
|
|
54
|
-
let checkCondition = "WHERE FALSE";
|
|
54
|
+
// let checkCondition = "WHERE FALSE";
|
|
55
|
+
let checkCondition = "FALSE";
|
|
55
56
|
if (checkFilter) {
|
|
56
57
|
const checkCond = await tableHandler.prepareWhere({
|
|
57
58
|
select: undefined,
|
|
@@ -60,53 +61,60 @@ export const runInsertUpdateQuery = async (args: RunInsertUpdateQueryArgs) => {
|
|
|
60
61
|
filter: checkFilter,
|
|
61
62
|
addWhere: false,
|
|
62
63
|
});
|
|
63
|
-
checkCondition = `WHERE NOT (${checkCond.where})`;
|
|
64
|
+
// checkCondition = `WHERE NOT (${checkCond.where})`;
|
|
65
|
+
checkCondition = `NOT (${checkCond.where})`;
|
|
64
66
|
}
|
|
65
67
|
const hasReturning = !!returningSelectItems.length;
|
|
66
68
|
const userRLS = withUserRLS(localParams, "");
|
|
67
|
-
const
|
|
69
|
+
const CHECK_CONDITION_ALIAS = "prostgles_check_condition";
|
|
70
|
+
const RETURNING_ALIAS_PREFIX = "prostgles_returning_";
|
|
71
|
+
const returningSelectKeyRemap = new Map<string, string>();
|
|
68
72
|
const query = `
|
|
69
|
-
${userRLS}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
73
|
+
${userRLS}
|
|
74
|
+
${queryWithoutUserRLS}
|
|
75
|
+
RETURNING ${[
|
|
76
|
+
"*",
|
|
77
|
+
getSelectItemQuery(
|
|
78
|
+
returningSelectItems
|
|
79
|
+
.map((item, index) => {
|
|
80
|
+
/** Skip if exists in 'returning *' */
|
|
81
|
+
if (item.type === "column" && asName(item.alias) === item.getQuery()) {
|
|
82
|
+
if (!tableHandler.columnSet.has(item.alias)) {
|
|
83
|
+
throw new Error(`Returning column ${item.alias} does not exist in table ${name}`);
|
|
84
|
+
}
|
|
85
|
+
returningSelectKeyRemap.set(item.alias, item.alias);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const newAlias = RETURNING_ALIAS_PREFIX + index;
|
|
89
|
+
if (tableHandler.columnSet.has(newAlias)) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Internal Returning alias rewrite ${newAlias} collides with actual table column name. Please report this issue.`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
returningSelectKeyRemap.set(newAlias, item.alias);
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
...item,
|
|
98
|
+
alias: newAlias,
|
|
99
|
+
};
|
|
100
|
+
})
|
|
101
|
+
.filter(isDefined),
|
|
102
|
+
),
|
|
103
|
+
`${checkCondition} as ${CHECK_CONDITION_ALIAS}`,
|
|
104
|
+
].filter(Boolean)}
|
|
97
105
|
`;
|
|
98
106
|
|
|
99
107
|
const allowedFieldKeys = tableHandler.parseFieldFilter(fields);
|
|
100
108
|
|
|
101
|
-
const queryType = "
|
|
109
|
+
const queryType = "any";
|
|
102
110
|
|
|
103
111
|
const tx = tableHandler.getTransaction(localParams)?.t;
|
|
104
|
-
const queryPromise: Promise<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
const queryPromise: Promise<
|
|
113
|
+
{
|
|
114
|
+
[CHECK_CONDITION_ALIAS]: boolean;
|
|
115
|
+
[key: string]: unknown;
|
|
116
|
+
}[]
|
|
117
|
+
> = tx ? tx[queryType](query) : tableHandler.db.tx((t) => t[queryType](query));
|
|
110
118
|
|
|
111
119
|
const result = await queryPromise.catch((err: unknown) =>
|
|
112
120
|
rejectWithPGClientError(err, {
|
|
@@ -118,27 +126,44 @@ export const runInsertUpdateQuery = async (args: RunInsertUpdateQueryArgs) => {
|
|
|
118
126
|
}),
|
|
119
127
|
);
|
|
120
128
|
|
|
121
|
-
if (checkFilter && result.
|
|
129
|
+
if (checkFilter && result.some((row) => row[CHECK_CONDITION_ALIAS])) {
|
|
122
130
|
throw new Error(
|
|
123
131
|
`Insert ${name} records failed the check condition: ${JSON.stringify(checkFilter, null, 2)}`,
|
|
124
132
|
);
|
|
125
133
|
}
|
|
126
134
|
|
|
127
|
-
const
|
|
135
|
+
const rowCount = Number(result.length);
|
|
136
|
+
const returningRows = hasReturning ? ([] as AnyObject[]) : undefined;
|
|
137
|
+
|
|
138
|
+
const tableRows = result.map((row) => {
|
|
139
|
+
const { [CHECK_CONDITION_ALIAS]: _checkCondition, ...tableRowWithReturning } = row;
|
|
140
|
+
if (returningRows) {
|
|
141
|
+
const returningRow: AnyObject = {};
|
|
142
|
+
for (const [newAlias, expectedAlias] of returningSelectKeyRemap.entries()) {
|
|
143
|
+
returningRow[expectedAlias] = tableRowWithReturning[newAlias];
|
|
144
|
+
if (newAlias.startsWith(RETURNING_ALIAS_PREFIX)) {
|
|
145
|
+
delete tableRowWithReturning[newAlias];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
returningRows.push(returningRow);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return tableRowWithReturning;
|
|
152
|
+
});
|
|
128
153
|
|
|
129
154
|
await executeAfterHooksCheckAndPostValidation({
|
|
130
155
|
tableHandler,
|
|
131
156
|
operation: command === "insert" ? { name: "insert", rule } : { name: "update", rule },
|
|
132
157
|
localParams,
|
|
133
|
-
rows,
|
|
158
|
+
rows: tableRows,
|
|
134
159
|
data,
|
|
135
160
|
});
|
|
136
161
|
|
|
137
162
|
let returnMany = false;
|
|
138
163
|
if (args.command === "update") {
|
|
139
164
|
const { multi = true } = args.params || {};
|
|
140
|
-
if (!multi &&
|
|
141
|
-
throw `More than 1 row modified: ${
|
|
165
|
+
if (!multi && rowCount && rowCount > 1) {
|
|
166
|
+
throw `More than 1 row modified: ${rowCount} rows affected`;
|
|
142
167
|
}
|
|
143
168
|
|
|
144
169
|
if (hasReturning) {
|
|
@@ -150,10 +175,10 @@ export const runInsertUpdateQuery = async (args: RunInsertUpdateQueryArgs) => {
|
|
|
150
175
|
|
|
151
176
|
if (!hasReturning) return undefined;
|
|
152
177
|
|
|
153
|
-
const
|
|
154
|
-
...
|
|
178
|
+
const returningRowsWithNestedInserts = returningRows?.map((returningRow) => ({
|
|
179
|
+
...returningRow,
|
|
155
180
|
...nestedInsertsResultsObj,
|
|
156
181
|
}));
|
|
157
182
|
|
|
158
|
-
return returnMany ?
|
|
183
|
+
return returnMany ? returningRowsWithNestedInserts : returningRowsWithNestedInserts?.[0];
|
|
159
184
|
};
|
|
@@ -2,25 +2,26 @@ import type { AnyObject } from "prostgles-types";
|
|
|
2
2
|
import { getJSONBObjectSchemaValidationError, omitKeys } from "prostgles-types";
|
|
3
3
|
import type { FileTableConfig } from "../../ProstglesTypes";
|
|
4
4
|
import type { FileTableRow } from "../../StorageClient/getFileTableConfig";
|
|
5
|
-
import type { LocalParams } from "../DboBuilder";
|
|
6
|
-
import { uploadFile } from "../uploadFile";
|
|
7
5
|
import type { TableHandler } from "./TableHandler";
|
|
6
|
+
import { uploadFile, type UploadFileArgs } from "./uploadFile";
|
|
8
7
|
|
|
9
|
-
type Args =
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
type Args = Pick<
|
|
9
|
+
UploadFileArgs,
|
|
10
|
+
"localParams" | "data" | "original_name" | "original_last_modified"
|
|
11
|
+
> & {
|
|
12
12
|
filter: AnyObject;
|
|
13
|
-
localParams: LocalParams | undefined;
|
|
14
13
|
};
|
|
15
14
|
export const updateFile = async (
|
|
16
15
|
tableHandler: TableHandler,
|
|
17
16
|
config: FileTableConfig,
|
|
18
|
-
{ filter, data,
|
|
17
|
+
{ filter, data, original_name, original_last_modified, localParams }: Args,
|
|
19
18
|
) => {
|
|
20
19
|
const { data: validFilter } = getJSONBObjectSchemaValidationError(
|
|
21
20
|
{ id: { optional: true, type: "string" } },
|
|
22
21
|
filter,
|
|
23
22
|
"filter",
|
|
23
|
+
undefined,
|
|
24
|
+
{ allowExtraProperties: false },
|
|
24
25
|
);
|
|
25
26
|
const existingMediaId = validFilter?.id;
|
|
26
27
|
if (!existingMediaId) {
|
|
@@ -33,16 +34,17 @@ export const updateFile = async (
|
|
|
33
34
|
id: existingMediaId,
|
|
34
35
|
})) as FileTableRow | undefined;
|
|
35
36
|
|
|
36
|
-
if (!existingFile?.
|
|
37
|
+
if (!existingFile?.id) {
|
|
37
38
|
throw new Error("Existing file record not found");
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
await config.storageClient.delete(existingFile.
|
|
41
|
+
await config.storageClient.delete(existingFile.id);
|
|
41
42
|
const newFile = await uploadFile(config, {
|
|
42
|
-
|
|
43
|
+
original_name,
|
|
43
44
|
data,
|
|
44
45
|
localParams,
|
|
45
46
|
mediaId: existingFile.id,
|
|
47
|
+
original_last_modified,
|
|
46
48
|
});
|
|
47
49
|
return { newData: omitKeys(newFile, ["id"]) };
|
|
48
50
|
};
|
|
@@ -1,26 +1,39 @@
|
|
|
1
1
|
import { randomUUID } from "crypto";
|
|
2
|
-
import {
|
|
3
|
-
import type { FileTableConfig } from "
|
|
4
|
-
import type { FileTableRow } from "
|
|
5
|
-
import { getValidatedFileType } from "
|
|
6
|
-
import { getFileServeRoute } from "
|
|
7
|
-
import type { LocalParams } from "
|
|
2
|
+
import { getJSONBObjectSchemaValidationError, type JSONB } from "prostgles-types";
|
|
3
|
+
import type { FileTableConfig } from "../../ProstglesTypes";
|
|
4
|
+
import type { FileTableRow } from "../../StorageClient/getFileTableConfig";
|
|
5
|
+
import { getValidatedFileType } from "../../StorageClient/getValidatedFileType";
|
|
6
|
+
import { getFileServeRoute } from "../../StorageClient/setupFileServeHandler";
|
|
7
|
+
import type { LocalParams } from "../DboBuilder";
|
|
8
8
|
|
|
9
9
|
const FILE_SCHEMA = {
|
|
10
10
|
id: { type: "string", optional: true },
|
|
11
|
-
|
|
11
|
+
original_name: "string",
|
|
12
|
+
original_last_modified: { type: "string", optional: true },
|
|
12
13
|
data: "Blob",
|
|
13
14
|
} as const;
|
|
14
15
|
|
|
15
16
|
type AssertFileObjectValid = (row: any) => asserts row is JSONB.GetObjectType<typeof FILE_SCHEMA>;
|
|
16
17
|
|
|
17
18
|
export const assertFileObjectValid: AssertFileObjectValid = (row) => {
|
|
18
|
-
|
|
19
|
+
const validation = getJSONBObjectSchemaValidationError(
|
|
20
|
+
FILE_SCHEMA,
|
|
21
|
+
row,
|
|
22
|
+
"file insert",
|
|
23
|
+
undefined,
|
|
24
|
+
{
|
|
25
|
+
allowExtraProperties: false,
|
|
26
|
+
},
|
|
27
|
+
);
|
|
28
|
+
if (validation.error) {
|
|
29
|
+
throw new Error(validation.error);
|
|
30
|
+
}
|
|
19
31
|
};
|
|
20
32
|
|
|
21
|
-
type UploadFileArgs = {
|
|
33
|
+
export type UploadFileArgs = {
|
|
22
34
|
data: Buffer<ArrayBufferLike>;
|
|
23
|
-
|
|
35
|
+
original_name: string;
|
|
36
|
+
original_last_modified: string | null;
|
|
24
37
|
localParams: LocalParams | undefined;
|
|
25
38
|
/**
|
|
26
39
|
* Used to update an existing file
|
|
@@ -30,31 +43,30 @@ type UploadFileArgs = {
|
|
|
30
43
|
|
|
31
44
|
export const uploadFile = async (
|
|
32
45
|
config: FileTableConfig,
|
|
33
|
-
{ data,
|
|
34
|
-
): Promise<FileTableRow> => {
|
|
46
|
+
{ data, original_name, original_last_modified, localParams, mediaId }: UploadFileArgs,
|
|
47
|
+
): Promise<Omit<FileTableRow, "added"> & Partial<Pick<FileTableRow, "added">>> => {
|
|
35
48
|
const storageClient = config.storageClient;
|
|
36
49
|
|
|
37
50
|
const media_id = mediaId ?? randomUUID();
|
|
38
51
|
const nestedInsert = localParams?.nestedInsert;
|
|
39
52
|
const type = await getValidatedFileType(config, {
|
|
40
53
|
file: data,
|
|
41
|
-
fileName:
|
|
54
|
+
fileName: original_name,
|
|
42
55
|
tableName: nestedInsert?.previousTable,
|
|
43
56
|
colName: nestedInsert?.referencingColumn,
|
|
44
57
|
});
|
|
45
|
-
|
|
46
|
-
const _parsedMediaKeys = ["id", "
|
|
58
|
+
|
|
59
|
+
const _parsedMediaKeys = ["id", "original_name", "extension", "content_type"] as const;
|
|
47
60
|
const coreInfo: Required<Pick<FileTableRow, (typeof _parsedMediaKeys)[number]>> = {
|
|
48
61
|
id: media_id,
|
|
49
|
-
|
|
50
|
-
original_name: name,
|
|
62
|
+
original_name,
|
|
51
63
|
extension: type.ext,
|
|
52
64
|
content_type: type.mime,
|
|
53
65
|
};
|
|
54
66
|
|
|
55
67
|
const uploadedInfo = await storageClient.upload({
|
|
56
68
|
file: data,
|
|
57
|
-
fileName: coreInfo.
|
|
69
|
+
fileName: coreInfo.id,
|
|
58
70
|
contentType: coreInfo.content_type,
|
|
59
71
|
});
|
|
60
72
|
|
|
@@ -63,20 +75,29 @@ export const uploadFile = async (
|
|
|
63
75
|
const { url } = uploadedInfo.type === "cloud" ? uploadedInfo : {};
|
|
64
76
|
|
|
65
77
|
const fileServeRoute = getFileServeRoute(config);
|
|
66
|
-
const mediaRow: FileTableRow = {
|
|
78
|
+
const mediaRow: Omit<FileTableRow, "added"> = {
|
|
67
79
|
signed_url: null,
|
|
68
80
|
signed_url_expires: null,
|
|
69
|
-
|
|
81
|
+
updated: new Date().toISOString(),
|
|
70
82
|
deleted: null,
|
|
71
83
|
deleted_from_storage: null,
|
|
72
84
|
description: "",
|
|
73
85
|
...coreInfo,
|
|
86
|
+
original_last_modified,
|
|
74
87
|
cloud_url: url ?? "",
|
|
75
88
|
etag: contentHash,
|
|
76
89
|
extension: type.ext,
|
|
77
|
-
url: [fileServeRoute, coreInfo.
|
|
90
|
+
url: [fileServeRoute, coreInfo.id].join("/"),
|
|
78
91
|
content_length: String(contentLength),
|
|
92
|
+
data: Buffer.from([0x01]),
|
|
79
93
|
};
|
|
80
94
|
|
|
81
|
-
|
|
95
|
+
const isInsert = !mediaId;
|
|
96
|
+
|
|
97
|
+
return isInsert ?
|
|
98
|
+
{
|
|
99
|
+
...mediaRow,
|
|
100
|
+
added: new Date().toISOString(),
|
|
101
|
+
}
|
|
102
|
+
: mediaRow;
|
|
82
103
|
};
|
|
@@ -46,6 +46,7 @@ export class ViewHandler {
|
|
|
46
46
|
columns: TableSchema["columns"];
|
|
47
47
|
columnsForTypes: ColumnInfo[];
|
|
48
48
|
column_names: string[];
|
|
49
|
+
columnSet: Set<string>;
|
|
49
50
|
tableOrViewInfo: TableSchema;
|
|
50
51
|
tsColumnDefs: string[] = [];
|
|
51
52
|
joins: Join[];
|
|
@@ -96,6 +97,7 @@ export class ViewHandler {
|
|
|
96
97
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
97
98
|
|
|
98
99
|
this.column_names = tableOrViewInfo.columns.map((c) => c.name);
|
|
100
|
+
this.columnSet = new Set(this.column_names);
|
|
99
101
|
|
|
100
102
|
this.dboBuilder = dboBuilder;
|
|
101
103
|
this.joins = this.dboBuilder.joins;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { omitKeys } from "prostgles-types";
|
|
2
2
|
import { updateFile } from "../DboBuilder/TableHandler/updateFile";
|
|
3
|
-
import { assertFileObjectValid, uploadFile } from "../DboBuilder/uploadFile";
|
|
3
|
+
import { assertFileObjectValid, uploadFile } from "../DboBuilder/TableHandler/uploadFile";
|
|
4
4
|
import type { Prostgles } from "../Prostgles";
|
|
5
5
|
import type { TableConfig } from "../TableConfig/TableConfigTypes";
|
|
6
6
|
import { setupFileServeHandler } from "./setupFileServeHandler";
|
|
@@ -8,27 +8,33 @@ import { onDeleteFromFileTable } from "../DboBuilder/TableHandler/onDeleteFromFi
|
|
|
8
8
|
import type { BeforeEachTsTrigger } from "../PublishParser/publishTypesAndUtils";
|
|
9
9
|
|
|
10
10
|
const FILE_TABLE_COLUMN_DEFINITIONS = {
|
|
11
|
-
name: `TEXT NOT NULL UNIQUE`,
|
|
12
|
-
extension: `TEXT NOT NULL`,
|
|
13
|
-
content_type: `TEXT NOT NULL`,
|
|
14
|
-
content_length: `BIGINT NOT NULL DEFAULT 0`,
|
|
15
|
-
added: `TIMESTAMP NOT NULL DEFAULT NOW()`,
|
|
16
|
-
url: `TEXT NOT NULL`,
|
|
17
11
|
id: `UUID PRIMARY KEY DEFAULT gen_random_uuid()`,
|
|
12
|
+
extension: `TEXT NOT NULL DEFAULT ''`,
|
|
13
|
+
content_type: `TEXT NOT NULL DEFAULT ''`,
|
|
14
|
+
content_length: `BIGINT NOT NULL DEFAULT 0`,
|
|
15
|
+
etag: `TEXT NOT NULL DEFAULT ''`,
|
|
18
16
|
original_name: `TEXT NOT NULL`,
|
|
17
|
+
original_last_modified: `TIMESTAMPTZ`,
|
|
19
18
|
description: `TEXT`,
|
|
19
|
+
url: `TEXT NOT NULL DEFAULT ''`,
|
|
20
20
|
cloud_url: `TEXT`,
|
|
21
21
|
signed_url: `TEXT`,
|
|
22
22
|
signed_url_expires: `BIGINT`,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
added: `TIMESTAMP NOT NULL DEFAULT NOW()`,
|
|
24
|
+
updated: `TIMESTAMP NOT NULL DEFAULT NOW()`,
|
|
25
|
+
deleted: `TIMESTAMPTZ`,
|
|
26
|
+
deleted_from_storage: `TIMESTAMPTZ`,
|
|
27
|
+
data: `BYTEA NOT NULL CHECK (data = decode('01', 'hex'))`, // Used as a placeholder to ensure insert types are correct. Actual data is uploaded to storageClient and not stored in the DB
|
|
26
28
|
} as const;
|
|
27
29
|
|
|
28
30
|
type FileTableColumnDefinitions = typeof FILE_TABLE_COLUMN_DEFINITIONS;
|
|
29
31
|
|
|
30
32
|
export type FileTableRow = {
|
|
31
33
|
[K in keyof FileTableColumnDefinitions as K]: FileTableColumnDefinitions[K] extends (
|
|
34
|
+
`BYTEA NOT NULL${string}`
|
|
35
|
+
) ?
|
|
36
|
+
Buffer
|
|
37
|
+
: FileTableColumnDefinitions[K] extends (
|
|
32
38
|
`${string} NOT NULL${string}` | `${string}PRIMARY KEY${string}`
|
|
33
39
|
) ?
|
|
34
40
|
string
|
|
@@ -101,14 +107,20 @@ export const getFileTableConfig = (prg: Prostgles): TableConfig | undefined => {
|
|
|
101
107
|
if (!tableHandler) throw "Storage tableHandler not found";
|
|
102
108
|
assertFileObjectValid(insertData);
|
|
103
109
|
|
|
104
|
-
const {
|
|
110
|
+
const {
|
|
111
|
+
data: dataBlob,
|
|
112
|
+
original_name,
|
|
113
|
+
id,
|
|
114
|
+
original_last_modified = null,
|
|
115
|
+
} = insertData;
|
|
105
116
|
const data = dataBlob as unknown as Buffer;
|
|
106
117
|
if (command === "update") {
|
|
107
118
|
const { newData } = await updateFile(tableHandler, fileTable, {
|
|
108
119
|
filter: filter ?? {},
|
|
109
120
|
localParams,
|
|
110
121
|
data,
|
|
111
|
-
|
|
122
|
+
original_name,
|
|
123
|
+
original_last_modified,
|
|
112
124
|
});
|
|
113
125
|
return {
|
|
114
126
|
row: newData,
|
|
@@ -120,9 +132,10 @@ export const getFileTableConfig = (prg: Prostgles): TableConfig | undefined => {
|
|
|
120
132
|
|
|
121
133
|
const media = await uploadFile(fileTable, {
|
|
122
134
|
data,
|
|
123
|
-
|
|
135
|
+
original_name,
|
|
124
136
|
localParams,
|
|
125
137
|
mediaId: id,
|
|
138
|
+
original_last_modified,
|
|
126
139
|
});
|
|
127
140
|
|
|
128
141
|
return {
|