fix(storage): safely batch folder deletion binds

This commit is contained in:
shuaiplus
2026-07-13 13:30:52 +08:00
parent e943357067
commit 63b642b251
2 changed files with 20 additions and 12 deletions
+12 -9
View File
@@ -68,20 +68,22 @@ export async function bulkDeleteFolders(
db: D1Database,
userId: string,
ids: string[],
sqlChunkSize: (fixedBindCount: number) => number,
sqlChunkSize: (fixedBindCount: number, bindCountPerItem?: number) => number,
updateRevisionDate: (userId: string) => Promise<string>
): Promise<string | null> {
const uniqueIds = Array.from(new Set(ids.map((id) => String(id || '').trim()).filter(Boolean)));
if (!uniqueIds.length) return null;
const now = new Date().toISOString();
const chunkSize = sqlChunkSize(2);
// Each folder ID is bound in all three compatibility predicates below.
const chunkSize = sqlChunkSize(2, 3);
const statements: D1PreparedStatement[] = [];
for (let i = 0; i < uniqueIds.length; i += chunkSize) {
const chunk = uniqueIds.slice(i, i + chunkSize);
const placeholders = chunk.map(() => '?').join(',');
await db
.prepare(
statements.push(
db.prepare(
`UPDATE ciphers
SET folder_id = NULL, updated_at = ?,
data = json_remove(data, '$.folderId', '$.folder_id', '$.updatedAt', '$.revisionDate')
@@ -93,14 +95,15 @@ export async function bulkDeleteFolders(
)`
)
.bind(now, userId, ...chunk, ...chunk, ...chunk)
.run();
await db
.prepare(`DELETE FROM folders WHERE user_id = ? AND id IN (${placeholders})`)
);
statements.push(
db.prepare(`DELETE FROM folders WHERE user_id = ? AND id IN (${placeholders})`)
.bind(userId, ...chunk)
.run();
);
}
await db.batch(statements);
return updateRevisionDate(userId);
}
+7 -2
View File
@@ -209,10 +209,15 @@ export class StorageService {
return REQUIRED_SCHEMA_TABLES.every((table) => found.has(table));
}
private sqlChunkSize(fixedBindCount: number): number {
private sqlChunkSize(fixedBindCount: number, bindCountPerItem = 1): number {
const safeFixedBindCount = Math.max(0, Math.floor(fixedBindCount));
const safeBindCountPerItem = Math.max(1, Math.floor(bindCountPerItem));
return Math.max(
1,
Math.min(LIMITS.performance.bulkMoveChunkSize, StorageService.MAX_D1_SQL_VARIABLES - fixedBindCount)
Math.min(
LIMITS.performance.bulkMoveChunkSize,
Math.floor((StorageService.MAX_D1_SQL_VARIABLES - safeFixedBindCount) / safeBindCountPerItem)
)
);
}