System.Data.SQLite
Check-in [74ccc76eee]
Not logged in

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

Overview
Comment:Add connection handle locking semantics to the SQLiteBase.SQLiteLastError method.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tkt-996d13cd87
Files: files | file ages | folders
SHA1: 74ccc76eee81e13c6f220ffc36d1157778dbf58d
User & Date: mistachkin 2012-04-30 17:45:31
Context
2012-04-30
17:54
Rename internal SQLiteLastError methods to GetLastError. check-in: 5ee7dd00e0 user: mistachkin tags: tkt-996d13cd87
17:45
Add connection handle locking semantics to the SQLiteBase.SQLiteLastError method. check-in: 74ccc76eee user: mistachkin tags: tkt-996d13cd87
17:18
Remove superfluous using statement. check-in: b8fb8d4b6a user: mistachkin tags: tkt-996d13cd87
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

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

388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
        throw new SQLiteException(n, SQLiteLastError());

      return 0; // We reset OK, no schema changes
    }

    internal override string SQLiteLastError()
    {
      return SQLiteBase.SQLiteLastError(_sql);
    }

    internal override SQLiteStatement Prepare(SQLiteConnection cnn, string strSql, SQLiteStatement previous, uint timeoutMS, out string strRemain)
    {
      if (!String.IsNullOrEmpty(strSql))
      {
        //







|







388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
        throw new SQLiteException(n, SQLiteLastError());

      return 0; // We reset OK, no schema changes
    }

    internal override string SQLiteLastError()
    {
      return SQLiteBase.SQLiteLastError(_sql, _sql);
    }

    internal override SQLiteStatement Prepare(SQLiteConnection cnn, string strSql, SQLiteStatement previous, uint timeoutMS, out string strRemain)
    {
      if (!String.IsNullOrEmpty(strSql))
      {
        //

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

340
341
342
343
344
345
346
347
348
349




350
351
352
353
354
355

356
357
358
359
360
361
362
...
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
...
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
    ///////////////////////////////////////////////////////////////////////////////////////////////

    // These statics are here for lack of a better place to put them.
    // They exist here because they are called during the finalization of
    // a SQLiteStatementHandle, SQLiteConnectionHandle, and SQLiteFunctionCookieHandle.
    // Therefore these functions have to be static, and have to be low-level.

    internal static string SQLiteLastError(IntPtr db)
    {
      if (db == IntPtr.Zero) return "invalid database handle";




#if !SQLITE_STANDARD
      int len;
      return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(db, out len), len);
#else
      return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1);
#endif

    }

    internal static void FinishBackup(IntPtr backup)
    {
        if (backup == IntPtr.Zero) return;
        int n = UnsafeNativeMethods.sqlite3_backup_finish(backup);
        if (n > 0) throw new SQLiteException(n, null);
................................................................................
        {
#if !SQLITE_STANDARD
            int n = UnsafeNativeMethods.sqlite3_close_interop(db);
#else
            ResetConnection(hdl, db);
            int n = UnsafeNativeMethods.sqlite3_close(db);
#endif
            if (n > 0) throw new SQLiteException(n, SQLiteLastError(db));
        }
    }

    internal static void ResetConnection(SQLiteConnectionHandle hdl, IntPtr db)
    {
        if ((hdl == null) || (db == IntPtr.Zero)) return;
        lock (hdl)
................................................................................
            {
                stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt);
                if (stmt != IntPtr.Zero)
                {
#if !SQLITE_STANDARD
                    n = UnsafeNativeMethods.sqlite3_reset_interop(stmt);
#else
                n = UnsafeNativeMethods.sqlite3_reset(stmt);
#endif
                }
            } while (stmt != IntPtr.Zero);

            if (IsAutocommit(db) == false) // a transaction is pending on the connection
            {
                n = UnsafeNativeMethods.sqlite3_exec(db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero, out stmt);
                if (n > 0) throw new SQLiteException(n, SQLiteLastError(db));
            }
        }
    }

    internal static bool IsAutocommit(IntPtr db)
    {
      if (db == IntPtr.Zero) return false;







|

|
>
>
>
>

|
|

|

>







 







|







 







|







|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
...
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
...
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
    ///////////////////////////////////////////////////////////////////////////////////////////////

    // These statics are here for lack of a better place to put them.
    // They exist here because they are called during the finalization of
    // a SQLiteStatementHandle, SQLiteConnectionHandle, and SQLiteFunctionCookieHandle.
    // Therefore these functions have to be static, and have to be low-level.

    internal static string SQLiteLastError(SQLiteConnectionHandle hdl, IntPtr db)
    {
        if ((hdl == null) || (db == IntPtr.Zero))
            return "invalid connection or database handle";

        lock (hdl)
        {
#if !SQLITE_STANDARD
            int len;
            return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(db, out len), len);
#else
            return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1);
#endif
        }
    }

    internal static void FinishBackup(IntPtr backup)
    {
        if (backup == IntPtr.Zero) return;
        int n = UnsafeNativeMethods.sqlite3_backup_finish(backup);
        if (n > 0) throw new SQLiteException(n, null);
................................................................................
        {
#if !SQLITE_STANDARD
            int n = UnsafeNativeMethods.sqlite3_close_interop(db);
#else
            ResetConnection(hdl, db);
            int n = UnsafeNativeMethods.sqlite3_close(db);
#endif
            if (n > 0) throw new SQLiteException(n, SQLiteLastError(hdl, db));
        }
    }

    internal static void ResetConnection(SQLiteConnectionHandle hdl, IntPtr db)
    {
        if ((hdl == null) || (db == IntPtr.Zero)) return;
        lock (hdl)
................................................................................
            {
                stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt);
                if (stmt != IntPtr.Zero)
                {
#if !SQLITE_STANDARD
                    n = UnsafeNativeMethods.sqlite3_reset_interop(stmt);
#else
                    n = UnsafeNativeMethods.sqlite3_reset(stmt);
#endif
                }
            } while (stmt != IntPtr.Zero);

            if (IsAutocommit(db) == false) // a transaction is pending on the connection
            {
                n = UnsafeNativeMethods.sqlite3_exec(db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero, out stmt);
                if (n > 0) throw new SQLiteException(n, SQLiteLastError(hdl, db));
            }
        }
    }

    internal static bool IsAutocommit(IntPtr db)
    {
      if (db == IntPtr.Zero) return false;