@quereus/store 0.3.6 → 0.3.7
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/README.md +2 -2
- package/dist/src/common/ddl-generator.d.ts +15 -0
- package/dist/src/common/ddl-generator.d.ts.map +1 -0
- package/dist/src/common/ddl-generator.js +131 -0
- package/dist/src/common/ddl-generator.js.map +1 -0
- package/dist/src/common/encoding.d.ts +65 -0
- package/dist/src/common/encoding.d.ts.map +1 -0
- package/dist/src/common/encoding.js +339 -0
- package/dist/src/common/encoding.js.map +1 -0
- package/dist/src/common/events.d.ts +119 -0
- package/dist/src/common/events.d.ts.map +1 -0
- package/dist/src/common/events.js +158 -0
- package/dist/src/common/events.js.map +1 -0
- package/dist/src/common/index.d.ts +15 -0
- package/dist/src/common/index.d.ts.map +1 -0
- package/dist/src/common/index.js +23 -0
- package/dist/src/common/index.js.map +1 -0
- package/dist/src/common/key-builder.d.ts +58 -0
- package/dist/src/common/key-builder.d.ts.map +1 -0
- package/dist/src/common/key-builder.js +130 -0
- package/dist/src/common/key-builder.js.map +1 -0
- package/dist/src/common/kv-store.d.ts +150 -0
- package/dist/src/common/kv-store.d.ts.map +1 -0
- package/dist/src/common/kv-store.js +6 -0
- package/dist/src/common/kv-store.js.map +1 -0
- package/dist/src/common/memory-store.d.ts +37 -0
- package/dist/src/common/memory-store.d.ts.map +1 -0
- package/dist/src/common/memory-store.js +146 -0
- package/dist/src/common/memory-store.js.map +1 -0
- package/dist/src/common/serialization.d.ts +41 -0
- package/dist/src/common/serialization.d.ts.map +1 -0
- package/dist/src/common/serialization.js +111 -0
- package/dist/src/common/serialization.js.map +1 -0
- package/dist/src/common/store-connection.d.ts +34 -0
- package/dist/src/common/store-connection.d.ts.map +1 -0
- package/dist/src/common/store-connection.js +55 -0
- package/dist/src/common/store-connection.js.map +1 -0
- package/dist/src/common/store-module.d.ts +111 -0
- package/dist/src/common/store-module.d.ts.map +1 -0
- package/dist/src/common/store-module.js +331 -0
- package/dist/src/common/store-module.js.map +1 -0
- package/dist/src/common/store-table.d.ts +115 -0
- package/dist/src/common/store-table.d.ts.map +1 -0
- package/dist/src/common/store-table.js +472 -0
- package/dist/src/common/store-table.js.map +1 -0
- package/dist/src/common/transaction.d.ts +57 -0
- package/dist/src/common/transaction.d.ts.map +1 -0
- package/dist/src/common/transaction.js +156 -0
- package/dist/src/common/transaction.js.map +1 -0
- package/dist/src/index.d.ts +17 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +18 -0
- package/dist/src/index.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic Store Module for Quereus.
|
|
3
|
+
*
|
|
4
|
+
* A platform-agnostic VirtualTableModule that uses a KVStoreProvider
|
|
5
|
+
* to create StoreTable instances. This enables any storage backend
|
|
6
|
+
* (LevelDB, IndexedDB, React Native, etc.) to be used with the same
|
|
7
|
+
* table implementation.
|
|
8
|
+
*/
|
|
9
|
+
import type { Database, TableSchema, TableIndexSchema, VirtualTableModule, BaseModuleConfig, BestAccessPlanRequest, BestAccessPlanResult } from '@quereus/quereus';
|
|
10
|
+
import type { KVStore, KVStoreProvider } from './kv-store.js';
|
|
11
|
+
import type { StoreEventEmitter } from './events.js';
|
|
12
|
+
import { TransactionCoordinator } from './transaction.js';
|
|
13
|
+
import { StoreTable, type StoreTableConfig, type StoreTableModule } from './store-table.js';
|
|
14
|
+
/**
|
|
15
|
+
* Configuration options for StoreModule tables.
|
|
16
|
+
*/
|
|
17
|
+
export interface StoreModuleConfig extends BaseModuleConfig {
|
|
18
|
+
/** Collation for text keys. Default: 'NOCASE'. */
|
|
19
|
+
collation?: 'BINARY' | 'NOCASE';
|
|
20
|
+
/** Additional platform-specific options. */
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Generic store module that works with any KVStoreProvider.
|
|
25
|
+
*
|
|
26
|
+
* Usage:
|
|
27
|
+
* ```typescript
|
|
28
|
+
* import { StoreModule } from '@quereus/plugin-store';
|
|
29
|
+
* import { createLevelDBProvider } from '@quereus/store-leveldb';
|
|
30
|
+
*
|
|
31
|
+
* const provider = createLevelDBProvider({ basePath: './data' });
|
|
32
|
+
* const module = new StoreModule(provider);
|
|
33
|
+
* db.registerVtabModule('store', module);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare class StoreModule implements VirtualTableModule<StoreTable, StoreModuleConfig>, StoreTableModule {
|
|
37
|
+
private provider;
|
|
38
|
+
private stores;
|
|
39
|
+
private coordinators;
|
|
40
|
+
private tables;
|
|
41
|
+
private eventEmitter?;
|
|
42
|
+
constructor(provider: KVStoreProvider, eventEmitter?: StoreEventEmitter);
|
|
43
|
+
/**
|
|
44
|
+
* Get the event emitter for this module.
|
|
45
|
+
*/
|
|
46
|
+
getEventEmitter(): StoreEventEmitter | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Get the KVStoreProvider used by this module.
|
|
49
|
+
*/
|
|
50
|
+
getProvider(): KVStoreProvider;
|
|
51
|
+
/**
|
|
52
|
+
* Creates a new store-backed table.
|
|
53
|
+
* Called by CREATE TABLE.
|
|
54
|
+
*/
|
|
55
|
+
create(db: Database, tableSchema: TableSchema): StoreTable;
|
|
56
|
+
/**
|
|
57
|
+
* Connects to an existing store-backed table.
|
|
58
|
+
* Called when loading schema from persistent storage.
|
|
59
|
+
*/
|
|
60
|
+
connect(db: Database, _pAux: unknown, _moduleName: string, schemaName: string, tableName: string, options: StoreModuleConfig, importedTableSchema?: TableSchema): StoreTable;
|
|
61
|
+
/**
|
|
62
|
+
* Destroys a store table and its storage.
|
|
63
|
+
*/
|
|
64
|
+
destroy(_db: Database, _pAux: unknown, _moduleName: string, schemaName: string, tableName: string): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Creates an index on a store-backed table.
|
|
67
|
+
*/
|
|
68
|
+
createIndex(_db: Database, schemaName: string, tableName: string, indexSchema: TableIndexSchema): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Build index entries for all existing rows in a table.
|
|
71
|
+
*/
|
|
72
|
+
private buildIndexEntries;
|
|
73
|
+
/**
|
|
74
|
+
* Modern access planning interface.
|
|
75
|
+
*/
|
|
76
|
+
getBestAccessPlan(_db: Database, tableInfo: TableSchema, request: BestAccessPlanRequest): BestAccessPlanResult;
|
|
77
|
+
/**
|
|
78
|
+
* Get or create a store for a table.
|
|
79
|
+
*/
|
|
80
|
+
getStore(tableKey: string, _config: StoreTableConfig): Promise<KVStore>;
|
|
81
|
+
/**
|
|
82
|
+
* Get or create a transaction coordinator for a table.
|
|
83
|
+
*/
|
|
84
|
+
getCoordinator(tableKey: string, config: StoreTableConfig): Promise<TransactionCoordinator>;
|
|
85
|
+
/**
|
|
86
|
+
* Save table DDL to persistent storage (both table store and catalog).
|
|
87
|
+
*/
|
|
88
|
+
saveTableDDL(tableSchema: TableSchema): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Load all DDL statements from the catalog store.
|
|
91
|
+
* Used to restore persisted tables on startup.
|
|
92
|
+
*/
|
|
93
|
+
loadAllDDL(): Promise<string[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Remove DDL from the catalog store when a table is dropped.
|
|
96
|
+
*/
|
|
97
|
+
removeTableDDL(schemaName: string, tableName: string): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Parse module configuration from vtab args.
|
|
100
|
+
*/
|
|
101
|
+
private parseConfig;
|
|
102
|
+
/**
|
|
103
|
+
* Close all stores.
|
|
104
|
+
*/
|
|
105
|
+
closeAll(): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Get a table by schema and name.
|
|
108
|
+
*/
|
|
109
|
+
getTable(schemaName: string, tableName: string): StoreTable | undefined;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=store-module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-module.d.ts","sourceRoot":"","sources":["../../../src/common/store-module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic Store Module for Quereus.
|
|
3
|
+
*
|
|
4
|
+
* A platform-agnostic VirtualTableModule that uses a KVStoreProvider
|
|
5
|
+
* to create StoreTable instances. This enables any storage backend
|
|
6
|
+
* (LevelDB, IndexedDB, React Native, etc.) to be used with the same
|
|
7
|
+
* table implementation.
|
|
8
|
+
*/
|
|
9
|
+
import { AccessPlanBuilder, QuereusError, StatusCode } from '@quereus/quereus';
|
|
10
|
+
import { TransactionCoordinator } from './transaction.js';
|
|
11
|
+
import { StoreTable } from './store-table.js';
|
|
12
|
+
import { buildMetaKey, buildMetaScanBounds, buildIndexKey, buildTableScanBounds } from './key-builder.js';
|
|
13
|
+
import { serializeRow, deserializeRow } from './serialization.js';
|
|
14
|
+
import { generateTableDDL } from './ddl-generator.js';
|
|
15
|
+
/**
|
|
16
|
+
* Generic store module that works with any KVStoreProvider.
|
|
17
|
+
*
|
|
18
|
+
* Usage:
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { StoreModule } from '@quereus/plugin-store';
|
|
21
|
+
* import { createLevelDBProvider } from '@quereus/store-leveldb';
|
|
22
|
+
*
|
|
23
|
+
* const provider = createLevelDBProvider({ basePath: './data' });
|
|
24
|
+
* const module = new StoreModule(provider);
|
|
25
|
+
* db.registerVtabModule('store', module);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export class StoreModule {
|
|
29
|
+
provider;
|
|
30
|
+
stores = new Map();
|
|
31
|
+
coordinators = new Map();
|
|
32
|
+
tables = new Map();
|
|
33
|
+
eventEmitter;
|
|
34
|
+
constructor(provider, eventEmitter) {
|
|
35
|
+
this.provider = provider;
|
|
36
|
+
this.eventEmitter = eventEmitter;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get the event emitter for this module.
|
|
40
|
+
*/
|
|
41
|
+
getEventEmitter() {
|
|
42
|
+
return this.eventEmitter;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get the KVStoreProvider used by this module.
|
|
46
|
+
*/
|
|
47
|
+
getProvider() {
|
|
48
|
+
return this.provider;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Creates a new store-backed table.
|
|
52
|
+
* Called by CREATE TABLE.
|
|
53
|
+
*/
|
|
54
|
+
create(db, tableSchema) {
|
|
55
|
+
const tableKey = `${tableSchema.schemaName}.${tableSchema.name}`.toLowerCase();
|
|
56
|
+
if (this.tables.has(tableKey)) {
|
|
57
|
+
throw new QuereusError(`Store table '${tableSchema.name}' already exists in schema '${tableSchema.schemaName}'`, StatusCode.ERROR);
|
|
58
|
+
}
|
|
59
|
+
const config = this.parseConfig(tableSchema.vtabArgs);
|
|
60
|
+
const table = new StoreTable(db, this, tableSchema, config, this.eventEmitter);
|
|
61
|
+
this.tables.set(tableKey, table);
|
|
62
|
+
// Emit schema change event for table creation
|
|
63
|
+
this.eventEmitter?.emitSchemaChange({
|
|
64
|
+
type: 'create',
|
|
65
|
+
objectType: 'table',
|
|
66
|
+
schemaName: tableSchema.schemaName,
|
|
67
|
+
objectName: tableSchema.name,
|
|
68
|
+
ddl: generateTableDDL(tableSchema),
|
|
69
|
+
});
|
|
70
|
+
return table;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Connects to an existing store-backed table.
|
|
74
|
+
* Called when loading schema from persistent storage.
|
|
75
|
+
*/
|
|
76
|
+
connect(db, _pAux, _moduleName, schemaName, tableName, options, importedTableSchema) {
|
|
77
|
+
const tableKey = `${schemaName}.${tableName}`.toLowerCase();
|
|
78
|
+
// Check if we already have this table connected
|
|
79
|
+
const existing = this.tables.get(tableKey);
|
|
80
|
+
if (existing) {
|
|
81
|
+
return existing;
|
|
82
|
+
}
|
|
83
|
+
// Convert options to Record<string, SqlValue> for vtabArgs
|
|
84
|
+
const vtabArgs = {};
|
|
85
|
+
if (options?.collation !== undefined)
|
|
86
|
+
vtabArgs.collation = options.collation;
|
|
87
|
+
// Use the imported schema if provided, otherwise create a minimal one
|
|
88
|
+
const tableSchema = importedTableSchema ?? {
|
|
89
|
+
name: tableName,
|
|
90
|
+
schemaName: schemaName,
|
|
91
|
+
columns: Object.freeze([]),
|
|
92
|
+
columnIndexMap: new Map(),
|
|
93
|
+
primaryKeyDefinition: [],
|
|
94
|
+
checkConstraints: Object.freeze([]),
|
|
95
|
+
isTemporary: false,
|
|
96
|
+
isView: false,
|
|
97
|
+
vtabModuleName: 'store',
|
|
98
|
+
vtabArgs,
|
|
99
|
+
vtabModule: this,
|
|
100
|
+
estimatedRows: 0,
|
|
101
|
+
};
|
|
102
|
+
const config = this.parseConfig(vtabArgs);
|
|
103
|
+
const table = new StoreTable(db, this, tableSchema, config, this.eventEmitter, true // isConnected - DDL already exists in storage
|
|
104
|
+
);
|
|
105
|
+
this.tables.set(tableKey, table);
|
|
106
|
+
return table;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Destroys a store table and its storage.
|
|
110
|
+
*/
|
|
111
|
+
async destroy(_db, _pAux, _moduleName, schemaName, tableName) {
|
|
112
|
+
const tableKey = `${schemaName}.${tableName}`.toLowerCase();
|
|
113
|
+
const table = this.tables.get(tableKey);
|
|
114
|
+
if (table) {
|
|
115
|
+
await table.disconnect();
|
|
116
|
+
this.tables.delete(tableKey);
|
|
117
|
+
}
|
|
118
|
+
// Close the store via provider
|
|
119
|
+
await this.provider.closeStore(schemaName, tableName);
|
|
120
|
+
this.stores.delete(tableKey);
|
|
121
|
+
this.coordinators.delete(tableKey);
|
|
122
|
+
// Emit schema change event for table drop
|
|
123
|
+
this.eventEmitter?.emitSchemaChange({
|
|
124
|
+
type: 'drop',
|
|
125
|
+
objectType: 'table',
|
|
126
|
+
schemaName,
|
|
127
|
+
objectName: tableName,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Creates an index on a store-backed table.
|
|
132
|
+
*/
|
|
133
|
+
async createIndex(_db, schemaName, tableName, indexSchema) {
|
|
134
|
+
const tableKey = `${schemaName}.${tableName}`.toLowerCase();
|
|
135
|
+
const table = this.tables.get(tableKey);
|
|
136
|
+
if (!table) {
|
|
137
|
+
throw new QuereusError(`Store table '${tableName}' not found in schema '${schemaName}'`, StatusCode.NOTFOUND);
|
|
138
|
+
}
|
|
139
|
+
const store = await this.getStore(tableKey, table.getConfig());
|
|
140
|
+
const tableSchema = table.getSchema();
|
|
141
|
+
// Store index metadata
|
|
142
|
+
const indexMetaKey = buildMetaKey('index', schemaName, tableName, indexSchema.name);
|
|
143
|
+
const indexMetaValue = serializeRow([
|
|
144
|
+
indexSchema.name,
|
|
145
|
+
JSON.stringify(indexSchema.columns),
|
|
146
|
+
]);
|
|
147
|
+
await store.put(indexMetaKey, indexMetaValue);
|
|
148
|
+
// Build index entries for existing rows
|
|
149
|
+
await this.buildIndexEntries(store, tableSchema, indexSchema);
|
|
150
|
+
// Emit schema change event
|
|
151
|
+
this.eventEmitter?.emitSchemaChange({
|
|
152
|
+
type: 'create',
|
|
153
|
+
objectType: 'index',
|
|
154
|
+
schemaName,
|
|
155
|
+
objectName: indexSchema.name,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Build index entries for all existing rows in a table.
|
|
160
|
+
*/
|
|
161
|
+
async buildIndexEntries(store, tableSchema, indexSchema) {
|
|
162
|
+
const encodeOptions = { collation: 'NOCASE' };
|
|
163
|
+
// Scan all data rows
|
|
164
|
+
const bounds = buildTableScanBounds(tableSchema.schemaName, tableSchema.name);
|
|
165
|
+
const batch = store.batch();
|
|
166
|
+
for await (const entry of store.iterate(bounds)) {
|
|
167
|
+
const row = deserializeRow(entry.value);
|
|
168
|
+
// Extract PK values
|
|
169
|
+
const pkValues = tableSchema.primaryKeyDefinition.map(pk => row[pk.index]);
|
|
170
|
+
// Extract index column values
|
|
171
|
+
const indexValues = indexSchema.columns.map(col => row[col.index]);
|
|
172
|
+
// Build and store index key
|
|
173
|
+
const indexKey = buildIndexKey(tableSchema.schemaName, tableSchema.name, indexSchema.name, indexValues, pkValues, encodeOptions);
|
|
174
|
+
batch.put(indexKey, new Uint8Array(0)); // Index value is empty
|
|
175
|
+
}
|
|
176
|
+
await batch.write();
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Modern access planning interface.
|
|
180
|
+
*/
|
|
181
|
+
getBestAccessPlan(_db, tableInfo, request) {
|
|
182
|
+
const estimatedRows = request.estimatedRows ?? 1000;
|
|
183
|
+
// Check for primary key equality constraints
|
|
184
|
+
const pkColumns = tableInfo.primaryKeyDefinition.map(pk => pk.index);
|
|
185
|
+
const pkFilters = request.filters.filter(f => f.columnIndex !== undefined &&
|
|
186
|
+
pkColumns.includes(f.columnIndex) &&
|
|
187
|
+
f.op === '=');
|
|
188
|
+
if (pkFilters.length === pkColumns.length && pkColumns.length > 0) {
|
|
189
|
+
// Full PK match - point lookup
|
|
190
|
+
const handledFilters = request.filters.map(f => pkFilters.some(pf => pf.columnIndex === f.columnIndex && pf.op === f.op));
|
|
191
|
+
return AccessPlanBuilder
|
|
192
|
+
.eqMatch(1, 0.1)
|
|
193
|
+
.setHandledFilters(handledFilters)
|
|
194
|
+
.setIsSet(true)
|
|
195
|
+
.setExplanation('Store primary key lookup')
|
|
196
|
+
.build();
|
|
197
|
+
}
|
|
198
|
+
// Check for range constraints on PK
|
|
199
|
+
const rangeOps = ['<', '<=', '>', '>='];
|
|
200
|
+
const rangeFilters = request.filters.filter(f => f.columnIndex !== undefined &&
|
|
201
|
+
pkColumns.includes(f.columnIndex) &&
|
|
202
|
+
rangeOps.includes(f.op));
|
|
203
|
+
if (rangeFilters.length > 0) {
|
|
204
|
+
// Range scan on PK
|
|
205
|
+
const handledFilters = request.filters.map(f => rangeFilters.some(rf => rf.columnIndex === f.columnIndex && rf.op === f.op));
|
|
206
|
+
const rangeRows = Math.max(1, Math.floor(estimatedRows * 0.3));
|
|
207
|
+
return AccessPlanBuilder
|
|
208
|
+
.rangeScan(rangeRows, 0.2)
|
|
209
|
+
.setHandledFilters(handledFilters)
|
|
210
|
+
.setExplanation('Store primary key range scan')
|
|
211
|
+
.build();
|
|
212
|
+
}
|
|
213
|
+
// Check for secondary index usage
|
|
214
|
+
const indexes = tableInfo.indexes || [];
|
|
215
|
+
for (const index of indexes) {
|
|
216
|
+
const indexColumns = index.columns.map(c => c.index);
|
|
217
|
+
const indexFilters = request.filters.filter(f => f.columnIndex !== undefined &&
|
|
218
|
+
indexColumns.includes(f.columnIndex) &&
|
|
219
|
+
f.op === '=');
|
|
220
|
+
if (indexFilters.length > 0) {
|
|
221
|
+
const handledFilters = request.filters.map(f => indexFilters.some(idf => idf.columnIndex === f.columnIndex && idf.op === f.op));
|
|
222
|
+
const matchedRows = Math.max(1, Math.floor(estimatedRows * 0.1));
|
|
223
|
+
return AccessPlanBuilder
|
|
224
|
+
.eqMatch(matchedRows, 0.3)
|
|
225
|
+
.setHandledFilters(handledFilters)
|
|
226
|
+
.setExplanation(`Store index scan on ${index.name}`)
|
|
227
|
+
.build();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// Fallback to full scan
|
|
231
|
+
return AccessPlanBuilder
|
|
232
|
+
.fullScan(estimatedRows)
|
|
233
|
+
.setHandledFilters(new Array(request.filters.length).fill(false))
|
|
234
|
+
.setExplanation('Store full table scan')
|
|
235
|
+
.build();
|
|
236
|
+
}
|
|
237
|
+
// --- StoreTableModule interface implementation ---
|
|
238
|
+
/**
|
|
239
|
+
* Get or create a store for a table.
|
|
240
|
+
*/
|
|
241
|
+
async getStore(tableKey, _config) {
|
|
242
|
+
let store = this.stores.get(tableKey);
|
|
243
|
+
if (!store) {
|
|
244
|
+
const [schemaName, tableName] = tableKey.split('.');
|
|
245
|
+
store = await this.provider.getStore(schemaName, tableName);
|
|
246
|
+
this.stores.set(tableKey, store);
|
|
247
|
+
}
|
|
248
|
+
return store;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Get or create a transaction coordinator for a table.
|
|
252
|
+
*/
|
|
253
|
+
async getCoordinator(tableKey, config) {
|
|
254
|
+
let coordinator = this.coordinators.get(tableKey);
|
|
255
|
+
if (!coordinator) {
|
|
256
|
+
const store = await this.getStore(tableKey, config);
|
|
257
|
+
coordinator = new TransactionCoordinator(store, this.eventEmitter);
|
|
258
|
+
this.coordinators.set(tableKey, coordinator);
|
|
259
|
+
}
|
|
260
|
+
return coordinator;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Save table DDL to persistent storage (both table store and catalog).
|
|
264
|
+
*/
|
|
265
|
+
async saveTableDDL(tableSchema) {
|
|
266
|
+
const tableKey = `${tableSchema.schemaName}.${tableSchema.name}`.toLowerCase();
|
|
267
|
+
const ddl = generateTableDDL(tableSchema);
|
|
268
|
+
const metaKey = buildMetaKey('ddl', tableSchema.schemaName, tableSchema.name);
|
|
269
|
+
const encoder = new TextEncoder();
|
|
270
|
+
const encodedDDL = encoder.encode(ddl);
|
|
271
|
+
// Save to table's own store
|
|
272
|
+
const store = this.stores.get(tableKey);
|
|
273
|
+
if (store) {
|
|
274
|
+
await store.put(metaKey, encodedDDL);
|
|
275
|
+
}
|
|
276
|
+
// Also save to catalog store for discovery
|
|
277
|
+
const catalogStore = await this.provider.getCatalogStore();
|
|
278
|
+
await catalogStore.put(metaKey, encodedDDL);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Load all DDL statements from the catalog store.
|
|
282
|
+
* Used to restore persisted tables on startup.
|
|
283
|
+
*/
|
|
284
|
+
async loadAllDDL() {
|
|
285
|
+
const catalogStore = await this.provider.getCatalogStore();
|
|
286
|
+
const bounds = buildMetaScanBounds('ddl');
|
|
287
|
+
const decoder = new TextDecoder();
|
|
288
|
+
const ddlStatements = [];
|
|
289
|
+
for await (const entry of catalogStore.iterate(bounds)) {
|
|
290
|
+
const ddl = decoder.decode(entry.value);
|
|
291
|
+
ddlStatements.push(ddl);
|
|
292
|
+
}
|
|
293
|
+
return ddlStatements;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Remove DDL from the catalog store when a table is dropped.
|
|
297
|
+
*/
|
|
298
|
+
async removeTableDDL(schemaName, tableName) {
|
|
299
|
+
const metaKey = buildMetaKey('ddl', schemaName, tableName);
|
|
300
|
+
const catalogStore = await this.provider.getCatalogStore();
|
|
301
|
+
await catalogStore.delete(metaKey);
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Parse module configuration from vtab args.
|
|
305
|
+
*/
|
|
306
|
+
parseConfig(args) {
|
|
307
|
+
return {
|
|
308
|
+
collation: args?.collation || 'NOCASE',
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Close all stores.
|
|
313
|
+
*/
|
|
314
|
+
async closeAll() {
|
|
315
|
+
for (const table of this.tables.values()) {
|
|
316
|
+
await table.disconnect();
|
|
317
|
+
}
|
|
318
|
+
this.tables.clear();
|
|
319
|
+
this.coordinators.clear();
|
|
320
|
+
await this.provider.closeAll();
|
|
321
|
+
this.stores.clear();
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Get a table by schema and name.
|
|
325
|
+
*/
|
|
326
|
+
getTable(schemaName, tableName) {
|
|
327
|
+
const tableKey = `${schemaName}.${tableName}`.toLowerCase();
|
|
328
|
+
return this.tables.get(tableKey);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=store-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-module.js","sourceRoot":"","sources":["../../../src/common/store-module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic KVStore-backed Virtual Table implementation.
|
|
3
|
+
*
|
|
4
|
+
* This is a platform-agnostic table implementation that works with any
|
|
5
|
+
* KVStore implementation (LevelDB, IndexedDB, or custom stores).
|
|
6
|
+
*/
|
|
7
|
+
import { VirtualTable, IndexConstraintOp, type Database, type TableSchema, type Row, type FilterInfo, type SqlValue, type VirtualTableConnection, type UpdateArgs } from '@quereus/quereus';
|
|
8
|
+
import type { KVStore } from './kv-store.js';
|
|
9
|
+
import type { StoreEventEmitter } from './events.js';
|
|
10
|
+
import type { TransactionCoordinator } from './transaction.js';
|
|
11
|
+
import { StoreConnection } from './store-connection.js';
|
|
12
|
+
import { type TableStats } from './serialization.js';
|
|
13
|
+
import type { EncodeOptions } from './encoding.js';
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for a store table.
|
|
16
|
+
*/
|
|
17
|
+
export interface StoreTableConfig {
|
|
18
|
+
/** Collation for text keys. Default: 'NOCASE'. */
|
|
19
|
+
collation?: 'BINARY' | 'NOCASE';
|
|
20
|
+
/** Additional platform-specific options. */
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Interface for the store module that manages this table.
|
|
25
|
+
* Provides access to stores and coordinators.
|
|
26
|
+
*/
|
|
27
|
+
export interface StoreTableModule {
|
|
28
|
+
/** Get a store for a table. */
|
|
29
|
+
getStore(tableKey: string, config: StoreTableConfig): Promise<KVStore>;
|
|
30
|
+
/** Get a coordinator for a table. */
|
|
31
|
+
getCoordinator(tableKey: string, config: StoreTableConfig): Promise<TransactionCoordinator>;
|
|
32
|
+
/** Save table DDL to persistent storage. */
|
|
33
|
+
saveTableDDL(tableSchema: TableSchema): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Generic KVStore-backed virtual table.
|
|
37
|
+
*
|
|
38
|
+
* This class provides the core table functionality shared across all
|
|
39
|
+
* storage backends. Platform-specific behavior is delegated to the
|
|
40
|
+
* StoreTableModule.
|
|
41
|
+
*/
|
|
42
|
+
export declare class StoreTable extends VirtualTable {
|
|
43
|
+
protected storeModule: StoreTableModule;
|
|
44
|
+
protected config: StoreTableConfig;
|
|
45
|
+
protected store: KVStore | null;
|
|
46
|
+
protected coordinator: TransactionCoordinator | null;
|
|
47
|
+
protected connection: StoreConnection | null;
|
|
48
|
+
protected eventEmitter?: StoreEventEmitter;
|
|
49
|
+
protected encodeOptions: EncodeOptions;
|
|
50
|
+
protected ddlSaved: boolean;
|
|
51
|
+
protected cachedStats: TableStats | null;
|
|
52
|
+
protected pendingStatsDelta: number;
|
|
53
|
+
protected mutationCount: number;
|
|
54
|
+
protected statsFlushPending: boolean;
|
|
55
|
+
constructor(db: Database, storeModule: StoreTableModule, tableSchema: TableSchema, config: StoreTableConfig, eventEmitter?: StoreEventEmitter, isConnected?: boolean);
|
|
56
|
+
/** Get the table configuration. */
|
|
57
|
+
getConfig(): StoreTableConfig;
|
|
58
|
+
/** Get the table schema. */
|
|
59
|
+
getSchema(): TableSchema;
|
|
60
|
+
/**
|
|
61
|
+
* Ensure the store is open and DDL is persisted.
|
|
62
|
+
*/
|
|
63
|
+
protected ensureStore(): Promise<KVStore>;
|
|
64
|
+
/**
|
|
65
|
+
* Ensure the coordinator is available and connection is registered.
|
|
66
|
+
*/
|
|
67
|
+
protected ensureCoordinator(): Promise<TransactionCoordinator>;
|
|
68
|
+
/** Apply pending stats on commit. */
|
|
69
|
+
protected applyPendingStats(): void;
|
|
70
|
+
/** Discard pending stats on rollback. */
|
|
71
|
+
protected discardPendingStats(): void;
|
|
72
|
+
/** Flush statistics to persistent storage. */
|
|
73
|
+
protected flushStats(): Promise<void>;
|
|
74
|
+
/** Create a new connection for transaction support. */
|
|
75
|
+
createConnection(): Promise<VirtualTableConnection>;
|
|
76
|
+
/** Get the current connection. */
|
|
77
|
+
getConnection(): VirtualTableConnection | undefined;
|
|
78
|
+
/** Extract primary key values from a row. */
|
|
79
|
+
protected extractPK(row: Row): SqlValue[];
|
|
80
|
+
/** Query the table with optional filters. */
|
|
81
|
+
query(filterInfo: FilterInfo): AsyncIterable<Row>;
|
|
82
|
+
/** Analyze filter info to determine PK access pattern. */
|
|
83
|
+
protected analyzePKAccess(filterInfo: FilterInfo): PKAccessPattern;
|
|
84
|
+
/** Scan a range of PK values. */
|
|
85
|
+
protected scanPKRange(store: KVStore, _access: PKAccessPattern, filterInfo: FilterInfo): AsyncIterable<Row>;
|
|
86
|
+
/** Check if a row matches the filter constraints. */
|
|
87
|
+
protected matchesFilters(row: Row, filterInfo: FilterInfo): boolean;
|
|
88
|
+
/** Compare two values according to an operator. */
|
|
89
|
+
protected compareValues(a: SqlValue, op: IndexConstraintOp, b: SqlValue): boolean;
|
|
90
|
+
/** Perform an update operation (INSERT, UPDATE, DELETE). */
|
|
91
|
+
update(args: UpdateArgs): Promise<Row | undefined>;
|
|
92
|
+
/** Update secondary indexes after a row change. */
|
|
93
|
+
protected updateSecondaryIndexes(coordinator: TransactionCoordinator, inTransaction: boolean, oldRow: Row | null, newRow: Row | null, pk: SqlValue[]): Promise<void>;
|
|
94
|
+
/** Check if two PK arrays are equal. */
|
|
95
|
+
protected keysEqual(a: SqlValue[], b: SqlValue[]): boolean;
|
|
96
|
+
/** Disconnect from the store. */
|
|
97
|
+
disconnect(): Promise<void>;
|
|
98
|
+
/** Get the current estimated row count. */
|
|
99
|
+
getEstimatedRowCount(): Promise<number>;
|
|
100
|
+
/** Track a mutation and schedule lazy stats persistence. */
|
|
101
|
+
protected trackMutation(delta: number, inTransaction?: boolean): void;
|
|
102
|
+
}
|
|
103
|
+
/** PK access pattern analysis result. */
|
|
104
|
+
interface PKAccessPattern {
|
|
105
|
+
type: 'point' | 'range' | 'scan';
|
|
106
|
+
values?: SqlValue[];
|
|
107
|
+
columnIndex?: number;
|
|
108
|
+
constraints?: Array<{
|
|
109
|
+
columnIndex: number;
|
|
110
|
+
op: IndexConstraintOp;
|
|
111
|
+
value?: SqlValue;
|
|
112
|
+
}>;
|
|
113
|
+
}
|
|
114
|
+
export {};
|
|
115
|
+
//# sourceMappingURL=store-table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-table.d.ts","sourceRoot":"","sources":["../../../src/common/store-table.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,YAAY,EACZ,iBAAiB,EAKjB,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,GAAG,EACR,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EAEhB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAOxD,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAKnD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAChC,4CAA4C;IAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+BAA+B;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvE,qCAAqC;IACrC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC5F,4CAA4C;IAC5C,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD;AAED;;;;;;GAMG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,SAAS,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACxC,SAAS,CAAC,MAAM,EAAE,gBAAgB,CAAC;IACnC,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAQ;IACvC,SAAS,CAAC,WAAW,EAAE,sBAAsB,GAAG,IAAI,CAAQ;IAC5D,SAAS,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,CAAQ;IACpD,SAAS,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC;IAC3C,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;IACvC,SAAS,CAAC,QAAQ,UAAS;IAG3B,SAAS,CAAC,WAAW,EAAE,UAAU,GAAG,IAAI,CAAQ;IAChD,SAAS,CAAC,iBAAiB,SAAK;IAChC,SAAS,CAAC,aAAa,SAAK;IAC5B,SAAS,CAAC,iBAAiB,UAAS;gBAGlC,EAAE,EAAE,QAAQ,EACZ,WAAW,EAAE,gBAAgB,EAC7B,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,gBAAgB,EACxB,YAAY,CAAC,EAAE,iBAAiB,EAChC,WAAW,UAAQ;IAYrB,mCAAmC;IACnC,SAAS,IAAI,gBAAgB;IAI7B,4BAA4B;IAC5B,SAAS,IAAI,WAAW;IAIxB;;OAEG;cACa,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAc/C;;OAEG;cACa,iBAAiB,IAAI,OAAO,CAAC,sBAAsB,CAAC;IA0BpE,qCAAqC;IACrC,SAAS,CAAC,iBAAiB,IAAI,IAAI;IAkBnC,yCAAyC;IACzC,SAAS,CAAC,mBAAmB,IAAI,IAAI;IAIrC,8CAA8C;cAC9B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3C,uDAAuD;IACjD,gBAAgB,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAKzD,kCAAkC;IAClC,aAAa,IAAI,sBAAsB,GAAG,SAAS;IAInD,6CAA6C;IAC7C,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,QAAQ,EAAE;IAKzC,6CAA6C;IACtC,KAAK,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC;IAkCxD,0DAA0D;IAC1D,SAAS,CAAC,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,eAAe;IAmDlE,iCAAiC;cAChB,WAAW,CAC1B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,eAAe,EACxB,UAAU,EAAE,UAAU,GACrB,aAAa,CAAC,GAAG,CAAC;IAarB,qDAAqD;IACrD,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO;IAsBnE,mDAAmD;IACnD,SAAS,CAAC,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,iBAAiB,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO;IAkBjF,4DAA4D;IACtD,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC;IA8IxD,mDAAmD;cACnC,sBAAsB,CACpC,WAAW,EAAE,sBAAsB,EACnC,aAAa,EAAE,OAAO,EACtB,MAAM,EAAE,GAAG,GAAG,IAAI,EAClB,MAAM,EAAE,GAAG,GAAG,IAAI,EAClB,EAAE,EAAE,QAAQ,EAAE,GACb,OAAO,CAAC,IAAI,CAAC;IAgDhB,wCAAwC;IACxC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO;IAQ1D,iCAAiC;IAC3B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASjC,2CAA2C;IACrC,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAmB7C,4DAA4D;IAC5D,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,UAAQ,GAAG,IAAI;CAqBpE;AAED,yCAAyC;AACzC,UAAU,eAAe;IACvB,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,iBAAiB,CAAC;QAAC,KAAK,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC;CACvF"}
|