mirror of
https://github.com/matrix-org/dendrite
synced 2024-12-14 07:12:53 +00:00
Add RoomInfo metadata struct (#1367)
* Add RoomInfo struct * Remove RoomNID and replace with RoomInfo * Bugfix and remove another needless query * nil guard
This commit is contained in:
parent
0ab5bccd11
commit
6d79f04354
10 changed files with 106 additions and 85 deletions
|
@ -293,11 +293,11 @@ func joinEventsFromHistoryVisibility(
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
// get joined members
|
// get joined members
|
||||||
roomNID, err := db.RoomNID(ctx, roomID)
|
info, err := db.RoomInfo(ctx, roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
joinEventNIDs, err := db.GetMembershipEventNIDsForRoom(ctx, roomNID, true, false)
|
joinEventNIDs, err := db.GetMembershipEventNIDsForRoom(ctx, info.RoomNID, true, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,17 @@ func (r *RoomserverInternalAPI) PerformInvite(
|
||||||
|
|
||||||
roomID := event.RoomID()
|
roomID := event.RoomID()
|
||||||
targetUserID := *event.StateKey()
|
targetUserID := *event.StateKey()
|
||||||
|
info, err := r.DB.RoomInfo(ctx, roomID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Failed to load RoomInfo: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"event_id": event.EventID(),
|
"event_id": event.EventID(),
|
||||||
"room_id": roomID,
|
"room_id": roomID,
|
||||||
"room_version": req.RoomVersion,
|
"room_version": req.RoomVersion,
|
||||||
"target_user_id": targetUserID,
|
"target_user_id": targetUserID,
|
||||||
|
"room_info_exists": info != nil,
|
||||||
}).Info("processing invite event")
|
}).Info("processing invite event")
|
||||||
|
|
||||||
_, domain, _ := gomatrixserverlib.SplitID('@', targetUserID)
|
_, domain, _ := gomatrixserverlib.SplitID('@', targetUserID)
|
||||||
|
@ -39,25 +44,25 @@ func (r *RoomserverInternalAPI) PerformInvite(
|
||||||
isOriginLocal := event.Origin() == r.Cfg.Matrix.ServerName
|
isOriginLocal := event.Origin() == r.Cfg.Matrix.ServerName
|
||||||
|
|
||||||
inviteState := req.InviteRoomState
|
inviteState := req.InviteRoomState
|
||||||
if len(inviteState) == 0 {
|
if len(inviteState) == 0 && info != nil {
|
||||||
if is, err := buildInviteStrippedState(ctx, r.DB, req); err == nil {
|
var is []gomatrixserverlib.InviteV2StrippedState
|
||||||
|
if is, err = buildInviteStrippedState(ctx, r.DB, info, req); err == nil {
|
||||||
inviteState = is
|
inviteState = is
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(inviteState) == 0 {
|
if len(inviteState) == 0 {
|
||||||
if err := event.SetUnsignedField("invite_room_state", struct{}{}); err != nil {
|
if err = event.SetUnsignedField("invite_room_state", struct{}{}); err != nil {
|
||||||
return fmt.Errorf("event.SetUnsignedField: %w", err)
|
return fmt.Errorf("event.SetUnsignedField: %w", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := event.SetUnsignedField("invite_room_state", inviteState); err != nil {
|
if err = event.SetUnsignedField("invite_room_state", inviteState); err != nil {
|
||||||
return fmt.Errorf("event.SetUnsignedField: %w", err)
|
return fmt.Errorf("event.SetUnsignedField: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var isAlreadyJoined bool
|
var isAlreadyJoined bool
|
||||||
roomNID, err := r.DB.RoomNID(ctx, roomID)
|
if info != nil {
|
||||||
if err == nil {
|
_, isAlreadyJoined, err = r.DB.GetMembership(ctx, info.RoomNID, *event.StateKey())
|
||||||
_, isAlreadyJoined, err = r.DB.GetMembership(ctx, roomNID, *event.StateKey())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("r.DB.GetMembership: %w", err)
|
return fmt.Errorf("r.DB.GetMembership: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -187,12 +192,9 @@ func (r *RoomserverInternalAPI) PerformInvite(
|
||||||
func buildInviteStrippedState(
|
func buildInviteStrippedState(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
db storage.Database,
|
db storage.Database,
|
||||||
|
info *types.RoomInfo,
|
||||||
input *api.PerformInviteRequest,
|
input *api.PerformInviteRequest,
|
||||||
) ([]gomatrixserverlib.InviteV2StrippedState, error) {
|
) ([]gomatrixserverlib.InviteV2StrippedState, error) {
|
||||||
roomNID, err := db.RoomNID(ctx, input.Event.RoomID())
|
|
||||||
if err != nil || roomNID == 0 {
|
|
||||||
return nil, fmt.Errorf("room %q unknown", input.Event.RoomID())
|
|
||||||
}
|
|
||||||
stateWanted := []gomatrixserverlib.StateKeyTuple{}
|
stateWanted := []gomatrixserverlib.StateKeyTuple{}
|
||||||
// "If they are set on the room, at least the state for m.room.avatar, m.room.canonical_alias, m.room.join_rules, and m.room.name SHOULD be included."
|
// "If they are set on the room, at least the state for m.room.avatar, m.room.canonical_alias, m.room.join_rules, and m.room.name SHOULD be included."
|
||||||
// https://matrix.org/docs/spec/client_server/r0.6.0#m-room-member
|
// https://matrix.org/docs/spec/client_server/r0.6.0#m-room-member
|
||||||
|
@ -206,13 +208,9 @@ func buildInviteStrippedState(
|
||||||
StateKey: "",
|
StateKey: "",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_, currentStateSnapshotNID, _, err := db.LatestEventIDs(ctx, roomNID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
roomState := state.NewStateResolution(db)
|
roomState := state.NewStateResolution(db)
|
||||||
stateEntries, err := roomState.LoadStateAtSnapshotForStringTuples(
|
stateEntries, err := roomState.LoadStateAtSnapshotForStringTuples(
|
||||||
ctx, currentStateSnapshotNID, stateWanted,
|
ctx, info.StateSnapshotNID, stateWanted,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -172,9 +172,12 @@ func (r *RoomserverInternalAPI) isInvitePending(
|
||||||
roomID, userID string,
|
roomID, userID string,
|
||||||
) (bool, string, string, error) {
|
) (bool, string, string, error) {
|
||||||
// Look up the room NID for the supplied room ID.
|
// Look up the room NID for the supplied room ID.
|
||||||
roomNID, err := r.DB.RoomNID(ctx, roomID)
|
info, err := r.DB.RoomInfo(ctx, roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, "", "", fmt.Errorf("r.DB.RoomNID: %w", err)
|
return false, "", "", fmt.Errorf("r.DB.RoomInfo: %w", err)
|
||||||
|
}
|
||||||
|
if info == nil {
|
||||||
|
return false, "", "", fmt.Errorf("cannot get RoomInfo: unknown room ID %s", roomID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look up the state key NID for the supplied user ID.
|
// Look up the state key NID for the supplied user ID.
|
||||||
|
@ -190,7 +193,7 @@ func (r *RoomserverInternalAPI) isInvitePending(
|
||||||
// Let's see if we have an event active for the user in the room. If
|
// Let's see if we have an event active for the user in the room. If
|
||||||
// we do then it will contain a server name that we can direct the
|
// we do then it will contain a server name that we can direct the
|
||||||
// send_leave to.
|
// send_leave to.
|
||||||
senderUserNIDs, eventIDs, err := r.DB.GetInvitesForUser(ctx, roomNID, targetUserNID)
|
senderUserNIDs, eventIDs, err := r.DB.GetInvitesForUser(ctx, info.RoomNID, targetUserNID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, "", "", fmt.Errorf("r.DB.GetInvitesForUser: %w", err)
|
return false, "", "", fmt.Errorf("r.DB.GetInvitesForUser: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,11 +46,11 @@ func (r *RoomserverInternalAPI) QueryLatestEventsAndState(
|
||||||
|
|
||||||
roomState := state.NewStateResolution(r.DB)
|
roomState := state.NewStateResolution(r.DB)
|
||||||
|
|
||||||
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
|
info, err := r.DB.RoomInfo(ctx, request.RoomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if roomNID == 0 {
|
if info.IsStub {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
response.RoomExists = true
|
response.RoomExists = true
|
||||||
|
@ -58,7 +58,7 @@ func (r *RoomserverInternalAPI) QueryLatestEventsAndState(
|
||||||
|
|
||||||
var currentStateSnapshotNID types.StateSnapshotNID
|
var currentStateSnapshotNID types.StateSnapshotNID
|
||||||
response.LatestEvents, currentStateSnapshotNID, response.Depth, err =
|
response.LatestEvents, currentStateSnapshotNID, response.Depth, err =
|
||||||
r.DB.LatestEventIDs(ctx, roomNID)
|
r.DB.LatestEventIDs(ctx, info.RoomNID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -105,11 +105,11 @@ func (r *RoomserverInternalAPI) QueryStateAfterEvents(
|
||||||
|
|
||||||
roomState := state.NewStateResolution(r.DB)
|
roomState := state.NewStateResolution(r.DB)
|
||||||
|
|
||||||
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
|
info, err := r.DB.RoomInfo(ctx, request.RoomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if roomNID == 0 {
|
if info.IsStub {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
response.RoomExists = true
|
response.RoomExists = true
|
||||||
|
@ -128,7 +128,7 @@ func (r *RoomserverInternalAPI) QueryStateAfterEvents(
|
||||||
|
|
||||||
// Look up the currrent state for the requested tuples.
|
// Look up the currrent state for the requested tuples.
|
||||||
stateEntries, err := roomState.LoadStateAfterEventsForStringTuples(
|
stateEntries, err := roomState.LoadStateAfterEventsForStringTuples(
|
||||||
ctx, roomNID, prevStates, request.StateToFetch,
|
ctx, info.RoomNID, prevStates, request.StateToFetch,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -210,12 +210,12 @@ func (r *RoomserverInternalAPI) QueryMembershipForUser(
|
||||||
request *api.QueryMembershipForUserRequest,
|
request *api.QueryMembershipForUserRequest,
|
||||||
response *api.QueryMembershipForUserResponse,
|
response *api.QueryMembershipForUserResponse,
|
||||||
) error {
|
) error {
|
||||||
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
info, err := r.DB.RoomInfo(ctx, request.RoomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
membershipEventNID, stillInRoom, err := r.DB.GetMembership(ctx, roomNID, request.UserID)
|
membershipEventNID, stillInRoom, err := r.DB.GetMembership(ctx, info.RoomNID, request.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -247,12 +247,12 @@ func (r *RoomserverInternalAPI) QueryMembershipsForRoom(
|
||||||
request *api.QueryMembershipsForRoomRequest,
|
request *api.QueryMembershipsForRoomRequest,
|
||||||
response *api.QueryMembershipsForRoomResponse,
|
response *api.QueryMembershipsForRoomResponse,
|
||||||
) error {
|
) error {
|
||||||
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
info, err := r.DB.RoomInfo(ctx, request.RoomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
membershipEventNID, stillInRoom, err := r.DB.GetMembership(ctx, roomNID, request.Sender)
|
membershipEventNID, stillInRoom, err := r.DB.GetMembership(ctx, info.RoomNID, request.Sender)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ func (r *RoomserverInternalAPI) QueryMembershipsForRoom(
|
||||||
var stateEntries []types.StateEntry
|
var stateEntries []types.StateEntry
|
||||||
if stillInRoom {
|
if stillInRoom {
|
||||||
var eventNIDs []types.EventNID
|
var eventNIDs []types.EventNID
|
||||||
eventNIDs, err = r.DB.GetMembershipEventNIDsForRoom(ctx, roomNID, request.JoinedOnly, false)
|
eventNIDs, err = r.DB.GetMembershipEventNIDsForRoom(ctx, info.RoomNID, request.JoinedOnly, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -555,12 +555,15 @@ func (r *RoomserverInternalAPI) backfillViaFederation(ctx context.Context, req *
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoomserverInternalAPI) isServerCurrentlyInRoom(ctx context.Context, serverName gomatrixserverlib.ServerName, roomID string) (bool, error) {
|
func (r *RoomserverInternalAPI) isServerCurrentlyInRoom(ctx context.Context, serverName gomatrixserverlib.ServerName, roomID string) (bool, error) {
|
||||||
roomNID, err := r.DB.RoomNID(ctx, roomID)
|
info, err := r.DB.RoomInfo(ctx, roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
if info == nil {
|
||||||
|
return false, fmt.Errorf("unknown room %s", roomID)
|
||||||
|
}
|
||||||
|
|
||||||
eventNIDs, err := r.DB.GetMembershipEventNIDsForRoom(ctx, roomNID, true, false)
|
eventNIDs, err := r.DB.GetMembershipEventNIDsForRoom(ctx, info.RoomNID, true, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -737,20 +740,15 @@ func (r *RoomserverInternalAPI) QueryStateAndAuthChain(
|
||||||
request *api.QueryStateAndAuthChainRequest,
|
request *api.QueryStateAndAuthChainRequest,
|
||||||
response *api.QueryStateAndAuthChainResponse,
|
response *api.QueryStateAndAuthChainResponse,
|
||||||
) error {
|
) error {
|
||||||
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
|
info, err := r.DB.RoomInfo(ctx, request.RoomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if roomNID == 0 {
|
if info.IsStub {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
response.RoomExists = true
|
response.RoomExists = true
|
||||||
|
response.RoomVersion = info.RoomVersion
|
||||||
roomVersion, err := r.DB.GetRoomVersionForRoom(ctx, request.RoomID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
response.RoomVersion = roomVersion
|
|
||||||
|
|
||||||
stateEvents, err := r.loadStateAtEventIDs(ctx, request.PrevEventIDs)
|
stateEvents, err := r.loadStateAtEventIDs(ctx, request.PrevEventIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -773,18 +771,18 @@ func (r *RoomserverInternalAPI) QueryStateAndAuthChain(
|
||||||
|
|
||||||
if request.ResolveState {
|
if request.ResolveState {
|
||||||
if stateEvents, err = state.ResolveConflictsAdhoc(
|
if stateEvents, err = state.ResolveConflictsAdhoc(
|
||||||
roomVersion, stateEvents, authEvents,
|
info.RoomVersion, stateEvents, authEvents,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, event := range stateEvents {
|
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 {
|
for _, event := range authEvents {
|
||||||
response.AuthChainEvents = append(response.AuthChainEvents, event.Headered(roomVersion))
|
response.AuthChainEvents = append(response.AuthChainEvents, event.Headered(info.RoomVersion))
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -26,6 +26,8 @@ import (
|
||||||
type Database interface {
|
type Database interface {
|
||||||
// Do we support processing input events for more than one room at a time?
|
// Do we support processing input events for more than one room at a time?
|
||||||
SupportsConcurrentRoomInputs() bool
|
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
|
// Store the room state at an event in the database
|
||||||
AddState(
|
AddState(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
@ -94,14 +96,6 @@ type Database interface {
|
||||||
// This is used to determine if the room event is processed/processing already.
|
// This is used to determine if the room event is processed/processing already.
|
||||||
// Returns an empty string if no such event exists.
|
// Returns an empty string if no such event exists.
|
||||||
GetTransactionEventID(ctx context.Context, transactionID string, sessionID int64, userID string) (string, error)
|
GetTransactionEventID(ctx context.Context, transactionID string, sessionID int64, userID string) (string, error)
|
||||||
// Look up the numeric ID for the room.
|
|
||||||
// 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.
|
// 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 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.
|
// Returns an error if there was a problem talking to the database.
|
||||||
|
|
|
@ -74,6 +74,9 @@ const selectRoomVersionForRoomIDSQL = "" +
|
||||||
const selectRoomVersionForRoomNIDSQL = "" +
|
const selectRoomVersionForRoomNIDSQL = "" +
|
||||||
"SELECT room_version FROM roomserver_rooms WHERE room_nid = $1"
|
"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 {
|
type roomStatements struct {
|
||||||
insertRoomNIDStmt *sql.Stmt
|
insertRoomNIDStmt *sql.Stmt
|
||||||
selectRoomNIDStmt *sql.Stmt
|
selectRoomNIDStmt *sql.Stmt
|
||||||
|
@ -82,6 +85,7 @@ type roomStatements struct {
|
||||||
updateLatestEventNIDsStmt *sql.Stmt
|
updateLatestEventNIDsStmt *sql.Stmt
|
||||||
selectRoomVersionForRoomIDStmt *sql.Stmt
|
selectRoomVersionForRoomIDStmt *sql.Stmt
|
||||||
selectRoomVersionForRoomNIDStmt *sql.Stmt
|
selectRoomVersionForRoomNIDStmt *sql.Stmt
|
||||||
|
selectRoomInfoStmt *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPostgresRoomsTable(db *sql.DB) (tables.Rooms, error) {
|
func NewPostgresRoomsTable(db *sql.DB) (tables.Rooms, error) {
|
||||||
|
@ -98,6 +102,7 @@ func NewPostgresRoomsTable(db *sql.DB) (tables.Rooms, error) {
|
||||||
{&s.updateLatestEventNIDsStmt, updateLatestEventNIDsSQL},
|
{&s.updateLatestEventNIDsStmt, updateLatestEventNIDsSQL},
|
||||||
{&s.selectRoomVersionForRoomIDStmt, selectRoomVersionForRoomIDSQL},
|
{&s.selectRoomVersionForRoomIDStmt, selectRoomVersionForRoomIDSQL},
|
||||||
{&s.selectRoomVersionForRoomNIDStmt, selectRoomVersionForRoomNIDSQL},
|
{&s.selectRoomVersionForRoomNIDStmt, selectRoomVersionForRoomNIDSQL},
|
||||||
|
{&s.selectRoomInfoStmt, selectRoomInfoSQL},
|
||||||
}.Prepare(db)
|
}.Prepare(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +116,19 @@ func (s *roomStatements) InsertRoomNID(
|
||||||
return types.RoomNID(roomNID), err
|
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(
|
func (s *roomStatements) SelectRoomNID(
|
||||||
ctx context.Context, txn *sql.Tx, roomID string,
|
ctx context.Context, txn *sql.Tx, roomID string,
|
||||||
) (types.RoomNID, error) {
|
) (types.RoomNID, error) {
|
||||||
|
|
|
@ -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(
|
func (d *Database) AddState(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
roomNID types.RoomNID,
|
roomNID types.RoomNID,
|
||||||
|
@ -194,34 +198,6 @@ func (d *Database) EventsFromIDs(ctx context.Context, eventIDs []string) ([]type
|
||||||
return d.Events(ctx, nids)
|
return d.Events(ctx, nids)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) RoomNID(ctx context.Context, roomID string) (types.RoomNID, error) {
|
|
||||||
if nid, ok := d.Cache.GetRoomServerRoomNID(roomID); ok {
|
|
||||||
return nid, nil
|
|
||||||
}
|
|
||||||
roomNID, err := d.RoomsTable.SelectRoomNID(ctx, nil, roomID)
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
d.Cache.StoreRoomServerRoomNID(roomID, roomNID)
|
|
||||||
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(
|
func (d *Database) LatestEventIDs(
|
||||||
ctx context.Context, roomNID types.RoomNID,
|
ctx context.Context, roomNID types.RoomNID,
|
||||||
) (references []gomatrixserverlib.EventReference, currentStateSnapshotNID types.StateSnapshotNID, depth int64, err error) {
|
) (references []gomatrixserverlib.EventReference, currentStateSnapshotNID types.StateSnapshotNID, depth int64, err error) {
|
||||||
|
|
|
@ -64,6 +64,9 @@ const selectRoomVersionForRoomIDSQL = "" +
|
||||||
const selectRoomVersionForRoomNIDSQL = "" +
|
const selectRoomVersionForRoomNIDSQL = "" +
|
||||||
"SELECT room_version FROM roomserver_rooms WHERE room_nid = $1"
|
"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 {
|
type roomStatements struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
insertRoomNIDStmt *sql.Stmt
|
insertRoomNIDStmt *sql.Stmt
|
||||||
|
@ -73,6 +76,7 @@ type roomStatements struct {
|
||||||
updateLatestEventNIDsStmt *sql.Stmt
|
updateLatestEventNIDsStmt *sql.Stmt
|
||||||
selectRoomVersionForRoomIDStmt *sql.Stmt
|
selectRoomVersionForRoomIDStmt *sql.Stmt
|
||||||
selectRoomVersionForRoomNIDStmt *sql.Stmt
|
selectRoomVersionForRoomNIDStmt *sql.Stmt
|
||||||
|
selectRoomInfoStmt *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSqliteRoomsTable(db *sql.DB) (tables.Rooms, error) {
|
func NewSqliteRoomsTable(db *sql.DB) (tables.Rooms, error) {
|
||||||
|
@ -91,9 +95,30 @@ func NewSqliteRoomsTable(db *sql.DB) (tables.Rooms, error) {
|
||||||
{&s.updateLatestEventNIDsStmt, updateLatestEventNIDsSQL},
|
{&s.updateLatestEventNIDsStmt, updateLatestEventNIDsSQL},
|
||||||
{&s.selectRoomVersionForRoomIDStmt, selectRoomVersionForRoomIDSQL},
|
{&s.selectRoomVersionForRoomIDStmt, selectRoomVersionForRoomIDSQL},
|
||||||
{&s.selectRoomVersionForRoomNIDStmt, selectRoomVersionForRoomNIDSQL},
|
{&s.selectRoomVersionForRoomNIDStmt, selectRoomVersionForRoomNIDSQL},
|
||||||
|
{&s.selectRoomInfoStmt, selectRoomInfoSQL},
|
||||||
}.Prepare(db)
|
}.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(
|
func (s *roomStatements) InsertRoomNID(
|
||||||
ctx context.Context, txn *sql.Tx,
|
ctx context.Context, txn *sql.Tx,
|
||||||
roomID string, roomVersion gomatrixserverlib.RoomVersion,
|
roomID string, roomVersion gomatrixserverlib.RoomVersion,
|
||||||
|
|
|
@ -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
|
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)
|
SelectRoomVersionForRoomID(ctx context.Context, txn *sql.Tx, roomID string) (gomatrixserverlib.RoomVersion, error)
|
||||||
SelectRoomVersionForRoomNID(ctx context.Context, roomNID types.RoomNID) (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 {
|
type Transactions interface {
|
||||||
|
|
|
@ -144,3 +144,11 @@ type StateEntryList struct {
|
||||||
type MissingEventError string
|
type MissingEventError string
|
||||||
|
|
||||||
func (e MissingEventError) Error() string { return string(e) }
|
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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue