MCPcopy
hub / github.com/afar1/fieldtheory-cli / buildIndex

Function buildIndex

src/bookmarks-db.ts:436–507  ·  view source on GitHub ↗
(options?: { force?: boolean })

Source from the content-addressed store, hash-verified

434}
435
436export async function buildIndex(options?: { force?: boolean }): Promise<{ dbPath: string; recordCount: number; newRecords: number }> {
437 const cachePath = twitterBookmarksCachePath();
438 const dbPath = twitterBookmarksIndexPath();
439 const records = await readJsonLines<BookmarkRecord>(cachePath);
440
441 const db = await openDb(dbPath);
442 try {
443 if (options?.force) {
444 db.run('DROP TABLE IF EXISTS bookmarks_fts');
445 db.run('DROP TABLE IF EXISTS bookmarks');
446 db.run('DROP TABLE IF EXISTS meta');
447 }
448
449 initSchema(db);
450 ensureMigrations(db);
451
452 // Preserve classification and enrichment fields when refreshing existing rows.
453 // Folder fields are normally sourced from JSONL (source of truth) but we also
454 // preserve them here as defense-in-depth: if a future code path writes folder
455 // state to the DB without updating JSONL, this keeps it from being wiped on
456 // the next buildIndex.
457 const existingRows = new Map<string, PreservedBookmarkFields>();
458 try {
459 const rows = db.exec(
460 `SELECT id, categories, primary_category, github_urls, domains, primary_domain,
461 quoted_tweet_json, article_title, article_text, article_site, enriched_at,
462 folder_ids, folder_names
463 FROM bookmarks`
464 );
465 for (const r of (rows[0]?.values ?? [])) {
466 existingRows.set(r[0] as string, {
467 categories: (r[1] as string) ?? null,
468 primaryCategory: (r[2] as string) ?? null,
469 githubUrls: (r[3] as string) ?? null,
470 domains: (r[4] as string) ?? null,
471 primaryDomain: (r[5] as string) ?? null,
472 quotedTweetJson: (r[6] as string) ?? null,
473 articleTitle: (r[7] as string) ?? null,
474 articleText: (r[8] as string) ?? null,
475 articleSite: (r[9] as string) ?? null,
476 enrichedAt: (r[10] as string) ?? null,
477 folderIds: (r[11] as string) ?? null,
478 folderNames: (r[12] as string) ?? null,
479 });
480 }
481 } catch { /* table may be empty */ }
482
483 const newRecords: BookmarkRecord[] = records.filter(r => !existingRows.has(r.id));
484
485 if (records.length > 0) {
486 db.run('BEGIN TRANSACTION');
487 try {
488 for (const record of records) {
489 insertRecord(db, record, existingRows.get(record.id));
490 }
491 db.run('COMMIT');
492 } catch (err) {
493 db.run('ROLLBACK');

Callers 9

enableBookmarksFunction · 0.85
classifyAndRebuildFunction · 0.85
rebuildIndexFunction · 0.85
buildCliFunction · 0.85
md-export.test.tsFile · 0.85

Calls 8

openDbFunction · 0.85
initSchemaFunction · 0.85
ensureMigrationsFunction · 0.85
insertRecordFunction · 0.85
saveDbFunction · 0.85
closeMethod · 0.65

Tested by

no test coverage detected