Skip to content
Snippets Groups Projects
Commit af82a63f authored by gbe's avatar gbe
Browse files

Move DB stuff into separate file

parent 97bef402
No related branches found
No related tags found
No related merge requests found
db.go 0 → 100644
package main
import (
"embed"
"errors"
"fmt"
"io/fs"
"log"
"sort"
"github.com/jmoiron/sqlx"
)
//go:embed migrations/*.sql
var migrationFS embed.FS
func initDB(db *sqlx.DB) error {
// Create table tracking migration state
const query = `CREATE TABLE IF NOT EXISTS migrations (name TEXT UNIQUE);`
_, err := db.Exec(query)
if err != nil {
return err
}
entries, err := migrationFS.ReadDir("migrations")
if err != nil {
return err
}
sort.Slice(entries, func(i, j int) bool {
return entries[i].Name() < entries[j].Name()
})
for _, e := range entries {
data, err := fs.ReadFile(migrationFS, "migrations/"+e.Name())
if err != nil {
return err
}
tx, err := db.Begin()
if err != nil {
return err
}
row := tx.QueryRow("SELECT count(*) FROM migrations WHERE name = ?", e.Name())
var howMany int
err = row.Scan(&howMany)
if err != nil {
tx.Rollback()
return fmt.Errorf("checking status for migration %s: %w", e.Name(), err)
}
switch howMany {
case 0:
// not yet applied
case 1:
// applied, no need to do anything
log.Printf("skipping migration %s: already applied", e.Name())
tx.Rollback()
continue
default:
// very weird
tx.Rollback()
return fmt.Errorf("unexpected migration count for %s: %d", e.Name(), howMany)
}
log.Println("applying migration", e.Name())
_, err = tx.Exec(string(data))
if err != nil {
tx.Rollback()
return fmt.Errorf("applying migration %s: %w", e.Name(), err)
}
// Record migration as applied
_, err = tx.Exec("INSERT INTO migrations (name) VALUES (?)", e.Name())
if err != nil {
tx.Rollback()
return fmt.Errorf("recording migration %s: %w", e.Name(), err)
}
err = tx.Commit()
if err != nil {
return err
}
log.Println("it has", len(data), "bytes")
}
return errors.New("here be dragons")
}
......@@ -2,13 +2,9 @@ package main
import (
"embed"
"errors"
"fmt"
"html/template"
"io/fs"
"log"
"net/http"
"sort"
"github.com/jmoiron/sqlx"
_ "modernc.org/sqlite" // Imported for side effects: registers DB driver
......@@ -21,87 +17,6 @@ var templates = template.Must(template.ParseFS(templateFS, "templates/*.tpl"))
//go:embed static/*
var staticFS embed.FS
//go:embed migrations/*.sql
var migrationFS embed.FS
func initDB(db *sqlx.DB) error {
// Create table tracking migration state
const query = `CREATE TABLE IF NOT EXISTS migrations (name TEXT UNIQUE);`
_, err := db.Exec(query)
if err != nil {
return err
}
entries, err := migrationFS.ReadDir("migrations")
if err != nil {
return err
}
sort.Slice(entries, func(i, j int) bool {
return entries[i].Name() < entries[j].Name()
})
for _, e := range entries {
data, err := fs.ReadFile(migrationFS, "migrations/"+e.Name())
if err != nil {
return err
}
tx, err := db.Begin()
if err != nil {
return err
}
row := tx.QueryRow("SELECT count(*) FROM migrations WHERE name = ?", e.Name())
var howMany int
err = row.Scan(&howMany)
if err != nil {
tx.Rollback()
return fmt.Errorf("checking status for migration %s: %w", e.Name(), err)
}
switch howMany {
case 0:
// not yet applied
case 1:
// applied, no need to do anything
log.Printf("skipping migration %s: already applied", e.Name())
tx.Rollback()
continue
default:
// very weird
tx.Rollback()
return fmt.Errorf("unexpected migration count for %s: %d", e.Name(), howMany)
}
log.Println("applying migration", e.Name())
_, err = tx.Exec(string(data))
if err != nil {
tx.Rollback()
return fmt.Errorf("applying migration %s: %w", e.Name(), err)
}
// Record migration as applied
_, err = tx.Exec("INSERT INTO migrations (name) VALUES (?)", e.Name())
if err != nil {
tx.Rollback()
return fmt.Errorf("recording migration %s: %w", e.Name(), err)
}
err = tx.Commit()
if err != nil {
return err
}
log.Println("it has", len(data), "bytes")
}
return errors.New("here be dragons")
}
func main() {
db, err := sqlx.Open("sqlite", "vino.sqlite")
if err != nil {
......
CREATE TABLE wines (
name TEXT,
rating INT, -- number of stars
picture BINARY, -- jpeg/png image of the label on the bottle
UNIQUE(name)
);
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment