Index: System.Data.SQLite/SQLiteCommand.cs
==================================================================
--- System.Data.SQLite/SQLiteCommand.cs
+++ System.Data.SQLite/SQLiteCommand.cs
@@ -1,9 +1,9 @@
/********************************************************
* 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!
********************************************************/
namespace System.Data.SQLite
{
@@ -88,11 +88,11 @@
///
/// Initializes the command with the given command text
///
/// The SQL command text
- public SQLiteCommand(string commandText)
+ public SQLiteCommand(string commandText)
: this(commandText, null, null)
{
}
///
@@ -108,11 +108,11 @@
///
/// Initializes the command and associates it with the specified connection.
///
/// The connection to associate with the command
- public SQLiteCommand(SQLiteConnection connection)
+ public SQLiteCommand(SQLiteConnection connection)
: this(null, connection, null)
{
}
private SQLiteCommand(SQLiteCommand source) : this(source.CommandText, source.Connection, source.Transaction)
@@ -304,32 +304,40 @@
_statementList = null;
}
///////////////////////////////////////////////////////////////////////////////////////////////
- ///
- /// Clears and destroys all statements currently prepared
- ///
- internal void ClearCommands()
+ private void ClearDataReader()
{
if (_activeReader != null)
{
SQLiteDataReader reader = null;
+
try
{
reader = _activeReader.Target as SQLiteDataReader;
}
catch(InvalidOperationException)
{
+ // do nothing.
}
if (reader != null)
- reader.Close();
+ reader.Close(); /* Dispose */
_activeReader = null;
}
+ }
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Clears and destroys all statements currently prepared
+ ///
+ internal void ClearCommands()
+ {
+ ClearDataReader();
DisposeStatements();
_parameterCollection.Unbind();
}
@@ -879,11 +887,11 @@
}
///
/// Called by the SQLiteDataReader when the data reader is closed.
///
- internal void ClearDataReader()
+ internal void ResetDataReader()
{
_activeReader = null;
}
///
@@ -948,10 +956,77 @@
if (reader.Read())
return reader[0];
}
return null;
}
+
+ ///
+ /// This method resets all the prepared statements held by this instance
+ /// back to their initial states, ready to be re-executed.
+ ///
+ public void Reset()
+ {
+ CheckDisposed();
+ SQLiteConnection.Check(_cnn);
+
+ Reset(true, false);
+ }
+
+ ///
+ /// This method resets all the prepared statements held by this instance
+ /// back to their initial states, ready to be re-executed.
+ ///
+ ///
+ /// Non-zero if the parameter bindings should be cleared as well.
+ ///
+ ///
+ /// If this is zero, a may be thrown for
+ /// any unsuccessful return codes from the native library; otherwise, a
+ /// will only be thrown if the connection
+ /// or its state is invalid.
+ ///
+ public void Reset(
+ bool clearBindings,
+ bool ignoreErrors
+ )
+ {
+ CheckDisposed();
+ SQLiteConnection.Check(_cnn);
+
+ if (clearBindings && (_parameterCollection != null))
+ _parameterCollection.Unbind();
+
+ ClearDataReader();
+
+ if (_statementList == null)
+ return;
+
+ SQLiteBase sqlBase = _cnn._sql;
+ SQLiteErrorCode rc;
+
+ foreach (SQLiteStatement item in _statementList)
+ {
+ if (item == null)
+ continue;
+
+ SQLiteStatementHandle stmt = item._sqlite_stmt;
+
+ if (stmt == null)
+ continue;
+
+ rc = sqlBase.Reset(item);
+
+ if ((rc == SQLiteErrorCode.Ok) && clearBindings &&
+ (SQLite3.SQLiteVersionNumber >= 3003007))
+ {
+ rc = UnsafeNativeMethods.sqlite3_clear_bindings(stmt);
+ }
+
+ if (!ignoreErrors && (rc != SQLiteErrorCode.Ok))
+ throw new SQLiteException(rc, sqlBase.GetLastError());
+ }
+ }
///
/// Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards.
///
public override void Prepare()
Index: System.Data.SQLite/SQLiteDataReader.cs
==================================================================
--- System.Data.SQLite/SQLiteDataReader.cs
+++ System.Data.SQLite/SQLiteDataReader.cs
@@ -222,11 +222,11 @@
}
catch(SQLiteException)
{
}
}
- _command.ClearDataReader();
+ _command.ResetDataReader();
}
finally
{
// If the datareader's behavior includes closing the connection, then do so here.
if ((_commandBehavior & CommandBehavior.CloseConnection) != 0 && _command.Connection != null)
Index: System.Data.SQLite/UnsafeNativeMethods.cs
==================================================================
--- System.Data.SQLite/UnsafeNativeMethods.cs
+++ System.Data.SQLite/UnsafeNativeMethods.cs
@@ -1861,10 +1861,17 @@
#else
[DllImport(SQLITE_DLL)]
#endif
internal static extern SQLiteErrorCode sqlite3_busy_timeout(IntPtr db, int ms);
+#if !PLATFORM_COMPACTFRAMEWORK
+ [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
+#else
+ [DllImport(SQLITE_DLL)]
+#endif
+ internal static extern SQLiteErrorCode sqlite3_clear_bindings(IntPtr stmt);
+
#if !PLATFORM_COMPACTFRAMEWORK
[DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
[DllImport(SQLITE_DLL)]
#endif
Index: Tests/basic.eagle
==================================================================
--- Tests/basic.eagle
+++ Tests/basic.eagle
@@ -3852,10 +3852,62 @@
rename getMyFuncArgs ""
} -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -match regexp -result {^0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 \{1\
2 3 A a M m Z z\} True 1 True 1 True 1 True 1 True 1 True 1 True 1 True 1\
\{(?:-)?\d+ (?:-)?\d+\}$}}
+
+###############################################################################
+
+runTest {test data-1.75 {SQLiteCommand.Reset method} -setup {
+ setupDb [set fileName data-1.75.db]
+} -body {
+ set connection [getDbConnection]
+
+ set result [list]
+
+ sql execute $db {
+ CREATE TABLE t1(x);
+ INSERT INTO t1 (x) VALUES(1);
+ INSERT INTO t1 (x) VALUES(2);
+ INSERT INTO t1 (x) VALUES(3);
+ INSERT INTO t1 (x) VALUES(4);
+ }
+
+ set command [$connection -alias CreateCommand]
+ set parameter [$command -alias CreateParameter]
+
+ $parameter ParameterName param1
+ $parameter DbType Int32
+ $parameter Value 4
+
+ $command CommandText "SELECT x FROM t1 WHERE x < ? ORDER BY x;"
+ $command Parameters.Add $parameter
+
+ set dataReader(1) [$command -alias ExecuteReader]
+
+ $dataReader(1) Read; lappend result [$dataReader(1) Item x]
+ $dataReader(1) Read; lappend result [$dataReader(1) Item x]
+
+ $command Reset; set dataReader(2) [$command -alias ExecuteReader]
+ $dataReader(2) Read; lappend result [$dataReader(2) Item x]
+ $dataReader(2) Read; lappend result [$dataReader(2) Item x]
+
+ $command Reset; set dataReader(3) [$command -alias ExecuteReader]
+ $dataReader(3) Read; lappend result [$dataReader(3) Item x]
+ $dataReader(3) Read; lappend result [$dataReader(3) Item x]
+
+ set result
+} -cleanup {
+ unset -nocomplain dataReader parameter command connection
+
+ freeDbConnection
+
+ cleanupDb $fileName
+
+ unset -nocomplain result db fileName
+} -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
+System.Data.SQLite} -result {1 2 1 2 1 2}}
###############################################################################
reportSQLiteResources $test_channel