@saltcorn/data 1.4.0-beta.3 → 1.4.0-beta.5
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/base-plugin/actions.d.ts +1 -1
- package/dist/base-plugin/actions.d.ts.map +1 -1
- package/dist/base-plugin/actions.js +5 -4
- package/dist/base-plugin/actions.js.map +1 -1
- package/dist/base-plugin/fileviews.js +3 -3
- package/dist/base-plugin/fileviews.js.map +1 -1
- package/dist/base-plugin/viewtemplates/edit.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/edit.js +1 -1
- package/dist/base-plugin/viewtemplates/edit.js.map +1 -1
- package/dist/db/state.d.ts +7 -3
- package/dist/db/state.d.ts.map +1 -1
- package/dist/db/state.js +21 -11
- package/dist/db/state.js.map +1 -1
- package/dist/models/file.d.ts.map +1 -1
- package/dist/models/file.js +2 -0
- package/dist/models/file.js.map +1 -1
- package/dist/models/table.d.ts +3 -3
- package/dist/models/table.d.ts.map +1 -1
- package/dist/models/table.js +110 -63
- package/dist/models/table.js.map +1 -1
- package/dist/models/trigger.d.ts.map +1 -1
- package/dist/models/trigger.js +1 -1
- package/dist/models/trigger.js.map +1 -1
- package/dist/tests/actions.test.js +2 -2
- package/dist/tests/actions.test.js.map +1 -1
- package/dist/tests/auth.test.js +15 -2
- package/dist/tests/auth.test.js.map +1 -1
- package/package.json +9 -10
package/dist/models/table.js
CHANGED
|
@@ -56,7 +56,7 @@ const promises_1 = require("fs/promises");
|
|
|
56
56
|
//import { num_between } from "@saltcorn/types/generators";
|
|
57
57
|
//import { devNull } from "os";
|
|
58
58
|
const utils_1 = __importDefault(require("../utils"));
|
|
59
|
-
const { prefixFieldsInWhere, InvalidConfiguration, InvalidAdminAction, satisfies, structuredClone, getLines, mergeIntoWhere, stringToJSON, isNode, apply, applyAsync, asyncMap, } = utils_1.default;
|
|
59
|
+
const { prefixFieldsInWhere, InvalidConfiguration, mergeActionResults, InvalidAdminAction, satisfies, structuredClone, getLines, mergeIntoWhere, stringToJSON, isNode, apply, applyAsync, asyncMap, } = utils_1.default;
|
|
60
60
|
const tags_1 = __importDefault(require("@saltcorn/markup/tags"));
|
|
61
61
|
const { text } = tags_1.default;
|
|
62
62
|
const table_helper_1 = require("./internal/table_helper");
|
|
@@ -750,22 +750,28 @@ class Table {
|
|
|
750
750
|
}
|
|
751
751
|
}
|
|
752
752
|
async addDeleteSyncInfo(ids, timestamp) {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
753
|
+
await db_1.default.tryCatchInTransaction(async () => {
|
|
754
|
+
if (ids.length > 0) {
|
|
755
|
+
const schema = db_1.default.getTenantSchemaPrefix();
|
|
756
|
+
const pkName = this.pk_name || "id";
|
|
757
|
+
if (isNode()) {
|
|
758
|
+
await db_1.default.query(`delete from ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" where ref in (
|
|
758
759
|
${ids.map((row) => row[pkName]).join(",")})`);
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
760
|
+
await db_1.default.query(`insert into ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" values ${ids
|
|
761
|
+
.map((row) => `(${row[pkName]}, date_trunc('milliseconds', to_timestamp( ${timestamp.valueOf() / 1000.0} ) ), true)`)
|
|
762
|
+
.join(",")}`);
|
|
763
|
+
}
|
|
764
|
+
else {
|
|
765
|
+
await db_1.default.query(`update "${db_1.default.sqlsanitize(this.name)}_sync_info"
|
|
765
766
|
set deleted = true, modified_local = true
|
|
766
767
|
where ref in (${ids.map((row) => row[pkName]).join(",")})`);
|
|
768
|
+
}
|
|
767
769
|
}
|
|
768
|
-
}
|
|
770
|
+
}, (e) => {
|
|
771
|
+
require("../db/state")
|
|
772
|
+
.getState()
|
|
773
|
+
.log(2, `Error in addDeleteSyncInfo: ${e.message}`);
|
|
774
|
+
});
|
|
769
775
|
}
|
|
770
776
|
/**
|
|
771
777
|
* Delete rows from table. The first argument is a where expression indicating the conditions for the rows to be deleted
|
|
@@ -780,7 +786,7 @@ class Table {
|
|
|
780
786
|
* @param user - optional user, if null then no authorization will be checked
|
|
781
787
|
* @returns
|
|
782
788
|
*/
|
|
783
|
-
async deleteRows(where, user, noTrigger) {
|
|
789
|
+
async deleteRows(where, user, noTrigger, resultCollector) {
|
|
784
790
|
//Fast truncate if user is admin and where is blank
|
|
785
791
|
const cfields = await field_1.default.find({ reftable_name: this.name }, { cached: true });
|
|
786
792
|
if ((!user || user?.role_id === 1) &&
|
|
@@ -816,7 +822,7 @@ class Table {
|
|
|
816
822
|
rows = await this.getJoinedRows({
|
|
817
823
|
where,
|
|
818
824
|
forUser: user,
|
|
819
|
-
forPublic:
|
|
825
|
+
forPublic: user?.role_id === 100,
|
|
820
826
|
});
|
|
821
827
|
}
|
|
822
828
|
const deleteFileFields = fields.filter((f) => f.type === "File" && f.attributes?.also_delete_file);
|
|
@@ -826,13 +832,17 @@ class Table {
|
|
|
826
832
|
if (!rows)
|
|
827
833
|
rows = await this.getJoinedRows({
|
|
828
834
|
where,
|
|
835
|
+
forUser: user,
|
|
836
|
+
forPublic: user?.role_id === 100,
|
|
829
837
|
});
|
|
830
838
|
for (const trigger of triggers) {
|
|
831
839
|
for (const row of rows) {
|
|
832
840
|
// run triggers on delete
|
|
833
841
|
if (trigger.haltOnOnlyIf?.(row, user))
|
|
834
842
|
continue;
|
|
835
|
-
await trigger.run(row, { user });
|
|
843
|
+
const runres = await trigger.run(row, { user });
|
|
844
|
+
if (runres && resultCollector)
|
|
845
|
+
mergeActionResults(resultCollector, runres);
|
|
836
846
|
}
|
|
837
847
|
}
|
|
838
848
|
if (isNode()) {
|
|
@@ -1378,40 +1388,61 @@ class Table {
|
|
|
1378
1388
|
return rows?.length === 1 ? rows[0] : null;
|
|
1379
1389
|
}
|
|
1380
1390
|
async latestSyncInfos(ids) {
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1391
|
+
return await db_1.default.tryCatchInTransaction(async () => {
|
|
1392
|
+
const schema = db_1.default.getTenantSchemaPrefix();
|
|
1393
|
+
const dbResult = await db_1.default.query(`select max(last_modified) "last_modified", ref
|
|
1394
|
+
from ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info"
|
|
1395
|
+
group by ref having ref = ${db_1.default.isSQLite ? "" : "ANY"} ($1)`, db_1.default.isSQLite ? ids : [ids]);
|
|
1396
|
+
return dbResult.rows;
|
|
1397
|
+
}, (e) => {
|
|
1398
|
+
require("../db/state")
|
|
1399
|
+
.getState()
|
|
1400
|
+
.log(2, `Error in latestSyncInfos: ${e.message}`);
|
|
1401
|
+
return null;
|
|
1402
|
+
});
|
|
1386
1403
|
}
|
|
1387
1404
|
async insertSyncInfo(id, syncTimestamp) {
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1405
|
+
await db_1.default.tryCatchInTransaction(async () => {
|
|
1406
|
+
const schema = db_1.default.getTenantSchemaPrefix();
|
|
1407
|
+
if (isNode()) {
|
|
1408
|
+
await db_1.default.query(`insert into ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" values($1,
|
|
1391
1409
|
date_trunc('milliseconds', to_timestamp($2)))`, [
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1410
|
+
id,
|
|
1411
|
+
(syncTimestamp ? syncTimestamp : await db_1.default.time()).valueOf() /
|
|
1412
|
+
1000.0,
|
|
1413
|
+
]);
|
|
1414
|
+
}
|
|
1415
|
+
else {
|
|
1416
|
+
await db_1.default.query(`insert into "${db_1.default.sqlsanitize(this.name)}_sync_info"
|
|
1398
1417
|
(ref, modified_local, deleted)
|
|
1399
1418
|
values('${id}', true, false)`);
|
|
1400
|
-
|
|
1419
|
+
}
|
|
1420
|
+
}, (e) => {
|
|
1421
|
+
require("../db/state")
|
|
1422
|
+
.getState()
|
|
1423
|
+
.log(2, `Error in insertSyncInfo: ${e.message}`);
|
|
1424
|
+
});
|
|
1401
1425
|
}
|
|
1402
1426
|
async updateSyncInfo(id, oldLastModified, syncTimestamp) {
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1427
|
+
await db_1.default.tryCatchInTransaction(async () => {
|
|
1428
|
+
const schema = db_1.default.getTenantSchemaPrefix();
|
|
1429
|
+
if (!db_1.default.isSQLite) {
|
|
1430
|
+
await db_1.default.query(`update ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" set last_modified=date_trunc('milliseconds', to_timestamp($1)) where ref=$2 and last_modified = to_timestamp($3)`, [
|
|
1431
|
+
(syncTimestamp ? syncTimestamp : await db_1.default.time()).valueOf() /
|
|
1432
|
+
1000.0,
|
|
1433
|
+
id,
|
|
1434
|
+
oldLastModified.valueOf() / 1000.0,
|
|
1435
|
+
]);
|
|
1436
|
+
}
|
|
1437
|
+
else {
|
|
1438
|
+
await db_1.default.query(`update "${db_1.default.sqlsanitize(this.name)}_sync_info" set modified_local = true
|
|
1413
1439
|
where ref = ${id} and last_modified = ${oldLastModified ? oldLastModified.valueOf() : "null"}`);
|
|
1414
|
-
|
|
1440
|
+
}
|
|
1441
|
+
}, (e) => {
|
|
1442
|
+
require("../db/state")
|
|
1443
|
+
.getState()
|
|
1444
|
+
.log(2, `Error in updateSyncInfo: ${e.message}`);
|
|
1445
|
+
});
|
|
1415
1446
|
}
|
|
1416
1447
|
/**
|
|
1417
1448
|
* Try to Update row
|
|
@@ -1650,17 +1681,21 @@ class Table {
|
|
|
1650
1681
|
_time: new Date(),
|
|
1651
1682
|
});
|
|
1652
1683
|
if (this.has_sync_info) {
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1684
|
+
await db_1.default.tryCatchInTransaction(async () => {
|
|
1685
|
+
if (isNode()) {
|
|
1686
|
+
const schemaPrefix = db_1.default.getTenantSchemaPrefix();
|
|
1687
|
+
await db_1.default.query(`insert into ${schemaPrefix}"${db_1.default.sqlsanitize(this.name)}_sync_info"
|
|
1656
1688
|
values(${id}, date_trunc('milliseconds', to_timestamp(${(syncTimestamp ? syncTimestamp : await db_1.default.time()).valueOf() /
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1689
|
+
1000.0})))`);
|
|
1690
|
+
}
|
|
1691
|
+
else {
|
|
1692
|
+
await db_1.default.query(`insert into "${db_1.default.sqlsanitize(this.name)}_sync_info"
|
|
1661
1693
|
(last_modified, ref, modified_local, deleted)
|
|
1662
1694
|
values(NULL, ${id}, true, false)`);
|
|
1663
|
-
|
|
1695
|
+
}
|
|
1696
|
+
}, (e) => {
|
|
1697
|
+
state.log(2, `Error inserting sync info for table ${this.name}: ${e.message}`);
|
|
1698
|
+
});
|
|
1664
1699
|
}
|
|
1665
1700
|
const newRow = { [pk_name]: id, ...v };
|
|
1666
1701
|
await this.auto_update_calc_aggregations(newRow);
|
|
@@ -1951,21 +1986,33 @@ class Table {
|
|
|
1951
1986
|
);`);
|
|
1952
1987
|
}
|
|
1953
1988
|
async create_sync_info_table() {
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1989
|
+
await db_1.default.tryCatchInTransaction(async () => {
|
|
1990
|
+
const schemaPrefix = db_1.default.getTenantSchemaPrefix();
|
|
1991
|
+
const fields = this.fields;
|
|
1992
|
+
const pk = fields.find((f) => f.primary_key)?.name;
|
|
1993
|
+
if (!pk) {
|
|
1994
|
+
throw new Error("Unable to find a field with a primary key.");
|
|
1995
|
+
}
|
|
1996
|
+
await db_1.default.query(`create table ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}_sync_info" (ref integer, last_modified timestamp, deleted boolean default false)`);
|
|
1997
|
+
await db_1.default.query(`create index "${(0, internal_1.sqlsanitize)(this.name)}_sync_info_ref_index" on ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}_sync_info"(ref)`);
|
|
1998
|
+
await db_1.default.query(`create index "${(0, internal_1.sqlsanitize)(this.name)}_sync_info_lm_index" on ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}_sync_info"(last_modified)`);
|
|
1999
|
+
await db_1.default.query(`create index "${(0, internal_1.sqlsanitize)(this.name)}_sync_info_deleted_index" on ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}_sync_info"(deleted)`);
|
|
2000
|
+
}, (e) => {
|
|
2001
|
+
require("../db/state")
|
|
2002
|
+
.getState()
|
|
2003
|
+
.log(2, `Error creating sync_info table for ${this.name}: ${e.message}`);
|
|
2004
|
+
});
|
|
1964
2005
|
}
|
|
1965
2006
|
async drop_sync_table() {
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
2007
|
+
await db_1.default.tryCatchInTransaction(async () => {
|
|
2008
|
+
const schemaPrefix = db_1.default.getTenantSchemaPrefix();
|
|
2009
|
+
await db_1.default.query(`
|
|
2010
|
+
drop table ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}_sync_info";`);
|
|
2011
|
+
}, (e) => {
|
|
2012
|
+
require("../db/state")
|
|
2013
|
+
.getState()
|
|
2014
|
+
.log(2, `Error dropping sync_info table for ${this.name}: ${e.message}`);
|
|
2015
|
+
});
|
|
1969
2016
|
}
|
|
1970
2017
|
/**
|
|
1971
2018
|
* Restore Row Version
|