@opra/sqb 1.0.0-alpha.2 → 1.0.0-alpha.21
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/cjs/adapter-utils/parse-filter.js +5 -5
- package/cjs/augmentation/datatype-factory.augmentation.js +6 -2
- package/cjs/sqb-adapter.js +9 -4
- package/cjs/sqb-collection-service.js +71 -60
- package/cjs/sqb-entity-service.js +115 -101
- package/cjs/sqb-singleton-service.js +38 -31
- package/esm/adapter-utils/parse-filter.js +4 -4
- package/esm/augmentation/datatype-factory.augmentation.js +6 -2
- package/esm/sqb-adapter.js +9 -4
- package/esm/sqb-collection-service.js +71 -60
- package/esm/sqb-entity-service.js +115 -101
- package/esm/sqb-singleton-service.js +38 -31
- package/package.json +12 -8
- package/types/sqb-collection-service.d.ts +8 -8
- package/types/sqb-entity-service.d.ts +101 -87
- package/types/sqb-singleton-service.d.ts +5 -5
|
@@ -4,6 +4,7 @@ exports.SqbEntityService = void 0;
|
|
|
4
4
|
const common_1 = require("@opra/common");
|
|
5
5
|
const core_1 = require("@opra/core");
|
|
6
6
|
const connect_1 = require("@sqb/connect");
|
|
7
|
+
const valgen_1 = require("valgen");
|
|
7
8
|
const sqb_adapter_js_1 = require("./sqb-adapter.js");
|
|
8
9
|
/**
|
|
9
10
|
* @class SqbEntityService
|
|
@@ -19,12 +20,13 @@ class SqbEntityService extends core_1.ServiceBase {
|
|
|
19
20
|
*/
|
|
20
21
|
constructor(dataType, options) {
|
|
21
22
|
super();
|
|
22
|
-
this.
|
|
23
|
+
this._inputCodecs = {};
|
|
24
|
+
this._outputCodecs = {};
|
|
23
25
|
this._dataType_ = dataType;
|
|
24
26
|
this.db = options?.db;
|
|
25
|
-
this
|
|
26
|
-
this
|
|
27
|
-
this
|
|
27
|
+
this.resourceName = options?.resourceName;
|
|
28
|
+
this.commonFilter = options?.commonFilter;
|
|
29
|
+
this.interceptor = options?.interceptor;
|
|
28
30
|
}
|
|
29
31
|
/**
|
|
30
32
|
* Retrieves the OPRA data type
|
|
@@ -68,145 +70,145 @@ class SqbEntityService extends core_1.ServiceBase {
|
|
|
68
70
|
* @throws {Error} If the collection name is not defined.
|
|
69
71
|
*/
|
|
70
72
|
getResourceName() {
|
|
71
|
-
const out = typeof this
|
|
73
|
+
const out = typeof this.resourceName === 'function' ? this.resourceName(this) : this.resourceName || this.dataType.name;
|
|
72
74
|
if (out)
|
|
73
75
|
return out;
|
|
74
76
|
throw new Error('resourceName is not defined');
|
|
75
77
|
}
|
|
76
78
|
/**
|
|
77
|
-
* Retrieves the
|
|
79
|
+
* Retrieves the codec for the specified operation.
|
|
78
80
|
*
|
|
79
81
|
* @param operation - The operation to retrieve the encoder for. Valid values are 'create' and 'update'.
|
|
80
82
|
*/
|
|
81
|
-
|
|
82
|
-
let
|
|
83
|
-
if (
|
|
84
|
-
return
|
|
83
|
+
getInputCodec(operation) {
|
|
84
|
+
let validator = this._inputCodecs[operation];
|
|
85
|
+
if (validator)
|
|
86
|
+
return validator;
|
|
85
87
|
const options = { projection: '*' };
|
|
86
88
|
if (operation === 'update')
|
|
87
89
|
options.partial = 'deep';
|
|
88
90
|
const dataType = this.dataType;
|
|
89
|
-
|
|
90
|
-
this.
|
|
91
|
-
return
|
|
91
|
+
validator = dataType.generateCodec('decode', options);
|
|
92
|
+
this._inputCodecs[operation] = validator;
|
|
93
|
+
return validator;
|
|
92
94
|
}
|
|
93
95
|
/**
|
|
94
|
-
* Retrieves the
|
|
96
|
+
* Retrieves the codec.
|
|
95
97
|
*/
|
|
96
|
-
|
|
97
|
-
let
|
|
98
|
-
if (
|
|
99
|
-
return
|
|
98
|
+
getOutputCodec(operation) {
|
|
99
|
+
let validator = this._outputCodecs[operation];
|
|
100
|
+
if (validator)
|
|
101
|
+
return validator;
|
|
100
102
|
const options = { projection: '*', partial: 'deep' };
|
|
101
103
|
const dataType = this.dataType;
|
|
102
|
-
|
|
103
|
-
this.
|
|
104
|
-
return
|
|
104
|
+
validator = dataType.generateCodec('decode', options);
|
|
105
|
+
this._outputCodecs[operation] = validator;
|
|
106
|
+
return validator;
|
|
105
107
|
}
|
|
106
108
|
/**
|
|
107
109
|
* Insert a new record into database
|
|
108
110
|
*
|
|
109
|
-
* @param
|
|
110
|
-
* @
|
|
111
|
-
* @returns {Promise<PartialDTO<T>>} A promise that resolves to the created resource
|
|
112
|
-
* @throws {InternalServerError} if an unknown error occurs while creating the resource
|
|
111
|
+
* @param command
|
|
112
|
+
* @returns - A promise that resolves to the created resource
|
|
113
113
|
* @protected
|
|
114
114
|
*/
|
|
115
|
-
async _create(
|
|
116
|
-
const
|
|
117
|
-
|
|
115
|
+
async _create(command) {
|
|
116
|
+
const { input, options } = command;
|
|
117
|
+
(0, valgen_1.isNotNullish)(command.input, { label: 'input' });
|
|
118
|
+
const inputCodec = this.getInputCodec('create');
|
|
119
|
+
const outputCodec = this.getOutputCodec('create');
|
|
120
|
+
const data = inputCodec(input);
|
|
118
121
|
const out = await this._dbCreate(data, options);
|
|
119
122
|
if (out)
|
|
120
|
-
return out;
|
|
123
|
+
return outputCodec(out);
|
|
121
124
|
throw new common_1.InternalServerError(`Unknown error while creating document for "${this.getResourceName()}"`);
|
|
122
125
|
}
|
|
123
126
|
/**
|
|
124
127
|
* Returns the count of records based on the provided options
|
|
125
128
|
*
|
|
126
|
-
* @param
|
|
127
|
-
* @return
|
|
129
|
+
* @param command
|
|
130
|
+
* @return - A promise that resolves to the count of records
|
|
128
131
|
* @protected
|
|
129
132
|
*/
|
|
130
|
-
async _count(
|
|
131
|
-
return this._dbCount(options);
|
|
133
|
+
async _count(command) {
|
|
134
|
+
return this._dbCount(command.options);
|
|
132
135
|
}
|
|
133
136
|
/**
|
|
134
137
|
* Deletes a record from the collection.
|
|
135
138
|
*
|
|
136
|
-
* @param
|
|
137
|
-
* @
|
|
138
|
-
* @return {Promise<number>} - A Promise that resolves to the number of documents deleted.
|
|
139
|
+
* @param command
|
|
140
|
+
* @return - A Promise that resolves to the number of documents deleted.
|
|
139
141
|
* @protected
|
|
140
142
|
*/
|
|
141
|
-
async _delete(
|
|
142
|
-
|
|
143
|
+
async _delete(command) {
|
|
144
|
+
(0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
|
|
145
|
+
return this._dbDelete(command.documentId, command.options);
|
|
143
146
|
}
|
|
144
147
|
/**
|
|
145
148
|
* Deletes multiple documents from the collection that meet the specified filter criteria.
|
|
146
149
|
*
|
|
147
|
-
* @param
|
|
148
|
-
* @return
|
|
150
|
+
* @param command
|
|
151
|
+
* @return - A promise that resolves to the number of documents deleted.
|
|
149
152
|
* @protected
|
|
150
153
|
*/
|
|
151
|
-
async _deleteMany(
|
|
152
|
-
return await this._dbDeleteMany(options);
|
|
154
|
+
async _deleteMany(command) {
|
|
155
|
+
return await this._dbDeleteMany(command.options);
|
|
153
156
|
}
|
|
154
157
|
/**
|
|
155
158
|
* Checks if a record with the given id exists.
|
|
156
159
|
*
|
|
157
|
-
* @param
|
|
158
|
-
* @param {SqbEntityService.ExistsOptions} [options] - The options for the query (optional).
|
|
159
|
-
* @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
|
|
160
|
+
* @param command
|
|
160
161
|
* @protected
|
|
161
162
|
*/
|
|
162
|
-
async _exists(
|
|
163
|
-
|
|
163
|
+
async _exists(command) {
|
|
164
|
+
(0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
|
|
165
|
+
return await this._dbExists(command.documentId, command.options);
|
|
164
166
|
}
|
|
165
167
|
/**
|
|
166
168
|
* Checks if a record with the given arguments exists.
|
|
167
169
|
*
|
|
168
|
-
* @param
|
|
169
|
-
* @return
|
|
170
|
+
* @param command
|
|
171
|
+
* @return - A Promise that resolves to a boolean indicating whether the record exists or not.
|
|
170
172
|
* @protected
|
|
171
173
|
*/
|
|
172
|
-
async _existsOne(
|
|
173
|
-
return await this._dbExistsOne(options);
|
|
174
|
+
async _existsOne(command) {
|
|
175
|
+
return await this._dbExistsOne(command.options);
|
|
174
176
|
}
|
|
175
177
|
/**
|
|
176
178
|
* Finds a record by ID.
|
|
177
179
|
*
|
|
178
|
-
* @param
|
|
179
|
-
* @
|
|
180
|
-
* @return {Promise<PartialDTO<T | undefined>>} - A promise resolving to the found document, or undefined if not found.
|
|
180
|
+
* @param command
|
|
181
|
+
* @return - A promise resolving to the found document, or undefined if not found.
|
|
181
182
|
* @protected
|
|
182
183
|
*/
|
|
183
|
-
async _findById(
|
|
184
|
-
|
|
185
|
-
const
|
|
184
|
+
async _findById(command) {
|
|
185
|
+
(0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
|
|
186
|
+
const decode = this.getOutputCodec('find');
|
|
187
|
+
const out = await this._dbFindById(command.documentId, command.options);
|
|
186
188
|
return out ? decode(out) : undefined;
|
|
187
189
|
}
|
|
188
190
|
/**
|
|
189
191
|
* Finds a record in the collection that matches the specified options.
|
|
190
192
|
*
|
|
191
|
-
* @param
|
|
192
|
-
* @return
|
|
193
|
+
* @param command
|
|
194
|
+
* @return - A promise that resolves with the found document or undefined if no document is found.
|
|
193
195
|
* @protected
|
|
194
196
|
*/
|
|
195
|
-
async _findOne(
|
|
196
|
-
const decode = this.
|
|
197
|
-
const out = await this._dbFindOne(options);
|
|
197
|
+
async _findOne(command) {
|
|
198
|
+
const decode = this.getOutputCodec('find');
|
|
199
|
+
const out = await this._dbFindOne(command.options);
|
|
198
200
|
return out ? decode(out) : undefined;
|
|
199
201
|
}
|
|
200
202
|
/**
|
|
201
203
|
* Finds multiple records in collection.
|
|
202
204
|
*
|
|
203
|
-
* @param
|
|
204
|
-
* @return A Promise that resolves to an array of partial outputs of type T.
|
|
205
|
+
* @param command
|
|
206
|
+
* @return - A Promise that resolves to an array of partial outputs of type T.
|
|
205
207
|
* @protected
|
|
206
208
|
*/
|
|
207
|
-
async _findMany(
|
|
208
|
-
const decode = this.
|
|
209
|
-
const out = await this._dbFindMany(options);
|
|
209
|
+
async _findMany(command) {
|
|
210
|
+
const decode = this.getOutputCodec('find');
|
|
211
|
+
const out = await this._dbFindMany(command.options);
|
|
210
212
|
if (out?.length) {
|
|
211
213
|
return out.map(x => decode(x));
|
|
212
214
|
}
|
|
@@ -215,47 +217,48 @@ class SqbEntityService extends core_1.ServiceBase {
|
|
|
215
217
|
/**
|
|
216
218
|
* Updates a record with the given id in the collection.
|
|
217
219
|
*
|
|
218
|
-
* @param
|
|
219
|
-
* @
|
|
220
|
-
* @param {SqbEntityService.UpdateOptions} [options] - The options for the update operation.
|
|
221
|
-
* @returns {Promise<PartialDTO<T> | undefined>} A promise that resolves to the updated document or
|
|
222
|
-
* undefined if the document was not found.
|
|
220
|
+
* @param command
|
|
221
|
+
* @returns A promise that resolves to the updated document or undefined if the document was not found.
|
|
223
222
|
* @protected
|
|
224
223
|
*/
|
|
225
|
-
async _update(
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const
|
|
229
|
-
const
|
|
224
|
+
async _update(command) {
|
|
225
|
+
(0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
|
|
226
|
+
(0, valgen_1.isNotNullish)(command.input, { label: 'input' });
|
|
227
|
+
const { documentId, input, options } = command;
|
|
228
|
+
const inputCodec = this.getInputCodec('update');
|
|
229
|
+
const data = inputCodec(input);
|
|
230
|
+
const out = await this._dbUpdate(documentId, data, options);
|
|
231
|
+
const outputCodec = this.getOutputCodec('update');
|
|
230
232
|
if (out)
|
|
231
|
-
return
|
|
233
|
+
return outputCodec(out);
|
|
232
234
|
}
|
|
233
235
|
/**
|
|
234
236
|
* Updates a record in the collection with the specified ID and returns updated record count
|
|
235
237
|
*
|
|
236
|
-
* @param
|
|
237
|
-
* @
|
|
238
|
-
* @param {SqbEntityService.UpdateOptions} options - The options for updating the document.
|
|
239
|
-
* @returns {Promise<number>} - A promise that resolves to the number of documents modified.
|
|
238
|
+
* @param command
|
|
239
|
+
* @returns - A promise that resolves to the number of documents modified.
|
|
240
240
|
* @protected
|
|
241
241
|
*/
|
|
242
|
-
async _updateOnly(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
242
|
+
async _updateOnly(command) {
|
|
243
|
+
(0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
|
|
244
|
+
(0, valgen_1.isNotNullish)(command.input, { label: 'input' });
|
|
245
|
+
const { documentId, input, options } = command;
|
|
246
|
+
const inputCodec = this.getInputCodec('update');
|
|
247
|
+
const data = inputCodec(input);
|
|
248
|
+
return await this._dbUpdateOnly(documentId, data, options);
|
|
246
249
|
}
|
|
247
250
|
/**
|
|
248
251
|
* Updates multiple records in the collection based on the specified input and options.
|
|
249
252
|
*
|
|
250
|
-
* @param
|
|
251
|
-
* @
|
|
252
|
-
* @return {Promise<number>} - A promise that resolves to the number of documents matched and modified.
|
|
253
|
+
* @param command
|
|
254
|
+
* @return - A promise that resolves to the number of documents matched and modified.
|
|
253
255
|
* @protected
|
|
254
256
|
*/
|
|
255
|
-
async _updateMany(
|
|
256
|
-
|
|
257
|
-
const
|
|
258
|
-
|
|
257
|
+
async _updateMany(command) {
|
|
258
|
+
(0, valgen_1.isNotNullish)(command.input, { label: 'input' });
|
|
259
|
+
const inputCodec = this.getInputCodec('update');
|
|
260
|
+
const data = inputCodec(command.input);
|
|
261
|
+
return await this._dbUpdateMany(data, command.options);
|
|
259
262
|
}
|
|
260
263
|
/**
|
|
261
264
|
* Acquires a connection and performs Repository.create operation
|
|
@@ -442,17 +445,28 @@ class SqbEntityService extends core_1.ServiceBase {
|
|
|
442
445
|
* that resolves to the common filter, or undefined if not available.
|
|
443
446
|
*/
|
|
444
447
|
_getCommonFilter(args) {
|
|
445
|
-
return typeof this
|
|
446
|
-
}
|
|
447
|
-
async
|
|
448
|
+
return typeof this.commonFilter === 'function' ? this.commonFilter(args, this) : this.commonFilter;
|
|
449
|
+
}
|
|
450
|
+
async _executeCommand(command, commandFn) {
|
|
451
|
+
let proto;
|
|
452
|
+
const next = async () => {
|
|
453
|
+
proto = proto ? Object.getPrototypeOf(proto) : this;
|
|
454
|
+
while (proto) {
|
|
455
|
+
if (proto.interceptor && Object.prototype.hasOwnProperty.call(proto, 'interceptor')) {
|
|
456
|
+
return await proto.interceptor.call(this, next, command, this);
|
|
457
|
+
}
|
|
458
|
+
proto = Object.getPrototypeOf(proto);
|
|
459
|
+
if (!(proto instanceof SqbEntityService))
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
return commandFn();
|
|
463
|
+
};
|
|
448
464
|
try {
|
|
449
|
-
|
|
450
|
-
return this.$interceptor(callback, args, this);
|
|
451
|
-
return callback();
|
|
465
|
+
return await next();
|
|
452
466
|
}
|
|
453
467
|
catch (e) {
|
|
454
|
-
Error.captureStackTrace(e, this.
|
|
455
|
-
await this
|
|
468
|
+
Error.captureStackTrace(e, this._executeCommand);
|
|
469
|
+
await this.onError?.(e, this);
|
|
456
470
|
throw e;
|
|
457
471
|
}
|
|
458
472
|
}
|
|
@@ -40,27 +40,29 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
|
|
|
40
40
|
* @throws {Error} if an unknown error occurs while creating the resource
|
|
41
41
|
*/
|
|
42
42
|
async create(input, options) {
|
|
43
|
-
const
|
|
43
|
+
const command = {
|
|
44
44
|
crud: 'create',
|
|
45
45
|
method: 'create',
|
|
46
46
|
byId: false,
|
|
47
47
|
input,
|
|
48
48
|
options,
|
|
49
49
|
};
|
|
50
|
-
return this.
|
|
50
|
+
return this._executeCommand(command, async () => {
|
|
51
51
|
const primaryFields = connect_1.EntityMetadata.getPrimaryIndexColumns(this.entityMetadata);
|
|
52
|
-
const data = { ...input };
|
|
52
|
+
const data = { ...command.input };
|
|
53
53
|
if (primaryFields.length > 1) {
|
|
54
|
-
if (typeof primaryFields !== 'object')
|
|
54
|
+
if (typeof primaryFields !== 'object') {
|
|
55
55
|
throw new TypeError(`"${this.entityMetadata.name}" should has multiple primary key fields. So you should provide and object that contains key fields`);
|
|
56
|
+
}
|
|
56
57
|
for (const field of primaryFields) {
|
|
57
58
|
data[field.name] = this.id[field.name];
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
else
|
|
61
62
|
data[primaryFields[0].name] = this.id;
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
command.input = data;
|
|
64
|
+
return await this._create(command);
|
|
65
|
+
});
|
|
64
66
|
}
|
|
65
67
|
/**
|
|
66
68
|
* Deletes the singleton record
|
|
@@ -69,17 +71,18 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
|
|
|
69
71
|
* @return {Promise<number>} - A Promise that resolves to the number of records deleted
|
|
70
72
|
*/
|
|
71
73
|
async delete(options) {
|
|
72
|
-
const
|
|
74
|
+
const command = {
|
|
73
75
|
crud: 'delete',
|
|
74
76
|
method: 'delete',
|
|
75
77
|
byId: true,
|
|
76
78
|
documentId: this.id,
|
|
77
79
|
options,
|
|
78
80
|
};
|
|
79
|
-
return this.
|
|
80
|
-
const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
return this._executeCommand(command, async () => {
|
|
82
|
+
const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
|
|
83
|
+
command.options = { ...command.options, filter };
|
|
84
|
+
return this._delete(command);
|
|
85
|
+
});
|
|
83
86
|
}
|
|
84
87
|
/**
|
|
85
88
|
* Checks if the singleton record exists.
|
|
@@ -88,17 +91,18 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
|
|
|
88
91
|
* @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
|
|
89
92
|
*/
|
|
90
93
|
async exists(options) {
|
|
91
|
-
const
|
|
94
|
+
const command = {
|
|
92
95
|
crud: 'read',
|
|
93
96
|
method: 'exists',
|
|
94
97
|
byId: true,
|
|
95
98
|
documentId: this.id,
|
|
96
99
|
options,
|
|
97
100
|
};
|
|
98
|
-
return this.
|
|
99
|
-
const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
return this._executeCommand(command, async () => {
|
|
102
|
+
const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
|
|
103
|
+
command.options = { ...command.options, filter };
|
|
104
|
+
return this._exists(command);
|
|
105
|
+
});
|
|
102
106
|
}
|
|
103
107
|
/**
|
|
104
108
|
* Finds the singleton record. Returns `undefined` if not found
|
|
@@ -107,17 +111,18 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
|
|
|
107
111
|
* @return {Promise<PartialDTO<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
|
|
108
112
|
*/
|
|
109
113
|
async find(options) {
|
|
110
|
-
const
|
|
114
|
+
const command = {
|
|
111
115
|
crud: 'read',
|
|
112
116
|
method: 'findById',
|
|
113
117
|
byId: true,
|
|
114
118
|
documentId: this.id,
|
|
115
119
|
options,
|
|
116
120
|
};
|
|
117
|
-
return this.
|
|
118
|
-
const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
return this._executeCommand(command, async () => {
|
|
122
|
+
const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
|
|
123
|
+
command.options = { ...command.options, filter };
|
|
124
|
+
return this._findById(command);
|
|
125
|
+
});
|
|
121
126
|
}
|
|
122
127
|
/**
|
|
123
128
|
* Retrieves the singleton record. Throws error if not found.
|
|
@@ -142,7 +147,7 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
|
|
|
142
147
|
* undefined if the document was not found.
|
|
143
148
|
*/
|
|
144
149
|
async update(input, options) {
|
|
145
|
-
const
|
|
150
|
+
const command = {
|
|
146
151
|
crud: 'update',
|
|
147
152
|
method: 'update',
|
|
148
153
|
documentId: this.id,
|
|
@@ -150,10 +155,11 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
|
|
|
150
155
|
input,
|
|
151
156
|
options,
|
|
152
157
|
};
|
|
153
|
-
return this.
|
|
154
|
-
const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(
|
|
155
|
-
|
|
156
|
-
|
|
158
|
+
return this._executeCommand(command, async () => {
|
|
159
|
+
const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
|
|
160
|
+
command.options = { ...command.options, filter };
|
|
161
|
+
return this._update(command);
|
|
162
|
+
});
|
|
157
163
|
}
|
|
158
164
|
/**
|
|
159
165
|
* Updates the singleton and returns updated record count
|
|
@@ -163,7 +169,7 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
|
|
|
163
169
|
* @returns {Promise<number>} - A promise that resolves to the number of documents modified.
|
|
164
170
|
*/
|
|
165
171
|
async updateOnly(input, options) {
|
|
166
|
-
const
|
|
172
|
+
const command = {
|
|
167
173
|
crud: 'update',
|
|
168
174
|
method: 'update',
|
|
169
175
|
documentId: this.id,
|
|
@@ -171,10 +177,11 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
|
|
|
171
177
|
input,
|
|
172
178
|
options,
|
|
173
179
|
};
|
|
174
|
-
return this.
|
|
175
|
-
const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(
|
|
176
|
-
|
|
177
|
-
|
|
180
|
+
return this._executeCommand(command, async () => {
|
|
181
|
+
const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
|
|
182
|
+
command.options = { ...command.options, filter };
|
|
183
|
+
return this._updateOnly(command);
|
|
184
|
+
});
|
|
178
185
|
}
|
|
179
186
|
}
|
|
180
187
|
exports.SqbSingletonService = SqbSingletonService;
|
|
@@ -75,13 +75,13 @@ function prepareFilterAst(ast) {
|
|
|
75
75
|
case '!in':
|
|
76
76
|
return sqb.Nin(left, right);
|
|
77
77
|
case 'like':
|
|
78
|
-
return sqb.Like(left, String(right).replace(
|
|
78
|
+
return sqb.Like(left, String(right).replace(/\*/g, '%'));
|
|
79
79
|
case 'ilike':
|
|
80
|
-
return sqb.Ilike(left, String(right).replace(
|
|
80
|
+
return sqb.Ilike(left, String(right).replace(/\*/g, '%'));
|
|
81
81
|
case '!like':
|
|
82
|
-
return sqb.NotLike(left, String(right).replace(
|
|
82
|
+
return sqb.NotLike(left, String(right).replace(/\*/g, '%'));
|
|
83
83
|
case '!ilike':
|
|
84
|
-
return sqb.NotILike(left, String(right).replace(
|
|
84
|
+
return sqb.NotILike(left, String(right).replace(/\*/g, '%'));
|
|
85
85
|
default:
|
|
86
86
|
throw new Error(`ComparisonExpression operator (${ast.op}) not implemented yet`);
|
|
87
87
|
}
|
|
@@ -57,16 +57,20 @@ DataTypeFactory._prepareComplexTypeArgs = async function (context, owner, initAr
|
|
|
57
57
|
if (hasNoType || fieldSchema.type === String)
|
|
58
58
|
fieldSchema.type = 'time';
|
|
59
59
|
break;
|
|
60
|
+
default:
|
|
61
|
+
break;
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
if (isAssociationField(sqbField)) {
|
|
63
65
|
if (sqbField.association.returnsMany())
|
|
64
66
|
fieldSchema.isArray = true;
|
|
65
|
-
if (!
|
|
67
|
+
if (!Object.prototype.hasOwnProperty.call(fieldSchema, 'exclusive'))
|
|
66
68
|
fieldSchema.exclusive = true;
|
|
67
69
|
}
|
|
68
|
-
if (!
|
|
70
|
+
if (!Object.prototype.hasOwnProperty.call(fieldSchema, 'exclusive') &&
|
|
71
|
+
Object.prototype.hasOwnProperty.call(sqbField, 'exclusive')) {
|
|
69
72
|
fieldSchema.exclusive = sqbField.exclusive;
|
|
73
|
+
}
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
return _prepareComplexTypeArgs.apply(DataTypeFactory, [context, owner, initArgs, metadata]);
|
package/esm/sqb-adapter.js
CHANGED
|
@@ -10,7 +10,7 @@ export var SQBAdapter;
|
|
|
10
10
|
const entityMetadata = EntityMetadata.get(dataType.ctor);
|
|
11
11
|
if (!entityMetadata)
|
|
12
12
|
throw new Error(`Type class "${dataType.ctor}" is not an SQB entity`);
|
|
13
|
-
const
|
|
13
|
+
const controller = operation.owner;
|
|
14
14
|
switch (operation.composition) {
|
|
15
15
|
case 'Entity.Create': {
|
|
16
16
|
const data = await context.getBody();
|
|
@@ -20,7 +20,8 @@ export var SQBAdapter;
|
|
|
20
20
|
return { method: 'create', data, options };
|
|
21
21
|
}
|
|
22
22
|
case 'Entity.Delete': {
|
|
23
|
-
const
|
|
23
|
+
const keyParam = operation.parameters.find(p => p.keyParam) || controller.parameters.find(p => p.keyParam);
|
|
24
|
+
const key = keyParam && context.pathParams[String(keyParam.name)];
|
|
24
25
|
const options = {
|
|
25
26
|
filter: SQBAdapter.parseFilter(context.queryParams.filter),
|
|
26
27
|
};
|
|
@@ -44,7 +45,8 @@ export var SQBAdapter;
|
|
|
44
45
|
return { method: 'findMany', options };
|
|
45
46
|
}
|
|
46
47
|
case 'Entity.Get': {
|
|
47
|
-
const
|
|
48
|
+
const keyParam = operation.parameters.find(p => p.keyParam) || controller.parameters.find(p => p.keyParam);
|
|
49
|
+
const key = keyParam && context.pathParams[String(keyParam.name)];
|
|
48
50
|
const options = {
|
|
49
51
|
projection: context.queryParams.projection,
|
|
50
52
|
filter: SQBAdapter.parseFilter(context.queryParams.filter),
|
|
@@ -53,7 +55,8 @@ export var SQBAdapter;
|
|
|
53
55
|
}
|
|
54
56
|
case 'Entity.Update': {
|
|
55
57
|
const data = await context.getBody();
|
|
56
|
-
const
|
|
58
|
+
const keyParam = operation.parameters.find(p => p.keyParam) || controller.parameters.find(p => p.keyParam);
|
|
59
|
+
const key = keyParam && context.pathParams[String(keyParam.name)];
|
|
57
60
|
const options = {
|
|
58
61
|
projection: context.queryParams.projection,
|
|
59
62
|
filter: SQBAdapter.parseFilter(context.queryParams.filter),
|
|
@@ -67,6 +70,8 @@ export var SQBAdapter;
|
|
|
67
70
|
};
|
|
68
71
|
return { method: 'updateMany', data, options };
|
|
69
72
|
}
|
|
73
|
+
default:
|
|
74
|
+
break;
|
|
70
75
|
}
|
|
71
76
|
}
|
|
72
77
|
throw new Error(`This operation is not compatible to SQB Adapter`);
|