2023-01-19 14:02:32 -06:00
// 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 postgres
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 = ANY(" +
" 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 && ANY(" +
" SELECT ARRAY_AGG(event_nid) FROM roomserver_events WHERE room_nid = $1" +
")"
2024-09-10 13:43:50 -05:00
// This removes the majority of prev events and is way faster than the above.
// The above query is still needed to delete the remaining prev events.
const purgePreviousEvents2SQL = "" +
"DELETE FROM roomserver_previous_events rpe WHERE EXISTS(SELECT event_id FROM roomserver_events re WHERE room_nid = $1 AND re.event_id = rpe.previous_event_id)"
2023-01-19 14:02:32 -06:00
const purgePublishedSQL = "" +
"DELETE FROM roomserver_published WHERE room_id = $1"
const purgeRedactionsSQL = "" +
"DELETE FROM roomserver_redactions WHERE redaction_event_id = ANY(" +
" 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 purgeStateBlockEntriesSQL = "" +
"DELETE FROM roomserver_state_block WHERE state_block_nid = ANY(" +
" SELECT DISTINCT UNNEST(state_block_nids) FROM roomserver_state_snapshots 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
2024-09-10 13:43:50 -05:00
purgePreviousEvents2Stmt * sql . Stmt
2023-01-19 14:02:32 -06:00
purgePublishedStmt * sql . Stmt
purgeRedactionStmt * sql . Stmt
purgeRoomAliasesStmt * sql . Stmt
purgeRoomStmt * sql . Stmt
purgeStateBlockEntriesStmt * sql . Stmt
purgeStateSnapshotEntriesStmt * sql . Stmt
}
func PreparePurgeStatements ( db * sql . DB ) ( * purgeStatements , error ) {
s := & purgeStatements { }
return s , sqlutil . StatementList {
{ & s . purgeEventJSONStmt , purgeEventJSONSQL } ,
{ & s . purgeEventsStmt , purgeEventsSQL } ,
{ & s . purgeInvitesStmt , purgeInvitesSQL } ,
{ & s . purgeMembershipsStmt , purgeMembershipsSQL } ,
{ & s . purgePublishedStmt , purgePublishedSQL } ,
{ & s . purgePreviousEventsStmt , purgePreviousEventsSQL } ,
2024-09-10 13:43:50 -05:00
{ & s . purgePreviousEvents2Stmt , purgePreviousEvents2SQL } ,
2023-01-19 14:02:32 -06:00
{ & 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
purgeByRoomNID := [ ] * sql . Stmt {
s . purgeStateBlockEntriesStmt ,
s . purgeStateSnapshotEntriesStmt ,
s . purgeInvitesStmt ,
s . purgeMembershipsStmt ,
2024-09-10 13:43:50 -05:00
s . purgePreviousEvents2Stmt , // Fast purge the majority of events
s . purgePreviousEventsStmt , // Slow purge the remaining events
2023-01-19 14:02:32 -06:00
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
}