Add RoomInfo struct

This commit is contained in:
Kegan Dougal 2020-08-28 18:18:13 +01:00
parent 737802fc06
commit b1fe8ae2f5
7 changed files with 70 additions and 37 deletions

View file

@ -46,11 +46,11 @@ func (r *RoomserverInternalAPI) QueryLatestEventsAndState(
roomState := state.NewStateResolution(r.DB)
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
info, err := r.DB.RoomInfo(ctx, request.RoomID)
if err != nil {
return err
}
if roomNID == 0 {
if info.IsStub {
return nil
}
response.RoomExists = true
@ -58,7 +58,7 @@ func (r *RoomserverInternalAPI) QueryLatestEventsAndState(
var currentStateSnapshotNID types.StateSnapshotNID
response.LatestEvents, currentStateSnapshotNID, response.Depth, err =
r.DB.LatestEventIDs(ctx, roomNID)
r.DB.LatestEventIDs(ctx, info.RoomNID)
if err != nil {
return err
}
@ -105,11 +105,11 @@ func (r *RoomserverInternalAPI) QueryStateAfterEvents(
roomState := state.NewStateResolution(r.DB)
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
info, err := r.DB.RoomInfo(ctx, request.RoomID)
if err != nil {
return err
}
if roomNID == 0 {
if info.IsStub {
return nil
}
response.RoomExists = true
@ -128,7 +128,7 @@ func (r *RoomserverInternalAPI) QueryStateAfterEvents(
// Look up the currrent state for the requested tuples.
stateEntries, err := roomState.LoadStateAfterEventsForStringTuples(
ctx, roomNID, prevStates, request.StateToFetch,
ctx, info.RoomNID, prevStates, request.StateToFetch,
)
if err != nil {
return err
@ -737,20 +737,15 @@ func (r *RoomserverInternalAPI) QueryStateAndAuthChain(
request *api.QueryStateAndAuthChainRequest,
response *api.QueryStateAndAuthChainResponse,
) error {
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
info, err := r.DB.RoomInfo(ctx, request.RoomID)
if err != nil {
return err
}
if roomNID == 0 {
if info.IsStub {
return nil
}
response.RoomExists = true
roomVersion, err := r.DB.GetRoomVersionForRoom(ctx, request.RoomID)
if err != nil {
return err
}
response.RoomVersion = roomVersion
response.RoomVersion = info.RoomVersion
stateEvents, err := r.loadStateAtEventIDs(ctx, request.PrevEventIDs)
if err != nil {
@ -773,18 +768,18 @@ func (r *RoomserverInternalAPI) QueryStateAndAuthChain(
if request.ResolveState {
if stateEvents, err = state.ResolveConflictsAdhoc(
roomVersion, stateEvents, authEvents,
info.RoomVersion, stateEvents, authEvents,
); err != nil {
return err
}
}
for _, event := range stateEvents {
response.StateEvents = append(response.StateEvents, event.Headered(roomVersion))
response.StateEvents = append(response.StateEvents, event.Headered(info.RoomVersion))
}
for _, event := range authEvents {
response.AuthChainEvents = append(response.AuthChainEvents, event.Headered(roomVersion))
response.AuthChainEvents = append(response.AuthChainEvents, event.Headered(info.RoomVersion))
}
return err

View file

@ -26,6 +26,8 @@ import (
type Database interface {
// Do we support processing input events for more than one room at a time?
SupportsConcurrentRoomInputs() bool
// RoomInfo returns room information for the given room ID, or nil if there is no room.
RoomInfo(ctx context.Context, roomID string) (*types.RoomInfo, error)
// Store the room state at an event in the database
AddState(
ctx context.Context,
@ -98,10 +100,6 @@ type Database interface {
// Returns 0 if the room doesn't exists.
// Returns an error if there was a problem talking to the database.
RoomNID(ctx context.Context, roomID string) (types.RoomNID, error)
// RoomNIDExcludingStubs is a special variation of RoomNID that will return 0 as if the room
// does not exist if the room has no latest events. This can happen when we've received an
// invite over federation for a room that we don't know anything else about yet.
RoomNIDExcludingStubs(ctx context.Context, roomID string) (types.RoomNID, error)
// Look up event references for the latest events in the room and the current state snapshot.
// Returns the latest events, the current state and the maximum depth of the latest events plus 1.
// Returns an error if there was a problem talking to the database.

View file

@ -74,6 +74,9 @@ const selectRoomVersionForRoomIDSQL = "" +
const selectRoomVersionForRoomNIDSQL = "" +
"SELECT room_version FROM roomserver_rooms WHERE room_nid = $1"
const selectRoomInfoSQL = "" +
"SELECT room_version, room_nid, state_snapshot_nid, latest_event_nids FROM roomserver_rooms WHERE room_id = $1"
type roomStatements struct {
insertRoomNIDStmt *sql.Stmt
selectRoomNIDStmt *sql.Stmt
@ -82,6 +85,7 @@ type roomStatements struct {
updateLatestEventNIDsStmt *sql.Stmt
selectRoomVersionForRoomIDStmt *sql.Stmt
selectRoomVersionForRoomNIDStmt *sql.Stmt
selectRoomInfoStmt *sql.Stmt
}
func NewPostgresRoomsTable(db *sql.DB) (tables.Rooms, error) {
@ -98,6 +102,7 @@ func NewPostgresRoomsTable(db *sql.DB) (tables.Rooms, error) {
{&s.updateLatestEventNIDsStmt, updateLatestEventNIDsSQL},
{&s.selectRoomVersionForRoomIDStmt, selectRoomVersionForRoomIDSQL},
{&s.selectRoomVersionForRoomNIDStmt, selectRoomVersionForRoomNIDSQL},
{&s.selectRoomInfoStmt, selectRoomInfoSQL},
}.Prepare(db)
}
@ -111,6 +116,19 @@ func (s *roomStatements) InsertRoomNID(
return types.RoomNID(roomNID), err
}
func (s *roomStatements) SelectRoomInfo(ctx context.Context, roomID string) (*types.RoomInfo, error) {
var info types.RoomInfo
var latestNIDs pq.Int64Array
err := s.selectRoomInfoStmt.QueryRowContext(ctx, roomID).Scan(
&info.RoomVersion, &info.RoomNID, &info.StateSnapshotNID, &latestNIDs,
)
if err == sql.ErrNoRows {
return nil, nil
}
info.IsStub = len(latestNIDs) == 0
return &info, err
}
func (s *roomStatements) SelectRoomNID(
ctx context.Context, txn *sql.Tx, roomID string,
) (types.RoomNID, error) {

View file

@ -120,6 +120,10 @@ func (d *Database) StateEntriesForTuples(
)
}
func (d *Database) RoomInfo(ctx context.Context, roomID string) (*types.RoomInfo, error) {
return d.RoomsTable.SelectRoomInfo(ctx, roomID)
}
func (d *Database) AddState(
ctx context.Context,
roomNID types.RoomNID,
@ -206,22 +210,6 @@ func (d *Database) RoomNID(ctx context.Context, roomID string) (types.RoomNID, e
return roomNID, err
}
func (d *Database) RoomNIDExcludingStubs(ctx context.Context, roomID string) (roomNID types.RoomNID, err error) {
roomNID, err = d.RoomNID(ctx, roomID)
if err != nil {
return
}
latestEvents, _, err := d.RoomsTable.SelectLatestEventNIDs(ctx, nil, roomNID)
if err != nil {
return
}
if len(latestEvents) == 0 {
roomNID = 0
return
}
return
}
func (d *Database) LatestEventIDs(
ctx context.Context, roomNID types.RoomNID,
) (references []gomatrixserverlib.EventReference, currentStateSnapshotNID types.StateSnapshotNID, depth int64, err error) {

View file

@ -64,6 +64,9 @@ const selectRoomVersionForRoomIDSQL = "" +
const selectRoomVersionForRoomNIDSQL = "" +
"SELECT room_version FROM roomserver_rooms WHERE room_nid = $1"
const selectRoomInfoSQL = "" +
"SELECT room_version, room_nid, state_snapshot_nid, latest_event_nids FROM roomserver_rooms WHERE room_id = $1"
type roomStatements struct {
db *sql.DB
insertRoomNIDStmt *sql.Stmt
@ -73,6 +76,7 @@ type roomStatements struct {
updateLatestEventNIDsStmt *sql.Stmt
selectRoomVersionForRoomIDStmt *sql.Stmt
selectRoomVersionForRoomNIDStmt *sql.Stmt
selectRoomInfoStmt *sql.Stmt
}
func NewSqliteRoomsTable(db *sql.DB) (tables.Rooms, error) {
@ -91,9 +95,30 @@ func NewSqliteRoomsTable(db *sql.DB) (tables.Rooms, error) {
{&s.updateLatestEventNIDsStmt, updateLatestEventNIDsSQL},
{&s.selectRoomVersionForRoomIDStmt, selectRoomVersionForRoomIDSQL},
{&s.selectRoomVersionForRoomNIDStmt, selectRoomVersionForRoomNIDSQL},
{&s.selectRoomInfoStmt, selectRoomInfoSQL},
}.Prepare(db)
}
func (s *roomStatements) SelectRoomInfo(ctx context.Context, roomID string) (*types.RoomInfo, error) {
var info types.RoomInfo
var latestNIDsJSON string
err := s.selectRoomInfoStmt.QueryRowContext(ctx, roomID).Scan(
&info.RoomVersion, &info.RoomNID, &info.StateSnapshotNID, &latestNIDsJSON,
)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, err
}
var latestNIDs []int64
if err = json.Unmarshal([]byte(latestNIDsJSON), &latestNIDs); err != nil {
return nil, err
}
info.IsStub = len(latestNIDs) == 0
return &info, err
}
func (s *roomStatements) InsertRoomNID(
ctx context.Context, txn *sql.Tx,
roomID string, roomVersion gomatrixserverlib.RoomVersion,

View file

@ -65,6 +65,7 @@ type Rooms interface {
UpdateLatestEventNIDs(ctx context.Context, txn *sql.Tx, roomNID types.RoomNID, eventNIDs []types.EventNID, lastEventSentNID types.EventNID, stateSnapshotNID types.StateSnapshotNID) error
SelectRoomVersionForRoomID(ctx context.Context, txn *sql.Tx, roomID string) (gomatrixserverlib.RoomVersion, error)
SelectRoomVersionForRoomNID(ctx context.Context, roomNID types.RoomNID) (gomatrixserverlib.RoomVersion, error)
SelectRoomInfo(ctx context.Context, roomID string) (*types.RoomInfo, error)
}
type Transactions interface {

View file

@ -144,3 +144,11 @@ type StateEntryList struct {
type MissingEventError string
func (e MissingEventError) Error() string { return string(e) }
// RoomInfo contains metadata about a room
type RoomInfo struct {
RoomNID RoomNID
RoomVersion gomatrixserverlib.RoomVersion
StateSnapshotNID StateSnapshotNID
IsStub bool
}