diff --git a/src/github.com/matrix-org/dendrite/federationsender/storage/room_table.go b/src/github.com/matrix-org/dendrite/federationsender/storage/room_table.go index 66b8fa299..e11ed4213 100644 --- a/src/github.com/matrix-org/dendrite/federationsender/storage/room_table.go +++ b/src/github.com/matrix-org/dendrite/federationsender/storage/room_table.go @@ -21,7 +21,7 @@ import ( const roomSchema = ` CREATE TABLE IF NOT EXISTS rooms ( -- The string ID of the room - room_id TEXT NOT NULL CONSTRAINT room_id_unique UNIQUE, + room_id TEXT PRIMARY KEY, -- The most recent event state by the room server. -- We can use this to tell if our view of the room state has become -- desynchronised. @@ -29,10 +29,8 @@ CREATE TABLE IF NOT EXISTS rooms ( );` const insertRoomSQL = "" + - "INSERT INTO rooms (room_id, last_event_id)" + - " VALUES ($1, '')" + - " ON CONFLICT ON CONSTRAINT room_id_unique" + - " DO NOTHING" + "INSERT INTO rooms (room_id, last_event_id) VALUES ($1, '')" + + " ON CONFLICT DO NOTHING" const selectRoomForUpdateSQL = "" + "SELECT last_event_id FROM rooms WHERE room_id = $1 FOR UPDATE" @@ -64,11 +62,16 @@ func (s *roomStatements) prepare(db *sql.DB) (err error) { return } +// insertRoom inserts the room if it didn't already exist. +// If the room didn't exist then last_event_id is set to the empty string. func (s *roomStatements) insertRoom(txn *sql.Tx, roomID string) error { _, err := txn.Stmt(s.insertRoomStmt).Exec(roomID) return err } +// selectRoomForUpdate locks the row for the room and returns the last_event_id. +// The row must already exist in the table. Callers can ensure that the row +// exists by calling insertRoom first. func (s *roomStatements) selectRoomForUpdate(txn *sql.Tx, roomID string) (string, error) { var lastEventID string err := txn.Stmt(s.selectRoomForUpdateStmt).QueryRow(roomID).Scan(&lastEventID) @@ -78,6 +81,8 @@ func (s *roomStatements) selectRoomForUpdate(txn *sql.Tx, roomID string) (string return lastEventID, nil } +// updateRoom updates the last_event_id for the room. selectRoomForUpdate should +// have already been called earlier within the transaction. func (s *roomStatements) updateRoom(txn *sql.Tx, roomID, lastEventID string) error { _, err := txn.Stmt(s.updateRoomStmt).Exec(roomID, lastEventID) return err