System.Data.SQLite
Check-in [dae0c2e6fc]
Not logged in

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

Overview
Comment:Make sure that manually calling the Cancel method still causes an Interrupt exception to be thrown. Update master release archive manifest.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: dae0c2e6fccf12557f2ebc97560f170703264ae5
User & Date: mistachkin 2015-06-24 22:43:10
Context
2015-06-26
03:13
Update SQLite core library to the latest trunk code. check-in: a92cbefdad user: mistachkin tags: trunk
2015-06-24
22:43
Make sure that manually calling the Cancel method still causes an Interrupt exception to be thrown. Update master release archive manifest. check-in: dae0c2e6fc user: mistachkin tags: trunk
20:02
Change the base type for the SQLiteConnectionFlags enumeration to long integer. Improve exception handling in all native callbacks implemented in the SQLiteConnection class. Add Progress event and ProgressOps connection string property to enable raising progress events during long-running queries. check-in: 3b020c8c80 user: mistachkin tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Setup/data/verify.lst.

709
710
711
712
713
714
715

716
717
718
719
720
721
722
...
753
754
755
756
757
758
759

760
761
762
763
764
765
766
  Tests/data/Uninstaller_Test_Vs2010.log
  Tests/data/Uninstaller_Test_Vs2012.log
  Tests/data/Uninstaller_Test_Vs2013.log
  Tests/data/wal.db
  Tests/empty.eagle
  Tests/installer.eagle
  Tests/linq.eagle

  Tests/speed.eagle
  Tests/stress.eagle
  Tests/thread.eagle
  Tests/tkt-00f86f9739.eagle
  Tests/tkt-0a32885109.eagle
  Tests/tkt-0d5b1ef362.eagle
  Tests/tkt-17045010df.eagle
................................................................................
  Tests/tkt-8b7d179c3c.eagle
  Tests/tkt-8c3bee31c8.eagle
  Tests/tkt-8d928c3e88.eagle
  Tests/tkt-92dbf1229a.eagle
  Tests/tkt-94252b9059.eagle
  Tests/tkt-996d13cd87.eagle
  Tests/tkt-9ba9346f75.eagle

  Tests/tkt-a4d9c7ee94.eagle
  Tests/tkt-a7d04fb111.eagle
  Tests/tkt-aba4549801.eagle
  Tests/tkt-ac47dd230a.eagle
  Tests/tkt-ae5267b863.eagle
  Tests/tkt-b4a7ddc83f.eagle
  Tests/tkt-bb4b04d457.eagle







>







 







>







709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
...
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
  Tests/data/Uninstaller_Test_Vs2010.log
  Tests/data/Uninstaller_Test_Vs2012.log
  Tests/data/Uninstaller_Test_Vs2013.log
  Tests/data/wal.db
  Tests/empty.eagle
  Tests/installer.eagle
  Tests/linq.eagle
  Tests/progress.eagle
  Tests/speed.eagle
  Tests/stress.eagle
  Tests/thread.eagle
  Tests/tkt-00f86f9739.eagle
  Tests/tkt-0a32885109.eagle
  Tests/tkt-0d5b1ef362.eagle
  Tests/tkt-17045010df.eagle
................................................................................
  Tests/tkt-8b7d179c3c.eagle
  Tests/tkt-8c3bee31c8.eagle
  Tests/tkt-8d928c3e88.eagle
  Tests/tkt-92dbf1229a.eagle
  Tests/tkt-94252b9059.eagle
  Tests/tkt-996d13cd87.eagle
  Tests/tkt-9ba9346f75.eagle
  Tests/tkt-9d353b0bd8.eagle
  Tests/tkt-a4d9c7ee94.eagle
  Tests/tkt-a7d04fb111.eagle
  Tests/tkt-aba4549801.eagle
  Tests/tkt-ac47dd230a.eagle
  Tests/tkt-ae5267b863.eagle
  Tests/tkt-b4a7ddc83f.eagle
  Tests/tkt-bb4b04d457.eagle

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

13
14
15
16
17
18
19

20
21
22
23
24
25
26
..
63
64
65
66
67
68
69

70
71
72
73
74
75
76
...
259
260
261
262
263
264
265







































266
267
268
269
270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
...
804
805
806
807
808
809
810


811
812
813
814
815
816
817
818
819
820
821



822
823







824


825
826
827
828
829
830
831
....
1082
1083
1084
1085
1086
1087
1088


1089
1090
1091
1092
1093
1094
1095
....
1129
1130
1131
1132
1133
1134
1135












1136
1137
1138
1139
1140
1141
1142
....
1202
1203
1204
1205
1206
1207
1208












1209
1210
1211
1212
1213
1214
1215
#if !NET_COMPACT_20 && (TRACE_CONNECTION || TRACE_STATEMENT)
  using System.Diagnostics;
#endif

  using System.Globalization;
  using System.Runtime.InteropServices;
  using System.Text;


  /// <summary>
  /// This is the method signature for the SQLite core library logging callback
  /// function for use with sqlite3_log() and the SQLITE_CONFIG_LOG.
  ///
  /// WARNING: This delegate is used more-or-less directly by native code, do
  ///          not modify its type signature.
................................................................................
    /// <summary>
    /// The opaque pointer returned to us by the sqlite provider
    /// </summary>
    protected internal SQLiteConnectionHandle _sql;
    protected string _fileName;
    protected bool _usePool;
    protected int _poolVersion;


#if (NET_35 || NET_40 || NET_45 || NET_451) && !PLATFORM_COMPACTFRAMEWORK
    private bool _buildingSchema;
#endif

    /// <summary>
    /// The user-defined functions registered on this connection
................................................................................
          }
          _sql = null;
      }
    }

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








































    /// <summary>
    /// Attempts to interrupt the query currently executing on the associated
    /// native database connection.
    /// </summary>
    internal override void Cancel()
    {
      try
      {
        // do nothing.
      }
      finally /* NOTE: Thread.Abort() protection. */
      {

        UnsafeNativeMethods.sqlite3_interrupt(_sql);
      }
    }

    /// <summary>
    /// This function binds a user-defined function to the connection.
    /// </summary>
................................................................................
    internal override bool Step(SQLiteStatement stmt)
    {
      SQLiteErrorCode n;
      Random rnd = null;
      uint starttick = (uint)Environment.TickCount;
      uint timeout = (uint)(stmt._command._commandTimeout * 1000);



      while (true)
      {
        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
          n = UnsafeNativeMethods.sqlite3_step(stmt._sqlite_stmt);
        }




        if (n == SQLiteErrorCode.Row) return true;
        if (n == SQLiteErrorCode.Done) return false;







        if (n == SQLiteErrorCode.Interrupt) return false;



        if (n != SQLiteErrorCode.Ok)
        {
          SQLiteErrorCode r;

          // An error occurred, attempt to reset the statement.  If the reset worked because the
          // schema has changed, re-try the step again.  If it errored our because the database
................................................................................
      int retries = 0;
      int maximumRetries = (cnn != null) ? cnn._prepareRetries : SQLiteConnection.DefaultPrepareRetries;
      byte[] b = ToUTF8(strSql);
      string typedefs = null;
      SQLiteStatement cmd = null;
      Random rnd = null;
      uint starttick = (uint)Environment.TickCount;



      GCHandle handle = GCHandle.Alloc(b, GCHandleType.Pinned);
      IntPtr psql = handle.AddrOfPinnedObject();
      SQLiteStatementHandle statementHandle = null;
      try
      {
        while ((n == SQLiteErrorCode.Schema || n == SQLiteErrorCode.Locked || n == SQLiteErrorCode.Busy) && retries < maximumRetries)
................................................................................
          if (statementHandle != null)
          {
            SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
              SQLiteConnectionEventType.NewCriticalHandle, null, null,
              null, null, statementHandle, strSql, new object[] { cnn,
              strSql, previous, timeoutMS }));
          }













          if (n == SQLiteErrorCode.Interrupt)
            break;
          else if (n == SQLiteErrorCode.Schema)
            retries++;
          else if (n == SQLiteErrorCode.Error)
          {
................................................................................
            else
            {
              // Otherwise sleep for a random amount of time up to 150ms
              System.Threading.Thread.Sleep(rnd.Next(1, 150));
            }
          }
        }













        if (n == SQLiteErrorCode.Interrupt) return null;
        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());

        strRemain = UTF8ToString(ptr, len);

        if (statementHandle != null) cmd = new SQLiteStatement(this, flags, statementHandle, strSql.Substring(0, strSql.Length - strRemain.Length), previous);







>







 







>







 







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












>







 







>
>











>
>
>
|
|
>
>
>
>
>
>
>

>
>







 







>
>







 







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







 







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







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
..
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
...
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
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
...
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
....
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
....
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
....
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
#if !NET_COMPACT_20 && (TRACE_CONNECTION || TRACE_STATEMENT)
  using System.Diagnostics;
#endif

  using System.Globalization;
  using System.Runtime.InteropServices;
  using System.Text;
  using System.Threading;

  /// <summary>
  /// This is the method signature for the SQLite core library logging callback
  /// function for use with sqlite3_log() and the SQLITE_CONFIG_LOG.
  ///
  /// WARNING: This delegate is used more-or-less directly by native code, do
  ///          not modify its type signature.
................................................................................
    /// <summary>
    /// The opaque pointer returned to us by the sqlite provider
    /// </summary>
    protected internal SQLiteConnectionHandle _sql;
    protected string _fileName;
    protected bool _usePool;
    protected int _poolVersion;
    private int _cancelCount;

#if (NET_35 || NET_40 || NET_45 || NET_451) && !PLATFORM_COMPACTFRAMEWORK
    private bool _buildingSchema;
#endif

    /// <summary>
    /// The user-defined functions registered on this connection
................................................................................
          }
          _sql = null;
      }
    }

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

    /// <summary>
    /// Returns the number of times the <see cref="Cancel" /> method has been
    /// called.
    /// </summary>
    private int GetCancelCount()
    {
        return Interlocked.CompareExchange(ref _cancelCount, 0, 0);
    }

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

    /// <summary>
    /// This method determines whether or not a <see cref="SQLiteException" />
    /// with a return code of <see cref="SQLiteErrorCode.Interrupt" /> should
    /// be thrown after making a call into the SQLite core library.
    /// </summary>
    /// <returns>
    /// Non-zero if a <see cref="SQLiteException" /> to be thrown.  This method
    /// will only return non-zero if the <see cref="Cancel" /> method was called
    /// one or more times during a call into the SQLite core library (e.g. when
    /// the sqlite3_prepare*() or sqlite3_step() APIs are used).
    /// </returns>
    private bool ShouldThrowForCancel()
    {
        return GetCancelCount() > 0;
    }

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

    /// <summary>
    /// Resets the value of the <see cref="_cancelCount" /> field.
    /// </summary>
    private int ResetCancelCount()
    {
        return Interlocked.CompareExchange(ref _cancelCount, 0, _cancelCount);
    }

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

    /// <summary>
    /// Attempts to interrupt the query currently executing on the associated
    /// native database connection.
    /// </summary>
    internal override void Cancel()
    {
      try
      {
        // do nothing.
      }
      finally /* NOTE: Thread.Abort() protection. */
      {
        Interlocked.Increment(ref _cancelCount);
        UnsafeNativeMethods.sqlite3_interrupt(_sql);
      }
    }

    /// <summary>
    /// This function binds a user-defined function to the connection.
    /// </summary>
................................................................................
    internal override bool Step(SQLiteStatement stmt)
    {
      SQLiteErrorCode n;
      Random rnd = null;
      uint starttick = (uint)Environment.TickCount;
      uint timeout = (uint)(stmt._command._commandTimeout * 1000);

      ResetCancelCount();

      while (true)
      {
        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
          n = UnsafeNativeMethods.sqlite3_step(stmt._sqlite_stmt);
        }

        if (ShouldThrowForCancel())
        {
            if ((n == SQLiteErrorCode.Ok) ||
                (n == SQLiteErrorCode.Row) ||
                (n == SQLiteErrorCode.Done))
            {
                n = SQLiteErrorCode.Interrupt;
            }

            throw new SQLiteException(n, null);
        }

        if (n == SQLiteErrorCode.Interrupt) return false;
        if (n == SQLiteErrorCode.Row) return true;
        if (n == SQLiteErrorCode.Done) return false;

        if (n != SQLiteErrorCode.Ok)
        {
          SQLiteErrorCode r;

          // An error occurred, attempt to reset the statement.  If the reset worked because the
          // schema has changed, re-try the step again.  If it errored our because the database
................................................................................
      int retries = 0;
      int maximumRetries = (cnn != null) ? cnn._prepareRetries : SQLiteConnection.DefaultPrepareRetries;
      byte[] b = ToUTF8(strSql);
      string typedefs = null;
      SQLiteStatement cmd = null;
      Random rnd = null;
      uint starttick = (uint)Environment.TickCount;

      ResetCancelCount();

      GCHandle handle = GCHandle.Alloc(b, GCHandleType.Pinned);
      IntPtr psql = handle.AddrOfPinnedObject();
      SQLiteStatementHandle statementHandle = null;
      try
      {
        while ((n == SQLiteErrorCode.Schema || n == SQLiteErrorCode.Locked || n == SQLiteErrorCode.Busy) && retries < maximumRetries)
................................................................................
          if (statementHandle != null)
          {
            SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
              SQLiteConnectionEventType.NewCriticalHandle, null, null,
              null, null, statementHandle, strSql, new object[] { cnn,
              strSql, previous, timeoutMS }));
          }

          if (ShouldThrowForCancel())
          {
              if ((n == SQLiteErrorCode.Ok) ||
                  (n == SQLiteErrorCode.Row) ||
                  (n == SQLiteErrorCode.Done))
              {
                  n = SQLiteErrorCode.Interrupt;
              }

              throw new SQLiteException(n, null);
          }

          if (n == SQLiteErrorCode.Interrupt)
            break;
          else if (n == SQLiteErrorCode.Schema)
            retries++;
          else if (n == SQLiteErrorCode.Error)
          {
................................................................................
            else
            {
              // Otherwise sleep for a random amount of time up to 150ms
              System.Threading.Thread.Sleep(rnd.Next(1, 150));
            }
          }
        }

        if (ShouldThrowForCancel())
        {
            if ((n == SQLiteErrorCode.Ok) ||
                (n == SQLiteErrorCode.Row) ||
                (n == SQLiteErrorCode.Done))
            {
                n = SQLiteErrorCode.Interrupt;
            }

            throw new SQLiteException(n, null);
        }

        if (n == SQLiteErrorCode.Interrupt) return null;
        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());

        strRemain = UTF8ToString(ptr, len);

        if (statementHandle != null) cmd = new SQLiteStatement(this, flags, statementHandle, strSql.Substring(0, strSql.Length - strRemain.Length), previous);