@sqb/connect 4.11.3 → 4.12.1
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 +9 -24
- package/cjs/client/cursor-stream.js +6 -3
- package/cjs/client/cursor.js +8 -6
- package/cjs/client/field-info-map.js +3 -3
- package/cjs/client/sqb-client.js +2 -3
- package/cjs/client/sqb-connection.js +14 -13
- package/cjs/index.js +1 -0
- package/cjs/orm/commands/command.helper.js +8 -9
- package/cjs/orm/commands/create.command.js +4 -5
- package/cjs/orm/commands/find.command.js +30 -57
- package/cjs/orm/commands/row-converter.js +6 -6
- package/cjs/orm/commands/update.command.js +3 -4
- package/cjs/orm/decorators/column.decorator.js +7 -3
- package/cjs/orm/decorators/embedded.decorator.js +1 -1
- package/cjs/orm/decorators/entity.decorator.js +2 -2
- package/cjs/orm/decorators/link.decorator.js +1 -1
- package/cjs/orm/decorators/transform.decorator.js +2 -4
- package/cjs/orm/model/association-field-metadata.js +1 -1
- package/cjs/orm/model/association.js +2 -4
- package/cjs/orm/model/column-field-metadata.js +1 -1
- package/cjs/orm/model/embedded-field-metadata.js +1 -1
- package/cjs/orm/model/entity-metadata.js +7 -7
- package/cjs/orm/model/link-chain.js +2 -2
- package/cjs/orm/orm.const.js +2 -1
- package/cjs/orm/repository.class.js +29 -15
- package/cjs/orm/util/apply-mixins.js +6 -4
- package/cjs/orm/util/extract-keyvalues.js +1 -1
- package/cjs/orm/util/parse-fields-projection.js +66 -0
- package/cjs/orm/util/serialize-field.js +10 -10
- package/esm/client/cursor-stream.js +6 -3
- package/esm/client/cursor.js +8 -6
- package/esm/client/field-info-map.js +3 -3
- package/esm/client/helpers.js +1 -1
- package/esm/client/sqb-client.js +2 -3
- package/esm/client/sqb-connection.js +15 -14
- package/esm/index.js +1 -0
- package/esm/orm/commands/command.helper.js +9 -10
- package/esm/orm/commands/create.command.js +4 -5
- package/esm/orm/commands/find.command.js +30 -57
- package/esm/orm/commands/row-converter.js +6 -6
- package/esm/orm/commands/update.command.js +3 -4
- package/esm/orm/decorators/column.decorator.js +6 -2
- package/esm/orm/decorators/embedded.decorator.js +1 -1
- package/esm/orm/decorators/entity.decorator.js +2 -2
- package/esm/orm/decorators/link.decorator.js +1 -1
- package/esm/orm/decorators/transform.decorator.js +2 -4
- package/esm/orm/model/association-field-metadata.js +1 -1
- package/esm/orm/model/association.js +2 -4
- package/esm/orm/model/column-field-metadata.js +1 -1
- package/esm/orm/model/embedded-field-metadata.js +1 -1
- package/esm/orm/model/entity-metadata.js +7 -7
- package/esm/orm/model/link-chain.js +2 -2
- package/esm/orm/orm.const.js +1 -0
- package/esm/orm/repository.class.js +29 -15
- package/esm/orm/util/apply-mixins.js +6 -4
- package/esm/orm/util/extract-keyvalues.js +1 -1
- package/esm/orm/util/parse-fields-projection.js +61 -0
- package/esm/orm/util/serialize-field.js +10 -10
- package/package.json +10 -6
- package/types/index.d.ts +1 -0
- package/types/orm/commands/find.command.d.ts +2 -3
- package/types/orm/decorators/column.decorator.d.ts +1 -0
- package/types/orm/decorators/entity.decorator.d.ts +2 -2
- package/types/orm/model/field-metadata.d.ts +1 -1
- package/types/orm/orm.const.d.ts +1 -0
- package/types/orm/orm.type.d.ts +1 -1
- package/types/orm/repository.class.d.ts +11 -8
- package/types/orm/util/parse-fields-projection.d.ts +10 -0
package/README.md
CHANGED
|
@@ -18,12 +18,12 @@ SQB is an extensible, multi-dialect SQL query builder and Database connection wr
|
|
|
18
18
|
|
|
19
19
|
## Main goals
|
|
20
20
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
21
|
+
- Single code base for any sql based database
|
|
22
|
+
- Powerful and simplified query coding scheme
|
|
23
|
+
- Fast applications with low memory requirements
|
|
24
|
+
- Let applications work with large data tables efficiently
|
|
25
|
+
- Support latest JavaScript language standards
|
|
26
|
+
- Lightweight and extensible framework.
|
|
27
27
|
|
|
28
28
|
You can report bugs and discuss features on the [GitHub issues](https://github.com/sqbjs/sqb/issues) page
|
|
29
29
|
|
|
@@ -39,40 +39,25 @@ $ npm install @sqb/connect --save
|
|
|
39
39
|
|
|
40
40
|
## Node Compatibility
|
|
41
41
|
|
|
42
|
-
-
|
|
42
|
+
- node >= 16.x
|
|
43
43
|
|
|
44
44
|
### License
|
|
45
45
|
|
|
46
46
|
SQB is available under [MIT](LICENSE) license.
|
|
47
47
|
|
|
48
48
|
[npm-image]: https://img.shields.io/npm/v/@sqb/connect.svg
|
|
49
|
-
|
|
50
49
|
[npm-url]: https://npmjs.org/package/@sqb/connect
|
|
51
|
-
|
|
52
50
|
[travis-image]: https://img.shields.io/travis/sqbjs/@sqb/connect/master.svg
|
|
53
|
-
|
|
54
51
|
[travis-url]: https://travis-ci.org/sqbjs/@sqb/connect
|
|
55
|
-
|
|
56
52
|
[coveralls-image]: https://img.shields.io/coveralls/sqbjs/@sqb/connect/master.svg
|
|
57
|
-
|
|
58
53
|
[coveralls-url]: https://coveralls.io/r/sqbjs/@sqb/connect
|
|
59
|
-
|
|
60
54
|
[downloads-image]: https://img.shields.io/npm/dm/@sqb/connect.svg
|
|
61
|
-
|
|
62
55
|
[downloads-url]: https://npmjs.org/package/@sqb/connect
|
|
63
|
-
|
|
64
56
|
[gitter-image]: https://badges.gitter.im/sqbjs/@sqb/connect.svg
|
|
65
|
-
|
|
66
57
|
[gitter-url]: https://gitter.im/sqbjs/@sqb/connect?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
|
67
|
-
|
|
68
58
|
[dependencies-image]: https://david-dm.org/sqbjs/@sqb/connect/status.svg
|
|
69
|
-
|
|
70
|
-
[dependencies-url]:https://david-dm.org/sqbjs/@sqb/connect
|
|
71
|
-
|
|
59
|
+
[dependencies-url]: https://david-dm.org/sqbjs/@sqb/connect
|
|
72
60
|
[devdependencies-image]: https://david-dm.org/sqbjs/@sqb/connect/dev-status.svg
|
|
73
|
-
|
|
74
|
-
[devdependencies-url]:https://david-dm.org/sqbjs/@sqb/connect?type=dev
|
|
75
|
-
|
|
61
|
+
[devdependencies-url]: https://david-dm.org/sqbjs/@sqb/connect?type=dev
|
|
76
62
|
[quality-image]: http://npm.packagequality.com/shield/@sqb/connect.png
|
|
77
|
-
|
|
78
63
|
[quality-url]: http://packagequality.com/#?package=@sqb/connect
|
|
@@ -18,7 +18,7 @@ class CursorStream extends stream_1.Readable {
|
|
|
18
18
|
this.close().catch(() => false);
|
|
19
19
|
});
|
|
20
20
|
cursor.once('close', () => this.emit('close'));
|
|
21
|
-
cursor.on('error',
|
|
21
|
+
cursor.on('error', err => this.emit('error', err));
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Returns if stream is closed.
|
|
@@ -47,7 +47,9 @@ class CursorStream extends stream_1.Readable {
|
|
|
47
47
|
this.emit('end');
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
|
-
this._cursor
|
|
50
|
+
this._cursor
|
|
51
|
+
.next()
|
|
52
|
+
.then(row => {
|
|
51
53
|
if (this._eof)
|
|
52
54
|
return this.push(null);
|
|
53
55
|
let buf = '';
|
|
@@ -74,7 +76,8 @@ class CursorStream extends stream_1.Readable {
|
|
|
74
76
|
buf += ',';
|
|
75
77
|
this.push(buf + JSON.stringify(row));
|
|
76
78
|
}
|
|
77
|
-
})
|
|
79
|
+
})
|
|
80
|
+
.catch(err => {
|
|
78
81
|
/* istanbul ignore next */
|
|
79
82
|
if (typeof this.destroy == 'function')
|
|
80
83
|
this.destroy(err);
|
package/cjs/client/cursor.js
CHANGED
|
@@ -179,7 +179,8 @@ class Cursor extends (0, strict_typed_events_1.TypedEventEmitterClass)(strict_ty
|
|
|
179
179
|
if (step < 0 && !this._cache)
|
|
180
180
|
throw new Error('To move cursor back, it needs cache to be enabled');
|
|
181
181
|
const _this = this;
|
|
182
|
-
await this._taskQueue
|
|
182
|
+
await this._taskQueue
|
|
183
|
+
.enqueue(async function () {
|
|
183
184
|
/* If moving backward */
|
|
184
185
|
if (step < 0) {
|
|
185
186
|
/* Seek cache */
|
|
@@ -212,7 +213,8 @@ class Cursor extends (0, strict_typed_events_1.TypedEventEmitterClass)(strict_ty
|
|
|
212
213
|
return;
|
|
213
214
|
await _this._fetchRows();
|
|
214
215
|
}
|
|
215
|
-
})
|
|
216
|
+
})
|
|
217
|
+
.toPromise();
|
|
216
218
|
if (!silent)
|
|
217
219
|
this.emit('move', this.row, this._rowNum);
|
|
218
220
|
return this._rowNum;
|
|
@@ -227,12 +229,12 @@ class Cursor extends (0, strict_typed_events_1.TypedEventEmitterClass)(strict_ty
|
|
|
227
229
|
if (rows && rows.length) {
|
|
228
230
|
debug('Fetched %d rows from database', rows.length);
|
|
229
231
|
// Normalize rows
|
|
230
|
-
rows = this._request.objectRows
|
|
231
|
-
(0, helpers_js_1.normalizeRowsToObjectRows)(this._fields, this._intlcur.rowType, rows, this._request)
|
|
232
|
-
(0, helpers_js_1.normalizeRowsToArrayRows)(this._fields, this._intlcur.rowType, rows, this._request);
|
|
232
|
+
rows = this._request.objectRows
|
|
233
|
+
? (0, helpers_js_1.normalizeRowsToObjectRows)(this._fields, this._intlcur.rowType, rows, this._request)
|
|
234
|
+
: (0, helpers_js_1.normalizeRowsToArrayRows)(this._fields, this._intlcur.rowType, rows, this._request);
|
|
233
235
|
(0, helpers_js_1.callFetchHooks)(rows, this._request);
|
|
234
236
|
for (const [idx, row] of rows.entries()) {
|
|
235
|
-
this.emit('fetch', row,
|
|
237
|
+
this.emit('fetch', row, this._rowNum + idx + 1);
|
|
236
238
|
}
|
|
237
239
|
/* Add rows to cache */
|
|
238
240
|
if (this._cache) {
|
|
@@ -7,13 +7,13 @@ class FieldInfoMap {
|
|
|
7
7
|
enumerable: false,
|
|
8
8
|
configurable: false,
|
|
9
9
|
writable: true,
|
|
10
|
-
value: {}
|
|
10
|
+
value: {},
|
|
11
11
|
});
|
|
12
12
|
Object.defineProperty(this, '_arr', {
|
|
13
13
|
enumerable: false,
|
|
14
14
|
configurable: false,
|
|
15
15
|
writable: true,
|
|
16
|
-
value: []
|
|
16
|
+
value: [],
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
19
|
add(field) {
|
|
@@ -28,7 +28,7 @@ class FieldInfoMap {
|
|
|
28
28
|
enumerable: false,
|
|
29
29
|
configurable: false,
|
|
30
30
|
writable: true,
|
|
31
|
-
value: _obj
|
|
31
|
+
value: _obj,
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
get(k) {
|
package/cjs/client/sqb-client.js
CHANGED
|
@@ -50,7 +50,7 @@ class SqbClient extends (0, strict_typed_events_1.TypedEventEmitterClass)(strict
|
|
|
50
50
|
create: () => adapter.connect(cfg),
|
|
51
51
|
destroy: instance => instance.close(),
|
|
52
52
|
reset: async (instance) => instance.reset(),
|
|
53
|
-
validate: instance => instance.test()
|
|
53
|
+
validate: instance => instance.test(),
|
|
54
54
|
};
|
|
55
55
|
this._pool = (0, lightning_pool_1.createPool)(poolFactory, poolOptions);
|
|
56
56
|
this._pool.on('closing', () => this.emit('closing'));
|
|
@@ -159,8 +159,7 @@ class SqbClient extends (0, strict_typed_events_1.TypedEventEmitterClass)(strict
|
|
|
159
159
|
return this._entities[name];
|
|
160
160
|
}
|
|
161
161
|
toString() {
|
|
162
|
-
return '[object ' + Object.getPrototypeOf(this).constructor.name + '(' +
|
|
163
|
-
this.dialect + ')]';
|
|
162
|
+
return '[object ' + Object.getPrototypeOf(this).constructor.name + '(' + this.dialect + ')]';
|
|
164
163
|
}
|
|
165
164
|
[inspect]() {
|
|
166
165
|
return this.toString();
|
|
@@ -78,7 +78,7 @@ class SqbConnection extends (0, strict_typed_events_1.TypedEventEmitterClass)(st
|
|
|
78
78
|
await this.emitAsyncSerial('close');
|
|
79
79
|
const intlcon = this._intlcon;
|
|
80
80
|
this._intlcon = undefined;
|
|
81
|
-
this.client.pool.release(intlcon,
|
|
81
|
+
this.client.pool.release(intlcon, e => {
|
|
82
82
|
if (e)
|
|
83
83
|
this.client.emit('error', e);
|
|
84
84
|
});
|
|
@@ -135,7 +135,7 @@ class SqbConnection extends (0, strict_typed_events_1.TypedEventEmitterClass)(st
|
|
|
135
135
|
if (!response)
|
|
136
136
|
throw new Error('Database adapter returned an empty response');
|
|
137
137
|
const result = {
|
|
138
|
-
executeTime: Date.now() - startTime
|
|
138
|
+
executeTime: Date.now() - startTime,
|
|
139
139
|
};
|
|
140
140
|
if (request.showSql)
|
|
141
141
|
result.query = request;
|
|
@@ -147,13 +147,13 @@ class SqbConnection extends (0, strict_typed_events_1.TypedEventEmitterClass)(st
|
|
|
147
147
|
result.fields = (0, helpers_js_1.wrapAdapterFields)(response.fields, request.fieldNaming);
|
|
148
148
|
result.rowType = response.rowType;
|
|
149
149
|
if (response.rows) {
|
|
150
|
-
result.rows = request.objectRows
|
|
151
|
-
(0, helpers_js_1.normalizeRowsToObjectRows)(result.fields, response.rowType, response.rows, request)
|
|
152
|
-
(0, helpers_js_1.normalizeRowsToArrayRows)(result.fields, response.rowType, response.rows, request);
|
|
150
|
+
result.rows = request.objectRows
|
|
151
|
+
? (0, helpers_js_1.normalizeRowsToObjectRows)(result.fields, response.rowType, response.rows, request)
|
|
152
|
+
: (0, helpers_js_1.normalizeRowsToArrayRows)(result.fields, response.rowType, response.rows, request);
|
|
153
153
|
(0, helpers_js_1.callFetchHooks)(result.rows, request);
|
|
154
154
|
}
|
|
155
155
|
else if (response.cursor) {
|
|
156
|
-
const cursor = result.cursor = new cursor_js_1.Cursor(this, result.fields, response.cursor, request);
|
|
156
|
+
const cursor = (result.cursor = new cursor_js_1.Cursor(this, result.fields, response.cursor, request));
|
|
157
157
|
const hook = () => cursor.close();
|
|
158
158
|
cursor.once('close', () => this.off('close', hook));
|
|
159
159
|
this.on('close', hook);
|
|
@@ -226,8 +226,9 @@ class SqbConnection extends (0, strict_typed_events_1.TypedEventEmitterClass)(st
|
|
|
226
226
|
const request = {
|
|
227
227
|
dialect: this.client.dialect,
|
|
228
228
|
sql: '',
|
|
229
|
-
autoCommit: this.inTransaction
|
|
230
|
-
|
|
229
|
+
autoCommit: this.inTransaction
|
|
230
|
+
? false
|
|
231
|
+
: (0, putil_varhelpers_1.coerceToBoolean)((0, putil_varhelpers_1.coalesce)(options.autoCommit, this._options?.autoCommit, defaults.autoCommit), true),
|
|
231
232
|
cursor: (0, putil_varhelpers_1.coerceToBoolean)((0, putil_varhelpers_1.coalesce)(options.cursor, defaults.cursor), false),
|
|
232
233
|
objectRows: (0, putil_varhelpers_1.coerceToBoolean)((0, putil_varhelpers_1.coalesce)(options.objectRows, defaults.objectRows), true),
|
|
233
234
|
ignoreNulls: (0, putil_varhelpers_1.coerceToBoolean)((0, putil_varhelpers_1.coalesce)(options.ignoreNulls, defaults.ignoreNulls), false),
|
|
@@ -237,19 +238,18 @@ class SqbConnection extends (0, strict_typed_events_1.TypedEventEmitterClass)(st
|
|
|
237
238
|
showSql: (0, putil_varhelpers_1.coerceToBoolean)((0, putil_varhelpers_1.coalesce)(options.showSql, defaults.showSql), false),
|
|
238
239
|
prettyPrint: (0, putil_varhelpers_1.coerceToBoolean)((0, putil_varhelpers_1.coalesce)(options.prettyPrint, defaults.prettyPrint), false),
|
|
239
240
|
action: (0, putil_varhelpers_1.coerceToString)(options.action),
|
|
240
|
-
fetchAsString: options.fetchAsString
|
|
241
|
+
fetchAsString: options.fetchAsString,
|
|
241
242
|
};
|
|
242
243
|
request.ignoreNulls = request.ignoreNulls && request.objectRows;
|
|
243
244
|
if (query instanceof builder_1.classes.Query) {
|
|
244
245
|
if (this._intlcon.onGenerateQuery)
|
|
245
246
|
this._intlcon.onGenerateQuery(request, query);
|
|
246
|
-
const q = query
|
|
247
|
-
.generate({
|
|
247
|
+
const q = query.generate({
|
|
248
248
|
dialect: request.dialect,
|
|
249
249
|
dialectVersion: request.dialectVersion,
|
|
250
250
|
params: options.params,
|
|
251
251
|
strictParams: true,
|
|
252
|
-
prettyPrint: request.prettyPrint
|
|
252
|
+
prettyPrint: request.prettyPrint,
|
|
253
253
|
});
|
|
254
254
|
request.sql = q.sql;
|
|
255
255
|
request.params = q.params;
|
|
@@ -261,7 +261,8 @@ class SqbConnection extends (0, strict_typed_events_1.TypedEventEmitterClass)(st
|
|
|
261
261
|
if (query.listenerCount('fetch'))
|
|
262
262
|
request.fetchHooks = query.listeners('fetch');
|
|
263
263
|
}
|
|
264
|
-
else {
|
|
264
|
+
else {
|
|
265
|
+
// noinspection SuspiciousTypeOfGuard
|
|
265
266
|
if (typeof query === 'string') {
|
|
266
267
|
request.sql = query;
|
|
267
268
|
request.params = options.params;
|
package/cjs/index.js
CHANGED
|
@@ -38,4 +38,5 @@ Object.defineProperty(exports, "isColumnField", { enumerable: true, get: functio
|
|
|
38
38
|
Object.defineProperty(exports, "isEmbeddedField", { enumerable: true, get: function () { return orm_helper_js_1.isEmbeddedField; } });
|
|
39
39
|
Object.defineProperty(exports, "isAssociationField", { enumerable: true, get: function () { return orm_helper_js_1.isAssociationField; } });
|
|
40
40
|
Object.defineProperty(exports, "isEntityClass", { enumerable: true, get: function () { return orm_helper_js_1.isEntityClass; } });
|
|
41
|
+
tslib_1.__exportStar(require("./orm/util/parse-fields-projection.js"), exports);
|
|
41
42
|
tslib_1.__exportStar(require("./orm/backward.js"), exports);
|
|
@@ -27,8 +27,9 @@ async function joinAssociation(joinInfos, association, parentAlias, innerJoin) {
|
|
|
27
27
|
const keyCol = await node.resolveSourceProperty();
|
|
28
28
|
const targetCol = await node.resolveTargetProperty();
|
|
29
29
|
const joinAlias = 'J' + (joinInfos.length + 1);
|
|
30
|
-
const join = innerJoin
|
|
31
|
-
(0, builder_1.
|
|
30
|
+
const join = innerJoin
|
|
31
|
+
? (0, builder_1.InnerJoin)(targetEntity.tableName + ' as ' + joinAlias)
|
|
32
|
+
: (0, builder_1.LeftOuterJoin)(targetEntity.tableName + ' as ' + joinAlias);
|
|
32
33
|
join.on((0, builder_1.Eq)((0, builder_1.Field)(joinAlias + '.' + targetCol.fieldName, targetCol.dataType, targetCol.isArray), (0, builder_1.Field)(parentAlias + '.' + keyCol.fieldName, keyCol.dataType, keyCol.isArray)));
|
|
33
34
|
if (node.conditions)
|
|
34
35
|
await prepareFilter(targetEntity, node.conditions, join._conditions, joinAlias);
|
|
@@ -37,7 +38,7 @@ async function joinAssociation(joinInfos, association, parentAlias, innerJoin) {
|
|
|
37
38
|
sourceEntity,
|
|
38
39
|
targetEntity,
|
|
39
40
|
joinAlias,
|
|
40
|
-
join
|
|
41
|
+
join,
|
|
41
42
|
};
|
|
42
43
|
joinInfos.push(joinInfo);
|
|
43
44
|
}
|
|
@@ -52,7 +53,7 @@ async function joinAssociation(joinInfos, association, parentAlias, innerJoin) {
|
|
|
52
53
|
exports.joinAssociation = joinAssociation;
|
|
53
54
|
async function prepareFilter(entityDef, filter, trgOp, tableAlias = 'T') {
|
|
54
55
|
let srcOp;
|
|
55
|
-
if ((0, builder_1.isLogicalOperator)(filter))
|
|
56
|
+
if ((0, builder_1.isLogicalOperator)(filter) && filter._operatorType === trgOp._operatorType)
|
|
56
57
|
srcOp = filter;
|
|
57
58
|
else {
|
|
58
59
|
srcOp = (0, builder_1.And)();
|
|
@@ -107,8 +108,7 @@ async function prepareFilter(entityDef, filter, trgOp, tableAlias = 'T') {
|
|
|
107
108
|
if (!subSelect) {
|
|
108
109
|
const keyCol = await col.association.resolveSourceProperty();
|
|
109
110
|
const targetCol = await col.association.resolveTargetProperty();
|
|
110
|
-
subSelect = (0, builder_1.Select)((0, builder_1.Raw)('1'))
|
|
111
|
-
.from(_curEntity.tableName + ' K');
|
|
111
|
+
subSelect = (0, builder_1.Select)((0, builder_1.Raw)('1')).from(_curEntity.tableName + ' K');
|
|
112
112
|
subSelect.where((0, builder_1.Eq)((0, builder_1.Field)('K.' + targetCol.fieldName, targetCol.dataType, targetCol.isArray), (0, builder_1.Field)(tableAlias + '.' + keyCol.fieldName, keyCol.dataType, keyCol.isArray)));
|
|
113
113
|
trgOp.add((0, builder_1.Exists)(subSelect));
|
|
114
114
|
trgOp = subSelect._where;
|
|
@@ -124,9 +124,8 @@ async function prepareFilter(entityDef, filter, trgOp, tableAlias = 'T') {
|
|
|
124
124
|
const targetEntity = await node.resolveTarget();
|
|
125
125
|
const sourceColumn = await node.resolveSourceProperty();
|
|
126
126
|
const targetColumn = await node.resolveTargetProperty();
|
|
127
|
-
const joinAlias = 'J' + ((
|
|
128
|
-
subSelect.join((0, builder_1.InnerJoin)(targetEntity.tableName + ' ' + joinAlias)
|
|
129
|
-
.on((0, builder_1.Eq)((0, builder_1.Field)(joinAlias + '.' + targetColumn.fieldName, targetColumn.dataType, targetColumn.isArray), (0, builder_1.Field)(_curAlias + '.' + sourceColumn.fieldName, sourceColumn.dataType, sourceColumn.isArray))));
|
|
127
|
+
const joinAlias = 'J' + ((subSelect?._joins?.length || 0) + 1);
|
|
128
|
+
subSelect.join((0, builder_1.InnerJoin)(targetEntity.tableName + ' ' + joinAlias).on((0, builder_1.Eq)((0, builder_1.Field)(joinAlias + '.' + targetColumn.fieldName, targetColumn.dataType, targetColumn.isArray), (0, builder_1.Field)(_curAlias + '.' + sourceColumn.fieldName, sourceColumn.dataType, sourceColumn.isArray))));
|
|
130
129
|
_curEntity = targetEntity;
|
|
131
130
|
_curAlias = joinAlias;
|
|
132
131
|
node = node.next;
|
|
@@ -21,7 +21,7 @@ class CreateCommand {
|
|
|
21
21
|
entity,
|
|
22
22
|
queryParams: {},
|
|
23
23
|
queryValues: {},
|
|
24
|
-
colCount: 0
|
|
24
|
+
colCount: 0,
|
|
25
25
|
};
|
|
26
26
|
// Prepare
|
|
27
27
|
await this._prepareParams(ctx, entity, args.values);
|
|
@@ -36,7 +36,7 @@ class CreateCommand {
|
|
|
36
36
|
const qr = await args.connection.execute(query, {
|
|
37
37
|
params: ctx.queryParams,
|
|
38
38
|
objectRows: false,
|
|
39
|
-
cursor: false
|
|
39
|
+
cursor: false,
|
|
40
40
|
});
|
|
41
41
|
if (args.returning && qr.fields && qr.rows?.length) {
|
|
42
42
|
const keyValues = {};
|
|
@@ -58,8 +58,7 @@ class CreateCommand {
|
|
|
58
58
|
if (col.noInsert)
|
|
59
59
|
continue;
|
|
60
60
|
if (v == null && col.default !== undefined) {
|
|
61
|
-
v = typeof col.default === 'function' ?
|
|
62
|
-
col.default(values) : col.default;
|
|
61
|
+
v = typeof col.default === 'function' ? col.default(values) : col.default;
|
|
63
62
|
}
|
|
64
63
|
if (typeof col.serialize === 'function')
|
|
65
64
|
v = col.serialize(v, col.name);
|
|
@@ -74,7 +73,7 @@ class CreateCommand {
|
|
|
74
73
|
ctx.queryValues[fieldName] = (0, builder_1.Param)({
|
|
75
74
|
name: k,
|
|
76
75
|
dataType: col.dataType,
|
|
77
|
-
isArray: col.isArray
|
|
76
|
+
isArray: col.isArray,
|
|
78
77
|
});
|
|
79
78
|
ctx.queryParams[k] = v;
|
|
80
79
|
ctx.colCount++;
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FindCommand = void 0;
|
|
4
4
|
const builder_1 = require("@sqb/builder");
|
|
5
|
-
const entity_decorator_js_1 = require("../decorators/entity.decorator.js");
|
|
6
5
|
const association_node_js_1 = require("../model/association-node.js");
|
|
7
6
|
const embedded_field_metadata_js_1 = require("../model/embedded-field-metadata.js");
|
|
8
7
|
const entity_metadata_js_1 = require("../model/entity-metadata.js");
|
|
9
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
10
|
const command_helper_js_1 = require("./command.helper.js");
|
|
11
11
|
const row_converter_js_1 = require("./row-converter.js");
|
|
12
12
|
const SORT_ORDER_PATTERN = /^([-+])?(.*)$/;
|
|
@@ -56,10 +56,8 @@ class FindCommand {
|
|
|
56
56
|
maxEagerFetch: args.maxEagerFetch,
|
|
57
57
|
});
|
|
58
58
|
await command.addFields({
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
omit: args.omit,
|
|
62
|
-
sort: args.sort
|
|
59
|
+
projection: args.projection,
|
|
60
|
+
sort: args.sort,
|
|
63
61
|
});
|
|
64
62
|
if (args.filter)
|
|
65
63
|
await command.filter(args.filter);
|
|
@@ -71,27 +69,11 @@ class FindCommand {
|
|
|
71
69
|
const tableAlias = opts.tableAlias || this.resultAlias;
|
|
72
70
|
const entity = opts.entity || this._getEntityFromAlias(tableAlias);
|
|
73
71
|
const converter = opts.converter || this.converter;
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
opts.include.map(x => x.toLowerCase()) : undefined;
|
|
80
|
-
let requestedFields;
|
|
81
|
-
if (_pick)
|
|
82
|
-
requestedFields = [..._pick];
|
|
83
|
-
else {
|
|
84
|
-
requestedFields = entity_decorator_js_1.Entity.getFieldNames(entity.ctor).reduce((a, x) => {
|
|
85
|
-
const f = entity_decorator_js_1.Entity.getField(entity.ctor, x);
|
|
86
|
-
if (f && !f.exclusive)
|
|
87
|
-
a.push(x.toLowerCase());
|
|
88
|
-
return a;
|
|
89
|
-
}, []);
|
|
90
|
-
}
|
|
91
|
-
if (_include)
|
|
92
|
-
requestedFields.push(..._include);
|
|
93
|
-
const sortFields = opts.sort && opts.sort.length ?
|
|
94
|
-
opts.sort.map(x => x.toLowerCase()) : undefined;
|
|
72
|
+
const projection = typeof opts.projection === 'string' || Array.isArray(opts.projection)
|
|
73
|
+
? (0, parse_fields_projection_js_1.parseFieldsProjection)(opts.projection)
|
|
74
|
+
: opts.projection;
|
|
75
|
+
const defaultFields = !projection || !Object.values(projection).find(p => !p.sign);
|
|
76
|
+
const sortFields = opts.sort && opts.sort.length ? opts.sort.map(x => x.toLowerCase()) : undefined;
|
|
95
77
|
const prefix = opts.prefix || '';
|
|
96
78
|
const suffix = opts.suffix || '';
|
|
97
79
|
for (const key of Object.keys(entity.fields)) {
|
|
@@ -99,12 +81,16 @@ class FindCommand {
|
|
|
99
81
|
if (!col || col.hidden)
|
|
100
82
|
continue;
|
|
101
83
|
const colNameLower = col.name.toLowerCase();
|
|
102
|
-
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
84
|
+
const p = projection?.[colNameLower];
|
|
85
|
+
if (
|
|
86
|
+
/** Ignore if field is omitted */
|
|
87
|
+
p?.sign === '-' ||
|
|
88
|
+
/** Ignore if default fields and field is not in projection */
|
|
89
|
+
(!defaultFields && !p) ||
|
|
90
|
+
/** Ignore if default fields enabled and fields is exclusive */
|
|
91
|
+
(defaultFields && col.exclusive && !p)) {
|
|
107
92
|
continue;
|
|
93
|
+
}
|
|
108
94
|
// Add field to select list if field is a column
|
|
109
95
|
if ((0, orm_helper_js_1.isColumnField)(col)) {
|
|
110
96
|
const fieldAlias = this._selectColumn(tableAlias, col, prefix, suffix);
|
|
@@ -113,7 +99,7 @@ class FindCommand {
|
|
|
113
99
|
name: col.name,
|
|
114
100
|
fieldAlias,
|
|
115
101
|
dataType: col.dataType,
|
|
116
|
-
parse: col.parse
|
|
102
|
+
parse: col.parse,
|
|
117
103
|
});
|
|
118
104
|
continue;
|
|
119
105
|
}
|
|
@@ -121,7 +107,7 @@ class FindCommand {
|
|
|
121
107
|
const typ = await embedded_field_metadata_js_1.EmbeddedFieldMetadata.resolveType(col);
|
|
122
108
|
const subConverter = converter.addObjectProperty({
|
|
123
109
|
name: col.name,
|
|
124
|
-
type: typ.ctor
|
|
110
|
+
type: typ.ctor,
|
|
125
111
|
}).converter;
|
|
126
112
|
await this.addFields({
|
|
127
113
|
tableAlias,
|
|
@@ -129,10 +115,7 @@ class FindCommand {
|
|
|
129
115
|
entity: typ,
|
|
130
116
|
prefix: col.fieldNamePrefix,
|
|
131
117
|
suffix: col.fieldNameSuffix,
|
|
132
|
-
|
|
133
|
-
extractSubFields(colNameLower, _pick),
|
|
134
|
-
include: extractSubFields(colNameLower, _include),
|
|
135
|
-
omit: extractSubFields(colNameLower, _omit),
|
|
118
|
+
projection: p?.projection,
|
|
136
119
|
sort: extractSubFields(colNameLower, sortFields),
|
|
137
120
|
});
|
|
138
121
|
continue;
|
|
@@ -143,17 +126,14 @@ class FindCommand {
|
|
|
143
126
|
const joinInfo = await (0, command_helper_js_1.joinAssociationGetLast)(this._joins, col.association, tableAlias);
|
|
144
127
|
const subConverter = converter.addObjectProperty({
|
|
145
128
|
name: col.name,
|
|
146
|
-
type: joinInfo.targetEntity.ctor
|
|
129
|
+
type: joinInfo.targetEntity.ctor,
|
|
147
130
|
}).converter;
|
|
148
131
|
// Add join fields to select columns list
|
|
149
132
|
await this.addFields({
|
|
150
133
|
tableAlias: joinInfo.joinAlias,
|
|
151
134
|
converter: subConverter,
|
|
152
135
|
entity: joinInfo.targetEntity,
|
|
153
|
-
|
|
154
|
-
extractSubFields(colNameLower, _pick),
|
|
155
|
-
include: extractSubFields(colNameLower, _include),
|
|
156
|
-
omit: extractSubFields(colNameLower, _omit),
|
|
136
|
+
projection: p?.projection,
|
|
157
137
|
sort: extractSubFields(colNameLower, sortFields),
|
|
158
138
|
});
|
|
159
139
|
continue;
|
|
@@ -167,16 +147,13 @@ class FindCommand {
|
|
|
167
147
|
const parentField = this._selectColumn(tableAlias, sourceCol);
|
|
168
148
|
const findCommand = await FindCommand.create(col.association, {
|
|
169
149
|
maxSubQueries: this.maxSubQueries - 1,
|
|
170
|
-
maxEagerFetch: this.maxEagerFetch
|
|
150
|
+
maxEagerFetch: this.maxEagerFetch,
|
|
171
151
|
});
|
|
172
152
|
findCommand.converter.parent = this.converter;
|
|
173
153
|
await findCommand.filter((0, builder_1.In)(targetCol.name, (0, builder_1.Param)(parentField)));
|
|
174
154
|
const sort = sortFields && extractSubFields(colNameLower, sortFields);
|
|
175
155
|
await findCommand.addFields({
|
|
176
|
-
|
|
177
|
-
extractSubFields(colNameLower, _pick),
|
|
178
|
-
include: extractSubFields(colNameLower, _include),
|
|
179
|
-
omit: extractSubFields(colNameLower, _omit),
|
|
156
|
+
projection: p?.projection,
|
|
180
157
|
sort,
|
|
181
158
|
});
|
|
182
159
|
if (sort)
|
|
@@ -189,20 +166,18 @@ class FindCommand {
|
|
|
189
166
|
findCommand,
|
|
190
167
|
parentField,
|
|
191
168
|
keyField,
|
|
192
|
-
sort: extractSubFields(colNameLower, sortFields)
|
|
169
|
+
sort: extractSubFields(colNameLower, sortFields),
|
|
193
170
|
});
|
|
194
171
|
}
|
|
195
172
|
}
|
|
196
173
|
}
|
|
197
174
|
}
|
|
198
175
|
_selectColumn(tableAlias, el, prefix, suffix) {
|
|
199
|
-
const fieldName = (prefix || '').toLowerCase() +
|
|
200
|
-
el.fieldName.toUpperCase() +
|
|
201
|
-
(suffix || '').toLowerCase();
|
|
176
|
+
const fieldName = (prefix || '').toLowerCase() + el.fieldName.toUpperCase() + (suffix || '').toLowerCase();
|
|
202
177
|
const fieldAlias = (tableAlias + '_' + fieldName).substring(0, 30);
|
|
203
178
|
this._selectColumns[fieldAlias] = {
|
|
204
179
|
field: el,
|
|
205
|
-
statement: tableAlias + '.' + fieldName + ' as ' + fieldAlias
|
|
180
|
+
statement: tableAlias + '.' + fieldName + ' as ' + fieldAlias,
|
|
206
181
|
};
|
|
207
182
|
return fieldAlias;
|
|
208
183
|
}
|
|
@@ -259,12 +234,10 @@ class FindCommand {
|
|
|
259
234
|
}
|
|
260
235
|
async execute(args) {
|
|
261
236
|
// Generate select query
|
|
262
|
-
const columnSqls = Object.keys(this._selectColumns)
|
|
263
|
-
.map(x => this._selectColumns[x].statement);
|
|
237
|
+
const columnSqls = Object.keys(this._selectColumns).map(x => this._selectColumns[x].statement);
|
|
264
238
|
if (!columnSqls.length)
|
|
265
239
|
columnSqls.push('1');
|
|
266
|
-
const query = (0, builder_1.Select)(...columnSqls)
|
|
267
|
-
.from(this.mainEntity.tableName + ' as ' + this.mainAlias);
|
|
240
|
+
const query = (0, builder_1.Select)(...columnSqls).from(this.mainEntity.tableName + ' as ' + this.mainAlias);
|
|
268
241
|
if (args.distinct)
|
|
269
242
|
query.distinct();
|
|
270
243
|
query.where(...this._filter._items);
|
|
@@ -283,7 +256,7 @@ class FindCommand {
|
|
|
283
256
|
params: args?.params,
|
|
284
257
|
fetchRows: args?.limit,
|
|
285
258
|
objectRows: false,
|
|
286
|
-
cursor: false
|
|
259
|
+
cursor: false,
|
|
287
260
|
});
|
|
288
261
|
// Create objects
|
|
289
262
|
if (resp.rows && resp.fields) {
|
|
@@ -22,7 +22,7 @@ class RowConverter {
|
|
|
22
22
|
const item = {
|
|
23
23
|
fieldAlias: args.fieldAlias,
|
|
24
24
|
dataType: args.dataType,
|
|
25
|
-
parse: args.parse
|
|
25
|
+
parse: args.parse,
|
|
26
26
|
};
|
|
27
27
|
this._properties[args.name] = item;
|
|
28
28
|
return item;
|
|
@@ -33,7 +33,7 @@ class RowConverter {
|
|
|
33
33
|
const converter = new RowConverter(args.type, this);
|
|
34
34
|
const item = {
|
|
35
35
|
converter,
|
|
36
|
-
type: args.type
|
|
36
|
+
type: args.type,
|
|
37
37
|
};
|
|
38
38
|
this._properties[args.name] = item;
|
|
39
39
|
return item;
|
|
@@ -48,7 +48,7 @@ class RowConverter {
|
|
|
48
48
|
keyField: args.keyField,
|
|
49
49
|
findCommand: args.findCommand,
|
|
50
50
|
sort: args.sort,
|
|
51
|
-
paramValues: []
|
|
51
|
+
paramValues: [],
|
|
52
52
|
};
|
|
53
53
|
this._properties[args.name] = item;
|
|
54
54
|
return item;
|
|
@@ -129,7 +129,7 @@ class RowConverter {
|
|
|
129
129
|
if (!(prop.paramValues && prop.paramValues.length))
|
|
130
130
|
continue;
|
|
131
131
|
const resultType = this.resultType;
|
|
132
|
-
const promise = async function (p) {
|
|
132
|
+
const promise = (async function (p) {
|
|
133
133
|
const findCommand = p.findCommand;
|
|
134
134
|
let fld;
|
|
135
135
|
const map = new Map();
|
|
@@ -151,7 +151,7 @@ class RowConverter {
|
|
|
151
151
|
arr.push(obj);
|
|
152
152
|
});
|
|
153
153
|
}
|
|
154
|
-
}
|
|
154
|
+
},
|
|
155
155
|
});
|
|
156
156
|
if (r.length > findCommand.maxEagerFetch)
|
|
157
157
|
throw new Error(`Number of returning rows for "${propKey}" exceeds maxEagerFetch limit`);
|
|
@@ -171,7 +171,7 @@ class RowConverter {
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
|
-
}(prop);
|
|
174
|
+
})(prop);
|
|
175
175
|
promises.push(promise);
|
|
176
176
|
}
|
|
177
177
|
else if (isObjectProperty(prop)) {
|
|
@@ -30,12 +30,11 @@ class UpdateCommand {
|
|
|
30
30
|
return 0;
|
|
31
31
|
if (args.filter)
|
|
32
32
|
await this._prepareFilter(ctx, args.filter);
|
|
33
|
-
const query = (0, builder_1.Update)(tableName + ' as T', ctx.queryValues)
|
|
34
|
-
.where(...ctx.queryFilter);
|
|
33
|
+
const query = (0, builder_1.Update)(tableName + ' as T', ctx.queryValues).where(...ctx.queryFilter);
|
|
35
34
|
const qr = await args.connection.execute(query, {
|
|
36
35
|
params: args.params ? [...args.params, ctx.queryParams] : ctx.queryParams,
|
|
37
36
|
objectRows: false,
|
|
38
|
-
cursor: false
|
|
37
|
+
cursor: false,
|
|
39
38
|
});
|
|
40
39
|
return qr.rowsAffected || 0;
|
|
41
40
|
}
|
|
@@ -69,7 +68,7 @@ class UpdateCommand {
|
|
|
69
68
|
ctx.queryValues[fieldName] = (0, builder_1.Param)({
|
|
70
69
|
name: k,
|
|
71
70
|
dataType: col.dataType,
|
|
72
|
-
isArray: col.isArray
|
|
71
|
+
isArray: col.isArray,
|
|
73
72
|
});
|
|
74
73
|
ctx.queryParams[k] = v;
|
|
75
74
|
ctx.colCount++;
|
|
@@ -2,14 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Column = void 0;
|
|
4
4
|
const entity_metadata_js_1 = require("../model/entity-metadata.js");
|
|
5
|
+
const orm_const_js_1 = require("../orm.const.js");
|
|
5
6
|
function Column(arg0) {
|
|
7
|
+
return Column[orm_const_js_1.DECORATOR_FACTORY](arg0);
|
|
8
|
+
}
|
|
9
|
+
exports.Column = Column;
|
|
10
|
+
Column[orm_const_js_1.DECORATOR_FACTORY] = function (arg0) {
|
|
6
11
|
return (target, propertyKey) => {
|
|
7
12
|
if (typeof propertyKey !== 'string')
|
|
8
13
|
throw new Error('Symbol properties are not accepted');
|
|
9
14
|
const options = (typeof arg0 === 'string' ? { dataType: arg0 } : arg0) || {};
|
|
10
15
|
const entity = entity_metadata_js_1.EntityMetadata.define(target.constructor);
|
|
11
16
|
if (!options.type) {
|
|
12
|
-
const typ = Reflect.getMetadata(
|
|
17
|
+
const typ = Reflect.getMetadata('design:type', entity.ctor.prototype, propertyKey);
|
|
13
18
|
if (typ === Array) {
|
|
14
19
|
options.type = String;
|
|
15
20
|
options.isArray = true;
|
|
@@ -19,5 +24,4 @@ function Column(arg0) {
|
|
|
19
24
|
}
|
|
20
25
|
entity_metadata_js_1.EntityMetadata.defineColumnField(entity, propertyKey, options);
|
|
21
26
|
};
|
|
22
|
-
}
|
|
23
|
-
exports.Column = Column;
|
|
27
|
+
};
|