latticesql 0.18.0 → 0.18.2
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/dist/cli.js +4 -0
- package/dist/index.cjs +41 -2
- package/dist/index.d.cts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +40 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -536,6 +536,10 @@ var SchemaManager = class {
|
|
|
536
536
|
*/
|
|
537
537
|
queryTable(adapter, name) {
|
|
538
538
|
if (this._tables.has(name)) {
|
|
539
|
+
const def = this._tables.get(name);
|
|
540
|
+
if (def.columns && "deleted_at" in def.columns) {
|
|
541
|
+
return adapter.all(`SELECT * FROM "${name}" WHERE deleted_at IS NULL`);
|
|
542
|
+
}
|
|
539
543
|
return adapter.all(`SELECT * FROM "${name}"`);
|
|
540
544
|
}
|
|
541
545
|
if (this._entityContexts.has(name)) {
|
package/dist/index.cjs
CHANGED
|
@@ -43,6 +43,7 @@ __export(index_exports, {
|
|
|
43
43
|
deriveKey: () => deriveKey,
|
|
44
44
|
encrypt: () => encrypt,
|
|
45
45
|
entityFileNames: () => entityFileNames,
|
|
46
|
+
fixSchemaConflicts: () => fixSchemaConflicts,
|
|
46
47
|
frontmatter: () => frontmatter,
|
|
47
48
|
generateEntryId: () => generateEntryId,
|
|
48
49
|
generateWriteEntryId: () => generateWriteEntryId,
|
|
@@ -288,6 +289,10 @@ var SchemaManager = class {
|
|
|
288
289
|
*/
|
|
289
290
|
queryTable(adapter, name) {
|
|
290
291
|
if (this._tables.has(name)) {
|
|
292
|
+
const def = this._tables.get(name);
|
|
293
|
+
if (def.columns && "deleted_at" in def.columns) {
|
|
294
|
+
return adapter.all(`SELECT * FROM "${name}" WHERE deleted_at IS NULL`);
|
|
295
|
+
}
|
|
291
296
|
return adapter.all(`SELECT * FROM "${name}"`);
|
|
292
297
|
}
|
|
293
298
|
if (this._entityContexts.has(name)) {
|
|
@@ -2644,6 +2649,39 @@ var Lattice = class {
|
|
|
2644
2649
|
}
|
|
2645
2650
|
};
|
|
2646
2651
|
|
|
2652
|
+
// src/lifecycle/pre-init.ts
|
|
2653
|
+
function fixSchemaConflicts(db, checks) {
|
|
2654
|
+
for (const { table, requiredColumns } of checks) {
|
|
2655
|
+
if (!tableExists(db, table)) continue;
|
|
2656
|
+
const cols = getColumns(db, table);
|
|
2657
|
+
const missing = requiredColumns.filter((c) => !cols.includes(c));
|
|
2658
|
+
if (missing.length > 0) {
|
|
2659
|
+
renameTable(db, table);
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
if (tableExists(db, "__lattice_migrations")) {
|
|
2663
|
+
const versionCol = db.prepare('PRAGMA table_info("__lattice_migrations")').all().find((c) => c.name === "version");
|
|
2664
|
+
if (versionCol && versionCol.type.toUpperCase().includes("INTEGER")) {
|
|
2665
|
+
db.exec(
|
|
2666
|
+
'ALTER TABLE "__lattice_migrations" RENAME TO "__lattice_migrations_v1"'
|
|
2667
|
+
);
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
function tableExists(db, name) {
|
|
2672
|
+
return !!db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?").get(name);
|
|
2673
|
+
}
|
|
2674
|
+
function getColumns(db, table) {
|
|
2675
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().map((c) => c.name);
|
|
2676
|
+
}
|
|
2677
|
+
function renameTable(db, table) {
|
|
2678
|
+
const target = `_legacy_${table}`;
|
|
2679
|
+
if (tableExists(db, target)) {
|
|
2680
|
+
db.exec(`DROP TABLE "${target}"`);
|
|
2681
|
+
}
|
|
2682
|
+
db.exec(`ALTER TABLE "${table}" RENAME TO "${target}"`);
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2647
2685
|
// src/session/parser.ts
|
|
2648
2686
|
var import_node_crypto4 = require("crypto");
|
|
2649
2687
|
function generateWriteEntryId(timestamp, agentName, op, table, target) {
|
|
@@ -2990,8 +3028,8 @@ function applyWriteEntry(db, entry) {
|
|
|
2990
3028
|
if (!TABLE_NAME_RE2.test(table)) {
|
|
2991
3029
|
return { ok: false, reason: `Invalid table name: "${table}". Only [a-zA-Z0-9_] allowed` };
|
|
2992
3030
|
}
|
|
2993
|
-
const
|
|
2994
|
-
if (!
|
|
3031
|
+
const tableExists2 = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?").get(table);
|
|
3032
|
+
if (!tableExists2) {
|
|
2995
3033
|
return { ok: false, reason: `Unknown table: "${table}"` };
|
|
2996
3034
|
}
|
|
2997
3035
|
const columnRows = db.prepare(`PRAGMA table_info("${table}")`).all();
|
|
@@ -3061,6 +3099,7 @@ function applyWriteEntry(db, entry) {
|
|
|
3061
3099
|
deriveKey,
|
|
3062
3100
|
encrypt,
|
|
3063
3101
|
entityFileNames,
|
|
3102
|
+
fixSchemaConflicts,
|
|
3064
3103
|
frontmatter,
|
|
3065
3104
|
generateEntryId,
|
|
3066
3105
|
generateWriteEntryId,
|
package/dist/index.d.cts
CHANGED
|
@@ -1494,6 +1494,38 @@ declare function parseConfigString(yamlContent: string, configDir: string): Pars
|
|
|
1494
1494
|
|
|
1495
1495
|
declare function contentHash(content: string): string;
|
|
1496
1496
|
|
|
1497
|
+
/**
|
|
1498
|
+
* Fix legacy schema conflicts before Lattice init().
|
|
1499
|
+
*
|
|
1500
|
+
* When upgrading from an older schema version, existing tables may have
|
|
1501
|
+
* incompatible column definitions (e.g., a column with PRIMARY KEY that
|
|
1502
|
+
* new code tries to add via ALTER TABLE, which SQLite doesn't support).
|
|
1503
|
+
*
|
|
1504
|
+
* This utility renames conflicting tables to `_legacy_{name}` so init()
|
|
1505
|
+
* can create fresh tables with the new schema.
|
|
1506
|
+
*
|
|
1507
|
+
* @param db - An open better-sqlite3 database instance
|
|
1508
|
+
* @param checks - Array of { table, requiredColumns } to verify
|
|
1509
|
+
*
|
|
1510
|
+
* @example
|
|
1511
|
+
* ```ts
|
|
1512
|
+
* import Database from 'better-sqlite3';
|
|
1513
|
+
* import { fixSchemaConflicts } from 'latticesql';
|
|
1514
|
+
*
|
|
1515
|
+
* const db = new Database('./app.db');
|
|
1516
|
+
* fixSchemaConflicts(db, [
|
|
1517
|
+
* { table: 'sessions', requiredColumns: ['id'] },
|
|
1518
|
+
* { table: 'messages', requiredColumns: ['id'] },
|
|
1519
|
+
* ]);
|
|
1520
|
+
* db.close();
|
|
1521
|
+
* // Now safe to call lattice.init()
|
|
1522
|
+
* ```
|
|
1523
|
+
*/
|
|
1524
|
+
declare function fixSchemaConflicts(db: Database.Database, checks: Array<{
|
|
1525
|
+
table: string;
|
|
1526
|
+
requiredColumns: string[];
|
|
1527
|
+
}>): void;
|
|
1528
|
+
|
|
1497
1529
|
/**
|
|
1498
1530
|
* Derive a 256-bit AES key from a master password using scrypt.
|
|
1499
1531
|
* The salt is fixed per Lattice instance — callers should use a unique
|
|
@@ -1760,4 +1792,4 @@ declare function createReadOnlyHeader(options?: ReadOnlyHeaderOptions): string;
|
|
|
1760
1792
|
*/
|
|
1761
1793
|
declare const READ_ONLY_HEADER: string;
|
|
1762
1794
|
|
|
1763
|
-
export { type ApplyWriteResult, type AuditEvent, type BelongsToRelation, type BelongsToSource, type BuiltinTemplateName, type CleanupOptions, type CleanupResult, type CountOptions, type CustomSource, DEFAULT_ENTRY_TYPES, DEFAULT_TYPE_ALIASES, type EnrichedSource, type EnrichmentLookup, type EntityContextDefinition, type EntityContextManifestEntry, type EntityFileManifestInfo, type EntityFileSource, type EntityFileSpec, type EntityProfileField, type EntityProfileSection, type EntityProfileTemplate, type EntityRenderSpec, type EntityRenderTemplate, type EntitySectionPerRow, type EntitySectionsTemplate, type EntityTableColumn, type EntityTableTemplate, type Filter, type FilterOp, type HasManyRelation, type HasManySource, InMemoryStateStore, type InitOptions, Lattice, type LatticeConfig, type LatticeConfigInput, type LatticeEntityDef, type LatticeEntityRenderSpec, type LatticeFieldDef, type LatticeFieldType, type LatticeManifest, type LatticeOptions, type LinkOptions, type ManyToManySource, type MarkdownTableColumn, type Migration, type MultiTableDefinition, type OrderBySpec, type ParseError, type ParseResult, type ParsedConfig, type PkLookup, type PrimaryKey, type QueryOptions, READ_ONLY_HEADER, type ReadOnlyHeaderOptions, type ReconcileOptions, type ReconcileResult, type Relation, type RenderHooks, type RenderResult, type RenderSpec, type ReportConfig, type ReportResult, type ReportSection, type ReportSectionResult, type ReverseSyncError, type ReverseSyncResult, type ReverseSyncUpdate, type Row, type SecurityOptions, type SeedConfig, type SeedLinkSpec, type SeedResult, type SelfSource, type SessionEntry, type SessionParseOptions, type SessionWriteEntry, type SessionWriteOp, type SessionWriteParseResult, type SourceQueryOptions, type StopFn, type SyncResult, type TableDefinition, type TemplateRenderSpec, type UpsertByNaturalKeyOptions, type WatchOptions, type WriteHook, type WriteHookContext, type WritebackDefinition, type WritebackStateStore, applyWriteEntry, contentHash, createReadOnlyHeader, createSQLiteStateStore, decrypt, deriveKey, encrypt, entityFileNames, frontmatter, generateEntryId, generateWriteEntryId, isEncrypted, isV1EntityFiles, manifestPath, markdownTable, normalizeEntityFiles, parseConfigFile, parseConfigString, parseMarkdownEntries, parseSessionMD, parseSessionWrites, readManifest, slugify, truncate, validateEntryId, writeManifest };
|
|
1795
|
+
export { type ApplyWriteResult, type AuditEvent, type BelongsToRelation, type BelongsToSource, type BuiltinTemplateName, type CleanupOptions, type CleanupResult, type CountOptions, type CustomSource, DEFAULT_ENTRY_TYPES, DEFAULT_TYPE_ALIASES, type EnrichedSource, type EnrichmentLookup, type EntityContextDefinition, type EntityContextManifestEntry, type EntityFileManifestInfo, type EntityFileSource, type EntityFileSpec, type EntityProfileField, type EntityProfileSection, type EntityProfileTemplate, type EntityRenderSpec, type EntityRenderTemplate, type EntitySectionPerRow, type EntitySectionsTemplate, type EntityTableColumn, type EntityTableTemplate, type Filter, type FilterOp, type HasManyRelation, type HasManySource, InMemoryStateStore, type InitOptions, Lattice, type LatticeConfig, type LatticeConfigInput, type LatticeEntityDef, type LatticeEntityRenderSpec, type LatticeFieldDef, type LatticeFieldType, type LatticeManifest, type LatticeOptions, type LinkOptions, type ManyToManySource, type MarkdownTableColumn, type Migration, type MultiTableDefinition, type OrderBySpec, type ParseError, type ParseResult, type ParsedConfig, type PkLookup, type PrimaryKey, type QueryOptions, READ_ONLY_HEADER, type ReadOnlyHeaderOptions, type ReconcileOptions, type ReconcileResult, type Relation, type RenderHooks, type RenderResult, type RenderSpec, type ReportConfig, type ReportResult, type ReportSection, type ReportSectionResult, type ReverseSyncError, type ReverseSyncResult, type ReverseSyncUpdate, type Row, type SecurityOptions, type SeedConfig, type SeedLinkSpec, type SeedResult, type SelfSource, type SessionEntry, type SessionParseOptions, type SessionWriteEntry, type SessionWriteOp, type SessionWriteParseResult, type SourceQueryOptions, type StopFn, type SyncResult, type TableDefinition, type TemplateRenderSpec, type UpsertByNaturalKeyOptions, type WatchOptions, type WriteHook, type WriteHookContext, type WritebackDefinition, type WritebackStateStore, applyWriteEntry, contentHash, createReadOnlyHeader, createSQLiteStateStore, decrypt, deriveKey, encrypt, entityFileNames, fixSchemaConflicts, frontmatter, generateEntryId, generateWriteEntryId, isEncrypted, isV1EntityFiles, manifestPath, markdownTable, normalizeEntityFiles, parseConfigFile, parseConfigString, parseMarkdownEntries, parseSessionMD, parseSessionWrites, readManifest, slugify, truncate, validateEntryId, writeManifest };
|
package/dist/index.d.ts
CHANGED
|
@@ -1494,6 +1494,38 @@ declare function parseConfigString(yamlContent: string, configDir: string): Pars
|
|
|
1494
1494
|
|
|
1495
1495
|
declare function contentHash(content: string): string;
|
|
1496
1496
|
|
|
1497
|
+
/**
|
|
1498
|
+
* Fix legacy schema conflicts before Lattice init().
|
|
1499
|
+
*
|
|
1500
|
+
* When upgrading from an older schema version, existing tables may have
|
|
1501
|
+
* incompatible column definitions (e.g., a column with PRIMARY KEY that
|
|
1502
|
+
* new code tries to add via ALTER TABLE, which SQLite doesn't support).
|
|
1503
|
+
*
|
|
1504
|
+
* This utility renames conflicting tables to `_legacy_{name}` so init()
|
|
1505
|
+
* can create fresh tables with the new schema.
|
|
1506
|
+
*
|
|
1507
|
+
* @param db - An open better-sqlite3 database instance
|
|
1508
|
+
* @param checks - Array of { table, requiredColumns } to verify
|
|
1509
|
+
*
|
|
1510
|
+
* @example
|
|
1511
|
+
* ```ts
|
|
1512
|
+
* import Database from 'better-sqlite3';
|
|
1513
|
+
* import { fixSchemaConflicts } from 'latticesql';
|
|
1514
|
+
*
|
|
1515
|
+
* const db = new Database('./app.db');
|
|
1516
|
+
* fixSchemaConflicts(db, [
|
|
1517
|
+
* { table: 'sessions', requiredColumns: ['id'] },
|
|
1518
|
+
* { table: 'messages', requiredColumns: ['id'] },
|
|
1519
|
+
* ]);
|
|
1520
|
+
* db.close();
|
|
1521
|
+
* // Now safe to call lattice.init()
|
|
1522
|
+
* ```
|
|
1523
|
+
*/
|
|
1524
|
+
declare function fixSchemaConflicts(db: Database.Database, checks: Array<{
|
|
1525
|
+
table: string;
|
|
1526
|
+
requiredColumns: string[];
|
|
1527
|
+
}>): void;
|
|
1528
|
+
|
|
1497
1529
|
/**
|
|
1498
1530
|
* Derive a 256-bit AES key from a master password using scrypt.
|
|
1499
1531
|
* The salt is fixed per Lattice instance — callers should use a unique
|
|
@@ -1760,4 +1792,4 @@ declare function createReadOnlyHeader(options?: ReadOnlyHeaderOptions): string;
|
|
|
1760
1792
|
*/
|
|
1761
1793
|
declare const READ_ONLY_HEADER: string;
|
|
1762
1794
|
|
|
1763
|
-
export { type ApplyWriteResult, type AuditEvent, type BelongsToRelation, type BelongsToSource, type BuiltinTemplateName, type CleanupOptions, type CleanupResult, type CountOptions, type CustomSource, DEFAULT_ENTRY_TYPES, DEFAULT_TYPE_ALIASES, type EnrichedSource, type EnrichmentLookup, type EntityContextDefinition, type EntityContextManifestEntry, type EntityFileManifestInfo, type EntityFileSource, type EntityFileSpec, type EntityProfileField, type EntityProfileSection, type EntityProfileTemplate, type EntityRenderSpec, type EntityRenderTemplate, type EntitySectionPerRow, type EntitySectionsTemplate, type EntityTableColumn, type EntityTableTemplate, type Filter, type FilterOp, type HasManyRelation, type HasManySource, InMemoryStateStore, type InitOptions, Lattice, type LatticeConfig, type LatticeConfigInput, type LatticeEntityDef, type LatticeEntityRenderSpec, type LatticeFieldDef, type LatticeFieldType, type LatticeManifest, type LatticeOptions, type LinkOptions, type ManyToManySource, type MarkdownTableColumn, type Migration, type MultiTableDefinition, type OrderBySpec, type ParseError, type ParseResult, type ParsedConfig, type PkLookup, type PrimaryKey, type QueryOptions, READ_ONLY_HEADER, type ReadOnlyHeaderOptions, type ReconcileOptions, type ReconcileResult, type Relation, type RenderHooks, type RenderResult, type RenderSpec, type ReportConfig, type ReportResult, type ReportSection, type ReportSectionResult, type ReverseSyncError, type ReverseSyncResult, type ReverseSyncUpdate, type Row, type SecurityOptions, type SeedConfig, type SeedLinkSpec, type SeedResult, type SelfSource, type SessionEntry, type SessionParseOptions, type SessionWriteEntry, type SessionWriteOp, type SessionWriteParseResult, type SourceQueryOptions, type StopFn, type SyncResult, type TableDefinition, type TemplateRenderSpec, type UpsertByNaturalKeyOptions, type WatchOptions, type WriteHook, type WriteHookContext, type WritebackDefinition, type WritebackStateStore, applyWriteEntry, contentHash, createReadOnlyHeader, createSQLiteStateStore, decrypt, deriveKey, encrypt, entityFileNames, frontmatter, generateEntryId, generateWriteEntryId, isEncrypted, isV1EntityFiles, manifestPath, markdownTable, normalizeEntityFiles, parseConfigFile, parseConfigString, parseMarkdownEntries, parseSessionMD, parseSessionWrites, readManifest, slugify, truncate, validateEntryId, writeManifest };
|
|
1795
|
+
export { type ApplyWriteResult, type AuditEvent, type BelongsToRelation, type BelongsToSource, type BuiltinTemplateName, type CleanupOptions, type CleanupResult, type CountOptions, type CustomSource, DEFAULT_ENTRY_TYPES, DEFAULT_TYPE_ALIASES, type EnrichedSource, type EnrichmentLookup, type EntityContextDefinition, type EntityContextManifestEntry, type EntityFileManifestInfo, type EntityFileSource, type EntityFileSpec, type EntityProfileField, type EntityProfileSection, type EntityProfileTemplate, type EntityRenderSpec, type EntityRenderTemplate, type EntitySectionPerRow, type EntitySectionsTemplate, type EntityTableColumn, type EntityTableTemplate, type Filter, type FilterOp, type HasManyRelation, type HasManySource, InMemoryStateStore, type InitOptions, Lattice, type LatticeConfig, type LatticeConfigInput, type LatticeEntityDef, type LatticeEntityRenderSpec, type LatticeFieldDef, type LatticeFieldType, type LatticeManifest, type LatticeOptions, type LinkOptions, type ManyToManySource, type MarkdownTableColumn, type Migration, type MultiTableDefinition, type OrderBySpec, type ParseError, type ParseResult, type ParsedConfig, type PkLookup, type PrimaryKey, type QueryOptions, READ_ONLY_HEADER, type ReadOnlyHeaderOptions, type ReconcileOptions, type ReconcileResult, type Relation, type RenderHooks, type RenderResult, type RenderSpec, type ReportConfig, type ReportResult, type ReportSection, type ReportSectionResult, type ReverseSyncError, type ReverseSyncResult, type ReverseSyncUpdate, type Row, type SecurityOptions, type SeedConfig, type SeedLinkSpec, type SeedResult, type SelfSource, type SessionEntry, type SessionParseOptions, type SessionWriteEntry, type SessionWriteOp, type SessionWriteParseResult, type SourceQueryOptions, type StopFn, type SyncResult, type TableDefinition, type TemplateRenderSpec, type UpsertByNaturalKeyOptions, type WatchOptions, type WriteHook, type WriteHookContext, type WritebackDefinition, type WritebackStateStore, applyWriteEntry, contentHash, createReadOnlyHeader, createSQLiteStateStore, decrypt, deriveKey, encrypt, entityFileNames, fixSchemaConflicts, frontmatter, generateEntryId, generateWriteEntryId, isEncrypted, isV1EntityFiles, manifestPath, markdownTable, normalizeEntityFiles, parseConfigFile, parseConfigString, parseMarkdownEntries, parseSessionMD, parseSessionWrites, readManifest, slugify, truncate, validateEntryId, writeManifest };
|
package/dist/index.js
CHANGED
|
@@ -222,6 +222,10 @@ var SchemaManager = class {
|
|
|
222
222
|
*/
|
|
223
223
|
queryTable(adapter, name) {
|
|
224
224
|
if (this._tables.has(name)) {
|
|
225
|
+
const def = this._tables.get(name);
|
|
226
|
+
if (def.columns && "deleted_at" in def.columns) {
|
|
227
|
+
return adapter.all(`SELECT * FROM "${name}" WHERE deleted_at IS NULL`);
|
|
228
|
+
}
|
|
225
229
|
return adapter.all(`SELECT * FROM "${name}"`);
|
|
226
230
|
}
|
|
227
231
|
if (this._entityContexts.has(name)) {
|
|
@@ -2578,6 +2582,39 @@ var Lattice = class {
|
|
|
2578
2582
|
}
|
|
2579
2583
|
};
|
|
2580
2584
|
|
|
2585
|
+
// src/lifecycle/pre-init.ts
|
|
2586
|
+
function fixSchemaConflicts(db, checks) {
|
|
2587
|
+
for (const { table, requiredColumns } of checks) {
|
|
2588
|
+
if (!tableExists(db, table)) continue;
|
|
2589
|
+
const cols = getColumns(db, table);
|
|
2590
|
+
const missing = requiredColumns.filter((c) => !cols.includes(c));
|
|
2591
|
+
if (missing.length > 0) {
|
|
2592
|
+
renameTable(db, table);
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
if (tableExists(db, "__lattice_migrations")) {
|
|
2596
|
+
const versionCol = db.prepare('PRAGMA table_info("__lattice_migrations")').all().find((c) => c.name === "version");
|
|
2597
|
+
if (versionCol && versionCol.type.toUpperCase().includes("INTEGER")) {
|
|
2598
|
+
db.exec(
|
|
2599
|
+
'ALTER TABLE "__lattice_migrations" RENAME TO "__lattice_migrations_v1"'
|
|
2600
|
+
);
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
function tableExists(db, name) {
|
|
2605
|
+
return !!db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?").get(name);
|
|
2606
|
+
}
|
|
2607
|
+
function getColumns(db, table) {
|
|
2608
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().map((c) => c.name);
|
|
2609
|
+
}
|
|
2610
|
+
function renameTable(db, table) {
|
|
2611
|
+
const target = `_legacy_${table}`;
|
|
2612
|
+
if (tableExists(db, target)) {
|
|
2613
|
+
db.exec(`DROP TABLE "${target}"`);
|
|
2614
|
+
}
|
|
2615
|
+
db.exec(`ALTER TABLE "${table}" RENAME TO "${target}"`);
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2581
2618
|
// src/session/parser.ts
|
|
2582
2619
|
import { createHash as createHash2 } from "crypto";
|
|
2583
2620
|
function generateWriteEntryId(timestamp, agentName, op, table, target) {
|
|
@@ -2924,8 +2961,8 @@ function applyWriteEntry(db, entry) {
|
|
|
2924
2961
|
if (!TABLE_NAME_RE2.test(table)) {
|
|
2925
2962
|
return { ok: false, reason: `Invalid table name: "${table}". Only [a-zA-Z0-9_] allowed` };
|
|
2926
2963
|
}
|
|
2927
|
-
const
|
|
2928
|
-
if (!
|
|
2964
|
+
const tableExists2 = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?").get(table);
|
|
2965
|
+
if (!tableExists2) {
|
|
2929
2966
|
return { ok: false, reason: `Unknown table: "${table}"` };
|
|
2930
2967
|
}
|
|
2931
2968
|
const columnRows = db.prepare(`PRAGMA table_info("${table}")`).all();
|
|
@@ -2994,6 +3031,7 @@ export {
|
|
|
2994
3031
|
deriveKey,
|
|
2995
3032
|
encrypt,
|
|
2996
3033
|
entityFileNames,
|
|
3034
|
+
fixSchemaConflicts,
|
|
2997
3035
|
frontmatter,
|
|
2998
3036
|
generateEntryId,
|
|
2999
3037
|
generateWriteEntryId,
|