@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
|
@@ -6,7 +6,7 @@ function Embedded(type, options) {
|
|
|
6
6
|
return (target, propertyKey) => {
|
|
7
7
|
if (typeof propertyKey !== 'string')
|
|
8
8
|
throw new Error('Symbol properties are not accepted');
|
|
9
|
-
type = type || Reflect.getMetadata(
|
|
9
|
+
type = type || Reflect.getMetadata('design:type', target, propertyKey);
|
|
10
10
|
if (typeof type !== 'function')
|
|
11
11
|
throw new Error('"type" must be defined');
|
|
12
12
|
const entity = entity_metadata_js_1.EntityMetadata.define(target.constructor);
|
|
@@ -115,7 +115,7 @@ exports.Entity = Entity;
|
|
|
115
115
|
}
|
|
116
116
|
};
|
|
117
117
|
const pickKeys = keys.map(x => x.toLowerCase());
|
|
118
|
-
const filter =
|
|
118
|
+
const filter = k => pickKeys.includes(k.toLowerCase());
|
|
119
119
|
(0, apply_mixins_js_1.applyMixins)(PickEntityClass, classRef, filter);
|
|
120
120
|
const srcMeta = entity_metadata_js_1.EntityMetadata.get(classRef);
|
|
121
121
|
if (srcMeta) {
|
|
@@ -132,7 +132,7 @@ exports.Entity = Entity;
|
|
|
132
132
|
}
|
|
133
133
|
};
|
|
134
134
|
const omitKeys = keys.map(x => x.toLowerCase());
|
|
135
|
-
const filter =
|
|
135
|
+
const filter = k => !omitKeys.includes(k.toLowerCase());
|
|
136
136
|
(0, apply_mixins_js_1.applyMixins)(OmitEntityClass, classRef, filter);
|
|
137
137
|
const srcMeta = entity_metadata_js_1.EntityMetadata.get(classRef);
|
|
138
138
|
if (srcMeta) {
|
|
@@ -9,7 +9,7 @@ function Link(options) {
|
|
|
9
9
|
const fn = (target, propertyKey) => {
|
|
10
10
|
if (typeof propertyKey !== 'string')
|
|
11
11
|
throw new TypeError('Symbol properties are not allowed');
|
|
12
|
-
const reflectType = Reflect.getMetadata(
|
|
12
|
+
const reflectType = Reflect.getMetadata('design:type', target, propertyKey);
|
|
13
13
|
if (!root) {
|
|
14
14
|
if (reflectType === Array)
|
|
15
15
|
throw new TypeError(`Can't get type information while it is an array. Please define entity type`);
|
|
@@ -7,8 +7,7 @@ function Parse(fn) {
|
|
|
7
7
|
if (typeof propertyKey !== 'string')
|
|
8
8
|
throw new Error('You can define a Column for only string properties');
|
|
9
9
|
const entity = entity_metadata_js_1.EntityMetadata.define(target.constructor);
|
|
10
|
-
entity_metadata_js_1.EntityMetadata.defineColumnField(entity, propertyKey)
|
|
11
|
-
.parse = fn;
|
|
10
|
+
entity_metadata_js_1.EntityMetadata.defineColumnField(entity, propertyKey).parse = fn;
|
|
12
11
|
};
|
|
13
12
|
}
|
|
14
13
|
exports.Parse = Parse;
|
|
@@ -17,8 +16,7 @@ function Serialize(fn) {
|
|
|
17
16
|
if (typeof propertyKey !== 'string')
|
|
18
17
|
throw new Error('You can define a Column for only string properties');
|
|
19
18
|
const entity = entity_metadata_js_1.EntityMetadata.define(target.constructor);
|
|
20
|
-
entity_metadata_js_1.EntityMetadata.defineColumnField(entity, propertyKey)
|
|
21
|
-
.serialize = fn;
|
|
19
|
+
entity_metadata_js_1.EntityMetadata.defineColumnField(entity, propertyKey).serialize = fn;
|
|
22
20
|
};
|
|
23
21
|
}
|
|
24
22
|
exports.Serialize = Serialize;
|
|
@@ -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;
|
package/cjs/orm/orm.const.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.REPOSITORY_KEY = exports.ENTITY_METADATA_KEY = void 0;
|
|
3
|
+
exports.DECORATOR_FACTORY = exports.REPOSITORY_KEY = exports.ENTITY_METADATA_KEY = void 0;
|
|
4
4
|
exports.ENTITY_METADATA_KEY = Symbol.for('SQB_ENTITY_METADATA');
|
|
5
5
|
exports.REPOSITORY_KEY = Symbol.for('SQB_REPOSITORY');
|
|
6
|
+
exports.DECORATOR_FACTORY = Symbol.for('decorator.factory');
|
|
@@ -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;
|
|
@@ -42,15 +41,16 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
42
41
|
return this._exists(keyValue, { ...options, connection });
|
|
43
42
|
}, options);
|
|
44
43
|
}
|
|
44
|
+
existsOne(options) {
|
|
45
|
+
return this._execute(async (connection) => {
|
|
46
|
+
return this._existsOne({ ...options, connection });
|
|
47
|
+
}, options);
|
|
48
|
+
}
|
|
45
49
|
count(options) {
|
|
46
50
|
return this._execute(async (connection) => {
|
|
47
51
|
return this._count({ ...options, connection });
|
|
48
52
|
}, options);
|
|
49
53
|
}
|
|
50
|
-
/** @deprecated - Use findById instead */
|
|
51
|
-
find(keyValue, options) {
|
|
52
|
-
return this.findById(keyValue, options);
|
|
53
|
-
}
|
|
54
54
|
findById(keyValue, options) {
|
|
55
55
|
return this._execute(async (connection) => {
|
|
56
56
|
return this._find(keyValue, { ...options, connection });
|
|
@@ -119,7 +119,7 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
119
119
|
const keyValues = await create_command_js_1.CreateCommand.execute({
|
|
120
120
|
...options,
|
|
121
121
|
entity: this._entity,
|
|
122
|
-
values
|
|
122
|
+
values,
|
|
123
123
|
});
|
|
124
124
|
if (options.returning && !keyValues)
|
|
125
125
|
throw new Error('Unable to insert new row');
|
|
@@ -133,16 +133,30 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
133
133
|
else
|
|
134
134
|
filter.push(options.filter);
|
|
135
135
|
}
|
|
136
|
-
return
|
|
136
|
+
return this._existsOne({
|
|
137
137
|
...options,
|
|
138
138
|
filter,
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
async _existsOne(options) {
|
|
142
|
+
const filter = [];
|
|
143
|
+
if (options && options.filter) {
|
|
144
|
+
if (Array.isArray(options.filter))
|
|
145
|
+
filter.push(...options.filter);
|
|
146
|
+
else
|
|
147
|
+
filter.push(options.filter);
|
|
148
|
+
}
|
|
149
|
+
const resp = await find_command_js_1.FindCommand.execute({
|
|
150
|
+
...options,
|
|
151
|
+
filter,
|
|
152
|
+
entity: this._entity,
|
|
153
|
+
});
|
|
154
|
+
return resp.length > 0;
|
|
141
155
|
}
|
|
142
156
|
async _count(options) {
|
|
143
157
|
return count_command_js_1.CountCommand.execute({
|
|
144
158
|
...options,
|
|
145
|
-
entity: this._entity
|
|
159
|
+
entity: this._entity,
|
|
146
160
|
});
|
|
147
161
|
}
|
|
148
162
|
async _findMany(options) {
|
|
@@ -154,7 +168,7 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
154
168
|
async _findOne(options) {
|
|
155
169
|
const rows = await this._findMany({
|
|
156
170
|
...options,
|
|
157
|
-
limit: 1
|
|
171
|
+
limit: 1,
|
|
158
172
|
});
|
|
159
173
|
return rows && rows[0];
|
|
160
174
|
}
|
|
@@ -187,7 +201,7 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
187
201
|
...options,
|
|
188
202
|
entity: this._entity,
|
|
189
203
|
filter: options?.filter,
|
|
190
|
-
params: options?.params
|
|
204
|
+
params: options?.params,
|
|
191
205
|
});
|
|
192
206
|
}
|
|
193
207
|
async _update(keyValue, values, options) {
|
|
@@ -207,7 +221,7 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
207
221
|
...options,
|
|
208
222
|
entity: this._entity,
|
|
209
223
|
values: updateValues,
|
|
210
|
-
filter
|
|
224
|
+
filter,
|
|
211
225
|
});
|
|
212
226
|
return rowsAffected ? keyValues : undefined;
|
|
213
227
|
}
|
|
@@ -217,7 +231,7 @@ class Repository extends (0, strict_typed_events_1.TypedEventEmitterClass)(stric
|
|
|
217
231
|
return await update_command_js_1.UpdateCommand.execute({
|
|
218
232
|
...options,
|
|
219
233
|
entity: this._entity,
|
|
220
|
-
values
|
|
234
|
+
values,
|
|
221
235
|
});
|
|
222
236
|
}
|
|
223
237
|
}
|
|
@@ -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}"`);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseFieldsProjection = exports.FieldsProjection = void 0;
|
|
4
|
+
const fast_tokenizer_1 = require("fast-tokenizer");
|
|
5
|
+
const FIELD_PATTERN = /^([+-])?([a-z_$]\w*)$/i;
|
|
6
|
+
const NO_DOT_BRACKET_PATTERN = /[^.]\(/g;
|
|
7
|
+
class FieldsProjection {
|
|
8
|
+
}
|
|
9
|
+
exports.FieldsProjection = FieldsProjection;
|
|
10
|
+
(function (FieldsProjection) {
|
|
11
|
+
class Item {
|
|
12
|
+
}
|
|
13
|
+
FieldsProjection.Item = Item;
|
|
14
|
+
})(FieldsProjection || (exports.FieldsProjection = FieldsProjection = {}));
|
|
15
|
+
function parseFieldsProjection(projection, keepCase) {
|
|
16
|
+
const arr = Array.isArray(projection) ? projection : [projection];
|
|
17
|
+
if (!(arr && arr.length))
|
|
18
|
+
return;
|
|
19
|
+
const out = new FieldsProjection();
|
|
20
|
+
for (let s of arr) {
|
|
21
|
+
if (!keepCase)
|
|
22
|
+
s = s.toLowerCase();
|
|
23
|
+
parse(s, out);
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
exports.parseFieldsProjection = parseFieldsProjection;
|
|
28
|
+
function parse(input, target) {
|
|
29
|
+
/** Add dot before brackets which is required to split fields */
|
|
30
|
+
input = input.replace(NO_DOT_BRACKET_PATTERN, s => {
|
|
31
|
+
return s.charAt(0) + '.' + s.substring(1);
|
|
32
|
+
});
|
|
33
|
+
const fields = (0, fast_tokenizer_1.splitString)(input, {
|
|
34
|
+
delimiters: '.',
|
|
35
|
+
brackets: true,
|
|
36
|
+
keepBrackets: false,
|
|
37
|
+
});
|
|
38
|
+
for (let i = 0; i < fields.length; i++) {
|
|
39
|
+
const f = fields[i];
|
|
40
|
+
if (f.includes(',')) {
|
|
41
|
+
const subFields = (0, fast_tokenizer_1.splitString)(f, {
|
|
42
|
+
delimiters: ',',
|
|
43
|
+
brackets: true,
|
|
44
|
+
keepBrackets: true,
|
|
45
|
+
});
|
|
46
|
+
for (const n of subFields) {
|
|
47
|
+
parse(n, target);
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const m = FIELD_PATTERN.exec(f);
|
|
52
|
+
/* istanbul ignore next */
|
|
53
|
+
if (!m)
|
|
54
|
+
throw new TypeError(`Invalid field path (${input})`);
|
|
55
|
+
const fieldName = m[2];
|
|
56
|
+
const treeItem = (target[fieldName] = target[fieldName] || new FieldsProjection.Item());
|
|
57
|
+
if (m[1])
|
|
58
|
+
treeItem.sign = m[1];
|
|
59
|
+
if (i === fields.length - 1) {
|
|
60
|
+
delete treeItem.projection;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
target = treeItem.projection = treeItem.projection || new FieldsProjection();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -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;
|
package/esm/index.js
CHANGED
|
@@ -28,4 +28,5 @@ export * from './orm/decorators/link.decorator.js';
|
|
|
28
28
|
export * from './orm/decorators/primarykey.decorator.js';
|
|
29
29
|
export * from './orm/decorators/transform.decorator.js';
|
|
30
30
|
export { isColumnField, isEmbeddedField, isAssociationField, isEntityClass } from './orm/util/orm.helper.js';
|
|
31
|
+
export * from './orm/util/parse-fields-projection.js';
|
|
31
32
|
export * from './orm/backward.js';
|