|
|
|
@@ -35,6 +35,11 @@ export class SqliteAdapter implements DatabaseInterface {
|
|
|
|
|
if (!columns.some(col => col.name === 'folder_id')) {
|
|
|
|
|
this.db.exec('ALTER TABLE projects ADD COLUMN folder_id TEXT REFERENCES project_folders(id) ON DELETE SET NULL');
|
|
|
|
|
}
|
|
|
|
|
// Add is_favorite column to global_blocks table for existing databases (Task F2)
|
|
|
|
|
const gbColumns = this.db.prepare("PRAGMA table_info('global_blocks')").all() as { name: string }[];
|
|
|
|
|
if (!gbColumns.some(col => col.name === 'is_favorite')) {
|
|
|
|
|
this.db.exec('ALTER TABLE global_blocks ADD COLUMN is_favorite INTEGER NOT NULL DEFAULT 0');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
close(): void {
|
|
|
|
@@ -423,25 +428,31 @@ export class SqliteAdapter implements DatabaseInterface {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Global Blocks ─────────────────────────────────────
|
|
|
|
|
// Map DB row to DBGlobalBlock (is_favorite 0/1 → boolean, Task F2)
|
|
|
|
|
private mapGlobalBlockRow(row: Record<string, unknown>): DBGlobalBlock {
|
|
|
|
|
return { ...(row as unknown as DBGlobalBlock), is_favorite: Number(row.is_favorite ?? 0) === 1 };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
listGlobalBlocks(folderId?: string | null): DBGlobalBlock[] {
|
|
|
|
|
if (folderId === undefined) {
|
|
|
|
|
return this.db.prepare('SELECT * FROM global_blocks ORDER BY updated_at DESC').all() as DBGlobalBlock[];
|
|
|
|
|
return (this.db.prepare('SELECT * FROM global_blocks ORDER BY updated_at DESC').all() as Record<string, unknown>[]).map(r => this.mapGlobalBlockRow(r));
|
|
|
|
|
}
|
|
|
|
|
if (folderId === null) {
|
|
|
|
|
return this.db.prepare('SELECT * FROM global_blocks WHERE folder_id IS NULL ORDER BY updated_at DESC').all() as DBGlobalBlock[];
|
|
|
|
|
return (this.db.prepare('SELECT * FROM global_blocks WHERE folder_id IS NULL ORDER BY updated_at DESC').all() as Record<string, unknown>[]).map(r => this.mapGlobalBlockRow(r));
|
|
|
|
|
}
|
|
|
|
|
return this.db.prepare('SELECT * FROM global_blocks WHERE folder_id = ? ORDER BY updated_at DESC').all(folderId) as DBGlobalBlock[];
|
|
|
|
|
return (this.db.prepare('SELECT * FROM global_blocks WHERE folder_id = ? ORDER BY updated_at DESC').all(folderId) as Record<string, unknown>[]).map(r => this.mapGlobalBlockRow(r));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getGlobalBlock(id: string): DBGlobalBlock | null {
|
|
|
|
|
return (this.db.prepare('SELECT * FROM global_blocks WHERE id = ?').get(id) as DBGlobalBlock) ?? null;
|
|
|
|
|
const row = this.db.prepare('SELECT * FROM global_blocks WHERE id = ?').get(id) as Record<string, unknown> | undefined;
|
|
|
|
|
return row ? this.mapGlobalBlockRow(row) : null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
createGlobalBlock(data: Partial<DBGlobalBlock>): DBGlobalBlock {
|
|
|
|
|
const id = data.id ?? `gblock-${randomUUID().slice(0, 8)}`;
|
|
|
|
|
this.db.prepare(
|
|
|
|
|
'INSERT INTO global_blocks (id, folder_id, name, block_data, svg_data) VALUES (?, ?, ?, ?, ?)',
|
|
|
|
|
).run(id, data.folder_id ?? null, data.name ?? 'Global Block', data.block_data ?? '{}', data.svg_data ?? null);
|
|
|
|
|
'INSERT INTO global_blocks (id, folder_id, name, block_data, svg_data, is_favorite) VALUES (?, ?, ?, ?, ?, ?)',
|
|
|
|
|
).run(id, data.folder_id ?? null, data.name ?? 'Global Block', data.block_data ?? '{}', data.svg_data ?? null, data.is_favorite ? 1 : 0);
|
|
|
|
|
return this.getGlobalBlock(id)!;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -452,6 +463,7 @@ export class SqliteAdapter implements DatabaseInterface {
|
|
|
|
|
if (data.folder_id !== undefined) { sets.push('folder_id = ?'); vals.push(data.folder_id); }
|
|
|
|
|
if (data.block_data !== undefined) { sets.push('block_data = ?'); vals.push(data.block_data); }
|
|
|
|
|
if (data.svg_data !== undefined) { sets.push('svg_data = ?'); vals.push(data.svg_data); }
|
|
|
|
|
if (data.is_favorite !== undefined) { sets.push('is_favorite = ?'); vals.push(data.is_favorite ? 1 : 0); }
|
|
|
|
|
sets.push("updated_at = datetime('now')");
|
|
|
|
|
this.db.prepare(`UPDATE global_blocks SET ${sets.join(', ')} WHERE id = ?`).run(...vals, id);
|
|
|
|
|
return this.getGlobalBlock(id);
|
|
|
|
|