orange-orm 4.8.0 → 4.8.2

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 (50) hide show
  1. package/dist/index.browser.mjs +4355 -3529
  2. package/dist/index.mjs +5185 -3581
  3. package/docs/changelog.md +7 -1
  4. package/package.json +1 -1
  5. package/src/applyPatch.js +67 -45
  6. package/src/bunPg/newTransaction.js +18 -0
  7. package/src/bunPg/wrapCommand.js +148 -0
  8. package/src/bunSqlite/newTransaction.js +18 -0
  9. package/src/bunSqlite/wrapCommand.js +30 -0
  10. package/src/bunSqlite/wrapQuery.js +1 -1
  11. package/src/d1/newTransaction.js +18 -0
  12. package/src/d1/wrapCommand.js +34 -0
  13. package/src/mssql/newTransaction.js +19 -0
  14. package/src/mssql/wrapCommand.js +129 -0
  15. package/src/mySql/newTransaction.js +18 -0
  16. package/src/mySql/wrapCommand.js +22 -0
  17. package/src/nodeSqlite/newTransaction.js +18 -0
  18. package/src/nodeSqlite/wrapCommand.js +34 -0
  19. package/src/oracle/newTransaction.js +18 -0
  20. package/src/oracle/wrapCommand.js +37 -0
  21. package/src/patchTable.js +111 -17
  22. package/src/pg/newTransaction.js +18 -0
  23. package/src/pg/wrapCommand.js +31 -0
  24. package/src/pglite/newTransaction.js +18 -0
  25. package/src/pglite/wrapCommand.js +30 -0
  26. package/src/sap/newTransaction.js +18 -0
  27. package/src/sqlite3/newTransaction.js +18 -0
  28. package/src/sqlite3/wrapCommand.js +23 -0
  29. package/src/table/commands/delete/newSingleCommand.js +3 -3
  30. package/src/table/commands/delete/singleCommand/newSingleCommandCore.js +112 -3
  31. package/src/table/commands/newDeleteCommand.js +3 -3
  32. package/src/table/commands/newRow.js +2 -2
  33. package/src/table/commands/newUpdateCommand.js +52 -2
  34. package/src/table/commands/newUpdateCommandCore.js +307 -4
  35. package/src/table/executeQueries/executeChanges.js +3 -3
  36. package/src/table/executeQueries/executeCommand.js +8 -0
  37. package/src/table/executeQueries/negotiateNullParams.js +26 -0
  38. package/src/table/executeQueries/resolveExecuteCommand.js +28 -0
  39. package/src/table/executeQueries/resolveExecuteQuery.js +1 -23
  40. package/src/table/isJsonUpdateSupported.js +5 -0
  41. package/src/table/resultToRows/decodeDbRow.js +13 -7
  42. package/src/table/resultToRows/delete.js +43 -2
  43. package/src/table/resultToRows/newDecodeDbRow.js +1 -7
  44. package/src/table.js +62 -0
  45. package/src/tedious/newTransaction.js +18 -0
  46. package/src/tedious/wrapCommand.js +121 -0
  47. package/src/validateDeleteAllowed.js +27 -10
  48. package/src/patchRow.js +0 -13
  49. package/src/table/insertDefault.js +0 -88
  50. package/src/validateDeleteConflict.js +0 -98
@@ -1,4 +1,5 @@
1
1
  const getSessionSingleton = require('../getSessionSingleton');
2
+ const negotiateNullParams = require('./negotiateNullParams');
2
3
 
3
4
  function resolveExecuteQuery(context, query) {
4
5
  return resolve;
@@ -22,29 +23,6 @@ function resolveExecuteQuery(context, query) {
22
23
 
23
24
  }
24
25
 
25
- function negotiateNullParams(query) {
26
- if (query && query.parameters && query.parameters.length > 0 && (query.parameters.filter(x => x === null || x === undefined).length > 0)) {
27
- var splitted = query.sql().split('?');
28
- var sql = '';
29
- var parameters = [];
30
- var lastIndex = splitted.length - 1;
31
- for (var i = 0; i < lastIndex; i++) {
32
- if (query.parameters[i] === null || query.parameters[i] === undefined)
33
- sql += splitted[i] + 'null';
34
- else {
35
- sql += splitted[i] + '?';
36
- parameters.push(query.parameters[i]);
37
- }
38
- }
39
- sql += splitted[lastIndex];
40
- return {
41
- sql: () => sql,
42
- parameters
43
- };
44
26
 
45
- }
46
- else
47
- return query;
48
- }
49
27
 
50
28
  module.exports = resolveExecuteQuery;
@@ -0,0 +1,5 @@
1
+ function isJsonUpdateSupported(engine) {
2
+ return engine === 'pg' || engine === 'mysql' || engine === 'sqlite' || engine === 'mssql' || engine === 'mssqlNative' || engine === 'oracle';
3
+ }
4
+
5
+ module.exports = isJsonUpdateSupported;
@@ -1,7 +1,18 @@
1
1
  var newDecodeDbRow = require('./newDecodeDbRow');
2
2
 
3
3
  function decodeDbRow(context, span, table, dbRow, shouldValidate, isInsert) {
4
- var decode = span._decodeDbRow;
4
+ var decodeCache = span._decodeDbRowCache;
5
+ if (!decodeCache) {
6
+ decodeCache = {};
7
+ Object.defineProperty(span, '_decodeDbRowCache', {
8
+ enumerable: false,
9
+ get: function() {
10
+ return decodeCache;
11
+ },
12
+ });
13
+ }
14
+ var cacheKey = (shouldValidate ? 'v' : 'nv') + (isInsert ? ':i' : ':u');
15
+ var decode = decodeCache[cacheKey];
5
16
  if (!decode) {
6
17
  let aliases = new Set();
7
18
  if (span.columns)
@@ -12,12 +23,7 @@ function decodeDbRow(context, span, table, dbRow, shouldValidate, isInsert) {
12
23
  if (aliases.size === 0)
13
24
  aliases = undefined;
14
25
  decode = newDecodeDbRow(table, dbRow, aliases, shouldValidate, isInsert);
15
- Object.defineProperty(span, '_decodeDbRow', {
16
- enumerable: false,
17
- get: function() {
18
- return decode;
19
- },
20
- });
26
+ decodeCache[cacheKey] = decode;
21
27
  }
22
28
  return decode(context, dbRow);
23
29
  }
@@ -14,11 +14,25 @@ function _delete(context, row, strategy, table) {
14
14
  args.push(row[primary.alias]);
15
15
  });
16
16
  var filter = newPrimaryKeyFilter.apply(null, args);
17
- var cmds = newDeleteCommand(context, [], table, filter, strategy, relations);
17
+ var concurrencyState = row._concurrencyState;
18
+ delete row._concurrencyState;
19
+ var cmds = newDeleteCommand(context, [], table, filter, strategy, relations, concurrencyState);
18
20
  cmds.forEach(function(cmd) {
19
21
  pushCommand(context, cmd);
20
22
  });
21
23
  var cmd = cmds[0];
24
+ var concurrencySummary = summarizeConcurrency(concurrencyState);
25
+ if (concurrencySummary.hasConcurrency) {
26
+ var deleteCmd = cmds[cmds.length - 1];
27
+ deleteCmd.onResult = function(result) {
28
+ var rowCount = extractRowCount(result);
29
+ if (rowCount === undefined)
30
+ return;
31
+ if (rowCount === 0 && concurrencySummary.hasOptimistic) {
32
+ throw new Error('The row was changed by another user.');
33
+ }
34
+ };
35
+ }
22
36
  if (table._emitChanged.callbacks.length > 0) {
23
37
  cmd.disallowCompress = true;
24
38
  var dto = createDto(table, row);
@@ -28,4 +42,31 @@ function _delete(context, row, strategy, table) {
28
42
 
29
43
  }
30
44
 
31
- module.exports = _delete;
45
+ function summarizeConcurrency(concurrencyState) {
46
+ const summary = { hasConcurrency: false, hasOptimistic: false };
47
+ if (!concurrencyState || !concurrencyState.columns)
48
+ return summary;
49
+ for (let name in concurrencyState.columns) {
50
+ const state = concurrencyState.columns[name];
51
+ if (!state)
52
+ continue;
53
+ const strategy = state.concurrency || 'optimistic';
54
+ if (strategy === 'overwrite')
55
+ continue;
56
+ summary.hasConcurrency = true;
57
+ if (strategy === 'optimistic')
58
+ summary.hasOptimistic = true;
59
+ }
60
+ return summary;
61
+ }
62
+
63
+ function extractRowCount(result) {
64
+ if (Array.isArray(result) && typeof result[0].rowsAffected === 'number')
65
+ return result[0].rowsAffected;
66
+ if (!result || typeof result !== 'object')
67
+ return;
68
+ if (typeof result.rowsAffected === 'number')
69
+ return result.rowsAffected;
70
+ }
71
+
72
+ module.exports = _delete;
@@ -7,7 +7,6 @@ let _delete = require('./delete');
7
7
  let newObject = require('../../newObject');
8
8
  let toDto = require('./toDto');
9
9
  let createDto = require('./toDto/createDto');
10
- let patchRow = require('../../patchRow');
11
10
  let onChange = require('@lroal/on-change');
12
11
  let flags = require('../../flags');
13
12
  let tryGetSessionContext = require('../tryGetSessionContext');
@@ -78,7 +77,7 @@ function newDecodeDbRow(table, dbRow, filteredAliases, shouldValidate, isInsert)
78
77
  return negotiateNull(this[intName]);
79
78
  },
80
79
  set: function(value) {
81
- if (column.onChange && (this[intName] !== null && this[intName] !== undefined) && typeof value === 'object') {
80
+ if (column.onChange && (this[intName] !== null && this[intName] !== undefined) && value && typeof value === 'object') {
82
81
  if (this[intName] === onChange.target(value))
83
82
  return;
84
83
  this._proxies[name] = column.onChange(value, () => {
@@ -198,11 +197,6 @@ function newDecodeDbRow(table, dbRow, filteredAliases, shouldValidate, isInsert)
198
197
 
199
198
  Row.prototype.deleteCascade = Row.prototype.cascadeDelete;
200
199
 
201
- Row.prototype.patch = async function(patches, options) {
202
- await patchRow(this._context, table, this, patches, options);
203
- return this;
204
- };
205
-
206
200
  function decodeDbRow(context, row) {
207
201
  for (let i = 0; i < numberOfColumns; i++) {
208
202
  let index = offset + i;
package/src/table.js CHANGED
@@ -17,6 +17,8 @@ const cascadeDelete = require('./table/cascadeDelete');
17
17
  const patchTable = require('./patchTable');
18
18
  const newEmitEvent = require('./emitEvent');
19
19
  const hostLocal = require('./hostLocal');
20
+ const getSessionSingleton = require('./table/getSessionSingleton');
21
+ const isJsonUpdateSupported = require('./table/isJsonUpdateSupported');
20
22
  // const getTSDefinition = require('./getTSDefinition'); //todo: unused ?
21
23
  const where = require('./table/where');
22
24
  const aggregate = require('./table/aggregate');
@@ -141,6 +143,55 @@ function _new(tableName) {
141
143
  return insert.apply(null, args);
142
144
  };
143
145
 
146
+ table.updateWithConcurrency = function(context, options, row, property, value, oldValue, patchInfo) {
147
+ options = options || {};
148
+ const columnOptions = inferColumnOptions(options, property);
149
+ const concurrency = columnOptions.concurrency || 'optimistic';
150
+ const column = table[property];
151
+
152
+ if (patchInfo && column && column.tsType === 'JSONColumn' && Array.isArray(patchInfo.path) && patchInfo.path.length > 1) {
153
+ const engine = getSessionSingleton(context, 'engine');
154
+ if (isJsonUpdateSupported(engine)) {
155
+ const jsonPath = patchInfo.path.slice(1);
156
+ const jsonUpdateState = row._jsonUpdateState || {};
157
+ const columnState = jsonUpdateState[property] || { patches: [] };
158
+ columnState.patches.push({
159
+ path: jsonPath,
160
+ op: patchInfo.op,
161
+ value: patchInfo.value,
162
+ oldValue: patchInfo.oldValue
163
+ });
164
+ jsonUpdateState[property] = columnState;
165
+ row._jsonUpdateState = jsonUpdateState;
166
+ if (concurrency !== 'overwrite') {
167
+ const state = row._concurrencyState || { columns: {} };
168
+ const columnConcurrency = state.columns[property] || {};
169
+ columnConcurrency.concurrency = concurrency;
170
+ columnConcurrency.paths = columnConcurrency.paths || [];
171
+ columnConcurrency.paths.push({
172
+ path: jsonPath,
173
+ oldValue: patchInfo.oldValue
174
+ });
175
+ delete columnConcurrency.oldValue;
176
+ state.columns[property] = columnConcurrency;
177
+ row._concurrencyState = state;
178
+ }
179
+ }
180
+ else if (concurrency !== 'overwrite') {
181
+ const state = row._concurrencyState || { columns: {} };
182
+ const fullOldValue = Object.prototype.hasOwnProperty.call(patchInfo, 'fullOldValue') ? patchInfo.fullOldValue : oldValue;
183
+ state.columns[property] = { oldValue: fullOldValue, concurrency };
184
+ row._concurrencyState = state;
185
+ }
186
+ }
187
+ else if (concurrency !== 'overwrite') {
188
+ const state = row._concurrencyState || { columns: {} };
189
+ state.columns[property] = { oldValue, concurrency };
190
+ row._concurrencyState = state;
191
+ }
192
+ row[property] = value;
193
+ };
194
+
144
195
  table.delete = _delete.bind(null, table);
145
196
  table.cascadeDelete = function(context, ...rest) {
146
197
  const args = [context, table, ...rest];
@@ -174,4 +225,15 @@ function _new(tableName) {
174
225
  return table;
175
226
  }
176
227
 
228
+ function inferColumnOptions(defaults, property) {
229
+ const parent = {};
230
+ if (!defaults)
231
+ return parent;
232
+ if ('readonly' in defaults)
233
+ parent.readonly = defaults.readonly;
234
+ if ('concurrency' in defaults)
235
+ parent.concurrency = defaults.concurrency;
236
+ return { ...parent, ...(defaults[property] || {}) };
237
+ }
238
+
177
239
  module.exports = _new;
@@ -1,4 +1,5 @@
1
1
  var wrapQuery = require('./wrapQuery');
2
+ var wrapCommand = require('./wrapCommand');
2
3
  var encodeBoolean = require('./encodeBoolean');
3
4
  var deleteFromSql = require('./deleteFromSql');
4
5
  var selectForUpdateSql = require('./selectForUpdateSql');
@@ -65,6 +66,22 @@ function newResolveTransaction(domain, pool, { readonly = false } = {}) {
65
66
  callback(e);
66
67
  }
67
68
  });
69
+ },
70
+ executeCommand: function(query, callback) {
71
+ pool.connect((err, client, done) => {
72
+ if (err) {
73
+ return callback(err);
74
+ }
75
+ try {
76
+ wrapCommand(domain, client)(query, (err, res) => {
77
+ done();
78
+ callback(err, res);
79
+ });
80
+ } catch (e) {
81
+ done();
82
+ callback(e);
83
+ }
84
+ });
68
85
  }
69
86
  };
70
87
  domain.rdb = rdb;
@@ -81,6 +98,7 @@ function newResolveTransaction(domain, pool, { readonly = false } = {}) {
81
98
  return;
82
99
  }
83
100
  client.executeQuery = wrapQuery(domain, client);
101
+ client.executeCommand = wrapCommand(domain, client);
84
102
  rdb.dbClient = client;
85
103
  rdb.dbClientDone = done;
86
104
  domain.rdb = rdb;
@@ -0,0 +1,121 @@
1
+ var log = require('../table/log');
2
+
3
+ function wrapCommand(_context, connection) {
4
+ let CachedRequest = null;
5
+ let CachedTypes = null;
6
+
7
+ return runQuery;
8
+
9
+ function runQuery(query, onCompleted) {
10
+ if (!CachedRequest || !CachedTypes) {
11
+ import('tedious')
12
+ .then(({ Request, TYPES }) => {
13
+ CachedRequest = Request;
14
+ CachedTypes = TYPES;
15
+ doQuery(query, onCompleted);
16
+ })
17
+ .catch((err) => onCompleted(extractError(err), { rowsAffected: 0 }));
18
+ } else {
19
+ doQuery(query, onCompleted);
20
+ }
21
+ }
22
+
23
+ function doQuery(query, onCompleted) {
24
+ log.emitQuery({ sql: query.sql(), parameters: query.parameters });
25
+ const sql = replaceParamChar(query.sql(), query.parameters);
26
+
27
+ if (sql.length < 18 && query.parameters.length === 0) {
28
+ if (sql === 'BEGIN TRANSACTION') {
29
+ connection.beginTransaction((err) => {
30
+ if (err) return onCompleted(extractError(err), { rowsAffected: 0 });
31
+ return onCompleted(null, { rowsAffected: 0 });
32
+ });
33
+ return;
34
+ } else if (sql === 'COMMIT') {
35
+ connection.commitTransaction((err) => {
36
+ if (err) return onCompleted(extractError(err), { rowsAffected: 0 });
37
+ return onCompleted(null, { rowsAffected: 0 });
38
+ });
39
+ return;
40
+ } else if (sql === 'ROLLBACK') {
41
+ connection.rollbackTransaction((err) => {
42
+ if (err) return onCompleted(extractError(err), { rowsAffected: 0 });
43
+ return onCompleted(null, { rowsAffected: 0 });
44
+ });
45
+ return;
46
+ }
47
+ }
48
+
49
+ let affectedRows = 0;
50
+
51
+ var request = new CachedRequest(sql, onInnerCompleted);
52
+ addParameters(request, query.parameters, CachedTypes);
53
+
54
+ request.on('doneInProc', (rowCount) => {
55
+ if (typeof rowCount === 'number') affectedRows += rowCount;
56
+ });
57
+
58
+ request.on('doneProc', (rowCount) => {
59
+ if (typeof rowCount === 'number') affectedRows += rowCount;
60
+ });
61
+
62
+ request.on('done', (rowCount) => {
63
+ if (typeof rowCount === 'number') affectedRows += rowCount;
64
+ });
65
+
66
+ connection.execSql(request);
67
+
68
+ function onInnerCompleted(err) {
69
+ if (err) return onCompleted(extractError(err), { rowsAffected: 0 });
70
+ return onCompleted(null, { rowsAffected: affectedRows });
71
+ }
72
+ }
73
+ }
74
+
75
+ function extractError(e) {
76
+ if (e && e.errors) {
77
+ return e.errors[0];
78
+ } else {
79
+ return e;
80
+ }
81
+ }
82
+
83
+ function replaceParamChar(sql, params) {
84
+ if (params.length === 0) return sql;
85
+ var splitted = sql.split('?');
86
+ sql = '';
87
+ var lastIndex = splitted.length - 1;
88
+ for (var i = 0; i < lastIndex; i++) {
89
+ sql += splitted[i] + '@' + i;
90
+ }
91
+ sql += splitted[lastIndex];
92
+ return sql;
93
+ }
94
+
95
+ function addParameters(request, params, TYPES) {
96
+ const res = [];
97
+ for (let i = 0; i < params.length; i++) {
98
+ const p = [`${i}`, toType(params[i]), params[i]];
99
+ request.addParameter.apply(request, p);
100
+ res.push(p);
101
+ }
102
+ return res;
103
+
104
+ function toType(p) {
105
+ if (typeof p === 'string') return TYPES.VarChar;
106
+ else if (Number.isInteger(p)) {
107
+ if (p >= -2147483648 && p <= 2147483647) {
108
+ return TYPES.Int;
109
+ } else {
110
+ return TYPES.BigInt;
111
+ }
112
+ } else if (typeof p === 'number') return TYPES.Money;
113
+ else if (p instanceof Date && !isNaN(p)) return TYPES.Date;
114
+ else if (Array.isArray(p)) return TYPES.NVarChar;
115
+ else if (Buffer.isBuffer(p)) return TYPES.VarBinary;
116
+ else if (typeof p === 'object' && p instanceof Object) return TYPES.NVarChar;
117
+ else throw new Error('Unknown data type');
118
+ }
119
+ }
120
+
121
+ module.exports = wrapCommand;
@@ -5,12 +5,14 @@ async function validateDeleteAllowed({ row, options, table }) {
5
5
  e.status = 405;
6
6
  throw e;
7
7
  }
8
- for (let p in options)
9
- if (isColumn(p, table))
10
- return;
11
- else if (isManyRelation(p, table)) {
8
+ if (!hasReadonlyTrue(options))
9
+ return;
10
+ for (let p in options) {
11
+ if (isManyRelation(p, table)) {
12
12
  const childTable = table[p]._relation.childTable;
13
13
  const childOptions = inferOptions(options, p);
14
+ if (!hasReadonlyTrue(childOptions))
15
+ continue;
14
16
  const children = await row[p];
15
17
  for (let i = 0; i < children.length; i++) {
16
18
  const childRow = children[i];
@@ -19,22 +21,22 @@ async function validateDeleteAllowed({ row, options, table }) {
19
21
  }
20
22
  else if (isOneRelation(p, table)) {
21
23
  const childOptions = inferOptions(options, p);
24
+ if (!hasReadonlyTrue(childOptions))
25
+ continue;
22
26
  const childTable = table[p]._relation.childTable;
23
27
  let childRow = await row[p];
24
28
  await validateDeleteAllowed({ row: childRow, options: childOptions, table: childTable });
25
29
  }
30
+ }
26
31
  }
27
32
 
28
- function isColumn(name, table) {
29
- return table[name] && table[name].equal;
30
- }
31
33
 
32
34
  function isManyRelation(name, table) {
33
- return table[name] && table[name]._relation.isMany;
35
+ return table[name] && table[name]._relation && table[name]._relation.isMany;
34
36
  }
35
37
 
36
38
  function isOneRelation(name, table) {
37
- return table[name] && table[name]._relation.isOne;
39
+ return table[name] && table[name]._relation && table[name]._relation.isOne;
38
40
  }
39
41
 
40
42
  function inferOptions(defaults, property) {
@@ -46,4 +48,19 @@ function inferOptions(defaults, property) {
46
48
  return {...parent, ...(defaults[property] || {})};
47
49
  }
48
50
 
49
- module.exports = validateDeleteAllowed;
51
+ function hasReadonlyTrue(options) {
52
+ if (!options || options !== Object(options))
53
+ return false;
54
+ if (options.readonly === true)
55
+ return true;
56
+ for (let p in options) {
57
+ const value = options[p];
58
+ if (!value || value !== Object(value))
59
+ continue;
60
+ if (hasReadonlyTrue(value))
61
+ return true;
62
+ }
63
+ return false;
64
+ }
65
+
66
+ module.exports = validateDeleteAllowed;
package/src/patchRow.js DELETED
@@ -1,13 +0,0 @@
1
- let patchTable = require('./patchTable');
2
-
3
- function patchRow(context, table, row, patches, options) {
4
- patches = JSON.parse(JSON.stringify(patches));
5
- let pkName = table._primaryColumns[0].alias;
6
- let id = row[pkName];
7
- for (let i = 0; i < patches.length; i++) {
8
- patches[i].path = '/' + id + patches[i].path;
9
- }
10
- return patchTable(context, table, patches, options);
11
- }
12
-
13
- module.exports = patchRow;
@@ -1,88 +0,0 @@
1
- let getSessionContext = require('./getSessionContext');
2
- let executeQueries = require('./executeQueries');
3
- let newRow = require('./commands/newRow');
4
- let newInsertCommand = require('./commands/newInsertCommand');
5
- let newInsertCommandCore = require('./commands/newInsertCommandCore');
6
- let newGetLastInsertedCommand = require('./commands/newGetLastInsertedCommand');
7
- let pushCommand = require('./commands/pushCommand');
8
-
9
- function insert({table, options}, arg) {
10
- if (Array.isArray(arg)) {
11
- let all = [];
12
- for (let i = 0; i < arg.length; i++) {
13
- all.push(insert(table, arg[i]));
14
- }
15
- return Promise.all(all);
16
- }
17
- let args = [table].slice.call(arguments);
18
- let row = newRow.apply(null, args);
19
- let hasPrimary = getHasPrimary(table, row);
20
- if (hasPrimary)
21
- row = table._cache.tryAdd(row);
22
- let cmd = newInsertCommand(newInsertCommandCore, table, row, options);
23
-
24
- pushCommand(cmd);
25
- expand(table, row);
26
- Object.defineProperty(row, 'then', {
27
- value: then,
28
- writable: true,
29
- enumerable: false,
30
- configurable: true
31
- });
32
-
33
- let selectCmd;
34
- if (getSessionContext().lastInsertedIsSeparate) {
35
- selectCmd = newGetLastInsertedCommand(table, row, cmd);
36
- pushCommand(selectCmd);
37
- selectCmd.onResult = onResult;
38
- }
39
- else {
40
- cmd.onResult = onResult;
41
- cmd.disallowCompress = true;
42
- }
43
-
44
- return row;
45
- function then(fn,efn) {
46
- delete row.then;
47
- return executeQueries([]).then(() => fn(row), efn);
48
- }
49
-
50
- function onResult([result]) {
51
- row.hydrate(result);
52
- if (!hasPrimary)
53
- row = table._cache.tryAdd(row);
54
- table._cache.tryAdd(row);
55
- }
56
- }
57
-
58
- function expand(table, row) {
59
- let relationName;
60
- let visitor = {};
61
- visitor.visitJoin = function() { };
62
-
63
- visitor.visitMany = function() {
64
- row.expand(relationName);
65
- };
66
-
67
- visitor.visitOne = function() {
68
- row.expand(relationName);
69
- };
70
-
71
- for (relationName in table._relations) {
72
- let relation = table._relations[relationName];
73
- relation.accept(visitor);
74
- }
75
-
76
- }
77
-
78
- function getHasPrimary(table, row) {
79
- for (let i = 0; i < table._primaryColumns.length; i++) {
80
- let column = table._primaryColumns[i];
81
- if (row[column.alias] === null)
82
- return;
83
- }
84
- return true;
85
-
86
- }
87
-
88
- module.exports = insert;
@@ -1,98 +0,0 @@
1
- // @ts-nocheck
2
- /* eslint-disable */
3
- const toCompareObject = require('./toCompareObject');
4
-
5
- async function validateDeleteConflict({ row, oldValue, options, table }) {
6
- for (let p in oldValue) {
7
- if (isColumn(p, table)) {
8
- const option = inferOptions(options, p);
9
- let strategy = option.concurrency || 'optimistic';
10
- if ((strategy === 'optimistic')) {
11
- try {
12
- const column = table[p];
13
- if (column?.tsType === 'DateColumn') {
14
- assertDatesEqual(oldValue[p], toCompareObject(row[p]));
15
- }
16
- else
17
- assertDeepEqual(oldValue[p], toCompareObject(row[p]));
18
- }
19
- catch (e) {
20
- throw new Error(`The field ${p} was changed by another user. Expected ${inspect(oldValue[p])}, but was ${inspect(row[p])}.`);
21
- }
22
- }
23
- }
24
- else if (isManyRelation(p, table)) {
25
- const childTable = table[p]._relation.childTable;
26
- for (let name in oldValue[p]) {
27
- if (name === '__patchType')
28
- continue;
29
- let childRow = await childTable.tryGetById.apply(null, JSON.parse(name));
30
- if (!childRow)
31
- throw new Error(`${p} with id ${name} was deleted by another user`);
32
- if (! await validateDeleteConflict({ row: childRow, oldValue: oldValue[p][name], options: inferOptions(options, p), table: childTable }))
33
- return false;
34
- }
35
- }
36
- else if (isOneRelation(p, table)) {
37
- const childTable = table[p]._relation.childTable;
38
- let childRow = await row[p];
39
- if (!childRow)
40
- throw new Error(`${p} was deleted by another user`);
41
- if (! await validateDeleteConflict({ row: childRow, oldValue: oldValue[p], options: inferOptions(options, p), table: childTable }))
42
- return false;
43
- }
44
-
45
- }
46
- return true;
47
- }
48
-
49
- function isColumn(name, table) {
50
- return table[name] && table[name].equal;
51
- }
52
-
53
- function isManyRelation(name, table) {
54
- return table[name] && table[name]._relation.isMany;
55
- }
56
-
57
- function isOneRelation(name, table) {
58
- return table[name] && table[name]._relation.isOne;
59
-
60
- }
61
-
62
- function inferOptions(defaults, property) {
63
- const parent = {};
64
- if ('readonly' in defaults)
65
- parent.readonly = defaults.readonly;
66
- if ('concurrency' in defaults)
67
- parent.concurrency = defaults.concurrency;
68
- return {...parent, ...(defaults[property] || {})};
69
- }
70
-
71
- function assertDatesEqual(date1, date2) {
72
- if (date1 && date2) {
73
- const parts1 = date1.split('T');
74
- const time1parts = (parts1[1] || '').split(/[-+.]/);
75
- const parts2 = date2.split('T');
76
- const time2parts = (parts2[1] || '').split(/[-+.]/);
77
- while (time1parts.length !== time2parts.length) {
78
- if (time1parts.length > time2parts.length)
79
- time1parts.pop();
80
- else if (time1parts.length < time2parts.length)
81
- time2parts.pop();
82
- }
83
- date1 = `${parts1[0]}T${time1parts[0]}`;
84
- date2 = `${parts2[0]}T${time2parts[0]}`;
85
- }
86
- assertDeepEqual(date1, date2);
87
- }
88
-
89
- function assertDeepEqual(a, b) {
90
- if (JSON.stringify(a) !== JSON.stringify(b))
91
- throw new Error('A, b are not equal');
92
- }
93
-
94
- function inspect(obj) {
95
- return JSON.stringify(obj, null, 2);
96
- }
97
-
98
- module.exports = validateDeleteConflict;