Synchronous delete call link

This commit is contained in:
ayumi-signal 2024-10-09 09:35:24 -07:00 committed by GitHub
parent e60df56500
commit 42cc5e0013
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 443 additions and 135 deletions

View file

@ -20,7 +20,7 @@ import type { ReadableDB, WritableDB } from '../Interface';
import { prepare } from '../Server';
import { sql } from '../util';
import { strictAssert } from '../../util/assert';
import { CallStatusValue } from '../../types/CallDisposition';
import { CallStatusValue, DirectCallStatus } from '../../types/CallDisposition';
import { parseStrict, parseUnknown } from '../../util/schemas';
export function callLinkExists(db: ReadableDB, roomId: string): boolean {
@ -190,7 +190,10 @@ function assertRoomIdMatchesRootKey(roomId: string, rootKey: string): void {
);
}
function deleteCallHistoryByRoomId(db: WritableDB, roomId: string) {
export function deleteCallHistoryByRoomId(
db: WritableDB,
roomId: string
): void {
const [
markCallHistoryDeleteByPeerIdQuery,
markCallHistoryDeleteByPeerIdParams,
@ -222,17 +225,14 @@ export function deleteCallLinkFromSync(db: WritableDB, roomId: string): void {
})();
}
export type DeleteCallLinkOptions = {
storageNeedsSync: boolean;
deletedAt?: number;
};
export function beginDeleteCallLink(
db: WritableDB,
roomId: string,
options: DeleteCallLinkOptions
): void {
db.transaction(() => {
/**
* Deletes a non-admin call link from the local database, or if it's an admin call link,
* then marks it for deletion and storage sync.
*
* @returns boolean: True if storage sync is needed; False if not
*/
export function beginDeleteCallLink(db: WritableDB, roomId: string): boolean {
return db.transaction(() => {
// If adminKey is null, then we should delete the call link
const [deleteNonAdminCallLinksQuery, deleteNonAdminCallLinksParams] = sql`
DELETE FROM callLinks
@ -244,35 +244,62 @@ export function beginDeleteCallLink(
.prepare(deleteNonAdminCallLinksQuery)
.run(deleteNonAdminCallLinksParams);
// Skip this query if the call is already deleted
if (result.changes === 0) {
const { storageNeedsSync } = options;
const deletedAt = options.deletedAt ?? new Date().getTime();
// If the admin key is not null, we should mark it for deletion
const [markAdminCallLinksDeletedQuery, markAdminCallLinksDeletedParams] =
sql`
UPDATE callLinks
SET
deleted = 1,
deletedAt = ${deletedAt},
storageNeedsSync = ${storageNeedsSync ? 1 : 0}
WHERE adminKey IS NOT NULL
AND roomId = ${roomId};
`;
db.prepare(markAdminCallLinksDeletedQuery).run(
markAdminCallLinksDeletedParams
);
// If we successfully deleted the call link, then it was a non-admin call link
// and we're done
if (result.changes !== 0) {
return false;
}
deleteCallHistoryByRoomId(db, roomId);
const deletedAt = new Date().getTime();
// If the admin key is not null, we should mark it for deletion
const [markAdminCallLinksDeletedQuery, markAdminCallLinksDeletedParams] =
sql`
UPDATE callLinks
SET
deleted = 1,
deletedAt = ${deletedAt},
storageNeedsSync = 1
WHERE adminKey IS NOT NULL
AND deleted IS NOT 1
AND roomId = ${roomId};
`;
const deleteAdminLinkResult = db
.prepare(markAdminCallLinksDeletedQuery)
.run(markAdminCallLinksDeletedParams);
return deleteAdminLinkResult.changes > 0;
})();
}
export function beginDeleteAllCallLinks(db: WritableDB): void {
const deletedAt = new Date().getTime();
export function deleteCallLinkAndHistory(db: WritableDB, roomId: string): void {
db.transaction(() => {
const [deleteCallLinkQuery, deleteCallLinkParams] = sql`
DELETE FROM callLinks
WHERE roomId = ${roomId};
`;
db.prepare(deleteCallLinkQuery).run(deleteCallLinkParams);
const [deleteCallHistoryQuery, clearCallHistoryParams] = sql`
UPDATE callsHistory
SET
status = ${DirectCallStatus.Deleted},
timestamp = ${Date.now()}
WHERE peerId = ${roomId};
`;
db.prepare(deleteCallHistoryQuery).run(clearCallHistoryParams);
})();
}
/**
* Deletes all non-admin call link from the local database, and marks all admin call links
* for deletion and storage sync.
*
* @returns boolean: True if storage sync is needed; False if not
*/
export function beginDeleteAllCallLinks(db: WritableDB): boolean {
const deletedAt = new Date().getTime();
return db.transaction(() => {
const [markAdminCallLinksDeletedQuery, markAdminCallLinksDeletedParams] =
sql`
UPDATE callLinks
@ -280,12 +307,13 @@ export function beginDeleteAllCallLinks(db: WritableDB): void {
deleted = 1,
deletedAt = ${deletedAt},
storageNeedsSync = 1
WHERE adminKey IS NOT NULL;
WHERE adminKey IS NOT NULL
AND deleted IS NOT 1;
`;
db.prepare(markAdminCallLinksDeletedQuery).run(
markAdminCallLinksDeletedParams
);
const markAdminCallLinksDeletedResult = db
.prepare(markAdminCallLinksDeletedQuery)
.run(markAdminCallLinksDeletedParams);
const [deleteNonAdminCallLinksQuery] = sql`
DELETE FROM callLinks
@ -293,6 +321,9 @@ export function beginDeleteAllCallLinks(db: WritableDB): void {
`;
db.prepare(deleteNonAdminCallLinksQuery).run();
// If admin call links were marked deleted, then storage will need sync
return markAdminCallLinksDeletedResult.changes > 0;
})();
}
@ -311,6 +342,14 @@ export function getAllCallLinkRecordsWithAdminKey(
.map((item: unknown) => parseUnknown(callLinkRecordSchema, item));
}
export function getAllAdminCallLinks(
db: ReadableDB
): ReadonlyArray<CallLinkType> {
return getAllCallLinkRecordsWithAdminKey(db).map((record: CallLinkRecord) =>
callLinkFromRecord(record)
);
}
export function getAllMarkedDeletedCallLinkRoomIds(
db: ReadableDB
): ReadonlyArray<string> {