@@ -174,3 +174,135 @@ func Test_Changeset_OneRow(t *testing.T) {
174
174
t .Fatalf ("Failed to finalize changeset iterator: %v" , err )
175
175
}
176
176
}
177
+
178
+ func Test_Changeset_Multi (t * testing.T ) {
179
+ db , err := sql .Open ("sqlite3" , ":memory:" )
180
+ if err != nil {
181
+ t .Fatal ("Failed to open" , err )
182
+ }
183
+ err = db .Ping ()
184
+ if err != nil {
185
+ t .Fatal ("Failed to ping" , err )
186
+ }
187
+ defer db .Close ()
188
+
189
+ ctx := context .Background ()
190
+ conn , err := db .Conn (ctx )
191
+ if err != nil {
192
+ t .Fatal ("Failed to get connection to database:" , err )
193
+ }
194
+ defer conn .Close ()
195
+
196
+ // Create tables, and attach a session.
197
+ mustExecute (conn , `CREATE TABLE table1 (id INTEGER PRIMARY KEY, name TEXT, gpa FLOAT, alive boolean)` )
198
+ mustExecute (conn , `CREATE TABLE table2 (id INTEGER PRIMARY KEY, age INTEGER)` )
199
+ var session * Session
200
+ if err := conn .Raw (func (raw any ) error {
201
+ var err error
202
+ session , err = raw .(* SQLiteConn ).CreateSession ("main" )
203
+ return err
204
+ }); err != nil {
205
+ t .Fatal ("Failed to create session:" , err )
206
+ }
207
+ defer func () {
208
+ if err := session .DeleteSession (); err != nil {
209
+ t .Fatalf ("Failed to delete session: %v" , err )
210
+ }
211
+ }()
212
+ err = session .AttachSession ("" )
213
+ if err != nil {
214
+ t .Fatalf ("Failed to attach session to table: %v" , err )
215
+ }
216
+
217
+ // Make a bunch of changes.
218
+ mustExecute (conn , `INSERT INTO table1 (name, gpa, alive) VALUES ('fiona', 3.5, 1)` )
219
+ mustExecute (conn , `INSERT INTO table1 (name, gpa, alive) VALUES ('declan', 2.5, 0)` )
220
+ mustExecute (conn , `INSERT INTO table2 (age) VALUES (20)` )
221
+ mustExecute (conn , `INSERT INTO table2 (age) VALUES (30)` )
222
+
223
+ // Prepare to iterate over the changes.
224
+ changeset , err := NewChangeset (session )
225
+ if err != nil {
226
+ t .Fatalf ("Failed to generate changeset: %v" , err )
227
+ }
228
+ iter , err := NewChangesetIterator (changeset )
229
+ if err != nil {
230
+ t .Fatalf ("Failed to create changeset iterator: %v" , err )
231
+ }
232
+
233
+ tt := []struct {
234
+ table string
235
+ op int
236
+ data []any
237
+ }{
238
+ {
239
+ table : "table1" ,
240
+ op : SQLITE_INSERT ,
241
+ data : []any {int64 (1 ), "fiona" , 3.5 , int64 (1 )},
242
+ },
243
+ {
244
+ table : "table1" ,
245
+ op : SQLITE_INSERT ,
246
+ data : []any {int64 (2 ), "declan" , 2.5 , int64 (0 )},
247
+ },
248
+ {
249
+ table : "table2" ,
250
+ op : SQLITE_INSERT ,
251
+ data : []any {int64 (1 ), int64 (20 )},
252
+ },
253
+ {
254
+ table : "table2" ,
255
+ op : SQLITE_INSERT ,
256
+ data : []any {int64 (2 ), int64 (30 )},
257
+ },
258
+ }
259
+
260
+ for _ , v := range tt {
261
+ if b , err := iter .Next (); err != nil {
262
+ t .Fatalf ("Failed to get next changeset: %v" , err )
263
+ } else if ! b {
264
+ t .Fatalf ("changeset does not contain changes: %v" , b )
265
+ }
266
+
267
+ tblName , nCol , op , _ , err := iter .Op ()
268
+ if err != nil {
269
+ t .Fatalf ("Failed to get changeset operation: %v" , err )
270
+ }
271
+ if exp , got := v .table , tblName ; exp != got {
272
+ t .Fatalf ("Expected table name '%s', got '%s'" , exp , got )
273
+ }
274
+ if exp , got := len (v .data ), nCol ; exp != got {
275
+ t .Fatalf ("Expected %d columns, got %d" , exp , got )
276
+ }
277
+ if exp , got := v .op , op ; exp != got {
278
+ t .Fatalf ("Expected operation %d, got %d" , exp , got )
279
+ }
280
+
281
+ dest := make ([]any , nCol )
282
+ if err := iter .New (dest ); err != nil {
283
+ t .Fatalf ("Failed to get new row: %v" , err )
284
+ }
285
+ for j , d := range v .data {
286
+ if exp , got := d , dest [j ]; exp != got {
287
+ t .Fatalf ("Expected %v (%T) for dest[%d], got %v (%T)" , exp , exp , j , got , got )
288
+ }
289
+ }
290
+ }
291
+
292
+ if b , err := iter .Next (); err != nil {
293
+ t .Fatalf ("Failed to get next changeset: %v" , err )
294
+ } else if b {
295
+ t .Fatalf ("changeset contains changes: %v" , b )
296
+ }
297
+
298
+ if err := iter .Finalize (); err != nil {
299
+ t .Fatalf ("Failed to finalize changeset iterator: %v" , err )
300
+ }
301
+ }
302
+
303
+ func mustExecute (conn * sql.Conn , stmt string ) {
304
+ _ , err := conn .ExecContext (context .Background (), stmt )
305
+ if err != nil {
306
+ panic (err )
307
+ }
308
+ }
0 commit comments