lib/sqlite3: store and use the error code of a failed database opening
authorAlexis Laferrière <alexis.laf@xymus.net>
Thu, 17 Jul 2014 18:04:28 +0000 (14:04 -0400)
committerAlexis Laferrière <alexis.laf@xymus.net>
Fri, 18 Jul 2014 17:02:07 +0000 (13:02 -0400)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

lib/sqlite3/native_sqlite3.nit
lib/sqlite3/sqlite3.nit

index f6cf0e9..da93820 100644 (file)
@@ -22,6 +22,11 @@ in "C header" `{
        #include <sqlite3.h>
 `}
 
+redef class Sys
+       # Last error raised when calling `Sqlite3::open`
+       var sqlite_open_error: nullable Sqlite3Code = null
+end
+
 extern class Sqlite3Code `{int`}
        new ok `{ return SQLITE_OK; `} #         0   /* Successful result */
        fun is_ok: Bool `{ return recv == SQLITE_OK; `}
@@ -128,12 +133,18 @@ end
 extern class NativeSqlite3 `{sqlite3 *`}
 
        # Open a connection to a database in UTF-8
-       new open(filename: String) import String.to_cstring `{
+       new open(filename: String) import String.to_cstring, set_sys_sqlite_open_error `{
                sqlite3 *self = NULL;
-               sqlite3_open(String_to_cstring(filename), &self);
+               int err = sqlite3_open(String_to_cstring(filename), &self);
+               NativeSqlite3_set_sys_sqlite_open_error(self, (void*)(long)err);
+               // The previous cast is a hack, using non pointers in extern classes is not
+               // yet in the spec of the FFI.
                return self;
        `}
 
+       # Utility method to set `Sys.sqlite_open_error`
+       private fun set_sys_sqlite_open_error(err: Sqlite3Code) do sys.sqlite_open_error = err
+
        # Has this DB been correctly opened?
        #
        # To know if it has been closed or interrupted, you must check for errors with `error`.
index f4e855d..d194362 100644 (file)
@@ -95,6 +95,12 @@ class Sqlite3DB
        # The latest error message, or `null` if there is none
        fun error: nullable String
        do
+               if not native_connection.is_valid then
+                       var err = sys.sqlite_open_error
+                       if err == null then return null
+                       return err.to_s
+               end
+
                var err = native_connection.error
                if err.is_ok then return null
                return err.to_s