@samet-it/be-couchbase-common 1.0.8 → 1.0.10
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/dist/adapter/cb-adapter.service.d.ts +2 -23
- package/dist/adapter/cb-adapter.service.js +17 -180
- package/dist/adapter/index.types.d.ts +1 -39
- package/dist/filter/cb-filter-util.impl.js +11 -6
- package/dist/repo/cb.repo.d.ts +16 -0
- package/dist/repo/cb.repo.js +104 -47
- package/package.json +1 -1
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { Cluster,
|
|
1
|
+
import { Cluster, QueryResult } from 'couchbase';
|
|
2
2
|
import type { IgnoreFieldsByType, ReplaceType } from "@leyyo/common";
|
|
3
|
-
import type { CbAdapterServiceLike,
|
|
3
|
+
import type { CbAdapterServiceLike, CbExecOpt, CbQueryResultMore, CbQueryResultOne } from "./index.types";
|
|
4
4
|
import type { CbRepoDef } from "../repo";
|
|
5
5
|
export declare class CbAdapterService implements CbAdapterServiceLike {
|
|
6
6
|
private readonly _CLEAR_ERROR_INTERVAL;
|
|
7
7
|
private logger;
|
|
8
8
|
private _connected;
|
|
9
|
-
private _undefined;
|
|
10
9
|
private _cluster;
|
|
11
|
-
private readonly _cbErrors;
|
|
12
10
|
private readonly _nativeErrors;
|
|
13
11
|
constructor();
|
|
14
12
|
/**
|
|
@@ -19,25 +17,14 @@ export declare class CbAdapterService implements CbAdapterServiceLike {
|
|
|
19
17
|
* Ping to DB
|
|
20
18
|
* */
|
|
21
19
|
private _ping;
|
|
22
|
-
/**
|
|
23
|
-
* Execute the creation of index
|
|
24
|
-
* */
|
|
25
|
-
private _createIndex;
|
|
26
|
-
/**
|
|
27
|
-
* Build json format of CB object
|
|
28
|
-
* */
|
|
29
|
-
private _toJson;
|
|
30
20
|
protected _checkError(err: Error, opt: CbExecOpt): void;
|
|
31
21
|
/** {@inheritDoc} */
|
|
32
22
|
f(field: string): string;
|
|
33
23
|
/** {@inheritDoc} */
|
|
34
24
|
field(field: string): string;
|
|
35
|
-
s(value: string): string;
|
|
36
25
|
v(value: unknown): string;
|
|
37
26
|
value(value: unknown): string;
|
|
38
27
|
/** {@inheritDoc} */
|
|
39
|
-
string(value: string): string;
|
|
40
|
-
/** {@inheritDoc} */
|
|
41
28
|
flatten<T>(result: QueryResult<T>): Array<T>;
|
|
42
29
|
/** {@inheritDoc} */
|
|
43
30
|
rows<T>(rows: Array<T>): Array<T>;
|
|
@@ -46,14 +33,6 @@ export declare class CbAdapterService implements CbAdapterServiceLike {
|
|
|
46
33
|
/** {@inheritDoc} */
|
|
47
34
|
first<T>(rows: Array<T>): T | undefined;
|
|
48
35
|
/** {@inheritDoc} */
|
|
49
|
-
checkError(p1: string | Error, p2?: Error): void;
|
|
50
|
-
/** {@inheritDoc} */
|
|
51
|
-
createIndex<T = Record<string, unknown>>(coll: Collection, p1: (keyof T | string) | Array<keyof T | string>, name?: string): Promise<void>;
|
|
52
|
-
/** {@inheritDoc} */
|
|
53
|
-
createBaseIndices(coll: Collection, ...keys: Array<keyof CbEntity>): Promise<void>;
|
|
54
|
-
/** {@inheritDoc} */
|
|
55
|
-
createPk(coll: Collection): Promise<void>;
|
|
56
|
-
/** {@inheritDoc} */
|
|
57
36
|
castDates<T>(given: ReplaceType<T, Date, string> | T, ...fields: Array<IgnoreFieldsByType<T, Date>>): void;
|
|
58
37
|
/** {@inheritDoc} */
|
|
59
38
|
castDatesForList<T>(given: Array<ReplaceType<T, Date, string> | T>, ...fields: Array<IgnoreFieldsByType<T, Date>>): void;
|
|
@@ -55,24 +55,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
55
55
|
exports.CbAdapterService = void 0;
|
|
56
56
|
const couchbase = __importStar(require("couchbase"));
|
|
57
57
|
const common_1 = require("@nestjs/common");
|
|
58
|
-
const couchbase_1 = require("couchbase");
|
|
59
58
|
const config_1 = require("../config");
|
|
59
|
+
const common_2 = require("@leyyo/common");
|
|
60
60
|
// noinspection JSUnusedGlobalSymbols
|
|
61
61
|
let CbAdapterService = class CbAdapterService {
|
|
62
62
|
constructor() {
|
|
63
63
|
this._CLEAR_ERROR_INTERVAL = 1000 * 60 * 60 * 24; // daily
|
|
64
|
-
this._undefined = 0;
|
|
65
|
-
this._cbErrors = new Map();
|
|
66
64
|
this._nativeErrors = new Map();
|
|
67
65
|
this.logger = new common_1.Logger(this.constructor.name);
|
|
68
66
|
this._clearErrors();
|
|
69
|
-
this._cbErrors.set('AmbiguousTimeoutError', { count: 0, log: true, known: true });
|
|
70
|
-
this._cbErrors.set('AuthenticationFailureError', { count: 0, log: true, known: true });
|
|
71
|
-
this._cbErrors.set('ConnectionClosedError', { count: 0, log: true, known: true });
|
|
72
|
-
this._cbErrors.set('InternalServerFailureError', { count: 0, log: true, known: true });
|
|
73
|
-
this._cbErrors.set('ServiceNotAvailableError', { count: 0, log: true, known: true });
|
|
74
|
-
this._cbErrors.set('TimeoutError', { count: 0, log: true, known: true });
|
|
75
|
-
this._cbErrors.set('UnambiguousTimeoutError', { count: 0, log: true, known: true });
|
|
76
67
|
}
|
|
77
68
|
/**
|
|
78
69
|
* Clear native errors
|
|
@@ -90,113 +81,45 @@ let CbAdapterService = class CbAdapterService {
|
|
|
90
81
|
yield this.exec(this._cluster.ping(), { name: 'ping' });
|
|
91
82
|
}
|
|
92
83
|
catch (err) {
|
|
84
|
+
this.logger.warn(`Ping error => [${err.name}: ${err.message}]`);
|
|
93
85
|
}
|
|
94
86
|
setTimeout(() => this._ping(), 30000);
|
|
95
87
|
});
|
|
96
88
|
}
|
|
97
|
-
/**
|
|
98
|
-
* Execute the creation of index
|
|
99
|
-
* */
|
|
100
|
-
_createIndex(scope, sql) {
|
|
101
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
102
|
-
var _a;
|
|
103
|
-
try {
|
|
104
|
-
return yield scope.query(sql);
|
|
105
|
-
}
|
|
106
|
-
catch (e) {
|
|
107
|
-
if (e instanceof couchbase_1.IndexExistsError) {
|
|
108
|
-
return undefined;
|
|
109
|
-
}
|
|
110
|
-
this.logger.error(`!index[${(_a = e.name) !== null && _a !== void 0 ? _a : ''}] #${scope.name}] => ${sql}`, e);
|
|
111
|
-
// throw e; // TODO
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Build json format of CB object
|
|
117
|
-
* */
|
|
118
|
-
_toJson(val) {
|
|
119
|
-
if ([undefined, null].includes(val)) {
|
|
120
|
-
return 'null';
|
|
121
|
-
}
|
|
122
|
-
switch (typeof val) {
|
|
123
|
-
case "string":
|
|
124
|
-
case "number":
|
|
125
|
-
case "bigint":
|
|
126
|
-
case "boolean":
|
|
127
|
-
return JSON.stringify(val);
|
|
128
|
-
case "object":
|
|
129
|
-
if (Array.isArray(val)) {
|
|
130
|
-
return '[' + val
|
|
131
|
-
.filter(v => v !== undefined)
|
|
132
|
-
.map(v => this._toJson(v))
|
|
133
|
-
.join(', ') + ']';
|
|
134
|
-
}
|
|
135
|
-
else if (val instanceof Map) {
|
|
136
|
-
return this._toJson(Object.fromEntries(val.entries()));
|
|
137
|
-
}
|
|
138
|
-
else if (val instanceof Set) {
|
|
139
|
-
return this._toJson(Array.from(val.values()));
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
return '{' + Array.from(Object.entries(val))
|
|
143
|
-
.filter(item => item[1] !== undefined)
|
|
144
|
-
.map(item => {
|
|
145
|
-
const [k, v] = item;
|
|
146
|
-
return '`' + k + '`: ' + this._toJson(v);
|
|
147
|
-
}).join(', ') + '}';
|
|
148
|
-
}
|
|
149
|
-
case "symbol":
|
|
150
|
-
return JSON.stringify(val.description);
|
|
151
|
-
case "function":
|
|
152
|
-
case "undefined":
|
|
153
|
-
return 'null';
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
89
|
_checkError(err, opt) {
|
|
157
|
-
var _a;
|
|
90
|
+
var _a, _b, _c;
|
|
91
|
+
let size = 1;
|
|
158
92
|
if (!this._nativeErrors.has(err)) {
|
|
159
|
-
this._nativeErrors.set(err,
|
|
93
|
+
this._nativeErrors.set(err, size);
|
|
160
94
|
}
|
|
161
95
|
else {
|
|
162
|
-
|
|
96
|
+
size = this._nativeErrors.get(err) + 1;
|
|
97
|
+
this._nativeErrors.set(err, size);
|
|
163
98
|
}
|
|
164
99
|
if ((_a = opt === null || opt === void 0 ? void 0 : opt.ignoredErrors) === null || _a === void 0 ? void 0 : _a.includes(err)) {
|
|
165
|
-
this.logger.warn(
|
|
100
|
+
this.logger.warn(`[${size}] ${(_b = opt.name) !== null && _b !== void 0 ? _b : 'Ignored error'} => [${err.name}: ${err.message}]`);
|
|
166
101
|
return;
|
|
167
102
|
}
|
|
168
|
-
this.logger.
|
|
103
|
+
this.logger.error(`[${size}] ${(_c = opt.name) !== null && _c !== void 0 ? _c : 'Database error'} => [${err.name}: ${err.message}]`, JSON.stringify(err.context));
|
|
169
104
|
throw err;
|
|
170
105
|
}
|
|
171
106
|
/** {@inheritDoc} */
|
|
172
107
|
f(field) {
|
|
173
|
-
|
|
174
|
-
return field.split('.').map(part => this.f(part)).join('.');
|
|
175
|
-
}
|
|
176
|
-
else if (field.startsWith('`')) {
|
|
177
|
-
return field;
|
|
178
|
-
}
|
|
179
|
-
return `\`${field}\``;
|
|
108
|
+
return this.field(field);
|
|
180
109
|
}
|
|
181
110
|
/** {@inheritDoc} */
|
|
182
111
|
field(field) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
if (typeof value === 'string') {
|
|
187
|
-
return value.includes('"') ? this._toJson(value) : `"${value}"`;
|
|
112
|
+
field = field.trim();
|
|
113
|
+
if (field.includes('.')) {
|
|
114
|
+
return field.split('.').map(part => this.field(part)).join('.');
|
|
188
115
|
}
|
|
189
|
-
return
|
|
116
|
+
return field.startsWith('`') ? field : `\`${field}\``;
|
|
190
117
|
}
|
|
191
118
|
v(value) {
|
|
192
|
-
return this.
|
|
119
|
+
return this.value(value);
|
|
193
120
|
}
|
|
194
121
|
value(value) {
|
|
195
|
-
return
|
|
196
|
-
}
|
|
197
|
-
/** {@inheritDoc} */
|
|
198
|
-
string(value) {
|
|
199
|
-
return this.s(value);
|
|
122
|
+
return common_2.$dev.secureJson(value);
|
|
200
123
|
}
|
|
201
124
|
/** {@inheritDoc} */
|
|
202
125
|
flatten(result) {
|
|
@@ -227,91 +150,6 @@ let CbAdapterService = class CbAdapterService {
|
|
|
227
150
|
return undefined;
|
|
228
151
|
}
|
|
229
152
|
/** {@inheritDoc} */
|
|
230
|
-
checkError(p1, p2) {
|
|
231
|
-
var _a;
|
|
232
|
-
let op;
|
|
233
|
-
let err;
|
|
234
|
-
if (typeof p1 === 'string') {
|
|
235
|
-
p1 = p1.trim();
|
|
236
|
-
op = p1 ? `(${p1})` : '';
|
|
237
|
-
err = p2;
|
|
238
|
-
}
|
|
239
|
-
else {
|
|
240
|
-
op = '';
|
|
241
|
-
err = p1;
|
|
242
|
-
}
|
|
243
|
-
const name = (_a = err === null || err === void 0 ? void 0 : err.constructor) === null || _a === void 0 ? void 0 : _a.name;
|
|
244
|
-
if (name) {
|
|
245
|
-
if (!this._cbErrors.has(name)) {
|
|
246
|
-
this.logger.warn(`!first[${name}] #${op} [1]`, err);
|
|
247
|
-
this._cbErrors.set(name, { count: 1, log: true });
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
const obj = this._cbErrors.get(name);
|
|
251
|
-
obj.count++;
|
|
252
|
-
if (obj.known) {
|
|
253
|
-
this.logger.debug(`!known[${name}] #${op} [${obj.count}]`, err);
|
|
254
|
-
}
|
|
255
|
-
else {
|
|
256
|
-
this.logger.debug(`!unknown[${name}] #${op} [${obj.count}]`, err);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
this._undefined++;
|
|
262
|
-
this.logger.warn(`!undefined[] #${op} [${this._undefined}]`, err);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
/** {@inheritDoc} */
|
|
266
|
-
createIndex(coll, p1, name) {
|
|
267
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
268
|
-
if (Array.isArray(p1)) {
|
|
269
|
-
const fields = p1.map(f => f.split('.').map(part => '`' + part + '`').join('.'));
|
|
270
|
-
name = name.split('.').join('_').split('-').join('_');
|
|
271
|
-
if (!name.startsWith('idx_')) {
|
|
272
|
-
name = 'idx_' + name;
|
|
273
|
-
}
|
|
274
|
-
yield this._createIndex(coll.scope, `CREATE INDEX \`${name}\` ON \`${coll.name}\` (${fields.join(', ')})`);
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
const field = p1;
|
|
278
|
-
if (!name) {
|
|
279
|
-
name = 'idx_' + field.split('.').join('_').split('-').join('_');
|
|
280
|
-
}
|
|
281
|
-
else if (!name.startsWith('idx_')) {
|
|
282
|
-
name = 'idx_' + name;
|
|
283
|
-
}
|
|
284
|
-
yield this._createIndex(coll.scope, `CREATE INDEX \`${name}\` ON \`${coll.name}\` (${field.split('.').map(part => '`' + part + '`').join('.')})`);
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
/** {@inheritDoc} */
|
|
289
|
-
createBaseIndices(coll, ...keys) {
|
|
290
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
291
|
-
if (keys.includes('id')) {
|
|
292
|
-
yield this.createIndex(coll, 'id');
|
|
293
|
-
}
|
|
294
|
-
if (keys.includes('createdAt')) {
|
|
295
|
-
yield this.createIndex(coll, 'createdAt');
|
|
296
|
-
}
|
|
297
|
-
if (keys.includes('updatedAt')) {
|
|
298
|
-
yield this.createIndex(coll, 'updatedAt');
|
|
299
|
-
}
|
|
300
|
-
if (keys.includes('_trashId')) {
|
|
301
|
-
yield this.createIndex(coll, '_trashId', 'trashId');
|
|
302
|
-
}
|
|
303
|
-
if (keys.includes('_urn')) {
|
|
304
|
-
yield this.createIndex(coll, '_urn', 'urn');
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
/** {@inheritDoc} */
|
|
309
|
-
createPk(coll) {
|
|
310
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
311
|
-
yield this._createIndex(coll.scope, `CREATE PRIMARY INDEX \`pk\` ON \`${coll.name}\``);
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
/** {@inheritDoc} */
|
|
315
153
|
castDates(given, ...fields) {
|
|
316
154
|
if (fields.length < 1) {
|
|
317
155
|
return;
|
|
@@ -410,7 +248,6 @@ let CbAdapterService = class CbAdapterService {
|
|
|
410
248
|
/** {@inheritDoc} */
|
|
411
249
|
connectDb() {
|
|
412
250
|
return __awaiter(this, void 0, void 0, function* () {
|
|
413
|
-
var _a;
|
|
414
251
|
if (this._connected) {
|
|
415
252
|
return this._cluster;
|
|
416
253
|
}
|
|
@@ -426,7 +263,7 @@ let CbAdapterService = class CbAdapterService {
|
|
|
426
263
|
return this._cluster;
|
|
427
264
|
}
|
|
428
265
|
catch (e) {
|
|
429
|
-
this.logger.error(
|
|
266
|
+
this.logger.error(`Connection error => [${e.name}: ${e.message}]`);
|
|
430
267
|
throw e;
|
|
431
268
|
}
|
|
432
269
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Cluster, Collection, CouchbaseError, QueryMetaData, QueryOptions, QueryResult, Scope } from "couchbase";
|
|
2
2
|
import type { IgnoreFieldsByType, ReplaceType } from "@leyyo/common";
|
|
3
3
|
import type { CbRepoDef } from "../repo";
|
|
4
|
-
import { CouchbaseError } from "couchbase/dist/errors";
|
|
5
4
|
export interface CbAdapterServiceLike {
|
|
6
5
|
/**
|
|
7
6
|
* Field name
|
|
@@ -11,14 +10,6 @@ export interface CbAdapterServiceLike {
|
|
|
11
10
|
* Field name
|
|
12
11
|
* */
|
|
13
12
|
f(field: string): string;
|
|
14
|
-
/**
|
|
15
|
-
* Basic value: string
|
|
16
|
-
* */
|
|
17
|
-
string(value: string): string;
|
|
18
|
-
/**
|
|
19
|
-
* Basic value: string
|
|
20
|
-
* */
|
|
21
|
-
s(value: string): string;
|
|
22
13
|
/**
|
|
23
14
|
* Complex value
|
|
24
15
|
* */
|
|
@@ -43,30 +34,6 @@ export interface CbAdapterServiceLike {
|
|
|
43
34
|
* Return first row of rows
|
|
44
35
|
* */
|
|
45
36
|
first<T>(rows: Array<T>): T | undefined;
|
|
46
|
-
/**
|
|
47
|
-
* Check error
|
|
48
|
-
* */
|
|
49
|
-
checkError(err: Error): void;
|
|
50
|
-
/**
|
|
51
|
-
* Check error with operation
|
|
52
|
-
* */
|
|
53
|
-
checkError(op: string, err: Error): void;
|
|
54
|
-
/**
|
|
55
|
-
* Create index for multiple fields
|
|
56
|
-
* */
|
|
57
|
-
createIndex<T = Record<string, unknown>>(coll: Collection, fields: Array<keyof T | string>, name: string): Promise<void>;
|
|
58
|
-
/**
|
|
59
|
-
* Create index for a field
|
|
60
|
-
* */
|
|
61
|
-
createIndex<T = Record<string, unknown>>(coll: Collection, field: keyof T | string, name?: string): Promise<void>;
|
|
62
|
-
/**
|
|
63
|
-
* Create base indices for system fields
|
|
64
|
-
* */
|
|
65
|
-
createBaseIndices(coll: Collection, ...keys: Array<keyof CbEntity>): Promise<void>;
|
|
66
|
-
/**
|
|
67
|
-
* Create primary key
|
|
68
|
-
* */
|
|
69
|
-
createPk(coll: Collection): Promise<void>;
|
|
70
37
|
/**
|
|
71
38
|
* Cast dates
|
|
72
39
|
* */
|
|
@@ -140,11 +107,6 @@ export interface CbEntity {
|
|
|
140
107
|
* */
|
|
141
108
|
_trashId?: string;
|
|
142
109
|
}
|
|
143
|
-
export interface CbErrorRec {
|
|
144
|
-
count: number;
|
|
145
|
-
log: boolean;
|
|
146
|
-
known?: boolean;
|
|
147
|
-
}
|
|
148
110
|
type CbIgnoreFields<T, I> = {
|
|
149
111
|
[K in keyof T]: T[K] extends I ? K : never;
|
|
150
112
|
}[keyof T];
|
|
@@ -53,17 +53,17 @@ class CbFilterUtilImpl {
|
|
|
53
53
|
if (Array.isArray(items) && items.length > 0) {
|
|
54
54
|
items = items.map(v => (v instanceof Date) ? v.toISOString() : v);
|
|
55
55
|
if (items.length === 1) {
|
|
56
|
-
return `${this._where(opt)} ${field} =
|
|
56
|
+
return `${this._where(opt)} ${this.cb.f(field)} = ${this.cb.v(items[0])}`;
|
|
57
57
|
}
|
|
58
58
|
else {
|
|
59
|
-
return `${this._where(opt)} ${field} IN
|
|
59
|
+
return `${this._where(opt)} ${this.cb.f(field)} IN ${this.cb.v(items[0])}`;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
/** @inheritDoc */
|
|
64
64
|
sqlBool(opt, field, value) {
|
|
65
65
|
if (typeof value === 'boolean') {
|
|
66
|
-
return `${this._where(opt)} ${field} = ${value ? 'true' : 'false'}`;
|
|
66
|
+
return `${this._where(opt)} ${this.cb.f(field)} = ${value ? 'true' : 'false'}`;
|
|
67
67
|
}
|
|
68
68
|
return undefined;
|
|
69
69
|
}
|
|
@@ -72,17 +72,22 @@ class CbFilterUtilImpl {
|
|
|
72
72
|
if (Array.isArray(value) && value.length === 2) {
|
|
73
73
|
const [first, last] = value.map(v => (v instanceof Date) ? v.toISOString() : v);
|
|
74
74
|
if (first !== undefined && last !== undefined) {
|
|
75
|
-
return `${this._where(opt)} ${field} BETWEEN
|
|
75
|
+
return `${this._where(opt)} ${this.cb.f(field)} BETWEEN ${this.cb.v(first)} AND ${this.cb.v(last)}`;
|
|
76
76
|
}
|
|
77
77
|
else if (first !== undefined && last === undefined) {
|
|
78
|
-
return `${this._where(opt)} ${field} >=
|
|
78
|
+
return `${this._where(opt)} ${this.cb.f(field)} >= ${this.cb.v(first)}`;
|
|
79
79
|
}
|
|
80
80
|
else if (first === undefined && last !== undefined) {
|
|
81
|
-
return `${this._where(opt)} ${field} <=
|
|
81
|
+
return `${this._where(opt)} ${this.cb.f(field)} <= ${this.cb.v(last)}`;
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
return undefined;
|
|
85
85
|
}
|
|
86
|
+
$set(cb) {
|
|
87
|
+
if (!this.cb) {
|
|
88
|
+
this.cb = cb;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
86
91
|
}
|
|
87
92
|
// noinspection JSUnusedGlobalSymbols
|
|
88
93
|
exports.cbFilterUtil = new CbFilterUtilImpl();
|
package/dist/repo/cb.repo.d.ts
CHANGED
|
@@ -34,6 +34,22 @@ export declare abstract class CbRepo<E extends CbEntity, ID> implements CbRepoLi
|
|
|
34
34
|
* Build update sql as set and unset
|
|
35
35
|
* */
|
|
36
36
|
protected _updateSql<T>(urn: string, doc: T): string;
|
|
37
|
+
/**
|
|
38
|
+
* Execute the creation of index for one field
|
|
39
|
+
* */
|
|
40
|
+
protected _createIndex(field: keyof E | string, name?: string): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Execute the creation of index for complex fields
|
|
43
|
+
* */
|
|
44
|
+
protected _createIndex(fields: Array<keyof E | string>, name: string): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Execute the creation of indexes with keys
|
|
47
|
+
* */
|
|
48
|
+
protected _createMoreIndices(...keys: Array<keyof CbEntity>): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Execute the creation of primary key
|
|
51
|
+
* */
|
|
52
|
+
protected _createPk(): Promise<void>;
|
|
37
53
|
/**
|
|
38
54
|
* Create indices
|
|
39
55
|
* */
|
package/dist/repo/cb.repo.js
CHANGED
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.CbRepo = void 0;
|
|
14
|
+
const couchbase_1 = require("couchbase");
|
|
14
15
|
const common_1 = require("@leyyo/common");
|
|
15
16
|
const config_1 = require("../config");
|
|
16
17
|
const line_1 = require("../line");
|
|
@@ -29,9 +30,9 @@ class CbRepo {
|
|
|
29
30
|
this._tryCount = 0;
|
|
30
31
|
this.logger = new common_2.Logger(this.constructor.name);
|
|
31
32
|
if (!F_ID) {
|
|
32
|
-
F_ID =
|
|
33
|
-
F_URN =
|
|
34
|
-
F_TRASH_ID =
|
|
33
|
+
F_ID = cb.f('id');
|
|
34
|
+
F_URN = cb.f('_urn');
|
|
35
|
+
F_TRASH_ID = cb.f('_trashId');
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
@@ -57,10 +58,10 @@ class CbRepo {
|
|
|
57
58
|
return keys
|
|
58
59
|
.map(item => {
|
|
59
60
|
switch (typeof item) {
|
|
60
|
-
case
|
|
61
|
+
case 'string':
|
|
61
62
|
const str = item.trim();
|
|
62
63
|
return str ? str : undefined;
|
|
63
|
-
case
|
|
64
|
+
case 'number':
|
|
64
65
|
return item;
|
|
65
66
|
default:
|
|
66
67
|
return undefined;
|
|
@@ -72,22 +73,23 @@ class CbRepo {
|
|
|
72
73
|
* Build update sql as set and unset
|
|
73
74
|
* */
|
|
74
75
|
_updateSql(urn, doc) {
|
|
76
|
+
const cb = this.cb;
|
|
75
77
|
const set = [];
|
|
76
78
|
const unset = [];
|
|
77
79
|
for (const [k, v] of Object.entries(doc)) {
|
|
78
80
|
if (!['_urn', 'id'].includes(k)) {
|
|
79
81
|
if (v === undefined) {
|
|
80
|
-
unset.push(
|
|
82
|
+
unset.push(cb.f(k));
|
|
81
83
|
}
|
|
82
84
|
else {
|
|
83
|
-
set.push([
|
|
85
|
+
set.push([cb.f(k), cb.v(v)]);
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
const lines = (0, line_1.cbLine)();
|
|
88
90
|
lines
|
|
89
91
|
.add(`UPDATE ${this.fullPath}`)
|
|
90
|
-
.add(`USE KEYS ${
|
|
92
|
+
.add(`USE KEYS ${cb.v(urn)}`);
|
|
91
93
|
if (unset.length > 0) {
|
|
92
94
|
lines.add('UNSET ', unset.join(', '));
|
|
93
95
|
}
|
|
@@ -97,6 +99,48 @@ class CbRepo {
|
|
|
97
99
|
lines.add(`RETURNING meta().id ${F_URN}`);
|
|
98
100
|
return lines.end();
|
|
99
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Execute the creation of index
|
|
104
|
+
* */
|
|
105
|
+
_createIndex(p1, name) {
|
|
106
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
107
|
+
let sql;
|
|
108
|
+
const fields = [];
|
|
109
|
+
if (Array.isArray(p1)) {
|
|
110
|
+
fields.push(...p1.map(f => this.cb.f(f)));
|
|
111
|
+
if (common_1.$is.text(name)) {
|
|
112
|
+
name = fields[0];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
fields.push(p1);
|
|
117
|
+
}
|
|
118
|
+
if (!name.startsWith('idx_')) {
|
|
119
|
+
name = 'idx_' + name;
|
|
120
|
+
}
|
|
121
|
+
sql = `CREATE INDEX ${this.cb.f(name)} ON ${this.fullPath} (${fields.join(', ')})`;
|
|
122
|
+
yield this.cb.one(this.def, sql, { name: `${this.path}.index`, ignoredErrors: [couchbase_1.IndexExistsError] });
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Execute the creation of indexes with keys
|
|
127
|
+
* */
|
|
128
|
+
_createMoreIndices(...keys) {
|
|
129
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
const promises = keys.map(k => this._createIndex(k));
|
|
131
|
+
promises.push(this._createPk());
|
|
132
|
+
yield Promise.all(promises);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Execute the creation of primary key
|
|
137
|
+
* */
|
|
138
|
+
_createPk() {
|
|
139
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
140
|
+
const sql = `CREATE PRIMARY INDEX \`pk\` ON ${this.fullPath}`;
|
|
141
|
+
yield this.cb.one(this.def, sql, { name: `${this.path}.pk`, ignoredErrors: [couchbase_1.IndexExistsError] });
|
|
142
|
+
});
|
|
143
|
+
}
|
|
100
144
|
/** @inheritDoc */
|
|
101
145
|
get def() {
|
|
102
146
|
return this;
|
|
@@ -105,14 +149,15 @@ class CbRepo {
|
|
|
105
149
|
onModuleInit() {
|
|
106
150
|
return __awaiter(this, void 0, void 0, function* () {
|
|
107
151
|
var _a, _b;
|
|
152
|
+
const cb = this.cb;
|
|
108
153
|
const mutable = this;
|
|
109
154
|
try {
|
|
110
|
-
mutable.cluster = yield
|
|
155
|
+
mutable.cluster = yield cb.connectDb();
|
|
111
156
|
mutable.bucket = this.cluster.bucket((_a = this._bucketName) !== null && _a !== void 0 ? _a : config_1.couchbaseCommonConfig.raw.CB_BUCKET);
|
|
112
157
|
mutable.scope = this.bucket.scope((_b = this._scopeName) !== null && _b !== void 0 ? _b : config_1.couchbaseCommonConfig.raw.CB_SCOPE);
|
|
113
158
|
mutable.collection = this.scope.collection(this.colName);
|
|
114
159
|
mutable.path = `${this.bucket.name}.${this.scope.name}.${this.collection.name}`;
|
|
115
|
-
mutable.fullPath =
|
|
160
|
+
mutable.fullPath = cb.f(`${this.bucket.name}.${this.scope.name}.${this.collection.name}`);
|
|
116
161
|
if (config_1.couchbaseCommonConfig.raw.CB_CREATE_INDICES) {
|
|
117
162
|
yield this._createIndices();
|
|
118
163
|
}
|
|
@@ -122,7 +167,6 @@ class CbRepo {
|
|
|
122
167
|
throw e;
|
|
123
168
|
}
|
|
124
169
|
this._tryCount++;
|
|
125
|
-
this.logger.error(`[${this._tryCount}] ${e.name} => ${e.message}`);
|
|
126
170
|
setTimeout(() => this.onModuleInit().then().catch(e2 => {
|
|
127
171
|
throw e2;
|
|
128
172
|
}), 1000);
|
|
@@ -133,30 +177,32 @@ class CbRepo {
|
|
|
133
177
|
urnById(id, p1) {
|
|
134
178
|
return __awaiter(this, void 0, void 0, function* () {
|
|
135
179
|
var _a;
|
|
136
|
-
const
|
|
180
|
+
const cb = this.cb;
|
|
181
|
+
const opt = cb.buildOpt(p1, 'urnById');
|
|
137
182
|
const lines = (0, line_1.cbLine)();
|
|
138
183
|
lines
|
|
139
184
|
.add(`SELECT meta().id as ${F_URN}`)
|
|
140
185
|
.add(`FROM ${this.fullPath} a`)
|
|
141
|
-
.add(`WHERE (a.${F_ID} = ${
|
|
186
|
+
.add(`WHERE (a.${F_ID} = ${cb.v(id)})`)
|
|
142
187
|
.add(`AND (a.${F_TRASH_ID} is missing)`)
|
|
143
188
|
.add('LIMIT 1');
|
|
144
|
-
return (_a = (yield
|
|
189
|
+
return (_a = (yield cb.one(this, lines.end(), opt)).row) === null || _a === void 0 ? void 0 : _a._urn;
|
|
145
190
|
});
|
|
146
191
|
}
|
|
147
192
|
/** @inheritDoc */
|
|
148
193
|
existsByUrn(urn, p1) {
|
|
149
194
|
return __awaiter(this, void 0, void 0, function* () {
|
|
150
195
|
var _a;
|
|
151
|
-
const
|
|
196
|
+
const cb = this.cb;
|
|
197
|
+
const opt = cb.buildOpt(p1, 'existsByUrn');
|
|
152
198
|
const lines = (0, line_1.cbLine)();
|
|
153
199
|
lines
|
|
154
200
|
.add(`SELECT meta().id as ${F_URN}`)
|
|
155
201
|
.add(`FROM ${this.fullPath} a`)
|
|
156
|
-
.add(`USE KEYS ${
|
|
202
|
+
.add(`USE KEYS ${cb.v(urn)}`)
|
|
157
203
|
.add(`WHERE (a.${F_TRASH_ID} IS MISSING)`)
|
|
158
204
|
.add('LIMIT 1');
|
|
159
|
-
return ((_a = (yield
|
|
205
|
+
return ((_a = (yield cb.one(this, lines.end(), opt)).row) === null || _a === void 0 ? void 0 : _a._urn) !== undefined;
|
|
160
206
|
});
|
|
161
207
|
}
|
|
162
208
|
/** @inheritDoc */
|
|
@@ -169,35 +215,38 @@ class CbRepo {
|
|
|
169
215
|
/** @inheritDoc */
|
|
170
216
|
getByUrn(urn, p1) {
|
|
171
217
|
return __awaiter(this, void 0, void 0, function* () {
|
|
172
|
-
const
|
|
218
|
+
const cb = this.cb;
|
|
219
|
+
const opt = cb.buildOpt(p1, 'getByUrn');
|
|
173
220
|
const lines = (0, line_1.cbLine)();
|
|
174
221
|
lines
|
|
175
222
|
.add(`SELECT a.*`)
|
|
176
223
|
.add(`FROM ${this.fullPath} a`)
|
|
177
|
-
.add(`USE KEYS ${
|
|
224
|
+
.add(`USE KEYS ${cb.v(urn)}`)
|
|
178
225
|
.add(`WHERE (a.${F_TRASH_ID} IS MISSING)`)
|
|
179
226
|
.add('LIMIT 1');
|
|
180
|
-
return (yield
|
|
227
|
+
return (yield cb.one(this, lines.end(), opt)).row;
|
|
181
228
|
});
|
|
182
229
|
}
|
|
183
230
|
/** @inheritDoc */
|
|
184
231
|
getById(id, p1) {
|
|
185
232
|
return __awaiter(this, void 0, void 0, function* () {
|
|
186
|
-
const
|
|
233
|
+
const cb = this.cb;
|
|
234
|
+
const opt = cb.buildOpt(p1, 'getById');
|
|
187
235
|
const lines = (0, line_1.cbLine)();
|
|
188
236
|
lines
|
|
189
237
|
.add(`SELECT a.*`)
|
|
190
238
|
.add(`FROM ${this.fullPath} a`)
|
|
191
|
-
.add(`WHERE (a.${F_ID} = ${
|
|
239
|
+
.add(`WHERE (a.${F_ID} = ${cb.v(id)})`)
|
|
192
240
|
.add(`AND (a.${F_TRASH_ID} is missing)`)
|
|
193
241
|
.add('LIMIT 1');
|
|
194
|
-
return (yield
|
|
242
|
+
return (yield cb.one(this, lines.end(), opt)).row;
|
|
195
243
|
});
|
|
196
244
|
}
|
|
197
245
|
/** @inheritDoc */
|
|
198
246
|
listByUrn(urnList, p1) {
|
|
199
247
|
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
-
const
|
|
248
|
+
const cb = this.cb;
|
|
249
|
+
const opt = cb.buildOpt(p1, 'listByUrn');
|
|
201
250
|
urnList = this._checkKeys(urnList);
|
|
202
251
|
if (urnList.length < 1) {
|
|
203
252
|
return [];
|
|
@@ -206,15 +255,16 @@ class CbRepo {
|
|
|
206
255
|
lines
|
|
207
256
|
.add(`SELECT a.*`)
|
|
208
257
|
.add(`FROM ${this.fullPath} a`)
|
|
209
|
-
.add(`USE KEYS
|
|
258
|
+
.add(`USE KEYS ${cb.v(urnList)}`)
|
|
210
259
|
.add(`WHERE (a.${F_TRASH_ID} IS MISSING)`);
|
|
211
|
-
return (yield
|
|
260
|
+
return (yield cb.more(this, lines.end(), opt)).rows;
|
|
212
261
|
});
|
|
213
262
|
}
|
|
214
263
|
/** @inheritDoc */
|
|
215
264
|
listById(ids, p1) {
|
|
216
265
|
return __awaiter(this, void 0, void 0, function* () {
|
|
217
|
-
const
|
|
266
|
+
const cb = this.cb;
|
|
267
|
+
const opt = cb.buildOpt(p1, 'listById');
|
|
218
268
|
ids = this._checkKeys(ids);
|
|
219
269
|
if (ids.length < 1) {
|
|
220
270
|
return [];
|
|
@@ -223,68 +273,73 @@ class CbRepo {
|
|
|
223
273
|
lines
|
|
224
274
|
.add(`SELECT a.*`)
|
|
225
275
|
.add(`FROM ${this.fullPath} a`)
|
|
226
|
-
.add(`WHERE (a.${F_ID}
|
|
276
|
+
.add(`WHERE (a.${F_ID} ${ids.length === 1 ? '=' : 'IN'} ${cb.v(ids)})`)
|
|
227
277
|
.add(`AND (a.${F_TRASH_ID} is missing)`);
|
|
228
|
-
return (yield
|
|
278
|
+
return (yield cb.more(this, lines.end(), opt)).rows;
|
|
229
279
|
});
|
|
230
280
|
}
|
|
231
281
|
/** @inheritDoc */
|
|
232
282
|
removeByUrn(urn, p1) {
|
|
233
283
|
return __awaiter(this, void 0, void 0, function* () {
|
|
234
284
|
var _a;
|
|
235
|
-
const
|
|
285
|
+
const cb = this.cb;
|
|
286
|
+
const opt = cb.buildOpt(p1, 'removeByUrn');
|
|
236
287
|
const lines = (0, line_1.cbLine)();
|
|
237
288
|
lines
|
|
238
289
|
.add(`DELETE
|
|
239
290
|
FROM ${this.fullPath} a`)
|
|
240
|
-
.add(`USE KEYS ${
|
|
291
|
+
.add(`USE KEYS ${cb.v(urn)}`)
|
|
241
292
|
.add(`WHERE (a.${F_TRASH_ID} is missing)`)
|
|
242
293
|
.add(`RETURNING a.${F_ID}`);
|
|
243
|
-
return (_a = (yield
|
|
294
|
+
return (_a = (yield cb.one(this, lines.end(), opt)).row) === null || _a === void 0 ? void 0 : _a.id;
|
|
244
295
|
});
|
|
245
296
|
}
|
|
246
297
|
/** @inheritDoc */
|
|
247
298
|
removeById(id, p1) {
|
|
248
299
|
return __awaiter(this, void 0, void 0, function* () {
|
|
249
300
|
var _a;
|
|
250
|
-
const
|
|
301
|
+
const cb = this.cb;
|
|
302
|
+
const opt = cb.buildOpt(p1, 'removeById');
|
|
251
303
|
const lines = (0, line_1.cbLine)();
|
|
252
304
|
lines
|
|
253
305
|
.add(`DELETE FROM ${this.fullPath} a`)
|
|
254
|
-
.add(`WHERE (a.${F_ID} = ${
|
|
306
|
+
.add(`WHERE (a.${F_ID} = ${cb.v(id)})`)
|
|
255
307
|
.add(`AND (a.${F_TRASH_ID} is missing)`)
|
|
256
308
|
.add(`RETURNING meta().id ${F_URN}`);
|
|
257
|
-
return (_a = (yield
|
|
309
|
+
return (_a = (yield cb.one(this, lines.end(), opt)).row) === null || _a === void 0 ? void 0 : _a._urn;
|
|
258
310
|
});
|
|
259
311
|
}
|
|
260
312
|
/** @inheritDoc */
|
|
261
313
|
insert(doc, p1) {
|
|
262
314
|
return __awaiter(this, void 0, void 0, function* () {
|
|
263
|
-
const
|
|
315
|
+
const cb = this.cb;
|
|
316
|
+
const opt = cb.buildOpt(p1, 'insert');
|
|
264
317
|
const urn = this._urnFromDoc(doc, 'insert');
|
|
265
318
|
doc.createdAt = new Date().toISOString();
|
|
266
319
|
doc.updatedAt = new Date().toISOString();
|
|
267
|
-
const result = yield
|
|
320
|
+
const result = yield cb.exec(this.collection.insert(urn, doc), opt);
|
|
268
321
|
return (result === null || result === void 0 ? void 0 : result.token) ? result.token.toString() : 'inserted';
|
|
269
322
|
});
|
|
270
323
|
}
|
|
271
324
|
/** @inheritDoc */
|
|
272
325
|
replace(doc, p1) {
|
|
273
326
|
return __awaiter(this, void 0, void 0, function* () {
|
|
274
|
-
const
|
|
327
|
+
const cb = this.cb;
|
|
328
|
+
const opt = cb.buildOpt(p1, 'replace');
|
|
275
329
|
const urn = this._urnFromDoc(doc, 'replace');
|
|
276
330
|
doc.updatedAt = new Date().toISOString();
|
|
277
|
-
const result = yield
|
|
331
|
+
const result = yield cb.exec(this.collection.replace(urn, doc), opt);
|
|
278
332
|
return (result === null || result === void 0 ? void 0 : result.token) ? result.token.toString() : 'inserted';
|
|
279
333
|
});
|
|
280
334
|
}
|
|
281
335
|
/** @inheritDoc */
|
|
282
336
|
upsert(doc, p1) {
|
|
283
337
|
return __awaiter(this, void 0, void 0, function* () {
|
|
284
|
-
const
|
|
338
|
+
const cb = this.cb;
|
|
339
|
+
const opt = cb.buildOpt(p1, 'upsert');
|
|
285
340
|
const urn = this._urnFromDoc(doc, 'upsert');
|
|
286
341
|
doc.updatedAt = new Date().toISOString();
|
|
287
|
-
const result = yield
|
|
342
|
+
const result = yield cb.exec(this.collection.upsert(urn, doc), opt);
|
|
288
343
|
return (result === null || result === void 0 ? void 0 : result.token) ? result.token.toString() : 'modified';
|
|
289
344
|
});
|
|
290
345
|
}
|
|
@@ -292,18 +347,20 @@ class CbRepo {
|
|
|
292
347
|
update(doc, p1) {
|
|
293
348
|
return __awaiter(this, void 0, void 0, function* () {
|
|
294
349
|
var _a;
|
|
295
|
-
const
|
|
350
|
+
const cb = this.cb;
|
|
351
|
+
const opt = cb.buildOpt(p1, 'update');
|
|
296
352
|
const urn = this._urnFromDoc(doc, 'update');
|
|
297
353
|
doc.updatedAt = new Date().toISOString();
|
|
298
354
|
doc.updatedAt = new Date().toISOString();
|
|
299
355
|
const sql = this._updateSql(urn, doc);
|
|
300
|
-
return (_a = (yield
|
|
356
|
+
return (_a = (yield cb.one(this, sql, opt)).row) === null || _a === void 0 ? void 0 : _a._urn;
|
|
301
357
|
});
|
|
302
358
|
}
|
|
303
359
|
/** @inheritDoc */
|
|
304
360
|
trash(doc, p1) {
|
|
305
361
|
return __awaiter(this, void 0, void 0, function* () {
|
|
306
|
-
const
|
|
362
|
+
const cb = this.cb;
|
|
363
|
+
const opt = cb.buildOpt(p1, 'trash');
|
|
307
364
|
const urn = this._urnFromDoc(doc, 'trash');
|
|
308
365
|
if (opt.trashId === undefined) {
|
|
309
366
|
opt.trashId = (0, node_crypto_1.randomUUID)();
|
|
@@ -311,10 +368,10 @@ class CbRepo {
|
|
|
311
368
|
const lines = (0, line_1.cbLine)();
|
|
312
369
|
lines
|
|
313
370
|
.add(`UPDATE ${this.fullPath} a`)
|
|
314
|
-
.add(`USE KEYS ${
|
|
315
|
-
.add(`SET a.${F_TRASH_ID} = ${
|
|
371
|
+
.add(`USE KEYS ${cb.v(urn)}`)
|
|
372
|
+
.add(`SET a.${F_TRASH_ID} = ${cb.v(opt.trashId)}`)
|
|
316
373
|
.add(`WHERE (a.${F_TRASH_ID} is missing)`);
|
|
317
|
-
yield
|
|
374
|
+
yield cb.one(this, lines.end(), opt);
|
|
318
375
|
return opt.trashId;
|
|
319
376
|
});
|
|
320
377
|
}
|