lookbook/vendor/github.com/pressly/goose/v3/register.go
soup fc625fb9cf
Initial lookbook implementation
Pinterest-style visual bookmarking app with:
- URL metadata extraction (OG/Twitter meta, oEmbed fallback)
- Image caching in Postgres with 480px thumbnails
- Multi-tag filtering with Ctrl/Cmd for OR mode
- Fuzzy tag suggestions and inline tag editing
- Browser console auth() with first-use password setup
- Brutalist UI with Commit Mono font and Pico CSS
- Light/dark mode via browser preference
2026-01-16 21:14:23 -05:00

133 lines
4.1 KiB
Go

package goose
import (
"context"
"database/sql"
"fmt"
"runtime"
)
// GoMigrationContext is a Go migration func that is run within a transaction and receives a
// context.
type GoMigrationContext func(ctx context.Context, tx *sql.Tx) error
// AddMigrationContext adds Go migrations.
func AddMigrationContext(up, down GoMigrationContext) {
_, filename, _, _ := runtime.Caller(1)
AddNamedMigrationContext(filename, up, down)
}
// AddNamedMigrationContext adds named Go migrations.
func AddNamedMigrationContext(filename string, up, down GoMigrationContext) {
if err := register(
filename,
true,
&GoFunc{RunTx: up, Mode: TransactionEnabled},
&GoFunc{RunTx: down, Mode: TransactionEnabled},
); err != nil {
panic(err)
}
}
// GoMigrationNoTxContext is a Go migration func that is run outside a transaction and receives a
// context.
type GoMigrationNoTxContext func(ctx context.Context, db *sql.DB) error
// AddMigrationNoTxContext adds Go migrations that will be run outside transaction.
func AddMigrationNoTxContext(up, down GoMigrationNoTxContext) {
_, filename, _, _ := runtime.Caller(1)
AddNamedMigrationNoTxContext(filename, up, down)
}
// AddNamedMigrationNoTxContext adds named Go migrations that will be run outside transaction.
func AddNamedMigrationNoTxContext(filename string, up, down GoMigrationNoTxContext) {
if err := register(
filename,
false,
&GoFunc{RunDB: up, Mode: TransactionDisabled},
&GoFunc{RunDB: down, Mode: TransactionDisabled},
); err != nil {
panic(err)
}
}
func register(filename string, useTx bool, up, down *GoFunc) error {
v, _ := NumericComponent(filename)
if existing, ok := registeredGoMigrations[v]; ok {
return fmt.Errorf("failed to add migration %q: version %d conflicts with %q",
filename,
v,
existing.Source,
)
}
// Add to global as a registered migration.
m := NewGoMigration(v, up, down)
m.Source = filename
// We explicitly set transaction to maintain existing behavior. Both up and down may be nil, but
// we know based on the register function what the user is requesting.
m.UseTx = useTx
registeredGoMigrations[v] = m
return nil
}
// withContext changes the signature of a function that receives one argument to receive a context
// and the argument.
func withContext[T any](fn func(T) error) func(context.Context, T) error {
if fn == nil {
return nil
}
return func(ctx context.Context, t T) error {
return fn(t)
}
}
// withoutContext changes the signature of a function that receives a context and one argument to
// receive only the argument. When called the passed context is always context.Background().
func withoutContext[T any](fn func(context.Context, T) error) func(T) error {
if fn == nil {
return nil
}
return func(t T) error {
return fn(context.Background(), t)
}
}
// GoMigration is a Go migration func that is run within a transaction.
//
// Deprecated: Use GoMigrationContext.
type GoMigration func(tx *sql.Tx) error
// GoMigrationNoTx is a Go migration func that is run outside a transaction.
//
// Deprecated: Use GoMigrationNoTxContext.
type GoMigrationNoTx func(db *sql.DB) error
// AddMigration adds Go migrations.
//
// Deprecated: Use AddMigrationContext.
func AddMigration(up, down GoMigration) {
_, filename, _, _ := runtime.Caller(1)
AddNamedMigrationContext(filename, withContext(up), withContext(down))
}
// AddNamedMigration adds named Go migrations.
//
// Deprecated: Use AddNamedMigrationContext.
func AddNamedMigration(filename string, up, down GoMigration) {
AddNamedMigrationContext(filename, withContext(up), withContext(down))
}
// AddMigrationNoTx adds Go migrations that will be run outside transaction.
//
// Deprecated: Use AddMigrationNoTxContext.
func AddMigrationNoTx(up, down GoMigrationNoTx) {
_, filename, _, _ := runtime.Caller(1)
AddNamedMigrationNoTxContext(filename, withContext(up), withContext(down))
}
// AddNamedMigrationNoTx adds named Go migrations that will be run outside transaction.
//
// Deprecated: Use AddNamedMigrationNoTxContext.
func AddNamedMigrationNoTx(filename string, up, down GoMigrationNoTx) {
AddNamedMigrationNoTxContext(filename, withContext(up), withContext(down))
}