@quereus/store 0.3.6 → 0.3.8
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
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ This package provides the **abstract layer** that separates virtual table logic
|
|
|
24
24
|
|
|
25
25
|
This architecture enables:
|
|
26
26
|
- **Platform portability** - Same SQL tables work across Node.js, browsers, and mobile
|
|
27
|
-
- **Custom storage backends** - Implement `KVStore` for
|
|
27
|
+
- **Custom storage backends** - Implement `KVStore` for IndexedDB, LevelDB, LMDB, or other "NoSQL" stores
|
|
28
28
|
- **Dependency injection** - Use `KVStoreProvider` for store management
|
|
29
29
|
|
|
30
30
|
## Installation
|
|
@@ -171,7 +171,7 @@ interface KVStoreProvider {
|
|
|
171
171
|
|
|
172
172
|
- [`@quereus/plugin-leveldb`](../quereus-plugin-leveldb/) - LevelDB implementation for Node.js
|
|
173
173
|
- [`@quereus/plugin-indexeddb`](../quereus-plugin-indexeddb/) - IndexedDB implementation for browsers
|
|
174
|
-
- [`@quereus/
|
|
174
|
+
- [`@quereus/sync`](../quereus-sync/) - CRDT sync layer
|
|
175
175
|
|
|
176
176
|
## License
|
|
177
177
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DDL generation utilities for schema persistence.
|
|
3
|
+
*
|
|
4
|
+
* Generates CREATE TABLE and CREATE INDEX statements from schema objects.
|
|
5
|
+
*/
|
|
6
|
+
import type { TableSchema, TableIndexSchema } from '@quereus/quereus';
|
|
7
|
+
/**
|
|
8
|
+
* Generate a CREATE TABLE statement from a TableSchema.
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateTableDDL(tableSchema: TableSchema): string;
|
|
11
|
+
/**
|
|
12
|
+
* Generate a CREATE INDEX statement from an IndexSchema and TableSchema.
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateIndexDDL(indexSchema: TableIndexSchema, tableSchema: TableSchema): string;
|
|
15
|
+
//# sourceMappingURL=ddl-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ddl-generator.d.ts","sourceRoot":"","sources":["../../../src/common/ddl-generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEtE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAwDjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,gBAAgB,EAC7B,WAAW,EAAE,WAAW,GACvB,MAAM,CA4BR"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DDL generation utilities for schema persistence.
|
|
3
|
+
*
|
|
4
|
+
* Generates CREATE TABLE and CREATE INDEX statements from schema objects.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Generate a CREATE TABLE statement from a TableSchema.
|
|
8
|
+
*/
|
|
9
|
+
export function generateTableDDL(tableSchema) {
|
|
10
|
+
const parts = ['CREATE TABLE'];
|
|
11
|
+
if (tableSchema.isTemporary) {
|
|
12
|
+
parts.push('TEMP');
|
|
13
|
+
}
|
|
14
|
+
// Schema-qualified name
|
|
15
|
+
if (tableSchema.schemaName && tableSchema.schemaName !== 'main') {
|
|
16
|
+
parts.push(`"${tableSchema.schemaName}"."${tableSchema.name}"`);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
parts.push(`"${tableSchema.name}"`);
|
|
20
|
+
}
|
|
21
|
+
// Generate column definitions
|
|
22
|
+
const columnDefs = [];
|
|
23
|
+
for (const col of tableSchema.columns) {
|
|
24
|
+
let colDef = `"${col.name}"`;
|
|
25
|
+
if (col.logicalType) {
|
|
26
|
+
colDef += ` ${col.logicalType.name}`;
|
|
27
|
+
}
|
|
28
|
+
// Explicitly output NULL for nullable columns (Quereus defaults to NOT NULL)
|
|
29
|
+
if (!col.notNull) {
|
|
30
|
+
colDef += ' NULL';
|
|
31
|
+
}
|
|
32
|
+
if (col.primaryKey && tableSchema.primaryKeyDefinition.length === 1) {
|
|
33
|
+
colDef += ' PRIMARY KEY';
|
|
34
|
+
}
|
|
35
|
+
if (col.defaultValue !== undefined && col.defaultValue !== null) {
|
|
36
|
+
colDef += ` DEFAULT ${formatDefaultValue(col.defaultValue)}`;
|
|
37
|
+
}
|
|
38
|
+
columnDefs.push(colDef);
|
|
39
|
+
}
|
|
40
|
+
// Add table-level PRIMARY KEY if composite
|
|
41
|
+
if (tableSchema.primaryKeyDefinition.length > 1) {
|
|
42
|
+
const pkCols = tableSchema.primaryKeyDefinition
|
|
43
|
+
.map(pk => `"${tableSchema.columns[pk.index].name}"`)
|
|
44
|
+
.join(', ');
|
|
45
|
+
columnDefs.push(`PRIMARY KEY (${pkCols})`);
|
|
46
|
+
}
|
|
47
|
+
parts.push(`(${columnDefs.join(', ')})`);
|
|
48
|
+
// Add USING clause for virtual table module
|
|
49
|
+
if (tableSchema.vtabModuleName) {
|
|
50
|
+
parts.push(`USING ${tableSchema.vtabModuleName}`);
|
|
51
|
+
if (tableSchema.vtabArgs && Object.keys(tableSchema.vtabArgs).length > 0) {
|
|
52
|
+
const args = Object.entries(tableSchema.vtabArgs)
|
|
53
|
+
.map(([key, value]) => `${key} = ${formatArgValue(value)}`)
|
|
54
|
+
.join(', ');
|
|
55
|
+
parts.push(`(${args})`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return parts.join(' ');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Generate a CREATE INDEX statement from an IndexSchema and TableSchema.
|
|
62
|
+
*/
|
|
63
|
+
export function generateIndexDDL(indexSchema, tableSchema) {
|
|
64
|
+
const parts = ['CREATE INDEX'];
|
|
65
|
+
parts.push(`"${indexSchema.name}"`);
|
|
66
|
+
parts.push('ON');
|
|
67
|
+
// Schema-qualified table name
|
|
68
|
+
if (tableSchema.schemaName && tableSchema.schemaName !== 'main') {
|
|
69
|
+
parts.push(`"${tableSchema.schemaName}"."${tableSchema.name}"`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
parts.push(`"${tableSchema.name}"`);
|
|
73
|
+
}
|
|
74
|
+
// Index columns
|
|
75
|
+
const columns = indexSchema.columns.map(col => {
|
|
76
|
+
let colStr = `"${tableSchema.columns[col.index].name}"`;
|
|
77
|
+
if (col.collation) {
|
|
78
|
+
colStr += ` COLLATE ${col.collation}`;
|
|
79
|
+
}
|
|
80
|
+
if (col.desc) {
|
|
81
|
+
colStr += ' DESC';
|
|
82
|
+
}
|
|
83
|
+
return colStr;
|
|
84
|
+
});
|
|
85
|
+
parts.push(`(${columns.join(', ')})`);
|
|
86
|
+
return parts.join(' ');
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Format a default value expression for DDL.
|
|
90
|
+
* Handles Expression AST nodes from the parser.
|
|
91
|
+
*/
|
|
92
|
+
function formatDefaultValue(expr) {
|
|
93
|
+
if (expr === null)
|
|
94
|
+
return 'NULL';
|
|
95
|
+
// Handle Expression AST nodes
|
|
96
|
+
if (typeof expr === 'object' && expr !== null && 'type' in expr) {
|
|
97
|
+
const astNode = expr;
|
|
98
|
+
if (astNode.type === 'literal') {
|
|
99
|
+
// Use lexeme if available for exact representation
|
|
100
|
+
if (astNode.lexeme)
|
|
101
|
+
return astNode.lexeme;
|
|
102
|
+
return formatDefaultValue(astNode.value);
|
|
103
|
+
}
|
|
104
|
+
// For other expression types, we can't easily serialize them
|
|
105
|
+
// Return a placeholder or the original lexeme if available
|
|
106
|
+
return '(expression)';
|
|
107
|
+
}
|
|
108
|
+
if (typeof expr === 'string')
|
|
109
|
+
return `'${expr.replace(/'/g, "''")}'`;
|
|
110
|
+
if (typeof expr === 'number' || typeof expr === 'bigint')
|
|
111
|
+
return String(expr);
|
|
112
|
+
if (typeof expr === 'boolean')
|
|
113
|
+
return expr ? '1' : '0';
|
|
114
|
+
// For complex expressions, attempt to stringify
|
|
115
|
+
return String(expr);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Format a vtab argument value for DDL.
|
|
119
|
+
*/
|
|
120
|
+
function formatArgValue(value) {
|
|
121
|
+
if (value === null)
|
|
122
|
+
return 'NULL';
|
|
123
|
+
if (typeof value === 'string')
|
|
124
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
125
|
+
if (typeof value === 'number' || typeof value === 'bigint')
|
|
126
|
+
return String(value);
|
|
127
|
+
if (typeof value === 'boolean')
|
|
128
|
+
return value ? '1' : '0';
|
|
129
|
+
return JSON.stringify(value);
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=ddl-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ddl-generator.js","sourceRoot":"","sources":["../../../src/common/ddl-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Key encoding utilities for persistent storage.
|
|
3
|
+
*
|
|
4
|
+
* Encodes SQL values into byte arrays that preserve sort order when compared
|
|
5
|
+
* lexicographically. Supports composite keys and collation-aware encoding.
|
|
6
|
+
*
|
|
7
|
+
* Type prefixes ensure correct cross-type ordering:
|
|
8
|
+
* 0x00 - NULL (sorts first)
|
|
9
|
+
* 0x01 - INTEGER (signed, big-endian with sign flip)
|
|
10
|
+
* 0x02 - REAL (IEEE 754 with sign flip)
|
|
11
|
+
* 0x03 - TEXT (UTF-8, null-terminated, NOCASE by default)
|
|
12
|
+
* 0x04 - BLOB (length-prefixed)
|
|
13
|
+
*
|
|
14
|
+
* Collation support:
|
|
15
|
+
* Collations can register a CollationEncoder to transform strings before
|
|
16
|
+
* binary encoding, preserving their sort semantics in the key-value store.
|
|
17
|
+
*/
|
|
18
|
+
import type { SqlValue } from '@quereus/quereus';
|
|
19
|
+
/**
|
|
20
|
+
* Interface for collation-aware string encoding.
|
|
21
|
+
* Implementations transform strings to preserve collation sort order
|
|
22
|
+
* when encoded as binary keys.
|
|
23
|
+
*/
|
|
24
|
+
export interface CollationEncoder {
|
|
25
|
+
/** Transform a string for sort-preserving binary encoding. */
|
|
26
|
+
encode(value: string): string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Register a collation encoder.
|
|
30
|
+
* @param name Collation name (case-insensitive)
|
|
31
|
+
* @param encoder The encoder implementation
|
|
32
|
+
*/
|
|
33
|
+
export declare function registerCollationEncoder(name: string, encoder: CollationEncoder): void;
|
|
34
|
+
/**
|
|
35
|
+
* Get a registered collation encoder.
|
|
36
|
+
* @param name Collation name (case-insensitive)
|
|
37
|
+
* @returns The encoder, or undefined if not registered
|
|
38
|
+
*/
|
|
39
|
+
export declare function getCollationEncoder(name: string): CollationEncoder | undefined;
|
|
40
|
+
/** Options for encoding keys. */
|
|
41
|
+
export interface EncodeOptions {
|
|
42
|
+
/** Collation name for TEXT values. Default: 'NOCASE'. */
|
|
43
|
+
collation?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Encode a single SQL value into a sortable byte array.
|
|
47
|
+
*/
|
|
48
|
+
export declare function encodeValue(value: SqlValue, options?: EncodeOptions): Uint8Array;
|
|
49
|
+
/**
|
|
50
|
+
* Encode a composite key (multiple values) into a single byte array.
|
|
51
|
+
*/
|
|
52
|
+
export declare function encodeCompositeKey(values: SqlValue[], options?: EncodeOptions): Uint8Array;
|
|
53
|
+
/**
|
|
54
|
+
* Decode a single value from a byte array.
|
|
55
|
+
* Returns the decoded value and the number of bytes consumed.
|
|
56
|
+
*/
|
|
57
|
+
export declare function decodeValue(buffer: Uint8Array, offset?: number, options?: EncodeOptions): {
|
|
58
|
+
value: SqlValue;
|
|
59
|
+
bytesRead: number;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Decode a composite key into an array of values.
|
|
63
|
+
*/
|
|
64
|
+
export declare function decodeCompositeKey(buffer: Uint8Array, expectedCount?: number, options?: EncodeOptions): SqlValue[];
|
|
65
|
+
//# sourceMappingURL=encoding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../../src/common/encoding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAMjD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CAC/B;AAKD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAEtF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAE9E;AA4BD,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,UAAU,CA4BhF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,UAAU,CAU1F;AA2HD;;;GAGG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,UAAU,EAClB,MAAM,GAAE,MAAU,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA0BxC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAClB,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,aAAa,GACtB,QAAQ,EAAE,CAeZ"}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Key encoding utilities for persistent storage.
|
|
3
|
+
*
|
|
4
|
+
* Encodes SQL values into byte arrays that preserve sort order when compared
|
|
5
|
+
* lexicographically. Supports composite keys and collation-aware encoding.
|
|
6
|
+
*
|
|
7
|
+
* Type prefixes ensure correct cross-type ordering:
|
|
8
|
+
* 0x00 - NULL (sorts first)
|
|
9
|
+
* 0x01 - INTEGER (signed, big-endian with sign flip)
|
|
10
|
+
* 0x02 - REAL (IEEE 754 with sign flip)
|
|
11
|
+
* 0x03 - TEXT (UTF-8, null-terminated, NOCASE by default)
|
|
12
|
+
* 0x04 - BLOB (length-prefixed)
|
|
13
|
+
*
|
|
14
|
+
* Collation support:
|
|
15
|
+
* Collations can register a CollationEncoder to transform strings before
|
|
16
|
+
* binary encoding, preserving their sort semantics in the key-value store.
|
|
17
|
+
*/
|
|
18
|
+
/** Registry of collation encoders. */
|
|
19
|
+
const collationEncoders = new Map();
|
|
20
|
+
/**
|
|
21
|
+
* Register a collation encoder.
|
|
22
|
+
* @param name Collation name (case-insensitive)
|
|
23
|
+
* @param encoder The encoder implementation
|
|
24
|
+
*/
|
|
25
|
+
export function registerCollationEncoder(name, encoder) {
|
|
26
|
+
collationEncoders.set(name.toUpperCase(), encoder);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get a registered collation encoder.
|
|
30
|
+
* @param name Collation name (case-insensitive)
|
|
31
|
+
* @returns The encoder, or undefined if not registered
|
|
32
|
+
*/
|
|
33
|
+
export function getCollationEncoder(name) {
|
|
34
|
+
return collationEncoders.get(name.toUpperCase());
|
|
35
|
+
}
|
|
36
|
+
// Built-in collation encoders
|
|
37
|
+
/** NOCASE: Lowercase for case-insensitive ordering (default). */
|
|
38
|
+
const NOCASE_ENCODER = {
|
|
39
|
+
encode: (value) => value.toLowerCase(),
|
|
40
|
+
};
|
|
41
|
+
/** BINARY: No transformation, native byte ordering. */
|
|
42
|
+
const BINARY_ENCODER = {
|
|
43
|
+
encode: (value) => value,
|
|
44
|
+
};
|
|
45
|
+
/** RTRIM: Trim trailing spaces before encoding. */
|
|
46
|
+
const RTRIM_ENCODER = {
|
|
47
|
+
encode: (value) => value.replace(/\s+$/, ''),
|
|
48
|
+
};
|
|
49
|
+
// Register built-in encoders
|
|
50
|
+
registerCollationEncoder('NOCASE', NOCASE_ENCODER);
|
|
51
|
+
registerCollationEncoder('BINARY', BINARY_ENCODER);
|
|
52
|
+
registerCollationEncoder('RTRIM', RTRIM_ENCODER);
|
|
53
|
+
/** Type prefix bytes. */
|
|
54
|
+
const TYPE_NULL = 0x00;
|
|
55
|
+
const TYPE_INTEGER = 0x01;
|
|
56
|
+
const TYPE_REAL = 0x02;
|
|
57
|
+
const TYPE_TEXT = 0x03;
|
|
58
|
+
const TYPE_BLOB = 0x04;
|
|
59
|
+
/** Escape byte for null bytes within strings. */
|
|
60
|
+
const ESCAPE_BYTE = 0x01;
|
|
61
|
+
const NULL_BYTE = 0x00;
|
|
62
|
+
/**
|
|
63
|
+
* Encode a single SQL value into a sortable byte array.
|
|
64
|
+
*/
|
|
65
|
+
export function encodeValue(value, options) {
|
|
66
|
+
const collation = options?.collation ?? 'NOCASE';
|
|
67
|
+
if (value === null) {
|
|
68
|
+
return new Uint8Array([TYPE_NULL]);
|
|
69
|
+
}
|
|
70
|
+
if (typeof value === 'bigint' || (typeof value === 'number' && Number.isInteger(value))) {
|
|
71
|
+
return encodeInteger(typeof value === 'bigint' ? value : BigInt(value));
|
|
72
|
+
}
|
|
73
|
+
if (typeof value === 'number') {
|
|
74
|
+
return encodeReal(value);
|
|
75
|
+
}
|
|
76
|
+
if (typeof value === 'string') {
|
|
77
|
+
return encodeText(value, collation);
|
|
78
|
+
}
|
|
79
|
+
if (value instanceof Uint8Array) {
|
|
80
|
+
return encodeBlob(value);
|
|
81
|
+
}
|
|
82
|
+
if (typeof value === 'boolean') {
|
|
83
|
+
return encodeInteger(value ? 1n : 0n);
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`Cannot encode value of type ${typeof value}`);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Encode a composite key (multiple values) into a single byte array.
|
|
89
|
+
*/
|
|
90
|
+
export function encodeCompositeKey(values, options) {
|
|
91
|
+
const parts = values.map(v => encodeValue(v, options));
|
|
92
|
+
const totalLength = parts.reduce((sum, p) => sum + p.length, 0);
|
|
93
|
+
const result = new Uint8Array(totalLength);
|
|
94
|
+
let offset = 0;
|
|
95
|
+
for (const part of parts) {
|
|
96
|
+
result.set(part, offset);
|
|
97
|
+
offset += part.length;
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Encode an integer with sign-preserving byte ordering.
|
|
103
|
+
* Uses big-endian with XOR on sign bit so negative < positive.
|
|
104
|
+
*/
|
|
105
|
+
function encodeInteger(value) {
|
|
106
|
+
const buffer = new Uint8Array(9);
|
|
107
|
+
buffer[0] = TYPE_INTEGER;
|
|
108
|
+
// Convert to 64-bit signed representation
|
|
109
|
+
const view = new DataView(buffer.buffer);
|
|
110
|
+
// Write as big-endian int64
|
|
111
|
+
view.setBigInt64(1, value, false);
|
|
112
|
+
// Flip sign bit so negative numbers sort before positive
|
|
113
|
+
buffer[1] ^= 0x80;
|
|
114
|
+
return buffer;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Encode a floating-point number with proper sort ordering.
|
|
118
|
+
* IEEE 754 with sign manipulation for correct ordering.
|
|
119
|
+
*/
|
|
120
|
+
function encodeReal(value) {
|
|
121
|
+
const buffer = new Uint8Array(9);
|
|
122
|
+
buffer[0] = TYPE_REAL;
|
|
123
|
+
const view = new DataView(buffer.buffer);
|
|
124
|
+
view.setFloat64(1, value, false); // big-endian
|
|
125
|
+
// Flip all bits for negative, just sign bit for positive
|
|
126
|
+
// This makes: -Inf < -1 < -0 < +0 < +1 < +Inf < NaN
|
|
127
|
+
if (value < 0 || Object.is(value, -0)) {
|
|
128
|
+
for (let i = 1; i < 9; i++) {
|
|
129
|
+
buffer[i] ^= 0xff;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
buffer[1] ^= 0x80;
|
|
134
|
+
}
|
|
135
|
+
return buffer;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Encode text with collation support.
|
|
139
|
+
* Uses null-termination with escape sequences for embedded nulls.
|
|
140
|
+
*/
|
|
141
|
+
function encodeText(value, collation) {
|
|
142
|
+
// Apply collation transformation via encoder registry
|
|
143
|
+
const collationEncoder = getCollationEncoder(collation) ?? NOCASE_ENCODER;
|
|
144
|
+
const sortValue = collationEncoder.encode(value);
|
|
145
|
+
// Encode as UTF-8
|
|
146
|
+
const encoder = new TextEncoder();
|
|
147
|
+
const utf8 = encoder.encode(sortValue);
|
|
148
|
+
// Count bytes needing escape (null bytes and escape bytes)
|
|
149
|
+
let escapeCount = 0;
|
|
150
|
+
for (const byte of utf8) {
|
|
151
|
+
if (byte === NULL_BYTE || byte === ESCAPE_BYTE) {
|
|
152
|
+
escapeCount++;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Allocate: type prefix + escaped content + null terminator
|
|
156
|
+
const result = new Uint8Array(1 + utf8.length + escapeCount + 1);
|
|
157
|
+
result[0] = TYPE_TEXT;
|
|
158
|
+
let writePos = 1;
|
|
159
|
+
for (const byte of utf8) {
|
|
160
|
+
if (byte === NULL_BYTE) {
|
|
161
|
+
result[writePos++] = ESCAPE_BYTE;
|
|
162
|
+
result[writePos++] = 0x01; // Escaped null
|
|
163
|
+
}
|
|
164
|
+
else if (byte === ESCAPE_BYTE) {
|
|
165
|
+
result[writePos++] = ESCAPE_BYTE;
|
|
166
|
+
result[writePos++] = 0x02; // Escaped escape
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
result[writePos++] = byte;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
result[writePos] = NULL_BYTE; // Terminator
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Encode a blob with length prefix.
|
|
177
|
+
* Length is encoded as a variable-length integer for compact storage.
|
|
178
|
+
*/
|
|
179
|
+
function encodeBlob(value) {
|
|
180
|
+
const lengthBytes = encodeVarInt(value.length);
|
|
181
|
+
const result = new Uint8Array(1 + lengthBytes.length + value.length);
|
|
182
|
+
result[0] = TYPE_BLOB;
|
|
183
|
+
result.set(lengthBytes, 1);
|
|
184
|
+
result.set(value, 1 + lengthBytes.length);
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Encode an unsigned integer as a variable-length byte sequence.
|
|
189
|
+
* Uses high bit continuation: 1xxxxxxx means more bytes follow.
|
|
190
|
+
*/
|
|
191
|
+
function encodeVarInt(value) {
|
|
192
|
+
if (value < 0)
|
|
193
|
+
throw new Error('VarInt must be non-negative');
|
|
194
|
+
const bytes = [];
|
|
195
|
+
do {
|
|
196
|
+
let byte = value & 0x7f;
|
|
197
|
+
value >>>= 7;
|
|
198
|
+
if (value > 0)
|
|
199
|
+
byte |= 0x80;
|
|
200
|
+
bytes.push(byte);
|
|
201
|
+
} while (value > 0);
|
|
202
|
+
return new Uint8Array(bytes);
|
|
203
|
+
}
|
|
204
|
+
// ============================================================================
|
|
205
|
+
// Decoding functions
|
|
206
|
+
// ============================================================================
|
|
207
|
+
/**
|
|
208
|
+
* Decode a single value from a byte array.
|
|
209
|
+
* Returns the decoded value and the number of bytes consumed.
|
|
210
|
+
*/
|
|
211
|
+
export function decodeValue(buffer, offset = 0, options) {
|
|
212
|
+
if (offset >= buffer.length) {
|
|
213
|
+
throw new Error('Buffer underflow: no type byte');
|
|
214
|
+
}
|
|
215
|
+
const typePrefix = buffer[offset];
|
|
216
|
+
switch (typePrefix) {
|
|
217
|
+
case TYPE_NULL:
|
|
218
|
+
return { value: null, bytesRead: 1 };
|
|
219
|
+
case TYPE_INTEGER:
|
|
220
|
+
return decodeInteger(buffer, offset);
|
|
221
|
+
case TYPE_REAL:
|
|
222
|
+
return decodeReal(buffer, offset);
|
|
223
|
+
case TYPE_TEXT:
|
|
224
|
+
return decodeText(buffer, offset, options?.collation ?? 'NOCASE');
|
|
225
|
+
case TYPE_BLOB:
|
|
226
|
+
return decodeBlob(buffer, offset);
|
|
227
|
+
default:
|
|
228
|
+
throw new Error(`Unknown type prefix: 0x${typePrefix.toString(16)}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Decode a composite key into an array of values.
|
|
233
|
+
*/
|
|
234
|
+
export function decodeCompositeKey(buffer, expectedCount, options) {
|
|
235
|
+
const values = [];
|
|
236
|
+
let offset = 0;
|
|
237
|
+
while (offset < buffer.length) {
|
|
238
|
+
const { value, bytesRead } = decodeValue(buffer, offset, options);
|
|
239
|
+
values.push(value);
|
|
240
|
+
offset += bytesRead;
|
|
241
|
+
if (expectedCount !== undefined && values.length >= expectedCount) {
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return values;
|
|
246
|
+
}
|
|
247
|
+
function decodeInteger(buffer, offset) {
|
|
248
|
+
if (offset + 9 > buffer.length) {
|
|
249
|
+
throw new Error('Buffer underflow: expected 9 bytes for INTEGER');
|
|
250
|
+
}
|
|
251
|
+
// Copy and flip sign bit back
|
|
252
|
+
const copy = buffer.slice(offset + 1, offset + 9);
|
|
253
|
+
copy[0] ^= 0x80;
|
|
254
|
+
const view = new DataView(copy.buffer, copy.byteOffset, 8);
|
|
255
|
+
const value = view.getBigInt64(0, false);
|
|
256
|
+
return { value, bytesRead: 9 };
|
|
257
|
+
}
|
|
258
|
+
function decodeReal(buffer, offset) {
|
|
259
|
+
if (offset + 9 > buffer.length) {
|
|
260
|
+
throw new Error('Buffer underflow: expected 9 bytes for REAL');
|
|
261
|
+
}
|
|
262
|
+
const copy = buffer.slice(offset + 1, offset + 9);
|
|
263
|
+
// Check sign bit (before any flipping)
|
|
264
|
+
const isNegative = (buffer[offset + 1] & 0x80) === 0;
|
|
265
|
+
if (isNegative) {
|
|
266
|
+
// Was negative: flip all bits back
|
|
267
|
+
for (let i = 0; i < 8; i++) {
|
|
268
|
+
copy[i] ^= 0xff;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
// Was positive: flip just sign bit back
|
|
273
|
+
copy[0] ^= 0x80;
|
|
274
|
+
}
|
|
275
|
+
const view = new DataView(copy.buffer, copy.byteOffset, 8);
|
|
276
|
+
const value = view.getFloat64(0, false);
|
|
277
|
+
return { value, bytesRead: 9 };
|
|
278
|
+
}
|
|
279
|
+
function decodeText(buffer, offset, _collation) {
|
|
280
|
+
// Find null terminator, handling escapes
|
|
281
|
+
const bytes = [];
|
|
282
|
+
let i = offset + 1;
|
|
283
|
+
while (i < buffer.length) {
|
|
284
|
+
const byte = buffer[i];
|
|
285
|
+
if (byte === NULL_BYTE) {
|
|
286
|
+
// Terminator found
|
|
287
|
+
i++;
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
if (byte === ESCAPE_BYTE && i + 1 < buffer.length) {
|
|
291
|
+
const next = buffer[i + 1];
|
|
292
|
+
if (next === 0x01) {
|
|
293
|
+
bytes.push(NULL_BYTE);
|
|
294
|
+
i += 2;
|
|
295
|
+
}
|
|
296
|
+
else if (next === 0x02) {
|
|
297
|
+
bytes.push(ESCAPE_BYTE);
|
|
298
|
+
i += 2;
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
bytes.push(byte);
|
|
302
|
+
i++;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
bytes.push(byte);
|
|
307
|
+
i++;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const decoder = new TextDecoder();
|
|
311
|
+
const value = decoder.decode(new Uint8Array(bytes));
|
|
312
|
+
// Note: We return the lowercase version if NOCASE was used during encoding.
|
|
313
|
+
// The original case is preserved in the row value, not the key.
|
|
314
|
+
return { value, bytesRead: i - offset };
|
|
315
|
+
}
|
|
316
|
+
function decodeBlob(buffer, offset) {
|
|
317
|
+
const { value: length, bytesRead: lengthBytes } = decodeVarInt(buffer, offset + 1);
|
|
318
|
+
const dataStart = offset + 1 + lengthBytes;
|
|
319
|
+
if (dataStart + length > buffer.length) {
|
|
320
|
+
throw new Error('Buffer underflow: BLOB data truncated');
|
|
321
|
+
}
|
|
322
|
+
const value = buffer.slice(dataStart, dataStart + length);
|
|
323
|
+
return { value, bytesRead: 1 + lengthBytes + length };
|
|
324
|
+
}
|
|
325
|
+
function decodeVarInt(buffer, offset) {
|
|
326
|
+
let value = 0;
|
|
327
|
+
let shift = 0;
|
|
328
|
+
let bytesRead = 0;
|
|
329
|
+
while (offset + bytesRead < buffer.length) {
|
|
330
|
+
const byte = buffer[offset + bytesRead];
|
|
331
|
+
bytesRead++;
|
|
332
|
+
value |= (byte & 0x7f) << shift;
|
|
333
|
+
if ((byte & 0x80) === 0)
|
|
334
|
+
break;
|
|
335
|
+
shift += 7;
|
|
336
|
+
}
|
|
337
|
+
return { value, bytesRead };
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=encoding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../../src/common/encoding.ts"],"names":[],"mappings":"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"}
|