Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Improve diagnostics for test data-1.1. Fix connection handle leak by removing superfluous _ownHandle fields and add properties instead. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | virtualTables |
Files: | files | file ages | folders |
SHA1: |
0e4ebe697a83904197f671e5b88cef1c |
User & Date: | mistachkin 2013-06-22 00:52:12.459 |
Context
2013-06-22
| ||
01:35 | Make the error codes used with the SQLiteException class consistent. Throw an exception if the SQLite3.Open method is called when already open. check-in: 7aae5042f8 user: mistachkin tags: virtualTables | |
00:52 | Improve diagnostics for test data-1.1. Fix connection handle leak by removing superfluous _ownHandle fields and add properties instead. check-in: 0e4ebe697a user: mistachkin tags: virtualTables | |
2013-06-21
| ||
23:44 | In the SQLite3.Close method, be sure to null out of the _sql field when _ownHandle is false. Centralize the SQLite3 instance creation logic used by the SQLiteConnection class. Restrict the ConnectionStringBuilder test to run only when SQLite is in use. check-in: 67f779810e user: mistachkin tags: virtualTables | |
Changes
Changes to System.Data.SQLite/SQLite3.cs.
︙ | ︙ | |||
68 69 70 71 72 73 74 | protected bool _usePool; protected int _poolVersion; #if (NET_35 || NET_40 || NET_45) && !PLATFORM_COMPACTFRAMEWORK private bool _buildingSchema; #endif | < < < < < < | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | protected bool _usePool; protected int _poolVersion; #if (NET_35 || NET_40 || NET_45) && !PLATFORM_COMPACTFRAMEWORK private bool _buildingSchema; #endif /// <summary> /// The user-defined functions registered on this connection /// </summary> protected SQLiteFunction[] _functionsArray; /// <summary> /// The modules created using this connection. |
︙ | ︙ | |||
98 99 100 101 102 103 104 | string fileName, bool ownHandle ) : base(fmt, kind, fmtString) { if (db != IntPtr.Zero) { | < | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | string fileName, bool ownHandle ) : base(fmt, kind, fmtString) { if (db != IntPtr.Zero) { _sql = new SQLiteConnectionHandle(db, ownHandle); _fileName = fileName; } } /////////////////////////////////////////////////////////////////////////////////////////////// #region IDisposable "Pattern" Members |
︙ | ︙ | |||
168 169 170 171 172 173 174 | // It isn't necessary to cleanup any functions we've registered. If the connection // goes to the pool and is resurrected later, re-registered functions will overwrite the // previous functions. The SQLiteFunctionCookieHandle will take care of freeing unmanaged // resources belonging to the previously-registered functions. internal override void Close(bool canThrow) { | > > | | | | | < < | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | // It isn't necessary to cleanup any functions we've registered. If the connection // goes to the pool and is resurrected later, re-registered functions will overwrite the // previous functions. The SQLiteFunctionCookieHandle will take care of freeing unmanaged // resources belonging to the previously-registered functions. internal override void Close(bool canThrow) { if (_sql != null) { if (!_sql.OwnHandle) { _sql = null; return; } if (_usePool) { if (SQLiteBase.ResetConnection(_sql, _sql, canThrow)) { SQLiteConnectionPool.Add(_fileName, _sql, _poolVersion); #if !NET_COMPACT_20 && TRACE_CONNECTION |
︙ | ︙ | |||
340 341 342 343 344 345 346 347 348 349 350 351 352 353 | UnsafeNativeMethods.sqlite3_memory_highwater_interop(0, ref bytes); return bytes; #else throw new NotImplementedException(); #endif } } internal override SQLiteErrorCode SetMemoryStatus(bool value) { return StaticSetMemoryStatus(value); } internal static SQLiteErrorCode StaticSetMemoryStatus(bool value) | > > > > > > > > > > > > > > > > > > | 333 334 335 336 337 338 339 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 | 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 { get { if (_sql == null) { throw new SQLiteException(SQLiteErrorCode.Error, "no connection handle available"); } return _sql.OwnHandle; } } internal override SQLiteErrorCode SetMemoryStatus(bool value) { return StaticSetMemoryStatus(value); } internal static SQLiteErrorCode StaticSetMemoryStatus(bool value) |
︙ | ︙ | |||
413 414 415 416 417 418 419 | } #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(String.Format("Open: {0}", db)); #endif if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null); | < | | 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | } #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(String.Format("Open: {0}", db)); #endif if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null); _sql = new SQLiteConnectionHandle(db, true); } lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ } } // Bind functions to this connection. If any previous functions of the same name // were already bound, then the new bindings replace the old. _functionsArray = SQLiteFunction.BindFunctions(this, connectionFlags); SetTimeout(0); |
︙ | ︙ |
Changes to System.Data.SQLite/SQLite3_UTF16.cs.
︙ | ︙ | |||
146 147 148 149 150 151 152 | } #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(String.Format("Open16: {0}", db)); #endif if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null); | < | | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | } #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(String.Format("Open16: {0}", db)); #endif if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null); _sql = new SQLiteConnectionHandle(db, true); } lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ } } _functionsArray = SQLiteFunction.BindFunctions(this, connectionFlags); SetTimeout(0); GC.KeepAlive(_sql); } |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteBase.cs.
︙ | ︙ | |||
54 55 56 57 58 59 60 61 62 63 64 65 66 67 | /// </summary> internal abstract long MemoryUsed { get; } /// <summary> /// Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. /// This is not really a per-connection value, it is global to the process. /// </summary> internal abstract long MemoryHighwater { get; } /// <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> /// <returns>A standard SQLite return code (i.e. zero for success and non-zero for failure).</returns> | > > > > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | /// </summary> internal abstract long MemoryUsed { get; } /// <summary> /// Returns the maximum amount of memory (in bytes) used by the SQLite core library since the high-water mark was last reset. /// This is not really a per-connection value, it is global to the process. /// </summary> internal abstract long MemoryHighwater { get; } /// <summary> /// Returns non-zero if the underlying native connection handle is owned by this instance. /// </summary> internal abstract bool OwnHandle { get; } /// <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> /// <returns>A standard SQLite return code (i.e. zero for success and non-zero for failure).</returns> |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteConnection.cs.
︙ | ︙ | |||
400 401 402 403 404 405 406 | #if !PLATFORM_COMPACTFRAMEWORK /// <summary> /// Whether or not the connection is enlisted in a distrubuted transaction /// </summary> internal SQLiteEnlistment _enlistment; #endif | < < < < < < | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 | #if !PLATFORM_COMPACTFRAMEWORK /// <summary> /// Whether or not the connection is enlisted in a distrubuted transaction /// </summary> internal SQLiteEnlistment _enlistment; #endif /// <summary> /// The base SQLite object to interop with /// </summary> internal SQLiteBase _sql; /// <summary> /// The database filename minus path and extension /// </summary> |
︙ | ︙ | |||
507 508 509 510 511 512 513 | /// <param name="ownHandle"> /// Non-zero if this instance owns the native connection handle and /// should dispose of it when it is no longer needed. /// </param> internal SQLiteConnection(IntPtr db, string fileName, bool ownHandle) : this() { | < < | | 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 | /// <param name="ownHandle"> /// Non-zero if this instance owns the native connection handle and /// should dispose of it when it is no longer needed. /// </param> internal SQLiteConnection(IntPtr db, string fileName, bool ownHandle) : this() { _sql = new SQLite3( SQLiteDateFormats.Default, DateTimeKind.Unspecified, null, db, fileName, ownHandle); _flags = SQLiteConnectionFlags.None; _connectionState = (db != IntPtr.Zero) ? ConnectionState.Open : ConnectionState.Closed; _connectionString = null; /* unknown */ |
︙ | ︙ | |||
905 906 907 908 909 910 911 | string dateTimeFormat = FindKey(opts, "DateTimeFormatString", DefaultDateTimeFormatString); // // NOTE: SQLite automatically sets the encoding of the database // to UTF16 if called from sqlite3_open16(). // | < < | | | 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 | string dateTimeFormat = FindKey(opts, "DateTimeFormatString", DefaultDateTimeFormatString); // // NOTE: SQLite automatically sets the encoding of the database // to UTF16 if called from sqlite3_open16(). // if (SQLiteConvert.ToBoolean(FindKey(opts, "UseUTF16Encoding", DefaultUseUTF16Encoding.ToString()))) { _sql = new SQLite3_UTF16( dateFormat, kind, dateTimeFormat, IntPtr.Zero, null, false); } else { _sql = new SQLite3( dateFormat, kind, dateTimeFormat, IntPtr.Zero, null, false); } } /////////////////////////////////////////////////////////////////////////////////////////////// #region IDisposable "Pattern" Members private bool disposed; |
︙ | ︙ | |||
2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 | /// possible values. /// </summary> public SQLiteConnectionFlags Flags { get { CheckDisposed(); return _flags; } set { CheckDisposed(); _flags = value; } } /// <summary> /// Returns the version of the underlying SQLite database engine /// </summary> #if !PLATFORM_COMPACTFRAMEWORK [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] #endif | > > > > > > > > > > > > > > > > > | 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 | /// possible values. /// </summary> public SQLiteConnectionFlags Flags { get { CheckDisposed(); return _flags; } set { CheckDisposed(); _flags = value; } } /// <summary> /// Returns non-zero if the underlying native connection handle is /// owned by this instance. /// </summary> public bool OwnHandle { get { CheckDisposed(); if (_sql == null) throw new InvalidOperationException("Database connection not valid for checking handle."); return _sql.OwnHandle; } } /// <summary> /// Returns the version of the underlying SQLite database engine /// </summary> #if !PLATFORM_COMPACTFRAMEWORK [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] #endif |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteLog.cs.
︙ | ︙ | |||
180 181 182 183 184 185 186 | // // NOTE: Create an instance of the SQLite wrapper class. // if (_sql == null) { _sql = new SQLite3( SQLiteDateFormats.Default, DateTimeKind.Unspecified, | | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | // // NOTE: Create an instance of the SQLite wrapper class. // if (_sql == null) { _sql = new SQLite3( SQLiteDateFormats.Default, DateTimeKind.Unspecified, null, IntPtr.Zero, null, false); } // // NOTE: Create a single "global" (i.e. per-process) callback // to register with SQLite. This callback will pass the // event on to any registered handler. We only want to // do this once. |
︙ | ︙ |
Changes to System.Data.SQLite/UnsafeNativeMethods.cs.
︙ | ︙ | |||
2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 | #if COUNT_HANDLE public int WasReleasedOk() { return Interlocked.Decrement( ref UnsafeNativeMethods.connectionCount); } #endif /////////////////////////////////////////////////////////////////////// public override bool IsInvalid { get { | > > > > > > > > > > > > > > > | 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 | #if COUNT_HANDLE public int WasReleasedOk() { return Interlocked.Decrement( ref UnsafeNativeMethods.connectionCount); } #endif /////////////////////////////////////////////////////////////////////// public bool OwnHandle { get { #if PLATFORM_COMPACTFRAMEWORK lock (syncRoot) #endif { return ownHandle; } } } /////////////////////////////////////////////////////////////////////// public override bool IsInvalid { get { |
︙ | ︙ |
Changes to Tests/basic.eagle.
︙ | ︙ | |||
74 75 76 77 78 79 80 81 82 83 84 85 86 87 | # NOTE: For the sake of backward compatibility, the "-autoRun" argument # must be first. # testClrExec $testExeFile [list -eventflags Wait -directory \ [file dirname $testExeFile] -stdout output -success 0] -autoRun \ -fileName [appendArgs \" [file nativename $fileName] \"] } error] tlog "---- BEGIN STDOUT OUTPUT\n" tlog $output tlog "\n---- END STDOUT OUTPUT\n" list $code [expr {$code == 0 ? "" : $error}] } -cleanup { | > > > > > > > > > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | # NOTE: For the sake of backward compatibility, the "-autoRun" argument # must be first. # testClrExec $testExeFile [list -eventflags Wait -directory \ [file dirname $testExeFile] -stdout output -success 0] -autoRun \ -fileName [appendArgs \" [file nativename $fileName] \"] } error] set successCount [regexp -all -- {\tSucceeded\t} $output] set failureCount [regexp -all -- {\tFailed\t} $output] set totalCount [expr {$successCount + $failureCount}] tputs $test_channel [appendArgs \ "---- found and executed " $totalCount " unit tests from \"" \ $testExeFile "\", " $successCount " passed, " $failureCount \ " failed\n"] tlog "---- BEGIN STDOUT OUTPUT\n" tlog $output tlog "\n---- END STDOUT OUTPUT\n" list $code [expr {$code == 0 ? "" : $error}] } -cleanup { |
︙ | ︙ |