| 353 | }, |
| 354 | |
| 355 | async createMany(table, values) { |
| 356 | const idField = table.getIdColumn().names.drizzle; |
| 357 | const drizzleTable = toDrizzle(table); |
| 358 | values = values.map((v) => mapValues(v, table)); |
| 359 | // A multi-row insert binds (rows * columns) parameters in one statement. |
| 360 | // Some engines cap bound parameters per query (Cloudflare D1: 100), so |
| 361 | // size the batch by PARAMETER count, not row count — otherwise a wide |
| 362 | // table (e.g. tools) overflows with "too many SQL variables". Engines |
| 363 | // without a tight cap keep the row-count batch. |
| 364 | const columnsPerRow = values.length > 0 ? Math.max(1, Object.keys(values[0]!).length) : 1; |
| 365 | const batchSize = maxBoundParameters |
| 366 | ? Math.max(1, Math.min(CREATE_MANY_BATCH_SIZE, Math.floor(maxBoundParameters / columnsPerRow))) |
| 367 | : CREATE_MANY_BATCH_SIZE; |
| 368 | const batches: (typeof values)[] = []; |
| 369 | for (let i = 0; i < values.length; i += batchSize) { |
| 370 | batches.push(values.slice(i, i + batchSize)); |
| 371 | } |
| 372 | |
| 373 | if (provider === "sqlite" || provider === "postgresql") { |
| 374 | const out: { _id: unknown }[] = []; |
| 375 | for (const batch of batches) { |
| 376 | out.push( |
| 377 | ...(await (db as unknown as P_DBType) |
| 378 | .insert(drizzleTable as unknown as P_TableType) |
| 379 | .values(batch) |
| 380 | .returning({ |
| 381 | _id: (drizzleTable as unknown as P_TableType)[idField], |
| 382 | })), |
| 383 | ); |
| 384 | } |
| 385 | return out; |
| 386 | } |
| 387 | |
| 388 | const results: Record<string, unknown>[] = []; |
| 389 | for (const batch of batches) { |
| 390 | results.push(...(await db.insert(drizzleTable).values(batch).$returningId())); |
| 391 | } |
| 392 | return results.map((result) => ({ _id: result[idField] })); |
| 393 | }, |
| 394 | |
| 395 | async deleteMany(table, v) { |
| 396 | const drizzleTable = toDrizzle(table); |