@saltcorn/data 1.5.0-beta.14 → 1.5.0-beta.16

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 (47) 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 +3 -3
  5. package/dist/base-plugin/fileviews.js.map +1 -1
  6. package/dist/db/connect.d.ts.map +1 -1
  7. package/dist/db/connect.js +4 -1
  8. package/dist/db/connect.js.map +1 -1
  9. package/dist/db/state.d.ts.map +1 -1
  10. package/dist/db/state.js +9 -1
  11. package/dist/db/state.js.map +1 -1
  12. package/dist/models/config.d.ts.map +1 -1
  13. package/dist/models/config.js +12 -0
  14. package/dist/models/config.js.map +1 -1
  15. package/dist/models/email.js.map +1 -1
  16. package/dist/models/file.d.ts.map +1 -1
  17. package/dist/models/file.js +3 -0
  18. package/dist/models/file.js.map +1 -1
  19. package/dist/models/index.d.ts.map +1 -1
  20. package/dist/models/internal/s3_helpers.d.ts.map +1 -1
  21. package/dist/models/internal/s3_helpers.js +58 -2
  22. package/dist/models/internal/s3_helpers.js.map +1 -1
  23. package/dist/models/plugin.d.ts +11 -3
  24. package/dist/models/plugin.d.ts.map +1 -1
  25. package/dist/models/plugin.js +51 -12
  26. package/dist/models/plugin.js.map +1 -1
  27. package/dist/models/table.d.ts.map +1 -1
  28. package/dist/models/table.js +61 -20
  29. package/dist/models/table.js.map +1 -1
  30. package/dist/test-utils/mocks.d.ts +203 -0
  31. package/dist/test-utils/mocks.d.ts.map +1 -0
  32. package/dist/test-utils/mocks.js +329 -0
  33. package/dist/test-utils/mocks.js.map +1 -0
  34. package/dist/tests/assertions.d.ts.map +1 -1
  35. package/dist/tests/assertions.js +10 -9
  36. package/dist/tests/assertions.js.map +1 -1
  37. package/dist/tests/calc.test.js +59 -1
  38. package/dist/tests/calc.test.js.map +1 -1
  39. package/dist/tests/table_sync_info.test.d.ts +2 -0
  40. package/dist/tests/table_sync_info.test.d.ts.map +1 -0
  41. package/dist/tests/table_sync_info.test.js +62 -0
  42. package/dist/tests/table_sync_info.test.js.map +1 -0
  43. package/dist/utils.d.ts +1 -0
  44. package/dist/utils.d.ts.map +1 -1
  45. package/dist/utils.js +4 -0
  46. package/dist/utils.js.map +1 -1
  47. package/package.json +11 -8
@@ -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
  }
@@ -1364,9 +1365,9 @@ class Table {
1364
1365
  if (this.has_sync_info) {
1365
1366
  const oldInfo = await this.latestSyncInfo(id);
1366
1367
  if (oldInfo && !oldInfo.deleted)
1367
- await this.updateSyncInfo(id, oldInfo.last_modified, syncTimestamp);
1368
+ await this.updateSyncInfo(id, v, oldInfo.last_modified, syncTimestamp);
1368
1369
  else
1369
- await this.insertSyncInfo(id, syncTimestamp);
1370
+ await this.insertSyncInfo(id, v, syncTimestamp);
1370
1371
  if (state.pushHelper)
1371
1372
  state.pushHelper.pushSync(this.name);
1372
1373
  }
@@ -1407,10 +1408,26 @@ class Table {
1407
1408
  async latestSyncInfos(ids) {
1408
1409
  return await db_1.default.tryCatchInTransaction(async () => {
1409
1410
  const schema = db_1.default.getTenantSchemaPrefix();
1410
- const dbResult = await db_1.default.query(`select max(last_modified) "last_modified", ref
1411
- from ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info"
1412
- group by ref having ref = ${db_1.default.isSQLite ? "" : "ANY"} ($1)`, db_1.default.isSQLite ? ids : [ids]);
1413
- 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;
1414
1431
  }, (e) => {
1415
1432
  require("../db/state")
1416
1433
  .getState()
@@ -1418,16 +1435,21 @@ class Table {
1418
1435
  return null;
1419
1436
  });
1420
1437
  }
1421
- async insertSyncInfo(id, syncTimestamp) {
1438
+ async insertSyncInfo(id, updates, syncTimestamp) {
1422
1439
  await db_1.default.tryCatchInTransaction(async () => {
1423
1440
  const schema = db_1.default.getTenantSchemaPrefix();
1424
1441
  if (isNode()) {
1425
- await db_1.default.query(`insert into ${schema}"${db_1.default.sqlsanitize(this.name)}_sync_info" values($1,
1426
- date_trunc('milliseconds', to_timestamp($2)))`, [
1427
- id,
1428
- (syncTimestamp ? syncTimestamp : await db_1.default.time()).valueOf() /
1429
- 1000.0,
1430
- ]);
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)]);
1431
1453
  }
1432
1454
  else {
1433
1455
  await db_1.default.query(`insert into "${db_1.default.sqlsanitize(this.name)}_sync_info"
@@ -1440,15 +1462,28 @@ class Table {
1440
1462
  .log(2, `Error in insertSyncInfo: ${e.message}`);
1441
1463
  });
1442
1464
  }
1443
- async updateSyncInfo(id, oldLastModified, syncTimestamp) {
1465
+ async updateSyncInfo(id, v, oldLastModified, syncTimestamp) {
1444
1466
  await db_1.default.tryCatchInTransaction(async () => {
1445
1467
  const schema = db_1.default.getTenantSchemaPrefix();
1446
1468
  if (!db_1.default.isSQLite) {
1447
- 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)`, [
1448
- (syncTimestamp ? syncTimestamp : await db_1.default.time()).valueOf() /
1449
- 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,
1450
1484
  id,
1451
1485
  oldLastModified.valueOf() / 1000.0,
1486
+ JSON.stringify(fieldTimestamps),
1452
1487
  ]);
1453
1488
  }
1454
1489
  else {
@@ -1706,9 +1741,11 @@ class Table {
1706
1741
  if (this.has_sync_info) {
1707
1742
  await db_1.default.tryCatchInTransaction(async () => {
1708
1743
  if (isNode()) {
1744
+ // sync_info for insert
1709
1745
  const schemaPrefix = db_1.default.getTenantSchemaPrefix();
1710
1746
  await db_1.default.query(`insert into ${schemaPrefix}"${db_1.default.sqlsanitize(this.name)}_sync_info"
1711
- 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() /
1712
1749
  1000.0})))`);
1713
1750
  }
1714
1751
  else {
@@ -2018,7 +2055,11 @@ class Table {
2018
2055
  if (!pk) {
2019
2056
  throw new Error("Unable to find a field with a primary key.");
2020
2057
  }
2021
- 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)`);
2022
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)`);
2023
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)`);
2024
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)`);