orange-orm 5.3.6 → 5.4.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.
- package/README.md +54 -8
- package/dist/index.browser.mjs +351 -117
- package/dist/index.mjs +401 -142
- package/docs/changelog.md +2 -0
- package/package.json +1 -1
- package/src/applyPatch.js +25 -20
- package/src/client/index.js +33 -16
- package/src/getManyDto/query/newSingleQuery.js +5 -1
- package/src/getTSDefinition.js +2 -0
- package/src/hostExpress/executePath.js +39 -2
- package/src/hostLocal.js +19 -1
- package/src/map2.d.ts +3 -1
- package/src/mySql/selectForUpdateSql.js +10 -3
- package/src/oracle/selectForUpdateSql.js +10 -5
- package/src/patchTable.js +66 -3
- package/src/pg/selectForUpdateSql.js +13 -3
- package/src/sap/selectForUpdateSql.js +5 -5
- package/src/sqlite/selectForUpdateSql.js +5 -5
- package/src/table/commands/newUpdateCommandCore.js +7 -2
- package/src/table/getMany.js +2 -2
- package/src/table/newPrimaryKeyFilter.js +2 -2
- package/src/table/query/newSingleQuery.js +7 -5
- package/src/table/query/singleQuery/joinSql/joinLegToShallowJoinSql.js +2 -2
- package/src/table/query/singleQuery/joinSql/newShallowJoinSql.js +5 -3
- package/src/table/query/singleQuery/joinSql/oneLegToShallowJoinSql.js +2 -2
- package/src/table/query/singleQuery/lockSql.js +74 -0
- package/src/table/tryGetFromDbById.js +9 -3
- package/src/tedious/getManyDto/query/newSingleQuery.js +4 -2
- package/src/tedious/selectForUpdateSql.js +17 -4
package/dist/index.browser.mjs
CHANGED
|
@@ -269,6 +269,8 @@ export interface ${name}Strategy {
|
|
|
269
269
|
offset?: number;
|
|
270
270
|
orderBy?: Array<${orderByColumns(table)}> | ${orderByColumns(table)};
|
|
271
271
|
where?: (table: ${name}TableBase) => RawFilter;
|
|
272
|
+
forUpdate?: boolean;
|
|
273
|
+
skipLocked?: boolean;
|
|
272
274
|
}
|
|
273
275
|
|
|
274
276
|
${otherConcurrency}
|
|
@@ -1836,7 +1838,7 @@ function requireExecutePath () {
|
|
|
1836
1838
|
|
|
1837
1839
|
async function replace(subject, strategy = { insertAndForget: true }) {
|
|
1838
1840
|
validateStrategy(table, strategy);
|
|
1839
|
-
const refinedStrategy = objectToStrategy(subject, {}, table);
|
|
1841
|
+
const refinedStrategy = withLockingStrategy(objectToStrategy(subject, {}, table), strategy);
|
|
1840
1842
|
const JSONFilter2 = {
|
|
1841
1843
|
path: 'getManyDto',
|
|
1842
1844
|
args: [subject, refinedStrategy]
|
|
@@ -1853,7 +1855,7 @@ function requireExecutePath () {
|
|
|
1853
1855
|
|
|
1854
1856
|
async function update(subject, whereStrategy, strategy = { insertAndForget: true }) {
|
|
1855
1857
|
validateStrategy(table, strategy);
|
|
1856
|
-
const refinedWhereStrategy = objectToStrategy(subject, whereStrategy, table);
|
|
1858
|
+
const refinedWhereStrategy = withLockingStrategy(objectToStrategy(subject, whereStrategy, table), strategy);
|
|
1857
1859
|
const JSONFilter2 = {
|
|
1858
1860
|
path: 'getManyDto',
|
|
1859
1861
|
args: [null, refinedWhereStrategy]
|
|
@@ -1873,6 +1875,43 @@ function requireExecutePath () {
|
|
|
1873
1875
|
return changed;
|
|
1874
1876
|
}
|
|
1875
1877
|
|
|
1878
|
+
function withLockingStrategy(fetchStrategy, strategy) {
|
|
1879
|
+
const lockStrategy = extractLockingStrategy(strategy);
|
|
1880
|
+
if (!lockStrategy)
|
|
1881
|
+
return fetchStrategy;
|
|
1882
|
+
return mergeLockingStrategy(fetchStrategy, lockStrategy);
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
function extractLockingStrategy(strategy) {
|
|
1886
|
+
if (!strategy || typeof strategy !== 'object')
|
|
1887
|
+
return;
|
|
1888
|
+
const result = {};
|
|
1889
|
+
if (strategy.forUpdate)
|
|
1890
|
+
result.forUpdate = strategy.forUpdate;
|
|
1891
|
+
if (strategy.skipLocked)
|
|
1892
|
+
result.skipLocked = strategy.skipLocked;
|
|
1893
|
+
for (let name in strategy) {
|
|
1894
|
+
if (name === 'where' || name === 'orderBy' || name === 'limit' || name === 'offset' || name === 'forUpdate' || name === 'skipLocked')
|
|
1895
|
+
continue;
|
|
1896
|
+
const child = extractLockingStrategy(strategy[name]);
|
|
1897
|
+
if (child)
|
|
1898
|
+
result[name] = child;
|
|
1899
|
+
}
|
|
1900
|
+
return Object.keys(result).length > 0 ? result : undefined;
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
function mergeLockingStrategy(fetchStrategy, lockStrategy) {
|
|
1904
|
+
const result = { ...fetchStrategy };
|
|
1905
|
+
for (let name in lockStrategy) {
|
|
1906
|
+
const value = lockStrategy[name];
|
|
1907
|
+
if (name === 'forUpdate' || name === 'skipLocked')
|
|
1908
|
+
result[name] = value;
|
|
1909
|
+
else
|
|
1910
|
+
result[name] = mergeLockingStrategy(result[name] && typeof result[name] === 'object' ? result[name] : {}, value);
|
|
1911
|
+
}
|
|
1912
|
+
return result;
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1876
1915
|
function objectToStrategy(object, whereStrategy, table, strategy = {}) {
|
|
1877
1916
|
strategy = { ...whereStrategy, ...strategy };
|
|
1878
1917
|
if (Array.isArray(object)) {
|
|
@@ -2694,7 +2733,7 @@ function requireHostLocal () {
|
|
|
2694
2733
|
|| beforeCommit
|
|
2695
2734
|
|| afterCommit
|
|
2696
2735
|
|| afterRollback);
|
|
2697
|
-
if (!hasTransactionHooks && readonlyOps.includes(body.path))
|
|
2736
|
+
if (!hasTransactionHooks && readonlyOps.includes(body.path) && !hasLockingStrategy(body))
|
|
2698
2737
|
await db.transaction({ readonly: true }, fn);
|
|
2699
2738
|
else {
|
|
2700
2739
|
await db.transaction(async (context) => {
|
|
@@ -2728,6 +2767,24 @@ function requireHostLocal () {
|
|
|
2728
2767
|
result = await executePath(context, options);
|
|
2729
2768
|
}
|
|
2730
2769
|
}
|
|
2770
|
+
|
|
2771
|
+
function hasLockingStrategy(body) {
|
|
2772
|
+
if (!body || !body.args)
|
|
2773
|
+
return false;
|
|
2774
|
+
return hasLockingStrategyCore(body.args[1]);
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
function hasLockingStrategyCore(strategy) {
|
|
2778
|
+
if (!strategy || typeof strategy !== 'object')
|
|
2779
|
+
return false;
|
|
2780
|
+
if (strategy.forUpdate || strategy.skipLocked)
|
|
2781
|
+
return true;
|
|
2782
|
+
for (let name in strategy) {
|
|
2783
|
+
if (name !== 'where' && hasLockingStrategyCore(strategy[name]))
|
|
2784
|
+
return true;
|
|
2785
|
+
}
|
|
2786
|
+
return false;
|
|
2787
|
+
}
|
|
2731
2788
|
async function query() {
|
|
2732
2789
|
let args = arguments;
|
|
2733
2790
|
let result;
|
|
@@ -3593,7 +3650,7 @@ function requireClient () {
|
|
|
3593
3650
|
return false;
|
|
3594
3651
|
if (Object.keys(value).length === 0)
|
|
3595
3652
|
return true;
|
|
3596
|
-
if ('where' in value || 'orderBy' in value || 'limit' in value || 'offset' in value)
|
|
3653
|
+
if ('where' in value || 'orderBy' in value || 'limit' in value || 'offset' in value || 'forUpdate' in value || 'skipLocked' in value)
|
|
3597
3654
|
return true;
|
|
3598
3655
|
for (let key in value) {
|
|
3599
3656
|
const v = value[key];
|
|
@@ -3843,6 +3900,7 @@ function requireClient () {
|
|
|
3843
3900
|
|
|
3844
3901
|
function proxifyArray(array, strategy, fast) {
|
|
3845
3902
|
let _array = array;
|
|
3903
|
+
const storedStrategy = toStoredFetchStrategy(strategy);
|
|
3846
3904
|
if (_reactive)
|
|
3847
3905
|
array = _reactive(array);
|
|
3848
3906
|
let handler = {
|
|
@@ -3870,17 +3928,17 @@ function requireClient () {
|
|
|
3870
3928
|
};
|
|
3871
3929
|
|
|
3872
3930
|
let watcher = onChange(array, () => {
|
|
3873
|
-
rootMap.set(array, { json: cloneFromDb(array, fast), strategy, originalArray: [...array] });
|
|
3931
|
+
rootMap.set(array, { json: cloneFromDb(array, fast), strategy: storedStrategy, originalArray: [...array] });
|
|
3874
3932
|
});
|
|
3875
3933
|
let innerProxy = new Proxy(watcher, handler);
|
|
3876
|
-
if (
|
|
3877
|
-
|
|
3878
|
-
fetchingStrategyMap.set(array, cleanStrategy);
|
|
3934
|
+
if (storedStrategy !== undefined) {
|
|
3935
|
+
fetchingStrategyMap.set(array, storedStrategy);
|
|
3879
3936
|
}
|
|
3880
3937
|
return innerProxy;
|
|
3881
3938
|
}
|
|
3882
3939
|
|
|
3883
3940
|
function proxifyRow(row, strategy, fast) {
|
|
3941
|
+
const storedStrategy = toStoredFetchStrategy(strategy);
|
|
3884
3942
|
let handler = {
|
|
3885
3943
|
get(_target, property,) {
|
|
3886
3944
|
if (property === 'save' || property === 'saveChanges') //call server then acceptChanges
|
|
@@ -3905,10 +3963,10 @@ function requireClient () {
|
|
|
3905
3963
|
|
|
3906
3964
|
};
|
|
3907
3965
|
let watcher = onChange(row, () => {
|
|
3908
|
-
rootMap.set(row, { json: cloneFromDb(row, fast), strategy });
|
|
3966
|
+
rootMap.set(row, { json: cloneFromDb(row, fast), strategy: storedStrategy });
|
|
3909
3967
|
});
|
|
3910
3968
|
let innerProxy = new Proxy(watcher, handler);
|
|
3911
|
-
fetchingStrategyMap.set(row,
|
|
3969
|
+
fetchingStrategyMap.set(row, storedStrategy);
|
|
3912
3970
|
return innerProxy;
|
|
3913
3971
|
}
|
|
3914
3972
|
|
|
@@ -3999,7 +4057,7 @@ function requireClient () {
|
|
|
3999
4057
|
let insertedPositions = getInsertedRowsPosition(array);
|
|
4000
4058
|
let { changed, strategy: newStrategy } = await p;
|
|
4001
4059
|
copyIntoArray(changed, array, [...insertedPositions, ...updatedPositions]);
|
|
4002
|
-
rootMap.set(array, { json: cloneFromDb(array), strategy: newStrategy, originalArray: [...array] });
|
|
4060
|
+
rootMap.set(array, { json: cloneFromDb(array), strategy: toStoredFetchStrategy(newStrategy), originalArray: [...array] });
|
|
4003
4061
|
}
|
|
4004
4062
|
|
|
4005
4063
|
async function patch(patch, concurrencyOptions, strategy) {
|
|
@@ -4061,8 +4119,7 @@ function requireClient () {
|
|
|
4061
4119
|
let context = rootMap.get(obj);
|
|
4062
4120
|
if (context?.strategy !== undefined) {
|
|
4063
4121
|
// @ts-ignore
|
|
4064
|
-
|
|
4065
|
-
return strategy;
|
|
4122
|
+
return toStoredFetchStrategy(context.strategy);
|
|
4066
4123
|
}
|
|
4067
4124
|
}
|
|
4068
4125
|
}
|
|
@@ -4072,9 +4129,24 @@ function requireClient () {
|
|
|
4072
4129
|
return strategy;
|
|
4073
4130
|
else if (fetchingStrategyMap.get(obj) !== undefined) {
|
|
4074
4131
|
// @ts-ignore
|
|
4075
|
-
|
|
4132
|
+
return toStoredFetchStrategy(fetchingStrategyMap.get(obj));
|
|
4133
|
+
}
|
|
4134
|
+
}
|
|
4135
|
+
|
|
4136
|
+
function toStoredFetchStrategy(strategy) {
|
|
4137
|
+
if (strategy === undefined || strategy === null || typeof strategy !== 'object')
|
|
4076
4138
|
return strategy;
|
|
4139
|
+
if (Array.isArray(strategy))
|
|
4140
|
+
return strategy.map(toStoredFetchStrategy);
|
|
4141
|
+
const cleanStrategy = { ...strategy };
|
|
4142
|
+
delete cleanStrategy.limit;
|
|
4143
|
+
delete cleanStrategy.forUpdate;
|
|
4144
|
+
delete cleanStrategy.skipLocked;
|
|
4145
|
+
for (let name in cleanStrategy) {
|
|
4146
|
+
if (name !== 'where' && cleanStrategy[name] && typeof cleanStrategy[name] === 'object')
|
|
4147
|
+
cleanStrategy[name] = toStoredFetchStrategy(cleanStrategy[name]);
|
|
4077
4148
|
}
|
|
4149
|
+
return cleanStrategy;
|
|
4078
4150
|
}
|
|
4079
4151
|
|
|
4080
4152
|
function clearChangesArray(array) {
|
|
@@ -4165,8 +4237,9 @@ function requireClient () {
|
|
|
4165
4237
|
array.splice(i + offset, 1);
|
|
4166
4238
|
offset--;
|
|
4167
4239
|
}
|
|
4168
|
-
|
|
4169
|
-
|
|
4240
|
+
const storedStrategy = toStoredFetchStrategy(strategy);
|
|
4241
|
+
rootMap.set(array, { json: cloneFromDb(array), strategy: storedStrategy, originalArray: [...array] });
|
|
4242
|
+
fetchingStrategyMap.set(array, storedStrategy);
|
|
4170
4243
|
}
|
|
4171
4244
|
|
|
4172
4245
|
async function deleteRow(row, options) {
|
|
@@ -4200,7 +4273,7 @@ function requireClient () {
|
|
|
4200
4273
|
let adapter = netAdapter(url, tableName, { http: httpInterceptor, tableOptions });
|
|
4201
4274
|
let { changed, strategy: newStrategy } = await adapter.patch(body);
|
|
4202
4275
|
copyInto(changed, [row]);
|
|
4203
|
-
rootMap.set(row, { json: cloneFromDb(row), strategy: newStrategy });
|
|
4276
|
+
rootMap.set(row, { json: cloneFromDb(row), strategy: toStoredFetchStrategy(newStrategy) });
|
|
4204
4277
|
}
|
|
4205
4278
|
|
|
4206
4279
|
async function refreshRow(row, strategy) {
|
|
@@ -4224,8 +4297,9 @@ function requireClient () {
|
|
|
4224
4297
|
for (let p in rows[0]) {
|
|
4225
4298
|
row[p] = rows[0][p];
|
|
4226
4299
|
}
|
|
4227
|
-
|
|
4228
|
-
|
|
4300
|
+
const storedStrategy = toStoredFetchStrategy(strategy);
|
|
4301
|
+
rootMap.set(row, { json: cloneFromDb(row), strategy: storedStrategy });
|
|
4302
|
+
fetchingStrategyMap.set(row, storedStrategy);
|
|
4229
4303
|
}
|
|
4230
4304
|
|
|
4231
4305
|
function acceptChangesRow(row) {
|
|
@@ -6731,8 +6805,8 @@ function requireNewPrimaryKeyFilter () {
|
|
|
6731
6805
|
var primaryColumns = table._primaryColumns;
|
|
6732
6806
|
var key = arguments[2];
|
|
6733
6807
|
var filter = primaryColumns[0].equal(context, key);
|
|
6734
|
-
for (var i =
|
|
6735
|
-
key = arguments[i+
|
|
6808
|
+
for (var i = 1; i < primaryColumns.length; i++) {
|
|
6809
|
+
key = arguments[i + 2];
|
|
6736
6810
|
var colFilter = primaryColumns[i].equal(context, key);
|
|
6737
6811
|
filter = filter.and(context, colFilter);
|
|
6738
6812
|
}
|
|
@@ -6869,6 +6943,89 @@ function requireNewColumnSql () {
|
|
|
6869
6943
|
return newColumnSql;
|
|
6870
6944
|
}
|
|
6871
6945
|
|
|
6946
|
+
var lockSql;
|
|
6947
|
+
var hasRequiredLockSql;
|
|
6948
|
+
|
|
6949
|
+
function requireLockSql () {
|
|
6950
|
+
if (hasRequiredLockSql) return lockSql;
|
|
6951
|
+
hasRequiredLockSql = 1;
|
|
6952
|
+
const getSessionSingleton = requireGetSessionSingleton();
|
|
6953
|
+
|
|
6954
|
+
function selectLockSql(context, span, alias, exclusive) {
|
|
6955
|
+
const lock = collectSelectLock(span, alias, exclusive);
|
|
6956
|
+
if (!hasLock(lock))
|
|
6957
|
+
return '';
|
|
6958
|
+
const encode = getSessionSingleton(context, 'selectForUpdateSql');
|
|
6959
|
+
if (!encode)
|
|
6960
|
+
return '';
|
|
6961
|
+
return encode(context, lock);
|
|
6962
|
+
}
|
|
6963
|
+
|
|
6964
|
+
function tableHintSql(context, span, exclusive) {
|
|
6965
|
+
const lock = spanToLock(span, exclusive);
|
|
6966
|
+
if (!hasLock(lock))
|
|
6967
|
+
return '';
|
|
6968
|
+
const encode = getSessionSingleton(context, 'selectForUpdateSql');
|
|
6969
|
+
if (!encode || !encode.tableHint)
|
|
6970
|
+
return '';
|
|
6971
|
+
return encode.tableHint(context, lock);
|
|
6972
|
+
}
|
|
6973
|
+
|
|
6974
|
+
function collectSelectLock(span, alias, exclusive) {
|
|
6975
|
+
const lock = {
|
|
6976
|
+
aliases: [],
|
|
6977
|
+
forUpdate: Boolean(exclusive),
|
|
6978
|
+
skipLocked: false
|
|
6979
|
+
};
|
|
6980
|
+
collect(span, alias, lock);
|
|
6981
|
+
if (exclusive && lock.aliases.indexOf(alias) === -1)
|
|
6982
|
+
lock.aliases.unshift(alias);
|
|
6983
|
+
return lock;
|
|
6984
|
+
}
|
|
6985
|
+
|
|
6986
|
+
function collect(span, alias, lock) {
|
|
6987
|
+
if (!span)
|
|
6988
|
+
return;
|
|
6989
|
+
if (span.forUpdate) {
|
|
6990
|
+
lock.forUpdate = true;
|
|
6991
|
+
lock.aliases.push(alias);
|
|
6992
|
+
}
|
|
6993
|
+
if (span.skipLocked)
|
|
6994
|
+
lock.skipLocked = true;
|
|
6995
|
+
|
|
6996
|
+
if (!span.legs)
|
|
6997
|
+
return;
|
|
6998
|
+
const visitor = {};
|
|
6999
|
+
visitor.visitJoin = visitJoinedLeg;
|
|
7000
|
+
visitor.visitOne = visitJoinedLeg;
|
|
7001
|
+
visitor.visitMany = function() {};
|
|
7002
|
+
|
|
7003
|
+
function visitJoinedLeg(leg) {
|
|
7004
|
+
collect(leg.span, alias + leg.name, lock);
|
|
7005
|
+
}
|
|
7006
|
+
|
|
7007
|
+
span.legs.forEach(leg => leg.accept(visitor));
|
|
7008
|
+
}
|
|
7009
|
+
|
|
7010
|
+
function spanToLock(span, exclusive) {
|
|
7011
|
+
return {
|
|
7012
|
+
aliases: [],
|
|
7013
|
+
forUpdate: Boolean(exclusive || span?.forUpdate),
|
|
7014
|
+
skipLocked: Boolean(span?.skipLocked)
|
|
7015
|
+
};
|
|
7016
|
+
}
|
|
7017
|
+
|
|
7018
|
+
function hasLock(lock) {
|
|
7019
|
+
return Boolean(lock.forUpdate || lock.skipLocked);
|
|
7020
|
+
}
|
|
7021
|
+
|
|
7022
|
+
lockSql = {
|
|
7023
|
+
selectLockSql,
|
|
7024
|
+
tableHintSql
|
|
7025
|
+
};
|
|
7026
|
+
return lockSql;
|
|
7027
|
+
}
|
|
7028
|
+
|
|
6872
7029
|
var newShallowJoinSql;
|
|
6873
7030
|
var hasRequiredNewShallowJoinSql;
|
|
6874
7031
|
|
|
@@ -6877,10 +7034,12 @@ function requireNewShallowJoinSql () {
|
|
|
6877
7034
|
hasRequiredNewShallowJoinSql = 1;
|
|
6878
7035
|
const newJoinCore = requireNewShallowJoinSqlCore();
|
|
6879
7036
|
const getSessionSingleton = requireGetSessionSingleton();
|
|
7037
|
+
const lockSql = requireLockSql();
|
|
6880
7038
|
|
|
6881
|
-
function _new(context, rightTable, leftColumns, rightColumns, leftAlias, rightAlias, filter) {
|
|
7039
|
+
function _new(context, rightTable, leftColumns, rightColumns, leftAlias, rightAlias, filter, span) {
|
|
6882
7040
|
const quote = getSessionSingleton(context, 'quote');
|
|
6883
|
-
const
|
|
7041
|
+
const tableHint = lockSql.tableHintSql(context, span);
|
|
7042
|
+
const sql = ' JOIN ' + quote(rightTable._dbName) + ' ' + quote(rightAlias) + tableHint + ' ON (';
|
|
6884
7043
|
const joinCore = newJoinCore(context, rightTable, leftColumns, rightColumns, leftAlias, rightAlias, filter);
|
|
6885
7044
|
return joinCore.prepend(sql).append(')');
|
|
6886
7045
|
}
|
|
@@ -6900,7 +7059,7 @@ function requireJoinLegToShallowJoinSql () {
|
|
|
6900
7059
|
function toJoinSql(context,leg,alias,childAlias) {
|
|
6901
7060
|
var columns = leg.columns;
|
|
6902
7061
|
var childTable = leg.span.table;
|
|
6903
|
-
return newShallowJoinSql(context,childTable,columns,childTable._primaryColumns,alias,childAlias,leg.span.where).prepend(' LEFT');
|
|
7062
|
+
return newShallowJoinSql(context,childTable,columns,childTable._primaryColumns,alias,childAlias,leg.span.where,leg.span).prepend(' LEFT');
|
|
6904
7063
|
}
|
|
6905
7064
|
|
|
6906
7065
|
joinLegToShallowJoinSql = toJoinSql;
|
|
@@ -6936,7 +7095,7 @@ function requireOneLegToShallowJoinSql () {
|
|
|
6936
7095
|
var parentTable = leg.table;
|
|
6937
7096
|
var columns = leg.columns;
|
|
6938
7097
|
var childTable = leg.span.table;
|
|
6939
|
-
return newShallowJoinSql(context,childTable,parentTable._primaryColumns,columns,alias,childAlias, leg.span.where).prepend(' LEFT');
|
|
7098
|
+
return newShallowJoinSql(context,childTable,parentTable._primaryColumns,columns,alias,childAlias, leg.span.where,leg.span).prepend(' LEFT');
|
|
6940
7099
|
}
|
|
6941
7100
|
|
|
6942
7101
|
oneLegToShallowJoinSql = toJoinSql;
|
|
@@ -7056,26 +7215,6 @@ function requireNegotiateLimit () {
|
|
|
7056
7215
|
return negotiateLimit_1;
|
|
7057
7216
|
}
|
|
7058
7217
|
|
|
7059
|
-
var negotiateExclusive_1;
|
|
7060
|
-
var hasRequiredNegotiateExclusive;
|
|
7061
|
-
|
|
7062
|
-
function requireNegotiateExclusive () {
|
|
7063
|
-
if (hasRequiredNegotiateExclusive) return negotiateExclusive_1;
|
|
7064
|
-
hasRequiredNegotiateExclusive = 1;
|
|
7065
|
-
var getSessionSingleton = requireGetSessionSingleton();
|
|
7066
|
-
|
|
7067
|
-
function negotiateExclusive(context, table, alias, _exclusive) {
|
|
7068
|
-
if (table._exclusive || _exclusive) {
|
|
7069
|
-
var encode = getSessionSingleton(context, 'selectForUpdateSql');
|
|
7070
|
-
return encode(context, alias);
|
|
7071
|
-
}
|
|
7072
|
-
return '';
|
|
7073
|
-
}
|
|
7074
|
-
|
|
7075
|
-
negotiateExclusive_1 = negotiateExclusive;
|
|
7076
|
-
return negotiateExclusive_1;
|
|
7077
|
-
}
|
|
7078
|
-
|
|
7079
7218
|
var newSingleQuery$1;
|
|
7080
7219
|
var hasRequiredNewSingleQuery$1;
|
|
7081
7220
|
|
|
@@ -7086,23 +7225,25 @@ function requireNewSingleQuery$1 () {
|
|
|
7086
7225
|
var newJoinSql = requireNewJoinSql();
|
|
7087
7226
|
var newWhereSql = requireNewWhereSql();
|
|
7088
7227
|
var negotiateLimit = requireNegotiateLimit();
|
|
7089
|
-
var
|
|
7228
|
+
var lockSql = requireLockSql();
|
|
7090
7229
|
var newParameterized = requireNewParameterized();
|
|
7091
7230
|
var quote = requireQuote$2();
|
|
7092
7231
|
|
|
7093
7232
|
function _new(context, table, filter, span, alias, innerJoin, orderBy, limit, offset, exclusive) {
|
|
7094
7233
|
|
|
7095
7234
|
var name = quote(context, table._dbName);
|
|
7235
|
+
var quotedAlias = quote(context, alias);
|
|
7096
7236
|
var columnSql = newColumnSql(context, table, span, alias);
|
|
7097
7237
|
var joinSql = newJoinSql(context, span, alias);
|
|
7098
7238
|
var whereSql = newWhereSql(context, table, filter, alias);
|
|
7099
7239
|
var safeLimit = negotiateLimit(limit);
|
|
7100
|
-
var
|
|
7101
|
-
|
|
7240
|
+
var lockClause = lockSql.selectLockSql(context, span, alias, exclusive);
|
|
7241
|
+
var tableHint = lockSql.tableHintSql(context, span, exclusive);
|
|
7242
|
+
return newParameterized('select' + safeLimit + ' ' + columnSql + ' from ' + name + ' ' + quotedAlias + tableHint)
|
|
7102
7243
|
.append(innerJoin)
|
|
7103
7244
|
.append(joinSql)
|
|
7104
7245
|
.append(whereSql)
|
|
7105
|
-
.append(orderBy + offset +
|
|
7246
|
+
.append(orderBy + offset + lockClause);
|
|
7106
7247
|
}
|
|
7107
7248
|
|
|
7108
7249
|
newSingleQuery$1 = _new;
|
|
@@ -7368,7 +7509,7 @@ function requireNewUpdateCommandCore () {
|
|
|
7368
7509
|
const encoded = encodeJsonValue(pathState.oldValue, column);
|
|
7369
7510
|
const jsonPath = buildJsonPath(pathState.path);
|
|
7370
7511
|
const columnExpr = buildJsonExtractExpression(quote(column._dbName), jsonPath, pathState.oldValue);
|
|
7371
|
-
command = appendJsonPathComparison(columnExpr, encoded);
|
|
7512
|
+
command = appendJsonPathComparison(columnExpr, encoded, pathState.oldValue);
|
|
7372
7513
|
}
|
|
7373
7514
|
}
|
|
7374
7515
|
else {
|
|
@@ -7428,7 +7569,12 @@ function requireNewUpdateCommandCore () {
|
|
|
7428
7569
|
return command;
|
|
7429
7570
|
}
|
|
7430
7571
|
|
|
7431
|
-
function appendJsonPathComparison(columnExpr, encoded) {
|
|
7572
|
+
function appendJsonPathComparison(columnExpr, encoded, oldValue) {
|
|
7573
|
+
if (oldValue === undefined) {
|
|
7574
|
+
command = command.append(separator).append(columnExpr).append(' IS NULL');
|
|
7575
|
+
separator = ' AND ';
|
|
7576
|
+
return command;
|
|
7577
|
+
}
|
|
7432
7578
|
if (engine === 'pg') {
|
|
7433
7579
|
command = command.append(separator).append(columnExpr).append(' IS NOT DISTINCT FROM ').append(encoded);
|
|
7434
7580
|
}
|
|
@@ -9412,46 +9558,14 @@ function requireGetMany () {
|
|
|
9412
9558
|
return resultToRows(context, span,result);
|
|
9413
9559
|
}
|
|
9414
9560
|
|
|
9415
|
-
getMany.exclusive = function(table,filter,strategy) {
|
|
9416
|
-
return getManyCore(table,filter,strategy,true);
|
|
9561
|
+
getMany.exclusive = function(context,table,filter,strategy) {
|
|
9562
|
+
return getManyCore(context,table,filter,strategy,true);
|
|
9417
9563
|
};
|
|
9418
9564
|
|
|
9419
9565
|
getMany_1 = getMany;
|
|
9420
9566
|
return getMany_1;
|
|
9421
9567
|
}
|
|
9422
9568
|
|
|
9423
|
-
var tryGetFirstFromDb;
|
|
9424
|
-
var hasRequiredTryGetFirstFromDb;
|
|
9425
|
-
|
|
9426
|
-
function requireTryGetFirstFromDb () {
|
|
9427
|
-
if (hasRequiredTryGetFirstFromDb) return tryGetFirstFromDb;
|
|
9428
|
-
hasRequiredTryGetFirstFromDb = 1;
|
|
9429
|
-
var getMany = requireGetMany();
|
|
9430
|
-
|
|
9431
|
-
function tryGet(context, table, filter, strategy) {
|
|
9432
|
-
strategy = setLimit(strategy);
|
|
9433
|
-
return getMany(context, table, filter, strategy).then(filterRows);
|
|
9434
|
-
}
|
|
9435
|
-
|
|
9436
|
-
function filterRows(rows) {
|
|
9437
|
-
if (rows.length > 0)
|
|
9438
|
-
return rows[0];
|
|
9439
|
-
return null;
|
|
9440
|
-
}
|
|
9441
|
-
|
|
9442
|
-
tryGet.exclusive = function(context, table, filter, strategy) {
|
|
9443
|
-
strategy = setLimit(strategy);
|
|
9444
|
-
return getMany.exclusive(context, table, filter, strategy).then(filterRows);
|
|
9445
|
-
};
|
|
9446
|
-
|
|
9447
|
-
function setLimit(strategy) {
|
|
9448
|
-
return {...strategy, ...{limit: 1}};
|
|
9449
|
-
}
|
|
9450
|
-
|
|
9451
|
-
tryGetFirstFromDb = tryGet;
|
|
9452
|
-
return tryGetFirstFromDb;
|
|
9453
|
-
}
|
|
9454
|
-
|
|
9455
9569
|
var extractStrategy;
|
|
9456
9570
|
var hasRequiredExtractStrategy;
|
|
9457
9571
|
|
|
@@ -9476,25 +9590,31 @@ function requireTryGetFromDbById () {
|
|
|
9476
9590
|
if (hasRequiredTryGetFromDbById) return tryGetFromDbById;
|
|
9477
9591
|
hasRequiredTryGetFromDbById = 1;
|
|
9478
9592
|
var newPrimaryKeyFilter = requireNewPrimaryKeyFilter();
|
|
9479
|
-
var
|
|
9593
|
+
var getMany = requireGetMany();
|
|
9480
9594
|
var extractStrategy = requireExtractStrategy();
|
|
9481
9595
|
|
|
9482
9596
|
function tryGet(context) {
|
|
9483
9597
|
var filter = newPrimaryKeyFilter.apply(null, arguments);
|
|
9484
9598
|
var table = arguments[1];
|
|
9485
9599
|
var strategy = extractStrategy.apply(null, arguments);
|
|
9486
|
-
return
|
|
9600
|
+
return getMany(context, table, filter, strategy).then(filterRows);
|
|
9487
9601
|
}
|
|
9488
9602
|
|
|
9489
9603
|
tryGet.exclusive = function tryGet(context) {
|
|
9490
9604
|
var filter = newPrimaryKeyFilter.apply(null, arguments);
|
|
9491
9605
|
var table = arguments[1];
|
|
9492
9606
|
var strategy = extractStrategy.apply(null, arguments);
|
|
9493
|
-
return
|
|
9607
|
+
return getMany.exclusive(context, table, filter, strategy).then(filterRows);
|
|
9494
9608
|
|
|
9495
9609
|
|
|
9496
9610
|
};
|
|
9497
9611
|
|
|
9612
|
+
function filterRows(rows) {
|
|
9613
|
+
if (rows.length > 0)
|
|
9614
|
+
return rows[0];
|
|
9615
|
+
return null;
|
|
9616
|
+
}
|
|
9617
|
+
|
|
9498
9618
|
tryGetFromDbById = tryGet;
|
|
9499
9619
|
return tryGetFromDbById;
|
|
9500
9620
|
}
|
|
@@ -11708,18 +11828,22 @@ function requireNewSingleQuery () {
|
|
|
11708
11828
|
var newJoinSql = requireNewJoinSql();
|
|
11709
11829
|
var newParameterized = requireNewParameterized();
|
|
11710
11830
|
var getSessionSingleton = requireGetSessionSingleton();
|
|
11831
|
+
var lockSql = requireLockSql();
|
|
11711
11832
|
|
|
11712
11833
|
function _new(context,table,filter,span, alias,orderBy,limit,offset,distinct = false) {
|
|
11713
11834
|
var quote = getSessionSingleton(context, 'quote');
|
|
11714
11835
|
var name = quote(table._dbName);
|
|
11836
|
+
var quotedAlias = quote(alias);
|
|
11715
11837
|
var columnSql = newColumnSql(context,table,span,alias,true);
|
|
11716
11838
|
var joinSql = newJoinSql(context, span, alias);
|
|
11717
11839
|
var whereSql = newWhereSql(context,table,filter,alias);
|
|
11718
11840
|
if (limit)
|
|
11719
11841
|
limit = limit + ' ';
|
|
11720
11842
|
const selectClause = distinct ? 'select distinct ' : 'select ';
|
|
11843
|
+
const lockClause = lockSql.selectLockSql(context, span, alias);
|
|
11844
|
+
const tableHint = lockSql.tableHintSql(context, span);
|
|
11721
11845
|
|
|
11722
|
-
return newParameterized(selectClause + limit + columnSql + ' from ' + name + ' ' +
|
|
11846
|
+
return newParameterized(selectClause + limit + columnSql + ' from ' + name + ' ' + quotedAlias + tableHint).append(joinSql).append(whereSql).append(orderBy + offset + lockClause);
|
|
11723
11847
|
|
|
11724
11848
|
}
|
|
11725
11849
|
|
|
@@ -12177,6 +12301,38 @@ function requireTryGetById () {
|
|
|
12177
12301
|
return tryGetById;
|
|
12178
12302
|
}
|
|
12179
12303
|
|
|
12304
|
+
var tryGetFirstFromDb;
|
|
12305
|
+
var hasRequiredTryGetFirstFromDb;
|
|
12306
|
+
|
|
12307
|
+
function requireTryGetFirstFromDb () {
|
|
12308
|
+
if (hasRequiredTryGetFirstFromDb) return tryGetFirstFromDb;
|
|
12309
|
+
hasRequiredTryGetFirstFromDb = 1;
|
|
12310
|
+
var getMany = requireGetMany();
|
|
12311
|
+
|
|
12312
|
+
function tryGet(context, table, filter, strategy) {
|
|
12313
|
+
strategy = setLimit(strategy);
|
|
12314
|
+
return getMany(context, table, filter, strategy).then(filterRows);
|
|
12315
|
+
}
|
|
12316
|
+
|
|
12317
|
+
function filterRows(rows) {
|
|
12318
|
+
if (rows.length > 0)
|
|
12319
|
+
return rows[0];
|
|
12320
|
+
return null;
|
|
12321
|
+
}
|
|
12322
|
+
|
|
12323
|
+
tryGet.exclusive = function(context, table, filter, strategy) {
|
|
12324
|
+
strategy = setLimit(strategy);
|
|
12325
|
+
return getMany.exclusive(context, table, filter, strategy).then(filterRows);
|
|
12326
|
+
};
|
|
12327
|
+
|
|
12328
|
+
function setLimit(strategy) {
|
|
12329
|
+
return {...strategy, ...{limit: 1}};
|
|
12330
|
+
}
|
|
12331
|
+
|
|
12332
|
+
tryGetFirstFromDb = tryGet;
|
|
12333
|
+
return tryGetFirstFromDb;
|
|
12334
|
+
}
|
|
12335
|
+
|
|
12180
12336
|
var newRowCache_1;
|
|
12181
12337
|
var hasRequiredNewRowCache;
|
|
12182
12338
|
|
|
@@ -12697,29 +12853,34 @@ function requireApplyPatch () {
|
|
|
12697
12853
|
|
|
12698
12854
|
}
|
|
12699
12855
|
|
|
12700
|
-
// function assertDatesEqual(date1, date2) {
|
|
12701
|
-
// if (date1 && date2) {
|
|
12702
|
-
// const parts1 = date1.split('T');
|
|
12703
|
-
// const time1parts = (parts1[1] || '').split(/[-+.]/);
|
|
12704
|
-
// const parts2 = date2.split('T');
|
|
12705
|
-
// const time2parts = (parts2[1] || '').split(/[-+.]/);
|
|
12706
|
-
// while (time1parts.length !== time2parts.length) {
|
|
12707
|
-
// if (time1parts.length > time2parts.length)
|
|
12708
|
-
// time1parts.pop();
|
|
12709
|
-
// else if (time1parts.length < time2parts.length)
|
|
12710
|
-
// time2parts.pop();
|
|
12711
|
-
// }
|
|
12712
|
-
// date1 = `${parts1[0]}T${time1parts[0]}`;
|
|
12713
|
-
// date2 = `${parts2[0]}T${time2parts[0]}`;
|
|
12714
|
-
// }
|
|
12715
|
-
// assertDeepEqual(date1, date2);
|
|
12716
|
-
// }
|
|
12717
|
-
|
|
12718
12856
|
function assertDeepEqual(a, b) {
|
|
12719
|
-
if (
|
|
12857
|
+
if (!deepEqual(a, b))
|
|
12720
12858
|
throw new Error('A, b are not equal');
|
|
12721
12859
|
}
|
|
12722
12860
|
|
|
12861
|
+
function deepEqual(a, b) {
|
|
12862
|
+
if (a === b) return true;
|
|
12863
|
+
if (a && b && typeof a === 'object' && typeof b === 'object') {
|
|
12864
|
+
if (Array.isArray(a)) {
|
|
12865
|
+
if (!Array.isArray(b) || a.length !== b.length) return false;
|
|
12866
|
+
for (let i = 0; i < a.length; i++) {
|
|
12867
|
+
if (!deepEqual(a[i], b[i])) return false;
|
|
12868
|
+
}
|
|
12869
|
+
return true;
|
|
12870
|
+
}
|
|
12871
|
+
if (Array.isArray(b)) return false;
|
|
12872
|
+
|
|
12873
|
+
const keysA = Object.keys(a);
|
|
12874
|
+
const keysB = Object.keys(b);
|
|
12875
|
+
if (keysA.length !== keysB.length) return false;
|
|
12876
|
+
for (const key of keysA) {
|
|
12877
|
+
if (!Object.prototype.hasOwnProperty.call(b, key) || !deepEqual(a[key], b[key])) return false;
|
|
12878
|
+
}
|
|
12879
|
+
return true;
|
|
12880
|
+
}
|
|
12881
|
+
return false;
|
|
12882
|
+
}
|
|
12883
|
+
|
|
12723
12884
|
applyPatch_1 = applyPatch;
|
|
12724
12885
|
return applyPatch_1;
|
|
12725
12886
|
}
|
|
@@ -12844,6 +13005,7 @@ function requirePatchTable () {
|
|
|
12844
13005
|
const engine = getSessionSingleton(context, 'engine');
|
|
12845
13006
|
options = cleanOptions(options);
|
|
12846
13007
|
strategy = JSON.parse(JSON.stringify(strategy || {}));
|
|
13008
|
+
await lockTouchedRows();
|
|
12847
13009
|
let changed = new Set();
|
|
12848
13010
|
for (let i = 0; i < patches.length; i++) {
|
|
12849
13011
|
let patch = { path: undefined, value: undefined, op: undefined };
|
|
@@ -12863,14 +13025,28 @@ function requirePatchTable () {
|
|
|
12863
13025
|
}
|
|
12864
13026
|
if (strategy['insertAndForget'])
|
|
12865
13027
|
return {
|
|
12866
|
-
changed: [], strategy
|
|
13028
|
+
changed: [], strategy: stripLockingStrategy(strategy)
|
|
12867
13029
|
};
|
|
12868
|
-
return { changed: await toDtos(changed), strategy };
|
|
13030
|
+
return { changed: await toDtos(changed), strategy: stripLockingStrategy(strategy) };
|
|
12869
13031
|
|
|
12870
13032
|
|
|
12871
13033
|
async function toDtos(set) {
|
|
12872
13034
|
set = [...set];
|
|
12873
|
-
const result = await table.getManyDto(context, set, strategy);
|
|
13035
|
+
const result = await table.getManyDto(context, set, stripLockingStrategy(strategy));
|
|
13036
|
+
return result;
|
|
13037
|
+
}
|
|
13038
|
+
|
|
13039
|
+
function stripLockingStrategy(strategy) {
|
|
13040
|
+
if (!strategy || typeof strategy !== 'object')
|
|
13041
|
+
return strategy;
|
|
13042
|
+
if (Array.isArray(strategy))
|
|
13043
|
+
return strategy.map(stripLockingStrategy);
|
|
13044
|
+
const result = {};
|
|
13045
|
+
for (let name in strategy) {
|
|
13046
|
+
if (name === 'forUpdate' || name === 'skipLocked')
|
|
13047
|
+
continue;
|
|
13048
|
+
result[name] = stripLockingStrategy(strategy[name]);
|
|
13049
|
+
}
|
|
12874
13050
|
return result;
|
|
12875
13051
|
}
|
|
12876
13052
|
|
|
@@ -12881,6 +13057,54 @@ function requirePatchTable () {
|
|
|
12881
13057
|
return [property];
|
|
12882
13058
|
}
|
|
12883
13059
|
|
|
13060
|
+
async function lockTouchedRows() {
|
|
13061
|
+
if (!hasLockingStrategy(strategy))
|
|
13062
|
+
return;
|
|
13063
|
+
const keys = [];
|
|
13064
|
+
const keySet = new Set();
|
|
13065
|
+
for (let i = 0; i < patches.length; i++) {
|
|
13066
|
+
const patch = patches[i];
|
|
13067
|
+
const path = patch.path.split('/').slice(1);
|
|
13068
|
+
if (path.length === 0)
|
|
13069
|
+
continue;
|
|
13070
|
+
if (patch.op === 'add' && path.length === 1)
|
|
13071
|
+
continue;
|
|
13072
|
+
const key = toKey(path[0]);
|
|
13073
|
+
if (isTemporaryKey(key))
|
|
13074
|
+
continue;
|
|
13075
|
+
const keyString = JSON.stringify(key);
|
|
13076
|
+
if (keySet.has(keyString))
|
|
13077
|
+
continue;
|
|
13078
|
+
keySet.add(keyString);
|
|
13079
|
+
keys.push(key);
|
|
13080
|
+
}
|
|
13081
|
+
for (let i = 0; i < keys.length; i++) {
|
|
13082
|
+
const row = await table.tryGetById.apply(null, [context, ...keys[i], strategy]);
|
|
13083
|
+
if (!row)
|
|
13084
|
+
throw new Error(`Row ${table._dbName} with id ${keys[i]} was not found.`);
|
|
13085
|
+
}
|
|
13086
|
+
}
|
|
13087
|
+
|
|
13088
|
+
function hasLockingStrategy(strategy) {
|
|
13089
|
+
if (!strategy || typeof strategy !== 'object')
|
|
13090
|
+
return false;
|
|
13091
|
+
if (strategy.forUpdate || strategy.skipLocked)
|
|
13092
|
+
return true;
|
|
13093
|
+
for (let name in strategy) {
|
|
13094
|
+
if (name !== 'where' && hasLockingStrategy(strategy[name]))
|
|
13095
|
+
return true;
|
|
13096
|
+
}
|
|
13097
|
+
return false;
|
|
13098
|
+
}
|
|
13099
|
+
|
|
13100
|
+
function isTemporaryKey(key) {
|
|
13101
|
+
for (let i = 0; i < key.length; i++) {
|
|
13102
|
+
if (typeof key[i] === 'string' && key[i].indexOf('~') === 0)
|
|
13103
|
+
return true;
|
|
13104
|
+
}
|
|
13105
|
+
return false;
|
|
13106
|
+
}
|
|
13107
|
+
|
|
12884
13108
|
async function add({ path, value, op, oldValue, strategy, options }, table, row, parentRow, relation) {
|
|
12885
13109
|
let property = path[0];
|
|
12886
13110
|
path = path.slice(1);
|
|
@@ -14535,10 +14759,10 @@ var hasRequiredSelectForUpdateSql$1;
|
|
|
14535
14759
|
function requireSelectForUpdateSql$1 () {
|
|
14536
14760
|
if (hasRequiredSelectForUpdateSql$1) return selectForUpdateSql$1;
|
|
14537
14761
|
hasRequiredSelectForUpdateSql$1 = 1;
|
|
14538
|
-
|
|
14539
|
-
|
|
14540
|
-
|
|
14541
|
-
return '
|
|
14762
|
+
selectForUpdateSql$1 = function(_context, lock) {
|
|
14763
|
+
if (lock)
|
|
14764
|
+
throw new Error('select for update is not supported by SQLite');
|
|
14765
|
+
return '';
|
|
14542
14766
|
};
|
|
14543
14767
|
return selectForUpdateSql$1;
|
|
14544
14768
|
}
|
|
@@ -16235,8 +16459,18 @@ function requireSelectForUpdateSql () {
|
|
|
16235
16459
|
hasRequiredSelectForUpdateSql = 1;
|
|
16236
16460
|
const quote = requireQuote$2();
|
|
16237
16461
|
|
|
16238
|
-
selectForUpdateSql = function(
|
|
16239
|
-
|
|
16462
|
+
selectForUpdateSql = function(context, lock) {
|
|
16463
|
+
if (typeof lock === 'string')
|
|
16464
|
+
lock = { aliases: [lock], forUpdate: true };
|
|
16465
|
+
let sql = '';
|
|
16466
|
+
if (lock.forUpdate) {
|
|
16467
|
+
sql = ' FOR UPDATE';
|
|
16468
|
+
if (lock.aliases && lock.aliases.length > 0)
|
|
16469
|
+
sql += ' OF ' + lock.aliases.map(alias => quote(context, alias)).join(', ');
|
|
16470
|
+
}
|
|
16471
|
+
if (lock.skipLocked)
|
|
16472
|
+
sql += ' SKIP LOCKED';
|
|
16473
|
+
return sql;
|
|
16240
16474
|
};
|
|
16241
16475
|
return selectForUpdateSql;
|
|
16242
16476
|
}
|