v0.33.1 9577fee

migrations.go RawHistoryFolder

1package sqlite
2
3import (
4	"context"
5	"database/sql"
6	"embed"
7	"fmt"
8
9	"github.com/bnema/dumber/internal/logging"
10	"github.com/pressly/goose/v3"
11)
12
13//go:embed migrations/*.sql
14var embedMigrations embed.FS
15
16// RunMigrations applies all pending migrations to the database.
17// Uses goose with embedded SQL files for automatic schema management.
18func RunMigrations(ctx context.Context, db *sql.DB) error {
19	log := logging.FromContext(ctx)
20
21	// Configure goose
22	goose.SetBaseFS(embedMigrations)
23
24	if err := goose.SetDialect("sqlite3"); err != nil {
25		return fmt.Errorf("failed to set goose dialect: %w", err)
26	}
27
28	// Disable verbose logging from goose
29	goose.SetLogger(goose.NopLogger())
30
31	// Get current version before migration
32	currentVersion, err := goose.GetDBVersion(db)
33	if err != nil {
34		log.Debug().Err(err).Msg("could not get current db version (may be new database)")
35		currentVersion = 0
36	}
37
38	// Run migrations
39	if migrateErr := goose.Up(db, "migrations"); migrateErr != nil {
40		return fmt.Errorf("failed to run migrations: %w", migrateErr)
41	}
42
43	// Get new version after migration
44	newVersion, err := goose.GetDBVersion(db)
45	if err != nil {
46		return fmt.Errorf("failed to get db version after migration: %w", err)
47	}
48
49	if newVersion > currentVersion {
50		log.Info().
51			Int64("from_version", currentVersion).
52			Int64("to_version", newVersion).
53			Msg("database migrations applied")
54	} else {
55		log.Debug().Int64("version", newVersion).Msg("database schema up to date")
56	}
57
58	return nil
59}
60
61// GetMigrationStatus returns the current migration version.
62func GetMigrationStatus(db *sql.DB) (int64, error) {
63	goose.SetBaseFS(embedMigrations)
64	if err := goose.SetDialect("sqlite3"); err != nil {
65		return 0, err
66	}
67	return goose.GetDBVersion(db)
68}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close