mirror of
https://github.com/matrix-org/dendrite
synced 2024-09-11 05:29:18 +02:00
154 lines
4.6 KiB
Go
154 lines
4.6 KiB
Go
|
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||
|
//
|
||
|
// 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 sqlite3
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"database/sql"
|
||
|
|
||
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||
|
"github.com/matrix-org/dendrite/roomserver/types"
|
||
|
)
|
||
|
|
||
|
const purgeEventJSONSQL = "" +
|
||
|
"DELETE FROM roomserver_event_json WHERE event_nid IN (" +
|
||
|
" SELECT event_nid FROM roomserver_events WHERE room_nid = $1" +
|
||
|
")"
|
||
|
|
||
|
const purgeEventsSQL = "" +
|
||
|
"DELETE FROM roomserver_events WHERE room_nid = $1"
|
||
|
|
||
|
const purgeInvitesSQL = "" +
|
||
|
"DELETE FROM roomserver_invites WHERE room_nid = $1"
|
||
|
|
||
|
const purgeMembershipsSQL = "" +
|
||
|
"DELETE FROM roomserver_membership WHERE room_nid = $1"
|
||
|
|
||
|
const purgePreviousEventsSQL = "" +
|
||
|
"DELETE FROM roomserver_previous_events WHERE event_nids IN(" +
|
||
|
" SELECT event_nid FROM roomserver_events WHERE room_nid = $1" +
|
||
|
")"
|
||
|
|
||
|
const purgePublishedSQL = "" +
|
||
|
"DELETE FROM roomserver_published WHERE room_id = $1"
|
||
|
|
||
|
const purgeRedactionsSQL = "" +
|
||
|
"DELETE FROM roomserver_redactions WHERE redaction_event_id IN(" +
|
||
|
" SELECT event_id FROM roomserver_events WHERE room_nid = $1" +
|
||
|
")"
|
||
|
|
||
|
const purgeRoomAliasesSQL = "" +
|
||
|
"DELETE FROM roomserver_room_aliases WHERE room_id = $1"
|
||
|
|
||
|
const purgeRoomSQL = "" +
|
||
|
"DELETE FROM roomserver_rooms WHERE room_nid = $1"
|
||
|
|
||
|
const purgeStateSnapshotEntriesSQL = "" +
|
||
|
"DELETE FROM roomserver_state_snapshots WHERE room_nid = $1"
|
||
|
|
||
|
type purgeStatements struct {
|
||
|
purgeEventJSONStmt *sql.Stmt
|
||
|
purgeEventsStmt *sql.Stmt
|
||
|
purgeInvitesStmt *sql.Stmt
|
||
|
purgeMembershipsStmt *sql.Stmt
|
||
|
purgePreviousEventsStmt *sql.Stmt
|
||
|
purgePublishedStmt *sql.Stmt
|
||
|
purgeRedactionStmt *sql.Stmt
|
||
|
purgeRoomAliasesStmt *sql.Stmt
|
||
|
purgeRoomStmt *sql.Stmt
|
||
|
purgeStateSnapshotEntriesStmt *sql.Stmt
|
||
|
stateSnapshot *stateSnapshotStatements
|
||
|
}
|
||
|
|
||
|
func PreparePurgeStatements(db *sql.DB, stateSnapshot *stateSnapshotStatements) (*purgeStatements, error) {
|
||
|
s := &purgeStatements{stateSnapshot: stateSnapshot}
|
||
|
return s, sqlutil.StatementList{
|
||
|
{&s.purgeEventJSONStmt, purgeEventJSONSQL},
|
||
|
{&s.purgeEventsStmt, purgeEventsSQL},
|
||
|
{&s.purgeInvitesStmt, purgeInvitesSQL},
|
||
|
{&s.purgeMembershipsStmt, purgeMembershipsSQL},
|
||
|
{&s.purgePublishedStmt, purgePublishedSQL},
|
||
|
{&s.purgePreviousEventsStmt, purgePreviousEventsSQL},
|
||
|
{&s.purgeRedactionStmt, purgeRedactionsSQL},
|
||
|
{&s.purgeRoomAliasesStmt, purgeRoomAliasesSQL},
|
||
|
{&s.purgeRoomStmt, purgeRoomSQL},
|
||
|
//{&s.purgeStateBlockEntriesStmt, purgeStateBlockEntriesSQL},
|
||
|
{&s.purgeStateSnapshotEntriesStmt, purgeStateSnapshotEntriesSQL},
|
||
|
}.Prepare(db)
|
||
|
}
|
||
|
|
||
|
func (s *purgeStatements) PurgeRoom(
|
||
|
ctx context.Context, txn *sql.Tx, roomNID types.RoomNID, roomID string,
|
||
|
) error {
|
||
|
|
||
|
// purge by roomID
|
||
|
purgeByRoomID := []*sql.Stmt{
|
||
|
s.purgeRoomAliasesStmt,
|
||
|
s.purgePublishedStmt,
|
||
|
}
|
||
|
for _, stmt := range purgeByRoomID {
|
||
|
_, err := sqlutil.TxStmt(txn, stmt).ExecContext(ctx, roomID)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// purge by roomNID
|
||
|
if err := s.purgeStateBlocks(ctx, txn, roomNID); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
purgeByRoomNID := []*sql.Stmt{
|
||
|
s.purgeStateSnapshotEntriesStmt,
|
||
|
s.purgeInvitesStmt,
|
||
|
s.purgeMembershipsStmt,
|
||
|
s.purgePreviousEventsStmt,
|
||
|
s.purgeEventJSONStmt,
|
||
|
s.purgeRedactionStmt,
|
||
|
s.purgeEventsStmt,
|
||
|
s.purgeRoomStmt,
|
||
|
}
|
||
|
for _, stmt := range purgeByRoomNID {
|
||
|
_, err := sqlutil.TxStmt(txn, stmt).ExecContext(ctx, roomNID)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (s *purgeStatements) purgeStateBlocks(
|
||
|
ctx context.Context, txn *sql.Tx, roomNID types.RoomNID,
|
||
|
) error {
|
||
|
// Get all stateBlockNIDs
|
||
|
stateBlockNIDs, err := s.stateSnapshot.selectStateBlockNIDsForRoomNID(ctx, txn, roomNID)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
params := make([]interface{}, len(stateBlockNIDs))
|
||
|
seenNIDs := make(map[types.StateBlockNID]struct{}, len(stateBlockNIDs))
|
||
|
// dedupe NIDs
|
||
|
for k, v := range stateBlockNIDs {
|
||
|
if _, ok := seenNIDs[v]; ok {
|
||
|
continue
|
||
|
}
|
||
|
params[k] = v
|
||
|
seenNIDs[v] = struct{}{}
|
||
|
}
|
||
|
|
||
|
query := "DELETE FROM roomserver_state_block WHERE state_block_nid IN($1)"
|
||
|
return sqlutil.RunLimitedVariablesExec(ctx, query, txn, params, sqlutil.SQLite3MaxVariables)
|
||
|
}
|