@saltcorn/data 1.3.0-beta.9 → 1.3.0

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 (66) hide show
  1. package/dist/base-plugin/actions.d.ts.map +1 -1
  2. package/dist/base-plugin/actions.js +21 -9
  3. package/dist/base-plugin/actions.js.map +1 -1
  4. package/dist/base-plugin/fieldviews.d.ts +15 -0
  5. package/dist/base-plugin/fieldviews.d.ts.map +1 -1
  6. package/dist/base-plugin/fieldviews.js +62 -1
  7. package/dist/base-plugin/fieldviews.js.map +1 -1
  8. package/dist/base-plugin/index.d.ts +18 -0
  9. package/dist/base-plugin/index.d.ts.map +1 -1
  10. package/dist/base-plugin/types.d.ts +19 -0
  11. package/dist/base-plugin/types.d.ts.map +1 -1
  12. package/dist/base-plugin/types.js +4 -1
  13. package/dist/base-plugin/types.js.map +1 -1
  14. package/dist/base-plugin/viewtemplates/edit.js +1 -1
  15. package/dist/base-plugin/viewtemplates/edit.js.map +1 -1
  16. package/dist/base-plugin/viewtemplates/filter.d.ts.map +1 -1
  17. package/dist/base-plugin/viewtemplates/filter.js +18 -4
  18. package/dist/base-plugin/viewtemplates/filter.js.map +1 -1
  19. package/dist/base-plugin/viewtemplates/list.js +3 -3
  20. package/dist/base-plugin/viewtemplates/list.js.map +1 -1
  21. package/dist/base-plugin/viewtemplates/viewable_fields.d.ts.map +1 -1
  22. package/dist/base-plugin/viewtemplates/viewable_fields.js +2 -1
  23. package/dist/base-plugin/viewtemplates/viewable_fields.js.map +1 -1
  24. package/dist/models/config.d.ts.map +1 -1
  25. package/dist/models/config.js +60 -0
  26. package/dist/models/config.js.map +1 -1
  27. package/dist/models/expression.d.ts +10 -2
  28. package/dist/models/expression.d.ts.map +1 -1
  29. package/dist/models/expression.js +23 -1
  30. package/dist/models/expression.js.map +1 -1
  31. package/dist/models/field.d.ts.map +1 -1
  32. package/dist/models/field.js +1 -0
  33. package/dist/models/field.js.map +1 -1
  34. package/dist/models/file.d.ts +0 -1
  35. package/dist/models/file.d.ts.map +1 -1
  36. package/dist/models/form.d.ts +2 -0
  37. package/dist/models/form.d.ts.map +1 -1
  38. package/dist/models/form.js +3 -0
  39. package/dist/models/form.js.map +1 -1
  40. package/dist/models/index.d.ts +1 -1
  41. package/dist/models/index.d.ts.map +1 -1
  42. package/dist/models/model_instance.d.ts +0 -1
  43. package/dist/models/model_instance.d.ts.map +1 -1
  44. package/dist/models/notification.d.ts.map +1 -1
  45. package/dist/models/notification.js +37 -1
  46. package/dist/models/notification.js.map +1 -1
  47. package/dist/models/table.d.ts +1 -0
  48. package/dist/models/table.d.ts.map +1 -1
  49. package/dist/models/table.js +67 -45
  50. package/dist/models/table.js.map +1 -1
  51. package/dist/models/table_constraints.d.ts.map +1 -1
  52. package/dist/models/table_constraints.js +4 -1
  53. package/dist/models/table_constraints.js.map +1 -1
  54. package/dist/plugin-helper.d.ts.map +1 -1
  55. package/dist/plugin-helper.js +3 -1
  56. package/dist/plugin-helper.js.map +1 -1
  57. package/dist/tests/edit.test.js +2 -2
  58. package/dist/tests/edit.test.js.map +1 -1
  59. package/dist/tests/exact_views.test.js +14 -14
  60. package/dist/tests/exact_views.test.js.map +1 -1
  61. package/dist/tests/field.test.js +5 -0
  62. package/dist/tests/field.test.js.map +1 -1
  63. package/dist/utils.d.ts.map +1 -1
  64. package/dist/utils.js +2 -2
  65. package/dist/utils.js.map +1 -1
  66. package/package.json +13 -11
@@ -836,39 +836,54 @@ class Table {
836
836
  }
837
837
  }
838
838
  }
839
- if (rows) {
840
- const delIds = rows.map((r) => r[this.pk_name]);
841
- if (!db_1.default.isSQLite) {
842
- await db_1.default.deleteWhere(this.name, {
843
- [this.pk_name]: { in: delIds },
844
- });
839
+ await db_1.default.tryCatchInTransaction(async () => {
840
+ if (rows) {
841
+ const delIds = rows.map((r) => r[this.pk_name]);
842
+ if (!db_1.default.isSQLite) {
843
+ await db_1.default.deleteWhere(this.name, {
844
+ [this.pk_name]: { in: delIds },
845
+ });
846
+ }
847
+ else {
848
+ await db_1.default.query(`delete from "${db_1.default.sqlsanitize(this.name)}" where "${db_1.default.sqlsanitize(this.pk_name)}" in (${delIds.join(",")})`);
849
+ }
850
+ for (const row of rows)
851
+ await this.auto_update_calc_aggregations(row);
852
+ if (this.has_sync_info) {
853
+ const dbTime = await db_1.default.time();
854
+ await this.addDeleteSyncInfo(rows, dbTime);
855
+ }
845
856
  }
846
857
  else {
847
- await db_1.default.query(`delete from "${db_1.default.sqlsanitize(this.name)}" where "${db_1.default.sqlsanitize(this.pk_name)}" in (${delIds.join(",")})`);
848
- }
849
- for (const row of rows)
850
- await this.auto_update_calc_aggregations(row);
851
- if (this.has_sync_info) {
852
- const dbTime = await db_1.default.time();
853
- await this.addDeleteSyncInfo(rows, dbTime);
858
+ const delIds = this.has_sync_info
859
+ ? await db_1.default.select(this.name, where, {
860
+ fields: [this.pk_name],
861
+ })
862
+ : null;
863
+ await db_1.default.deleteWhere(this.name, where);
864
+ if (this.has_sync_info) {
865
+ const dbTime = await db_1.default.time();
866
+ await this.addDeleteSyncInfo(delIds, dbTime);
867
+ }
854
868
  }
855
- }
856
- else {
857
- const delIds = this.has_sync_info
858
- ? await db_1.default.select(this.name, where, {
859
- fields: [this.pk_name],
860
- })
861
- : null;
862
- await db_1.default.deleteWhere(this.name, where);
863
- if (this.has_sync_info) {
864
- const dbTime = await db_1.default.time();
865
- await this.addDeleteSyncInfo(delIds, dbTime);
869
+ //if (fields.find((f) => f.primary_key)) await this.resetSequence();
870
+ for (const file of deleteFiles) {
871
+ await file.delete();
872
+ }
873
+ }, (e) => {
874
+ if (+e.code == 23503 && e.table) {
875
+ const table = Table.findOne(e.table);
876
+ const field = table?.fields.find((f) => f.reftable_name === this.name && f.attributes.fkey_error_msg);
877
+ // TODO there could in theory be multiple key fields onto this table.
878
+ // check if e.constraint matches tableName_fieldName_fkey. if yes that is field
879
+ if (field)
880
+ throw new Error(field.attributes.fkey_error_msg);
881
+ else
882
+ throw e;
866
883
  }
867
- }
868
- //if (fields.find((f) => f.primary_key)) await this.resetSequence();
869
- for (const file of deleteFiles) {
870
- await file.delete();
871
- }
884
+ else
885
+ throw e;
886
+ });
872
887
  }
873
888
  /**
874
889
  * Returns row with only fields that can be read from db (readFromDB flag)
@@ -1263,6 +1278,7 @@ class Table {
1263
1278
  [pk_name]: id,
1264
1279
  _version: {
1265
1280
  next_version_by_id: id,
1281
+ pk_name,
1266
1282
  },
1267
1283
  _time: new Date(),
1268
1284
  _userid: user?.id,
@@ -1336,6 +1352,7 @@ class Table {
1336
1352
  this.stringify_json_fields(v1);
1337
1353
  const id = await db_1.default.insert(this.name + "__history", v1, {
1338
1354
  onConflictDoNothing: true,
1355
+ pk_name: this.pk_name,
1339
1356
  });
1340
1357
  if (!id && retry <= 3)
1341
1358
  await this.insert_history_row(v1, retry + 1);
@@ -1598,6 +1615,7 @@ class Table {
1598
1615
  [pk_name]: id,
1599
1616
  _version: {
1600
1617
  next_version_by_id: id,
1618
+ pk_name,
1601
1619
  },
1602
1620
  _userid: user?.id,
1603
1621
  _time: new Date(),
@@ -1646,7 +1664,7 @@ class Table {
1646
1664
  let v = v0;
1647
1665
  if (refetch && (calc_agg_fields.length || calc_join_agg_fields.length)) {
1648
1666
  v = (await this.getJoinedRow({
1649
- where: { [pk_name]: v0.id },
1667
+ where: { [pk_name]: v0[pk_name] },
1650
1668
  }));
1651
1669
  }
1652
1670
  //track which rows in which tables are updated
@@ -1722,7 +1740,7 @@ class Table {
1722
1740
  [matching.field]: {
1723
1741
  inSelect: {
1724
1742
  table: matching.throughTable[0],
1725
- field: "id",
1743
+ field: Table.findOne(matching.throughTable[0])?.pk_name || "id",
1726
1744
  tenant: db_1.default.isSQLite ? undefined : db_1.default.getTenantSchema(),
1727
1745
  where: { [matching.through[0]]: v[this.pk_name] },
1728
1746
  },
@@ -1923,7 +1941,7 @@ class Table {
1923
1941
  */
1924
1942
  async restore_row_version(id, version, user) {
1925
1943
  const row = await db_1.default.selectOne(`${db_1.default.sqlsanitize(this.name)}__history`, {
1926
- id,
1944
+ [this.pk_name]: id,
1927
1945
  _version: version,
1928
1946
  });
1929
1947
  var r = {};
@@ -1940,10 +1958,10 @@ class Table {
1940
1958
  * @param user
1941
1959
  */
1942
1960
  async undo_row_changes(id, user) {
1943
- const current_version_row = await db_1.default.selectMaybeOne(`${(0, internal_1.sqlsanitize)(this.name)}__history`, { id }, { orderBy: "_version", orderDesc: true, limit: 1 });
1961
+ const current_version_row = await db_1.default.selectMaybeOne(`${(0, internal_1.sqlsanitize)(this.name)}__history`, { [this.pk_name]: id }, { orderBy: "_version", orderDesc: true, limit: 1 });
1944
1962
  //get max that is not a restore
1945
1963
  const last_non_restore = await db_1.default.selectMaybeOne(`${(0, internal_1.sqlsanitize)(this.name)}__history`, {
1946
- id,
1964
+ [this.pk_name]: id,
1947
1965
  _version: {
1948
1966
  lt: current_version_row._restore_of_version
1949
1967
  ? current_version_row._restore_of_version
@@ -1960,10 +1978,10 @@ class Table {
1960
1978
  * @param user
1961
1979
  */
1962
1980
  async redo_row_changes(id, user) {
1963
- const current_version_row = await db_1.default.selectMaybeOne(`${(0, internal_1.sqlsanitize)(this.name)}__history`, { id }, { orderBy: "_version", orderDesc: true, limit: 1 });
1981
+ const current_version_row = await db_1.default.selectMaybeOne(`${(0, internal_1.sqlsanitize)(this.name)}__history`, { [this.pk_name]: id }, { orderBy: "_version", orderDesc: true, limit: 1 });
1964
1982
  if (current_version_row._restore_of_version) {
1965
1983
  const next_version = await db_1.default.selectMaybeOne(`${(0, internal_1.sqlsanitize)(this.name)}__history`, {
1966
- id,
1984
+ [this.pk_name]: id,
1967
1985
  _version: {
1968
1986
  gt: current_version_row._restore_of_version,
1969
1987
  },
@@ -1984,10 +2002,10 @@ class Table {
1984
2002
  if (typeof interval_secs === "number" && interval_secs > 0.199) {
1985
2003
  await db_1.default.query(`
1986
2004
  delete from ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}__history"
1987
- where (${(0, internal_1.sqlsanitize)(pk)}, _version) in (
2005
+ where ("${(0, internal_1.sqlsanitize)(pk)}", _version) in (
1988
2006
  select h1."${(0, internal_1.sqlsanitize)(pk)}", h1._version
1989
2007
  FROM ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}__history" h1
1990
- JOIN ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}__history" h2 ON h1.${(0, internal_1.sqlsanitize)(pk)} = h2.${(0, internal_1.sqlsanitize)(pk)}
2008
+ JOIN ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}__history" h2 ON h1."${(0, internal_1.sqlsanitize)(pk)}" = h2."${(0, internal_1.sqlsanitize)(pk)}"
1991
2009
  AND h1._version < h2._version
1992
2010
  AND h1._time < h2._time
1993
2011
  AND h2._time - h1._time <= INTERVAL '${+interval_secs} seconds'
@@ -2015,7 +2033,7 @@ class Table {
2015
2033
  ON curr.rn = prev.rn + 1 AND curr."${pk}" = prev."${pk}"
2016
2034
  )
2017
2035
  DELETE FROM ${schemaPrefix}"${(0, internal_1.sqlsanitize)(this.name)}__history"
2018
- where (${(0, internal_1.sqlsanitize)(pk)}, _version) in (select id, this_version from paired where not is_changed);`);
2036
+ where ("${(0, internal_1.sqlsanitize)(pk)}", _version) in (select id, this_version from paired where not is_changed);`);
2019
2037
  }
2020
2038
  }
2021
2039
  /**
@@ -2362,11 +2380,12 @@ class Table {
2362
2380
  let i = 1;
2363
2381
  let rejects = 0;
2364
2382
  let rejectDetails = "";
2365
- const client = db_1.default.isSQLite ? db_1.default : await db_1.default.getClient();
2383
+ const client = db_1.default.isSQLite || options?.no_transaction ? db_1.default : await db_1.default.getClient();
2366
2384
  const stats = await (0, promises_1.stat)(filePath);
2367
2385
  const fileSizeInMegabytes = stats.size / (1024 * 1024);
2368
2386
  // start sql transaction
2369
- await client.query("BEGIN");
2387
+ if (!options?.no_transaction)
2388
+ await client.query("BEGIN");
2370
2389
  const readStream = (0, fs_1.createReadStream)(filePath);
2371
2390
  const returnedRows = [];
2372
2391
  try {
@@ -2482,6 +2501,7 @@ class Table {
2482
2501
  });
2483
2502
  }
2484
2503
  catch (e) {
2504
+ console.log(e);
2485
2505
  if (!(e?.message || "").includes("current transaction is aborted, commands ignored until end of transaction"))
2486
2506
  rejectDetails += `Reject row ${i} because: ${e?.message}\n`;
2487
2507
  rejects += 1;
@@ -2510,8 +2530,9 @@ class Table {
2510
2530
  }
2511
2531
  }
2512
2532
  catch (e) {
2513
- await client.query("ROLLBACK");
2514
- if (!db_1.default.isSQLite)
2533
+ if (!options?.no_transaction)
2534
+ await client.query("ROLLBACK");
2535
+ if (!db_1.default.isSQLite && !options?.no_transaction)
2515
2536
  await client.release(true);
2516
2537
  if (e instanceof Error)
2517
2538
  reject({ error: `${e.message} in row ${i}` });
@@ -2534,8 +2555,9 @@ ${rejectDetails}`,
2534
2555
  if (rejectDetails)
2535
2556
  state.log(6, `CSV import rejectDetails: ` + rejectDetails);
2536
2557
  // stop sql transaction
2537
- await client.query("COMMIT");
2538
- if (!db_1.default.isSQLite)
2558
+ if (!options?.no_transaction)
2559
+ await client.query("COMMIT");
2560
+ if (!db_1.default.isSQLite && !options?.no_transaction)
2539
2561
  await client.release(true);
2540
2562
  if (options?.no_table_write) {
2541
2563
  return {