System.Data.SQLite

Login
This project makes use of Eagle, provided by Mistachkin Systems.
Eagle: Secure Software Automation

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch cmdReset Excluding Merge-Ins

This is equivalent to a diff from 463bcfb351 to 6fa1fe8314

2015-09-09
23:44
Add Reset method to the SQLiteCommand class. check-in: 3e82d3be5b user: mistachkin tags: trunk
23:34
Bump all version numbers to 1.0.99.0. Update SQLite core library to the latest trunk code. check-in: c1fc6af85e user: mistachkin tags: trunk
2015-09-04
19:59
Add FileName property to the SQLiteConnection class. check-in: 71cc174339 user: mistachkin tags: dbFileName
2015-08-28
22:16
Fix implementation and tests for SQLiteCommand.Reset method. Remove (now) superfluous new code. Closed-Leaf check-in: 6fa1fe8314 user: mistachkin tags: cmdReset
20:26
Work in progress on exerpimental method to reset the statements associated with a SQLiteCommand. check-in: f12609cfe9 user: mistachkin tags: cmdReset
2015-08-25
21:16
Remove duplicate (and incorrect for Visual Studio 2015) link from the download page. check-in: 463bcfb351 user: mistachkin tags: trunk
2015-08-21
19:53
Sync up extended error codes with the SQLite core library. check-in: c6cacbbfa5 user: mistachkin tags: trunk

Changes to System.Data.SQLite/SQLiteCommand.cs.

1
2
3
4
5
6
7
8
9
10
11
/********************************************************
 * 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
{
  using System;
  using System.Data;



|







1
2
3
4
5
6
7
8
9
10
11
/********************************************************
 * 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
{
  using System;
  using System.Data;
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    {
    }

    /// <summary>
    /// Initializes the command with the given command text
    /// </summary>
    /// <param name="commandText">The SQL command text</param>
    public SQLiteCommand(string commandText) 
      : this(commandText, null, null)
    {
    }

    /// <summary>
    /// Initializes the command with the given SQL command text and attach the command to the specified
    /// connection.
    /// </summary>
    /// <param name="commandText">The SQL command text</param>
    /// <param name="connection">The connection to associate with the command</param>
    public SQLiteCommand(string commandText, SQLiteConnection connection)
      : this(commandText, connection, null)
    {
    }

    /// <summary>
    /// Initializes the command and associates it with the specified connection.
    /// </summary>
    /// <param name="connection">The connection to associate with the command</param>
    public SQLiteCommand(SQLiteConnection connection) 
      : this(null, connection, null)
    {
    }

    private SQLiteCommand(SQLiteCommand source) : this(source.CommandText, source.Connection, source.Transaction)
    {
      CommandTimeout = source.CommandTimeout;







|



















|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    {
    }

    /// <summary>
    /// Initializes the command with the given command text
    /// </summary>
    /// <param name="commandText">The SQL command text</param>
    public SQLiteCommand(string commandText)
      : this(commandText, null, null)
    {
    }

    /// <summary>
    /// Initializes the command with the given SQL command text and attach the command to the specified
    /// connection.
    /// </summary>
    /// <param name="commandText">The SQL command text</param>
    /// <param name="connection">The connection to associate with the command</param>
    public SQLiteCommand(string commandText, SQLiteConnection connection)
      : this(commandText, connection, null)
    {
    }

    /// <summary>
    /// Initializes the command and associates it with the specified connection.
    /// </summary>
    /// <param name="connection">The connection to associate with the command</param>
    public SQLiteCommand(SQLiteConnection connection)
      : this(null, connection, null)
    {
    }

    private SQLiteCommand(SQLiteCommand source) : this(source.CommandText, source.Connection, source.Transaction)
    {
      CommandTimeout = source.CommandTimeout;
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316

317
318
319
320
321
322

323
324
325
326
327
328
329
330









331
332
333
334
335
336
337
        }

        _statementList = null;
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Clears and destroys all statements currently prepared
    /// </summary>
    internal void ClearCommands()
    {
      if (_activeReader != null)
      {
        SQLiteDataReader reader = null;

        try
        {
          reader = _activeReader.Target as SQLiteDataReader;
        }
        catch(InvalidOperationException)
        {

        }

        if (reader != null)
          reader.Close();

        _activeReader = null;
      }










      DisposeStatements();

      _parameterCollection.Unbind();
    }

    /// <summary>
    /// Builds an array of prepared statements for each complete SQL statement in the command text







<
<
<
|




>






>



|



|
>
>
>
>
>
>
>
>
>







302
303
304
305
306
307
308



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
        }

        _statementList = null;
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////




    private void ClearDataReader()
    {
      if (_activeReader != null)
      {
        SQLiteDataReader reader = null;

        try
        {
          reader = _activeReader.Target as SQLiteDataReader;
        }
        catch(InvalidOperationException)
        {
          // do nothing.
        }

        if (reader != null)
          reader.Close(); /* Dispose */

        _activeReader = null;
      }
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Clears and destroys all statements currently prepared
    /// </summary>
    internal void ClearCommands()
    {
      ClearDataReader();
      DisposeStatements();

      _parameterCollection.Unbind();
    }

    /// <summary>
    /// Builds an array of prepared statements for each complete SQL statement in the command text
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
      SQLiteConnection.Check(_cnn);
      return ExecuteReader(CommandBehavior.Default);
    }

    /// <summary>
    /// Called by the SQLiteDataReader when the data reader is closed.
    /// </summary>
    internal void ClearDataReader()
    {
      _activeReader = null;
    }

    /// <summary>
    /// Execute the command and return the number of rows inserted/updated affected by it.
    /// </summary>







|







885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
      SQLiteConnection.Check(_cnn);
      return ExecuteReader(CommandBehavior.Default);
    }

    /// <summary>
    /// Called by the SQLiteDataReader when the data reader is closed.
    /// </summary>
    internal void ResetDataReader()
    {
      _activeReader = null;
    }

    /// <summary>
    /// Execute the command and return the number of rows inserted/updated affected by it.
    /// </summary>
946
947
948
949
950
951
952



































































953
954
955
956
957
958
959
          CommandBehavior.SingleRow | CommandBehavior.SingleResult))
      {
        if (reader.Read())
          return reader[0];
      }
      return null;
    }




































































    /// <summary>
    /// Does nothing.  Commands are prepared as they are executed the first time, and kept in prepared state afterwards.
    /// </summary>
    public override void Prepare()
    {
      CheckDisposed();







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
          CommandBehavior.SingleRow | CommandBehavior.SingleResult))
      {
        if (reader.Read())
          return reader[0];
      }
      return null;
    }

    /// <summary>
    /// This method resets all the prepared statements held by this instance
    /// back to their initial states, ready to be re-executed.
    /// </summary>
    public void Reset()
    {
        CheckDisposed();
        SQLiteConnection.Check(_cnn);

        Reset(true, false);
    }

    /// <summary>
    /// This method resets all the prepared statements held by this instance
    /// back to their initial states, ready to be re-executed.
    /// </summary>
    /// <param name="clearBindings">
    /// Non-zero if the parameter bindings should be cleared as well.
    /// </param>
    /// <param name="ignoreErrors">
    /// If this is zero, a <see cref="SQLiteException" /> may be thrown for
    /// any unsuccessful return codes from the native library; otherwise, a
    /// <see cref="SQLiteException" /> will only be thrown if the connection
    /// or its state is invalid.
    /// </param>
    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());
        }
    }

    /// <summary>
    /// Does nothing.  Commands are prepared as they are executed the first time, and kept in prepared state afterwards.
    /// </summary>
    public override void Prepare()
    {
      CheckDisposed();

Changes to System.Data.SQLite/SQLiteDataReader.cs.

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
                  {
                  }
                }
                catch(SQLiteException)
                {
                }
              }
              _command.ClearDataReader();
            }
            finally
            {
              // If the datareader's behavior includes closing the connection, then do so here.
              if ((_commandBehavior & CommandBehavior.CloseConnection) != 0 && _command.Connection != null)
                _command.Connection.Close();
            }







|







220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
                  {
                  }
                }
                catch(SQLiteException)
                {
                }
              }
              _command.ResetDataReader();
            }
            finally
            {
              // If the datareader's behavior includes closing the connection, then do so here.
              if ((_commandBehavior & CommandBehavior.CloseConnection) != 0 && _command.Connection != null)
                _command.Connection.Close();
            }

Changes to System.Data.SQLite/UnsafeNativeMethods.cs.

1859
1860
1861
1862
1863
1864
1865







1866
1867
1868
1869
1870
1871
1872
#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#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_bind_blob(IntPtr stmt, int index, Byte[] value, int nSize, IntPtr nTransient);








>
>
>
>
>
>
>







1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#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
    internal static extern SQLiteErrorCode sqlite3_bind_blob(IntPtr stmt, int index, Byte[] value, int nSize, IntPtr nTransient);

Changes to Tests/basic.eagle.

3850
3851
3852
3853
3854
3855
3856




















































3857
3858
3859
3860
3861
3862
3863
  rename hashManagedArray ""
  rename getHashCode ""
  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+\}$}}





















































###############################################################################

reportSQLiteResources $test_channel

###############################################################################








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
  rename hashManagedArray ""
  rename getHashCode ""
  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

###############################################################################