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

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

Overview
Comment:Merge updates from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | publishWithNuGetPkg
Files: files | file ages | folders
SHA1: d48e9010a9a6e2c6b3889112304285a4670f9109
User & Date: mistachkin 2014-11-14 00:58:37
Context
2014-11-19
00:45
Make sure the interop files are copied when publishing a project that refers to a NuGet package containing them. Fix for [e796ac82c1]. check-in: ee40baa88e user: mistachkin tags: publishWithNuGetPkg
2014-11-14
00:58
Merge updates from trunk. check-in: d48e9010a9 user: mistachkin tags: publishWithNuGetPkg
00:55
Wrap SELECT statements in parenthesis if they have an ORDER BY, LIMIT, or OFFSET clause and a compound operator is involved. Fix for [0a32885109]. check-in: a0f4a5ebcf user: mistachkin tags: trunk
2014-10-17
23:08
Slightly improve build task naming. check-in: a72d3b55ad user: mistachkin tags: publishWithNuGetPkg
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Doc/Extra/Provider/version.html.

    41     41         </table>
    42     42       </div>
    43     43       <div id="mainSection">
    44     44       <div id="mainBody">
    45     45       <h1 class="heading">Version History</h1>
    46     46       <p><b>1.0.95.0 - November XX, 2014 <font color="red">(release scheduled)</font></b></p>
    47     47       <ul>
    48         -      <li>Updated to <a href="http://www.sqlite.org/releaselog/3_8_7.html">SQLite 3.8.7</a>.</li>
           48  +      <li>Updated to <a href="http://www.sqlite.org/releaselog/3_8_7_1.html">SQLite 3.8.7.1</a>.</li>
    49     49         <li>Make sure SQL statements generated for DbUpdateCommandTree objects are properly delimited.</li>
    50     50         <li>Various minor performance enhancements to the SQLiteDataReader class. Pursuant to <a href="http://system.data.sqlite.org/index.html/info/e122d26e70">[e122d26e70]</a>.</li>
           51  +      <li>Defer disposing of connections created by the static SQLiteCommand.Execute method when a data reader is returned. Fix for <a href="http://system.data.sqlite.org/index.html/info/daeaf3150a">[daeaf3150a]</a>.</li>
           52  +      <li>Wrap SELECT statements in parenthesis if they have an ORDER BY, LIMIT, or OFFSET clause and a compound operator is involved. Fix for <a href="http://system.data.sqlite.org/index.html/info/0a32885109">[0a32885109]</a>.</li>
    51     53         <li>In the SQLiteDataReader.VerifyType method, remove duplicate &quot;if&quot; statement for the DbType.SByte value and move the remaining &quot;if&quot; to the Int64 affinity. Fix for <a href="http://system.data.sqlite.org/index.html/info/c5cc2fb334">[c5cc2fb334]</a>.&nbsp;<b>** Potentially Incompatible Change **</b></li>
           54  +      <li>Handle Julian Day values that fall outside of the supported range for OLE Automation dates. Fix for <a href="http://system.data.sqlite.org/index.html/info/3e783eecbe">[3e783eecbe]</a>.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    52     55       </ul>
    53     56       <p><b>1.0.94.0 - September 9, 2014</b></p>
    54     57       <ul>
    55     58         <li>Updated to <a href="http://www.sqlite.org/releaselog/3_8_6.html">SQLite 3.8.6</a>.</li>
    56     59         <li>Updated to <a href="http://www.nuget.org/packages/EntityFramework/6.1.1">Entity Framework 6.1.1</a>.</li>
    57     60         <li>Refactor and simplify NuGet packages in order to support per-solution SQLite interop assembly files.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    58     61         <li>Add RefreshFlags method to the SQLiteDataReader class to forcibly refresh its connection flags.</li>

Changes to SQLite.Designer/Editors/TableDesignerDoc.cs.

   795    795         {
   796    796           case __FRAMESHOW.FRAMESHOW_WinShown:
   797    797           case __FRAMESHOW.FRAMESHOW_WinRestored:
   798    798             SetPropertyWindow();
   799    799             if (_warned == false)
   800    800             {
   801    801               _warned = true;
   802         -            MessageBox.Show(this, "The table designer is still in development.  Please report bugs to robert@blackcastlesoft.com", "Feature Under Review", MessageBoxButtons.OK);
          802  +            MessageBox.Show(this, "The table designer is still in development.  Please report bugs to the sqlite-users mailing list at sqlite-users@sqlite.org", "Feature Under Review", MessageBoxButtons.OK);
   803    803             }
   804    804             break;
   805    805         }
   806    806         return VSConstants.S_OK;
   807    807       }
   808    808   
   809    809       int IVsWindowFrameNotify.OnSize()

Changes to SQLite.Designer/Editors/ViewDesignerDoc.cs.

   564    564           case __FRAMESHOW.FRAMESHOW_WinShown:
   565    565           case __FRAMESHOW.FRAMESHOW_WinRestored:
   566    566             _timer.Enabled = true;
   567    567             SetPropertyWindow();
   568    568             if (_warned == false)
   569    569             {
   570    570               _warned = true;
   571         -            MessageBox.Show(this, "The view designer is still in development.  Please report bugs to robert@blackcastlesoft.com", "Feature Under Review", MessageBoxButtons.OK);
          571  +            MessageBox.Show(this, "The view designer is still in development.  Please report bugs to the sqlite-users mailing list at sqlite-users@sqlite.org", "Feature Under Review", MessageBoxButtons.OK);
   572    572             }
   573    573             break;
   574    574         }
   575    575         return VSConstants.S_OK;
   576    576       }
   577    577   
   578    578       int IVsWindowFrameNotify.OnSize()

Changes to SQLite.Interop/props/sqlite3.props.

     5      5    *
     6      6    * Written by Joe Mistachkin.
     7      7    * Released to the public domain, use at your own risk!
     8      8    *
     9      9   -->
    10     10   <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
    11     11     <PropertyGroup Label="UserMacros">
    12         -    <SQLITE_MANIFEST_VERSION>3.8.7</SQLITE_MANIFEST_VERSION>
    13         -    <SQLITE_RC_VERSION>3,8,7</SQLITE_RC_VERSION>
           12  +    <SQLITE_MANIFEST_VERSION>3.8.7.1</SQLITE_MANIFEST_VERSION>
           13  +    <SQLITE_RC_VERSION>3,8,7,1</SQLITE_RC_VERSION>
    14     14       <SQLITE_COMMON_DEFINES>_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;SQLITE_THREADSAFE=1;SQLITE_USE_URI=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT4=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1;SQLITE_ENABLE_MEMORY_MANAGEMENT=1</SQLITE_COMMON_DEFINES>
    15     15       <SQLITE_EXTRA_DEFINES>SQLITE_HAS_CODEC=1</SQLITE_EXTRA_DEFINES>
    16     16       <SQLITE_WINCE_200X_DEFINES>SQLITE_OMIT_WAL=1</SQLITE_WINCE_200X_DEFINES>
    17     17       <SQLITE_WINCE_2013_DEFINES>HAVE_ERRNO_H=1;SQLITE_MSVC_LOCALTIME_API=1</SQLITE_WINCE_2013_DEFINES>
    18     18       <SQLITE_DEBUG_DEFINES>SQLITE_DEBUG=1;SQLITE_MEMDEBUG=1;SQLITE_ENABLE_EXPENSIVE_ASSERT=1</SQLITE_DEBUG_DEFINES>
    19     19       <SQLITE_RELEASE_DEFINES>SQLITE_WIN32_MALLOC=1</SQLITE_RELEASE_DEFINES>
    20     20       <SQLITE_DISABLE_WARNINGS>4055;4100;4127;4146;4210;4232;4244;4245;4267;4306;4389;4701;4703;4706</SQLITE_DISABLE_WARNINGS>

Changes to SQLite.Interop/props/sqlite3.vsprops.

    10     10   <VisualStudioPropertySheet
    11     11   	ProjectType="Visual C++"
    12     12   	Version="8.00"
    13     13   	Name="sqlite3"
    14     14   	>
    15     15   	<UserMacro
    16     16   		Name="SQLITE_MANIFEST_VERSION"
    17         -		Value="3.8.7"
           17  +		Value="3.8.7.1"
    18     18   		PerformEnvironmentSet="true"
    19     19   	/>
    20     20   	<UserMacro
    21     21   		Name="SQLITE_RC_VERSION"
    22         -		Value="3,8,7"
           22  +		Value="3,8,7,1"
    23     23   		PerformEnvironmentSet="true"
    24     24   	/>
    25     25   	<UserMacro
    26     26   		Name="SQLITE_COMMON_DEFINES"
    27     27   		Value="_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;SQLITE_THREADSAFE=1;SQLITE_USE_URI=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT4=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1;SQLITE_ENABLE_MEMORY_MANAGEMENT=1"
    28     28   		PerformEnvironmentSet="true"
    29     29   	/>

Changes to SQLite.Interop/src/core/sqlite3.c.

     1      1   /******************************************************************************
     2      2   ** This file is an amalgamation of many separate C source files from SQLite
     3         -** version 3.8.7.  By combining all the individual C code files into this 
            3  +** version 3.8.7.1.  By combining all the individual C code files into this 
     4      4   ** single large file, the entire code can be compiled as a single translation
     5      5   ** unit.  This allows many compilers to do optimizations that would not be
     6      6   ** possible if the files were compiled separately.  Performance improvements
     7      7   ** of 5% or more are commonly seen when SQLite is compiled as a single
     8      8   ** translation unit.
     9      9   **
    10     10   ** This file is all you need to compile SQLite.  To use SQLite in other
................................................................................
   227    227   ** string contains the date and time of the check-in (UTC) and an SHA1
   228    228   ** hash of the entire source tree.
   229    229   **
   230    230   ** See also: [sqlite3_libversion()],
   231    231   ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
   232    232   ** [sqlite_version()] and [sqlite_source_id()].
   233    233   */
   234         -#define SQLITE_VERSION        "3.8.7"
          234  +#define SQLITE_VERSION        "3.8.7.1"
   235    235   #define SQLITE_VERSION_NUMBER 3008007
   236         -#define SQLITE_SOURCE_ID      "2014-10-17 11:24:17 e4ab094f8afce0817f4074e823fabe59fc29ebb4"
          236  +#define SQLITE_SOURCE_ID      "2014-10-29 13:59:56 3b7b72c4685aa5cf5e675c2c47ebec10d9704221"
   237    237   
   238    238   /*
   239    239   ** CAPI3REF: Run-Time Library Version Numbers
   240    240   ** KEYWORDS: sqlite3_version, sqlite3_sourceid
   241    241   **
   242    242   ** These interfaces provide the same information as the [SQLITE_VERSION],
   243    243   ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
................................................................................
 20752  20752   /*
 20753  20753   ** If the strchrnul() library function is available, then set
 20754  20754   ** HAVE_STRCHRNUL.  If that routine is not available, this module
 20755  20755   ** will supply its own.  The built-in version is slower than
 20756  20756   ** the glibc version so the glibc version is definitely preferred.
 20757  20757   */
 20758  20758   #if !defined(HAVE_STRCHRNUL)
 20759         -# if defined(linux)
 20760         -#  define HAVE_STRCHRNUL 1
 20761         -# else
 20762         -#  define HAVE_STRCHRNUL 0
 20763         -# endif
        20759  +# define HAVE_STRCHRNUL 0
 20764  20760   #endif
 20765  20761   
 20766  20762   
 20767  20763   /*
 20768  20764   ** Conversion types fall into various categories as defined by the
 20769  20765   ** following enumeration.
 20770  20766   */
................................................................................
 42802  42798         assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
 42803  42799         sqlite3OsClose(pPager->jfd);
 42804  42800       }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
 42805  42801         if( pPager->journalOff==0 ){
 42806  42802           rc = SQLITE_OK;
 42807  42803         }else{
 42808  42804           rc = sqlite3OsTruncate(pPager->jfd, 0);
        42805  +        if( rc==SQLITE_OK && pPager->fullSync ){
        42806  +          /* Make sure the new file size is written into the inode right away.
        42807  +          ** Otherwise the journal might resurrect following a power loss and
        42808  +          ** cause the last transaction to roll back.  See
        42809  +          ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
        42810  +          */
        42811  +          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
        42812  +        }
 42809  42813         }
 42810  42814         pPager->journalOff = 0;
 42811  42815       }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
 42812  42816         || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
 42813  42817       ){
 42814  42818         rc = zeroJournalHdr(pPager, hasMaster);
 42815  42819         pPager->journalOff = 0;
................................................................................
 71439  71443       ** still not up to p2, that means that the record has fewer than p2
 71440  71444       ** columns.  So the result will be either the default value or a NULL.
 71441  71445       */
 71442  71446       if( pC->nHdrParsed<=p2 ){
 71443  71447         if( pOp->p4type==P4_MEM ){
 71444  71448           sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
 71445  71449         }else{
 71446         -        MemSetTypeFlag(pDest, MEM_Null);
        71450  +        sqlite3VdbeMemSetNull(pDest);
 71447  71451         }
 71448  71452         goto op_column_out;
 71449  71453       }
 71450  71454     }
 71451  71455   
 71452  71456     /* Extract the content for the p2+1-th column.  Control can only
 71453  71457     ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
................................................................................
 93753  93757       ** where-clause loop above.
 93754  93758       */
 93755  93759       if( okOnePass ){
 93756  93760         /* Just one row.  Hence the top-of-loop is a no-op */
 93757  93761         assert( nKey==nPk );  /* OP_Found will use an unpacked key */
 93758  93762         assert( !IsVirtual(pTab) );
 93759  93763         if( aToOpen[iDataCur-iTabCur] ){
 93760         -        assert( pPk!=0 );
        93764  +        assert( pPk!=0 || pTab->pSelect!=0 );
 93761  93765           sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
 93762  93766           VdbeCoverage(v);
 93763  93767         }
 93764  93768       }else if( pPk ){
 93765  93769         addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
 93766  93770         sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
 93767  93771         assert( nKey==0 );  /* OP_Found will use a composite key */
................................................................................
111277 111281       }
111278 111282       sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iBaseCur, aToOpen,
111279 111283                                  0, 0);
111280 111284     }
111281 111285   
111282 111286     /* Top of the update loop */
111283 111287     if( okOnePass ){
111284         -    if( aToOpen[iDataCur-iBaseCur] ){
111285         -      assert( pPk!=0 );
       111288  +    if( aToOpen[iDataCur-iBaseCur] && !isView ){
       111289  +      assert( pPk );
111286 111290         sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
111287 111291         VdbeCoverageNeverTaken(v);
111288 111292       }
111289 111293       labelContinue = labelBreak;
111290 111294       sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
111291 111295       VdbeCoverageIf(v, pPk==0);
111292 111296       VdbeCoverageIf(v, pPk!=0);

Changes to SQLite.Interop/src/core/sqlite3.h.

   103    103   ** string contains the date and time of the check-in (UTC) and an SHA1
   104    104   ** hash of the entire source tree.
   105    105   **
   106    106   ** See also: [sqlite3_libversion()],
   107    107   ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
   108    108   ** [sqlite_version()] and [sqlite_source_id()].
   109    109   */
   110         -#define SQLITE_VERSION        "3.8.7"
          110  +#define SQLITE_VERSION        "3.8.7.1"
   111    111   #define SQLITE_VERSION_NUMBER 3008007
   112         -#define SQLITE_SOURCE_ID      "2014-10-17 11:24:17 e4ab094f8afce0817f4074e823fabe59fc29ebb4"
          112  +#define SQLITE_SOURCE_ID      "2014-10-29 13:59:56 3b7b72c4685aa5cf5e675c2c47ebec10d9704221"
   113    113   
   114    114   /*
   115    115   ** CAPI3REF: Run-Time Library Version Numbers
   116    116   ** KEYWORDS: sqlite3_version, sqlite3_sourceid
   117    117   **
   118    118   ** These interfaces provide the same information as the [SQLITE_VERSION],
   119    119   ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros

Changes to System.Data.SQLite.Linq/SQL Generation/SqlGenerator.cs.

  2466   2466         return result;
  2467   2467       }
  2468   2468   
  2469   2469       ISqlFragment VisitSetOpExpression(DbExpression left, DbExpression right, string separator)
  2470   2470       {
  2471   2471   
  2472   2472         SqlSelectStatement leftSelectStatement = VisitExpressionEnsureSqlStatement(left);
         2473  +      bool leftOrderByLimitOrOffset = leftSelectStatement.HaveOrderByLimitOrOffset();
  2473   2474         SqlSelectStatement rightSelectStatement = VisitExpressionEnsureSqlStatement(right);
         2475  +      bool rightOrderByLimitOrOffset = rightSelectStatement.HaveOrderByLimitOrOffset();
  2474   2476   
  2475   2477         SqlBuilder setStatement = new SqlBuilder();
         2478  +
         2479  +      if (leftOrderByLimitOrOffset)
         2480  +          setStatement.Append("SELECT * FROM (");
         2481  +
  2476   2482         setStatement.Append(leftSelectStatement);
         2483  +
         2484  +      if (leftOrderByLimitOrOffset)
         2485  +          setStatement.Append(") ");
         2486  +
  2477   2487         setStatement.AppendLine();
  2478   2488         setStatement.Append(separator); // e.g. UNION ALL
  2479   2489         setStatement.AppendLine();
         2490  +
         2491  +      if (rightOrderByLimitOrOffset)
         2492  +          setStatement.Append("SELECT * FROM (");
         2493  +
  2480   2494         setStatement.Append(rightSelectStatement);
         2495  +
         2496  +      if (rightOrderByLimitOrOffset)
         2497  +          setStatement.Append(") ");
  2481   2498   
  2482   2499         return setStatement;
  2483   2500       }
  2484   2501   
  2485   2502   
  2486   2503       #endregion
  2487   2504   

Changes to System.Data.SQLite.Linq/SQL Generation/SqlSelectStatement.cs.

   191    191       // if not Order By should be omitted unless there is a corresponding TOP
   192    192       private bool isTopMost;
   193    193       internal bool IsTopMost
   194    194       {
   195    195         get { return this.isTopMost; }
   196    196         set { this.isTopMost = value; }
   197    197       }
          198  +
          199  +    /// <summary>
          200  +    /// Checks if the statement has an ORDER BY, LIMIT, or OFFSET clause.
          201  +    /// </summary>
          202  +    /// <returns>
          203  +    /// Non-zero if there is an ORDER BY, LIMIT, or OFFSET clause;
          204  +    /// otherwise, zero.
          205  +    /// </returns>
          206  +    public bool HaveOrderByLimitOrOffset()
          207  +    {
          208  +        if ((this.orderBy != null) && !this.orderBy.IsEmpty)
          209  +            return true;
          210  +
          211  +        if (this.top != null)
          212  +            return true;
          213  +
          214  +        if (this.skip != null)
          215  +            return true;
          216  +
          217  +        return false;
          218  +    }
   198    219   
   199    220       #region ISqlFragment Members
   200    221   
   201    222       /// <summary>
   202    223       /// Write out a SQL select statement as a string.
   203    224       /// We have to
   204    225       /// <list type="number">

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

   702    702           return Execute(
   703    703               commandText, executeType, CommandBehavior.Default,
   704    704               connectionString, args);
   705    705       }
   706    706   
   707    707       /// <summary>
   708    708       /// This method creates a new connection, executes the query using the given
   709         -    /// execution type and command behavior, closes the connection, and returns
   710         -    /// the results.  If the connection string is null, a temporary in-memory
   711         -    /// database connection will be used.
          709  +    /// execution type and command behavior, closes the connection unless a data
          710  +    /// reader is created, and returns the results.  If the connection string is
          711  +    /// null, a temporary in-memory database connection will be used.
   712    712       /// </summary>
   713    713       /// <param name="commandText">
   714    714       /// The text of the command to be executed.
   715    715       /// </param>
   716    716       /// <param name="executeType">
   717    717       /// The execution type for the command.  This is used to determine which method
   718    718       /// of the command object to call, which then determines the type of results
................................................................................
   737    737           string commandText,
   738    738           SQLiteExecuteType executeType,
   739    739           CommandBehavior commandBehavior,
   740    740           string connectionString,
   741    741           params object[] args
   742    742           )
   743    743       {
   744         -        if (connectionString == null)
   745         -            connectionString = DefaultConnectionString;
          744  +        SQLiteConnection connection = null;
   746    745   
   747         -        using (SQLiteConnection connection = new SQLiteConnection(connectionString))
          746  +        try
   748    747           {
   749         -            connection.Open();
          748  +            if (connectionString == null)
          749  +                connectionString = DefaultConnectionString;
   750    750   
   751         -            using (SQLiteCommand command = connection.CreateCommand())
          751  +            using (connection = new SQLiteConnection(connectionString))
   752    752               {
   753         -                command.CommandText = commandText;
          753  +                connection.Open();
   754    754   
   755         -                if (args != null)
          755  +                using (SQLiteCommand command = connection.CreateCommand())
   756    756                   {
   757         -                    foreach (object arg in args)
          757  +                    command.CommandText = commandText;
          758  +
          759  +                    if (args != null)
   758    760                       {
   759         -                        if (arg is SQLiteParameter)
   760         -                            command.Parameters.Add((SQLiteParameter)arg);
   761         -                        else
   762         -                            command.Parameters.Add(new SQLiteParameter(DbType.Object, arg));
          761  +                        foreach (object arg in args)
          762  +                        {
          763  +                            if (arg is SQLiteParameter)
          764  +                                command.Parameters.Add((SQLiteParameter)arg);
          765  +                            else
          766  +                                command.Parameters.Add(new SQLiteParameter(DbType.Object, arg));
          767  +                        }
   763    768                       }
   764         -                }
   765         -
   766         -                switch (executeType)
   767         -                {
   768         -                    case SQLiteExecuteType.None:
   769         -                        {
   770         -                            //
   771         -                            // NOTE: Do nothing.
   772         -                            //
   773         -                            break;
   774         -                        }
   775         -                    case SQLiteExecuteType.NonQuery:
   776         -                        {
   777         -                            return command.ExecuteNonQuery(commandBehavior);
   778         -                        }
   779         -                    case SQLiteExecuteType.Scalar:
   780         -                        {
   781         -                            return command.ExecuteScalar(commandBehavior);
   782         -                        }
   783         -                    case SQLiteExecuteType.Reader:
   784         -                        {
   785         -                            return command.ExecuteReader(commandBehavior);
   786         -                        }
          769  +
          770  +                    switch (executeType)
          771  +                    {
          772  +                        case SQLiteExecuteType.None:
          773  +                            {
          774  +                                //
          775  +                                // NOTE: Do nothing.
          776  +                                //
          777  +                                break;
          778  +                            }
          779  +                        case SQLiteExecuteType.NonQuery:
          780  +                            {
          781  +                                return command.ExecuteNonQuery(commandBehavior);
          782  +                            }
          783  +                        case SQLiteExecuteType.Scalar:
          784  +                            {
          785  +                                return command.ExecuteScalar(commandBehavior);
          786  +                            }
          787  +                        case SQLiteExecuteType.Reader:
          788  +                            {
          789  +                                bool success = true;
          790  +
          791  +                                try
          792  +                                {
          793  +                                    //
          794  +                                    // NOTE: The CloseConnection flag is being added here.
          795  +                                    //       This should force the returned data reader to
          796  +                                    //       close the connection when it is disposed.  In
          797  +                                    //       order to prevent the containing using block
          798  +                                    //       from disposing the connection prematurely,
          799  +                                    //       the innermost finally block sets the internal
          800  +                                    //       no-disposal flag to true.  The outer finally
          801  +                                    //       block will reset the internal no-disposal flag
          802  +                                    //       to false so that the data reader will be able
          803  +                                    //       to (eventually) dispose of the connection.
          804  +                                    //
          805  +                                    return command.ExecuteReader(
          806  +                                        commandBehavior | CommandBehavior.CloseConnection);
          807  +                                }
          808  +                                catch
          809  +                                {
          810  +                                    success = false;
          811  +                                    throw;
          812  +                                }
          813  +                                finally
          814  +                                {
          815  +                                    //
          816  +                                    // NOTE: If an exception was not thrown, that can only
          817  +                                    //       mean the data reader was successfully created
          818  +                                    //       and now owns the connection.  Therefore, set
          819  +                                    //       the internal no-disposal flag (temporarily)
          820  +                                    //       in order to exit the containing using block
          821  +                                    //       without disposing it.
          822  +                                    //
          823  +                                    if (success)
          824  +                                        connection._noDispose = true;
          825  +                                }
          826  +                            }
          827  +                    }
   787    828                   }
   788    829               }
   789    830           }
          831  +        finally
          832  +        {
          833  +            //
          834  +            // NOTE: Now that the using block has been exited, reset the
          835  +            //       internal disposal flag for the connection.  This is
          836  +            //       always done if the connection was created because
          837  +            //       it will be harmless whether or not the data reader
          838  +            //       now owns it.
          839  +            //
          840  +            if (connection != null)
          841  +                connection._noDispose = false;
          842  +        }
   790    843   
   791    844           return null;
   792    845       }
   793    846   
   794    847       /// <summary>
   795    848       /// Overrides the default behavior to return a SQLiteDataReader specialization class
   796    849       /// </summary>

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

   320    320     /// <b>False</b> - Skip attempting to expand the data source file name to a fully qualified path before opening.
   321    321     /// </description>
   322    322     /// <description>N</description>
   323    323     /// <description>True</description>
   324    324     /// </item>
   325    325     /// </list>
   326    326     /// </remarks>
   327         -  public sealed partial class SQLiteConnection : DbConnection, ICloneable
          327  +  public sealed partial class SQLiteConnection : DbConnection, ICloneable, IDisposable
   328    328     {
   329    329       #region Private Constants
   330    330       /// <summary>
   331    331       /// The "invalid value" for the <see cref="DbType" /> enumeration used
   332    332       /// by the <see cref="DefaultDbType" /> property.  This constant is shared
   333    333       /// by this class and the SQLiteConnectionStringBuilder class.
   334    334       /// </summary>
................................................................................
   430    430       /// </summary>
   431    431       private string _connectionString;
   432    432       /// <summary>
   433    433       /// Nesting level of the transactions open on the connection
   434    434       /// </summary>
   435    435       internal int _transactionLevel;
   436    436   
          437  +    /// <summary>
          438  +    /// If this flag is non-zero, the <see cref="Dispose()" /> method will have
          439  +    /// no effect; however, the <see cref="Close" /> method will continue to
          440  +    /// behave as normal.
          441  +    /// </summary>
          442  +    internal bool _noDispose;
          443  +
   437    444       /// <summary>
   438    445       /// If set, then the connection is currently being disposed.
   439    446       /// </summary>
   440    447       private bool _disposing;
   441    448   
   442    449       /// <summary>
   443    450       /// The default isolation level for new transactions
................................................................................
   603    610       /// </param>
   604    611       /// <param name="parseViaFramework">
   605    612       /// Non-zero to parse the connection string using the built-in (i.e.
   606    613       /// framework provided) parser when opening the connection.
   607    614       /// </param>
   608    615       public SQLiteConnection(string connectionString, bool parseViaFramework)
   609    616       {
          617  +      _noDispose = false;
          618  +
   610    619   #if (SQLITE_STANDARD || USE_INTEROP_DLL || PLATFORM_COMPACTFRAMEWORK) && PRELOAD_NATIVE_LIBRARY
   611    620         UnsafeNativeMethods.Initialize();
   612    621   #endif
   613    622   
   614    623         SQLiteLog.Initialize();
   615    624   
   616    625   #if !PLATFORM_COMPACTFRAMEWORK && !INTEROP_LEGACY_CLOSE && SQLITE_STANDARD
................................................................................
  1240   1249                   dateFormat, kind, dateTimeFormat, IntPtr.Zero, null,
  1241   1250                   false);
  1242   1251           }
  1243   1252       }
  1244   1253   
  1245   1254       ///////////////////////////////////////////////////////////////////////////////////////////////
  1246   1255   
         1256  +    #region IDisposable Members
         1257  +    /// <summary>
         1258  +    /// Disposes and finalizes the connection, if applicable.
         1259  +    /// </summary>
         1260  +    public new void Dispose()
         1261  +    {
         1262  +        if (_noDispose)
         1263  +            return;
         1264  +
         1265  +        base.Dispose();
         1266  +    }
         1267  +    #endregion
         1268  +
         1269  +    ///////////////////////////////////////////////////////////////////////////////////////////////
         1270  +
  1247   1271       #region IDisposable "Pattern" Members
  1248   1272       private bool disposed;
  1249   1273       private void CheckDisposed() /* throw */
  1250   1274       {
  1251   1275   #if THROW_ON_DISPOSED
  1252   1276           if (disposed)
  1253   1277               throw new ObjectDisposedException(typeof(SQLiteConnection).Name);
................................................................................
  1254   1278   #endif
  1255   1279       }
  1256   1280   
  1257   1281       ///////////////////////////////////////////////////////////////////////////////////////////////
  1258   1282   
  1259   1283       protected override void Dispose(bool disposing)
  1260   1284       {
         1285  +#if !NET_COMPACT_20 && TRACE_WARNING
         1286  +        if ((_flags & SQLiteConnectionFlags.TraceWarning) == SQLiteConnectionFlags.TraceWarning)
         1287  +        {
         1288  +            if (_noDispose)
         1289  +            {
         1290  +                System.Diagnostics.Trace.WriteLine(String.Format(CultureInfo.CurrentCulture,
         1291  +                    "WARNING: Disposing of connection \"{0}\" with the no-dispose flag set.",
         1292  +                    _connectionString));
         1293  +            }
         1294  +        }
         1295  +#endif
         1296  +
  1261   1297           _disposing = true;
  1262   1298   
  1263   1299           try
  1264   1300           {
  1265   1301               if (!disposed)
  1266   1302               {
  1267   1303                   //if (disposing)

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

    37     37   
    38     38       /// <summary>
    39     39       /// The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC).
    40     40       /// </summary>
    41     41       protected static readonly DateTime UnixEpoch =
    42     42           new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    43     43   
           44  +    #pragma warning disable 414
    44     45       /// <summary>
    45         -    /// The value of the OLE Automation epoch represented as a Julian day.
           46  +    /// The value of the OLE Automation epoch represented as a Julian day.  This
           47  +    /// field cannot be removed as the test suite relies upon it.
    46     48       /// </summary>
    47     49       private static readonly double OleAutomationEpochAsJulianDay = 2415018.5;
           50  +    #pragma warning restore 414
    48     51   
    49     52       /// <summary>
    50     53       /// The format string for DateTime values when using the InvariantCulture or CurrentCulture formats.
    51     54       /// </summary>
    52     55       private const string FullFormat = "yyyy-MM-ddTHH:mm:ss.fffffffK";
    53     56   
           57  +    /// <summary>
           58  +    /// This is the minimum Julian Day value supported by this library
           59  +    /// (148731163200000).
           60  +    /// </summary>
           61  +    private static readonly long MinimumJd = computeJD(DateTime.MinValue);
           62  +
           63  +    /// <summary>
           64  +    /// This is the maximum Julian Day value supported by this library
           65  +    /// (464269060799000).
           66  +    /// </summary>
           67  +    private static readonly long MaximumJd = computeJD(DateTime.MaxValue);
           68  +
    54     69       /// <summary>
    55     70       /// An array of ISO-8601 DateTime formats that we support parsing.
    56     71       /// </summary>
    57     72       private static string[] _datetimeFormats = new string[] {
    58     73         "THHmmssK",
    59     74         "THHmmK",
    60     75         "HH:mm:ss.FFFFFFFK",
................................................................................
   197    212   
   198    213         byte[] byteArray = new byte[nativestringlen];
   199    214   
   200    215         Marshal.Copy(nativestring, byteArray, 0, nativestringlen);
   201    216   
   202    217         return _utf8.GetString(byteArray, 0, nativestringlen);
   203    218       }
   204         -
   205         -
   206    219       #endregion
          220  +
          221  +    ///////////////////////////////////////////////////////////////////////////
   207    222   
   208    223       #region DateTime Conversion Functions
          224  +    #region New Julian Day Conversion Methods
          225  +    /// <summary>
          226  +    /// Checks if the specified <see cref="Int64" /> is within the
          227  +    /// supported range for a Julian Day value.
          228  +    /// </summary>
          229  +    /// <param name="jd">
          230  +    /// The Julian Day value to check.
          231  +    /// </param>
          232  +    /// <returns>
          233  +    /// Non-zero if the specified Julian Day value is in the supported
          234  +    /// range; otherwise, zero.
          235  +    /// </returns>
          236  +    private static bool isValidJd(
          237  +        long jd
          238  +        )
          239  +    {
          240  +        return ((jd >= MinimumJd) && (jd <= MaximumJd));
          241  +    }
          242  +
          243  +    ///////////////////////////////////////////////////////////////////////////
          244  +
          245  +    /// <summary>
          246  +    /// Converts a Julian Day value from a <see cref="Double" /> to an
          247  +    /// <see cref="Int64" />.
          248  +    /// </summary>
          249  +    /// <param name="julianDay">
          250  +    /// The Julian Day <see cref="Double" /> value to convert.
          251  +    /// </param>
          252  +    /// <returns>
          253  +    /// The resulting Julian Day <see cref="Int64" /> value.
          254  +    /// </returns>
          255  +    private static long DoubleToJd(
          256  +        double julianDay
          257  +        )
          258  +    {
          259  +        return (long)(julianDay * 86400000.0);
          260  +    }
          261  +
          262  +    ///////////////////////////////////////////////////////////////////////////
          263  +
          264  +    /// <summary>
          265  +    /// Converts a Julian Day value from an <see cref="Int64" /> to a
          266  +    /// <see cref="Double" />.
          267  +    /// </summary>
          268  +    /// <param name="jd">
          269  +    /// The Julian Day <see cref="Int64" /> value to convert.
          270  +    /// </param>
          271  +    /// <returns>
          272  +    /// The resulting Julian Day <see cref="Double" /> value.
          273  +    /// </returns>
          274  +    private static double JdToDouble(
          275  +        long jd
          276  +        )
          277  +    {
          278  +        return (double)(jd / 86400000.0);
          279  +    }
          280  +
          281  +    ///////////////////////////////////////////////////////////////////////////
          282  +
          283  +    /// <summary>
          284  +    /// Converts a Julian Day value to a <see cref="DateTime" />.
          285  +    /// This method was translated from the "computeYMD" function in the
          286  +    /// "date.c" file belonging to the SQLite core library.
          287  +    /// </summary>
          288  +    /// <param name="jd">
          289  +    /// The Julian Day value to convert.
          290  +    /// </param>
          291  +    /// <param name="badValue">
          292  +    /// The <see cref="DateTime" /> value to return in the event that the
          293  +    /// Julian Day is out of the supported range.  If this value is null,
          294  +    /// an exception will be thrown instead.
          295  +    /// </param>
          296  +    /// <returns>
          297  +    /// A <see cref="DateTime" /> value that contains the year, month, and
          298  +    /// day values that are closest to the specified Julian Day value.
          299  +    /// </returns>
          300  +    private static DateTime computeYMD(
          301  +        long jd,
          302  +        DateTime? badValue
          303  +        )
          304  +    {
          305  +        if (!isValidJd(jd))
          306  +        {
          307  +            if (badValue == null)
          308  +            {
          309  +                throw new ArgumentException(
          310  +                    "Not a supported Julian Day value.");
          311  +            }
          312  +
          313  +            return (DateTime)badValue;
          314  +        }
          315  +
          316  +        int Z, A, B, C, D, E, X1;
          317  +
          318  +        Z = (int)((jd + 43200000) / 86400000);
          319  +        A = (int)((Z - 1867216.25) / 36524.25);
          320  +        A = Z + 1 + A - (A / 4);
          321  +        B = A + 1524;
          322  +        C = (int)((B - 122.1) / 365.25);
          323  +        D = (36525 * C) / 100;
          324  +        E = (int)((B - D) / 30.6001);
          325  +        X1 = (int)(30.6001 * E);
          326  +
          327  +        int day, month, year;
          328  +
          329  +        day = B - D - X1;
          330  +        month = E < 14 ? E - 1 : E - 13;
          331  +        year = month > 2 ? C - 4716 : C - 4715;
          332  +
          333  +        try
          334  +        {
          335  +            return new DateTime(year, month, day);
          336  +        }
          337  +        catch
          338  +        {
          339  +            if (badValue == null)
          340  +                throw;
          341  +
          342  +            return (DateTime)badValue;
          343  +        }
          344  +    }
          345  +
          346  +    ///////////////////////////////////////////////////////////////////////////
          347  +
          348  +    /// <summary>
          349  +    /// Converts a Julian Day value to a <see cref="DateTime" />.
          350  +    /// This method was translated from the "computeHMS" function in the
          351  +    /// "date.c" file belonging to the SQLite core library.
          352  +    /// </summary>
          353  +    /// <param name="jd">
          354  +    /// The Julian Day value to convert.
          355  +    /// </param>
          356  +    /// <param name="badValue">
          357  +    /// The <see cref="DateTime" /> value to return in the event that the
          358  +    /// Julian Day value is out of the supported range.  If this value is
          359  +    /// null, an exception will be thrown instead.
          360  +    /// </param>
          361  +    /// <returns>
          362  +    /// A <see cref="DateTime" /> value that contains the hour, minute, and
          363  +    /// second, and millisecond values that are closest to the specified
          364  +    /// Julian Day value.
          365  +    /// </returns>
          366  +    private static DateTime computeHMS(
          367  +        long jd,
          368  +        DateTime? badValue
          369  +        )
          370  +    {
          371  +        if (!isValidJd(jd))
          372  +        {
          373  +            if (badValue == null)
          374  +            {
          375  +                throw new ArgumentException(
          376  +                    "Not a supported Julian Day value.");
          377  +            }
          378  +
          379  +            return (DateTime)badValue;
          380  +        }
          381  +
          382  +        int si;
          383  +
          384  +        si = (int)((jd + 43200000) % 86400000);
          385  +
          386  +        decimal sd;
          387  +
          388  +        sd = si / 1000.0M;
          389  +        si = (int)sd;
          390  +
          391  +        int millisecond = (int)((sd - si) * 1000.0M);
          392  +
          393  +        sd -= si;
          394  +
          395  +        int hour;
          396  +
          397  +        hour = si / 3600;
          398  +        si -= hour * 3600;
          399  +
          400  +        int minute;
          401  +
          402  +        minute = si / 60;
          403  +        sd += si - minute * 60;
          404  +
          405  +        int second = (int)sd;
          406  +
          407  +        try
          408  +        {
          409  +            DateTime minValue = DateTime.MinValue;
          410  +
          411  +            return new DateTime(
          412  +                minValue.Year, minValue.Month, minValue.Day,
          413  +                hour, minute, second, millisecond);
          414  +        }
          415  +        catch
          416  +        {
          417  +            if (badValue == null)
          418  +                throw;
          419  +
          420  +            return (DateTime)badValue;
          421  +        }
          422  +    }
          423  +
          424  +    ///////////////////////////////////////////////////////////////////////////
          425  +
          426  +    /// <summary>
          427  +    /// Converts a <see cref="DateTime" /> to a Julian Day value.
          428  +    /// This method was translated from the "computeJD" function in
          429  +    /// the "date.c" file belonging to the SQLite core library.
          430  +    /// Since the range of Julian Day values supported by this method
          431  +    /// includes all possible (valid) values of a <see cref="DateTime" />
          432  +    /// value, it should be extremely difficult for this method to
          433  +    /// raise an exception or return an undefined result.
          434  +    /// </summary>
          435  +    /// <param name="dateTime">
          436  +    /// The <see cref="DateTime" /> value to convert.  This value
          437  +    /// will be within the range of <see cref="DateTime.MinValue" />
          438  +    /// (00:00:00.0000000, January 1, 0001) to
          439  +    /// <see cref="DateTime.MaxValue" /> (23:59:59.9999999, December
          440  +    /// 31, 9999).
          441  +    /// </param>
          442  +    /// <returns>
          443  +    /// The nearest Julian Day value corresponding to the specified
          444  +    /// <see cref="DateTime" /> value.
          445  +    /// </returns>
          446  +    private static long computeJD(
          447  +        DateTime dateTime
          448  +        )
          449  +    {
          450  +        int Y, M, D;
          451  +
          452  +        Y = dateTime.Year;
          453  +        M = dateTime.Month;
          454  +        D = dateTime.Day;
          455  +
          456  +        if (M <= 2)
          457  +        {
          458  +            Y--;
          459  +            M += 12;
          460  +        }
          461  +
          462  +        int A, B, X1, X2;
          463  +
          464  +        A = Y / 100;
          465  +        B = 2 - A + (A / 4);
          466  +        X1 = 36525 * (Y + 4716) / 100;
          467  +        X2 = 306001 * (M + 1) / 10000;
          468  +
          469  +        long jd;
          470  +
          471  +        jd = (long)((X1 + X2 + D + B - 1524.5) * 86400000);
          472  +
          473  +        jd += (dateTime.Hour * 3600000) + (dateTime.Minute * 60000) +
          474  +            (dateTime.Second * 1000) + dateTime.Millisecond;
          475  +
          476  +        return jd;
          477  +    }
          478  +    #endregion
          479  +
          480  +    ///////////////////////////////////////////////////////////////////////////
          481  +
   209    482       /// <summary>
   210    483       /// Converts a string into a DateTime, using the DateTimeFormat, DateTimeKind,
   211    484       /// and DateTimeFormatString specified for the connection when it was opened.
   212    485       /// </summary>
   213    486       /// <remarks>
   214    487       /// Acceptable ISO8601 DateTime formats are:
   215    488       /// <list type="bullet">
................................................................................
   404    677   
   405    678       /// <summary>
   406    679       /// Converts a julianday value into a DateTime
   407    680       /// </summary>
   408    681       /// <param name="julianDay">The value to convert</param>
   409    682       /// <param name="kind">The DateTimeKind to use.</param>
   410    683       /// <returns>A .NET DateTime</returns>
   411         -    public static DateTime ToDateTime(double julianDay, DateTimeKind kind)
          684  +    public static DateTime ToDateTime(
          685  +        double julianDay,
          686  +        DateTimeKind kind
          687  +        )
   412    688       {
   413         -        return DateTime.SpecifyKind(
   414         -            DateTime.FromOADate(julianDay - OleAutomationEpochAsJulianDay), kind);
          689  +        long jd = DoubleToJd(julianDay);
          690  +        DateTime dateTimeYMD = computeYMD(jd, null);
          691  +        DateTime dateTimeHMS = computeHMS(jd, null);
          692  +
          693  +        return new DateTime(
          694  +            dateTimeYMD.Year, dateTimeYMD.Month, dateTimeYMD.Day,
          695  +            dateTimeHMS.Hour, dateTimeHMS.Minute, dateTimeHMS.Second,
          696  +            dateTimeHMS.Millisecond, kind);
   415    697       }
   416    698   
   417    699       /// <summary>
   418    700       /// Converts the specified number of seconds from the Unix epoch into a
   419    701       /// <see cref="DateTime" /> value.
   420    702       /// </summary>
   421    703       /// <param name="seconds">
................................................................................
   453    735       /// <summary>
   454    736       /// Converts a DateTime struct to a JulianDay double
   455    737       /// </summary>
   456    738       /// <param name="value">The DateTime to convert</param>
   457    739       /// <returns>The JulianDay value the Datetime represents</returns>
   458    740       public static double ToJulianDay(DateTime value)
   459    741       {
   460         -      return value.ToOADate() + OleAutomationEpochAsJulianDay;
          742  +        return JdToDouble(computeJD(value));
   461    743       }
   462    744   
   463    745       /// <summary>
   464    746       /// Converts a DateTime struct to the whole number of seconds since the
   465    747       /// Unix epoch.
   466    748       /// </summary>
   467    749       /// <param name="value">The DateTime to convert</param>

Added Tests/tkt-0a32885109.eagle.

            1  +###############################################################################
            2  +#
            3  +# tkt-0a32885109.eagle --
            4  +#
            5  +# Written by Joe Mistachkin.
            6  +# Released to the public domain, use at your own risk!
            7  +#
            8  +###############################################################################
            9  +
           10  +package require Eagle
           11  +package require Eagle.Library
           12  +package require Eagle.Test
           13  +
           14  +runTestPrologue
           15  +
           16  +###############################################################################
           17  +
           18  +package require System.Data.SQLite.Test
           19  +runSQLiteTestPrologue
           20  +runSQLiteTestFilesPrologue
           21  +
           22  +###############################################################################
           23  +
           24  +runTest {test tkt-0a32885109-1.1 {LINQ compound-operator handling} -body {
           25  +  #
           26  +  # NOTE: Re-copy the reference database file used for this unit test to the
           27  +  #       build directory in case it has been changed by a previous test run.
           28  +  #
           29  +  file copy -force $northwindEfDbFile \
           30  +      [file join [getBuildDirectory] [file tail $northwindEfDbFile]]
           31  +
           32  +  set result [list]
           33  +  set output ""
           34  +
           35  +  set code [catch {
           36  +    testClrExec $testLinqExeFile [list -eventflags Wait -directory \
           37  +        [file dirname $testLinqExeFile] -nocarriagereturns -stdout output \
           38  +        -success 0] -unionall
           39  +  } error]
           40  +
           41  +  tlog "---- BEGIN STDOUT OUTPUT\n"
           42  +  tlog $output
           43  +  tlog "\n---- END STDOUT OUTPUT\n"
           44  +
           45  +  lappend result $code
           46  +
           47  +  if {$code == 0} then {
           48  +    lappend result [string trim $output]
           49  +  } else {
           50  +    lappend result [string trim $error]
           51  +  }
           52  +
           53  +  set result
           54  +} -cleanup {
           55  +  unset -nocomplain code output error result
           56  +} -constraints {eagle monoToDo SQLite file_System.Data.SQLite.dll testExec\
           57  +file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db} \
           58  +-result {0 {WHITC ANATR BERGS WHITC ANATR WHITC ANATR BERGS}}}
           59  +
           60  +###############################################################################
           61  +
           62  +runSQLiteTestFilesEpilogue
           63  +runSQLiteTestEpilogue
           64  +runTestEpilogue

Added Tests/tkt-3e783eecbe.eagle.

            1  +###############################################################################
            2  +#
            3  +# tkt-3e783eecbe.eagle --
            4  +#
            5  +# Written by Joe Mistachkin.
            6  +# Released to the public domain, use at your own risk!
            7  +#
            8  +###############################################################################
            9  +
           10  +package require Eagle
           11  +package require Eagle.Library
           12  +package require Eagle.Test
           13  +
           14  +runTestPrologue
           15  +
           16  +###############################################################################
           17  +
           18  +package require System.Data.SQLite.Test
           19  +runSQLiteTestPrologue
           20  +
           21  +###############################################################################
           22  +
           23  +runTest {test tkt-3e783eecbe-1.1 {To Julian Day w/o OLE Automation} -setup {
           24  +  set minDateTime [object invoke -create -alias DateTime MinValue]
           25  +  set maxDateTime [object invoke -create -alias DateTime MaxValue]
           26  +
           27  +  set dateTimeValues [list $minDateTime "0099-12-31 00:00:00" \
           28  +      "0100-01-01 00:00:00" $maxDateTime]
           29  +} -body {
           30  +  set results [list]
           31  +
           32  +  foreach dateTimeValue $dateTimeValues {
           33  +    if {$dateTimeValue ni [info objects]} then {
           34  +      set dateTimeValue [object invoke \
           35  +          -create DateTime ParseExact $dateTimeValue \
           36  +          [getDateTimeFormat] null]
           37  +
           38  +      set dateTimeValue [object invoke -create -alias \
           39  +          DateTime SpecifyKind $dateTimeValue Utc]
           40  +    }
           41  +
           42  +    set code [catch {
           43  +      object invoke System.Data.SQLite.SQLiteConvert ToJulianDay \
           44  +          $dateTimeValue
           45  +    } result]
           46  +
           47  +    if {$code != 0} then {
           48  +      regexp -- {---> (.*?):} $result result result
           49  +      regexp -- {(System\..*?):} $result result result
           50  +    }
           51  +
           52  +    lappend results [list [$dateTimeValue ToString [getDateTimeFormat]] \
           53  +        $code $result]
           54  +  }
           55  +
           56  +  set results
           57  +} -cleanup {
           58  +  unset -nocomplain code result results dateTimeValue dateTimeValues \
           59  +      maxDateTime minDateTime
           60  +} -constraints {eagle System.Data.SQLite} -result {{{0001-01-01 00:00:00} 0\
           61  +1721425.5} {{0099-12-31 00:00:00Z} 0 1757583.5} {{0100-01-01 00:00:00Z} 0\
           62  +1757584.5} {{9999-12-31 23:59:59.9999999} 0 5373484.49999999}}}
           63  +
           64  +###############################################################################
           65  +
           66  +runTest {test tkt-3e783eecbe-1.2 {From Julian Day w/o OLE Automation} -setup {
           67  +  set minDoubleValue [object invoke -create -alias Double MinValue]
           68  +  set maxDoubleValue [object invoke -create -alias Double MaxValue]
           69  +
           70  +  set doubleValues [list \
           71  +      $minDoubleValue -1.0 0.0 1.0 1721425.5 1757583.5 2451910.5 \
           72  +      2456962.0 5373484.49999998 5373484.49999999 $maxDoubleValue]
           73  +} -body {
           74  +  set results [list]
           75  +
           76  +  foreach doubleValue $doubleValues {
           77  +    if {$doubleValue ni [info objects]} then {
           78  +      set doubleValue [object invoke \
           79  +          -create -alias Double Parse $doubleValue]
           80  +    }
           81  +
           82  +    set code [catch {
           83  +      set dateTimeValue [object invoke -create -alias \
           84  +          System.Data.SQLite.SQLiteConvert ToDateTime $doubleValue Utc]
           85  +
           86  +      $dateTimeValue ToString [getDateTimeFormat]
           87  +    } result]
           88  +
           89  +    if {$code != 0} then {
           90  +      regexp -- {---> (.*?):} $result result result
           91  +      regexp -- {(System\..*?):} $result result result
           92  +    }
           93  +
           94  +    lappend results [list [$doubleValue ToString] $code $result]
           95  +  }
           96  +
           97  +  set results
           98  +} -cleanup {
           99  +  unset -nocomplain code result results dateTimeValue doubleValue \
          100  +      doubleValues maxDoubleValue minDoubleValue
          101  +} -constraints {eagle System.Data.SQLite} -result {{-1.79769313486232E+308 1\
          102  +System.ArgumentException} {-1 1 System.ArgumentException} {0 1\
          103  +System.ArgumentException} {1 1 System.ArgumentException} {1721425.5 0\
          104  +{0001-01-01 00:00:00Z}} {1757583.5 0 {0099-12-31 00:00:00Z}} {2451910.5 0\
          105  +{2001-01-01 00:00:00Z}} {2456962 0 {2014-10-31 12:00:00Z}} {5373484.49999998 0\
          106  +{9999-12-31 23:59:59.998Z}} {5373484.49999999 0 {9999-12-31 23:59:59.999Z}}\
          107  +{1.79769313486232E+308 1 System.ArgumentException}}}
          108  +
          109  +###############################################################################
          110  +
          111  +runTest {test tkt-3e783eecbe-1.3 {Julian Day storage} -setup {
          112  +  set doubleValues [list \
          113  +      -1.0 0.0 1.0 1721425.5 1757583.5 2451910.5 2456962.0 \
          114  +      5373484.49999998 5373484.49999999]
          115  +
          116  +  setupDb [set fileName tkt-3e783eecbe-1.3.db] "" JulianDay
          117  +} -body {
          118  +  sql execute $db "CREATE TABLE t1(x INTEGER, y DATETIME);"
          119  +
          120  +  set i 1
          121  +  set results [list]
          122  +
          123  +  foreach doubleValue $doubleValues {
          124  +    if {$doubleValue ni [info objects]} then {
          125  +      set doubleValue [object invoke \
          126  +          -create -alias Double Parse $doubleValue]
          127  +    }
          128  +
          129  +    set code [catch {
          130  +      sql execute $db "INSERT INTO t1 (x, y) VALUES(?, ?);" \
          131  +          [list param1 Int32 $i] [list param2 Double $doubleValue]
          132  +
          133  +      sql execute -execute reader -format list -datetimeformat \
          134  +          [getDateTimeFormat] $db "SELECT y FROM t1 WHERE x = ?;" \
          135  +          [list param1 Int32 $i]
          136  +    } result]
          137  +
          138  +    if {$code != 0} then {
          139  +      regexp -- {---> (.*?):} $result result result
          140  +      regexp -- {(System\..*?):} $result result result
          141  +    }
          142  +
          143  +    lappend results [list [$doubleValue ToString] $code $result]
          144  +    incr i
          145  +  }
          146  +
          147  +  set results
          148  +} -cleanup {
          149  +  unset -nocomplain code result results i dateTimeValue doubleValue \
          150  +      doubleValues maxDoubleValue minDoubleValue
          151  +
          152  +  cleanupDb $fileName
          153  +
          154  +  unset -nocomplain db fileName
          155  +} -constraints \
          156  +{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
          157  +{{-1 1 System.ArgumentException} {0 1 System.ArgumentException} {1 1\
          158  +System.ArgumentException} {1721425.5 0 {{0001-01-01 00:00:00}}} {1757583.5 0\
          159  +{{0099-12-31 00:00:00}}} {2451910.5 0 {{2001-01-01 00:00:00}}} {2456962 0\
          160  +{{2014-10-31 12:00:00}}} {5373484.49999998 0 {{9999-12-31 23:59:59.998}}}\
          161  +{5373484.49999999 0 {{9999-12-31 23:59:59.999}}}}}
          162  +
          163  +###############################################################################
          164  +
          165  +runSQLiteTestEpilogue
          166  +runTestEpilogue

Added Tests/tkt-daeaf3150a.eagle.

            1  +###############################################################################
            2  +#
            3  +# tkt-daeaf3150a.eagle --
            4  +#
            5  +# Written by Joe Mistachkin.
            6  +# Released to the public domain, use at your own risk!
            7  +#
            8  +###############################################################################
            9  +
           10  +package require Eagle
           11  +package require Eagle.Library
           12  +package require Eagle.Test
           13  +
           14  +runTestPrologue
           15  +
           16  +###############################################################################
           17  +
           18  +package require System.Data.SQLite.Test
           19  +runSQLiteTestPrologue
           20  +
           21  +###############################################################################
           22  +
           23  +runTest {test tkt-daeaf3150a-1.1 {static Execute connection disposal} -setup {
           24  +  unset -nocomplain result sql
           25  +} -body {
           26  +  set sql(1) { \
           27  +    CREATE TABLE t1(x); \
           28  +    INSERT INTO t1 (x) VALUES (NULL); \
           29  +    SELECT x FROM t1 ORDER BY x; \
           30  +  }
           31  +
           32  +  set sql(2) { \
           33  +    CREATE TABLE t1(x); \
           34  +    INSERT INTO t1 (x) VALUES (?); \
           35  +    SELECT x FROM t1 ORDER BY x; \
           36  +  }
           37  +
           38  +  set result(1) [object invoke System.Data.SQLite.SQLiteCommand Execute \
           39  +      "this will not execute" None null]
           40  +
           41  +  set result(2) [object invoke System.Data.SQLite.SQLiteCommand Execute \
           42  +      $sql(1) NonQuery null]
           43  +
           44  +  set result(3) [object invoke System.Data.SQLite.SQLiteCommand Execute \
           45  +      $sql(1) Scalar null]
           46  +
           47  +  set result(4) [object invoke System.Data.SQLite.SQLiteCommand Execute \
           48  +      $sql(1) Reader null]
           49  +
           50  +  object invoke $result(4) Read; object invoke $result(4) Close
           51  +
           52  +  set result(5) [object invoke System.Data.SQLite.SQLiteCommand Execute \
           53  +      "this will not execute" None null 1]
           54  +
           55  +  set result(6) [object invoke System.Data.SQLite.SQLiteCommand Execute \
           56  +      $sql(2) NonQuery null 1]
           57  +
           58  +  set result(7) [object invoke System.Data.SQLite.SQLiteCommand Execute \
           59  +      $sql(2) Scalar null 1]
           60  +
           61  +  set result(8) [object invoke System.Data.SQLite.SQLiteCommand Execute \
           62  +      $sql(2) Reader null 1]
           63  +
           64  +  list $result(1) $result(2) $result(3) $result(4) $result(5) $result(6) \
           65  +      $result(7) $result(8)
           66  +} -cleanup {
           67  +  unset -nocomplain result sql
           68  +} -constraints {eagle monoBug28 SQLite System.Data.SQLite} -match regexp \
           69  +-result {^\{\} 1 System#DBNull#\d+ System#Data#SQLite#SQLiteDataReader#\d+ \{\}\
           70  +1 1 System#Data#SQLite#SQLiteDataReader#\d+$}}
           71  +
           72  +###############################################################################
           73  +
           74  +runSQLiteTestEpilogue
           75  +runTestEpilogue

Changes to readme.htm.

     2      2   <html>
     3      3   <head>
     4      4   <title></title>
     5      5   </head>
     6      6   <body>
     7      7   ADO.NET SQLite Data Provider<br />
     8      8   Version 1.0.95.0 November XX, 2014 <font color="red">(release scheduled)</font><br />
     9         -Using <a href="http://www.sqlite.org/releaselog/3_8_7.html">SQLite 3.8.7</a><br />
            9  +Using <a href="http://www.sqlite.org/releaselog/3_8_7_1.html">SQLite 3.8.7.1</a><br />
    10     10   Originally written by Robert Simpson<br />
    11     11   Released to the public domain, use at your own risk!<br />
    12     12   Official provider website:&nbsp;<a href="http://system.data.sqlite.org/">http://system.data.sqlite.org/</a><br />
    13     13   Legacy versions:&nbsp;<a href="http://sqlite.phxsoftware.com/">http://sqlite.phxsoftware.com/</a><br />
    14     14   <br />
    15     15   The current development version can be downloaded from <a href="http://system.data.sqlite.org/index.html/timeline?y=ci">
    16     16   http://system.data.sqlite.org/index.html/timeline?y=ci</a>
................................................................................
   211    211   <p>
   212    212       <b>1.0.95.0 - November XX, 2014 <font color="red">(release scheduled)</font></b>
   213    213   </p>
   214    214   <ul>
   215    215       <li>Updated to <a href="http://www.sqlite.org/releaselog/3_8_7.html">SQLite 3.8.7</a>.</li>
   216    216       <li>Make sure SQL statements generated for DbUpdateCommandTree objects are properly delimited.</li>
   217    217       <li>Various minor performance enhancements to the SQLiteDataReader class. Pursuant to [e122d26e70].</li>
          218  +    <li>Defer disposing of connections created by the static SQLiteCommand.Execute method when a data reader is returned. Fix for [daeaf3150a].</li>
          219  +    <li>Wrap SELECT statements in parenthesis if they have an ORDER BY, LIMIT, or OFFSET clause and a compound operator is involved. Fix for [0a32885109].</li>
   218    220       <li>In the SQLiteDataReader.VerifyType method, remove duplicate &quot;if&quot; statement for the DbType.SByte value and move the remaining &quot;if&quot; to the Int64 affinity. Fix for [c5cc2fb334].&nbsp;<b>** Potentially Incompatible Change **</b></li>
          221  +    <li>Handle Julian Day values that fall outside of the supported range for OLE Automation dates. Fix for [3e783eecbe].&nbsp;<b>** Potentially Incompatible Change **</b></li>
   219    222   </ul>
   220    223   <p>
   221    224       <b>1.0.94.0 - September 9, 2014</b>
   222    225   </p>
   223    226   <ul>
   224    227       <li>Updated to <a href="http://www.sqlite.org/releaselog/3_8_6.html">SQLite 3.8.6</a>.</li>
   225    228       <li>Updated to <a href="http://www.nuget.org/packages/EntityFramework/6.1.1">Entity Framework 6.1.1</a>.</li>

Changes to testlinq/Program.cs.

    72     72   
    73     73                             if (arg != null)
    74     74                                 pageSize = int.Parse(arg.Trim());
    75     75                         }
    76     76   
    77     77                         return SkipTest(pageSize);
    78     78                     }
           79  +              case "unionall":
           80  +                  {
           81  +                      return UnionAllTest();
           82  +                  }
    79     83                 case "endswith":
    80     84                     {
    81     85                         string value = null;
    82     86   
    83     87                         if (args.Length > 1)
    84     88                         {
    85     89                             value = args[1];
................................................................................
   213    217                         Console.Write(' ');
   214    218   
   215    219                     Console.Write(customers.CustomerID);
   216    220   
   217    221                     once = true;
   218    222                 }
   219    223             }
          224  +
          225  +          return 0;
          226  +      }
          227  +
          228  +      //
          229  +      // NOTE: Used to test the fix for ticket [0a32885109].
          230  +      //
          231  +      private static int UnionAllTest()
          232  +      {
          233  +          using (northwindEFEntities db = new northwindEFEntities())
          234  +          {
          235  +              bool once = false;
          236  +
          237  +              var customers1 = db.Customers.Where(
          238  +                  f => f.Orders.Any()).OrderByDescending(
          239  +                    f => f.CompanyName).Skip(1).Take(1);
          240  +
          241  +              var customers2 = db.Customers.Where(
          242  +                  f => f.Orders.Any()).OrderBy(
          243  +                    f => f.CompanyName).Skip(1).Take(1);
          244  +
          245  +              var customers3 = db.Customers.Where(
          246  +                  f => f.CustomerID.StartsWith("B")).OrderBy(
          247  +                    f => f.CompanyName).Skip(1).Take(1);
          248  +
          249  +              foreach (var customer in customers1)
          250  +              {
          251  +                  if (once)
          252  +                      Console.Write(' ');
          253  +
          254  +                  Console.Write(customer.CustomerID);
          255  +                  once = true;
          256  +              }
          257  +
          258  +              foreach (var customer in customers2)
          259  +              {
          260  +                  if (once)
          261  +                      Console.Write(' ');
          262  +
          263  +                  Console.Write(customer.CustomerID);
          264  +                  once = true;
          265  +              }
          266  +
          267  +              foreach (var customer in customers3)
          268  +              {
          269  +                  if (once)
          270  +                      Console.Write(' ');
          271  +
          272  +                  Console.Write(customer.CustomerID);
          273  +                  once = true;
          274  +              }
          275  +
          276  +              foreach (var customer in customers1.Concat(customers2))
          277  +              {
          278  +                  if (once)
          279  +                      Console.Write(' ');
          280  +
          281  +                  Console.Write(customer.CustomerID);
          282  +                  once = true;
          283  +              }
          284  +
          285  +              foreach (var customer in
          286  +                    customers1.Concat(customers2).Concat(customers3))
          287  +              {
          288  +                  if (once)
          289  +                      Console.Write(' ');
          290  +
          291  +                  Console.Write(customer.CustomerID);
          292  +                  once = true;
          293  +              }
          294  +          }
   220    295   
   221    296             return 0;
   222    297         }
   223    298   
   224    299         //
   225    300         // NOTE: Used to test the fix for ticket [ccfa69fc32].
   226    301         //

Changes to www/news.wiki.

     2      2   
     3      3   <b>Version History</b>
     4      4   
     5      5   <p>
     6      6       <b>1.0.95.0 - November XX, 2014 <font color="red">(release scheduled)</font></b>
     7      7   </p>
     8      8   <ul>
     9         -    <li>Updated to [http://www.sqlite.org/releaselog/3_8_7.html|SQLite 3.8.7].</li>
            9  +    <li>Updated to [http://www.sqlite.org/releaselog/3_8_7_1.html|SQLite 3.8.7.1].</li>
    10     10       <li>Make sure SQL statements generated for DbUpdateCommandTree objects are properly delimited.</li>
    11     11       <li>Various minor performance enhancements to the SQLiteDataReader class. Pursuant to [e122d26e70].</li>
           12  +    <li>Defer disposing of connections created by the static SQLiteCommand.Execute method when a data reader is returned. Fix for [daeaf3150a].</li>
           13  +    <li>Wrap SELECT statements in parenthesis if they have an ORDER BY, LIMIT, or OFFSET clause and a compound operator is involved. Fix for [0a32885109].</li>
    12     14       <li>In the SQLiteDataReader.VerifyType method, remove duplicate &quot;if&quot; statement for the DbType.SByte value and move the remaining &quot;if&quot; to the Int64 affinity.  Fix for [c5cc2fb334].&nbsp;<b>** Potentially Incompatible Change **</b></li>
           15  +    <li>Handle Julian Day values that fall outside of the supported range for OLE Automation dates. Fix for [3e783eecbe].&nbsp;<b>** Potentially Incompatible Change **</b></li>
    13     16   </ul>
    14     17   <p>
    15     18       <b>1.0.94.0 - September 9, 2014</b>
    16     19   </p>
    17     20   <ul>
    18     21       <li>Updated to [http://www.sqlite.org/releaselog/3_8_6.html|SQLite 3.8.6].</li>
    19     22       <li>Updated to [http://www.nuget.org/packages/EntityFramework/6.1.1|Entity Framework 6.1.1].</li>