@sqb/connect 4.11.3 → 4.12.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 +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/orm/commands/command.helper.js +7 -8
- package/cjs/orm/commands/create.command.js +4 -5
- package/cjs/orm/commands/find.command.js +18 -29
- 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 +1 -1
- 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/repository.class.js +8 -9
- package/cjs/orm/util/apply-mixins.js +6 -4
- package/cjs/orm/util/extract-keyvalues.js +1 -1
- 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/orm/commands/command.helper.js +8 -9
- package/esm/orm/commands/create.command.js +4 -5
- package/esm/orm/commands/find.command.js +18 -29
- 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 +1 -1
- 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/repository.class.js +8 -9
- package/esm/orm/util/apply-mixins.js +6 -4
- package/esm/orm/util/extract-keyvalues.js +1 -1
- package/esm/orm/util/serialize-field.js +10 -10
- package/package.json +8 -7
- package/types/orm/decorators/entity.decorator.d.ts +2 -2
- package/types/orm/orm.type.d.ts +1 -1
- package/types/orm/repository.class.d.ts +2 -1
|
@@ -81,8 +81,7 @@ class Association {
|
|
|
81
81
|
if (this.many) {
|
|
82
82
|
if (!sourceKey) {
|
|
83
83
|
const primaryIndexColumns = entity_metadata_js_1.EntityMetadata.getPrimaryIndexColumns(source);
|
|
84
|
-
sourceKey = primaryIndexColumns && primaryIndexColumns.length === 1 ?
|
|
85
|
-
primaryIndexColumns[0].name : 'id';
|
|
84
|
+
sourceKey = primaryIndexColumns && primaryIndexColumns.length === 1 ? primaryIndexColumns[0].name : 'id';
|
|
86
85
|
}
|
|
87
86
|
if (!targetKey && sourceKey) {
|
|
88
87
|
// snake-case
|
|
@@ -95,8 +94,7 @@ class Association {
|
|
|
95
94
|
else {
|
|
96
95
|
if (!targetKey) {
|
|
97
96
|
const primaryIndexColumns = entity_metadata_js_1.EntityMetadata.getPrimaryIndexColumns(target);
|
|
98
|
-
targetKey = primaryIndexColumns && primaryIndexColumns.length === 1 ?
|
|
99
|
-
primaryIndexColumns[0].name : 'id';
|
|
97
|
+
targetKey = primaryIndexColumns && primaryIndexColumns.length === 1 ? primaryIndexColumns[0].name : 'id';
|
|
100
98
|
}
|
|
101
99
|
if (!sourceKey && targetKey) {
|
|
102
100
|
// snake-case
|
|
@@ -21,7 +21,7 @@ var EntityMetadata;
|
|
|
21
21
|
fields: {},
|
|
22
22
|
indexes: [],
|
|
23
23
|
foreignKeys: [],
|
|
24
|
-
eventListeners: {}
|
|
24
|
+
eventListeners: {},
|
|
25
25
|
};
|
|
26
26
|
Reflect.defineMetadata(orm_const_js_1.ENTITY_METADATA_KEY, meta, ctor);
|
|
27
27
|
// Merge base entity columns into this one
|
|
@@ -93,7 +93,7 @@ var EntityMetadata;
|
|
|
93
93
|
enumerable: false,
|
|
94
94
|
configurable: true,
|
|
95
95
|
writable: true,
|
|
96
|
-
value: Object.values(entity.fields).map(m => m.name)
|
|
96
|
+
value: Object.values(entity.fields).map(m => m.name),
|
|
97
97
|
});
|
|
98
98
|
return entity._fieldNames;
|
|
99
99
|
}
|
|
@@ -144,7 +144,7 @@ var EntityMetadata;
|
|
|
144
144
|
if (!src.foreignKeys)
|
|
145
145
|
return;
|
|
146
146
|
for (const f of src.foreignKeys) {
|
|
147
|
-
if (await f.resolveTarget() === trg)
|
|
147
|
+
if ((await f.resolveTarget()) === trg)
|
|
148
148
|
return f;
|
|
149
149
|
}
|
|
150
150
|
}
|
|
@@ -153,7 +153,7 @@ var EntityMetadata;
|
|
|
153
153
|
entity.indexes = entity.indexes || [];
|
|
154
154
|
index = {
|
|
155
155
|
...index,
|
|
156
|
-
columns: Array.isArray(index.columns) ? index.columns : [index.columns]
|
|
156
|
+
columns: Array.isArray(index.columns) ? index.columns : [index.columns],
|
|
157
157
|
};
|
|
158
158
|
if (index.primary)
|
|
159
159
|
entity.indexes.forEach(idx => delete idx.primary);
|
|
@@ -166,7 +166,7 @@ var EntityMetadata;
|
|
|
166
166
|
source: entity.ctor,
|
|
167
167
|
sourceKey: propertyKey,
|
|
168
168
|
target,
|
|
169
|
-
targetKey
|
|
169
|
+
targetKey,
|
|
170
170
|
});
|
|
171
171
|
entity.foreignKeys.push(fk);
|
|
172
172
|
}
|
|
@@ -255,7 +255,7 @@ var EntityMetadata;
|
|
|
255
255
|
let l = association;
|
|
256
256
|
let i = 1;
|
|
257
257
|
while (l) {
|
|
258
|
-
l.name = entity.name + '.' + propertyKey + '#' +
|
|
258
|
+
l.name = entity.name + '.' + propertyKey + '#' + i++;
|
|
259
259
|
l = l.next;
|
|
260
260
|
}
|
|
261
261
|
entity.fields[propertyKey.toLowerCase()] = prop;
|
|
@@ -267,7 +267,7 @@ var EntityMetadata;
|
|
|
267
267
|
...options,
|
|
268
268
|
columns: Array.isArray(column) ? column : [column],
|
|
269
269
|
unique: true,
|
|
270
|
-
primary: true
|
|
270
|
+
primary: true,
|
|
271
271
|
});
|
|
272
272
|
}
|
|
273
273
|
EntityMetadata.setPrimaryKeys = setPrimaryKeys;
|
|
@@ -10,7 +10,7 @@ class LinkChain {
|
|
|
10
10
|
target,
|
|
11
11
|
source: null,
|
|
12
12
|
sourceKey,
|
|
13
|
-
targetKey: targetKey
|
|
13
|
+
targetKey: targetKey,
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
16
|
where(conditions) {
|
|
@@ -33,7 +33,7 @@ class LinkChain {
|
|
|
33
33
|
source: this.current.target,
|
|
34
34
|
target,
|
|
35
35
|
sourceKey: parentKey,
|
|
36
|
-
targetKey: targetKey
|
|
36
|
+
targetKey: targetKey,
|
|
37
37
|
});
|
|
38
38
|
child.prior = this.current;
|
|
39
39
|
this.current.next = child;
|
|
@@ -25,8 +25,7 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
25
25
|
create(values, options) {
|
|
26
26
|
return this._execute(async (connection) => {
|
|
27
27
|
const keyValue = await this._create(values, { ...options, connection, returning: true });
|
|
28
|
-
const result = keyValue &&
|
|
29
|
-
await this._find(keyValue, { ...options, connection });
|
|
28
|
+
const result = keyValue && (await this._find(keyValue, { ...options, connection }));
|
|
30
29
|
if (!result)
|
|
31
30
|
throw new Error('Unable to insert new row');
|
|
32
31
|
return result;
|
|
@@ -119,7 +118,7 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
119
118
|
const keyValues = await create_command_js_1.CreateCommand.execute({
|
|
120
119
|
...options,
|
|
121
120
|
entity: this._entity,
|
|
122
|
-
values
|
|
121
|
+
values,
|
|
123
122
|
});
|
|
124
123
|
if (options.returning && !keyValues)
|
|
125
124
|
throw new Error('Unable to insert new row');
|
|
@@ -136,13 +135,13 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
136
135
|
return !!(await count_command_js_1.CountCommand.execute({
|
|
137
136
|
...options,
|
|
138
137
|
filter,
|
|
139
|
-
entity: this._entity
|
|
138
|
+
entity: this._entity,
|
|
140
139
|
}));
|
|
141
140
|
}
|
|
142
141
|
async _count(options) {
|
|
143
142
|
return count_command_js_1.CountCommand.execute({
|
|
144
143
|
...options,
|
|
145
|
-
entity: this._entity
|
|
144
|
+
entity: this._entity,
|
|
146
145
|
});
|
|
147
146
|
}
|
|
148
147
|
async _findMany(options) {
|
|
@@ -154,7 +153,7 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
154
153
|
async _findOne(options) {
|
|
155
154
|
const rows = await this._findMany({
|
|
156
155
|
...options,
|
|
157
|
-
limit: 1
|
|
156
|
+
limit: 1,
|
|
158
157
|
});
|
|
159
158
|
return rows && rows[0];
|
|
160
159
|
}
|
|
@@ -187,7 +186,7 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
187
186
|
...options,
|
|
188
187
|
entity: this._entity,
|
|
189
188
|
filter: options?.filter,
|
|
190
|
-
params: options?.params
|
|
189
|
+
params: options?.params,
|
|
191
190
|
});
|
|
192
191
|
}
|
|
193
192
|
async _update(keyValue, values, options) {
|
|
@@ -207,7 +206,7 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
207
206
|
...options,
|
|
208
207
|
entity: this._entity,
|
|
209
208
|
values: updateValues,
|
|
210
|
-
filter
|
|
209
|
+
filter,
|
|
211
210
|
});
|
|
212
211
|
return rowsAffected ? keyValues : undefined;
|
|
213
212
|
}
|
|
@@ -217,7 +216,7 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
217
216
|
return await update_command_js_1.UpdateCommand.execute({
|
|
218
217
|
...options,
|
|
219
218
|
entity: this._entity,
|
|
220
|
-
values
|
|
219
|
+
values,
|
|
221
220
|
});
|
|
222
221
|
}
|
|
223
222
|
}
|
|
@@ -3,11 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.applyMixins = void 0;
|
|
4
4
|
function applyMixins(derivedCtor, baseCtor, filter) {
|
|
5
5
|
for (const name of Object.getOwnPropertyNames(baseCtor.prototype)) {
|
|
6
|
-
if (
|
|
7
|
-
|
|
6
|
+
if (name === 'constructor' ||
|
|
7
|
+
name === '__proto__' ||
|
|
8
|
+
name === 'toJSON' ||
|
|
9
|
+
name === 'toString' ||
|
|
10
|
+
(filter && !filter(name)))
|
|
8
11
|
continue;
|
|
9
|
-
Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
|
|
10
|
-
Object.create(null));
|
|
12
|
+
Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || Object.create(null));
|
|
11
13
|
}
|
|
12
14
|
}
|
|
13
15
|
exports.applyMixins = applyMixins;
|
|
@@ -7,7 +7,7 @@ function extractKeyValues(entityDef, valueOrInstance, keepOther) {
|
|
|
7
7
|
const primaryIndex = entity_metadata_js_1.EntityMetadata.getPrimaryIndex(entityDef);
|
|
8
8
|
if (!primaryIndex)
|
|
9
9
|
throw new Error(`No primary fields defined for "${entityDef.name}" entity`);
|
|
10
|
-
const validateCol =
|
|
10
|
+
const validateCol = k => {
|
|
11
11
|
const col = entity_metadata_js_1.EntityMetadata.getField(entityDef, k);
|
|
12
12
|
if (!col)
|
|
13
13
|
throw new Error(`Unknown column (${k}) defined as primary key in entity "${entityDef.name}"`);
|
|
@@ -21,19 +21,19 @@ const padZero = (n) => (n < 9 ? '0' : '') + n;
|
|
|
21
21
|
function serializeDataValue(dataType, v) {
|
|
22
22
|
if (v == null)
|
|
23
23
|
return;
|
|
24
|
-
if (v instanceof Date &&
|
|
25
|
-
(
|
|
26
|
-
|
|
27
|
-
padZero(v.getMonth() + 1) +
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
padZero(v.
|
|
24
|
+
if (v instanceof Date && (dataType === builder_1.DataType.DATE || dataType === builder_1.DataType.TIMESTAMP)) {
|
|
25
|
+
return (v.getFullYear() +
|
|
26
|
+
'-' +
|
|
27
|
+
padZero(v.getMonth() + 1) +
|
|
28
|
+
'-' +
|
|
29
|
+
padZero(v.getDate()) +
|
|
30
|
+
(dataType === builder_1.DataType.TIMESTAMP
|
|
31
|
+
? 'T' + padZero(v.getHours()) + ':' + padZero(v.getMinutes()) + ':' + padZero(v.getSeconds())
|
|
32
|
+
: ''));
|
|
32
33
|
}
|
|
33
34
|
if (v instanceof Buffer)
|
|
34
35
|
return v.toString('base64');
|
|
35
|
-
if (typeof v === 'number' && (dataType === builder_1.DataType.SMALLINT ||
|
|
36
|
-
dataType === builder_1.DataType.INTEGER))
|
|
36
|
+
if (typeof v === 'number' && (dataType === builder_1.DataType.SMALLINT || dataType === builder_1.DataType.INTEGER))
|
|
37
37
|
return Math.trunc(v);
|
|
38
38
|
if (typeof v === 'bigint')
|
|
39
39
|
return v.toString();
|
|
@@ -14,7 +14,7 @@ export class CursorStream extends Readable {
|
|
|
14
14
|
this.close().catch(() => false);
|
|
15
15
|
});
|
|
16
16
|
cursor.once('close', () => this.emit('close'));
|
|
17
|
-
cursor.on('error',
|
|
17
|
+
cursor.on('error', err => this.emit('error', err));
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Returns if stream is closed.
|
|
@@ -43,7 +43,9 @@ export class CursorStream extends Readable {
|
|
|
43
43
|
this.emit('end');
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
-
this._cursor
|
|
46
|
+
this._cursor
|
|
47
|
+
.next()
|
|
48
|
+
.then(row => {
|
|
47
49
|
if (this._eof)
|
|
48
50
|
return this.push(null);
|
|
49
51
|
let buf = '';
|
|
@@ -70,7 +72,8 @@ export class CursorStream extends Readable {
|
|
|
70
72
|
buf += ',';
|
|
71
73
|
this.push(buf + JSON.stringify(row));
|
|
72
74
|
}
|
|
73
|
-
})
|
|
75
|
+
})
|
|
76
|
+
.catch(err => {
|
|
74
77
|
/* istanbul ignore next */
|
|
75
78
|
if (typeof this.destroy == 'function')
|
|
76
79
|
this.destroy(err);
|
package/esm/client/cursor.js
CHANGED
|
@@ -175,7 +175,8 @@ export class Cursor extends TypedEventEmitterClass(AsyncEventEmitter) {
|
|
|
175
175
|
if (step < 0 && !this._cache)
|
|
176
176
|
throw new Error('To move cursor back, it needs cache to be enabled');
|
|
177
177
|
const _this = this;
|
|
178
|
-
await this._taskQueue
|
|
178
|
+
await this._taskQueue
|
|
179
|
+
.enqueue(async function () {
|
|
179
180
|
/* If moving backward */
|
|
180
181
|
if (step < 0) {
|
|
181
182
|
/* Seek cache */
|
|
@@ -208,7 +209,8 @@ export class Cursor extends TypedEventEmitterClass(AsyncEventEmitter) {
|
|
|
208
209
|
return;
|
|
209
210
|
await _this._fetchRows();
|
|
210
211
|
}
|
|
211
|
-
})
|
|
212
|
+
})
|
|
213
|
+
.toPromise();
|
|
212
214
|
if (!silent)
|
|
213
215
|
this.emit('move', this.row, this._rowNum);
|
|
214
216
|
return this._rowNum;
|
|
@@ -223,12 +225,12 @@ export class Cursor extends TypedEventEmitterClass(AsyncEventEmitter) {
|
|
|
223
225
|
if (rows && rows.length) {
|
|
224
226
|
debug('Fetched %d rows from database', rows.length);
|
|
225
227
|
// Normalize rows
|
|
226
|
-
rows = this._request.objectRows
|
|
227
|
-
normalizeRowsToObjectRows(this._fields, this._intlcur.rowType, rows, this._request)
|
|
228
|
-
normalizeRowsToArrayRows(this._fields, this._intlcur.rowType, rows, this._request);
|
|
228
|
+
rows = this._request.objectRows
|
|
229
|
+
? normalizeRowsToObjectRows(this._fields, this._intlcur.rowType, rows, this._request)
|
|
230
|
+
: normalizeRowsToArrayRows(this._fields, this._intlcur.rowType, rows, this._request);
|
|
229
231
|
callFetchHooks(rows, this._request);
|
|
230
232
|
for (const [idx, row] of rows.entries()) {
|
|
231
|
-
this.emit('fetch', row,
|
|
233
|
+
this.emit('fetch', row, this._rowNum + idx + 1);
|
|
232
234
|
}
|
|
233
235
|
/* Add rows to cache */
|
|
234
236
|
if (this._cache) {
|
|
@@ -4,13 +4,13 @@ export class FieldInfoMap {
|
|
|
4
4
|
enumerable: false,
|
|
5
5
|
configurable: false,
|
|
6
6
|
writable: true,
|
|
7
|
-
value: {}
|
|
7
|
+
value: {},
|
|
8
8
|
});
|
|
9
9
|
Object.defineProperty(this, '_arr', {
|
|
10
10
|
enumerable: false,
|
|
11
11
|
configurable: false,
|
|
12
12
|
writable: true,
|
|
13
|
-
value: []
|
|
13
|
+
value: [],
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
16
|
add(field) {
|
|
@@ -25,7 +25,7 @@ export class FieldInfoMap {
|
|
|
25
25
|
enumerable: false,
|
|
26
26
|
configurable: false,
|
|
27
27
|
writable: true,
|
|
28
|
-
value: _obj
|
|
28
|
+
value: _obj,
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
get(k) {
|
package/esm/client/helpers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { camelCase, pascalCase } from
|
|
1
|
+
import { camelCase, pascalCase } from 'putil-varhelpers';
|
|
2
2
|
import { FieldInfoMap } from './field-info-map.js';
|
|
3
3
|
export function applyNamingStrategy(value, namingStrategy) {
|
|
4
4
|
if (typeof namingStrategy === 'string' && namingStrategy !== 'original') {
|
package/esm/client/sqb-client.js
CHANGED
|
@@ -46,7 +46,7 @@ export class SqbClient extends TypedEventEmitterClass(AsyncEventEmitter) {
|
|
|
46
46
|
create: () => adapter.connect(cfg),
|
|
47
47
|
destroy: instance => instance.close(),
|
|
48
48
|
reset: async (instance) => instance.reset(),
|
|
49
|
-
validate: instance => instance.test()
|
|
49
|
+
validate: instance => instance.test(),
|
|
50
50
|
};
|
|
51
51
|
this._pool = createPool(poolFactory, poolOptions);
|
|
52
52
|
this._pool.on('closing', () => this.emit('closing'));
|
|
@@ -155,8 +155,7 @@ export class SqbClient extends TypedEventEmitterClass(AsyncEventEmitter) {
|
|
|
155
155
|
return this._entities[name];
|
|
156
156
|
}
|
|
157
157
|
toString() {
|
|
158
|
-
return '[object ' + Object.getPrototypeOf(this).constructor.name + '(' +
|
|
159
|
-
this.dialect + ')]';
|
|
158
|
+
return '[object ' + Object.getPrototypeOf(this).constructor.name + '(' + this.dialect + ')]';
|
|
160
159
|
}
|
|
161
160
|
[inspect]() {
|
|
162
161
|
return this.toString();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'assert';
|
|
2
2
|
import _debug from 'debug';
|
|
3
3
|
import { TaskQueue } from 'power-tasks';
|
|
4
|
-
import { coalesce, coerceToBoolean, coerceToInt, coerceToString } from
|
|
4
|
+
import { coalesce, coerceToBoolean, coerceToInt, coerceToString } from 'putil-varhelpers';
|
|
5
5
|
import { AsyncEventEmitter, TypedEventEmitterClass } from 'strict-typed-events';
|
|
6
6
|
import { classes } from '@sqb/builder';
|
|
7
7
|
import { EntityMetadata } from '../orm/model/entity-metadata.js';
|
|
@@ -74,7 +74,7 @@ export class SqbConnection extends TypedEventEmitterClass(AsyncEventEmitter) {
|
|
|
74
74
|
await this.emitAsyncSerial('close');
|
|
75
75
|
const intlcon = this._intlcon;
|
|
76
76
|
this._intlcon = undefined;
|
|
77
|
-
this.client.pool.release(intlcon,
|
|
77
|
+
this.client.pool.release(intlcon, e => {
|
|
78
78
|
if (e)
|
|
79
79
|
this.client.emit('error', e);
|
|
80
80
|
});
|
|
@@ -131,7 +131,7 @@ export class SqbConnection extends TypedEventEmitterClass(AsyncEventEmitter) {
|
|
|
131
131
|
if (!response)
|
|
132
132
|
throw new Error('Database adapter returned an empty response');
|
|
133
133
|
const result = {
|
|
134
|
-
executeTime: Date.now() - startTime
|
|
134
|
+
executeTime: Date.now() - startTime,
|
|
135
135
|
};
|
|
136
136
|
if (request.showSql)
|
|
137
137
|
result.query = request;
|
|
@@ -143,13 +143,13 @@ export class SqbConnection extends TypedEventEmitterClass(AsyncEventEmitter) {
|
|
|
143
143
|
result.fields = wrapAdapterFields(response.fields, request.fieldNaming);
|
|
144
144
|
result.rowType = response.rowType;
|
|
145
145
|
if (response.rows) {
|
|
146
|
-
result.rows = request.objectRows
|
|
147
|
-
normalizeRowsToObjectRows(result.fields, response.rowType, response.rows, request)
|
|
148
|
-
normalizeRowsToArrayRows(result.fields, response.rowType, response.rows, request);
|
|
146
|
+
result.rows = request.objectRows
|
|
147
|
+
? normalizeRowsToObjectRows(result.fields, response.rowType, response.rows, request)
|
|
148
|
+
: normalizeRowsToArrayRows(result.fields, response.rowType, response.rows, request);
|
|
149
149
|
callFetchHooks(result.rows, request);
|
|
150
150
|
}
|
|
151
151
|
else if (response.cursor) {
|
|
152
|
-
const cursor = result.cursor = new Cursor(this, result.fields, response.cursor, request);
|
|
152
|
+
const cursor = (result.cursor = new Cursor(this, result.fields, response.cursor, request));
|
|
153
153
|
const hook = () => cursor.close();
|
|
154
154
|
cursor.once('close', () => this.off('close', hook));
|
|
155
155
|
this.on('close', hook);
|
|
@@ -222,8 +222,9 @@ export class SqbConnection extends TypedEventEmitterClass(AsyncEventEmitter) {
|
|
|
222
222
|
const request = {
|
|
223
223
|
dialect: this.client.dialect,
|
|
224
224
|
sql: '',
|
|
225
|
-
autoCommit: this.inTransaction
|
|
226
|
-
|
|
225
|
+
autoCommit: this.inTransaction
|
|
226
|
+
? false
|
|
227
|
+
: coerceToBoolean(coalesce(options.autoCommit, this._options?.autoCommit, defaults.autoCommit), true),
|
|
227
228
|
cursor: coerceToBoolean(coalesce(options.cursor, defaults.cursor), false),
|
|
228
229
|
objectRows: coerceToBoolean(coalesce(options.objectRows, defaults.objectRows), true),
|
|
229
230
|
ignoreNulls: coerceToBoolean(coalesce(options.ignoreNulls, defaults.ignoreNulls), false),
|
|
@@ -233,19 +234,18 @@ export class SqbConnection extends TypedEventEmitterClass(AsyncEventEmitter) {
|
|
|
233
234
|
showSql: coerceToBoolean(coalesce(options.showSql, defaults.showSql), false),
|
|
234
235
|
prettyPrint: coerceToBoolean(coalesce(options.prettyPrint, defaults.prettyPrint), false),
|
|
235
236
|
action: coerceToString(options.action),
|
|
236
|
-
fetchAsString: options.fetchAsString
|
|
237
|
+
fetchAsString: options.fetchAsString,
|
|
237
238
|
};
|
|
238
239
|
request.ignoreNulls = request.ignoreNulls && request.objectRows;
|
|
239
240
|
if (query instanceof classes.Query) {
|
|
240
241
|
if (this._intlcon.onGenerateQuery)
|
|
241
242
|
this._intlcon.onGenerateQuery(request, query);
|
|
242
|
-
const q = query
|
|
243
|
-
.generate({
|
|
243
|
+
const q = query.generate({
|
|
244
244
|
dialect: request.dialect,
|
|
245
245
|
dialectVersion: request.dialectVersion,
|
|
246
246
|
params: options.params,
|
|
247
247
|
strictParams: true,
|
|
248
|
-
prettyPrint: request.prettyPrint
|
|
248
|
+
prettyPrint: request.prettyPrint,
|
|
249
249
|
});
|
|
250
250
|
request.sql = q.sql;
|
|
251
251
|
request.params = q.params;
|
|
@@ -257,7 +257,8 @@ export class SqbConnection extends TypedEventEmitterClass(AsyncEventEmitter) {
|
|
|
257
257
|
if (query.listenerCount('fetch'))
|
|
258
258
|
request.fetchHooks = query.listeners('fetch');
|
|
259
259
|
}
|
|
260
|
-
else {
|
|
260
|
+
else {
|
|
261
|
+
// noinspection SuspiciousTypeOfGuard
|
|
261
262
|
if (typeof query === 'string') {
|
|
262
263
|
request.sql = query;
|
|
263
264
|
request.params = options.params;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { And, Eq, Exists, Field, InnerJoin, isCompOperator, isLogicalOperator, LeftOuterJoin, Raw, Select } from '@sqb/builder';
|
|
1
|
+
import { And, Eq, Exists, Field, InnerJoin, isCompOperator, isLogicalOperator, LeftOuterJoin, Raw, Select, } from '@sqb/builder';
|
|
2
2
|
import { EmbeddedFieldMetadata } from '../model/embedded-field-metadata.js';
|
|
3
3
|
import { EntityMetadata } from '../model/entity-metadata.js';
|
|
4
4
|
import { isAssociationField, isColumnField, isEmbeddedField } from '../util/orm.helper.js';
|
|
@@ -22,8 +22,9 @@ export async function joinAssociation(joinInfos, association, parentAlias, inner
|
|
|
22
22
|
const keyCol = await node.resolveSourceProperty();
|
|
23
23
|
const targetCol = await node.resolveTargetProperty();
|
|
24
24
|
const joinAlias = 'J' + (joinInfos.length + 1);
|
|
25
|
-
const join = innerJoin
|
|
26
|
-
|
|
25
|
+
const join = innerJoin
|
|
26
|
+
? InnerJoin(targetEntity.tableName + ' as ' + joinAlias)
|
|
27
|
+
: LeftOuterJoin(targetEntity.tableName + ' as ' + joinAlias);
|
|
27
28
|
join.on(Eq(Field(joinAlias + '.' + targetCol.fieldName, targetCol.dataType, targetCol.isArray), Field(parentAlias + '.' + keyCol.fieldName, keyCol.dataType, keyCol.isArray)));
|
|
28
29
|
if (node.conditions)
|
|
29
30
|
await prepareFilter(targetEntity, node.conditions, join._conditions, joinAlias);
|
|
@@ -32,7 +33,7 @@ export async function joinAssociation(joinInfos, association, parentAlias, inner
|
|
|
32
33
|
sourceEntity,
|
|
33
34
|
targetEntity,
|
|
34
35
|
joinAlias,
|
|
35
|
-
join
|
|
36
|
+
join,
|
|
36
37
|
};
|
|
37
38
|
joinInfos.push(joinInfo);
|
|
38
39
|
}
|
|
@@ -101,8 +102,7 @@ export async function prepareFilter(entityDef, filter, trgOp, tableAlias = 'T')
|
|
|
101
102
|
if (!subSelect) {
|
|
102
103
|
const keyCol = await col.association.resolveSourceProperty();
|
|
103
104
|
const targetCol = await col.association.resolveTargetProperty();
|
|
104
|
-
subSelect = Select(Raw('1'))
|
|
105
|
-
.from(_curEntity.tableName + ' K');
|
|
105
|
+
subSelect = Select(Raw('1')).from(_curEntity.tableName + ' K');
|
|
106
106
|
subSelect.where(Eq(Field('K.' + targetCol.fieldName, targetCol.dataType, targetCol.isArray), Field(tableAlias + '.' + keyCol.fieldName, keyCol.dataType, keyCol.isArray)));
|
|
107
107
|
trgOp.add(Exists(subSelect));
|
|
108
108
|
trgOp = subSelect._where;
|
|
@@ -118,9 +118,8 @@ export async function prepareFilter(entityDef, filter, trgOp, tableAlias = 'T')
|
|
|
118
118
|
const targetEntity = await node.resolveTarget();
|
|
119
119
|
const sourceColumn = await node.resolveSourceProperty();
|
|
120
120
|
const targetColumn = await node.resolveTargetProperty();
|
|
121
|
-
const joinAlias = 'J' + ((
|
|
122
|
-
subSelect.join(InnerJoin(targetEntity.tableName + ' ' + joinAlias)
|
|
123
|
-
.on(Eq(Field(joinAlias + '.' + targetColumn.fieldName, targetColumn.dataType, targetColumn.isArray), Field(_curAlias + '.' + sourceColumn.fieldName, sourceColumn.dataType, sourceColumn.isArray))));
|
|
121
|
+
const joinAlias = 'J' + ((subSelect?._joins?.length || 0) + 1);
|
|
122
|
+
subSelect.join(InnerJoin(targetEntity.tableName + ' ' + joinAlias).on(Eq(Field(joinAlias + '.' + targetColumn.fieldName, targetColumn.dataType, targetColumn.isArray), Field(_curAlias + '.' + sourceColumn.fieldName, sourceColumn.dataType, sourceColumn.isArray))));
|
|
124
123
|
_curEntity = targetEntity;
|
|
125
124
|
_curAlias = joinAlias;
|
|
126
125
|
node = node.next;
|
|
@@ -18,7 +18,7 @@ export class CreateCommand {
|
|
|
18
18
|
entity,
|
|
19
19
|
queryParams: {},
|
|
20
20
|
queryValues: {},
|
|
21
|
-
colCount: 0
|
|
21
|
+
colCount: 0,
|
|
22
22
|
};
|
|
23
23
|
// Prepare
|
|
24
24
|
await this._prepareParams(ctx, entity, args.values);
|
|
@@ -33,7 +33,7 @@ export class CreateCommand {
|
|
|
33
33
|
const qr = await args.connection.execute(query, {
|
|
34
34
|
params: ctx.queryParams,
|
|
35
35
|
objectRows: false,
|
|
36
|
-
cursor: false
|
|
36
|
+
cursor: false,
|
|
37
37
|
});
|
|
38
38
|
if (args.returning && qr.fields && qr.rows?.length) {
|
|
39
39
|
const keyValues = {};
|
|
@@ -55,8 +55,7 @@ export class CreateCommand {
|
|
|
55
55
|
if (col.noInsert)
|
|
56
56
|
continue;
|
|
57
57
|
if (v == null && col.default !== undefined) {
|
|
58
|
-
v = typeof col.default === 'function' ?
|
|
59
|
-
col.default(values) : col.default;
|
|
58
|
+
v = typeof col.default === 'function' ? col.default(values) : col.default;
|
|
60
59
|
}
|
|
61
60
|
if (typeof col.serialize === 'function')
|
|
62
61
|
v = col.serialize(v, col.name);
|
|
@@ -71,7 +70,7 @@ export class CreateCommand {
|
|
|
71
70
|
ctx.queryValues[fieldName] = Param({
|
|
72
71
|
name: k,
|
|
73
72
|
dataType: col.dataType,
|
|
74
|
-
isArray: col.isArray
|
|
73
|
+
isArray: col.isArray,
|
|
75
74
|
});
|
|
76
75
|
ctx.queryParams[k] = v;
|
|
77
76
|
ctx.colCount++;
|