feat: add offline flag to reindex (mostly for dev)
1 file changed, 61 insertions(+), 37 deletions(-)
changed files
M internal/programs/programs.go → internal/programs/programs.go
@@ -8,6 +8,7 @@ "os/exec" "strings" "alin.ovh/searchix/internal/config" + "alin.ovh/searchix/internal/file" "alin.ovh/x/log" "github.com/Southclaws/fault" "github.com/Southclaws/fault/fmsg"@@ -15,62 +16,75 @@ _ "modernc.org/sqlite" //nolint:blank-imports // sqlite driver needed for database/sql ) type DB struct { - Path string - Source *config.Source - + source *config.Source logger *log.Logger + root *file.Root db *sql.DB stmt *sql.Stmt } -func Instantiate( - ctx context.Context, - source *config.Source, - logger *log.Logger, -) (*DB, error) { +type Options struct { + Logger *log.Logger + Root *file.Root +} + +func New(source *config.Source, options *Options) (*DB, error) { + db, err := sql.Open("sqlite", fmt.Sprintf( + "file:%s?mode=%s&_pragma=foreign_keys(1)&_pragma=mmap_size(%d)", + //nolint:forbidigo // external package + options.Root.JoinPath( + source.JoinPath("programs.db"), + ), + "rwc", + 16*1024*1024, + )) + if err != nil { + return nil, fault.Wrap(err, fmsg.With("failed to open sqlite database")) + } + options.Logger.Debug("opened sqlite database") + + return &DB{ + source: source, + + logger: options.Logger, + root: options.Root, + db: db, + }, nil +} + +func (p *DB) Instantiate(ctx context.Context) error { // nix-instantiate --eval --json -I nixpkgs=channel:nixos-unstable --expr 'toString <nixpkgs/programs.sqlite>' args := []string{ "--eval", "--json", - "-I", fmt.Sprintf("%s=channel:%s", source.Key, source.Channel), - "--expr", fmt.Sprintf("toString <%s/%s>", source.Key, source.Programs.Attribute), + "-I", fmt.Sprintf("%s=channel:%s", p.source.Key, p.source.Channel), + "--expr", fmt.Sprintf("toString <%s/%s>", p.source.Key, p.source.Programs.Attribute), } - logger.Debug("nix-instantiate command", "args", args) + p.logger.Debug("nix-instantiate command", "args", args) cmd := exec.CommandContext(ctx, "nix-instantiate", args...) out, err := cmd.Output() if err != nil { - return nil, fault.Wrap(err, fmsg.With("failed to run nix-instantiate")) + return fault.Wrap(err, fmsg.With("failed to run nix-instantiate")) } outPath := strings.Trim(strings.TrimSpace(string(out)), "\"") - logger.Debug("got output path", "outputPath", outPath) + p.logger.Debug("got output path", "outputPath", outPath) - return &DB{ - Source: source, - Path: outPath, - - logger: logger, - }, nil -} - -func (p *DB) Open() error { - var err error - p.db, err = sql.Open("sqlite", p.Path) + _, err = p.db.ExecContext(ctx, "ATTACH DATABASE ? AS input", outPath) if err != nil { - return fault.Wrap(err, fmsg.With("failed to open sqlite database")) + return fault.Wrap(err, fmsg.With("failed to attach nix-store programs database")) } - p.logger.Debug("opened sqlite database") - _, err = p.db.Exec("ATTACH DATABASE ':memory:' AS mem") + _, err = p.db.ExecContext(ctx, "DROP TABLE IF EXISTS programs") if err != nil { - return fault.Wrap(err, fmsg.With("failed to attach in-memory database")) + return fault.Wrap(err, fmsg.With("failed to drop programs table")) } - _, err = p.db.Exec(` -CREATE TABLE mem.programs AS + _, err = p.db.ExecContext(ctx, ` +CREATE TABLE programs AS SELECT name, package -FROM main.Programs +FROM input.Programs GROUP BY name, package `) if err != nil {@@ -78,15 +92,28 @@ return fault.Wrap(err, fmsg.With("failed to create programs table")) } p.logger.Debug("created programs table") - _, err = p.db.Exec(`CREATE INDEX mem.idx_package ON programs(package)`) + _, err = p.db.ExecContext(ctx, `CREATE INDEX idx_package ON programs(package)`) if err != nil { return fault.Wrap(err, fmsg.With("failed to create idx_package index")) } p.logger.Debug("created idx_package index") - p.stmt, err = p.db.Prepare(` + _, err = p.db.ExecContext(ctx, "DETACH DATABASE input") + if err != nil { + return fault.Wrap(err, fmsg.With("failed to detach nix-store programs database")) + } + + return nil +} + +func (p *DB) Open(ctx context.Context) (err error) { + if p.db == nil { + return fault.New("database not open") + } + + p.stmt, err = p.db.PrepareContext(ctx, ` SELECT name -FROM mem.programs +FROM programs WHERE package = ? `) if err != nil {@@ -107,9 +134,6 @@ } func (p *DB) GetPackagePrograms(ctx context.Context, pkg string) ([]string, error) { var programs []string - if p.db == nil { - return nil, fault.New("database not open") - } rows, err := p.stmt.QueryContext(ctx, pkg) if err != nil { return nil, fault.Wrap(err, fmsg.With("failed to execute query"))