* Create multiple new items at once. Inserts all provided records sequentially wrapped in a transaction. * * Uses `this.createOne` under the hood.
(data: Partial<Item>[], opts: MutationOptions = {})
| 442 | * Uses `this.createOne` under the hood. |
| 443 | */ |
| 444 | async createMany(data: Partial<Item>[], opts: MutationOptions = {}): Promise<PrimaryKey[]> { |
| 445 | if (!opts.mutationTracker) opts.mutationTracker = this.createMutationTracker(); |
| 446 | |
| 447 | if (this.collection === 'directus_users') { |
| 448 | opts.userIntegrityCheckFlags = |
| 449 | (opts.userIntegrityCheckFlags ?? UserIntegrityCheckFlag.None) | UserIntegrityCheckFlag.UserLimits; |
| 450 | } |
| 451 | |
| 452 | const { primaryKeys, nestedActionEvents } = await transaction(this.knex, async (knex) => { |
| 453 | const previousSeatCount = await captureSeatCount(knex, opts.userIntegrityCheckFlags); |
| 454 | |
| 455 | const service = this.fork({ knex }); |
| 456 | |
| 457 | let userIntegrityCheckFlags = opts.userIntegrityCheckFlags ?? UserIntegrityCheckFlag.None; |
| 458 | |
| 459 | const primaryKeys: PrimaryKey[] = []; |
| 460 | const nestedActionEvents: ActionEventParams[] = []; |
| 461 | |
| 462 | const pkField = this.schema.collections[this.collection]!.primary; |
| 463 | |
| 464 | for (const [index, payload] of data.entries()) { |
| 465 | let bypassAutoIncrementSequenceReset = true; |
| 466 | |
| 467 | // the auto_increment sequence needs to be reset if the current item contains a manual PK and |
| 468 | // if it's the last item of the batch or if the next item doesn't include a PK and hence one needs to be generated |
| 469 | if (payload[pkField] && (index === data.length - 1 || !data[index + 1]?.[pkField])) { |
| 470 | bypassAutoIncrementSequenceReset = false; |
| 471 | } |
| 472 | |
| 473 | const primaryKey = await service.createOne(payload, { |
| 474 | ...(opts || {}), |
| 475 | autoPurgeCache: false, |
| 476 | onRequireUserIntegrityCheck: (flags) => (userIntegrityCheckFlags |= flags), |
| 477 | bypassEmitAction: (params) => nestedActionEvents.push(params), |
| 478 | mutationTracker: opts.mutationTracker, |
| 479 | overwriteDefaults: opts.overwriteDefaults?.[index], |
| 480 | bypassAutoIncrementSequenceReset, |
| 481 | }); |
| 482 | |
| 483 | primaryKeys.push(primaryKey); |
| 484 | } |
| 485 | |
| 486 | if (userIntegrityCheckFlags) { |
| 487 | if (opts.onRequireUserIntegrityCheck) { |
| 488 | opts.onRequireUserIntegrityCheck(userIntegrityCheckFlags); |
| 489 | } else { |
| 490 | await validateUserCountIntegrity({ |
| 491 | flags: userIntegrityCheckFlags, |
| 492 | knex, |
| 493 | previousSeatCount, |
| 494 | }); |
| 495 | } |
| 496 | } |
| 497 | |
| 498 | return { primaryKeys, nestedActionEvents }; |
| 499 | }); |
| 500 | |
| 501 | if (opts.emitEvents !== false) { |
no test coverage detected