System.Data.SQLite

Check-in [7e2f11fd49]
Login

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

Overview
Comment:Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Fix for [aba4549801]. Update Eagle in externals to pickup fixes necessary for testing.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7e2f11fd499f463e4cfcf6b49e43c567c561f5fa
User & Date: mistachkin 2013-09-06 04:29:42.286
Context
2013-09-06
18:39
Include the XML documentation files in the NuGet packages. Fix for [5970d5b0a6]. check-in: a1eddcc027 user: mistachkin tags: trunk
04:29
Raise the static SQLiteConnection.Changed event when any SQLiteCommand, SQLiteDataReader, or CriticalHandle derived object instance is created. Fix for [aba4549801]. Update Eagle in externals to pickup fixes necessary for testing. check-in: 7e2f11fd49 user: mistachkin tags: trunk
2013-09-05
05:26
Move the statement list disposal code in the SQLiteCommand class into its own method. check-in: f629afe04c user: mistachkin tags: trunk
2013-09-04
04:31
Update version history docs. Closed-Leaf check-in: 2843f57cae user: mistachkin tags: onChanged
Changes
Unified Diff Ignore Whitespace Patch
Changes to Doc/Extra/version.html.
45
46
47
48
49
50
51


52
53
54
55
56
57
58
    <h1 class="heading">Version History</h1>
    <p><b>1.0.89.0 - September XX, 2013 <font color="red">(release scheduled)</font></b></p>
    <ul>
      <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>


    </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>
      <li>When automatically registering custom functions, use the executing assembly (i.e. System.Data.SQLite) for reference detection. Fix for <a href="http://system.data.sqlite.org/index.html/info/4e49a58c4c">[4e49a58c4c]</a>.</li>







>
>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    <h1 class="heading">Version History</h1>
    <p><b>1.0.89.0 - September XX, 2013 <font color="red">(release scheduled)</font></b></p>
    <ul>
      <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>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></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>
      <li>When automatically registering custom functions, use the executing assembly (i.e. System.Data.SQLite) for reference detection. Fix for <a href="http://system.data.sqlite.org/index.html/info/4e49a58c4c">[4e49a58c4c]</a>.</li>
Changes to Externals/Eagle/bin/Eagle.dll.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/EagleShell.exe.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/EagleShell.exe.mda.config.
64
65
66
67
68
69
70

71
72
73
74
75
76
77
        <match dllName="advapi32.dll" />
        <match dllName="advpack.dll" />
        <match dllName="kernel32.dll" />
        <match dllName="mscoree.dll" />
        <match dllName="msvcrt.dll" />
        <match dllName="ntdll.dll" />
        <match dllName="shell32.dll" />

        <match dllName="user32.dll" />
        <match dllName="wintrust.dll" />
      </filter>
    </pInvokeLog>
    <pInvokeStackImbalance />
    <raceOnRCWCleanup />
    <reentrancy />







>







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
        <match dllName="advapi32.dll" />
        <match dllName="advpack.dll" />
        <match dllName="kernel32.dll" />
        <match dllName="mscoree.dll" />
        <match dllName="msvcrt.dll" />
        <match dllName="ntdll.dll" />
        <match dllName="shell32.dll" />
        <match dllName="spilornis.dll" />
        <match dllName="user32.dll" />
        <match dllName="wintrust.dll" />
      </filter>
    </pInvokeLog>
    <pInvokeStackImbalance />
    <raceOnRCWCleanup />
    <reentrancy />
Changes to Externals/Eagle/lib/Eagle1.0/test.eagle.
2199
2200
2201
2202
2203
2204
2205






2206
2207
2208
2209
2210
2211
2212
2213

2214
2215
2216
2217
2218
2219
2220
2221
        # NOTE: If there is no effective test configuration available, we
        #       cannot continue.
        #
        if {[string length $configuration] == 0} then {
          return ""
        }







        #
        # NOTE: Build the full path and file name of the Garuda DLL, using
        #       the Eagle base path.  Currently, this will only work
        #       correctly if the test suite is being run from inside the
        #       source tree.
        #
        return [file join $::base_path bin \
            [machineToPlatform [getMachineForTclShell]] [appendArgs \

            $configuration Dll] [appendArgs Garuda [info sharedlibextension]]]
      } else {
        #
        # NOTE: We are missing the base path, return nothing.
        #
        return ""
      }
    }







>
>
>
>
>
>








>
|







2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
        # NOTE: If there is no effective test configuration available, we
        #       cannot continue.
        #
        if {[string length $configuration] == 0} then {
          return ""
        }

        #
        # NOTE: Get the effective test suffix.  This is allowed to be an
        #       empty string.
        #
        set suffix [getTestSuffix]

        #
        # NOTE: Build the full path and file name of the Garuda DLL, using
        #       the Eagle base path.  Currently, this will only work
        #       correctly if the test suite is being run from inside the
        #       source tree.
        #
        return [file join $::base_path bin \
            [machineToPlatform [getMachineForTclShell]] [appendArgs \
            $configuration Dll $suffix] [appendArgs Garuda [info \
            sharedlibextension]]]
      } else {
        #
        # NOTE: We are missing the base path, return nothing.
        #
        return ""
      }
    }
Changes to Externals/Eagle/lib/Test1.0/prologue.eagle.
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
      #
      if {![info exists no(testProperties)]} then {
        #
        # NOTE: For tests "basic-1.39", "basic-1.40", "basic-1.41",
        #       "basic-1.42", and "basic-1.43".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *get_SimpleProperty*

        #
        # NOTE: For test "object-3.1".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *get_Item*








|







1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
      #
      if {![info exists no(testProperties)]} then {
        #
        # NOTE: For tests "basic-1.39", "basic-1.40", "basic-1.41",
        #       "basic-1.42", and "basic-1.43".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *get_SimpleIntProperty*

        #
        # NOTE: For test "object-3.1".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *get_Item*

Changes to System.Data.SQLite/SQLite3.cs.
122
123
124
125
126
127
128





129
130
131
132
133
134
135
        )
      : base(fmt, kind, fmtString)
    {
        if (db != IntPtr.Zero)
        {
            _sql = new SQLiteConnectionHandle(db, ownHandle);
            _fileName = fileName;





        }
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;







>
>
>
>
>







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
        )
      : base(fmt, kind, fmtString)
    {
        if (db != IntPtr.Zero)
        {
            _sql = new SQLiteConnectionHandle(db, ownHandle);
            _fileName = fileName;

            SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
                SQLiteConnectionEventType.NewCriticalHandle, null, null,
                null, null, _sql, fileName, new object[] { fmt, kind,
                fmtString, db, fileName, ownHandle }));
        }
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
533
534
535
536
537
538
539





540
541
542
543
544
545
546
          Trace.WriteLine(String.Format("Open: {0}", db));
#endif

          if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
          _sql = new SQLiteConnectionHandle(db, true);
        }
        lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ }





      }

      // Bind functions to this connection.  If any previous functions of the same name
      // were already bound, then the new bindings replace the old.
      if ((connectionFlags & SQLiteConnectionFlags.NoBindFunctions) != SQLiteConnectionFlags.NoBindFunctions)
      {
          if (_functions == null)







>
>
>
>
>







538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
          Trace.WriteLine(String.Format("Open: {0}", db));
#endif

          if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
          _sql = new SQLiteConnectionHandle(db, true);
        }
        lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ }

        SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
            SQLiteConnectionEventType.NewCriticalHandle, null, null,
            null, null, _sql, strFilename, new object[] { strFilename,
            connectionFlags, openFlags, maxPoolSize, usePool }));
      }

      // Bind functions to this connection.  If any previous functions of the same name
      // were already bound, then the new bindings replace the old.
      if ((connectionFlags & SQLiteConnectionFlags.NoBindFunctions) != SQLiteConnectionFlags.NoBindFunctions)
      {
          if (_functions == null)
570
571
572
573
574
575
576


577
578
579
580
581
582
583
584
            ref totalCount);

        return totalCount;
    }

    internal override void SetTimeout(int nTimeoutMS)
    {


      SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_busy_timeout(_sql, nTimeoutMS);
      if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
    }

    internal override bool Step(SQLiteStatement stmt)
    {
      SQLiteErrorCode n;
      Random rnd = null;







>
>
|







580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
            ref totalCount);

        return totalCount;
    }

    internal override void SetTimeout(int nTimeoutMS)
    {
      IntPtr db = _sql;
      if (db == IntPtr.Zero) throw new SQLiteException("no connection handle available");
      SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_busy_timeout(db, nTimeoutMS);
      if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
    }

    internal override bool Step(SQLiteStatement stmt)
    {
      SQLiteErrorCode n;
      Random rnd = null;
739
740
741
742
743
744
745


746









747
748
749
750
751
752
753
#endif

#if !NET_COMPACT_20 && TRACE_STATEMENT
            Trace.WriteLine(String.Format("Prepare ({0}): {1}", n, stmt));
#endif

            if ((n == SQLiteErrorCode.Ok) && (stmt != IntPtr.Zero))


              statementHandle = new SQLiteStatementHandle(_sql, stmt);









          }

          if (n == SQLiteErrorCode.Schema)
            retries++;
          else if (n == SQLiteErrorCode.Error)
          {
            if (String.Compare(GetLastError(), "near \"TYPES\": syntax error", StringComparison.OrdinalIgnoreCase) == 0)







>
>

>
>
>
>
>
>
>
>
>







751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
#endif

#if !NET_COMPACT_20 && TRACE_STATEMENT
            Trace.WriteLine(String.Format("Prepare ({0}): {1}", n, stmt));
#endif

            if ((n == SQLiteErrorCode.Ok) && (stmt != IntPtr.Zero))
            {
              if (statementHandle != null) statementHandle.Dispose();
              statementHandle = new SQLiteStatementHandle(_sql, stmt);
            }
          }

          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.Schema)
            retries++;
          else if (n == SQLiteErrorCode.Error)
          {
            if (String.Compare(GetLastError(), "near \"TYPES\": syntax error", StringComparison.OrdinalIgnoreCase) == 0)
2103
2104
2105
2106
2107
2108
2109





2110
2111
2112
2113
2114
2115
2116
                    throw new SQLiteException(resultCode, GetLastError());
                else
                    throw new SQLiteException("failed to initialize backup");
            }

            backupHandle = new SQLiteBackupHandle(destHandle, backup);
        }






        return new SQLiteBackup(
            this, backupHandle, destHandle, zDestName, sourceHandle,
            zSourceName);
    }

    /// <summary>







>
>
>
>
>







2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
                    throw new SQLiteException(resultCode, GetLastError());
                else
                    throw new SQLiteException("failed to initialize backup");
            }

            backupHandle = new SQLiteBackupHandle(destHandle, backup);
        }

        SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
            SQLiteConnectionEventType.NewCriticalHandle, null, null,
            null, null, backupHandle, null, new object[] { destCnn,
            destName, sourceName }));

        return new SQLiteBackup(
            this, backupHandle, destHandle, zDestName, sourceHandle,
            zSourceName);
    }

    /// <summary>
Changes to System.Data.SQLite/SQLite3_UTF16.cs.
192
193
194
195
196
197
198





199
200
201
202
203
204
205
          Trace.WriteLine(String.Format("Open16: {0}", db));
#endif

          if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
          _sql = new SQLiteConnectionHandle(db, true);
        }
        lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ }





      }

      // Bind functions to this connection.  If any previous functions of the same name
      // were already bound, then the new bindings replace the old.
      if ((connectionFlags & SQLiteConnectionFlags.NoBindFunctions) != SQLiteConnectionFlags.NoBindFunctions)
      {
          if (_functions == null)







>
>
>
>
>







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
          Trace.WriteLine(String.Format("Open16: {0}", db));
#endif

          if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
          _sql = new SQLiteConnectionHandle(db, true);
        }
        lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ }

        SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
            SQLiteConnectionEventType.NewCriticalHandle, null, null,
            null, null, _sql, strFilename, new object[] { strFilename,
            connectionFlags, openFlags, maxPoolSize, usePool }));
      }

      // Bind functions to this connection.  If any previous functions of the same name
      // were already bound, then the new bindings replace the old.
      if ((connectionFlags & SQLiteConnectionFlags.NoBindFunctions) != SQLiteConnectionFlags.NoBindFunctions)
      {
          if (_functions == null)
Changes to System.Data.SQLite/SQLiteCommand.cs.
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
        _commandTimeout = connection.DefaultTimeout;
      }

      if (transaction != null)
        Transaction = transaction;

      SQLiteConnection.OnChanged(connection, new ConnectionEventArgs(
          SQLiteConnectionEventType.NewCommand, null, transaction, this, null, null));

    }

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

    [Conditional("CHECK_STATE")]
    internal static void Check(SQLiteCommand command)
    {







|
>







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
        _commandTimeout = connection.DefaultTimeout;
      }

      if (transaction != null)
        Transaction = transaction;

      SQLiteConnection.OnChanged(connection, new ConnectionEventArgs(
          SQLiteConnectionEventType.NewCommand, null, transaction, this,
          null, null, null, null));
    }

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

    [Conditional("CHECK_STATE")]
    internal static void Check(SQLiteCommand command)
    {
Changes to System.Data.SQLite/SQLiteConnection.cs.
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
      public readonly IDbTransaction Transaction;

      /// <summary>
      /// The command associated with this event, if any.
      /// </summary>
      public readonly IDbCommand Command;











      /// <summary>
      /// Command or message text associated with this event, if any.
      /// </summary>
      public readonly string Text;

      /// <summary>
      /// Extra data associated with this event, if any.
      /// </summary>
      public readonly object Data;

      /// <summary>
      /// Constructs the object.
      /// </summary>
      /// <param name="eventType">The type of event being raised.</param>
      /// <param name="eventArgs">The base <see cref="EventArgs" /> associated
      /// with this event, if any.</param>
      /// <param name="transaction">The transaction associated with this event, if any.</param>
      /// <param name="command">The command associated with this event, if any.</param>


      /// <param name="text">The command or message text, if any.</param>
      /// <param name="data">The extra data, if any.</param>
      internal ConnectionEventArgs(
          SQLiteConnectionEventType eventType,
          StateChangeEventArgs eventArgs,
          IDbTransaction transaction,
          IDbCommand command,


          string text,
          object data
          )
      {
          EventType = eventType;
          EventArgs = eventArgs;
          Transaction = transaction;
          Command = command;


          Text = text;
          Data = data;
      }
  }

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








>
>
>
>
>
>
>
>
>
>


















>
>







>
>








>
>







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
      public readonly IDbTransaction Transaction;

      /// <summary>
      /// The command associated with this event, if any.
      /// </summary>
      public readonly IDbCommand Command;

      /// <summary>
      /// The data reader associated with this event, if any.
      /// </summary>
      public readonly IDataReader DataReader;

      /// <summary>
      /// The critical handle associated with this event, if any.
      /// </summary>
      public readonly CriticalHandle CriticalHandle;

      /// <summary>
      /// Command or message text associated with this event, if any.
      /// </summary>
      public readonly string Text;

      /// <summary>
      /// Extra data associated with this event, if any.
      /// </summary>
      public readonly object Data;

      /// <summary>
      /// Constructs the object.
      /// </summary>
      /// <param name="eventType">The type of event being raised.</param>
      /// <param name="eventArgs">The base <see cref="EventArgs" /> associated
      /// with this event, if any.</param>
      /// <param name="transaction">The transaction associated with this event, if any.</param>
      /// <param name="command">The command associated with this event, if any.</param>
      /// <param name="dataReader">The data reader associated with this event, if any.</param>
      /// <param name="criticalHandle">The critical handle associated with this event, if any.</param>
      /// <param name="text">The command or message text, if any.</param>
      /// <param name="data">The extra data, if any.</param>
      internal ConnectionEventArgs(
          SQLiteConnectionEventType eventType,
          StateChangeEventArgs eventArgs,
          IDbTransaction transaction,
          IDbCommand command,
          IDataReader dataReader,
          CriticalHandle criticalHandle,
          string text,
          object data
          )
      {
          EventType = eventType;
          EventArgs = eventArgs;
          Transaction = transaction;
          Command = command;
          DataReader = dataReader;
          CriticalHandle = criticalHandle;
          Text = text;
          Data = data;
      }
  }

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

487
488
489
490
491
492
493


494
495
496
497
498
499
500
        : this(connectionString, false)
    {
        // do nothing.
    }

    /// <summary>
    /// Initializes the connection with a pre-existing native connection handle.


    /// </summary>
    /// <param name="db">
    /// The native connection handle to use.
    /// </param>
    /// <param name="fileName">
    /// The file name corresponding to the native connection handle.
    /// </param>







>
>







503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
        : this(connectionString, false)
    {
        // do nothing.
    }

    /// <summary>
    /// Initializes the connection with a pre-existing native connection handle.
    /// This constructor overload is intended to be used only by the private
    /// <see cref="SQLiteModule.CreateOrConnect" /> method.
    /// </summary>
    /// <param name="db">
    /// The native connection handle to use.
    /// </param>
    /// <param name="fileName">
    /// The file name corresponding to the native connection handle.
    /// </param>
613
614
615
616
617
618
619
620


621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641

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

    /// <summary>
    /// Raises the <see cref="Changed" /> event.
    /// </summary>
    /// <param name="connection">
    /// The connection associated with this event.


    /// </param>
    /// <param name="e">
    /// A <see cref="ConnectionEventArgs" /> that contains the event data.
    /// </param>
    internal static void OnChanged(
        SQLiteConnection connection,
        ConnectionEventArgs e
        )
    {
        if (connection == null)
            return;

#if !PLATFORM_COMPACTFRAMEWORK
        if (!connection.CanRaiseEvents)
            return;
#endif

        SQLiteConnectionEventHandler handlers;

        lock (_syncRoot)
        {







|
>
>









<
<
<

|







631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649



650
651
652
653
654
655
656
657
658

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

    /// <summary>
    /// Raises the <see cref="Changed" /> event.
    /// </summary>
    /// <param name="connection">
    /// The connection associated with this event.  If this parameter is not
    /// null and the specified connection cannot raise events, then the
    /// registered event handlers will not be invoked.
    /// </param>
    /// <param name="e">
    /// A <see cref="ConnectionEventArgs" /> that contains the event data.
    /// </param>
    internal static void OnChanged(
        SQLiteConnection connection,
        ConnectionEventArgs e
        )
    {



#if !PLATFORM_COMPACTFRAMEWORK
        if ((connection != null) && !connection.CanRaiseEvents)
            return;
#endif

        SQLiteConnectionEventHandler handlers;

        lock (_syncRoot)
        {
708
709
710
711
712
713
714








715
716










717
718
719
720
721
722
723
    /// The new managed database connection handle or null if it cannot be
    /// created.
    /// </returns>
    public static object CreateHandle(
        IntPtr nativeHandle
        )
    {








        if (nativeHandle == IntPtr.Zero) return null;
        return new SQLiteConnectionHandle(nativeHandle, true);










    }

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

    #region Backup API Members
    /// <summary>
    /// Backs up the database, using the specified database connection as the







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







725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
    /// The new managed database connection handle or null if it cannot be
    /// created.
    /// </returns>
    public static object CreateHandle(
        IntPtr nativeHandle
        )
    {
        SQLiteConnectionHandle result;

        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
            result = (nativeHandle != IntPtr.Zero) ?
                new SQLiteConnectionHandle(nativeHandle, true) : null;
        }

        if (result != null)
        {
            SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
                SQLiteConnectionEventType.NewCriticalHandle, null, null,
                null, null, result, null, new object[] { nativeHandle }));
        }

        return result;
    }

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

    #region Backup API Members
    /// <summary>
    /// Backs up the database, using the specified database connection as the
1133
1134
1135
1136
1137
1138
1139
1140

1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155

1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168

1169
1170
1171
1172
1173
1174
1175
      if (isolationLevel != IsolationLevel.Serializable && isolationLevel != IsolationLevel.ReadCommitted)
        throw new ArgumentException("isolationLevel");

      SQLiteTransaction transaction =
          new SQLiteTransaction(this, isolationLevel != IsolationLevel.Serializable);

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.NewTransaction, null, transaction, null, null, null));


      return transaction;
    }

    /// <summary>
    /// This method is not implemented; however, the <see cref="Changed" />
    /// event will still be raised.
    /// </summary>
    /// <param name="databaseName"></param>
    public override void ChangeDatabase(string databaseName)
    {
      CheckDisposed();

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.ChangeDatabase, null, null, null, databaseName, null));


      throw new NotImplementedException(); // NOTE: For legacy compatibility.
    }

    /// <summary>
    /// When the database connection is closed, all commands linked to this connection are automatically reset.
    /// </summary>
    public override void Close()
    {
      CheckDisposed();

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.Closing, null, null, null, null, null));


      if (_sql != null)
      {
#if !PLATFORM_COMPACTFRAMEWORK
        if (_enlistment != null)
        {
          // If the connection is enlisted in a transaction scope and the scope is still active,







|
>














|
>












|
>







1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
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
1213
      if (isolationLevel != IsolationLevel.Serializable && isolationLevel != IsolationLevel.ReadCommitted)
        throw new ArgumentException("isolationLevel");

      SQLiteTransaction transaction =
          new SQLiteTransaction(this, isolationLevel != IsolationLevel.Serializable);

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.NewTransaction, null, transaction,
          null, null, null, null, null));

      return transaction;
    }

    /// <summary>
    /// This method is not implemented; however, the <see cref="Changed" />
    /// event will still be raised.
    /// </summary>
    /// <param name="databaseName"></param>
    public override void ChangeDatabase(string databaseName)
    {
      CheckDisposed();

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.ChangeDatabase, null, null, null, null,
          null, databaseName, null));

      throw new NotImplementedException(); // NOTE: For legacy compatibility.
    }

    /// <summary>
    /// When the database connection is closed, all commands linked to this connection are automatically reset.
    /// </summary>
    public override void Close()
    {
      CheckDisposed();

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.Closing, null, null, null, null, null,
          null, null));

      if (_sql != null)
      {
#if !PLATFORM_COMPACTFRAMEWORK
        if (_enlistment != null)
        {
          // If the connection is enlisted in a transaction scope and the scope is still active,
1197
1198
1199
1200
1201
1202
1203
1204

1205
1206
1207
1208
1209
1210
1211
        _transactionLevel = 0;
      }

      StateChangeEventArgs eventArgs = null;
      OnStateChange(ConnectionState.Closed, ref eventArgs);

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.Closed, eventArgs, null, null, null, null));

    }

    /// <summary>
    /// Returns the number of pool entries for the file name associated with this connection.
    /// </summary>
    public int PoolCount
    {







|
>







1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
        _transactionLevel = 0;
      }

      StateChangeEventArgs eventArgs = null;
      OnStateChange(ConnectionState.Closed, ref eventArgs);

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.Closed, eventArgs, null, null, null,
          null, null, null));
    }

    /// <summary>
    /// Returns the number of pool entries for the file name associated with this connection.
    /// </summary>
    public int PoolCount
    {
1659
1660
1661
1662
1663
1664
1665
1666

1667
1668
1669
1670
1671
1672
1673
        throw new ArgumentException("Unable to enlist in transaction, a local transaction already exists");
      else if (transaction == null)
        throw new ArgumentNullException("Unable to enlist in transaction, it is null");

      _enlistment = new SQLiteEnlistment(this, transaction);

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.EnlistTransaction, null, null, null, null, _enlistment));

    }
#endif

    /// <summary>
    /// Looks for a key in the array of key/values of the parameter string.  If not found, return the specified default value
    /// </summary>
    /// <param name="items">The list to look in</param>







|
>







1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
        throw new ArgumentException("Unable to enlist in transaction, a local transaction already exists");
      else if (transaction == null)
        throw new ArgumentNullException("Unable to enlist in transaction, it is null");

      _enlistment = new SQLiteEnlistment(this, transaction);

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.EnlistTransaction, null, null, null, null,
          null, null, new object[] { _enlistment }));
    }
#endif

    /// <summary>
    /// Looks for a key in the array of key/values of the parameter string.  If not found, return the specified default value
    /// </summary>
    /// <param name="items">The list to look in</param>
1948
1949
1950
1951
1952
1953
1954
1955

1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966

1967
1968
1969
1970
1971
1972
1973
    /// Opens the connection using the parameters found in the <see cref="ConnectionString" />.
    /// </summary>
    public override void Open()
    {
      CheckDisposed();

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.Opening, null, null, null, null, null));


      if (_connectionState != ConnectionState.Closed)
        throw new InvalidOperationException();

      Close();

      SortedList<string, string> opts = ParseConnectionString(
          _connectionString, _parseViaFramework);

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.ConnectionString, null, null, null, _connectionString, opts));


      object enumValue;

      enumValue = TryParseEnum(typeof(SQLiteConnectionFlags), FindKey(opts, "Flags", DefaultFlags.ToString()), true);
      _flags = (enumValue is SQLiteConnectionFlags) ? (SQLiteConnectionFlags)enumValue : DefaultFlags;

      bool fullUri = false;







|
>










|
>







1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
    /// Opens the connection using the parameters found in the <see cref="ConnectionString" />.
    /// </summary>
    public override void Open()
    {
      CheckDisposed();

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.Opening, null, null, null, null, null,
          null, null));

      if (_connectionState != ConnectionState.Closed)
        throw new InvalidOperationException();

      Close();

      SortedList<string, string> opts = ParseConnectionString(
          _connectionString, _parseViaFramework);

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.ConnectionString, null, null, null, null,
          null, _connectionString, new object[] { opts }));

      object enumValue;

      enumValue = TryParseEnum(typeof(SQLiteConnectionFlags), FindKey(opts, "Flags", DefaultFlags.ToString()), true);
      _flags = (enumValue is SQLiteConnectionFlags) ? (SQLiteConnectionFlags)enumValue : DefaultFlags;

      bool fullUri = false;
2189
2190
2191
2192
2193
2194
2195
2196

2197
2198
2199
2200
2201
2202
2203

          _connectionState = oldstate;

          StateChangeEventArgs eventArgs = null;
          OnStateChange(ConnectionState.Open, ref eventArgs);

          OnChanged(this, new ConnectionEventArgs(
              SQLiteConnectionEventType.Opened, eventArgs, null, null, null, null));

        }
        catch
        {
          _connectionState = oldstate;
          throw;
        }
      }







|
>







2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246

          _connectionState = oldstate;

          StateChangeEventArgs eventArgs = null;
          OnStateChange(ConnectionState.Open, ref eventArgs);

          OnChanged(this, new ConnectionEventArgs(
              SQLiteConnectionEventType.Opened, eventArgs, null, null, null,
              null, null, null));
        }
        catch
        {
          _connectionState = oldstate;
          throw;
        }
      }
Changes to System.Data.SQLite/SQLiteConvert.cs.
1294
1295
1296
1297
1298
1299
1300











1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317

1318

1319
1320





1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
      EnlistTransaction = 6,

      /// <summary>
      /// A command was created using the connection.
      /// </summary>
      NewCommand = 7,












      /// <summary>
      /// The connection is being closed.
      /// </summary>
      Closing = 8,

      /// <summary>
      /// The connection was closed.
      /// </summary>
      Closed = 9
  }

  /// <summary>
  /// This implementation of SQLite for ADO.NET can process date/time fields in databases in only one of three formats.  Ticks, ISO8601
  /// and JulianDay.
  /// </summary>
  /// <remarks>
  /// ISO8601 is more compatible, readable, fully-processable, but less accurate as it doesn't provide time down to fractions of a second.

  /// JulianDay is the numeric format the SQLite uses internally and is arguably the most compatible with 3rd party tools.  It is

  /// not readable as text without post-processing.
  /// Ticks less compatible with 3rd party tools that query the database, and renders the DateTime field unreadable as text without post-processing.





  ///
  /// The preferred order of choosing a datetime format is JulianDay, ISO8601, and then Ticks.  Ticks is mainly present for legacy
  /// code support.
  /// </remarks>
  public enum SQLiteDateFormats
  {
    /// <summary>
    /// Use the value of DateTime.Ticks.  This value is not recommended and is not well supported with LINQ.
    /// </summary>
    Ticks = 0,







>
>
>
>
>
>
>
>
>
>
>



|




|



|
|


|
>
|
>
|
|
>
>
>
>
>

|
|







1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
      EnlistTransaction = 6,

      /// <summary>
      /// A command was created using the connection.
      /// </summary>
      NewCommand = 7,

      /// <summary>
      /// A data reader was created using the connection.
      /// </summary>
      NewDataReader = 8,

      /// <summary>
      /// An instance of a <see cref="CriticalHandle" /> derived class has
      /// been created to wrap a native resource.
      /// </summary>
      NewCriticalHandle = 9,

      /// <summary>
      /// The connection is being closed.
      /// </summary>
      Closing = 10,

      /// <summary>
      /// The connection was closed.
      /// </summary>
      Closed = 11
  }

  /// <summary>
  /// This implementation of SQLite for ADO.NET can process date/time fields in
  /// databases in one of six formats.
  /// </summary>
  /// <remarks>
  /// ISO8601 format is more compatible, readable, fully-processable, but less
  /// accurate as it does not provide time down to fractions of a second.
  /// JulianDay is the numeric format the SQLite uses internally and is arguably
  /// the most compatible with 3rd party tools.  It is not readable as text
  /// without post-processing.  Ticks less compatible with 3rd party tools that
  /// query the database, and renders the DateTime field unreadable as text
  /// without post-processing.  UnixEpoch is more compatible with Unix systems.
  /// InvariantCulture allows the configured format for the invariant culture
  /// format to be used and is human readable.  CurrentCulture allows the
  /// configured format for the current culture to be used and is also human
  /// readable.
  ///
  /// The preferred order of choosing a DateTime format is JulianDay, ISO8601,
  /// and then Ticks.  Ticks is mainly present for legacy code support.
  /// </remarks>
  public enum SQLiteDateFormats
  {
    /// <summary>
    /// Use the value of DateTime.Ticks.  This value is not recommended and is not well supported with LINQ.
    /// </summary>
    Ticks = 0,
Changes to System.Data.SQLite/SQLiteDataReader.cs.
101
102
103
104
105
106
107





108

109
110
111
112
113
114
115
      _baseSchemaName = _command.Connection._baseSchemaName;

      _commandBehavior = behave;
      _activeStatementIndex = -1;
      _rowsAffected = -1;

      if (_command != null)





        NextResult();

    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */







>
>
>
>
>
|
>







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
      _baseSchemaName = _command.Connection._baseSchemaName;

      _commandBehavior = behave;
      _activeStatementIndex = -1;
      _rowsAffected = -1;

      if (_command != null)
      {
          SQLiteConnection.OnChanged(_command.Connection,
              new ConnectionEventArgs(SQLiteConnectionEventType.NewDataReader,
              null, null, _command, this, null, null, new object[] { behave }));

          NextResult();
      }
    }

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

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
Added Tests/tkt-aba4549801.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
###############################################################################
#
# tkt-aba4549801.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-aba4549801-1.1 {SQLiteConnection.Changed event} -setup {
  proc onChanged { sender e } {
    set list [list $sender]

    if {[string length $e] > 0} then {
      lappend list [$e EventType]
      lappend list [set o1 [$e -objectflags NoDispose Transaction]]
      lappend list [set o2 [$e -objectflags NoDispose Command]]
      lappend list [set o3 [$e -objectflags NoDispose DataReader]]
      lappend list [set o4 [$e -objectflags NoDispose CriticalHandle]]
    }

    lappend ::result $list
  }

  set callback onChanged
  object invoke System.Data.SQLite.SQLiteConnection add_Changed $callback

  setupDb [set fileName tkt-aba4549801-1.1.db]
} -body {
  sql execute $db "CREATE TABLE t1(x);"

  set transaction [sql transaction begin $db]

  sql execute -execute reader $db \
      "INSERT INTO t1(x) VALUES(1); SELECT x FROM t1;"

  sql transaction commit $transaction

  cleanupDb $fileName
  collectGarbage $test_channel

  set result
} -cleanup {
  object invoke System.Data.SQLite.SQLiteConnection remove_Changed $callback
  catch {object removecallback $callback}

  unset -nocomplain rows transaction result callback db fileName

  rename onChanged ""
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^\{System#Data#SQLite#SQLiteConnection#\d+ Opening \{\} \{\}\
\{\} \{\}\} \{System#Data#SQLite#SQLiteConnection#\d+ Closing \{\} \{\} \{\}\
\{\}\} \{System#Data#SQLite#SQLiteConnection#\d+ Closed \{\} \{\} \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ ConnectionString \{\} \{\} \{\}\
\{\}\} \{System#Object#\d+ NewCriticalHandle \{\} \{\} \{\}\
System#Data#SQLite#SQLiteConnectionHandle#\d+\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewCommand \{\}\
System#Data#SQLite#SQLiteCommand#\d+ \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ Opened \{\} \{\} \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewCommand \{\}\
System#Data#SQLite#SQLiteCommand#\d+ \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewDataReader \{\}\
System#Data#SQLite#SQLiteCommand#\d+ System#Data#SQLite#SQLiteDataReader#\d+\
\{\}\} \{System#Object#\d+ NewCriticalHandle \{\} \{\} \{\}\
System#Data#SQLite#SQLiteStatementHandle#\d+\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewCommand \{\}\
System#Data#SQLite#SQLiteCommand#\d+ \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewDataReader \{\}\
System#Data#SQLite#SQLiteCommand#\d+ System#Data#SQLite#SQLiteDataReader#\d+\
\{\}\} \{System#Object#\d+ NewCriticalHandle \{\} \{\} \{\}\
System#Data#SQLite#SQLiteStatementHandle#\d+\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewCommand \{\}\
System#Data#SQLite#SQLiteCommand#\d+ \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewDataReader \{\}\
System#Data#SQLite#SQLiteCommand#\d+ System#Data#SQLite#SQLiteDataReader#\d+\
\{\}\} \{System#Object#\d+ NewCriticalHandle \{\} \{\} \{\}\
System#Data#SQLite#SQLiteStatementHandle#\d+\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewTransaction\
System#Data#SQLite#SQLiteTransaction#\d+ \{\} \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewCommand \{\}\
System#Data#SQLite#SQLiteCommand#\d+ \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewDataReader \{\}\
System#Data#SQLite#SQLiteCommand#\d+ System#Data#SQLite#SQLiteDataReader#\d+\
\{\}\} \{System#Object#\d+ NewCriticalHandle \{\} \{\} \{\}\
System#Data#SQLite#SQLiteStatementHandle#\d+\} \{System#Object#\d+\
NewCriticalHandle \{\} \{\} \{\} System#Data#SQLite#SQLiteStatementHandle#\d+\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewCommand \{\}\
System#Data#SQLite#SQLiteCommand#\d+ \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ NewDataReader \{\}\
System#Data#SQLite#SQLiteCommand#\d+ System#Data#SQLite#SQLiteDataReader#\d+\
\{\}\} \{System#Object#\d+ NewCriticalHandle \{\} \{\} \{\}\
System#Data#SQLite#SQLiteStatementHandle#\d+\}\
\{System#Data#SQLite#SQLiteConnection#\d+ Closing \{\} \{\} \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ Closed \{\} \{\} \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ Closing \{\} \{\} \{\} \{\}\}\
\{System#Data#SQLite#SQLiteConnection#\d+ Closed \{\} \{\} \{\} \{\}\}$}}

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

runSQLiteTestEpilogue
runTestEpilogue
Changes to readme.htm.
190
191
192
193
194
195
196


197
198
199
200
201
202
203
    <b>1.0.89.0 - September XX, 2013 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <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>


</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 [9ac9862611].</li>







>
>







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
    <b>1.0.89.0 - September XX, 2013 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <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>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></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 [9ac9862611].</li>
Changes to www/news.wiki.
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18
19
<title>News</title>

<b>Version History</b>

<p>
    <b>1.0.89.0 - September XX, 2013 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <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>


</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 [9ac9862611].</li>












>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<title>News</title>

<b>Version History</b>

<p>
    <b>1.0.89.0 - September XX, 2013 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <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>Revise how the extra object data is passed to the static SQLiteConnection.Changed event.&nbsp;<b>** Potentially Incompatible Change **</b></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 [9ac9862611].</li>