'use strict'; const assert = require('node:assert'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); const Database = require('better-sqlite3'); const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'clip-fts-')); const db = new Database(path.join(tmp, 'h.db')); db.exec(`CREATE TABLE clips (id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT, text TEXT)`); let hasFts5 = true; try { db.exec(`CREATE VIRTUAL TABLE clips_fts USING fts5(text, content='clips', content_rowid='id')`); } catch (e) { hasFts5 = false; db.close(); console.log(' SKIP - no FTS5 available'); process.exit(0); } db.exec(` CREATE TRIGGER clips_ai AFTER INSERT ON clips BEGIN INSERT INTO clips_fts(rowid,text) VALUES (new.id, new.text); END; `); for (let i = 0; i < 50; i++) { const txt = i % 3 === 0 ? `hello world ${i}` : `lorem ipsum ${i}`; db.prepare('INSERT INTO clips(type,text) VALUES(?,?)').run('text', txt); } let passed = 0; function check(name, fn) { try { fn(); console.log(' ok -', name); passed++; } catch (e) { console.error(' FAIL -', name, e.message); process.exitCode = 1; } } check('FTS5 MATCH finds exact substring', () => { const r = db.prepare(`SELECT rowid FROM clips_fts WHERE clips_fts MATCH ?`).all('hello'); assert.ok(r.length > 0); }); db.close();