@@ -1013,6 +1013,157 @@ func TestInsertManyMultiRowFail(t *testing.T) {
10131013 assert .NoError (t , mock .ExpectationsWereMet ())
10141014}
10151015
1016+ func TestInsertManyMultiRowChunkedOK (t * testing.T ) {
1017+ mp := NewMockProvider ()
1018+ mp .MultiRowInsert = true
1019+ mp .MaxPlaceholders = 22 // 11 columns per row, so 2 rows per chunk
1020+ db , mock := mp .UTInit ()
1021+ db .FakePSQLInsert = true
1022+ tc := newCRUDCollection (& db .Database , "ns1" )
1023+ mock .ExpectBegin ()
1024+ // First chunk: 2 rows
1025+ mock .ExpectQuery (`INSERT INTO crudables.*VALUES \(.*\),\(.*\)` ).WillReturnRows (
1026+ sqlmock .NewRows ([]string {db .sequenceColumn }).
1027+ AddRow (101 ).
1028+ AddRow (102 ),
1029+ )
1030+ // Second chunk: 1 row
1031+ mock .ExpectQuery (`INSERT INTO crudables.*VALUES \(.*\)` ).WillReturnRows (
1032+ sqlmock .NewRows ([]string {db .sequenceColumn }).
1033+ AddRow (103 ),
1034+ )
1035+ mock .ExpectCommit ()
1036+ err := tc .InsertMany (context .Background (), []* TestCRUDable {
1037+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1038+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1039+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1040+ }, false )
1041+ assert .NoError (t , err )
1042+ assert .NoError (t , mock .ExpectationsWereMet ())
1043+ }
1044+
1045+ func TestInsertManyMultiRowChunkedFailSecondChunk (t * testing.T ) {
1046+ mp := NewMockProvider ()
1047+ mp .MultiRowInsert = true
1048+ mp .MaxPlaceholders = 22
1049+ db , mock := mp .UTInit ()
1050+ db .FakePSQLInsert = true
1051+ tc := newCRUDCollection (& db .Database , "ns1" )
1052+ mock .ExpectBegin ()
1053+ mock .ExpectQuery (`INSERT INTO crudables.*VALUES \(.*\),\(.*\)` ).WillReturnRows (
1054+ sqlmock .NewRows ([]string {db .sequenceColumn }).
1055+ AddRow (101 ).
1056+ AddRow (102 ),
1057+ )
1058+ mock .ExpectQuery (`INSERT INTO crudables.*VALUES \(.*\)` ).WillReturnError (fmt .Errorf ("pop" ))
1059+ err := tc .InsertMany (context .Background (), []* TestCRUDable {
1060+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1061+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1062+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1063+ }, false )
1064+ assert .Regexp (t , "FF00177" , err )
1065+ assert .NoError (t , mock .ExpectationsWereMet ())
1066+ }
1067+
1068+ func TestInsertManyMultiRowNoChunkingWhenUnderLimit (t * testing.T ) {
1069+ mp := NewMockProvider ()
1070+ mp .MultiRowInsert = true
1071+ mp .MaxPlaceholders = 100 // 11 columns * 2 rows = 22, well under 100
1072+ db , mock := mp .UTInit ()
1073+ db .FakePSQLInsert = true
1074+ tc := newCRUDCollection (& db .Database , "ns1" )
1075+ mock .ExpectBegin ()
1076+ mock .ExpectQuery (`INSERT INTO crudables.*VALUES \(.*\),\(.*\)` ).WillReturnRows (
1077+ sqlmock .NewRows ([]string {db .sequenceColumn }).
1078+ AddRow (201 ).
1079+ AddRow (202 ),
1080+ )
1081+ mock .ExpectCommit ()
1082+ err := tc .InsertMany (context .Background (), []* TestCRUDable {
1083+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1084+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1085+ }, false )
1086+ assert .NoError (t , err )
1087+ assert .NoError (t , mock .ExpectationsWereMet ())
1088+ }
1089+
1090+ func TestInsertManyArrayInsertOK (t * testing.T ) {
1091+ mp := NewMockProvider ()
1092+ mp .FakePSQLArrayInsert = true
1093+ db , mock := mp .UTInit ()
1094+ tc := newCRUDCollection (& db .Database , "ns1" )
1095+ mock .ExpectBegin ()
1096+ mock .ExpectQuery (`INSERT INTO crudables .* SELECT UNNEST.*RETURNING seq` ).WillReturnRows (
1097+ sqlmock .NewRows ([]string {db .sequenceColumn }).
1098+ AddRow (301 ).
1099+ AddRow (302 ),
1100+ )
1101+ mock .ExpectCommit ()
1102+ err := tc .InsertMany (context .Background (), []* TestCRUDable {
1103+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1104+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1105+ }, false )
1106+ assert .NoError (t , err )
1107+ assert .NoError (t , mock .ExpectationsWereMet ())
1108+ }
1109+
1110+ func TestInsertManyArrayInsertFail (t * testing.T ) {
1111+ mp := NewMockProvider ()
1112+ mp .FakePSQLArrayInsert = true
1113+ db , mock := mp .UTInit ()
1114+ tc := newCRUDCollection (& db .Database , "ns1" )
1115+ mock .ExpectBegin ()
1116+ mock .ExpectQuery (`INSERT INTO crudables .* SELECT UNNEST.*` ).WillReturnError (fmt .Errorf ("pop" ))
1117+ err := tc .InsertMany (context .Background (), []* TestCRUDable {
1118+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1119+ }, false )
1120+ assert .Regexp (t , "FF00177" , err )
1121+ assert .NoError (t , mock .ExpectationsWereMet ())
1122+ }
1123+
1124+ func TestInsertManyArrayInsertPrefersOverMultiRow (t * testing.T ) {
1125+ mp := NewMockProvider ()
1126+ mp .FakePSQLArrayInsert = true
1127+ mp .MultiRowInsert = true
1128+ db , mock := mp .UTInit ()
1129+ tc := newCRUDCollection (& db .Database , "ns1" )
1130+ mock .ExpectBegin ()
1131+ // Should use UNNEST, not multi-row VALUES
1132+ mock .ExpectQuery (`INSERT INTO crudables .* SELECT UNNEST.*RETURNING seq` ).WillReturnRows (
1133+ sqlmock .NewRows ([]string {db .sequenceColumn }).
1134+ AddRow (401 ),
1135+ )
1136+ mock .ExpectCommit ()
1137+ err := tc .InsertMany (context .Background (), []* TestCRUDable {
1138+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1139+ }, false )
1140+ assert .NoError (t , err )
1141+ assert .NoError (t , mock .ExpectationsWereMet ())
1142+ }
1143+
1144+ func TestInsertManyArrayInsertWithEvents (t * testing.T ) {
1145+ mp := NewMockProvider ()
1146+ mp .FakePSQLArrayInsert = true
1147+ db , mock := mp .UTInit ()
1148+ tc := newCRUDCollection (& db .Database , "ns1" )
1149+ mock .ExpectBegin ()
1150+ mock .ExpectQuery (`INSERT INTO crudables .* SELECT UNNEST.*RETURNING seq` ).WillReturnRows (
1151+ sqlmock .NewRows ([]string {db .sequenceColumn }).
1152+ AddRow (501 ).
1153+ AddRow (502 ),
1154+ )
1155+ mock .ExpectCommit ()
1156+ err := tc .InsertMany (context .Background (), []* TestCRUDable {
1157+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1158+ {ResourceBase : ResourceBase {ID : fftypes .NewUUID ()}},
1159+ }, false )
1160+ assert .NoError (t , err )
1161+ assert .Equal (t , 2 , len (tc .events ))
1162+ assert .Equal (t , Created , tc .events [0 ])
1163+ assert .Equal (t , Created , tc .events [1 ])
1164+ assert .NoError (t , mock .ExpectationsWereMet ())
1165+ }
1166+
10161167func TestInsertManyFallbackSingleRowFail (t * testing.T ) {
10171168 db , mock := NewMockProvider ().UTInit ()
10181169 tc := newCRUDCollection (& db .Database , "ns1" )
0 commit comments