Index: System.Data.SQLite/SQLiteCommand.cs ================================================================== --- System.Data.SQLite/SQLiteCommand.cs +++ System.Data.SQLite/SQLiteCommand.cs @@ -948,10 +948,75 @@ 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(); + + 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 @@ -1546,10 +1546,52 @@ _activeStatement, i); } return typ; } + + /// + /// This method resets all the prepared statements referenced by this + /// instance back to their initial states, ready to be re-executed. + /// + public void Reset() + { + CheckDisposed(); + CheckClosed(); + + if (_command == null) + return; + + _command.Reset(); + } + + /// + /// This method resets all the prepared statements referenced 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(); + CheckClosed(); + + if (_command == null) + return; + + _command.Reset(clearBindings, ignoreErrors); + } /// /// Reads the next row from the resultset /// /// True if a new row was successfully loaded and is ready for processing 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,52 @@ 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 {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 dataReader [sql execute -execute reader -format datareader \ + -alias $db "SELECT x FROM t1 WHERE x < ? ORDER BY x;" \ + [list param1 Int32 4]] + + $dataReader Read; lappend result [$dataReader Item x] + $dataReader Read; lappend result [$dataReader Item x] + + $dataReader Reset; $dataReader NextResult; # TODO: Fix me. + $dataReader Read; lappend result [$dataReader Item x] + $dataReader Read; lappend result [$dataReader Item x] + + $dataReader Reset; $dataReader NextResult; # TODO: Fix me. + $dataReader Read; lappend result [$dataReader Item x] + $dataReader Read; lappend result [$dataReader Item x] + + set result +} -cleanup { + cleanupDb $fileName + + freeDbConnection + + unset -nocomplain result connection 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