CI / test (pull_request) Successful in 4s
This introduces deduplicated per-user image/3D asset records linked into feature properties, adds visibility-controlled download routing, and wires local S3-compatible storage with automatic bucket bootstrap in Docker Compose. Made-with: Cursor
49 lines
920 B
Go
49 lines
920 B
Go
package store
|
|
|
|
import (
|
|
"database/sql"
|
|
"embed"
|
|
"fmt"
|
|
"io/fs"
|
|
"log"
|
|
"path/filepath"
|
|
"sort"
|
|
|
|
_ "github.com/jackc/pgx/v5/stdlib"
|
|
)
|
|
|
|
//go:embed migrations
|
|
var migrationsFS embed.FS
|
|
|
|
func Migrate(databaseURL string) error {
|
|
db, err := sql.Open("pgx", databaseURL)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer db.Close()
|
|
|
|
files, err := fs.ReadDir(migrationsFS, "migrations")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
paths := make([]string, 0, len(files))
|
|
for _, entry := range files {
|
|
if entry.IsDir() || filepath.Ext(entry.Name()) != ".sql" {
|
|
continue
|
|
}
|
|
paths = append(paths, "migrations/"+entry.Name())
|
|
}
|
|
sort.Strings(paths)
|
|
for _, path := range paths {
|
|
sqlBytes, readErr := migrationsFS.ReadFile(path)
|
|
if readErr != nil {
|
|
return readErr
|
|
}
|
|
if _, execErr := db.Exec(string(sqlBytes)); execErr != nil {
|
|
return fmt.Errorf("%s: %w", path, execErr)
|
|
}
|
|
}
|
|
log.Printf("migrations applied")
|
|
return nil
|
|
}
|