Skip to content

Commit

Permalink
Migrate DB with embedded Goose.
Browse files Browse the repository at this point in the history
  • Loading branch information
efixler committed May 5, 2024
1 parent f4a3e4f commit bb1ba9e
Show file tree
Hide file tree
Showing 12 changed files with 185 additions and 92 deletions.
9 changes: 7 additions & 2 deletions cmd/scrape/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func main() {
clearDatabase(dbFactory)
return
} else if dbFlags.Migrate {
createDatabase(dbFactory)
migrateDatabase(dbFactory)
return
} else if maintain {
maintainDatabase(dbFactory)
Expand Down Expand Up @@ -150,7 +150,7 @@ func maintainDatabase(dbFactory store.Factory) {
slog.Warn("Database maintenance complete", "database", db)
}

func createDatabase(dbFactory store.Factory) {
func migrateDatabase(dbFactory store.Factory) {
db, ok := openDatabase(dbFactory).(store.Maintainable)
if !ok {
slog.Error("Creating database not available for this storage backend", "database", db)
Expand All @@ -162,6 +162,11 @@ func createDatabase(dbFactory store.Factory) {
slog.Error("Error creating database", "database", db, "err", err)
os.Exit(1)
}
err = db.Migrate()
if err != nil {
slog.Error("Error creating database", "database", db, "err", err)
os.Exit(1)
}
slog.Warn("Database creation complete", "database", db)
}

Expand Down
8 changes: 6 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
github.com/markusmobius/go-trafilatura v1.5.1
github.com/mattn/go-sqlite3 v1.14.22
github.com/mmcdole/gofeed v1.3.0
github.com/pressly/goose/v3 v3.20.0
)

require (
Expand Down Expand Up @@ -46,18 +47,21 @@ require (
github.com/markusmobius/go-htmldate v1.2.2 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mfridman/interpolate v0.0.2 // indirect
github.com/mmcdole/goxpp v1.1.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rs/zerolog v1.32.0 // indirect
github.com/sethvargo/go-retry v0.2.4 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/tetratelabs/wazero v1.7.0 // indirect
github.com/wasilibs/go-re2 v1.5.1 // indirect
github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
)
40 changes: 36 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
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/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/efixler/envflags v0.0.0-20240216173636-8ba3a3ae2ac0 h1:0Mtp62zJ0jY58bdJqty71UtJxM3u15kM2I2lI4bS07A=
github.com/efixler/envflags v0.0.0-20240216173636-8ba3a3ae2ac0/go.mod h1:raY03IjmZ5RonoJ7HhBULK630UCrvufj0Z76qy382mM=
github.com/efixler/headless v0.0.0-20240401160743-c33a69e27195 h1:Z6pasaGokuQbLXWrg/pDyyiD2eV0Cc8OSc9iX1Up9yk=
Expand All @@ -43,10 +45,14 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs=
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hablullah/go-hijri v1.0.2 h1:drT/MZpSZJQXo7jftf5fthArShcaMtsal0Zf/dnmp6k=
github.com/hablullah/go-hijri v1.0.2/go.mod h1:OS5qyYLDjORXzK4O1adFw9Q5WfhOcMdAKglDkcTxgWQ=
github.com/hablullah/go-juliandays v1.0.0 h1:A8YM7wIj16SzlKT0SRJc9CD29iiaUzpBLzh5hr0/5p0=
github.com/hablullah/go-juliandays v1.0.0/go.mod h1:0JOYq4oFOuDja+oospuc61YoX+uNEn7Z6uHYTbBzdGc=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 h1:qxLoi6CAcXVzjfvu+KXIXJOAsQB62LXjsfbOaErsVzE=
github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958/go.mod h1:Wqfu7mjUHj9WDzSSPI5KfBclTTEnLveRUFr/ujWnTgE=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
Expand Down Expand Up @@ -75,6 +81,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY=
github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg=
github.com/mmcdole/gofeed v1.3.0 h1:5yn+HeqlcvjMeAI4gu6T+crm7d0anY85+M+v6fIFNG4=
github.com/mmcdole/gofeed v1.3.0/go.mod h1:9TGv2LcJhdXePDzxiuMnukhV2/zb6VtnZt1mS+SjkLE=
github.com/mmcdole/goxpp v1.1.1 h1:RGIX+D6iQRIunGHrKqnA2+700XMCnNv0bAOOv5MUhx8=
Expand All @@ -84,18 +92,26 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/pressly/goose/v3 v3.20.0 h1:uPJdOxF/Ipj7ABVNOAMJXSxwFXZGwMGHNqjC8e61VA0=
github.com/pressly/goose/v3 v3.20.0/go.mod h1:BRfF2GcG4FTG12QfdBVy3q1yveaf4ckL9vWwEcIO3lA=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec=
github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand All @@ -112,6 +128,8 @@ github.com/wasilibs/nottinygc v0.4.0/go.mod h1:oDcIotskuYNMpqMF23l7Z8uzD4TC0WXHK
github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4 h1:0sw0nJM544SpsihWx1bkXdYLQDlzRflMgFJQ4Yih9ts=
github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4/go.mod h1:+ccdNT0xMY1dtc5XBxumbYfOUhmduiGudqaDgD2rVRE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw=
Expand All @@ -123,13 +141,13 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down Expand Up @@ -164,3 +182,17 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk=
modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
modernc.org/sqlite v1.29.6 h1:0lOXGrycJPptfHDuohfYgNqoe4hu+gYuN/pKgY5XjS4=
modernc.org/sqlite v1.29.6/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U=
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
16 changes: 16 additions & 0 deletions internal/storage/mysql/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"embed"
"errors"
"text/template"

"github.com/pressly/goose/v3"
)

//go:embed create.sql
Expand Down Expand Up @@ -39,6 +41,20 @@ func (s *Store) Create() error {
return err
}

//go:embed migrations/*.sql
var migrationsFS embed.FS

func (s *Store) Migrate() error {
goose.SetBaseFS(migrationsFS)
if err := goose.SetDialect(string(goose.DialectMySQL)); err != nil {
return err
}
if err := goose.Up(s.DB, "migrations"); err != nil {
return err
}
return nil
}

func (s *Store) Maintain() error {
return errors.New("mysql: maintain not implemented")
}
36 changes: 3 additions & 33 deletions internal/storage/mysql/create.sql
Original file line number Diff line number Diff line change
@@ -1,42 +1,12 @@
-- {{.TargetSchema}}
BEGIN;
CREATE DATABASE IF NOT EXISTS `{{.TargetSchema}}` DEFAULT CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci' ;
USE {{.TargetSchema}} ;

CREATE TABLE IF NOT EXISTS `urls` (
`id` BIGINT UNSIGNED NOT NULL,
`url` VARCHAR(255) CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci' NOT NULL,
`parsed_url` VARCHAR(255) CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci' NOT NULL,
`fetch_time` BIGINT NOT NULL,
`expires` BIGINT NOT NULL,
`metadata` JSON NOT NULL,
`content_text` MEDIUMTEXT CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci' NULL,
PRIMARY KEY (`id`));

CREATE TABLE IF NOT EXISTS `id_map` (
`requested_id` BIGINT UNSIGNED NOT NULL,
`canonical_id` BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (`requested_id`)
);

-- Following two statements are added to support tracking headless
-- fetched state (or other alternate fetch methods)
-- The following cannot be executed idempotently
-- TODO: Goose migrations
ALTER TABLE urls ADD column fetch_method
INT UNSIGNED
NOT NULL DEFAULT 0;

CREATE INDEX fetch_method_expires_index ON urls (
expires DESC,
fetch_method ASC
);


CREATE ROLE IF NOT EXISTS scrape_app;
GRANT SELECT, INSERT, UPDATE, DELETE on {{.TargetSchema}}.* to scrape_app;
CREATE ROLE IF NOT EXISTS scrape_admin;
GRANT ALL ON {{.TargetSchema}}.* to scrape_admin;


USE {{.TargetSchema}} ;

COMMIT;
SET AUTOCOMMIT = 1;
33 changes: 33 additions & 0 deletions internal/storage/mysql/migrations/20240505204420_init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- +goose Up
-- +goose StatementBegin

CREATE TABLE IF NOT EXISTS `urls` (
`id` BIGINT UNSIGNED NOT NULL,
`url` VARCHAR(255) CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci' NOT NULL,
`parsed_url` VARCHAR(255) CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci' NOT NULL,
`fetch_time` BIGINT NOT NULL,
`fetch_method` INT UNSIGNED NOT NULL DEFAULT 0,
`expires` BIGINT NOT NULL,
`metadata` JSON NOT NULL,
`content_text` MEDIUMTEXT CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci' NULL,
PRIMARY KEY (`id`));

CREATE TABLE IF NOT EXISTS `id_map` (
`requested_id` BIGINT UNSIGNED NOT NULL,
`canonical_id` BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (`requested_id`)
);

CREATE INDEX fetch_method_expires_index ON urls (
expires DESC,
fetch_method ASC
);

-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
USE `scrape_test`;
DROP TABLE IF EXISTS `urls`;
DROP TABLE IF EXISTS `id_map`;
-- +goose StatementEnd
13 changes: 12 additions & 1 deletion internal/storage/mysql_loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ package storage
import (
"bytes"
"context"
"embed"
_ "embed"
"fmt"
"testing"
"text/template"

"github.com/efixler/scrape/database"
_ "github.com/go-sql-driver/mysql"
"github.com/pressly/goose/v3"
)

const (
Expand All @@ -31,6 +33,9 @@ var (
dbConfig = mysqlConfig{TargetSchema: testSchema}
)

//go:embed mysql/migrations/*.sql
var migrationsFS embed.FS

// Returns a new SQLStorage instance for testing. Each instance returns
// a freshly created db. Since a 'USE' statement is included in the create.sql
// subsequent queries will continue to use the test database.
Expand Down Expand Up @@ -58,7 +63,13 @@ func getTestDatabase(t *testing.T) *SQLStorage {
if _, err := db.DB.Exec(q); err != nil {
t.Logf("error dropping mysql test database %q: %v", dbConfig.TargetSchema, err)
}

})
goose.SetBaseFS(migrationsFS)
if err := goose.SetDialect(string(goose.DialectMySQL)); err != nil {
t.Fatalf("Error setting dialect: %v", err)
}
if err := goose.Up(db.DB, "mysql/migrations"); err != nil {
t.Fatalf("Error creating MySQL test db via migration: %v", err)
}
return db
}
20 changes: 19 additions & 1 deletion internal/storage/sqlite/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package sqlite
import (
"context"
"database/sql"
_ "embed"
"embed"
"errors"
"fmt"
"log/slog"
Expand All @@ -12,6 +12,7 @@ import (
"time"

"github.com/efixler/scrape/store"
"github.com/pressly/goose/v3"
)

const (
Expand Down Expand Up @@ -72,13 +73,30 @@ var createSQL string

// When this is called, the path to the database must already exist.
func (s *Store) Create() error {
// NB: The creation sql has been stripped down to a few pragmas; the actual creation is now
// handled by the migrations. SQLite doesn't need the two-stage create/migrate, but MySQL does, so,
// for now, keeping this in-place pending refactoring.
_, err := s.DB.ExecContext(s.Ctx, createSQL)
if err != nil {
slog.Error("sqlite: error creating database", "error", err)
}
return err
}

//go:embed migrations/*.sql
var migrationsFS embed.FS

func (s *Store) Migrate() error {
goose.SetBaseFS(migrationsFS)
if err := goose.SetDialect(string(goose.DialectSQLite3)); err != nil {
return err
}
if err := goose.Up(s.DB, "migrations"); err != nil {
return err
}
return nil
}

// Private version of the maintenance function that doesn't log, for running
// on the timer provided by DBHandle.
func maintain(ctx context.Context, db *sql.DB, tm time.Time) error {
Expand Down
Loading

0 comments on commit bb1ba9e

Please sign in to comment.