rushlink/cmd/rushlink-migrate-db/main.go
Daan Sprenkels 3f09c1517d migrate: Fix 'no such table: migrations' err
Apparently, if you CREATE TABLE inside of a transaction, and then
(in the same transaction) do a SELECT on the same table before
committing, the table will not exist yet.

Now we do the migration in two steps: first initialize the schema;
then migrate the data.
2020-12-31 14:34:33 +01:00

111 lines
2.7 KiB
Go

package main
import (
"flag"
"log"
"time"
"gitea.hashru.nl/dsprenkels/rushlink/internal/boltdb"
"gitea.hashru.nl/dsprenkels/rushlink/internal/db"
bolt "go.etcd.io/bbolt"
"gorm.io/gorm"
)
var (
boltDBPath = flag.String("boltdb", "", "location of the bolt database file")
fileStorePath = flag.String("file-store", "", "path to the directory where uploaded files will be stored")
)
func main() {
flag.Parse()
boltFileStore, err := boltdb.OpenFileStore(*fileStorePath)
if err != nil {
log.Fatalln(err)
}
boltDB, err := boltdb.OpenDB(*boltDBPath, boltFileStore)
if err != nil {
log.Fatalln(err)
}
defer boltDB.Close()
sqlDB, err := db.OpenDBFromEnvironment()
if err != nil {
log.Fatalln(err)
}
// Migrate database schema
m := db.Gormigrate(sqlDB)
if err := m.MigrateTo("202010251337"); err != nil {
log.Fatalln(err)
}
// Migrate all files in filestorage
if err := sqlDB.Transaction(func(sqlTx *gorm.DB) error {
return boltDB.Bolt.View(func(boltTx *bolt.Tx) error {
// Migrate all the file uploads
allFUs, err := boltdb.AllFileUploads(boltTx)
if err != nil {
return err
}
var fusDeleted uint
var sqlFUs []db.FileUpload
for _, fu := range allFUs {
isDeleted := fu.State == boltdb.FileUploadStateDeleted
sqlFU := db.FileUpload{
State: db.FileUploadState(int(fu.State)),
PubID: fu.ID,
FileName: fu.FileName,
ContentType: fu.ContentType,
Checksum: fu.Checksum,
DeletedAt: deletedAt(isDeleted),
}
sqlFUs = append(sqlFUs, sqlFU)
if isDeleted {
fusDeleted++
}
}
log.Printf("migrating %v file uploads (of which %v deleted)", len(sqlFUs), fusDeleted)
sqlTx.Create(sqlFUs)
// Migrate all the pastes.
allPastes, err := boltdb.AllPastes(boltTx)
if err != nil {
return err
}
var pastesDeleted uint
var sqlPastes []db.Paste
for _, paste := range allPastes {
isDeleted := paste.State == boltdb.PasteStateDeleted
sqlPaste := db.Paste{
Type: db.PasteType(int(paste.Type)),
State: db.PasteState(int(paste.State)),
Content: paste.Content,
Key: paste.Key,
DeleteToken: paste.DeleteToken,
CreatedAt: paste.TimeCreated,
DeletedAt: deletedAt(isDeleted),
}
sqlPastes = append(sqlPastes, sqlPaste)
if isDeleted {
pastesDeleted++
}
}
log.Printf("migrating %v pastes (of which %v deleted)", len(sqlPastes), pastesDeleted)
sqlTx.Create(sqlPastes)
return nil
})
}); err != nil {
log.Fatalln(err)
}
log.Println("migration successful! :D")
}
func deletedAt(isDeleted bool) gorm.DeletedAt {
if isDeleted {
return gorm.DeletedAt{Time: time.Now(), Valid: true}
}
return gorm.DeletedAt{}
}