@naturalcycles/db-lib
Advanced tools
Comparing version 9.15.1 to 9.16.0
@@ -34,4 +34,5 @@ "use strict"; | ||
rows = rows.sort((a, b) => { | ||
// biome-ignore lint/suspicious/noDoubleEquals: ok | ||
if (a[name] == b[name]) | ||
return 0; // eslint-disable-line eqeqeq | ||
return 0; | ||
if (descending) { | ||
@@ -38,0 +39,0 @@ return a[name] < b[name] ? 1 : -1; |
@@ -15,13 +15,13 @@ import { JsonSchemaObject, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib'; | ||
getTables(): Promise<string[]>; | ||
getTableSchema<ROW extends ObjectWithId>(table: string): Promise<JsonSchemaRootObject<ROW>>; | ||
createTable<ROW extends ObjectWithId>(table: string, schema: JsonSchemaObject<ROW>): Promise<void>; | ||
getByIds<ROW extends ObjectWithId>(table: string, ids: string[]): Promise<ROW[]>; | ||
deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>): Promise<number>; | ||
updateByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, patch: DBPatch<ROW>, opt?: CommonDBOptions): Promise<number>; | ||
runQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>): Promise<RunQueryResult<ROW>>; | ||
runQueryCount<ROW extends ObjectWithId>(q: DBQuery<ROW>): Promise<number>; | ||
saveBatch<ROW extends ObjectWithId>(table: string, rows: ROW[], opt?: CommonDBSaveOptions<ROW>): Promise<void>; | ||
streamQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>): ReadableTyped<ROW>; | ||
deleteByIds(table: string, ids: string[], opt?: CommonDBOptions): Promise<number>; | ||
runInTransaction(fn: DBTransactionFn, opt?: CommonDBTransactionOptions): Promise<void>; | ||
getTableSchema<ROW extends ObjectWithId>(_table: string): Promise<JsonSchemaRootObject<ROW>>; | ||
createTable<ROW extends ObjectWithId>(_table: string, _schema: JsonSchemaObject<ROW>): Promise<void>; | ||
getByIds<ROW extends ObjectWithId>(_table: string, _ids: string[]): Promise<ROW[]>; | ||
deleteByQuery<ROW extends ObjectWithId>(_q: DBQuery<ROW>): Promise<number>; | ||
updateByQuery<ROW extends ObjectWithId>(_q: DBQuery<ROW>, _patch: DBPatch<ROW>, _opt?: CommonDBOptions): Promise<number>; | ||
runQuery<ROW extends ObjectWithId>(_q: DBQuery<ROW>): Promise<RunQueryResult<ROW>>; | ||
runQueryCount<ROW extends ObjectWithId>(_q: DBQuery<ROW>): Promise<number>; | ||
saveBatch<ROW extends ObjectWithId>(_table: string, _rows: ROW[], _opt?: CommonDBSaveOptions<ROW>): Promise<void>; | ||
streamQuery<ROW extends ObjectWithId>(_q: DBQuery<ROW>): ReadableTyped<ROW>; | ||
deleteByIds(_table: string, _ids: string[], _opt?: CommonDBOptions): Promise<number>; | ||
runInTransaction(fn: DBTransactionFn, _opt?: CommonDBTransactionOptions): Promise<void>; | ||
} |
@@ -6,3 +6,2 @@ "use strict"; | ||
const dbTransaction_util_1 = require("./transaction/dbTransaction.util"); | ||
/* eslint-disable unused-imports/no-unused-vars */ | ||
/** | ||
@@ -23,33 +22,33 @@ * No-op implementation of CommonDB interface. | ||
} | ||
async getTableSchema(table) { | ||
async getTableSchema(_table) { | ||
throw new Error('getTableSchema is not implemented'); | ||
} | ||
async createTable(table, schema) { | ||
async createTable(_table, _schema) { | ||
// no-op | ||
} | ||
async getByIds(table, ids) { | ||
async getByIds(_table, _ids) { | ||
throw new Error('getByIds is not implemented'); | ||
} | ||
async deleteByQuery(q) { | ||
async deleteByQuery(_q) { | ||
throw new Error('deleteByQuery is not implemented'); | ||
} | ||
async updateByQuery(q, patch, opt) { | ||
async updateByQuery(_q, _patch, _opt) { | ||
throw new Error('updateByQuery is not implemented'); | ||
} | ||
async runQuery(q) { | ||
async runQuery(_q) { | ||
throw new Error('runQuery is not implemented'); | ||
} | ||
async runQueryCount(q) { | ||
async runQueryCount(_q) { | ||
throw new Error('runQueryCount is not implemented'); | ||
} | ||
async saveBatch(table, rows, opt) { | ||
async saveBatch(_table, _rows, _opt) { | ||
throw new Error('saveBatch is not implemented'); | ||
} | ||
streamQuery(q) { | ||
streamQuery(_q) { | ||
throw new Error('streamQuery is not implemented'); | ||
} | ||
async deleteByIds(table, ids, opt) { | ||
async deleteByIds(_table, _ids, _opt) { | ||
throw new Error('deleteByIds is not implemented'); | ||
} | ||
async runInTransaction(fn, opt) { | ||
async runInTransaction(fn, _opt) { | ||
const tx = new dbTransaction_util_1.FakeDBTransaction(this); | ||
@@ -56,0 +55,0 @@ await fn(tx); |
@@ -160,2 +160,6 @@ import { Transform } from 'node:stream'; | ||
runInTransaction<T = void>(fn: CommonDaoTransactionFn<T>, opt?: CommonDBTransactionOptions): Promise<T>; | ||
/** | ||
* Throws if query uses a property that is in `excludeFromIndexes` list. | ||
*/ | ||
private validateQueryIndexes; | ||
protected logResult(started: number, op: string, res: any, table: string): void; | ||
@@ -162,0 +166,0 @@ protected logSaveResult(started: number, op: string, table: string): void; |
@@ -205,2 +205,3 @@ "use strict"; | ||
async runQueryExtended(q, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table; | ||
@@ -226,2 +227,3 @@ const op = `runQuery(${q.pretty()})`; | ||
async runQueryExtendedAsDBM(q, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table; | ||
@@ -240,2 +242,3 @@ const op = `runQueryAsDBM(${q.pretty()})`; | ||
async runQueryCount(q, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table; | ||
@@ -251,2 +254,3 @@ const op = `runQueryCount(${q.pretty()})`; | ||
async streamQueryForEach(q, mapper, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table; | ||
@@ -290,2 +294,3 @@ opt.skipValidation = opt.skipValidation !== false; // default true | ||
async streamQueryAsDBMForEach(q, mapper, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table; | ||
@@ -332,2 +337,3 @@ opt.skipValidation = opt.skipValidation !== false; // default true | ||
streamQueryAsDBM(q, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table; | ||
@@ -363,2 +369,3 @@ opt.skipValidation = opt.skipValidation !== false; // default true | ||
streamQuery(q, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table; | ||
@@ -404,2 +411,3 @@ opt.skipValidation = opt.skipValidation !== false; // default true | ||
async queryIds(q, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table; | ||
@@ -410,2 +418,3 @@ const { rows } = await this.cfg.db.runQuery(q.select(['id']), opt); | ||
streamQueryIds(q, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table; | ||
@@ -429,2 +438,3 @@ opt.errorMode ||= js_lib_1.ErrorMode.SUPPRESS; | ||
async streamQueryIdsForEach(q, mapper, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table; | ||
@@ -790,2 +800,3 @@ opt.errorMode ||= js_lib_1.ErrorMode.SUPPRESS; | ||
async deleteByQuery(q, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
this.requireWriteAccess(); | ||
@@ -834,2 +845,3 @@ this.requireObjectMutability(opt); | ||
async updateByQuery(q, patch, opt = {}) { | ||
this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property | ||
this.requireWriteAccess(); | ||
@@ -974,2 +986,15 @@ this.requireObjectMutability(opt); | ||
} | ||
/** | ||
* Throws if query uses a property that is in `excludeFromIndexes` list. | ||
*/ | ||
validateQueryIndexes(q) { | ||
const { excludeFromIndexes } = this.cfg; | ||
if (!excludeFromIndexes) | ||
return; | ||
for (const f of q._filters) { | ||
(0, js_lib_1._assert)(!excludeFromIndexes.includes(f.name), `cannot query on non-indexed property: ${this.cfg.table}.${f.name}`, { | ||
query: q.pretty(), | ||
}); | ||
} | ||
} | ||
logResult(started, op, res, table) { | ||
@@ -976,0 +1001,0 @@ if (!this.cfg.logLevel) |
@@ -11,3 +11,2 @@ "use strict"; | ||
const test_model_1 = require("./test.model"); | ||
// eslint-disable-next-line jest/no-export | ||
function runCommonDaoTest(db, quirks = {}) { | ||
@@ -14,0 +13,0 @@ const { support } = db; |
@@ -10,7 +10,6 @@ "use strict"; | ||
const test_model_1 = require("./test.model"); | ||
const test_util_1 = require("./test.util"); | ||
function runCommonDBTest(db, quirks = {}) { | ||
const { support } = db; | ||
const items = (0, test_model_1.createTestItemsDBM)(3); | ||
(0, test_util_1.deepFreeze)(items); | ||
(0, js_lib_1._deepFreeze)(items); | ||
const item1 = items[0]; | ||
@@ -58,3 +57,3 @@ const queryAll = () => dbQuery_1.DBQuery.create(test_model_1.TEST_TABLE); | ||
}; | ||
(0, test_util_1.deepFreeze)(item3); | ||
(0, js_lib_1._deepFreeze)(item3); | ||
await db.saveBatch(test_model_1.TEST_TABLE, [item3]); | ||
@@ -72,3 +71,3 @@ const item3Loaded = (await db.getByIds(test_model_1.TEST_TABLE, [item3.id]))[0]; | ||
}; | ||
(0, test_util_1.deepFreeze)(item3); | ||
(0, js_lib_1._deepFreeze)(item3); | ||
const expected = { ...item3 }; | ||
@@ -75,0 +74,0 @@ delete expected.k2; |
@@ -5,3 +5,2 @@ "use strict"; | ||
const js_lib_1 = require("@naturalcycles/js-lib"); | ||
/* eslint-disable jest/no-export */ | ||
const testIds = (0, js_lib_1._range)(1, 4).map(n => `id${n}`); | ||
@@ -8,0 +7,0 @@ const testEntries = testIds.map(id => [id, Buffer.from(`${id}value`)]); |
@@ -6,3 +6,2 @@ "use strict"; | ||
const test_model_1 = require("./test.model"); | ||
/* eslint-disable jest/no-export */ | ||
const testIds = (0, js_lib_1._range)(1, 4).map(n => `id${n}`); | ||
@@ -9,0 +8,0 @@ const testEntries = testIds.map(id => [id, Buffer.from(`${id}value`)]); |
@@ -16,2 +16,3 @@ { | ||
"devDependencies": { | ||
"@biomejs/biome": "^1.8.3", | ||
"@naturalcycles/bench-lib": "^3.0.0", | ||
@@ -49,3 +50,3 @@ "@naturalcycles/dev-lib": "^15.4.1", | ||
}, | ||
"version": "9.15.1", | ||
"version": "9.16.0", | ||
"description": "Lowest Common Denominator API to supported Databases", | ||
@@ -52,0 +53,0 @@ "keywords": [ |
@@ -38,3 +38,4 @@ import { _pick, ObjectWithId } from '@naturalcycles/js-lib' | ||
rows = rows.sort((a, b) => { | ||
if (a[name] == b[name]) return 0 // eslint-disable-line eqeqeq | ||
// biome-ignore lint/suspicious/noDoubleEquals: ok | ||
if (a[name] == b[name]) return 0 | ||
@@ -41,0 +42,0 @@ if (descending) { |
@@ -15,4 +15,2 @@ import { JsonSchemaObject, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib' | ||
/* eslint-disable unused-imports/no-unused-vars */ | ||
/** | ||
@@ -36,3 +34,3 @@ * No-op implementation of CommonDB interface. | ||
async getTableSchema<ROW extends ObjectWithId>( | ||
table: string, | ||
_table: string, | ||
): Promise<JsonSchemaRootObject<ROW>> { | ||
@@ -43,4 +41,4 @@ throw new Error('getTableSchema is not implemented') | ||
async createTable<ROW extends ObjectWithId>( | ||
table: string, | ||
schema: JsonSchemaObject<ROW>, | ||
_table: string, | ||
_schema: JsonSchemaObject<ROW>, | ||
): Promise<void> { | ||
@@ -50,7 +48,7 @@ // no-op | ||
async getByIds<ROW extends ObjectWithId>(table: string, ids: string[]): Promise<ROW[]> { | ||
async getByIds<ROW extends ObjectWithId>(_table: string, _ids: string[]): Promise<ROW[]> { | ||
throw new Error('getByIds is not implemented') | ||
} | ||
async deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>): Promise<number> { | ||
async deleteByQuery<ROW extends ObjectWithId>(_q: DBQuery<ROW>): Promise<number> { | ||
throw new Error('deleteByQuery is not implemented') | ||
@@ -60,5 +58,5 @@ } | ||
async updateByQuery<ROW extends ObjectWithId>( | ||
q: DBQuery<ROW>, | ||
patch: DBPatch<ROW>, | ||
opt?: CommonDBOptions, | ||
_q: DBQuery<ROW>, | ||
_patch: DBPatch<ROW>, | ||
_opt?: CommonDBOptions, | ||
): Promise<number> { | ||
@@ -68,7 +66,7 @@ throw new Error('updateByQuery is not implemented') | ||
async runQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>): Promise<RunQueryResult<ROW>> { | ||
async runQuery<ROW extends ObjectWithId>(_q: DBQuery<ROW>): Promise<RunQueryResult<ROW>> { | ||
throw new Error('runQuery is not implemented') | ||
} | ||
async runQueryCount<ROW extends ObjectWithId>(q: DBQuery<ROW>): Promise<number> { | ||
async runQueryCount<ROW extends ObjectWithId>(_q: DBQuery<ROW>): Promise<number> { | ||
throw new Error('runQueryCount is not implemented') | ||
@@ -78,5 +76,5 @@ } | ||
async saveBatch<ROW extends ObjectWithId>( | ||
table: string, | ||
rows: ROW[], | ||
opt?: CommonDBSaveOptions<ROW>, | ||
_table: string, | ||
_rows: ROW[], | ||
_opt?: CommonDBSaveOptions<ROW>, | ||
): Promise<void> { | ||
@@ -86,11 +84,11 @@ throw new Error('saveBatch is not implemented') | ||
streamQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>): ReadableTyped<ROW> { | ||
streamQuery<ROW extends ObjectWithId>(_q: DBQuery<ROW>): ReadableTyped<ROW> { | ||
throw new Error('streamQuery is not implemented') | ||
} | ||
async deleteByIds(table: string, ids: string[], opt?: CommonDBOptions): Promise<number> { | ||
async deleteByIds(_table: string, _ids: string[], _opt?: CommonDBOptions): Promise<number> { | ||
throw new Error('deleteByIds is not implemented') | ||
} | ||
async runInTransaction(fn: DBTransactionFn, opt?: CommonDBTransactionOptions): Promise<void> { | ||
async runInTransaction(fn: DBTransactionFn, _opt?: CommonDBTransactionOptions): Promise<void> { | ||
const tx = new FakeDBTransaction(this) | ||
@@ -97,0 +95,0 @@ await fn(tx) |
@@ -298,2 +298,3 @@ import { Transform } from 'node:stream' | ||
async runQueryExtended(q: DBQuery<DBM>, opt: CommonDaoOptions = {}): Promise<RunQueryResult<BM>> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table | ||
@@ -327,2 +328,3 @@ const op = `runQuery(${q.pretty()})` | ||
): Promise<RunQueryResult<DBM>> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table | ||
@@ -345,2 +347,3 @@ const op = `runQueryAsDBM(${q.pretty()})` | ||
async runQueryCount(q: DBQuery<DBM>, opt: CommonDaoOptions = {}): Promise<number> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table | ||
@@ -361,2 +364,3 @@ const op = `runQueryCount(${q.pretty()})` | ||
): Promise<void> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table | ||
@@ -411,2 +415,3 @@ opt.skipValidation = opt.skipValidation !== false // default true | ||
): Promise<void> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table | ||
@@ -460,2 +465,3 @@ opt.skipValidation = opt.skipValidation !== false // default true | ||
streamQueryAsDBM(q: DBQuery<DBM>, opt: CommonDaoStreamOptions<DBM> = {}): ReadableTyped<DBM> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table | ||
@@ -499,2 +505,3 @@ opt.skipValidation = opt.skipValidation !== false // default true | ||
streamQuery(q: DBQuery<DBM>, opt: CommonDaoStreamOptions<BM> = {}): ReadableTyped<BM> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table | ||
@@ -550,2 +557,3 @@ opt.skipValidation = opt.skipValidation !== false // default true | ||
async queryIds(q: DBQuery<DBM>, opt: CommonDaoOptions = {}): Promise<string[]> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table | ||
@@ -557,2 +565,3 @@ const { rows } = await this.cfg.db.runQuery(q.select(['id']), opt) | ||
streamQueryIds(q: DBQuery<DBM>, opt: CommonDaoStreamOptions<string> = {}): ReadableTyped<string> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table | ||
@@ -584,2 +593,3 @@ opt.errorMode ||= ErrorMode.SUPPRESS | ||
): Promise<void> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
q.table = opt.table || q.table | ||
@@ -1028,2 +1038,3 @@ opt.errorMode ||= ErrorMode.SUPPRESS | ||
): Promise<number> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
this.requireWriteAccess() | ||
@@ -1087,2 +1098,3 @@ this.requireObjectMutability(opt) | ||
): Promise<number> { | ||
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property | ||
this.requireWriteAccess() | ||
@@ -1274,2 +1286,20 @@ this.requireObjectMutability(opt) | ||
/** | ||
* Throws if query uses a property that is in `excludeFromIndexes` list. | ||
*/ | ||
private validateQueryIndexes(q: DBQuery<DBM>): void { | ||
const { excludeFromIndexes } = this.cfg | ||
if (!excludeFromIndexes) return | ||
for (const f of q._filters) { | ||
_assert( | ||
!excludeFromIndexes.includes(f.name), | ||
`cannot query on non-indexed property: ${this.cfg.table}.${f.name as string}`, | ||
{ | ||
query: q.pretty(), | ||
}, | ||
) | ||
} | ||
} | ||
protected logResult(started: number, op: string, res: any, table: string): void { | ||
@@ -1276,0 +1306,0 @@ if (!this.cfg.logLevel) return |
@@ -17,3 +17,2 @@ import { Readable } from 'node:stream' | ||
// eslint-disable-next-line jest/no-export | ||
export function runCommonDaoTest(db: CommonDB, quirks: CommonDBImplementationQuirks = {}): void { | ||
@@ -20,0 +19,0 @@ const { support } = db |
@@ -1,2 +0,2 @@ | ||
import { _filterObject, _pick, _sortBy, pMap } from '@naturalcycles/js-lib' | ||
import { _deepFreeze, _filterObject, _pick, _sortBy, pMap } from '@naturalcycles/js-lib' | ||
import { CommonDB, CommonDBType } from '../common.db' | ||
@@ -12,6 +12,3 @@ import { DBIncrement, DBPatch } from '../db.model' | ||
} from './test.model' | ||
import { deepFreeze } from './test.util' | ||
/* eslint-disable jest/no-export */ | ||
/** | ||
@@ -35,3 +32,3 @@ * All options default to `false`. | ||
const items = createTestItemsDBM(3) | ||
deepFreeze(items) | ||
_deepFreeze(items) | ||
const item1 = items[0]! | ||
@@ -93,3 +90,3 @@ | ||
} | ||
deepFreeze(item3) | ||
_deepFreeze(item3) | ||
await db.saveBatch(TEST_TABLE, [item3]) | ||
@@ -108,3 +105,3 @@ const item3Loaded = (await db.getByIds<TestItemDBM>(TEST_TABLE, [item3.id]))[0]! | ||
} | ||
deepFreeze(item3) | ||
_deepFreeze(item3) | ||
const expected = { ...item3 } | ||
@@ -111,0 +108,0 @@ delete expected.k2 |
@@ -5,4 +5,2 @@ import { _range, _sortBy } from '@naturalcycles/js-lib' | ||
/* eslint-disable jest/no-export */ | ||
const testIds = _range(1, 4).map(n => `id${n}`) | ||
@@ -9,0 +7,0 @@ const testEntries: KeyValueDBTuple[] = testIds.map(id => [id, Buffer.from(`${id}value`)]) |
@@ -5,4 +5,2 @@ import { _range, _sortBy } from '@naturalcycles/js-lib' | ||
/* eslint-disable jest/no-export */ | ||
const testIds = _range(1, 4).map(n => `id${n}`) | ||
@@ -9,0 +7,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
417890
5
116
10976