@@ -497,8 +497,42 @@ func (c *CrudBase[T]) InsertMany(ctx context.Context, instances []T, allowPartia
497497 }
498498 defer c .DB .RollbackTx (ctx , tx , autoCommit )
499499 if c .DB .Features ().MultiRowInsert {
500- insert := sq .Insert (c .Table ).Columns (c .Columns ... )
500+ if err := c .insertManyMultiRow (ctx , tx , instances , allowPartialSuccess ); err != nil {
501+ return err
502+ }
503+ } else {
501504 for _ , inst := range instances {
505+ err := c .attemptInsert (ctx , tx , inst , false )
506+ if err != nil {
507+ return err
508+ }
509+ }
510+ }
511+
512+ for _ , hook := range hooks {
513+ tx .AddPostCommitHook (hook )
514+ }
515+
516+ return c .DB .CommitTx (ctx , tx , autoCommit )
517+
518+ }
519+
520+ func (c * CrudBase [T ]) insertManyMultiRow (ctx context.Context , tx * TXWrapper , instances []T , allowPartialSuccess bool ) error {
521+ chunkSize := len (instances )
522+ if maxPlaceholders := c .DB .Features ().MaxPlaceholders ; maxPlaceholders > 0 && len (c .Columns ) > 0 {
523+ chunkSize = maxPlaceholders / len (c .Columns )
524+ }
525+
526+ allSequences := make ([]int64 , len (instances ))
527+ for offset := 0 ; offset < len (instances ); offset += chunkSize {
528+ end := offset + chunkSize
529+ if end > len (instances ) {
530+ end = len (instances )
531+ }
532+ chunk := instances [offset :end ]
533+
534+ insert := sq .Insert (c .Table ).Columns (c .Columns ... )
535+ for _ , inst := range chunk {
502536 c .setInsertTimestamps (inst , fftypes .Now ())
503537 values := make ([]interface {}, len (c .Columns ))
504538 for i , col := range c .Columns {
@@ -507,10 +541,9 @@ func (c *CrudBase[T]) InsertMany(ctx context.Context, instances []T, allowPartia
507541 insert = insert .Values (values ... )
508542 }
509543
510- // Use a single multi-row insert
511- sequences := make ([]int64 , len (instances ))
544+ sequences := allSequences [offset :end ]
512545 err := c .DB .InsertTxRows (ctx , c .Table , tx , insert , func () {
513- for _ , inst := range instances {
546+ for _ , inst := range chunk {
514547 if c .EventHandler != nil {
515548 c .EventHandler (inst .GetID (), Created )
516549 }
@@ -519,27 +552,12 @@ func (c *CrudBase[T]) InsertMany(ctx context.Context, instances []T, allowPartia
519552 if err != nil {
520553 return err
521554 }
522- if len (sequences ) == len (instances ) {
523- for i , seq := range sequences {
524- c .attemptSetSequence (instances [i ], seq )
525- }
526- }
527- } else {
528- // Fall back to individual inserts grouped in a TX
529- for _ , inst := range instances {
530- err := c .attemptInsert (ctx , tx , inst , false )
531- if err != nil {
532- return err
533- }
534- }
535555 }
536556
537- for _ , hook := range hooks {
538- tx . AddPostCommitHook ( hook )
557+ for i , seq := range allSequences {
558+ c . attemptSetSequence ( instances [ i ], seq )
539559 }
540-
541- return c .DB .CommitTx (ctx , tx , autoCommit )
542-
560+ return nil
543561}
544562
545563func (c * CrudBase [T ]) Insert (ctx context.Context , inst T , hooks ... PostCompletionHook ) (err error ) {
0 commit comments