@@ -152,6 +152,13 @@ public final class Connection {
152152 return Int ( sqlite3_total_changes ( handle) )
153153 }
154154
155+ /// Whether or not the database will return extended error codes when errors are handled.
156+ public var usesExtendedErrorCodes : Bool = false {
157+ didSet {
158+ sqlite3_extended_result_codes ( handle, usesExtendedErrorCodes ? 1 : 0 )
159+ }
160+ }
161+
155162 // MARK: - Execute
156163
157164 /// Executes a batch of SQL statements.
@@ -252,9 +259,9 @@ public final class Connection {
252259 @discardableResult public func run( _ statement: String , _ bindings: [ String : Binding ? ] ) throws -> Statement {
253260 return try prepare ( statement) . run ( bindings)
254261 }
255-
262+
256263 // MARK: - VACUUM
257-
264+
258265 /// Run a vacuum on the database
259266 ///
260267 /// - Throws: `Result.Error` if query execution fails.
@@ -729,11 +736,25 @@ public enum Result : Error {
729736 /// - statement: the statement which produced the error
730737 case error( message: String , code: Int32 , statement: Statement ? )
731738
739+ /// Represents a SQLite specific [extended error code] (https://sqlite.org/rescode.html#primary_result_codes_versus_extended_result_codes)
740+ ///
741+ /// - message: English-language text that describes the error
742+ ///
743+ /// - extendedCode: SQLite [extended error code](https://sqlite.org/rescode.html#extended_result_code_list)
744+ ///
745+ /// - statement: the statement which produced the error
746+ case extendedError( message: String , extendedCode: Int32 , statement: Statement ? )
747+
732748 init ? ( errorCode: Int32 , connection: Connection , statement: Statement ? = nil ) {
733749 guard !Result. successCodes. contains ( errorCode) else { return nil }
734750
735751 let message = String ( cString: sqlite3_errmsg ( connection. handle) )
736- self = . error( message: message, code: errorCode, statement: statement)
752+ guard connection. usesExtendedErrorCodes else {
753+ self = . error( message: message, code: errorCode, statement: statement)
754+ return
755+ }
756+ let extendedErrorCode = sqlite3_extended_errcode ( connection. handle)
757+ self = . extendedError( message: message, extendedCode: extendedErrorCode, statement: statement)
737758 }
738759
739760}
@@ -748,6 +769,12 @@ extension Result : CustomStringConvertible {
748769 } else {
749770 return " \( message) (code: \( errorCode) ) "
750771 }
772+ case let . extendedError( message, extendedCode, statement) :
773+ if let statement = statement {
774+ return " \( message) ( \( statement) ) (extended code: \( extendedCode) ) "
775+ } else {
776+ return " \( message) (extended code: \( extendedCode) ) "
777+ }
751778 }
752779 }
753780}
0 commit comments