an atproto based link aggregator
at main 98 lines 3.0 kB view raw
1/** 2 * Set up FTS5 full-text search tables and triggers 3 * Run with: pnpm db:fts 4 */ 5 6import { createClient } from '@libsql/client'; 7 8const CONTENT_DB_PATH = process.env.CONTENT_DB_PATH || './data/content.db'; 9 10// FTS setup statements - each is a complete statement 11const statements = [ 12 // Posts FTS table 13 `CREATE VIRTUAL TABLE IF NOT EXISTS posts_fts USING fts5( 14 uri UNINDEXED, 15 title, 16 text, 17 url, 18 content='posts', 19 content_rowid='rowid' 20 )`, 21 22 // Posts triggers 23 `CREATE TRIGGER IF NOT EXISTS posts_fts_insert AFTER INSERT ON posts BEGIN 24 INSERT INTO posts_fts(rowid, uri, title, text, url) 25 VALUES (new.rowid, new.uri, new.title, new.text, new.url); 26 END`, 27 28 `CREATE TRIGGER IF NOT EXISTS posts_fts_delete AFTER DELETE ON posts BEGIN 29 INSERT INTO posts_fts(posts_fts, rowid, uri, title, text, url) 30 VALUES ('delete', old.rowid, old.uri, old.title, old.text, old.url); 31 END`, 32 33 `CREATE TRIGGER IF NOT EXISTS posts_fts_update AFTER UPDATE ON posts BEGIN 34 INSERT INTO posts_fts(posts_fts, rowid, uri, title, text, url) 35 VALUES ('delete', old.rowid, old.uri, old.title, old.text, old.url); 36 INSERT INTO posts_fts(rowid, uri, title, text, url) 37 VALUES (new.rowid, new.uri, new.title, new.text, new.url); 38 END`, 39 40 // Comments FTS table 41 `CREATE VIRTUAL TABLE IF NOT EXISTS comments_fts USING fts5( 42 uri UNINDEXED, 43 post_uri UNINDEXED, 44 text, 45 content='comments', 46 content_rowid='rowid' 47 )`, 48 49 // Comments triggers 50 `CREATE TRIGGER IF NOT EXISTS comments_fts_insert AFTER INSERT ON comments BEGIN 51 INSERT INTO comments_fts(rowid, uri, post_uri, text) 52 VALUES (new.rowid, new.uri, new.post_uri, new.text); 53 END`, 54 55 `CREATE TRIGGER IF NOT EXISTS comments_fts_delete AFTER DELETE ON comments BEGIN 56 INSERT INTO comments_fts(comments_fts, rowid, uri, post_uri, text) 57 VALUES ('delete', old.rowid, old.uri, old.post_uri, old.text); 58 END`, 59 60 `CREATE TRIGGER IF NOT EXISTS comments_fts_update AFTER UPDATE ON comments BEGIN 61 INSERT INTO comments_fts(comments_fts, rowid, uri, post_uri, text) 62 VALUES ('delete', old.rowid, old.uri, old.post_uri, old.text); 63 INSERT INTO comments_fts(rowid, uri, post_uri, text) 64 VALUES (new.rowid, new.uri, new.post_uri, new.text); 65 END`, 66 67 // Rebuild FTS indexes from existing data 68 `INSERT INTO posts_fts(posts_fts) VALUES('rebuild')`, 69 `INSERT INTO comments_fts(comments_fts) VALUES('rebuild')` 70]; 71 72async function setupFTS() { 73 console.log(`Setting up FTS5 for ${CONTENT_DB_PATH}...`); 74 75 const client = createClient({ 76 url: `file:${CONTENT_DB_PATH}` 77 }); 78 79 for (const sql of statements) { 80 const preview = sql.slice(0, 60).replace(/\s+/g, ' ').trim(); 81 try { 82 await client.execute(sql); 83 console.log('✓', preview + '...'); 84 } catch (err) { 85 if (err instanceof Error && err.message.includes('already exists')) { 86 console.log('⊘', preview + '... (already exists)'); 87 } else { 88 console.error('✗', preview); 89 console.error(' Error:', err instanceof Error ? err.message : err); 90 } 91 } 92 } 93 94 console.log('\nFTS5 setup complete!'); 95 process.exit(0); 96} 97 98setupFTS();