mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-10 16:33:11 -06:00
Storage functions for invite events
This commit is contained in:
parent
a6bb92520c
commit
3ea0644002
|
|
@ -0,0 +1,161 @@
|
|||
// Copyright 2017 Vector Creations Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
)
|
||||
|
||||
const inviteSchema = `
|
||||
CREATE TABLE invites (
|
||||
-- The numeric ID of the invite event itself.
|
||||
invite_event_nid BIGINT NOT NULL CONSTRAINT invite_event_nid_unique UNIQUE,
|
||||
-- The numeric ID of the room the invite m.room.member event is in.
|
||||
room_nid BIGINT NOT NULL,
|
||||
-- The numeric ID for the state key of the invite m.room.member event.
|
||||
-- This tells us who the invite is for.
|
||||
-- This is used to query the active invites for a user.
|
||||
target_state_key_nid BIGINT NOT NULL,
|
||||
-- The numeric ID for the sender of the invite m.room.member event.
|
||||
-- This tells us who sent the invite.
|
||||
-- This is used to work out which matrix server we should talk to when
|
||||
-- we try to join the room.
|
||||
sender_state_key_nid BIGINT NOT NULL DEFAULT 0,
|
||||
-- The numeric ID of the join or leave event that replaced the invite event.
|
||||
-- This is used to track whether the invite is still active.
|
||||
-- This is set implicitly when processing a KIND_NEW events and explici
|
||||
-- is set
|
||||
replaced_by_event_nid BIGINT NOT NULL DEFAULT 0,
|
||||
-- Whether the invite has been sent to the output stream.
|
||||
-- We maintain a separate output stream of invite events since they don't
|
||||
-- always occur within a room we have state for.
|
||||
sent_invite_to_output BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
-- Whether the replacement has been sent to the output stream.
|
||||
sent_replaced_to_output BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
);
|
||||
|
||||
CREATE INDEX invites_active_idx ON invites (target_state_key_nid, room_nid)
|
||||
WHERE replaced_by_event_nid == 0;
|
||||
`
|
||||
|
||||
const upsertInviteEventSQL = "" +
|
||||
"INSERT INTO invites (invite_event_nid, room_nid, target_state_key_nid," +
|
||||
" sender_state_key_nid) VALUES ($1, $2, $3, $4)" +
|
||||
" ON CONFLICT ON invite_event_nid_unique" +
|
||||
" DO UPDATE SET sender_state_key_nid = $4"
|
||||
|
||||
const upsertInviteReplacedBySQL = "" +
|
||||
"INSERT INTO invites (invite_event_nid, room_nid, target_state_key_nid," +
|
||||
" replaced_by_event_nid) VALUES ($1, $2, $3, $4)" +
|
||||
" ON CONFLICT ON invite_event_nid_unique" +
|
||||
" DO UPDATE SET replaced_by_event_nid = $4"
|
||||
|
||||
const selectInviteSQL = "" +
|
||||
"SELECT replaced_by_event_nid, sent_invite_to_output," +
|
||||
" sent_replaced_to_output FROM invites" +
|
||||
" WHERE invite_event_nid = $1"
|
||||
|
||||
const selectActiveInviteForUserInRoomSQL = "" +
|
||||
"SELECT invite_event_nid, sender_state_key_nid FROM invites" +
|
||||
" WHERE target_state_key_nid = $1 AND room_nid = $2" +
|
||||
" AND replaced_by_event_nid = 0"
|
||||
|
||||
const updateInviteSentInviteToOutputSQL = "" +
|
||||
"UPDATE invites SET sent_invite_to_output = TRUE" +
|
||||
" WHERE invite_event_nid = $1"
|
||||
|
||||
const updateInviteSentReplacedToOutputSQL = "" +
|
||||
"UPDATE invites SET sent_replaced_to_output = TRUE" +
|
||||
" WHERE invite_event_nid = $1"
|
||||
|
||||
type inviteStatements struct {
|
||||
upsertInviteEventStmt *sql.Stmt
|
||||
upsertInviteReplacedByStmt *sql.Stmt
|
||||
selectInviteStmt *sql.Stmt
|
||||
selectActiveInviteForUserInRoomStmt *sql.Stmt
|
||||
updateInviteSentInviteToOutputStmt *sql.Stmt
|
||||
updateInviteSentReplacedToOutputStmt *sql.Stmt
|
||||
}
|
||||
|
||||
func (s *inviteStatements) prepare(db *sql.DB) (err error) {
|
||||
_, err = db.Exec(inviteSchema)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return statementList{
|
||||
{&s.upsertInviteEventStmt, upsertInviteEventSQL},
|
||||
{&s.upsertInviteReplacedByStmt, upsertInviteReplacedBySQL},
|
||||
{&s.selectInviteStmt, selectInviteSQL},
|
||||
{&s.selectActiveInviteForUserInRoomStmt, selectActiveInviteForUserInRoomSQL},
|
||||
{&s.updateInviteSentInviteToOutputStmt, updateInviteSentInviteToOutputSQL},
|
||||
{&s.updateInviteSentReplacedToOutputStmt, updateInviteSentReplacedToOutputSQL},
|
||||
}.prepare(db)
|
||||
}
|
||||
|
||||
func (s *inviteStatements) upsertInviteEvent(
|
||||
inviteEventNID types.EventNID, roomNID types.RoomNID,
|
||||
targetStateKeyNID, senderStateKeyNID types.EventStateKeyNID,
|
||||
) error {
|
||||
_, err := s.upsertInviteEventStmt.Exec(
|
||||
inviteEventNID, roomNID, targetStateKeyNID, senderStateKeyNID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *inviteStatements) upsertInviteReplacedBy(
|
||||
inviteEventNID types.EventNID, roomNID types.RoomNID,
|
||||
targetStateKeyNID types.EventStateKeyNID,
|
||||
replacedByEventNID types.EventNID,
|
||||
) error {
|
||||
_, err := s.upsertInviteReplacedByStmt.Exec(
|
||||
inviteEventNID, roomNID, targetStateKeyNID, replacedByEventNID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *inviteStatements) selectInvite(
|
||||
inviteEventNID types.EventNID,
|
||||
) (replacedByNID types.EventNID, sentInviteToOutput, sentReplacedToOutput bool, err error) {
|
||||
err = s.selectInviteStmt.QueryRow(inviteEventNID).Scan(
|
||||
&replacedByNID, &sentInviteToOutput, &sentReplacedToOutput,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *inviteStatements) selectActiveInviteForUserInRoom(
|
||||
targetStateKeyNID types.EventStateKeyNID, roomNID types.RoomNID,
|
||||
) (inviteEventNID types.EventNID, senderStateKeyNID types.EventStateKeyNID, err error) {
|
||||
err = s.selectActiveInviteForUserInRoomStmt.QueryRow(
|
||||
targetStateKeyNID, roomNID,
|
||||
).Scan(&inviteEventNID, &senderStateKeyNID)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *inviteStatements) updateInviteSentInviteToOutput(
|
||||
inviteEventNID types.EventNID,
|
||||
) error {
|
||||
_, err := s.updateInviteSentInviteToOutputStmt.Exec(inviteEventNID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *inviteStatements) updateInviteSentReplacedToOutput(
|
||||
inviteEventNID types.EventNID,
|
||||
) error {
|
||||
_, err := s.updateInviteSentReplacedToOutputStmt.Exec(inviteEventNID)
|
||||
return err
|
||||
}
|
||||
|
|
@ -30,45 +30,27 @@ type statements struct {
|
|||
stateSnapshotStatements
|
||||
stateBlockStatements
|
||||
previousEventStatements
|
||||
inviteStatements
|
||||
}
|
||||
|
||||
func (s *statements) prepare(db *sql.DB) error {
|
||||
var err error
|
||||
|
||||
if err = s.PartitionOffsetStatements.Prepare(db); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = s.eventTypeStatements.prepare(db); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = s.eventStateKeyStatements.prepare(db); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = s.roomStatements.prepare(db); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = s.eventStatements.prepare(db); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = s.eventJSONStatements.prepare(db); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = s.stateSnapshotStatements.prepare(db); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = s.stateBlockStatements.prepare(db); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = s.previousEventStatements.prepare(db); err != nil {
|
||||
return err
|
||||
for _, prepare := range []func(db *sql.DB) error{
|
||||
s.PartitionOffsetStatements.Prepare,
|
||||
s.eventTypeStatements.prepare,
|
||||
s.eventStateKeyStatements.prepare,
|
||||
s.roomStatements.prepare,
|
||||
s.eventStatements.prepare,
|
||||
s.eventJSONStatements.prepare,
|
||||
s.stateSnapshotStatements.prepare,
|
||||
s.stateBlockStatements.prepare,
|
||||
s.previousEventStatements.prepare,
|
||||
s.inviteStatements.prepare,
|
||||
} {
|
||||
if err = prepare(db); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -372,3 +372,41 @@ func (d *Database) StateEntriesForTuples(
|
|||
) ([]types.StateEntryList, error) {
|
||||
return d.statements.bulkSelectFilteredStateBlockEntries(stateBlockNIDs, stateKeyTuples)
|
||||
}
|
||||
|
||||
// StoreInvite implements input.EventDatabase
|
||||
func (d *Database) StoreInvite(
|
||||
roomNID types.RoomNID, inviteEventNID types.EventNID,
|
||||
targetNID types.EventStateKeyNID, senderID string,
|
||||
) (replacedByNID types.EventNID, sentInviteToOutput bool, err error) {
|
||||
var senderNID types.EventStateKeyNID
|
||||
if senderNID, err = d.assignStateKeyNID(senderID); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = d.statements.upsertInviteEvent(inviteEventNID, roomNID, targetNID, senderNID); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if replacedByNID, sentInviteToOutput, _, err = d.statements.selectInvite(inviteEventNID); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// MarkInviteAsSent implements input.EventDatabase
|
||||
func (d *Database) MarkInviteAsSent(inviteEventNID types.EventNID) error {
|
||||
return d.statements.updateInviteSentInviteToOutput(inviteEventNID)
|
||||
}
|
||||
|
||||
// MarkInviteReplacedAsSent implements input.EventDatabase
|
||||
func (d *Database) MarkInviteReplacedAsSent(inviteEventNID types.EventNID) error {
|
||||
return d.statements.updateInviteSentReplacedToOutput(inviteEventNID)
|
||||
}
|
||||
|
||||
// LookupInviteForUserInRoom implements query.RoomserverQueryAPIDB
|
||||
func (d *Database) LookupInviteForUserInRoom(
|
||||
roomNID types.RoomNID, targetNID types.EventStateKeyNID,
|
||||
) (eventNID types.EventNID, senderNID types.EventStateKeyNID, err error) {
|
||||
return d.statements.selectActiveInviteForUserInRoom(targetNID, roomNID)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue