@bbn/bbn 2.0.240 → 2.0.243
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/bbn.js +1 -1
- package/dist/bbn.js.map +1 -1
- package/dist/bbn.sw.js +1 -1
- package/dist/bbn.sw.js.map +1 -1
- package/dist/db/classes/Object.js +258 -26
- package/dist/db/classes/ObjectProxy.d.ts +1 -0
- package/dist/db/classes/ObjectProxy.js +3 -0
- package/dist/db/types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -153,44 +153,212 @@ class DbObject {
|
|
|
153
153
|
const rows = await this.selectAll(table, fields, where, order, start, 1);
|
|
154
154
|
return rows.length ? rows[0] : null;
|
|
155
155
|
}
|
|
156
|
+
/* async selectAll(
|
|
157
|
+
table: string,
|
|
158
|
+
fields: string[] = [],
|
|
159
|
+
where: unknown = null,
|
|
160
|
+
order: OrderClause = null,
|
|
161
|
+
start = 0,
|
|
162
|
+
limit: number | null = null
|
|
163
|
+
): Promise<Record<string, unknown>[]> {
|
|
164
|
+
void order;
|
|
165
|
+
|
|
166
|
+
const [tx, store] = await this.getStore(table, 'readonly');
|
|
167
|
+
const structure = this.structure[table];
|
|
168
|
+
const primary = getPrimaryKey(structure);
|
|
169
|
+
const results: Record<string, unknown>[] = [];
|
|
170
|
+
|
|
171
|
+
const searchField = isObject(where)
|
|
172
|
+
? Object.keys(where as Record<string, unknown>)[0]
|
|
173
|
+
: (!where || isArray(where) ? null : primary);
|
|
174
|
+
|
|
175
|
+
if (!Array.isArray(primary) && searchField === primary) {
|
|
176
|
+
if (Array.isArray((where as any)?.[primary])) {
|
|
177
|
+
const ids = (where as any)[primary] as IDBValidKey[];
|
|
178
|
+
const max = Math.min(ids.length - start, limit ?? ids.length);
|
|
179
|
+
const slice = ids.slice(start, start + max);
|
|
180
|
+
|
|
181
|
+
for (const id of slice) {
|
|
182
|
+
const row = await requestToPromise<Record<string, unknown> | undefined>(store.get(id));
|
|
183
|
+
const transformed = transformResult(row, fields);
|
|
184
|
+
if (transformed) {
|
|
185
|
+
results.push(transformed);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
await transactionDone(tx);
|
|
190
|
+
return results;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const key = isObject(where)
|
|
194
|
+
? (where as Record<string, unknown>)[primary]
|
|
195
|
+
: where;
|
|
196
|
+
|
|
197
|
+
const row = await requestToPromise<Record<string, unknown> | undefined>(
|
|
198
|
+
store.get(key as IDBValidKey)
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const transformed = transformResult(row, fields);
|
|
202
|
+
if (transformed) {
|
|
203
|
+
results.push(transformed);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
await transactionDone(tx);
|
|
207
|
+
return results;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
await new Promise<void>((resolve, reject) => {
|
|
211
|
+
const req = store.openCursor();
|
|
212
|
+
let i = 0;
|
|
213
|
+
|
|
214
|
+
req.onsuccess = (e: Event) => {
|
|
215
|
+
const cursor = (e.target as IDBRequest<IDBCursorWithValue | null>).result;
|
|
216
|
+
|
|
217
|
+
if (!cursor) {
|
|
218
|
+
resolve();
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const matches = !where || !(globalThis as any).bbn?.fn?.search
|
|
223
|
+
? true
|
|
224
|
+
: 0 === (globalThis as any).bbn.fn.search([cursor.value], where);
|
|
225
|
+
|
|
226
|
+
if (matches) {
|
|
227
|
+
if (i >= start) {
|
|
228
|
+
const transformed = transformResult(cursor.value, fields);
|
|
229
|
+
if (transformed) {
|
|
230
|
+
results.push(transformed);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (limit !== null && results.length >= limit) {
|
|
234
|
+
resolve();
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
i++;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
cursor.continue();
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
req.onerror = () => {
|
|
245
|
+
this.lastErr = req.error;
|
|
246
|
+
log(req.error);
|
|
247
|
+
reject(req.error);
|
|
248
|
+
};
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
await transactionDone(tx);
|
|
252
|
+
return results;
|
|
253
|
+
} */
|
|
156
254
|
async selectAll(table, fields = [], where = null, order = null, start = 0, limit = null) {
|
|
157
|
-
void order;
|
|
158
255
|
const [tx, store] = await this.getStore(table, 'readonly');
|
|
159
256
|
const structure = this.structure[table];
|
|
160
257
|
const primary = getPrimaryKey(structure);
|
|
161
|
-
const
|
|
258
|
+
const rows = [];
|
|
259
|
+
const normalizeDir = (dir) => {
|
|
260
|
+
return String(dir).toLowerCase() === 'desc' ? 'desc' : 'asc';
|
|
261
|
+
};
|
|
262
|
+
const normalizeOrder = (order) => {
|
|
263
|
+
if (!order) {
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
/*
|
|
267
|
+
* Format:
|
|
268
|
+
* { field: 'asc' }
|
|
269
|
+
* { field: 'desc' }
|
|
270
|
+
*/
|
|
271
|
+
if (isObject(order) && !Array.isArray(order)) {
|
|
272
|
+
return Object.keys(order).map(field => ({
|
|
273
|
+
field,
|
|
274
|
+
dir: normalizeDir(order[field])
|
|
275
|
+
}));
|
|
276
|
+
}
|
|
277
|
+
/*
|
|
278
|
+
* Format:
|
|
279
|
+
* [
|
|
280
|
+
* { field: 'field', dir: 'asc' },
|
|
281
|
+
* { field: 'field2', dir: 'desc' }
|
|
282
|
+
* ]
|
|
283
|
+
*/
|
|
284
|
+
if (Array.isArray(order)) {
|
|
285
|
+
return order
|
|
286
|
+
.filter(item => isObject(item) && typeof item.field === 'string')
|
|
287
|
+
.map(item => ({
|
|
288
|
+
field: item.field,
|
|
289
|
+
dir: normalizeDir(item.dir)
|
|
290
|
+
}));
|
|
291
|
+
}
|
|
292
|
+
return [];
|
|
293
|
+
};
|
|
294
|
+
const orderClauses = normalizeOrder(order);
|
|
295
|
+
const compareValues = (a, b) => {
|
|
296
|
+
if (a === b) {
|
|
297
|
+
return 0;
|
|
298
|
+
}
|
|
299
|
+
if (a === undefined || a === null) {
|
|
300
|
+
return -1;
|
|
301
|
+
}
|
|
302
|
+
if (b === undefined || b === null) {
|
|
303
|
+
return 1;
|
|
304
|
+
}
|
|
305
|
+
if (typeof a === 'number' && typeof b === 'number') {
|
|
306
|
+
return a - b;
|
|
307
|
+
}
|
|
308
|
+
if (a instanceof Date && b instanceof Date) {
|
|
309
|
+
return a.getTime() - b.getTime();
|
|
310
|
+
}
|
|
311
|
+
return String(a).localeCompare(String(b));
|
|
312
|
+
};
|
|
313
|
+
const sortRows = (rows) => {
|
|
314
|
+
if (!orderClauses.length) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
rows.sort((a, b) => {
|
|
318
|
+
for (const clause of orderClauses) {
|
|
319
|
+
const cmp = compareValues(a[clause.field], b[clause.field]);
|
|
320
|
+
if (cmp !== 0) {
|
|
321
|
+
return clause.dir === 'desc' ? -cmp : cmp;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return 0;
|
|
325
|
+
});
|
|
326
|
+
};
|
|
162
327
|
const searchField = isObject(where)
|
|
163
328
|
? Object.keys(where)[0]
|
|
164
329
|
: (!where || isArray(where) ? null : primary);
|
|
165
330
|
if (!Array.isArray(primary) && searchField === primary) {
|
|
166
331
|
if (Array.isArray(where?.[primary])) {
|
|
167
332
|
const ids = where[primary];
|
|
168
|
-
|
|
169
|
-
const slice = ids.slice(start, start + max);
|
|
170
|
-
for (const id of slice) {
|
|
333
|
+
for (const id of ids) {
|
|
171
334
|
const row = await requestToPromise(store.get(id));
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
results.push(transformed);
|
|
335
|
+
if (row) {
|
|
336
|
+
rows.push(row);
|
|
175
337
|
}
|
|
176
338
|
}
|
|
177
339
|
await transactionDone(tx);
|
|
178
|
-
|
|
340
|
+
sortRows(rows);
|
|
341
|
+
const sliced = limit === null
|
|
342
|
+
? rows.slice(start)
|
|
343
|
+
: rows.slice(start, start + limit);
|
|
344
|
+
return sliced
|
|
345
|
+
.map(row => transformResult(row, fields))
|
|
346
|
+
.filter((row) => !!row);
|
|
179
347
|
}
|
|
180
348
|
const key = isObject(where)
|
|
181
349
|
? where[primary]
|
|
182
350
|
: where;
|
|
183
351
|
const row = await requestToPromise(store.get(key));
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
results.push(transformed);
|
|
352
|
+
if (row) {
|
|
353
|
+
rows.push(row);
|
|
187
354
|
}
|
|
188
355
|
await transactionDone(tx);
|
|
189
|
-
return
|
|
356
|
+
return rows
|
|
357
|
+
.map(row => transformResult(row, fields))
|
|
358
|
+
.filter((row) => !!row);
|
|
190
359
|
}
|
|
191
360
|
await new Promise((resolve, reject) => {
|
|
192
361
|
const req = store.openCursor();
|
|
193
|
-
let i = 0;
|
|
194
362
|
req.onsuccess = (e) => {
|
|
195
363
|
const cursor = e.target.result;
|
|
196
364
|
if (!cursor) {
|
|
@@ -201,17 +369,7 @@ class DbObject {
|
|
|
201
369
|
? true
|
|
202
370
|
: 0 === globalThis.bbn.fn.search([cursor.value], where);
|
|
203
371
|
if (matches) {
|
|
204
|
-
|
|
205
|
-
const transformed = transformResult(cursor.value, fields);
|
|
206
|
-
if (transformed) {
|
|
207
|
-
results.push(transformed);
|
|
208
|
-
}
|
|
209
|
-
if (limit !== null && results.length >= limit) {
|
|
210
|
-
resolve();
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
i++;
|
|
372
|
+
rows.push(cursor.value);
|
|
215
373
|
}
|
|
216
374
|
cursor.continue();
|
|
217
375
|
};
|
|
@@ -222,7 +380,13 @@ class DbObject {
|
|
|
222
380
|
};
|
|
223
381
|
});
|
|
224
382
|
await transactionDone(tx);
|
|
225
|
-
|
|
383
|
+
sortRows(rows);
|
|
384
|
+
const sliced = limit === null
|
|
385
|
+
? rows.slice(start)
|
|
386
|
+
: rows.slice(start, start + limit);
|
|
387
|
+
return sliced
|
|
388
|
+
.map(row => transformResult(row, fields))
|
|
389
|
+
.filter((row) => !!row);
|
|
226
390
|
}
|
|
227
391
|
async getColumnValues(table, field, where = null, order = null, start = 0, limit = null) {
|
|
228
392
|
const rows = await this.selectAll(table, fieldsFromFilter(where, [field]), where, order, start, limit);
|
|
@@ -230,6 +394,74 @@ class DbObject {
|
|
|
230
394
|
.map(row => row[field])
|
|
231
395
|
.filter(v => v !== undefined);
|
|
232
396
|
}
|
|
397
|
+
async count(table, where = null) {
|
|
398
|
+
const [tx, store] = await this.getStore(table, 'readonly');
|
|
399
|
+
const structure = this.structure[table];
|
|
400
|
+
const primary = getPrimaryKey(structure);
|
|
401
|
+
const searchField = isObject(where)
|
|
402
|
+
? Object.keys(where)[0]
|
|
403
|
+
: (!where || isArray(where) ? null : primary);
|
|
404
|
+
if (!where) {
|
|
405
|
+
const total = await requestToPromise(store.count());
|
|
406
|
+
await transactionDone(tx);
|
|
407
|
+
return total;
|
|
408
|
+
}
|
|
409
|
+
if (!Array.isArray(primary) && searchField === primary) {
|
|
410
|
+
if (Array.isArray(where?.[primary])) {
|
|
411
|
+
const ids = where[primary];
|
|
412
|
+
let total = 0;
|
|
413
|
+
for (const id of ids) {
|
|
414
|
+
const exists = await requestToPromise(store.getKey(id));
|
|
415
|
+
if (exists !== undefined) {
|
|
416
|
+
total++;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
await transactionDone(tx);
|
|
420
|
+
return total;
|
|
421
|
+
}
|
|
422
|
+
const key = isObject(where)
|
|
423
|
+
? where[primary]
|
|
424
|
+
: where;
|
|
425
|
+
const total = await requestToPromise(store.count(key));
|
|
426
|
+
await transactionDone(tx);
|
|
427
|
+
return total;
|
|
428
|
+
}
|
|
429
|
+
if (typeof searchField === 'string' &&
|
|
430
|
+
isObject(where) &&
|
|
431
|
+
!Array.isArray(where[searchField]) &&
|
|
432
|
+
store.indexNames.contains(searchField)) {
|
|
433
|
+
const index = store.index(searchField);
|
|
434
|
+
const value = where[searchField];
|
|
435
|
+
const total = await requestToPromise(index.count(IDBKeyRange.only(value)));
|
|
436
|
+
await transactionDone(tx);
|
|
437
|
+
return total;
|
|
438
|
+
}
|
|
439
|
+
let total = 0;
|
|
440
|
+
await new Promise((resolve, reject) => {
|
|
441
|
+
const req = store.openCursor();
|
|
442
|
+
req.onsuccess = (e) => {
|
|
443
|
+
const cursor = e.target.result;
|
|
444
|
+
if (!cursor) {
|
|
445
|
+
resolve();
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
const matches = !where || !globalThis.bbn?.fn?.search
|
|
449
|
+
? true
|
|
450
|
+
: 0 === globalThis.bbn.fn.search([cursor.value], where);
|
|
451
|
+
if (matches) {
|
|
452
|
+
total++;
|
|
453
|
+
}
|
|
454
|
+
cursor.continue();
|
|
455
|
+
};
|
|
456
|
+
req.onerror = () => {
|
|
457
|
+
this.lastErr = req.error;
|
|
458
|
+
log(req.error);
|
|
459
|
+
reject(req.error);
|
|
460
|
+
};
|
|
461
|
+
});
|
|
462
|
+
await transactionDone(tx);
|
|
463
|
+
return total;
|
|
464
|
+
}
|
|
233
465
|
async copyTable(target, table, fields = [], where = null, order = null, start = 0, limit = null) {
|
|
234
466
|
if (!this.structure[table]) {
|
|
235
467
|
throw new Error(_('Source table %s does not exist in structure', table));
|
|
@@ -11,6 +11,7 @@ export default class bbnDbObjectProxy implements DbApi {
|
|
|
11
11
|
select(table: string, fields?: string[], where?: unknown, order?: OrderClause, start?: number): Promise<unknown>;
|
|
12
12
|
selectAll(table: string, fields?: string[], where?: unknown, order?: OrderClause, start?: number, limit?: number | null): Promise<unknown>;
|
|
13
13
|
getColumnValues(table: string, field: string, where?: unknown, order?: OrderClause, start?: number, limit?: number | null): Promise<unknown>;
|
|
14
|
+
count(table: string, where?: unknown): Promise<number>;
|
|
14
15
|
copyTable(target: string, table: string, fields?: string[], where?: unknown, order?: OrderClause, start?: number, limit?: number | null): Promise<number>;
|
|
15
16
|
deleteTable(table: string): Promise<boolean>;
|
|
16
17
|
close(): void;
|
|
@@ -64,6 +64,9 @@ export default class bbnDbObjectProxy {
|
|
|
64
64
|
getColumnValues(table, field, where, order, start, limit) {
|
|
65
65
|
return callServiceWorker(this, 'object.getColumnValues', [table, field, where, order, start, limit]);
|
|
66
66
|
}
|
|
67
|
+
count(table, where) {
|
|
68
|
+
return callServiceWorker(this, 'object.count', [table, where]);
|
|
69
|
+
}
|
|
67
70
|
copyTable(target, table, fields, where, order, start, limit) {
|
|
68
71
|
return callServiceWorker(this, 'object.copyTable', [target, table, fields, where, order, start, limit]);
|
|
69
72
|
}
|
package/dist/db/types.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export interface DbApi {
|
|
|
34
34
|
select(table: string, fields?: string[], where?: unknown, order?: OrderClause, start?: number): Promise<unknown>;
|
|
35
35
|
selectAll(table: string, fields?: string[], where?: unknown, order?: OrderClause, start?: number, limit?: number | null): Promise<unknown>;
|
|
36
36
|
getColumnValues(table: string, field: string, where?: unknown, order?: OrderClause, start?: number, limit?: number | null): Promise<unknown>;
|
|
37
|
+
count(table: string, where?: unknown): Promise<number>;
|
|
37
38
|
copyTable(target: string, table: string, fields?: string[], where?: unknown, order?: OrderClause, start?: number, limit?: number | null): Promise<number>;
|
|
38
39
|
deleteTable(table: string): Promise<boolean>;
|
|
39
40
|
}
|