2020-09-10 14:10:32 +00:00
|
|
|
// This is custom goose binary
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
|
2020-10-15 17:09:41 +00:00
|
|
|
pgaccounts "github.com/matrix-org/dendrite/userapi/storage/accounts/postgres/deltas"
|
|
|
|
slaccounts "github.com/matrix-org/dendrite/userapi/storage/accounts/sqlite3/deltas"
|
|
|
|
pgdevices "github.com/matrix-org/dendrite/userapi/storage/devices/postgres/deltas"
|
|
|
|
sldevices "github.com/matrix-org/dendrite/userapi/storage/devices/sqlite3/deltas"
|
2020-09-10 14:10:32 +00:00
|
|
|
"github.com/pressly/goose"
|
|
|
|
|
|
|
|
_ "github.com/lib/pq"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
|
|
)
|
|
|
|
|
2020-10-15 17:09:41 +00:00
|
|
|
const (
|
|
|
|
AppService = "appservice"
|
|
|
|
FederationSender = "federationsender"
|
|
|
|
KeyServer = "keyserver"
|
|
|
|
MediaAPI = "mediaapi"
|
|
|
|
RoomServer = "roomserver"
|
|
|
|
SigningKeyServer = "signingkeyserver"
|
|
|
|
SyncAPI = "syncapi"
|
|
|
|
UserAPIAccounts = "userapi_accounts"
|
|
|
|
UserAPIDevices = "userapi_devices"
|
|
|
|
)
|
|
|
|
|
2020-09-10 14:10:32 +00:00
|
|
|
var (
|
2020-10-15 17:09:41 +00:00
|
|
|
dir = flags.String("dir", "", "directory with migration files")
|
|
|
|
flags = flag.NewFlagSet("goose", flag.ExitOnError)
|
|
|
|
component = flags.String("component", "", "dendrite component name")
|
|
|
|
knownDBs = []string{
|
|
|
|
AppService, FederationSender, KeyServer, MediaAPI, RoomServer, SigningKeyServer, SyncAPI, UserAPIAccounts, UserAPIDevices,
|
|
|
|
}
|
2020-09-10 14:10:32 +00:00
|
|
|
)
|
|
|
|
|
2020-10-15 17:09:41 +00:00
|
|
|
// nolint: gocyclo
|
2020-09-10 14:10:32 +00:00
|
|
|
func main() {
|
|
|
|
err := flags.Parse(os.Args[1:])
|
|
|
|
if err != nil {
|
|
|
|
panic(err.Error())
|
|
|
|
}
|
|
|
|
args := flags.Args()
|
|
|
|
|
|
|
|
if len(args) < 3 {
|
|
|
|
fmt.Println(
|
|
|
|
`Usage: goose [OPTIONS] DRIVER DBSTRING COMMAND
|
|
|
|
|
|
|
|
Drivers:
|
|
|
|
postgres
|
|
|
|
sqlite3
|
|
|
|
|
|
|
|
Examples:
|
2020-10-15 17:09:41 +00:00
|
|
|
goose -component roomserver sqlite3 ./roomserver.db status
|
|
|
|
goose -component roomserver sqlite3 ./roomserver.db up
|
2020-09-10 14:10:32 +00:00
|
|
|
|
2020-10-15 17:09:41 +00:00
|
|
|
goose -component roomserver postgres "user=dendrite dbname=dendrite sslmode=disable" status
|
2020-09-10 14:10:32 +00:00
|
|
|
|
|
|
|
Options:
|
2020-10-15 17:09:41 +00:00
|
|
|
-component string
|
|
|
|
Dendrite component name e.g roomserver, signingkeyserver, clientapi, syncapi
|
2020-09-10 14:10:32 +00:00
|
|
|
-table string
|
|
|
|
migrations table name (default "goose_db_version")
|
|
|
|
-h print help
|
|
|
|
-v enable verbose mode
|
2020-10-15 17:09:41 +00:00
|
|
|
-dir string
|
|
|
|
directory with migration files, only relevant when creating new migrations.
|
2020-09-10 14:10:32 +00:00
|
|
|
-version
|
|
|
|
print version
|
|
|
|
|
|
|
|
Commands:
|
|
|
|
up Migrate the DB to the most recent version available
|
|
|
|
up-by-one Migrate the DB up by 1
|
|
|
|
up-to VERSION Migrate the DB to a specific VERSION
|
|
|
|
down Roll back the version by 1
|
|
|
|
down-to VERSION Roll back to a specific VERSION
|
|
|
|
redo Re-run the latest migration
|
|
|
|
reset Roll back all migrations
|
|
|
|
status Dump the migration status for the current DB
|
|
|
|
version Print the current version of the database
|
|
|
|
create NAME [sql|go] Creates new migration file with the current timestamp
|
|
|
|
fix Apply sequential ordering to migrations`,
|
|
|
|
)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
engine := args[0]
|
|
|
|
if engine != "sqlite3" && engine != "postgres" {
|
|
|
|
fmt.Println("engine must be one of 'sqlite3' or 'postgres'")
|
|
|
|
return
|
|
|
|
}
|
2020-10-15 17:09:41 +00:00
|
|
|
|
|
|
|
knownComponent := false
|
|
|
|
for _, c := range knownDBs {
|
|
|
|
if c == *component {
|
|
|
|
knownComponent = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !knownComponent {
|
|
|
|
fmt.Printf("component must be one of %v\n", knownDBs)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if engine == "sqlite3" {
|
|
|
|
loadSQLiteDeltas(*component)
|
|
|
|
} else {
|
|
|
|
loadPostgresDeltas(*component)
|
|
|
|
}
|
|
|
|
|
2020-09-10 14:10:32 +00:00
|
|
|
dbstring, command := args[1], args[2]
|
|
|
|
|
|
|
|
db, err := goose.OpenDBWithDriver(engine, dbstring)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("goose: failed to open DB: %v\n", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err := db.Close(); err != nil {
|
|
|
|
log.Fatalf("goose: failed to close DB: %v\n", err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
arguments := []string{}
|
|
|
|
if len(args) > 3 {
|
|
|
|
arguments = append(arguments, args[3:]...)
|
|
|
|
}
|
|
|
|
|
2020-10-15 17:09:41 +00:00
|
|
|
// goose demands a directory even though we don't use it for upgrades
|
|
|
|
d := *dir
|
|
|
|
if d == "" {
|
|
|
|
d = os.TempDir()
|
|
|
|
}
|
|
|
|
if err := goose.Run(command, db, d, arguments...); err != nil {
|
2020-09-10 14:10:32 +00:00
|
|
|
log.Fatalf("goose %v: %v", command, err)
|
|
|
|
}
|
|
|
|
}
|
2020-10-15 17:09:41 +00:00
|
|
|
|
|
|
|
func loadSQLiteDeltas(component string) {
|
|
|
|
switch component {
|
|
|
|
case UserAPIAccounts:
|
|
|
|
slaccounts.LoadFromGoose()
|
|
|
|
case UserAPIDevices:
|
|
|
|
sldevices.LoadFromGoose()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func loadPostgresDeltas(component string) {
|
|
|
|
switch component {
|
|
|
|
case UserAPIAccounts:
|
|
|
|
pgaccounts.LoadFromGoose()
|
|
|
|
case UserAPIDevices:
|
|
|
|
pgdevices.LoadFromGoose()
|
|
|
|
}
|
|
|
|
}
|