@samet-it/be-couchbase-common 1.0.16 → 1.1.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.
Files changed (40) hide show
  1. package/README.md +10 -10
  2. package/dist/config/couchbase-common.config.d.ts +5 -1
  3. package/dist/config/couchbase-common.config.js +15 -9
  4. package/dist/config/index.types.d.ts +17 -13
  5. package/dist/connection/cb-connection.fn.d.ts +8 -0
  6. package/dist/connection/cb-connection.fn.js +14 -0
  7. package/dist/connection/cb-direct.connection.d.ts +13 -0
  8. package/dist/connection/cb-direct.connection.js +21 -0
  9. package/dist/connection/cb.connection.d.ts +35 -0
  10. package/dist/{adapter/cb-adapter.service.js → connection/cb.connection.js} +99 -127
  11. package/dist/connection/index.d.ts +4 -0
  12. package/dist/{adapter → connection}/index.js +3 -2
  13. package/dist/connection/index.types.d.ts +94 -0
  14. package/dist/filter/cb-filter-util.impl.js +4 -4
  15. package/dist/filter/index.types.d.ts +4 -2
  16. package/dist/index.d.ts +1 -3
  17. package/dist/index.js +1 -6
  18. package/dist/repo/cb-direct.repo.d.ts +11 -0
  19. package/dist/repo/cb-direct.repo.js +37 -0
  20. package/dist/repo/cb-schema.error.d.ts +4 -0
  21. package/dist/repo/cb-schema.error.js +10 -0
  22. package/dist/repo/cb.repo.d.ts +43 -61
  23. package/dist/repo/cb.repo.js +480 -269
  24. package/dist/repo/index.d.ts +2 -0
  25. package/dist/repo/index.js +2 -0
  26. package/dist/repo/index.types.d.ts +121 -93
  27. package/package.json +8 -5
  28. package/dist/adapter/cb-adapter.module.d.ts +0 -2
  29. package/dist/adapter/cb-adapter.module.js +0 -23
  30. package/dist/adapter/cb-adapter.service.d.ts +0 -46
  31. package/dist/adapter/index.d.ts +0 -3
  32. package/dist/adapter/index.types.d.ts +0 -135
  33. package/dist/assets/source.MD +0 -1
  34. package/dist/line/cb-line.impl.d.ts +0 -2
  35. package/dist/line/cb-line.impl.js +0 -119
  36. package/dist/line/index.d.ts +0 -2
  37. package/dist/line/index.js +0 -18
  38. package/dist/line/index.types.d.ts +0 -62
  39. package/dist/line/index.types.js +0 -2
  40. /package/dist/{adapter → connection}/index.types.js +0 -0
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- // ~~console.log(__filename);
3
2
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
3
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
4
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -12,144 +11,85 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
12
11
  Object.defineProperty(exports, "__esModule", { value: true });
13
12
  exports.CbRepo = void 0;
14
13
  const couchbase_1 = require("couchbase");
15
- const common_1 = require("@leyyo/common");
16
- const config_1 = require("../config");
17
- const line_1 = require("../line");
18
- const node_crypto_1 = require("node:crypto");
19
- const common_2 = require("@nestjs/common");
20
- let F_ID;
14
+ const be_db_common_1 = require("@samet-it/be-db-common");
15
+ const type_1 = require("@leyyo/type");
16
+ const type_2 = require("@leyyo/type");
17
+ const cb_schema_error_1 = require("./cb-schema.error");
21
18
  let F_URN;
19
+ let F_ID;
22
20
  let F_TRASH_ID;
23
- // noinspection JSUnusedGlobalSymbols
24
- class CbRepo {
25
- constructor(colName, cb, _scopeName, _bucketName) {
26
- this.colName = colName;
27
- this.cb = cb;
28
- this._scopeName = _scopeName;
29
- this._bucketName = _bucketName;
30
- this._tryCount = 0;
31
- this.logger = new common_2.Logger(this.constructor.name);
32
- if (!F_ID) {
33
- F_ID = cb.f('id');
34
- F_URN = cb.f('_urn');
35
- F_TRASH_ID = cb.f('_trashId');
36
- }
37
- }
38
- get _randomIndexName() {
39
- return 'idx_' + (0, node_crypto_1.randomUUID)().match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
40
- .map(s => s.toLowerCase())
41
- .join('_');
42
- }
43
- _indexName(name) {
44
- if (typeof name !== 'string') {
45
- return this._randomIndexName;
46
- }
47
- name = name.trim();
48
- if (name === '') {
49
- return this._randomIndexName;
21
+ /**
22
+ * Couchbase repository abstract class
23
+ * */
24
+ class CbRepo extends be_db_common_1.DbRepo {
25
+ // endregion protected-property
26
+ constructor(conn, opt) {
27
+ var _a, _b, _c;
28
+ super(conn, opt);
29
+ conn.onFirstConnected(() => this._afterConnected());
30
+ const { _props: props } = this;
31
+ props.bucketName = this._checkName(props.bucketName);
32
+ props.scopeName = this._checkName(props.scopeName);
33
+ props.collectionName = this._checkName(props.collectionName);
34
+ props.bucketName = (_a = props.bucketName) !== null && _a !== void 0 ? _a : conn.props.bucketName;
35
+ props.scopeName = (_b = props.scopeName) !== null && _b !== void 0 ? _b : conn.props.scopeName;
36
+ props.createIndices = (_c = props.createIndices) !== null && _c !== void 0 ? _c : conn.props.createIndices;
37
+ if (!props.bucketName) {
38
+ throw new be_db_common_1.DbInvalidValueError('Bucket', typeof props.bucketName, 'CbRepo', 'constructor');
50
39
  }
51
- name = name.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
52
- .map(s => s.toLowerCase())
53
- .join('_');
54
- name = name.replace(/^_+|_+$/g, '');
55
- if (name === '') {
56
- return this._randomIndexName;
40
+ if (!props.scopeName) {
41
+ throw new be_db_common_1.DbInvalidValueError('Scope', typeof props.scopeName, 'CbRepo', 'constructor');
57
42
  }
58
- if (!name.startsWith('idx_')) {
59
- name = 'idx_' + name;
43
+ if (!props.collectionName) {
44
+ throw new be_db_common_1.DbInvalidValueError('Collection', typeof props.collectionName, 'CbRepo', 'constructor');
60
45
  }
61
- if (name.length > 30) {
62
- name = name.substring(0, 30);
63
- }
64
- return name;
65
- }
66
- /**
67
- * Fetch urn from doc as doc._urn
68
- * */
69
- _urnFromDoc(doc, method) {
70
- common_1.$assert.object(doc, () => {
71
- return { field: 'doc', where: 'CbRepo', path: this.path, method };
72
- });
73
- const urn = doc._urn;
74
- common_1.$assert.text(urn, () => {
75
- return { field: 'urn', where: 'CbRepo', path: this.path, method };
76
- });
77
- return urn;
78
- }
79
- /**
80
- * Check array keys as id list or urn list
81
- * */
82
- _checkKeys(keys) {
83
- if (!keys || !Array.isArray(keys) || keys.length < 1) {
84
- return [];
46
+ if (!F_URN) {
47
+ F_URN = props.conn.f('_urn');
48
+ F_ID = props.conn.f('id');
49
+ F_TRASH_ID = props.conn.f('_trashId');
85
50
  }
86
- return keys
87
- .map(item => {
88
- switch (typeof item) {
89
- case 'string':
90
- const str = item.trim();
91
- return str ? str : undefined;
92
- case 'number':
93
- return item;
94
- default:
95
- return undefined;
96
- }
97
- })
98
- .filter(item => item !== undefined);
99
51
  }
100
- /**
101
- * Build update sql as set and unset
102
- * */
103
- _updateSql(urn, doc) {
104
- const cb = this.cb;
105
- const set = [];
106
- const unset = [];
107
- for (const [k, v] of Object.entries(doc)) {
108
- if (!['_urn', 'id'].includes(k)) {
109
- if (v === undefined) {
110
- unset.push(cb.f(k));
111
- }
112
- else {
113
- set.push([cb.f(k), cb.v(v)]);
114
- }
52
+ // region protected-method
53
+ _checkName(value) {
54
+ if (typeof value === 'string') {
55
+ value = value.trim();
56
+ if (!value) {
57
+ value = undefined;
115
58
  }
116
59
  }
117
- const lines = (0, line_1.cbLine)();
118
- lines
119
- .add(`UPDATE ${this.fullPath}`)
120
- .add(`USE KEYS ${cb.v(urn)}`);
121
- if (unset.length > 0) {
122
- lines.add('UNSET ', unset.join(', '));
60
+ else {
61
+ value = undefined;
123
62
  }
124
- if (set.length > 0) {
125
- lines.add('SET ', set.join(',\n '));
126
- }
127
- lines.add(`RETURNING meta().id ${F_URN}`);
128
- return lines.end();
63
+ return value;
129
64
  }
130
65
  /**
131
66
  * Execute the creation of index
132
67
  * */
133
68
  _createIndex(p1, name) {
134
69
  return __awaiter(this, void 0, void 0, function* () {
70
+ const { conn, full, path } = this._props;
135
71
  let sql;
136
72
  const fields = [];
137
73
  if (Array.isArray(p1)) {
138
74
  const given = p1;
139
- if (!common_1.$is.text(name)) {
75
+ if (!(0, type_1.isText)(name)) {
140
76
  name = given.map(item => item.split('.').pop()).join('.');
141
77
  }
142
- fields.push(...given.map(f => this.cb.f(f)));
78
+ fields.push(...given.map(f => conn.f(f)));
143
79
  }
144
80
  else {
145
81
  fields.push(p1);
146
82
  name = p1;
147
83
  }
148
84
  name = this._indexName(name);
149
- sql = `CREATE INDEX ${this.cb.f(name)} ON ${this.fullPath} (${fields.join(', ')})`;
150
- yield this.cb.one(this.def, sql, { name: `${this.path}.index`, ignoredErrors: [couchbase_1.IndexExistsError] });
85
+ sql = `CREATE INDEX ${conn.f(name)} ON ${full} (${fields.join(', ')}) IF NOT EXISTS`;
86
+ yield conn.one(this.$def, sql, {
87
+ name: `${path}.index`,
88
+ ignoredErrors: [couchbase_1.IndexExistsError.name]
89
+ });
151
90
  });
152
91
  }
92
+ // noinspection JSUnusedGlobalSymbols
153
93
  /**
154
94
  * Execute the creation of indexes with keys
155
95
  * */
@@ -165,9 +105,7 @@ class CbRepo {
165
105
  return true;
166
106
  })
167
107
  .map(k => this._createIndex(k));
168
- if (!this._pkIndexed) {
169
- promises.push(this._createPk());
170
- }
108
+ promises.push(this._createPk());
171
109
  if (promises.length > 0) {
172
110
  yield Promise.all(promises);
173
111
  }
@@ -178,246 +116,519 @@ class CbRepo {
178
116
  * */
179
117
  _createPk() {
180
118
  return __awaiter(this, void 0, void 0, function* () {
181
- if (!this._pkIndexed) {
182
- const sql = `CREATE PRIMARY INDEX \`pk\` ON ${this.fullPath}`;
183
- yield this.cb.one(this.def, sql, { name: `${this.path}.pk`, ignoredErrors: [couchbase_1.IndexExistsError] });
184
- this._pkIndexed = true;
185
- }
119
+ const { full, path, conn } = this._props;
120
+ const sql = `CREATE PRIMARY INDEX \`pk\` ON ${full} IF NOT EXISTS`;
121
+ yield conn.one(this.$def, sql, {
122
+ name: `${path}.pk`,
123
+ ignoredErrors: [couchbase_1.IndexExistsError.name]
124
+ });
186
125
  });
187
126
  }
188
127
  /** @inheritDoc */
189
- get def() {
190
- return this;
128
+ _afterConnected() {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ const { _props: props } = this;
131
+ props.cluster = props.conn.props.cluster;
132
+ yield this._loadBucket();
133
+ yield this._loadScope();
134
+ yield this._loadCollection();
135
+ props.path = `${props.bucket.name}.${props.scope.name}.${props.collection.name}`;
136
+ props.full = props.conn.f(props.path);
137
+ if (props.createIndices) {
138
+ yield this.$createIndices();
139
+ }
140
+ });
191
141
  }
192
- /** @inheritDoc */
193
- onModuleInit() {
142
+ _loadBucket() {
194
143
  return __awaiter(this, void 0, void 0, function* () {
195
- var _a, _b;
196
- const cb = this.cb;
197
- const mutable = this;
198
- try {
199
- mutable.cluster = yield cb.connectDb();
200
- mutable.bucket = this.cluster.bucket((_a = this._bucketName) !== null && _a !== void 0 ? _a : config_1.couchbaseCommonConfig.raw.CB_BUCKET);
201
- mutable.scope = this.bucket.scope((_b = this._scopeName) !== null && _b !== void 0 ? _b : config_1.couchbaseCommonConfig.raw.CB_SCOPE);
202
- mutable.collection = this.scope.collection(this.colName);
203
- mutable.path = `${this.bucket.name}.${this.scope.name}.${this.collection.name}`;
204
- mutable.fullPath = cb.f(`${this.bucket.name}.${this.scope.name}.${this.collection.name}`);
205
- if (config_1.couchbaseCommonConfig.raw.CB_CREATE_INDICES) {
206
- yield this._createIndices();
144
+ const { _props: props } = this;
145
+ (0, type_2.assertText)(props.bucketName, { field: 'bucket', where: 'CbRepo', method: '_loadBucket' });
146
+ let spec = Array.from(CbRepo._specs.keys())
147
+ .find(s => s.name === props.bucketName);
148
+ if (!spec) {
149
+ const bucketManager = props.cluster.buckets();
150
+ const allBuckets = yield bucketManager.getAllBuckets();
151
+ spec = allBuckets.find(b => b.name === props.bucketName);
152
+ if (!spec) {
153
+ throw new cb_schema_error_1.CbSchemaError('Bucket', props.bucketName, 'CbRepo', '_loadBucket');
207
154
  }
155
+ CbRepo._specs.set(spec, []);
208
156
  }
209
- catch (e) {
210
- if (this._tryCount > 100) {
211
- throw e;
157
+ const ins = props.cluster.bucket(props.bucketName);
158
+ ins.$spec = spec;
159
+ props.bucket = ins;
160
+ });
161
+ }
162
+ _loadScope() {
163
+ return __awaiter(this, void 0, void 0, function* () {
164
+ const { _props: props } = this;
165
+ (0, type_2.assertText)(props.scopeName, { field: 'scopeName', where: 'CbRepo', method: '_loadScope' });
166
+ let spec = CbRepo._specs.get(props.bucket.$spec)
167
+ .find(s => s.name === props.scopeName);
168
+ if (!spec) {
169
+ const scopeManager = props.bucket.collections();
170
+ const allScopes = yield scopeManager.getAllScopes();
171
+ spec = allScopes.find(s => s.name === props.scopeName);
172
+ if (!spec) {
173
+ throw new cb_schema_error_1.CbSchemaError('Scope', `${props.bucketName}.${props.scopeName}`, 'CbRepo', '_loadScope');
212
174
  }
213
- this._tryCount++;
214
- setTimeout(() => this.onModuleInit().then().catch(e2 => {
215
- throw e2;
216
- }), 1000);
175
+ CbRepo._specs.get(props.bucket.$spec).push(spec);
176
+ }
177
+ const ins = props.bucket.scope(props.scopeName);
178
+ ins.$spec = spec;
179
+ props.scope = ins;
180
+ });
181
+ }
182
+ _loadCollection() {
183
+ return __awaiter(this, void 0, void 0, function* () {
184
+ const { _props: props } = this;
185
+ (0, type_2.assertText)(props.collectionName, { field: 'collectionName', where: 'CbRepo', method: '_loadCollection' });
186
+ const spec = props.scope.$spec.collections
187
+ .find(s => s.name === props.collectionName);
188
+ if (!spec) {
189
+ throw new cb_schema_error_1.CbSchemaError('Collection', `${props.bucketName}.${props.scopeName}.${props.collectionName}`, 'CbRepo', '_loadCollection');
217
190
  }
191
+ const ins = props.scope.collection(props.collectionName);
192
+ ins.$spec = spec;
193
+ props.collection = ins;
194
+ });
195
+ }
196
+ /**
197
+ * Create indices in final repo
198
+ * */
199
+ $createIndices() {
200
+ return __awaiter(this, void 0, void 0, function* () {
201
+ // can be overloaded
218
202
  });
219
203
  }
204
+ // endregion protected-method
205
+ // region getter
206
+ /** @inheritDoc */
207
+ get $def() {
208
+ return this;
209
+ }
210
+ /** @inheritDoc */
211
+ get props() {
212
+ return this._props;
213
+ }
214
+ // endregion getter
215
+ // region get
220
216
  /** @inheritDoc */
221
- urnById(id, p1) {
217
+ $getByPrimary(key, p1, ignoreCheck) {
222
218
  return __awaiter(this, void 0, void 0, function* () {
223
- var _a;
224
- const cb = this.cb;
225
- const opt = cb.buildOpt(p1, 'urnById');
226
- const lines = (0, line_1.cbLine)();
219
+ if (!ignoreCheck) {
220
+ (0, type_2.assertText)(key, { field: 'id', where: 'CbRepo', method: '$getByPrimary' });
221
+ }
222
+ const { conn, useSoftDelete, collection, full } = this._props;
223
+ const opt = conn.buildOpt(p1, '$getById');
224
+ if (!useSoftDelete) {
225
+ if (!Array.isArray(opt.ignoredErrors)) {
226
+ opt.ignoredErrors = [];
227
+ }
228
+ opt.ignoredErrors.push(couchbase_1.DocumentNotFoundError.name);
229
+ const result = yield conn.exec(collection.get(key, opt), opt);
230
+ return result === null || result === void 0 ? void 0 : result.content;
231
+ }
232
+ const lines = (0, be_db_common_1.dbLines)();
227
233
  lines
228
- .add(`SELECT meta().id as ${F_URN}`)
229
- .add(`FROM ${this.fullPath} a`)
230
- .add(`WHERE (a.${F_ID} = ${cb.v(id)})`)
231
- .add(`AND (a.${F_TRASH_ID} is missing)`)
234
+ .add(`SELECT a.*`)
235
+ .add(`FROM ${full} a`)
236
+ .add(`USE KEYS $key`)
237
+ .add(`WHERE (a.${F_TRASH_ID} is missing)`)
232
238
  .add('LIMIT 1');
233
- return (_a = (yield cb.one(this, lines.end(), opt)).row) === null || _a === void 0 ? void 0 : _a._urn;
239
+ const parameters = { key };
240
+ return (yield conn.one(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }))).row;
234
241
  });
235
242
  }
236
243
  /** @inheritDoc */
237
- existsByUrn(urn, p1) {
244
+ $getBySecondary(key, p1, ignoreCheck) {
238
245
  return __awaiter(this, void 0, void 0, function* () {
239
- var _a;
240
- const cb = this.cb;
241
- const opt = cb.buildOpt(p1, 'existsByUrn');
242
- const lines = (0, line_1.cbLine)();
246
+ const { conn, useSoftDelete, useNumericId, full } = this._props;
247
+ if (!ignoreCheck) {
248
+ if (useNumericId) {
249
+ (0, type_1.assertInteger)(key, { field: 'key', where: 'CbRepo', method: '$getBySecondary' });
250
+ }
251
+ else {
252
+ (0, type_2.assertText)(key, { field: 'key', where: 'CbRepo', method: '$getBySecondary' });
253
+ }
254
+ }
255
+ const opt = conn.buildOpt(p1, '$getBySecondary');
256
+ const lines = (0, be_db_common_1.dbLines)();
243
257
  lines
244
- .add(`SELECT meta().id as ${F_URN}`)
245
- .add(`FROM ${this.fullPath} a`)
246
- .add(`USE KEYS ${cb.v(urn)}`)
247
- .add(`WHERE (a.${F_TRASH_ID} IS MISSING)`)
258
+ .add(`SELECT a.*`)
259
+ .add(`FROM ${full} a`)
260
+ .add(`WHERE (a.${F_ID} = $key)`)
261
+ .no(useSoftDelete, ` AND (a.${F_TRASH_ID} is missing)`)
248
262
  .add('LIMIT 1');
249
- return ((_a = (yield cb.one(this, lines.end(), opt)).row) === null || _a === void 0 ? void 0 : _a._urn) !== undefined;
263
+ const parameters = { key };
264
+ return (yield conn.one(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }))).row;
250
265
  });
251
266
  }
267
+ // endregion get
268
+ // region exists
252
269
  /** @inheritDoc */
253
- existsById(id, p1) {
270
+ $existsByPrimary(key, p1, ignoreCheck) {
254
271
  return __awaiter(this, void 0, void 0, function* () {
255
- const opt = this.cb.buildOpt(p1, 'existsById');
256
- return (yield this.urnById(id, opt)) !== undefined;
272
+ var _a, _b, _c;
273
+ if (!ignoreCheck) {
274
+ (0, type_2.assertText)(key, { field: 'key', where: 'CbRepo', method: '$existsByPrimary' });
275
+ }
276
+ const { useSoftDelete, conn, collection, full } = this._props;
277
+ const opt = conn.buildOpt(p1, '$existsByPrimary');
278
+ if (!useSoftDelete) {
279
+ return (_b = (_a = (yield conn.exec(collection.exists(key, opt), opt))) === null || _a === void 0 ? void 0 : _a.exists) !== null && _b !== void 0 ? _b : false;
280
+ }
281
+ const lines = (0, be_db_common_1.dbLines)();
282
+ lines
283
+ .add(`SELECT meta().id \`x\``)
284
+ .add(`FROM ${full} a`)
285
+ .add(`USE KEYS $key`)
286
+ .add(`WHERE (a.${F_TRASH_ID} is missing)`)
287
+ .add('LIMIT 1');
288
+ const parameters = { key };
289
+ return ((_c = (yield conn.one(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }))).row) === null || _c === void 0 ? void 0 : _c.x) === undefined;
257
290
  });
258
291
  }
259
292
  /** @inheritDoc */
260
- getByUrn(urn, p1) {
293
+ $existsBySecondary(key, p1, ignoreCheck) {
261
294
  return __awaiter(this, void 0, void 0, function* () {
262
- const cb = this.cb;
263
- const opt = cb.buildOpt(p1, 'getByUrn');
264
- const lines = (0, line_1.cbLine)();
295
+ var _a;
296
+ const { useSoftDelete, useNumericId, conn, full } = this._props;
297
+ if (!ignoreCheck) {
298
+ if (useNumericId) {
299
+ (0, type_1.assertInteger)(key, { field: 'key', where: 'CbRepo', method: '$existsBySecondary' });
300
+ }
301
+ else {
302
+ (0, type_2.assertText)(key, { field: 'key', where: 'CbRepo', method: '$existsBySecondary' });
303
+ }
304
+ }
305
+ const opt = conn.buildOpt(p1, '$existsBySecondary');
306
+ const lines = (0, be_db_common_1.dbLines)();
265
307
  lines
266
- .add(`SELECT a.*`)
267
- .add(`FROM ${this.fullPath} a`)
268
- .add(`USE KEYS ${cb.v(urn)}`)
269
- .add(`WHERE (a.${F_TRASH_ID} IS MISSING)`)
308
+ .add(`SELECT meta().id \`x\``)
309
+ .add(`FROM ${full} a`)
310
+ .add(`USE KEYS $key`)
311
+ .yes(useSoftDelete, `WHERE (a.${F_TRASH_ID} IS MISSING)`)
270
312
  .add('LIMIT 1');
271
- return (yield cb.one(this, lines.end(), opt)).row;
313
+ const parameters = { key };
314
+ return ((_a = (yield conn.one(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }))).row) === null || _a === void 0 ? void 0 : _a.x) === undefined;
272
315
  });
273
316
  }
317
+ // endregion exists
318
+ // region list
274
319
  /** @inheritDoc */
275
- getById(id, p1) {
320
+ $listByPrimary(keys, p1, ignoreCheck) {
276
321
  return __awaiter(this, void 0, void 0, function* () {
277
- const cb = this.cb;
278
- const opt = cb.buildOpt(p1, 'getById');
279
- const lines = (0, line_1.cbLine)();
322
+ if (!ignoreCheck) {
323
+ (0, type_2.assertArray)(keys, { field: 'keys', where: 'CbRepo', method: '$listByPrimary' });
324
+ keys.forEach((key, index) => {
325
+ (0, type_2.assertText)(key, { field: 'key', where: 'CbRepo', method: '$listByPrimary', index });
326
+ });
327
+ }
328
+ const { useSoftDelete, conn, full } = this._props;
329
+ const opt = conn.buildOpt(p1, '$listByIds');
330
+ const lines = (0, be_db_common_1.dbLines)();
280
331
  lines
281
332
  .add(`SELECT a.*`)
282
- .add(`FROM ${this.fullPath} a`)
283
- .add(`WHERE (a.${F_ID} = ${cb.v(id)})`)
284
- .add(`AND (a.${F_TRASH_ID} is missing)`)
285
- .add('LIMIT 1');
286
- return (yield cb.one(this, lines.end(), opt)).row;
333
+ .add(`FROM ${full} a`)
334
+ .add(`USE KEYS $keys`)
335
+ .yes(useSoftDelete, `WHERE (a.${F_TRASH_ID} is missing)`);
336
+ const parameters = { keys };
337
+ return (yield conn.more(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }))).rows;
287
338
  });
288
339
  }
289
340
  /** @inheritDoc */
290
- listByUrn(urnList, p1) {
341
+ $listBySecondary(keys, p1, ignoreCheck) {
291
342
  return __awaiter(this, void 0, void 0, function* () {
292
- const cb = this.cb;
293
- const opt = cb.buildOpt(p1, 'listByUrn');
294
- urnList = this._checkKeys(urnList);
295
- if (urnList.length < 1) {
296
- return [];
343
+ const { useSoftDelete, useNumericId, conn, full } = this._props;
344
+ if (!ignoreCheck) {
345
+ (0, type_2.assertArray)(keys, { field: 'keys', where: 'CbRepo', method: '$listBySecondary' });
346
+ keys.forEach((key, index) => {
347
+ if (useNumericId) {
348
+ (0, type_1.assertInteger)(key, { field: 'key', where: 'CbRepo', method: '$listBySecondary', index });
349
+ }
350
+ else {
351
+ (0, type_2.assertText)(key, { field: 'key', where: 'CbRepo', method: '$listBySecondary', index });
352
+ }
353
+ });
297
354
  }
298
- const lines = (0, line_1.cbLine)();
355
+ const opt = conn.buildOpt(p1, '$listBySecondary');
356
+ const lines = (0, be_db_common_1.dbLines)();
299
357
  lines
300
358
  .add(`SELECT a.*`)
301
- .add(`FROM ${this.fullPath} a`)
302
- .add(`USE KEYS ${cb.v(urnList)}`)
303
- .add(`WHERE (a.${F_TRASH_ID} IS MISSING)`);
304
- return (yield cb.more(this, lines.end(), opt)).rows;
359
+ .add(`FROM ${full} a`)
360
+ .add(`WHERE (a.${F_ID} IN $keys)`)
361
+ .yes(useSoftDelete, ` AND (a.${F_TRASH_ID} IS MISSING)`);
362
+ const parameters = { keys };
363
+ return (yield conn.more(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }))).rows;
305
364
  });
306
365
  }
366
+ // endregion list
367
+ // region filter
307
368
  /** @inheritDoc */
308
- listById(ids, p1) {
369
+ $filter(query, p1) {
309
370
  return __awaiter(this, void 0, void 0, function* () {
310
- const cb = this.cb;
311
- const opt = cb.buildOpt(p1, 'listById');
312
- ids = this._checkKeys(ids);
313
- if (ids.length < 1) {
314
- return [];
315
- }
316
- const lines = (0, line_1.cbLine)();
371
+ const { useSoftDelete, conn, full } = this._props;
372
+ const opt = conn.buildOpt(p1, '$filter');
373
+ // @todo - work for query builder
374
+ const lines = (0, be_db_common_1.dbLines)();
317
375
  lines
318
376
  .add(`SELECT a.*`)
319
- .add(`FROM ${this.fullPath} a`)
320
- .add(`WHERE (a.${F_ID} ${ids.length === 1 ? '=' : 'IN'} ${cb.v(ids)})`)
321
- .add(`AND (a.${F_TRASH_ID} is missing)`);
322
- return (yield cb.more(this, lines.end(), opt)).rows;
377
+ .add(`FROM ${full} a`)
378
+ .both(useSoftDelete, `WHERE (a.${F_TRASH_ID} is missing)`, `WHERE (meta().id is not missing)`);
379
+ return (yield conn.more(this.$def, lines.end(), opt)).rows;
323
380
  });
324
381
  }
382
+ // endregion filter
383
+ // region insert
325
384
  /** @inheritDoc */
326
- removeByUrn(urn, p1) {
385
+ $insert(doc, p1, ignoreCheck) {
327
386
  return __awaiter(this, void 0, void 0, function* () {
328
- var _a;
329
- const cb = this.cb;
330
- const opt = cb.buildOpt(p1, 'removeByUrn');
331
- const lines = (0, line_1.cbLine)();
332
- lines
333
- .add(`DELETE
334
- FROM ${this.fullPath} a`)
335
- .add(`USE KEYS ${cb.v(urn)}`)
336
- .add(`WHERE (a.${F_TRASH_ID} is missing)`)
337
- .add(`RETURNING a.${F_ID}`);
338
- return (_a = (yield cb.one(this, lines.end(), opt)).row) === null || _a === void 0 ? void 0 : _a.id;
387
+ const { conn, collection, useNumericId } = this._props;
388
+ if (!ignoreCheck) {
389
+ (0, type_2.assertObject)(doc, { field: 'doc', where: 'CbRepo', method: '$insert' });
390
+ (0, type_2.assertText)(doc._urn, { field: 'doc._urn', where: 'CbRepo', method: '$insert' });
391
+ if (useNumericId) {
392
+ (0, type_1.assertInteger)(doc.id, { field: 'doc.id', where: 'CbRepo', method: '$insert' });
393
+ }
394
+ else {
395
+ (0, type_2.assertText)(doc.id, { field: 'doc.id', where: 'CbRepo', method: '$insert' });
396
+ }
397
+ }
398
+ const opt = conn.buildOpt(p1, '$insert');
399
+ yield conn.exec(collection.insert(doc._urn, doc), opt);
400
+ return doc._urn;
339
401
  });
340
402
  }
403
+ // endregion insert
404
+ // region replace
341
405
  /** @inheritDoc */
342
- removeById(id, p1) {
406
+ $replace(doc, p1, ignoreCheck) {
343
407
  return __awaiter(this, void 0, void 0, function* () {
344
- var _a;
345
- const cb = this.cb;
346
- const opt = cb.buildOpt(p1, 'removeById');
347
- const lines = (0, line_1.cbLine)();
348
- lines
349
- .add(`DELETE FROM ${this.fullPath} a`)
350
- .add(`WHERE (a.${F_ID} = ${cb.v(id)})`)
351
- .add(`AND (a.${F_TRASH_ID} is missing)`)
352
- .add(`RETURNING meta().id ${F_URN}`);
353
- return (_a = (yield cb.one(this, lines.end(), opt)).row) === null || _a === void 0 ? void 0 : _a._urn;
408
+ const { conn, collection, useNumericId } = this._props;
409
+ if (!ignoreCheck) {
410
+ (0, type_2.assertObject)(doc, { field: 'doc', where: 'CbRepo', method: '$replace' });
411
+ (0, type_2.assertText)(doc._urn, { field: 'doc._urn', where: 'CbRepo', method: '$replace' });
412
+ if (useNumericId) {
413
+ (0, type_1.assertInteger)(doc.id, { field: 'doc.id', where: 'CbRepo', method: '$replace' });
414
+ }
415
+ else {
416
+ (0, type_2.assertText)(doc.id, { field: 'doc.id', where: 'CbRepo', method: '$replace' });
417
+ }
418
+ }
419
+ const opt = conn.buildOpt(p1, '$replace');
420
+ yield conn.exec(collection.replace(doc._urn, doc), opt);
421
+ return doc._urn;
354
422
  });
355
423
  }
424
+ // endregion replace
425
+ // region update
356
426
  /** @inheritDoc */
357
- insert(doc, p1) {
427
+ $updateByPrimary(key, doc, p1, ignoreCheck) {
358
428
  return __awaiter(this, void 0, void 0, function* () {
359
- const cb = this.cb;
360
- const opt = cb.buildOpt(p1, 'insert');
361
- const urn = this._urnFromDoc(doc, 'insert');
362
- doc.createdAt = new Date().toISOString();
363
- doc.updatedAt = new Date().toISOString();
364
- const result = yield cb.exec(this.collection.insert(urn, doc), opt);
365
- return (result === null || result === void 0 ? void 0 : result.token) ? result.token.toString() : 'inserted';
429
+ if (!ignoreCheck) {
430
+ (0, type_2.assertText)(key, { field: 'key', where: 'CbRepo', method: '$updateByPrimary' });
431
+ (0, type_2.assertObject)(doc, { field: 'doc', where: 'CbRepo', method: '$updateByPrimary' });
432
+ }
433
+ const { conn, full, useSoftDelete } = this._props;
434
+ const opt = conn.buildOpt(p1, '$updateByPrimary');
435
+ const parameters = {};
436
+ let paramId = 0;
437
+ const set = [];
438
+ const unset = [];
439
+ for (const [k, v] of Object.entries(doc)) {
440
+ if (v === undefined) {
441
+ unset.push('a.' + conn.f(k));
442
+ }
443
+ else {
444
+ set.push(['a.' + conn.f(k), '$param_' + paramId]);
445
+ parameters['param_' + paramId] = v;
446
+ paramId++;
447
+ }
448
+ }
449
+ if (set.length > 0 || unset.length > 0) {
450
+ const lines = (0, be_db_common_1.dbLines)();
451
+ lines.add(`UPDATE ${full} a`);
452
+ lines.add(`USE KEYS $key`);
453
+ parameters['key'] = key;
454
+ if (set.length > 0) {
455
+ lines.add('SET').add(set.join(',\n '));
456
+ }
457
+ if (unset.length > 0) {
458
+ lines.add('UNSET').add(unset.join(', '));
459
+ }
460
+ lines
461
+ .yes(useSoftDelete, `WHERE (a.${F_TRASH_ID} is missing)`);
462
+ yield conn.one(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }));
463
+ return key;
464
+ }
465
+ return undefined;
366
466
  });
367
467
  }
368
468
  /** @inheritDoc */
369
- replace(doc, p1) {
469
+ $updateBySecondary(key, doc, p1, ignoreCheck) {
370
470
  return __awaiter(this, void 0, void 0, function* () {
371
- const cb = this.cb;
372
- const opt = cb.buildOpt(p1, 'replace');
373
- const urn = this._urnFromDoc(doc, 'replace');
374
- doc.updatedAt = new Date().toISOString();
375
- const result = yield cb.exec(this.collection.replace(urn, doc), opt);
376
- return (result === null || result === void 0 ? void 0 : result.token) ? result.token.toString() : 'inserted';
471
+ var _a;
472
+ const { useNumericId, useSoftDelete, conn, full } = this._props;
473
+ if (!ignoreCheck) {
474
+ if (useNumericId) {
475
+ (0, type_1.assertInteger)(key, { field: 'key', where: 'CbRepo', method: '$updateBySecondary' });
476
+ }
477
+ else {
478
+ (0, type_2.assertText)(key, { field: 'key', where: 'CbRepo', method: '$updateBySecondary' });
479
+ }
480
+ (0, type_2.assertObject)(doc, { field: 'doc', where: 'CbRepo', method: '$updateBySecondary' });
481
+ }
482
+ const opt = conn.buildOpt(p1, '$updateBySecondary');
483
+ const parameters = {};
484
+ let paramId = 0;
485
+ const set = [];
486
+ const unset = [];
487
+ for (const [k, v] of Object.entries(doc)) {
488
+ if (v === undefined) {
489
+ unset.push('a.' + conn.f(k));
490
+ }
491
+ else {
492
+ set.push(['a.' + conn.f(k), '$param_' + paramId]);
493
+ parameters['param_' + paramId] = v;
494
+ paramId++;
495
+ }
496
+ }
497
+ if (set.length > 0 || unset.length > 0) {
498
+ const lines = (0, be_db_common_1.dbLines)();
499
+ lines.add(`UPDATE ${full} a`);
500
+ if (set.length > 0) {
501
+ lines.add('SET').add(set.join(',\n '));
502
+ }
503
+ if (unset.length > 0) {
504
+ lines.add('UNSET').add(unset.join(', '));
505
+ }
506
+ lines
507
+ .add(`WHERE (a.${F_ID} = $key)`)
508
+ .yes(useSoftDelete, ` AND (a.${F_TRASH_ID} is missing)`);
509
+ parameters['key'] = key;
510
+ lines.add('RETURNING meta().id \`x\`');
511
+ return (_a = (yield conn.one(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }))).row) === null || _a === void 0 ? void 0 : _a.x;
512
+ }
513
+ return undefined;
377
514
  });
378
515
  }
516
+ // endregion update
517
+ // region remove
379
518
  /** @inheritDoc */
380
- upsert(doc, p1) {
519
+ $removeByPrimary(key, p1, ignoreCheck) {
381
520
  return __awaiter(this, void 0, void 0, function* () {
382
- const cb = this.cb;
383
- const opt = cb.buildOpt(p1, 'upsert');
384
- const urn = this._urnFromDoc(doc, 'upsert');
385
- doc.updatedAt = new Date().toISOString();
386
- const result = yield cb.exec(this.collection.upsert(urn, doc), opt);
387
- return (result === null || result === void 0 ? void 0 : result.token) ? result.token.toString() : 'modified';
521
+ if (!ignoreCheck) {
522
+ (0, type_2.assertText)(key, { field: 'key', where: 'CbRepo', method: '$removeByPrimary' });
523
+ }
524
+ const { useSoftDelete, conn, full, collection } = this._props;
525
+ const opt = conn.buildOpt(p1, '$removeByPrimary');
526
+ if (!useSoftDelete) {
527
+ yield conn.exec(collection.remove(key, opt), opt);
528
+ return key;
529
+ }
530
+ const lines = (0, be_db_common_1.dbLines)();
531
+ lines
532
+ .add('DELETE')
533
+ .add(`FROM ${full} a`)
534
+ .add(`USE KEYS $key`)
535
+ .yes(useSoftDelete, ` AND (a.${F_TRASH_ID} is missing)`);
536
+ const parameters = { key };
537
+ yield conn.one(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }));
538
+ return key;
388
539
  });
389
540
  }
390
541
  /** @inheritDoc */
391
- update(doc, p1) {
542
+ $removeBySecondary(key, p1, ignoreCheck) {
392
543
  return __awaiter(this, void 0, void 0, function* () {
393
544
  var _a;
394
- const cb = this.cb;
395
- const opt = cb.buildOpt(p1, 'update');
396
- const urn = this._urnFromDoc(doc, 'update');
397
- doc.updatedAt = new Date().toISOString();
398
- doc.updatedAt = new Date().toISOString();
399
- const sql = this._updateSql(urn, doc);
400
- return (_a = (yield cb.one(this, sql, opt)).row) === null || _a === void 0 ? void 0 : _a._urn;
545
+ const { useNumericId, useSoftDelete, conn, full } = this._props;
546
+ if (!ignoreCheck) {
547
+ if (useNumericId) {
548
+ (0, type_1.assertInteger)(key, { field: 'key', where: 'CbRepo', method: '$removeBySecondary' });
549
+ }
550
+ else {
551
+ (0, type_2.assertText)(key, { field: 'key', where: 'CbRepo', method: '$removeBySecondary' });
552
+ }
553
+ }
554
+ const opt = conn.buildOpt(p1, '$removeBySecondary');
555
+ const lines = (0, be_db_common_1.dbLines)();
556
+ lines
557
+ .add('DELETE')
558
+ .add(`FROM ${full} a`)
559
+ .add(`WHERE (a.${F_ID} = $key)`)
560
+ .yes(useSoftDelete, ` AND (a.${F_TRASH_ID} is missing)`)
561
+ .add('RETURNING meta().id \`x\`');
562
+ const parameters = { key };
563
+ return (_a = (yield conn.one(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }))).row) === null || _a === void 0 ? void 0 : _a.x;
401
564
  });
402
565
  }
566
+ // endregion remove
567
+ // region trash
403
568
  /** @inheritDoc */
404
- trash(doc, p1) {
569
+ $trashByPrimary(key, p1, ignoreCheck) {
405
570
  return __awaiter(this, void 0, void 0, function* () {
406
- const cb = this.cb;
407
- const opt = cb.buildOpt(p1, 'trash');
408
- const urn = this._urnFromDoc(doc, 'trash');
409
- if (opt.trashId === undefined) {
410
- opt.trashId = (0, node_crypto_1.randomUUID)();
571
+ const { useSoftDelete, conn, full } = this._props;
572
+ if (!useSoftDelete) {
573
+ throw new be_db_common_1.DbNotSupportedError('Soft delete', 'CbRepo', '$trashByPrimary');
411
574
  }
412
- const lines = (0, line_1.cbLine)();
575
+ if (!ignoreCheck) {
576
+ (0, type_2.assertText)(key, { field: 'key', where: 'CbRepo', method: '$trashByPrimary' });
577
+ }
578
+ const opt = conn.buildOpt(p1, '$trashByPrimary');
579
+ const lines = (0, be_db_common_1.dbLines)();
413
580
  lines
414
- .add(`UPDATE ${this.fullPath} a`)
415
- .add(`USE KEYS ${cb.v(urn)}`)
416
- .add(`SET a.${F_TRASH_ID} = ${cb.v(opt.trashId)}`)
581
+ .add(`UPDATE ${full} a`)
582
+ .add(`SET`)
583
+ .add(` \`updatedAt\` = $updated,`)
584
+ .add(` ${F_TRASH_ID} = $trashId`)
585
+ .add(`USE KEYS $key`)
417
586
  .add(`WHERE (a.${F_TRASH_ID} is missing)`);
418
- yield cb.one(this, lines.end(), opt);
419
- return opt.trashId;
587
+ const parameters = {
588
+ updated: this._now,
589
+ trashId: opt.trashId,
590
+ key,
591
+ };
592
+ yield conn.one(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }));
593
+ return key;
594
+ });
595
+ }
596
+ /** @inheritDoc */
597
+ $trashBySecondary(key, p1, ignoreCheck) {
598
+ return __awaiter(this, void 0, void 0, function* () {
599
+ var _a;
600
+ const { useSoftDelete, useNumericId, conn, full } = this._props;
601
+ if (!useSoftDelete) {
602
+ throw new be_db_common_1.DbNotSupportedError('Soft delete', 'CbRepo', '$trashBySecondary');
603
+ }
604
+ if (!ignoreCheck) {
605
+ if (useNumericId) {
606
+ (0, type_1.assertInteger)(key, { field: 'key', where: 'CbRepo', method: '$trashBySecondary' });
607
+ }
608
+ else {
609
+ (0, type_2.assertText)(key, { field: 'key', where: 'CbRepo', method: '$trashBySecondary' });
610
+ }
611
+ }
612
+ const opt = conn.buildOpt(p1, '$trashBySecondary');
613
+ const lines = (0, be_db_common_1.dbLines)();
614
+ lines
615
+ .add(`UPDATE ${full} a`)
616
+ .add(`SET`)
617
+ .add(` \`updatedAt\` = $updated,`)
618
+ .add(` ${F_TRASH_ID} = $trashId`)
619
+ .add(`WHERE (a.${F_ID} = $key)`)
620
+ .add(` AND (a.${F_TRASH_ID} is missing)`)
621
+ .add('RETURNING meta().id \`x\`');
622
+ const parameters = {
623
+ updated: this._now,
624
+ trashId: opt.trashId,
625
+ key,
626
+ };
627
+ return (_a = (yield conn.one(this.$def, lines.end(), Object.assign(Object.assign({}, opt), { parameters }))).row) === null || _a === void 0 ? void 0 : _a.x;
420
628
  });
421
629
  }
422
630
  }
423
631
  exports.CbRepo = CbRepo;
632
+ // region private-property
633
+ // {bucket: scope[]}
634
+ CbRepo._specs = new Map;