2022-11-11 16:41:37 +00:00
|
|
|
package deltas
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"database/sql"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/lib/pq"
|
2023-04-19 15:50:33 +01:00
|
|
|
"github.com/matrix-org/gomatrixserverlib/spec"
|
2022-11-11 16:41:37 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var serverNamesTables = []string{
|
|
|
|
"userapi_accounts",
|
|
|
|
"userapi_account_datas",
|
|
|
|
"userapi_devices",
|
|
|
|
"userapi_notifications",
|
|
|
|
"userapi_openid_tokens",
|
|
|
|
"userapi_profiles",
|
|
|
|
"userapi_pushers",
|
|
|
|
"userapi_threepids",
|
|
|
|
}
|
|
|
|
|
|
|
|
// These tables have a PRIMARY KEY constraint which we need to drop so
|
|
|
|
// that we can recreate a new unique index that contains the server name.
|
|
|
|
// If the new key doesn't exist (i.e. the database was created before the
|
|
|
|
// table rename migration) we'll try to drop the old one instead.
|
|
|
|
var serverNamesDropPK = map[string]string{
|
|
|
|
"userapi_accounts": "account_accounts",
|
|
|
|
"userapi_account_datas": "account_data",
|
|
|
|
"userapi_profiles": "account_profiles",
|
|
|
|
}
|
|
|
|
|
|
|
|
// These indices are out of date so let's drop them. They will get recreated
|
|
|
|
// automatically.
|
|
|
|
var serverNamesDropIndex = []string{
|
|
|
|
"userapi_pusher_localpart_idx",
|
|
|
|
"userapi_pusher_app_id_pushkey_localpart_idx",
|
|
|
|
}
|
|
|
|
|
|
|
|
// I know what you're thinking: you're wondering "why doesn't this use $1
|
|
|
|
// and pass variadic parameters to ExecContext?" — the answer is because
|
|
|
|
// PostgreSQL doesn't expect the table name to be specified as a substituted
|
|
|
|
// argument in that way so it results in a syntax error in the query.
|
|
|
|
|
2023-04-19 15:50:33 +01:00
|
|
|
func UpServerNames(ctx context.Context, tx *sql.Tx, serverName spec.ServerName) error {
|
2022-11-11 16:41:37 +00:00
|
|
|
for _, table := range serverNamesTables {
|
|
|
|
q := fmt.Sprintf(
|
|
|
|
"ALTER TABLE IF EXISTS %s ADD COLUMN IF NOT EXISTS server_name TEXT NOT NULL DEFAULT '';",
|
|
|
|
pq.QuoteIdentifier(table),
|
|
|
|
)
|
|
|
|
if _, err := tx.ExecContext(ctx, q); err != nil {
|
|
|
|
return fmt.Errorf("add server name to %q error: %w", table, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for newTable, oldTable := range serverNamesDropPK {
|
|
|
|
q := fmt.Sprintf(
|
|
|
|
"ALTER TABLE IF EXISTS %s DROP CONSTRAINT IF EXISTS %s;",
|
|
|
|
pq.QuoteIdentifier(newTable), pq.QuoteIdentifier(newTable+"_pkey"),
|
|
|
|
)
|
|
|
|
if _, err := tx.ExecContext(ctx, q); err != nil {
|
|
|
|
return fmt.Errorf("drop new PK from %q error: %w", newTable, err)
|
|
|
|
}
|
|
|
|
q = fmt.Sprintf(
|
|
|
|
"ALTER TABLE IF EXISTS %s DROP CONSTRAINT IF EXISTS %s;",
|
|
|
|
pq.QuoteIdentifier(newTable), pq.QuoteIdentifier(oldTable+"_pkey"),
|
|
|
|
)
|
|
|
|
if _, err := tx.ExecContext(ctx, q); err != nil {
|
|
|
|
return fmt.Errorf("drop old PK from %q error: %w", newTable, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, index := range serverNamesDropIndex {
|
|
|
|
q := fmt.Sprintf(
|
|
|
|
"DROP INDEX IF EXISTS %s;",
|
|
|
|
pq.QuoteIdentifier(index),
|
|
|
|
)
|
|
|
|
if _, err := tx.ExecContext(ctx, q); err != nil {
|
|
|
|
return fmt.Errorf("drop index %q error: %w", index, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|