Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | virtualTables |
Files: | files | file ages | folders |
SHA1: |
67f779810e605ed88c9dac6d58ec72f7 |
User & Date: | mistachkin 2013-06-21 23:44:34.746 |
Context
2013-06-22
| ||
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 | |
21:01 | Fix vtshim error message handling. Adjust the data-1.28 test to account for the new SQLite3 constructor parameters. Fix delegate declaration for the xFilter method. check-in: ee4c57e435 user: mistachkin tags: virtualTables | |
Changes
Changes to System.Data.SQLite/SQLite3.cs.
︙ | ︙ | |||
98 99 100 101 102 103 104 | string fileName, bool ownHandle ) : base(fmt, kind, fmtString) { if (db != IntPtr.Zero) { | > | < | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | string fileName, bool ownHandle ) : base(fmt, kind, fmtString) { if (db != IntPtr.Zero) { _ownHandle = ownHandle; _sql = new SQLiteConnectionHandle(db, _ownHandle); _fileName = fileName; } } /////////////////////////////////////////////////////////////////////////////////////////////// #region IDisposable "Pattern" Members private bool disposed; |
︙ | ︙ | |||
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | // 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 (!_ownHandle) return; if (_sql != null) { if (_usePool) { if (SQLiteBase.ResetConnection(_sql, _sql, canThrow)) { | > > > | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | // 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 (!_ownHandle) { _sql = null; return; } if (_sql != null) { if (_usePool) { if (SQLiteBase.ResetConnection(_sql, _sql, canThrow)) { |
︙ | ︙ | |||
528 529 530 531 532 533 534 | } else if (n == SQLiteErrorCode.Locked || n == SQLiteErrorCode.Busy) return n; if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError()); | | | 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | } else if (n == SQLiteErrorCode.Locked || n == SQLiteErrorCode.Busy) return n; if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError()); return n; // We reset OK, no schema changes } internal override string GetLastError() { return SQLiteBase.GetLastError(_sql, _sql); } |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteConnection.cs.
︙ | ︙ | |||
512 513 514 515 516 517 518 519 520 521 522 523 524 525 | : this() { _ownHandle = ownHandle; _sql = new SQLite3( SQLiteDateFormats.Default, DateTimeKind.Unspecified, null, db, fileName, _ownHandle); } /// <summary> /// Initializes the connection with the specified connection string. /// </summary> /// <param name="connectionString"> /// The connection string to use. | > > > > > > > | 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 | : this() { _ownHandle = ownHandle; _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 */ } /// <summary> /// Initializes the connection with the specified connection string. /// </summary> /// <param name="connectionString"> /// The connection string to use. |
︙ | ︙ | |||
567 568 569 570 571 572 573 | { UnsafeNativeMethods.sqlite3_log( SQLiteErrorCode.Ok, SQLiteConvert.ToUTF8("logging initialized.")); } #endif _parseViaFramework = parseViaFramework; | < < < | | 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 | { UnsafeNativeMethods.sqlite3_log( SQLiteErrorCode.Ok, SQLiteConvert.ToUTF8("logging initialized.")); } #endif _parseViaFramework = parseViaFramework; _flags = SQLiteConnectionFlags.Default; _connectionState = ConnectionState.Closed; _connectionString = null; if (connectionString != null) ConnectionString = connectionString; } /// <summary> /// Clones the settings and connection string from an existing connection. If the existing connection is already open, this /// function will open its own connection, enumerate any attached databases of the original connection, and automatically /// attach to them. /// </summary> /// <param name="connection">The connection to copy the settings from.</param> public SQLiteConnection(SQLiteConnection connection) : this(connection.ConnectionString, connection.ParseViaFramework) { if (connection.State == ConnectionState.Open) { Open(); // Reattach all attached databases from the existing connection using (DataTable tbl = connection.GetSchema("Catalogs")) { foreach (DataRow row in tbl.Rows) { string str = row[0].ToString(); if (String.Compare(str, "main", StringComparison.OrdinalIgnoreCase) != 0 && String.Compare(str, "temp", StringComparison.OrdinalIgnoreCase) != 0) { using (SQLiteCommand cmd = CreateCommand()) { cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "ATTACH DATABASE '{0}' AS [{1}]", row[1], row[0]); cmd.ExecuteNonQuery(); |
︙ | ︙ | |||
861 862 863 864 865 866 867 868 869 870 871 872 873 874 | if (handle.IsInvalid) throw new InvalidOperationException("The connection handle is invalid."); if (handle.IsClosed) throw new InvalidOperationException("The connection handle is closed."); } /////////////////////////////////////////////////////////////////////////////////////////////// #region IDisposable "Pattern" Members private bool disposed; private void CheckDisposed() /* throw */ { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 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 923 924 925 926 927 928 929 930 931 932 933 934 | if (handle.IsInvalid) throw new InvalidOperationException("The connection handle is invalid."); if (handle.IsClosed) throw new InvalidOperationException("The connection handle is closed."); } /////////////////////////////////////////////////////////////////////////////////////////////// private static SortedList<string, string> ParseConnectionString( string connectionString, bool parseViaFramework ) { return parseViaFramework ? ParseConnectionStringViaFramework(connectionString, false) : ParseConnectionString(connectionString); } /////////////////////////////////////////////////////////////////////////////////////////////// private void SetupSQLiteBase(SortedList<string, string> opts) { object enumValue; enumValue = TryParseEnum( typeof(SQLiteDateFormats), FindKey(opts, "DateTimeFormat", DefaultDateTimeFormat.ToString()), true); SQLiteDateFormats dateFormat = (enumValue is SQLiteDateFormats) ? (SQLiteDateFormats)enumValue : DefaultDateTimeFormat; enumValue = TryParseEnum( typeof(DateTimeKind), FindKey(opts, "DateTimeKind", DefaultDateTimeKind.ToString()), true); DateTimeKind kind = (enumValue is DateTimeKind) ? (DateTimeKind)enumValue : DefaultDateTimeKind; string dateTimeFormat = FindKey(opts, "DateTimeFormatString", DefaultDateTimeFormatString); // // NOTE: SQLite automatically sets the encoding of the database // to UTF16 if called from sqlite3_open16(). // _ownHandle = true; if (SQLiteConvert.ToBoolean(FindKey(opts, "UseUTF16Encoding", DefaultUseUTF16Encoding.ToString()))) { _sql = new SQLite3_UTF16( dateFormat, kind, dateTimeFormat, IntPtr.Zero, null, _ownHandle); } else { _sql = new SQLite3( dateFormat, kind, dateTimeFormat, IntPtr.Zero, null, _ownHandle); } } /////////////////////////////////////////////////////////////////////////////////////////////// #region IDisposable "Pattern" Members private bool disposed; private void CheckDisposed() /* throw */ { |
︙ | ︙ | |||
1863 1864 1865 1866 1867 1868 1869 | SQLiteConnectionEventType.Opening, null, null, null, null, null)); if (_connectionState != ConnectionState.Closed) throw new InvalidOperationException(); Close(); | | < | | 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 | SQLiteConnectionEventType.Opening, null, null, null, null, null)); if (_connectionState != ConnectionState.Closed) throw new InvalidOperationException(); Close(); SortedList<string, string> opts = ParseConnectionString( _connectionString, _parseViaFramework); OnChanged(this, new ConnectionEventArgs( SQLiteConnectionEventType.ConnectionString, null, null, null, _connectionString, opts)); object enumValue; enumValue = TryParseEnum(typeof(SQLiteConnectionFlags), FindKey(opts, "Flags", DefaultFlags.ToString()), true); |
︙ | ︙ | |||
1932 1933 1934 1935 1936 1937 1938 | if (_defaultIsolation != IsolationLevel.Serializable && _defaultIsolation != IsolationLevel.ReadCommitted) throw new NotSupportedException("Invalid Default IsolationLevel specified"); _baseSchemaName = FindKey(opts, "BaseSchemaName", DefaultBaseSchemaName); if (_sql == null) { | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 | if (_defaultIsolation != IsolationLevel.Serializable && _defaultIsolation != IsolationLevel.ReadCommitted) throw new NotSupportedException("Invalid Default IsolationLevel specified"); _baseSchemaName = FindKey(opts, "BaseSchemaName", DefaultBaseSchemaName); if (_sql == null) { SetupSQLiteBase(opts); } SQLiteOpenFlagsEnum flags = SQLiteOpenFlagsEnum.None; if (!SQLiteConvert.ToBoolean(FindKey(opts, "FailIfMissing", DefaultFailIfMissing.ToString()))) flags |= SQLiteOpenFlagsEnum.Create; |
︙ | ︙ | |||
2361 2362 2363 2364 2365 2366 2367 | public SQLiteErrorCode Shutdown() { CheckDisposed(); // make sure we have an instance of the base class if (_sql == null) { | | < | < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 | public SQLiteErrorCode Shutdown() { CheckDisposed(); // make sure we have an instance of the base class if (_sql == null) { SortedList<string, string> opts = ParseConnectionString( _connectionString, _parseViaFramework); SetupSQLiteBase(opts); } if (_sql != null) return _sql.Shutdown(); throw new InvalidOperationException("Database connection not active."); } /// Enables or disabled extended result codes returned by SQLite public void SetExtendedResultCodes(bool bOnOff) |
︙ | ︙ |
Changes to test/TestCases.cs.
︙ | ︙ | |||
1222 1223 1224 1225 1226 1227 1228 | } } } [Test] internal void ConnectionStringBuilder() { | > > | | | | > | 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 | } } } [Test] internal void ConnectionStringBuilder() { if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) > -1) { DbConnectionStringBuilder builder = _fact.CreateConnectionStringBuilder(); if (builder is SQLiteConnectionStringBuilder) { bool pool = ((SQLiteConnectionStringBuilder)builder).Pooling; } } } [Test] internal void LeakyCommands() { for (int n = 0; n < 100000; n++) |
︙ | ︙ |