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 tkt-f8dbab8baf Excluding Merge-Ins

This is equivalent to a diff from 00b02c1aa6 to 8106912e85

2013-09-14
00:31
Make sure the database cannot be changed by a query when the CommandBehavior.SchemaOnly flag is used. Fix for [f8dbab8baf]. check-in: 0474af7d87 user: mistachkin tags: trunk
2013-09-13
17:00
Add another test. Closed-Leaf check-in: 8106912e85 user: mistachkin tags: tkt-f8dbab8baf
01:40
Merge updates from trunk. check-in: 15ffbd9d69 user: mistachkin tags: tkt-f8dbab8baf
01:38
Add SQLiteCommand.Execute, SQLiteCommand.ExecuteNonQuery, and SQLiteCommand.ExecuteScalar method overloads that take a CommandBehavior parameter. check-in: 00b02c1aa6 user: mistachkin tags: trunk
2013-09-12
21:30
Update SQLite core library to the latest trunk code. check-in: b5ae536a3d user: mistachkin tags: trunk

Changes to Doc/Extra/version.html.

48
49
50
51
52
53
54

55
56
57
58
59
60
61
      <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.8.1</a>.</li>
      <li>Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for <a href="http://system.data.sqlite.org/index.html/info/3113734605">[3113734605]</a>.</li>
      <li>Check the result of sqlite3_column_name function against NULL.</li>
      <li>Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.</li>
      <li>Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Fix for <a href="http://system.data.sqlite.org/index.html/info/aba4549801">[aba4549801]</a>.</li>
      <li>Add SQLiteCommand.Execute, SQLiteCommand.ExecuteNonQuery, and SQLiteCommand.ExecuteScalar method overloads that take a CommandBehavior parameter.</li>
      <li>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></li>

      <li>Include the XML documentation files in the NuGet packages. Fix for <a href="http://system.data.sqlite.org/index.html/info/5970d5b0a6">[5970d5b0a6]</a>.</li>
    </ul>
    <p><b>1.0.88.0 - August 7, 2013</b></p>
    <ul>
      <li>Various fixes to managed virtual table integration infrastructure.</li>
      <li>Implement workaround for an incorrect PROCESSOR_ARCHITECTURE being reported. Fix for <a href="http://system.data.sqlite.org/index.html/info/9ac9862611">[9ac9862611]</a>.</li>
      <li>Modify classes that implement the IDisposable pattern to set the disposed flag after their base classes have been disposed.</li>







>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
      <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.8.1</a>.</li>
      <li>Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for <a href="http://system.data.sqlite.org/index.html/info/3113734605">[3113734605]</a>.</li>
      <li>Check the result of sqlite3_column_name function against NULL.</li>
      <li>Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.</li>
      <li>Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Fix for <a href="http://system.data.sqlite.org/index.html/info/aba4549801">[aba4549801]</a>.</li>
      <li>Add SQLiteCommand.Execute, SQLiteCommand.ExecuteNonQuery, and SQLiteCommand.ExecuteScalar method overloads that take a CommandBehavior parameter.</li>
      <li>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>Make sure the database cannot be changed by a query when the CommandBehavior.SchemaOnly flag is used. Fix for <a href="http://system.data.sqlite.org/index.html/info/f8dbab8baf">[f8dbab8baf]</a>.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>Include the XML documentation files in the NuGet packages. Fix for <a href="http://system.data.sqlite.org/index.html/info/5970d5b0a6">[5970d5b0a6]</a>.</li>
    </ul>
    <p><b>1.0.88.0 - August 7, 2013</b></p>
    <ul>
      <li>Various fixes to managed virtual table integration infrastructure.</li>
      <li>Implement workaround for an incorrect PROCESSOR_ARCHITECTURE being reported. Fix for <a href="http://system.data.sqlite.org/index.html/info/9ac9862611">[9ac9862611]</a>.</li>
      <li>Modify classes that implement the IDisposable pattern to set the disposed flag after their base classes have been disposed.</li>

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

1236
1237
1238
1239
1240
1241
1242

1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
    {
      CheckDisposed();
      CheckClosed();
      if (_throwOnDisposed) SQLiteCommand.Check(_command);

      SQLiteStatement stmt = null;
      int fieldCount;


      while (true)
      {
        if (stmt == null && _activeStatement != null && _activeStatement._sql != null && _activeStatement._sql.IsOpen())
        {
          // Reset the previously-executed statement
          _activeStatement._sql.Reset(_activeStatement);

          // If we're only supposed to return a single rowset, step through all remaining statements once until
          // they are all done and return false to indicate no more resultsets exist.
          if ((_commandBehavior & CommandBehavior.SingleResult) != 0)
          {
            for (; ; )
            {
              stmt = _command.GetStatement(_activeStatementIndex + 1);
              if (stmt == null) break;
              _activeStatementIndex++;

              stmt._sql.Step(stmt);
              if (stmt._sql.ColumnCount(stmt) == 0)
              {
                if (_rowsAffected == -1) _rowsAffected = 0;
                int changes = 0;
                if (stmt.TryGetChanges(ref changes))
                    _rowsAffected += changes;
                else
                    return false;
              }
              stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such!
            }
            return false;
          }
        }

        // Get the next statement to execute
        stmt = _command.GetStatement(_activeStatementIndex + 1);







>






|











|









|







1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
    {
      CheckDisposed();
      CheckClosed();
      if (_throwOnDisposed) SQLiteCommand.Check(_command);

      SQLiteStatement stmt = null;
      int fieldCount;
      bool schemaOnly = ((_commandBehavior & CommandBehavior.SchemaOnly) != 0);

      while (true)
      {
        if (stmt == null && _activeStatement != null && _activeStatement._sql != null && _activeStatement._sql.IsOpen())
        {
          // Reset the previously-executed statement
          if (!schemaOnly) _activeStatement._sql.Reset(_activeStatement);

          // If we're only supposed to return a single rowset, step through all remaining statements once until
          // they are all done and return false to indicate no more resultsets exist.
          if ((_commandBehavior & CommandBehavior.SingleResult) != 0)
          {
            for (; ; )
            {
              stmt = _command.GetStatement(_activeStatementIndex + 1);
              if (stmt == null) break;
              _activeStatementIndex++;

              if (!schemaOnly) stmt._sql.Step(stmt);
              if (stmt._sql.ColumnCount(stmt) == 0)
              {
                if (_rowsAffected == -1) _rowsAffected = 0;
                int changes = 0;
                if (stmt.TryGetChanges(ref changes))
                    _rowsAffected += changes;
                else
                    return false;
              }
              if (!schemaOnly) stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such!
            }
            return false;
          }
        }

        // Get the next statement to execute
        stmt = _command.GetStatement(_activeStatementIndex + 1);
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
          _readingState = 1;

        _activeStatementIndex++;

        fieldCount = stmt._sql.ColumnCount(stmt);

        // If the statement is not a select statement or we're not retrieving schema only, then perform the initial step
        if ((_commandBehavior & CommandBehavior.SchemaOnly) == 0 || fieldCount == 0)
        {
          if (stmt._sql.Step(stmt))
          {
            _readingState = -1;
          }
          else if (fieldCount == 0) // No rows returned, if fieldCount is zero, skip to the next statement
          {
            if (_rowsAffected == -1) _rowsAffected = 0;
            int changes = 0;
            if (stmt.TryGetChanges(ref changes))
                _rowsAffected += changes;
            else
                return false;
            stmt._sql.Reset(stmt);
            continue; // Skip this command and move to the next, it was not a row-returning resultset
          }
          else // No rows, fieldCount is non-zero so stop here
          {
            _readingState = 1; // This command returned columns but no rows, so return true, but HasRows = false and Read() returns false
          }
        }







|

|








|

|
|







1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
          _readingState = 1;

        _activeStatementIndex++;

        fieldCount = stmt._sql.ColumnCount(stmt);

        // If the statement is not a select statement or we're not retrieving schema only, then perform the initial step
        if (!schemaOnly || (fieldCount == 0))
        {
          if (!schemaOnly && stmt._sql.Step(stmt))
          {
            _readingState = -1;
          }
          else if (fieldCount == 0) // No rows returned, if fieldCount is zero, skip to the next statement
          {
            if (_rowsAffected == -1) _rowsAffected = 0;
            int changes = 0;
            if (stmt.TryGetChanges(ref changes))
              _rowsAffected += changes;
            else
              return false;
            if (!schemaOnly) stmt._sql.Reset(stmt);
            continue; // Skip this command and move to the next, it was not a row-returning resultset
          }
          else // No rows, fieldCount is non-zero so stop here
          {
            _readingState = 1; // This command returned columns but no rows, so return true, but HasRows = false and Read() returns false
          }
        }
1359
1360
1361
1362
1363
1364
1365



1366
1367
1368
1369
1370
1371
1372
    /// </summary>
    /// <returns>True if a new row was successfully loaded and is ready for processing</returns>
    public override bool Read()
    {
      CheckDisposed();
      CheckClosed();
      if (_throwOnDisposed) SQLiteCommand.Check(_command);




      if (_readingState == -1) // First step was already done at the NextResult() level, so don't step again, just return true.
      {
        _readingState = 0;
        return true;
      }
      else if (_readingState == 0) // Actively reading rows







>
>
>







1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
    /// </summary>
    /// <returns>True if a new row was successfully loaded and is ready for processing</returns>
    public override bool Read()
    {
      CheckDisposed();
      CheckClosed();
      if (_throwOnDisposed) SQLiteCommand.Check(_command);

      if ((_commandBehavior & CommandBehavior.SchemaOnly) != 0)
        return false;

      if (_readingState == -1) // First step was already done at the NextResult() level, so don't step again, just return true.
      {
        _readingState = 0;
        return true;
      }
      else if (_readingState == 0) // Actively reading rows

Changes to Tests/common.eagle.

915
916
917
918
919
920
921


















922
923
924
925
926
927
928
    proc isMemoryDb { fileName } {
      #
      # NOTE: Is the specified database file name really an in-memory database?
      #
      return [expr {$fileName eq ":memory:" || \
          [string range $fileName 0 12] eq "file::memory:"}]
    }



















    proc executeSql { sql {execute none} {fileName ""} } {
      if {[string length $fileName] == 0} then {set fileName :memory:}
      setupDb $fileName "" "" "" "" "" false false false false memDb

      try {
        return [sql execute -execute $execute $memDb $sql]







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







915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
    proc isMemoryDb { fileName } {
      #
      # NOTE: Is the specified database file name really an in-memory database?
      #
      return [expr {$fileName eq ":memory:" || \
          [string range $fileName 0 12] eq "file::memory:"}]
    }

    proc isTableInDb { name {varName db} } {
      #
      # NOTE: Refer to the specified variable (e.g. "db") in the context of our
      #       caller.  It contains the database connection handle that will be
      #       used to execute the query used to determine if the named table is
      #       present in that database.
      #
      upvar 1 $varName db

      #
      # NOTE: Execute the SQL query against the sqlite_master table to check if
      #       the named table is present and return non-zero if it is.
      #
      return [expr {[sql execute -execute scalar $db \
          "SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = ?;" \
          [list param1 String $name]] > 0}]
    }

    proc executeSql { sql {execute none} {fileName ""} } {
      if {[string length $fileName] == 0} then {set fileName :memory:}
      setupDb $fileName "" "" "" "" "" false false false false memDb

      try {
        return [sql execute -execute $execute $memDb $sql]

Added Tests/tkt-f8dbab8baf.eagle.































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
###############################################################################
#
# tkt-f8dbab8baf.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require Eagle.Library
package require Eagle.Test

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

runTest {test tkt-f8dbab8baf-1.1 {SchemaOnly with CREATE TABLE} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.1.db]
} -body {
  sql execute -execute reader -format none -behavior SchemaOnly $db \
      "CREATE TABLE t1(x);"

  isTableInDb t1
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{False}}

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

runTest {test tkt-f8dbab8baf-1.2 {SchemaOnly with ALTER TABLE} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.2.db]
} -body {
  sql execute $db "CREATE TABLE t1(x);"

  sql execute -execute reader -format none -behavior SchemaOnly $db \
      "ALTER TABLE t1 RENAME TO t2;"

  list [isTableInDb t1] [isTableInDb t2]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{True False}}

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

runTest {test tkt-f8dbab8baf-1.3 {SchemaOnly with DROP TABLE} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.3.db]
} -body {
  sql execute $db "CREATE TABLE t1(x);"

  sql execute -execute reader -format none -behavior SchemaOnly $db \
      "DROP TABLE t1;"

  isTableInDb t1
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{True}}

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

runTest {test tkt-f8dbab8baf-1.4 {CREATE/SELECT success} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.4.db]
} -body {
  sql execute -execute reader $db {
    CREATE TABLE t1(x);
    INSERT INTO t1 (x) VALUEs(1);
    SELECT x FROM t1;
  }

  list [isTableInDb t1] \
      [expr {[info exists rows(count)] ? $rows(count) : -1}] \
      [expr {[info exists rows(names)] ? $rows(names) : ""}]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain rows db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{True 1 x}}

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

runTest {test tkt-f8dbab8baf-1.5 {SchemaOnly CREATE/SELECT success} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.5.db]
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUEs(1);"
  sql execute -execute reader -behavior SchemaOnly $db "SELECT x FROM t1;"

  list [isTableInDb t1] \
      [expr {[info exists rows(count)] ? $rows(count) : -1}] \
      [expr {[info exists rows(names)] ? $rows(names) : ""}]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain rows db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{True 0 x}}

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

runTest {test tkt-f8dbab8baf-1.6 {SchemaOnly CREATE/SELECT failure} -setup {
  setupDb [set fileName tkt-f8dbab8baf-1.6.db]
} -body {
  sql execute -execute reader -format none -behavior SchemaOnly $db \
      "CREATE TABLE t1(x); SELECT x FROM t1;"

  list [isTableInDb t1] \
      [expr {[info exists rows(count)] ? $rows(count) : -1}] \
      [expr {[info exists rows(names)] ? $rows(names) : ""}]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain rows db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-returnCodes 1 -match regexp -result [string map [list \n \r\n] \
{^System\.Data\.SQLite\.SQLiteException \(0x80004005\): SQL logic error or\
missing database
no such table: t1.*$}]}

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

runSQLiteTestEpilogue
runTestEpilogue

Changes to readme.htm.

193
194
195
196
197
198
199

200
201
202
203
204
205
206
    <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.8.1</a>.</li>
    <li>Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for [3113734605].</li>
    <li>Check the result of sqlite3_column_name function against NULL.</li>
    <li>Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.</li>
    <li>Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Fix for [aba4549801].</li>
    <li>Add SQLiteCommand.Execute, SQLiteCommand.ExecuteNonQuery, and SQLiteCommand.ExecuteScalar method overloads that take a CommandBehavior parameter.</li>
    <li>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></li>

    <li>Include the XML documentation files in the NuGet packages. Fix for [5970d5b0a6].</li>
</ul>
<p>
    <b>1.0.88.0 - August 7, 2013</b>
</p>
<ul>
    <li>Various fixes to managed virtual table integration infrastructure.</li>







>







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
    <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.8.1</a>.</li>
    <li>Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for [3113734605].</li>
    <li>Check the result of sqlite3_column_name function against NULL.</li>
    <li>Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.</li>
    <li>Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Fix for [aba4549801].</li>
    <li>Add SQLiteCommand.Execute, SQLiteCommand.ExecuteNonQuery, and SQLiteCommand.ExecuteScalar method overloads that take a CommandBehavior parameter.</li>
    <li>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Make sure the database cannot be changed by a query when the CommandBehavior.SchemaOnly flag is used. Fix for [f8dbab8baf].&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Include the XML documentation files in the NuGet packages. Fix for [5970d5b0a6].</li>
</ul>
<p>
    <b>1.0.88.0 - August 7, 2013</b>
</p>
<ul>
    <li>Various fixes to managed virtual table integration infrastructure.</li>

Changes to www/news.wiki.

9
10
11
12
13
14
15

16
17
18
19
20
21
22
    <li>Updated to [http://www.sqlite.org/src/info/trunk|SQLite 3.8.1].</li>
    <li>Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for [3113734605].</li>
    <li>Check the result of sqlite3_column_name function against NULL.</li>
    <li>Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.</li>
    <li>Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Fix for [aba4549801].</li>
    <li>Add SQLiteCommand.Execute, SQLiteCommand.ExecuteNonQuery, and SQLiteCommand.ExecuteScalar method overloads that take a CommandBehavior parameter.</li>
    <li>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></li>

    <li>Include the XML documentation files in the NuGet packages. Fix for [5970d5b0a6].</li>
</ul>
<p>
    <b>1.0.88.0 - August 7, 2013</b>
</p>
<ul>
    <li>Various fixes to managed virtual table integration infrastructure.</li>







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    <li>Updated to [http://www.sqlite.org/src/info/trunk|SQLite 3.8.1].</li>
    <li>Use declared column sizes for the AnsiStringFixedLength and StringFixedLength mapped database types. Fix for [3113734605].</li>
    <li>Check the result of sqlite3_column_name function against NULL.</li>
    <li>Return false for the SQLiteParameterCollection.IsSynchronized property because it is not thread-safe.</li>
    <li>Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Fix for [aba4549801].</li>
    <li>Add SQLiteCommand.Execute, SQLiteCommand.ExecuteNonQuery, and SQLiteCommand.ExecuteScalar method overloads that take a CommandBehavior parameter.</li>
    <li>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Make sure the database cannot be changed by a query when the CommandBehavior.SchemaOnly flag is used. Fix for [f8dbab8baf].&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Include the XML documentation files in the NuGet packages. Fix for [5970d5b0a6].</li>
</ul>
<p>
    <b>1.0.88.0 - August 7, 2013</b>
</p>
<ul>
    <li>Various fixes to managed virtual table integration infrastructure.</li>