Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch tkt-5cee5409f8 Excluding Merge-Ins
This is equivalent to a diff from 0b0bd83ddd to 81d4c53f90
2018-01-28
| ||
05:28 | Support asynchronous completion of distributed transactions, fix for [5cee5409f8]. Add experimental WaitForEnlistmentReset method to the SQLiteConnection class, pursuant to [7e1dd697dc]. check-in: a27556f61d user: mistachkin tags: trunk | |
05:27 | Update version history docs. Closed-Leaf check-in: 81d4c53f90 user: mistachkin tags: tkt-5cee5409f8 | |
2018-01-27
| ||
22:24 | Refinements to the test for ticket [5cee5409f8], with a special focus on the new WaitForEnlistmentReset method. check-in: 2cb2ae35a3 user: mistachkin tags: tkt-5cee5409f8 | |
2018-01-26
| ||
02:23 | Merge updates from trunk. check-in: 596797845c user: mistachkin tags: tkt-5cee5409f8 | |
02:22 | Further debugging enhancements. check-in: 0b0bd83ddd user: mistachkin tags: trunk | |
01:47 | Setup the '_debugString' field consistently, for the debug build configuration only. check-in: ac4cc4a86e user: mistachkin tags: trunk | |
Changes to Doc/Extra/Provider/version.html.
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <div id="mainSection"> <div id="mainBody"> <h1 class="heading">Version History</h1> <p><b>1.0.107.0 - January XX, 2018 <font color="red">(release scheduled)</font></b></p> <ul> <li>Updated to <a href="https://www.sqlite.org/draft/releaselog/3_22_0.html">SQLite 3.22.0</a>.</li> <li>Improve performance of type name lookups by removing superfluous locking and string creation.</li> <li>Fix some internal memory accounting present only in the debug build.</li> <li>Make sure inbound native delegates are unhooked before adding a connection to the pool. Fix for <a href="https://system.data.sqlite.org/index.html/info/0e48e80333">[0e48e80333]</a>.</li> <li>Add preliminary support for the .NET Framework 4.7.1.</li> <li>Updates to internal DbType mapping related lookup tables. Pursuant to <a href="https://system.data.sqlite.org/index.html/info/a799e3978f">[a799e3978f]</a>.</li> </ul> <p><b>1.0.106.0 - November 2, 2017</b></p> <ul> | > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <div id="mainSection"> <div id="mainBody"> <h1 class="heading">Version History</h1> <p><b>1.0.107.0 - January XX, 2018 <font color="red">(release scheduled)</font></b></p> <ul> <li>Updated to <a href="https://www.sqlite.org/draft/releaselog/3_22_0.html">SQLite 3.22.0</a>.</li> <li>Improve performance of type name lookups by removing superfluous locking and string creation.</li> <li>Support asynchronous completion of distributed transactions. Fix for <a href="https://system.data.sqlite.org/index.html/info/5cee5409f8">[5cee5409f8]</a>.</li> <li>Add experimental WaitForEnlistmentReset method to the SQLiteConnection class. Pursuant to <a href="https://system.data.sqlite.org/index.html/info/7e1dd697dc">[7e1dd697dc]</a>.</li> <li>Fix some internal memory accounting present only in the debug build.</li> <li>Make sure inbound native delegates are unhooked before adding a connection to the pool. Fix for <a href="https://system.data.sqlite.org/index.html/info/0e48e80333">[0e48e80333]</a>.</li> <li>Add preliminary support for the .NET Framework 4.7.1.</li> <li>Updates to internal DbType mapping related lookup tables. Pursuant to <a href="https://system.data.sqlite.org/index.html/info/a799e3978f">[a799e3978f]</a>.</li> </ul> <p><b>1.0.106.0 - November 2, 2017</b></p> <ul> |
︙ | ︙ |
Changes to Setup/data/verify.lst.
︙ | ︙ | |||
861 862 863 864 865 866 867 868 869 870 871 872 873 874 | Tests/tkt-5251bd0878.eagle Tests/tkt-53633bbe39.eagle Tests/tkt-544dba0a2f.eagle Tests/tkt-5535448538.eagle Tests/tkt-56b42d99c1.eagle Tests/tkt-58ed318f2f.eagle Tests/tkt-59edc1018b.eagle Tests/tkt-6434e23a0f.eagle Tests/tkt-647d282d11.eagle Tests/tkt-69cf6e5dc8.eagle Tests/tkt-6c6ecccc5f.eagle Tests/tkt-71bedaca19.eagle Tests/tkt-72905c9a77.eagle Tests/tkt-74542e702e.eagle | > | 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 | Tests/tkt-5251bd0878.eagle Tests/tkt-53633bbe39.eagle Tests/tkt-544dba0a2f.eagle Tests/tkt-5535448538.eagle Tests/tkt-56b42d99c1.eagle Tests/tkt-58ed318f2f.eagle Tests/tkt-59edc1018b.eagle Tests/tkt-5cee5409f8.eagle Tests/tkt-6434e23a0f.eagle Tests/tkt-647d282d11.eagle Tests/tkt-69cf6e5dc8.eagle Tests/tkt-6c6ecccc5f.eagle Tests/tkt-71bedaca19.eagle Tests/tkt-72905c9a77.eagle Tests/tkt-74542e702e.eagle |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteConnection.cs.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | using System.Collections.Generic; using System.Globalization; using System.ComponentModel; using System.Reflection; using System.Runtime.InteropServices; using System.IO; using System.Text; ///////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// This class represents a single value to be returned /// from the <see cref="SQLiteDataReader" /> class via /// its <see cref="SQLiteDataReader.GetBlob" />, | > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | using System.Collections.Generic; using System.Globalization; using System.ComponentModel; using System.Reflection; using System.Runtime.InteropServices; using System.IO; using System.Text; using System.Threading; ///////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// This class represents a single value to be returned /// from the <see cref="SQLiteDataReader" /> class via /// its <see cref="SQLiteDataReader.GetBlob" />, |
︙ | ︙ | |||
1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 | /// <summary> /// The default isolation level for new transactions /// </summary> private IsolationLevel _defaultIsolation; #if !PLATFORM_COMPACTFRAMEWORK /// <summary> /// Whether or not the connection is enlisted in a distrubuted transaction /// </summary> internal SQLiteEnlistment _enlistment; #endif /// <summary> | > > > > > > | 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 | /// <summary> /// The default isolation level for new transactions /// </summary> private IsolationLevel _defaultIsolation; #if !PLATFORM_COMPACTFRAMEWORK /// <summary> /// This object is used with lock statements to synchronize access to the /// <see cref="_enlistment" /> field, below. /// </summary> internal readonly object _enlistmentSyncRoot = new object(); /// <summary> /// Whether or not the connection is enlisted in a distrubuted transaction /// </summary> internal SQLiteEnlistment _enlistment; #endif /// <summary> |
︙ | ︙ | |||
2029 2030 2031 2032 2033 2034 2035 | // NOTE: If we need to retry the previous operation, wait for // the number of milliseconds specified by our caller // unless the caller used a negative number, in that case // skip sleeping at all because we do not want to block // this thread forever. // if (retry && (retryMilliseconds >= 0)) | | | 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 | // NOTE: If we need to retry the previous operation, wait for // the number of milliseconds specified by our caller // unless the caller used a negative number, in that case // skip sleeping at all because we do not want to block // this thread forever. // if (retry && (retryMilliseconds >= 0)) Thread.Sleep(retryMilliseconds); // // NOTE: There is no point in calling the native API to copy // zero pages as it does nothing; therefore, stop now. // if (pages == 0) break; |
︙ | ︙ | |||
2916 2917 2918 2919 2920 2921 2922 | OnChanged(this, new ConnectionEventArgs( SQLiteConnectionEventType.Closing, null, null, null, null, null, null, null)); if (_sql != null) { #if !PLATFORM_COMPACTFRAMEWORK | > > > > > | | | | | | | | | | | | | | | | | > > > | > | | < > | 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 | OnChanged(this, new ConnectionEventArgs( SQLiteConnectionEventType.Closing, null, null, null, null, null, null, null)); if (_sql != null) { #if !PLATFORM_COMPACTFRAMEWORK lock (_enlistmentSyncRoot) /* TRANSACTIONAL */ { SQLiteEnlistment enlistment = _enlistment; _enlistment = null; if (enlistment != null) { // If the connection is enlisted in a transaction scope and the scope is still active, // we cannot truly shut down this connection until the scope has completed. Therefore make a // hidden connection temporarily to hold open the connection until the scope has completed. SQLiteConnection cnn = new SQLiteConnection(); #if DEBUG cnn._debugString = HelperMethods.StringFormat( CultureInfo.InvariantCulture, "closeThreadId = {0}, {1}{2}{2}{3}", HelperMethods.GetThreadId(), _sql, Environment.NewLine, _debugString); #endif cnn._sql = _sql; cnn._transactionLevel = _transactionLevel; cnn._transactionSequence = _transactionSequence; cnn._enlistment = enlistment; cnn._connectionState = _connectionState; cnn._version = _version; SQLiteTransaction transaction = enlistment._transaction; if (transaction != null) transaction._cnn = cnn; enlistment._disposeConnection = true; _sql = null; } } #endif if (_sql != null) { _sql.Close(_disposing); _sql = null; } |
︙ | ︙ | |||
3393 3394 3395 3396 3397 3398 3399 | #if !PLATFORM_COMPACTFRAMEWORK /// <summary> /// Manual distributed transaction enlistment support /// </summary> /// <param name="transaction">The distributed transaction to enlist in</param> public override void EnlistTransaction(System.Transactions.Transaction transaction) { | | > > | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 | #if !PLATFORM_COMPACTFRAMEWORK /// <summary> /// Manual distributed transaction enlistment support /// </summary> /// <param name="transaction">The distributed transaction to enlist in</param> public override void EnlistTransaction(System.Transactions.Transaction transaction) { CheckDisposed(); lock (_enlistmentSyncRoot) /* TRANSACTIONAL */ { if (_enlistment != null && transaction == _enlistment._scope) return; else if (_enlistment != null) throw new ArgumentException("Already enlisted in a transaction"); if (_transactionLevel > 0 && transaction != null) throw new ArgumentException("Unable to enlist in transaction, a local transaction already exists"); else if (transaction == null) throw new ArgumentNullException("Unable to enlist in transaction, it is null"); bool strictEnlistment = ((_flags & SQLiteConnectionFlags.StrictEnlistment) == SQLiteConnectionFlags.StrictEnlistment); _enlistment = new SQLiteEnlistment(this, transaction, GetFallbackDefaultIsolationLevel(), strictEnlistment, strictEnlistment); OnChanged(this, new ConnectionEventArgs( SQLiteConnectionEventType.EnlistTransaction, null, null, null, null, null, null, new object[] { _enlistment })); } } /// <summary> /// <![CDATA[<b>]]>EXPERIMENTAL<![CDATA[</b>]]> /// Waits for the enlistment associated with this connection to be reset. /// </summary> /// <param name="timeoutMilliseconds"> /// The approximate maximum number of milliseconds to wait before timing /// out the wait operation. /// </param> /// <returns> /// Non-zero if the enlistment assciated with this connection was reset; /// otherwise, zero. It should be noted that this method returning a /// non-zero value does not necessarily guarantee that the connection /// can enlist in a new transaction (i.e. due to potentical race with /// other threads); therefore, callers should generally use try/catch /// when calling the <see cref="EnlistTransaction" /> method. /// </returns> public bool WaitForEnlistmentReset( int timeoutMilliseconds ) { CheckDisposed(); if (timeoutMilliseconds < 0) throw new ArgumentException("timeout cannot be negative"); const int defaultMilliseconds = 100; int sleepMilliseconds; if (timeoutMilliseconds == 0) { sleepMilliseconds = 0; } else { sleepMilliseconds = Math.Min( timeoutMilliseconds / 10, defaultMilliseconds); if (sleepMilliseconds == 0) sleepMilliseconds = defaultMilliseconds; } DateTime start = DateTime.UtcNow; while (true) { // // NOTE: Attempt to acquire the necessary lock without blocking. // This method will treat a failure to obtain the lock the // same as the enlistment not being reset yet. Both will // advance toward the timeout. // bool locked = Monitor.TryEnter(_enlistmentSyncRoot); try { if (locked) { // // NOTE: Is there still an enlistment? If not, we are // done. There is a potential race condition in // the caller if another thread is able to setup // a new enlistment at any point prior to our // caller fully dealing with the result of this // method. However, that should generally never // happen because this class is not intended to // be used by multiple concurrent threads, with // the notable exception of an active enlistment // being asynchronously committed or rolled back // by the .NET Framework. // if (_enlistment == null) return true; } } finally { if (locked) { Monitor.Exit(_enlistmentSyncRoot); locked = false; } } // // NOTE: A timeout value of zero is special. It means never // sleep. // if (sleepMilliseconds == 0) return false; // // NOTE: How much time has elapsed since we first starting // waiting? // DateTime now = DateTime.UtcNow; TimeSpan elapsed = now.Subtract(start); // // NOTE: Are we done wait? // double totalMilliseconds = elapsed.TotalMilliseconds; if ((totalMilliseconds < 0) || /* Time went backward? */ (totalMilliseconds >= (double)timeoutMilliseconds)) { return false; } // // NOTE: Sleep for a bit and then try again. // Thread.Sleep(sleepMilliseconds); } } #endif /// <summary> /// Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value /// </summary> /// <param name="items">The list to look in</param> |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteEnlistment.cs.
︙ | ︙ | |||
102 103 104 105 106 107 108 | return defaultIsolationLevel; } /////////////////////////////////////////////////////////////////////////// private void Cleanup(SQLiteConnection cnn) { | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | return defaultIsolationLevel; } /////////////////////////////////////////////////////////////////////////// private void Cleanup(SQLiteConnection cnn) { if (_disposeConnection && (cnn != null)) cnn.Dispose(); _transaction = null; _scope = null; } #endregion |
︙ | ︙ | |||
180 181 182 183 184 185 186 | #endregion /////////////////////////////////////////////////////////////////////////// #region IEnlistmentNotification Members public void Commit(Enlistment enlistment) { | | | < | | > > > > > > > > > > > > > > > > > > > > > | | | > > > > | | | | | | | 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 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | #endregion /////////////////////////////////////////////////////////////////////////// #region IEnlistmentNotification Members public void Commit(Enlistment enlistment) { CheckDisposed(); SQLiteConnection cnn = null; try { while (true) { cnn = _transaction.Connection; if (cnn == null) break; lock (cnn._enlistmentSyncRoot) /* TRANSACTIONAL */ { // // NOTE: This check is necessary to detect the case where // the SQLiteConnection.Close() method changes the // connection associated with our transaction (i.e. // to avoid a race (condition) between grabbing the // Connection property and locking its enlistment). // if (!Object.ReferenceEquals(cnn, _transaction.Connection)) continue; cnn._enlistment = null; _transaction.IsValid(true); /* throw */ cnn._transactionLevel = 1; _transaction.Commit(); break; } } enlistment.Done(); } finally { Cleanup(cnn); } } /////////////////////////////////////////////////////////////////////////// public void InDoubt(Enlistment enlistment) { CheckDisposed(); |
︙ | ︙ | |||
223 224 225 226 227 228 229 | preparingEnlistment.Prepared(); } /////////////////////////////////////////////////////////////////////////// public void Rollback(Enlistment enlistment) { | | | < | | > > > > > > > > > > > > > > > > > > > > > | > > > > > | | | | | | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | preparingEnlistment.Prepared(); } /////////////////////////////////////////////////////////////////////////// public void Rollback(Enlistment enlistment) { CheckDisposed(); SQLiteConnection cnn = null; try { while (true) { cnn = _transaction.Connection; if (cnn == null) break; lock (cnn._enlistmentSyncRoot) /* TRANSACTIONAL */ { // // NOTE: This check is necessary to detect the case where // the SQLiteConnection.Close() method changes the // connection associated with our transaction (i.e. // to avoid a race (condition) between grabbing the // Connection property and locking its enlistment). // if (!Object.ReferenceEquals(cnn, _transaction.Connection)) continue; cnn._enlistment = null; _transaction.Rollback(); break; } } enlistment.Done(); } finally { Cleanup(cnn); } } #endregion } } #endif // !PLATFORM_COMPACT_FRAMEWORK |
Added Tests/tkt-5cee5409f8.eagle.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 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 | ############################################################################### # # tkt-5cee5409f8.eagle -- # # Written by Joe Mistachkin. # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle package require Eagle.Library package require Eagle.Test runTestPrologue ############################################################################### package require System.Data.SQLite.Test runSQLiteTestPrologue ############################################################################### runTest {test tkt-5cee5409f8-1.1 {asynchronous transaction handling} -setup { setupDb [set fileName tkt-5cee5409f8-1.1.db] } -body { sql execute $db "CREATE TABLE t1(x INTEGER);" set id [object invoke Interpreter.GetActive NextId] set dataSource [file join [getDatabaseDirectory] $fileName] unset -nocomplain results errors set code [compileCSharpWith [subst { using System; using System.Data.SQLite; using System.Threading; using System.Transactions; namespace _Dynamic${id} { public static class Test${id} { #region Private EnlistmentNotification Class private sealed class EnlistmentNotification : IEnlistmentNotification { #region Private Data private bool forceRollback; #endregion ///////////////////////////////////////////////////////////////////// #region Private Constructors private EnlistmentNotification(bool forceRollback) { this.forceRollback = forceRollback; } #endregion ///////////////////////////////////////////////////////////////////// #region IEnlistmentNotification Members public void Commit(Enlistment enlistment) { enlistment.Done(); } ///////////////////////////////////////////////////////////////////// public void InDoubt(Enlistment enlistment) { enlistment.Done(); } ///////////////////////////////////////////////////////////////////// public void Prepare(PreparingEnlistment preparingEnlistment) { if (forceRollback) preparingEnlistment.ForceRollback(); else preparingEnlistment.Prepared(); } ///////////////////////////////////////////////////////////////////// public void Rollback(Enlistment enlistment) { enlistment.Done(); } #endregion ///////////////////////////////////////////////////////////////////// #region Public Static Methods public static void UseDistributedTransaction(bool forceRollback) { Transaction.Current.EnlistDurable( Guid.NewGuid(), new EnlistmentNotification(forceRollback), EnlistmentOptions.None); } #endregion } #endregion /////////////////////////////////////////////////////////////////////// #region Private Static Data private static int resetCount; private static int timeoutCount; #endregion /////////////////////////////////////////////////////////////////////// #region Private Static Methods private static void DoTransactions(SQLiteConnection connection) { Random random = new Random(); for (int iteration = 0; iteration < 10000; iteration++) { using (TransactionScope transactionScope = new TransactionScope()) { EnlistmentNotification.UseDistributedTransaction(false); TransactionInformation transactionInformation = Transaction.Current.TransactionInformation; if (transactionInformation.DistributedIdentifier.Equals( Guid.Empty)) { throw new Exception("distributed identifier is empty"); } connection.EnlistTransaction(Transaction.Current); using (SQLiteCommand command = connection.CreateCommand()) { command.CommandText = "INSERT INTO t1(x) VALUES(?);"; command.Parameters.Add(new SQLiteParameter("", iteration)); command.ExecuteNonQuery(); } transactionScope.Complete(); } Thread.Sleep(random.Next(10)); } } /////////////////////////////////////////////////////////////////////// private static void WaitOnEnlistments(object state) { SQLiteConnection connection = (SQLiteConnection)state; Random random = new Random(); for (int iteration = 0; iteration < 1000; iteration++) { if (connection.WaitForEnlistmentReset(1)) Interlocked.Increment(ref resetCount); else Interlocked.Increment(ref timeoutCount); Thread.Sleep(random.Next(100)); } } #endregion /////////////////////////////////////////////////////////////////////// #region Public Static Methods public static string DoTest() { using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};[getTestProperties]")) { ThreadPool.QueueUserWorkItem(WaitOnEnlistments, connection); connection.Open(); DoTransactions(connection); } int count1 = Interlocked.CompareExchange(ref resetCount, 0, 0); int count2 = Interlocked.CompareExchange(ref timeoutCount, 0, 0); return String.Format("{0}, {1}", count1, count2); } /////////////////////////////////////////////////////////////////////// public static void Main() { // do nothing. } #endregion } } }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} DoTest } result] : [set result ""]}] \ [expr {[lindex $result 0] > 0}] \ [expr {[lindex $result 1] > 0}] } -cleanup { cleanupDb $fileName unset -nocomplain result results errors code dataSource id db fileName } -constraints {eagle command.object monoBug211 monoBug54 command.sql\ compile.DATA SQLite System.Data.SQLite compileCSharp} -match regexp -result \ {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 True True$}} ############################################################################### runSQLiteTestEpilogue runTestEpilogue |
Changes to readme.htm.
︙ | ︙ | |||
209 210 211 212 213 214 215 216 217 218 219 220 221 222 | <p> <b>1.0.107.0 - January XX, 2018 <font color="red">(release scheduled)</font></b> </p> <ul> <li>Updated to <a href="https://www.sqlite.org/draft/releaselog/3_22_0.html">SQLite 3.22.0</a>.</li> <li>Improve performance of type name lookups by removing superfluous locking and string creation.</li> <li>Fix some internal memory accounting present only in the debug build.</li> <li>Make sure inbound native delegates are unhooked before adding a connection to the pool. Fix for [0e48e80333].</li> <li>Add preliminary support for the .NET Framework 4.7.1.</li> <li>Updates to internal DbType mapping related lookup tables. Pursuant to [a799e3978f].</li> </ul> <p> <b>1.0.106.0 - November 2, 2017</b> | > > | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | <p> <b>1.0.107.0 - January XX, 2018 <font color="red">(release scheduled)</font></b> </p> <ul> <li>Updated to <a href="https://www.sqlite.org/draft/releaselog/3_22_0.html">SQLite 3.22.0</a>.</li> <li>Improve performance of type name lookups by removing superfluous locking and string creation.</li> <li>Support asynchronous completion of distributed transactions. Fix for [5cee5409f8].</li> <li>Add experimental WaitForEnlistmentReset method to the SQLiteConnection class. Pursuant to [7e1dd697dc].</li> <li>Fix some internal memory accounting present only in the debug build.</li> <li>Make sure inbound native delegates are unhooked before adding a connection to the pool. Fix for [0e48e80333].</li> <li>Add preliminary support for the .NET Framework 4.7.1.</li> <li>Updates to internal DbType mapping related lookup tables. Pursuant to [a799e3978f].</li> </ul> <p> <b>1.0.106.0 - November 2, 2017</b> |
︙ | ︙ |
Changes to www/news.wiki.
︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 56 57 58 59 | <p> <b>1.0.107.0 - January XX, 2018 <font color="red">(release scheduled)</font></b> </p> <ul> <li>Updated to [https://www.sqlite.org/draft/releaselog/3_22_0.html|SQLite 3.22.0].</li> <li>Improve performance of type name lookups by removing superfluous locking and string creation.</li> <li>Fix some internal memory accounting present only in the debug build.</li> <li>Make sure inbound native delegates are unhooked before adding a connection to the pool. Fix for [0e48e80333].</li> <li>Add preliminary support for the .NET Framework 4.7.1.</li> <li>Updates to internal DbType mapping related lookup tables. Pursuant to [a799e3978f].</li> </ul> <p> <b>1.0.106.0 - November 2, 2017</b> | > > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | <p> <b>1.0.107.0 - January XX, 2018 <font color="red">(release scheduled)</font></b> </p> <ul> <li>Updated to [https://www.sqlite.org/draft/releaselog/3_22_0.html|SQLite 3.22.0].</li> <li>Improve performance of type name lookups by removing superfluous locking and string creation.</li> <li>Support asynchronous completion of distributed transactions. Fix for [5cee5409f8].</li> <li>Add experimental WaitForEnlistmentReset method to the SQLiteConnection class. Pursuant to [7e1dd697dc].</li> <li>Fix some internal memory accounting present only in the debug build.</li> <li>Make sure inbound native delegates are unhooked before adding a connection to the pool. Fix for [0e48e80333].</li> <li>Add preliminary support for the .NET Framework 4.7.1.</li> <li>Updates to internal DbType mapping related lookup tables. Pursuant to [a799e3978f].</li> </ul> <p> <b>1.0.106.0 - November 2, 2017</b> |
︙ | ︙ |