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{} }