mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-08-04 22:40:11 +00:00
fix(storage): safely batch folder deletion binds
This commit is contained in:
@@ -68,20 +68,22 @@ export async function bulkDeleteFolders(
|
|||||||
db: D1Database,
|
db: D1Database,
|
||||||
userId: string,
|
userId: string,
|
||||||
ids: string[],
|
ids: string[],
|
||||||
sqlChunkSize: (fixedBindCount: number) => number,
|
sqlChunkSize: (fixedBindCount: number, bindCountPerItem?: number) => number,
|
||||||
updateRevisionDate: (userId: string) => Promise<string>
|
updateRevisionDate: (userId: string) => Promise<string>
|
||||||
): Promise<string | null> {
|
): Promise<string | null> {
|
||||||
const uniqueIds = Array.from(new Set(ids.map((id) => String(id || '').trim()).filter(Boolean)));
|
const uniqueIds = Array.from(new Set(ids.map((id) => String(id || '').trim()).filter(Boolean)));
|
||||||
if (!uniqueIds.length) return null;
|
if (!uniqueIds.length) return null;
|
||||||
|
|
||||||
const now = new Date().toISOString();
|
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) {
|
for (let i = 0; i < uniqueIds.length; i += chunkSize) {
|
||||||
const chunk = uniqueIds.slice(i, i + chunkSize);
|
const chunk = uniqueIds.slice(i, i + chunkSize);
|
||||||
const placeholders = chunk.map(() => '?').join(',');
|
const placeholders = chunk.map(() => '?').join(',');
|
||||||
await db
|
statements.push(
|
||||||
.prepare(
|
db.prepare(
|
||||||
`UPDATE ciphers
|
`UPDATE ciphers
|
||||||
SET folder_id = NULL, updated_at = ?,
|
SET folder_id = NULL, updated_at = ?,
|
||||||
data = json_remove(data, '$.folderId', '$.folder_id', '$.updatedAt', '$.revisionDate')
|
data = json_remove(data, '$.folderId', '$.folder_id', '$.updatedAt', '$.revisionDate')
|
||||||
@@ -93,14 +95,15 @@ export async function bulkDeleteFolders(
|
|||||||
)`
|
)`
|
||||||
)
|
)
|
||||||
.bind(now, userId, ...chunk, ...chunk, ...chunk)
|
.bind(now, userId, ...chunk, ...chunk, ...chunk)
|
||||||
.run();
|
);
|
||||||
|
statements.push(
|
||||||
await db
|
db.prepare(`DELETE FROM folders WHERE user_id = ? AND id IN (${placeholders})`)
|
||||||
.prepare(`DELETE FROM folders WHERE user_id = ? AND id IN (${placeholders})`)
|
|
||||||
.bind(userId, ...chunk)
|
.bind(userId, ...chunk)
|
||||||
.run();
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await db.batch(statements);
|
||||||
|
|
||||||
return updateRevisionDate(userId);
|
return updateRevisionDate(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,10 +209,15 @@ export class StorageService {
|
|||||||
return REQUIRED_SCHEMA_TABLES.every((table) => found.has(table));
|
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(
|
return Math.max(
|
||||||
1,
|
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