@@ -357,31 +357,43 @@ public final class Connection {
357
357
/// times it’s been called for this lock. If it returns `true`, it will
358
358
/// try again. If it returns `false`, no further attempts will be made.
359
359
public func busyHandler( callback: ( ( tries: Int ) -> Bool ) ? ) {
360
- if let callback = callback {
361
- busyHandler = { callback ( tries: Int ( $0) ) ? 1 : 0 }
362
- } else {
360
+ guard let callback = callback else {
361
+ sqlite3_busy_handler ( handle, nil , nil )
363
362
busyHandler = nil
363
+ return
364
364
}
365
+
366
+ let box : BusyHandler = { callback ( tries: Int ( $0) ) ? 1 : 0 }
367
+ sqlite3_busy_handler ( handle, { callback, tries in
368
+ unsafeBitCast ( callback, BusyHandler . self) ( tries)
369
+ } , unsafeBitCast ( box, UnsafeMutablePointer< Void> . self ) )
370
+ busyHandler = box
365
371
}
366
- private var busyHandler : _SQLiteBusyHandlerCallback ?
372
+ private typealias BusyHandler = @convention ( block) Int32 -> Int32
373
+ private var busyHandler : BusyHandler ?
367
374
368
375
/// Sets a handler to call when a statement is executed with the compiled
369
376
/// SQL.
370
377
///
371
378
/// - Parameter callback: This block is invoked when a statement is executed
372
- /// with the compiled SQL as its argument. E.g., pass `print` to act as a
373
- /// logger.
379
+ /// with the compiled SQL as its argument.
374
380
///
375
- /// db.trace( print)
381
+ /// db.trace { SQL in print(SQL) }
376
382
public func trace( callback: ( String -> Void ) ? ) {
377
- if let callback = callback {
378
- trace = { callback ( String . fromCString ( $0) !) }
379
- } else {
383
+ guard let callback = callback else {
384
+ sqlite3_trace ( handle, nil , nil )
380
385
trace = nil
386
+ return
381
387
}
382
- _SQLiteTrace ( handle, trace)
388
+
389
+ let box : Trace = { callback ( String . fromCString ( $0) !) }
390
+ sqlite3_trace ( handle, { callback, SQL in
391
+ unsafeBitCast ( callback, Trace . self) ( SQL)
392
+ } , unsafeBitCast ( box, UnsafeMutablePointer< Void> . self ) )
393
+ trace = box
383
394
}
384
- private var trace : _SQLiteTraceCallback ?
395
+ private typealias Trace = @convention ( block) UnsafePointer < Int8 > -> Void
396
+ private var trace : Trace ?
385
397
386
398
/// Registers a callback to be invoked whenever a row is inserted, updated,
387
399
/// or deleted in a rowid table.
@@ -390,53 +402,75 @@ public final class Connection {
390
402
/// `.Insert`, `.Update`, or `.Delete`), database name, table name, and
391
403
/// rowid.
392
404
public func updateHook( callback: ( ( operation: Operation , db: String , table: String , rowid: Int64 ) -> Void ) ? ) {
393
- if let callback = callback {
394
- updateHook = { operation, db, table, rowid in
395
- callback (
396
- operation: Operation ( rawValue: operation) ,
397
- db: String . fromCString ( db) !,
398
- table: String . fromCString ( table) !,
399
- rowid: rowid
400
- )
401
- }
402
- } else {
405
+ guard let callback = callback else {
406
+ sqlite3_update_hook ( handle, nil , nil )
403
407
updateHook = nil
408
+ return
404
409
}
405
- _SQLiteUpdateHook ( handle, updateHook)
410
+
411
+ let box : UpdateHook = {
412
+ callback (
413
+ operation: Operation ( rawValue: $0) ,
414
+ db: String . fromCString ( $1) !,
415
+ table: String . fromCString ( $2) !,
416
+ rowid: $3
417
+ )
418
+ }
419
+ sqlite3_update_hook ( handle, { callback, operation, db, table, rowid in
420
+ unsafeBitCast ( callback, UpdateHook . self) ( operation, db, table, rowid)
421
+ } , unsafeBitCast ( box, UnsafeMutablePointer< Void> . self ) )
422
+ updateHook = box
406
423
}
407
- private var updateHook : _SQLiteUpdateHookCallback ?
424
+ private typealias UpdateHook = @convention ( block) ( Int32 , UnsafePointer < Int8 > , UnsafePointer < Int8 > , Int64 ) -> Void
425
+ private var updateHook : UpdateHook ?
408
426
409
427
/// Registers a callback to be invoked whenever a transaction is committed.
410
428
///
411
429
/// - Parameter callback: A callback invoked whenever a transaction is
412
430
/// committed. If this callback throws, the transaction will be rolled
413
431
/// back.
414
432
public func commitHook( callback: ( ( ) throws -> Void ) ? ) {
415
- if let callback = callback {
416
- commitHook = {
417
- do {
418
- try callback ( )
419
- return 0
420
- } catch {
421
- return 1
422
- }
423
- }
424
- } else {
433
+ guard let callback = callback else {
434
+ sqlite3_commit_hook ( handle, nil , nil )
425
435
commitHook = nil
436
+ return
426
437
}
427
- _SQLiteCommitHook ( handle, commitHook)
438
+
439
+ let box : CommitHook = {
440
+ do {
441
+ try callback ( )
442
+ } catch {
443
+ return 1
444
+ }
445
+ return 0
446
+ }
447
+ sqlite3_commit_hook ( handle, { callback in
448
+ unsafeBitCast ( callback, CommitHook . self) ( )
449
+ } , unsafeBitCast ( box, UnsafeMutablePointer< Void> . self ) )
450
+ commitHook = box
428
451
}
429
- private var commitHook : _SQLiteCommitHookCallback ?
452
+ private typealias CommitHook = @convention ( block) ( ) -> Int32
453
+ private var commitHook : CommitHook ?
430
454
431
455
/// Registers a callback to be invoked whenever a transaction rolls back.
432
456
///
433
457
/// - Parameter callback: A callback invoked when a transaction is rolled
434
458
/// back.
435
- public func rollbackHook( callback: _SQLiteRollbackHookCallback ? ) {
436
- rollbackHook = callback
437
- _SQLiteRollbackHook ( handle, rollbackHook)
459
+ public func rollbackHook( callback: ( ( ) -> Void ) ? ) {
460
+ guard let callback = callback else {
461
+ sqlite3_rollback_hook ( handle, nil , nil )
462
+ rollbackHook = nil
463
+ return
464
+ }
465
+
466
+ let box : RollbackHook = { callback ( ) }
467
+ sqlite3_rollback_hook ( handle, { callback in
468
+ unsafeBitCast ( callback, RollbackHook . self) ( )
469
+ } , unsafeBitCast ( box, UnsafeMutablePointer< Void> . self ) )
470
+ rollbackHook = box
438
471
}
439
- private var rollbackHook : _SQLiteRollbackHookCallback ?
472
+ private typealias RollbackHook = @convention ( block) ( ) -> Void
473
+ private var rollbackHook : RollbackHook ?
440
474
441
475
/// Creates or redefines a custom SQL function.
442
476
///
@@ -459,8 +493,7 @@ public final class Connection {
459
493
/// parameters and should return a raw SQL value (or nil).
460
494
public func createFunction( function: String , argumentCount: UInt ? = nil , deterministic: Bool = false , _ block: ( args: [ Binding ? ] ) -> Binding ? ) {
461
495
let argc = argumentCount. map { Int ( $0) } ?? - 1
462
- if functions [ function] == nil { self . functions [ function] = [ : ] }
463
- functions [ function] ? [ argc] = { context, argc, argv in
496
+ let box : Function = { context, argc, argv in
464
497
let arguments : [ Binding ? ] = ( 0 ..< Int ( argc) ) . map { idx in
465
498
let value = argv [ idx]
466
499
switch sqlite3_value_type ( value) {
@@ -493,10 +526,18 @@ public final class Connection {
493
526
fatalError ( " unsupported result type: \( result) " )
494
527
}
495
528
}
496
- try ! check ( _SQLiteCreateFunction ( handle, function, Int32 ( argc) , deterministic ? 1 : 0 , functions [ function] ? [ argc] ) )
529
+ var flags = SQLITE_UTF8
530
+ if deterministic {
531
+ flags |= SQLITE_DETERMINISTIC
532
+ }
533
+ sqlite3_create_function_v2 ( handle, function, Int32 ( argc) , flags, unsafeBitCast ( box, UnsafeMutablePointer< Void> . self ) , { context, argc, value in
534
+ unsafeBitCast ( sqlite3_user_data ( context) , Function . self) ( context, argc, value)
535
+ } , nil , nil , nil )
536
+ if functions [ function] == nil { self . functions [ function] = [ : ] }
537
+ functions [ function] ? [ argc] = box
497
538
}
498
- private var functions = [ String : [ Int : _SQLiteCreateFunctionCallback ] ] ( )
499
-
539
+ private typealias Function = @ convention ( block ) ( COpaquePointer , Int32 , UnsafeMutablePointer < COpaquePointer > ) -> Void
540
+ private var functions = [ String : [ Int : Function ] ] ( )
500
541
501
542
/// The return type of a collation comparison function.
502
543
public typealias ComparisonResult = NSComparisonResult
@@ -510,12 +551,16 @@ public final class Connection {
510
551
/// - block: A collation function that takes two strings and returns the
511
552
/// comparison result.
512
553
public func createCollation( collation: String , _ block: ( lhs: String , rhs: String ) -> ComparisonResult ) {
513
- collations [ collation ] = { lhs, rhs in
514
- Int32 ( block ( lhs: String . fromCString ( lhs) !, rhs: String . fromCString ( rhs) !) . rawValue)
554
+ let box : Collation = { lhs, rhs in
555
+ Int32 ( block ( lhs: String . fromCString ( UnsafePointer < Int8 > ( lhs) ) !, rhs: String . fromCString ( UnsafePointer < Int8 > ( rhs) ) !) . rawValue)
515
556
}
516
- try ! check ( _SQLiteCreateCollation ( handle, collation, collations [ collation] ) )
557
+ try ! check ( sqlite3_create_collation_v2 ( handle, collation, SQLITE_UTF8, unsafeBitCast ( box, UnsafeMutablePointer< Void> . self ) , { callback, _, lhs, _, rhs in
558
+ unsafeBitCast ( callback, Collation . self) ( lhs, rhs)
559
+ } , nil ) )
560
+ collations [ collation] = box
517
561
}
518
- private var collations = [ String: _SQLiteCreateCollationCallback] ( )
562
+ private typealias Collation = @convention ( block) ( UnsafePointer < Void > , UnsafePointer < Void > ) -> Int32
563
+ private var collations = [ String: Collation] ( )
519
564
520
565
// MARK: - Error Handling
521
566
0 commit comments