feat: add fts indexing

This commit is contained in:
2026-04-15 08:31:06 -04:00
parent ac343a5477
commit 562f4bb073
11 changed files with 393 additions and 83 deletions

70
main.go
View File

@@ -3,27 +3,61 @@ package main
import (
"context"
"database/sql"
"embed"
_ "embed"
"flag"
"fmt"
"os"
"os/signal"
"path/filepath"
"runtime/pprof"
"strings"
"time"
_ "github.com/mattn/go-sqlite3"
_ "modernc.org/sqlite"
"codexis/db"
"codexis/indexer"
)
//go:embed db/schema.sql
var schemaSQL string
const dbDir = ".codexis"
const dbFileName = "index.db"
func main() {
force := flag.Bool("force", false, "Force full re-index (ignore file hashes)")
output := flag.String("o", "", "Output database path (default: <root>/.codexis/index.db)")
cpuprofile := flag.String("cpuprofile", "", "Write CPU profile to file")
flag.Parse()
// CPU profiling
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
fmt.Fprintf(os.Stderr, "error creating profile: %v\n", err)
os.Exit(1)
}
pprof.StartCPUProfile(f)
// Flush profile on interrupt
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt)
go func() {
<-sigCh
fmt.Fprintf(os.Stderr, "\nInterrupted, flushing CPU profile...\n")
pprof.StopCPUProfile()
f.Close()
os.Exit(1)
}()
defer func() {
pprof.StopCPUProfile()
f.Close()
}()
}
root := "."
if flag.NArg() > 0 {
root = flag.Arg(0)
@@ -54,7 +88,7 @@ func main() {
func run(root, dbPath string, force bool) error {
ctx := context.Background()
sqlDB, err := sql.Open("sqlite3", dbPath+"?_journal_mode=WAL&_foreign_keys=on")
sqlDB, err := sql.Open("sqlite", dbPath+"?_pragma=journal_mode(WAL)&_pragma=foreign_keys(1)")
if err != nil {
return fmt.Errorf("opening database: %w", err)
}
@@ -66,7 +100,26 @@ func run(root, dbPath string, force bool) error {
}
queries := db.New(sqlDB)
idx := indexer.New(queries, root, force)
idx := indexer.New(sqlDB, queries, root, force)
isTTY := fileIsTTY(os.Stderr)
idx.OnProgress = func(current, total int, path string) {
if !isTTY {
return
}
pct := current * 100 / total
barWidth := 30
filled := barWidth * current / total
bar := strings.Repeat("█", filled) + strings.Repeat("░", barWidth-filled)
display := path
if len(display) > 40 {
display = "..." + display[len(display)-37:]
}
fmt.Fprintf(os.Stderr, "\r %s %3d%% (%d/%d) %s\033[K", bar, pct, current, total, display)
if current == total {
fmt.Fprintf(os.Stderr, "\r\033[K")
}
}
start := time.Now()
fmt.Fprintf(os.Stderr, "Indexing %s...\n", root)
@@ -86,8 +139,13 @@ func run(root, dbPath string, force bool) error {
return nil
}
//go:embed db/schema.sql
var schemaSQL string
func fileIsTTY(f *os.File) bool {
fi, err := f.Stat()
if err != nil {
return false
}
return fi.Mode()&os.ModeCharDevice != 0
}
func createSchema(ctx context.Context, sqlDB *sql.DB) error {
_, err := sqlDB.ExecContext(ctx, schemaSQL)