@@ -47,6 +47,9 @@ public typealias SQLTableColums = [(name: String, type: SQLType)]
4747public typealias SQLValues = [ ( type: SQLType , value: Any ? ) ]
4848
4949public protocol SQLiteType {
50+ var lastInsertID : Int { get }
51+ var changes : Int { get }
52+ var totalChanges : Int { get }
5053 func createTable( sql: String ) throws
5154 func checkIfTableExists( _ table: SQLTable ) throws -> Bool
5255 func dropTable( _ table: SQLTable , vacuum: Bool ) throws
@@ -65,12 +68,9 @@ public protocol SQLiteType {
6568 func getRow( from table: SQLTable , sql: String , params: [ Any ] ? ) throws -> [ SQLValues ]
6669 func getAllRows( from table: SQLTable ) throws -> [ SQLValues ]
6770 func getByID( from table: SQLTable , id: Int ) throws -> SQLValues
71+ func getFirstRow( from table: SQLTable ) throws -> SQLValues
6872 func getLastRow( from table: SQLTable ) throws -> SQLValues
69- func getLastInsertID( ) -> Int
70- func getChanges( ) -> Int
71- func getTotalChanges( ) -> Int
7273 func vacuum( ) throws
73- func resetAutoincrement( in table: SQLTable ) throws
7474 func query( sql: String , params: [ Any ] ? ) throws
7575}
7676
@@ -82,10 +82,39 @@ open class SQLite: SQLiteType {
8282 private let SQLITE_STATIC = unsafeBitCast ( 0 , to: sqlite3_destructor_type. self)
8383 private let SQLITE_TRANSIENT = unsafeBitCast ( - 1 , to: sqlite3_destructor_type. self)
8484
85- private let serialQueue = DispatchQueue ( label: " SQLite Serial Queue " )
85+ private let queue = DispatchQueue ( label: " SQLite Queue " )
8686
8787 public var dateFormatter = DateFormatter ( )
8888
89+ public var lastInsertID : Int {
90+ var id = 0
91+ queue. sync {
92+ id = Int ( sqlite3_last_insert_rowid ( dbPointer) )
93+ }
94+ log ( " last inserted id: \( id) " )
95+ return id
96+ }
97+
98+ /// Returns number of rows changed by last INSERT, UPDATE or DELETE statement
99+ public var changes : Int {
100+ var changes = 0
101+ queue. sync {
102+ changes = Int ( sqlite3_changes ( dbPointer) )
103+ }
104+ log ( " number of changes: \( changes) " )
105+ return changes
106+ }
107+
108+ /// Returns number of rows changed by INSERT, UPDATE or DELETE statements since the DB was opened
109+ public var totalChanges : Int {
110+ var totalChanges = 0
111+ queue. sync {
112+ totalChanges = Int ( sqlite3_total_changes ( dbPointer) )
113+ }
114+ log ( " number of total changes: \( totalChanges) " )
115+ return totalChanges
116+ }
117+
89118 public init ( path: String , recreateDB: Bool = false ) throws {
90119 if recreateDB {
91120 try deleteDB ( path: path)
@@ -195,7 +224,7 @@ open class SQLite: SQLiteType {
195224 }
196225
197226 private func operation( sql: String , params: [ Any ] ? = nil ) throws {
198- try serialQueue . sync {
227+ try queue . sync {
199228 let sqlStatement = try prepareStatement ( sql: sql)
200229
201230 defer {
@@ -210,6 +239,11 @@ open class SQLite: SQLiteType {
210239 }
211240 }
212241
242+ private func resetAutoincrement( in table: SQLTable ) throws {
243+ let sql = " UPDATE sqlite_sequence SET SEQ=0 WHERE name=' \( table. name) '; "
244+ try operation ( sql: sql)
245+ }
246+
213247 public func createTable( sql: String ) throws {
214248 guard sql. uppercased ( ) . trimmingCharacters ( in: . whitespaces) . hasPrefix ( " CREATE " ) else {
215249 throw SQLiteError . Statement ( " Invalid SQL statement " )
@@ -296,7 +330,7 @@ open class SQLite: SQLiteType {
296330 }
297331 try operation ( sql: sql, params: params)
298332 log ( " successfully inserted row(s), sql: \( sql) " )
299- return getLastInsertID ( )
333+ return self . lastInsertID
300334 }
301335
302336 /// Can be used to update one or several rows depending on the SQL statement
@@ -337,7 +371,7 @@ open class SQLite: SQLiteType {
337371
338372 public func getRowCount( in table: SQLTable ) throws -> Int {
339373 var count : Int32 = 0
340- try serialQueue . sync {
374+ try queue . sync {
341375 let sql = " SELECT count(*) FROM \( table. name) ; "
342376 let sqlStatement = try prepareStatement ( sql: sql)
343377 defer {
@@ -357,7 +391,7 @@ open class SQLite: SQLiteType {
357391 throw SQLiteError . Statement ( " Invalid SQL statement " )
358392 }
359393 var count : Int32 = 0
360- try serialQueue . sync {
394+ try queue . sync {
361395 let sqlStatement = try prepareStatement ( sql: sql)
362396 defer {
363397 sqlite3_finalize ( sqlStatement)
@@ -382,7 +416,7 @@ open class SQLite: SQLiteType {
382416
383417 var allRows : [ SQLValues ] = [ ]
384418
385- try serialQueue . sync {
419+ try queue . sync {
386420 let sqlStatement = try prepareStatement ( sql: sql)
387421 defer {
388422 sqlite3_finalize ( sqlStatement)
@@ -454,7 +488,7 @@ open class SQLite: SQLiteType {
454488 }
455489 }
456490
457- log ( " successfully read a row(s), count: \( allRows. count) , sql: \( sql) " )
491+ log ( " successfully read row(s), count: \( allRows. count) , sql: \( sql) " )
458492 return allRows
459493 }
460494
@@ -496,48 +530,30 @@ open class SQLite: SQLiteType {
496530 log ( " successfully read a row by id \( id) in \( table. name) " )
497531 return result [ 0 ]
498532 } else {
499- throw SQLiteError . Column ( getErrorMessage ( dbPointer: dbPointer) )
533+ throw SQLiteError . Other ( getErrorMessage ( dbPointer: dbPointer) )
500534 }
501535 }
502536
503- public func getLastRow ( from table: SQLTable ) throws -> SQLValues {
504- let sql = " SELECT * FROM \( table. name) WHERE \( table. primaryKey) = (SELECT MAX ( \( table. primaryKey) ) FROM \( table. name) ); "
537+ public func getFirstRow ( from table: SQLTable ) throws -> SQLValues {
538+ let sql = " SELECT * FROM \( table. name) WHERE \( table. primaryKey) = (SELECT MIN ( \( table. primaryKey) ) FROM \( table. name) ); "
505539 let result = try getRow ( from: table, sql: sql)
506540 if result. count == 1 {
507- log ( " successfully read the last row in \( table. name) " )
541+ log ( " successfully read the first row in \( table. name) " )
508542 return result [ 0 ]
509543 } else {
510- throw SQLiteError . Column ( getErrorMessage ( dbPointer: dbPointer) )
544+ throw SQLiteError . Other ( getErrorMessage ( dbPointer: dbPointer) )
511545 }
512546 }
513547
514- public func getLastInsertID( ) -> Int {
515- var id = 0
516- serialQueue. sync {
517- id = Int ( sqlite3_last_insert_rowid ( dbPointer) )
518- }
519- log ( " last inserted id: \( id) " )
520- return id
521- }
522-
523- /// Returns number of rows changed by last INSERT, UPDATE or DELETE statement
524- public func getChanges( ) -> Int {
525- var changes = 0
526- serialQueue. sync {
527- changes = Int ( sqlite3_changes ( dbPointer) )
528- }
529- log ( " number of changes: \( changes) " )
530- return changes
531- }
532-
533- /// Returns number of rows changed by INSERT, UPDATE or DELETE statements since the DB was opened
534- public func getTotalChanges( ) -> Int {
535- var totalChanges = 0
536- serialQueue. sync {
537- totalChanges = Int ( sqlite3_total_changes ( dbPointer) )
548+ public func getLastRow( from table: SQLTable ) throws -> SQLValues {
549+ let sql = " SELECT * FROM \( table. name) WHERE \( table. primaryKey) = (SELECT MAX( \( table. primaryKey) ) FROM \( table. name) ); "
550+ let result = try getRow ( from: table, sql: sql)
551+ if result. count == 1 {
552+ log ( " successfully read the last row in \( table. name) " )
553+ return result [ 0 ]
554+ } else {
555+ throw SQLiteError . Other ( getErrorMessage ( dbPointer: dbPointer) )
538556 }
539- log ( " number of total changes: \( totalChanges) " )
540- return totalChanges
541557 }
542558
543559 /// Repacks the DB to take advantage of deleted data
@@ -547,12 +563,6 @@ open class SQLite: SQLiteType {
547563 log ( " VACUUM " )
548564 }
549565
550- public func resetAutoincrement( in table: SQLTable ) throws {
551- let sql = " UPDATE sqlite_sequence SET SEQ=0 WHERE name=' \( table. name) '; "
552- try operation ( sql: sql)
553- log ( " successfully reseted autoincrement in \( table. name) " )
554- }
555-
556566 /// Any other query except reading
557567 public func query( sql: String , params: [ Any ] ? = nil ) throws {
558568 try operation ( sql: sql, params: params)
0 commit comments