mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-08-05 06:50:10 +00:00
fix(storage): safely batch folder deletion binds
This commit is contained in:
@@ -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})`)
|
||||
.bind(userId, ...chunk)
|
||||
.run();
|
||||
);
|
||||
statements.push(
|
||||
db.prepare(`DELETE FROM folders WHERE user_id = ? AND id IN (${placeholders})`)
|
||||
.bind(userId, ...chunk)
|
||||
);
|
||||
}
|
||||
|
||||
await db.batch(statements);
|
||||
|
||||
return updateRevisionDate(userId);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user