Resolve sticker pack references after import

This commit is contained in:
Fedor Indutny 2025-01-28 13:57:19 -08:00 committed by GitHub
parent fbdf589f13
commit 9fab74e867
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 216 additions and 40 deletions

View file

@ -365,6 +365,13 @@ export type StickerPackType = InstalledStickerPackType &
title: string;
}>;
export type StickerPackRefType = Readonly<{
packId: string;
messageId: string;
stickerId: number;
isUnresolved: boolean;
}>;
export type UnprocessedType = {
id: string;
timestamp: number;
@ -940,12 +947,14 @@ type WritableInterface = {
stickerId: number,
lastUsed: number
) => void;
addStickerPackReference: (messageId: string, packId: string) => void;
addStickerPackReference: (ref: StickerPackRefType) => void;
deleteStickerPackReference: (
messageId: string,
packId: string
ref: Pick<StickerPackRefType, 'messageId' | 'packId'>
) => ReadonlyArray<string> | undefined;
deleteStickerPack: (packId: string) => Array<string>;
getUnresolvedStickerPackReferences: (
packId: string
) => Array<StickerPackRefType>;
addUninstalledStickerPack: (pack: UninstalledStickerPackType) => void;
addUninstalledStickerPacks: (
pack: ReadonlyArray<UninstalledStickerPackType>

View file

@ -160,6 +160,7 @@ import type {
SignedPreKeyIdType,
StickerPackInfoType,
StickerPackStatusType,
StickerPackRefType,
StickerPackType,
StickerType,
StoredAllItemsType,
@ -503,6 +504,7 @@ export const DataWriter: ServerWritableInterface = {
addStickerPackReference,
deleteStickerPackReference,
deleteStickerPack,
getUnresolvedStickerPackReferences,
addUninstalledStickerPack,
addUninstalledStickerPacks,
removeUninstalledStickerPack,
@ -5570,8 +5572,7 @@ function updateStickerLastUsed(
}
function addStickerPackReference(
db: WritableDB,
messageId: string,
packId: string
{ messageId, packId, stickerId, isUnresolved }: StickerPackRefType
): void {
if (!messageId) {
throw new Error(
@ -5584,37 +5585,32 @@ function addStickerPackReference(
);
}
db.prepare<Query>(
prepare(
db,
`
INSERT OR REPLACE INTO sticker_references (
messageId,
packId
packId,
stickerId,
isUnresolved
) values (
$messageId,
$packId
$packId,
$stickerId,
$isUnresolved
)
`
).run({
messageId,
packId,
stickerId,
isUnresolved: isUnresolved ? 1 : 0,
});
}
function deleteStickerPackReference(
db: WritableDB,
messageId: string,
packId: string
{ messageId, packId }: Pick<StickerPackRefType, 'messageId' | 'packId'>
): ReadonlyArray<string> | undefined {
if (!messageId) {
throw new Error(
'addStickerPackReference: Provided data did not have a truthy messageId'
);
}
if (!packId) {
throw new Error(
'addStickerPackReference: Provided data did not have a truthy packId'
);
}
return db.transaction(() => {
// We use an immediate transaction here to immediately acquire an exclusive lock,
// which would normally only happen when we did our first write.
@ -5690,6 +5686,27 @@ function deleteStickerPackReference(
return (stickerPathRows || []).map(row => row.path);
})();
}
function getUnresolvedStickerPackReferences(
db: WritableDB,
packId: string
): Array<StickerPackRefType> {
return db.transaction(() => {
const [query, params] = sql`
UPDATE sticker_references
SET isUnresolved = 0
WHERE packId IS ${packId} AND isUnresolved IS 1
RETURNING messageId, stickerId;
`;
const rows = db.prepare(query).all(params);
return rows.map(({ messageId, stickerId }) => ({
messageId,
packId,
stickerId,
isUnresolved: true,
}));
})();
}
function deleteStickerPack(db: WritableDB, packId: string): Array<string> {
if (!packId) {

View file

@ -0,0 +1,35 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { LoggerType } from '../../types/Logging';
import { sql } from '../util';
import type { WritableDB } from '../Interface';
export const version = 1300;
export function updateToSchemaVersion1300(
currentVersion: number,
db: WritableDB,
logger: LoggerType
): void {
if (currentVersion >= 1300) {
return;
}
db.transaction(() => {
const [query] = sql`
ALTER TABLE sticker_references
ADD COLUMN stickerId INTEGER NOT NULL DEFAULT -1;
ALTER TABLE sticker_references
ADD COLUMN isUnresolved INTEGER NOT NULL DEFAULT 0;
CREATE INDEX unresolved_sticker_refs
ON sticker_references (packId, stickerId)
WHERE isUnresolved IS 1;
`;
db.exec(query);
db.pragma('user_version = 1300');
})();
logger.info('updateToSchemaVersion1300: success!');
}

View file

@ -105,10 +105,11 @@ import { updateToSchemaVersion1250 } from './1250-defunct-call-links-storage';
import { updateToSchemaVersion1260 } from './1260-sync-tasks-rowid';
import { updateToSchemaVersion1270 } from './1270-normalize-messages';
import { updateToSchemaVersion1280 } from './1280-blob-unprocessed';
import { updateToSchemaVersion1290 } from './1290-int-unprocessed-source-device';
import {
updateToSchemaVersion1290,
updateToSchemaVersion1300,
version as MAX_VERSION,
} from './1290-int-unprocessed-source-device';
} from './1300-sticker-pack-refs';
import { DataWriter } from '../Server';
function updateToSchemaVersion1(
@ -2084,6 +2085,8 @@ export const SCHEMA_VERSIONS = [
updateToSchemaVersion1270,
updateToSchemaVersion1280,
updateToSchemaVersion1290,
updateToSchemaVersion1300,
];
export class DBVersionFromFutureError extends Error {