Index: Doc/Extra/version.html
==================================================================
--- Doc/Extra/version.html
+++ Doc/Extra/version.html
@@ -47,10 +47,12 @@
- Updated to SQLite 3.8.1.
- Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for [3113734605].
- Check the result of sqlite3_column_name function against NULL.
- Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.
+ - Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Pursuant to [aba4549801].
+ - Revise how the extra object data is passed to the static SQLiteConnection.Changed event. ** Potentially Incompatible Change **
1.0.88.0 - August 7, 2013
- Various fixes to managed virtual table integration infrastructure.
- Implement workaround for an incorrect PROCESSOR_ARCHITECTURE being reported. Fix for [9ac9862611].
Index: System.Data.SQLite/SQLite3.cs
==================================================================
--- System.Data.SQLite/SQLite3.cs
+++ System.Data.SQLite/SQLite3.cs
@@ -124,10 +124,15 @@
{
if (db != IntPtr.Zero)
{
_sql = new SQLiteConnectionHandle(db, ownHandle);
_fileName = fileName;
+
+ SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
+ SQLiteConnectionEventType.NewCriticalHandle, null, null,
+ null, null, _sql, fileName, new object[] { fmt, kind,
+ fmtString, db, fileName, ownHandle }));
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -535,10 +540,15 @@
if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
_sql = new SQLiteConnectionHandle(db, true);
}
lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ }
+
+ SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
+ SQLiteConnectionEventType.NewCriticalHandle, null, null,
+ null, null, _sql, strFilename, new object[] { strFilename,
+ connectionFlags, openFlags, maxPoolSize, usePool }));
}
// Bind functions to this connection. If any previous functions of the same name
// were already bound, then the new bindings replace the old.
if ((connectionFlags & SQLiteConnectionFlags.NoBindFunctions) != SQLiteConnectionFlags.NoBindFunctions)
@@ -741,11 +751,22 @@
#if !NET_COMPACT_20 && TRACE_STATEMENT
Trace.WriteLine(String.Format("Prepare ({0}): {1}", n, stmt));
#endif
if ((n == SQLiteErrorCode.Ok) && (stmt != IntPtr.Zero))
+ {
+ if (statementHandle != null) statementHandle.Dispose();
statementHandle = new SQLiteStatementHandle(_sql, stmt);
+ }
+ }
+
+ if (statementHandle != null)
+ {
+ SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
+ SQLiteConnectionEventType.NewCriticalHandle, null, null,
+ null, null, statementHandle, strSql, new object[] { cnn,
+ strSql, previous, timeoutMS }));
}
if (n == SQLiteErrorCode.Schema)
retries++;
else if (n == SQLiteErrorCode.Error)
@@ -2105,10 +2126,15 @@
throw new SQLiteException("failed to initialize backup");
}
backupHandle = new SQLiteBackupHandle(destHandle, backup);
}
+
+ SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
+ SQLiteConnectionEventType.NewCriticalHandle, null, null,
+ null, null, backupHandle, null, new object[] { destCnn,
+ destName, sourceName }));
return new SQLiteBackup(
this, backupHandle, destHandle, zDestName, sourceHandle,
zSourceName);
}
Index: System.Data.SQLite/SQLite3_UTF16.cs
==================================================================
--- System.Data.SQLite/SQLite3_UTF16.cs
+++ System.Data.SQLite/SQLite3_UTF16.cs
@@ -194,10 +194,15 @@
if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
_sql = new SQLiteConnectionHandle(db, true);
}
lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ }
+
+ SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
+ SQLiteConnectionEventType.NewCriticalHandle, null, null,
+ null, null, _sql, strFilename, new object[] { strFilename,
+ connectionFlags, openFlags, maxPoolSize, usePool }));
}
// Bind functions to this connection. If any previous functions of the same name
// were already bound, then the new bindings replace the old.
if ((connectionFlags & SQLiteConnectionFlags.NoBindFunctions) != SQLiteConnectionFlags.NoBindFunctions)
Index: System.Data.SQLite/SQLiteCommand.cs
==================================================================
--- System.Data.SQLite/SQLiteCommand.cs
+++ System.Data.SQLite/SQLiteCommand.cs
@@ -149,11 +149,12 @@
if (transaction != null)
Transaction = transaction;
SQLiteConnection.OnChanged(connection, new ConnectionEventArgs(
- SQLiteConnectionEventType.NewCommand, null, transaction, this, null, null));
+ SQLiteConnectionEventType.NewCommand, null, transaction, this,
+ null, null, null, null));
}
///////////////////////////////////////////////////////////////////////////////////////////////
[Conditional("CHECK_STATE")]
Index: System.Data.SQLite/SQLiteConnection.cs
==================================================================
--- System.Data.SQLite/SQLiteConnection.cs
+++ System.Data.SQLite/SQLiteConnection.cs
@@ -43,10 +43,20 @@
///
/// The command associated with this event, if any.
///
public readonly IDbCommand Command;
+ ///
+ /// The data reader associated with this event, if any.
+ ///
+ public readonly IDataReader DataReader;
+
+ ///
+ /// The critical handle associated with this event, if any.
+ ///
+ public readonly CriticalHandle CriticalHandle;
+
///
/// Command or message text associated with this event, if any.
///
public readonly string Text;
@@ -61,25 +71,31 @@
/// The type of event being raised.
/// The base associated
/// with this event, if any.
/// The transaction associated with this event, if any.
/// The command associated with this event, if any.
+ /// The data reader associated with this event, if any.
+ /// The critical handle associated with this event, if any.
/// The command or message text, if any.
/// The extra data, if any.
internal ConnectionEventArgs(
SQLiteConnectionEventType eventType,
StateChangeEventArgs eventArgs,
IDbTransaction transaction,
IDbCommand command,
+ IDataReader dataReader,
+ CriticalHandle criticalHandle,
string text,
object data
)
{
EventType = eventType;
EventArgs = eventArgs;
Transaction = transaction;
Command = command;
+ DataReader = dataReader;
+ CriticalHandle = criticalHandle;
Text = text;
Data = data;
}
}
@@ -388,11 +404,11 @@
internal int _transactionLevel;
///
/// If set, then the connection is currently being disposed.
///
- private bool _disposing;
+ private bool _disposing;
///
/// The default isolation level for new transactions
///
private IsolationLevel _defaultIsolation;
@@ -429,11 +445,11 @@
///
/// The extra behavioral flags for this connection, if any. See the
/// enumeration for a list of
/// possible values.
///
- private SQLiteConnectionFlags _flags;
+ private SQLiteConnectionFlags _flags;
///
/// Default command timeout
///
private int _defaultTimeout = 30;
@@ -489,10 +505,12 @@
// do nothing.
}
///
/// Initializes the connection with a pre-existing native connection handle.
+ /// This constructor overload is intended to be used only by the private
+ /// method.
///
///
/// The native connection handle to use.
///
///
@@ -615,25 +633,24 @@
///
/// Raises the event.
///
///
- /// The connection associated with this event.
+ /// The connection associated with this event. If this parameter is not
+ /// null and the specified connection cannot raise events, then the
+ /// registered event handlers will not be invoked.
///
///
/// A that contains the event data.
///
internal static void OnChanged(
SQLiteConnection connection,
ConnectionEventArgs e
)
{
- if (connection == null)
- return;
-
#if !PLATFORM_COMPACTFRAMEWORK
- if (!connection.CanRaiseEvents)
+ if ((connection != null) && !connection.CanRaiseEvents)
return;
#endif
SQLiteConnectionEventHandler handlers;
@@ -710,12 +727,30 @@
///
public static object CreateHandle(
IntPtr nativeHandle
)
{
- if (nativeHandle == IntPtr.Zero) return null;
- return new SQLiteConnectionHandle(nativeHandle, true);
+ SQLiteConnectionHandle result;
+
+ try
+ {
+ // do nothing.
+ }
+ finally /* NOTE: Thread.Abort() protection. */
+ {
+ result = (nativeHandle != IntPtr.Zero) ?
+ new SQLiteConnectionHandle(nativeHandle, true) : null;
+ }
+
+ if (result != null)
+ {
+ SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
+ SQLiteConnectionEventType.NewCriticalHandle, null, null,
+ null, null, result, null, new object[] { nativeHandle }));
+ }
+
+ return result;
}
///////////////////////////////////////////////////////////////////////////////////////////////
#region Backup API Members
@@ -1135,11 +1170,12 @@
SQLiteTransaction transaction =
new SQLiteTransaction(this, isolationLevel != IsolationLevel.Serializable);
OnChanged(this, new ConnectionEventArgs(
- SQLiteConnectionEventType.NewTransaction, null, transaction, null, null, null));
+ SQLiteConnectionEventType.NewTransaction, null, transaction,
+ null, null, null, null, null));
return transaction;
}
///
@@ -1150,11 +1186,12 @@
public override void ChangeDatabase(string databaseName)
{
CheckDisposed();
OnChanged(this, new ConnectionEventArgs(
- SQLiteConnectionEventType.ChangeDatabase, null, null, null, databaseName, null));
+ SQLiteConnectionEventType.ChangeDatabase, null, null, null, null,
+ null, databaseName, null));
throw new NotImplementedException(); // NOTE: For legacy compatibility.
}
///
@@ -1163,11 +1200,12 @@
public override void Close()
{
CheckDisposed();
OnChanged(this, new ConnectionEventArgs(
- SQLiteConnectionEventType.Closing, null, null, null, null, null));
+ SQLiteConnectionEventType.Closing, null, null, null, null, null,
+ null, null));
if (_sql != null)
{
#if !PLATFORM_COMPACTFRAMEWORK
if (_enlistment != null)
@@ -1199,11 +1237,12 @@
StateChangeEventArgs eventArgs = null;
OnStateChange(ConnectionState.Closed, ref eventArgs);
OnChanged(this, new ConnectionEventArgs(
- SQLiteConnectionEventType.Closed, eventArgs, null, null, null, null));
+ SQLiteConnectionEventType.Closed, eventArgs, null, null, null,
+ null, null, null));
}
///
/// Returns the number of pool entries for the file name associated with this connection.
///
@@ -1637,11 +1676,11 @@
// string parser as the built-in (i.e. framework provided) one is
// unavailable.
//
return ParseConnectionString(connectionString);
#endif
- }
+ }
#if !PLATFORM_COMPACTFRAMEWORK
///
/// Manual distributed transaction enlistment support
///
@@ -1661,11 +1700,12 @@
throw new ArgumentNullException("Unable to enlist in transaction, it is null");
_enlistment = new SQLiteEnlistment(this, transaction);
OnChanged(this, new ConnectionEventArgs(
- SQLiteConnectionEventType.EnlistTransaction, null, null, null, null, _enlistment));
+ SQLiteConnectionEventType.EnlistTransaction, null, null, null, null,
+ null, null, new object[] { _enlistment }));
}
#endif
///
/// Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value
@@ -1950,11 +1990,12 @@
public override void Open()
{
CheckDisposed();
OnChanged(this, new ConnectionEventArgs(
- SQLiteConnectionEventType.Opening, null, null, null, null, null));
+ SQLiteConnectionEventType.Opening, null, null, null, null, null,
+ null, null));
if (_connectionState != ConnectionState.Closed)
throw new InvalidOperationException();
Close();
@@ -1961,11 +2002,12 @@
SortedList opts = ParseConnectionString(
_connectionString, _parseViaFramework);
OnChanged(this, new ConnectionEventArgs(
- SQLiteConnectionEventType.ConnectionString, null, null, null, _connectionString, opts));
+ SQLiteConnectionEventType.ConnectionString, null, null, null, null,
+ null, _connectionString, new object[] { opts }));
object enumValue;
enumValue = TryParseEnum(typeof(SQLiteConnectionFlags), FindKey(opts, "Flags", DefaultFlags.ToString()), true);
_flags = (enumValue is SQLiteConnectionFlags) ? (SQLiteConnectionFlags)enumValue : DefaultFlags;
@@ -2191,11 +2233,12 @@
StateChangeEventArgs eventArgs = null;
OnStateChange(ConnectionState.Open, ref eventArgs);
OnChanged(this, new ConnectionEventArgs(
- SQLiteConnectionEventType.Opened, eventArgs, null, null, null, null));
+ SQLiteConnectionEventType.Opened, eventArgs, null, null, null,
+ null, null, null));
}
catch
{
_connectionState = oldstate;
throw;
Index: System.Data.SQLite/SQLiteConvert.cs
==================================================================
--- System.Data.SQLite/SQLiteConvert.cs
+++ System.Data.SQLite/SQLiteConvert.cs
@@ -1296,33 +1296,51 @@
///
/// A command was created using the connection.
///
NewCommand = 7,
+ ///
+ /// A data reader was created using the connection.
+ ///
+ NewDataReader = 8,
+
+ ///
+ /// An instance of a derived class has
+ /// been created to wrap a native resource.
+ ///
+ NewCriticalHandle = 9,
+
///
/// The connection is being closed.
///
- Closing = 8,
+ Closing = 10,
///
/// The connection was closed.
///
- Closed = 9
+ Closed = 11
}
///
- /// This implementation of SQLite for ADO.NET can process date/time fields in databases in only one of three formats. Ticks, ISO8601
- /// and JulianDay.
+ /// This implementation of SQLite for ADO.NET can process date/time fields in
+ /// databases in one of six formats.
///
///
- /// ISO8601 is more compatible, readable, fully-processable, but less accurate as it doesn't provide time down to fractions of a second.
- /// JulianDay is the numeric format the SQLite uses internally and is arguably the most compatible with 3rd party tools. It is
- /// not readable as text without post-processing.
- /// Ticks less compatible with 3rd party tools that query the database, and renders the DateTime field unreadable as text without post-processing.
+ /// ISO8601 format is more compatible, readable, fully-processable, but less
+ /// accurate as it does not provide time down to fractions of a second.
+ /// JulianDay is the numeric format the SQLite uses internally and is arguably
+ /// the most compatible with 3rd party tools. It is not readable as text
+ /// without post-processing. Ticks less compatible with 3rd party tools that
+ /// query the database, and renders the DateTime field unreadable as text
+ /// without post-processing. UnixEpoch is more compatible with Unix systems.
+ /// InvariantCulture allows the configured format for the invariant culture
+ /// format to be used and is human readable. CurrentCulture allows the
+ /// configured format for the current culture to be used and is also human
+ /// readable.
///
- /// The preferred order of choosing a datetime format is JulianDay, ISO8601, and then Ticks. Ticks is mainly present for legacy
- /// code support.
+ /// The preferred order of choosing a DateTime format is JulianDay, ISO8601,
+ /// and then Ticks. Ticks is mainly present for legacy code support.
///
public enum SQLiteDateFormats
{
///
/// Use the value of DateTime.Ticks. This value is not recommended and is not well supported with LINQ.
Index: System.Data.SQLite/SQLiteDataReader.cs
==================================================================
--- System.Data.SQLite/SQLiteDataReader.cs
+++ System.Data.SQLite/SQLiteDataReader.cs
@@ -100,14 +100,20 @@
_version = _command.Connection._version;
_baseSchemaName = _command.Connection._baseSchemaName;
_commandBehavior = behave;
_activeStatementIndex = -1;
- _rowsAffected = -1;
-
- if (_command != null)
- NextResult();
+ _rowsAffected = -1;
+
+ if (_command != null)
+ {
+ SQLiteConnection.OnChanged(_command.Connection,
+ new ConnectionEventArgs(SQLiteConnectionEventType.NewDataReader,
+ null, null, _command, this, null, null, new object[] { behave }));
+
+ NextResult();
+ }
}
///////////////////////////////////////////////////////////////////////////////////////////////
#region IDisposable "Pattern" Members
Index: readme.htm
==================================================================
--- readme.htm
+++ readme.htm
@@ -192,10 +192,12 @@
- Updated to SQLite 3.8.1.
- Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for [3113734605].
- Check the result of sqlite3_column_name function against NULL.
- Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.
+ - Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Pursuant to [aba4549801].
+ - Revise how the extra object data is passed to the static SQLiteConnection.Changed event. ** Potentially Incompatible Change **
1.0.88.0 - August 7, 2013
Index: www/news.wiki
==================================================================
--- www/news.wiki
+++ www/news.wiki
@@ -8,10 +8,12 @@
- Updated to [http://www.sqlite.org/src/info/trunk|SQLite 3.8.1].
- Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for [3113734605].
- Check the result of sqlite3_column_name function against NULL.
- Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.
+ - Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Pursuant to [aba4549801].
+ - Revise how the extra object data is passed to the static SQLiteConnection.Changed event. ** Potentially Incompatible Change **
1.0.88.0 - August 7, 2013