mpackdb
All repositories: gitoria
2.9 KB
import assert from 'node:assert/strict';import MPackDB from '../src/MPackDB.js';import { rm } from 'fs/promises';const TEST_DB_PATH = 'db/index-path-guard';console.log('--- Index Path Guard Test ---');console.log('Declared indexes must recover missing path slots; unknown hints must fail clearly.\n');await rm(TEST_DB_PATH, { recursive: true, force: true });const writer = new MPackDB(`${TEST_DB_PATH}/records`, {primaryKey: '*id',indexes: ['url', 'name'],compact: false,indexPersistInterval: 0,});await writer.insert({ url: 'https://example.test/a', name: 'A' });await writer.close();const db = new MPackDB(`${TEST_DB_PATH}/records`, {primaryKey: '*id',indexes: ['url', 'name'],compact: false,indexPersistInterval: 0,});await db.init();const expectedUrlPath = db._indexManager._indexPaths.url;// Reproduce the reported failure condition directly: a declared field whose// path slot is unexpectedly absent. Both lookup paths must reconstruct it.delete db._indexManager._indexPaths.url;const exact = await db.find(r => r.url === 'https://example.test/a', {index: { field: 'url', value: 'https://example.test/a' },});assert.equal(exact.length, 1);assert.equal(db._indexManager._indexPaths.url, expectedUrlPath);delete db._indexManager._indexPaths.url;const ranged = await db.find(null, {index: { field: 'url', from: 'https://example.test/a', to: 'https://example.test/z' },});assert.equal(ranged.length, 1);assert.equal(db._indexManager._indexPaths.url, expectedUrlPath);const assertUnknownIndex = error => {assert.equal(error.code, 'INDEX_NOT_FOUND');assert.equal(error.field, 'unknown');assert.deepEqual(error.indexes, ['id', 'url', 'name']);assert.match(error.message, /No index configured for field "unknown"/);return true;};await assert.rejects(() => db.find(() => true, { index: { field: 'unknown', value: 'x' } }).toArray(),assertUnknownIndex,);await assert.rejects(() => db.find(null, { index: { field: 'unknown', from: 'a', to: 'z' } }).toArray(),assertUnknownIndex,);// Exercise the report's suspected trigger: another attached instance replaces// the data file through compaction, then this instance refreshes and queries.const compactor = new MPackDB(`${TEST_DB_PATH}/records`, {primaryKey: '*id',indexes: ['url', 'name'],compact: false,indexPersistInterval: 0,});await compactor.init();const pathsBeforeReplace = { ...db._indexManager._indexPaths };await compactor.compact();await db.refresh();assert.deepEqual(db._indexManager._indexPaths, pathsBeforeReplace);const afterReplace = await db.find(r => r.url === 'https://example.test/a', {index: { field: 'url', value: 'https://example.test/a' },});assert.equal(afterReplace.length, 1);await compactor.close();await db.close();console.log('✓ Missing declared paths recovered for exact and range lookups');console.log('✓ Unknown exact and range hints return INDEX_NOT_FOUND');console.log('✓ Declared paths and lookups survive external replacement');
Branches
- mastermain branch
Latest commits
- 87888725release 1.0.7caramboleyo
- c4cdb9b6node: import prefixes (Deno compat) + pre-existing index-state WIPcaramboleyo
- 0afb8f4bupdate now must be a callbackcaramboleyo
- cde73eb4release 1.0.6caramboleyo
- d01dda02add index hints, intersection, boundingBox; remove findByIndexcaramboleyo
- b8ffc1a0release 1.0.5caramboleyo
- d47876a1reimplemented lost features like indexed find and more testscaramboleyo
- 7f08da9afixed insert ignoring model definitioncaramboleyo
- 705774a9added flush before findcaramboleyo
- b4db6391initial commitcaramboleyo