@@ -200,126 +200,209 @@ impl<'stmt, 'query> Field<'stmt, Sqlite> for SqliteField<'stmt, 'query> {
200
200
}
201
201
}
202
202
203
- #[ test]
204
- fn fun_with_row_iters ( ) {
205
- crate :: table! {
206
- #[ allow( unused_parens) ]
207
- users( id) {
208
- id -> Integer ,
209
- name -> Text ,
203
+ #[ cfg( test) ]
204
+ mod tests {
205
+ use super :: * ;
206
+
207
+ #[ test]
208
+ fn fun_with_row_iters ( ) {
209
+ crate :: table! {
210
+ #[ allow( unused_parens) ]
211
+ users( id) {
212
+ id -> Integer ,
213
+ name -> Text ,
214
+ }
210
215
}
211
- }
212
216
213
- use crate :: connection:: LoadConnection ;
214
- use crate :: deserialize:: { FromSql , FromSqlRow } ;
215
- use crate :: prelude:: * ;
216
- use crate :: row:: { Field , Row } ;
217
- use crate :: sql_types;
217
+ use crate :: connection:: LoadConnection ;
218
+ use crate :: deserialize:: { FromSql , FromSqlRow } ;
219
+ use crate :: prelude:: * ;
220
+ use crate :: row:: { Field , Row } ;
221
+ use crate :: sql_types;
218
222
219
- let conn = & mut crate :: test_helpers:: connection ( ) ;
223
+ let conn = & mut crate :: test_helpers:: connection ( ) ;
220
224
221
- crate :: sql_query ( "CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT NOT NULL);" )
222
- . execute ( conn)
223
- . unwrap ( ) ;
225
+ crate :: sql_query ( "CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT NOT NULL);" )
226
+ . execute ( conn)
227
+ . unwrap ( ) ;
224
228
225
- crate :: insert_into ( users:: table)
226
- . values ( vec ! [
227
- ( users:: id. eq( 1 ) , users:: name. eq( "Sean" ) ) ,
228
- ( users:: id. eq( 2 ) , users:: name. eq( "Tess" ) ) ,
229
- ] )
230
- . execute ( conn)
231
- . unwrap ( ) ;
229
+ crate :: insert_into ( users:: table)
230
+ . values ( vec ! [
231
+ ( users:: id. eq( 1 ) , users:: name. eq( "Sean" ) ) ,
232
+ ( users:: id. eq( 2 ) , users:: name. eq( "Tess" ) ) ,
233
+ ] )
234
+ . execute ( conn)
235
+ . unwrap ( ) ;
232
236
233
- let query = users:: table. select ( ( users:: id, users:: name) ) ;
237
+ let query = users:: table. select ( ( users:: id, users:: name) ) ;
234
238
235
- let expected = vec ! [ ( 1 , String :: from( "Sean" ) ) , ( 2 , String :: from( "Tess" ) ) ] ;
239
+ let expected = vec ! [ ( 1 , String :: from( "Sean" ) ) , ( 2 , String :: from( "Tess" ) ) ] ;
236
240
237
- let row_iter = conn. load ( query) . unwrap ( ) ;
238
- for ( row, expected) in row_iter. zip ( & expected) {
239
- let row = row. unwrap ( ) ;
241
+ let row_iter = conn. load ( query) . unwrap ( ) ;
242
+ for ( row, expected) in row_iter. zip ( & expected) {
243
+ let row = row. unwrap ( ) ;
240
244
241
- let deserialized = <( i32 , String ) as FromSqlRow <
242
- ( sql_types:: Integer , sql_types:: Text ) ,
243
- _ ,
244
- > >:: build_from_row ( & row)
245
- . unwrap ( ) ;
245
+ let deserialized = <( i32 , String ) as FromSqlRow <
246
+ ( sql_types:: Integer , sql_types:: Text ) ,
247
+ _ ,
248
+ > >:: build_from_row ( & row)
249
+ . unwrap ( ) ;
246
250
247
- assert_eq ! ( & deserialized, expected) ;
248
- }
251
+ assert_eq ! ( & deserialized, expected) ;
252
+ }
249
253
250
- {
251
- let collected_rows = conn. load ( query) . unwrap ( ) . collect :: < Vec < _ > > ( ) ;
254
+ {
255
+ let collected_rows = conn. load ( query) . unwrap ( ) . collect :: < Vec < _ > > ( ) ;
252
256
253
- for ( row, expected) in collected_rows. iter ( ) . zip ( & expected) {
254
- let deserialized = row
255
- . as_ref ( )
256
- . map ( |row| {
257
- <( i32 , String ) as FromSqlRow <
257
+ for ( row, expected) in collected_rows. iter ( ) . zip ( & expected) {
258
+ let deserialized = row
259
+ . as_ref ( )
260
+ . map ( |row| {
261
+ <( i32 , String ) as FromSqlRow <
258
262
( sql_types:: Integer , sql_types:: Text ) ,
259
263
_ ,
260
264
> >:: build_from_row ( row) . unwrap ( )
261
- } )
262
- . unwrap ( ) ;
265
+ } )
266
+ . unwrap ( ) ;
263
267
264
- assert_eq ! ( & deserialized, expected) ;
268
+ assert_eq ! ( & deserialized, expected) ;
269
+ }
265
270
}
271
+
272
+ let mut row_iter = conn. load ( query) . unwrap ( ) ;
273
+
274
+ let first_row = row_iter. next ( ) . unwrap ( ) . unwrap ( ) ;
275
+ let first_fields = ( first_row. get ( 0 ) . unwrap ( ) , first_row. get ( 1 ) . unwrap ( ) ) ;
276
+ let first_values = ( first_fields. 0 . value ( ) , first_fields. 1 . value ( ) ) ;
277
+
278
+ assert ! ( row_iter. next( ) . unwrap( ) . is_err( ) ) ;
279
+ std:: mem:: drop ( first_values) ;
280
+ assert ! ( row_iter. next( ) . unwrap( ) . is_err( ) ) ;
281
+ std:: mem:: drop ( first_fields) ;
282
+
283
+ let second_row = row_iter. next ( ) . unwrap ( ) . unwrap ( ) ;
284
+ let second_fields = ( second_row. get ( 0 ) . unwrap ( ) , second_row. get ( 1 ) . unwrap ( ) ) ;
285
+ let second_values = ( second_fields. 0 . value ( ) , second_fields. 1 . value ( ) ) ;
286
+
287
+ assert ! ( row_iter. next( ) . unwrap( ) . is_err( ) ) ;
288
+ std:: mem:: drop ( second_values) ;
289
+ assert ! ( row_iter. next( ) . unwrap( ) . is_err( ) ) ;
290
+ std:: mem:: drop ( second_fields) ;
291
+
292
+ assert ! ( row_iter. next( ) . is_none( ) ) ;
293
+
294
+ let first_fields = ( first_row. get ( 0 ) . unwrap ( ) , first_row. get ( 1 ) . unwrap ( ) ) ;
295
+ let second_fields = ( second_row. get ( 0 ) . unwrap ( ) , second_row. get ( 1 ) . unwrap ( ) ) ;
296
+
297
+ let first_values = ( first_fields. 0 . value ( ) , first_fields. 1 . value ( ) ) ;
298
+ let second_values = ( second_fields. 0 . value ( ) , second_fields. 1 . value ( ) ) ;
299
+
300
+ assert_eq ! (
301
+ <i32 as FromSql <sql_types:: Integer , Sqlite >>:: from_nullable_sql( first_values. 0 )
302
+ . unwrap( ) ,
303
+ expected[ 0 ] . 0
304
+ ) ;
305
+ assert_eq ! (
306
+ <String as FromSql <sql_types:: Text , Sqlite >>:: from_nullable_sql( first_values. 1 )
307
+ . unwrap( ) ,
308
+ expected[ 0 ] . 1
309
+ ) ;
310
+
311
+ assert_eq ! (
312
+ <i32 as FromSql <sql_types:: Integer , Sqlite >>:: from_nullable_sql( second_values. 0 )
313
+ . unwrap( ) ,
314
+ expected[ 1 ] . 0
315
+ ) ;
316
+ assert_eq ! (
317
+ <String as FromSql <sql_types:: Text , Sqlite >>:: from_nullable_sql( second_values. 1 )
318
+ . unwrap( ) ,
319
+ expected[ 1 ] . 1
320
+ ) ;
321
+
322
+ let first_fields = ( first_row. get ( 0 ) . unwrap ( ) , first_row. get ( 1 ) . unwrap ( ) ) ;
323
+ let first_values = ( first_fields. 0 . value ( ) , first_fields. 1 . value ( ) ) ;
324
+
325
+ assert_eq ! (
326
+ <i32 as FromSql <sql_types:: Integer , Sqlite >>:: from_nullable_sql( first_values. 0 )
327
+ . unwrap( ) ,
328
+ expected[ 0 ] . 0
329
+ ) ;
330
+ assert_eq ! (
331
+ <String as FromSql <sql_types:: Text , Sqlite >>:: from_nullable_sql( first_values. 1 )
332
+ . unwrap( ) ,
333
+ expected[ 0 ] . 1
334
+ ) ;
266
335
}
267
336
268
- let mut row_iter = conn. load ( query) . unwrap ( ) ;
269
-
270
- let first_row = row_iter. next ( ) . unwrap ( ) . unwrap ( ) ;
271
- let first_fields = ( first_row. get ( 0 ) . unwrap ( ) , first_row. get ( 1 ) . unwrap ( ) ) ;
272
- let first_values = ( first_fields. 0 . value ( ) , first_fields. 1 . value ( ) ) ;
273
-
274
- assert ! ( row_iter. next( ) . unwrap( ) . is_err( ) ) ;
275
- std:: mem:: drop ( first_values) ;
276
- assert ! ( row_iter. next( ) . unwrap( ) . is_err( ) ) ;
277
- std:: mem:: drop ( first_fields) ;
278
-
279
- let second_row = row_iter. next ( ) . unwrap ( ) . unwrap ( ) ;
280
- let second_fields = ( second_row. get ( 0 ) . unwrap ( ) , second_row. get ( 1 ) . unwrap ( ) ) ;
281
- let second_values = ( second_fields. 0 . value ( ) , second_fields. 1 . value ( ) ) ;
282
-
283
- assert ! ( row_iter. next( ) . unwrap( ) . is_err( ) ) ;
284
- std:: mem:: drop ( second_values) ;
285
- assert ! ( row_iter. next( ) . unwrap( ) . is_err( ) ) ;
286
- std:: mem:: drop ( second_fields) ;
287
-
288
- assert ! ( row_iter. next( ) . is_none( ) ) ;
289
-
290
- let first_fields = ( first_row. get ( 0 ) . unwrap ( ) , first_row. get ( 1 ) . unwrap ( ) ) ;
291
- let second_fields = ( second_row. get ( 0 ) . unwrap ( ) , second_row. get ( 1 ) . unwrap ( ) ) ;
292
-
293
- let first_values = ( first_fields. 0 . value ( ) , first_fields. 1 . value ( ) ) ;
294
- let second_values = ( second_fields. 0 . value ( ) , second_fields. 1 . value ( ) ) ;
295
-
296
- assert_eq ! (
297
- <i32 as FromSql <sql_types:: Integer , Sqlite >>:: from_nullable_sql( first_values. 0 ) . unwrap( ) ,
298
- expected[ 0 ] . 0
299
- ) ;
300
- assert_eq ! (
301
- <String as FromSql <sql_types:: Text , Sqlite >>:: from_nullable_sql( first_values. 1 ) . unwrap( ) ,
302
- expected[ 0 ] . 1
303
- ) ;
304
-
305
- assert_eq ! (
306
- <i32 as FromSql <sql_types:: Integer , Sqlite >>:: from_nullable_sql( second_values. 0 ) . unwrap( ) ,
307
- expected[ 1 ] . 0
308
- ) ;
309
- assert_eq ! (
310
- <String as FromSql <sql_types:: Text , Sqlite >>:: from_nullable_sql( second_values. 1 ) . unwrap( ) ,
311
- expected[ 1 ] . 1
312
- ) ;
313
-
314
- let first_fields = ( first_row. get ( 0 ) . unwrap ( ) , first_row. get ( 1 ) . unwrap ( ) ) ;
315
- let first_values = ( first_fields. 0 . value ( ) , first_fields. 1 . value ( ) ) ;
316
-
317
- assert_eq ! (
318
- <i32 as FromSql <sql_types:: Integer , Sqlite >>:: from_nullable_sql( first_values. 0 ) . unwrap( ) ,
319
- expected[ 0 ] . 0
320
- ) ;
321
- assert_eq ! (
322
- <String as FromSql <sql_types:: Text , Sqlite >>:: from_nullable_sql( first_values. 1 ) . unwrap( ) ,
323
- expected[ 0 ] . 1
324
- ) ;
337
+ #[ cfg( feature = "returning_clauses_for_sqlite_3_35" ) ]
338
+ crate :: define_sql_function! { fn sleep( a: diesel:: sql_types:: Integer ) -> diesel:: sql_types:: Integer }
339
+
340
+ #[ test]
341
+ #[ cfg( feature = "returning_clauses_for_sqlite_3_35" ) ]
342
+ fn parallel_iter_with_error ( ) {
343
+ use crate :: connection:: Connection ;
344
+ use crate :: connection:: LoadConnection ;
345
+ use crate :: connection:: SimpleConnection ;
346
+ use crate :: expression_methods:: ExpressionMethods ;
347
+ use crate :: SqliteConnection ;
348
+ use std:: sync:: { Arc , Barrier } ;
349
+ use std:: time:: Duration ;
350
+
351
+ let temp_dir = tempfile:: tempdir ( ) . unwrap ( ) ;
352
+ let db_path = format ! ( "{}/test.db" , temp_dir. path( ) . display( ) ) ;
353
+ let mut conn1 = SqliteConnection :: establish ( & db_path) . unwrap ( ) ;
354
+ let mut conn2 = SqliteConnection :: establish ( & db_path) . unwrap ( ) ;
355
+
356
+ crate :: table! {
357
+ users {
358
+ id -> Integer ,
359
+ name -> Text ,
360
+ }
361
+ }
362
+
363
+ conn1
364
+ . batch_execute ( "CREATE TABLE users(id INTEGER NOT NULL PRIMARY KEY, name TEXT)" )
365
+ . unwrap ( ) ;
366
+
367
+ let barrier = Arc :: new ( Barrier :: new ( 2 ) ) ;
368
+ let barrier2 = barrier. clone ( ) ;
369
+
370
+ // we unblock the main thread from the sleep function
371
+ sleep_utils:: register_impl ( & mut conn2, move |a : i32 | {
372
+ barrier. wait ( ) ;
373
+ std:: thread:: sleep ( Duration :: from_secs ( a as u64 ) ) ;
374
+ a
375
+ } )
376
+ . unwrap ( ) ;
377
+
378
+ // spawn a background thread that locks the database file
379
+ let handle = std:: thread:: spawn ( move || {
380
+ use crate :: query_dsl:: RunQueryDsl ;
381
+
382
+ conn2
383
+ . immediate_transaction ( |conn| diesel:: select ( sleep ( 1 ) ) . execute ( conn) )
384
+ . unwrap ( ) ;
385
+ } ) ;
386
+ barrier2. wait ( ) ;
387
+
388
+ // execute some action that also requires a lock
389
+ let mut iter = conn1
390
+ . load (
391
+ diesel:: insert_into ( users:: table)
392
+ . values ( ( users:: id. eq ( 1 ) , users:: name. eq ( "John" ) ) )
393
+ . returning ( users:: id) ,
394
+ )
395
+ . unwrap ( ) ;
396
+
397
+ // get the first iterator result, that should return the lock error
398
+ let n = iter. next ( ) . unwrap ( ) ;
399
+ assert ! ( n. is_err( ) ) ;
400
+
401
+ // check that the iterator is now empty
402
+ let n = iter. next ( ) ;
403
+ assert ! ( n. is_none( ) ) ;
404
+
405
+ // join the background thread
406
+ handle. join ( ) . unwrap ( ) ;
407
+ }
325
408
}
0 commit comments