@ruiapp/rapid-core 0.2.3 → 0.2.5

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/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @ruiapp/rapid-core
2
+
3
+ ## 0.2.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 146a99d: add between filterMode, range is deprecated
@@ -2,12 +2,13 @@ export type DataAccessPgColumnTypes = "int4" | "int8" | "float4" | "float8" | "d
2
2
  export type RowFilterRelationalOperators = "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "contains" | "notContains" | "containsCS" | "notContainsCS" | "startsWith" | "notStartsWith" | "endsWith" | "notEndsWith";
3
3
  export type RowFilterArrayOperators = "arrayContains" | "arrayOverlap";
4
4
  export type RowFilterSetOperators = "in" | "notIn";
5
+ export type RowFilterRangeOperators = "between";
5
6
  export type RowFilterLogicalOperators = "or" | "and";
6
7
  export type RowFilterUnaryOperators = "null" | "notNull";
7
8
  export type RowFilterExistenceOperators = "exists" | "notExists";
8
- export type RowFilterOperators = RowFilterRelationalOperators | RowFilterArrayOperators | RowFilterSetOperators | RowFilterLogicalOperators | RowFilterUnaryOperators | RowFilterExistenceOperators;
9
- export type RowFilterOptions = FindRowRelationalFilterOptions | FindRowArrayFilterOptions | FindRowSetFilterOptions | FindRowLogicalFilterOptions | FindRowUnaryFilterOptions | FindRowExistenceFilterOptions;
10
- export type RowNonRelationPropertyFilterOptions = FindRowRelationalFilterOptions | FindRowArrayFilterOptions | FindRowSetFilterOptions | FindRowUnaryFilterOptions;
9
+ export type RowFilterOperators = RowFilterRelationalOperators | RowFilterArrayOperators | RowFilterSetOperators | RowFilterRangeOperators | RowFilterLogicalOperators | RowFilterUnaryOperators | RowFilterExistenceOperators;
10
+ export type RowFilterOptions = FindRowRelationalFilterOptions | FindRowArrayFilterOptions | FindRowSetFilterOptions | FindRowRangeFilterOptions | FindRowLogicalFilterOptions | FindRowUnaryFilterOptions | FindRowExistenceFilterOptions;
11
+ export type RowNonRelationPropertyFilterOptions = FindRowRelationalFilterOptions | FindRowArrayFilterOptions | FindRowSetFilterOptions | FindRowRangeFilterOptions | FindRowUnaryFilterOptions;
11
12
  export type ColumnSelectOptions = string | ColumnNameWithTableName;
12
13
  export type ColumnNameWithTableName = {
13
14
  name: string;
@@ -38,6 +39,12 @@ export interface FindRowSetFilterOptions {
38
39
  value: any[];
39
40
  itemType?: string;
40
41
  }
42
+ export interface FindRowRangeFilterOptions {
43
+ field: ColumnSelectOptions;
44
+ operator: RowFilterRangeOperators;
45
+ value: any[];
46
+ itemType?: string;
47
+ }
41
48
  export interface FindRowLogicalFilterOptions {
42
49
  operator: RowFilterLogicalOperators;
43
50
  filters: RowFilterOptions[];
package/dist/index.js CHANGED
@@ -202,8 +202,8 @@ const pgPropertyTypeColumnMap = {
202
202
  "image[]": "jsonb",
203
203
  };
204
204
 
205
- const objLeftQuoteChar = '"';
206
- const objRightQuoteChar = '"';
205
+ const objLeftQuoteChar = "\"";
206
+ const objRightQuoteChar = "\"";
207
207
  const relationalOperatorsMap = new Map([
208
208
  ["eq", "="],
209
209
  ["ne", "<>"],
@@ -369,7 +369,7 @@ class QueryBuilder {
369
369
  paramToLiteral: false,
370
370
  };
371
371
  let { filters } = options;
372
- let command = 'SELECT COUNT(*)::int as "count" FROM ';
372
+ let command = "SELECT COUNT(*)::int as \"count\" FROM ";
373
373
  command += this.quoteTable(model);
374
374
  if (filters && filters.length) {
375
375
  command += " WHERE ";
@@ -389,7 +389,7 @@ class QueryBuilder {
389
389
  paramToLiteral: false,
390
390
  };
391
391
  let { filters } = options;
392
- let command = 'SELECT COUNT(*)::int as "count" FROM ';
392
+ let command = "SELECT COUNT(*)::int as \"count\" FROM ";
393
393
  command += `${this.quoteTable(derivedModel)} LEFT JOIN ${this.quoteTable(baseModel)} ON ${this.quoteObject(derivedModel.tableName)}.id = ${this.quoteObject(baseModel.tableName)}.id`;
394
394
  if (filters && filters.length) {
395
395
  command += " WHERE ";
@@ -535,6 +535,9 @@ function buildFilterQuery(level, ctx, filter) {
535
535
  else if (operator === "in" || operator === "notIn") {
536
536
  return buildInFilterQuery(ctx, filter);
537
537
  }
538
+ else if (operator === "between") {
539
+ return buildRangeFilterQuery(ctx, filter);
540
+ }
538
541
  else if (operator === "contains") {
539
542
  return buildContainsFilterQuery(ctx, filter);
540
543
  }
@@ -607,6 +610,24 @@ function buildInFilterQuery(ctx, filter) {
607
610
  }
608
611
  return command;
609
612
  }
613
+ function buildRangeFilterQuery(ctx, filter) {
614
+ let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
615
+ if (filter.operator === "between") {
616
+ if (filter.value.length != 2) {
617
+ throw new Error(`Filter operator '${filter.operator}' need two values.`);
618
+ }
619
+ command += " BETWEEN ";
620
+ ctx.params.push(filter.value[0]);
621
+ command += `$${ctx.params.length}`;
622
+ command += " AND ";
623
+ ctx.params.push(filter.value[1]);
624
+ command += `$${ctx.params.length}`;
625
+ }
626
+ else {
627
+ throw new Error(`Filter operator '${filter.operator}' is not supported.`);
628
+ }
629
+ return command;
630
+ }
610
631
  function buildContainsFilterQuery(ctx, filter) {
611
632
  let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
612
633
  command += " LIKE ";
@@ -2196,7 +2217,7 @@ function getEntityPartChanges(server, model, before, after) {
2196
2217
  let changes = {};
2197
2218
  for (const key in after) {
2198
2219
  const property = getEntityPropertyByCode(server, model, key);
2199
- if (isOneRelationProperty(property)) {
2220
+ if (property && isOneRelationProperty(property)) {
2200
2221
  const afterValue = after[key];
2201
2222
  const beforeValue = before[key] || before[property.targetIdColumnName];
2202
2223
  if (afterValue) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -32,6 +32,8 @@ export type RowFilterArrayOperators = "arrayContains" | "arrayOverlap";
32
32
 
33
33
  export type RowFilterSetOperators = "in" | "notIn";
34
34
 
35
+ export type RowFilterRangeOperators = "between";
36
+
35
37
  export type RowFilterLogicalOperators = "or" | "and";
36
38
 
37
39
  export type RowFilterUnaryOperators = "null" | "notNull";
@@ -42,6 +44,7 @@ export type RowFilterOperators =
42
44
  | RowFilterRelationalOperators
43
45
  | RowFilterArrayOperators
44
46
  | RowFilterSetOperators
47
+ | RowFilterRangeOperators
45
48
  | RowFilterLogicalOperators
46
49
  | RowFilterUnaryOperators
47
50
  | RowFilterExistenceOperators;
@@ -50,6 +53,7 @@ export type RowFilterOptions =
50
53
  | FindRowRelationalFilterOptions
51
54
  | FindRowArrayFilterOptions
52
55
  | FindRowSetFilterOptions
56
+ | FindRowRangeFilterOptions
53
57
  | FindRowLogicalFilterOptions
54
58
  | FindRowUnaryFilterOptions
55
59
  | FindRowExistenceFilterOptions;
@@ -58,6 +62,7 @@ export type RowNonRelationPropertyFilterOptions =
58
62
  | FindRowRelationalFilterOptions
59
63
  | FindRowArrayFilterOptions
60
64
  | FindRowSetFilterOptions
65
+ | FindRowRangeFilterOptions
61
66
  | FindRowUnaryFilterOptions;
62
67
 
63
68
  export type ColumnSelectOptions = string | ColumnNameWithTableName;
@@ -98,6 +103,13 @@ export interface FindRowSetFilterOptions {
98
103
  itemType?: string;
99
104
  }
100
105
 
106
+ export interface FindRowRangeFilterOptions {
107
+ field: ColumnSelectOptions;
108
+ operator: RowFilterRangeOperators;
109
+ value: any[];
110
+ itemType?: string;
111
+ }
112
+
101
113
  export interface FindRowLogicalFilterOptions {
102
114
  operator: RowFilterLogicalOperators;
103
115
  filters: RowFilterOptions[];
@@ -16,7 +16,7 @@ export function getEntityPartChanges(server: IRpdServer, model: RpdDataModel, be
16
16
  let changes = {};
17
17
  for (const key in after) {
18
18
  const property = getEntityPropertyByCode(server, model, key);
19
- if (isOneRelationProperty(property)) {
19
+ if (property && isOneRelationProperty(property)) {
20
20
  const afterValue: number | { id: number } | null = after[key];
21
21
  const beforeValue: number | { id: number } | null = before[key] || before[property.targetIdColumnName];
22
22
  if (afterValue) {
@@ -15,11 +15,12 @@ import {
15
15
  ColumnNameWithTableName,
16
16
  DataAccessPgColumnTypes,
17
17
  FindRowArrayFilterOptions,
18
+ FindRowRangeFilterOptions,
18
19
  } from "~/dataAccess/dataAccessTypes";
19
20
  import { pgPropertyTypeColumnMap } from "~/dataAccess/columnTypeMapper";
20
21
 
21
- const objLeftQuoteChar = '"';
22
- const objRightQuoteChar = '"';
22
+ const objLeftQuoteChar = "\"";
23
+ const objRightQuoteChar = "\"";
23
24
 
24
25
  const relationalOperatorsMap = new Map<RowFilterRelationalOperators, string>([
25
26
  ["eq", "="],
@@ -222,7 +223,7 @@ export default class QueryBuilder {
222
223
  paramToLiteral: false,
223
224
  };
224
225
  let { filters } = options;
225
- let command = 'SELECT COUNT(*)::int as "count" FROM ';
226
+ let command = "SELECT COUNT(*)::int as \"count\" FROM ";
226
227
 
227
228
  command += this.quoteTable(model);
228
229
 
@@ -246,7 +247,7 @@ export default class QueryBuilder {
246
247
  paramToLiteral: false,
247
248
  };
248
249
  let { filters } = options;
249
- let command = 'SELECT COUNT(*)::int as "count" FROM ';
250
+ let command = "SELECT COUNT(*)::int as \"count\" FROM ";
250
251
 
251
252
  command += `${this.quoteTable(derivedModel)} LEFT JOIN ${this.quoteTable(baseModel)} ON ${this.quoteObject(derivedModel.tableName)}.id = ${this.quoteObject(
252
253
  baseModel.tableName,
@@ -413,6 +414,8 @@ function buildFilterQuery(level: number, ctx: BuildQueryContext, filter: RowFilt
413
414
  return buildUnaryFilterQuery(ctx, filter);
414
415
  } else if (operator === "in" || operator === "notIn") {
415
416
  return buildInFilterQuery(ctx, filter);
417
+ } else if (operator === "between") {
418
+ return buildRangeFilterQuery(ctx, filter);
416
419
  } else if (operator === "contains") {
417
420
  return buildContainsFilterQuery(ctx, filter);
418
421
  } else if (operator === "notContains") {
@@ -482,6 +485,31 @@ function buildInFilterQuery(ctx: BuildQueryContext, filter: FindRowSetFilterOpti
482
485
  return command;
483
486
  }
484
487
 
488
+ function buildRangeFilterQuery(ctx: BuildQueryContext, filter: FindRowRangeFilterOptions) {
489
+ let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
490
+
491
+ if (filter.operator === "between") {
492
+ if (filter.value.length != 2) {
493
+ throw new Error(`Filter operator '${filter.operator}' need two values.`);
494
+ }
495
+
496
+ command += " BETWEEN ";
497
+
498
+ ctx.params.push(filter.value[0]);
499
+ command += `$${ctx.params.length}`;
500
+
501
+ command += " AND "
502
+
503
+ ctx.params.push(filter.value[1]);
504
+ command += `$${ctx.params.length}`;
505
+
506
+ } else {
507
+ throw new Error(`Filter operator '${filter.operator}' is not supported.`);
508
+ }
509
+
510
+ return command;
511
+ }
512
+
485
513
  function buildContainsFilterQuery(ctx: BuildQueryContext, filter: FindRowRelationalFilterOptions) {
486
514
  let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
487
515