@sqb/connect 4.20.7 → 4.21.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.
Files changed (144) hide show
  1. package/{types/client → client}/cursor-stream.d.ts +1 -1
  2. package/{types/client → client}/cursor.d.ts +4 -4
  3. package/{types/client → client}/sqb-connection.d.ts +4 -4
  4. package/{esm/orm → orm}/commands/command.helper.js +2 -3
  5. package/{types/orm → orm}/commands/count.command.d.ts +2 -2
  6. package/{types/orm → orm}/commands/create.command.d.ts +1 -1
  7. package/{esm/orm → orm}/commands/create.command.js +3 -5
  8. package/{types/orm → orm}/commands/delete.command.d.ts +2 -2
  9. package/{types/orm → orm}/commands/find.command.d.ts +2 -2
  10. package/{esm/orm → orm}/commands/find.command.js +3 -4
  11. package/{types/orm → orm}/commands/row-converter.d.ts +1 -1
  12. package/{types/orm → orm}/commands/update.command.d.ts +2 -2
  13. package/{esm/orm → orm}/commands/update.command.js +3 -5
  14. package/{types/orm → orm}/model/association-field-metadata.d.ts +0 -5
  15. package/{types/orm → orm}/model/association.d.ts +3 -3
  16. package/{esm/orm → orm}/model/association.js +1 -1
  17. package/{types/orm → orm}/model/column-field-metadata.d.ts +2 -8
  18. package/{types/orm → orm}/model/embedded-field-metadata.d.ts +0 -1
  19. package/{esm/orm → orm}/model/embedded-field-metadata.js +0 -14
  20. package/{types/orm → orm}/model/entity-metadata.d.ts +3 -3
  21. package/{esm/orm → orm}/model/entity-metadata.js +21 -6
  22. package/orm/model/index-metadata.js +1 -0
  23. package/orm/orm.type.js +1 -0
  24. package/{types/orm → orm}/repository.class.d.ts +2 -2
  25. package/{esm/orm → orm}/repository.class.js +1 -1
  26. package/{types/orm → orm}/util/orm.helper.d.ts +5 -3
  27. package/{esm/orm → orm}/util/orm.helper.js +14 -0
  28. package/package.json +10 -26
  29. package/cjs/client/adapter.js +0 -2
  30. package/cjs/client/cursor-stream.js +0 -104
  31. package/cjs/client/cursor.js +0 -261
  32. package/cjs/client/extensions.js +0 -41
  33. package/cjs/client/field-info-map.js +0 -54
  34. package/cjs/client/helpers.js +0 -140
  35. package/cjs/client/sqb-client.js +0 -175
  36. package/cjs/client/sqb-connection.js +0 -293
  37. package/cjs/client/sqb-error.js +0 -15
  38. package/cjs/client/types.js +0 -5
  39. package/cjs/index.js +0 -41
  40. package/cjs/orm/backward.js +0 -24
  41. package/cjs/orm/base-entity.js +0 -29
  42. package/cjs/orm/commands/command.helper.js +0 -170
  43. package/cjs/orm/commands/count.command.js +0 -30
  44. package/cjs/orm/commands/create.command.js +0 -92
  45. package/cjs/orm/commands/delete.command.js +0 -30
  46. package/cjs/orm/commands/find.command.js +0 -301
  47. package/cjs/orm/commands/row-converter.js +0 -190
  48. package/cjs/orm/commands/update.command.js +0 -83
  49. package/cjs/orm/decorators/column.decorator.js +0 -32
  50. package/cjs/orm/decorators/embedded.decorator.js +0 -15
  51. package/cjs/orm/decorators/entity.decorator.js +0 -180
  52. package/cjs/orm/decorators/events.decorator.js +0 -63
  53. package/cjs/orm/decorators/foreignkey.decorator.js +0 -12
  54. package/cjs/orm/decorators/index.decorator.js +0 -20
  55. package/cjs/orm/decorators/link.decorator.js +0 -72
  56. package/cjs/orm/decorators/primarykey.decorator.js +0 -24
  57. package/cjs/orm/decorators/transform.decorator.js +0 -21
  58. package/cjs/orm/model/association-field-metadata.js +0 -24
  59. package/cjs/orm/model/association-node.js +0 -28
  60. package/cjs/orm/model/association.js +0 -141
  61. package/cjs/orm/model/column-field-metadata.js +0 -32
  62. package/cjs/orm/model/embedded-field-metadata.js +0 -28
  63. package/cjs/orm/model/entity-metadata.js +0 -327
  64. package/cjs/orm/model/field-metadata.js +0 -2
  65. package/cjs/orm/model/index-metadata.js +0 -2
  66. package/cjs/orm/model/link-chain.js +0 -47
  67. package/cjs/orm/orm.const.js +0 -6
  68. package/cjs/orm/orm.type.js +0 -2
  69. package/cjs/orm/repository.class.js +0 -293
  70. package/cjs/orm/util/apply-mixins.js +0 -16
  71. package/cjs/orm/util/extract-keyvalues.js +0 -63
  72. package/cjs/orm/util/orm.helper.js +0 -34
  73. package/cjs/orm/util/parse-fields-projection.js +0 -68
  74. package/cjs/orm/util/serialize-field.js +0 -49
  75. package/cjs/package.json +0 -3
  76. package/esm/orm/model/association-field-metadata.js +0 -20
  77. package/esm/orm/model/column-field-metadata.js +0 -28
  78. package/esm/package.json +0 -3
  79. package/types/index.d.cts +0 -33
  80. /package/{types/client → client}/adapter.d.ts +0 -0
  81. /package/{esm/client → client}/adapter.js +0 -0
  82. /package/{esm/client → client}/cursor-stream.js +0 -0
  83. /package/{esm/client → client}/cursor.js +0 -0
  84. /package/{types/client → client}/extensions.d.ts +0 -0
  85. /package/{esm/client → client}/extensions.js +0 -0
  86. /package/{types/client → client}/field-info-map.d.ts +0 -0
  87. /package/{esm/client → client}/field-info-map.js +0 -0
  88. /package/{types/client → client}/helpers.d.ts +0 -0
  89. /package/{esm/client → client}/helpers.js +0 -0
  90. /package/{types/client → client}/sqb-client.d.ts +0 -0
  91. /package/{esm/client → client}/sqb-client.js +0 -0
  92. /package/{esm/client → client}/sqb-connection.js +0 -0
  93. /package/{types/client → client}/sqb-error.d.ts +0 -0
  94. /package/{esm/client → client}/sqb-error.js +0 -0
  95. /package/{types/client → client}/types.d.ts +0 -0
  96. /package/{esm/client → client}/types.js +0 -0
  97. /package/{types/index.d.ts → index.d.ts} +0 -0
  98. /package/{esm/index.js → index.js} +0 -0
  99. /package/{types/orm → orm}/backward.d.ts +0 -0
  100. /package/{esm/orm → orm}/backward.js +0 -0
  101. /package/{types/orm → orm}/base-entity.d.ts +0 -0
  102. /package/{esm/orm → orm}/base-entity.js +0 -0
  103. /package/{types/orm → orm}/commands/command.helper.d.ts +0 -0
  104. /package/{esm/orm → orm}/commands/count.command.js +0 -0
  105. /package/{esm/orm → orm}/commands/delete.command.js +0 -0
  106. /package/{esm/orm → orm}/commands/row-converter.js +0 -0
  107. /package/{types/orm → orm}/decorators/column.decorator.d.ts +0 -0
  108. /package/{esm/orm → orm}/decorators/column.decorator.js +0 -0
  109. /package/{types/orm → orm}/decorators/embedded.decorator.d.ts +0 -0
  110. /package/{esm/orm → orm}/decorators/embedded.decorator.js +0 -0
  111. /package/{types/orm → orm}/decorators/entity.decorator.d.ts +0 -0
  112. /package/{esm/orm → orm}/decorators/entity.decorator.js +0 -0
  113. /package/{types/orm → orm}/decorators/events.decorator.d.ts +0 -0
  114. /package/{esm/orm → orm}/decorators/events.decorator.js +0 -0
  115. /package/{types/orm → orm}/decorators/foreignkey.decorator.d.ts +0 -0
  116. /package/{esm/orm → orm}/decorators/foreignkey.decorator.js +0 -0
  117. /package/{types/orm → orm}/decorators/index.decorator.d.ts +0 -0
  118. /package/{esm/orm → orm}/decorators/index.decorator.js +0 -0
  119. /package/{types/orm → orm}/decorators/link.decorator.d.ts +0 -0
  120. /package/{esm/orm → orm}/decorators/link.decorator.js +0 -0
  121. /package/{types/orm → orm}/decorators/primarykey.decorator.d.ts +0 -0
  122. /package/{esm/orm → orm}/decorators/primarykey.decorator.js +0 -0
  123. /package/{types/orm → orm}/decorators/transform.decorator.d.ts +0 -0
  124. /package/{esm/orm → orm}/decorators/transform.decorator.js +0 -0
  125. /package/{esm/orm/model/field-metadata.js → orm/model/association-field-metadata.js} +0 -0
  126. /package/{types/orm → orm}/model/association-node.d.ts +0 -0
  127. /package/{esm/orm → orm}/model/association-node.js +0 -0
  128. /package/{esm/orm/model/index-metadata.js → orm/model/column-field-metadata.js} +0 -0
  129. /package/{types/orm → orm}/model/field-metadata.d.ts +0 -0
  130. /package/{esm/orm/orm.type.js → orm/model/field-metadata.js} +0 -0
  131. /package/{types/orm → orm}/model/index-metadata.d.ts +0 -0
  132. /package/{types/orm → orm}/model/link-chain.d.ts +0 -0
  133. /package/{esm/orm → orm}/model/link-chain.js +0 -0
  134. /package/{types/orm → orm}/orm.const.d.ts +0 -0
  135. /package/{esm/orm → orm}/orm.const.js +0 -0
  136. /package/{types/orm → orm}/orm.type.d.ts +0 -0
  137. /package/{types/orm → orm}/util/apply-mixins.d.ts +0 -0
  138. /package/{esm/orm → orm}/util/apply-mixins.js +0 -0
  139. /package/{types/orm → orm}/util/extract-keyvalues.d.ts +0 -0
  140. /package/{esm/orm → orm}/util/extract-keyvalues.js +0 -0
  141. /package/{types/orm → orm}/util/parse-fields-projection.d.ts +0 -0
  142. /package/{esm/orm → orm}/util/parse-fields-projection.js +0 -0
  143. /package/{types/orm → orm}/util/serialize-field.d.ts +0 -0
  144. /package/{esm/orm → orm}/util/serialize-field.js +0 -0
@@ -1,92 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CreateCommand = void 0;
4
- const builder_1 = require("@sqb/builder");
5
- const column_field_metadata_js_1 = require("../model/column-field-metadata.js");
6
- const embedded_field_metadata_js_1 = require("../model/embedded-field-metadata.js");
7
- const entity_metadata_js_1 = require("../model/entity-metadata.js");
8
- const orm_helper_js_1 = require("../util/orm.helper.js");
9
- class CreateCommand {
10
- // istanbul ignore next
11
- constructor() {
12
- throw new Error('This class is abstract');
13
- }
14
- static async execute(args) {
15
- const { entity } = args;
16
- const tableName = entity.tableName;
17
- if (!tableName)
18
- throw new Error(`${entity.ctor.name} is not decorated with @Entity decorator`);
19
- // Create a context
20
- const ctx = {
21
- entity,
22
- queryParams: {},
23
- queryValues: {},
24
- colCount: 0,
25
- };
26
- // Prepare
27
- await this._prepareParams(ctx, entity, args.values);
28
- if (!ctx.colCount)
29
- throw new Error('No field given to create new entity instance');
30
- const query = (0, builder_1.Insert)(tableName, ctx.queryValues);
31
- if (args.returning) {
32
- const primaryIndexColumns = entity_metadata_js_1.EntityMetadata.getPrimaryIndexColumns(entity);
33
- if (primaryIndexColumns.length)
34
- query.returning(...primaryIndexColumns.map(col => col.fieldName));
35
- }
36
- const qr = await args.connection.execute(query, {
37
- params: ctx.queryParams,
38
- objectRows: false,
39
- cursor: false,
40
- });
41
- if (args.returning && qr.fields && qr.rows?.length) {
42
- const keyValues = {};
43
- for (const f of qr.fields.values()) {
44
- const el = entity_metadata_js_1.EntityMetadata.getColumnFieldByFieldName(entity, f.fieldName);
45
- if (el)
46
- keyValues[el.name] = qr.rows[0][f.index];
47
- }
48
- return keyValues;
49
- }
50
- }
51
- static async _prepareParams(ctx, entity, values, prefix, suffix) {
52
- let v;
53
- prefix = prefix || '';
54
- suffix = suffix || '';
55
- for (const col of Object.values(entity.fields)) {
56
- v = values[col.name];
57
- if ((0, orm_helper_js_1.isColumnField)(col)) {
58
- if (col.noInsert)
59
- continue;
60
- if (v == null && col.default !== undefined) {
61
- v =
62
- typeof col.default === 'function'
63
- ? col.default(values)
64
- : col.default;
65
- }
66
- if (typeof col.serialize === 'function')
67
- v = col.serialize(v, col.name);
68
- if (v == null) {
69
- if (col.notNull && !col.autoGenerated) {
70
- throw new Error(`${entity.name}.${col.name} is required and can't be null`);
71
- }
72
- continue;
73
- }
74
- column_field_metadata_js_1.ColumnFieldMetadata.checkEnumValue(col, v);
75
- const fieldName = prefix + col.fieldName + suffix;
76
- const k = ('I$_' + fieldName).substring(0, 30);
77
- ctx.queryValues[fieldName] = (0, builder_1.Param)({
78
- name: k,
79
- dataType: col.dataType,
80
- isArray: col.isArray,
81
- });
82
- ctx.queryParams[k] = v;
83
- ctx.colCount++;
84
- }
85
- else if (v != null && (0, orm_helper_js_1.isEmbeddedField)(col)) {
86
- const type = await embedded_field_metadata_js_1.EmbeddedFieldMetadata.resolveType(col);
87
- await this._prepareParams(ctx, type, v, col.fieldNamePrefix, col.fieldNameSuffix);
88
- }
89
- }
90
- }
91
- }
92
- exports.CreateCommand = CreateCommand;
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DeleteCommand = void 0;
4
- const builder_1 = require("@sqb/builder");
5
- const command_helper_js_1 = require("./command.helper.js");
6
- class DeleteCommand {
7
- // istanbul ignore next
8
- constructor() {
9
- throw new Error('This class is abstract');
10
- }
11
- static async execute(args) {
12
- const { connection, entity, filter, params } = args;
13
- let where;
14
- if (filter) {
15
- where = (0, builder_1.And)();
16
- await (0, command_helper_js_1.prepareFilter)(entity, filter, where);
17
- }
18
- const query = (0, builder_1.Delete)(entity.tableName + ' T');
19
- if (where)
20
- query.where(...where._items);
21
- // Execute query
22
- const resp = await connection.execute(query, {
23
- params,
24
- objectRows: false,
25
- cursor: false,
26
- });
27
- return (resp && resp.rowsAffected) || 0;
28
- }
29
- }
30
- exports.DeleteCommand = DeleteCommand;
@@ -1,301 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FindCommand = void 0;
4
- const builder_1 = require("@sqb/builder");
5
- const association_node_js_1 = require("../model/association-node.js");
6
- const embedded_field_metadata_js_1 = require("../model/embedded-field-metadata.js");
7
- const entity_metadata_js_1 = require("../model/entity-metadata.js");
8
- const orm_helper_js_1 = require("../util/orm.helper.js");
9
- const parse_fields_projection_js_1 = require("../util/parse-fields-projection.js");
10
- const command_helper_js_1 = require("./command.helper.js");
11
- const row_converter_js_1 = require("./row-converter.js");
12
- const SORT_ORDER_PATTERN = /^([-+])?(.*)$/;
13
- class FindCommand {
14
- maxEagerFetch = 100000;
15
- maxSubQueries = 5;
16
- mainEntity;
17
- resultEntity;
18
- converter;
19
- mainAlias = 'T';
20
- resultAlias = 'T';
21
- _joins = [];
22
- _selectColumns = {};
23
- _filter = (0, builder_1.And)();
24
- _sort;
25
- constructor(selectEntity, outputEntity) {
26
- this.mainEntity = selectEntity;
27
- this.resultEntity = outputEntity;
28
- this.converter = new row_converter_js_1.RowConverter(outputEntity.ctor);
29
- }
30
- static async create(source, opts = {}) {
31
- let command;
32
- let listingEntity;
33
- if (source instanceof association_node_js_1.AssociationNode) {
34
- const node = source;
35
- listingEntity = await node.resolveTarget();
36
- const resultEntity = await node.getLast().resolveTarget();
37
- command = new FindCommand(listingEntity, resultEntity);
38
- if (node.conditions)
39
- await command.filter(node.conditions);
40
- if (node.next) {
41
- const join = await (0, command_helper_js_1.joinAssociationGetLast)(command._joins, node.next, command.mainAlias);
42
- command.resultAlias = join.joinAlias;
43
- }
44
- }
45
- else {
46
- listingEntity = source;
47
- command = new FindCommand(listingEntity, listingEntity);
48
- }
49
- if (!listingEntity.tableName)
50
- throw new Error(`${listingEntity.ctor.name} is not decorated with @Entity decorator`);
51
- if (typeof opts.maxSubQueries === 'number')
52
- command.maxSubQueries = opts.maxSubQueries;
53
- if (typeof opts.maxEagerFetch === 'number')
54
- command.maxEagerFetch = opts.maxEagerFetch;
55
- return command;
56
- }
57
- static async execute(args) {
58
- const command = await FindCommand.create(args.entity, {
59
- maxSubQueries: args.maxSubQueries,
60
- maxEagerFetch: args.maxEagerFetch,
61
- });
62
- await command.addFields({
63
- projection: args.projection,
64
- sort: args.sort,
65
- });
66
- if (args.filter)
67
- await command.filter(args.filter);
68
- if (args.sort)
69
- await command.sort(args.sort);
70
- return await command.execute(args);
71
- }
72
- async addFields(opts = {}) {
73
- const tableAlias = opts.tableAlias || this.resultAlias;
74
- const entity = opts.entity || this._getEntityFromAlias(tableAlias);
75
- const converter = opts.converter || this.converter;
76
- const projection = typeof opts.projection === 'string' || Array.isArray(opts.projection)
77
- ? (0, parse_fields_projection_js_1.parseFieldsProjection)(opts.projection)
78
- : opts.projection;
79
- const defaultFields = !projection || !Object.values(projection).find(p => !p.sign);
80
- const sortFields = opts.sort && opts.sort.length
81
- ? opts.sort.map(x => x.toLowerCase())
82
- : undefined;
83
- const prefix = opts.prefix || '';
84
- const suffix = opts.suffix || '';
85
- for (const key of Object.keys(entity.fields)) {
86
- const col = entity_metadata_js_1.EntityMetadata.getField(entity, key);
87
- if (!col || col.hidden)
88
- continue;
89
- const colNameLower = col.name.toLowerCase();
90
- const p = projection?.[colNameLower];
91
- if (
92
- /** Ignore if field is omitted */
93
- p?.sign === '-' ||
94
- /** Ignore if default fields and field is not in projection */
95
- (!defaultFields && !p) ||
96
- /** Ignore if default fields enabled and fields is exclusive */
97
- (defaultFields && col.exclusive && !p)) {
98
- continue;
99
- }
100
- // Add field to select list if field is a column
101
- if ((0, orm_helper_js_1.isColumnField)(col)) {
102
- const fieldAlias = this._selectColumn(tableAlias, col, prefix, suffix);
103
- // Add column to converter
104
- converter.addValueProperty({
105
- name: col.name,
106
- fieldAlias,
107
- dataType: col.dataType,
108
- parse: col.parse,
109
- });
110
- continue;
111
- }
112
- if ((0, orm_helper_js_1.isEmbeddedField)(col)) {
113
- const typ = await embedded_field_metadata_js_1.EmbeddedFieldMetadata.resolveType(col);
114
- const subConverter = converter.addObjectProperty({
115
- name: col.name,
116
- type: typ.ctor,
117
- }).converter;
118
- await this.addFields({
119
- tableAlias,
120
- converter: subConverter,
121
- entity: typ,
122
- prefix: col.fieldNamePrefix,
123
- suffix: col.fieldNameSuffix,
124
- projection: p?.projection,
125
- sort: extractSubFields(colNameLower, sortFields),
126
- });
127
- continue;
128
- }
129
- if ((0, orm_helper_js_1.isAssociationField)(col)) {
130
- // OtO relation
131
- if (!col.association.returnsMany()) {
132
- const joinInfo = await (0, command_helper_js_1.joinAssociationGetLast)(this._joins, col.association, tableAlias);
133
- const subConverter = converter.addObjectProperty({
134
- name: col.name,
135
- type: joinInfo.targetEntity.ctor,
136
- }).converter;
137
- // Add join fields to select columns list
138
- await this.addFields({
139
- tableAlias: joinInfo.joinAlias,
140
- converter: subConverter,
141
- entity: joinInfo.targetEntity,
142
- projection: p?.projection,
143
- sort: extractSubFields(colNameLower, sortFields),
144
- });
145
- continue;
146
- }
147
- // One-2-Many Eager relation
148
- if (this.maxSubQueries > 0) {
149
- const targetCol = await col.association.resolveTargetProperty();
150
- const sourceCol = await col.association.resolveSourceProperty();
151
- // We need to know key value to filter sub query.
152
- // So add key field into select columns
153
- const parentField = this._selectColumn(tableAlias, sourceCol);
154
- const findCommand = await FindCommand.create(col.association, {
155
- maxSubQueries: this.maxSubQueries - 1,
156
- maxEagerFetch: this.maxEagerFetch,
157
- });
158
- findCommand.converter.parent = this.converter;
159
- await findCommand.filter((0, builder_1.In)(targetCol.name, (0, builder_1.Param)(parentField)));
160
- const sort = sortFields && extractSubFields(colNameLower, sortFields);
161
- await findCommand.addFields({
162
- projection: p?.projection,
163
- sort,
164
- });
165
- if (sort)
166
- await findCommand.sort(sort);
167
- const keyField = findCommand._selectColumn(findCommand.mainAlias, targetCol);
168
- const resultType = await col.association.getLast().resolveTarget();
169
- converter.addNestedProperty({
170
- name: col.name,
171
- type: resultType.ctor,
172
- findCommand,
173
- parentField,
174
- keyField,
175
- sort: extractSubFields(colNameLower, sortFields),
176
- });
177
- }
178
- }
179
- }
180
- }
181
- _selectColumn(tableAlias, el, prefix, suffix) {
182
- const fieldName = (prefix || '').toLowerCase() +
183
- el.fieldName.toUpperCase() +
184
- (suffix || '').toLowerCase();
185
- const fieldAlias = (tableAlias + '_' + fieldName).substring(0, 30);
186
- this._selectColumns[fieldAlias] = {
187
- field: el,
188
- statement: tableAlias + '.' + fieldName + ' as ' + fieldAlias,
189
- };
190
- return fieldAlias;
191
- }
192
- async filter(filter) {
193
- await (0, command_helper_js_1.prepareFilter)(this.mainEntity, filter, this._filter);
194
- }
195
- async sort(sortFields) {
196
- const out = [];
197
- for (const item of sortFields) {
198
- const m = item.match(SORT_ORDER_PATTERN);
199
- if (!m)
200
- throw new Error(`"${item}" is not a valid order expression`);
201
- let elName = m[2];
202
- let prefix = '';
203
- let suffix = '';
204
- let _entityDef = this.resultEntity;
205
- let tableAlias = this.resultAlias;
206
- if (elName.includes('.')) {
207
- const a = elName.split('.');
208
- while (a.length > 1) {
209
- const col = entity_metadata_js_1.EntityMetadata.getField(_entityDef, a.shift() || '');
210
- if ((0, orm_helper_js_1.isEmbeddedField)(col)) {
211
- _entityDef = await embedded_field_metadata_js_1.EmbeddedFieldMetadata.resolveType(col);
212
- if (col.fieldNamePrefix)
213
- prefix += col.fieldNamePrefix;
214
- if (col.fieldNameSuffix)
215
- suffix = col.fieldNameSuffix + suffix;
216
- }
217
- else if ((0, orm_helper_js_1.isAssociationField)(col)) {
218
- if (col.association.returnsMany()) {
219
- elName = '';
220
- break;
221
- }
222
- const joinInfo = await (0, command_helper_js_1.joinAssociationGetLast)(this._joins, col.association, tableAlias);
223
- tableAlias = joinInfo.joinAlias;
224
- _entityDef = joinInfo.targetEntity;
225
- }
226
- else
227
- throw new Error(`Invalid column (${elName}) declared in sort property`);
228
- }
229
- if (!elName)
230
- continue;
231
- elName = a.shift() || '';
232
- }
233
- const col = entity_metadata_js_1.EntityMetadata.getField(_entityDef, elName);
234
- if (!col)
235
- throw new Error(`Unknown field (${elName}) declared in sort property`);
236
- if (!(0, orm_helper_js_1.isColumnField)(col))
237
- throw new Error(`Can not sort by "${elName}", because it is not a data column`);
238
- const dir = m[1] || '+';
239
- out.push((dir || '') + tableAlias + '.' + prefix + col.fieldName + suffix);
240
- }
241
- this._sort = out;
242
- }
243
- async execute(args) {
244
- // Generate select query
245
- const columnSqls = Object.keys(this._selectColumns).map(x => this._selectColumns[x].statement);
246
- if (!columnSqls.length)
247
- columnSqls.push('1');
248
- const query = (0, builder_1.Select)(...columnSqls).from(this.mainEntity.tableName + ' as ' + this.mainAlias);
249
- if (args.distinct)
250
- query.distinct();
251
- query.where(...this._filter._items);
252
- if (this._sort) {
253
- query.orderBy(...this._sort);
254
- }
255
- if (args.offset)
256
- query.offset(args.offset);
257
- // joins must be added last
258
- if (this._joins) {
259
- for (const j of this._joins) {
260
- query.join(j.join);
261
- }
262
- }
263
- // Execute query
264
- const resp = await args.connection.execute(query, {
265
- params: args?.params,
266
- fetchRows: args?.limit,
267
- objectRows: false,
268
- cursor: false,
269
- prettyPrint: args.prettyPrint,
270
- });
271
- // Create objects
272
- if (resp.rows && resp.fields) {
273
- return this.converter.transform(args.connection, resp.fields, resp.rows, args.onTransformRow);
274
- }
275
- return [];
276
- }
277
- _getEntityFromAlias(tableAlias) {
278
- if (tableAlias === this.mainAlias)
279
- return this.mainEntity;
280
- if (tableAlias === this.resultAlias)
281
- return this.resultEntity;
282
- if (this._joins) {
283
- const join = this._joins.find(j => j.joinAlias === tableAlias);
284
- if (join)
285
- return join.targetEntity;
286
- }
287
- throw new Error(`Unknown table alias "${tableAlias}"`);
288
- }
289
- }
290
- exports.FindCommand = FindCommand;
291
- function extractSubFields(colNameLower, fields) {
292
- if (!(fields && fields.length))
293
- return;
294
- if (fields) {
295
- return fields.reduce((trg, v) => {
296
- if (v.startsWith(colNameLower + '.'))
297
- trg.push(v.substring(colNameLower.length + 1).toLowerCase());
298
- return trg;
299
- }, []);
300
- }
301
- }
@@ -1,190 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RowConverter = void 0;
4
- const builder_1 = require("@sqb/builder");
5
- const isValueProperty = (prop) => prop.fieldAlias && !prop.converter;
6
- const isObjectProperty = (prop) => prop.converter && !prop.findCommand;
7
- const isNestedProperty = (prop) => prop.converter && prop.findCommand;
8
- class RowConverter {
9
- resultType;
10
- parent;
11
- _properties = {};
12
- _propertyKeys;
13
- constructor(resultType, parent) {
14
- this.resultType = resultType;
15
- this.parent = parent;
16
- }
17
- addValueProperty(args) {
18
- this._propertyKeys = undefined;
19
- const item = {
20
- fieldAlias: args.fieldAlias,
21
- dataType: args.dataType,
22
- parse: args.parse,
23
- };
24
- this._properties[args.name] = item;
25
- return item;
26
- }
27
- addObjectProperty(args) {
28
- this._checkCircularDep(args.type);
29
- this._propertyKeys = undefined;
30
- const converter = new RowConverter(args.type, this);
31
- const item = {
32
- converter,
33
- type: args.type,
34
- };
35
- this._properties[args.name] = item;
36
- return item;
37
- }
38
- addNestedProperty(args) {
39
- this._checkCircularDep(args.type);
40
- const converter = new RowConverter(args.type, this);
41
- const item = {
42
- converter,
43
- type: args.type,
44
- parentField: args.parentField,
45
- keyField: args.keyField,
46
- findCommand: args.findCommand,
47
- sort: args.sort,
48
- paramValues: [],
49
- };
50
- this._properties[args.name] = item;
51
- return item;
52
- }
53
- get keys() {
54
- if (!this._propertyKeys)
55
- this._propertyKeys = Object.keys(this._properties);
56
- return this._propertyKeys;
57
- }
58
- async transform(connection, fields, rows, onTransform) {
59
- const rowLen = rows.length;
60
- const result = [];
61
- for (let rowIdx = 0; rowIdx < rowLen; rowIdx++) {
62
- const row = rows[rowIdx];
63
- const o = (await this._rowToObject(connection, fields, row)) || {};
64
- if (onTransform)
65
- onTransform(fields, row, o);
66
- result.push(o);
67
- }
68
- if (!this.keys)
69
- return result;
70
- await this._iterateForNested(this, connection, fields, rows, result);
71
- // Return only non empty objects
72
- return result.filter(x => !!x);
73
- }
74
- _rowToObject(executor, fields, row) {
75
- // Cache keys for better performance
76
- const fieldKeys = this.keys;
77
- const fieldsLen = fieldKeys.length;
78
- let result;
79
- for (let elIdx = 0; elIdx < fieldsLen; elIdx++) {
80
- const elKey = fieldKeys[elIdx];
81
- const prop = this._properties[elKey];
82
- if (isValueProperty(prop)) {
83
- const field = fields.get(prop.fieldAlias);
84
- if (field) {
85
- let v = row[field.index];
86
- if (typeof prop.parse === 'function')
87
- v = prop.parse(v, elKey);
88
- if (v != null) {
89
- result = result || {};
90
- if (prop.dataType === builder_1.DataType.JSON && typeof v === 'string')
91
- v = JSON.parse(v);
92
- result[elKey] = v;
93
- }
94
- }
95
- }
96
- else if (isNestedProperty(prop)) {
97
- // One2Many Eager field
98
- // Keep a list of key field/value pairs to fetch rows for eager relation
99
- const _params = prop.paramValues;
100
- const f = fields.get(prop.parentField);
101
- const v = f && row[f.index];
102
- if (v != null && !_params.includes(v))
103
- _params.push(v);
104
- }
105
- else if (isObjectProperty(prop)) {
106
- const v = prop.converter._rowToObject(executor, fields, row);
107
- if (v != null) {
108
- result = result || {};
109
- result[elKey] = v;
110
- }
111
- }
112
- }
113
- if (result)
114
- Object.setPrototypeOf(result, this.resultType.prototype);
115
- return result;
116
- }
117
- async _iterateForNested(node, connection, fields, rows, result) {
118
- // Fetch one-2-many related rows and merge with result rows
119
- const keys = node.keys;
120
- const propertyLen = keys.length;
121
- const promises = [];
122
- for (let propIdx = 0; propIdx < propertyLen; propIdx++) {
123
- const propKey = keys[propIdx];
124
- const prop = node._properties[propKey];
125
- if (isNestedProperty(prop)) {
126
- if (!(prop.paramValues && prop.paramValues.length))
127
- continue;
128
- const resultType = this.resultType;
129
- const promise = (async function (p) {
130
- const findCommand = p.findCommand;
131
- let fld;
132
- const map = new Map();
133
- const r = await findCommand.execute({
134
- connection,
135
- limit: findCommand.maxEagerFetch + 1,
136
- params: { [p.parentField]: p.paramValues },
137
- onTransformRow: (_fields, row, obj) => {
138
- fld = fld || _fields.get('' + p.keyField);
139
- const keyValue = fld && row[fld.index];
140
- if (keyValue != null) {
141
- const keyValues = Array.isArray(keyValue)
142
- ? keyValue
143
- : [keyValue];
144
- keyValues.forEach(k => {
145
- let arr = map.get(k);
146
- if (!arr) {
147
- arr = [];
148
- map.set(k, arr);
149
- }
150
- arr.push(obj);
151
- });
152
- }
153
- },
154
- });
155
- if (r.length > findCommand.maxEagerFetch) {
156
- throw new Error(`Number of returning rows for "${propKey}" exceeds maxEagerFetch limit`);
157
- }
158
- for (let i = 0; i < result.length; i++) {
159
- const row = rows[i];
160
- let obj = result[i];
161
- if (!obj) {
162
- obj = {};
163
- Object.setPrototypeOf(result, resultType.prototype);
164
- }
165
- const f = fields.get('' + p.parentField);
166
- const keyValue = f && row[f.index];
167
- if (keyValue != null) {
168
- const arr = map.get(keyValue);
169
- if (arr) {
170
- obj[propKey] = arr;
171
- }
172
- }
173
- }
174
- })(prop);
175
- promises.push(promise);
176
- }
177
- else if (isObjectProperty(prop)) {
178
- promises.push(this._iterateForNested(prop.converter, connection, fields, rows, result));
179
- }
180
- }
181
- await Promise.all(promises);
182
- }
183
- _checkCircularDep(t) {
184
- if (this.resultType === t)
185
- throw new Error('Circular fields requested');
186
- if (this.parent)
187
- this.parent._checkCircularDep(t);
188
- }
189
- }
190
- exports.RowConverter = RowConverter;