orange-orm 5.1.0 → 5.2.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 +69 -1
- package/bin/build.js +1 -0
- package/dist/index.browser.mjs +385 -28
- package/dist/index.mjs +385 -28
- package/docs/changelog.md +4 -0
- package/package.json +1 -1
- package/src/client/index.js +24 -3
- package/src/getManyDto/query/newSingleQuery.js +4 -3
- package/src/hostExpress/executePath.js +64 -11
- package/src/hostLocal.js +1 -1
- package/src/map2.d.ts +34 -25
- package/src/table/column/encodeFilterArg.js +3 -1
- package/src/table/column/newColumn.js +17 -0
- package/src/table/column/string/containsCore.js +7 -3
- package/src/table/column/string/endsWithCore.js +6 -2
- package/src/table/column/string/newLikeColumnArg.js +38 -0
- package/src/table/column/string/startsWithCore.js +6 -2
- package/src/table/groupBy/newQuery.js +12 -3
- package/src/table/groupBy.js +3 -3
- package/src/table/newRelatedTable.js +5 -1
- package/src/table/relatedTable/count.js +139 -0
- package/src/table/relatedTable/newFilterArg.js +20 -0
- package/src/table/relatedTable/relatedColumn.js +11 -1
- package/src/table.js +4 -0
package/dist/index.mjs
CHANGED
|
@@ -1566,7 +1566,7 @@ function requireExecutePath () {
|
|
|
1566
1566
|
|
|
1567
1567
|
async function executePath({ table, JSONFilter, baseFilter, customFilters = {}, request, response, readonly, disableBulkDeletes, isHttp, client }) {
|
|
1568
1568
|
let allowedOps = { ..._allowedOps, insert: !readonly, ...extractRelations(getMeta(table)) };
|
|
1569
|
-
let ops = { ..._ops, ...getCustomFilterPaths(customFilters), getManyDto, getMany, aggregate, count, delete: _delete, cascadeDelete, update, replace };
|
|
1569
|
+
let ops = { ..._ops, ...getCustomFilterPaths(customFilters), getManyDto, getMany, aggregate, distinct, count, delete: _delete, cascadeDelete, update, replace };
|
|
1570
1570
|
|
|
1571
1571
|
let res = await parseFilter(JSONFilter, table);
|
|
1572
1572
|
if (res === undefined)
|
|
@@ -1580,9 +1580,12 @@ function requireExecutePath () {
|
|
|
1580
1580
|
|
|
1581
1581
|
let anyAllNone = tryGetAnyAllNone(json.path, table);
|
|
1582
1582
|
if (anyAllNone) {
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1583
|
+
const arg0 = json.args[0];
|
|
1584
|
+
if (isHttp && arg0 !== undefined)
|
|
1585
|
+
validateArgs(arg0);
|
|
1586
|
+
const f = arg0 === undefined
|
|
1587
|
+
? anyAllNone(context)
|
|
1588
|
+
: anyAllNone(context, x => parseFilter(arg0, x));
|
|
1586
1589
|
if(!('isSafe' in f))
|
|
1587
1590
|
f.isSafe = isSafe;
|
|
1588
1591
|
return f;
|
|
@@ -1601,17 +1604,22 @@ function requireExecutePath () {
|
|
|
1601
1604
|
}
|
|
1602
1605
|
return result;
|
|
1603
1606
|
}
|
|
1607
|
+
else if (isColumnRef(json)) {
|
|
1608
|
+
return resolveColumnRef(table, json.__columnRef);
|
|
1609
|
+
}
|
|
1604
1610
|
return json;
|
|
1605
1611
|
|
|
1606
1612
|
function tryGetAnyAllNone(path, table) {
|
|
1607
|
-
|
|
1608
|
-
for (let i = 0; i <
|
|
1609
|
-
table = table[
|
|
1613
|
+
const parts = path.split('.');
|
|
1614
|
+
for (let i = 0; i < parts.length; i++) {
|
|
1615
|
+
table = table[parts[i]];
|
|
1610
1616
|
}
|
|
1611
1617
|
|
|
1612
1618
|
let ops = new Set(['all', 'any', 'none', 'where', '_aggregate']);
|
|
1613
1619
|
// let ops = new Set(['all', 'any', 'none', 'where']);
|
|
1614
|
-
let last =
|
|
1620
|
+
let last = parts[parts.length - 1];
|
|
1621
|
+
if (last === 'count' && parts.length > 1)
|
|
1622
|
+
ops.add('count');
|
|
1615
1623
|
if (ops.has(last) || (table && (table._primaryColumns || (table.any && table.all))))
|
|
1616
1624
|
return table;
|
|
1617
1625
|
}
|
|
@@ -1644,8 +1652,21 @@ function requireExecutePath () {
|
|
|
1644
1652
|
target = target[pathArray[i]];
|
|
1645
1653
|
}
|
|
1646
1654
|
|
|
1647
|
-
if (!target)
|
|
1655
|
+
if (!target) {
|
|
1656
|
+
const left = args && args[0];
|
|
1657
|
+
if (left) {
|
|
1658
|
+
target = left;
|
|
1659
|
+
for (let i = 0; i < pathArray.length; i++) {
|
|
1660
|
+
target = target[pathArray[i]];
|
|
1661
|
+
}
|
|
1662
|
+
if (target) {
|
|
1663
|
+
let res = target.apply(null, [context].concat(args.slice(1)));
|
|
1664
|
+
setSafe(res);
|
|
1665
|
+
return res;
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1648
1668
|
throw new Error(`Method '${path}' does not exist`);
|
|
1669
|
+
}
|
|
1649
1670
|
let res = target.apply(null, [context, ...args]);
|
|
1650
1671
|
setSafe(res);
|
|
1651
1672
|
return res;
|
|
@@ -1691,7 +1712,7 @@ function requireExecutePath () {
|
|
|
1691
1712
|
|
|
1692
1713
|
function nextTable(path, table) {
|
|
1693
1714
|
path = path.split('.');
|
|
1694
|
-
let ops = new Set(['all', 'any', 'none']);
|
|
1715
|
+
let ops = new Set(['all', 'any', 'none', 'count']);
|
|
1695
1716
|
let last = path.slice(-1)[0];
|
|
1696
1717
|
if (ops.has(last)) {
|
|
1697
1718
|
for (let i = 0; i < path.length - 1; i++) {
|
|
@@ -1841,6 +1862,17 @@ function requireExecutePath () {
|
|
|
1841
1862
|
return table.aggregate.apply(null, args);
|
|
1842
1863
|
}
|
|
1843
1864
|
|
|
1865
|
+
async function distinct(filter, strategy) {
|
|
1866
|
+
validateStrategy(table, strategy);
|
|
1867
|
+
filter = negotiateFilter(filter);
|
|
1868
|
+
const _baseFilter = await invokeBaseFilter();
|
|
1869
|
+
if (_baseFilter)
|
|
1870
|
+
filter = filter.and(context, _baseFilter);
|
|
1871
|
+
let args = [context, filter].concat(Array.prototype.slice.call(arguments).slice(1));
|
|
1872
|
+
await negotiateWhereAndAggregate(strategy);
|
|
1873
|
+
return table.distinct.apply(null, args);
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1844
1876
|
|
|
1845
1877
|
|
|
1846
1878
|
async function negotiateWhereAndAggregate(strategy) {
|
|
@@ -1950,6 +1982,27 @@ function requireExecutePath () {
|
|
|
1950
1982
|
return json instanceof Object && 'path' in json && 'args' in json;
|
|
1951
1983
|
}
|
|
1952
1984
|
|
|
1985
|
+
function isColumnRef(json) {
|
|
1986
|
+
return json instanceof Object && typeof json.__columnRef === 'string';
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
function resolveColumnRef(table, path) {
|
|
1990
|
+
let current = table;
|
|
1991
|
+
const parts = path.split('.');
|
|
1992
|
+
for (let i = 0; i < parts.length; i++) {
|
|
1993
|
+
if (current)
|
|
1994
|
+
current = current[parts[i]];
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
if (!current || typeof current._toFilterArg !== 'function') {
|
|
1998
|
+
let e = new Error(`Column reference '${path}' is invalid`);
|
|
1999
|
+
// @ts-ignore
|
|
2000
|
+
e.status = 400;
|
|
2001
|
+
throw e;
|
|
2002
|
+
}
|
|
2003
|
+
return current;
|
|
2004
|
+
}
|
|
2005
|
+
|
|
1953
2006
|
function setSafe(o) {
|
|
1954
2007
|
if (o instanceof Object)
|
|
1955
2008
|
Object.defineProperty(o, 'isSafe', {
|
|
@@ -2523,7 +2576,7 @@ function requireHostLocal () {
|
|
|
2523
2576
|
let executeSqliteFunction = requireSqliteFunction();
|
|
2524
2577
|
let hostExpress = requireHostExpress();
|
|
2525
2578
|
let hostHono = requireHostHono();
|
|
2526
|
-
const readonlyOps = ['getManyDto', 'getMany', 'aggregate', 'count'];
|
|
2579
|
+
const readonlyOps = ['getManyDto', 'getMany', 'aggregate', 'distinct', 'count'];
|
|
2527
2580
|
// { db, table, defaultConcurrency,
|
|
2528
2581
|
// concurrency,
|
|
2529
2582
|
// customFilters,
|
|
@@ -3329,6 +3382,7 @@ function requireClient () {
|
|
|
3329
3382
|
count,
|
|
3330
3383
|
getMany,
|
|
3331
3384
|
aggregate: groupBy,
|
|
3385
|
+
distinct,
|
|
3332
3386
|
getAll,
|
|
3333
3387
|
getOne,
|
|
3334
3388
|
getById,
|
|
@@ -3384,9 +3438,17 @@ function requireClient () {
|
|
|
3384
3438
|
}
|
|
3385
3439
|
|
|
3386
3440
|
async function groupBy(strategy) {
|
|
3441
|
+
return executeGroupBy('aggregate', strategy);
|
|
3442
|
+
}
|
|
3443
|
+
|
|
3444
|
+
async function distinct(strategy) {
|
|
3445
|
+
return executeGroupBy('distinct', strategy);
|
|
3446
|
+
}
|
|
3447
|
+
|
|
3448
|
+
async function executeGroupBy(path, strategy) {
|
|
3387
3449
|
let args = negotiateGroupBy(null, strategy);
|
|
3388
3450
|
let body = stringify({
|
|
3389
|
-
path
|
|
3451
|
+
path,
|
|
3390
3452
|
args
|
|
3391
3453
|
});
|
|
3392
3454
|
let adapter = netAdapter(url, tableName, { axios: axiosInterceptor, tableOptions });
|
|
@@ -4181,12 +4243,20 @@ function requireClient () {
|
|
|
4181
4243
|
}
|
|
4182
4244
|
}
|
|
4183
4245
|
|
|
4246
|
+
const isColumnProxyKey = '__isColumnProxy';
|
|
4247
|
+
const columnPathKey = '__columnPath';
|
|
4248
|
+
const columnRefKey = '__columnRef';
|
|
4249
|
+
|
|
4184
4250
|
function column(path, ...previous) {
|
|
4185
4251
|
function c() {
|
|
4186
4252
|
let args = [];
|
|
4187
4253
|
for (let i = 0; i < arguments.length; i++) {
|
|
4188
|
-
if (typeof arguments[i] === 'function')
|
|
4189
|
-
|
|
4254
|
+
if (typeof arguments[i] === 'function') {
|
|
4255
|
+
if (arguments[i][isColumnProxyKey])
|
|
4256
|
+
args[i] = { [columnRefKey]: arguments[i][columnPathKey] };
|
|
4257
|
+
else
|
|
4258
|
+
args[i] = arguments[i](tableProxy(path.split('.').slice(0, -1).join('.')));
|
|
4259
|
+
}
|
|
4190
4260
|
else
|
|
4191
4261
|
args[i] = arguments[i];
|
|
4192
4262
|
}
|
|
@@ -4209,6 +4279,10 @@ function requireClient () {
|
|
|
4209
4279
|
}
|
|
4210
4280
|
let handler = {
|
|
4211
4281
|
get(_target, property) {
|
|
4282
|
+
if (property === isColumnProxyKey)
|
|
4283
|
+
return true;
|
|
4284
|
+
if (property === columnPathKey)
|
|
4285
|
+
return path;
|
|
4212
4286
|
if (property === 'toJSON')
|
|
4213
4287
|
return Reflect.get(...arguments);
|
|
4214
4288
|
else if (property === 'then')
|
|
@@ -4281,6 +4355,8 @@ function requireEncodeFilterArg () {
|
|
|
4281
4355
|
if (hasRequiredEncodeFilterArg) return encodeFilterArg_1;
|
|
4282
4356
|
hasRequiredEncodeFilterArg = 1;
|
|
4283
4357
|
function encodeFilterArg(context, column, arg) {
|
|
4358
|
+
if (arg && typeof arg._toFilterArg === 'function')
|
|
4359
|
+
return arg._toFilterArg(context);
|
|
4284
4360
|
if (column.encode.safe)
|
|
4285
4361
|
return column.encode.safe(context, arg);
|
|
4286
4362
|
else
|
|
@@ -4689,6 +4765,7 @@ function requireNewColumn () {
|
|
|
4689
4765
|
const quote = requireQuote$6();
|
|
4690
4766
|
const aggregate = requireColumnAggregate$1();
|
|
4691
4767
|
const aggregateGroup = requireColumnAggregateGroup$1();
|
|
4768
|
+
const newParameterized = requireNewParameterized();
|
|
4692
4769
|
|
|
4693
4770
|
newColumn = function(table, name) {
|
|
4694
4771
|
var c = {};
|
|
@@ -4696,6 +4773,16 @@ function requireNewColumn () {
|
|
|
4696
4773
|
c._dbName = name;
|
|
4697
4774
|
c.alias = name;
|
|
4698
4775
|
table._aliases.add(name);
|
|
4776
|
+
Object.defineProperty(c, '_table', {
|
|
4777
|
+
value: table,
|
|
4778
|
+
enumerable: false,
|
|
4779
|
+
writable: false
|
|
4780
|
+
});
|
|
4781
|
+
Object.defineProperty(c, '_toFilterArg', {
|
|
4782
|
+
value: toFilterArg,
|
|
4783
|
+
enumerable: false,
|
|
4784
|
+
writable: false
|
|
4785
|
+
});
|
|
4699
4786
|
|
|
4700
4787
|
c.dbNull = null;
|
|
4701
4788
|
table._columns.push(c);
|
|
@@ -4781,6 +4868,12 @@ function requireNewColumn () {
|
|
|
4781
4868
|
};
|
|
4782
4869
|
}
|
|
4783
4870
|
|
|
4871
|
+
function toFilterArg(context) {
|
|
4872
|
+
const tableAlias = quote(context, table._rootAlias || table._dbName);
|
|
4873
|
+
const columnName = quote(context, c._dbName);
|
|
4874
|
+
return newParameterized(`${tableAlias}.${columnName}`);
|
|
4875
|
+
}
|
|
4876
|
+
|
|
4784
4877
|
return c;
|
|
4785
4878
|
};
|
|
4786
4879
|
return newColumn;
|
|
@@ -4866,6 +4959,53 @@ function requireNewDecodeCore () {
|
|
|
4866
4959
|
return newDecodeCore;
|
|
4867
4960
|
}
|
|
4868
4961
|
|
|
4962
|
+
var newLikeColumnArg_1;
|
|
4963
|
+
var hasRequiredNewLikeColumnArg;
|
|
4964
|
+
|
|
4965
|
+
function requireNewLikeColumnArg () {
|
|
4966
|
+
if (hasRequiredNewLikeColumnArg) return newLikeColumnArg_1;
|
|
4967
|
+
hasRequiredNewLikeColumnArg = 1;
|
|
4968
|
+
var getSessionSingleton = requireGetSessionSingleton();
|
|
4969
|
+
var newParameterized = requireNewParameterized();
|
|
4970
|
+
|
|
4971
|
+
function newLikeColumnArg(context, column, encodedArg, prefix, suffix) {
|
|
4972
|
+
var encodedPrefix = prefix ? column.encode(context, prefix) : null;
|
|
4973
|
+
var encodedSuffix = suffix ? column.encode(context, suffix) : null;
|
|
4974
|
+
var engine = getSessionSingleton(context, 'engine');
|
|
4975
|
+
|
|
4976
|
+
if (engine === 'mysql')
|
|
4977
|
+
return concatWithFunction(encodedPrefix, encodedArg, encodedSuffix);
|
|
4978
|
+
if (engine === 'mssql' || engine === 'mssqlNative')
|
|
4979
|
+
return concatWithOperator('+', encodedPrefix, encodedArg, encodedSuffix);
|
|
4980
|
+
return concatWithOperator('||', encodedPrefix, encodedArg, encodedSuffix);
|
|
4981
|
+
}
|
|
4982
|
+
|
|
4983
|
+
function concatWithFunction(prefix, value, suffix) {
|
|
4984
|
+
var args = [prefix, value, suffix].filter(Boolean);
|
|
4985
|
+
var sql = 'CONCAT(' + args.map(x => x.sql()).join(',') + ')';
|
|
4986
|
+
var parameters = [];
|
|
4987
|
+
for (var i = 0; i < args.length; i++)
|
|
4988
|
+
parameters = parameters.concat(args[i].parameters);
|
|
4989
|
+
return newParameterized(sql, parameters);
|
|
4990
|
+
}
|
|
4991
|
+
|
|
4992
|
+
function concatWithOperator(operator, prefix, value, suffix) {
|
|
4993
|
+
var args = [prefix, value, suffix].filter(Boolean);
|
|
4994
|
+
var sql = '';
|
|
4995
|
+
var parameters = [];
|
|
4996
|
+
for (var i = 0; i < args.length; i++) {
|
|
4997
|
+
if (i > 0)
|
|
4998
|
+
sql += ' ' + operator + ' ';
|
|
4999
|
+
sql += args[i].sql();
|
|
5000
|
+
parameters = parameters.concat(args[i].parameters);
|
|
5001
|
+
}
|
|
5002
|
+
return newParameterized(sql, parameters);
|
|
5003
|
+
}
|
|
5004
|
+
|
|
5005
|
+
newLikeColumnArg_1 = newLikeColumnArg;
|
|
5006
|
+
return newLikeColumnArg_1;
|
|
5007
|
+
}
|
|
5008
|
+
|
|
4869
5009
|
var startsWithCore_1;
|
|
4870
5010
|
var hasRequiredStartsWithCore;
|
|
4871
5011
|
|
|
@@ -4875,12 +5015,16 @@ function requireStartsWithCore () {
|
|
|
4875
5015
|
var newBoolean = requireNewBoolean();
|
|
4876
5016
|
var nullOperator = ' is ';
|
|
4877
5017
|
var quote = requireQuote$6();
|
|
5018
|
+
var encodeFilterArg = requireEncodeFilterArg();
|
|
5019
|
+
var newLikeColumnArg = requireNewLikeColumnArg();
|
|
4878
5020
|
|
|
4879
5021
|
function startsWithCore(context, operator, column,arg,alias) {
|
|
4880
5022
|
operator = ' ' + operator + ' ';
|
|
4881
|
-
var encoded =
|
|
5023
|
+
var encoded = encodeFilterArg(context, column, arg);
|
|
4882
5024
|
if (encoded.sql() == 'null')
|
|
4883
5025
|
operator = nullOperator;
|
|
5026
|
+
else if (arg && typeof arg._toFilterArg === 'function')
|
|
5027
|
+
encoded = newLikeColumnArg(context, column, encoded, null, '%');
|
|
4884
5028
|
else
|
|
4885
5029
|
encoded = column.encode(context, arg + '%');
|
|
4886
5030
|
var firstPart = quote(context, alias) + '.' + quote(context, column._dbName) + operator;
|
|
@@ -4913,13 +5057,17 @@ function requireEndsWithCore () {
|
|
|
4913
5057
|
const quote = requireQuote$6();
|
|
4914
5058
|
var newBoolean = requireNewBoolean();
|
|
4915
5059
|
var nullOperator = ' is ';
|
|
5060
|
+
var encodeFilterArg = requireEncodeFilterArg();
|
|
5061
|
+
var newLikeColumnArg = requireNewLikeColumnArg();
|
|
4916
5062
|
|
|
4917
5063
|
function endsWithCore(context, operator, column,arg,alias) {
|
|
4918
5064
|
alias = quote(context, alias);
|
|
4919
5065
|
operator = ' ' + operator + ' ';
|
|
4920
|
-
var encoded =
|
|
5066
|
+
var encoded = encodeFilterArg(context, column, arg);
|
|
4921
5067
|
if (encoded.sql() == 'null')
|
|
4922
5068
|
operator = nullOperator;
|
|
5069
|
+
else if (arg && typeof arg._toFilterArg === 'function')
|
|
5070
|
+
encoded = newLikeColumnArg(context, column, encoded, '%', null);
|
|
4923
5071
|
else
|
|
4924
5072
|
encoded = column.encode(context, '%' + arg);
|
|
4925
5073
|
var firstPart = alias + '.' + quote(context, column._dbName) + operator;
|
|
@@ -4943,22 +5091,26 @@ function requireEndsWith () {
|
|
|
4943
5091
|
return endsWith;
|
|
4944
5092
|
}
|
|
4945
5093
|
|
|
4946
|
-
var
|
|
5094
|
+
var containsCore_1;
|
|
4947
5095
|
var hasRequiredContainsCore;
|
|
4948
5096
|
|
|
4949
5097
|
function requireContainsCore () {
|
|
4950
|
-
if (hasRequiredContainsCore) return
|
|
5098
|
+
if (hasRequiredContainsCore) return containsCore_1;
|
|
4951
5099
|
hasRequiredContainsCore = 1;
|
|
4952
5100
|
const quote = requireQuote$6();
|
|
4953
5101
|
var newBoolean = requireNewBoolean();
|
|
4954
5102
|
var nullOperator = ' is ';
|
|
5103
|
+
var encodeFilterArg = requireEncodeFilterArg();
|
|
5104
|
+
var newLikeColumnArg = requireNewLikeColumnArg();
|
|
4955
5105
|
|
|
4956
|
-
function
|
|
5106
|
+
function containsCore(context, operator, column,arg,alias) {
|
|
4957
5107
|
alias = quote(context, alias);
|
|
4958
5108
|
operator = ' ' + operator + ' ';
|
|
4959
|
-
var encoded =
|
|
5109
|
+
var encoded = encodeFilterArg(context, column, arg);
|
|
4960
5110
|
if (encoded.sql() == 'null')
|
|
4961
5111
|
operator = nullOperator;
|
|
5112
|
+
else if (arg && typeof arg._toFilterArg === 'function')
|
|
5113
|
+
encoded = newLikeColumnArg(context, column, encoded, '%', '%');
|
|
4962
5114
|
else
|
|
4963
5115
|
encoded = column.encode(context, '%' + arg + '%');
|
|
4964
5116
|
var firstPart = alias + '.' + quote(context, column._dbName) + operator;
|
|
@@ -4966,8 +5118,8 @@ function requireContainsCore () {
|
|
|
4966
5118
|
return newBoolean(filter);
|
|
4967
5119
|
}
|
|
4968
5120
|
|
|
4969
|
-
|
|
4970
|
-
return
|
|
5121
|
+
containsCore_1 = containsCore;
|
|
5122
|
+
return containsCore_1;
|
|
4971
5123
|
}
|
|
4972
5124
|
|
|
4973
5125
|
var contains;
|
|
@@ -9880,6 +10032,35 @@ function requireChildColumn () {
|
|
|
9880
10032
|
return childColumn_1;
|
|
9881
10033
|
}
|
|
9882
10034
|
|
|
10035
|
+
var newFilterArg_1;
|
|
10036
|
+
var hasRequiredNewFilterArg;
|
|
10037
|
+
|
|
10038
|
+
function requireNewFilterArg () {
|
|
10039
|
+
if (hasRequiredNewFilterArg) return newFilterArg_1;
|
|
10040
|
+
hasRequiredNewFilterArg = 1;
|
|
10041
|
+
var newJoin = requireJoinSql();
|
|
10042
|
+
var newWhere = requireWhereSql();
|
|
10043
|
+
var newParameterized = requireNewParameterized();
|
|
10044
|
+
var quote = requireQuote$6();
|
|
10045
|
+
|
|
10046
|
+
function newFilterArg(context, column, relations, depth = 0) {
|
|
10047
|
+
var relationCount = relations.length;
|
|
10048
|
+
var alias = 'x' + relationCount;
|
|
10049
|
+
var table = relations[relationCount - 1].childTable;
|
|
10050
|
+
|
|
10051
|
+
var quotedAlias = quote(context, alias);
|
|
10052
|
+
var quotedColumn = quote(context, column._dbName);
|
|
10053
|
+
var quotedTable = quote(context, table._dbName);
|
|
10054
|
+
var select = newParameterized(`(SELECT ${quotedAlias}.${quotedColumn} FROM ${quotedTable} ${quotedAlias}`);
|
|
10055
|
+
var join = newJoin(context, relations, depth);
|
|
10056
|
+
var where = newWhere(context, relations, null, depth);
|
|
10057
|
+
return select.append(join).append(where).append(')');
|
|
10058
|
+
}
|
|
10059
|
+
|
|
10060
|
+
newFilterArg_1 = newFilterArg;
|
|
10061
|
+
return newFilterArg_1;
|
|
10062
|
+
}
|
|
10063
|
+
|
|
9883
10064
|
var relatedColumn;
|
|
9884
10065
|
var hasRequiredRelatedColumn;
|
|
9885
10066
|
|
|
@@ -9890,6 +10071,7 @@ function requireRelatedColumn () {
|
|
|
9890
10071
|
var aggregateGroup = requireColumnAggregateGroup();
|
|
9891
10072
|
var aggregate = requireColumnAggregate();
|
|
9892
10073
|
var childColumn = requireChildColumn();
|
|
10074
|
+
var newFilterArg = requireNewFilterArg();
|
|
9893
10075
|
|
|
9894
10076
|
function newRelatedColumn(column, relations, isShallow, depth) {
|
|
9895
10077
|
var c = {};
|
|
@@ -9913,9 +10095,18 @@ function requireRelatedColumn () {
|
|
|
9913
10095
|
c.max = (context, ...rest) => aggregate.apply(null, [context, 'max', column, relations, false, ...rest]);
|
|
9914
10096
|
c.count = (context, ...rest) => aggregate.apply(null, [context, 'count', column, relations, false, ...rest]);
|
|
9915
10097
|
c.self = (context, ...rest) => childColumn.apply(null, [context, column, relations, ...rest]);
|
|
10098
|
+
Object.defineProperty(c, '_toFilterArg', {
|
|
10099
|
+
value: toFilterArg,
|
|
10100
|
+
enumerable: false,
|
|
10101
|
+
writable: false
|
|
10102
|
+
});
|
|
9916
10103
|
|
|
9917
10104
|
return c;
|
|
9918
10105
|
|
|
10106
|
+
function toFilterArg(context) {
|
|
10107
|
+
return newFilterArg(context, column, relations, depth);
|
|
10108
|
+
}
|
|
10109
|
+
|
|
9919
10110
|
function wrapFilter(filter) {
|
|
9920
10111
|
return runFilter;
|
|
9921
10112
|
|
|
@@ -10163,6 +10354,154 @@ function requireNone () {
|
|
|
10163
10354
|
return none;
|
|
10164
10355
|
}
|
|
10165
10356
|
|
|
10357
|
+
var count;
|
|
10358
|
+
var hasRequiredCount$1;
|
|
10359
|
+
|
|
10360
|
+
function requireCount$1 () {
|
|
10361
|
+
if (hasRequiredCount$1) return count;
|
|
10362
|
+
hasRequiredCount$1 = 1;
|
|
10363
|
+
const negotiateRawSqlFilter = requireNegotiateRawSqlFilter();
|
|
10364
|
+
const newJoin = requireJoinSql();
|
|
10365
|
+
const newWhere = requireWhereSql();
|
|
10366
|
+
const getSessionSingleton = requireGetSessionSingleton();
|
|
10367
|
+
const newParameterized = requireNewParameterized();
|
|
10368
|
+
const newBoolean = requireNewBoolean();
|
|
10369
|
+
|
|
10370
|
+
const nullOperator = ' is ';
|
|
10371
|
+
const notNullOperator = ' is not ';
|
|
10372
|
+
const isShallow = true;
|
|
10373
|
+
|
|
10374
|
+
function newCount(newRelatedTable, relations, depth) {
|
|
10375
|
+
|
|
10376
|
+
function count(context, fn) {
|
|
10377
|
+
let shallowFilter;
|
|
10378
|
+
|
|
10379
|
+
if (fn !== undefined) {
|
|
10380
|
+
let relatedTable = newRelatedTable(relations, isShallow, depth + 1);
|
|
10381
|
+
let arg = typeof fn === 'function' ? fn(relatedTable) : fn;
|
|
10382
|
+
shallowFilter = negotiateRawSqlFilter(context, arg);
|
|
10383
|
+
}
|
|
10384
|
+
|
|
10385
|
+
const subQuery = newCountSubQuery(context, relations, shallowFilter, depth);
|
|
10386
|
+
return newCountFilter(subQuery);
|
|
10387
|
+
}
|
|
10388
|
+
|
|
10389
|
+
return count;
|
|
10390
|
+
}
|
|
10391
|
+
|
|
10392
|
+
function newCountSubQuery(context, relations, shallowFilter, depth) {
|
|
10393
|
+
const quote = getSessionSingleton(context, 'quote');
|
|
10394
|
+
const relationCount = relations.length;
|
|
10395
|
+
const alias = 'x' + relationCount;
|
|
10396
|
+
const table = relations[relationCount - 1].childTable;
|
|
10397
|
+
const select = newParameterized(`SELECT COUNT(*) FROM ${quote(table._dbName)} ${quote(alias)}`);
|
|
10398
|
+
const join = newJoin(context, relations, depth);
|
|
10399
|
+
const where = newWhere(context, relations, shallowFilter, depth);
|
|
10400
|
+
|
|
10401
|
+
return select.append(join).append(where);
|
|
10402
|
+
}
|
|
10403
|
+
|
|
10404
|
+
function newCountFilter(subQuery) {
|
|
10405
|
+
let c = {};
|
|
10406
|
+
|
|
10407
|
+
c.equal = function(context, arg) {
|
|
10408
|
+
return compare(context, '=', arg);
|
|
10409
|
+
};
|
|
10410
|
+
|
|
10411
|
+
c.notEqual = function(context, arg) {
|
|
10412
|
+
return compare(context, '<>', arg);
|
|
10413
|
+
};
|
|
10414
|
+
|
|
10415
|
+
c.lessThan = function(context, arg) {
|
|
10416
|
+
return compare(context, '<', arg);
|
|
10417
|
+
};
|
|
10418
|
+
|
|
10419
|
+
c.lessThanOrEqual = function(context, arg) {
|
|
10420
|
+
return compare(context, '<=', arg);
|
|
10421
|
+
};
|
|
10422
|
+
|
|
10423
|
+
c.greaterThan = function(context, arg) {
|
|
10424
|
+
return compare(context, '>', arg);
|
|
10425
|
+
};
|
|
10426
|
+
|
|
10427
|
+
c.greaterThanOrEqual = function(context, arg) {
|
|
10428
|
+
return compare(context, '>=', arg);
|
|
10429
|
+
};
|
|
10430
|
+
|
|
10431
|
+
c.between = function(context, from, to) {
|
|
10432
|
+
from = c.greaterThanOrEqual(context, from);
|
|
10433
|
+
to = c.lessThanOrEqual(context, to);
|
|
10434
|
+
return from.and(context, to);
|
|
10435
|
+
};
|
|
10436
|
+
|
|
10437
|
+
c.in = function(context, values) {
|
|
10438
|
+
if (values.length === 0)
|
|
10439
|
+
return newBoolean(newParameterized('1=2'));
|
|
10440
|
+
|
|
10441
|
+
let sqlParts = new Array(values.length);
|
|
10442
|
+
let params = [];
|
|
10443
|
+
for (let i = 0; i < values.length; i++) {
|
|
10444
|
+
const encoded = encodeArg(context, values[i]);
|
|
10445
|
+
sqlParts[i] = encoded.sql();
|
|
10446
|
+
params = params.concat(encoded.parameters);
|
|
10447
|
+
}
|
|
10448
|
+
|
|
10449
|
+
const sql = toSubQuery().sql() + ' in (' + sqlParts.join(',') + ')';
|
|
10450
|
+
const allParams = toSubQuery().parameters.concat(params);
|
|
10451
|
+
return newBoolean(newParameterized(sql, allParams));
|
|
10452
|
+
};
|
|
10453
|
+
|
|
10454
|
+
c.notIn = function(context, values) {
|
|
10455
|
+
return c.in(context, values).not(context);
|
|
10456
|
+
};
|
|
10457
|
+
|
|
10458
|
+
c.eq = c.equal;
|
|
10459
|
+
c.EQ = c.eq;
|
|
10460
|
+
c.ne = c.notEqual;
|
|
10461
|
+
c.NE = c.ne;
|
|
10462
|
+
c.gt = c.greaterThan;
|
|
10463
|
+
c.GT = c.gt;
|
|
10464
|
+
c.ge = c.greaterThanOrEqual;
|
|
10465
|
+
c.GE = c.ge;
|
|
10466
|
+
c.lt = c.lessThan;
|
|
10467
|
+
c.LT = c.lt;
|
|
10468
|
+
c.le = c.lessThanOrEqual;
|
|
10469
|
+
c.LE = c.le;
|
|
10470
|
+
c.IN = c.in;
|
|
10471
|
+
|
|
10472
|
+
return c;
|
|
10473
|
+
|
|
10474
|
+
function compare(context, operator, arg) {
|
|
10475
|
+
let encoded = encodeArg(context, arg);
|
|
10476
|
+
let operatorSql = ' ' + operator + ' ';
|
|
10477
|
+
if (encoded.sql() === 'null') {
|
|
10478
|
+
if (operator === '=')
|
|
10479
|
+
operatorSql = nullOperator;
|
|
10480
|
+
else if (operator === '<>')
|
|
10481
|
+
operatorSql = notNullOperator;
|
|
10482
|
+
}
|
|
10483
|
+
|
|
10484
|
+
let sql = toSubQuery().append(operatorSql).append(encoded);
|
|
10485
|
+
return newBoolean(sql);
|
|
10486
|
+
}
|
|
10487
|
+
|
|
10488
|
+
function encodeArg(context, arg) {
|
|
10489
|
+
if (arg && typeof arg._toFilterArg === 'function')
|
|
10490
|
+
return arg._toFilterArg(context);
|
|
10491
|
+
if (arg == null)
|
|
10492
|
+
return newParameterized('null');
|
|
10493
|
+
return newParameterized('?', [arg]);
|
|
10494
|
+
}
|
|
10495
|
+
|
|
10496
|
+
function toSubQuery() {
|
|
10497
|
+
return subQuery.prepend('(').append(')');
|
|
10498
|
+
}
|
|
10499
|
+
}
|
|
10500
|
+
|
|
10501
|
+
count = newCount;
|
|
10502
|
+
return count;
|
|
10503
|
+
}
|
|
10504
|
+
|
|
10166
10505
|
var newRelatedTable_1;
|
|
10167
10506
|
var hasRequiredNewRelatedTable;
|
|
10168
10507
|
|
|
@@ -10176,6 +10515,7 @@ function requireNewRelatedTable () {
|
|
|
10176
10515
|
var where = requireWhere$1();
|
|
10177
10516
|
var aggregate = requireAggregate$1();
|
|
10178
10517
|
var none = requireNone();
|
|
10518
|
+
var count = requireCount$1();
|
|
10179
10519
|
|
|
10180
10520
|
function newRelatedTable(relations, isShallow, depth = 0) {
|
|
10181
10521
|
var table = relations[relations.length - 1].childTable;
|
|
@@ -10197,6 +10537,9 @@ function requireNewRelatedTable () {
|
|
|
10197
10537
|
// @ts-ignore
|
|
10198
10538
|
c.where = where(relations, depth);
|
|
10199
10539
|
|
|
10540
|
+
// @ts-ignore
|
|
10541
|
+
c.count = count(newRelatedTable, relations, depth);
|
|
10542
|
+
|
|
10200
10543
|
// @ts-ignore
|
|
10201
10544
|
c._aggregate = aggregate(relations);
|
|
10202
10545
|
|
|
@@ -11176,7 +11519,7 @@ function requireNewSingleQuery () {
|
|
|
11176
11519
|
var newParameterized = requireNewParameterized();
|
|
11177
11520
|
var getSessionSingleton = requireGetSessionSingleton();
|
|
11178
11521
|
|
|
11179
|
-
function _new(context,table,filter,span, alias,orderBy,limit,offset) {
|
|
11522
|
+
function _new(context,table,filter,span, alias,orderBy,limit,offset,distinct = false) {
|
|
11180
11523
|
var quote = getSessionSingleton(context, 'quote');
|
|
11181
11524
|
var name = quote(table._dbName);
|
|
11182
11525
|
var columnSql = newColumnSql(context,table,span,alias,true);
|
|
@@ -11184,8 +11527,9 @@ function requireNewSingleQuery () {
|
|
|
11184
11527
|
var whereSql = newWhereSql(context,table,filter,alias);
|
|
11185
11528
|
if (limit)
|
|
11186
11529
|
limit = limit + ' ';
|
|
11530
|
+
const selectClause = distinct ? 'select distinct ' : 'select ';
|
|
11187
11531
|
|
|
11188
|
-
return newParameterized(
|
|
11532
|
+
return newParameterized(selectClause + limit + columnSql + ' from ' + name + ' ' + quote(alias)).append(joinSql).append(whereSql).append(orderBy + offset);
|
|
11189
11533
|
|
|
11190
11534
|
}
|
|
11191
11535
|
|
|
@@ -12752,13 +13096,17 @@ function requireNewQuery () {
|
|
|
12752
13096
|
var newParameterized = requireNewParameterized();
|
|
12753
13097
|
var extractOffset = requireExtractOffset();
|
|
12754
13098
|
|
|
12755
|
-
function newQuery(context, table,filter,span,alias) {
|
|
13099
|
+
function newQuery(context, table,filter,span,alias,options = {}) {
|
|
12756
13100
|
filter = extractFilter(filter);
|
|
12757
13101
|
var orderBy = '';
|
|
12758
13102
|
var limit = extractLimit(context, span);
|
|
12759
13103
|
var offset = extractOffset(context, span);
|
|
13104
|
+
const useDistinct = options.distinct && canUseDistinct(span);
|
|
13105
|
+
|
|
13106
|
+
var query = newSingleQuery(context, table,filter,span,alias,orderBy,limit,offset,useDistinct);
|
|
13107
|
+
if (useDistinct)
|
|
13108
|
+
return query;
|
|
12760
13109
|
|
|
12761
|
-
var query = newSingleQuery(context, table,filter,span,alias,orderBy,limit,offset);
|
|
12762
13110
|
const groupClause = groupBy(span);
|
|
12763
13111
|
return newParameterized(query.sql(), query.parameters).append(groupClause);
|
|
12764
13112
|
}
|
|
@@ -12770,6 +13118,11 @@ function requireNewQuery () {
|
|
|
12770
13118
|
return ' GROUP BY ' + keys.map(key => span.aggregates[key].groupBy).join(',');
|
|
12771
13119
|
}
|
|
12772
13120
|
|
|
13121
|
+
function canUseDistinct(span) {
|
|
13122
|
+
const keys = Object.keys(span.aggregates);
|
|
13123
|
+
return keys.every(key => !!span.aggregates[key].column);
|
|
13124
|
+
}
|
|
13125
|
+
|
|
12773
13126
|
newQuery_1 = newQuery;
|
|
12774
13127
|
return newQuery_1;
|
|
12775
13128
|
}
|
|
@@ -12785,7 +13138,7 @@ function requireGroupBy () {
|
|
|
12785
13138
|
const strategyToSpan = requireStrategyToSpan();
|
|
12786
13139
|
const executeQueries = requireExecuteQueries();
|
|
12787
13140
|
|
|
12788
|
-
async function groupBy(context, table, filter, strategy) {
|
|
13141
|
+
async function groupBy(context, table, filter, strategy, options) {
|
|
12789
13142
|
filter = negotiateRawSqlFilter(context, filter, table);
|
|
12790
13143
|
if (strategy && strategy.where) {
|
|
12791
13144
|
let arg = typeof strategy.where === 'function' ? strategy.where(table) : strategy.where;
|
|
@@ -12797,7 +13150,7 @@ function requireGroupBy () {
|
|
|
12797
13150
|
|
|
12798
13151
|
let alias = table._dbName;
|
|
12799
13152
|
|
|
12800
|
-
const query = newQuery(context, table, filter, span, alias);
|
|
13153
|
+
const query = newQuery(context, table, filter, span, alias, options);
|
|
12801
13154
|
const res = await executeQueries(context, [query]);
|
|
12802
13155
|
return decode(context, span, await res[0]);
|
|
12803
13156
|
}
|
|
@@ -12935,6 +13288,10 @@ function requireTable () {
|
|
|
12935
13288
|
const args = [context, table, ...rest];
|
|
12936
13289
|
return groupBy.apply(null, args);
|
|
12937
13290
|
};
|
|
13291
|
+
table.distinct = function(context, ...rest) {
|
|
13292
|
+
const args = [context, table, ...rest, { distinct: true }];
|
|
13293
|
+
return groupBy.apply(null, args);
|
|
13294
|
+
};
|
|
12938
13295
|
|
|
12939
13296
|
table.getMany.exclusive = function(context, ...rest) {
|
|
12940
13297
|
const args = [context, table, ...rest];
|
package/docs/changelog.md
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
## Changelog
|
|
2
|
+
__5.2.0__
|
|
3
|
+
Distinct aggregates via `distinct()` [#119](https://github.com/alfateam/orange-orm/issues/119)
|
|
4
|
+
Column-to-column filters (incl. `contains`, `startsWith`, `endsWith`) [#150](htps://github.com/alfateam/orange-orm/issues/150)
|
|
5
|
+
Relation count filters: `x.lines.count()` with optional predicate [#151](htps://github.com/alfateam/orange-orm/issues/151)
|
|
2
6
|
__5.1.0__
|
|
3
7
|
Support for Hono [#149](https://github.com/alfateam/orange-orm/issues/149)
|
|
4
8
|
Removed dependency `glob`
|