@saltcorn/data 1.5.0-beta.13 → 1.5.0-beta.15

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.
Files changed (56) hide show
  1. package/dist/base-plugin/actions.d.ts.map +1 -1
  2. package/dist/base-plugin/actions.js +15 -0
  3. package/dist/base-plugin/actions.js.map +1 -1
  4. package/dist/base-plugin/fileviews.js +2 -2
  5. package/dist/base-plugin/fileviews.js.map +1 -1
  6. package/dist/db/state.d.ts +4 -0
  7. package/dist/db/state.d.ts.map +1 -1
  8. package/dist/db/state.js +49 -2
  9. package/dist/db/state.js.map +1 -1
  10. package/dist/mobile-mocks/npm/dockerode.d.ts +1 -0
  11. package/dist/mobile-mocks/npm/dockerode.d.ts.map +1 -0
  12. package/dist/mobile-mocks/npm/dockerode.js +2 -0
  13. package/dist/mobile-mocks/npm/dockerode.js.map +1 -0
  14. package/dist/models/config.d.ts.map +1 -1
  15. package/dist/models/config.js +42 -4
  16. package/dist/models/config.js.map +1 -1
  17. package/dist/models/field.d.ts +1 -1
  18. package/dist/models/field.d.ts.map +1 -1
  19. package/dist/models/field.js +6 -0
  20. package/dist/models/field.js.map +1 -1
  21. package/dist/models/file.d.ts.map +1 -1
  22. package/dist/models/file.js +3 -0
  23. package/dist/models/file.js.map +1 -1
  24. package/dist/models/form.d.ts.map +1 -1
  25. package/dist/models/form.js.map +1 -1
  26. package/dist/models/internal/push_message_helper.d.ts +42 -12
  27. package/dist/models/internal/push_message_helper.d.ts.map +1 -1
  28. package/dist/models/internal/push_message_helper.js +117 -50
  29. package/dist/models/internal/push_message_helper.js.map +1 -1
  30. package/dist/models/internal/s3_helpers.d.ts.map +1 -1
  31. package/dist/models/internal/s3_helpers.js +58 -2
  32. package/dist/models/internal/s3_helpers.js.map +1 -1
  33. package/dist/models/notification.d.ts.map +1 -1
  34. package/dist/models/notification.js +2 -5
  35. package/dist/models/notification.js.map +1 -1
  36. package/dist/models/table.d.ts.map +1 -1
  37. package/dist/models/table.js +70 -20
  38. package/dist/models/table.js.map +1 -1
  39. package/dist/models/workflow_step.js +1 -1
  40. package/dist/models/workflow_step.js.map +1 -1
  41. package/dist/tests/calc.test.js +59 -1
  42. package/dist/tests/calc.test.js.map +1 -1
  43. package/dist/tests/form.test.js +150 -71
  44. package/dist/tests/form.test.js.map +1 -1
  45. package/dist/tests/table_sync_info.test.d.ts +2 -0
  46. package/dist/tests/table_sync_info.test.d.ts.map +1 -0
  47. package/dist/tests/table_sync_info.test.js +62 -0
  48. package/dist/tests/table_sync_info.test.js.map +1 -0
  49. package/dist/tests/workflow.test.js +1 -1
  50. package/dist/tests/workflow.test.js.map +1 -1
  51. package/dist/utils.d.ts +7 -0
  52. package/dist/utils.d.ts.map +1 -1
  53. package/dist/utils.js +26 -0
  54. package/dist/utils.js.map +1 -1
  55. package/package.json +10 -8
  56. package/webpack.config.js +3 -0
@@ -757,7 +757,8 @@ class Table {
757
757
  if (isNode()) {
758
758
  await db_1.default.query(`delete from ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" where ref in (
759
759
  ${ids.map((row) => row[pkName]).join(",")})`);
760
- await db_1.default.query(`insert into ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" values ${ids
760
+ await db_1.default.query(`insert into ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" (ref, last_modified, deleted)
761
+ values ${ids
761
762
  .map((row) => `(${row[pkName]}, date_trunc('milliseconds', to_timestamp( ${timestamp.valueOf() / 1000.0} ) ), true)`)
762
763
  .join(",")}`);
763
764
  }
@@ -907,6 +908,11 @@ class Table {
907
908
  else
908
909
  throw e;
909
910
  });
911
+ if (this.has_sync_info) {
912
+ const state = require("../db/state").getState();
913
+ if (state.pushHelper)
914
+ state.pushHelper.pushSync(this.name);
915
+ }
910
916
  }
911
917
  /**
912
918
  * Returns row with only fields that can be read from db (readFromDB flag)
@@ -1359,9 +1365,11 @@ class Table {
1359
1365
  if (this.has_sync_info) {
1360
1366
  const oldInfo = await this.latestSyncInfo(id);
1361
1367
  if (oldInfo && !oldInfo.deleted)
1362
- await this.updateSyncInfo(id, oldInfo.last_modified, syncTimestamp);
1368
+ await this.updateSyncInfo(id, v, oldInfo.last_modified, syncTimestamp);
1363
1369
  else
1364
- await this.insertSyncInfo(id, syncTimestamp);
1370
+ await this.insertSyncInfo(id, v, syncTimestamp);
1371
+ if (state.pushHelper)
1372
+ state.pushHelper.pushSync(this.name);
1365
1373
  }
1366
1374
  const newRow = { ...existing, ...v, [pk_name]: id };
1367
1375
  if (really_changed_field_names.size > 0) {
@@ -1400,10 +1408,26 @@ class Table {
1400
1408
  async latestSyncInfos(ids) {
1401
1409
  return await db_1.default.tryCatchInTransaction(async () => {
1402
1410
  const schema = db_1.default.getTenantSchemaPrefix();
1403
- const dbResult = await db_1.default.query(`select max(last_modified) "last_modified", ref
1404
- from ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info"
1405
- group by ref having ref = ${db_1.default.isSQLite ? "" : "ANY"} ($1)`, db_1.default.isSQLite ? ids : [ids]);
1406
- return dbResult.rows;
1411
+ const sql = !db_1.default.isSQLite
1412
+ ? `
1413
+ SELECT s.last_modified, s.ref, s.updated_fields
1414
+ FROM ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" s
1415
+ JOIN (
1416
+ SELECT
1417
+ ref,
1418
+ MAX(last_modified) AS last_modified
1419
+ FROM ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info"
1420
+ WHERE ref = ${db_1.default.isSQLite ? "" : "ANY"} ($1)
1421
+ GROUP BY ref
1422
+ ) m
1423
+ ON s.ref = m.ref
1424
+ AND s.last_modified = m.last_modified`
1425
+ : `
1426
+ SELECT MAX(last_modified) "last_modified", ref
1427
+ FROM ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info"
1428
+ GROUP BY ref HAVING ref = ($1)`;
1429
+ const result = await db_1.default.query(sql, db_1.default.isSQLite ? ids : [ids]);
1430
+ return result.rows;
1407
1431
  }, (e) => {
1408
1432
  require("../db/state")
1409
1433
  .getState()
@@ -1411,16 +1435,21 @@ class Table {
1411
1435
  return null;
1412
1436
  });
1413
1437
  }
1414
- async insertSyncInfo(id, syncTimestamp) {
1438
+ async insertSyncInfo(id, updates, syncTimestamp) {
1415
1439
  await db_1.default.tryCatchInTransaction(async () => {
1416
1440
  const schema = db_1.default.getTenantSchemaPrefix();
1417
1441
  if (isNode()) {
1418
- await db_1.default.query(`insert into ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" values($1,
1419
- date_trunc('milliseconds', to_timestamp($2)))`, [
1420
- id,
1421
- (syncTimestamp ? syncTimestamp : await db_1.default.time()).valueOf() /
1422
- 1000.0,
1423
- ]);
1442
+ const timestamp = syncTimestamp ? syncTimestamp : await db_1.default.time();
1443
+ const fieldTimestamps = {};
1444
+ for (const k of Object.keys(updates).filter((key) => key !== this.pk_name)) {
1445
+ fieldTimestamps[k] = timestamp;
1446
+ }
1447
+ await db_1.default.query(`insert into ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" (ref, last_modified, updated_fields)
1448
+ values(
1449
+ $1,
1450
+ date_trunc('milliseconds', to_timestamp($2)),
1451
+ $3::jsonb
1452
+ )`, [id, timestamp.valueOf() / 1000.0, JSON.stringify(fieldTimestamps)]);
1424
1453
  }
1425
1454
  else {
1426
1455
  await db_1.default.query(`insert into "${db_1.default.sqlsanitize(this.name)}_sync_info"
@@ -1433,15 +1462,28 @@ class Table {
1433
1462
  .log(2, `Error in insertSyncInfo: ${e.message}`);
1434
1463
  });
1435
1464
  }
1436
- async updateSyncInfo(id, oldLastModified, syncTimestamp) {
1465
+ async updateSyncInfo(id, v, oldLastModified, syncTimestamp) {
1437
1466
  await db_1.default.tryCatchInTransaction(async () => {
1438
1467
  const schema = db_1.default.getTenantSchemaPrefix();
1439
1468
  if (!db_1.default.isSQLite) {
1440
- 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)`, [
1441
- (syncTimestamp ? syncTimestamp : await db_1.default.time()).valueOf() /
1442
- 1000.0,
1469
+ const timestamp = syncTimestamp
1470
+ ? new Date(syncTimestamp)
1471
+ : await db_1.default.time();
1472
+ const fieldTimestamps = {};
1473
+ for (const k of Object.keys(v).filter((key) => key !== this.pk_name)) {
1474
+ fieldTimestamps[k] = timestamp;
1475
+ }
1476
+ await db_1.default.query(`update ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info"
1477
+ set
1478
+ last_modified=date_trunc('milliseconds', to_timestamp($1)),
1479
+ updated_fields =
1480
+ coalesce(updated_fields, '{}'::jsonb) || $4::jsonb
1481
+ where
1482
+ ref=$2 and last_modified = to_timestamp($3)`, [
1483
+ timestamp.valueOf() / 1000.0,
1443
1484
  id,
1444
1485
  oldLastModified.valueOf() / 1000.0,
1486
+ JSON.stringify(fieldTimestamps),
1445
1487
  ]);
1446
1488
  }
1447
1489
  else {
@@ -1699,9 +1741,11 @@ class Table {
1699
1741
  if (this.has_sync_info) {
1700
1742
  await db_1.default.tryCatchInTransaction(async () => {
1701
1743
  if (isNode()) {
1744
+ // sync_info for insert
1702
1745
  const schemaPrefix = db_1.default.getTenantSchemaPrefix();
1703
1746
  await db_1.default.query(`insert into ${schemaPrefix}"${db_1.default.sqlsanitize(this.name)}_sync_info"
1704
- values(${id}, date_trunc('milliseconds', to_timestamp(${(syncTimestamp ? syncTimestamp : await db_1.default.time()).valueOf() /
1747
+ (ref, last_modified) values(
1748
+ ${id}, date_trunc('milliseconds', to_timestamp(${(syncTimestamp ? syncTimestamp : await db_1.default.time()).valueOf() /
1705
1749
  1000.0})))`);
1706
1750
  }
1707
1751
  else {
@@ -1712,6 +1756,8 @@ class Table {
1712
1756
  }, (e) => {
1713
1757
  state.log(2, `Error inserting sync info for table ${this.name}: ${e.message}`);
1714
1758
  });
1759
+ if (state.pushHelper)
1760
+ state.pushHelper.pushSync(this.name);
1715
1761
  }
1716
1762
  const newRow = { [pk_name]: id, ...v };
1717
1763
  await this.auto_update_calc_aggregations(newRow);
@@ -2009,7 +2055,11 @@ class Table {
2009
2055
  if (!pk) {
2010
2056
  throw new Error("Unable to find a field with a primary key.");
2011
2057
  }
2012
- 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)`);
2058
+ await db_1.default.query(`create table ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}_sync_info" (
2059
+ ref integer,
2060
+ last_modified timestamp,
2061
+ deleted boolean default false,
2062
+ updated_fields jsonb)`);
2013
2063
  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)`);
2014
2064
  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)`);
2015
2065
  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)`);