mirror of
https://github.com/Fluffy-Bean/TastyBites.git
synced 2024-12-26 09:26:24 +00:00
Add migration, status and pending checks to database
This commit is contained in:
parent
b2933a41c1
commit
66fb03fa0d
|
@ -16,6 +16,8 @@ func Parse() {
|
|||
run(os.Args[2:])
|
||||
case "migrate":
|
||||
migrate(os.Args[2:])
|
||||
case "status":
|
||||
status(os.Args[2:])
|
||||
case "-h":
|
||||
case "--help":
|
||||
fmt.Println("Available commands are:")
|
||||
|
|
|
@ -3,19 +3,15 @@ package cmd
|
|||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
db "github.com/Fluffy-Bean/TastyBites/database"
|
||||
sb "github.com/huandu/go-sqlbuilder"
|
||||
)
|
||||
|
||||
func migrate(flags []string) {
|
||||
|
||||
cmd := flag.NewFlagSet("migrate", flag.ExitOnError)
|
||||
|
||||
tables := cmd.Bool("tables", false, "Create tables")
|
||||
verbose := cmd.Bool("v", false, "Verbose")
|
||||
downgrade := cmd.Bool("downgrade", false, "Downgrade Database")
|
||||
|
||||
err := cmd.Parse(flags)
|
||||
if err != nil {
|
||||
|
@ -23,36 +19,17 @@ func migrate(flags []string) {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !*tables {
|
||||
builder := db.ItemStruct.InsertInto("Item")
|
||||
for _, item := range db.SampleData {
|
||||
builder.Values(item.UUID, item.Name, item.Price, item.Description)
|
||||
}
|
||||
query, args := builder.Build()
|
||||
|
||||
_, err = db.Conn.Exec(query, args...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
fmt.Println("Success")
|
||||
}
|
||||
} else {
|
||||
itemTable := sb.CreateTable("Item").IfNotExists()
|
||||
itemTable.Define("uuid", "TEXT", "NOT NULL", "PRIMARY KEY")
|
||||
itemTable.Define("name", "TEXT", "NOT NULL")
|
||||
itemTable.Define("price", "INTEGER", "NOT NULL")
|
||||
itemTable.Define("description", "TEXT")
|
||||
query, args := itemTable.BuildWithFlavor(sb.SQLite)
|
||||
|
||||
if *verbose {
|
||||
fmt.Println(query, args)
|
||||
}
|
||||
|
||||
_, err := db.Conn.Exec(query, args...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
fmt.Println("Success")
|
||||
}
|
||||
err = db.Migrate(!*downgrade)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func status(flags []string) {
|
||||
err := db.Status()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
16
cmd/run.go
16
cmd/run.go
|
@ -6,12 +6,14 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/Fluffy-Bean/TastyBites/api"
|
||||
db "github.com/Fluffy-Bean/TastyBites/database"
|
||||
)
|
||||
|
||||
func run(flags []string) {
|
||||
cmd := flag.NewFlagSet("run", flag.ExitOnError)
|
||||
|
||||
host := cmd.String("host", "127.0.0.1:8080", "Host address, such as 0.0.0.0:8080")
|
||||
skip := cmd.Bool("skipMigrations", false, "Skip any pending migrations")
|
||||
logging := cmd.Bool("log", false, "Enable logging for the application")
|
||||
|
||||
err := cmd.Parse(flags)
|
||||
|
@ -20,6 +22,20 @@ func run(flags []string) {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !*skip {
|
||||
pending, err := db.Pending()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if pending {
|
||||
fmt.Println("Pending migrations!")
|
||||
fmt.Println("Run `TastyBites status` or use the flag -skipMigrations")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
api.Serve(api.Config{
|
||||
Host: *host,
|
||||
Logging: *logging,
|
||||
|
|
|
@ -2,7 +2,8 @@ package database
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
@ -16,19 +17,22 @@ func Open() {
|
|||
|
||||
Conn, err = sql.Open("sqlite3", "tastybites.db?_journal_mode=WAL")
|
||||
if err != nil {
|
||||
log.Fatal("Error opening connection: ", err)
|
||||
fmt.Println("Error opening connection:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
//Set the connection to use WAL mode
|
||||
_, err = Conn.Exec("PRAGMA journal_mode=WAL;")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func Close() {
|
||||
err := Conn.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
11
database/migrations/20240506163617-init_tables.sql
Normal file
11
database/migrations/20240506163617-init_tables.sql
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
-- +migrate Up
|
||||
CREATE TABLE IF NOT EXISTS Item (
|
||||
uuid TEXT NOT NULL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
price INTEGER NOT NULL,
|
||||
description TEXT
|
||||
);
|
||||
|
||||
-- +migrate Down
|
||||
DROP TABLE Item;
|
64
database/migrator.go
Normal file
64
database/migrator.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
|
||||
migrate "github.com/rubenv/sql-migrate"
|
||||
)
|
||||
|
||||
//go:embed migrations/*
|
||||
var dbMigrations embed.FS
|
||||
var migrations = migrate.EmbedFileSystemMigrationSource{
|
||||
FileSystem: dbMigrations,
|
||||
Root: "migrations",
|
||||
}
|
||||
|
||||
func Migrate(Up bool) error {
|
||||
var direction migrate.MigrationDirection
|
||||
if Up {
|
||||
direction = migrate.Up
|
||||
} else {
|
||||
direction = migrate.Down
|
||||
}
|
||||
|
||||
n, err := migrate.Exec(Conn, "sqlite3", migrations, direction)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Applied %d migrations!\n", n)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Status() error {
|
||||
// Get the list of applied migrations
|
||||
applied, err := migrate.GetMigrationRecords(Conn, "sqlite3")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the list of migrations that are yet to be applied
|
||||
planned, _, err := migrate.PlanMigration(Conn, "sqlite3", migrations, migrate.Up, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Migration list:")
|
||||
for _, migration := range applied {
|
||||
fmt.Printf("DONE: %s\n", migration.Id)
|
||||
}
|
||||
for _, migration := range planned {
|
||||
fmt.Printf("TODO: %s\n", migration.Id)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Pending() (bool, error) {
|
||||
planned, _, err := migrate.PlanMigration(Conn, "sqlite3", migrations, migrate.Up, 0)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return len(planned) > 0, nil
|
||||
}
|
9
dbconfig.yml
Normal file
9
dbconfig.yml
Normal file
|
@ -0,0 +1,9 @@
|
|||
development:
|
||||
dialect: sqlite3
|
||||
datasource: tastybites.db
|
||||
dir: database/migrations
|
||||
|
||||
production:
|
||||
dialect: sqlite3
|
||||
datasource: tastybites.db
|
||||
dir: database/migrations
|
4
go.mod
4
go.mod
|
@ -6,11 +6,13 @@ require (
|
|||
github.com/huandu/go-sqlbuilder v1.27.1
|
||||
github.com/labstack/echo/v4 v4.12.0
|
||||
github.com/mattn/go-sqlite3 v1.14.22
|
||||
github.com/rubenv/sql-migrate v1.6.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/huandu/xstrings v1.3.2 // indirect
|
||||
github.com/huandu/xstrings v1.4.0 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
|
|
21
go.sum
21
go.sum
|
@ -1,18 +1,29 @@
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
|
||||
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c=
|
||||
github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U=
|
||||
github.com/huandu/go-sqlbuilder v1.27.1 h1:7UU/3EMIQYYX8wn+L7BNcGVz1aEs5TPNOVFd7ryrPos=
|
||||
github.com/huandu/go-sqlbuilder v1.27.1/go.mod h1:nUVmMitjOmn/zacMLXT0d3Yd3RHoO2K+vy906JzqxMI=
|
||||
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
|
||||
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
|
||||
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
|
||||
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
|
@ -22,6 +33,12 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o
|
|||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY=
|
||||
github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rubenv/sql-migrate v1.6.1 h1:bo6/sjsan9HaXAsNxYP/jCEDUGibHp8JmOBw7NTGRos=
|
||||
github.com/rubenv/sql-migrate v1.6.1/go.mod h1:tPzespupJS0jacLfhbwto/UjSX+8h2FdWB7ar+QlHa0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
|
@ -43,6 +60,8 @@ golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
|||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
Loading…
Reference in a new issue