BREAKING(db): Add predecessor_room_id to the rooms table

This tracks the room ID supplied in the create event.
This commit is contained in:
Kegan Dougal 2022-09-08 15:44:48 +01:00
parent 55ed63ef97
commit d591dd0584
3 changed files with 50 additions and 9 deletions

View File

@ -105,6 +105,7 @@ func (a *Accumulator) roomInfoDelta(roomID string, events []Event) RoomInfo {
isEncrypted := false
var upgradedRoomID *string
var roomType *string
var pred *string
for _, ev := range events {
if ev.Type == "m.room.encryption" && ev.StateKey == "" {
isEncrypted = true
@ -120,13 +121,19 @@ func (a *Accumulator) roomInfoDelta(roomID string, events []Event) RoomInfo {
if contentType.Exists() && contentType.Type == gjson.String {
roomType = &contentType.Str
}
predecessorRoomID := gjson.GetBytes(ev.JSON, "content.predecessor.room_id").Str
if predecessorRoomID != "" {
pred = &predecessorRoomID
}
}
}
return RoomInfo{
ID: roomID,
IsEncrypted: isEncrypted,
UpgradedRoomID: upgradedRoomID,
Type: roomType,
ID: roomID,
IsEncrypted: isEncrypted,
UpgradedRoomID: upgradedRoomID,
Type: roomType,
PredecessorRoomID: pred,
}
}

View File

@ -9,10 +9,11 @@ import (
)
type RoomInfo struct {
ID string `db:"room_id"`
IsEncrypted bool `db:"is_encrypted"`
UpgradedRoomID *string `db:"upgraded_room_id"`
Type *string `db:"type"`
ID string `db:"room_id"`
IsEncrypted bool `db:"is_encrypted"`
UpgradedRoomID *string `db:"upgraded_room_id"` // from the most recent valid tombstone event, or NULL
PredecessorRoomID *string `db:"predecessor_room_id"` // from the create event
Type *string `db:"type"`
}
// RoomsTable stores the current snapshot for a room.
@ -26,6 +27,7 @@ func NewRoomsTable(db *sqlx.DB) *RoomsTable {
current_snapshot_id BIGINT NOT NULL,
is_encrypted BOOL NOT NULL DEFAULT FALSE,
upgraded_room_id TEXT,
predecessor_room_id TEXT,
latest_nid BIGINT NOT NULL DEFAULT 0,
type TEXT -- nullable
);
@ -34,7 +36,7 @@ func NewRoomsTable(db *sqlx.DB) *RoomsTable {
}
func (t *RoomsTable) SelectRoomInfos(txn *sqlx.Tx) (infos []RoomInfo, err error) {
err = txn.Select(&infos, `SELECT room_id, is_encrypted, upgraded_room_id, type FROM syncv3_rooms`)
err = txn.Select(&infos, `SELECT room_id, is_encrypted, upgraded_room_id, predecessor_room_id, type FROM syncv3_rooms`)
return
}
@ -65,6 +67,12 @@ func (t *RoomsTable) Upsert(txn *sqlx.Tx, info RoomInfo, snapshotID, latestNID i
doUpdate += fmt.Sprintf(", type = $%d", n) // should never be updated but you never know...
n++
}
if info.PredecessorRoomID != nil {
cols += ", predecessor_room_id"
vals += fmt.Sprintf(", $%d", n)
doUpdate += fmt.Sprintf(", predecessor_room_id = $%d", n)
n++
}
insertQuery := fmt.Sprintf(`INSERT INTO syncv3_rooms(%s) VALUES(%s) %s`, cols, vals, doUpdate)
args := []interface{}{
info.ID, snapshotID, latestNID,
@ -75,6 +83,9 @@ func (t *RoomsTable) Upsert(txn *sqlx.Tx, info RoomInfo, snapshotID, latestNID i
if info.Type != nil {
args = append(args, info.Type)
}
if info.PredecessorRoomID != nil {
args = append(args, *info.PredecessorRoomID)
}
_, err = txn.Exec(insertQuery, args...)
return err
}

View File

@ -188,6 +188,29 @@ func TestRoomsTable(t *testing.T) {
if nidMap[untombstonedRoomID] != 1003 { // not 1002 as it should be updated by the subsequent update
t.Errorf("LatestNIDs: got %v want 1003", nidMap[untombstonedRoomID])
}
// check predecessor can be set
sucessorRoomID := "!sucessorRoomID:localhost"
predecessorRoomID := "!predecessor:localhost"
if err = table.Upsert(txn, RoomInfo{
ID: sucessorRoomID,
PredecessorRoomID: &predecessorRoomID,
IsEncrypted: true,
}, 2222, 1); err != nil {
t.Fatalf("Failed to update current snapshot ID: %s", err)
}
// verify
ri := getRoomInfo(t, txn, table, sucessorRoomID)
if !ri.IsEncrypted {
t.Errorf("upgraded room did not set encryption bit")
}
if ri.PredecessorRoomID == nil {
t.Errorf("predecessor room is nil")
}
if *ri.PredecessorRoomID == sucessorRoomID {
t.Errorf("predecessor room got %v want %v", *ri.PredecessorRoomID, predecessorRoomID)
}
}
func getRoomInfo(t *testing.T, txn *sqlx.Tx, table *RoomsTable, roomID string) RoomInfo {