mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-07-29 12:42:46 +00:00
Refactor StoreEvent
, add MaybeRedactEvent
, create an EventDatabase
(#2989)
This PR changes the following: - `StoreEvent` now only stores an event (and possibly prev event), instead of also doing redactions - Adds a `MaybeRedactEvent` (pulled out from `StoreEvent`), which should be called after storing events - a few other things
This commit is contained in:
parent
1aa70b0f56
commit
6c20f8f742
34 changed files with 488 additions and 420 deletions
|
@ -29,6 +29,7 @@ type Database interface {
|
|||
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)
|
||||
RoomInfoByNID(ctx context.Context, roomNID types.RoomNID) (*types.RoomInfo, error)
|
||||
// Store the room state at an event in the database
|
||||
AddState(
|
||||
ctx context.Context,
|
||||
|
@ -69,12 +70,12 @@ type Database interface {
|
|||
) ([]types.StateEntryList, error)
|
||||
// Look up the Events for a list of numeric event IDs.
|
||||
// Returns a sorted list of events.
|
||||
Events(ctx context.Context, roomNID types.RoomNID, eventNIDs []types.EventNID) ([]types.Event, error)
|
||||
Events(ctx context.Context, roomInfo *types.RoomInfo, eventNIDs []types.EventNID) ([]types.Event, error)
|
||||
// Look up snapshot NID for an event ID string
|
||||
SnapshotNIDFromEventID(ctx context.Context, eventID string) (types.StateSnapshotNID, error)
|
||||
BulkSelectSnapshotsFromEventIDs(ctx context.Context, eventIDs []string) (map[types.StateSnapshotNID][]string, error)
|
||||
// Stores a matrix room event in the database. Returns the room NID, the state snapshot and the redacted event ID if any, or an error.
|
||||
StoreEvent(ctx context.Context, event *gomatrixserverlib.Event, roomNID types.RoomNID, eventTypeNID types.EventTypeNID, eventStateKeyNID types.EventStateKeyNID, authEventNIDs []types.EventNID, isRejected bool) (types.EventNID, types.StateAtEvent, *gomatrixserverlib.Event, string, error)
|
||||
// Stores a matrix room event in the database. Returns the room NID, the state snapshot or an error.
|
||||
StoreEvent(ctx context.Context, event *gomatrixserverlib.Event, roomInfo *types.RoomInfo, eventTypeNID types.EventTypeNID, eventStateKeyNID types.EventStateKeyNID, authEventNIDs []types.EventNID, isRejected bool) (types.EventNID, types.StateAtEvent, error)
|
||||
// Look up the state entries for a list of string event IDs
|
||||
// Returns an error if the there is an error talking to the database
|
||||
// Returns a types.MissingEventError if the event IDs aren't in the database.
|
||||
|
@ -135,7 +136,7 @@ type Database interface {
|
|||
// EventsFromIDs looks up the Events for a list of event IDs. Does not error if event was
|
||||
// not found.
|
||||
// Returns an error if the retrieval went wrong.
|
||||
EventsFromIDs(ctx context.Context, roomNID types.RoomNID, eventIDs []string) ([]types.Event, error)
|
||||
EventsFromIDs(ctx context.Context, roomInfo *types.RoomInfo, eventIDs []string) ([]types.Event, error)
|
||||
// Publish or unpublish a room from the room directory.
|
||||
PublishRoom(ctx context.Context, roomID, appserviceID, networkID string, publish bool) error
|
||||
// Returns a list of room IDs for rooms which are published.
|
||||
|
@ -179,36 +180,53 @@ type Database interface {
|
|||
GetMembershipForHistoryVisibility(
|
||||
ctx context.Context, userNID types.EventStateKeyNID, info *types.RoomInfo, eventIDs ...string,
|
||||
) (map[string]*gomatrixserverlib.HeaderedEvent, error)
|
||||
GetOrCreateRoomNID(ctx context.Context, event *gomatrixserverlib.Event) (types.RoomNID, error)
|
||||
GetOrCreateRoomInfo(ctx context.Context, event *gomatrixserverlib.Event) (*types.RoomInfo, error)
|
||||
GetOrCreateEventTypeNID(ctx context.Context, eventType string) (eventTypeNID types.EventTypeNID, err error)
|
||||
GetOrCreateEventStateKeyNID(ctx context.Context, eventStateKey *string) (types.EventStateKeyNID, error)
|
||||
MaybeRedactEvent(
|
||||
ctx context.Context, roomInfo *types.RoomInfo, eventNID types.EventNID, event *gomatrixserverlib.Event, redactAllowed bool,
|
||||
) (*gomatrixserverlib.Event, *gomatrixserverlib.Event, error)
|
||||
}
|
||||
|
||||
type RoomDatabase interface {
|
||||
EventDatabase
|
||||
// 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)
|
||||
RoomInfoByNID(ctx context.Context, roomNID types.RoomNID) (*types.RoomInfo, error)
|
||||
// IsEventRejected returns true if the event is known and rejected.
|
||||
IsEventRejected(ctx context.Context, roomNID types.RoomNID, eventID string) (rejected bool, err error)
|
||||
MissingAuthPrevEvents(ctx context.Context, e *gomatrixserverlib.Event) (missingAuth, missingPrev []string, err error)
|
||||
// Stores a matrix room event in the database. Returns the room NID, the state snapshot and the redacted event ID if any, or an error.
|
||||
StoreEvent(ctx context.Context, event *gomatrixserverlib.Event, roomNID types.RoomNID, eventTypeNID types.EventTypeNID, eventStateKeyNID types.EventStateKeyNID, authEventNIDs []types.EventNID, isRejected bool) (types.EventNID, types.StateAtEvent, *gomatrixserverlib.Event, string, error)
|
||||
UpgradeRoom(ctx context.Context, oldRoomID, newRoomID, eventSender string) error
|
||||
GetRoomUpdater(ctx context.Context, roomInfo *types.RoomInfo) (*shared.RoomUpdater, error)
|
||||
StateEntriesForEventIDs(ctx context.Context, eventIDs []string, excludeRejected bool) ([]types.StateEntry, error)
|
||||
GetMembershipEventNIDsForRoom(ctx context.Context, roomNID types.RoomNID, joinOnly bool, localOnly bool) ([]types.EventNID, error)
|
||||
StateBlockNIDs(ctx context.Context, stateNIDs []types.StateSnapshotNID) ([]types.StateBlockNIDList, error)
|
||||
StateEntries(ctx context.Context, stateBlockNIDs []types.StateBlockNID) ([]types.StateEntryList, error)
|
||||
SnapshotNIDFromEventID(ctx context.Context, eventID string) (types.StateSnapshotNID, error)
|
||||
BulkSelectSnapshotsFromEventIDs(ctx context.Context, eventIDs []string) (map[types.StateSnapshotNID][]string, error)
|
||||
StateEntriesForTuples(ctx context.Context, stateBlockNIDs []types.StateBlockNID, stateKeyTuples []types.StateKeyTuple) ([]types.StateEntryList, error)
|
||||
StateAtEventIDs(ctx context.Context, eventIDs []string) ([]types.StateAtEvent, error)
|
||||
AddState(ctx context.Context, roomNID types.RoomNID, stateBlockNIDs []types.StateBlockNID, state []types.StateEntry) (types.StateSnapshotNID, error)
|
||||
Events(ctx context.Context, roomNID types.RoomNID, eventNIDs []types.EventNID) ([]types.Event, error)
|
||||
EventsFromIDs(ctx context.Context, roomNID types.RoomNID, eventIDs []string) ([]types.Event, error)
|
||||
LatestEventIDs(ctx context.Context, roomNID types.RoomNID) ([]gomatrixserverlib.EventReference, types.StateSnapshotNID, int64, error)
|
||||
EventTypeNIDs(ctx context.Context, eventTypes []string) (map[string]types.EventTypeNID, error)
|
||||
EventStateKeyNIDs(ctx context.Context, eventStateKeys []string) (map[string]types.EventStateKeyNID, error)
|
||||
GetOrCreateRoomNID(ctx context.Context, event *gomatrixserverlib.Event) (types.RoomNID, error)
|
||||
GetOrCreateRoomInfo(ctx context.Context, event *gomatrixserverlib.Event) (*types.RoomInfo, error)
|
||||
GetOrCreateEventTypeNID(ctx context.Context, eventType string) (eventTypeNID types.EventTypeNID, err error)
|
||||
GetOrCreateEventStateKeyNID(ctx context.Context, eventStateKey *string) (types.EventStateKeyNID, error)
|
||||
GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*gomatrixserverlib.HeaderedEvent, error)
|
||||
}
|
||||
|
||||
type EventDatabase interface {
|
||||
EventTypeNIDs(ctx context.Context, eventTypes []string) (map[string]types.EventTypeNID, error)
|
||||
EventStateKeys(ctx context.Context, eventStateKeyNIDs []types.EventStateKeyNID) (map[types.EventStateKeyNID]string, error)
|
||||
EventStateKeyNIDs(ctx context.Context, eventStateKeys []string) (map[string]types.EventStateKeyNID, error)
|
||||
StateEntriesForEventIDs(ctx context.Context, eventIDs []string, excludeRejected bool) ([]types.StateEntry, error)
|
||||
EventNIDs(ctx context.Context, eventIDs []string) (map[string]types.EventMetadata, error)
|
||||
SetState(ctx context.Context, eventNID types.EventNID, stateNID types.StateSnapshotNID) error
|
||||
StateAtEventIDs(ctx context.Context, eventIDs []string) ([]types.StateAtEvent, error)
|
||||
SnapshotNIDFromEventID(ctx context.Context, eventID string) (types.StateSnapshotNID, error)
|
||||
EventIDs(ctx context.Context, eventNIDs []types.EventNID) (map[types.EventNID]string, error)
|
||||
EventsFromIDs(ctx context.Context, roomInfo *types.RoomInfo, eventIDs []string) ([]types.Event, error)
|
||||
Events(ctx context.Context, roomInfo *types.RoomInfo, eventNIDs []types.EventNID) ([]types.Event, error)
|
||||
// MaybeRedactEvent returns the redaction event and the redacted event if this call resulted in a redaction, else an error
|
||||
// (nil if there was nothing to do)
|
||||
MaybeRedactEvent(
|
||||
ctx context.Context, roomInfo *types.RoomInfo, eventNID types.EventNID, event *gomatrixserverlib.Event, redactAllowed bool,
|
||||
) (*gomatrixserverlib.Event, *gomatrixserverlib.Event, error)
|
||||
StoreEvent(ctx context.Context, event *gomatrixserverlib.Event, roomInfo *types.RoomInfo, eventTypeNID types.EventTypeNID, eventStateKeyNID types.EventStateKeyNID, authEventNIDs []types.EventNID, isRejected bool) (types.EventNID, types.StateAtEvent, error)
|
||||
}
|
||||
|
|
|
@ -194,23 +194,28 @@ func (d *Database) prepare(db *sql.DB, writer sqlutil.Writer, cache caching.Room
|
|||
return err
|
||||
}
|
||||
d.Database = shared.Database{
|
||||
DB: db,
|
||||
Cache: cache,
|
||||
Writer: writer,
|
||||
EventTypesTable: eventTypes,
|
||||
EventStateKeysTable: eventStateKeys,
|
||||
EventJSONTable: eventJSON,
|
||||
EventsTable: events,
|
||||
RoomsTable: rooms,
|
||||
StateBlockTable: stateBlock,
|
||||
StateSnapshotTable: stateSnapshot,
|
||||
PrevEventsTable: prevEvents,
|
||||
RoomAliasesTable: roomAliases,
|
||||
InvitesTable: invites,
|
||||
MembershipTable: membership,
|
||||
PublishedTable: published,
|
||||
RedactionsTable: redactions,
|
||||
Purge: purge,
|
||||
DB: db,
|
||||
EventDatabase: shared.EventDatabase{
|
||||
DB: db,
|
||||
Cache: cache,
|
||||
Writer: writer,
|
||||
EventsTable: events,
|
||||
EventJSONTable: eventJSON,
|
||||
EventTypesTable: eventTypes,
|
||||
EventStateKeysTable: eventStateKeys,
|
||||
PrevEventsTable: prevEvents,
|
||||
RedactionsTable: redactions,
|
||||
},
|
||||
Cache: cache,
|
||||
Writer: writer,
|
||||
RoomsTable: rooms,
|
||||
StateBlockTable: stateBlock,
|
||||
StateSnapshotTable: stateSnapshot,
|
||||
RoomAliasesTable: roomAliases,
|
||||
InvitesTable: invites,
|
||||
MembershipTable: membership,
|
||||
PublishedTable: published,
|
||||
Purge: purge,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -116,8 +116,8 @@ func (u *RoomUpdater) StorePreviousEvents(eventNID types.EventNID, previousEvent
|
|||
})
|
||||
}
|
||||
|
||||
func (u *RoomUpdater) Events(ctx context.Context, _ types.RoomNID, eventNIDs []types.EventNID) ([]types.Event, error) {
|
||||
return u.d.events(ctx, u.txn, u.roomInfo.RoomNID, eventNIDs)
|
||||
func (u *RoomUpdater) Events(ctx context.Context, _ *types.RoomInfo, eventNIDs []types.EventNID) ([]types.Event, error) {
|
||||
return u.d.events(ctx, u.txn, u.roomInfo, eventNIDs)
|
||||
}
|
||||
|
||||
func (u *RoomUpdater) SnapshotNIDFromEventID(
|
||||
|
@ -195,8 +195,8 @@ func (u *RoomUpdater) StateAtEventIDs(
|
|||
return u.d.EventsTable.BulkSelectStateAtEventByID(ctx, u.txn, eventIDs)
|
||||
}
|
||||
|
||||
func (u *RoomUpdater) EventsFromIDs(ctx context.Context, roomNID types.RoomNID, eventIDs []string) ([]types.Event, error) {
|
||||
return u.d.eventsFromIDs(ctx, u.txn, roomNID, eventIDs, NoFilter)
|
||||
func (u *RoomUpdater) EventsFromIDs(ctx context.Context, roomInfo *types.RoomInfo, eventIDs []string) ([]types.Event, error) {
|
||||
return u.d.eventsFromIDs(ctx, u.txn, u.roomInfo, eventIDs, NoFilter)
|
||||
}
|
||||
|
||||
// IsReferenced implements types.RoomRecentEventsUpdater
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/matrix-org/dendrite/internal/caching"
|
||||
|
@ -28,6 +27,23 @@ import (
|
|||
const redactionsArePermanent = true
|
||||
|
||||
type Database struct {
|
||||
DB *sql.DB
|
||||
EventDatabase
|
||||
Cache caching.RoomServerCaches
|
||||
Writer sqlutil.Writer
|
||||
RoomsTable tables.Rooms
|
||||
StateSnapshotTable tables.StateSnapshot
|
||||
StateBlockTable tables.StateBlock
|
||||
RoomAliasesTable tables.RoomAliases
|
||||
InvitesTable tables.Invites
|
||||
MembershipTable tables.Membership
|
||||
PublishedTable tables.Published
|
||||
Purge tables.Purge
|
||||
GetRoomUpdaterFn func(ctx context.Context, roomInfo *types.RoomInfo) (*RoomUpdater, error)
|
||||
}
|
||||
|
||||
// EventDatabase contains all tables needed to work with events
|
||||
type EventDatabase struct {
|
||||
DB *sql.DB
|
||||
Cache caching.RoomServerCaches
|
||||
Writer sqlutil.Writer
|
||||
|
@ -35,17 +51,8 @@ type Database struct {
|
|||
EventJSONTable tables.EventJSON
|
||||
EventTypesTable tables.EventTypes
|
||||
EventStateKeysTable tables.EventStateKeys
|
||||
RoomsTable tables.Rooms
|
||||
StateSnapshotTable tables.StateSnapshot
|
||||
StateBlockTable tables.StateBlock
|
||||
RoomAliasesTable tables.RoomAliases
|
||||
PrevEventsTable tables.PreviousEvents
|
||||
InvitesTable tables.Invites
|
||||
MembershipTable tables.Membership
|
||||
PublishedTable tables.Published
|
||||
RedactionsTable tables.Redactions
|
||||
Purge tables.Purge
|
||||
GetRoomUpdaterFn func(ctx context.Context, roomInfo *types.RoomInfo) (*RoomUpdater, error)
|
||||
}
|
||||
|
||||
func (d *Database) SupportsConcurrentRoomInputs() bool {
|
||||
|
@ -58,13 +65,13 @@ func (d *Database) GetMembershipForHistoryVisibility(
|
|||
return d.StateSnapshotTable.BulkSelectMembershipForHistoryVisibility(ctx, nil, userNID, roomInfo, eventIDs...)
|
||||
}
|
||||
|
||||
func (d *Database) EventTypeNIDs(
|
||||
func (d *EventDatabase) EventTypeNIDs(
|
||||
ctx context.Context, eventTypes []string,
|
||||
) (map[string]types.EventTypeNID, error) {
|
||||
return d.eventTypeNIDs(ctx, nil, eventTypes)
|
||||
}
|
||||
|
||||
func (d *Database) eventTypeNIDs(
|
||||
func (d *EventDatabase) eventTypeNIDs(
|
||||
ctx context.Context, txn *sql.Tx, eventTypes []string,
|
||||
) (map[string]types.EventTypeNID, error) {
|
||||
result := make(map[string]types.EventTypeNID)
|
||||
|
@ -91,7 +98,7 @@ func (d *Database) eventTypeNIDs(
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func (d *Database) EventStateKeys(
|
||||
func (d *EventDatabase) EventStateKeys(
|
||||
ctx context.Context, eventStateKeyNIDs []types.EventStateKeyNID,
|
||||
) (map[types.EventStateKeyNID]string, error) {
|
||||
result := make(map[types.EventStateKeyNID]string, len(eventStateKeyNIDs))
|
||||
|
@ -116,13 +123,13 @@ func (d *Database) EventStateKeys(
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func (d *Database) EventStateKeyNIDs(
|
||||
func (d *EventDatabase) EventStateKeyNIDs(
|
||||
ctx context.Context, eventStateKeys []string,
|
||||
) (map[string]types.EventStateKeyNID, error) {
|
||||
return d.eventStateKeyNIDs(ctx, nil, eventStateKeys)
|
||||
}
|
||||
|
||||
func (d *Database) eventStateKeyNIDs(
|
||||
func (d *EventDatabase) eventStateKeyNIDs(
|
||||
ctx context.Context, txn *sql.Tx, eventStateKeys []string,
|
||||
) (map[string]types.EventStateKeyNID, error) {
|
||||
result := make(map[string]types.EventStateKeyNID)
|
||||
|
@ -174,7 +181,7 @@ func (d *Database) eventStateKeyNIDs(
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func (d *Database) StateEntriesForEventIDs(
|
||||
func (d *EventDatabase) StateEntriesForEventIDs(
|
||||
ctx context.Context, eventIDs []string, excludeRejected bool,
|
||||
) ([]types.StateEntry, error) {
|
||||
return d.EventsTable.BulkSelectStateEventByID(ctx, nil, eventIDs, excludeRejected)
|
||||
|
@ -213,6 +220,17 @@ func (d *Database) stateEntriesForTuples(
|
|||
return lists, nil
|
||||
}
|
||||
|
||||
func (d *Database) RoomInfoByNID(ctx context.Context, roomNID types.RoomNID) (*types.RoomInfo, error) {
|
||||
roomIDs, err := d.RoomsTable.BulkSelectRoomIDs(ctx, nil, []types.RoomNID{roomNID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(roomIDs) == 0 {
|
||||
return nil, fmt.Errorf("room does not exist")
|
||||
}
|
||||
return d.roomInfo(ctx, nil, roomIDs[0])
|
||||
}
|
||||
|
||||
func (d *Database) RoomInfo(ctx context.Context, roomID string) (*types.RoomInfo, error) {
|
||||
return d.roomInfo(ctx, nil, roomID)
|
||||
}
|
||||
|
@ -292,7 +310,7 @@ func (d *Database) addState(
|
|||
return
|
||||
}
|
||||
|
||||
func (d *Database) EventNIDs(
|
||||
func (d *EventDatabase) EventNIDs(
|
||||
ctx context.Context, eventIDs []string,
|
||||
) (map[string]types.EventMetadata, error) {
|
||||
return d.eventNIDs(ctx, nil, eventIDs, NoFilter)
|
||||
|
@ -305,7 +323,7 @@ const (
|
|||
FilterUnsentOnly UnsentFilter = true
|
||||
)
|
||||
|
||||
func (d *Database) eventNIDs(
|
||||
func (d *EventDatabase) eventNIDs(
|
||||
ctx context.Context, txn *sql.Tx, eventIDs []string, filter UnsentFilter,
|
||||
) (map[string]types.EventMetadata, error) {
|
||||
switch filter {
|
||||
|
@ -318,7 +336,7 @@ func (d *Database) eventNIDs(
|
|||
}
|
||||
}
|
||||
|
||||
func (d *Database) SetState(
|
||||
func (d *EventDatabase) SetState(
|
||||
ctx context.Context, eventNID types.EventNID, stateNID types.StateSnapshotNID,
|
||||
) error {
|
||||
return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
||||
|
@ -326,19 +344,19 @@ func (d *Database) SetState(
|
|||
})
|
||||
}
|
||||
|
||||
func (d *Database) StateAtEventIDs(
|
||||
func (d *EventDatabase) StateAtEventIDs(
|
||||
ctx context.Context, eventIDs []string,
|
||||
) ([]types.StateAtEvent, error) {
|
||||
return d.EventsTable.BulkSelectStateAtEventByID(ctx, nil, eventIDs)
|
||||
}
|
||||
|
||||
func (d *Database) SnapshotNIDFromEventID(
|
||||
func (d *EventDatabase) SnapshotNIDFromEventID(
|
||||
ctx context.Context, eventID string,
|
||||
) (types.StateSnapshotNID, error) {
|
||||
return d.snapshotNIDFromEventID(ctx, nil, eventID)
|
||||
}
|
||||
|
||||
func (d *Database) snapshotNIDFromEventID(
|
||||
func (d *EventDatabase) snapshotNIDFromEventID(
|
||||
ctx context.Context, txn *sql.Tx, eventID string,
|
||||
) (types.StateSnapshotNID, error) {
|
||||
_, stateNID, err := d.EventsTable.SelectEvent(ctx, txn, eventID)
|
||||
|
@ -351,17 +369,17 @@ func (d *Database) snapshotNIDFromEventID(
|
|||
return stateNID, err
|
||||
}
|
||||
|
||||
func (d *Database) EventIDs(
|
||||
func (d *EventDatabase) EventIDs(
|
||||
ctx context.Context, eventNIDs []types.EventNID,
|
||||
) (map[types.EventNID]string, error) {
|
||||
return d.EventsTable.BulkSelectEventID(ctx, nil, eventNIDs)
|
||||
}
|
||||
|
||||
func (d *Database) EventsFromIDs(ctx context.Context, roomNID types.RoomNID, eventIDs []string) ([]types.Event, error) {
|
||||
return d.eventsFromIDs(ctx, nil, roomNID, eventIDs, NoFilter)
|
||||
func (d *EventDatabase) EventsFromIDs(ctx context.Context, roomInfo *types.RoomInfo, eventIDs []string) ([]types.Event, error) {
|
||||
return d.eventsFromIDs(ctx, nil, roomInfo, eventIDs, NoFilter)
|
||||
}
|
||||
|
||||
func (d *Database) eventsFromIDs(ctx context.Context, txn *sql.Tx, roomNID types.RoomNID, eventIDs []string, filter UnsentFilter) ([]types.Event, error) {
|
||||
func (d *EventDatabase) eventsFromIDs(ctx context.Context, txn *sql.Tx, roomInfo *types.RoomInfo, eventIDs []string, filter UnsentFilter) ([]types.Event, error) {
|
||||
nidMap, err := d.eventNIDs(ctx, txn, eventIDs, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -370,15 +388,9 @@ func (d *Database) eventsFromIDs(ctx context.Context, txn *sql.Tx, roomNID types
|
|||
var nids []types.EventNID
|
||||
for _, nid := range nidMap {
|
||||
nids = append(nids, nid.EventNID)
|
||||
if roomNID != 0 && roomNID != nid.RoomNID {
|
||||
logrus.Errorf("expected events from room %d, but also found %d", roomNID, nid.RoomNID)
|
||||
}
|
||||
if roomNID == 0 {
|
||||
roomNID = nid.RoomNID
|
||||
}
|
||||
}
|
||||
|
||||
return d.events(ctx, txn, roomNID, nids)
|
||||
return d.events(ctx, txn, roomInfo, nids)
|
||||
}
|
||||
|
||||
func (d *Database) LatestEventIDs(
|
||||
|
@ -517,19 +529,17 @@ func (d *Database) GetInvitesForUser(
|
|||
return d.InvitesTable.SelectInviteActiveForUserInRoom(ctx, nil, targetUserNID, roomNID)
|
||||
}
|
||||
|
||||
func (d *Database) Events(
|
||||
ctx context.Context, roomNID types.RoomNID, eventNIDs []types.EventNID,
|
||||
) ([]types.Event, error) {
|
||||
return d.events(ctx, nil, roomNID, eventNIDs)
|
||||
func (d *EventDatabase) Events(ctx context.Context, roomInfo *types.RoomInfo, eventNIDs []types.EventNID) ([]types.Event, error) {
|
||||
return d.events(ctx, nil, roomInfo, eventNIDs)
|
||||
}
|
||||
|
||||
func (d *Database) events(
|
||||
ctx context.Context, txn *sql.Tx, roomNID types.RoomNID, inputEventNIDs types.EventNIDs,
|
||||
func (d *EventDatabase) events(
|
||||
ctx context.Context, txn *sql.Tx, roomInfo *types.RoomInfo, inputEventNIDs types.EventNIDs,
|
||||
) ([]types.Event, error) {
|
||||
if roomNID == 0 {
|
||||
// No need to go further, as we won't find any events for this room.
|
||||
return nil, nil
|
||||
if roomInfo == nil { // this should never happen
|
||||
return nil, fmt.Errorf("unable to parse events without roomInfo")
|
||||
}
|
||||
|
||||
sort.Sort(inputEventNIDs)
|
||||
events := make(map[types.EventNID]*gomatrixserverlib.Event, len(inputEventNIDs))
|
||||
eventNIDs := make([]types.EventNID, 0, len(inputEventNIDs))
|
||||
|
@ -566,31 +576,9 @@ func (d *Database) events(
|
|||
eventIDs = map[types.EventNID]string{}
|
||||
}
|
||||
|
||||
var roomVersion gomatrixserverlib.RoomVersion
|
||||
var fetchRoomVersion bool
|
||||
var ok bool
|
||||
var roomID string
|
||||
if roomID, ok = d.Cache.GetRoomServerRoomID(roomNID); ok {
|
||||
roomVersion, ok = d.Cache.GetRoomVersion(roomID)
|
||||
if !ok {
|
||||
fetchRoomVersion = true
|
||||
}
|
||||
}
|
||||
|
||||
if roomVersion == "" || fetchRoomVersion {
|
||||
var dbRoomVersions map[types.RoomNID]gomatrixserverlib.RoomVersion
|
||||
dbRoomVersions, err = d.RoomsTable.SelectRoomVersionsForRoomNIDs(ctx, txn, []types.RoomNID{roomNID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if roomVersion, ok = dbRoomVersions[roomNID]; !ok {
|
||||
return nil, fmt.Errorf("unable to find roomversion for room %d", roomNID)
|
||||
}
|
||||
}
|
||||
|
||||
for _, eventJSON := range eventJSONs {
|
||||
events[eventJSON.EventNID], err = gomatrixserverlib.NewEventFromTrustedJSONWithEventID(
|
||||
eventIDs[eventJSON.EventNID], eventJSON.EventJSON, false, roomVersion,
|
||||
eventIDs[eventJSON.EventNID], eventJSON.EventJSON, false, roomInfo.RoomVersion,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -660,8 +648,8 @@ func (d *Database) IsEventRejected(ctx context.Context, roomNID types.RoomNID, e
|
|||
return d.EventsTable.SelectEventRejected(ctx, nil, roomNID, eventID)
|
||||
}
|
||||
|
||||
// GetOrCreateRoomNID gets or creates a new roomNID for the given event
|
||||
func (d *Database) GetOrCreateRoomNID(ctx context.Context, event *gomatrixserverlib.Event) (roomNID types.RoomNID, err error) {
|
||||
// GetOrCreateRoomInfo gets or creates a new RoomInfo, which is only safe to use with functions only needing a roomVersion or roomNID.
|
||||
func (d *Database) GetOrCreateRoomInfo(ctx context.Context, event *gomatrixserverlib.Event) (roomInfo *types.RoomInfo, err error) {
|
||||
// Get the default room version. If the client doesn't supply a room_version
|
||||
// then we will use our configured default to create the room.
|
||||
// https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-createroom
|
||||
|
@ -670,8 +658,9 @@ func (d *Database) GetOrCreateRoomNID(ctx context.Context, event *gomatrixserver
|
|||
// room.
|
||||
var roomVersion gomatrixserverlib.RoomVersion
|
||||
if roomVersion, err = extractRoomVersionFromCreateEvent(event); err != nil {
|
||||
return 0, fmt.Errorf("extractRoomVersionFromCreateEvent: %w", err)
|
||||
return nil, fmt.Errorf("extractRoomVersionFromCreateEvent: %w", err)
|
||||
}
|
||||
var roomNID types.RoomNID
|
||||
err = d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
||||
roomNID, err = d.assignRoomNID(ctx, txn, event.RoomID(), roomVersion)
|
||||
if err != nil {
|
||||
|
@ -679,7 +668,10 @@ func (d *Database) GetOrCreateRoomNID(ctx context.Context, event *gomatrixserver
|
|||
}
|
||||
return nil
|
||||
})
|
||||
return roomNID, err
|
||||
return &types.RoomInfo{
|
||||
RoomVersion: roomVersion,
|
||||
RoomNID: roomNID,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (d *Database) GetOrCreateEventTypeNID(ctx context.Context, eventType string) (eventTypeNID types.EventTypeNID, err error) {
|
||||
|
@ -710,25 +702,22 @@ func (d *Database) GetOrCreateEventStateKeyNID(ctx context.Context, eventStateKe
|
|||
return eventStateKeyNID, nil
|
||||
}
|
||||
|
||||
func (d *Database) StoreEvent(
|
||||
func (d *EventDatabase) StoreEvent(
|
||||
ctx context.Context, event *gomatrixserverlib.Event,
|
||||
roomNID types.RoomNID, eventTypeNID types.EventTypeNID, eventStateKeyNID types.EventStateKeyNID,
|
||||
roomInfo *types.RoomInfo, eventTypeNID types.EventTypeNID, eventStateKeyNID types.EventStateKeyNID,
|
||||
authEventNIDs []types.EventNID, isRejected bool,
|
||||
) (types.EventNID, types.StateAtEvent, *gomatrixserverlib.Event, string, error) {
|
||||
) (types.EventNID, types.StateAtEvent, error) {
|
||||
var (
|
||||
eventNID types.EventNID
|
||||
stateNID types.StateSnapshotNID
|
||||
redactionEvent *gomatrixserverlib.Event
|
||||
redactedEventID string
|
||||
err error
|
||||
eventNID types.EventNID
|
||||
stateNID types.StateSnapshotNID
|
||||
err error
|
||||
)
|
||||
// Second writer is using the database-provided transaction, probably from the
|
||||
// room updater, for easy roll-back if required.
|
||||
|
||||
err = d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
||||
if eventNID, stateNID, err = d.EventsTable.InsertEvent(
|
||||
ctx,
|
||||
txn,
|
||||
roomNID,
|
||||
roomInfo.RoomNID,
|
||||
eventTypeNID,
|
||||
eventStateKeyNID,
|
||||
event.EventID(),
|
||||
|
@ -751,16 +740,26 @@ func (d *Database) StoreEvent(
|
|||
if err = d.EventJSONTable.InsertEventJSON(ctx, txn, eventNID, event.JSON()); err != nil {
|
||||
return fmt.Errorf("d.EventJSONTable.InsertEventJSON: %w", err)
|
||||
}
|
||||
if !isRejected { // ignore rejected redaction events
|
||||
redactionEvent, redactedEventID, err = d.handleRedactions(ctx, txn, roomNID, eventNID, event)
|
||||
if err != nil {
|
||||
return fmt.Errorf("d.handleRedactions: %w", err)
|
||||
|
||||
if prevEvents := event.PrevEvents(); len(prevEvents) > 0 {
|
||||
// Create an updater - NB: on sqlite this WILL create a txn as we are directly calling the shared DB form of
|
||||
// GetLatestEventsForUpdate - not via the SQLiteDatabase form which has `nil` txns. This
|
||||
// function only does SELECTs though so the created txn (at this point) is just a read txn like
|
||||
// any other so this is fine. If we ever update GetLatestEventsForUpdate or NewLatestEventsUpdater
|
||||
// to do writes however then this will need to go inside `Writer.Do`.
|
||||
|
||||
// The following is a copy of RoomUpdater.StorePreviousEvents
|
||||
for _, ref := range prevEvents {
|
||||
if err = d.PrevEventsTable.InsertPreviousEvent(ctx, txn, ref.EventID, ref.EventSHA256, eventNID); err != nil {
|
||||
return fmt.Errorf("u.d.PrevEventsTable.InsertPreviousEvent: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return 0, types.StateAtEvent{}, nil, "", fmt.Errorf("d.Writer.Do: %w", err)
|
||||
return 0, types.StateAtEvent{}, fmt.Errorf("d.Writer.Do: %w", err)
|
||||
}
|
||||
|
||||
// We should attempt to update the previous events table with any
|
||||
|
@ -768,33 +767,6 @@ func (d *Database) StoreEvent(
|
|||
// events updater because it somewhat works as a mutex, ensuring
|
||||
// that there's a row-level lock on the latest room events (well,
|
||||
// on Postgres at least).
|
||||
if prevEvents := event.PrevEvents(); len(prevEvents) > 0 {
|
||||
// Create an updater - NB: on sqlite this WILL create a txn as we are directly calling the shared DB form of
|
||||
// GetLatestEventsForUpdate - not via the SQLiteDatabase form which has `nil` txns. This
|
||||
// function only does SELECTs though so the created txn (at this point) is just a read txn like
|
||||
// any other so this is fine. If we ever update GetLatestEventsForUpdate or NewLatestEventsUpdater
|
||||
// to do writes however then this will need to go inside `Writer.Do`.
|
||||
succeeded := false
|
||||
var roomInfo *types.RoomInfo
|
||||
roomInfo, err = d.roomInfo(ctx, nil, event.RoomID())
|
||||
if err != nil {
|
||||
return 0, types.StateAtEvent{}, nil, "", fmt.Errorf("d.RoomInfo: %w", err)
|
||||
}
|
||||
if roomInfo == nil && len(prevEvents) > 0 {
|
||||
return 0, types.StateAtEvent{}, nil, "", fmt.Errorf("expected room %q to exist", event.RoomID())
|
||||
}
|
||||
var updater *RoomUpdater
|
||||
updater, err = d.GetRoomUpdater(ctx, roomInfo)
|
||||
if err != nil {
|
||||
return 0, types.StateAtEvent{}, nil, "", fmt.Errorf("GetRoomUpdater: %w", err)
|
||||
}
|
||||
defer sqlutil.EndTransactionWithCheck(updater, &succeeded, &err)
|
||||
|
||||
if err = updater.StorePreviousEvents(eventNID, prevEvents); err != nil {
|
||||
return 0, types.StateAtEvent{}, nil, "", fmt.Errorf("updater.StorePreviousEvents: %w", err)
|
||||
}
|
||||
succeeded = true
|
||||
}
|
||||
|
||||
return eventNID, types.StateAtEvent{
|
||||
BeforeStateSnapshotNID: stateNID,
|
||||
|
@ -805,7 +777,7 @@ func (d *Database) StoreEvent(
|
|||
},
|
||||
EventNID: eventNID,
|
||||
},
|
||||
}, redactionEvent, redactedEventID, err
|
||||
}, err
|
||||
}
|
||||
|
||||
func (d *Database) PublishRoom(ctx context.Context, roomID, appserviceID, networkID string, publish bool) error {
|
||||
|
@ -893,7 +865,7 @@ func (d *Database) assignEventTypeNID(
|
|||
return eventTypeNID, nil
|
||||
}
|
||||
|
||||
func (d *Database) assignStateKeyNID(
|
||||
func (d *EventDatabase) assignStateKeyNID(
|
||||
ctx context.Context, txn *sql.Tx, eventStateKey string,
|
||||
) (types.EventStateKeyNID, error) {
|
||||
eventStateKeyNID, ok := d.Cache.GetEventStateKeyNID(eventStateKey)
|
||||
|
@ -937,7 +909,7 @@ func extractRoomVersionFromCreateEvent(event *gomatrixserverlib.Event) (
|
|||
return roomVersion, err
|
||||
}
|
||||
|
||||
// handleRedactions manages the redacted status of events. There's two cases to consider in order to comply with the spec:
|
||||
// MaybeRedactEvent manages the redacted status of events. There's two cases to consider in order to comply with the spec:
|
||||
// "servers should not apply or send redactions to clients until both the redaction event and original event have been seen, and are valid."
|
||||
// https://matrix.org/docs/spec/rooms/v3#authorization-rules-for-events
|
||||
// These cases are:
|
||||
|
@ -952,95 +924,95 @@ func extractRoomVersionFromCreateEvent(event *gomatrixserverlib.Event) (
|
|||
// when loading events to determine whether to apply redactions. This keeps the hot-path of reading events quick as we don't need
|
||||
// to cross-reference with other tables when loading.
|
||||
//
|
||||
// Returns the redaction event and the event ID of the redacted event if this call resulted in a redaction.
|
||||
func (d *Database) handleRedactions(
|
||||
ctx context.Context, txn *sql.Tx, roomNID types.RoomNID, eventNID types.EventNID, event *gomatrixserverlib.Event,
|
||||
) (*gomatrixserverlib.Event, string, error) {
|
||||
var err error
|
||||
isRedactionEvent := event.Type() == gomatrixserverlib.MRoomRedaction && event.StateKey() == nil
|
||||
if isRedactionEvent {
|
||||
// an event which redacts itself should be ignored
|
||||
if event.EventID() == event.Redacts() {
|
||||
return nil, "", nil
|
||||
// Returns the redaction event and the redacted event if this call resulted in a redaction.
|
||||
func (d *EventDatabase) MaybeRedactEvent(
|
||||
ctx context.Context, roomInfo *types.RoomInfo, eventNID types.EventNID, event *gomatrixserverlib.Event, redactAllowed bool,
|
||||
) (*gomatrixserverlib.Event, *gomatrixserverlib.Event, error) {
|
||||
var (
|
||||
redactionEvent, redactedEvent *types.Event
|
||||
err error
|
||||
validated bool
|
||||
ignoreRedaction bool
|
||||
)
|
||||
|
||||
wErr := d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
||||
isRedactionEvent := event.Type() == gomatrixserverlib.MRoomRedaction && event.StateKey() == nil
|
||||
if isRedactionEvent {
|
||||
// an event which redacts itself should be ignored
|
||||
if event.EventID() == event.Redacts() {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = d.RedactionsTable.InsertRedaction(ctx, txn, tables.RedactionInfo{
|
||||
Validated: false,
|
||||
RedactionEventID: event.EventID(),
|
||||
RedactsEventID: event.Redacts(),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("d.RedactionsTable.InsertRedaction: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = d.RedactionsTable.InsertRedaction(ctx, txn, tables.RedactionInfo{
|
||||
Validated: false,
|
||||
RedactionEventID: event.EventID(),
|
||||
RedactsEventID: event.Redacts(),
|
||||
})
|
||||
redactionEvent, redactedEvent, validated, err = d.loadRedactionPair(ctx, txn, roomInfo, eventNID, event)
|
||||
switch {
|
||||
case err != nil:
|
||||
return fmt.Errorf("d.loadRedactionPair: %w", err)
|
||||
case validated || redactedEvent == nil || redactionEvent == nil:
|
||||
// we've seen this redaction before or there is nothing to redact
|
||||
return nil
|
||||
case redactedEvent.RoomID() != redactionEvent.RoomID():
|
||||
// redactions across rooms aren't allowed
|
||||
ignoreRedaction = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// 1. The power level of the redaction event’s sender is greater than or equal to the redact level. (redactAllowed)
|
||||
// 2. The domain of the redaction event’s sender matches that of the original event’s sender.
|
||||
_, sender1, _ := gomatrixserverlib.SplitID('@', redactedEvent.Sender())
|
||||
_, sender2, _ := gomatrixserverlib.SplitID('@', redactionEvent.Sender())
|
||||
if !redactAllowed || sender1 != sender2 {
|
||||
ignoreRedaction = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// mark the event as redacted
|
||||
if redactionsArePermanent {
|
||||
redactedEvent.Redact()
|
||||
}
|
||||
|
||||
err = redactedEvent.SetUnsignedField("redacted_because", redactionEvent)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("d.RedactionsTable.InsertRedaction: %w", err)
|
||||
return fmt.Errorf("redactedEvent.SetUnsignedField: %w", err)
|
||||
}
|
||||
// NOTSPEC: sytest relies on this unspecced field existing :(
|
||||
err = redactedEvent.SetUnsignedField("redacted_by", redactionEvent.EventID())
|
||||
if err != nil {
|
||||
return fmt.Errorf("redactedEvent.SetUnsignedField: %w", err)
|
||||
}
|
||||
// overwrite the eventJSON table
|
||||
err = d.EventJSONTable.InsertEventJSON(ctx, txn, redactedEvent.EventNID, redactedEvent.JSON())
|
||||
if err != nil {
|
||||
return fmt.Errorf("d.EventJSONTable.InsertEventJSON: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
redactionEvent, redactedEvent, validated, err := d.loadRedactionPair(ctx, txn, roomNID, eventNID, event)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("d.loadRedactionPair: %w", err)
|
||||
err = d.RedactionsTable.MarkRedactionValidated(ctx, txn, redactionEvent.EventID(), true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("d.RedactionsTable.MarkRedactionValidated: %w", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if wErr != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if validated || redactedEvent == nil || redactionEvent == nil {
|
||||
// we've seen this redaction before or there is nothing to redact
|
||||
return nil, "", nil
|
||||
if ignoreRedaction || redactionEvent == nil || redactedEvent == nil {
|
||||
return nil, nil, nil
|
||||
}
|
||||
if redactedEvent.RoomID() != redactionEvent.RoomID() {
|
||||
// redactions across rooms aren't allowed
|
||||
return nil, "", nil
|
||||
}
|
||||
|
||||
// Get the power level from the database, so we can verify the user is allowed to redact the event
|
||||
powerLevels, err := d.GetStateEvent(ctx, event.RoomID(), gomatrixserverlib.MRoomPowerLevels, "")
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("d.GetStateEvent: %w", err)
|
||||
}
|
||||
if powerLevels == nil {
|
||||
return nil, "", fmt.Errorf("unable to fetch m.room.power_levels event from database for room %s", event.RoomID())
|
||||
}
|
||||
pl, err := powerLevels.PowerLevels()
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("unable to get powerlevels for room: %w", err)
|
||||
}
|
||||
|
||||
redactUser := pl.UserLevel(redactionEvent.Sender())
|
||||
switch {
|
||||
case redactUser >= pl.Redact:
|
||||
// The power level of the redaction event’s sender is greater than or equal to the redact level.
|
||||
case redactedEvent.Sender() == redactionEvent.Sender():
|
||||
// The domain of the redaction event’s sender matches that of the original event’s sender.
|
||||
default:
|
||||
return nil, "", nil
|
||||
}
|
||||
|
||||
// mark the event as redacted
|
||||
if redactionsArePermanent {
|
||||
redactedEvent.Redact()
|
||||
}
|
||||
|
||||
err = redactedEvent.SetUnsignedField("redacted_because", redactionEvent)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("redactedEvent.SetUnsignedField: %w", err)
|
||||
}
|
||||
// NOTSPEC: sytest relies on this unspecced field existing :(
|
||||
err = redactedEvent.SetUnsignedField("redacted_by", redactionEvent.EventID())
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("redactedEvent.SetUnsignedField: %w", err)
|
||||
}
|
||||
// overwrite the eventJSON table
|
||||
err = d.EventJSONTable.InsertEventJSON(ctx, txn, redactedEvent.EventNID, redactedEvent.JSON())
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("d.EventJSONTable.InsertEventJSON: %w", err)
|
||||
}
|
||||
|
||||
err = d.RedactionsTable.MarkRedactionValidated(ctx, txn, redactionEvent.EventID(), true)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("d.RedactionsTable.MarkRedactionValidated: %w", err)
|
||||
}
|
||||
|
||||
return redactionEvent.Event, redactedEvent.EventID(), err
|
||||
return redactionEvent.Event, redactedEvent.Event, nil
|
||||
}
|
||||
|
||||
// loadRedactionPair returns both the redaction event and the redacted event, else nil.
|
||||
func (d *Database) loadRedactionPair(
|
||||
ctx context.Context, txn *sql.Tx, roomNID types.RoomNID, eventNID types.EventNID, event *gomatrixserverlib.Event,
|
||||
func (d *EventDatabase) loadRedactionPair(
|
||||
ctx context.Context, txn *sql.Tx, roomInfo *types.RoomInfo, eventNID types.EventNID, event *gomatrixserverlib.Event,
|
||||
) (*types.Event, *types.Event, bool, error) {
|
||||
var redactionEvent, redactedEvent *types.Event
|
||||
var info *tables.RedactionInfo
|
||||
|
@ -1072,16 +1044,16 @@ func (d *Database) loadRedactionPair(
|
|||
}
|
||||
|
||||
if isRedactionEvent {
|
||||
redactedEvent = d.loadEvent(ctx, roomNID, info.RedactsEventID)
|
||||
redactedEvent = d.loadEvent(ctx, roomInfo, info.RedactsEventID)
|
||||
} else {
|
||||
redactionEvent = d.loadEvent(ctx, roomNID, info.RedactionEventID)
|
||||
redactionEvent = d.loadEvent(ctx, roomInfo, info.RedactionEventID)
|
||||
}
|
||||
|
||||
return redactionEvent, redactedEvent, info.Validated, nil
|
||||
}
|
||||
|
||||
// applyRedactions will redact events that have an `unsigned.redacted_because` field.
|
||||
func (d *Database) applyRedactions(events []types.Event) {
|
||||
func (d *EventDatabase) applyRedactions(events []types.Event) {
|
||||
for i := range events {
|
||||
if result := gjson.GetBytes(events[i].Unsigned(), "redacted_because"); result.Exists() {
|
||||
events[i].Redact()
|
||||
|
@ -1090,7 +1062,7 @@ func (d *Database) applyRedactions(events []types.Event) {
|
|||
}
|
||||
|
||||
// loadEvent loads a single event or returns nil on any problems/missing event
|
||||
func (d *Database) loadEvent(ctx context.Context, roomNID types.RoomNID, eventID string) *types.Event {
|
||||
func (d *EventDatabase) loadEvent(ctx context.Context, roomInfo *types.RoomInfo, eventID string) *types.Event {
|
||||
nids, err := d.EventNIDs(ctx, []string{eventID})
|
||||
if err != nil {
|
||||
return nil
|
||||
|
@ -1098,7 +1070,7 @@ func (d *Database) loadEvent(ctx context.Context, roomNID types.RoomNID, eventID
|
|||
if len(nids) == 0 {
|
||||
return nil
|
||||
}
|
||||
evs, err := d.Events(ctx, roomNID, []types.EventNID{nids[eventID].EventNID})
|
||||
evs, err := d.Events(ctx, roomInfo, []types.EventNID{nids[eventID].EventNID})
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -1144,7 +1116,7 @@ func (d *Database) GetHistoryVisibilityState(ctx context.Context, roomInfo *type
|
|||
// If no event could be found, returns nil
|
||||
// If there was an issue during the retrieval, returns an error
|
||||
func (d *Database) GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*gomatrixserverlib.HeaderedEvent, error) {
|
||||
roomInfo, err := d.RoomInfo(ctx, roomID)
|
||||
roomInfo, err := d.roomInfo(ctx, nil, roomID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1209,7 +1181,7 @@ func (d *Database) GetStateEvent(ctx context.Context, roomID, evType, stateKey s
|
|||
// Same as GetStateEvent but returns all matching state events with this event type. Returns no error
|
||||
// if there are no events with this event type.
|
||||
func (d *Database) GetStateEventsWithEventType(ctx context.Context, roomID, evType string) ([]*gomatrixserverlib.HeaderedEvent, error) {
|
||||
roomInfo, err := d.RoomInfo(ctx, roomID)
|
||||
roomInfo, err := d.roomInfo(ctx, nil, roomID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1340,7 +1312,7 @@ func (d *Database) GetBulkStateContent(ctx context.Context, roomIDs []string, tu
|
|||
eventNIDToVer := make(map[types.EventNID]gomatrixserverlib.RoomVersion)
|
||||
// TODO: This feels like this is going to be really slow...
|
||||
for _, roomID := range roomIDs {
|
||||
roomInfo, err2 := d.RoomInfo(ctx, roomID)
|
||||
roomInfo, err2 := d.roomInfo(ctx, nil, roomID)
|
||||
if err2 != nil {
|
||||
return nil, fmt.Errorf("GetBulkStateContent: failed to load room info for room %s : %w", roomID, err2)
|
||||
}
|
||||
|
|
|
@ -52,12 +52,14 @@ func mustCreateRoomserverDatabase(t *testing.T, dbType test.DBType) (*shared.Dat
|
|||
|
||||
cache := caching.NewRistrettoCache(8*1024*1024, time.Hour, false)
|
||||
|
||||
evDb := shared.EventDatabase{EventStateKeysTable: stateKeyTable, Cache: cache}
|
||||
|
||||
return &shared.Database{
|
||||
DB: db,
|
||||
EventStateKeysTable: stateKeyTable,
|
||||
MembershipTable: membershipTable,
|
||||
Writer: sqlutil.NewExclusiveWriter(),
|
||||
Cache: cache,
|
||||
DB: db,
|
||||
EventDatabase: evDb,
|
||||
MembershipTable: membershipTable,
|
||||
Writer: sqlutil.NewExclusiveWriter(),
|
||||
Cache: cache,
|
||||
}, func() {
|
||||
err := base.Close()
|
||||
assert.NoError(t, err)
|
||||
|
|
|
@ -203,24 +203,29 @@ func (d *Database) prepare(db *sql.DB, writer sqlutil.Writer, cache caching.Room
|
|||
}
|
||||
|
||||
d.Database = shared.Database{
|
||||
DB: db,
|
||||
Cache: cache,
|
||||
Writer: writer,
|
||||
EventsTable: events,
|
||||
EventTypesTable: eventTypes,
|
||||
EventStateKeysTable: eventStateKeys,
|
||||
EventJSONTable: eventJSON,
|
||||
RoomsTable: rooms,
|
||||
StateBlockTable: stateBlock,
|
||||
StateSnapshotTable: stateSnapshot,
|
||||
PrevEventsTable: prevEvents,
|
||||
RoomAliasesTable: roomAliases,
|
||||
InvitesTable: invites,
|
||||
MembershipTable: membership,
|
||||
PublishedTable: published,
|
||||
RedactionsTable: redactions,
|
||||
GetRoomUpdaterFn: d.GetRoomUpdater,
|
||||
Purge: purge,
|
||||
DB: db,
|
||||
EventDatabase: shared.EventDatabase{
|
||||
DB: db,
|
||||
Cache: cache,
|
||||
Writer: writer,
|
||||
EventsTable: events,
|
||||
EventTypesTable: eventTypes,
|
||||
EventStateKeysTable: eventStateKeys,
|
||||
EventJSONTable: eventJSON,
|
||||
PrevEventsTable: prevEvents,
|
||||
RedactionsTable: redactions,
|
||||
},
|
||||
Cache: cache,
|
||||
Writer: writer,
|
||||
RoomsTable: rooms,
|
||||
StateBlockTable: stateBlock,
|
||||
StateSnapshotTable: stateSnapshot,
|
||||
RoomAliasesTable: roomAliases,
|
||||
InvitesTable: invites,
|
||||
MembershipTable: membership,
|
||||
PublishedTable: published,
|
||||
GetRoomUpdaterFn: d.GetRoomUpdater,
|
||||
Purge: purge,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue