Refactor droomserver database setup for migrations

This commit is contained in:
Neil Alexander 2021-04-20 15:43:03 +01:00
parent c617d7c335
commit dc056f7e40
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
32 changed files with 325 additions and 190 deletions

View file

@ -41,7 +41,8 @@ func LoadStateBlocksRefactor(m *sqlutil.Migrations) {
} }
func UpStateBlocksRefactor(tx *sql.Tx) error { func UpStateBlocksRefactor(tx *sql.Tx) error {
logrus.Warn("Performing state block refactor upgrade. Please wait, this may take some time!") logrus.Warn("Performing state storage upgrade. Please wait, this may take some time!")
defer logrus.Warn("State storage upgrade complete")
if _, err := tx.Exec(`ALTER TABLE roomserver_state_block RENAME TO _roomserver_state_block;`); err != nil { if _, err := tx.Exec(`ALTER TABLE roomserver_state_block RENAME TO _roomserver_state_block;`); err != nil {
return fmt.Errorf("tx.Exec: %w", err) return fmt.Errorf("tx.Exec: %w", err)

View file

@ -59,12 +59,14 @@ type eventJSONStatements struct {
bulkSelectEventJSONStmt *sql.Stmt bulkSelectEventJSONStmt *sql.Stmt
} }
func NewPostgresEventJSONTable(db *sql.DB) (tables.EventJSON, error) { func createEventJSONTable(db *sql.DB) error {
s := &eventJSONStatements{}
_, err := db.Exec(eventJSONSchema) _, err := db.Exec(eventJSONSchema)
if err != nil { return err
return nil, err
} }
func prepareEventJSONTable(db *sql.DB) (tables.EventJSON, error) {
s := &eventJSONStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertEventJSONStmt, insertEventJSONSQL}, {&s.insertEventJSONStmt, insertEventJSONSQL},
{&s.bulkSelectEventJSONStmt, bulkSelectEventJSONSQL}, {&s.bulkSelectEventJSONStmt, bulkSelectEventJSONSQL},

View file

@ -77,12 +77,14 @@ type eventStateKeyStatements struct {
bulkSelectEventStateKeyStmt *sql.Stmt bulkSelectEventStateKeyStmt *sql.Stmt
} }
func NewPostgresEventStateKeysTable(db *sql.DB) (tables.EventStateKeys, error) { func createEventStateKeysTable(db *sql.DB) error {
s := &eventStateKeyStatements{}
_, err := db.Exec(eventStateKeysSchema) _, err := db.Exec(eventStateKeysSchema)
if err != nil { return err
return nil, err
} }
func prepareEventStateKeysTable(db *sql.DB) (tables.EventStateKeys, error) {
s := &eventStateKeyStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertEventStateKeyNIDStmt, insertEventStateKeyNIDSQL}, {&s.insertEventStateKeyNIDStmt, insertEventStateKeyNIDSQL},
{&s.selectEventStateKeyNIDStmt, selectEventStateKeyNIDSQL}, {&s.selectEventStateKeyNIDStmt, selectEventStateKeyNIDSQL},

View file

@ -100,13 +100,14 @@ type eventTypeStatements struct {
bulkSelectEventTypeNIDStmt *sql.Stmt bulkSelectEventTypeNIDStmt *sql.Stmt
} }
func NewPostgresEventTypesTable(db *sql.DB) (tables.EventTypes, error) { func createEventTypesTable(db *sql.DB) error {
s := &eventTypeStatements{}
_, err := db.Exec(eventTypesSchema) _, err := db.Exec(eventTypesSchema)
if err != nil { return err
return nil, err
} }
func prepareEventTypesTable(db *sql.DB) (tables.EventTypes, error) {
s := &eventTypeStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertEventTypeNIDStmt, insertEventTypeNIDSQL}, {&s.insertEventTypeNIDStmt, insertEventTypeNIDSQL},
{&s.selectEventTypeNIDStmt, selectEventTypeNIDSQL}, {&s.selectEventTypeNIDStmt, selectEventTypeNIDSQL},

View file

@ -149,13 +149,14 @@ type eventStatements struct {
selectRoomNIDsForEventNIDsStmt *sql.Stmt selectRoomNIDsForEventNIDsStmt *sql.Stmt
} }
func NewPostgresEventsTable(db *sql.DB) (tables.Events, error) { func createEventsTable(db *sql.DB) error {
s := &eventStatements{}
_, err := db.Exec(eventsSchema) _, err := db.Exec(eventsSchema)
if err != nil { return err
return nil, err
} }
func prepareEventsTable(db *sql.DB) (tables.Events, error) {
s := &eventStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertEventStmt, insertEventSQL}, {&s.insertEventStmt, insertEventSQL},
{&s.selectEventStmt, selectEventSQL}, {&s.selectEventStmt, selectEventSQL},

View file

@ -82,13 +82,14 @@ type inviteStatements struct {
updateInviteRetiredStmt *sql.Stmt updateInviteRetiredStmt *sql.Stmt
} }
func NewPostgresInvitesTable(db *sql.DB) (tables.Invites, error) { func createInvitesTable(db *sql.DB) error {
s := &inviteStatements{}
_, err := db.Exec(inviteSchema) _, err := db.Exec(inviteSchema)
if err != nil { return err
return nil, err
} }
func prepareInvitesTable(db *sql.DB) (tables.Invites, error) {
s := &inviteStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertInviteEventStmt, insertInviteEventSQL}, {&s.insertInviteEventStmt, insertInviteEventSQL},
{&s.selectInviteActiveForUserInRoomStmt, selectInviteActiveForUserInRoomSQL}, {&s.selectInviteActiveForUserInRoomStmt, selectInviteActiveForUserInRoomSQL},

View file

@ -139,13 +139,14 @@ type membershipStatements struct {
updateMembershipForgetRoomStmt *sql.Stmt updateMembershipForgetRoomStmt *sql.Stmt
} }
func NewPostgresMembershipTable(db *sql.DB) (tables.Membership, error) { func createMembershipTable(db *sql.DB) error {
s := &membershipStatements{}
_, err := db.Exec(membershipSchema) _, err := db.Exec(membershipSchema)
if err != nil { return err
return nil, err
} }
func prepareMembershipTable(db *sql.DB) (tables.Membership, error) {
s := &membershipStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertMembershipStmt, insertMembershipSQL}, {&s.insertMembershipStmt, insertMembershipSQL},
{&s.selectMembershipForUpdateStmt, selectMembershipForUpdateSQL}, {&s.selectMembershipForUpdateStmt, selectMembershipForUpdateSQL},
@ -162,11 +163,6 @@ func NewPostgresMembershipTable(db *sql.DB) (tables.Membership, error) {
}.Prepare(db) }.Prepare(db)
} }
func (s *membershipStatements) execSchema(db *sql.DB) error {
_, err := db.Exec(membershipSchema)
return err
}
func (s *membershipStatements) InsertMembership( func (s *membershipStatements) InsertMembership(
ctx context.Context, ctx context.Context,
txn *sql.Tx, roomNID types.RoomNID, targetUserNID types.EventStateKeyNID, txn *sql.Tx, roomNID types.RoomNID, targetUserNID types.EventStateKeyNID,

View file

@ -65,13 +65,14 @@ type previousEventStatements struct {
selectPreviousEventExistsStmt *sql.Stmt selectPreviousEventExistsStmt *sql.Stmt
} }
func NewPostgresPreviousEventsTable(db *sql.DB) (tables.PreviousEvents, error) { func createPrevEventsTable(db *sql.DB) error {
s := &previousEventStatements{}
_, err := db.Exec(previousEventSchema) _, err := db.Exec(previousEventSchema)
if err != nil { return err
return nil, err
} }
func preparePrevEventsTable(db *sql.DB) (tables.PreviousEvents, error) {
s := &previousEventStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertPreviousEventStmt, insertPreviousEventSQL}, {&s.insertPreviousEventStmt, insertPreviousEventSQL},
{&s.selectPreviousEventExistsStmt, selectPreviousEventExistsSQL}, {&s.selectPreviousEventExistsStmt, selectPreviousEventExistsSQL},

View file

@ -50,12 +50,14 @@ type publishedStatements struct {
selectPublishedStmt *sql.Stmt selectPublishedStmt *sql.Stmt
} }
func NewPostgresPublishedTable(db *sql.DB) (tables.Published, error) { func createPublishedTable(db *sql.DB) error {
s := &publishedStatements{}
_, err := db.Exec(publishedSchema) _, err := db.Exec(publishedSchema)
if err != nil { return err
return nil, err
} }
func preparePublishedTable(db *sql.DB) (tables.Published, error) {
s := &publishedStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.upsertPublishedStmt, upsertPublishedSQL}, {&s.upsertPublishedStmt, upsertPublishedSQL},
{&s.selectAllPublishedStmt, selectAllPublishedSQL}, {&s.selectAllPublishedStmt, selectAllPublishedSQL},

View file

@ -60,13 +60,14 @@ type redactionStatements struct {
markRedactionValidatedStmt *sql.Stmt markRedactionValidatedStmt *sql.Stmt
} }
func NewPostgresRedactionsTable(db *sql.DB) (tables.Redactions, error) { func createRedactionsTable(db *sql.DB) error {
s := &redactionStatements{}
_, err := db.Exec(redactionsSchema) _, err := db.Exec(redactionsSchema)
if err != nil { return err
return nil, err
} }
func prepareRedactionsTable(db *sql.DB) (tables.Redactions, error) {
s := &redactionStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertRedactionStmt, insertRedactionSQL}, {&s.insertRedactionStmt, insertRedactionSQL},
{&s.selectRedactionInfoByRedactionEventIDStmt, selectRedactionInfoByRedactionEventIDSQL}, {&s.selectRedactionInfoByRedactionEventIDStmt, selectRedactionInfoByRedactionEventIDSQL},

View file

@ -62,12 +62,14 @@ type roomAliasesStatements struct {
deleteRoomAliasStmt *sql.Stmt deleteRoomAliasStmt *sql.Stmt
} }
func NewPostgresRoomAliasesTable(db *sql.DB) (tables.RoomAliases, error) { func createRoomAliasesTable(db *sql.DB) error {
s := &roomAliasesStatements{}
_, err := db.Exec(roomAliasesSchema) _, err := db.Exec(roomAliasesSchema)
if err != nil { return err
return nil, err
} }
func prepareRoomAliasesTable(db *sql.DB) (tables.RoomAliases, error) {
s := &roomAliasesStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertRoomAliasStmt, insertRoomAliasSQL}, {&s.insertRoomAliasStmt, insertRoomAliasSQL},
{&s.selectRoomIDFromAliasStmt, selectRoomIDFromAliasSQL}, {&s.selectRoomIDFromAliasStmt, selectRoomIDFromAliasSQL},

View file

@ -96,12 +96,14 @@ type roomStatements struct {
bulkSelectRoomNIDsStmt *sql.Stmt bulkSelectRoomNIDsStmt *sql.Stmt
} }
func NewPostgresRoomsTable(db *sql.DB) (tables.Rooms, error) { func createRoomsTable(db *sql.DB) error {
s := &roomStatements{}
_, err := db.Exec(roomsSchema) _, err := db.Exec(roomsSchema)
if err != nil { return err
return nil, err
} }
func prepareRoomsTable(db *sql.DB) (tables.Rooms, error) {
s := &roomStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertRoomNIDStmt, insertRoomNIDSQL}, {&s.insertRoomNIDStmt, insertRoomNIDSQL},
{&s.selectRoomNIDStmt, selectRoomNIDSQL}, {&s.selectRoomNIDStmt, selectRoomNIDSQL},

View file

@ -61,13 +61,14 @@ type stateBlockStatements struct {
bulkSelectStateBlockEntriesStmt *sql.Stmt bulkSelectStateBlockEntriesStmt *sql.Stmt
} }
func NewPostgresStateBlockTable(db *sql.DB) (tables.StateBlock, error) { func createStateBlockTable(db *sql.DB) error {
s := &stateBlockStatements{}
_, err := db.Exec(stateDataSchema) _, err := db.Exec(stateDataSchema)
if err != nil { return err
return nil, err
} }
func prepareStateBlockTable(db *sql.DB) (tables.StateBlock, error) {
s := &stateBlockStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertStateDataStmt, insertStateDataSQL}, {&s.insertStateDataStmt, insertStateDataSQL},
{&s.bulkSelectStateBlockEntriesStmt, bulkSelectStateBlockEntriesSQL}, {&s.bulkSelectStateBlockEntriesStmt, bulkSelectStateBlockEntriesSQL},

View file

@ -67,13 +67,14 @@ type stateSnapshotStatements struct {
bulkSelectStateBlockNIDsStmt *sql.Stmt bulkSelectStateBlockNIDsStmt *sql.Stmt
} }
func NewPostgresStateSnapshotTable(db *sql.DB) (tables.StateSnapshot, error) { func createStateSnapshotTable(db *sql.DB) error {
s := &stateSnapshotStatements{}
_, err := db.Exec(stateSnapshotSchema) _, err := db.Exec(stateSnapshotSchema)
if err != nil { return err
return nil, err
} }
func prepareStateSnapshotTable(db *sql.DB) (tables.StateSnapshot, error) {
s := &stateSnapshotStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertStateStmt, insertStateSQL}, {&s.insertStateStmt, insertStateSQL},
{&s.bulkSelectStateBlockNIDsStmt, bulkSelectStateBlockNIDsSQL}, {&s.bulkSelectStateBlockNIDsStmt, bulkSelectStateBlockNIDsSQL},

View file

@ -43,80 +43,130 @@ func Open(dbProperties *config.DatabaseOptions, cache caching.RoomServerCaches)
return nil, fmt.Errorf("sqlutil.Open: %w", err) return nil, fmt.Errorf("sqlutil.Open: %w", err)
} }
// Create tables before executing migrations so we don't fail if the table is missing, // Create the tables.
// and THEN prepare statements so we don't fail due to referencing new columns if err := d.create(db); err != nil {
ms := membershipStatements{} return nil, err
if err := ms.execSchema(db); err != nil {
return nil, fmt.Errorf("ms.execSchema: %w", err)
} }
// Then execute the migrations. By this point the tables are created with the latest
// schemas.
m := sqlutil.NewMigrations() m := sqlutil.NewMigrations()
deltas.LoadAddForgottenColumn(m) deltas.LoadAddForgottenColumn(m)
deltas.LoadStateBlocksRefactor(m) deltas.LoadStateBlocksRefactor(m)
if err := m.RunDeltas(db, dbProperties); err != nil { if err := m.RunDeltas(db, dbProperties); err != nil {
return nil, fmt.Errorf("m.RunDeltas: %w", err) return nil, err
} }
// Then prepare the statements. Now that the migrations have run, any columns referred
// to in the database code should now exist.
if err := d.prepare(db, cache); err != nil { if err := d.prepare(db, cache); err != nil {
return nil, fmt.Errorf("d.prepare: %w", err) return nil, err
} }
return &d, nil return &d, nil
} }
// nolint: gocyclo func (d *Database) create(db *sql.DB) error {
func (d *Database) prepare(db *sql.DB, cache caching.RoomServerCaches) (err error) { if err := createEventStateKeysTable(db); err != nil {
eventStateKeys, err := NewPostgresEventStateKeysTable(db) return err
}
if err := createEventTypesTable(db); err != nil {
return err
}
if err := createEventJSONTable(db); err != nil {
return err
}
if err := createEventsTable(db); err != nil {
return err
}
if err := createRoomsTable(db); err != nil {
return err
}
if err := createTransactionsTable(db); err != nil {
return err
}
if err := createStateBlockTable(db); err != nil {
return err
}
if err := createStateSnapshotTable(db); err != nil {
return err
}
if err := createPrevEventsTable(db); err != nil {
return err
}
if err := createRoomAliasesTable(db); err != nil {
return err
}
if err := createInvitesTable(db); err != nil {
return err
}
if err := createMembershipTable(db); err != nil {
return err
}
if err := createPublishedTable(db); err != nil {
return err
}
if err := createRedactionsTable(db); err != nil {
return err
}
return nil
}
func (d *Database) prepare(db *sql.DB, cache caching.RoomServerCaches) error {
eventStateKeys, err := prepareEventStateKeysTable(db)
if err != nil { if err != nil {
return err return err
} }
eventTypes, err := NewPostgresEventTypesTable(db) eventTypes, err := prepareEventTypesTable(db)
if err != nil { if err != nil {
return err return err
} }
eventJSON, err := NewPostgresEventJSONTable(db) eventJSON, err := prepareEventJSONTable(db)
if err != nil { if err != nil {
return err return err
} }
events, err := NewPostgresEventsTable(db) events, err := prepareEventsTable(db)
if err != nil { if err != nil {
return err return err
} }
rooms, err := NewPostgresRoomsTable(db) rooms, err := prepareRoomsTable(db)
if err != nil { if err != nil {
return err return err
} }
transactions, err := NewPostgresTransactionsTable(db) transactions, err := prepareTransactionsTable(db)
if err != nil { if err != nil {
return err return err
} }
stateBlock, err := NewPostgresStateBlockTable(db) stateBlock, err := prepareStateBlockTable(db)
if err != nil { if err != nil {
return err return err
} }
stateSnapshot, err := NewPostgresStateSnapshotTable(db) stateSnapshot, err := prepareStateSnapshotTable(db)
if err != nil { if err != nil {
return err return err
} }
roomAliases, err := NewPostgresRoomAliasesTable(db) prevEvents, err := preparePrevEventsTable(db)
if err != nil { if err != nil {
return err return err
} }
prevEvents, err := NewPostgresPreviousEventsTable(db) roomAliases, err := prepareRoomAliasesTable(db)
if err != nil { if err != nil {
return err return err
} }
invites, err := NewPostgresInvitesTable(db) invites, err := prepareInvitesTable(db)
if err != nil { if err != nil {
return err return err
} }
membership, err := NewPostgresMembershipTable(db) membership, err := prepareMembershipTable(db)
if err != nil { if err != nil {
return err return err
} }
published, err := NewPostgresPublishedTable(db) published, err := preparePublishedTable(db)
if err != nil { if err != nil {
return err return err
} }
redactions, err := NewPostgresRedactionsTable(db) redactions, err := prepareRedactionsTable(db)
if err != nil { if err != nil {
return err return err
} }

View file

@ -54,13 +54,14 @@ type transactionStatements struct {
selectTransactionEventIDStmt *sql.Stmt selectTransactionEventIDStmt *sql.Stmt
} }
func NewPostgresTransactionsTable(db *sql.DB) (tables.Transactions, error) { func createTransactionsTable(db *sql.DB) error {
s := &transactionStatements{}
_, err := db.Exec(transactionsSchema) _, err := db.Exec(transactionsSchema)
if err != nil { return err
return nil, err
} }
func prepareTransactionsTable(db *sql.DB) (tables.Transactions, error) {
s := &transactionStatements{}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertTransactionStmt, insertTransactionSQL}, {&s.insertTransactionStmt, insertTransactionSQL},
{&s.selectTransactionEventIDStmt, selectTransactionEventIDSQL}, {&s.selectTransactionEventIDStmt, selectTransactionEventIDSQL},

View file

@ -24,6 +24,7 @@ import (
"github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/util" "github.com/matrix-org/util"
"github.com/sirupsen/logrus"
) )
func LoadStateBlocksRefactor(m *sqlutil.Migrations) { func LoadStateBlocksRefactor(m *sqlutil.Migrations) {
@ -31,6 +32,8 @@ func LoadStateBlocksRefactor(m *sqlutil.Migrations) {
} }
func UpStateBlocksRefactor(tx *sql.Tx) error { func UpStateBlocksRefactor(tx *sql.Tx) error {
logrus.Warn("Performing state block refactor upgrade. Please wait, this may take some time!")
if _, err := tx.Exec(`ALTER TABLE roomserver_state_block RENAME TO _roomserver_state_block;`); err != nil { if _, err := tx.Exec(`ALTER TABLE roomserver_state_block RENAME TO _roomserver_state_block;`); err != nil {
return fmt.Errorf("tx.Exec: %w", err) return fmt.Errorf("tx.Exec: %w", err)
} }

View file

@ -53,14 +53,16 @@ type eventJSONStatements struct {
bulkSelectEventJSONStmt *sql.Stmt bulkSelectEventJSONStmt *sql.Stmt
} }
func NewSqliteEventJSONTable(db *sql.DB) (tables.EventJSON, error) { func createEventJSONTable(db *sql.DB) error {
_, err := db.Exec(eventJSONSchema)
return err
}
func prepareEventJSONTable(db *sql.DB) (tables.EventJSON, error) {
s := &eventJSONStatements{ s := &eventJSONStatements{
db: db, db: db,
} }
_, err := db.Exec(eventJSONSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertEventJSONStmt, insertEventJSONSQL}, {&s.insertEventJSONStmt, insertEventJSONSQL},
{&s.bulkSelectEventJSONStmt, bulkSelectEventJSONSQL}, {&s.bulkSelectEventJSONStmt, bulkSelectEventJSONSQL},

View file

@ -70,14 +70,16 @@ type eventStateKeyStatements struct {
bulkSelectEventStateKeyStmt *sql.Stmt bulkSelectEventStateKeyStmt *sql.Stmt
} }
func NewSqliteEventStateKeysTable(db *sql.DB) (tables.EventStateKeys, error) { func createEventStateKeysTable(db *sql.DB) error {
_, err := db.Exec(eventStateKeysSchema)
return err
}
func prepareEventStateKeysTable(db *sql.DB) (tables.EventStateKeys, error) {
s := &eventStateKeyStatements{ s := &eventStateKeyStatements{
db: db, db: db,
} }
_, err := db.Exec(eventStateKeysSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertEventStateKeyNIDStmt, insertEventStateKeyNIDSQL}, {&s.insertEventStateKeyNIDStmt, insertEventStateKeyNIDSQL},
{&s.selectEventStateKeyNIDStmt, selectEventStateKeyNIDSQL}, {&s.selectEventStateKeyNIDStmt, selectEventStateKeyNIDSQL},

View file

@ -85,14 +85,15 @@ type eventTypeStatements struct {
bulkSelectEventTypeNIDStmt *sql.Stmt bulkSelectEventTypeNIDStmt *sql.Stmt
} }
func NewSqliteEventTypesTable(db *sql.DB) (tables.EventTypes, error) { func createEventTypesTable(db *sql.DB) error {
_, err := db.Exec(eventTypesSchema)
return err
}
func prepareEventTypesTable(db *sql.DB) (tables.EventTypes, error) {
s := &eventTypeStatements{ s := &eventTypeStatements{
db: db, db: db,
} }
_, err := db.Exec(eventTypesSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertEventTypeNIDStmt, insertEventTypeNIDSQL}, {&s.insertEventTypeNIDStmt, insertEventTypeNIDSQL},

View file

@ -121,14 +121,15 @@ type eventStatements struct {
//selectRoomNIDsForEventNIDsStmt *sql.Stmt //selectRoomNIDsForEventNIDsStmt *sql.Stmt
} }
func NewSqliteEventsTable(db *sql.DB) (tables.Events, error) { func createEventsTable(db *sql.DB) error {
_, err := db.Exec(eventsSchema)
return err
}
func prepareEventsTable(db *sql.DB) (tables.Events, error) {
s := &eventStatements{ s := &eventStatements{
db: db, db: db,
} }
_, err := db.Exec(eventsSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertEventStmt, insertEventSQL}, {&s.insertEventStmt, insertEventSQL},

View file

@ -70,14 +70,15 @@ type inviteStatements struct {
selectInvitesAboutToRetireStmt *sql.Stmt selectInvitesAboutToRetireStmt *sql.Stmt
} }
func NewSqliteInvitesTable(db *sql.DB) (tables.Invites, error) { func createInvitesTable(db *sql.DB) error {
_, err := db.Exec(inviteSchema)
return err
}
func prepareInvitesTable(db *sql.DB) (tables.Invites, error) {
s := &inviteStatements{ s := &inviteStatements{
db: db, db: db,
} }
_, err := db.Exec(inviteSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertInviteEventStmt, insertInviteEventSQL}, {&s.insertInviteEventStmt, insertInviteEventSQL},

View file

@ -115,7 +115,12 @@ type membershipStatements struct {
updateMembershipForgetRoomStmt *sql.Stmt updateMembershipForgetRoomStmt *sql.Stmt
} }
func NewSqliteMembershipTable(db *sql.DB) (tables.Membership, error) { func createMembershipTable(db *sql.DB) error {
_, err := db.Exec(membershipSchema)
return err
}
func prepareMembershipTable(db *sql.DB) (tables.Membership, error) {
s := &membershipStatements{ s := &membershipStatements{
db: db, db: db,
} }
@ -135,11 +140,6 @@ func NewSqliteMembershipTable(db *sql.DB) (tables.Membership, error) {
}.Prepare(db) }.Prepare(db)
} }
func (s *membershipStatements) execSchema(db *sql.DB) error {
_, err := db.Exec(membershipSchema)
return err
}
func (s *membershipStatements) InsertMembership( func (s *membershipStatements) InsertMembership(
ctx context.Context, txn *sql.Tx, ctx context.Context, txn *sql.Tx,
roomNID types.RoomNID, targetUserNID types.EventStateKeyNID, roomNID types.RoomNID, targetUserNID types.EventStateKeyNID,

View file

@ -71,14 +71,15 @@ type previousEventStatements struct {
selectPreviousEventExistsStmt *sql.Stmt selectPreviousEventExistsStmt *sql.Stmt
} }
func NewSqlitePrevEventsTable(db *sql.DB) (tables.PreviousEvents, error) { func createPrevEventsTable(db *sql.DB) error {
_, err := db.Exec(previousEventSchema)
return err
}
func preparePrevEventsTable(db *sql.DB) (tables.PreviousEvents, error) {
s := &previousEventStatements{ s := &previousEventStatements{
db: db, db: db,
} }
_, err := db.Exec(previousEventSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertPreviousEventStmt, insertPreviousEventSQL}, {&s.insertPreviousEventStmt, insertPreviousEventSQL},

View file

@ -50,14 +50,16 @@ type publishedStatements struct {
selectPublishedStmt *sql.Stmt selectPublishedStmt *sql.Stmt
} }
func NewSqlitePublishedTable(db *sql.DB) (tables.Published, error) { func createPublishedTable(db *sql.DB) error {
_, err := db.Exec(publishedSchema)
return err
}
func preparePublishedTable(db *sql.DB) (tables.Published, error) {
s := &publishedStatements{ s := &publishedStatements{
db: db, db: db,
} }
_, err := db.Exec(publishedSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.upsertPublishedStmt, upsertPublishedSQL}, {&s.upsertPublishedStmt, upsertPublishedSQL},
{&s.selectAllPublishedStmt, selectAllPublishedSQL}, {&s.selectAllPublishedStmt, selectAllPublishedSQL},

View file

@ -59,14 +59,15 @@ type redactionStatements struct {
markRedactionValidatedStmt *sql.Stmt markRedactionValidatedStmt *sql.Stmt
} }
func NewSqliteRedactionsTable(db *sql.DB) (tables.Redactions, error) { func createRedactionsTable(db *sql.DB) error {
_, err := db.Exec(redactionsSchema)
return err
}
func prepareRedactionsTable(db *sql.DB) (tables.Redactions, error) {
s := &redactionStatements{ s := &redactionStatements{
db: db, db: db,
} }
_, err := db.Exec(redactionsSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertRedactionStmt, insertRedactionSQL}, {&s.insertRedactionStmt, insertRedactionSQL},

View file

@ -64,14 +64,16 @@ type roomAliasesStatements struct {
deleteRoomAliasStmt *sql.Stmt deleteRoomAliasStmt *sql.Stmt
} }
func NewSqliteRoomAliasesTable(db *sql.DB) (tables.RoomAliases, error) { func createRoomAliasesTable(db *sql.DB) error {
_, err := db.Exec(roomAliasesSchema)
return err
}
func prepareRoomAliasesTable(db *sql.DB) (tables.RoomAliases, error) {
s := &roomAliasesStatements{ s := &roomAliasesStatements{
db: db, db: db,
} }
_, err := db.Exec(roomAliasesSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertRoomAliasStmt, insertRoomAliasSQL}, {&s.insertRoomAliasStmt, insertRoomAliasSQL},
{&s.selectRoomIDFromAliasStmt, selectRoomIDFromAliasSQL}, {&s.selectRoomIDFromAliasStmt, selectRoomIDFromAliasSQL},

View file

@ -86,14 +86,16 @@ type roomStatements struct {
selectRoomIDsStmt *sql.Stmt selectRoomIDsStmt *sql.Stmt
} }
func NewSqliteRoomsTable(db *sql.DB) (tables.Rooms, error) { func createRoomsTable(db *sql.DB) error {
_, err := db.Exec(roomsSchema)
return err
}
func prepareRoomsTable(db *sql.DB) (tables.Rooms, error) {
s := &roomStatements{ s := &roomStatements{
db: db, db: db,
} }
_, err := db.Exec(roomsSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertRoomNIDStmt, insertRoomNIDSQL}, {&s.insertRoomNIDStmt, insertRoomNIDSQL},
{&s.selectRoomNIDStmt, selectRoomNIDSQL}, {&s.selectRoomNIDStmt, selectRoomNIDSQL},

View file

@ -56,14 +56,15 @@ type stateBlockStatements struct {
bulkSelectStateBlockEntriesStmt *sql.Stmt bulkSelectStateBlockEntriesStmt *sql.Stmt
} }
func NewSqliteStateBlockTable(db *sql.DB) (tables.StateBlock, error) { func createStateBlockTable(db *sql.DB) error {
_, err := db.Exec(stateDataSchema)
return err
}
func prepareStateBlockTable(db *sql.DB) (tables.StateBlock, error) {
s := &stateBlockStatements{ s := &stateBlockStatements{
db: db, db: db,
} }
_, err := db.Exec(stateDataSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertStateDataStmt, insertStateDataSQL}, {&s.insertStateDataStmt, insertStateDataSQL},

View file

@ -59,14 +59,15 @@ type stateSnapshotStatements struct {
bulkSelectStateBlockNIDsStmt *sql.Stmt bulkSelectStateBlockNIDsStmt *sql.Stmt
} }
func NewSqliteStateSnapshotTable(db *sql.DB) (tables.StateSnapshot, error) { func createStateSnapshotTable(db *sql.DB) error {
_, err := db.Exec(stateSnapshotSchema)
return err
}
func prepareStateSnapshotTable(db *sql.DB) (tables.StateSnapshot, error) {
s := &stateSnapshotStatements{ s := &stateSnapshotStatements{
db: db, db: db,
} }
_, err := db.Exec(stateSnapshotSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertStateStmt, insertStateSQL}, {&s.insertStateStmt, insertStateSQL},

View file

@ -53,18 +53,22 @@ func Open(dbProperties *config.DatabaseOptions, cache caching.RoomServerCaches)
// which it will never obtain. // which it will never obtain.
db.SetMaxOpenConns(20) db.SetMaxOpenConns(20)
// Create tables before executing migrations so we don't fail if the table is missing, // Create the tables.
// and THEN prepare statements so we don't fail due to referencing new columns if err := d.create(db); err != nil {
ms := membershipStatements{}
if err := ms.execSchema(db); err != nil {
return nil, err return nil, err
} }
// Then execute the migrations. By this point the tables are created with the latest
// schemas.
m := sqlutil.NewMigrations() m := sqlutil.NewMigrations()
deltas.LoadAddForgottenColumn(m) deltas.LoadAddForgottenColumn(m)
deltas.LoadStateBlocksRefactor(m) deltas.LoadStateBlocksRefactor(m)
if err := m.RunDeltas(db, dbProperties); err != nil { if err := m.RunDeltas(db, dbProperties); err != nil {
return nil, err return nil, err
} }
// Then prepare the statements. Now that the migrations have run, any columns referred
// to in the database code should now exist.
if err := d.prepare(db, cache); err != nil { if err := d.prepare(db, cache); err != nil {
return nil, err return nil, err
} }
@ -72,62 +76,107 @@ func Open(dbProperties *config.DatabaseOptions, cache caching.RoomServerCaches)
return &d, nil return &d, nil
} }
// nolint: gocyclo func (d *Database) create(db *sql.DB) error {
if err := createEventStateKeysTable(db); err != nil {
return err
}
if err := createEventTypesTable(db); err != nil {
return err
}
if err := createEventJSONTable(db); err != nil {
return err
}
if err := createEventsTable(db); err != nil {
return err
}
if err := createRoomsTable(db); err != nil {
return err
}
if err := createTransactionsTable(db); err != nil {
return err
}
if err := createStateBlockTable(db); err != nil {
return err
}
if err := createStateSnapshotTable(db); err != nil {
return err
}
if err := createPrevEventsTable(db); err != nil {
return err
}
if err := createRoomAliasesTable(db); err != nil {
return err
}
if err := createInvitesTable(db); err != nil {
return err
}
if err := createMembershipTable(db); err != nil {
return err
}
if err := createPublishedTable(db); err != nil {
return err
}
if err := createRedactionsTable(db); err != nil {
return err
}
return nil
}
func (d *Database) prepare(db *sql.DB, cache caching.RoomServerCaches) error { func (d *Database) prepare(db *sql.DB, cache caching.RoomServerCaches) error {
var err error eventStateKeys, err := prepareEventStateKeysTable(db)
eventStateKeys, err := NewSqliteEventStateKeysTable(db)
if err != nil { if err != nil {
return err return err
} }
eventTypes, err := NewSqliteEventTypesTable(db) eventTypes, err := prepareEventTypesTable(db)
if err != nil { if err != nil {
return err return err
} }
eventJSON, err := NewSqliteEventJSONTable(db) eventJSON, err := prepareEventJSONTable(db)
if err != nil { if err != nil {
return err return err
} }
events, err := NewSqliteEventsTable(db) events, err := prepareEventsTable(db)
if err != nil { if err != nil {
return err return err
} }
rooms, err := NewSqliteRoomsTable(db) rooms, err := prepareRoomsTable(db)
if err != nil { if err != nil {
return err return err
} }
transactions, err := NewSqliteTransactionsTable(db) transactions, err := prepareTransactionsTable(db)
if err != nil { if err != nil {
return err return err
} }
stateBlock, err := NewSqliteStateBlockTable(db) stateBlock, err := prepareStateBlockTable(db)
if err != nil { if err != nil {
return err return err
} }
stateSnapshot, err := NewSqliteStateSnapshotTable(db) stateSnapshot, err := prepareStateSnapshotTable(db)
if err != nil { if err != nil {
return err return err
} }
prevEvents, err := NewSqlitePrevEventsTable(db) prevEvents, err := preparePrevEventsTable(db)
if err != nil { if err != nil {
return err return err
} }
roomAliases, err := NewSqliteRoomAliasesTable(db) roomAliases, err := prepareRoomAliasesTable(db)
if err != nil { if err != nil {
return err return err
} }
invites, err := NewSqliteInvitesTable(db) invites, err := prepareInvitesTable(db)
if err != nil { if err != nil {
return err return err
} }
membership, err := NewSqliteMembershipTable(db) membership, err := prepareMembershipTable(db)
if err != nil { if err != nil {
return err return err
} }
published, err := NewSqlitePublishedTable(db) published, err := preparePublishedTable(db)
if err != nil { if err != nil {
return err return err
} }
redactions, err := NewSqliteRedactionsTable(db) redactions, err := prepareRedactionsTable(db)
if err != nil { if err != nil {
return err return err
} }

View file

@ -49,14 +49,15 @@ type transactionStatements struct {
selectTransactionEventIDStmt *sql.Stmt selectTransactionEventIDStmt *sql.Stmt
} }
func NewSqliteTransactionsTable(db *sql.DB) (tables.Transactions, error) { func createTransactionsTable(db *sql.DB) error {
_, err := db.Exec(transactionsSchema)
return err
}
func prepareTransactionsTable(db *sql.DB) (tables.Transactions, error) {
s := &transactionStatements{ s := &transactionStatements{
db: db, db: db,
} }
_, err := db.Exec(transactionsSchema)
if err != nil {
return nil, err
}
return s, shared.StatementList{ return s, shared.StatementList{
{&s.insertTransactionStmt, insertTransactionSQL}, {&s.insertTransactionStmt, insertTransactionSQL},