@bbn/bbn 2.0.242 → 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.
@@ -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 results = [];
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
- const max = Math.min(ids.length - start, limit ?? ids.length);
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
- const transformed = transformResult(row, fields);
173
- if (transformed) {
174
- results.push(transformed);
335
+ if (row) {
336
+ rows.push(row);
175
337
  }
176
338
  }
177
339
  await transactionDone(tx);
178
- return results;
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
- const transformed = transformResult(row, fields);
185
- if (transformed) {
186
- results.push(transformed);
352
+ if (row) {
353
+ rows.push(row);
187
354
  }
188
355
  await transactionDone(tx);
189
- return results;
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
- if (i >= start) {
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
- return results;
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbn/bbn",
3
- "version": "2.0.242",
3
+ "version": "2.0.243",
4
4
  "description": "Javascript toolkit",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",