Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Never create a new connection wrapper in the SQLiteConnection.Shutdown method. Add experimental GetMemoryStatistics, ReleaseMemory, and Shutdown methods to the SQLiteConnection class. Add memory leak detection to the test project for the .NET Compact Framework. Miscellaneous internal refactoring and additional comments. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
aa16f48eeaceb2168d4a3c120f7cd711 |
User & Date: | mistachkin 2013-11-07 01:27:45.757 |
Context
2013-11-07
| ||
03:28 | Add SQLITE_ENABLE_MEMORY_MANAGEMENT compile-time option to the interop assembly. check-in: 9056f6e0d5 user: mistachkin tags: trunk | |
01:27 | Never create a new connection wrapper in the SQLiteConnection.Shutdown method. Add experimental GetMemoryStatistics, ReleaseMemory, and Shutdown methods to the SQLiteConnection class. Add memory leak detection to the test project for the .NET Compact Framework. Miscellaneous internal refactoring and additional comments. check-in: aa16f48eea user: mistachkin tags: trunk | |
2013-11-05
| ||
06:49 | For the batch build tool, automate modification of the 'include.vsprops' file, if necessary. check-in: a0780d663b user: mistachkin tags: trunk | |
Changes
Changes to Doc/Extra/version.html.
︙ | ︙ | |||
42 43 44 45 46 47 48 49 50 51 52 53 54 55 | </div> <div id="mainSection"> <div id="mainBody"> <h1 class="heading">Version History</h1> <p><b>1.0.90.0 - December XX, 2013 <font color="red">(release scheduled)</font></b></p> <ul> <li>Add experimental support for the native regexp extension.</li> </ul> <p><b>1.0.89.0 - October 28, 2013</b></p> <ul> <li>Updated to <a href="http://www.sqlite.org/releaselog/3_8_1.html">SQLite 3.8.1</a>.</li> <li>Add AutoCommit property to the SQLiteConnection class. Fix for <a href="http://system.data.sqlite.org/index.html/info/9ba9346f75">[9ba9346f75]</a>.</li> <li>Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for <a href="http://system.data.sqlite.org/index.html/info/3113734605">[3113734605]</a>.</li> <li>Check the result of sqlite3_column_name function against NULL.</li> | > > > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | </div> <div id="mainSection"> <div id="mainBody"> <h1 class="heading">Version History</h1> <p><b>1.0.90.0 - December XX, 2013 <font color="red">(release scheduled)</font></b></p> <ul> <li>Add experimental support for the native regexp extension.</li> <li>Never create a new connection wrapper in the SQLiteConnection.Shutdown method. <b>** Potentially Incompatible Change **</b></li> <li>Add experimental GetMemoryStatistics, ReleaseMemory, and Shutdown methods to the SQLiteConnection class.</li> <li>Add memory leak detection to the test project for the .NET Compact Framework.</li> </ul> <p><b>1.0.89.0 - October 28, 2013</b></p> <ul> <li>Updated to <a href="http://www.sqlite.org/releaselog/3_8_1.html">SQLite 3.8.1</a>.</li> <li>Add AutoCommit property to the SQLiteConnection class. Fix for <a href="http://system.data.sqlite.org/index.html/info/9ba9346f75">[9ba9346f75]</a>.</li> <li>Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for <a href="http://system.data.sqlite.org/index.html/info/3113734605">[3113734605]</a>.</li> <li>Check the result of sqlite3_column_name function against NULL.</li> |
︙ | ︙ |
Changes to System.Data.SQLite/SQLite3.cs.
︙ | ︙ | |||
423 424 425 426 427 428 429 | return UnsafeNativeMethods.sqlite3_changes(_sql); #endif } } internal override long MemoryUsed { | | | > > > > > > > > | | | | | | | | > > > > > > > > | | | | | | | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 | return UnsafeNativeMethods.sqlite3_changes(_sql); #endif } } internal override long MemoryUsed { get { return StaticMemoryUsed; } } internal static long StaticMemoryUsed { get { #if !PLATFORM_COMPACTFRAMEWORK return UnsafeNativeMethods.sqlite3_memory_used(); #elif !SQLITE_STANDARD long bytes = 0; UnsafeNativeMethods.sqlite3_memory_used_interop(ref bytes); return bytes; #else throw new NotImplementedException(); #endif } } internal override long MemoryHighwater { get { return StaticMemoryHighwater; } } internal static long StaticMemoryHighwater { get { #if !PLATFORM_COMPACTFRAMEWORK return UnsafeNativeMethods.sqlite3_memory_highwater(0); #elif !SQLITE_STANDARD long bytes = 0; UnsafeNativeMethods.sqlite3_memory_highwater_interop(0, ref bytes); return bytes; #else throw new NotImplementedException(); #endif } } /// <summary> /// Returns non-zero if the underlying native connection handle is owned /// by this instance. /// </summary> internal override bool OwnHandle |
︙ | ︙ | |||
482 483 484 485 486 487 488 | SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3_config_int( SQLiteConfigOpsEnum.SQLITE_CONFIG_MEMSTATUS, value ? 1 : 0); return rc; } /// <summary> | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 | SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3_config_int( SQLiteConfigOpsEnum.SQLITE_CONFIG_MEMSTATUS, value ? 1 : 0); return rc; } /// <summary> /// Attempts to free as much heap memory as possible for the database connection. /// </summary> /// <returns>A standard SQLite return code (i.e. zero for success and non-zero for failure).</returns> internal override SQLiteErrorCode ReleaseMemory() { SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3_db_release_memory(_sql); return rc; } /// <summary> /// Attempts to free N bytes of heap memory by deallocating non-essential memory /// allocations held by the database library. Memory used to cache database pages /// to improve performance is an example of non-essential memory. This is a no-op /// returning zero if the SQLite core library was not compiled with the compile-time /// option SQLITE_ENABLE_MEMORY_MANAGEMENT. /// </summary> /// <param name="nBytes"> /// The requested number of bytes to free. /// </param> /// <returns> /// The number of bytes actually freed. This value may be zero. /// </returns> internal static int StaticReleaseMemory(int nBytes) { return UnsafeNativeMethods.sqlite3_release_memory(nBytes); } /// <summary> /// Shutdown the SQLite engine so that it can be restarted with different /// configuration options. We depend on auto initialization to recover. /// </summary> /// <returns>Returns a standard SQLite result code.</returns> internal override SQLiteErrorCode Shutdown() { return StaticShutdown(false); } /// <summary> /// Shutdown the SQLite engine so that it can be restarted with different /// configuration options. We depend on auto initialization to recover. /// </summary> /// <param name="directories"> /// Non-zero to reset the database and temporary directories to their /// default values, which should be null for both. This parameter has no /// effect on non-Windows operating systems. /// </param> /// <returns>Returns a standard SQLite result code.</returns> internal static SQLiteErrorCode StaticShutdown( bool directories ) { SQLiteErrorCode rc = SQLiteErrorCode.Ok; if (directories) { #if WINDOWS if (rc == SQLiteErrorCode.Ok) rc = UnsafeNativeMethods.sqlite3_win32_set_directory(1, null); if (rc == SQLiteErrorCode.Ok) rc = UnsafeNativeMethods.sqlite3_win32_set_directory(2, null); #else #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine( "Shutdown: Cannot reset directories on this operating system."); #endif #endif } if (rc == SQLiteErrorCode.Ok) rc = UnsafeNativeMethods.sqlite3_shutdown(); return rc; } /// <summary> /// Determines if the associated native connection handle is open. /// </summary> /// <returns> |
︙ | ︙ | |||
696 697 698 699 700 701 702 | throw new SQLiteException(n, GetLastError()); return n; // We reset OK, no schema changes } internal override string GetLastError() { | > > > > > | > > | 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 | throw new SQLiteException(n, GetLastError()); return n; // We reset OK, no schema changes } internal override string GetLastError() { return GetLastError(null); } internal override string GetLastError(string defValue) { string result = SQLiteBase.GetLastError(_sql, _sql); if (String.IsNullOrEmpty(result)) result = defValue; return result; } 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.
︙ | ︙ | |||
66 67 68 69 70 71 72 73 74 75 76 77 78 79 | /// Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. /// If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is /// global to the process. /// </summary> /// <param name="value">Non-zero to enable memory usage tracking, zero otherwise.</param> /// <returns>A standard SQLite return code (i.e. zero for success and non-zero for failure).</returns> internal abstract SQLiteErrorCode SetMemoryStatus(bool value); /// <summary> /// Shutdown the SQLite engine so that it can be restarted with different config options. /// We depend on auto initialization to recover. /// </summary> internal abstract SQLiteErrorCode Shutdown(); /// <summary> /// Determines if the associated native connection handle is open. | > > > > > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | /// Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. /// If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is /// global to the process. /// </summary> /// <param name="value">Non-zero to enable memory usage tracking, zero otherwise.</param> /// <returns>A standard SQLite return code (i.e. zero for success and non-zero for failure).</returns> internal abstract SQLiteErrorCode SetMemoryStatus(bool value); /// <summary> /// Attempts to free as much heap memory as possible for the database connection. /// </summary> /// <returns>A standard SQLite return code (i.e. zero for success and non-zero for failure).</returns> internal abstract SQLiteErrorCode ReleaseMemory(); /// <summary> /// Shutdown the SQLite engine so that it can be restarted with different config options. /// We depend on auto initialization to recover. /// </summary> internal abstract SQLiteErrorCode Shutdown(); /// <summary> /// Determines if the associated native connection handle is open. |
︙ | ︙ | |||
111 112 113 114 115 116 117 118 119 120 121 122 123 124 | internal abstract void SetTimeout(int nTimeoutMS); /// <summary> /// Returns the text of the last error issued by SQLite /// </summary> /// <returns></returns> internal abstract string GetLastError(); /// <summary> /// When pooling is enabled, force this connection to be disposed rather than returned to the pool /// </summary> internal abstract void ClearPool(); /// <summary> /// When pooling is enabled, returns the number of pool entries matching the current file name. | > > > > > > > > > > > > | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | internal abstract void SetTimeout(int nTimeoutMS); /// <summary> /// Returns the text of the last error issued by SQLite /// </summary> /// <returns></returns> internal abstract string GetLastError(); /// <summary> /// Returns the text of the last error issued by SQLite -OR- the specified default error text if /// none is available from the SQLite core library. /// </summary> /// <param name="defValue"> /// The error text to return in the event that one is not available from the SQLite core library. /// </param> /// <returns> /// The error text. /// </returns> internal abstract string GetLastError(string defValue); /// <summary> /// When pooling is enabled, force this connection to be disposed rather than returned to the pool /// </summary> internal abstract void ClearPool(); /// <summary> /// When pooling is enabled, returns the number of pool entries matching the current file name. |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteConnection.cs.
︙ | ︙ | |||
2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 | if (_sql == null) throw new InvalidOperationException("Database connection not valid for getting maximum memory used."); return _sql.MemoryHighwater; } } /// <summary> /// Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. /// If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is /// global to the process. /// </summary> /// <param name="value">Non-zero to enable memory usage tracking, zero otherwise.</param> | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 | if (_sql == null) throw new InvalidOperationException("Database connection not valid for getting maximum memory used."); return _sql.MemoryHighwater; } } /// <summary> /// Returns various global memory statistics for the SQLite core library via /// a dictionary of key/value pairs. Currently, only the "MemoryUsed" and /// "MemoryHighwater" keys are returned and they have values that correspond /// to the values that could be obtained via the <see cref="MemoryUsed" /> /// and <see cref="MemoryHighwater" /> connection properties. /// </summary> /// <param name="statistics"> /// This dictionary will be populated with the global memory statistics. It /// will be created if necessary. /// </param> public static void GetMemoryStatistics( ref IDictionary<string, long> statistics ) { if (statistics == null) statistics = new Dictionary<string, long>(); statistics["MemoryUsed"] = SQLite3.StaticMemoryUsed; statistics["MemoryHighwater"] = SQLite3.StaticMemoryHighwater; } /// <summary> /// Attempts to free as much heap memory as possible for this database connection. /// </summary> public void ReleaseMemory() { CheckDisposed(); if (_sql == null) throw new InvalidOperationException("Database connection not valid for releasing memory."); SQLiteErrorCode rc = _sql.ReleaseMemory(); if (rc != SQLiteErrorCode.Ok) { throw new SQLiteException(rc, _sql.GetLastError("Could not release connection memory.")); } } /// <summary> /// Attempts to free N bytes of heap memory by deallocating non-essential memory /// allocations held by the database library. Memory used to cache database pages /// to improve performance is an example of non-essential memory. This is a no-op /// returning zero if the SQLite core library was not compiled with the compile-time /// option SQLITE_ENABLE_MEMORY_MANAGEMENT. /// </summary> /// <param name="nBytes"> /// The requested number of bytes to free. /// </param> /// <returns> /// The number of bytes actually freed. This value may be zero. /// </returns> public static int ReleaseMemory(int nBytes) { return SQLite3.StaticReleaseMemory(nBytes); } /// <summary> /// Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled. /// If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is /// global to the process. /// </summary> /// <param name="value">Non-zero to enable memory usage tracking, zero otherwise.</param> |
︙ | ︙ | |||
2605 2606 2607 2608 2609 2610 2611 | get { CheckDisposed(); return _connectionState; } } | > | > > > > > > < > | > > | > > > > | > | | > > > > > > > > > > > > > > > > > > | > > > > > | > | > | 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 | get { CheckDisposed(); return _connectionState; } } /// <summary> /// Passes a shutdown request to the SQLite core library. Does not throw /// an exception if the shutdown request fails. /// </summary> /// <returns> /// A standard SQLite return code (i.e. zero for success and non-zero for /// failure). /// </returns> public SQLiteErrorCode Shutdown() { CheckDisposed(); if (_sql == null) throw new InvalidOperationException("Database connection not valid for shutdown."); _sql.Close(true); /* NOTE: MUST be closed before shutdown. */ SQLiteErrorCode rc = _sql.Shutdown(); #if !NET_COMPACT_20 && TRACE_CONNECTION if (rc != SQLiteErrorCode.Ok) Trace.WriteLine(String.Format("Shutdown (Instance) Failed: {0}", rc)); #endif return rc; } /// <summary> /// Passes a shutdown request to the SQLite core library. Throws an /// exception if the shutdown request fails and the no-throw parameter /// is non-zero. /// </summary> /// <param name="directories"> /// Non-zero to reset the database and temporary directories to their /// default values, which should be null for both. /// </param> /// <param name="noThrow"> /// When non-zero, throw an exception if the shutdown request fails. /// </param> public static void Shutdown( bool directories, bool noThrow ) { SQLiteErrorCode rc = SQLite3.StaticShutdown(directories); if (rc != SQLiteErrorCode.Ok) { #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(String.Format("Shutdown (Static) Failed: {0}", rc)); #endif if (!noThrow) throw new SQLiteException(rc, null); } } /// Enables or disabled extended result codes returned by SQLite public void SetExtendedResultCodes(bool bOnOff) { CheckDisposed(); |
︙ | ︙ |
Changes to System.Data.SQLite/UnsafeNativeMethods.cs.
︙ | ︙ | |||
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 | #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern SQLiteErrorCode sqlite3_overload_function(IntPtr db, IntPtr zName, int nArgs); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] #else [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)] #endif internal static extern SQLiteErrorCode sqlite3_win32_set_directory(uint type, string value); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern IntPtr sqlite3_libversion(); | > > | 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 | #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern SQLiteErrorCode sqlite3_overload_function(IntPtr db, IntPtr zName, int nArgs); #if WINDOWS #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] #else [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)] #endif internal static extern SQLiteErrorCode sqlite3_win32_set_directory(uint type, string value); #endif #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern IntPtr sqlite3_libversion(); |
︙ | ︙ | |||
1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 | [DllImport(SQLITE_DLL)] #endif internal static extern IntPtr sqlite3_db_handle(IntPtr stmt); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern IntPtr sqlite3_db_filename(IntPtr db, IntPtr dbName); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern IntPtr sqlite3_next_stmt(IntPtr db, IntPtr stmt); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern SQLiteErrorCode sqlite3_exec(IntPtr db, byte[] strSql, IntPtr pvCallback, IntPtr pvParam, out IntPtr errMsg); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern int sqlite3_get_autocommit(IntPtr db); | > > > > > > > > > > > > > > | 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 | [DllImport(SQLITE_DLL)] #endif internal static extern IntPtr sqlite3_db_handle(IntPtr stmt); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern SQLiteErrorCode sqlite3_db_release_memory(IntPtr db); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern IntPtr sqlite3_db_filename(IntPtr db, IntPtr dbName); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern IntPtr sqlite3_next_stmt(IntPtr db, IntPtr stmt); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern SQLiteErrorCode sqlite3_exec(IntPtr db, byte[] strSql, IntPtr pvCallback, IntPtr pvParam, out IntPtr errMsg); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern int sqlite3_release_memory(int nBytes); #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern int sqlite3_get_autocommit(IntPtr db); |
︙ | ︙ |
Changes to readme.htm.
︙ | ︙ | |||
187 188 189 190 191 192 193 194 195 196 197 198 199 200 | <h2><b>Version History</b></h2> <p> <b>1.0.90.0 - December XX, 2013 <font color="red">(release scheduled)</font></b> </p> <ul> <li>Add experimental support for the native regexp extension.</li> </ul> <p> <b>1.0.89.0 - October 28, 2013</b> </p> <ul> <li>Updated to <a href="http://www.sqlite.org/releaselog/3_8_1.html">SQLite 3.8.1</a>.</li> <li>Add AutoCommit property to the SQLiteConnection class. Fix for [9ba9346f75].</li> | > > > | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | <h2><b>Version History</b></h2> <p> <b>1.0.90.0 - December XX, 2013 <font color="red">(release scheduled)</font></b> </p> <ul> <li>Add experimental support for the native regexp extension.</li> <li>Never create a new connection wrapper in the SQLiteConnection.Shutdown method. <b>** Potentially Incompatible Change **</b></li> <li>Add experimental GetMemoryStatistics, ReleaseMemory, and Shutdown methods to the SQLiteConnection class.</li> <li>Add memory leak detection to the test project for the .NET Compact Framework.</li> </ul> <p> <b>1.0.89.0 - October 28, 2013</b> </p> <ul> <li>Updated to <a href="http://www.sqlite.org/releaselog/3_8_1.html">SQLite 3.8.1</a>.</li> <li>Add AutoCommit property to the SQLiteConnection class. Fix for [9ba9346f75].</li> |
︙ | ︙ |
Changes to testce/TestCases.cs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ using System; using System.Data.Common; using System.Data; using System.Data.SQLite; using System.Threading; namespace test { | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ using System; using System.Collections.Generic; using System.Data.Common; using System.Data; using System.Data.SQLite; using System.Threading; namespace test { |
︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 | return String.Compare(param1, param2, true); } } internal sealed class TestCases { internal Form1 frm; private string connectionString; private DbConnection cnn; private string sql; private bool autoClose; private bool isolatedSql; private int total; | > | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | return String.Compare(param1, param2, true); } } internal sealed class TestCases { internal Form1 frm; internal IDictionary<string, long> statistics; private string connectionString; private DbConnection cnn; private string sql; private bool autoClose; private bool isolatedSql; private int total; |
︙ | ︙ | |||
96 97 98 99 100 101 102 | this.sql = sql; this.autoClose = autoExit; this.isolatedSql = isolatedSql; } internal bool Succeeded() { | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < > > > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | this.sql = sql; this.autoClose = autoExit; this.isolatedSql = isolatedSql; } internal bool Succeeded() { // // NOTE: Did all tests pass [without leaking any memory]? // long sqlBytes; return (failed == 0) && (passed == total) && ((statistics == null) || !statistics.TryGetValue("MemoryUsed", out sqlBytes) || (sqlBytes == 0)); } private static string FormatString(string value) { if (value == null) return "(null)"; if (value.Length == 0) return "(empty)"; if (value.Trim().Length == 0) return "(whitespace)"; return value; } private void WriteMemoryStatistics( bool forceFullCollection ) { long clrBytes = GC.GetTotalMemory(false); SQLiteConnection.GetMemoryStatistics(ref statistics); if (statistics != null) statistics["ClrUsedBefore"] = clrBytes; if (frm != null) { frm.WriteLine("\r\nMemory in use by the CLR before collection: " + clrBytes.ToString() + " bytes"); if (statistics != null) { long sqlBytes; if (statistics.TryGetValue("MemoryUsed", out sqlBytes)) { frm.WriteLine("Current SQLite memory usage before collection: " + sqlBytes.ToString() + " bytes"); } if (statistics.TryGetValue("MemoryHighwater", out sqlBytes)) { frm.WriteLine("Maximum SQLite memory usage before collection: " + sqlBytes.ToString() + " bytes"); } } } if (forceFullCollection) { clrBytes = GC.GetTotalMemory(true); SQLiteConnection.GetMemoryStatistics(ref statistics); if (statistics != null) statistics["ClrUsedAfter"] = clrBytes; if (frm != null) { frm.WriteLine("\r\nMemory in use by the CLR after collection: " + clrBytes.ToString() + " bytes"); if (statistics != null) { long sqlBytes; if (statistics.TryGetValue("MemoryUsed", out sqlBytes)) { frm.WriteLine("Current SQLite memory usage after collection: " + sqlBytes.ToString() + " bytes"); } if (statistics.TryGetValue("MemoryHighwater", out sqlBytes)) { frm.WriteLine("Maximum SQLite memory usage after collection: " + sqlBytes.ToString() + " bytes"); } } } } } internal void Run() { frm = new Form1(); frm.Show(); frm.WriteLine(String.Format("\r\nTest connection string:\r\n\r\n{0}", FormatString(connectionString))); frm.WriteLine(String.Format("\r\nTest initialization SQL:\r\n\r\n{0}", FormatString(sql))); Type type = cnn.GetType(); frm.WriteLine("\r\nBeginning Test on " + type.ToString()); SQLiteConnection cnn2 = cnn as SQLiteConnection; if (cnn2 != null) { frm.WriteLine("SQLite v" + SQLiteConnection.SQLiteVersion + " [" + SQLiteConnection.SQLiteSourceId + "]"); WriteMemoryStatistics(false); frm.WriteLine(String.Empty); } total++; try { CreateTable(cnn); frm.WriteLine("SUCCESS - CreateTable"); passed++; } catch (Exception) { frm.WriteLine("FAIL - CreateTable"); failed++; } total++; |
︙ | ︙ | |||
228 229 230 231 232 233 234 235 236 237 238 239 240 241 | catch (Exception) { frm.WriteLine("FAIL - MultipleThreadStress"); failed++; } total++; try { DropTable(cnn); frm.WriteLine("SUCCESS - DropTable"); passed++; } catch (Exception) { frm.WriteLine("FAIL - DropTable"); failed++; } frm.WriteLine("\r\nTests Finished."); frm.WriteLine(String.Format("\r\nCounts: {0} total, {1} passed, {2} failed", total, passed, failed)); frm.WriteLine(String.Format("Result: {0}", Succeeded() ? "SUCCESS" : "FAILURE")); if (autoClose) frm.Close(); } | > > > > > > | 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | catch (Exception) { frm.WriteLine("FAIL - MultipleThreadStress"); failed++; } total++; try { DropTable(cnn); frm.WriteLine("SUCCESS - DropTable"); passed++; } catch (Exception) { frm.WriteLine("FAIL - DropTable"); failed++; } frm.WriteLine("\r\nTests Finished."); if (cnn2 != null) cnn2.Close(); WriteMemoryStatistics(true); frm.WriteLine(String.Format("\r\nCounts: {0} total, {1} passed, {2} failed", total, passed, failed)); frm.WriteLine(String.Format("Result: {0}", Succeeded() ? "SUCCESS" : "FAILURE")); if (autoClose) frm.Close(); } |
︙ | ︙ |
Changes to www/news.wiki.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <title>News</title> <b>Version History</b> <p> <b>1.0.90.0 - December XX, 2013 <font color="red">(release scheduled)</font></b> </p> <ul> <li>Add experimental support for the native regexp extension.</li> </ul> <p> <b>1.0.89.0 - October 28, 2013</b> </p> <ul> <li>Updated to [http://www.sqlite.org/releaselog/3_8_1.html|SQLite 3.8.1].</li> <li>Add AutoCommit property to the SQLiteConnection class. Fix for [9ba9346f75].</li> | > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <title>News</title> <b>Version History</b> <p> <b>1.0.90.0 - December XX, 2013 <font color="red">(release scheduled)</font></b> </p> <ul> <li>Add experimental support for the native regexp extension.</li> <li>Never create a new connection wrapper in the SQLiteConnection.Shutdown method. <b>** Potentially Incompatible Change **</b></li> <li>Add experimental GetMemoryStatistics, ReleaseMemory, and Shutdown methods to the SQLiteConnection class.</li> <li>Add memory leak detection to the test project for the .NET Compact Framework.</li> </ul> <p> <b>1.0.89.0 - October 28, 2013</b> </p> <ul> <li>Updated to [http://www.sqlite.org/releaselog/3_8_1.html|SQLite 3.8.1].</li> <li>Add AutoCommit property to the SQLiteConnection class. Fix for [9ba9346f75].</li> |
︙ | ︙ |