System.Data.SQLite
Check-in [accc5da1ee]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Sync up (fallback) error messages with those in the SQLite core library. Mask off extended error codes prior to using the fallback table. Add tests for preserving extended error codes in the SQLiteException class.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: accc5da1ee5c6e07a0472a35c7b5c4c8ecef6b5a
User & Date: mistachkin 2018-02-08 01:02:25
Context
2018-02-08
01:47
Update SQLite core library to the latest trunk code. check-in: d5bde3713d user: mistachkin tags: trunk
01:02
Sync up (fallback) error messages with those in the SQLite core library. Mask off extended error codes prior to using the fallback table. Add tests for preserving extended error codes in the SQLiteException class. check-in: accc5da1ee user: mistachkin tags: trunk
00:50
Override the System.Object members for the SQLiteException class to improve its ToString return value. Pursuant to [53962f9eff]. check-in: 37dcaf8f5d user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to System.Data.SQLite/SQLiteBase.cs.

   589    589       // a SQLiteStatementHandle, SQLiteConnectionHandle, and SQLiteFunctionCookieHandle.
   590    590       // Therefore these functions have to be static, and have to be low-level.
   591    591   
   592    592       ///////////////////////////////////////////////////////////////////////////////////////////////
   593    593   
   594    594       private static string[] _errorMessages = {
   595    595           /* SQLITE_OK          */ "not an error",
   596         -        /* SQLITE_ERROR       */ "SQL logic error or missing database",
          596  +        /* SQLITE_ERROR       */ "SQL logic error",
   597    597           /* SQLITE_INTERNAL    */ "internal logic error",
   598    598           /* SQLITE_PERM        */ "access permission denied",
   599         -        /* SQLITE_ABORT       */ "callback requested query abort",
          599  +        /* SQLITE_ABORT       */ "query aborted",
   600    600           /* SQLITE_BUSY        */ "database is locked",
   601    601           /* SQLITE_LOCKED      */ "database table is locked",
   602    602           /* SQLITE_NOMEM       */ "out of memory",
   603    603           /* SQLITE_READONLY    */ "attempt to write a readonly database",
   604    604           /* SQLITE_INTERRUPT   */ "interrupted",
   605    605           /* SQLITE_IOERR       */ "disk I/O error",
   606    606           /* SQLITE_CORRUPT     */ "database disk image is malformed",
................................................................................
   609    609           /* SQLITE_CANTOPEN    */ "unable to open database file",
   610    610           /* SQLITE_PROTOCOL    */ "locking protocol",
   611    611           /* SQLITE_EMPTY       */ "table contains no data",
   612    612           /* SQLITE_SCHEMA      */ "database schema has changed",
   613    613           /* SQLITE_TOOBIG      */ "string or blob too big",
   614    614           /* SQLITE_CONSTRAINT  */ "constraint failed",
   615    615           /* SQLITE_MISMATCH    */ "datatype mismatch",
   616         -        /* SQLITE_MISUSE      */ "library routine called out of sequence",
          616  +        /* SQLITE_MISUSE      */ "bad parameter or other API misuse",
   617    617           /* SQLITE_NOLFS       */ "large file support is disabled",
   618    618           /* SQLITE_AUTH        */ "authorization denied",
   619    619           /* SQLITE_FORMAT      */ "auxiliary database format error",
   620         -        /* SQLITE_RANGE       */ "bind or column index out of range",
   621         -        /* SQLITE_NOTADB      */ "file is encrypted or is not a database",
          620  +        /* SQLITE_RANGE       */ "column index out of range",
          621  +        /* SQLITE_NOTADB      */ "file is not a database",
   622    622           /* SQLITE_NOTICE      */ "notification message",
   623    623           /* SQLITE_WARNING     */ "warning message"
   624    624       };
   625    625   
   626    626       ///////////////////////////////////////////////////////////////////////////////////////////////
   627    627   
   628    628       /// <summary>
................................................................................
   629    629       /// Returns the error message for the specified SQLite return code using
   630    630       /// the internal static lookup table.
   631    631       /// </summary>
   632    632       /// <param name="rc">The SQLite return code.</param>
   633    633       /// <returns>The error message or null if it cannot be found.</returns>
   634    634       protected static string FallbackGetErrorString(SQLiteErrorCode rc)
   635    635       {
          636  +        switch (rc)
          637  +        {
          638  +            case SQLiteErrorCode.Abort_Rollback:
          639  +                return "abort due to ROLLBACK";
          640  +            case SQLiteErrorCode.Row:
          641  +                return "another row available";
          642  +            case SQLiteErrorCode.Done:
          643  +                return "no more rows available";
          644  +        }
          645  +
   636    646           if (_errorMessages == null)
   637    647               return null;
   638    648   
   639         -        int index = (int)rc;
          649  +        int index = (int)(rc & SQLiteErrorCode.NonExtendedMask);
   640    650   
   641    651           if ((index < 0) || (index >= _errorMessages.Length))
   642    652               index = (int)SQLiteErrorCode.Error; /* Make into generic error. */
   643    653   
   644    654           return _errorMessages[index];
   645    655       }
   646    656   

Changes to Tests/basic.eagle.

  4753   4753   
  4754   4754     unset -nocomplain msg db fileName
  4755   4755   } -constraints [fixConstraints {eagle !System.Data.SQLite.Encryption monoBug28\
  4756   4756   command.sql compile.DATA SQLite System.Data.SQLite}] -result {1 {SQL logic\
  4757   4757   error -- Cannot use "HexPassword" connection string property: library was not\
  4758   4758   built with encryption support, please see "https://www.sqlite.org/see" for more\
  4759   4759   information}}}
         4760  +
         4761  +###############################################################################
         4762  +
         4763  +runTest {test data-1.93 {extended error code messages} -setup {
         4764  +  #
         4765  +  # HACK: Temporarily disable automatic detection (and use) of the
         4766  +  #       native sqlite3_errstr() API.
         4767  +  #
         4768  +  object invoke -flags +NonPublic \
         4769  +      System.Data.SQLite.SQLite3 have_errstr false
         4770  +
         4771  +  setupDb [set fileName data-1.93.db]
         4772  +} -body {
         4773  +  set errCodes [list]
         4774  +
         4775  +  lappend errCodes 256; # SQLITE_OK_LOAD_PERMANENTLY
         4776  +  lappend errCodes 513; # SQLITE_ERROR_RETRY
         4777  +  lappend errCodes 522; # SQLITE_IOERR_SHORT_READ
         4778  +  lappend errCodes 270; # SQLITE_CANTOPEN_NOTEMPDIR
         4779  +  lappend errCodes 539; # SQLITE_NOTICE_RECOVER_ROLLBACK
         4780  +  lappend errCodes 284; # SQLITE_WARNING_AUTOINDEX
         4781  +
         4782  +  set connection [getDbConnection]
         4783  +
         4784  +  lappend result [catchAndReturn {$connection EnableExtensions true}]
         4785  +
         4786  +  lappend result [catchAndReturn {$connection LoadExtension \
         4787  +      [getCoreExtensionBinaryFileName null] interop_test_extension_init}]
         4788  +
         4789  +  lappend result [catchAndReturn {$connection SetExtendedResultCodes false}]
         4790  +
         4791  +  foreach errCode $errCodes {
         4792  +    #
         4793  +    # HACK: Without extended error codes, SQLITE_OK_* cannot be handled via
         4794  +    #       the semantics in the System.Data.SQLite.SQLite3.Prepare method;
         4795  +    #       it will always assume that more results are available when the
         4796  +    #       error code is Ok, thereby looping forever.
         4797  +    #
         4798  +    if {($errCode & 0xFF) == 0} then {continue}
         4799  +
         4800  +    resetException; catchAndSetException {
         4801  +      sql execute -execute scalar $db \
         4802  +          "SELECT interopError(?);" [list param1 Int32 $errCode]
         4803  +    } exception
         4804  +
         4805  +    lappend result [$exception ResultCode] \
         4806  +        [normalizeExceptionMessage [$exception Message]]
         4807  +  }
         4808  +
         4809  +  lappend result [catchAndReturn {$connection SetExtendedResultCodes true}]
         4810  +
         4811  +  foreach errCode $errCodes {
         4812  +    resetException; catchAndSetException {
         4813  +      sql execute -execute scalar $db \
         4814  +          "SELECT interopError(?);" [list param1 Int32 $errCode]
         4815  +    } exception
         4816  +
         4817  +    lappend result [$exception ResultCode] \
         4818  +        [normalizeExceptionMessage [$exception Message]]
         4819  +  }
         4820  +
         4821  +  set result
         4822  +} -cleanup {
         4823  +  cleanupDb $fileName
         4824  +
         4825  +  freeDbConnection
         4826  +
         4827  +  catch {
         4828  +    #
         4829  +    # HACK: Restore automatic detection (and use) of the native
         4830  +    #       sqlite3_errstr() API.
         4831  +    #
         4832  +    object invoke -flags +NonPublic \
         4833  +        System.Data.SQLite.SQLite3 have_errstr null
         4834  +  }
         4835  +
         4836  +  unset -nocomplain result exception errCode errCodes
         4837  +  unset -nocomplain connection db fileName
         4838  +} -constraints {eagle command.object monoBug28\
         4839  +compile.DATA defineConstant.System.Data.SQLite.INTEROP_TEST_EXTENSION\
         4840  +command.sql SQLite System.Data.SQLite} -result {{0 {}} {0 {}} {0 {}} Error {SQL\
         4841  +logic error ==> SQL logic error} IoErr {disk I/O error ==> disk I/O error}\
         4842  +CantOpen {unable to open database file ==> unable to open database file} Notice\
         4843  +{notification message ==> unknown error} Warning {warning message ==> unknown\
         4844  +error} {0 {}} Ok_Load_Permanently {not an error ==> not an error} Error_Retry\
         4845  +{SQL logic error ==> SQL logic error} IoErr_Short_Read {disk I/O error ==> disk\
         4846  +I/O error} CantOpen_NoTempDir {unable to open database file ==> unable to open\
         4847  +database file} Notice_Recover_Rollback {notification message ==> unknown error}\
         4848  +Warning_AutoIndex {warning message ==> unknown error}}}
  4760   4849   
  4761   4850   ###############################################################################
  4762   4851   
  4763   4852   reportSQLiteResources $test_channel
  4764   4853   
  4765   4854   ###############################################################################
  4766   4855   
  4767   4856   runSQLiteTestFilesEpilogue
  4768   4857   runSQLiteTestEpilogue
  4769   4858   runTestEpilogue

Changes to lib/System.Data.SQLite/common.eagle.

  2167   2167           #       code for the interpreter, and the error message up to the
  2168   2168           #       point where the stack trace should start.
  2169   2169           #
  2170   2170           return [list $code $::errorCode \
  2171   2171               [extractSystemDataSQLiteExceptionMessage $result]]
  2172   2172         }
  2173   2173       }
         2174  +
         2175  +    proc resetException {} {
         2176  +      #
         2177  +      # NOTE: Reset exception associated with this interpreter (to null).
         2178  +      #       This (private) property is maintained on a per-thread basis.
         2179  +      #
         2180  +      object invoke -flags +NonPublic Interpreter.GetActive Exception null
         2181  +      return ""
         2182  +    }
         2183  +
         2184  +    proc catchAndSetException { script {varName ""} } {
         2185  +      #
         2186  +      # NOTE: Evaluate the script provided by our caller in their context.
         2187  +      #
         2188  +      catch {uplevel 1 $script}
         2189  +
         2190  +      #
         2191  +      # NOTE: Grab the (private) exception property from this interpreter,
         2192  +      #       for this thread, and add as an opaque object handle in the
         2193  +      #       context of our caller.
         2194  +      #
         2195  +      if {[string length $varName] > 0} then {
         2196  +        upvar 1 $varName exception
         2197  +      }
         2198  +
         2199  +      set exception [object invoke \
         2200  +          -alias -flags +NonPublic Interpreter.GetActive Exception]
         2201  +
         2202  +      return ""
         2203  +    }
  2174   2204   
  2175   2205       proc compileCSharpWith {
  2176   2206               text memory symbols strict resultsVarName errorsVarName fileNames
  2177   2207               args } {
  2178   2208         #
  2179   2209         # NOTE: Since we are going to use this method name a lot, assign it to a
  2180   2210         #       variable first.
................................................................................
  2284   2314           PRAGMA cache_size = 2000;
  2285   2315         }
  2286   2316   
  2287   2317         return [list \
  2288   2318             [sql execute -execute scalar $db "PRAGMA page_size;"] \
  2289   2319             [sql execute -execute scalar $db "PRAGMA cache_size;"]]
  2290   2320       }
         2321  +
         2322  +    proc normalizeExceptionMessage { value } {
         2323  +      if {[string length $value] == 0} then {return $value}
         2324  +      return [string map [list \r\n " ==> "] $value]
         2325  +    }
  2291   2326   
  2292   2327       proc extractSystemDataSQLiteExceptionMessage { value } {
  2293   2328         #
  2294   2329         # NOTE: If the string conforms to format of the normal exception
  2295   2330         #       error strings, extract and return only the error message
  2296   2331         #       portion itself.
  2297   2332         #