Index: SQLite.NET.Settings.targets
==================================================================
--- SQLite.NET.Settings.targets
+++ SQLite.NET.Settings.targets
@@ -104,10 +104,18 @@
false
+
+
+ true
+ (('$(IsCompactFramework)' == 'false' And Exists('$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.snk')) Or
+ ('$(IsCompactFramework)' != 'false' And Exists('$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.CF.snk')))">
true
Index: System.Data.SQLite/AssemblyInfo.cs
==================================================================
--- System.Data.SQLite/AssemblyInfo.cs
+++ System.Data.SQLite/AssemblyInfo.cs
@@ -1,5 +1,12 @@
+/********************************************************
+ * 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.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Resources;
@@ -31,11 +38,11 @@
// Setting ComVisible to false makes the types in this assembly not visible
// to COM componenets. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]
-[assembly: InternalsVisibleTo("System.Data.SQLite.Linq, PublicKey=002400000480000094000000060200000024000052534131000400000100010005a288de5687c4e1b621ddff5d844727418956997f475eb829429e411aff3e93f97b70de698b972640925bdd44280df0a25a843266973704137cbb0e7441c1fe7cae4e2440ae91ab8cde3933febcb1ac48dd33b40e13c421d8215c18a4349a436dd499e3c385cc683015f886f6c10bd90115eb2bd61b67750839e3a19941dc9c")]
+[assembly: InternalsVisibleTo("System.Data.SQLite.Linq, PublicKey=" + System.Data.SQLite.SQLite3.PublicKey)]
[assembly: NeutralResourcesLanguage("en")]
#if !PLATFORM_COMPACTFRAMEWORK
[assembly: AllowPartiallyTrustedCallers]
[assembly: ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
Index: System.Data.SQLite/SQLite3.cs
==================================================================
--- System.Data.SQLite/SQLite3.cs
+++ System.Data.SQLite/SQLite3.cs
@@ -21,10 +21,20 @@
///
/// This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET
///
internal class SQLite3 : SQLiteBase
{
+ //
+ // NOTE: This is the public key for the System.Data.SQLite assembly. If you change the
+ // SNK file, you will need to change this as well.
+ //
+ internal const string PublicKey =
+ "002400000480000094000000060200000024000052534131000400000100010005a288de5687c4e1" +
+ "b621ddff5d844727418956997f475eb829429e411aff3e93f97b70de698b972640925bdd44280df0" +
+ "a25a843266973704137cbb0e7441c1fe7cae4e2440ae91ab8cde3933febcb1ac48dd33b40e13c421" +
+ "d8215c18a4349a436dd499e3c385cc683015f886f6c10bd90115eb2bd61b67750839e3a19941dc9c";
+
#if !PLATFORM_COMPACTFRAMEWORK
internal const string DesignerVersion = "1.0.77.0";
#endif
///
@@ -46,34 +56,77 @@
internal SQLite3(SQLiteDateFormats fmt, DateTimeKind kind)
: base(fmt, kind)
{
}
- protected override void Dispose(bool bDisposing)
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
{
- Close();
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLite3).Name);
+#endif
}
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ Close();
+
+ disposed = true;
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
// 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()
{
if (_sql != null)
{
- if (_usePool)
- {
- SQLiteBase.ResetConnection(_sql);
- SQLiteConnectionPool.Add(_fileName, _sql, _poolVersion);
- }
- else
- _sql.Dispose();
- }
-
- _sql = null;
- }
+ if (_usePool)
+ {
+ SQLiteBase.ResetConnection(_sql);
+ SQLiteConnectionPool.Add(_fileName, _sql, _poolVersion);
+ }
+ else
+ {
+ _sql.Dispose();
+ }
+ _sql = null;
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
internal override void Cancel()
{
UnsafeNativeMethods.sqlite3_interrupt(_sql);
}
Index: System.Data.SQLite/SQLite3_UTF16.cs
==================================================================
--- System.Data.SQLite/SQLite3_UTF16.cs
+++ System.Data.SQLite/SQLite3_UTF16.cs
@@ -18,21 +18,65 @@
///
internal class SQLite3_UTF16 : SQLite3
{
internal SQLite3_UTF16(SQLiteDateFormats fmt, DateTimeKind kind)
: base(fmt, kind)
- {
- }
-
+ {
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLite3_UTF16).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8
///
/// A pointer to a UTF-16 string
/// The length (IN BYTES) of the string
/// A .NET string
public override string ToString(IntPtr b, int nbytelen)
- {
+ {
+ CheckDisposed();
return UTF16ToString(b, nbytelen);
}
public static string UTF16ToString(IntPtr b, int nbytelen)
{
@@ -43,11 +87,11 @@
else
return Marshal.PtrToStringUni(b, nbytelen / 2);
}
internal override void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool)
- {
+ {
if (_sql != null) return;
_usePool = usePool;
if (usePool)
{
@@ -126,86 +170,86 @@
}
}
}
internal override void Bind_Text(SQLiteStatement stmt, int index, string value)
- {
+ {
int n = UnsafeNativeMethods.sqlite3_bind_text16(stmt._sqlite_stmt, index, value, value.Length * 2, (IntPtr)(-1));
if (n > 0) throw new SQLiteException(n, SQLiteLastError());
}
- internal override DateTime GetDateTime(SQLiteStatement stmt, int index)
- {
+ internal override DateTime GetDateTime(SQLiteStatement stmt, int index)
+ {
return ToDateTime(GetText(stmt, index));
}
internal override string ColumnName(SQLiteStatement stmt, int index)
- {
+ {
#if !SQLITE_STANDARD
int len;
return UTF16ToString(UnsafeNativeMethods.sqlite3_column_name16_interop(stmt._sqlite_stmt, index, out len), len);
#else
return UTF16ToString(UnsafeNativeMethods.sqlite3_column_name16(stmt._sqlite_stmt, index), -1);
#endif
}
internal override string GetText(SQLiteStatement stmt, int index)
- {
+ {
#if !SQLITE_STANDARD
int len;
return UTF16ToString(UnsafeNativeMethods.sqlite3_column_text16_interop(stmt._sqlite_stmt, index, out len), len);
#else
return UTF16ToString(UnsafeNativeMethods.sqlite3_column_text16(stmt._sqlite_stmt, index), -1);
#endif
}
internal override string ColumnOriginalName(SQLiteStatement stmt, int index)
- {
+ {
#if !SQLITE_STANDARD
int len;
return UTF16ToString(UnsafeNativeMethods.sqlite3_column_origin_name16_interop(stmt._sqlite_stmt, index, out len), len);
#else
return UTF16ToString(UnsafeNativeMethods.sqlite3_column_origin_name16(stmt._sqlite_stmt, index), -1);
#endif
}
internal override string ColumnDatabaseName(SQLiteStatement stmt, int index)
- {
+ {
#if !SQLITE_STANDARD
int len;
return UTF16ToString(UnsafeNativeMethods.sqlite3_column_database_name16_interop(stmt._sqlite_stmt, index, out len), len);
#else
return UTF16ToString(UnsafeNativeMethods.sqlite3_column_database_name16(stmt._sqlite_stmt, index), -1);
#endif
}
internal override string ColumnTableName(SQLiteStatement stmt, int index)
- {
+ {
#if !SQLITE_STANDARD
int len;
return UTF16ToString(UnsafeNativeMethods.sqlite3_column_table_name16_interop(stmt._sqlite_stmt, index, out len), len);
#else
return UTF16ToString(UnsafeNativeMethods.sqlite3_column_table_name16(stmt._sqlite_stmt, index), -1);
#endif
}
internal override string GetParamValueText(IntPtr ptr)
- {
+ {
#if !SQLITE_STANDARD
int len;
return UTF16ToString(UnsafeNativeMethods.sqlite3_value_text16_interop(ptr, out len), len);
#else
return UTF16ToString(UnsafeNativeMethods.sqlite3_value_text16(ptr), -1);
#endif
}
internal override void ReturnError(IntPtr context, string value)
- {
+ {
UnsafeNativeMethods.sqlite3_result_error16(context, value, value.Length * 2);
}
- internal override void ReturnText(IntPtr context, string value)
- {
+ internal override void ReturnText(IntPtr context, string value)
+ {
UnsafeNativeMethods.sqlite3_result_text16(context, value, value.Length * 2, (IntPtr)(-1));
}
}
}
Index: System.Data.SQLite/SQLiteBase.cs
==================================================================
--- System.Data.SQLite/SQLiteBase.cs
+++ System.Data.SQLite/SQLiteBase.cs
@@ -220,19 +220,64 @@
get;
}
internal abstract int FileControl(string zDbName, int op, IntPtr pArg);
- protected virtual void Dispose(bool bDisposing)
- {
- }
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+ #region IDisposable Members
public void Dispose()
{
- Dispose(true);
- GC.SuppressFinalize(this);
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteBase).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Destructor
+ ~SQLiteBase()
+ {
+ Dispose(false);
}
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
// These statics are here for lack of a better place to put them.
// They exist here because they are called during the finalization of
// a SQLiteStatementHandle, SQLiteConnectionHandle, and SQLiteFunctionCookieHandle.
// Therefore these functions have to be static, and have to be low-level.
Index: System.Data.SQLite/SQLiteCommand.cs
==================================================================
--- System.Data.SQLite/SQLiteCommand.cs
+++ System.Data.SQLite/SQLiteCommand.cs
@@ -141,45 +141,80 @@
if (transaction != null)
Transaction = transaction;
}
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteCommand).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// Disposes of the command and clears all member variables
///
/// Whether or not the class is being explicitly or implicitly disposed
protected override void Dispose(bool disposing)
{
- base.Dispose(disposing);
-
- if (disposing)
- {
- // If a reader is active on this command, don't destroy the command, instead let the reader do it
- SQLiteDataReader reader = null;
- if (_activeReader != null)
- {
- try
- {
- reader = _activeReader.Target as SQLiteDataReader;
- }
- catch(InvalidOperationException)
- {
- }
- }
-
- if (reader != null)
- {
- reader._disposeCommand = true;
- _activeReader = null;
- return;
- }
-
- Connection = null;
- _parameterCollection.Clear();
- _commandText = null;
- }
- }
+ try
+ {
+ if (!disposed)
+ {
+ if (disposing)
+ {
+ ////////////////////////////////////
+ // dispose managed resources here...
+ ////////////////////////////////////
+
+ // If a reader is active on this command, don't destroy the command, instead let the reader do it
+ SQLiteDataReader reader = null;
+ if (_activeReader != null)
+ {
+ try
+ {
+ reader = _activeReader.Target as SQLiteDataReader;
+ }
+ catch (InvalidOperationException)
+ {
+ }
+ }
+
+ if (reader != null)
+ {
+ reader._disposeCommand = true;
+ _activeReader = null;
+ return;
+ }
+
+ Connection = null;
+ _parameterCollection.Clear();
+ _commandText = null;
+ }
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
///
/// Clears and destroys all statements currently prepared
///
internal void ClearCommands()
@@ -281,10 +316,12 @@
///
/// Not implemented
///
public override void Cancel()
{
+ CheckDisposed();
+
if (_activeReader != null)
{
SQLiteDataReader reader = _activeReader.Target as SQLiteDataReader;
if (reader != null)
reader.Cancel();
@@ -299,14 +336,17 @@
#endif
public override string CommandText
{
get
{
+ CheckDisposed();
return _commandText;
}
set
{
+ CheckDisposed();
+
if (_commandText == value) return;
if (_activeReader != null && _activeReader.IsAlive)
{
throw new InvalidOperationException("Cannot set CommandText while a DataReader is active");
@@ -327,14 +367,16 @@
#endif
public override int CommandTimeout
{
get
{
+ CheckDisposed();
return _commandTimeout;
}
set
{
+ CheckDisposed();
_commandTimeout = value;
}
}
///
@@ -345,14 +387,17 @@
#endif
public override CommandType CommandType
{
get
{
+ CheckDisposed();
return CommandType.Text;
}
set
{
+ CheckDisposed();
+
if (value != CommandType.Text)
{
throw new NotSupportedException();
}
}
@@ -371,10 +416,11 @@
/// Create a new parameter
///
///
public new SQLiteParameter CreateParameter()
{
+ CheckDisposed();
return new SQLiteParameter();
}
///
/// The connection associated with this command
@@ -382,13 +428,15 @@
#if !PLATFORM_COMPACTFRAMEWORK
[DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
public new SQLiteConnection Connection
{
- get { return _cnn; }
+ get { CheckDisposed(); return _cnn; }
set
{
+ CheckDisposed();
+
if (_activeReader != null && _activeReader.IsAlive)
throw new InvalidOperationException("Cannot set Connection while a DataReader is active");
if (_cnn != null)
{
@@ -426,11 +474,11 @@
#if !PLATFORM_COMPACTFRAMEWORK
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
#endif
public new SQLiteParameterCollection Parameters
{
- get { return _parameterCollection; }
+ get { CheckDisposed(); return _parameterCollection; }
}
///
/// Forwards to the local Parameters property
///
@@ -449,13 +497,15 @@
#if !PLATFORM_COMPACTFRAMEWORK
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
public new SQLiteTransaction Transaction
{
- get { return _transaction; }
+ get { CheckDisposed(); return _transaction; }
set
{
+ CheckDisposed();
+
if (_cnn != null)
{
if (_activeReader != null && _activeReader.IsAlive)
throw new InvalidOperationException("Cannot set Transaction while a DataReader is active");
@@ -534,10 +584,11 @@
///
/// The flags to be associated with the reader
/// A SQLiteDataReader
public new SQLiteDataReader ExecuteReader(CommandBehavior behavior)
{
+ CheckDisposed();
InitializeForReader();
SQLiteDataReader rd = new SQLiteDataReader(this, behavior);
_activeReader = new WeakReference(rd, false);
@@ -548,10 +599,11 @@
/// Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class
///
/// A SQLiteDataReader
public new SQLiteDataReader ExecuteReader()
{
+ CheckDisposed();
return ExecuteReader(CommandBehavior.Default);
}
///
/// Called by the SQLiteDataReader when the data reader is closed.
@@ -565,10 +617,12 @@
/// Execute the command and return the number of rows inserted/updated affected by it.
///
///
public override int ExecuteNonQuery()
{
+ CheckDisposed();
+
using (SQLiteDataReader reader = ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.SingleResult))
{
while (reader.NextResult()) ;
return reader.RecordsAffected;
}
@@ -579,10 +633,12 @@
/// (if present), or null if no resultset was returned.
///
/// The first column of the first row of the first resultset from the query
public override object ExecuteScalar()
{
+ CheckDisposed();
+
using (SQLiteDataReader reader = ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.SingleResult))
{
if (reader.Read())
return reader[0];
}
@@ -592,10 +648,11 @@
///
/// Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards.
///
public override void Prepare()
{
+ CheckDisposed();
}
///
/// Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable.
///
@@ -602,14 +659,16 @@
[DefaultValue(UpdateRowSource.None)]
public override UpdateRowSource UpdatedRowSource
{
get
{
+ CheckDisposed();
return _updateRowSource;
}
set
{
+ CheckDisposed();
_updateRowSource = value;
}
}
///
@@ -620,14 +679,17 @@
#endif
public override bool DesignTimeVisible
{
get
{
+ CheckDisposed();
return _designTimeVisible;
}
set
{
+ CheckDisposed();
+
_designTimeVisible = value;
#if !PLATFORM_COMPACTFRAMEWORK
TypeDescriptor.Refresh(this);
#endif
}
@@ -637,9 +699,10 @@
/// Clones a command, including all its parameters
///
/// A new SQLiteCommand with the same commandtext, connection and parameters
public object Clone()
{
+ CheckDisposed();
return new SQLiteCommand(this);
}
}
}
Index: System.Data.SQLite/SQLiteCommandBuilder.cs
==================================================================
--- System.Data.SQLite/SQLiteCommandBuilder.cs
+++ System.Data.SQLite/SQLiteCommandBuilder.cs
@@ -32,11 +32,54 @@
public SQLiteCommandBuilder(SQLiteDataAdapter adp)
{
QuotePrefix = "[";
QuoteSuffix = "]";
DataAdapter = adp;
- }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteCommandBuilder).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
///
/// Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema
///
/// The parameter to use in applying custom behaviors to a row
@@ -103,69 +146,75 @@
///
/// Gets/sets the DataAdapter for this CommandBuilder
///
public new SQLiteDataAdapter DataAdapter
- {
- get { return (SQLiteDataAdapter)base.DataAdapter; }
- set { base.DataAdapter = value; }
+ {
+ get { CheckDisposed(); return (SQLiteDataAdapter)base.DataAdapter; }
+ set { CheckDisposed(); base.DataAdapter = value; }
}
///
/// Returns the automatically-generated SQLite command to delete rows from the database
///
///
- public new SQLiteCommand GetDeleteCommand()
- {
+ public new SQLiteCommand GetDeleteCommand()
+ {
+ CheckDisposed();
return (SQLiteCommand)base.GetDeleteCommand();
}
///
/// Returns the automatically-generated SQLite command to delete rows from the database
///
///
///
public new SQLiteCommand GetDeleteCommand(bool useColumnsForParameterNames)
- {
+ {
+ CheckDisposed();
return (SQLiteCommand)base.GetDeleteCommand(useColumnsForParameterNames);
}
///
/// Returns the automatically-generated SQLite command to update rows in the database
///
///
- public new SQLiteCommand GetUpdateCommand()
- {
+ public new SQLiteCommand GetUpdateCommand()
+ {
+ CheckDisposed();
return (SQLiteCommand)base.GetUpdateCommand();
}
///
/// Returns the automatically-generated SQLite command to update rows in the database
///
///
///
public new SQLiteCommand GetUpdateCommand(bool useColumnsForParameterNames)
- {
+ {
+ CheckDisposed();
return (SQLiteCommand)base.GetUpdateCommand(useColumnsForParameterNames);
}
///
/// Returns the automatically-generated SQLite command to insert rows into the database
///
///
public new SQLiteCommand GetInsertCommand()
- {
+ {
+ CheckDisposed();
return (SQLiteCommand)base.GetInsertCommand();
}
///
/// Returns the automatically-generated SQLite command to insert rows into the database
///
///
///
public new SQLiteCommand GetInsertCommand(bool useColumnsForParameterNames)
- {
+ {
+ CheckDisposed();
return (SQLiteCommand)base.GetInsertCommand(useColumnsForParameterNames);
}
///
/// Overridden to hide its property from the designer
@@ -174,15 +223,17 @@
[Browsable(false)]
#endif
public override CatalogLocation CatalogLocation
{
get
- {
+ {
+ CheckDisposed();
return base.CatalogLocation;
}
set
- {
+ {
+ CheckDisposed();
base.CatalogLocation = value;
}
}
///
@@ -192,15 +243,17 @@
[Browsable(false)]
#endif
public override string CatalogSeparator
{
get
- {
+ {
+ CheckDisposed();
return base.CatalogSeparator;
}
set
- {
+ {
+ CheckDisposed();
base.CatalogSeparator = value;
}
}
///
@@ -211,15 +264,17 @@
#endif
[DefaultValue("[")]
public override string QuotePrefix
{
get
- {
+ {
+ CheckDisposed();
return base.QuotePrefix;
}
set
- {
+ {
+ CheckDisposed();
base.QuotePrefix = value;
}
}
///
@@ -229,26 +284,30 @@
[Browsable(false)]
#endif
public override string QuoteSuffix
{
get
- {
+ {
+ CheckDisposed();
return base.QuoteSuffix;
}
set
- {
+ {
+ CheckDisposed();
base.QuoteSuffix = value;
}
}
///
/// Places brackets around an identifier
///
/// The identifier to quote
/// The bracketed identifier
- public override string QuoteIdentifier(string unquotedIdentifier)
- {
+ public override string QuoteIdentifier(string unquotedIdentifier)
+ {
+ CheckDisposed();
+
if (String.IsNullOrEmpty(QuotePrefix)
|| String.IsNullOrEmpty(QuoteSuffix)
|| String.IsNullOrEmpty(unquotedIdentifier))
return unquotedIdentifier;
@@ -258,12 +317,14 @@
///
/// Removes brackets around an identifier
///
/// The quoted (bracketed) identifier
/// The undecorated identifier
- public override string UnquoteIdentifier(string quotedIdentifier)
- {
+ public override string UnquoteIdentifier(string quotedIdentifier)
+ {
+ CheckDisposed();
+
if (String.IsNullOrEmpty(QuotePrefix)
|| String.IsNullOrEmpty(QuoteSuffix)
|| String.IsNullOrEmpty(quotedIdentifier))
return quotedIdentifier;
@@ -281,15 +342,17 @@
[Browsable(false)]
#endif
public override string SchemaSeparator
{
get
- {
+ {
+ CheckDisposed();
return base.SchemaSeparator;
}
- set
- {
+ set
+ {
+ CheckDisposed();
base.SchemaSeparator = value;
}
}
///
Index: System.Data.SQLite/SQLiteConnection.cs
==================================================================
--- System.Data.SQLite/SQLiteConnection.cs
+++ System.Data.SQLite/SQLiteConnection.cs
@@ -311,10 +311,55 @@
}
}
}
}
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteConnection).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ Close();
+
+ disposed = true;
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
#if PLATFORM_COMPACTFRAMEWORK
///
/// Obsolete
///
public override int ConnectionTimeout
@@ -334,22 +379,10 @@
public object Clone()
{
return new SQLiteConnection(this);
}
- ///
- /// Disposes of the SQLiteConnection, closing it if it is active.
- ///
- /// True if the connection is being explicitly closed.
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
-
- if (disposing)
- Close();
- }
-
///
/// Creates a database file. This just creates a zero-byte file which SQLite
/// will turn into a database when the file is opened properly.
///
/// The file to create
Index: System.Data.SQLite/SQLiteDataAdapter.cs
==================================================================
--- System.Data.SQLite/SQLiteDataAdapter.cs
+++ System.Data.SQLite/SQLiteDataAdapter.cs
@@ -62,17 +62,62 @@
{
SQLiteConnection cnn = new SQLiteConnection(connectionString);
SelectCommand = new SQLiteCommand(commandText, cnn);
}
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteDataAdapter).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// Row updating event handler
///
public event EventHandler RowUpdating
{
add
{
+ CheckDisposed();
+
#if !PLATFORM_COMPACTFRAMEWORK
EventHandler previous = (EventHandler)base.Events[_updatingEventPH];
if ((previous != null) && (value.Target is DbCommandBuilder))
{
EventHandler handler = (EventHandler)FindBuilder(previous);
@@ -82,11 +127,11 @@
}
}
#endif
base.Events.AddHandler(_updatingEventPH, value);
}
- remove { base.Events.RemoveHandler(_updatingEventPH, value); }
+ remove { CheckDisposed(); base.Events.RemoveHandler(_updatingEventPH, value); }
}
#if !PLATFORM_COMPACTFRAMEWORK
internal static Delegate FindBuilder(MulticastDelegate mcd)
{
@@ -108,12 +153,12 @@
///
/// Row updated event handler
///
public event EventHandler RowUpdated
{
- add { base.Events.AddHandler(_updatedEventPH, value); }
- remove { base.Events.RemoveHandler(_updatedEventPH, value); }
+ add { CheckDisposed(); base.Events.AddHandler(_updatedEventPH, value); }
+ remove { CheckDisposed(); base.Events.RemoveHandler(_updatedEventPH, value); }
}
///
/// Raised by the underlying DbDataAdapter when a row is being updated
///
@@ -144,12 +189,12 @@
#if !PLATFORM_COMPACTFRAMEWORK
[DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
public new SQLiteCommand SelectCommand
{
- get { return (SQLiteCommand)base.SelectCommand; }
- set { base.SelectCommand = value; }
+ get { CheckDisposed(); return (SQLiteCommand)base.SelectCommand; }
+ set { CheckDisposed(); base.SelectCommand = value; }
}
///
/// Gets/sets the insert command for this DataAdapter
///
@@ -156,12 +201,12 @@
#if !PLATFORM_COMPACTFRAMEWORK
[DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
public new SQLiteCommand InsertCommand
{
- get { return (SQLiteCommand)base.InsertCommand; }
- set { base.InsertCommand = value; }
+ get { CheckDisposed(); return (SQLiteCommand)base.InsertCommand; }
+ set { CheckDisposed(); base.InsertCommand = value; }
}
///
/// Gets/sets the update command for this DataAdapter
///
@@ -168,12 +213,12 @@
#if !PLATFORM_COMPACTFRAMEWORK
[DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
public new SQLiteCommand UpdateCommand
{
- get { return (SQLiteCommand)base.UpdateCommand; }
- set { base.UpdateCommand = value; }
+ get { CheckDisposed(); return (SQLiteCommand)base.UpdateCommand; }
+ set { CheckDisposed(); base.UpdateCommand = value; }
}
///
/// Gets/sets the delete command for this DataAdapter
///
@@ -180,10 +225,10 @@
#if !PLATFORM_COMPACTFRAMEWORK
[DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
public new SQLiteCommand DeleteCommand
{
- get { return (SQLiteCommand)base.DeleteCommand; }
- set { base.DeleteCommand = value; }
+ get { CheckDisposed(); return (SQLiteCommand)base.DeleteCommand; }
+ set { CheckDisposed(); base.DeleteCommand = value; }
}
}
}
Index: System.Data.SQLite/SQLiteDataReader.cs
==================================================================
--- System.Data.SQLite/SQLiteDataReader.cs
+++ System.Data.SQLite/SQLiteDataReader.cs
@@ -63,15 +63,10 @@
///
/// If set, then raise an exception when the object is accessed after being disposed.
///
internal bool _throwOnDisposed;
-
- ///
- /// If set, then the object is currently being disposed.
- ///
- internal bool _disposing;
///
/// An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified
///
private SQLiteKeyReader _keyInfo;
@@ -104,38 +99,76 @@
_activeStatementIndex = -1;
_rowsAffected = -1;
if (_command != null)
NextResult();
- }
-
- internal void Cancel()
- {
- _version = 0;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed && _throwOnDisposed)
+ throw new ObjectDisposedException(typeof(SQLiteDataReader).Name);
+#endif
}
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
///
/// Dispose of all resources used by this datareader.
///
///
protected override void Dispose(bool disposing)
{
- //
- // NOTE: Fix for ticket [e1b2e0f769], do NOT throw exceptions while we
- // are being disposed.
- //
- _disposing = true;
- _throwOnDisposed = false;
-
- base.Dispose(disposing);
- }
+ try
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ //
+ // NOTE: Fix for ticket [e1b2e0f769], do NOT throw exceptions
+ // while we are being disposed.
+ //
+ _throwOnDisposed = false;
+ disposed = true;
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ internal void Cancel()
+ {
+ _version = 0;
+ }
///
/// Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified.
///
public override void Close()
- {
+ {
+ CheckDisposed();
+
try
{
if (_command != null)
{
try
@@ -214,22 +247,24 @@
///
/// Enumerator support
///
/// Returns a DbEnumerator object.
- public override Collections.IEnumerator GetEnumerator()
- {
+ public override Collections.IEnumerator GetEnumerator()
+ {
+ CheckDisposed();
return new DbEnumerator(this, ((_commandBehavior & CommandBehavior.CloseConnection) == CommandBehavior.CloseConnection));
}
///
/// Not implemented. Returns 0
///
public override int Depth
{
get
- {
+ {
+ CheckDisposed();
CheckClosed();
return 0;
}
}
@@ -237,12 +272,14 @@
/// Returns the number of columns in the current resultset
///
public override int FieldCount
{
get
- {
+ {
+ CheckDisposed();
CheckClosed();
+
if (_keyInfo == null)
return _fieldCount;
return _fieldCount + _keyInfo.Count;
}
@@ -251,12 +288,13 @@
///
/// Returns the number of visible fielsd in the current resultset
///
public override int VisibleFieldCount
{
- get
- {
+ get
+ {
+ CheckDisposed();
CheckClosed();
return _fieldCount;
}
}
@@ -272,13 +310,14 @@
/// This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity.
///
/// The index of the column to type-check
/// The type we want to get out of the column
private TypeAffinity VerifyType(int i, DbType typ)
- {
+ {
CheckClosed();
CheckValidRow();
+
TypeAffinity affinity = GetSQLiteType(i).Affinity;
switch (affinity)
{
case TypeAffinity.Int64:
@@ -319,12 +358,14 @@
///
/// Retrieves the column as a boolean value
///
/// The index of the column to retrieve
/// bool
- public override bool GetBoolean(int i)
- {
+ public override bool GetBoolean(int i)
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetBoolean(i - VisibleFieldCount);
VerifyType(i, DbType.Boolean);
return Convert.ToBoolean(GetValue(i), CultureInfo.CurrentCulture);
@@ -334,11 +375,13 @@
/// Retrieves the column as a single byte value
///
/// The index of the column to retrieve
/// byte
public override byte GetByte(int i)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetByte(i - VisibleFieldCount);
VerifyType(i, DbType.Byte);
return Convert.ToByte(_activeStatement._sql.GetInt32(_activeStatement, i));
@@ -355,11 +398,13 @@
/// The actual number of bytes written into the array
///
/// To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned.
///
public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetBytes(i - VisibleFieldCount, fieldOffset, buffer, bufferoffset, length);
VerifyType(i, DbType.Binary);
return _activeStatement._sql.GetBytes(_activeStatement, i, (int)fieldOffset, buffer, bufferoffset, length);
@@ -369,11 +414,13 @@
/// Returns the column as a single character
///
/// The index of the column to retrieve
/// char
public override char GetChar(int i)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetChar(i - VisibleFieldCount);
VerifyType(i, DbType.SByte);
return Convert.ToChar(_activeStatement._sql.GetInt32(_activeStatement, i));
@@ -390,11 +437,13 @@
/// The actual number of characters written into the array
///
/// To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned.
///
public override long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetChars(i - VisibleFieldCount, fieldoffset, buffer, bufferoffset, length);
VerifyType(i, DbType.String);
return _activeStatement._sql.GetChars(_activeStatement, i, (int)fieldoffset, buffer, bufferoffset, length);
@@ -404,11 +453,13 @@
/// Retrieves the name of the back-end datatype of the column
///
/// The index of the column to retrieve
/// string
public override string GetDataTypeName(int i)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetDataTypeName(i - VisibleFieldCount);
SQLiteType typ = GetSQLiteType(i);
if (typ.Type == DbType.Object) return SQLiteConvert.SQLiteTypeToType(typ).Name;
@@ -418,12 +469,14 @@
///
/// Retrieve the column as a date/time value
///
/// The index of the column to retrieve
/// DateTime
- public override DateTime GetDateTime(int i)
- {
+ public override DateTime GetDateTime(int i)
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetDateTime(i - VisibleFieldCount);
VerifyType(i, DbType.DateTime);
return _activeStatement._sql.GetDateTime(_activeStatement, i);
@@ -433,11 +486,13 @@
/// Retrieve the column as a decimal value
///
/// The index of the column to retrieve
/// decimal
public override decimal GetDecimal(int i)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetDecimal(i - VisibleFieldCount);
VerifyType(i, DbType.Decimal);
return Decimal.Parse(_activeStatement._sql.GetText(_activeStatement, i), NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent | NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture);
@@ -447,11 +502,13 @@
/// Returns the column as a double
///
/// The index of the column to retrieve
/// double
public override double GetDouble(int i)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetDouble(i - VisibleFieldCount);
VerifyType(i, DbType.Double);
return _activeStatement._sql.GetDouble(_activeStatement, i);
@@ -461,11 +518,13 @@
/// Returns the .NET type of a given column
///
/// The index of the column to retrieve
/// Type
public override Type GetFieldType(int i)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetFieldType(i - VisibleFieldCount);
return SQLiteConvert.SQLiteTypeToType(GetSQLiteType(i));
}
@@ -474,11 +533,13 @@
/// Returns a column as a float value
///
/// The index of the column to retrieve
/// float
public override float GetFloat(int i)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetFloat(i - VisibleFieldCount);
VerifyType(i, DbType.Single);
return Convert.ToSingle(_activeStatement._sql.GetDouble(_activeStatement, i));
@@ -487,12 +548,14 @@
///
/// Returns the column as a Guid
///
/// The index of the column to retrieve
/// Guid
- public override Guid GetGuid(int i)
- {
+ public override Guid GetGuid(int i)
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetGuid(i - VisibleFieldCount);
TypeAffinity affinity = VerifyType(i, DbType.Guid);
if (affinity == TypeAffinity.Blob)
@@ -508,12 +571,14 @@
///
/// Returns the column as a short
///
/// The index of the column to retrieve
/// Int16
- public override Int16 GetInt16(int i)
- {
+ public override Int16 GetInt16(int i)
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetInt16(i - VisibleFieldCount);
VerifyType(i, DbType.Int16);
return Convert.ToInt16(_activeStatement._sql.GetInt32(_activeStatement, i));
@@ -522,12 +587,14 @@
///
/// Retrieves the column as an int
///
/// The index of the column to retrieve
/// Int32
- public override Int32 GetInt32(int i)
- {
+ public override Int32 GetInt32(int i)
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetInt32(i - VisibleFieldCount);
VerifyType(i, DbType.Int32);
return _activeStatement._sql.GetInt32(_activeStatement, i);
@@ -536,12 +603,14 @@
///
/// Retrieves the column as a long
///
/// The index of the column to retrieve
/// Int64
- public override Int64 GetInt64(int i)
- {
+ public override Int64 GetInt64(int i)
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetInt64(i - VisibleFieldCount);
VerifyType(i, DbType.Int64);
return _activeStatement._sql.GetInt64(_activeStatement, i);
@@ -551,11 +620,13 @@
/// Retrieves the name of the column
///
/// The index of the column to retrieve
/// string
public override string GetName(int i)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetName(i - VisibleFieldCount);
return _activeStatement._sql.ColumnName(_activeStatement, i);
}
@@ -564,12 +635,14 @@
/// Retrieves the i of a column, given its name
///
/// The name of the column to retrieve
/// The int i of the column
public override int GetOrdinal(string name)
- {
+ {
+ CheckDisposed();
CheckClosed();
+
int r = _activeStatement._sql.ColumnIndex(_activeStatement, name);
if (r == -1 && _keyInfo != null)
{
r = _keyInfo.GetOrdinal(name);
if (r > -1) r += VisibleFieldCount;
@@ -582,11 +655,12 @@
/// Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done
/// to gather the necessary information so it can be represented in an ADO.NET manner.
///
/// Returns a DataTable containing the schema information for the active SELECT statement being processed.
public override DataTable GetSchemaTable()
- {
+ {
+ CheckDisposed();
return GetSchemaTable(true, false);
}
private class ColumnParent : IEqualityComparer
{
@@ -942,11 +1016,13 @@
/// Retrieves the column as a string
///
/// The index of the column to retrieve
/// string
public override string GetString(int i)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetString(i - VisibleFieldCount);
VerifyType(i, DbType.String);
return _activeStatement._sql.GetText(_activeStatement, i);
@@ -956,11 +1032,13 @@
/// Retrieves the column as an object corresponding to the underlying datatype of the column
///
/// The index of the column to retrieve
/// object
public override object GetValue(int i)
- {
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.GetValue(i - VisibleFieldCount);
SQLiteType typ = GetSQLiteType(i);
@@ -970,12 +1048,14 @@
///
/// Retreives the values of multiple columns, up to the size of the supplied array
///
/// The array to fill with values from the columns in the current resultset
/// The number of columns retrieved
- public override int GetValues(object[] values)
- {
+ public override int GetValues(object[] values)
+ {
+ CheckDisposed();
+
int nMax = FieldCount;
if (values.Length < nMax) nMax = values.Length;
for (int n = 0; n < nMax; n++)
{
@@ -988,32 +1068,35 @@
///
/// Returns True if the resultset has rows that can be fetched
///
public override bool HasRows
{
- get
- {
+ get
+ {
+ CheckDisposed();
CheckClosed();
return (_readingState != 1);
}
}
///
/// Returns True if the data reader is closed
///
public override bool IsClosed
- {
- get { return (_command == null); }
+ {
+ get { CheckDisposed(); return (_command == null); }
}
///
/// Returns True if the specified column is null
///
/// The index of the column to retrieve
/// True or False
- public override bool IsDBNull(int i)
- {
+ public override bool IsDBNull(int i)
+ {
+ CheckDisposed();
+
if (i >= VisibleFieldCount && _keyInfo != null)
return _keyInfo.IsDBNull(i - VisibleFieldCount);
return _activeStatement._sql.IsNull(_activeStatement, i);
}
@@ -1021,11 +1104,12 @@
///
/// Moves to the next resultset in multiple row-returning SQL command.
///
/// True if the command was successful and a new resultset is available, False otherwise.
public override bool NextResult()
- {
+ {
+ CheckDisposed();
CheckClosed();
SQLiteStatement stmt = null;
int fieldCount;
@@ -1136,11 +1220,12 @@
///
/// Reads the next row from the resultset
///
/// True if a new row was successfully loaded and is ready for processing
public override bool Read()
- {
+ {
+ CheckDisposed();
CheckClosed();
if (_readingState == -1) // First step was already done at the NextResult() level, so don't step again, just return true.
{
_readingState = 0;
@@ -1168,32 +1253,32 @@
///
/// Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed!
///
public override int RecordsAffected
- {
- get { return (_rowsAffected < 0) ? 0 : _rowsAffected; }
+ {
+ get { CheckDisposed(); return (_rowsAffected < 0) ? 0 : _rowsAffected; }
}
///
/// Indexer to retrieve data from a column given its name
///
/// The name of the column to retrieve data for
/// The value contained in the column
public override object this[string name]
- {
- get { return GetValue(GetOrdinal(name)); }
+ {
+ get { CheckDisposed(); return GetValue(GetOrdinal(name)); }
}
///
/// Indexer to retrieve data from a column given its i
///
/// The index of the column to retrieve
/// The value contained in the column
public override object this[int i]
- {
- get { return GetValue(i); }
+ {
+ get { CheckDisposed(); return GetValue(i); }
}
private void LoadKeyInfo()
{
if (_keyInfo != null)
Index: System.Data.SQLite/SQLiteEnlistment.cs
==================================================================
--- System.Data.SQLite/SQLiteEnlistment.cs
+++ System.Data.SQLite/SQLiteEnlistment.cs
@@ -8,11 +8,11 @@
#if !PLATFORM_COMPACTFRAMEWORK
namespace System.Data.SQLite
{
using System.Transactions;
- internal class SQLiteEnlistment : IEnlistmentNotification
+ internal class SQLiteEnlistment : IEnlistmentNotification, IDisposable
{
internal SQLiteTransaction _transaction;
internal Transaction _scope;
internal bool _disposeConnection;
@@ -22,10 +22,77 @@
_scope = scope;
_scope.EnlistVolatile(this, System.Transactions.EnlistmentOptions.None);
}
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable Members
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteEnlistment).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposed)
+ {
+ if (disposing)
+ {
+ ////////////////////////////////////
+ // dispose managed resources here...
+ ////////////////////////////////////
+
+ if (_transaction != null)
+ {
+ _transaction.Dispose();
+ _transaction = null;
+ }
+
+ if (_scope != null)
+ {
+ // _scope.Dispose(); // NOTE: Not "owned" by us.
+ _scope = null;
+ }
+ }
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Destructor
+ ~SQLiteEnlistment()
+ {
+ Dispose(false);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
private void Cleanup(SQLiteConnection cnn)
{
if (_disposeConnection)
cnn.Dispose();
@@ -34,11 +101,13 @@
}
#region IEnlistmentNotification Members
public void Commit(Enlistment enlistment)
- {
+ {
+ CheckDisposed();
+
SQLiteConnection cnn = _transaction.Connection;
cnn._enlistment = null;
try
{
@@ -52,25 +121,30 @@
{
Cleanup(cnn);
}
}
- public void InDoubt(Enlistment enlistment)
- {
+ public void InDoubt(Enlistment enlistment)
+ {
+ CheckDisposed();
enlistment.Done();
}
- public void Prepare(PreparingEnlistment preparingEnlistment)
- {
+ public void Prepare(PreparingEnlistment preparingEnlistment)
+ {
+ CheckDisposed();
+
if (_transaction.IsValid(false) == false)
preparingEnlistment.ForceRollback();
else
preparingEnlistment.Prepared();
}
public void Rollback(Enlistment enlistment)
- {
+ {
+ CheckDisposed();
+
SQLiteConnection cnn = _transaction.Connection;
cnn._enlistment = null;
try
{
Index: System.Data.SQLite/SQLiteFactory.cs
==================================================================
--- System.Data.SQLite/SQLiteFactory.cs
+++ System.Data.SQLite/SQLiteFactory.cs
@@ -12,24 +12,12 @@
#if !PLATFORM_COMPACTFRAMEWORK
///
/// SQLite implementation of DbProviderFactory.
///
- public sealed partial class SQLiteFactory : DbProviderFactory
- {
- ///
- /// This event is raised whenever SQLite raises a logging event.
- /// Note that this should be set as one of the first things in the
- /// application. This event is provided for backward compatibility only.
- /// New code should use the SQLiteLog class instead.
- ///
- public event SQLiteLogEventHandler Log
- {
- add { SQLiteLog.Log += value; }
- remove { SQLiteLog.Log -= value; }
- }
-
+ public sealed partial class SQLiteFactory : DbProviderFactory, IDisposable
+ {
///
/// Constructs a new SQLiteFactory object
///
///
/// Default constructor
@@ -39,10 +27,77 @@
//
// NOTE: Do nothing here now. All the logging setup related code has
// been moved to the new SQLiteLog static class.
//
}
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable Members
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteFactory).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ private void Dispose(bool disposing)
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Destructor
+ ~SQLiteFactory()
+ {
+ Dispose(false);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// This event is raised whenever SQLite raises a logging event.
+ /// Note that this should be set as one of the first things in the
+ /// application. This event is provided for backward compatibility only.
+ /// New code should use the SQLiteLog class instead.
+ ///
+ public event SQLiteLogEventHandler Log
+ {
+ add { CheckDisposed(); SQLiteLog.Log += value; }
+ remove { CheckDisposed(); SQLiteLog.Log -= value; }
+ }
///
/// Static instance member which returns an instanced SQLiteFactory class.
///
public static readonly SQLiteFactory Instance = new SQLiteFactory();
@@ -51,55 +106,61 @@
/// Returns a new SQLiteCommand object.
///
/// A SQLiteCommand object.
public override DbCommand CreateCommand()
{
+ CheckDisposed();
return new SQLiteCommand();
}
///
/// Returns a new SQLiteCommandBuilder object.
///
/// A SQLiteCommandBuilder object.
public override DbCommandBuilder CreateCommandBuilder()
{
+ CheckDisposed();
return new SQLiteCommandBuilder();
}
///
/// Creates a new SQLiteConnection.
///
/// A SQLiteConnection object.
public override DbConnection CreateConnection()
{
+ CheckDisposed();
return new SQLiteConnection();
}
///
/// Creates a new SQLiteConnectionStringBuilder.
///
/// A SQLiteConnectionStringBuilder object.
public override DbConnectionStringBuilder CreateConnectionStringBuilder()
{
+ CheckDisposed();
return new SQLiteConnectionStringBuilder();
}
///
/// Creates a new SQLiteDataAdapter.
///
/// A SQLiteDataAdapter object.
public override DbDataAdapter CreateDataAdapter()
{
+ CheckDisposed();
return new SQLiteDataAdapter();
}
///
/// Creates a new SQLiteParameter.
///
/// A SQLiteParameter object.
public override DbParameter CreateParameter()
{
+ CheckDisposed();
return new SQLiteParameter();
}
}
#endif
}
Index: System.Data.SQLite/SQLiteFunction.cs
==================================================================
--- System.Data.SQLite/SQLiteFunction.cs
+++ System.Data.SQLite/SQLiteFunction.cs
@@ -79,20 +79,101 @@
/// Internal constructor, initializes the function's internal variables.
///
protected SQLiteFunction()
{
_contextDataList = new Dictionary();
- }
-
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable Members
+ ///
+ /// Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if
+ /// someone closes the connection while a DataReader is open.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteFunction).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Placeholder for a user-defined disposal routine
+ ///
+ /// True if the object is being disposed explicitly
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposed)
+ {
+ if (disposing)
+ {
+ ////////////////////////////////////
+ // dispose managed resources here...
+ ////////////////////////////////////
+
+ IDisposable disp;
+
+ foreach (KeyValuePair kv in _contextDataList)
+ {
+ disp = kv.Value._data as IDisposable;
+ if (disp != null)
+ disp.Dispose();
+ }
+ _contextDataList.Clear();
+
+ _InvokeFunc = null;
+ _StepFunc = null;
+ _FinalFunc = null;
+ _CompareFunc = null;
+ _base = null;
+ _contextDataList = null;
+ }
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Destructor
+ ~SQLiteFunction()
+ {
+ Dispose(false);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert
/// strings and DateTime's into the current connection's encoding schema.
///
public SQLiteConvert SQLiteConvert
{
get
- {
+ {
+ CheckDisposed();
return _base;
}
}
///
@@ -105,12 +186,13 @@
///
/// The arguments for the command to process
/// You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
/// you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error,
/// just return it!
- public virtual object Invoke(object[] args)
- {
+ public virtual object Invoke(object[] args)
+ {
+ CheckDisposed();
return null;
}
///
/// Aggregate functions override this method to do their magic.
@@ -119,12 +201,13 @@
/// Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible.
///
/// The arguments for the command to process
/// The 1-based step number. This is incrememted each time the step method is called.
/// A placeholder for implementers to store contextual data pertaining to the current context.
- public virtual void Step(object[] args, int stepNumber, ref object contextData)
- {
+ public virtual void Step(object[] args, int stepNumber, ref object contextData)
+ {
+ CheckDisposed();
}
///
/// Aggregate functions override this method to finish their aggregate processing.
///
@@ -140,22 +223,24 @@
/// You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
/// you may return an Exception-derived class if you wish to return an error to SQLite. Do not actually throw the error,
/// just return it!
///
public virtual object Final(object contextData)
- {
+ {
+ CheckDisposed();
return null;
}
///
/// User-defined collation sequences override this method to provide a custom string sorting algorithm.
///
/// The first string to compare
/// The second strnig to compare
/// 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2
- public virtual int Compare(string param1, string param2)
- {
+ public virtual int Compare(string param1, string param2)
+ {
+ CheckDisposed();
return 0;
}
///
/// Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to.
@@ -216,11 +301,11 @@
///
/// Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context.
///
/// The context the return value applies to
/// The parameter to return to SQLite
- void SetReturnValue(IntPtr context, object returnValue)
+ private void SetReturnValue(IntPtr context, object returnValue)
{
if (returnValue == null || returnValue == DBNull.Value)
{
_base.ReturnNull(context);
return;
@@ -349,47 +434,10 @@
IDisposable disp = obj as IDisposable;
if (disp != null) disp.Dispose();
}
- ///
- /// Placeholder for a user-defined disposal routine
- ///
- /// True if the object is being disposed explicitly
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- IDisposable disp;
-
- foreach (KeyValuePair kv in _contextDataList)
- {
- disp = kv.Value._data as IDisposable;
- if (disp != null)
- disp.Dispose();
- }
- _contextDataList.Clear();
-
- _InvokeFunc = null;
- _StepFunc = null;
- _FinalFunc = null;
- _CompareFunc = null;
- _base = null;
- _contextDataList = null;
- }
- }
-
- ///
- /// Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if
- /// someone closes the connection while a DataReader is open.
- ///
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
///
/// Using reflection, enumerate all assemblies in the current appdomain looking for classes that
/// have a SQLiteFunctionAttribute attribute, and registering them accordingly.
///
#if !PLATFORM_COMPACTFRAMEWORK
@@ -537,11 +585,52 @@
///
///
protected CollationSequence GetCollationSequence()
{
return _base.GetCollationSequence(this, _context);
- }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteFunctionEx).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+ #endregion
}
///
/// The type of user-defined function to declare
///
Index: System.Data.SQLite/SQLiteKeyReader.cs
==================================================================
--- System.Data.SQLite/SQLiteKeyReader.cs
+++ System.Data.SQLite/SQLiteKeyReader.cs
@@ -40,58 +40,108 @@
internal int column;
}
///
/// A single sub-query for a given table/database.
- ///
- private sealed class KeyQuery : IDisposable
- {
- private SQLiteCommand _command;
- internal SQLiteDataReader _reader;
-
- internal KeyQuery(SQLiteConnection cnn, string database, string table, params string[] columns)
- {
- using (SQLiteCommandBuilder builder = new SQLiteCommandBuilder())
- {
- _command = cnn.CreateCommand();
- for (int n = 0; n < columns.Length; n++)
- {
- columns[n] = builder.QuoteIdentifier(columns[n]);
- }
- }
- _command.CommandText = String.Format(CultureInfo.InvariantCulture, "SELECT {0} FROM [{1}].[{2}] WHERE ROWID = ?", String.Join(",", columns), database, table);
- _command.Parameters.AddWithValue(null, (long)0);
- }
-
- internal bool IsValid
- {
- set
- {
- if (value != false) throw new ArgumentException();
- if (_reader != null)
- {
- _reader.Dispose();
- _reader = null;
- }
- }
- }
-
- internal void Sync(long rowid)
- {
- IsValid = false;
- _command.Parameters[0].Value = rowid;
- _reader = _command.ExecuteReader();
- _reader.Read();
- }
-
- public void Dispose()
- {
- IsValid = false;
-
- if (_command != null) _command.Dispose();
- _command = null;
- }
+ ///
+ private sealed class KeyQuery : IDisposable
+ {
+ private SQLiteCommand _command;
+ internal SQLiteDataReader _reader;
+
+ internal KeyQuery(SQLiteConnection cnn, string database, string table, params string[] columns)
+ {
+ using (SQLiteCommandBuilder builder = new SQLiteCommandBuilder())
+ {
+ _command = cnn.CreateCommand();
+ for (int n = 0; n < columns.Length; n++)
+ {
+ columns[n] = builder.QuoteIdentifier(columns[n]);
+ }
+ }
+ _command.CommandText = String.Format(CultureInfo.InvariantCulture, "SELECT {0} FROM [{1}].[{2}] WHERE ROWID = ?", String.Join(",", columns), database, table);
+ _command.Parameters.AddWithValue(null, (long)0);
+ }
+
+ internal bool IsValid
+ {
+ set
+ {
+ if (value != false) throw new ArgumentException();
+ if (_reader != null)
+ {
+ _reader.Dispose();
+ _reader = null;
+ }
+ }
+ }
+
+ internal void Sync(long rowid)
+ {
+ IsValid = false;
+ _command.Parameters[0].Value = rowid;
+ _reader = _command.ExecuteReader();
+ _reader.Read();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable Members
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(KeyQuery).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ private void Dispose(bool disposing)
+ {
+ if (!disposed)
+ {
+ if (disposing)
+ {
+ ////////////////////////////////////
+ // dispose managed resources here...
+ ////////////////////////////////////
+
+ IsValid = false;
+
+ if (_command != null) _command.Dispose();
+ _command = null;
+ }
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Destructor
+ ~KeyQuery()
+ {
+ Dispose(false);
+ }
+ #endregion
}
///
/// This function does all the nasty work at determining what keys need to be returned for
/// a given statement.
@@ -257,10 +307,77 @@
// CommandBehavior.KeyInfo
_keyInfo = new KeyInfo[keys.Count];
keys.CopyTo(_keyInfo);
}
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable Members
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteKeyReader).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ private void Dispose(bool disposing)
+ {
+ if (!disposed)
+ {
+ if (disposing)
+ {
+ ////////////////////////////////////
+ // dispose managed resources here...
+ ////////////////////////////////////
+
+ _stmt = null;
+
+ if (_keyInfo == null) return;
+
+ for (int n = 0; n < _keyInfo.Length; n++)
+ {
+ if (_keyInfo[n].query != null)
+ _keyInfo[n].query.Dispose();
+ }
+
+ _keyInfo = null;
+ }
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Destructor
+ ~SQLiteKeyReader()
+ {
+ Dispose(false);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// How many additional columns of keyinfo we're holding
///
internal int Count
{
@@ -312,24 +429,10 @@
if (_keyInfo[n].query != null)
_keyInfo[n].query.IsValid = false;
}
}
- public void Dispose()
- {
- _stmt = null;
-
- if (_keyInfo == null) return;
-
- for (int n = 0; n < _keyInfo.Length; n++)
- {
- if (_keyInfo[n].query != null)
- _keyInfo[n].query.Dispose();
- }
- _keyInfo = null;
- }
-
internal string GetDataTypeName(int i)
{
Sync();
if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDataTypeName(_keyInfo[i].column);
else return "integer";
Index: System.Data.SQLite/SQLiteStatement.cs
==================================================================
--- System.Data.SQLite/SQLiteStatement.cs
+++ System.Data.SQLite/SQLiteStatement.cs
@@ -86,10 +86,79 @@
_paramValues[x] = null;
}
}
}
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable Members
+ ///
+ /// Disposes and finalizes the statement
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteStatement).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ private void Dispose(bool disposing)
+ {
+ if (!disposed)
+ {
+ if (disposing)
+ {
+ ////////////////////////////////////
+ // dispose managed resources here...
+ ////////////////////////////////////
+
+ if (_sqlite_stmt != null)
+ {
+ _sqlite_stmt.Dispose();
+ _sqlite_stmt = null;
+ }
+
+ _paramNames = null;
+ _paramValues = null;
+ _sql = null;
+ _sqlStatement = null;
+ }
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Destructor
+ ~SQLiteStatement()
+ {
+ Dispose(false);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
///
/// Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to
/// this statement, and if so, keeps a reference to the parameter so it can be bound later.
///
/// The parameter name to map
@@ -115,29 +184,10 @@
}
}
return false;
}
- #region IDisposable Members
- ///
- /// Disposes and finalizes the statement
- ///
- public void Dispose()
- {
- if (_sqlite_stmt != null)
- {
- _sqlite_stmt.Dispose();
- }
- _sqlite_stmt = null;
-
- _paramNames = null;
- _paramValues = null;
- _sql = null;
- _sqlStatement = null;
- }
- #endregion
-
///
/// Bind all parameters, making sure the caller didn't miss any
///
internal void BindParameters()
{
Index: System.Data.SQLite/SQLiteTransaction.cs
==================================================================
--- System.Data.SQLite/SQLiteTransaction.cs
+++ System.Data.SQLite/SQLiteTransaction.cs
@@ -55,17 +55,69 @@
_cnn._transactionLevel--;
_cnn = null;
throw;
}
}
- }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ throw new ObjectDisposedException(typeof(SQLiteTransaction).Name);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Disposes the transaction. If it is currently active, any changes are rolled back.
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (!disposed)
+ {
+ if (disposing)
+ {
+ ////////////////////////////////////
+ // dispose managed resources here...
+ ////////////////////////////////////
+
+ if (IsValid(false))
+ {
+ IssueRollback();
+ }
+ }
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
///
/// Commits the current transaction.
///
public override void Commit()
- {
+ {
+ CheckDisposed();
IsValid(true);
if (_cnn._transactionLevel - 1 == 0)
{
using (SQLiteCommand cmd = _cnn.CreateCommand())
@@ -80,50 +132,36 @@
///
/// Returns the underlying connection to which this transaction applies.
///
public new SQLiteConnection Connection
- {
- get { return _cnn; }
+ {
+ get { CheckDisposed(); return _cnn; }
}
///
/// Forwards to the local Connection property
///
protected override DbConnection DbConnection
- {
+ {
get { return Connection; }
}
- ///
- /// Disposes the transaction. If it is currently active, any changes are rolled back.
- ///
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (IsValid(false))
- {
- IssueRollback();
- }
- }
- base.Dispose(disposing);
- }
-
///
/// Gets the isolation level of the transaction. SQLite only supports Serializable transactions.
///
public override IsolationLevel IsolationLevel
- {
- get { return _level; }
+ {
+ get { CheckDisposed(); return _level; }
}
///
/// Rolls back the active transaction.
///
public override void Rollback()
- {
+ {
+ CheckDisposed();
IsValid(true);
IssueRollback();
}
internal void IssueRollback()
Index: System.Data.SQLite/SR.Designer.cs
==================================================================
--- System.Data.SQLite/SR.Designer.cs
+++ System.Data.SQLite/SR.Designer.cs
@@ -1,5 +1,12 @@
+/********************************************************
+ * 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!
+ ********************************************************/
+
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:4.0.30319.1
//
Index: System.Data.SQLite/System.Data.SQLite.Properties.targets
==================================================================
--- System.Data.SQLite/System.Data.SQLite.Properties.targets
+++ System.Data.SQLite/System.Data.SQLite.Properties.targets
@@ -48,6 +48,13 @@
flag from the AssemblyNameFlags enumeration?
-->
$(DefineConstants);RETARGETABLE
+
+
+
+ $(DefineConstants);THROW_ON_DISPOSED
+
Index: testlinq/NorthwindModel2010.Designer.cs
==================================================================
--- testlinq/NorthwindModel2010.Designer.cs
+++ testlinq/NorthwindModel2010.Designer.cs
@@ -1,13 +1,11 @@
-
//------------------------------------------------------------------------------
//
// This code was generated from a template.
//
Index: www/test.wiki
==================================================================
--- www/test.wiki
+++ www/test.wiki
@@ -109,11 +109,11 @@
Make sure all tests pass; the log file
"%TEMP%\EagleShell.exe.test.<pid>.log" may be checked if any
errors should occur. EagleTest should produce "success" messages
very similar to the following:
- PASSED: 96
- TOTAL: 96
+ PASSED: 107
+ TOTAL: 107
PASS PERCENTAGE: 100%
OVERALL RESULT: SUCCESS