@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.
@@ -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
- if (ids.length > 0) {
754
- const schema = db_1.default.getTenantSchemaPrefix();
755
- const pkName = this.pk_name || "id";
756
- if (isNode()) {
757
- await db_1.default.query(`delete from ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" where ref in (
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
- await db_1.default.query(`insert into ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" values ${ids
760
- .map((row) => `(${row[pkName]}, date_trunc('milliseconds', to_timestamp( ${timestamp.valueOf() / 1000.0} ) ), true)`)
761
- .join(",")}`);
762
- }
763
- else {
764
- await db_1.default.query(`update "${db_1.default.sqlsanitize(this.name)}_sync_info"
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: !user,
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
- const schema = db_1.default.getTenantSchemaPrefix();
1382
- const dbResult = await db_1.default.query(`select max(last_modified) "last_modified", ref
1383
- from ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info"
1384
- group by ref having ref = ${db_1.default.isSQLite ? "" : "ANY"} ($1)`, db_1.default.isSQLite ? ids : [ids]);
1385
- return dbResult.rows;
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
- const schema = db_1.default.getTenantSchemaPrefix();
1389
- if (isNode()) {
1390
- await db_1.default.query(`insert into ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" values($1,
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
- id,
1393
- (syncTimestamp ? syncTimestamp : await db_1.default.time()).valueOf() / 1000.0,
1394
- ]);
1395
- }
1396
- else {
1397
- await db_1.default.query(`insert into "${db_1.default.sqlsanitize(this.name)}_sync_info"
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
- const schema = db_1.default.getTenantSchemaPrefix();
1404
- if (!db_1.default.isSQLite) {
1405
- 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)`, [
1406
- (syncTimestamp ? syncTimestamp : await db_1.default.time()).valueOf() / 1000.0,
1407
- id,
1408
- oldLastModified.valueOf() / 1000.0,
1409
- ]);
1410
- }
1411
- else {
1412
- await db_1.default.query(`update "${db_1.default.sqlsanitize(this.name)}_sync_info" set modified_local = true
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
- if (isNode()) {
1654
- const schemaPrefix = db_1.default.getTenantSchemaPrefix();
1655
- await db_1.default.query(`insert into ${schemaPrefix}"${db_1.default.sqlsanitize(this.name)}_sync_info"
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
- 1000.0})))`);
1658
- }
1659
- else {
1660
- await db_1.default.query(`insert into "${db_1.default.sqlsanitize(this.name)}_sync_info"
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
- const schemaPrefix = db_1.default.getTenantSchemaPrefix();
1955
- const fields = this.fields;
1956
- const pk = fields.find((f) => f.primary_key)?.name;
1957
- if (!pk) {
1958
- throw new Error("Unable to find a field with a primary key.");
1959
- }
1960
- 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)`);
1961
- 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)`);
1962
- 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)`);
1963
- 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)`);
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
- const schemaPrefix = db_1.default.getTenantSchemaPrefix();
1967
- await db_1.default.query(`
1968
- drop table ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}_sync_info";`);
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