remult 3.3.11 → 3.3.13

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.
@@ -113,9 +113,16 @@ export class DataApi {
113
113
  }
114
114
  try {
115
115
  let { aggregate, ...rest } = body;
116
+ // The aggregate summarizes the whole filtered set, so it must not inherit
117
+ // the items query's paging/sorting/selection.
118
+ const aggregateRequest = {
119
+ get: (key) => ['_limit', '_page', '_sort', '_order', '_select'].includes(key)
120
+ ? undefined
121
+ : request?.get(key),
122
+ };
116
123
  let [{ r }, [aggregates]] = await Promise.all([
117
124
  this.getArrayImpl(request, rest),
118
- this.groupBy(request, { ...aggregate, where: body.where }),
125
+ this.groupBy(aggregateRequest, { ...aggregate, where: body.where }),
119
126
  ]);
120
127
  return {
121
128
  items: r,
@@ -329,10 +329,11 @@ export class ArrayEntityDataProvider {
329
329
  let idf = this.entity.idMetadata.field;
330
330
  if (!(idf instanceof CompoundIdField) &&
331
331
  idf.valueConverter.fieldTypeInDb === 'autoincrement') {
332
- j[names.$dbNameOf(idf)] = 1;
332
+ const idDbName = names.$dbNameOf(idf);
333
+ j[idDbName] = 1;
333
334
  for (const row of this.rows()) {
334
- if (row[idf.key] >= j[idf.key])
335
- j[idf.key] = row[idf.key] + 1;
335
+ if (row[idDbName] >= j[idDbName])
336
+ j[idDbName] = row[idDbName] + 1;
336
337
  }
337
338
  }
338
339
  else {
@@ -545,6 +545,7 @@ export function getRowAfterUpdate(meta, dataProvider, data, id, operation) {
545
545
  export async function groupByImpl(options, e, r, orderByNullFirst, limitSyntax) {
546
546
  let select = 'select count(*) as count';
547
547
  let groupBy = '';
548
+ const groupByCols = [];
548
549
  const processResultRow = [];
549
550
  processResultRow.push((sqlVal, theResult) => {
550
551
  theResult[GroupByCountMember] = Number(sqlVal);
@@ -562,6 +563,7 @@ export async function groupByImpl(options, e, r, orderByNullFirst, limitSyntax)
562
563
  else
563
564
  groupBy += ', ';
564
565
  groupBy += e.$dbNameOf(x);
566
+ groupByCols.push(e.$dbNameOf(x));
565
567
  }
566
568
  processResultRow.push((sqlResult, theResult) => {
567
569
  theResult[x.key] = x.valueConverter.fromDb(sqlResult);
@@ -625,7 +627,13 @@ export async function groupByImpl(options, e, r, orderByNullFirst, limitSyntax)
625
627
  if (orderBy)
626
628
  select += orderBy;
627
629
  }
628
- if (options?.limit) {
630
+ // Skip paging for a pure aggregate (single row); OFFSET/FETCH without an
631
+ // ORDER BY is also invalid on SQL Server.
632
+ if (options?.limit && groupByCols.length) {
633
+ // SQL Server requires an ORDER BY alongside OFFSET/FETCH; default to the
634
+ // group columns so paging is valid and deterministic on every dialect.
635
+ if (!orderBy)
636
+ select += ' order by ' + groupByCols.join(', ');
629
637
  let page = 1;
630
638
  if (options.page)
631
639
  page = options.page;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "3.3.11",
3
+ "version": "3.3.13",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
package/src/data-api.js CHANGED
@@ -187,7 +187,7 @@ var DataApi = /** @class */ (function () {
187
187
  };
188
188
  DataApi.prototype.query = function (response, request, body) {
189
189
  return tslib_1.__awaiter(this, void 0, void 0, function () {
190
- var aggregate, rest, _a, r, _b, aggregates, err_2;
190
+ var aggregate, rest, aggregateRequest, _a, r, _b, aggregates, err_2;
191
191
  return tslib_1.__generator(this, function (_c) {
192
192
  switch (_c.label) {
193
193
  case 0:
@@ -198,10 +198,20 @@ var DataApi = /** @class */ (function () {
198
198
  _c.label = 1;
199
199
  case 1:
200
200
  _c.trys.push([1, 3, , 4]);
201
- aggregate = body.aggregate, rest = tslib_1.__rest(body, ["aggregate"]);
201
+ aggregate = body.aggregate, rest = tslib_1.__rest(body
202
+ // The aggregate summarizes the whole filtered set, so it must not inherit
203
+ // the items query's paging/sorting/selection.
204
+ , ["aggregate"]);
205
+ aggregateRequest = {
206
+ get: function (key) {
207
+ return ['_limit', '_page', '_sort', '_order', '_select'].includes(key)
208
+ ? undefined
209
+ : request === null || request === void 0 ? void 0 : request.get(key);
210
+ },
211
+ };
202
212
  return [4 /*yield*/, Promise.all([
203
213
  this.getArrayImpl(request, rest),
204
- this.groupBy(request, tslib_1.__assign(tslib_1.__assign({}, aggregate), { where: body.where })),
214
+ this.groupBy(aggregateRequest, tslib_1.__assign(tslib_1.__assign({}, aggregate), { where: body.where })),
205
215
  ])];
206
216
  case 2:
207
217
  _a = tslib_1.__read.apply(void 0, [_c.sent(), 2]), r = _a[0].r, _b = tslib_1.__read(_a[1], 1), aggregates = _b[0];
@@ -555,7 +555,7 @@ var ArrayEntityDataProvider = /** @class */ (function () {
555
555
  };
556
556
  ArrayEntityDataProvider.prototype.insert = function (data) {
557
557
  return tslib_1.__awaiter(this, void 0, void 0, function () {
558
- var names, j, idf, _a, _b, row;
558
+ var names, j, idf, idDbName, _a, _b, row;
559
559
  var e_16, _c;
560
560
  var _this = this;
561
561
  return tslib_1.__generator(this, function (_d) {
@@ -567,12 +567,13 @@ var ArrayEntityDataProvider = /** @class */ (function () {
567
567
  idf = this.entity.idMetadata.field;
568
568
  if (!(idf instanceof CompoundIdField_js_1.CompoundIdField) &&
569
569
  idf.valueConverter.fieldTypeInDb === 'autoincrement') {
570
- j[names.$dbNameOf(idf)] = 1;
570
+ idDbName = names.$dbNameOf(idf);
571
+ j[idDbName] = 1;
571
572
  try {
572
573
  for (_a = tslib_1.__values(this.rows()), _b = _a.next(); !_b.done; _b = _a.next()) {
573
574
  row = _b.value;
574
- if (row[idf.key] >= j[idf.key])
575
- j[idf.key] = row[idf.key] + 1;
575
+ if (row[idDbName] >= j[idDbName])
576
+ j[idDbName] = row[idDbName] + 1;
576
577
  }
577
578
  }
578
579
  catch (e_16_1) { e_16 = { error: e_16_1 }; }
@@ -843,13 +843,14 @@ function groupByImpl(options, e, r, orderByNullFirst, limitSyntax) {
843
843
  ? "count (distinct ".concat(dbName, ")")
844
844
  : "".concat(operator, "( ").concat(dbName, " )");
845
845
  }
846
- var select, groupBy, processResultRow, _loop_1, _a, _b, x, _loop_2, GroupByOperators_1, GroupByOperators_1_1, operator, e_8_1, where, _c, orderBy, _d, _e, x, field, _f, e_9_1, page, result;
846
+ var select, groupBy, groupByCols, processResultRow, _loop_1, _a, _b, x, _loop_2, GroupByOperators_1, GroupByOperators_1_1, operator, e_8_1, where, _c, orderBy, _d, _e, x, field, _f, e_9_1, page, result;
847
847
  var e_10, _g, e_8, _h, e_9, _j;
848
848
  return tslib_1.__generator(this, function (_k) {
849
849
  switch (_k.label) {
850
850
  case 0:
851
851
  select = 'select count(*) as count';
852
852
  groupBy = '';
853
+ groupByCols = [];
853
854
  processResultRow = [];
854
855
  processResultRow.push(function (sqlVal, theResult) {
855
856
  theResult[remult3_js_1.GroupByCountMember] = Number(sqlVal);
@@ -867,6 +868,7 @@ function groupByImpl(options, e, r, orderByNullFirst, limitSyntax) {
867
868
  else
868
869
  groupBy += ', ';
869
870
  groupBy += e.$dbNameOf(x);
871
+ groupByCols.push(e.$dbNameOf(x));
870
872
  }
871
873
  processResultRow.push(function (sqlResult, theResult) {
872
874
  theResult[x.key] = x.valueConverter.fromDb(sqlResult);
@@ -1049,7 +1051,13 @@ function groupByImpl(options, e, r, orderByNullFirst, limitSyntax) {
1049
1051
  select += orderBy;
1050
1052
  _k.label = 20;
1051
1053
  case 20:
1052
- if (options === null || options === void 0 ? void 0 : options.limit) {
1054
+ // Skip paging for a pure aggregate (single row); OFFSET/FETCH without an
1055
+ // ORDER BY is also invalid on SQL Server.
1056
+ if ((options === null || options === void 0 ? void 0 : options.limit) && groupByCols.length) {
1057
+ // SQL Server requires an ORDER BY alongside OFFSET/FETCH; default to the
1058
+ // group columns so paging is valid and deterministic on every dialect.
1059
+ if (!orderBy)
1060
+ select += ' order by ' + groupByCols.join(', ');
1053
1061
  page = 1;
1054
1062
  if (options.page)
1055
1063
  page = options.page;