Index: Doc/Extra/dbfactorysupport.html ================================================================== --- Doc/Extra/dbfactorysupport.html +++ Doc/Extra/dbfactorysupport.html @@ -83,11 +83,11 @@ <DbProviderFactories> <remove invariant="System.Data.SQLite"/> <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, - Version=1.0.78.0, Culture=neutral, + Version=1.0.81.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139"/> </DbProviderFactories> </system.data> </configuration> Index: Doc/Extra/designer.html ================================================================== --- Doc/Extra/designer.html +++ Doc/Extra/designer.html @@ -48,22 +48,22 @@ SQLite databases from within Visual Studio is a great time-saver.  Though the support is not yet fully-implemented, there's certainly enough there to keep you busy.  You can create databases, design and execute queries, create typed datasets and lots more all from Visual Studio.

Installation Instructions

-

- In Windows Explorer, navigate to SQLite.Net\bin\Designer - and execute the INSTALL.EXE program.  It will automatically - detect what eligible Visual Studio products are installed, and allow you to check - and uncheck which environments to install the designer for.

+

Download and run one of the setup packages and then select the "Install + the designer components for Visual Studio 20XX." option when prompted.

Express Edition Limitations

-

All Express Editions (except Visual Web Developer) are hard-coded to only allow you to design for Jet and Sql Server Database Files.  The only way for SQLite - to install its designer is to temporarily replace one of the existing "approved" - designers.  Therefore, when you install the SQLite designer for one of these - express editions, it will temporarily replace the Microsoft Access designer.  - You can revert back to the Access designer simply by re-running the install.exe - program and un-checking the boxes.

+

Visual Studio design-time Support, works with all versions of Visual Studio + 2005/2008/2010. You can add a SQLite database to the Servers list, design + queries with the Query Designer, drag-and-drop tables onto a Typed DataSet, etc. +
+ + Due to Visual Studio licensing restrictions, the Express Editions can no + longer be supported. + +


Version History

-

1.0.78.0 - January XX, 2012

+

1.0.81.0 - June XX, 2012

+ +

1.0.80.0 - April 1, 2012

+ +

1.0.79.0 - January 28, 2012

+ +

1.0.78.0 - January 27, 2012

About SQLite.NET

-

This class library is an ADO.NET wrapper around the popular (and free!) - SQLite database engine. For information on SQL syntax, features of SQLite and a - good understanding of how it works and what it does, I highly recommend heading - over to sqlite.org and +

This class library is an ADO.NET wrapper around the popular (and free!) + SQLite database engine. For information on SQL syntax, features of SQLite and a + good understanding of how it works and what it does, I highly recommend heading + over to sqlite.org and reading the documentation there.

-

The C# provider, the very minor C code modifications to SQLite, documentation and - etc were written by Robert +

The C# provider, the very minor C code modifications to SQLite, documentation and + etc were written by Robert Simpson, and the SourceForge project page can be found here.

+

The System.Data.SQLite project is currently maintained by the + SQLite Development Team and + the latest source code and project information can be found + here.


What's New?

-

Click here to see the version history of this SQLite.NET +

Click here to see the version history of this SQLite.NET provider


Using this library

-

The following are links to information on various aspects of the library and +

The following are links to information on various aspects of the library and how to use it in your application(s)

How to install Visual Studio Design-Time Support

-

How to configure and enumerate SQLite.NET +

How to configure and enumerate SQLite.NET through the DbProviderFactories object

Getting the best performance out of SQLite

-

Limitations of the SQLite.NET provider and the SQLite +

Limitations of the SQLite.NET provider and the SQLite engine (compared to other providers and engines)


SQLite.NET Provider Features

-

This SQLite provider implements every feature of the underlying SQLite +

This SQLite provider implements every feature of the underlying SQLite database engine without omission. Here's a brief summary:

  • - Written from scratch on VS2005/2008 specifically for ADO.NET, implenting all the + Written from scratch on Visual Studio 2008 specifically for ADO.NET, implenting all the base classes and features recently introduced in the framework, including automatic transaction enlistment.
  • Supports the Full and Compact .NET Framework, as well as native C/C++ development.  100% binary compatible with the original sqlite3.dll.
  • -
  • Full support for Mono via a "managed only" provider that runs against the +
  • Full support for Mono via a "managed only" provider that runs against the official SQLite 3.6.1 or higher library.
  • Full Entity Framework support (ADO.NET 3.5 SP1)
  • On the Compact Framework, it is faster than Sql Server Mobile. SQLite's installed size is a fraction of Sql Mobile's. It uses less memory at runtime, runs queries faster, and has a smaller database file size as well.
  • Encrypted database support.  Encrypted databases are fully encrypted and support both binary and cleartext password types.
  • -
  • Visual Studio 2005/2008 Design-Time Support.  You can add a SQLite - database to the Servers list, design queries with the Query Designer, +
  • Visual Studio 2005/2008/2010 Design-Time Support.  You can add a SQLite + database to the Servers list, design queries with the Query Designer, drag-and-drop tables onto a Typed DataSet, etc.
  • -
  • Full SQLite schema editing inside Visual Studio.  You can create/edit +
  • Full SQLite schema editing inside Visual Studio.  You can create/edit tables, views, triggers, indexes, check constraints and foreign keys.
  • - Single file redistributable (except Compact Framework).  The core sqlite3 codebase and the ADO.NET wrapper + Available as a single file redistributable (except Compact Framework).  The core sqlite3 codebase and the ADO.NET wrapper are combined into one multi-module assembly.
  • -
  • Binaries included for Itanium, x64, x86 and ARM processors.
  • +
  • Also available as separate native and managed assemblies and optionally with the Visual C++ Runtime statically linked.
  • +
  • + Binaries included for Itanium, x64, x86 and ARM processors. +
    + + Itanium processor support not currently included. + +
  • DbProviderFactory support.
  • Full support for ATTACH'ed databases.  Exposed as Catalogs - in the schema.  When cloning a connection, all attached databases are + in the schema.  When cloning a connection, all attached databases are automatically re-attached to the new connection.
  • DbConnection.GetSchema(...) support includes the MetaDataCollections, DataSourceInformation, Columns, Tables, Views, ViewColumns, - Catalogs, Indexes, + Catalogs, Indexes, IndexColumns, ForeignKeys and Triggers.
  • - Enhanced DbDataReader.GetSchemaTable() functionality returns catalog, namespace + Enhanced DbDataReader.GetSchemaTable() functionality returns catalog, namespace and detailed schema information even for complex queries.
  • Named and unnamed parameters.
  • - Full UTF-8 and UTF-16 support, each with optimized pipelines into the native + Full UTF-8 and UTF-16 support, each with optimized pipelines into the native database core.
  • Multiple simultaneous DataReaders (one DataReader per Command however).
  • - Full support for user-defined scalar and aggregate functions, encapsulated into - an easy-to-use base class in which only a couple of overrides are necessary to + Full support for user-defined scalar and aggregate functions, encapsulated into + an easy-to-use base class in which only a couple of overrides are necessary to implement new SQL functions.
  • - Full support for user-defined collating sequences, every bit as simple to + Full support for user-defined collating sequences, every bit as simple to implement as user-defined functions and uses the same base class.
  • - Full source for the entire engine and wrapper.  No copyrights.  + Full source for the entire engine and wrapper.  No copyrights.  Public Domain.  100% free for commercial and non-commercial use. 

Distributing the Binaries (Desktop)

-

System.Data.SQLite.DLL is a mixed assembly signed with a strong name - in case you want to add it to the Global Assembly Cache (GAC). This is the only DLL required to be redistributed with - your SQLite.NET application(s).  It - comes in 3 - flavors: Win32, Itanium and x64 (AMD64).

+

When using the mixed-mode assembly, the System.Data.SQLite.DLL file + includes all the native and managed code. In that case, this is the only + DLL required to be redistributed with your SQLite.NET application(s).  + When using separate native and managed assemblies, the + System.Data.SQLite.DLL file contains all the managed code and the + SQLite.Interop.DLL file contains all the native code. + The native code comes in 3 flavors: Win32, Itanium and x64 (AMD64). +
+ + Itanium processor support not currently included. + +

Distributing the Binaries (Compact Framework)

-

System.Data.SQLite.DLL and SQLite.Interop.XXX.DLL must be - deployed on the Compact Framework.  The XXX is the build number of the - System.Data.SQLite library (e.g. "078").  SQLite.Interop.XXX is a fully - native assembly compiled for the ARM processor, and System.Data.SQLite is the - fully-managed Compact Framework assembly.

+

Both the System.Data.SQLite.DLL and SQLite.Interop.XXX.DLL files + must be deployed on the Compact Framework.  The XXX is the build number of + the System.Data.SQLite library (e.g. "081").  The + SQLite.Interop.XXX.DLL file is a fully native assembly compiled for + the ARM processor, and System.Data.SQLite is the fully-managed Compact + Framework assembly.


Index: Doc/SQLite.NET.chm ================================================================== --- Doc/SQLite.NET.chm +++ Doc/SQLite.NET.chm cannot compute difference between binary files Index: Externals/Eagle/bin/Eagle.dll ================================================================== --- Externals/Eagle/bin/Eagle.dll +++ Externals/Eagle/bin/Eagle.dll cannot compute difference between binary files Index: Externals/Eagle/bin/EagleShell.exe ================================================================== --- Externals/Eagle/bin/EagleShell.exe +++ Externals/Eagle/bin/EagleShell.exe cannot compute difference between binary files Index: Externals/Eagle/bin/EagleShell.exe.config ================================================================== --- Externals/Eagle/bin/EagleShell.exe.config +++ Externals/Eagle/bin/EagleShell.exe.config @@ -1,11 +1,11 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {1B7C6ACE-35AA-481C-9CF6-56B702E3E043} + Library + Properties + SQLiteProvider + SQLiteProvider + $(MSBuildProjectDirectory)\.. + true + 2005 + + + + $(BinaryOutputPath) + + + true + full + false + DEBUG;TRACE + prompt + + + pdbonly + true + TRACE + prompt + + + + + + + + + + + + + True + True + Settings.settings + + + + + True + True + ApplicationSql.resx + + + True + True + MembershipSql.resx + + + + True + True + RoleSql.resx + + + + + + + True + True + SiteMapSql.resx + SQLiteProvider + + + + + + + Designer + ResXFileCodeGenerator + ApplicationSql.Designer.cs + SQLiteProvider + + + Designer + ResXFileCodeGenerator + MembershipSql.Designer.cs + SQLiteProvider + + + Designer + ResXFileCodeGenerator + RoleSql.Designer.cs + SQLiteProvider + + + Designer + ResXFileCodeGenerator + SiteMapSql.Designer.cs + SQLiteProvider + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + + Index: SQLite.Designer/AssemblyInfo.cs ================================================================== --- SQLite.Designer/AssemblyInfo.cs +++ SQLite.Designer/AssemblyInfo.cs @@ -41,7 +41,7 @@ // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.78.0")] -[assembly: AssemblyFileVersion("1.0.78.0")] +[assembly: AssemblyVersion("1.0.81.0")] +[assembly: AssemblyFileVersion("1.0.81.0")] Index: SQLite.Designer/Design/ForeignKey.cs ================================================================== --- SQLite.Designer/Design/ForeignKey.cs +++ SQLite.Designer/Design/ForeignKey.cs @@ -281,11 +281,13 @@ } [DefaultProperty("From")] internal class ForeignKey : IHaveConnection, ICloneable { - internal Table _table; + internal Table _table; + internal int _id; + internal int _ordinal; internal ForeignKeyFromItem _from; internal ForeignKeyToItem _to; internal string _name; internal string _onUpdate; internal string _onDelete; @@ -292,11 +294,13 @@ internal string _match; private bool _dirty; private ForeignKey(ForeignKey source) { - _table = source._table; + _table = source._table; + _id = source._id; + _ordinal = source._ordinal; _from = new ForeignKeyFromItem(this, source._from.Column); _to = new ForeignKeyToItem(this, source._to.Catalog, source._to.Table, source._to.Column); _name = source._name; _onUpdate = source._onUpdate; _onDelete = source._onDelete; @@ -322,20 +326,24 @@ internal ForeignKey(DbConnection cnn, Table table, DataRow row) { _table = table; if (row != null) - { + { + _id = (int)row["FKEY_ID"]; + _ordinal = (int)row["FKEY_FROM_ORDINAL_POSITION"]; _from = new ForeignKeyFromItem(this, row["FKEY_FROM_COLUMN"].ToString()); _to = new ForeignKeyToItem(this, row["FKEY_TO_CATALOG"].ToString(), row["FKEY_TO_TABLE"].ToString(), row["FKEY_TO_COLUMN"].ToString()); _name = row["CONSTRAINT_NAME"].ToString(); _onUpdate = row["FKEY_ON_UPDATE"].ToString(); _onDelete = row["FKEY_ON_DELETE"].ToString(); _match = row["FKEY_MATCH"].ToString(); } else - { + { + _id = -1; + _ordinal = -1; _from = new ForeignKeyFromItem(this, ""); _to = new ForeignKeyToItem(this, _table.Catalog, "", ""); } } @@ -355,11 +363,11 @@ { get { if (String.IsNullOrEmpty(_name) == false) return _name; - return String.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}_{2}_{3}", _from.Table, _from.Column, _to.Table, _to.Column); + return String.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}_{2}", _from.Table, _id, _ordinal); } set { if (_name != value) { @@ -380,11 +388,27 @@ public DbConnection GetConnection() { return ((IHaveConnection)_table).GetConnection(); } - #endregion + #endregion + + [DisplayName("Id")] + [Category("Id")] + [Description("The identifier of this foreign key.")] + public int Id + { + get { return _id; } + } + + [DisplayName("Ordinal")] + [Category("Ordinal")] + [Description("The column ordinal of this foreign key.")] + public int Ordinal + { + get { return _ordinal; } + } [DisplayName("From Key")] [Category("From")] [Description("The source column in the current table that refers to the foreign key.")] public ForeignKeyFromItem From Index: SQLite.Designer/Design/Table.cs ================================================================== --- SQLite.Designer/Design/Table.cs +++ SQLite.Designer/Design/Table.cs @@ -406,39 +406,15 @@ } } builder.Append(separator); builder.AppendFormat("CONSTRAINT [CK_{0}_{1}] CHECK {2}", Name, n + 1, check); } - - List keys = new List(); - - for (int x = 0; x < ForeignKeys.Count; x++) - { - ForeignKey key = ForeignKeys[x]; - - if (String.IsNullOrEmpty(key.From.Column) == true || String.IsNullOrEmpty(key.From.Catalog) == true || - String.IsNullOrEmpty(key.To.Table) == true || String.IsNullOrEmpty(key.To.Column) == true) - continue; - - if (keys.Count > 0) - { - if (keys[0].Name == key.Name && keys[0].To.Catalog == key.To.Catalog && keys[0].To.Table == key.To.Table) - { - keys.Add(key); - continue; - } - builder.Append(separator); - WriteFKeys(keys, builder); - keys.Clear(); - } - keys.Add(key); - } - - if (keys.Count > 0) - { - builder.Append(separator); - WriteFKeys(keys, builder); + + if (ForeignKeys.Count > 0) + { + builder.Append(separator); + WriteFKeys(ForeignKeys, builder); } builder.Append("\r\n);\r\n"); // Rebuilding an existing table @@ -494,41 +470,66 @@ } builder.AppendLine(); } return builder.ToString(); - } - - private void WriteFKeys(List keys, StringBuilder builder) - { - builder.AppendFormat("CONSTRAINT [{0}] FOREIGN KEY (", keys[0].Name); - string separator = ""; - - foreach (ForeignKey key in keys) - { - builder.AppendFormat("{0}[{1}]", separator, key.From.Column); - separator = ", "; - } - - builder.AppendFormat(") REFERENCES [{0}] (", keys[0].To.Table); - - separator = ""; - foreach (ForeignKey key in keys) - { - builder.AppendFormat("{0}[{1}]", separator, key.To.Column); - separator = ", "; - } - builder.Append(")"); - - if (!String.IsNullOrEmpty(keys[0].Match)) - builder.AppendFormat(" MATCH {0}", keys[0].Match); - - if (!String.IsNullOrEmpty(keys[0].OnUpdate)) - builder.AppendFormat(" ON UPDATE {0}", keys[0].OnUpdate); - - if (!String.IsNullOrEmpty(keys[0].OnDelete)) - builder.AppendFormat(" ON DELETE {0}", keys[0].OnDelete); + } + + private void WriteFKeys(List keys, StringBuilder builder) + { + for (int index = 0; index < keys.Count; ) + { + ForeignKey key = keys[index]; + + if (index > 0) + builder.Append(",\r\n "); + + builder.AppendFormat( + "CONSTRAINT [{0}] FOREIGN KEY (", key.Name); + + int startIndex = index; + + do + { + builder.AppendFormat("{0}[{1}]", + index > startIndex ? ", " : String.Empty, + keys[index].From.Column); + + index++; + } while (index < keys.Count && keys[index].Id == key.Id); + + builder.AppendFormat(") REFERENCES [{0}]", key.To.Table); + + if (!String.IsNullOrEmpty(key.To.Column)) + { + builder.Append(" ("); + index = startIndex; + + do + { + builder.AppendFormat("{0}[{1}]", + index > startIndex ? ", " : String.Empty, + keys[index].To.Column); + + index++; + } while (index < keys.Count && keys[index].Id == key.Id); + + builder.Append(')'); + } + + if (!String.IsNullOrEmpty(key.Match)) + builder.AppendFormat(" MATCH {0}", key.Match); + + if (!String.IsNullOrEmpty(key.OnUpdate)) + builder.AppendFormat(" ON UPDATE {0}", key.OnUpdate); + + if (!String.IsNullOrEmpty(key.OnDelete)) + builder.AppendFormat(" ON DELETE {0}", key.OnDelete); + + if (index == startIndex) + index++; + } } [Browsable(false)] public override ViewTableBase DesignTable { ADDED SQLite.Designer/SQLite.Designer.2005.csproj Index: SQLite.Designer/SQLite.Designer.2005.csproj ================================================================== --- /dev/null +++ SQLite.Designer/SQLite.Designer.2005.csproj @@ -0,0 +1,220 @@ + + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198} + Library + Properties + SQLite.Designer + SQLite.Designer + $(MSBuildProjectDirectory)\.. + true + 2005 + + + + + $(BinaryOutputPath) + $(BinaryOutputPath)SQLite.Designer.xml + + + true + full + false + DEBUG;TRACE + prompt + + + pdbonly + true + TRACE + prompt + + + + + + + + + + False + + + False + False + + + False + + + False + False + + + False + + + False + + + False + + + False + + + + + + Form + + + ChangePasswordDialog.cs + + + Form + + + ChangeScriptDialog.cs + + + + + + + + + + + + + Component + + + UserControl + + + TableDesignerDoc.cs + + + UserControl + + + ViewDesignerDoc.cs + + + + + + + + UserControl + + + SQLiteConnectionUIControl.cs + + + + + + + + + + + Form + + + TableNameDialog.cs + + + True + True + VSPackage.resx + + + + + 1000 + + + + + + ResXFileCodeGenerator + VSPackage.Designer.cs + true + Designer + + + + + Designer + ChangePasswordDialog.cs + + + Designer + TableDesignerDoc.cs + + + ViewDesignerDoc.cs + + + Designer + SQLiteConnectionUIControl.cs + + + + TableNameDialog.cs + + + + + ChangeScriptDialog.cs + + + + + + + + + + + $(ProgramFiles)\Visual Studio 2005 SDK\2007.02\ + $(ProgramFiles%28x86%29)\Visual Studio 2005 SDK\2007.02\ + + + + + MissingVsSdk + + + + Index: SQLite.Designer/SQLite.Designer.2008.csproj ================================================================== --- SQLite.Designer/SQLite.Designer.2008.csproj +++ SQLite.Designer/SQLite.Designer.2008.csproj @@ -22,10 +22,11 @@ $(MSBuildProjectDirectory)\.. true 2008 + $(BinaryOutputPath) $(BinaryOutputPath)SQLite.Designer.xml @@ -46,35 +47,37 @@ - - False - - - False - - - False - - - False - - - False - - - False - - - False - - - False - - + + False + + + False + False + + + False + + + False + False + + + False + + + False + + + False + + + False + + False @@ -150,13 +153,11 @@ 1000 - - ResXFileCodeGenerator VSPackage.Designer.cs true Designer @@ -193,13 +194,28 @@ + + + + MissingVsSdk + + - + Index: SQLite.Designer/SQLite.Designer.2010.csproj ================================================================== --- SQLite.Designer/SQLite.Designer.2010.csproj +++ SQLite.Designer/SQLite.Designer.2010.csproj @@ -21,10 +21,11 @@ 3.5 $(MSBuildProjectDirectory)\.. 2010 + $(BinaryOutputPath) $(BinaryOutputPath)SQLite.Designer.xml @@ -45,35 +46,37 @@ - - False - - - False - - - False - - - False - - - False - - - False - - - False - - - False - - + + False + + + False + False + + + False + + + False + False + + + False + + + False + + + False + + + False + + False @@ -149,12 +152,10 @@ 1000 - - ResXFileCodeGenerator VSPackage.Designer.cs true @@ -192,13 +193,28 @@ + + + + MissingVsSdk + + Index: SQLite.Designer/SQLiteDataViewSupport2005.xml ================================================================== --- SQLite.Designer/SQLiteDataViewSupport2005.xml +++ SQLite.Designer/SQLiteDataViewSupport2005.xml @@ -76,16 +76,17 @@ - - - + + + + Columns @@ -144,10 +145,11 @@ + Columns @@ -170,10 +172,11 @@ + @@ -188,11 +191,11 @@ - + @@ -220,11 +223,11 @@ - + DELETED SQLite.Designer/VSDesign/Microsoft.Data.ConnectionUI.dll Index: SQLite.Designer/VSDesign/Microsoft.Data.ConnectionUI.dll ================================================================== --- SQLite.Designer/VSDesign/Microsoft.Data.ConnectionUI.dll +++ /dev/null cannot compute difference between binary files DELETED SQLite.Designer/VSDesign/Microsoft.VisualStudio.CommandBars.dll Index: SQLite.Designer/VSDesign/Microsoft.VisualStudio.CommandBars.dll ================================================================== --- SQLite.Designer/VSDesign/Microsoft.VisualStudio.CommandBars.dll +++ /dev/null cannot compute difference between binary files DELETED SQLite.Designer/VSDesign/Microsoft.VisualStudio.Data.dll Index: SQLite.Designer/VSDesign/Microsoft.VisualStudio.Data.dll ================================================================== --- SQLite.Designer/VSDesign/Microsoft.VisualStudio.Data.dll +++ /dev/null cannot compute difference between binary files DELETED SQLite.Designer/VSDesign/Microsoft.VisualStudio.OLE.Interop.dll Index: SQLite.Designer/VSDesign/Microsoft.VisualStudio.OLE.Interop.dll ================================================================== --- SQLite.Designer/VSDesign/Microsoft.VisualStudio.OLE.Interop.dll +++ /dev/null cannot compute difference between binary files DELETED SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.Interop.8.0.dll Index: SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.Interop.8.0.dll ================================================================== --- SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.Interop.8.0.dll +++ /dev/null cannot compute difference between binary files DELETED SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.Interop.dll Index: SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.Interop.dll ================================================================== --- SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.Interop.dll +++ /dev/null cannot compute difference between binary files DELETED SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.dll Index: SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.dll ================================================================== --- SQLite.Designer/VSDesign/Microsoft.VisualStudio.Shell.dll +++ /dev/null cannot compute difference between binary files DELETED SQLite.Designer/VSDesign/envdte.dll Index: SQLite.Designer/VSDesign/envdte.dll ================================================================== --- SQLite.Designer/VSDesign/envdte.dll +++ /dev/null cannot compute difference between binary files Index: SQLite.Designer/VSPackage.Designer.cs ================================================================== --- SQLite.Designer/VSPackage.Designer.cs +++ SQLite.Designer/VSPackage.Designer.cs @@ -66,11 +66,11 @@ resourceCulture = value; } } /// - /// Looks up a localized string similar to MHM2ZQETQKDTJEPTC1MTQCZ1R1KQEMAPZHETDZPZI9RPJ0E0DHAHKCHZPKQ8AQZICADHKIZ1JAQED8IDEHZPZKZEIKAQERHPRCQMAMRKDEZZQRDRDHJEZIKECZPDIIKC. + /// Looks up a localized string similar to RZE1PAAIMRZRE2CKM3CIRRIREIJQR1PTAEHTRHKTCPP1KKRRJQK9CTM9ZHMRETI9E9J8REKEA1MER9PDKQDIH8HMRRH2DIACHIP1KHK2IAZKM8R0EZRTKDHADII9ICCH. /// internal static string _400 { get { return ResourceManager.GetString("400", resourceCulture); } Index: SQLite.Designer/VSPackage.resx ================================================================== --- SQLite.Designer/VSPackage.resx +++ SQLite.Designer/VSPackage.resx @@ -125,11 +125,11 @@ The database and its metadata will be re-encrypted using the supplied password as a hash. - MHM2ZQETQKDTJEPTC1MTQCZ1R1KQEMAPZHETDZPZI9RPJ0E0DHAHKCHZPKQ8AQZICADHKIZ1JAQED8IDEHZPZKZEIKAQERHPRCQMAMRKDEZZQRDRDHJEZIKECZPDIIKC + RZE1PAAIMRZRE2CKM3CIRRIREIJQR1PTAEHTRHKTCPP1KKRRJQK9CTM9ZHMRETI9E9J8REKEA1MER9PDKQDIH8HMRRH2DIACHIP1KHK2IAZKM8R0EZRTKDHADII9ICCH Resources\info.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ADDED SQLite.Designer/plk.txt Index: SQLite.Designer/plk.txt ================================================================== --- /dev/null +++ SQLite.Designer/plk.txt @@ -0,0 +1,24 @@ +Package Load Key (PLK) + + RZE1PAAIMRZRE2CKM3CIRRIREIJQR1PTAEHTRHKTCPP1KKRRJQK9CTM9ZHMRETI9 + E9J8REKEA1MER9PDKQDIH8HMRRH2DIACHIP1KHK2IAZKM8R0EZRTKDHADII9ICCH + +Company Name + + http://system.data.sqlite.org/ + +Package Name + + System.Data.SQLite Designer Package + +Package GUID + + {dcbe6c8d-0e57-4099-a183-98ff74c64d9c} + +PLK Version + + 1.0 + +Min. Visual Studio Version + + Visual Studio 2005 Index: SQLite.Designer/source.extension.vsixmanifest ================================================================== --- SQLite.Designer/source.extension.vsixmanifest +++ SQLite.Designer/source.extension.vsixmanifest @@ -1,11 +1,11 @@ - SQLite Designer - Robert Simpson - 1.0.38.1 + System.Data.SQLite Designer + http://system.data.sqlite.org/ + 1.0.81.0 ADO.NET Data Designer for SQLite 1033 false ADDED SQLite.Interop/SQLite.Interop.2005.vcproj Index: SQLite.Interop/SQLite.Interop.2005.vcproj ================================================================== --- /dev/null +++ SQLite.Interop/SQLite.Interop.2005.vcproj @@ -0,0 +1,1183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: SQLite.Interop/SQLite.Interop.2008.vcproj ================================================================== --- SQLite.Interop/SQLite.Interop.2008.vcproj +++ SQLite.Interop/SQLite.Interop.2008.vcproj @@ -30,11 +30,11 @@ @@ -51,11 +51,11 @@ Name="VCMIDLTool" /> @@ -148,11 +148,11 @@ TargetEnvironment="3" /> @@ -244,11 +244,11 @@ Name="VCMIDLTool" /> @@ -335,11 +335,11 @@ TargetEnvironment="3" /> @@ -1167,11 +1167,11 @@ Index: SQLite.Interop/SQLite.Interop.2010.vcxproj ================================================================== --- SQLite.Interop/SQLite.Interop.2010.vcxproj +++ SQLite.Interop/SQLite.Interop.2010.vcxproj @@ -48,11 +48,11 @@ SQLite.Interop Win32Proj - + true Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default MultiThreadedDebugDLL Level4 ProgramDatabase @@ -164,11 +164,11 @@ Disabled - WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions) + WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default MultiThreadedDebugDLL Level4 ProgramDatabase @@ -205,11 +205,11 @@ Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default MultiThreadedDebugDLL Level4 ProgramDatabase @@ -233,17 +233,18 @@ true $(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32 true - XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y + XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\$(Platform)\" /D /E /V /I /F /H /Y +XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y Disabled - WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions) + WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default MultiThreadedDebugDLL Level4 ProgramDatabase @@ -267,19 +268,20 @@ true $(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32 true - XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y + XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\$(Platform)\" /D /E /V /I /F /H /Y +XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y Full true Speed - WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default true MultiThreadedDLL Level4 @@ -318,11 +320,11 @@ Full true Speed - WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions) + WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default true MultiThreadedDLL Level4 @@ -361,11 +363,11 @@ Full true Speed - WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default true MultiThreadedDLL Level4 @@ -390,19 +392,20 @@ true $(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32 true - XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y + XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\$(Platform)\" /D /E /V /I /F /H /Y +XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y Full true Speed - WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions) + WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default true MultiThreadedDLL Level4 @@ -427,11 +430,12 @@ true $(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32 true - XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y + XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\$(Platform)\" /D /E /V /I /F /H /Y +XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y true @@ -446,11 +450,11 @@ true - + Index: SQLite.Interop/SQLite.Interop.2010.vcxproj.filters ================================================================== --- SQLite.Interop/SQLite.Interop.2010.vcxproj.filters +++ SQLite.Interop/SQLite.Interop.2010.vcxproj.filters @@ -44,11 +44,11 @@ Property Files - + Property Files ADDED SQLite.Interop/SQLite.Interop.CE.2005.vcproj Index: SQLite.Interop/SQLite.Interop.CE.2005.vcproj ================================================================== --- /dev/null +++ SQLite.Interop/SQLite.Interop.CE.2005.vcproj @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: SQLite.Interop/SQLite.Interop.CE.2008.vcproj ================================================================== --- SQLite.Interop/SQLite.Interop.CE.2008.vcproj +++ SQLite.Interop/SQLite.Interop.CE.2008.vcproj @@ -1,6 +1,14 @@ + @@ -47,13 +55,14 @@ /> @@ -144,12 +153,13 @@ @@ -240,13 +250,14 @@ /> @@ -333,13 +344,14 @@ /> @@ -427,12 +439,13 @@ @@ -522,12 +535,13 @@ ADDED SQLite.Interop/SQLite.Interop.Static.2005.vcproj Index: SQLite.Interop/SQLite.Interop.Static.2005.vcproj ================================================================== --- /dev/null +++ SQLite.Interop/SQLite.Interop.Static.2005.vcproj @@ -0,0 +1,1183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: SQLite.Interop/SQLite.Interop.Static.2008.vcproj ================================================================== --- SQLite.Interop/SQLite.Interop.Static.2008.vcproj +++ SQLite.Interop/SQLite.Interop.Static.2008.vcproj @@ -30,11 +30,11 @@ @@ -51,11 +51,11 @@ Name="VCMIDLTool" /> @@ -148,11 +148,11 @@ TargetEnvironment="3" /> @@ -244,11 +244,11 @@ Name="VCMIDLTool" /> @@ -335,11 +335,11 @@ TargetEnvironment="3" /> @@ -1167,11 +1167,11 @@ Index: SQLite.Interop/SQLite.Interop.Static.2010.vcxproj ================================================================== --- SQLite.Interop/SQLite.Interop.Static.2010.vcxproj +++ SQLite.Interop/SQLite.Interop.Static.2010.vcxproj @@ -48,11 +48,11 @@ SQLite.Interop Win32Proj - + true Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default MultiThreadedDebug Level4 ProgramDatabase @@ -164,11 +164,11 @@ Disabled - WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions) + WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default MultiThreadedDebug Level4 ProgramDatabase @@ -205,11 +205,11 @@ Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default MultiThreadedDebug Level4 ProgramDatabase @@ -233,17 +233,18 @@ true $(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32 true - XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y + XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\$(Platform)\" /D /E /V /I /F /H /Y +XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y Disabled - WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);%(PreprocessorDefinitions) + WIN32;x64;_DEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_DEBUG_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default MultiThreadedDebug Level4 ProgramDatabase @@ -267,19 +268,20 @@ true $(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32 true - XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y + XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\$(Platform)\" /D /E /V /I /F /H /Y +XCOPY "$(TargetPath)" "$(OutDir)..\..\Debug\bin\" /D /E /V /I /F /H /Y Full true Speed - WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default true MultiThreaded Level4 @@ -318,11 +320,11 @@ Full true Speed - WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions) + WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default true MultiThreaded Level4 @@ -361,11 +363,11 @@ Full true Speed - WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default true MultiThreaded Level4 @@ -390,19 +392,20 @@ true $(ProjectName), processorArchitecture=x86, version=$(INTEROP_MANIFEST_VERSION), type=win32 true - XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y + XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\$(Platform)\" /D /E /V /I /F /H /Y +XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y Full true Speed - WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);%(PreprocessorDefinitions) + WIN32;x64;NDEBUG;_WINDOWS;_USRDLL;$(SQLITE_COMMON_DEFINES);$(SQLITE_EXTRA_DEFINES);$(SQLITE_RELEASE_DEFINES);$(INTEROP_EXTRA_DEFINES);%(PreprocessorDefinitions) false Default true MultiThreaded Level4 @@ -427,11 +430,12 @@ true $(ProjectName), processorArchitecture=amd64, version=$(INTEROP_MANIFEST_VERSION), type=win32 true - XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y + XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\$(Platform)\" /D /E /V /I /F /H /Y +XCOPY "$(TargetPath)" "$(OutDir)..\..\Release\bin\" /D /E /V /I /F /H /Y true @@ -446,11 +450,11 @@ true - + Index: SQLite.Interop/SQLite.Interop.Static.2010.vcxproj.filters ================================================================== --- SQLite.Interop/SQLite.Interop.Static.2010.vcxproj.filters +++ SQLite.Interop/SQLite.Interop.Static.2010.vcxproj.filters @@ -44,11 +44,11 @@ Property Files - + Property Files ADDED SQLite.Interop/props/SQLite.Interop.2005.vsprops Index: SQLite.Interop/props/SQLite.Interop.2005.vsprops ================================================================== --- /dev/null +++ SQLite.Interop/props/SQLite.Interop.2005.vsprops @@ -0,0 +1,60 @@ + + + + + + + + + + + + + ADDED SQLite.Interop/props/SQLite.Interop.2008.vsprops Index: SQLite.Interop/props/SQLite.Interop.2008.vsprops ================================================================== --- /dev/null +++ SQLite.Interop/props/SQLite.Interop.2008.vsprops @@ -0,0 +1,60 @@ + + + + + + + + + + + + + ADDED SQLite.Interop/props/SQLite.Interop.2010.props Index: SQLite.Interop/props/SQLite.Interop.2010.props ================================================================== --- /dev/null +++ SQLite.Interop/props/SQLite.Interop.2010.props @@ -0,0 +1,63 @@ + + + + + 2010 + 081 + 1.0.81.0 + 1,0,81,0 + INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1 + /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteCommand.bmp,System.Data.SQLite.SQLiteCommand.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteConnection.bmp,System.Data.SQLite.SQLiteConnection.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteDataAdapter.bmp,System.Data.SQLite.SQLiteDataAdapter.bmp + $(ProjectDir)..\System.Data.SQLite\System.Data.SQLite.snk + SQLite.Interop + System.Data.SQLite + + + <_ProjectFileVersion>10.0.30319.1 + + + + $(ConfigurationYear) + true + + + $(INTEROP_BUILD_NUMBER) + true + + + $(INTEROP_MANIFEST_VERSION) + true + + + $(INTEROP_RC_VERSION) + true + + + $(INTEROP_EXTRA_DEFINES) + true + + + $(INTEROP_ASSEMBLY_RESOURCES) + true + + + $(INTEROP_KEY_FILE) + true + + + $(INTEROP_NATIVE_NAME) + true + + + $(INTEROP_MIXED_NAME) + true + + + DELETED SQLite.Interop/props/SQLite.Interop.props Index: SQLite.Interop/props/SQLite.Interop.props ================================================================== --- SQLite.Interop/props/SQLite.Interop.props +++ /dev/null @@ -1,58 +0,0 @@ - - - - - 2010 - 078 - 1.0.78.0 - 1,0,78,0 - /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteCommand.bmp,System.Data.SQLite.SQLiteCommand.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteConnection.bmp,System.Data.SQLite.SQLiteConnection.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteDataAdapter.bmp,System.Data.SQLite.SQLiteDataAdapter.bmp - $(ProjectDir)..\System.Data.SQLite\System.Data.SQLite.snk - SQLite.Interop - System.Data.SQLite - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(ConfigurationYear) - true - - - $(INTEROP_BUILD_NUMBER) - true - - - $(INTEROP_MANIFEST_VERSION) - true - - - $(INTEROP_RC_VERSION) - true - - - $(INTEROP_ASSEMBLY_RESOURCES) - true - - - $(INTEROP_KEY_FILE) - true - - - $(INTEROP_NATIVE_NAME) - true - - - $(INTEROP_MIXED_NAME) - true - - - DELETED SQLite.Interop/props/SQLite.Interop.vsprops Index: SQLite.Interop/props/SQLite.Interop.vsprops ================================================================== --- SQLite.Interop/props/SQLite.Interop.vsprops +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - Index: SQLite.Interop/props/sqlite3.props ================================================================== --- SQLite.Interop/props/sqlite3.props +++ SQLite.Interop/props/sqlite3.props @@ -7,12 +7,12 @@ * Released to the public domain, use at your own risk! * --> - 3.7.10.0 - 3,7,10,0 + 3.7.11.0 + 3,7,11,0 SQLITE_THREADSAFE=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT3=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1 SQLITE_HAS_CODEC=1 SQLITE_OMIT_WAL=1 SQLITE_DEBUG=1;SQLITE_MEMDEBUG=1 SQLITE_WIN32_MALLOC=1 Index: SQLite.Interop/props/sqlite3.vsprops ================================================================== --- SQLite.Interop/props/sqlite3.vsprops +++ SQLite.Interop/props/sqlite3.vsprops @@ -12,16 +12,16 @@ Version="8.00" Name="sqlite3" > +**
  • [[SQLITE_FCNTL_SIZE_HINT]] ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS ** layer a hint of how large the database file will grow to be during the ** current transaction. This hint is not guaranteed to be accurate but it ** is often close. The underlying VFS might choose to preallocate database ** file space based on this hint in order to help writes to the database ** file run faster. ** +**
  • [[SQLITE_FCNTL_CHUNK_SIZE]] ** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS ** extends and truncates the database file in chunks of a size specified ** by the user. The fourth argument to [sqlite3_file_control()] should ** point to an integer (type int) containing the new chunk-size to use ** for the nominated database. Allocating database file space in large ** chunks (say 1MB at a time), may reduce file-system fragmentation and ** improve performance on some systems. ** +**
  • [[SQLITE_FCNTL_FILE_POINTER]] ** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer ** to the [sqlite3_file] object associated with a particular database ** connection. See the [sqlite3_file_control()] documentation for ** additional information. ** +**
  • [[SQLITE_FCNTL_SYNC_OMITTED]] ** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by ** SQLite and sent to all VFSes in place of a call to the xSync method ** when the database connection has [PRAGMA synchronous] set to OFF.)^ ** Some specialized VFSes need this signal in order to operate correctly ** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most @@ -1295,10 +1300,11 @@ ** VFSes do not need this signal and should silently ignore this opcode. ** Applications should not call [sqlite3_file_control()] with this ** opcode as doing so may disrupt the operation of the specialized VFSes ** that do require it. ** +**
  • [[SQLITE_FCNTL_WIN32_AV_RETRY]] ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic ** retry counts and intervals for certain disk I/O operations for the ** windows [VFS] in order to provide robustness in the presence of ** anti-virus programs. By default, the windows VFS will retry file read, ** file write, and file delete operations up to 10 times, with a delay @@ -1311,10 +1317,11 @@ ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** +**
  • [[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the ** persistent [WAL | Write AHead Log] setting. By default, the auxiliary ** write ahead log and shared memory files used for transaction control ** are automatically deleted when the latest connection to the database ** closes. Setting persistent WAL mode causes those files to persist after @@ -1325,24 +1332,27 @@ ** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. ** +**
  • [[SQLITE_FCNTL_POWERSAFE_OVERWRITE]] ** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the ** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting ** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the ** xDeviceCharacteristics methods. The fourth parameter to ** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage ** mode. If the integer is -1, then it is overwritten with the current ** zero-damage mode setting. ** +**
  • [[SQLITE_FCNTL_OVERWRITE]] ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. ** +**
  • [[SQLITE_FCNTL_VFSNAME]] ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of ** all [VFSes] in the VFS stack. The names are of all VFS shims and the ** final bottom-level VFS are written into memory obtained from ** [sqlite3_malloc()] and the result is stored in the char* variable ** that the fourth parameter of [sqlite3_file_control()] points to. @@ -1349,10 +1359,34 @@ ** The caller is responsible for freeing the memory when done. As with ** all file-control actions, there is no guarantee that this will actually ** do anything. Callers should initialize the char* variable to a NULL ** pointer in case this file-control is not implemented. This file-control ** is intended for diagnostic use only. +** +**
  • [[SQLITE_FCNTL_PRAGMA]] +** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] +** file control is sent to the open [sqlite3_file] object corresponding +** to the database file to which the pragma statement refers. ^The argument +** to the [SQLITE_FCNTL_PRAGMA] file control is an array of +** pointers to strings (char**) in which the second element of the array +** is the name of the pragma and the third element is the argument to the +** pragma or NULL if the pragma has no argument. ^The handler for an +** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element +** of the char** argument point to a string obtained from [sqlite3_mprintf()] +** or the equivalent and that string will become the result of the pragma or +** the error message if the pragma fails. ^If the +** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal +** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] +** file control returns [SQLITE_OK], then the parser assumes that the +** VFS has handled the PRAGMA itself and the parser generates a no-op +** prepared statement. ^If the [SQLITE_FCNTL_PRAGMA] file control returns +** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means +** that the VFS encountered an error while handling the [PRAGMA] and the +** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] +** file control occurs at the beginning of pragma statement analysis and so +** it is able to override built-in [PRAGMA] statements. +** */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 #define SQLITE_SET_LOCKPROXYFILE 3 #define SQLITE_LAST_ERRNO 4 @@ -1363,10 +1397,11 @@ #define SQLITE_FCNTL_WIN32_AV_RETRY 9 #define SQLITE_FCNTL_PERSIST_WAL 10 #define SQLITE_FCNTL_OVERWRITE 11 #define SQLITE_FCNTL_VFSNAME 12 #define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 +#define SQLITE_FCNTL_PRAGMA 14 /* ** CAPI3REF: Mutex Handle ** ** The mutex module within SQLite defines [sqlite3_mutex] to be an @@ -3192,13 +3227,18 @@ ** has no explicit value, then sqlite3_uri_parameter(F,P) returns ** a pointer to an empty string. ** ** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean ** parameter and returns true (1) or false (0) according to the value -** of P. The value of P is true if it is "yes" or "true" or "on" or -** a non-zero number and is false otherwise. If P is not a query parameter -** on F then sqlite3_uri_boolean(F,P,B) returns (B!=0). +** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the +** value of query parameter P is one of "yes", "true", or "on" in any +** case or if the value begins with a non-zero number. The +** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of +** query parameter P is one of "no", "false", or "off" in any case or +** if the value begins with a numeric zero. If P is not a query +** parameter on F or if the value of P is does not match any of the +** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0). ** ** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a ** 64-bit signed integer and returns that integer, or D if P does not ** exist. If the value of P is something other than an integer, then ** zero is returned. @@ -5007,10 +5047,19 @@ ** will be an absolute pathname, even if the filename used ** to open the database originally was a URI or relative pathname. */ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); +/* +** CAPI3REF: Determine if a database is read-only +** +** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N +** of connection D is read-only, 0 if it is read/write, or -1 if N is not +** the name of a database on connection D. +*/ +SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); + /* ** CAPI3REF: Find the next prepared statement ** ** ^This interface returns a pointer to the next [prepared statement] after ** pStmt associated with the [database connection] pDb. ^If pStmt is NULL @@ -7132,15 +7181,16 @@ /* ** CAPI3REF: String Comparison ** -** ^The [sqlite3_strnicmp()] API allows applications and extensions to -** compare the contents of two buffers containing UTF-8 strings in a -** case-independent fashion, using the same definition of case independence -** that SQLite uses internally when comparing identifiers. +** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications +** and extensions to compare the contents of two buffers containing UTF-8 +** strings in a case-independent fashion, using the same definition of "case +** independence" that SQLite uses internally when comparing identifiers. */ +SQLITE_API int sqlite3_stricmp(const char *, const char *); SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); /* ** CAPI3REF: Error Logging Interface ** @@ -8013,13 +8063,17 @@ */ #define ArraySize(X) ((int)(sizeof(X)/sizeof(X[0]))) /* ** The following value as a destructor means to use sqlite3DbFree(). -** This is an internal extension to SQLITE_STATIC and SQLITE_TRANSIENT. +** The sqlite3DbFree() routine requires two parameters instead of the +** one parameter that destructors normally want. So we have to introduce +** this magic value that the code knows to handle differently. Any +** pointer will work here as long as it is distinct from SQLITE_STATIC +** and SQLITE_TRANSIENT. */ -#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3DbFree) +#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3MallocSize) /* ** When SQLITE_OMIT_WSD is defined, it means that the target platform does ** not support Writable Static Data (WSD) such as global and static variables. ** All variables must either be on the stack or dynamically allocated from @@ -8175,14 +8229,13 @@ ** ** NOTE: These values must match the corresponding PAGER_ values in ** pager.h. */ #define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ -#define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ -#define BTREE_MEMORY 4 /* This is an in-memory DB */ -#define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ -#define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ +#define BTREE_MEMORY 2 /* This is an in-memory DB */ +#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */ +#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */ SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*); @@ -8196,11 +8249,11 @@ SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *); SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int); SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int); SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*); -SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*); +SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int); SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int); SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags); SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*); SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*); SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*); @@ -8851,12 +8904,11 @@ ** Allowed values for the flags parameter to sqlite3PagerOpen(). ** ** NOTE: These values must match the corresponding BTREE_ values in btree.h. */ #define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ -#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ -#define PAGER_MEMORY 0x0004 /* In-memory database */ +#define PAGER_MEMORY 0x0002 /* In-memory database */ /* ** Valid values for the second argument to sqlite3PagerLockingMode(). */ #define PAGER_LOCKINGMODE_QUERY -1 @@ -8937,10 +8989,13 @@ SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*); SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager); +#ifdef SQLITE_ENABLE_ZIPVFS +SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); +#endif /* Functions used to query pager state and configuration. */ SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); @@ -9009,12 +9064,12 @@ struct PgHdr { sqlite3_pcache_page *pPage; /* Pcache object page handle */ void *pData; /* Page data */ void *pExtra; /* Extra content */ PgHdr *pDirty; /* Transient list of dirty pages */ - Pgno pgno; /* Page number for this page */ Pager *pPager; /* The pager this page is part of */ + Pgno pgno; /* Page number for this page */ #ifdef SQLITE_CHECK_PAGES u32 pageHash; /* Hash of page content */ #endif u16 flags; /* PGHDR flags defined below */ @@ -9238,15 +9293,27 @@ # define SQLITE_TEMPNAME_SIZE 200 #endif /* ** Determine if we are dealing with Windows NT. +** +** We ought to be able to determine if we are compiling for win98 or winNT +** using the _WIN32_WINNT macro as follows: +** +** #if defined(_WIN32_WINNT) +** # define SQLITE_OS_WINNT 1 +** #else +** # define SQLITE_OS_WINNT 0 +** #endif +** +** However, vs2005 does not set _WIN32_WINNT by default, as it ought to, +** so the above test does not work. We'll just assume that everything is +** winNT unless the programmer explicitly says otherwise by setting +** SQLITE_OS_WINNT to 0. */ -#if defined(_WIN32_WINNT) +#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT) # define SQLITE_OS_WINNT 1 -#else -# define SQLITE_OS_WINNT 0 #endif /* ** Determine if we are dealing with WindowsCE - which has a much ** reduced API. @@ -9640,39 +9707,20 @@ FuncDef *a[23]; /* Hash table for functions */ }; /* ** Each database connection is an instance of the following structure. -** -** The sqlite.lastRowid records the last insert rowid generated by an -** insert statement. Inserts on views do not affect its value. Each -** trigger has its own context, so that lastRowid can be updated inside -** triggers as usual. The previous value will be restored once the trigger -** exits. Upon entering a before or instead of trigger, lastRowid is no -** longer (since after version 2.8.12) reset to -1. -** -** The sqlite.nChange does not count changes within triggers and keeps no -** context. It is reset at start of sqlite3_exec. -** The sqlite.lsChange represents the number of changes made by the last -** insert, update, or delete statement. It remains constant throughout the -** length of a statement and is then updated by OP_SetCounts. It keeps a -** context stack just like lastRowid so that the count of changes -** within a trigger is not seen outside the trigger. Changes to views do not -** affect the value of lsChange. -** The sqlite.csChange keeps track of the number of current changes (since -** the last statement) and is used to update sqlite_lsChange. -** -** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16 -** store the most recent error code and, if applicable, string. The -** internal function sqlite3Error() is used to set these variables -** consistently. */ struct sqlite3 { sqlite3_vfs *pVfs; /* OS Interface */ - int nDb; /* Number of backends currently in use */ + struct Vdbe *pVdbe; /* List of active virtual machines */ + CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ + sqlite3_mutex *mutex; /* Connection mutex */ Db *aDb; /* All backends */ + int nDb; /* Number of backends currently in use */ int flags; /* Miscellaneous flags. See below */ + i64 lastRowid; /* ROWID of most recent insert (see above) */ unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ @@ -9679,31 +9727,27 @@ u8 mallocFailed; /* True if we have seen a malloc failure */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ u8 suppressErr; /* Do not issue error messages if true */ u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ + u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ int nextPagesize; /* Pagesize after VACUUM if >0 */ - int nTable; /* Number of tables in the database */ - CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ - i64 lastRowid; /* ROWID of most recent insert (see above) */ u32 magic; /* Magic number for detect library misuse */ int nChange; /* Value returned by sqlite3_changes() */ int nTotalChange; /* Value returned by sqlite3_total_changes() */ - sqlite3_mutex *mutex; /* Connection mutex */ int aLimit[SQLITE_N_LIMIT]; /* Limits */ struct sqlite3InitInfo { /* Information used during initialization */ - int iDb; /* When back is being initialized */ int newTnum; /* Rootpage of table being initialized */ + u8 iDb; /* Which db file is being initialized */ u8 busy; /* TRUE if currently initializing */ u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ } init; - int nExtension; /* Number of loaded extensions */ - void **aExtension; /* Array of shared library handles */ - struct Vdbe *pVdbe; /* List of active virtual machines */ int activeVdbeCnt; /* Number of VDBEs currently executing */ int writeVdbeCnt; /* Number of active VDBEs that are writing */ int vdbeExecCnt; /* Number of nested calls to VdbeExec() */ + int nExtension; /* Number of loaded extensions */ + void **aExtension; /* Array of shared library handles */ void (*xTrace)(void*,const char*); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ void (*xProfile)(void*,const char*,u64); /* Profiling function */ void *pProfileArg; /* Argument to profile function */ void *pCommitArg; /* Argument to xCommitCallback() */ @@ -9736,25 +9780,24 @@ int (*xProgress)(void *); /* The progress callback */ void *pProgressArg; /* Argument to the progress callback */ int nProgressOps; /* Number of opcodes for progress callback */ #endif #ifndef SQLITE_OMIT_VIRTUALTABLE + int nVTrans; /* Allocated size of aVTrans */ Hash aModule; /* populated by sqlite3_create_module() */ VtabCtx *pVtabCtx; /* Context for active vtab connect/create */ VTable **aVTrans; /* Virtual tables with open transactions */ - int nVTrans; /* Allocated size of aVTrans */ VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ #endif FuncDefHash aFunc; /* Hash table of connection functions */ Hash aCollSeq; /* All collating sequences */ BusyHandler busyHandler; /* Busy callback */ - int busyTimeout; /* Busy handler timeout, in msec */ Db aDbStatic[2]; /* Static space for the 2 default backends */ Savepoint *pSavepoint; /* List of active savepoints */ + int busyTimeout; /* Busy handler timeout, in msec */ int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ - u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ i64 nDeferredCons; /* Net deferred constraints this transaction. */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY /* The following variables are all protected by the STATIC_MASTER @@ -9793,12 +9836,11 @@ #define SQLITE_NullCallback 0x00002000 /* Invoke the callback once if the */ /* result set is empty */ #define SQLITE_SqlTrace 0x00004000 /* Debug print SQL as it executes */ #define SQLITE_VdbeListing 0x00008000 /* Debug listings of VDBE programs */ #define SQLITE_WriteSchema 0x00010000 /* OK to update SQLITE_MASTER */ -#define SQLITE_NoReadlock 0x00020000 /* Readlocks are omitted when - ** accessing read-only databases */ + /* 0x00020000 Unused */ #define SQLITE_IgnoreChecks 0x00040000 /* Do not enforce check constraints */ #define SQLITE_ReadUncommitted 0x0080000 /* For shared-cache mode */ #define SQLITE_LegacyFileFmt 0x00100000 /* Create new databases in format 1 */ #define SQLITE_FullFSync 0x00200000 /* Use full fsync on the backend */ #define SQLITE_CkptFullFSync 0x00400000 /* Use full fsync for checkpoint */ @@ -9883,11 +9925,10 @@ */ #define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */ #define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */ #define SQLITE_FUNC_EPHEM 0x04 /* Ephemeral. Delete with VDBE */ #define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */ -#define SQLITE_FUNC_PRIVATE 0x10 /* Allowed for internal use only */ #define SQLITE_FUNC_COUNT 0x20 /* Built-in count(*) aggregate */ #define SQLITE_FUNC_COALESCE 0x40 /* Built-in coalesce() or ifnull() function */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -10166,12 +10207,10 @@ #define TF_Readonly 0x01 /* Read-only system table */ #define TF_Ephemeral 0x02 /* An ephemeral table */ #define TF_HasPrimaryKey 0x04 /* Table has a primary key */ #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ #define TF_Virtual 0x10 /* Is a virtual table */ -#define TF_NeedMetadata 0x20 /* aCol[].zType and aCol[].pColl missing */ - /* ** Test to see whether or not a table is a virtual table. This is ** done as a macro so that it will be optimized out when virtual @@ -10329,23 +10368,23 @@ ** algorithm to employ whenever an attempt is made to insert a non-unique ** element. */ struct Index { char *zName; /* Name of this index */ - int nColumn; /* Number of columns in the table used by this index */ int *aiColumn; /* Which columns are used by this index. 1st is 0 */ tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ Table *pTable; /* The SQL table being indexed */ - int tnum; /* Page containing root of this index in database file */ - u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ - u8 bUnordered; /* Use this index for == or IN queries only */ char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ + int nColumn; /* Number of columns in the table used by this index */ + int tnum; /* Page containing root of this index in database file */ + u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ + u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ + u8 bUnordered; /* Use this index for == or IN queries only */ #ifdef SQLITE_ENABLE_STAT3 int nSample; /* Number of elements in aSample[] */ tRowcnt avgEq; /* Average nEq value for key values not in aSample */ IndexSample *aSample; /* Samples of the left-most key */ #endif @@ -10400,22 +10439,21 @@ ** from source tables rather than from accumulators */ u8 useSortingIdx; /* In direct mode, reference the sorting index rather ** than the source table */ int sortingIdx; /* Cursor number of the sorting index */ int sortingIdxPTab; /* Cursor number of pseudo-table */ - ExprList *pGroupBy; /* The group by clause */ int nSortingColumn; /* Number of columns in the sorting index */ + ExprList *pGroupBy; /* The group by clause */ struct AggInfo_col { /* For each column used in source tables */ Table *pTab; /* Source table */ int iTable; /* Cursor number of the source table */ int iColumn; /* Column number within the source table */ int iSorterColumn; /* Column number in the sorting index */ int iMem; /* Memory location that acts as accumulator */ Expr *pExpr; /* The original expression */ } *aCol; int nColumn; /* Number of used entries in aCol[] */ - int nColumnAlloc; /* Number of slots allocated for aCol[] */ int nAccumulator; /* Number of columns that show through to the output. ** Additional columns are used only as parameters to ** aggregate functions */ struct AggInfo_func { /* For each aggregate function */ Expr *pExpr; /* Expression encoding the function */ @@ -10422,11 +10460,10 @@ FuncDef *pFunc; /* The aggregate function implementation */ int iMem; /* Memory location that acts as accumulator */ int iDistinct; /* Ephemeral table used to enforce DISTINCT */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ - int nFuncAlloc; /* Number of slots allocated for aFunc[] */ }; /* ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. ** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater @@ -10619,21 +10656,20 @@ ** also be used as the argument to a function, in which case the a.zName ** field is not used. */ struct ExprList { int nExpr; /* Number of expressions on the list */ - int nAlloc; /* Number of entries allocated below */ int iECursor; /* VDBE Cursor associated with this ExprList */ - struct ExprList_item { + struct ExprList_item { /* For each expression in the list */ Expr *pExpr; /* The list of expressions */ char *zName; /* Token associated with this expression */ char *zSpan; /* Original text of the expression */ u8 sortOrder; /* 1 for DESC or 0 for ASC */ u8 done; /* A flag to indicate when processing is finished */ u16 iOrderByCol; /* For ORDER BY, column number in result set */ u16 iAlias; /* Index into Parse.aAlias[] for zName */ - } *a; /* One entry for each expression */ + } *a; /* Alloc a power of two greater or equal to nExpr */ }; /* ** An instance of this structure is used by the parser to record both ** the parse tree for an expression and the span of input text for an @@ -10664,11 +10700,10 @@ struct IdList_item { char *zName; /* Name of the identifier */ int idx; /* Index in some Table.aCol[] of a column named zName */ } *a; int nId; /* Number of identifiers on the list */ - int nAlloc; /* Number of entries allocated for a[] below */ }; /* ** The bitmask datatype defined below is used for various optimizations. ** @@ -10908,10 +10943,13 @@ struct Select { ExprList *pEList; /* The fields of the result */ u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ char affinity; /* MakeRecord with this affinity for SRT_Set */ u16 selFlags; /* Various SF_* values */ + int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ + int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */ + double nSelectRow; /* Estimated number of result rows */ SrcList *pSrc; /* The FROM clause */ Expr *pWhere; /* The WHERE clause */ ExprList *pGroupBy; /* The GROUP BY clause */ Expr *pHaving; /* The HAVING clause */ ExprList *pOrderBy; /* The ORDER BY clause */ @@ -10918,13 +10956,10 @@ Select *pPrior; /* Prior select in a compound select statement */ Select *pNext; /* Next select to the left in a compound */ Select *pRightmost; /* Right-most select in a compound select statement */ Expr *pLimit; /* LIMIT expression. NULL means not used. */ Expr *pOffset; /* OFFSET expression. NULL means not used. */ - int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ - int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */ - double nSelectRow; /* Estimated number of result rows */ }; /* ** Allowed values for Select.selFlags. The "SF" prefix stands for ** "Select Flag". @@ -10934,10 +10969,11 @@ #define SF_Aggregate 0x04 /* Contains aggregate functions */ #define SF_UsesEphemeral 0x08 /* Uses the OpenEphemeral opcode */ #define SF_Expanded 0x10 /* sqlite3SelectExpand() called on this */ #define SF_HasTypeInfo 0x20 /* FROM subqueries have Table metadata */ #define SF_UseSorter 0x40 /* Sort using a sorter */ +#define SF_Values 0x80 /* Synthesized from VALUES clause */ /* ** The results of a select can be distributed in several ways. The ** "SRT" prefix means "SELECT Result Type". @@ -11011,14 +11047,14 @@ ** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to ** a mask of new.* columns used by the program. */ struct TriggerPrg { Trigger *pTrigger; /* Trigger this program was coded from */ - int orconf; /* Default ON CONFLICT policy */ + TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */ SubProgram *pProgram; /* Program implementing pTrigger/orconf */ + int orconf; /* Default ON CONFLICT policy */ u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */ - TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */ }; /* ** The yDbMask datatype for the bitmask of all attached databases. */ @@ -11044,18 +11080,22 @@ ** compiled. Function sqlite3TableLock() is used to add entries to the ** list. */ struct Parse { sqlite3 *db; /* The main database structure */ - int rc; /* Return code from execution */ char *zErrMsg; /* An error message */ Vdbe *pVdbe; /* An engine for executing database bytecode */ + int rc; /* Return code from execution */ u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ u8 checkSchema; /* Causes schema cookie check after an error */ u8 nested; /* Number of nested calls to the parser/code generator */ u8 nTempReg; /* Number of temporary registers in aTempReg[] */ u8 nTempInUse; /* Number of aTempReg[] currently checked out */ + u8 nColCache; /* Number of entries in aColCache[] */ + u8 iColCache; /* Next entry in aColCache[] to replace */ + u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ + u8 mayAbort; /* True if statement may throw an ABORT exception */ int aTempReg[8]; /* Holding area for temporary registers */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ @@ -11063,12 +11103,10 @@ int nSet; /* Number of sets used so far */ int nOnce; /* Number of OP_Once instructions so far */ int ckBase; /* Base register of data during check constraints */ int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ int iCacheCnt; /* Counter used to generate aColCache[].lru values */ - u8 nColCache; /* Number of entries in aColCache[] */ - u8 iColCache; /* Next entry in aColCache[] to replace */ struct yColCache { int iTable; /* Table cursor number */ int iColumn; /* Table column number */ u8 tempReg; /* iReg is a temp register that needs to be freed */ int iLevel; /* Nesting level */ @@ -11075,65 +11113,67 @@ int iReg; /* Reg with value of this column. 0 means none. */ int lru; /* Least recently used entry has the smallest value */ } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ - u8 isMultiWrite; /* True if statement may affect/insert multiple rows */ - u8 mayAbort; /* True if statement may throw an ABORT exception */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */ + int regRowid; /* Register holding rowid of CREATE TABLE entry */ + int regRoot; /* Register holding root page number for new objects */ + int nMaxArg; /* Max args passed to user function by sub-program */ #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ #endif - int regRowid; /* Register holding rowid of CREATE TABLE entry */ - int regRoot; /* Register holding root page number for new objects */ AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ - int nMaxArg; /* Max args passed to user function by sub-program */ /* Information used while coding trigger programs. */ Parse *pToplevel; /* Parse structure for main program (or NULL) */ Table *pTriggerTab; /* Table triggers are being coded for */ + double nQueryLoop; /* Estimated number of iterations of a query */ u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ - double nQueryLoop; /* Estimated number of iterations of a query */ /* Above is constant between recursions. Below is reset before and after ** each recursion */ - int nVar; /* Number of '?' variables seen in the SQL so far */ - int nzVar; /* Number of available slots in azVar[] */ - char **azVar; /* Pointers to names of parameters */ - Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ - int nAlias; /* Number of aliased result set columns */ - int *aAlias; /* Register used to hold aliased result */ - u8 explain; /* True if the EXPLAIN flag is found on the query */ - Token sNameToken; /* Token with unqualified schema object name */ - Token sLastToken; /* The last token parsed */ - const char *zTail; /* All SQL text past the last semicolon parsed */ - Table *pNewTable; /* A table being constructed by CREATE TABLE */ + int nVar; /* Number of '?' variables seen in the SQL so far */ + int nzVar; /* Number of available slots in azVar[] */ + u8 explain; /* True if the EXPLAIN flag is found on the query */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ + int nVtabLock; /* Number of virtual tables to lock */ +#endif + int nAlias; /* Number of aliased result set columns */ + int nHeight; /* Expression tree height of current sub-select */ +#ifndef SQLITE_OMIT_EXPLAIN + int iSelectId; /* ID of current select for EXPLAIN output */ + int iNextSelectId; /* Next available select ID for EXPLAIN output */ +#endif + char **azVar; /* Pointers to names of parameters */ + Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ + int *aAlias; /* Register used to hold aliased result */ + const char *zTail; /* All SQL text past the last semicolon parsed */ + Table *pNewTable; /* A table being constructed by CREATE TABLE */ Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ + Token sNameToken; /* Token with unqualified schema object name */ + Token sLastToken; /* The last token parsed */ #ifndef SQLITE_OMIT_VIRTUALTABLE - Token sArg; /* Complete text of a module argument */ - u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ - int nVtabLock; /* Number of virtual tables to lock */ - Table **apVtabLock; /* Pointer to virtual tables needing locking */ -#endif - int nHeight; /* Expression tree height of current sub-select */ - Table *pZombieTab; /* List of Table objects to delete after code gen */ - TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ - -#ifndef SQLITE_OMIT_EXPLAIN - int iSelectId; - int iNextSelectId; -#endif + Token sArg; /* Complete text of a module argument */ + Table **apVtabLock; /* Pointer to virtual tables needing locking */ +#endif + Table *pZombieTab; /* List of Table objects to delete after code gen */ + TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ }; +/* +** Return true if currently inside an sqlite3_declare_vtab() call. +*/ #ifdef SQLITE_OMIT_VIRTUALTABLE #define IN_DECLARE_VTAB 0 #else #define IN_DECLARE_VTAB (pParse->declareVtab) #endif @@ -11280,12 +11320,12 @@ ** A pointer to this structure is used to communicate information ** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback. */ typedef struct { sqlite3 *db; /* The database being initialized */ - int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */ char **pzErrMsg; /* Error message stored here */ + int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */ int rc; /* Result code stored here */ } InitData; /* ** Structure containing global configuration data for the SQLite library. @@ -11423,11 +11463,11 @@ #endif /* ** Internal function prototypes */ -SQLITE_PRIVATE int sqlite3StrICmp(const char *, const char *); +#define sqlite3StrICmp sqlite3_stricmp SQLITE_PRIVATE int sqlite3Strlen30(const char*); #define sqlite3StrNICmp sqlite3_strnicmp SQLITE_PRIVATE int sqlite3MallocInit(void); SQLITE_PRIVATE void sqlite3MallocEnd(void); @@ -11571,10 +11611,11 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*); SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*); SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); +SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*); SQLITE_PRIVATE int sqlite3CodeOnce(Parse *); SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32); SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32); SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32); @@ -11606,11 +11647,11 @@ #else # define sqlite3AutoincrementBegin(X) # define sqlite3AutoincrementEnd(X) #endif SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int); -SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int,int*,int*,int*); +SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, @@ -11670,11 +11711,11 @@ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*); SQLITE_PRIVATE void sqlite3PrngSaveState(void); SQLITE_PRIVATE void sqlite3PrngRestoreState(void); SQLITE_PRIVATE void sqlite3PrngResetState(void); -SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*); +SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*,int); SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int); SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int); SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*); SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*); @@ -11844,11 +11885,11 @@ #ifdef SQLITE_ENABLE_8_3_NAMES SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); #else # define sqlite3FileSuffix3(X,Y) #endif -SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z); +SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,int); SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); @@ -11970,11 +12011,11 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); -SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*); +SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int); SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*); SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*); SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*); SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); @@ -12899,25 +12940,25 @@ ** set to NULL if the currently executing frame is the main program. */ typedef struct VdbeFrame VdbeFrame; struct VdbeFrame { Vdbe *v; /* VM this frame belongs to */ - int pc; /* Program Counter in parent (calling) frame */ + VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */ Op *aOp; /* Program instructions for parent frame */ - int nOp; /* Size of aOp array */ Mem *aMem; /* Array of memory cells for parent frame */ - int nMem; /* Number of entries in aMem */ u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */ - int nOnceFlag; /* Number of entries in aOnceFlag */ VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ + void *token; /* Copy of SubProgram.token */ + i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ u16 nCursor; /* Number of entries in apCsr */ - void *token; /* Copy of SubProgram.token */ + int pc; /* Program Counter in parent (calling) frame */ + int nOp; /* Size of aOp array */ + int nMem; /* Number of entries in aMem */ + int nOnceFlag; /* Number of entries in aOnceFlag */ int nChildMem; /* Number of memory cells for child frame */ int nChildCsr; /* Number of cursors for child frame */ - i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ int nChange; /* Statement changes (Vdbe.nChanges) */ - VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */ }; #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) /* @@ -13040,12 +13081,13 @@ struct sqlite3_context { FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */ VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */ Mem s; /* The return value is stored here */ Mem *pMem; /* Memory cell used to store aggregate context */ - int isError; /* Error code returned by the function. */ CollSeq *pColl; /* Collating sequence */ + int isError; /* Error code returned by the function. */ + int skipFlag; /* Skip skip accumulator loading if true */ }; /* ** An Explain object accumulates indented output which is helpful ** in describing recursive data structures. @@ -13082,11 +13124,10 @@ Mem *pResultSet; /* Pointer to an array of results */ int nMem; /* Number of memory locations currently allocated */ int nOp; /* Number of instructions in the program */ int nOpAlloc; /* Number of slots allocated for aOp[] */ int nLabel; /* Number of labels used */ - int nLabelAlloc; /* Number of slots allocated in aLabel[] */ int *aLabel; /* Space to hold the labels */ u16 nResColumn; /* Number of columns in one row of the result set */ u16 nCursor; /* Number of slots in apCsr[] */ u32 magic; /* Magic number for sanity checking */ char *zErrMsg; /* Error message written here */ @@ -15149,11 +15190,35 @@ ** This file contains low-level memory allocation drivers for when ** SQLite will use the standard C-library malloc/realloc/free interface ** to obtain the memory it needs. ** ** This file contains implementations of the low-level memory allocation -** routines specified in the sqlite3_mem_methods object. +** routines specified in the sqlite3_mem_methods object. The content of +** this file is only used if SQLITE_SYSTEM_MALLOC is defined. The +** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the +** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined. The +** default configuration is to use memory allocation routines in this +** file. +** +** C-preprocessor macro summary: +** +** HAVE_MALLOC_USABLE_SIZE The configure script sets this symbol if +** the malloc_usable_size() interface exists +** on the target platform. Or, this symbol +** can be set manually, if desired. +** If an equivalent interface exists by +** a different name, using a separate -D +** option to rename it. +** +** SQLITE_WITHOUT_ZONEMALLOC Some older macs lack support for the zone +** memory allocator. Set this symbol to enable +** building on older macs. +** +** SQLITE_WITHOUT_MSIZE Set this symbol to disable the use of +** _msize() on windows systems. This might +** be necessary when compiling for Delphi, +** for example. */ /* ** This version of the memory allocator is the default. It is ** used when no other memory allocator is specified using compile-time @@ -15160,21 +15225,23 @@ ** macros. */ #ifdef SQLITE_SYSTEM_MALLOC /* -** Windows systems have malloc_usable_size() but it is called _msize() +** The MSVCRT has malloc_usable_size() but it is called _msize(). +** The use of _msize() is automatic, but can be disabled by compiling +** with -DSQLITE_WITHOUT_MSIZE */ -#if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN -# define HAVE_MALLOC_USABLE_SIZE 1 -# define malloc_usable_size _msize +#if defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE) +# define SQLITE_MALLOCSIZE _msize #endif -#if defined(__APPLE__) +#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) /* -** Use the zone allocator available on apple products +** Use the zone allocator available on apple products unless the +** SQLITE_WITHOUT_ZONEMALLOC symbol is defined. */ #include #include #include static malloc_zone_t* _sqliteZone_; @@ -15185,21 +15252,27 @@ (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x)) #else /* if not __APPLE__ */ /* -** Use standard C library malloc and free on non-Apple systems. +** Use standard C library malloc and free on non-Apple systems. +** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined. */ #define SQLITE_MALLOC(x) malloc(x) #define SQLITE_FREE(x) free(x) #define SQLITE_REALLOC(x,y) realloc((x),(y)) +#if (defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)) \ + || (defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE)) +# include /* Needed for malloc_usable_size on linux */ +#endif #ifdef HAVE_MALLOC_USABLE_SIZE -#include -#define SQLITE_MALLOCSIZE(x) malloc_usable_size(x) +# ifndef SQLITE_MALLOCSIZE +# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x) +# endif #else -#undef SQLITE_MALLOCSIZE +# undef SQLITE_MALLOCSIZE #endif #endif /* __APPLE__ or not __APPLE__ */ /* @@ -15317,11 +15390,11 @@ /* ** Initialize this module. */ static int sqlite3MemInit(void *NotUsed){ -#if defined(__APPLE__) +#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) int cpuCount; size_t len; if( _sqliteZone_ ){ return SQLITE_OK; } @@ -21186,17 +21259,17 @@ /* ** Some systems have stricmp(). Others have strcasecmp(). Because ** there is no consistency, we will define our own. ** -** IMPLEMENTATION-OF: R-20522-24639 The sqlite3_strnicmp() API allows -** applications and extensions to compare the contents of two buffers -** containing UTF-8 strings in a case-independent fashion, using the same -** definition of case independence that SQLite uses internally when -** comparing identifiers. +** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and +** sqlite3_strnicmp() APIs allow applications and extensions to compare +** the contents of two buffers containing UTF-8 strings in a +** case-independent fashion, using the same definition of "case +** independence" that SQLite uses internally when comparing identifiers. */ -SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){ +SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){ register unsigned char *a, *b; a = (unsigned char *)zLeft; b = (unsigned char *)zRight; while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } return UpperToLower[*a] - UpperToLower[*b]; @@ -24943,11 +25016,11 @@ sqlite3_io_methods const *pMethod; /* Always the first entry */ sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ unixInodeInfo *pInode; /* Info about locks on this inode */ int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ - unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ + unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ @@ -24994,10 +25067,11 @@ #endif #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ #define UNIXFILE_DELETE 0x20 /* Delete on close */ #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ +#define UNIXFILE_CHOWN 0x100 /* File ownership was changed */ /* ** Include code that is common to all os_*.c files */ /************** Include os_common.h in the middle of os_unix.c ***************/ @@ -25358,10 +25432,16 @@ #define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) + { "fchown", (sqlite3_syscall_ptr)fchown, 0 }, +#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) + + { "umask", (sqlite3_syscall_ptr)umask, 0 }, +#define osUmask ((mode_t(*)(mode_t))aSyscall[21].pCurrent) + }; /* End of the overrideable system calls */ /* ** This is the xSetSystemCall() method of sqlite3_vfs for all of the ** "unix" VFSes. Return SQLITE_OK opon successfully updating the @@ -25444,15 +25524,40 @@ } return 0; } /* -** Retry open() calls that fail due to EINTR +** Invoke open(). Do so multiple times, until it either succeeds or +** files for some reason other than EINTR. +** +** If the file creation mode "m" is 0 then set it to the default for +** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally +** 0644) as modified by the system umask. If m is not 0, then +** make the file creation mode be exactly m ignoring the umask. +** +** The m parameter will be non-zero only when creating -wal, -journal, +** and -shm files. We want those files to have *exactly* the same +** permissions as their original database, unadulterated by the umask. +** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a +** transaction crashes and leaves behind hot journals, then any +** process that is able to write to the database will also be able to +** recover the hot journals. */ -static int robust_open(const char *z, int f, int m){ +static int robust_open(const char *z, int f, mode_t m){ int rc; - do{ rc = osOpen(z,f,m); }while( rc<0 && errno==EINTR ); + mode_t m2; + mode_t origM = 0; + if( m==0 ){ + m2 = SQLITE_DEFAULT_FILE_PERMISSIONS; + }else{ + m2 = m; + origM = osUmask(0); + } + do{ rc = osOpen(z,f,m2); }while( rc<0 && errno==EINTR ); + if( m ){ + osUmask(origM); + } return rc; } /* ** Helper functions to obtain and relinquish the global mutex. The @@ -28796,12 +28901,11 @@ if( pShmNode==0 ){ struct stat sStat; /* fstat() info for database file */ /* Call fstat() to figure out the permissions on the database file. If ** a new *-shm file is created, an attempt will be made to create it - ** with the same permissions. The actual permissions the file is created - ** with are subject to the current umask setting. + ** with the same permissions. */ if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){ rc = SQLITE_IOERR_FSTAT; goto shm_open_err; } @@ -28841,14 +28945,23 @@ openFlags = O_RDONLY; pShmNode->isReadonly = 1; } pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777)); if( pShmNode->h<0 ){ - if( pShmNode->h<0 ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); - goto shm_open_err; - } + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); + goto shm_open_err; + } + + /* If this process is running as root, make sure that the SHM file + ** is owned by the same user that owns the original database. Otherwise, + ** the original owner will not be able to connect. If this process is + ** not root, the following fchown() will fail, but we don't care. The + ** if(){..} and the UNIXFILE_CHOWN flag are purely to silence compiler + ** warnings. + */ + if( osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid)==0 ){ + pDbFd->ctrlFlags |= UNIXFILE_CHOWN; } /* Check to see if another process is holding the dead-man switch. ** If not, truncate the file to zero length. */ @@ -29819,16 +29932,14 @@ ** to create new files with. If no error occurs, then SQLITE_OK is returned ** and a value suitable for passing as the third argument to open(2) is ** written to *pMode. If an IO error occurs, an SQLite error code is ** returned and the value of *pMode is not modified. ** -** If the file being opened is a temporary file, it is always created with -** the octal permissions 0600 (read/writable by owner only). If the file -** is a database or master journal file, it is created with the permissions -** mask SQLITE_DEFAULT_FILE_PERMISSIONS. -** -** Finally, if the file being opened is a WAL or regular journal file, then +** In most cases cases, this routine sets *pMode to 0, which will become +** an indication to robust_open() to create the file using +** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask. +** But if the file being opened is a WAL or regular journal file, then ** this function queries the file-system for the permissions on the ** corresponding database file and sets *pMode to this value. Whenever ** possible, WAL and journal files are created using the same permissions ** as the associated database file. ** @@ -29838,14 +29949,18 @@ ** the default permissions. */ static int findCreateFileMode( const char *zPath, /* Path of file (possibly) being created */ int flags, /* Flags passed as 4th argument to xOpen() */ - mode_t *pMode /* OUT: Permissions to open file with */ + mode_t *pMode, /* OUT: Permissions to open file with */ + uid_t *pUid, /* OUT: uid to set on the file */ + gid_t *pGid /* OUT: gid to set on the file */ ){ int rc = SQLITE_OK; /* Return Code */ - *pMode = SQLITE_DEFAULT_FILE_PERMISSIONS; + *pMode = 0; + *pUid = 0; + *pGid = 0; if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ char zDb[MAX_PATHNAME+1]; /* Database file path */ int nDb; /* Number of valid bytes in zDb */ struct stat sStat; /* Output of stat() on database file */ @@ -29875,10 +29990,12 @@ memcpy(zDb, zPath, nDb); zDb[nDb] = '\0'; if( 0==osStat(zDb, &sStat) ){ *pMode = sStat.st_mode & 0777; + *pUid = sStat.st_uid; + *pGid = sStat.st_gid; }else{ rc = SQLITE_IOERR_FSTAT; } }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ *pMode = 0600; @@ -30021,11 +30138,13 @@ if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW); openFlags |= (O_LARGEFILE|O_BINARY); if( fd<0 ){ mode_t openMode; /* Permissions to create file with */ - rc = findCreateFileMode(zName, flags, &openMode); + uid_t uid; /* Userid for the file */ + gid_t gid; /* Groupid for the file */ + rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); if( rc!=SQLITE_OK ){ assert( !p->pUnused ); assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); return rc; } @@ -30042,10 +30161,21 @@ } if( fd<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); goto open_finished; } + + /* If this process is running as root and if creating a new rollback + ** journal or WAL file, set the ownership of the journal or WAL to be + ** the same as the original database. If we are not running as root, + ** then the fchown() call will fail, but that's ok. The "if(){}" and + ** the setting of the UNIXFILE_CHOWN flag are purely to silence compiler + ** warnings from gcc. + */ + if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ + if( osFchown(fd, uid, gid)==0 ){ p->ctrlFlags |= UNIXFILE_CHOWN; } + } } assert( fd>=0 ); if( pOutFlags ){ *pOutFlags = flags; } @@ -30353,11 +30483,11 @@ ** tests repeatable. */ memset(zBuf, 0, nBuf); #if !defined(SQLITE_TEST) { - int pid, fd; + int pid, fd, got; fd = robust_open("/dev/urandom", O_RDONLY, 0); if( fd<0 ){ time_t t; time(&t); memcpy(zBuf, &t, sizeof(t)); @@ -30364,11 +30494,11 @@ pid = getpid(); memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid)); assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf ); nBuf = sizeof(t) + sizeof(pid); }else{ - do{ nBuf = osRead(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR ); + do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR ); robust_close(0, fd, __LINE__); } } #endif return nBuf; @@ -30768,21 +30898,21 @@ if( !pUnused ){ return SQLITE_NOMEM; } } if( fd<0 ){ - fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, 0); terrno = errno; if( fd<0 && errno==ENOENT && islockfile ){ if( proxyCreateLockPath(path) == SQLITE_OK ){ - fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, 0); } } } if( fd<0 ){ openFlags = O_RDONLY; - fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(path, openFlags, 0); terrno = errno; } if( fd<0 ){ if( islockfile ){ return SQLITE_BUSY; @@ -30902,12 +31032,11 @@ if( readLenh>=0 ){ robust_close(pFile, pFile->h, __LINE__); } pFile->h = -1; - fd = robust_open(pCtx->dbPath, pFile->openFlags, - SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = robust_open(pCtx->dbPath, pFile->openFlags, 0); OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); if( fd>=0 ){ pFile->h = fd; }else{ rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called @@ -31750,11 +31878,11 @@ }; unsigned int i; /* Loop counter */ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==20 ); + assert( ArraySize(aSyscall)==22 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ sqlite3_vfs_register(&aVfs[i], i==0); } @@ -36789,20 +36917,19 @@ int szExtra; /* Size of extra space in bytes */ int bPurgeable; /* True if cache is purgeable */ unsigned int nMin; /* Minimum number of pages reserved */ unsigned int nMax; /* Configured "cache_size" value */ unsigned int n90pct; /* nMax*9/10 */ + unsigned int iMaxKey; /* Largest key seen since xTruncate() */ /* Hash table of all pages. The following variables may only be accessed ** when the accessor is holding the PGroup mutex. */ unsigned int nRecyclable; /* Number of pages in the LRU list */ unsigned int nPage; /* Total number of pages in apHash */ unsigned int nHash; /* Number of slots in apHash[] */ PgHdr1 **apHash; /* Hash table for fast lookup by key */ - - unsigned int iMaxKey; /* Largest key seen since xTruncate() */ }; /* ** Each cache entry is represented by an instance of the following ** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of @@ -36842,12 +36969,12 @@ int nSlot; /* The number of pcache slots */ int nReserve; /* Try to keep nFreeSlot above this */ void *pStart, *pEnd; /* Bounds of pagecache malloc range */ /* Above requires no mutex. Use mutex below for variable that follow. */ sqlite3_mutex *mutex; /* Mutex for accessing the following: */ - int nFreeSlot; /* Number of unused pcache slots */ PgFreeslot *pFree; /* Free page blocks */ + int nFreeSlot; /* Number of unused pcache slots */ /* The following value requires a mutex to change. We skip the mutex on ** reading because (1) most platforms read a 32-bit integer atomically and ** (2) even if an incorrect value is read, no great harm is done since this ** is really just an optimization. */ int bUnderPressure; /* True if low on PAGECACHE memory */ @@ -38224,10 +38351,11 @@ # define sqlite3WalFrames(u,v,w,x,y,z) 0 # define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0 # define sqlite3WalCallback(z) 0 # define sqlite3WalExclusiveMode(y,z) 0 # define sqlite3WalHeapMemory(z) 0 +# define sqlite3WalFramesize(z) 0 #else #define WAL_SAVEPOINT_NDATA 4 /* Connection to a write-ahead log (WAL) file. @@ -38304,10 +38432,17 @@ /* Return true if the argument is non-NULL and the WAL module is using ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the ** WAL module is using shared-memory, return false. */ SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal); + +#ifdef SQLITE_ENABLE_ZIPVFS +/* If the WAL file is not empty, return the number of bytes of content +** stored in each frame (i.e. the db page-size when the WAL was created). +*/ +SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal); +#endif #endif /* ifndef SQLITE_OMIT_WAL */ #endif /* _WAL_H_ */ /************** End of wal.h *************************************************/ @@ -38901,11 +39036,10 @@ struct Pager { sqlite3_vfs *pVfs; /* OS functions to use for IO */ u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ u8 useJournal; /* Use a rollback journal on this file */ - u8 noReadlock; /* Do not bother to obtain readlocks */ u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ @@ -39149,11 +39283,11 @@ break; case PAGER_READER: assert( pPager->errCode==SQLITE_OK ); assert( p->eLock!=UNKNOWN_LOCK ); - assert( p->eLock>=SHARED_LOCK || p->noReadlock ); + assert( p->eLock>=SHARED_LOCK ); break; case PAGER_WRITER_LOCKED: assert( p->eLock!=UNKNOWN_LOCK ); assert( pPager->errCode==SQLITE_OK ); @@ -41358,11 +41492,11 @@ ** if the database size is not available. The database size is not ** available from the WAL sub-system if the log file is empty or ** contains no valid committed transactions. */ assert( pPager->eState==PAGER_OPEN ); - assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock ); + assert( pPager->eLock>=SHARED_LOCK ); nPage = sqlite3WalDbsize(pPager->pWal); /* If the database size was not available from the WAL sub-system, ** determine it based on the size of the database file. If the size ** of the database file is not an integer multiple of the page-size, @@ -41413,11 +41547,11 @@ ** other connection. */ static int pagerOpenWalIfPresent(Pager *pPager){ int rc = SQLITE_OK; assert( pPager->eState==PAGER_OPEN ); - assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock ); + assert( pPager->eLock>=SHARED_LOCK ); if( !pPager->tempFile ){ int isWal; /* True if WAL file exists */ Pgno nPage; /* Size of the database file */ @@ -42576,11 +42710,11 @@ ** along with each page reference. This space is available to the user ** via the sqlite3PagerGetExtra() API. ** ** The flags argument is used to specify properties that affect the ** operation of the pager. It should be passed some bitwise combination -** of the PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK flags. +** of the PAGER_* flags. ** ** The vfsFlags parameter is a bitmask to pass to the flags parameter ** of the xOpen() method of the supplied VFS when opening files. ** ** If the pager object is allocated and the specified file opened @@ -42607,11 +42741,10 @@ int readOnly = 0; /* True if this is a read-only file */ int journalFileSize; /* Bytes to allocate for each journal fd */ char *zPathname = 0; /* Full path to database file */ int nPathname = 0; /* Number of bytes in zPathname */ int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ - int noReadlock = (flags & PAGER_NO_READLOCK)!=0; /* True to omit read-lock */ int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ const char *zUri = 0; /* URI args to copy */ int nUri = 0; /* Number of bytes of URI args at *zUri */ @@ -42814,11 +42947,10 @@ PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename)); IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) pPager->useJournal = (u8)useJournal; - pPager->noReadlock = (noReadlock && readOnly) ?1:0; /* pPager->stmtOpen = 0; */ /* pPager->stmtInUse = 0; */ /* pPager->nRef = 0; */ /* pPager->stmtSize = 0; */ /* pPager->stmtJSize = 0; */ @@ -43036,18 +43168,15 @@ if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){ int bHotJournal = 1; /* True if there exists a hot journal-file */ assert( !MEMDB ); - assert( pPager->noReadlock==0 || pPager->readOnly ); - - if( pPager->noReadlock==0 ){ - rc = pager_wait_on_lock(pPager, SHARED_LOCK); - if( rc!=SQLITE_OK ){ - assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK ); - goto failed; - } + + rc = pager_wait_on_lock(pPager, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK ); + goto failed; } /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ @@ -45051,11 +45180,11 @@ */ static int pagerOpenWal(Pager *pPager){ int rc = SQLITE_OK; assert( pPager->pWal==0 && pPager->tempFile==0 ); - assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK || pPager->noReadlock); + assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); /* If the pager is already in exclusive-mode, the WAL module will use ** heap-memory for the wal-index instead of the VFS shared-memory ** implementation. Take the exclusive lock now, before opening the WAL ** file, to make sure this is safe. @@ -45165,10 +45294,24 @@ pPager->pWal = 0; } } return rc; } + +#ifdef SQLITE_ENABLE_ZIPVFS +/* +** A read-lock must be held on the pager when this function is called. If +** the pager is in WAL mode and the WAL file currently contains one or more +** frames, return the size in bytes of the page images stored within the +** WAL frames. Otherwise, if this is not a WAL database or the WAL file +** is empty, return 0. +*/ +SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ + assert( pPager->eState==PAGER_READER ); + return sqlite3WalFramesize(pPager->pWal); +} +#endif #ifdef SQLITE_HAS_CODEC /* ** This function is called by the wal module when writing page content ** into the log file. @@ -47585,11 +47728,11 @@ testcase( sz<=32768 ); testcase( sz>=65536 ); iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; *pInWal = 1; /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ - return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset); + return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); } *pInWal = 0; return SQLITE_OK; } @@ -48255,10 +48398,22 @@ ** WAL module is using shared-memory, return false. */ SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){ return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ); } + +#ifdef SQLITE_ENABLE_ZIPVFS +/* +** If the argument is not NULL, it points to a Wal object that holds a +** read-lock. This function returns the database page-size if it is known, +** or zero if it is not (or if pWal is NULL). +*/ +SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){ + assert( pWal==0 || pWal->readLock>=0 ); + return (pWal ? pWal->szPage : 0); +} +#endif #endif /* #ifndef SQLITE_OMIT_WAL */ /************** End of wal.c *************************************************/ /************** Begin file btmutex.c *****************************************/ @@ -48564,14 +48719,13 @@ u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ u16 cellOffset; /* Index in aData of first cell pointer */ u16 nFree; /* Number of free bytes on the page */ u16 nCell; /* Number of cells on this page, local and ovfl */ u16 maskPage; /* Mask for page offset */ - struct _OvflCell { /* Cells that will not fit on aData[] */ - u8 *pCell; /* Pointers to the body of the overflow cell */ - u16 idx; /* Insert this cell before idx-th non-overflow cell */ - } aOvfl[5]; + u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th + ** non-overflow cell */ + u8 *apOvfl[5]; /* Pointers to the body of overflow cells */ BtShared *pBt; /* Pointer to BtShared that this page is part of */ u8 *aData; /* Pointer to disk image of the page data */ u8 *aDataEnd; /* One byte past the end of usable data */ u8 *aCellIdx; /* The cell index area */ DbPage *pDbPage; /* Pager page handle */ @@ -48775,10 +48929,13 @@ struct BtCursor { Btree *pBtree; /* The Btree to which this cursor belongs */ BtShared *pBt; /* The BtShared this cursor points to */ BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ +#ifndef SQLITE_OMIT_INCRBLOB + Pgno *aOverflow; /* Cache of overflow page locations */ +#endif Pgno pgnoRoot; /* The root page of this tree */ sqlite3_int64 cachedRowid; /* Next rowid cache. 0 means not valid */ CellInfo info; /* A parse of the cell we are pointing at */ i64 nKey; /* Size of pKey, or last integer key */ void *pKey; /* Saved key that was cursor's last known position */ @@ -48786,11 +48943,10 @@ u8 wrFlag; /* True if writable */ u8 atLast; /* Cursor pointing to the last entry */ u8 validNKey; /* True if info.nKey is valid */ u8 eState; /* One of the CURSOR_XXX constants (see below) */ #ifndef SQLITE_OMIT_INCRBLOB - Pgno *aOverflow; /* Cache of overflow page locations */ u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ #endif i16 iPage; /* Index of current page in apPage */ u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ @@ -48915,12 +49071,12 @@ */ typedef struct IntegrityCk IntegrityCk; struct IntegrityCk { BtShared *pBt; /* The tree being checked out */ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ - Pgno nPage; /* Number of pages in the database */ int *anRef; /* Number of times each page is referenced */ + Pgno nPage; /* Number of pages in the database */ int mxErr; /* Stop accumulating errors when this reaches zero */ int nErr; /* Number of messages written to zErrMsg so far */ int mallocFailed; /* A memory allocation error has occurred */ StrAccum errMsg; /* Accumulate the error message text here */ }; @@ -50076,16 +50232,14 @@ static u8 *findOverflowCell(MemPage *pPage, int iCell){ int i; assert( sqlite3_mutex_held(pPage->pBt->mutex) ); for(i=pPage->nOverflow-1; i>=0; i--){ int k; - struct _OvflCell *pOvfl; - pOvfl = &pPage->aOvfl[i]; - k = pOvfl->idx; + k = pPage->aiOvfl[i]; if( k<=iCell ){ if( k==iCell ){ - return pOvfl->pCell; + return pPage->apOvfl[i]; } iCell--; } } return findCell(pPage, iCell); @@ -50895,15 +51049,12 @@ ** when sqlite3BtreeClose() is called. ** ** If zFilename is ":memory:" then an in-memory database is created ** that is automatically destroyed when it is closed. ** -** The "flags" parameter is a bitmask that might contain bits -** BTREE_OMIT_JOURNAL and/or BTREE_NO_READLOCK. The BTREE_NO_READLOCK -** bit is also set if the SQLITE_NoReadlock flags is set in db->flags. -** These flags are passed through into sqlite3PagerOpen() and must -** be the same values as PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK. +** The "flags" parameter is a bitmask that might contain bits like +** BTREE_OMIT_JOURNAL and/or BTREE_MEMORY. ** ** If the database is already opened in the same database connection ** and we are in shared cache mode, then the open will fail with an ** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared ** objects in the same database connection since doing so will lead @@ -50946,13 +51097,10 @@ assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ assert( (flags & BTREE_SINGLE)==0 || isTempDb ); - if( db->flags & SQLITE_NoReadlock ){ - flags |= BTREE_NO_READLOCK; - } if( isMemdb ){ flags |= BTREE_MEMORY; } if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; @@ -51255,11 +51403,11 @@ /* Rollback any active transaction and free the handle structure. ** The call to sqlite3BtreeRollback() drops any table-locks held by ** this handle. */ - sqlite3BtreeRollback(p); + sqlite3BtreeRollback(p, SQLITE_OK); sqlite3BtreeLeave(p); /* If there are still other outstanding references to the shared-btree ** structure, return now. The remainder of this procedure cleans ** up the shared-btree. @@ -52493,10 +52641,11 @@ ** save the state of the cursor. The cursor must be ** invalidated. */ SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){ BtCursor *p; + if( pBtree==0 ) return; sqlite3BtreeEnter(pBtree); for(p=pBtree->pBt->pCursor; p; p=p->pNext){ int i; sqlite3BtreeClearCursor(p); p->eState = CURSOR_FAULT; @@ -52516,29 +52665,24 @@ ** in an error. ** ** This will release the write lock on the database file. If there ** are no active cursors, it also releases the read lock. */ -SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode){ int rc; BtShared *pBt = p->pBt; MemPage *pPage1; sqlite3BtreeEnter(p); - rc = saveAllCursors(pBt, 0, 0); -#ifndef SQLITE_OMIT_SHARED_CACHE - if( rc!=SQLITE_OK ){ - /* This is a horrible situation. An IO or malloc() error occurred whilst - ** trying to save cursor positions. If this is an automatic rollback (as - ** the result of a constraint, malloc() failure or IO error) then - ** the cache may be internally inconsistent (not contain valid trees) so - ** we cannot simply return the error to the caller. Instead, abort - ** all queries that may be using any of the cursors that failed to save. - */ - sqlite3BtreeTripAllCursors(p, rc); - } -#endif + if( tripCode==SQLITE_OK ){ + rc = tripCode = saveAllCursors(pBt, 0, 0); + }else{ + rc = SQLITE_OK; + } + if( tripCode ){ + sqlite3BtreeTripAllCursors(p, tripCode); + } btreeIntegrity(p); if( p->inTrans==TRANS_WRITE ){ int rc2; @@ -54733,11 +54877,11 @@ ** content of the cell. ** ** If the cell content will fit on the page, then put it there. If it ** will not fit, then make a copy of the cell content into pTemp if ** pTemp is not null. Regardless of pTemp, allocate a new entry -** in pPage->aOvfl[] and make it point to the cell content (either +** in pPage->apOvfl[] and make it point to the cell content (either ** in pTemp or the original pCell) and also record its index. ** Allocating a new entry in pPage->aCell[] implies that ** pPage->nOverflow is incremented. ** ** If nSkip is non-zero, then do not copy the first nSkip bytes of the @@ -54767,11 +54911,12 @@ if( *pRC ) return; assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921 ); - assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) ); + assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); + assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); /* The cell should normally be sized correctly. However, when moving a ** malformed cell from a leaf page to an interior page, if the cell size ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size ** might be less than 8 (leaf-size + pointer) on the interior node. Hence @@ -54784,13 +54929,13 @@ } if( iChild ){ put4byte(pCell, iChild); } j = pPage->nOverflow++; - assert( j<(int)(sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0])) ); - pPage->aOvfl[j].pCell = pCell; - pPage->aOvfl[j].idx = (u16)i; + assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) ); + pPage->apOvfl[j] = pCell; + pPage->aiOvfl[j] = (u16)i; }else{ int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc!=SQLITE_OK ){ *pRC = rc; return; @@ -54934,11 +55079,11 @@ rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); if( rc==SQLITE_OK ){ u8 *pOut = &pSpace[4]; - u8 *pCell = pPage->aOvfl[0].pCell; + u8 *pCell = pPage->apOvfl[0]; u16 szCell = cellSizePtr(pPage, pCell); u8 *pStop; assert( sqlite3PagerIswriteable(pNew->pDbPage) ); assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) ); @@ -55044,11 +55189,11 @@ ** parent page stored in the pointer map is page pTo. If pFrom contained ** any cells with overflow page pointers, then the corresponding pointer ** map entries are also updated so that the parent page is page pTo. ** ** If pFrom is currently carrying any overflow cells (entries in the -** MemPage.aOvfl[] array), they are not copied to pTo. +** MemPage.apOvfl[] array), they are not copied to pTo. ** ** Before returning, page pTo is reinitialized using btreeInitPage(). ** ** The performance of this function is not critical. It is only used by ** the balance_shallower() and balance_deeper() procedures, neither of @@ -55181,11 +55326,11 @@ ** this overflow cell is present, it must be the cell with ** index iParentIdx. This scenario comes about when this function ** is called (indirectly) from sqlite3BtreeDelete(). */ assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); - assert( pParent->nOverflow==0 || pParent->aOvfl[0].idx==iParentIdx ); + assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx ); if( !aOvflSpace ){ return SQLITE_NOMEM; } @@ -55228,12 +55373,12 @@ goto balance_cleanup; } nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; if( (i--)==0 ) break; - if( i+nxDiv==pParent->aOvfl[0].idx && pParent->nOverflow ){ - apDiv[i] = pParent->aOvfl[0].pCell; + if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){ + apDiv[i] = pParent->apOvfl[0]; pgno = get4byte(apDiv[i]); szNew[i] = cellSizePtr(pParent, apDiv[i]); pParent->nOverflow = 0; }else{ apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow); @@ -55670,11 +55815,11 @@ ** actually moved between pages. */ MemPage *pNew = apNew[0]; MemPage *pOld = apCopy[0]; int nOverflow = pOld->nOverflow; int iNextOld = pOld->nCell + nOverflow; - int iOverflow = (nOverflow ? pOld->aOvfl[0].idx : -1); + int iOverflow = (nOverflow ? pOld->aiOvfl[0] : -1); j = 0; /* Current 'old' sibling page */ k = 0; /* Current 'new' sibling page */ for(i=0; inCell + pOld->nOverflow; if( pOld->nOverflow ){ nOverflow = pOld->nOverflow; - iOverflow = i + !leafData + pOld->aOvfl[0].idx; + iOverflow = i + !leafData + pOld->aiOvfl[0]; } isDivider = !leafData; } assert(nOverflow>0 || iOverflowaOvfl[0].idx==pOld->aOvfl[1].idx-1); - assert(nOverflow<3 || pOld->aOvfl[1].idx==pOld->aOvfl[2].idx-1); + assert(nOverflow<2 || pOld->aiOvfl[0]==pOld->aiOvfl[1]-1); + assert(nOverflow<3 || pOld->aiOvfl[1]==pOld->aiOvfl[2]-1); if( i==iOverflow ){ isDivider = 1; if( (--nOverflow)>0 ){ iOverflow++; } @@ -55812,11 +55957,14 @@ assert( pChild->nCell==pRoot->nCell ); TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno)); /* Copy the overflow cells from pRoot to pChild */ - memcpy(pChild->aOvfl, pRoot->aOvfl, pRoot->nOverflow*sizeof(pRoot->aOvfl[0])); + memcpy(pChild->aiOvfl, pRoot->aiOvfl, + pRoot->nOverflow*sizeof(pRoot->aiOvfl[0])); + memcpy(pChild->apOvfl, pRoot->apOvfl, + pRoot->nOverflow*sizeof(pRoot->apOvfl[0])); pChild->nOverflow = pRoot->nOverflow; /* Zero the contents of pRoot. Then install pChild as the right-child. */ zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF); put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild); @@ -55875,11 +56023,11 @@ rc = sqlite3PagerWrite(pParent->pDbPage); if( rc==SQLITE_OK ){ #ifndef SQLITE_OMIT_QUICKBALANCE if( pPage->hasData && pPage->nOverflow==1 - && pPage->aOvfl[0].idx==pPage->nCell + && pPage->aiOvfl[0]==pPage->nCell && pParent->pgno!=1 && pParent->nCell==iIdx ){ /* Call balance_quick() to create a new sibling of pPage on which ** to store the overflow cell. balance_quick() inserts a new cell @@ -58052,11 +58200,11 @@ } *pp = p->pNext; } /* If a transaction is still open on the Btree, roll it back. */ - sqlite3BtreeRollback(p->pDest); + sqlite3BtreeRollback(p->pDest, SQLITE_OK); /* Set the error code of the destination database handle. */ rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; sqlite3Error(p->pDestDb, rc, 0); @@ -58296,10 +58444,11 @@ if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){ memcpy(pMem->zMalloc, pMem->z, pMem->n); } if( pMem->flags&MEM_Dyn && pMem->xDel ){ + assert( pMem->xDel!=SQLITE_DYNAMIC ); pMem->xDel((void *)(pMem->z)); } pMem->z = pMem->zMalloc; if( pMem->z==0 ){ @@ -58475,10 +58624,11 @@ sqlite3VdbeMemFinalize(p, p->u.pDef); assert( (p->flags & MEM_Agg)==0 ); sqlite3VdbeMemRelease(p); }else if( p->flags&MEM_Dyn && p->xDel ){ assert( (p->flags&MEM_RowSet)==0 ); + assert( p->xDel!=SQLITE_DYNAMIC ); p->xDel((void *)p->z); p->xDel = 0; }else if( p->flags&MEM_RowSet ){ sqlite3RowSetClear(p->u.pRowSet); }else if( p->flags&MEM_Frame ){ @@ -58617,12 +58767,18 @@ ** the second condition under the assumption that addition overflow causes ** values to wrap around. On x86 hardware, the third term is always ** true and could be omitted. But we leave it in because other ** architectures might behave differently. */ - if( pMem->r==(double)pMem->u.i && pMem->u.i>SMALLEST_INT64 - && ALWAYS(pMem->u.ir==(double)pMem->u.i + && pMem->u.i>SMALLEST_INT64 +#if defined(__i486__) || defined(__x86_64__) + && ALWAYS(pMem->u.iu.iflags |= MEM_Int; } } /* @@ -59592,18 +59748,15 @@ ** Hence, a negative P2 value is a label that has yet to be resolved. ** ** Zero is returned if a malloc() fails. */ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *p){ - int i; - i = p->nLabel++; + int i = p->nLabel++; assert( p->magic==VDBE_MAGIC_INIT ); - if( i>=p->nLabelAlloc ){ - int n = p->nLabelAlloc*2 + 5; - p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, - n*sizeof(p->aLabel[0])); - p->nLabelAlloc = sqlite3DbMallocSize(p->db, p->aLabel)/sizeof(p->aLabel[0]); + if( (i & (i-1))==0 ){ + p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, + (i*2+1)*sizeof(p->aLabel[0])); } if( p->aLabel ){ p->aLabel[i] = -1; } return -1-i; @@ -61357,36 +61510,10 @@ } #else #define checkActiveVdbeCnt(x) #endif -/* -** For every Btree that in database connection db which -** has been modified, "trip" or invalidate each cursor in -** that Btree might have been modified so that the cursor -** can never be used again. This happens when a rollback -*** occurs. We have to trip all the other cursors, even -** cursor from other VMs in different database connections, -** so that none of them try to use the data at which they -** were pointing and which now may have been changed due -** to the rollback. -** -** Remember that a rollback can delete tables complete and -** reorder rootpages. So it is not sufficient just to save -** the state of the cursor. We have to invalidate the cursor -** so that it is never used again. -*/ -static void invalidateCursorsOnModifiedBtrees(sqlite3 *db){ - int i; - for(i=0; inDb; i++){ - Btree *p = db->aDb[i].pBt; - if( p && sqlite3BtreeIsInTrans(p) ){ - sqlite3BtreeTripAllCursors(p, SQLITE_ABORT); - } - } -} - /* ** If the Vdbe passed as the first argument opened a statement-transaction, ** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or ** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement ** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the @@ -61547,12 +61674,11 @@ eStatementOp = SAVEPOINT_ROLLBACK; }else{ /* We are forced to roll back the active transaction. Before doing ** so, abort any other statements this handle currently has active. */ - invalidateCursorsOnModifiedBtrees(db); - sqlite3RollbackAll(db); + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); sqlite3CloseSavepoints(db); db->autoCommit = 1; } } } @@ -61590,27 +61716,26 @@ if( rc==SQLITE_BUSY && p->readOnly ){ sqlite3VdbeLeave(p); return SQLITE_BUSY; }else if( rc!=SQLITE_OK ){ p->rc = rc; - sqlite3RollbackAll(db); + sqlite3RollbackAll(db, SQLITE_OK); }else{ db->nDeferredCons = 0; sqlite3CommitInternalChanges(db); } }else{ - sqlite3RollbackAll(db); + sqlite3RollbackAll(db, SQLITE_OK); } db->nStatement = 0; }else if( eStatementOp==0 ){ if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){ eStatementOp = SAVEPOINT_RELEASE; }else if( p->errorAction==OE_Abort ){ eStatementOp = SAVEPOINT_ROLLBACK; }else{ - invalidateCursorsOnModifiedBtrees(db); - sqlite3RollbackAll(db); + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); sqlite3CloseSavepoints(db); db->autoCommit = 1; } } @@ -61626,12 +61751,11 @@ if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){ p->rc = rc; sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; } - invalidateCursorsOnModifiedBtrees(db); - sqlite3RollbackAll(db); + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); sqlite3CloseSavepoints(db); db->autoCommit = 1; } } @@ -61644,16 +61768,10 @@ }else{ sqlite3VdbeSetChanges(db, 0); } p->nChange = 0; } - - /* Rollback or commit any schema changes that occurred. */ - if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){ - sqlite3ResetInternalSchema(db, -1); - db->flags = (db->flags | SQLITE_InternChanges); - } /* Release the locks */ sqlite3VdbeLeave(p); } @@ -66070,23 +66188,30 @@ arithmetic_result_is_null: sqlite3VdbeMemSetNull(pOut); break; } -/* Opcode: CollSeq * * P4 +/* Opcode: CollSeq P1 * * P4 ** ** P4 is a pointer to a CollSeq struct. If the next call to a user function ** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will ** be returned. This is used by the built-in min(), max() and nullif() ** functions. +** +** If P1 is not zero, then it is a register that a subsequent min() or +** max() aggregate will set to 1 if the current row is not the minimum or +** maximum. The P1 register is initialized to 0 by this instruction. ** ** The interface used by the implementation of the aforementioned functions ** to retrieve the collation sequence set by this opcode is not available ** publicly, only to user functions defined in func.c. */ case OP_CollSeq: { assert( pOp->p4type==P4_COLLSEQ ); + if( pOp->p1 ){ + sqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0); + } break; } /* Opcode: Function P1 P2 P3 P4 P5 ** @@ -67438,20 +67563,16 @@ u.ar.iSavepoint++; } if( !u.ar.pSavepoint ){ sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.ar.zName); rc = SQLITE_ERROR; - }else if( - db->writeVdbeCnt>0 || (u.ar.p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1) - ){ + }else if( db->writeVdbeCnt>0 && u.ar.p1==SAVEPOINT_RELEASE ){ /* It is not possible to release (commit) a savepoint if there are - ** active write statements. It is not possible to rollback a savepoint - ** if there are any active statements at all. + ** active write statements. */ sqlite3SetString(&p->zErrMsg, db, - "cannot %s savepoint - SQL statements in progress", - (u.ar.p1==SAVEPOINT_ROLLBACK ? "rollback": "release") + "cannot release savepoint - SQL statements in progress" ); rc = SQLITE_BUSY; }else{ /* Determine whether or not this is a transaction savepoint. If so, @@ -67472,10 +67593,13 @@ } db->isTransactionSavepoint = 0; rc = p->rc; }else{ u.ar.iSavepoint = db->nSavepoint - u.ar.iSavepoint - 1; + for(u.ar.ii=0; u.ar.iinDb; u.ar.ii++){ + sqlite3BtreeTripAllCursors(db->aDb[u.ar.ii].pBt, SQLITE_ABORT); + } for(u.ar.ii=0; u.ar.iinDb; u.ar.ii++){ rc = sqlite3BtreeSavepoint(db->aDb[u.ar.ii].pBt, u.ar.p1, u.ar.iSavepoint); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -67542,29 +67666,32 @@ u.as.turnOnAC = u.as.desiredAutoCommit && !db->autoCommit; assert( u.as.desiredAutoCommit==1 || u.as.desiredAutoCommit==0 ); assert( u.as.desiredAutoCommit==1 || u.as.iRollback==0 ); assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */ +#if 0 if( u.as.turnOnAC && u.as.iRollback && db->activeVdbeCnt>1 ){ /* If this instruction implements a ROLLBACK and other VMs are ** still running, and a transaction is active, return an error indicating ** that the other VMs must complete first. */ sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - " "SQL statements in progress"); rc = SQLITE_BUSY; - }else if( u.as.turnOnAC && !u.as.iRollback && db->writeVdbeCnt>0 ){ + }else +#endif + if( u.as.turnOnAC && !u.as.iRollback && db->writeVdbeCnt>0 ){ /* If this instruction implements a COMMIT and other VMs are writing ** return an error indicating that the other VMs must complete first. */ sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - " "SQL statements in progress"); rc = SQLITE_BUSY; }else if( u.as.desiredAutoCommit!=db->autoCommit ){ if( u.as.iRollback ){ assert( u.as.desiredAutoCommit==1 ); - sqlite3RollbackAll(db); + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); db->autoCommit = 1; }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ goto vdbe_return; }else{ db->autoCommit = (u8)u.as.desiredAutoCommit; @@ -67616,11 +67743,11 @@ ** If a write-transaction is started and the Vdbe.usesStmtJournal flag is ** true (this flag is set if the Vdbe may modify more than one row and may ** throw an ABORT exception), a statement transaction may also be opened. ** More specifically, a statement transaction is opened iff the database ** connection is currently not in autocommit mode, or if there are other -** active statements. A statement transaction allows the affects of this +** active statements. A statement transaction allows the changes made by this ** VDBE to be rolled back after an error without having to roll back the ** entire transaction. If no error is encountered, the statement transaction ** will automatically commit when the VDBE halts. ** ** If P2 is zero, then a read-lock is obtained on the database file. @@ -68626,11 +68753,11 @@ u.bg.v = 1; /* IMP: R-61914-48074 */ }else{ assert( sqlite3BtreeCursorIsValid(u.bg.pC->pCursor) ); rc = sqlite3BtreeKeySize(u.bg.pC->pCursor, &u.bg.v); assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ - if( u.bg.v==MAX_ROWID ){ + if( u.bg.v>=MAX_ROWID ){ u.bg.pC->useRandomRowid = 1; }else{ u.bg.v++; /* IMP: R-29538-34987 */ } } @@ -69660,10 +69787,11 @@ if( rc==SQLITE_OK ) rc = u.by.initData.rc; sqlite3DbFree(db, u.by.zSql); db->init.busy = 0; } } + if( rc ) sqlite3ResetInternalSchema(db, -1); if( rc==SQLITE_NOMEM ){ goto no_mem; } break; } @@ -70002,11 +70130,10 @@ p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; p->aOp = aOp = u.cc.pProgram->aOp; p->nOp = u.cc.pProgram->nOp; p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; p->nOnceFlag = u.cc.pProgram->nOnce; - p->nOp = u.cc.pProgram->nOp; pc = -1; memset(p->aOnceFlag, 0, p->nOnceFlag); break; } @@ -70197,10 +70324,11 @@ u.cf.ctx.s.zMalloc = 0; u.cf.ctx.s.xDel = 0; u.cf.ctx.s.db = db; u.cf.ctx.isError = 0; u.cf.ctx.pColl = 0; + u.cf.ctx.skipFlag = 0; if( u.cf.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ assert( pOp>p->aOp ); assert( pOp[-1].p4type==P4_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); u.cf.ctx.pColl = pOp[-1].p4.pColl; @@ -70208,10 +70336,15 @@ (u.cf.ctx.pFunc->xStep)(&u.cf.ctx, u.cf.n, u.cf.apVal); /* IMP: R-24505-23230 */ if( u.cf.ctx.isError ){ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cf.ctx.s)); rc = u.cf.ctx.isError; } + if( u.cf.ctx.skipFlag ){ + assert( pOp[-1].opcode==OP_CollSeq ); + u.cf.i = pOp[-1].p1; + if( u.cf.i ) sqlite3VdbeMemSetInt64(&aMem[u.cf.i], 1); + } sqlite3VdbeMemRelease(&u.cf.ctx.s); break; } @@ -71601,21 +71734,21 @@ ** In other words, each time we advance to the next sorter element, log2(N) ** key comparison operations are required, where N is the number of segments ** being merged (rounded up to the next power of 2). */ struct VdbeSorter { - int nInMemory; /* Current size of pRecord list as PMA */ - int nTree; /* Used size of aTree/aIter (power of 2) */ - VdbeSorterIter *aIter; /* Array of iterators to merge */ - int *aTree; /* Current state of incremental merge */ i64 iWriteOff; /* Current write offset within file pTemp1 */ i64 iReadOff; /* Current read offset within file pTemp1 */ - sqlite3_file *pTemp1; /* PMA file 1 */ + int nInMemory; /* Current size of pRecord list as PMA */ + int nTree; /* Used size of aTree/aIter (power of 2) */ int nPMA; /* Number of PMAs stored in pTemp1 */ - SorterRecord *pRecord; /* Head of in-memory record list */ int mnPmaSize; /* Minimum PMA size, in bytes */ int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */ + VdbeSorterIter *aIter; /* Array of iterators to merge */ + int *aTree; /* Current state of incremental merge */ + sqlite3_file *pTemp1; /* PMA file 1 */ + SorterRecord *pRecord; /* Head of in-memory record list */ UnpackedRecord *pUnpacked; /* Used to unpack keys */ }; /* ** The following type is an iterator for a PMA. It caches the current key in @@ -71622,14 +71755,14 @@ ** variables nKey/aKey. If the iterator is at EOF, pFile==0. */ struct VdbeSorterIter { i64 iReadOff; /* Current read offset */ i64 iEof; /* 1 byte past EOF for this iterator */ - sqlite3_file *pFile; /* File iterator is reading from */ int nAlloc; /* Bytes of space at aAlloc */ - u8 *aAlloc; /* Allocated space */ int nKey; /* Number of bytes in key */ + sqlite3_file *pFile; /* File iterator is reading from */ + u8 *aAlloc; /* Allocated space */ u8 *aKey; /* Pointer to current key */ }; /* ** A structure to store a single record. All in-memory records are connected @@ -75112,12 +75245,13 @@ int i; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->iECursor = 0; - pNew->nExpr = pNew->nAlloc = p->nExpr; - pNew->a = pItem = sqlite3DbMallocRaw(db, p->nExpr*sizeof(p->a[0]) ); + pNew->nExpr = i = p->nExpr; + if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; inExpr; i+=i){} + pNew->a = pItem = sqlite3DbMallocRaw(db, i*sizeof(p->a[0]) ); if( pItem==0 ){ sqlite3DbFree(db, pNew); return 0; } pOldItem = p->a; @@ -75181,16 +75315,19 @@ IdList *pNew; int i; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); if( pNew==0 ) return 0; - pNew->nId = pNew->nAlloc = p->nId; + pNew->nId = p->nId; pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) ); if( pNew->a==0 ){ sqlite3DbFree(db, pNew); return 0; } + /* Note that because the size of the allocation for p->a[] is not + ** necessarily a power of two, sqlite3IdListAppend() may not be called + ** on the duplicate created by this function. */ for(i=0; inId; i++){ struct IdList_item *pNewItem = &pNew->a[i]; struct IdList_item *pOldItem = &p->a[i]; pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->idx = pOldItem->idx; @@ -75248,21 +75385,20 @@ if( pList==0 ){ pList = sqlite3DbMallocZero(db, sizeof(ExprList) ); if( pList==0 ){ goto no_mem; } - assert( pList->nAlloc==0 ); - } - if( pList->nAlloc<=pList->nExpr ){ + pList->a = sqlite3DbMallocRaw(db, sizeof(pList->a[0])); + if( pList->a==0 ) goto no_mem; + }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ struct ExprList_item *a; - int n = pList->nAlloc*2 + 4; - a = sqlite3DbRealloc(db, pList->a, n*sizeof(pList->a[0])); + assert( pList->nExpr>0 ); + a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0])); if( a==0 ){ goto no_mem; } pList->a = a; - pList->nAlloc = sqlite3DbMallocSize(db, a)/sizeof(a[0]); } assert( pList->a!=0 ); if( 1 ){ struct ExprList_item *pItem = &pList->a[pList->nExpr++]; memset(pItem, 0, sizeof(*pItem)); @@ -75349,12 +75485,11 @@ */ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ int i; struct ExprList_item *pItem; if( pList==0 ) return; - assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) ); - assert( pList->nExpr<=pList->nAlloc ); + assert( pList->a!=0 || pList->nExpr==0 ); for(pItem=pList->a, i=0; inExpr; i++, pItem++){ sqlite3ExprDelete(db, pItem->pExpr); sqlite3DbFree(db, pItem->zName); sqlite3DbFree(db, pItem->zSpan); } @@ -78031,13 +78166,11 @@ int i; pInfo->aCol = sqlite3ArrayAllocate( db, pInfo->aCol, sizeof(pInfo->aCol[0]), - 3, &pInfo->nColumn, - &pInfo->nColumnAlloc, &i ); return i; } @@ -78049,13 +78182,11 @@ int i; pInfo->aFunc = sqlite3ArrayAllocate( db, pInfo->aFunc, sizeof(pInfo->aFunc[0]), - 3, &pInfo->nFunc, - &pInfo->nFuncAlloc, &i ); return i; } @@ -78828,11 +78959,11 @@ "name = CASE " "WHEN type='table' THEN %Q " "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " "'sqlite_autoindex_' || %Q || substr(name,%d+18) " "ELSE name END " - "WHERE tbl_name=%Q AND " + "WHERE tbl_name=%Q COLLATE nocase AND " "(type='table' OR type='index' OR type='trigger');", zDb, SCHEMA_TABLE(iDb), zName, zName, zName, #ifndef SQLITE_OMIT_TRIGGER zName, #endif @@ -80058,10 +80189,11 @@ Index *pPrevIdx = 0; /* Previous index in the loop */ int idx = 0; /* slot in pIdx->aSample[] for next sample */ int eType; /* Datatype of a sample */ IndexSample *pSample; /* A slot in pIdx->aSample[] */ + assert( db->lookaside.bEnabled==0 ); if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){ return SQLITE_OK; } zSql = sqlite3MPrintf(db, @@ -80084,11 +80216,11 @@ nSample = sqlite3_column_int(pStmt, 1); pIdx = sqlite3FindIndex(db, zIndex, zDb); if( pIdx==0 ) continue; assert( pIdx->nSample==0 ); pIdx->nSample = nSample; - pIdx->aSample = sqlite3MallocZero( nSample*sizeof(IndexSample) ); + pIdx->aSample = sqlite3DbMallocZero(db, nSample*sizeof(IndexSample)); pIdx->avgEq = pIdx->aiRowEst[1]; if( pIdx->aSample==0 ){ db->mallocFailed = 1; sqlite3_finalize(pStmt); return SQLITE_NOMEM; @@ -80157,11 +80289,11 @@ int n = z ? sqlite3_column_bytes(pStmt, 4) : 0; pSample->nByte = n; if( n < 1){ pSample->u.z = 0; }else{ - pSample->u.z = sqlite3Malloc(n); + pSample->u.z = sqlite3DbMallocRaw(db, n); if( pSample->u.z==0 ){ db->mallocFailed = 1; sqlite3_finalize(pStmt); return SQLITE_NOMEM; } @@ -80233,11 +80365,14 @@ /* Load the statistics from the sqlite_stat3 table. */ #ifdef SQLITE_ENABLE_STAT3 if( rc==SQLITE_OK ){ + int lookasideEnabled = db->lookaside.bEnabled; + db->lookaside.bEnabled = 0; rc = loadStat3(db, sInfo.zDatabase); + db->lookaside.bEnabled = lookasideEnabled; } #endif if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; @@ -82697,11 +82832,10 @@ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ db->mallocFailed = 1; return; } pParse->pNewTable = 0; - db->nTable++; db->flags |= SQLITE_InternChanges; #ifndef SQLITE_OMIT_ALTERTABLE if( !p->pSelect ){ const char *zName = (const char *)pParse->sNameToken.z; @@ -84118,31 +84252,27 @@ */ SQLITE_PRIVATE void *sqlite3ArrayAllocate( sqlite3 *db, /* Connection to notify of malloc failures */ void *pArray, /* Array of objects. Might be reallocated */ int szEntry, /* Size of each object in the array */ - int initSize, /* Suggested initial allocation, in elements */ int *pnEntry, /* Number of objects currently in use */ - int *pnAlloc, /* Current size of the allocation, in elements */ int *pIdx /* Write the index of a new slot here */ ){ char *z; - if( *pnEntry >= *pnAlloc ){ - void *pNew; - int newSize; - newSize = (*pnAlloc)*2 + initSize; - pNew = sqlite3DbRealloc(db, pArray, newSize*szEntry); + int n = *pnEntry; + if( (n & (n-1))==0 ){ + int sz = (n==0) ? 1 : 2*n; + void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry); if( pNew==0 ){ *pIdx = -1; return pArray; } - *pnAlloc = sqlite3DbMallocSize(db, pNew)/szEntry; pArray = pNew; } z = (char*)pArray; - memset(&z[*pnEntry * szEntry], 0, szEntry); - *pIdx = *pnEntry; + memset(&z[n * szEntry], 0, szEntry); + *pIdx = n; ++*pnEntry; return pArray; } /* @@ -84154,19 +84284,16 @@ SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ int i; if( pList==0 ){ pList = sqlite3DbMallocZero(db, sizeof(IdList) ); if( pList==0 ) return 0; - pList->nAlloc = 0; } pList->a = sqlite3ArrayAllocate( db, pList->a, sizeof(pList->a[0]), - 5, &pList->nId, - &pList->nAlloc, &i ); if( i<0 ){ sqlite3IdListDelete(db, pList); return 0; @@ -86021,10 +86148,18 @@ ** Return the collating function associated with a function. */ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ return context->pColl; } + +/* +** Indicate that the accumulator load should be skipped on this +** iteration of the aggregate loop. +*/ +static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){ + context->skipFlag = 1; +} /* ** Implementation of the non-aggregate min() and max() functions */ static void minmaxFunc( @@ -86402,11 +86537,11 @@ ** in a way that is testable, mask the sign bit off of negative ** values, resulting in a positive value. Then take the ** 2s complement of that positive value. The end result can ** therefore be no less than -9223372036854775807. */ - r = -(r ^ (((sqlite3_int64)1)<<63)); + r = -(r & LARGEST_INT64); } sqlite3_result_int64(context, r); } /* @@ -87328,15 +87463,16 @@ ){ Mem *pArg = (Mem *)argv[0]; Mem *pBest; UNUSED_PARAMETER(NotUsed); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest)); if( !pBest ) return; - if( pBest->flags ){ + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + if( pBest->flags ) sqlite3SkipAccumulatorLoad(context); + }else if( pBest->flags ){ int max; int cmp; CollSeq *pColl = sqlite3GetFuncCollSeq(context); /* This step function is used for both the min() and max() aggregates, ** the only difference between the two being that the sense of the @@ -87348,20 +87484,22 @@ */ max = sqlite3_user_data(context)!=0; cmp = sqlite3MemCompare(pBest, pArg, pColl); if( (max && cmp<0) || (!max && cmp>0) ){ sqlite3VdbeMemCopy(pBest, pArg); + }else{ + sqlite3SkipAccumulatorLoad(context); } }else{ sqlite3VdbeMemCopy(pBest, pArg); } } static void minMaxFinalize(sqlite3_context *context){ sqlite3_value *pRes; pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0); if( pRes ){ - if( ALWAYS(pRes->flags) ){ + if( pRes->flags ){ sqlite3_result_value(context, pRes); } sqlite3VdbeMemRelease(pRes); } } @@ -91939,18 +92077,19 @@ */ /* ** Interpret the given string as a safety level. Return 0 for OFF, ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or -** unrecognized string argument. +** unrecognized string argument. The FULL option is disallowed +** if the omitFull parameter it 1. ** ** Note that the values returned are one less that the values that ** should be passed into sqlite3BtreeSetSafetyLevel(). The is done ** to support legacy SQL code. The safety level used to be boolean ** and older scripts may have used numbers 0 for OFF and 1 for ON. */ -static u8 getSafetyLevel(const char *z){ +static u8 getSafetyLevel(const char *z, int omitFull, int dflt){ /* 123456789 123456789 */ static const char zText[] = "onoffalseyestruefull"; static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4}; static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; @@ -91957,23 +92096,23 @@ int i, n; if( sqlite3Isdigit(*z) ){ return (u8)sqlite3Atoi(z); } n = sqlite3Strlen30(z); - for(i=0; iflags |= mask; }else{ db->flags &= ~mask; } @@ -92235,13 +92373,16 @@ char *zLeft = 0; /* Nul-terminated UTF-8 string */ char *zRight = 0; /* Nul-terminated UTF-8 string , or NULL */ const char *zDb = 0; /* The database name */ Token *pId; /* Pointer to token */ int iDb; /* Database index for */ - sqlite3 *db = pParse->db; - Db *pDb; - Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db); + char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ + int rc; /* return value form SQLITE_FCNTL_PRAGMA */ + sqlite3 *db = pParse->db; /* The database connection */ + Db *pDb; /* The specific database being pragmaed */ + Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db); /* Prepared statement */ + if( v==0 ) return; sqlite3VdbeRunOnlyOnce(v); pParse->nMem = 2; /* Interpret the [database.] part of the pragma statement. iDb is the @@ -92268,10 +92409,38 @@ assert( pId2 ); zDb = pId2->n>0 ? pDb->zName : 0; if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ goto pragma_out; } + + /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS + ** connection. If it returns SQLITE_OK, then assume that the VFS + ** handled the pragma and generate a no-op prepared statement. + */ + aFcntl[0] = 0; + aFcntl[1] = zLeft; + aFcntl[2] = zRight; + aFcntl[3] = 0; + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); + if( rc==SQLITE_OK ){ + if( aFcntl[0] ){ + int mem = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); + sqlite3_free(aFcntl[0]); + } + }else if( rc!=SQLITE_NOTFOUND ){ + if( aFcntl[0] ){ + sqlite3ErrorMsg(pParse, "%s", aFcntl[0]); + sqlite3_free(aFcntl[0]); + } + pParse->nErr++; + pParse->rc = rc; + }else + #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) /* ** PRAGMA [database.]default_cache_size ** PRAGMA [database.]default_cache_size=N @@ -92360,11 +92529,11 @@ if( sqlite3StrICmp(zLeft,"secure_delete")==0 ){ Btree *pBt = pDb->pBt; int b = -1; assert( pBt!=0 ); if( zRight ){ - b = sqlite3GetBoolean(zRight); + b = sqlite3GetBoolean(zRight, 0); } if( pId2->n==0 && b>=0 ){ int ii; for(ii=0; iinDb; ii++){ sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b); @@ -92555,11 +92724,11 @@ /* Call SetAutoVacuum() to set initialize the internal auto and ** incr-vacuum flags. This is required in case this connection ** creates the database file. It is important that it is created ** as an auto-vacuum capable db. */ - int rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); + rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ /* When setting the auto_vacuum mode to either "full" or ** "incremental", write the value of meta[6] in the database ** file. Before writing to meta[6], check that meta[3] indicates ** that this really is an auto-vacuum capable database. @@ -92673,11 +92842,10 @@ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } }else{ #ifndef SQLITE_OMIT_WSD if( zRight[0] ){ - int rc; int res; rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); if( rc!=SQLITE_OK || res==0 ){ sqlite3ErrorMsg(pParse, "not a writable directory"); goto pragma_out; @@ -92765,11 +92933,11 @@ }else{ if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else{ - pDb->safety_level = getSafetyLevel(zRight)+1; + pDb->safety_level = getSafetyLevel(zRight,0,1)+1; } } }else #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ @@ -92964,11 +93132,11 @@ #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ #ifndef NDEBUG if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ if( zRight ){ - if( sqlite3GetBoolean(zRight) ){ + if( sqlite3GetBoolean(zRight, 0) ){ sqlite3ParserTrace(stderr, "parser: "); }else{ sqlite3ParserTrace(0, 0); } } @@ -92978,11 +93146,11 @@ /* Reinstall the LIKE and GLOB functions. The variant of LIKE ** used will be case sensitive or not depending on the RHS. */ if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){ if( zRight ){ - sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight)); + sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0)); } }else #ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX # define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 @@ -94404,10 +94572,11 @@ } if( pEList==0 ){ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0)); } pNew->pEList = pEList; + if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc)); pNew->pSrc = pSrc; pNew->pWhere = pWhere; pNew->pGroupBy = pGroupBy; pNew->pHaving = pHaving; pNew->pOrderBy = pOrderBy; @@ -95588,11 +95757,11 @@ int nCol; /* Number of columns in the result set */ Expr *p; /* Expression for a single result column */ char *zName; /* Column name */ int nName; /* Size of name in zName[] */ - *pnCol = nCol = pEList->nExpr; + *pnCol = nCol = pEList ? pEList->nExpr : 0; aCol = *paCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); if( aCol==0 ) return SQLITE_NOMEM; for(i=0, pCol=aCol; ipEList && pPrior->pEList ); if( p->pEList->nExpr!=pPrior->pEList->nExpr ){ - sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" - " do not have the same number of result columns", selectOpName(p->op)); + if( p->selFlags & SF_Values ){ + sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); + }else{ + sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" + " do not have the same number of result columns", selectOpName(p->op)); + } rc = 1; goto multi_select_end; } /* Compound SELECTs that have an ORDER BY clause are handled separately. @@ -96559,11 +96732,11 @@ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); if( pNew==0 ) return SQLITE_NOMEM; pNew->flags |= EP_IntValue; pNew->u.iValue = i; pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); - pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i; + if( pOrderBy ) pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i; } } } /* Compute the comparison permutation and keyinfo that is used with @@ -97922,10 +98095,12 @@ ** the current cursor position. */ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ Vdbe *v = pParse->pVdbe; int i; + int regHit = 0; + int addrHitTest = 0; struct AggInfo_func *pF; struct AggInfo_col *pC; pAggInfo->directMode = 1; sqlite3ExprCacheClear(pParse); @@ -97957,11 +98132,12 @@ pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr); } if( !pColl ){ pColl = pParse->db->pDfltColl; } - sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); + if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); } sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem, (void*)pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg); @@ -97980,16 +98156,22 @@ ** text or blob value. See ticket [883034dcb5]. ** ** Another solution would be to change the OP_SCopy used to copy cached ** values to an OP_Copy. */ + if( regHit ){ + addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); + } sqlite3ExprCacheClear(pParse); for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); } pAggInfo->directMode = 0; sqlite3ExprCacheClear(pParse); + if( addrHitTest ){ + sqlite3VdbeJumpHere(v, addrHitTest); + } } /* ** Add a single OP_Explain instruction to the VDBE to explain a simple ** count(*) query ("SELECT count(*) FROM pTab"). @@ -98926,11 +99108,11 @@ sqlite3ExplainPop(pVdbe); } /* End of the structure debug printing code *****************************************************************************/ -#endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ +#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */ /************** End of select.c **********************************************/ /************** Begin file table.c *******************************************/ /* ** 2001 September 15 @@ -101105,10 +101287,22 @@ char *zKey; sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); if( nKey ) db->nextPagesize = 0; } #endif + + rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF"); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + + /* Begin a transaction and take an exclusive lock on the main database + ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, + ** to ensure that we do not try to change the page-size on a WAL database. + */ + rc = execSql(db, pzErrMsg, "BEGIN;"); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = sqlite3BtreeBeginTrans(pMain, 2); + if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Do not attempt to change the page size for a WAL database */ if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain)) ==PAGER_JOURNALMODE_WAL ){ db->nextPagesize = 0; @@ -101119,24 +101313,16 @@ || NEVER(db->mallocFailed) ){ rc = SQLITE_NOMEM; goto end_of_vacuum; } - rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF"); - if( rc!=SQLITE_OK ){ - goto end_of_vacuum; - } #ifndef SQLITE_OMIT_AUTOVACUUM sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac : sqlite3BtreeGetAutoVacuum(pMain)); #endif - /* Begin a transaction */ - rc = execSql(db, pzErrMsg, "BEGIN EXCLUSIVE;"); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - /* Query the schema of the main database. Create a mirror schema ** in the temporary database. */ rc = execExecSql(db, pzErrMsg, "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) " @@ -101553,17 +101739,18 @@ */ SQLITE_PRIVATE void sqlite3VtabBeginParse( Parse *pParse, /* Parsing context */ Token *pName1, /* Name of new table, or database name */ Token *pName2, /* Name of new table or NULL */ - Token *pModuleName /* Name of the module for the virtual table */ + Token *pModuleName, /* Name of the module for the virtual table */ + int ifNotExists /* No error if the table already exists */ ){ int iDb; /* The database the table is being created in */ Table *pTable; /* The new virtual table */ sqlite3 *db; /* Database connection */ - sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0); + sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists); pTable = pParse->pNewTable; if( pTable==0 ) return; assert( 0==pTable->pIndex ); db = pParse->db; @@ -101594,11 +101781,11 @@ ** This routine takes the module argument that has been accumulating ** in pParse->zArg[] and appends it to the list of arguments on the ** virtual table currently under construction in pParse->pTable. */ static void addArgumentToVtab(Parse *pParse){ - if( pParse->sArg.z && ALWAYS(pParse->pNewTable) ){ + if( pParse->sArg.z && pParse->pNewTable ){ const char *z = (const char*)pParse->sArg.z; int n = pParse->sArg.n; sqlite3 *db = pParse->db; addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n)); } @@ -105446,11 +105633,13 @@ } /* If there is a DISTINCT qualifier and this index will scan rows in ** order of the DISTINCT expressions, clear bDist and set the appropriate ** flags in wsFlags. */ - if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq) ){ + if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq) + && (wsFlags & WHERE_COLUMN_IN)==0 + ){ bDist = 0; wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT; } /* If currently calculating the cost of using an index (not the IPK @@ -106143,12 +106332,11 @@ */ static Bitmask codeOneLoopStart( WhereInfo *pWInfo, /* Complete information about the WHERE clause */ int iLevel, /* Which level of pWInfo->a[] should be coded */ u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ - Bitmask notReady, /* Which tables are currently available */ - Expr *pWhere /* Complete WHERE clause */ + Bitmask notReady /* Which tables are currently available */ ){ int j, k; /* Loop counters */ int iCur; /* The VDBE cursor for the table */ int addrNxt; /* Where to jump to continue with the next IN case */ int omitTable; /* True if we use the index only */ @@ -106683,14 +106871,29 @@ /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y ** Then for every term xN, evaluate as the subexpression: xN AND z ** That way, terms in y that are factored into the disjunction will ** be picked up by the recursive calls to sqlite3WhereBegin() below. + ** + ** Actually, each subexpression is converted to "xN AND w" where w is + ** the "interesting" terms of z - terms that did not originate in the + ** ON or USING clause of a LEFT JOIN, and terms that are usable as + ** indices. */ if( pWC->nTerm>1 ){ - pAndExpr = sqlite3ExprAlloc(pParse->db, TK_AND, 0, 0); - pAndExpr->pRight = pWhere; + int iTerm; + for(iTerm=0; iTermnTerm; iTerm++){ + Expr *pExpr = pWC->a[iTerm].pExpr; + if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; + if( pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_ORINFO) ) continue; + if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; + pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); + pAndExpr = sqlite3ExprAnd(pParse->db, pAndExpr, pExpr); + } + if( pAndExpr ){ + pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0); + } } for(ii=0; iinTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){ @@ -106728,11 +106931,14 @@ /* Finish the loop through table entries that match term pOrTerm. */ sqlite3WhereEnd(pSubWInfo); } } } - sqlite3DbFree(pParse->db, pAndExpr); + if( pAndExpr ){ + pAndExpr->pLeft = 0; + sqlite3ExprDelete(pParse->db, pAndExpr); + } sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk); sqlite3VdbeResolveLabel(v, iLoopBody); if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab); @@ -107384,11 +107590,11 @@ */ notReady = ~(Bitmask)0; for(i=0; ia[i]; explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags); - notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady, pWhere); + notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady); pWInfo->iContinue = pLevel->addrCont; } #ifdef SQLITE_TEST /* For testing and debugging use only */ /* Record in the query plan information about the current table @@ -107639,10 +107845,18 @@ /* ** An instance of this structure holds the ATTACH key and the key type. */ struct AttachKey { int type; Token key; }; +/* +** One or more VALUES claues +*/ +struct ValueList { + ExprList *pList; + Select *pSelect; +}; + /* This is a utility routine used to set the ExprSpan.zStart and ** ExprSpan.zEnd values of pOut so that the span covers the complete ** range of text beginning with pStart and going to the end of pEnd. */ @@ -107762,40 +107976,41 @@ ** YYNRULE the number of rules in the grammar ** YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. */ #define YYCODETYPE unsigned char -#define YYNOCODE 253 +#define YYNOCODE 251 #define YYACTIONTYPE unsigned short int #define YYWILDCARD 67 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - int yy4; - struct TrigEvent yy90; - ExprSpan yy118; - TriggerStep* yy203; - u8 yy210; - struct {int value; int mask;} yy215; - SrcList* yy259; - struct LimitVal yy292; - Expr* yy314; - ExprList* yy322; - struct LikeOp yy342; - IdList* yy384; - Select* yy387; + struct LimitVal yy64; + Expr* yy122; + Select* yy159; + IdList* yy180; + struct {int value; int mask;} yy207; + u8 yy258; + struct LikeOp yy318; + TriggerStep* yy327; + ExprSpan yy342; + SrcList* yy347; + int yy392; + struct TrigEvent yy410; + ExprList* yy442; + struct ValueList yy487; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 #endif #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse -#define YYNSTATE 630 -#define YYNRULE 329 +#define YYNSTATE 629 +#define YYNRULE 327 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) #define YY_ERROR_ACTION (YYNSTATE+YYNRULE) @@ -107861,477 +108076,480 @@ ** shifting terminals. ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. */ -#define YY_ACTTAB_COUNT (1557) +#define YY_ACTTAB_COUNT (1580) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 313, 960, 186, 419, 2, 172, 627, 597, 55, 55, - /* 10 */ 55, 55, 48, 53, 53, 53, 53, 52, 52, 51, - /* 20 */ 51, 51, 50, 238, 302, 283, 623, 622, 516, 515, - /* 30 */ 590, 584, 55, 55, 55, 55, 282, 53, 53, 53, - /* 40 */ 53, 52, 52, 51, 51, 51, 50, 238, 6, 56, - /* 50 */ 57, 47, 582, 581, 583, 583, 54, 54, 55, 55, - /* 60 */ 55, 55, 608, 53, 53, 53, 53, 52, 52, 51, - /* 70 */ 51, 51, 50, 238, 313, 597, 409, 330, 579, 579, - /* 80 */ 32, 53, 53, 53, 53, 52, 52, 51, 51, 51, - /* 90 */ 50, 238, 330, 217, 620, 619, 166, 411, 624, 382, - /* 100 */ 379, 378, 7, 491, 590, 584, 200, 199, 198, 58, - /* 110 */ 377, 300, 414, 621, 481, 66, 623, 622, 621, 580, - /* 120 */ 254, 601, 94, 56, 57, 47, 582, 581, 583, 583, - /* 130 */ 54, 54, 55, 55, 55, 55, 671, 53, 53, 53, - /* 140 */ 53, 52, 52, 51, 51, 51, 50, 238, 313, 532, - /* 150 */ 226, 506, 507, 133, 177, 139, 284, 385, 279, 384, - /* 160 */ 169, 197, 342, 398, 251, 226, 253, 275, 388, 167, - /* 170 */ 139, 284, 385, 279, 384, 169, 570, 236, 590, 584, - /* 180 */ 672, 240, 275, 157, 620, 619, 554, 437, 51, 51, - /* 190 */ 51, 50, 238, 343, 439, 553, 438, 56, 57, 47, - /* 200 */ 582, 581, 583, 583, 54, 54, 55, 55, 55, 55, - /* 210 */ 465, 53, 53, 53, 53, 52, 52, 51, 51, 51, - /* 220 */ 50, 238, 313, 390, 52, 52, 51, 51, 51, 50, - /* 230 */ 238, 391, 166, 491, 566, 382, 379, 378, 409, 440, - /* 240 */ 579, 579, 252, 440, 607, 66, 377, 513, 621, 49, - /* 250 */ 46, 147, 590, 584, 621, 16, 466, 189, 621, 441, - /* 260 */ 442, 673, 526, 441, 340, 577, 595, 64, 194, 482, - /* 270 */ 434, 56, 57, 47, 582, 581, 583, 583, 54, 54, - /* 280 */ 55, 55, 55, 55, 30, 53, 53, 53, 53, 52, - /* 290 */ 52, 51, 51, 51, 50, 238, 313, 593, 593, 593, - /* 300 */ 387, 578, 606, 493, 259, 351, 258, 411, 1, 623, - /* 310 */ 622, 496, 623, 622, 65, 240, 623, 622, 597, 443, - /* 320 */ 237, 239, 414, 341, 237, 602, 590, 584, 18, 603, - /* 330 */ 166, 601, 87, 382, 379, 378, 67, 623, 622, 38, - /* 340 */ 623, 622, 176, 270, 377, 56, 57, 47, 582, 581, - /* 350 */ 583, 583, 54, 54, 55, 55, 55, 55, 175, 53, - /* 360 */ 53, 53, 53, 52, 52, 51, 51, 51, 50, 238, - /* 370 */ 313, 396, 233, 411, 531, 565, 317, 620, 619, 44, - /* 380 */ 620, 619, 240, 206, 620, 619, 597, 266, 414, 268, - /* 390 */ 409, 597, 579, 579, 352, 184, 505, 601, 73, 533, - /* 400 */ 590, 584, 466, 548, 190, 620, 619, 576, 620, 619, - /* 410 */ 547, 383, 551, 35, 332, 575, 574, 600, 504, 56, - /* 420 */ 57, 47, 582, 581, 583, 583, 54, 54, 55, 55, - /* 430 */ 55, 55, 567, 53, 53, 53, 53, 52, 52, 51, - /* 440 */ 51, 51, 50, 238, 313, 411, 561, 561, 528, 364, - /* 450 */ 259, 351, 258, 183, 361, 549, 524, 374, 411, 597, - /* 460 */ 414, 240, 560, 560, 409, 604, 579, 579, 328, 601, - /* 470 */ 93, 623, 622, 414, 590, 584, 237, 564, 559, 559, - /* 480 */ 520, 402, 601, 87, 409, 210, 579, 579, 168, 421, - /* 490 */ 950, 519, 950, 56, 57, 47, 582, 581, 583, 583, - /* 500 */ 54, 54, 55, 55, 55, 55, 192, 53, 53, 53, - /* 510 */ 53, 52, 52, 51, 51, 51, 50, 238, 313, 600, - /* 520 */ 293, 563, 511, 234, 357, 146, 475, 475, 367, 411, - /* 530 */ 562, 411, 358, 542, 425, 171, 411, 215, 144, 620, - /* 540 */ 619, 544, 318, 353, 414, 203, 414, 275, 590, 584, - /* 550 */ 549, 414, 174, 601, 94, 601, 79, 558, 471, 61, - /* 560 */ 601, 79, 421, 949, 350, 949, 34, 56, 57, 47, - /* 570 */ 582, 581, 583, 583, 54, 54, 55, 55, 55, 55, - /* 580 */ 535, 53, 53, 53, 53, 52, 52, 51, 51, 51, - /* 590 */ 50, 238, 313, 307, 424, 394, 272, 49, 46, 147, - /* 600 */ 349, 322, 4, 411, 491, 312, 321, 425, 568, 492, - /* 610 */ 216, 264, 407, 575, 574, 429, 66, 549, 414, 621, - /* 620 */ 540, 602, 590, 584, 13, 603, 621, 601, 72, 12, - /* 630 */ 618, 617, 616, 202, 210, 621, 546, 469, 422, 319, - /* 640 */ 148, 56, 57, 47, 582, 581, 583, 583, 54, 54, - /* 650 */ 55, 55, 55, 55, 338, 53, 53, 53, 53, 52, - /* 660 */ 52, 51, 51, 51, 50, 238, 313, 600, 600, 411, - /* 670 */ 39, 21, 37, 170, 237, 875, 411, 572, 572, 201, - /* 680 */ 144, 473, 538, 331, 414, 474, 143, 146, 630, 628, - /* 690 */ 334, 414, 353, 601, 68, 168, 590, 584, 132, 365, - /* 700 */ 601, 96, 307, 423, 530, 336, 49, 46, 147, 568, - /* 710 */ 406, 216, 549, 360, 529, 56, 57, 47, 582, 581, - /* 720 */ 583, 583, 54, 54, 55, 55, 55, 55, 411, 53, - /* 730 */ 53, 53, 53, 52, 52, 51, 51, 51, 50, 238, - /* 740 */ 313, 411, 605, 414, 484, 510, 172, 422, 597, 318, - /* 750 */ 496, 485, 601, 99, 411, 142, 414, 411, 231, 411, - /* 760 */ 540, 411, 359, 629, 2, 601, 97, 426, 308, 414, - /* 770 */ 590, 584, 414, 20, 414, 621, 414, 621, 601, 106, - /* 780 */ 503, 601, 105, 601, 108, 601, 109, 204, 28, 56, - /* 790 */ 57, 47, 582, 581, 583, 583, 54, 54, 55, 55, - /* 800 */ 55, 55, 411, 53, 53, 53, 53, 52, 52, 51, - /* 810 */ 51, 51, 50, 238, 313, 411, 597, 414, 411, 276, - /* 820 */ 214, 600, 411, 366, 213, 381, 601, 134, 274, 500, - /* 830 */ 414, 167, 130, 414, 621, 411, 354, 414, 376, 601, - /* 840 */ 135, 129, 601, 100, 590, 584, 601, 104, 522, 521, - /* 850 */ 414, 621, 224, 273, 600, 167, 327, 282, 600, 601, - /* 860 */ 103, 468, 521, 56, 57, 47, 582, 581, 583, 583, - /* 870 */ 54, 54, 55, 55, 55, 55, 411, 53, 53, 53, - /* 880 */ 53, 52, 52, 51, 51, 51, 50, 238, 313, 411, - /* 890 */ 27, 414, 411, 375, 276, 167, 359, 544, 50, 238, - /* 900 */ 601, 95, 128, 223, 414, 411, 165, 414, 411, 621, - /* 910 */ 411, 621, 612, 601, 102, 372, 601, 76, 590, 584, - /* 920 */ 414, 570, 236, 414, 470, 414, 167, 621, 188, 601, - /* 930 */ 98, 225, 601, 138, 601, 137, 232, 56, 45, 47, - /* 940 */ 582, 581, 583, 583, 54, 54, 55, 55, 55, 55, - /* 950 */ 411, 53, 53, 53, 53, 52, 52, 51, 51, 51, - /* 960 */ 50, 238, 313, 276, 276, 414, 411, 276, 544, 459, - /* 970 */ 359, 171, 209, 479, 601, 136, 628, 334, 621, 621, - /* 980 */ 125, 414, 621, 368, 411, 621, 257, 540, 589, 588, - /* 990 */ 601, 75, 590, 584, 458, 446, 23, 23, 124, 414, - /* 1000 */ 326, 325, 621, 427, 324, 309, 600, 288, 601, 92, - /* 1010 */ 586, 585, 57, 47, 582, 581, 583, 583, 54, 54, - /* 1020 */ 55, 55, 55, 55, 411, 53, 53, 53, 53, 52, - /* 1030 */ 52, 51, 51, 51, 50, 238, 313, 587, 411, 414, - /* 1040 */ 411, 207, 611, 476, 171, 472, 160, 123, 601, 91, - /* 1050 */ 323, 261, 15, 414, 464, 414, 411, 621, 411, 354, - /* 1060 */ 222, 411, 601, 74, 601, 90, 590, 584, 159, 264, - /* 1070 */ 158, 414, 461, 414, 621, 600, 414, 121, 120, 25, - /* 1080 */ 601, 89, 601, 101, 621, 601, 88, 47, 582, 581, - /* 1090 */ 583, 583, 54, 54, 55, 55, 55, 55, 544, 53, - /* 1100 */ 53, 53, 53, 52, 52, 51, 51, 51, 50, 238, - /* 1110 */ 43, 405, 263, 3, 610, 264, 140, 415, 622, 24, - /* 1120 */ 410, 11, 456, 594, 118, 155, 219, 452, 408, 621, - /* 1130 */ 621, 621, 156, 43, 405, 621, 3, 286, 621, 113, - /* 1140 */ 415, 622, 111, 445, 411, 400, 557, 403, 545, 10, - /* 1150 */ 411, 408, 264, 110, 205, 436, 541, 566, 453, 414, - /* 1160 */ 621, 621, 63, 621, 435, 414, 411, 621, 601, 94, - /* 1170 */ 403, 621, 411, 337, 601, 86, 150, 40, 41, 534, - /* 1180 */ 566, 414, 242, 264, 42, 413, 412, 414, 600, 595, - /* 1190 */ 601, 85, 191, 333, 107, 451, 601, 84, 621, 539, - /* 1200 */ 40, 41, 420, 230, 411, 149, 316, 42, 413, 412, - /* 1210 */ 398, 127, 595, 315, 621, 399, 278, 625, 181, 414, - /* 1220 */ 593, 593, 593, 592, 591, 14, 450, 411, 601, 71, - /* 1230 */ 240, 621, 43, 405, 264, 3, 615, 180, 264, 415, - /* 1240 */ 622, 614, 414, 593, 593, 593, 592, 591, 14, 621, - /* 1250 */ 408, 601, 70, 621, 417, 33, 405, 613, 3, 411, - /* 1260 */ 264, 411, 415, 622, 418, 626, 178, 509, 8, 403, - /* 1270 */ 241, 416, 126, 408, 414, 621, 414, 449, 208, 566, - /* 1280 */ 240, 221, 621, 601, 83, 601, 82, 599, 297, 277, - /* 1290 */ 296, 30, 403, 31, 395, 264, 295, 397, 489, 40, - /* 1300 */ 41, 411, 566, 220, 621, 294, 42, 413, 412, 271, - /* 1310 */ 621, 595, 600, 621, 59, 60, 414, 269, 267, 623, - /* 1320 */ 622, 36, 40, 41, 621, 601, 81, 598, 235, 42, - /* 1330 */ 413, 412, 621, 621, 595, 265, 344, 411, 248, 556, - /* 1340 */ 173, 185, 593, 593, 593, 592, 591, 14, 218, 29, - /* 1350 */ 621, 543, 414, 305, 304, 303, 179, 301, 411, 566, - /* 1360 */ 454, 601, 80, 289, 335, 593, 593, 593, 592, 591, - /* 1370 */ 14, 411, 287, 414, 151, 392, 246, 260, 411, 196, - /* 1380 */ 195, 523, 601, 69, 411, 245, 414, 526, 537, 285, - /* 1390 */ 389, 595, 621, 414, 536, 601, 17, 362, 153, 414, - /* 1400 */ 466, 463, 601, 78, 154, 414, 462, 152, 601, 77, - /* 1410 */ 355, 255, 621, 455, 601, 9, 621, 386, 444, 517, - /* 1420 */ 247, 621, 593, 593, 593, 621, 621, 244, 621, 243, - /* 1430 */ 430, 518, 292, 621, 329, 621, 145, 393, 280, 513, - /* 1440 */ 291, 131, 621, 514, 621, 621, 311, 621, 259, 346, - /* 1450 */ 249, 621, 621, 229, 314, 621, 228, 512, 227, 240, - /* 1460 */ 494, 488, 310, 164, 487, 486, 373, 480, 163, 262, - /* 1470 */ 369, 371, 162, 26, 212, 478, 477, 161, 141, 363, - /* 1480 */ 467, 122, 339, 187, 119, 348, 347, 117, 116, 115, - /* 1490 */ 114, 112, 182, 457, 320, 22, 433, 432, 448, 19, - /* 1500 */ 609, 431, 428, 62, 193, 596, 573, 298, 555, 552, - /* 1510 */ 571, 404, 290, 380, 498, 510, 495, 306, 281, 499, - /* 1520 */ 250, 5, 497, 460, 345, 447, 569, 550, 238, 299, - /* 1530 */ 527, 525, 508, 961, 502, 501, 961, 401, 961, 211, - /* 1540 */ 490, 356, 256, 961, 483, 961, 961, 961, 961, 961, - /* 1550 */ 961, 961, 961, 961, 961, 961, 370, + /* 0 */ 310, 328, 574, 573, 15, 172, 187, 596, 56, 56, + /* 10 */ 56, 56, 49, 54, 54, 54, 54, 53, 53, 52, + /* 20 */ 52, 52, 51, 234, 622, 621, 626, 622, 621, 299, + /* 30 */ 589, 583, 56, 56, 56, 56, 236, 54, 54, 54, + /* 40 */ 54, 53, 53, 52, 52, 52, 51, 234, 351, 57, + /* 50 */ 58, 48, 581, 580, 582, 582, 55, 55, 56, 56, + /* 60 */ 56, 56, 570, 54, 54, 54, 54, 53, 53, 52, + /* 70 */ 52, 52, 51, 234, 310, 596, 326, 607, 233, 232, + /* 80 */ 33, 54, 54, 54, 54, 53, 53, 52, 52, 52, + /* 90 */ 51, 234, 619, 618, 326, 619, 618, 166, 605, 492, + /* 100 */ 381, 378, 377, 235, 589, 583, 554, 495, 1, 59, + /* 110 */ 19, 376, 622, 621, 53, 53, 52, 52, 52, 51, + /* 120 */ 234, 571, 571, 57, 58, 48, 581, 580, 582, 582, + /* 130 */ 55, 55, 56, 56, 56, 56, 215, 54, 54, 54, + /* 140 */ 54, 53, 53, 52, 52, 52, 51, 234, 310, 224, + /* 150 */ 50, 47, 147, 177, 139, 281, 384, 276, 383, 169, + /* 160 */ 408, 553, 578, 578, 622, 621, 272, 224, 439, 550, + /* 170 */ 552, 410, 139, 281, 384, 276, 383, 169, 589, 583, + /* 180 */ 619, 618, 280, 620, 272, 195, 413, 309, 440, 441, + /* 190 */ 567, 491, 214, 279, 560, 600, 92, 57, 58, 48, + /* 200 */ 581, 580, 582, 582, 55, 55, 56, 56, 56, 56, + /* 210 */ 559, 54, 54, 54, 54, 53, 53, 52, 52, 52, + /* 220 */ 51, 234, 310, 464, 233, 232, 558, 133, 519, 50, + /* 230 */ 47, 147, 619, 618, 565, 436, 397, 515, 514, 518, + /* 240 */ 410, 387, 438, 389, 437, 622, 621, 442, 570, 433, + /* 250 */ 203, 390, 589, 583, 6, 413, 166, 670, 250, 381, + /* 260 */ 378, 377, 525, 190, 600, 92, 594, 571, 571, 465, + /* 270 */ 376, 57, 58, 48, 581, 580, 582, 582, 55, 55, + /* 280 */ 56, 56, 56, 56, 599, 54, 54, 54, 54, 53, + /* 290 */ 53, 52, 52, 52, 51, 234, 310, 592, 592, 592, + /* 300 */ 490, 182, 247, 548, 249, 397, 273, 410, 7, 439, + /* 310 */ 398, 606, 67, 619, 618, 620, 472, 256, 347, 255, + /* 320 */ 473, 620, 413, 576, 620, 65, 589, 583, 236, 440, + /* 330 */ 336, 600, 92, 68, 364, 192, 481, 622, 621, 547, + /* 340 */ 622, 621, 560, 323, 207, 57, 58, 48, 581, 580, + /* 350 */ 582, 582, 55, 55, 56, 56, 56, 56, 559, 54, + /* 360 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234, + /* 370 */ 310, 410, 397, 146, 558, 531, 401, 348, 599, 166, + /* 380 */ 248, 204, 381, 378, 377, 541, 413, 171, 337, 570, + /* 390 */ 622, 621, 40, 376, 38, 600, 74, 465, 548, 490, + /* 400 */ 589, 583, 532, 350, 579, 619, 618, 297, 619, 618, + /* 410 */ 480, 67, 470, 39, 620, 599, 406, 574, 573, 57, + /* 420 */ 58, 48, 581, 580, 582, 582, 55, 55, 56, 56, + /* 430 */ 56, 56, 577, 54, 54, 54, 54, 53, 53, 52, + /* 440 */ 52, 52, 51, 234, 310, 256, 347, 255, 530, 52, + /* 450 */ 52, 52, 51, 234, 345, 564, 236, 386, 619, 618, + /* 460 */ 957, 185, 418, 2, 408, 410, 578, 578, 198, 197, + /* 470 */ 196, 499, 183, 167, 589, 583, 671, 570, 505, 506, + /* 480 */ 413, 267, 601, 672, 546, 208, 602, 36, 601, 600, + /* 490 */ 91, 468, 602, 57, 58, 48, 581, 580, 582, 582, + /* 500 */ 55, 55, 56, 56, 56, 56, 202, 54, 54, 54, + /* 510 */ 54, 53, 53, 52, 52, 52, 51, 234, 310, 599, + /* 520 */ 157, 408, 527, 578, 578, 263, 490, 265, 410, 873, + /* 530 */ 410, 474, 474, 366, 373, 410, 504, 428, 67, 290, + /* 540 */ 599, 620, 352, 413, 408, 413, 578, 578, 589, 583, + /* 550 */ 413, 382, 600, 92, 600, 16, 543, 62, 503, 600, + /* 560 */ 92, 408, 346, 578, 578, 168, 45, 57, 58, 48, + /* 570 */ 581, 580, 582, 582, 55, 55, 56, 56, 56, 56, + /* 580 */ 200, 54, 54, 54, 54, 53, 53, 52, 52, 52, + /* 590 */ 51, 234, 310, 393, 395, 534, 510, 617, 616, 615, + /* 600 */ 318, 314, 172, 66, 596, 410, 338, 596, 324, 571, + /* 610 */ 571, 50, 47, 147, 599, 629, 627, 330, 539, 315, + /* 620 */ 413, 30, 589, 583, 272, 236, 199, 144, 176, 600, + /* 630 */ 73, 420, 947, 620, 947, 420, 946, 351, 946, 175, + /* 640 */ 596, 57, 58, 48, 581, 580, 582, 582, 55, 55, + /* 650 */ 56, 56, 56, 56, 410, 54, 54, 54, 54, 53, + /* 660 */ 53, 52, 52, 52, 51, 234, 310, 261, 410, 413, + /* 670 */ 269, 208, 596, 363, 410, 596, 424, 360, 600, 69, + /* 680 */ 424, 327, 620, 413, 50, 47, 147, 410, 358, 413, + /* 690 */ 575, 553, 600, 94, 483, 509, 589, 583, 600, 97, + /* 700 */ 552, 484, 413, 620, 188, 599, 551, 563, 596, 566, + /* 710 */ 334, 600, 95, 205, 201, 57, 58, 48, 581, 580, + /* 720 */ 582, 582, 55, 55, 56, 56, 56, 56, 352, 54, + /* 730 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234, + /* 740 */ 310, 410, 261, 410, 167, 22, 356, 599, 359, 623, + /* 750 */ 50, 47, 147, 548, 357, 562, 413, 620, 413, 332, + /* 760 */ 523, 270, 410, 167, 620, 600, 104, 600, 103, 603, + /* 770 */ 589, 583, 339, 539, 304, 423, 222, 413, 174, 304, + /* 780 */ 422, 561, 567, 405, 214, 260, 600, 106, 620, 57, + /* 790 */ 58, 48, 581, 580, 582, 582, 55, 55, 56, 56, + /* 800 */ 56, 56, 410, 54, 54, 54, 54, 53, 53, 52, + /* 810 */ 52, 52, 51, 234, 310, 410, 557, 413, 410, 421, + /* 820 */ 273, 35, 512, 146, 421, 12, 600, 107, 213, 144, + /* 830 */ 413, 410, 32, 413, 410, 620, 365, 353, 358, 600, + /* 840 */ 134, 11, 600, 135, 589, 583, 413, 21, 548, 413, + /* 850 */ 316, 148, 620, 620, 170, 600, 98, 223, 600, 102, + /* 860 */ 374, 168, 167, 57, 58, 48, 581, 580, 582, 582, + /* 870 */ 55, 55, 56, 56, 56, 56, 410, 54, 54, 54, + /* 880 */ 54, 53, 53, 52, 52, 52, 51, 234, 310, 410, + /* 890 */ 273, 413, 410, 273, 212, 469, 410, 167, 628, 2, + /* 900 */ 600, 101, 545, 221, 413, 620, 130, 413, 620, 410, + /* 910 */ 539, 413, 537, 600, 93, 315, 600, 100, 589, 583, + /* 920 */ 600, 77, 425, 305, 413, 620, 254, 322, 599, 458, + /* 930 */ 320, 171, 543, 600, 96, 521, 520, 57, 58, 48, + /* 940 */ 581, 580, 582, 582, 55, 55, 56, 56, 56, 56, + /* 950 */ 410, 54, 54, 54, 54, 53, 53, 52, 52, 52, + /* 960 */ 51, 234, 310, 410, 273, 413, 410, 457, 358, 35, + /* 970 */ 426, 230, 306, 319, 600, 138, 467, 520, 413, 620, + /* 980 */ 143, 413, 410, 620, 410, 353, 529, 600, 137, 142, + /* 990 */ 600, 136, 589, 583, 604, 261, 528, 413, 229, 413, + /* 1000 */ 620, 321, 495, 28, 543, 543, 600, 76, 600, 90, + /* 1010 */ 620, 57, 46, 48, 581, 580, 582, 582, 55, 55, + /* 1020 */ 56, 56, 56, 56, 410, 54, 54, 54, 54, 53, + /* 1030 */ 53, 52, 52, 52, 51, 234, 310, 261, 451, 413, + /* 1040 */ 410, 211, 611, 285, 283, 610, 609, 502, 600, 89, + /* 1050 */ 380, 217, 620, 128, 140, 413, 220, 620, 410, 409, + /* 1060 */ 620, 620, 588, 587, 600, 75, 589, 583, 271, 620, + /* 1070 */ 51, 234, 127, 413, 620, 599, 627, 330, 27, 375, + /* 1080 */ 449, 279, 600, 88, 585, 584, 58, 48, 581, 580, + /* 1090 */ 582, 582, 55, 55, 56, 56, 56, 56, 410, 54, + /* 1100 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234, + /* 1110 */ 310, 586, 410, 413, 410, 261, 593, 165, 399, 556, + /* 1120 */ 126, 371, 600, 87, 478, 186, 123, 413, 367, 413, + /* 1130 */ 620, 620, 410, 620, 620, 410, 600, 99, 600, 86, + /* 1140 */ 589, 583, 475, 122, 258, 171, 471, 413, 160, 121, + /* 1150 */ 413, 14, 159, 463, 25, 24, 600, 17, 448, 600, + /* 1160 */ 85, 48, 581, 580, 582, 582, 55, 55, 56, 56, + /* 1170 */ 56, 56, 158, 54, 54, 54, 54, 53, 53, 52, + /* 1180 */ 52, 52, 51, 234, 44, 404, 261, 3, 544, 261, + /* 1190 */ 540, 414, 621, 460, 119, 118, 538, 275, 10, 349, + /* 1200 */ 4, 620, 407, 620, 620, 620, 116, 44, 404, 410, + /* 1210 */ 3, 620, 620, 410, 414, 621, 456, 454, 252, 450, + /* 1220 */ 508, 402, 111, 109, 413, 407, 155, 444, 413, 447, + /* 1230 */ 435, 565, 219, 600, 84, 620, 108, 600, 83, 64, + /* 1240 */ 434, 417, 625, 150, 402, 333, 410, 237, 238, 124, + /* 1250 */ 274, 41, 42, 533, 565, 206, 189, 261, 43, 412, + /* 1260 */ 411, 413, 261, 594, 488, 620, 329, 149, 419, 268, + /* 1270 */ 600, 72, 620, 266, 41, 42, 181, 620, 410, 620, + /* 1280 */ 105, 43, 412, 411, 620, 624, 594, 614, 620, 599, + /* 1290 */ 228, 125, 313, 413, 592, 592, 592, 591, 590, 13, + /* 1300 */ 218, 410, 600, 71, 236, 244, 44, 404, 264, 3, + /* 1310 */ 312, 613, 340, 414, 621, 180, 413, 592, 592, 592, + /* 1320 */ 591, 590, 13, 620, 407, 600, 82, 410, 416, 34, + /* 1330 */ 404, 410, 3, 410, 262, 410, 414, 621, 612, 331, + /* 1340 */ 178, 415, 413, 402, 8, 236, 413, 407, 413, 620, + /* 1350 */ 413, 600, 81, 565, 257, 600, 80, 600, 70, 600, + /* 1360 */ 18, 598, 361, 462, 461, 30, 402, 294, 31, 620, + /* 1370 */ 293, 354, 251, 41, 42, 410, 565, 620, 620, 620, + /* 1380 */ 43, 412, 411, 453, 396, 594, 620, 620, 394, 61, + /* 1390 */ 413, 292, 443, 622, 621, 243, 41, 42, 620, 600, + /* 1400 */ 79, 597, 291, 43, 412, 411, 60, 620, 594, 240, + /* 1410 */ 620, 410, 231, 37, 555, 173, 592, 592, 592, 591, + /* 1420 */ 590, 13, 216, 239, 620, 184, 413, 302, 301, 300, + /* 1430 */ 179, 298, 388, 565, 452, 600, 78, 286, 620, 592, + /* 1440 */ 592, 592, 591, 590, 13, 429, 29, 413, 151, 289, + /* 1450 */ 242, 145, 392, 194, 193, 288, 600, 9, 542, 241, + /* 1460 */ 620, 525, 391, 284, 620, 594, 620, 620, 522, 536, + /* 1470 */ 620, 535, 153, 385, 465, 516, 282, 325, 154, 517, + /* 1480 */ 277, 152, 512, 511, 513, 129, 226, 308, 487, 486, + /* 1490 */ 485, 164, 372, 493, 307, 227, 592, 592, 592, 225, + /* 1500 */ 479, 163, 368, 370, 162, 476, 210, 477, 26, 259, + /* 1510 */ 161, 466, 362, 141, 132, 120, 117, 455, 156, 115, + /* 1520 */ 344, 343, 256, 342, 245, 114, 113, 446, 311, 112, + /* 1530 */ 23, 317, 432, 236, 131, 431, 110, 430, 20, 427, + /* 1540 */ 608, 595, 295, 63, 379, 287, 509, 191, 278, 403, + /* 1550 */ 572, 569, 497, 498, 496, 494, 335, 459, 445, 303, + /* 1560 */ 296, 246, 341, 355, 5, 568, 369, 507, 253, 549, + /* 1570 */ 526, 209, 400, 501, 500, 524, 234, 958, 489, 482, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78, + /* 0 */ 19, 169, 170, 171, 22, 24, 24, 26, 77, 78, /* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - /* 20 */ 89, 90, 91, 92, 15, 98, 26, 27, 7, 8, - /* 30 */ 49, 50, 77, 78, 79, 80, 109, 82, 83, 84, - /* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 22, 68, + /* 20 */ 89, 90, 91, 92, 26, 27, 1, 26, 27, 15, + /* 30 */ 49, 50, 77, 78, 79, 80, 116, 82, 83, 84, + /* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 128, 68, /* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - /* 60 */ 79, 80, 23, 82, 83, 84, 85, 86, 87, 88, - /* 70 */ 89, 90, 91, 92, 19, 94, 112, 19, 114, 115, + /* 60 */ 79, 80, 230, 82, 83, 84, 85, 86, 87, 88, + /* 70 */ 89, 90, 91, 92, 19, 94, 19, 23, 86, 87, /* 80 */ 25, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 90 */ 91, 92, 19, 22, 94, 95, 96, 150, 150, 99, - /* 100 */ 100, 101, 76, 150, 49, 50, 105, 106, 107, 54, - /* 110 */ 110, 158, 165, 165, 161, 162, 26, 27, 165, 113, - /* 120 */ 16, 174, 175, 68, 69, 70, 71, 72, 73, 74, - /* 130 */ 75, 76, 77, 78, 79, 80, 118, 82, 83, 84, - /* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 23, - /* 150 */ 92, 97, 98, 24, 96, 97, 98, 99, 100, 101, - /* 160 */ 102, 25, 97, 216, 60, 92, 62, 109, 221, 25, - /* 170 */ 97, 98, 99, 100, 101, 102, 86, 87, 49, 50, - /* 180 */ 118, 116, 109, 25, 94, 95, 32, 97, 88, 89, - /* 190 */ 90, 91, 92, 128, 104, 41, 106, 68, 69, 70, + /* 90 */ 91, 92, 94, 95, 19, 94, 95, 96, 172, 173, + /* 100 */ 99, 100, 101, 197, 49, 50, 177, 181, 22, 54, + /* 110 */ 204, 110, 26, 27, 86, 87, 88, 89, 90, 91, + /* 120 */ 92, 129, 130, 68, 69, 70, 71, 72, 73, 74, + /* 130 */ 75, 76, 77, 78, 79, 80, 22, 82, 83, 84, + /* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 92, + /* 150 */ 221, 222, 223, 96, 97, 98, 99, 100, 101, 102, + /* 160 */ 112, 32, 114, 115, 26, 27, 109, 92, 150, 25, + /* 170 */ 41, 150, 97, 98, 99, 100, 101, 102, 49, 50, + /* 180 */ 94, 95, 98, 165, 109, 25, 165, 163, 170, 171, + /* 190 */ 166, 167, 168, 109, 12, 174, 175, 68, 69, 70, /* 200 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - /* 210 */ 11, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 220 */ 91, 92, 19, 19, 86, 87, 88, 89, 90, 91, - /* 230 */ 92, 27, 96, 150, 66, 99, 100, 101, 112, 150, - /* 240 */ 114, 115, 138, 150, 161, 162, 110, 103, 165, 222, - /* 250 */ 223, 224, 49, 50, 165, 22, 57, 24, 165, 170, - /* 260 */ 171, 118, 94, 170, 171, 23, 98, 25, 185, 186, - /* 270 */ 243, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 280 */ 77, 78, 79, 80, 126, 82, 83, 84, 85, 86, + /* 210 */ 28, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 220 */ 91, 92, 19, 11, 86, 87, 44, 24, 46, 221, + /* 230 */ 222, 223, 94, 95, 66, 97, 215, 7, 8, 57, + /* 240 */ 150, 220, 104, 19, 106, 26, 27, 229, 230, 241, + /* 250 */ 160, 27, 49, 50, 22, 165, 96, 118, 16, 99, + /* 260 */ 100, 101, 94, 119, 174, 175, 98, 129, 130, 57, + /* 270 */ 110, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 280 */ 77, 78, 79, 80, 194, 82, 83, 84, 85, 86, /* 290 */ 87, 88, 89, 90, 91, 92, 19, 129, 130, 131, - /* 300 */ 88, 23, 172, 173, 105, 106, 107, 150, 22, 26, - /* 310 */ 27, 181, 26, 27, 22, 116, 26, 27, 26, 230, - /* 320 */ 231, 197, 165, 230, 231, 113, 49, 50, 204, 117, - /* 330 */ 96, 174, 175, 99, 100, 101, 22, 26, 27, 136, - /* 340 */ 26, 27, 118, 16, 110, 68, 69, 70, 71, 72, - /* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 118, 82, + /* 300 */ 150, 23, 60, 25, 62, 215, 150, 150, 76, 150, + /* 310 */ 220, 161, 162, 94, 95, 165, 30, 105, 106, 107, + /* 320 */ 34, 165, 165, 23, 165, 25, 49, 50, 116, 170, + /* 330 */ 171, 174, 175, 22, 48, 185, 186, 26, 27, 120, + /* 340 */ 26, 27, 12, 187, 160, 68, 69, 70, 71, 72, + /* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 28, 82, /* 360 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - /* 370 */ 19, 214, 215, 150, 23, 23, 155, 94, 95, 22, - /* 380 */ 94, 95, 116, 160, 94, 95, 94, 60, 165, 62, - /* 390 */ 112, 26, 114, 115, 128, 23, 36, 174, 175, 88, - /* 400 */ 49, 50, 57, 120, 22, 94, 95, 23, 94, 95, - /* 410 */ 120, 51, 25, 136, 169, 170, 171, 194, 58, 68, + /* 370 */ 19, 150, 215, 95, 44, 23, 46, 220, 194, 96, + /* 380 */ 138, 160, 99, 100, 101, 23, 165, 25, 229, 230, + /* 390 */ 26, 27, 135, 110, 137, 174, 175, 57, 120, 150, + /* 400 */ 49, 50, 88, 219, 113, 94, 95, 158, 94, 95, + /* 410 */ 161, 162, 21, 136, 165, 194, 169, 170, 171, 68, /* 420 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, /* 430 */ 79, 80, 23, 82, 83, 84, 85, 86, 87, 88, - /* 440 */ 89, 90, 91, 92, 19, 150, 12, 12, 23, 228, - /* 450 */ 105, 106, 107, 23, 233, 25, 165, 19, 150, 94, - /* 460 */ 165, 116, 28, 28, 112, 174, 114, 115, 108, 174, - /* 470 */ 175, 26, 27, 165, 49, 50, 231, 11, 44, 44, - /* 480 */ 46, 46, 174, 175, 112, 160, 114, 115, 50, 22, - /* 490 */ 23, 57, 25, 68, 69, 70, 71, 72, 73, 74, - /* 500 */ 75, 76, 77, 78, 79, 80, 119, 82, 83, 84, + /* 440 */ 89, 90, 91, 92, 19, 105, 106, 107, 23, 88, + /* 450 */ 89, 90, 91, 92, 63, 23, 116, 88, 94, 95, + /* 460 */ 142, 143, 144, 145, 112, 150, 114, 115, 105, 106, + /* 470 */ 107, 23, 23, 25, 49, 50, 118, 230, 97, 98, + /* 480 */ 165, 16, 113, 118, 120, 160, 117, 136, 113, 174, + /* 490 */ 175, 100, 117, 68, 69, 70, 71, 72, 73, 74, + /* 500 */ 75, 76, 77, 78, 79, 80, 160, 82, 83, 84, /* 510 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 194, - /* 520 */ 225, 23, 23, 215, 19, 95, 105, 106, 107, 150, - /* 530 */ 23, 150, 27, 23, 67, 25, 150, 206, 207, 94, - /* 540 */ 95, 166, 104, 218, 165, 22, 165, 109, 49, 50, - /* 550 */ 120, 165, 25, 174, 175, 174, 175, 23, 21, 234, - /* 560 */ 174, 175, 22, 23, 239, 25, 25, 68, 69, 70, + /* 520 */ 25, 112, 23, 114, 115, 60, 150, 62, 150, 138, + /* 530 */ 150, 105, 106, 107, 19, 150, 36, 161, 162, 224, + /* 540 */ 194, 165, 217, 165, 112, 165, 114, 115, 49, 50, + /* 550 */ 165, 51, 174, 175, 174, 175, 166, 232, 58, 174, + /* 560 */ 175, 112, 237, 114, 115, 50, 22, 68, 69, 70, /* 570 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - /* 580 */ 205, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 590 */ 91, 92, 19, 22, 23, 216, 23, 222, 223, 224, - /* 600 */ 63, 220, 35, 150, 150, 163, 220, 67, 166, 167, - /* 610 */ 168, 150, 169, 170, 171, 161, 162, 25, 165, 165, - /* 620 */ 150, 113, 49, 50, 25, 117, 165, 174, 175, 35, - /* 630 */ 7, 8, 9, 160, 160, 165, 120, 100, 67, 247, - /* 640 */ 248, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 650 */ 77, 78, 79, 80, 193, 82, 83, 84, 85, 86, - /* 660 */ 87, 88, 89, 90, 91, 92, 19, 194, 194, 150, - /* 670 */ 135, 24, 137, 35, 231, 138, 150, 129, 130, 206, - /* 680 */ 207, 30, 27, 213, 165, 34, 118, 95, 0, 1, - /* 690 */ 2, 165, 218, 174, 175, 50, 49, 50, 22, 48, - /* 700 */ 174, 175, 22, 23, 23, 244, 222, 223, 224, 166, - /* 710 */ 167, 168, 120, 239, 23, 68, 69, 70, 71, 72, - /* 720 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82, + /* 580 */ 160, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 590 */ 91, 92, 19, 215, 214, 205, 23, 7, 8, 9, + /* 600 */ 215, 155, 24, 22, 26, 150, 97, 26, 108, 129, + /* 610 */ 130, 221, 222, 223, 194, 0, 1, 2, 150, 104, + /* 620 */ 165, 126, 49, 50, 109, 116, 206, 207, 118, 174, + /* 630 */ 175, 22, 23, 165, 25, 22, 23, 128, 25, 118, + /* 640 */ 26, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 650 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86, + /* 660 */ 87, 88, 89, 90, 91, 92, 19, 150, 150, 165, + /* 670 */ 23, 160, 94, 227, 150, 94, 67, 231, 174, 175, + /* 680 */ 67, 213, 165, 165, 221, 222, 223, 150, 150, 165, + /* 690 */ 23, 32, 174, 175, 181, 182, 49, 50, 174, 175, + /* 700 */ 41, 188, 165, 165, 22, 194, 177, 11, 94, 23, + /* 710 */ 193, 174, 175, 160, 22, 68, 69, 70, 71, 72, + /* 720 */ 73, 74, 75, 76, 77, 78, 79, 80, 217, 82, /* 730 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - /* 740 */ 19, 150, 173, 165, 181, 182, 24, 67, 26, 104, - /* 750 */ 181, 188, 174, 175, 150, 39, 165, 150, 52, 150, - /* 760 */ 150, 150, 150, 144, 145, 174, 175, 249, 250, 165, - /* 770 */ 49, 50, 165, 52, 165, 165, 165, 165, 174, 175, - /* 780 */ 29, 174, 175, 174, 175, 174, 175, 160, 22, 68, + /* 740 */ 19, 150, 150, 150, 25, 24, 19, 194, 237, 150, + /* 750 */ 221, 222, 223, 25, 27, 23, 165, 165, 165, 242, + /* 760 */ 165, 23, 150, 25, 165, 174, 175, 174, 175, 174, + /* 770 */ 49, 50, 219, 150, 22, 23, 238, 165, 25, 22, + /* 780 */ 23, 23, 166, 167, 168, 193, 174, 175, 165, 68, /* 790 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, /* 800 */ 79, 80, 150, 82, 83, 84, 85, 86, 87, 88, - /* 810 */ 89, 90, 91, 92, 19, 150, 94, 165, 150, 150, - /* 820 */ 160, 194, 150, 213, 160, 52, 174, 175, 23, 23, - /* 830 */ 165, 25, 22, 165, 165, 150, 150, 165, 52, 174, - /* 840 */ 175, 22, 174, 175, 49, 50, 174, 175, 190, 191, - /* 850 */ 165, 165, 240, 23, 194, 25, 187, 109, 194, 174, - /* 860 */ 175, 190, 191, 68, 69, 70, 71, 72, 73, 74, + /* 810 */ 89, 90, 91, 92, 19, 150, 23, 165, 150, 67, + /* 820 */ 150, 25, 103, 95, 67, 35, 174, 175, 206, 207, + /* 830 */ 165, 150, 25, 165, 150, 165, 213, 150, 150, 174, + /* 840 */ 175, 35, 174, 175, 49, 50, 165, 52, 120, 165, + /* 850 */ 245, 246, 165, 165, 35, 174, 175, 187, 174, 175, + /* 860 */ 23, 50, 25, 68, 69, 70, 71, 72, 73, 74, /* 870 */ 75, 76, 77, 78, 79, 80, 150, 82, 83, 84, /* 880 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 150, - /* 890 */ 22, 165, 150, 23, 150, 25, 150, 166, 91, 92, - /* 900 */ 174, 175, 22, 217, 165, 150, 102, 165, 150, 165, - /* 910 */ 150, 165, 150, 174, 175, 19, 174, 175, 49, 50, - /* 920 */ 165, 86, 87, 165, 23, 165, 25, 165, 24, 174, - /* 930 */ 175, 187, 174, 175, 174, 175, 205, 68, 69, 70, + /* 890 */ 150, 165, 150, 150, 160, 23, 150, 25, 144, 145, + /* 900 */ 174, 175, 120, 216, 165, 165, 22, 165, 165, 150, + /* 910 */ 150, 165, 27, 174, 175, 104, 174, 175, 49, 50, + /* 920 */ 174, 175, 247, 248, 165, 165, 238, 187, 194, 23, + /* 930 */ 187, 25, 166, 174, 175, 190, 191, 68, 69, 70, /* 940 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, /* 950 */ 150, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 960 */ 91, 92, 19, 150, 150, 165, 150, 150, 166, 23, - /* 970 */ 150, 25, 160, 20, 174, 175, 1, 2, 165, 165, - /* 980 */ 104, 165, 165, 43, 150, 165, 240, 150, 49, 50, - /* 990 */ 174, 175, 49, 50, 23, 23, 25, 25, 53, 165, - /* 1000 */ 187, 187, 165, 23, 187, 25, 194, 205, 174, 175, - /* 1010 */ 71, 72, 69, 70, 71, 72, 73, 74, 75, 76, + /* 960 */ 91, 92, 19, 150, 150, 165, 150, 23, 150, 25, + /* 970 */ 23, 205, 25, 213, 174, 175, 190, 191, 165, 165, + /* 980 */ 118, 165, 150, 165, 150, 150, 23, 174, 175, 39, + /* 990 */ 174, 175, 49, 50, 173, 150, 23, 165, 52, 165, + /* 1000 */ 165, 187, 181, 22, 166, 166, 174, 175, 174, 175, + /* 1010 */ 165, 68, 69, 70, 71, 72, 73, 74, 75, 76, /* 1020 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86, - /* 1030 */ 87, 88, 89, 90, 91, 92, 19, 98, 150, 165, - /* 1040 */ 150, 160, 150, 59, 25, 53, 104, 22, 174, 175, - /* 1050 */ 213, 138, 5, 165, 1, 165, 150, 165, 150, 150, - /* 1060 */ 240, 150, 174, 175, 174, 175, 49, 50, 118, 150, - /* 1070 */ 35, 165, 27, 165, 165, 194, 165, 108, 127, 76, - /* 1080 */ 174, 175, 174, 175, 165, 174, 175, 70, 71, 72, - /* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 166, 82, + /* 1030 */ 87, 88, 89, 90, 91, 92, 19, 150, 193, 165, + /* 1040 */ 150, 160, 150, 205, 205, 150, 150, 29, 174, 175, + /* 1050 */ 52, 216, 165, 22, 150, 165, 238, 165, 150, 150, + /* 1060 */ 165, 165, 49, 50, 174, 175, 49, 50, 23, 165, + /* 1070 */ 91, 92, 22, 165, 165, 194, 1, 2, 22, 52, + /* 1080 */ 193, 109, 174, 175, 71, 72, 69, 70, 71, 72, + /* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82, /* 1100 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - /* 1110 */ 19, 20, 193, 22, 150, 150, 150, 26, 27, 76, - /* 1120 */ 150, 22, 1, 150, 119, 121, 217, 20, 37, 165, - /* 1130 */ 165, 165, 16, 19, 20, 165, 22, 205, 165, 119, - /* 1140 */ 26, 27, 108, 128, 150, 150, 150, 56, 150, 22, - /* 1150 */ 150, 37, 150, 127, 160, 23, 150, 66, 193, 165, - /* 1160 */ 165, 165, 16, 165, 23, 165, 150, 165, 174, 175, - /* 1170 */ 56, 165, 150, 65, 174, 175, 15, 86, 87, 88, - /* 1180 */ 66, 165, 140, 150, 93, 94, 95, 165, 194, 98, - /* 1190 */ 174, 175, 22, 3, 164, 193, 174, 175, 165, 150, - /* 1200 */ 86, 87, 4, 180, 150, 248, 251, 93, 94, 95, - /* 1210 */ 216, 180, 98, 251, 165, 221, 150, 149, 6, 165, - /* 1220 */ 129, 130, 131, 132, 133, 134, 193, 150, 174, 175, - /* 1230 */ 116, 165, 19, 20, 150, 22, 149, 151, 150, 26, - /* 1240 */ 27, 149, 165, 129, 130, 131, 132, 133, 134, 165, - /* 1250 */ 37, 174, 175, 165, 149, 19, 20, 13, 22, 150, - /* 1260 */ 150, 150, 26, 27, 146, 147, 151, 150, 25, 56, - /* 1270 */ 152, 159, 154, 37, 165, 165, 165, 193, 160, 66, - /* 1280 */ 116, 193, 165, 174, 175, 174, 175, 194, 199, 150, - /* 1290 */ 200, 126, 56, 124, 123, 150, 201, 122, 150, 86, - /* 1300 */ 87, 150, 66, 193, 165, 202, 93, 94, 95, 150, - /* 1310 */ 165, 98, 194, 165, 125, 22, 165, 150, 150, 26, - /* 1320 */ 27, 135, 86, 87, 165, 174, 175, 203, 226, 93, - /* 1330 */ 94, 95, 165, 165, 98, 150, 218, 150, 193, 157, - /* 1340 */ 118, 157, 129, 130, 131, 132, 133, 134, 5, 104, - /* 1350 */ 165, 211, 165, 10, 11, 12, 13, 14, 150, 66, - /* 1360 */ 17, 174, 175, 210, 246, 129, 130, 131, 132, 133, - /* 1370 */ 134, 150, 210, 165, 31, 121, 33, 150, 150, 86, - /* 1380 */ 87, 176, 174, 175, 150, 42, 165, 94, 211, 210, - /* 1390 */ 150, 98, 165, 165, 211, 174, 175, 150, 55, 165, - /* 1400 */ 57, 150, 174, 175, 61, 165, 150, 64, 174, 175, - /* 1410 */ 150, 150, 165, 150, 174, 175, 165, 104, 150, 184, - /* 1420 */ 150, 165, 129, 130, 131, 165, 165, 150, 165, 150, - /* 1430 */ 150, 176, 150, 165, 47, 165, 150, 150, 176, 103, - /* 1440 */ 150, 22, 165, 178, 165, 165, 179, 165, 105, 106, - /* 1450 */ 107, 165, 165, 229, 111, 165, 92, 176, 229, 116, - /* 1460 */ 184, 176, 179, 156, 176, 176, 18, 157, 156, 237, - /* 1470 */ 45, 157, 156, 135, 157, 157, 238, 156, 68, 157, - /* 1480 */ 189, 189, 139, 219, 22, 157, 18, 192, 192, 192, - /* 1490 */ 192, 189, 219, 199, 157, 242, 40, 157, 199, 242, - /* 1500 */ 153, 157, 38, 245, 196, 166, 232, 198, 177, 177, - /* 1510 */ 232, 227, 209, 178, 166, 182, 166, 148, 177, 177, - /* 1520 */ 209, 196, 177, 199, 209, 199, 166, 208, 92, 195, - /* 1530 */ 174, 174, 183, 252, 183, 183, 252, 191, 252, 235, - /* 1540 */ 186, 241, 241, 252, 186, 252, 252, 252, 252, 252, - /* 1550 */ 252, 252, 252, 252, 252, 252, 236, + /* 1110 */ 19, 98, 150, 165, 150, 150, 150, 102, 150, 150, + /* 1120 */ 22, 19, 174, 175, 20, 24, 104, 165, 43, 165, + /* 1130 */ 165, 165, 150, 165, 165, 150, 174, 175, 174, 175, + /* 1140 */ 49, 50, 59, 53, 138, 25, 53, 165, 104, 22, + /* 1150 */ 165, 5, 118, 1, 76, 76, 174, 175, 193, 174, + /* 1160 */ 175, 70, 71, 72, 73, 74, 75, 76, 77, 78, + /* 1170 */ 79, 80, 35, 82, 83, 84, 85, 86, 87, 88, + /* 1180 */ 89, 90, 91, 92, 19, 20, 150, 22, 150, 150, + /* 1190 */ 150, 26, 27, 27, 108, 127, 150, 150, 22, 25, + /* 1200 */ 22, 165, 37, 165, 165, 165, 119, 19, 20, 150, + /* 1210 */ 22, 165, 165, 150, 26, 27, 23, 1, 16, 20, + /* 1220 */ 150, 56, 119, 108, 165, 37, 121, 128, 165, 193, + /* 1230 */ 23, 66, 193, 174, 175, 165, 127, 174, 175, 16, + /* 1240 */ 23, 146, 147, 15, 56, 65, 150, 152, 140, 154, + /* 1250 */ 150, 86, 87, 88, 66, 160, 22, 150, 93, 94, + /* 1260 */ 95, 165, 150, 98, 150, 165, 3, 246, 4, 150, + /* 1270 */ 174, 175, 165, 150, 86, 87, 6, 165, 150, 165, + /* 1280 */ 164, 93, 94, 95, 165, 149, 98, 149, 165, 194, + /* 1290 */ 180, 180, 249, 165, 129, 130, 131, 132, 133, 134, + /* 1300 */ 193, 150, 174, 175, 116, 193, 19, 20, 150, 22, + /* 1310 */ 249, 149, 217, 26, 27, 151, 165, 129, 130, 131, + /* 1320 */ 132, 133, 134, 165, 37, 174, 175, 150, 149, 19, + /* 1330 */ 20, 150, 22, 150, 150, 150, 26, 27, 13, 244, + /* 1340 */ 151, 159, 165, 56, 25, 116, 165, 37, 165, 165, + /* 1350 */ 165, 174, 175, 66, 150, 174, 175, 174, 175, 174, + /* 1360 */ 175, 194, 150, 150, 150, 126, 56, 199, 124, 165, + /* 1370 */ 200, 150, 150, 86, 87, 150, 66, 165, 165, 165, + /* 1380 */ 93, 94, 95, 150, 122, 98, 165, 165, 123, 22, + /* 1390 */ 165, 201, 150, 26, 27, 150, 86, 87, 165, 174, + /* 1400 */ 175, 203, 202, 93, 94, 95, 125, 165, 98, 150, + /* 1410 */ 165, 150, 225, 135, 157, 118, 129, 130, 131, 132, + /* 1420 */ 133, 134, 5, 150, 165, 157, 165, 10, 11, 12, + /* 1430 */ 13, 14, 150, 66, 17, 174, 175, 210, 165, 129, + /* 1440 */ 130, 131, 132, 133, 134, 150, 104, 165, 31, 150, + /* 1450 */ 33, 150, 150, 86, 87, 150, 174, 175, 211, 42, + /* 1460 */ 165, 94, 121, 210, 165, 98, 165, 165, 176, 211, + /* 1470 */ 165, 211, 55, 104, 57, 184, 210, 47, 61, 176, + /* 1480 */ 176, 64, 103, 176, 178, 22, 92, 179, 176, 176, + /* 1490 */ 176, 156, 18, 184, 179, 228, 129, 130, 131, 228, + /* 1500 */ 157, 156, 45, 157, 156, 236, 157, 157, 135, 235, + /* 1510 */ 156, 189, 157, 68, 218, 189, 22, 199, 156, 192, + /* 1520 */ 157, 18, 105, 106, 107, 192, 192, 199, 111, 192, + /* 1530 */ 240, 157, 40, 116, 218, 157, 189, 157, 240, 38, + /* 1540 */ 153, 166, 198, 243, 178, 209, 182, 196, 177, 226, + /* 1550 */ 230, 230, 166, 177, 177, 166, 139, 199, 199, 148, + /* 1560 */ 195, 209, 209, 239, 196, 166, 234, 183, 239, 208, + /* 1570 */ 174, 233, 191, 183, 183, 174, 92, 250, 186, 186, }; -#define YY_SHIFT_USE_DFLT (-74) -#define YY_SHIFT_COUNT (418) -#define YY_SHIFT_MIN (-73) -#define YY_SHIFT_MAX (1468) +#define YY_SHIFT_USE_DFLT (-81) +#define YY_SHIFT_COUNT (417) +#define YY_SHIFT_MIN (-80) +#define YY_SHIFT_MAX (1503) static const short yy_shift_ofst[] = { - /* 0 */ 975, 1114, 1343, 1114, 1213, 1213, 90, 90, 0, -19, - /* 10 */ 1213, 1213, 1213, 1213, 1213, 345, 445, 721, 1091, 1213, - /* 20 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, - /* 30 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, - /* 40 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1236, 1213, 1213, - /* 50 */ 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, 1213, - /* 60 */ 1213, 199, 445, 445, 835, 835, 365, 1164, 55, 647, - /* 70 */ 573, 499, 425, 351, 277, 203, 129, 795, 795, 795, - /* 80 */ 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, - /* 90 */ 795, 795, 795, 795, 795, 869, 795, 943, 1017, 1017, - /* 100 */ -69, -45, -45, -45, -45, -45, -1, 58, 138, 100, - /* 110 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, - /* 120 */ 445, 445, 445, 445, 445, 445, 537, 438, 445, 445, - /* 130 */ 445, 445, 445, 365, 807, 1436, -74, -74, -74, 1293, - /* 140 */ 73, 434, 434, 311, 314, 290, 283, 286, 540, 467, - /* 150 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, - /* 160 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, - /* 170 */ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, - /* 180 */ 445, 445, 65, 722, 722, 722, 688, 266, 1164, 1164, - /* 190 */ 1164, -74, -74, -74, 136, 168, 168, 234, 360, 360, - /* 200 */ 360, 430, 372, 435, 352, 278, 126, -36, -36, -36, - /* 210 */ -36, 421, 651, -36, -36, 592, 292, 212, 623, 158, - /* 220 */ 204, 204, 505, 158, 505, 144, 365, 154, 365, 154, - /* 230 */ 645, 154, 204, 154, 154, 535, 548, 548, 365, 387, - /* 240 */ 508, 233, 1464, 1222, 1222, 1456, 1456, 1222, 1462, 1410, - /* 250 */ 1165, 1468, 1468, 1468, 1468, 1222, 1165, 1462, 1410, 1410, - /* 260 */ 1222, 1448, 1338, 1425, 1222, 1222, 1448, 1222, 1448, 1222, - /* 270 */ 1448, 1419, 1313, 1313, 1313, 1387, 1364, 1364, 1419, 1313, - /* 280 */ 1336, 1313, 1387, 1313, 1313, 1254, 1245, 1254, 1245, 1254, - /* 290 */ 1245, 1222, 1222, 1186, 1189, 1175, 1169, 1171, 1165, 1164, - /* 300 */ 1243, 1244, 1244, 1212, 1212, 1212, 1212, -74, -74, -74, - /* 310 */ -74, -74, -74, 939, 104, 680, 571, 327, 1, 980, - /* 320 */ 26, 972, 971, 946, 901, 870, 830, 806, 54, 21, - /* 330 */ -73, 510, 242, 1198, 1190, 1170, 1042, 1161, 1108, 1146, - /* 340 */ 1141, 1132, 1015, 1127, 1026, 1034, 1020, 1107, 1004, 1116, - /* 350 */ 1121, 1005, 1099, 951, 1043, 1003, 969, 1045, 1035, 950, - /* 360 */ 1053, 1047, 1025, 942, 913, 992, 1019, 945, 984, 940, - /* 370 */ 876, 904, 953, 896, 748, 804, 880, 786, 868, 819, - /* 380 */ 805, 810, 773, 751, 766, 706, 716, 691, 681, 568, - /* 390 */ 655, 638, 676, 516, 541, 594, 599, 567, 541, 534, - /* 400 */ 507, 527, 498, 523, 466, 382, 409, 384, 357, 6, - /* 410 */ 240, 224, 143, 62, 18, 71, 39, 9, 5, + /* 0 */ 1075, 1188, 1417, 1188, 1287, 1287, 138, 138, 1, -19, + /* 10 */ 1287, 1287, 1287, 1287, 340, -2, 129, 129, 795, 1165, + /* 20 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + /* 30 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + /* 40 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1310, 1287, + /* 50 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, + /* 60 */ 1287, 1287, 212, -2, -2, -8, -8, 614, 1229, 55, + /* 70 */ 721, 647, 573, 499, 425, 351, 277, 203, 869, 869, + /* 80 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, + /* 90 */ 869, 869, 869, 943, 869, 1017, 1091, 1091, -69, -45, + /* 100 */ -45, -45, -45, -45, -1, 57, 28, 361, -2, -2, + /* 110 */ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + /* 120 */ -2, -2, -2, -2, 391, 515, -2, -2, -2, -2, + /* 130 */ -2, 509, -80, 614, 979, 1484, -81, -81, -81, 1367, + /* 140 */ 75, 182, 182, 314, 311, 364, 219, 86, 613, 609, + /* 150 */ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + /* 160 */ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + /* 170 */ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + /* 180 */ -2, -2, 578, 578, 578, 615, 1229, 1229, 1229, -81, + /* 190 */ -81, -81, 160, 168, 168, 283, 500, 500, 500, 278, + /* 200 */ 449, 330, 432, 409, 352, 48, 48, 48, 48, 426, + /* 210 */ 286, 48, 48, 728, 581, 369, 590, 495, 224, 224, + /* 220 */ 727, 495, 727, 719, 614, 659, 614, 659, 811, 659, + /* 230 */ 224, 257, 480, 480, 614, 144, 375, -18, 1501, 1297, + /* 240 */ 1297, 1492, 1492, 1297, 1494, 1445, 1239, 1503, 1503, 1503, + /* 250 */ 1503, 1297, 1474, 1239, 1494, 1445, 1445, 1297, 1474, 1373, + /* 260 */ 1457, 1297, 1297, 1474, 1297, 1474, 1297, 1474, 1463, 1369, + /* 270 */ 1369, 1369, 1430, 1394, 1394, 1463, 1369, 1379, 1369, 1430, + /* 280 */ 1369, 1369, 1341, 1342, 1341, 1342, 1341, 1342, 1297, 1297, + /* 290 */ 1278, 1281, 1262, 1244, 1265, 1239, 1229, 1319, 1325, 1325, + /* 300 */ 1270, 1270, 1270, 1270, -81, -81, -81, -81, -81, -81, + /* 310 */ 1013, 242, 757, 752, 465, 363, 947, 232, 944, 906, + /* 320 */ 872, 837, 738, 448, 381, 230, 84, 362, 300, 1264, + /* 330 */ 1263, 1234, 1108, 1228, 1180, 1223, 1217, 1207, 1099, 1174, + /* 340 */ 1109, 1115, 1103, 1199, 1105, 1202, 1216, 1087, 1193, 1178, + /* 350 */ 1174, 1176, 1068, 1079, 1078, 1086, 1166, 1137, 1034, 1152, + /* 360 */ 1146, 1127, 1044, 1006, 1093, 1120, 1090, 1083, 1085, 1022, + /* 370 */ 1101, 1104, 1102, 972, 1015, 1098, 1027, 1056, 1050, 1045, + /* 380 */ 1031, 998, 1018, 981, 946, 950, 973, 963, 862, 885, + /* 390 */ 819, 884, 782, 796, 806, 807, 790, 796, 793, 758, + /* 400 */ 753, 732, 692, 696, 682, 686, 667, 544, 291, 521, + /* 410 */ 510, 365, 358, 139, 114, 54, 14, 25, }; -#define YY_REDUCE_USE_DFLT (-142) -#define YY_REDUCE_COUNT (312) -#define YY_REDUCE_MIN (-141) -#define YY_REDUCE_MAX (1369) +#define YY_REDUCE_USE_DFLT (-169) +#define YY_REDUCE_COUNT (309) +#define YY_REDUCE_MIN (-168) +#define YY_REDUCE_MAX (1411) static const short yy_reduce_ofst[] = { - /* 0 */ -141, 994, 1118, 223, 157, -53, 93, 89, 83, 375, - /* 10 */ 386, 381, 379, 308, 295, 325, -47, 27, 1240, 1234, - /* 20 */ 1228, 1221, 1208, 1187, 1151, 1111, 1109, 1077, 1054, 1022, - /* 30 */ 1016, 1000, 911, 908, 906, 890, 888, 874, 834, 816, - /* 40 */ 800, 760, 758, 755, 742, 739, 726, 685, 672, 668, - /* 50 */ 665, 652, 611, 609, 607, 604, 591, 578, 526, 519, - /* 60 */ 453, 474, 454, 461, 443, 245, 442, 473, 484, 484, - /* 70 */ 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - /* 80 */ 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - /* 90 */ 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - /* 100 */ 484, 484, 484, 484, 484, 484, 484, 130, 484, 484, - /* 110 */ 1145, 909, 1110, 1088, 1084, 1033, 1002, 965, 820, 837, - /* 120 */ 746, 686, 612, 817, 610, 919, 221, 563, 814, 813, - /* 130 */ 744, 669, 470, 543, 484, 484, 484, 484, 484, 291, - /* 140 */ 569, 671, 658, 970, 1290, 1287, 1286, 1282, 518, 518, - /* 150 */ 1280, 1279, 1277, 1270, 1268, 1263, 1261, 1260, 1256, 1251, - /* 160 */ 1247, 1227, 1185, 1168, 1167, 1159, 1148, 1139, 1117, 1066, - /* 170 */ 1049, 1006, 998, 996, 995, 973, 970, 966, 964, 892, - /* 180 */ 762, -52, 881, 932, 802, 731, 619, 812, 664, 660, - /* 190 */ 627, 392, 331, 124, 1358, 1357, 1356, 1354, 1352, 1351, - /* 200 */ 1349, 1319, 1334, 1346, 1334, 1334, 1334, 1334, 1334, 1334, - /* 210 */ 1334, 1320, 1304, 1334, 1334, 1319, 1360, 1325, 1369, 1326, - /* 220 */ 1315, 1311, 1301, 1324, 1300, 1335, 1350, 1345, 1348, 1342, - /* 230 */ 1333, 1341, 1303, 1332, 1331, 1284, 1278, 1274, 1339, 1309, - /* 240 */ 1308, 1347, 1258, 1344, 1340, 1257, 1253, 1337, 1273, 1302, - /* 250 */ 1299, 1298, 1297, 1296, 1295, 1328, 1294, 1264, 1292, 1291, - /* 260 */ 1322, 1321, 1238, 1232, 1318, 1317, 1316, 1314, 1312, 1310, - /* 270 */ 1307, 1283, 1289, 1288, 1285, 1276, 1229, 1224, 1267, 1281, - /* 280 */ 1265, 1262, 1235, 1255, 1205, 1183, 1179, 1177, 1162, 1140, - /* 290 */ 1153, 1184, 1182, 1102, 1124, 1103, 1095, 1090, 1089, 1093, - /* 300 */ 1112, 1115, 1086, 1105, 1092, 1087, 1068, 962, 955, 957, - /* 310 */ 1031, 1023, 1030, + /* 0 */ 318, 90, 1095, 221, 157, 21, 159, 18, 150, 390, + /* 10 */ 385, 378, 380, 315, 325, 249, 529, -71, 8, 1282, + /* 20 */ 1261, 1225, 1185, 1183, 1181, 1177, 1151, 1128, 1096, 1063, + /* 30 */ 1059, 985, 982, 964, 962, 948, 908, 890, 874, 834, + /* 40 */ 832, 816, 813, 800, 759, 746, 742, 739, 726, 684, + /* 50 */ 681, 668, 665, 652, 612, 593, 591, 537, 524, 518, + /* 60 */ 504, 455, 511, 376, 517, 247, -168, 24, 420, 463, + /* 70 */ 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, + /* 80 */ 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, + /* 90 */ 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, + /* 100 */ 463, 463, 463, 463, 463, -74, 463, 463, 1112, 835, + /* 110 */ 1107, 1039, 1036, 965, 887, 845, 818, 760, 688, 687, + /* 120 */ 538, 743, 623, 592, 446, 513, 814, 740, 670, 156, + /* 130 */ 468, 553, 184, 616, 463, 463, 463, 463, 463, 595, + /* 140 */ 821, 786, 745, 909, 1305, 1302, 1301, 1299, 675, 675, + /* 150 */ 1295, 1273, 1259, 1245, 1242, 1233, 1222, 1221, 1214, 1213, + /* 160 */ 1212, 1204, 1184, 1158, 1123, 1119, 1114, 1100, 1070, 1047, + /* 170 */ 1046, 1040, 1038, 969, 968, 966, 909, 904, 896, 895, + /* 180 */ 892, 599, 839, 838, 766, 754, 881, 734, 346, 605, + /* 190 */ 622, -94, 1393, 1401, 1396, 1392, 1391, 1390, 1384, 1361, + /* 200 */ 1365, 1381, 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1332, + /* 210 */ 1338, 1365, 1365, 1361, 1399, 1368, 1411, 1359, 1353, 1352, + /* 220 */ 1329, 1358, 1324, 1366, 1389, 1377, 1386, 1376, 1364, 1371, + /* 230 */ 1336, 1323, 1321, 1320, 1375, 1344, 1351, 1387, 1300, 1380, + /* 240 */ 1378, 1298, 1290, 1374, 1316, 1347, 1328, 1337, 1334, 1333, + /* 250 */ 1327, 1363, 1362, 1318, 1296, 1326, 1322, 1355, 1354, 1269, + /* 260 */ 1274, 1350, 1349, 1348, 1346, 1345, 1343, 1335, 1315, 1314, + /* 270 */ 1313, 1312, 1309, 1271, 1267, 1308, 1307, 1306, 1304, 1291, + /* 280 */ 1303, 1292, 1260, 1266, 1258, 1253, 1247, 1227, 1268, 1257, + /* 290 */ 1187, 1198, 1200, 1190, 1170, 1168, 1167, 1182, 1189, 1164, + /* 300 */ 1179, 1162, 1138, 1136, 1061, 1043, 1021, 1111, 1110, 1116, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 635, 870, 959, 959, 959, 870, 899, 899, 959, 759, - /* 10 */ 959, 959, 959, 959, 868, 959, 959, 933, 959, 959, - /* 20 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 30 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 40 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 50 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 60 */ 959, 959, 959, 959, 899, 899, 674, 763, 794, 959, - /* 70 */ 959, 959, 959, 959, 959, 959, 959, 932, 934, 809, - /* 80 */ 808, 802, 801, 912, 774, 799, 792, 785, 796, 871, - /* 90 */ 864, 865, 863, 867, 872, 959, 795, 831, 848, 830, - /* 100 */ 842, 847, 854, 846, 843, 833, 832, 666, 834, 835, - /* 110 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 120 */ 959, 959, 959, 959, 959, 959, 661, 728, 959, 959, - /* 130 */ 959, 959, 959, 959, 836, 837, 851, 850, 849, 959, - /* 140 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 150 */ 959, 939, 937, 959, 883, 959, 959, 959, 959, 959, - /* 160 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 170 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 180 */ 959, 641, 959, 759, 759, 759, 635, 959, 959, 959, - /* 190 */ 959, 951, 763, 753, 719, 959, 959, 959, 959, 959, - /* 200 */ 959, 959, 959, 959, 959, 959, 959, 804, 742, 922, - /* 210 */ 924, 959, 905, 740, 663, 761, 676, 751, 643, 798, - /* 220 */ 776, 776, 917, 798, 917, 700, 959, 788, 959, 788, - /* 230 */ 697, 788, 776, 788, 788, 866, 959, 959, 959, 760, - /* 240 */ 751, 959, 944, 767, 767, 936, 936, 767, 810, 732, - /* 250 */ 798, 739, 739, 739, 739, 767, 798, 810, 732, 732, - /* 260 */ 767, 658, 911, 909, 767, 767, 658, 767, 658, 767, - /* 270 */ 658, 876, 730, 730, 730, 715, 880, 880, 876, 730, - /* 280 */ 700, 730, 715, 730, 730, 780, 775, 780, 775, 780, - /* 290 */ 775, 767, 767, 959, 793, 781, 791, 789, 798, 959, - /* 300 */ 718, 651, 651, 640, 640, 640, 640, 956, 956, 951, - /* 310 */ 702, 702, 684, 959, 959, 959, 959, 959, 959, 959, - /* 320 */ 885, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 330 */ 959, 959, 959, 959, 636, 946, 959, 959, 943, 959, - /* 340 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 350 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 915, - /* 360 */ 959, 959, 959, 959, 959, 959, 908, 907, 959, 959, - /* 370 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 380 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 959, - /* 390 */ 959, 959, 959, 959, 790, 959, 782, 959, 869, 959, - /* 400 */ 959, 959, 959, 959, 959, 959, 959, 959, 959, 745, - /* 410 */ 819, 959, 818, 822, 817, 668, 959, 649, 959, 632, - /* 420 */ 637, 955, 958, 957, 954, 953, 952, 947, 945, 942, - /* 430 */ 941, 940, 938, 935, 931, 889, 887, 894, 893, 892, - /* 440 */ 891, 890, 888, 886, 884, 805, 803, 800, 797, 930, - /* 450 */ 882, 741, 738, 737, 657, 948, 914, 923, 921, 811, - /* 460 */ 920, 919, 918, 916, 913, 900, 807, 806, 733, 874, - /* 470 */ 873, 660, 904, 903, 902, 906, 910, 901, 769, 659, - /* 480 */ 656, 665, 722, 721, 729, 727, 726, 725, 724, 723, - /* 490 */ 720, 667, 675, 686, 714, 699, 698, 879, 881, 878, - /* 500 */ 877, 707, 706, 712, 711, 710, 709, 708, 705, 704, - /* 510 */ 703, 696, 695, 701, 694, 717, 716, 713, 693, 736, - /* 520 */ 735, 734, 731, 692, 691, 690, 822, 689, 688, 828, - /* 530 */ 827, 815, 858, 756, 755, 754, 766, 765, 778, 777, - /* 540 */ 813, 812, 779, 764, 758, 757, 773, 772, 771, 770, - /* 550 */ 762, 752, 784, 787, 786, 783, 860, 768, 857, 929, - /* 560 */ 928, 927, 926, 925, 862, 861, 829, 826, 679, 680, - /* 570 */ 898, 896, 897, 895, 682, 681, 678, 677, 859, 747, - /* 580 */ 746, 855, 852, 844, 840, 856, 853, 845, 841, 839, - /* 590 */ 838, 824, 823, 821, 820, 816, 825, 670, 748, 744, - /* 600 */ 743, 814, 750, 749, 687, 685, 683, 664, 662, 655, - /* 610 */ 653, 652, 654, 650, 648, 647, 646, 645, 644, 673, - /* 620 */ 672, 671, 669, 668, 642, 639, 638, 634, 633, 631, + /* 0 */ 634, 868, 956, 956, 868, 868, 956, 956, 956, 758, + /* 10 */ 956, 956, 956, 866, 956, 956, 786, 786, 930, 956, + /* 20 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 30 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 40 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 50 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 60 */ 956, 956, 956, 956, 956, 956, 956, 673, 762, 792, + /* 70 */ 956, 956, 956, 956, 956, 956, 956, 956, 929, 931, + /* 80 */ 800, 799, 909, 773, 797, 790, 794, 869, 862, 863, + /* 90 */ 861, 865, 870, 956, 793, 829, 846, 828, 840, 845, + /* 100 */ 852, 844, 841, 831, 830, 665, 832, 833, 956, 956, + /* 110 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 120 */ 956, 956, 956, 956, 660, 727, 956, 956, 956, 956, + /* 130 */ 956, 956, 956, 956, 834, 835, 849, 848, 847, 956, + /* 140 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 150 */ 956, 936, 934, 956, 881, 956, 956, 956, 956, 956, + /* 160 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 170 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 180 */ 956, 640, 758, 758, 758, 634, 956, 956, 956, 948, + /* 190 */ 762, 752, 718, 956, 956, 956, 956, 956, 956, 956, + /* 200 */ 956, 956, 956, 956, 956, 802, 741, 919, 921, 956, + /* 210 */ 902, 739, 662, 760, 675, 750, 642, 796, 775, 775, + /* 220 */ 914, 796, 914, 699, 956, 786, 956, 786, 696, 786, + /* 230 */ 775, 864, 956, 956, 956, 759, 750, 956, 941, 766, + /* 240 */ 766, 933, 933, 766, 808, 731, 796, 738, 738, 738, + /* 250 */ 738, 766, 657, 796, 808, 731, 731, 766, 657, 908, + /* 260 */ 906, 766, 766, 657, 766, 657, 766, 657, 874, 729, + /* 270 */ 729, 729, 714, 878, 878, 874, 729, 699, 729, 714, + /* 280 */ 729, 729, 779, 774, 779, 774, 779, 774, 766, 766, + /* 290 */ 956, 791, 780, 789, 787, 796, 956, 717, 650, 650, + /* 300 */ 639, 639, 639, 639, 953, 953, 948, 701, 701, 683, + /* 310 */ 956, 956, 956, 956, 956, 956, 956, 883, 956, 956, + /* 320 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 330 */ 635, 943, 956, 956, 940, 956, 956, 956, 956, 801, + /* 340 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 350 */ 918, 956, 956, 956, 956, 956, 956, 956, 912, 956, + /* 360 */ 956, 956, 956, 956, 956, 905, 904, 956, 956, 956, + /* 370 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 380 */ 956, 956, 956, 956, 956, 956, 956, 956, 956, 956, + /* 390 */ 956, 956, 956, 788, 956, 781, 956, 867, 956, 956, + /* 400 */ 956, 956, 956, 956, 956, 956, 956, 956, 744, 817, + /* 410 */ 956, 816, 820, 815, 667, 956, 648, 956, 631, 636, + /* 420 */ 952, 955, 954, 951, 950, 949, 944, 942, 939, 938, + /* 430 */ 937, 935, 932, 928, 887, 885, 892, 891, 890, 889, + /* 440 */ 888, 886, 884, 882, 803, 798, 795, 927, 880, 740, + /* 450 */ 737, 736, 656, 945, 911, 920, 807, 806, 809, 917, + /* 460 */ 916, 915, 913, 910, 897, 805, 804, 732, 872, 871, + /* 470 */ 659, 901, 900, 899, 903, 907, 898, 768, 658, 655, + /* 480 */ 664, 721, 720, 728, 726, 725, 724, 723, 722, 719, + /* 490 */ 666, 674, 685, 713, 698, 697, 877, 879, 876, 875, + /* 500 */ 706, 705, 711, 710, 709, 708, 707, 704, 703, 702, + /* 510 */ 695, 694, 700, 693, 716, 715, 712, 692, 735, 734, + /* 520 */ 733, 730, 691, 690, 689, 820, 688, 687, 826, 825, + /* 530 */ 813, 856, 755, 754, 753, 765, 764, 777, 776, 811, + /* 540 */ 810, 778, 763, 757, 756, 772, 771, 770, 769, 761, + /* 550 */ 751, 783, 785, 784, 782, 858, 767, 855, 926, 925, + /* 560 */ 924, 923, 922, 860, 859, 827, 824, 678, 679, 895, + /* 570 */ 894, 896, 893, 681, 680, 677, 676, 857, 746, 745, + /* 580 */ 853, 850, 842, 838, 854, 851, 843, 839, 837, 836, + /* 590 */ 822, 821, 819, 818, 814, 823, 669, 747, 743, 742, + /* 600 */ 812, 749, 748, 686, 684, 682, 663, 661, 654, 652, + /* 610 */ 651, 653, 649, 647, 646, 645, 644, 643, 672, 671, + /* 620 */ 670, 668, 667, 641, 638, 637, 633, 632, 630, }; /* The next table maps tokens into fallback tokens. If a construct ** like the following: ** @@ -108540,20 +108758,20 @@ "ifexists", "fullname", "oneselect", "multiselect_op", "distinct", "selcollist", "from", "where_opt", "groupby_opt", "having_opt", "orderby_opt", "limit_opt", "sclp", "as", "seltablist", "stl_prefix", "joinop", "indexed_opt", "on_opt", "using_opt", - "joinop2", "inscollist", "sortlist", "sortitem", - "nexprlist", "setlist", "insert_cmd", "inscollist_opt", - "itemlist", "exprlist", "likeop", "between_op", - "in_op", "case_operand", "case_exprlist", "case_else", - "uniqueflag", "collate", "nmnum", "plus_opt", - "number", "trigger_decl", "trigger_cmd_list", "trigger_time", - "trigger_event", "foreach_clause", "when_clause", "trigger_cmd", - "trnm", "tridxby", "database_kw_opt", "key_opt", - "add_column_fullname", "kwcolumn_opt", "create_vtab", "vtabarglist", - "vtabarg", "vtabargtoken", "lp", "anylist", + "joinop2", "inscollist", "sortlist", "nexprlist", + "setlist", "insert_cmd", "inscollist_opt", "valuelist", + "exprlist", "likeop", "between_op", "in_op", + "case_operand", "case_exprlist", "case_else", "uniqueflag", + "collate", "nmnum", "number", "trigger_decl", + "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause", + "when_clause", "trigger_cmd", "trnm", "tridxby", + "database_kw_opt", "key_opt", "add_column_fullname", "kwcolumn_opt", + "create_vtab", "vtabarglist", "vtabarg", "vtabargtoken", + "lp", "anylist", }; #endif /* NDEBUG */ #ifndef NDEBUG /* For tracing reduce actions, the names of all rules are required. @@ -108710,186 +108928,184 @@ /* 148 */ "indexed_opt ::= NOT INDEXED", /* 149 */ "using_opt ::= USING LP inscollist RP", /* 150 */ "using_opt ::=", /* 151 */ "orderby_opt ::=", /* 152 */ "orderby_opt ::= ORDER BY sortlist", - /* 153 */ "sortlist ::= sortlist COMMA sortitem sortorder", - /* 154 */ "sortlist ::= sortitem sortorder", - /* 155 */ "sortitem ::= expr", - /* 156 */ "sortorder ::= ASC", - /* 157 */ "sortorder ::= DESC", - /* 158 */ "sortorder ::=", - /* 159 */ "groupby_opt ::=", - /* 160 */ "groupby_opt ::= GROUP BY nexprlist", - /* 161 */ "having_opt ::=", - /* 162 */ "having_opt ::= HAVING expr", - /* 163 */ "limit_opt ::=", - /* 164 */ "limit_opt ::= LIMIT expr", - /* 165 */ "limit_opt ::= LIMIT expr OFFSET expr", - /* 166 */ "limit_opt ::= LIMIT expr COMMA expr", - /* 167 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt", - /* 168 */ "where_opt ::=", - /* 169 */ "where_opt ::= WHERE expr", - /* 170 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt", - /* 171 */ "setlist ::= setlist COMMA nm EQ expr", - /* 172 */ "setlist ::= nm EQ expr", - /* 173 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP", - /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", - /* 175 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES", - /* 176 */ "insert_cmd ::= INSERT orconf", - /* 177 */ "insert_cmd ::= REPLACE", - /* 178 */ "itemlist ::= itemlist COMMA expr", - /* 179 */ "itemlist ::= expr", - /* 180 */ "inscollist_opt ::=", - /* 181 */ "inscollist_opt ::= LP inscollist RP", - /* 182 */ "inscollist ::= inscollist COMMA nm", - /* 183 */ "inscollist ::= nm", - /* 184 */ "expr ::= term", - /* 185 */ "expr ::= LP expr RP", - /* 186 */ "term ::= NULL", - /* 187 */ "expr ::= id", - /* 188 */ "expr ::= JOIN_KW", - /* 189 */ "expr ::= nm DOT nm", - /* 190 */ "expr ::= nm DOT nm DOT nm", - /* 191 */ "term ::= INTEGER|FLOAT|BLOB", - /* 192 */ "term ::= STRING", - /* 193 */ "expr ::= REGISTER", - /* 194 */ "expr ::= VARIABLE", - /* 195 */ "expr ::= expr COLLATE ids", - /* 196 */ "expr ::= CAST LP expr AS typetoken RP", - /* 197 */ "expr ::= ID LP distinct exprlist RP", - /* 198 */ "expr ::= ID LP STAR RP", - /* 199 */ "term ::= CTIME_KW", - /* 200 */ "expr ::= expr AND expr", - /* 201 */ "expr ::= expr OR expr", - /* 202 */ "expr ::= expr LT|GT|GE|LE expr", - /* 203 */ "expr ::= expr EQ|NE expr", - /* 204 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 205 */ "expr ::= expr PLUS|MINUS expr", - /* 206 */ "expr ::= expr STAR|SLASH|REM expr", - /* 207 */ "expr ::= expr CONCAT expr", - /* 208 */ "likeop ::= LIKE_KW", - /* 209 */ "likeop ::= NOT LIKE_KW", - /* 210 */ "likeop ::= MATCH", - /* 211 */ "likeop ::= NOT MATCH", - /* 212 */ "expr ::= expr likeop expr", - /* 213 */ "expr ::= expr likeop expr ESCAPE expr", - /* 214 */ "expr ::= expr ISNULL|NOTNULL", - /* 215 */ "expr ::= expr NOT NULL", - /* 216 */ "expr ::= expr IS expr", - /* 217 */ "expr ::= expr IS NOT expr", - /* 218 */ "expr ::= NOT expr", - /* 219 */ "expr ::= BITNOT expr", - /* 220 */ "expr ::= MINUS expr", - /* 221 */ "expr ::= PLUS expr", - /* 222 */ "between_op ::= BETWEEN", - /* 223 */ "between_op ::= NOT BETWEEN", - /* 224 */ "expr ::= expr between_op expr AND expr", - /* 225 */ "in_op ::= IN", - /* 226 */ "in_op ::= NOT IN", - /* 227 */ "expr ::= expr in_op LP exprlist RP", - /* 228 */ "expr ::= LP select RP", - /* 229 */ "expr ::= expr in_op LP select RP", - /* 230 */ "expr ::= expr in_op nm dbnm", - /* 231 */ "expr ::= EXISTS LP select RP", - /* 232 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 233 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 234 */ "case_exprlist ::= WHEN expr THEN expr", - /* 235 */ "case_else ::= ELSE expr", - /* 236 */ "case_else ::=", - /* 237 */ "case_operand ::= expr", - /* 238 */ "case_operand ::=", - /* 239 */ "exprlist ::= nexprlist", - /* 240 */ "exprlist ::=", - /* 241 */ "nexprlist ::= nexprlist COMMA expr", - /* 242 */ "nexprlist ::= expr", - /* 243 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", - /* 244 */ "uniqueflag ::= UNIQUE", - /* 245 */ "uniqueflag ::=", - /* 246 */ "idxlist_opt ::=", - /* 247 */ "idxlist_opt ::= LP idxlist RP", - /* 248 */ "idxlist ::= idxlist COMMA nm collate sortorder", - /* 249 */ "idxlist ::= nm collate sortorder", - /* 250 */ "collate ::=", - /* 251 */ "collate ::= COLLATE ids", - /* 252 */ "cmd ::= DROP INDEX ifexists fullname", - /* 253 */ "cmd ::= VACUUM", - /* 254 */ "cmd ::= VACUUM nm", - /* 255 */ "cmd ::= PRAGMA nm dbnm", - /* 256 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 257 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 258 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 259 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 260 */ "nmnum ::= plus_num", - /* 261 */ "nmnum ::= nm", - /* 262 */ "nmnum ::= ON", - /* 263 */ "nmnum ::= DELETE", - /* 264 */ "nmnum ::= DEFAULT", - /* 265 */ "plus_num ::= plus_opt number", + /* 153 */ "sortlist ::= sortlist COMMA expr sortorder", + /* 154 */ "sortlist ::= expr sortorder", + /* 155 */ "sortorder ::= ASC", + /* 156 */ "sortorder ::= DESC", + /* 157 */ "sortorder ::=", + /* 158 */ "groupby_opt ::=", + /* 159 */ "groupby_opt ::= GROUP BY nexprlist", + /* 160 */ "having_opt ::=", + /* 161 */ "having_opt ::= HAVING expr", + /* 162 */ "limit_opt ::=", + /* 163 */ "limit_opt ::= LIMIT expr", + /* 164 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 165 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 166 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt", + /* 167 */ "where_opt ::=", + /* 168 */ "where_opt ::= WHERE expr", + /* 169 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt", + /* 170 */ "setlist ::= setlist COMMA nm EQ expr", + /* 171 */ "setlist ::= nm EQ expr", + /* 172 */ "cmd ::= insert_cmd INTO fullname inscollist_opt valuelist", + /* 173 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", + /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES", + /* 175 */ "insert_cmd ::= INSERT orconf", + /* 176 */ "insert_cmd ::= REPLACE", + /* 177 */ "valuelist ::= VALUES LP nexprlist RP", + /* 178 */ "valuelist ::= valuelist COMMA LP exprlist RP", + /* 179 */ "inscollist_opt ::=", + /* 180 */ "inscollist_opt ::= LP inscollist RP", + /* 181 */ "inscollist ::= inscollist COMMA nm", + /* 182 */ "inscollist ::= nm", + /* 183 */ "expr ::= term", + /* 184 */ "expr ::= LP expr RP", + /* 185 */ "term ::= NULL", + /* 186 */ "expr ::= id", + /* 187 */ "expr ::= JOIN_KW", + /* 188 */ "expr ::= nm DOT nm", + /* 189 */ "expr ::= nm DOT nm DOT nm", + /* 190 */ "term ::= INTEGER|FLOAT|BLOB", + /* 191 */ "term ::= STRING", + /* 192 */ "expr ::= REGISTER", + /* 193 */ "expr ::= VARIABLE", + /* 194 */ "expr ::= expr COLLATE ids", + /* 195 */ "expr ::= CAST LP expr AS typetoken RP", + /* 196 */ "expr ::= ID LP distinct exprlist RP", + /* 197 */ "expr ::= ID LP STAR RP", + /* 198 */ "term ::= CTIME_KW", + /* 199 */ "expr ::= expr AND expr", + /* 200 */ "expr ::= expr OR expr", + /* 201 */ "expr ::= expr LT|GT|GE|LE expr", + /* 202 */ "expr ::= expr EQ|NE expr", + /* 203 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 204 */ "expr ::= expr PLUS|MINUS expr", + /* 205 */ "expr ::= expr STAR|SLASH|REM expr", + /* 206 */ "expr ::= expr CONCAT expr", + /* 207 */ "likeop ::= LIKE_KW", + /* 208 */ "likeop ::= NOT LIKE_KW", + /* 209 */ "likeop ::= MATCH", + /* 210 */ "likeop ::= NOT MATCH", + /* 211 */ "expr ::= expr likeop expr", + /* 212 */ "expr ::= expr likeop expr ESCAPE expr", + /* 213 */ "expr ::= expr ISNULL|NOTNULL", + /* 214 */ "expr ::= expr NOT NULL", + /* 215 */ "expr ::= expr IS expr", + /* 216 */ "expr ::= expr IS NOT expr", + /* 217 */ "expr ::= NOT expr", + /* 218 */ "expr ::= BITNOT expr", + /* 219 */ "expr ::= MINUS expr", + /* 220 */ "expr ::= PLUS expr", + /* 221 */ "between_op ::= BETWEEN", + /* 222 */ "between_op ::= NOT BETWEEN", + /* 223 */ "expr ::= expr between_op expr AND expr", + /* 224 */ "in_op ::= IN", + /* 225 */ "in_op ::= NOT IN", + /* 226 */ "expr ::= expr in_op LP exprlist RP", + /* 227 */ "expr ::= LP select RP", + /* 228 */ "expr ::= expr in_op LP select RP", + /* 229 */ "expr ::= expr in_op nm dbnm", + /* 230 */ "expr ::= EXISTS LP select RP", + /* 231 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 232 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 233 */ "case_exprlist ::= WHEN expr THEN expr", + /* 234 */ "case_else ::= ELSE expr", + /* 235 */ "case_else ::=", + /* 236 */ "case_operand ::= expr", + /* 237 */ "case_operand ::=", + /* 238 */ "exprlist ::= nexprlist", + /* 239 */ "exprlist ::=", + /* 240 */ "nexprlist ::= nexprlist COMMA expr", + /* 241 */ "nexprlist ::= expr", + /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", + /* 243 */ "uniqueflag ::= UNIQUE", + /* 244 */ "uniqueflag ::=", + /* 245 */ "idxlist_opt ::=", + /* 246 */ "idxlist_opt ::= LP idxlist RP", + /* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder", + /* 248 */ "idxlist ::= nm collate sortorder", + /* 249 */ "collate ::=", + /* 250 */ "collate ::= COLLATE ids", + /* 251 */ "cmd ::= DROP INDEX ifexists fullname", + /* 252 */ "cmd ::= VACUUM", + /* 253 */ "cmd ::= VACUUM nm", + /* 254 */ "cmd ::= PRAGMA nm dbnm", + /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 256 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 257 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 258 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 259 */ "nmnum ::= plus_num", + /* 260 */ "nmnum ::= nm", + /* 261 */ "nmnum ::= ON", + /* 262 */ "nmnum ::= DELETE", + /* 263 */ "nmnum ::= DEFAULT", + /* 264 */ "plus_num ::= PLUS number", + /* 265 */ "plus_num ::= number", /* 266 */ "minus_num ::= MINUS number", /* 267 */ "number ::= INTEGER|FLOAT", - /* 268 */ "plus_opt ::= PLUS", - /* 269 */ "plus_opt ::=", - /* 270 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 271 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 272 */ "trigger_time ::= BEFORE", - /* 273 */ "trigger_time ::= AFTER", - /* 274 */ "trigger_time ::= INSTEAD OF", - /* 275 */ "trigger_time ::=", - /* 276 */ "trigger_event ::= DELETE|INSERT", - /* 277 */ "trigger_event ::= UPDATE", - /* 278 */ "trigger_event ::= UPDATE OF inscollist", - /* 279 */ "foreach_clause ::=", - /* 280 */ "foreach_clause ::= FOR EACH ROW", - /* 281 */ "when_clause ::=", - /* 282 */ "when_clause ::= WHEN expr", - /* 283 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 284 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 285 */ "trnm ::= nm", - /* 286 */ "trnm ::= nm DOT nm", - /* 287 */ "tridxby ::=", - /* 288 */ "tridxby ::= INDEXED BY nm", - /* 289 */ "tridxby ::= NOT INDEXED", - /* 290 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", - /* 291 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP", - /* 292 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select", - /* 293 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", - /* 294 */ "trigger_cmd ::= select", - /* 295 */ "expr ::= RAISE LP IGNORE RP", - /* 296 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 297 */ "raisetype ::= ROLLBACK", - /* 298 */ "raisetype ::= ABORT", - /* 299 */ "raisetype ::= FAIL", - /* 300 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 301 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 302 */ "cmd ::= DETACH database_kw_opt expr", - /* 303 */ "key_opt ::=", - /* 304 */ "key_opt ::= KEY expr", - /* 305 */ "database_kw_opt ::= DATABASE", - /* 306 */ "database_kw_opt ::=", - /* 307 */ "cmd ::= REINDEX", - /* 308 */ "cmd ::= REINDEX nm dbnm", - /* 309 */ "cmd ::= ANALYZE", - /* 310 */ "cmd ::= ANALYZE nm dbnm", - /* 311 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 312 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", - /* 313 */ "add_column_fullname ::= fullname", - /* 314 */ "kwcolumn_opt ::=", - /* 315 */ "kwcolumn_opt ::= COLUMNKW", - /* 316 */ "cmd ::= create_vtab", - /* 317 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 318 */ "create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm", - /* 319 */ "vtabarglist ::= vtabarg", - /* 320 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 321 */ "vtabarg ::=", - /* 322 */ "vtabarg ::= vtabarg vtabargtoken", - /* 323 */ "vtabargtoken ::= ANY", - /* 324 */ "vtabargtoken ::= lp anylist RP", - /* 325 */ "lp ::= LP", - /* 326 */ "anylist ::=", - /* 327 */ "anylist ::= anylist LP anylist RP", - /* 328 */ "anylist ::= anylist ANY", + /* 268 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 269 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 270 */ "trigger_time ::= BEFORE", + /* 271 */ "trigger_time ::= AFTER", + /* 272 */ "trigger_time ::= INSTEAD OF", + /* 273 */ "trigger_time ::=", + /* 274 */ "trigger_event ::= DELETE|INSERT", + /* 275 */ "trigger_event ::= UPDATE", + /* 276 */ "trigger_event ::= UPDATE OF inscollist", + /* 277 */ "foreach_clause ::=", + /* 278 */ "foreach_clause ::= FOR EACH ROW", + /* 279 */ "when_clause ::=", + /* 280 */ "when_clause ::= WHEN expr", + /* 281 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 283 */ "trnm ::= nm", + /* 284 */ "trnm ::= nm DOT nm", + /* 285 */ "tridxby ::=", + /* 286 */ "tridxby ::= INDEXED BY nm", + /* 287 */ "tridxby ::= NOT INDEXED", + /* 288 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", + /* 289 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist", + /* 290 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select", + /* 291 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", + /* 292 */ "trigger_cmd ::= select", + /* 293 */ "expr ::= RAISE LP IGNORE RP", + /* 294 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 295 */ "raisetype ::= ROLLBACK", + /* 296 */ "raisetype ::= ABORT", + /* 297 */ "raisetype ::= FAIL", + /* 298 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 299 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 300 */ "cmd ::= DETACH database_kw_opt expr", + /* 301 */ "key_opt ::=", + /* 302 */ "key_opt ::= KEY expr", + /* 303 */ "database_kw_opt ::= DATABASE", + /* 304 */ "database_kw_opt ::=", + /* 305 */ "cmd ::= REINDEX", + /* 306 */ "cmd ::= REINDEX nm dbnm", + /* 307 */ "cmd ::= ANALYZE", + /* 308 */ "cmd ::= ANALYZE nm dbnm", + /* 309 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 310 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", + /* 311 */ "add_column_fullname ::= fullname", + /* 312 */ "kwcolumn_opt ::=", + /* 313 */ "kwcolumn_opt ::= COLUMNKW", + /* 314 */ "cmd ::= create_vtab", + /* 315 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 316 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 317 */ "vtabarglist ::= vtabarg", + /* 318 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 319 */ "vtabarg ::=", + /* 320 */ "vtabarg ::= vtabarg vtabargtoken", + /* 321 */ "vtabargtoken ::= ANY", + /* 322 */ "vtabargtoken ::= lp anylist RP", + /* 323 */ "lp ::= LP", + /* 324 */ "anylist ::=", + /* 325 */ "anylist ::= anylist LP anylist RP", + /* 326 */ "anylist ::= anylist ANY", }; #endif /* NDEBUG */ #if YYSTACKDEPTH<=0 @@ -108967,71 +109183,77 @@ ** inside the C code. */ case 160: /* select */ case 194: /* oneselect */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy387)); +sqlite3SelectDelete(pParse->db, (yypminor->yy159)); } break; case 174: /* term */ case 175: /* expr */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy118).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy342).pExpr); } break; case 179: /* idxlist_opt */ case 187: /* idxlist */ case 197: /* selcollist */ case 200: /* groupby_opt */ case 202: /* orderby_opt */ case 204: /* sclp */ case 214: /* sortlist */ - case 216: /* nexprlist */ - case 217: /* setlist */ - case 220: /* itemlist */ - case 221: /* exprlist */ - case 226: /* case_exprlist */ + case 215: /* nexprlist */ + case 216: /* setlist */ + case 220: /* exprlist */ + case 225: /* case_exprlist */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy322)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy442)); } break; case 193: /* fullname */ case 198: /* from */ case 206: /* seltablist */ case 207: /* stl_prefix */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy259)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy347)); } break; case 199: /* where_opt */ case 201: /* having_opt */ case 210: /* on_opt */ - case 215: /* sortitem */ - case 225: /* case_operand */ - case 227: /* case_else */ - case 238: /* when_clause */ - case 243: /* key_opt */ + case 224: /* case_operand */ + case 226: /* case_else */ + case 236: /* when_clause */ + case 241: /* key_opt */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy314)); +sqlite3ExprDelete(pParse->db, (yypminor->yy122)); } break; case 211: /* using_opt */ case 213: /* inscollist */ - case 219: /* inscollist_opt */ + case 218: /* inscollist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy384)); +sqlite3IdListDelete(pParse->db, (yypminor->yy180)); +} + break; + case 219: /* valuelist */ +{ + + sqlite3ExprListDelete(pParse->db, (yypminor->yy487).pList); + sqlite3SelectDelete(pParse->db, (yypminor->yy487).pSelect); + } break; - case 234: /* trigger_cmd_list */ - case 239: /* trigger_cmd */ + case 232: /* trigger_cmd_list */ + case 237: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy203)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy327)); } break; - case 236: /* trigger_event */ + case 234: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy90).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy410).b); } break; default: break; /* If no destructor action specified: do nothing */ } } @@ -109427,11 +109649,10 @@ { 211, 0 }, { 202, 0 }, { 202, 3 }, { 214, 4 }, { 214, 2 }, - { 215, 1 }, { 177, 1 }, { 177, 1 }, { 177, 0 }, { 200, 0 }, { 200, 3 }, @@ -109443,21 +109664,21 @@ { 203, 4 }, { 147, 5 }, { 199, 0 }, { 199, 2 }, { 147, 7 }, - { 217, 5 }, - { 217, 3 }, - { 147, 8 }, + { 216, 5 }, + { 216, 3 }, + { 147, 5 }, { 147, 5 }, { 147, 6 }, - { 218, 2 }, - { 218, 1 }, - { 220, 3 }, - { 220, 1 }, - { 219, 0 }, - { 219, 3 }, + { 217, 2 }, + { 217, 1 }, + { 219, 4 }, + { 219, 5 }, + { 218, 0 }, + { 218, 3 }, { 213, 3 }, { 213, 1 }, { 175, 1 }, { 175, 3 }, { 174, 1 }, @@ -109480,14 +109701,14 @@ { 175, 3 }, { 175, 3 }, { 175, 3 }, { 175, 3 }, { 175, 3 }, - { 222, 1 }, - { 222, 2 }, - { 222, 1 }, - { 222, 2 }, + { 221, 1 }, + { 221, 2 }, + { 221, 1 }, + { 221, 2 }, { 175, 3 }, { 175, 5 }, { 175, 2 }, { 175, 3 }, { 175, 3 }, @@ -109494,117 +109715,116 @@ { 175, 4 }, { 175, 2 }, { 175, 2 }, { 175, 2 }, { 175, 2 }, + { 222, 1 }, + { 222, 2 }, + { 175, 5 }, { 223, 1 }, { 223, 2 }, - { 175, 5 }, - { 224, 1 }, - { 224, 2 }, { 175, 5 }, { 175, 3 }, { 175, 5 }, { 175, 4 }, { 175, 4 }, { 175, 5 }, - { 226, 5 }, - { 226, 4 }, - { 227, 2 }, - { 227, 0 }, - { 225, 1 }, - { 225, 0 }, - { 221, 1 }, - { 221, 0 }, - { 216, 3 }, - { 216, 1 }, + { 225, 5 }, + { 225, 4 }, + { 226, 2 }, + { 226, 0 }, + { 224, 1 }, + { 224, 0 }, + { 220, 1 }, + { 220, 0 }, + { 215, 3 }, + { 215, 1 }, { 147, 11 }, - { 228, 1 }, - { 228, 0 }, + { 227, 1 }, + { 227, 0 }, { 179, 0 }, { 179, 3 }, { 187, 5 }, { 187, 3 }, - { 229, 0 }, - { 229, 2 }, + { 228, 0 }, + { 228, 2 }, { 147, 4 }, { 147, 1 }, { 147, 2 }, { 147, 3 }, { 147, 5 }, { 147, 6 }, { 147, 5 }, { 147, 6 }, - { 230, 1 }, - { 230, 1 }, - { 230, 1 }, - { 230, 1 }, - { 230, 1 }, + { 229, 1 }, + { 229, 1 }, + { 229, 1 }, + { 229, 1 }, + { 229, 1 }, { 170, 2 }, + { 170, 1 }, { 171, 2 }, - { 232, 1 }, - { 231, 1 }, - { 231, 0 }, + { 230, 1 }, { 147, 5 }, - { 233, 11 }, - { 235, 1 }, - { 235, 1 }, - { 235, 2 }, + { 231, 11 }, + { 233, 1 }, + { 233, 1 }, + { 233, 2 }, + { 233, 0 }, + { 234, 1 }, + { 234, 1 }, + { 234, 3 }, { 235, 0 }, - { 236, 1 }, - { 236, 1 }, - { 236, 3 }, - { 237, 0 }, - { 237, 3 }, - { 238, 0 }, - { 238, 2 }, - { 234, 3 }, - { 234, 2 }, - { 240, 1 }, - { 240, 3 }, - { 241, 0 }, - { 241, 3 }, - { 241, 2 }, - { 239, 7 }, - { 239, 8 }, - { 239, 5 }, - { 239, 5 }, - { 239, 1 }, + { 235, 3 }, + { 236, 0 }, + { 236, 2 }, + { 232, 3 }, + { 232, 2 }, + { 238, 1 }, + { 238, 3 }, + { 239, 0 }, + { 239, 3 }, + { 239, 2 }, + { 237, 7 }, + { 237, 5 }, + { 237, 5 }, + { 237, 5 }, + { 237, 1 }, { 175, 4 }, { 175, 6 }, { 191, 1 }, { 191, 1 }, { 191, 1 }, { 147, 4 }, { 147, 6 }, { 147, 3 }, - { 243, 0 }, - { 243, 2 }, - { 242, 1 }, - { 242, 0 }, + { 241, 0 }, + { 241, 2 }, + { 240, 1 }, + { 240, 0 }, { 147, 1 }, { 147, 3 }, { 147, 1 }, { 147, 3 }, { 147, 6 }, { 147, 6 }, - { 244, 1 }, - { 245, 0 }, - { 245, 1 }, + { 242, 1 }, + { 243, 0 }, + { 243, 1 }, { 147, 1 }, { 147, 4 }, - { 246, 7 }, + { 244, 8 }, + { 245, 1 }, + { 245, 3 }, + { 246, 0 }, + { 246, 2 }, { 247, 1 }, { 247, 3 }, - { 248, 0 }, - { 248, 2 }, - { 249, 1 }, - { 249, 3 }, - { 250, 1 }, - { 251, 0 }, - { 251, 4 }, - { 251, 2 }, + { 248, 1 }, + { 249, 0 }, + { 249, 4 }, + { 249, 2 }, }; static void yy_accept(yyParser*); /* Forward Declaration */ /* @@ -109668,21 +109888,21 @@ break; case 8: /* cmdx ::= cmd */ { sqlite3FinishCoding(pParse); } break; case 9: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy4);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy392);} break; case 13: /* transtype ::= */ -{yygotominor.yy4 = TK_DEFERRED;} +{yygotominor.yy392 = TK_DEFERRED;} break; case 14: /* transtype ::= DEFERRED */ case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15); case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16); case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115); case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117); -{yygotominor.yy4 = yymsp[0].major;} +{yygotominor.yy392 = yymsp[0].major;} break; case 17: /* cmd ::= COMMIT trans_opt */ case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18); {sqlite3CommitTransaction(pParse);} break; @@ -109704,11 +109924,11 @@ sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0); } break; case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy392,0,0,yymsp[-2].minor.yy392); } break; case 27: /* createkw ::= CREATE */ { pParse->db->lookaside.bEnabled = 0; @@ -109723,33 +109943,33 @@ case 87: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==87); case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98); case 109: /* ifexists ::= */ yytestcase(yyruleno==109); case 120: /* distinct ::= ALL */ yytestcase(yyruleno==120); case 121: /* distinct ::= */ yytestcase(yyruleno==121); - case 222: /* between_op ::= BETWEEN */ yytestcase(yyruleno==222); - case 225: /* in_op ::= IN */ yytestcase(yyruleno==225); -{yygotominor.yy4 = 0;} + case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221); + case 224: /* in_op ::= IN */ yytestcase(yyruleno==224); +{yygotominor.yy392 = 0;} break; case 29: /* ifnotexists ::= IF NOT EXISTS */ case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30); case 71: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==71); case 86: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==86); case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108); case 119: /* distinct ::= DISTINCT */ yytestcase(yyruleno==119); - case 223: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==223); - case 226: /* in_op ::= NOT IN */ yytestcase(yyruleno==226); -{yygotominor.yy4 = 1;} + case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222); + case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225); +{yygotominor.yy392 = 1;} break; case 32: /* create_table_args ::= LP columnlist conslist_opt RP */ { sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0); } break; case 33: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy387); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387); + sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy159); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159); } break; case 36: /* column ::= columnid type carglist */ { yygotominor.yy0.z = yymsp[-2].minor.yy0.z; @@ -109772,20 +109992,21 @@ case 49: /* typename ::= ids */ yytestcase(yyruleno==49); case 127: /* as ::= AS nm */ yytestcase(yyruleno==127); case 128: /* as ::= ids */ yytestcase(yyruleno==128); case 138: /* dbnm ::= DOT nm */ yytestcase(yyruleno==138); case 147: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==147); - case 251: /* collate ::= COLLATE ids */ yytestcase(yyruleno==251); - case 260: /* nmnum ::= plus_num */ yytestcase(yyruleno==260); - case 261: /* nmnum ::= nm */ yytestcase(yyruleno==261); - case 262: /* nmnum ::= ON */ yytestcase(yyruleno==262); - case 263: /* nmnum ::= DELETE */ yytestcase(yyruleno==263); - case 264: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==264); - case 265: /* plus_num ::= plus_opt number */ yytestcase(yyruleno==265); + case 250: /* collate ::= COLLATE ids */ yytestcase(yyruleno==250); + case 259: /* nmnum ::= plus_num */ yytestcase(yyruleno==259); + case 260: /* nmnum ::= nm */ yytestcase(yyruleno==260); + case 261: /* nmnum ::= ON */ yytestcase(yyruleno==261); + case 262: /* nmnum ::= DELETE */ yytestcase(yyruleno==262); + case 263: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==263); + case 264: /* plus_num ::= PLUS number */ yytestcase(yyruleno==264); + case 265: /* plus_num ::= number */ yytestcase(yyruleno==265); case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266); case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267); - case 285: /* trnm ::= nm */ yytestcase(yyruleno==285); + case 283: /* trnm ::= nm */ yytestcase(yyruleno==283); {yygotominor.yy0 = yymsp[0].minor.yy0;} break; case 45: /* type ::= typetoken */ {sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);} break; @@ -109804,21 +110025,21 @@ case 50: /* typename ::= typename ids */ {yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} break; case 57: /* ccons ::= DEFAULT term */ case 59: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==59); -{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy118);} +{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy342);} break; case 58: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy118);} +{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy342);} break; case 60: /* ccons ::= DEFAULT MINUS term */ { ExprSpan v; - v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy118.pExpr, 0, 0); + v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy342.pExpr, 0, 0); v.zStart = yymsp[-1].minor.yy0.z; - v.zEnd = yymsp[0].minor.yy118.zEnd; + v.zEnd = yymsp[0].minor.yy342.zEnd; sqlite3AddDefaultValue(pParse,&v); } break; case 61: /* ccons ::= DEFAULT id */ { @@ -109826,897 +110047,921 @@ spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0); sqlite3AddDefaultValue(pParse,&v); } break; case 63: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy4);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy392);} break; case 64: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy4,yymsp[0].minor.yy4,yymsp[-2].minor.yy4);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy392,yymsp[0].minor.yy392,yymsp[-2].minor.yy392);} break; case 65: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy4,0,0,0,0);} +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy392,0,0,0,0);} break; case 66: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy118.pExpr);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy342.pExpr);} break; case 67: /* ccons ::= REFERENCES nm idxlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy4);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy442,yymsp[0].minor.yy392);} break; case 68: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy4);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy392);} break; case 69: /* ccons ::= COLLATE ids */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 72: /* refargs ::= */ -{ yygotominor.yy4 = OE_None*0x0101; /* EV: R-19803-45884 */} +{ yygotominor.yy392 = OE_None*0x0101; /* EV: R-19803-45884 */} break; case 73: /* refargs ::= refargs refarg */ -{ yygotominor.yy4 = (yymsp[-1].minor.yy4 & ~yymsp[0].minor.yy215.mask) | yymsp[0].minor.yy215.value; } +{ yygotominor.yy392 = (yymsp[-1].minor.yy392 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; } break; case 74: /* refarg ::= MATCH nm */ case 75: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==75); -{ yygotominor.yy215.value = 0; yygotominor.yy215.mask = 0x000000; } +{ yygotominor.yy207.value = 0; yygotominor.yy207.mask = 0x000000; } break; case 76: /* refarg ::= ON DELETE refact */ -{ yygotominor.yy215.value = yymsp[0].minor.yy4; yygotominor.yy215.mask = 0x0000ff; } +{ yygotominor.yy207.value = yymsp[0].minor.yy392; yygotominor.yy207.mask = 0x0000ff; } break; case 77: /* refarg ::= ON UPDATE refact */ -{ yygotominor.yy215.value = yymsp[0].minor.yy4<<8; yygotominor.yy215.mask = 0x00ff00; } +{ yygotominor.yy207.value = yymsp[0].minor.yy392<<8; yygotominor.yy207.mask = 0x00ff00; } break; case 78: /* refact ::= SET NULL */ -{ yygotominor.yy4 = OE_SetNull; /* EV: R-33326-45252 */} +{ yygotominor.yy392 = OE_SetNull; /* EV: R-33326-45252 */} break; case 79: /* refact ::= SET DEFAULT */ -{ yygotominor.yy4 = OE_SetDflt; /* EV: R-33326-45252 */} +{ yygotominor.yy392 = OE_SetDflt; /* EV: R-33326-45252 */} break; case 80: /* refact ::= CASCADE */ -{ yygotominor.yy4 = OE_Cascade; /* EV: R-33326-45252 */} +{ yygotominor.yy392 = OE_Cascade; /* EV: R-33326-45252 */} break; case 81: /* refact ::= RESTRICT */ -{ yygotominor.yy4 = OE_Restrict; /* EV: R-33326-45252 */} +{ yygotominor.yy392 = OE_Restrict; /* EV: R-33326-45252 */} break; case 82: /* refact ::= NO ACTION */ -{ yygotominor.yy4 = OE_None; /* EV: R-33326-45252 */} +{ yygotominor.yy392 = OE_None; /* EV: R-33326-45252 */} break; case 84: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 99: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==99); case 101: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==101); case 104: /* resolvetype ::= raisetype */ yytestcase(yyruleno==104); -{yygotominor.yy4 = yymsp[0].minor.yy4;} +{yygotominor.yy392 = yymsp[0].minor.yy392;} break; case 88: /* conslist_opt ::= */ {yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;} break; case 89: /* conslist_opt ::= COMMA conslist */ {yygotominor.yy0 = yymsp[-1].minor.yy0;} break; case 94: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy4,yymsp[-2].minor.yy4,0);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy442,yymsp[0].minor.yy392,yymsp[-2].minor.yy392,0);} break; case 95: /* tcons ::= UNIQUE LP idxlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy4,0,0,0,0);} +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy442,yymsp[0].minor.yy392,0,0,0,0);} break; case 96: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy118.pExpr);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy342.pExpr);} break; case 97: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy4); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy4); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy442, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy442, yymsp[-1].minor.yy392); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy392); } break; case 100: /* onconf ::= */ -{yygotominor.yy4 = OE_Default;} +{yygotominor.yy392 = OE_Default;} break; case 102: /* orconf ::= */ -{yygotominor.yy210 = OE_Default;} +{yygotominor.yy258 = OE_Default;} break; case 103: /* orconf ::= OR resolvetype */ -{yygotominor.yy210 = (u8)yymsp[0].minor.yy4;} +{yygotominor.yy258 = (u8)yymsp[0].minor.yy392;} break; case 105: /* resolvetype ::= IGNORE */ -{yygotominor.yy4 = OE_Ignore;} +{yygotominor.yy392 = OE_Ignore;} break; case 106: /* resolvetype ::= REPLACE */ -{yygotominor.yy4 = OE_Replace;} +{yygotominor.yy392 = OE_Replace;} break; case 107: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0, yymsp[-1].minor.yy4); + sqlite3DropTable(pParse, yymsp[0].minor.yy347, 0, yymsp[-1].minor.yy392); } break; case 110: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */ { - sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy387, yymsp[-6].minor.yy4, yymsp[-4].minor.yy4); + sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy159, yymsp[-6].minor.yy392, yymsp[-4].minor.yy392); } break; case 111: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1, yymsp[-1].minor.yy4); + sqlite3DropTable(pParse, yymsp[0].minor.yy347, 1, yymsp[-1].minor.yy392); } break; case 112: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy387, &dest); + sqlite3Select(pParse, yymsp[0].minor.yy159, &dest); sqlite3ExplainBegin(pParse->pVdbe); - sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy387); + sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy159); sqlite3ExplainFinish(pParse->pVdbe); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159); } break; case 113: /* select ::= oneselect */ -{yygotominor.yy387 = yymsp[0].minor.yy387;} +{yygotominor.yy159 = yymsp[0].minor.yy159;} break; case 114: /* select ::= select multiselect_op oneselect */ { - if( yymsp[0].minor.yy387 ){ - yymsp[0].minor.yy387->op = (u8)yymsp[-1].minor.yy4; - yymsp[0].minor.yy387->pPrior = yymsp[-2].minor.yy387; + if( yymsp[0].minor.yy159 ){ + yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392; + yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159; }else{ - sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy387); + sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159); } - yygotominor.yy387 = yymsp[0].minor.yy387; + yygotominor.yy159 = yymsp[0].minor.yy159; } break; case 116: /* multiselect_op ::= UNION ALL */ -{yygotominor.yy4 = TK_ALL;} +{yygotominor.yy392 = TK_ALL;} break; case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yygotominor.yy387 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy259,yymsp[-4].minor.yy314,yymsp[-3].minor.yy322,yymsp[-2].minor.yy314,yymsp[-1].minor.yy322,yymsp[-7].minor.yy4,yymsp[0].minor.yy292.pLimit,yymsp[0].minor.yy292.pOffset); + yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy392,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset); } break; case 122: /* sclp ::= selcollist COMMA */ - case 247: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==247); -{yygotominor.yy322 = yymsp[-1].minor.yy322;} + case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246); +{yygotominor.yy442 = yymsp[-1].minor.yy442;} break; case 123: /* sclp ::= */ case 151: /* orderby_opt ::= */ yytestcase(yyruleno==151); - case 159: /* groupby_opt ::= */ yytestcase(yyruleno==159); - case 240: /* exprlist ::= */ yytestcase(yyruleno==240); - case 246: /* idxlist_opt ::= */ yytestcase(yyruleno==246); -{yygotominor.yy322 = 0;} + case 158: /* groupby_opt ::= */ yytestcase(yyruleno==158); + case 239: /* exprlist ::= */ yytestcase(yyruleno==239); + case 245: /* idxlist_opt ::= */ yytestcase(yyruleno==245); +{yygotominor.yy442 = 0;} break; case 124: /* selcollist ::= sclp expr as */ { - yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, yymsp[-1].minor.yy118.pExpr); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yygotominor.yy322,&yymsp[-1].minor.yy118); + yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy442, yymsp[-1].minor.yy342.pExpr); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yygotominor.yy442,&yymsp[-1].minor.yy342); } break; case 125: /* selcollist ::= sclp STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0); - yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy322, p); + yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy442, p); } break; case 126: /* selcollist ::= sclp nm DOT STAR */ { Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0); Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); - yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, pDot); + yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442, pDot); } break; case 129: /* as ::= */ {yygotominor.yy0.n = 0;} break; case 130: /* from ::= */ -{yygotominor.yy259 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy259));} +{yygotominor.yy347 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy347));} break; case 131: /* from ::= FROM seltablist */ { - yygotominor.yy259 = yymsp[0].minor.yy259; - sqlite3SrcListShiftJoinType(yygotominor.yy259); + yygotominor.yy347 = yymsp[0].minor.yy347; + sqlite3SrcListShiftJoinType(yygotominor.yy347); } break; case 132: /* stl_prefix ::= seltablist joinop */ { - yygotominor.yy259 = yymsp[-1].minor.yy259; - if( ALWAYS(yygotominor.yy259 && yygotominor.yy259->nSrc>0) ) yygotominor.yy259->a[yygotominor.yy259->nSrc-1].jointype = (u8)yymsp[0].minor.yy4; + yygotominor.yy347 = yymsp[-1].minor.yy347; + if( ALWAYS(yygotominor.yy347 && yygotominor.yy347->nSrc>0) ) yygotominor.yy347->a[yygotominor.yy347->nSrc-1].jointype = (u8)yymsp[0].minor.yy392; } break; case 133: /* stl_prefix ::= */ -{yygotominor.yy259 = 0;} +{yygotominor.yy347 = 0;} break; case 134: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ { - yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384); - sqlite3SrcListIndexedBy(pParse, yygotominor.yy259, &yymsp[-2].minor.yy0); + yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180); + sqlite3SrcListIndexedBy(pParse, yygotominor.yy347, &yymsp[-2].minor.yy0); } break; case 135: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ { - yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy387,yymsp[-1].minor.yy314,yymsp[0].minor.yy384); + yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy159,yymsp[-1].minor.yy122,yymsp[0].minor.yy180); } break; case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ { - if( yymsp[-6].minor.yy259==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy314==0 && yymsp[0].minor.yy384==0 ){ - yygotominor.yy259 = yymsp[-4].minor.yy259; + if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){ + yygotominor.yy347 = yymsp[-4].minor.yy347; }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy259); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy259,0,0,0,0,0,0,0); - yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy314,yymsp[0].minor.yy384); + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,0,0,0); + yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180); } } break; case 137: /* dbnm ::= */ case 146: /* indexed_opt ::= */ yytestcase(yyruleno==146); {yygotominor.yy0.z=0; yygotominor.yy0.n=0;} break; case 139: /* fullname ::= nm dbnm */ -{yygotominor.yy259 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} +{yygotominor.yy347 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} break; case 140: /* joinop ::= COMMA|JOIN */ -{ yygotominor.yy4 = JT_INNER; } +{ yygotominor.yy392 = JT_INNER; } break; case 141: /* joinop ::= JOIN_KW JOIN */ -{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } +{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } break; case 142: /* joinop ::= JOIN_KW nm JOIN */ -{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); } +{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); } break; case 143: /* joinop ::= JOIN_KW nm nm JOIN */ -{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); } +{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); } break; case 144: /* on_opt ::= ON expr */ - case 155: /* sortitem ::= expr */ yytestcase(yyruleno==155); - case 162: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==162); - case 169: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==169); - case 235: /* case_else ::= ELSE expr */ yytestcase(yyruleno==235); - case 237: /* case_operand ::= expr */ yytestcase(yyruleno==237); -{yygotominor.yy314 = yymsp[0].minor.yy118.pExpr;} + case 161: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==161); + case 168: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==168); + case 234: /* case_else ::= ELSE expr */ yytestcase(yyruleno==234); + case 236: /* case_operand ::= expr */ yytestcase(yyruleno==236); +{yygotominor.yy122 = yymsp[0].minor.yy342.pExpr;} break; case 145: /* on_opt ::= */ - case 161: /* having_opt ::= */ yytestcase(yyruleno==161); - case 168: /* where_opt ::= */ yytestcase(yyruleno==168); - case 236: /* case_else ::= */ yytestcase(yyruleno==236); - case 238: /* case_operand ::= */ yytestcase(yyruleno==238); -{yygotominor.yy314 = 0;} + case 160: /* having_opt ::= */ yytestcase(yyruleno==160); + case 167: /* where_opt ::= */ yytestcase(yyruleno==167); + case 235: /* case_else ::= */ yytestcase(yyruleno==235); + case 237: /* case_operand ::= */ yytestcase(yyruleno==237); +{yygotominor.yy122 = 0;} break; case 148: /* indexed_opt ::= NOT INDEXED */ {yygotominor.yy0.z=0; yygotominor.yy0.n=1;} break; case 149: /* using_opt ::= USING LP inscollist RP */ - case 181: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==181); -{yygotominor.yy384 = yymsp[-1].minor.yy384;} + case 180: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==180); +{yygotominor.yy180 = yymsp[-1].minor.yy180;} break; case 150: /* using_opt ::= */ - case 180: /* inscollist_opt ::= */ yytestcase(yyruleno==180); -{yygotominor.yy384 = 0;} + case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179); +{yygotominor.yy180 = 0;} break; case 152: /* orderby_opt ::= ORDER BY sortlist */ - case 160: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==160); - case 239: /* exprlist ::= nexprlist */ yytestcase(yyruleno==239); -{yygotominor.yy322 = yymsp[0].minor.yy322;} - break; - case 153: /* sortlist ::= sortlist COMMA sortitem sortorder */ -{ - yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322,yymsp[-1].minor.yy314); - if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4; -} - break; - case 154: /* sortlist ::= sortitem sortorder */ -{ - yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy314); - if( yygotominor.yy322 && ALWAYS(yygotominor.yy322->a) ) yygotominor.yy322->a[0].sortOrder = (u8)yymsp[0].minor.yy4; -} - break; - case 156: /* sortorder ::= ASC */ - case 158: /* sortorder ::= */ yytestcase(yyruleno==158); -{yygotominor.yy4 = SQLITE_SO_ASC;} - break; - case 157: /* sortorder ::= DESC */ -{yygotominor.yy4 = SQLITE_SO_DESC;} - break; - case 163: /* limit_opt ::= */ -{yygotominor.yy292.pLimit = 0; yygotominor.yy292.pOffset = 0;} - break; - case 164: /* limit_opt ::= LIMIT expr */ -{yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr; yygotominor.yy292.pOffset = 0;} - break; - case 165: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yygotominor.yy292.pLimit = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pOffset = yymsp[0].minor.yy118.pExpr;} - break; - case 166: /* limit_opt ::= LIMIT expr COMMA expr */ -{yygotominor.yy292.pOffset = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr;} - break; - case 167: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */ -{ - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy259, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy259,yymsp[0].minor.yy314); -} - break; - case 170: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */ -{ - sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy259, &yymsp[-3].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy322,"set list"); - sqlite3Update(pParse,yymsp[-4].minor.yy259,yymsp[-1].minor.yy322,yymsp[0].minor.yy314,yymsp[-5].minor.yy210); -} - break; - case 171: /* setlist ::= setlist COMMA nm EQ expr */ -{ - yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy118.pExpr); - sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1); -} - break; - case 172: /* setlist ::= nm EQ expr */ -{ - yygotominor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy118.pExpr); - sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1); -} - break; - case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */ -{sqlite3Insert(pParse, yymsp[-5].minor.yy259, yymsp[-1].minor.yy322, 0, yymsp[-4].minor.yy384, yymsp[-7].minor.yy210);} - break; - case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */ -{sqlite3Insert(pParse, yymsp[-2].minor.yy259, 0, yymsp[0].minor.yy387, yymsp[-1].minor.yy384, yymsp[-4].minor.yy210);} - break; - case 175: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */ -{sqlite3Insert(pParse, yymsp[-3].minor.yy259, 0, 0, yymsp[-2].minor.yy384, yymsp[-5].minor.yy210);} - break; - case 176: /* insert_cmd ::= INSERT orconf */ -{yygotominor.yy210 = yymsp[0].minor.yy210;} - break; - case 177: /* insert_cmd ::= REPLACE */ -{yygotominor.yy210 = OE_Replace;} - break; - case 178: /* itemlist ::= itemlist COMMA expr */ - case 241: /* nexprlist ::= nexprlist COMMA expr */ yytestcase(yyruleno==241); -{yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy118.pExpr);} - break; - case 179: /* itemlist ::= expr */ - case 242: /* nexprlist ::= expr */ yytestcase(yyruleno==242); -{yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy118.pExpr);} - break; - case 182: /* inscollist ::= inscollist COMMA nm */ -{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy384,&yymsp[0].minor.yy0);} - break; - case 183: /* inscollist ::= nm */ -{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);} - break; - case 184: /* expr ::= term */ -{yygotominor.yy118 = yymsp[0].minor.yy118;} - break; - case 185: /* expr ::= LP expr RP */ -{yygotominor.yy118.pExpr = yymsp[-1].minor.yy118.pExpr; spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);} - break; - case 186: /* term ::= NULL */ - case 191: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==191); - case 192: /* term ::= STRING */ yytestcase(yyruleno==192); -{spanExpr(&yygotominor.yy118, pParse, yymsp[0].major, &yymsp[0].minor.yy0);} - break; - case 187: /* expr ::= id */ - case 188: /* expr ::= JOIN_KW */ yytestcase(yyruleno==188); -{spanExpr(&yygotominor.yy118, pParse, TK_ID, &yymsp[0].minor.yy0);} - break; - case 189: /* expr ::= nm DOT nm */ + case 159: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==159); + case 238: /* exprlist ::= nexprlist */ yytestcase(yyruleno==238); +{yygotominor.yy442 = yymsp[0].minor.yy442;} + break; + case 153: /* sortlist ::= sortlist COMMA expr sortorder */ +{ + yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442,yymsp[-1].minor.yy342.pExpr); + if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392; +} + break; + case 154: /* sortlist ::= expr sortorder */ +{ + yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy342.pExpr); + if( yygotominor.yy442 && ALWAYS(yygotominor.yy442->a) ) yygotominor.yy442->a[0].sortOrder = (u8)yymsp[0].minor.yy392; +} + break; + case 155: /* sortorder ::= ASC */ + case 157: /* sortorder ::= */ yytestcase(yyruleno==157); +{yygotominor.yy392 = SQLITE_SO_ASC;} + break; + case 156: /* sortorder ::= DESC */ +{yygotominor.yy392 = SQLITE_SO_DESC;} + break; + case 162: /* limit_opt ::= */ +{yygotominor.yy64.pLimit = 0; yygotominor.yy64.pOffset = 0;} + break; + case 163: /* limit_opt ::= LIMIT expr */ +{yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr; yygotominor.yy64.pOffset = 0;} + break; + case 164: /* limit_opt ::= LIMIT expr OFFSET expr */ +{yygotominor.yy64.pLimit = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pOffset = yymsp[0].minor.yy342.pExpr;} + break; + case 165: /* limit_opt ::= LIMIT expr COMMA expr */ +{yygotominor.yy64.pOffset = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr;} + break; + case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */ +{ + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy347, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy347,yymsp[0].minor.yy122); +} + break; + case 169: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */ +{ + sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy347, &yymsp[-3].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy442,"set list"); + sqlite3Update(pParse,yymsp[-4].minor.yy347,yymsp[-1].minor.yy442,yymsp[0].minor.yy122,yymsp[-5].minor.yy258); +} + break; + case 170: /* setlist ::= setlist COMMA nm EQ expr */ +{ + yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy442, yymsp[0].minor.yy342.pExpr); + sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1); +} + break; + case 171: /* setlist ::= nm EQ expr */ +{ + yygotominor.yy442 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy342.pExpr); + sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1); +} + break; + case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt valuelist */ +{sqlite3Insert(pParse, yymsp[-2].minor.yy347, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);} + break; + case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */ +{sqlite3Insert(pParse, yymsp[-2].minor.yy347, 0, yymsp[0].minor.yy159, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);} + break; + case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */ +{sqlite3Insert(pParse, yymsp[-3].minor.yy347, 0, 0, yymsp[-2].minor.yy180, yymsp[-5].minor.yy258);} + break; + case 175: /* insert_cmd ::= INSERT orconf */ +{yygotominor.yy258 = yymsp[0].minor.yy258;} + break; + case 176: /* insert_cmd ::= REPLACE */ +{yygotominor.yy258 = OE_Replace;} + break; + case 177: /* valuelist ::= VALUES LP nexprlist RP */ +{ + yygotominor.yy487.pList = yymsp[-1].minor.yy442; + yygotominor.yy487.pSelect = 0; +} + break; + case 178: /* valuelist ::= valuelist COMMA LP exprlist RP */ +{ + Select *pRight = sqlite3SelectNew(pParse, yymsp[-1].minor.yy442, 0, 0, 0, 0, 0, 0, 0, 0); + if( yymsp[-4].minor.yy487.pList ){ + yymsp[-4].minor.yy487.pSelect = sqlite3SelectNew(pParse, yymsp[-4].minor.yy487.pList, 0, 0, 0, 0, 0, 0, 0, 0); + yymsp[-4].minor.yy487.pList = 0; + } + yygotominor.yy487.pList = 0; + if( yymsp[-4].minor.yy487.pSelect==0 || pRight==0 ){ + sqlite3SelectDelete(pParse->db, pRight); + sqlite3SelectDelete(pParse->db, yymsp[-4].minor.yy487.pSelect); + yygotominor.yy487.pSelect = 0; + }else{ + pRight->op = TK_ALL; + pRight->pPrior = yymsp[-4].minor.yy487.pSelect; + pRight->selFlags |= SF_Values; + pRight->pPrior->selFlags |= SF_Values; + yygotominor.yy487.pSelect = pRight; + } +} + break; + case 181: /* inscollist ::= inscollist COMMA nm */ +{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy180,&yymsp[0].minor.yy0);} + break; + case 182: /* inscollist ::= nm */ +{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);} + break; + case 183: /* expr ::= term */ +{yygotominor.yy342 = yymsp[0].minor.yy342;} + break; + case 184: /* expr ::= LP expr RP */ +{yygotominor.yy342.pExpr = yymsp[-1].minor.yy342.pExpr; spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);} + break; + case 185: /* term ::= NULL */ + case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190); + case 191: /* term ::= STRING */ yytestcase(yyruleno==191); +{spanExpr(&yygotominor.yy342, pParse, yymsp[0].major, &yymsp[0].minor.yy0);} + break; + case 186: /* expr ::= id */ + case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187); +{spanExpr(&yygotominor.yy342, pParse, TK_ID, &yymsp[0].minor.yy0);} + break; + case 188: /* expr ::= nm DOT nm */ { Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0); - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); - spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); + spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } break; - case 190: /* expr ::= nm DOT nm DOT nm */ + case 189: /* expr ::= nm DOT nm DOT nm */ { Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0); Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0); Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0); - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); - spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); + spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); } break; - case 193: /* expr ::= REGISTER */ + case 192: /* expr ::= REGISTER */ { /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers ** in the virtual machine. #N is the N-th register. */ if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0); - yygotominor.yy118.pExpr = 0; - }else{ - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0); - if( yygotominor.yy118.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy118.pExpr->iTable); - } - spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); -} - break; - case 194: /* expr ::= VARIABLE */ -{ - spanExpr(&yygotominor.yy118, pParse, TK_VARIABLE, &yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yygotominor.yy118.pExpr); - spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); -} - break; - case 195: /* expr ::= expr COLLATE ids */ -{ - yygotominor.yy118.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy118.pExpr, &yymsp[0].minor.yy0); - yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart; - yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; -} - break; - case 196: /* expr ::= CAST LP expr AS typetoken RP */ -{ - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy118.pExpr, 0, &yymsp[-1].minor.yy0); - spanSet(&yygotominor.yy118,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); -} - break; - case 197: /* expr ::= ID LP distinct exprlist RP */ -{ - if( yymsp[-1].minor.yy322 && yymsp[-1].minor.yy322->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ + yygotominor.yy342.pExpr = 0; + }else{ + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0); + if( yygotominor.yy342.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy342.pExpr->iTable); + } + spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); +} + break; + case 193: /* expr ::= VARIABLE */ +{ + spanExpr(&yygotominor.yy342, pParse, TK_VARIABLE, &yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yygotominor.yy342.pExpr); + spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); +} + break; + case 194: /* expr ::= expr COLLATE ids */ +{ + yygotominor.yy342.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0); + yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart; + yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} + break; + case 195: /* expr ::= CAST LP expr AS typetoken RP */ +{ + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy342.pExpr, 0, &yymsp[-1].minor.yy0); + spanSet(&yygotominor.yy342,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); +} + break; + case 196: /* expr ::= ID LP distinct exprlist RP */ +{ + if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); } - yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); - spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); - if( yymsp[-2].minor.yy4 && yygotominor.yy118.pExpr ){ - yygotominor.yy118.pExpr->flags |= EP_Distinct; - } -} - break; - case 198: /* expr ::= ID LP STAR RP */ -{ - yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); - spanSet(&yygotominor.yy118,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); -} - break; - case 199: /* term ::= CTIME_KW */ + yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0); + spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); + if( yymsp[-2].minor.yy392 && yygotominor.yy342.pExpr ){ + yygotominor.yy342.pExpr->flags |= EP_Distinct; + } +} + break; + case 197: /* expr ::= ID LP STAR RP */ +{ + yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); + spanSet(&yygotominor.yy342,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); +} + break; + case 198: /* term ::= CTIME_KW */ { /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are ** treated as functions that return constants */ - yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0); - if( yygotominor.yy118.pExpr ){ - yygotominor.yy118.pExpr->op = TK_CONST_FUNC; - } - spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); -} - break; - case 200: /* expr ::= expr AND expr */ - case 201: /* expr ::= expr OR expr */ yytestcase(yyruleno==201); - case 202: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==202); - case 203: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==203); - case 204: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==204); - case 205: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==205); - case 206: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==206); - case 207: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==207); -{spanBinaryExpr(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);} - break; - case 208: /* likeop ::= LIKE_KW */ - case 210: /* likeop ::= MATCH */ yytestcase(yyruleno==210); -{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.not = 0;} - break; - case 209: /* likeop ::= NOT LIKE_KW */ - case 211: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==211); -{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.not = 1;} - break; - case 212: /* expr ::= expr likeop expr */ -{ - ExprList *pList; - pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy118.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy118.pExpr); - yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy342.eOperator); - if( yymsp[-1].minor.yy342.not ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); - yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart; - yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd; - if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc; -} - break; - case 213: /* expr ::= expr likeop expr ESCAPE expr */ -{ - ExprList *pList; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy118.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr); - yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy342.eOperator); - if( yymsp[-3].minor.yy342.not ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); - yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; - yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd; - if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc; -} - break; - case 214: /* expr ::= expr ISNULL|NOTNULL */ -{spanUnaryPostfix(&yygotominor.yy118,pParse,yymsp[0].major,&yymsp[-1].minor.yy118,&yymsp[0].minor.yy0);} - break; - case 215: /* expr ::= expr NOT NULL */ -{spanUnaryPostfix(&yygotominor.yy118,pParse,TK_NOTNULL,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy0);} - break; - case 216: /* expr ::= expr IS expr */ -{ - spanBinaryExpr(&yygotominor.yy118,pParse,TK_IS,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_ISNULL); -} - break; - case 217: /* expr ::= expr IS NOT expr */ -{ - spanBinaryExpr(&yygotominor.yy118,pParse,TK_ISNOT,&yymsp[-3].minor.yy118,&yymsp[0].minor.yy118); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_NOTNULL); -} - break; - case 218: /* expr ::= NOT expr */ - case 219: /* expr ::= BITNOT expr */ yytestcase(yyruleno==219); -{spanUnaryPrefix(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);} - break; - case 220: /* expr ::= MINUS expr */ -{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UMINUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);} - break; - case 221: /* expr ::= PLUS expr */ -{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UPLUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);} - break; - case 224: /* expr ::= expr between_op expr AND expr */ -{ - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr); - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy118.pExpr, 0, 0); - if( yygotominor.yy118.pExpr ){ - yygotominor.yy118.pExpr->x.pList = pList; + yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0); + if( yygotominor.yy342.pExpr ){ + yygotominor.yy342.pExpr->op = TK_CONST_FUNC; + } + spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); +} + break; + case 199: /* expr ::= expr AND expr */ + case 200: /* expr ::= expr OR expr */ yytestcase(yyruleno==200); + case 201: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==201); + case 202: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==202); + case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==203); + case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204); + case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205); + case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206); +{spanBinaryExpr(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);} + break; + case 207: /* likeop ::= LIKE_KW */ + case 209: /* likeop ::= MATCH */ yytestcase(yyruleno==209); +{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.not = 0;} + break; + case 208: /* likeop ::= NOT LIKE_KW */ + case 210: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==210); +{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.not = 1;} + break; + case 211: /* expr ::= expr likeop expr */ +{ + ExprList *pList; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy342.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy342.pExpr); + yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy318.eOperator); + if( yymsp[-1].minor.yy318.not ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); + yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart; + yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd; + if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc; +} + break; + case 212: /* expr ::= expr likeop expr ESCAPE expr */ +{ + ExprList *pList; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy342.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr); + yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy318.eOperator); + if( yymsp[-3].minor.yy318.not ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); + yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart; + yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd; + if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc; +} + break; + case 213: /* expr ::= expr ISNULL|NOTNULL */ +{spanUnaryPostfix(&yygotominor.yy342,pParse,yymsp[0].major,&yymsp[-1].minor.yy342,&yymsp[0].minor.yy0);} + break; + case 214: /* expr ::= expr NOT NULL */ +{spanUnaryPostfix(&yygotominor.yy342,pParse,TK_NOTNULL,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy0);} + break; + case 215: /* expr ::= expr IS expr */ +{ + spanBinaryExpr(&yygotominor.yy342,pParse,TK_IS,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_ISNULL); +} + break; + case 216: /* expr ::= expr IS NOT expr */ +{ + spanBinaryExpr(&yygotominor.yy342,pParse,TK_ISNOT,&yymsp[-3].minor.yy342,&yymsp[0].minor.yy342); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_NOTNULL); +} + break; + case 217: /* expr ::= NOT expr */ + case 218: /* expr ::= BITNOT expr */ yytestcase(yyruleno==218); +{spanUnaryPrefix(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);} + break; + case 219: /* expr ::= MINUS expr */ +{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UMINUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);} + break; + case 220: /* expr ::= PLUS expr */ +{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UPLUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);} + break; + case 223: /* expr ::= expr between_op expr AND expr */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr); + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy342.pExpr, 0, 0); + if( yygotominor.yy342.pExpr ){ + yygotominor.yy342.pExpr->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); - yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; - yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd; -} - break; - case 227: /* expr ::= expr in_op LP exprlist RP */ -{ - if( yymsp[-1].minor.yy322==0 ){ + if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); + yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart; + yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd; +} + break; + case 226: /* expr ::= expr in_op LP exprlist RP */ +{ + if( yymsp[-1].minor.yy442==0 ){ /* Expressions of the form ** ** expr1 IN () ** expr1 NOT IN () ** ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy4]); - sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy118.pExpr); - }else{ - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0); - if( yygotominor.yy118.pExpr ){ - yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy322; - sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); - }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); - } - if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); - } - yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; - yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; - } - break; - case 228: /* expr ::= LP select RP */ -{ - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); - if( yygotominor.yy118.pExpr ){ - yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387; - ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); - }else{ - sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387); - } - yygotominor.yy118.zStart = yymsp[-2].minor.yy0.z; - yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; - } - break; - case 229: /* expr ::= expr in_op LP select RP */ -{ - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0); - if( yygotominor.yy118.pExpr ){ - yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387; - ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); - }else{ - sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387); - } - if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); - yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart; - yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; - } - break; - case 230: /* expr ::= expr in_op nm dbnm */ + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy392]); + sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy342.pExpr); + }else{ + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0); + if( yygotominor.yy342.pExpr ){ + yygotominor.yy342.pExpr->x.pList = yymsp[-1].minor.yy442; + sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr); + }else{ + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy442); + } + if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); + } + yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart; + yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } + break; + case 227: /* expr ::= LP select RP */ +{ + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); + if( yygotominor.yy342.pExpr ){ + yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159; + ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr); + }else{ + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159); + } + yygotominor.yy342.zStart = yymsp[-2].minor.yy0.z; + yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } + break; + case 228: /* expr ::= expr in_op LP select RP */ +{ + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0); + if( yygotominor.yy342.pExpr ){ + yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159; + ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr); + }else{ + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159); + } + if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); + yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart; + yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } + break; + case 229: /* expr ::= expr in_op nm dbnm */ { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy118.pExpr, 0, 0); - if( yygotominor.yy118.pExpr ){ - yygotominor.yy118.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); - ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy342.pExpr, 0, 0); + if( yygotominor.yy342.pExpr ){ + yygotominor.yy342.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); + ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr); }else{ sqlite3SrcListDelete(pParse->db, pSrc); } - if( yymsp[-2].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0); - yygotominor.yy118.zStart = yymsp[-3].minor.yy118.zStart; - yygotominor.yy118.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]; - } - break; - case 231: /* expr ::= EXISTS LP select RP */ -{ - Expr *p = yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); + if( yymsp[-2].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); + yygotominor.yy342.zStart = yymsp[-3].minor.yy342.zStart; + yygotominor.yy342.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]; + } + break; + case 230: /* expr ::= EXISTS LP select RP */ +{ + Expr *p = yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); if( p ){ - p->x.pSelect = yymsp[-1].minor.yy387; + p->x.pSelect = yymsp[-1].minor.yy159; ExprSetProperty(p, EP_xIsSelect); sqlite3ExprSetHeight(pParse, p); }else{ - sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387); - } - yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z; - yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; - } - break; - case 232: /* expr ::= CASE case_operand case_exprlist case_else END */ -{ - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy314, yymsp[-1].minor.yy314, 0); - if( yygotominor.yy118.pExpr ){ - yygotominor.yy118.pExpr->x.pList = yymsp[-2].minor.yy322; - sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr); - }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322); - } - yygotominor.yy118.zStart = yymsp[-4].minor.yy0.z; - yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; -} - break; - case 233: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ -{ - yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy118.pExpr); - yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr); -} - break; - case 234: /* case_exprlist ::= WHEN expr THEN expr */ -{ - yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr); - yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr); -} - break; - case 243: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */ + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159); + } + yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z; + yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } + break; + case 231: /* expr ::= CASE case_operand case_exprlist case_else END */ +{ + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy122, yymsp[-1].minor.yy122, 0); + if( yygotominor.yy342.pExpr ){ + yygotominor.yy342.pExpr->x.pList = yymsp[-2].minor.yy442; + sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr); + }else{ + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy442); + } + yygotominor.yy342.zStart = yymsp[-4].minor.yy0.z; + yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} + break; + case 232: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ +{ + yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, yymsp[-2].minor.yy342.pExpr); + yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr); +} + break; + case 233: /* case_exprlist ::= WHEN expr THEN expr */ +{ + yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr); + yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr); +} + break; + case 240: /* nexprlist ::= nexprlist COMMA expr */ +{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);} + break; + case 241: /* nexprlist ::= expr */ +{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);} + break; + case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */ { sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, - sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy322, yymsp[-9].minor.yy4, - &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy4); + sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy442, yymsp[-9].minor.yy392, + &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy392); } break; - case 244: /* uniqueflag ::= UNIQUE */ - case 298: /* raisetype ::= ABORT */ yytestcase(yyruleno==298); -{yygotominor.yy4 = OE_Abort;} - break; - case 245: /* uniqueflag ::= */ -{yygotominor.yy4 = OE_None;} - break; - case 248: /* idxlist ::= idxlist COMMA nm collate sortorder */ + case 243: /* uniqueflag ::= UNIQUE */ + case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296); +{yygotominor.yy392 = OE_Abort;} + break; + case 244: /* uniqueflag ::= */ +{yygotominor.yy392 = OE_None;} + break; + case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */ { Expr *p = 0; if( yymsp[-1].minor.yy0.n>0 ){ p = sqlite3Expr(pParse->db, TK_COLUMN, 0); sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0); } - yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, p); - sqlite3ExprListSetName(pParse,yygotominor.yy322,&yymsp[-2].minor.yy0,1); - sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index"); - if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4; + yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p); + sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1); + sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index"); + if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392; } break; - case 249: /* idxlist ::= nm collate sortorder */ + case 248: /* idxlist ::= nm collate sortorder */ { Expr *p = 0; if( yymsp[-1].minor.yy0.n>0 ){ p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0); } - yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, p); - sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1); - sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index"); - if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4; + yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p); + sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1); + sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index"); + if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392; } break; - case 250: /* collate ::= */ + case 249: /* collate ::= */ {yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;} break; - case 252: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy259, yymsp[-1].minor.yy4);} + case 251: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy347, yymsp[-1].minor.yy392);} break; - case 253: /* cmd ::= VACUUM */ - case 254: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==254); + case 252: /* cmd ::= VACUUM */ + case 253: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==253); {sqlite3Vacuum(pParse);} break; - case 255: /* cmd ::= PRAGMA nm dbnm */ + case 254: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 256: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 255: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 257: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 256: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 258: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 257: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 259: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 258: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; - case 270: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 268: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy203, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy327, &all); } break; - case 271: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 269: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy4, yymsp[-4].minor.yy90.a, yymsp[-4].minor.yy90.b, yymsp[-2].minor.yy259, yymsp[0].minor.yy314, yymsp[-10].minor.yy4, yymsp[-8].minor.yy4); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy392, yymsp[-4].minor.yy410.a, yymsp[-4].minor.yy410.b, yymsp[-2].minor.yy347, yymsp[0].minor.yy122, yymsp[-10].minor.yy392, yymsp[-8].minor.yy392); yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); } break; - case 272: /* trigger_time ::= BEFORE */ - case 275: /* trigger_time ::= */ yytestcase(yyruleno==275); -{ yygotominor.yy4 = TK_BEFORE; } - break; - case 273: /* trigger_time ::= AFTER */ -{ yygotominor.yy4 = TK_AFTER; } - break; - case 274: /* trigger_time ::= INSTEAD OF */ -{ yygotominor.yy4 = TK_INSTEAD;} - break; - case 276: /* trigger_event ::= DELETE|INSERT */ - case 277: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==277); -{yygotominor.yy90.a = yymsp[0].major; yygotominor.yy90.b = 0;} - break; - case 278: /* trigger_event ::= UPDATE OF inscollist */ -{yygotominor.yy90.a = TK_UPDATE; yygotominor.yy90.b = yymsp[0].minor.yy384;} - break; - case 281: /* when_clause ::= */ - case 303: /* key_opt ::= */ yytestcase(yyruleno==303); -{ yygotominor.yy314 = 0; } - break; - case 282: /* when_clause ::= WHEN expr */ - case 304: /* key_opt ::= KEY expr */ yytestcase(yyruleno==304); -{ yygotominor.yy314 = yymsp[0].minor.yy118.pExpr; } - break; - case 283: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ -{ - assert( yymsp[-2].minor.yy203!=0 ); - yymsp[-2].minor.yy203->pLast->pNext = yymsp[-1].minor.yy203; - yymsp[-2].minor.yy203->pLast = yymsp[-1].minor.yy203; - yygotominor.yy203 = yymsp[-2].minor.yy203; -} - break; - case 284: /* trigger_cmd_list ::= trigger_cmd SEMI */ -{ - assert( yymsp[-1].minor.yy203!=0 ); - yymsp[-1].minor.yy203->pLast = yymsp[-1].minor.yy203; - yygotominor.yy203 = yymsp[-1].minor.yy203; -} - break; - case 286: /* trnm ::= nm DOT nm */ + case 270: /* trigger_time ::= BEFORE */ + case 273: /* trigger_time ::= */ yytestcase(yyruleno==273); +{ yygotominor.yy392 = TK_BEFORE; } + break; + case 271: /* trigger_time ::= AFTER */ +{ yygotominor.yy392 = TK_AFTER; } + break; + case 272: /* trigger_time ::= INSTEAD OF */ +{ yygotominor.yy392 = TK_INSTEAD;} + break; + case 274: /* trigger_event ::= DELETE|INSERT */ + case 275: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==275); +{yygotominor.yy410.a = yymsp[0].major; yygotominor.yy410.b = 0;} + break; + case 276: /* trigger_event ::= UPDATE OF inscollist */ +{yygotominor.yy410.a = TK_UPDATE; yygotominor.yy410.b = yymsp[0].minor.yy180;} + break; + case 279: /* when_clause ::= */ + case 301: /* key_opt ::= */ yytestcase(yyruleno==301); +{ yygotominor.yy122 = 0; } + break; + case 280: /* when_clause ::= WHEN expr */ + case 302: /* key_opt ::= KEY expr */ yytestcase(yyruleno==302); +{ yygotominor.yy122 = yymsp[0].minor.yy342.pExpr; } + break; + case 281: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ +{ + assert( yymsp[-2].minor.yy327!=0 ); + yymsp[-2].minor.yy327->pLast->pNext = yymsp[-1].minor.yy327; + yymsp[-2].minor.yy327->pLast = yymsp[-1].minor.yy327; + yygotominor.yy327 = yymsp[-2].minor.yy327; +} + break; + case 282: /* trigger_cmd_list ::= trigger_cmd SEMI */ +{ + assert( yymsp[-1].minor.yy327!=0 ); + yymsp[-1].minor.yy327->pLast = yymsp[-1].minor.yy327; + yygotominor.yy327 = yymsp[-1].minor.yy327; +} + break; + case 284: /* trnm ::= nm DOT nm */ { yygotominor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, "qualified table names are not allowed on INSERT, UPDATE, and DELETE " "statements within triggers"); } break; - case 288: /* tridxby ::= INDEXED BY nm */ + case 286: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 289: /* tridxby ::= NOT INDEXED */ + case 287: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 290: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */ -{ yygotominor.yy203 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy322, yymsp[0].minor.yy314, yymsp[-5].minor.yy210); } - break; - case 291: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP */ -{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy384, yymsp[-1].minor.yy322, 0, yymsp[-7].minor.yy210);} - break; - case 292: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */ -{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy384, 0, yymsp[0].minor.yy387, yymsp[-4].minor.yy210);} - break; - case 293: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */ -{yygotominor.yy203 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy314);} - break; - case 294: /* trigger_cmd ::= select */ -{yygotominor.yy203 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy387); } - break; - case 295: /* expr ::= RAISE LP IGNORE RP */ -{ - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); - if( yygotominor.yy118.pExpr ){ - yygotominor.yy118.pExpr->affinity = OE_Ignore; - } - yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z; - yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; -} - break; - case 296: /* expr ::= RAISE LP raisetype COMMA nm RP */ -{ - yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); - if( yygotominor.yy118.pExpr ) { - yygotominor.yy118.pExpr->affinity = (char)yymsp[-3].minor.yy4; - } - yygotominor.yy118.zStart = yymsp[-5].minor.yy0.z; - yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; -} - break; - case 297: /* raisetype ::= ROLLBACK */ -{yygotominor.yy4 = OE_Rollback;} - break; - case 299: /* raisetype ::= FAIL */ -{yygotominor.yy4 = OE_Fail;} - break; - case 300: /* cmd ::= DROP TRIGGER ifexists fullname */ -{ - sqlite3DropTrigger(pParse,yymsp[0].minor.yy259,yymsp[-1].minor.yy4); -} - break; - case 301: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ -{ - sqlite3Attach(pParse, yymsp[-3].minor.yy118.pExpr, yymsp[-1].minor.yy118.pExpr, yymsp[0].minor.yy314); -} - break; - case 302: /* cmd ::= DETACH database_kw_opt expr */ -{ - sqlite3Detach(pParse, yymsp[0].minor.yy118.pExpr); -} - break; - case 307: /* cmd ::= REINDEX */ + case 288: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */ +{ yygotominor.yy327 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy442, yymsp[0].minor.yy122, yymsp[-5].minor.yy258); } + break; + case 289: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist */ +{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-4].minor.yy258);} + break; + case 290: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */ +{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, 0, yymsp[0].minor.yy159, yymsp[-4].minor.yy258);} + break; + case 291: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */ +{yygotominor.yy327 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy122);} + break; + case 292: /* trigger_cmd ::= select */ +{yygotominor.yy327 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy159); } + break; + case 293: /* expr ::= RAISE LP IGNORE RP */ +{ + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); + if( yygotominor.yy342.pExpr ){ + yygotominor.yy342.pExpr->affinity = OE_Ignore; + } + yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z; + yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} + break; + case 294: /* expr ::= RAISE LP raisetype COMMA nm RP */ +{ + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); + if( yygotominor.yy342.pExpr ) { + yygotominor.yy342.pExpr->affinity = (char)yymsp[-3].minor.yy392; + } + yygotominor.yy342.zStart = yymsp[-5].minor.yy0.z; + yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} + break; + case 295: /* raisetype ::= ROLLBACK */ +{yygotominor.yy392 = OE_Rollback;} + break; + case 297: /* raisetype ::= FAIL */ +{yygotominor.yy392 = OE_Fail;} + break; + case 298: /* cmd ::= DROP TRIGGER ifexists fullname */ +{ + sqlite3DropTrigger(pParse,yymsp[0].minor.yy347,yymsp[-1].minor.yy392); +} + break; + case 299: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ +{ + sqlite3Attach(pParse, yymsp[-3].minor.yy342.pExpr, yymsp[-1].minor.yy342.pExpr, yymsp[0].minor.yy122); +} + break; + case 300: /* cmd ::= DETACH database_kw_opt expr */ +{ + sqlite3Detach(pParse, yymsp[0].minor.yy342.pExpr); +} + break; + case 305: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 308: /* cmd ::= REINDEX nm dbnm */ + case 306: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 309: /* cmd ::= ANALYZE */ + case 307: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 310: /* cmd ::= ANALYZE nm dbnm */ + case 308: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 311: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 309: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy259,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy347,&yymsp[0].minor.yy0); } break; - case 312: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */ + case 310: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */ { sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0); } break; - case 313: /* add_column_fullname ::= fullname */ + case 311: /* add_column_fullname ::= fullname */ { pParse->db->lookaside.bEnabled = 0; - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy259); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy347); } break; - case 316: /* cmd ::= create_vtab */ + case 314: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 317: /* cmd ::= create_vtab LP vtabarglist RP */ + case 315: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 318: /* create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm */ + case 316: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ { - sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy392); } break; - case 321: /* vtabarg ::= */ + case 319: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 323: /* vtabargtoken ::= ANY */ - case 324: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==324); - case 325: /* lp ::= LP */ yytestcase(yyruleno==325); + case 321: /* vtabargtoken ::= ANY */ + case 322: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==322); + case 323: /* lp ::= LP */ yytestcase(yyruleno==323); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; default: /* (0) input ::= cmdlist */ yytestcase(yyruleno==0); /* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1); @@ -110741,25 +110986,23 @@ /* (62) ccons ::= NULL onconf */ yytestcase(yyruleno==62); /* (90) conslist ::= conslist COMMA tcons */ yytestcase(yyruleno==90); /* (91) conslist ::= conslist tcons */ yytestcase(yyruleno==91); /* (92) conslist ::= tcons */ yytestcase(yyruleno==92); /* (93) tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==93); - /* (268) plus_opt ::= PLUS */ yytestcase(yyruleno==268); - /* (269) plus_opt ::= */ yytestcase(yyruleno==269); - /* (279) foreach_clause ::= */ yytestcase(yyruleno==279); - /* (280) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==280); - /* (287) tridxby ::= */ yytestcase(yyruleno==287); - /* (305) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==305); - /* (306) database_kw_opt ::= */ yytestcase(yyruleno==306); - /* (314) kwcolumn_opt ::= */ yytestcase(yyruleno==314); - /* (315) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==315); - /* (319) vtabarglist ::= vtabarg */ yytestcase(yyruleno==319); - /* (320) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==320); - /* (322) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==322); - /* (326) anylist ::= */ yytestcase(yyruleno==326); - /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327); - /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328); + /* (277) foreach_clause ::= */ yytestcase(yyruleno==277); + /* (278) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==278); + /* (285) tridxby ::= */ yytestcase(yyruleno==285); + /* (303) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==303); + /* (304) database_kw_opt ::= */ yytestcase(yyruleno==304); + /* (312) kwcolumn_opt ::= */ yytestcase(yyruleno==312); + /* (313) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==313); + /* (317) vtabarglist ::= vtabarg */ yytestcase(yyruleno==317); + /* (318) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==318); + /* (320) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==320); + /* (324) anylist ::= */ yytestcase(yyruleno==324); + /* (325) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==325); + /* (326) anylist ::= anylist ANY */ yytestcase(yyruleno==326); break; }; yygoto = yyRuleInfo[yyruleno].lhs; yysize = yyRuleInfo[yyruleno].nrhs; yypParser->yyidx -= yysize; @@ -113040,23 +113283,27 @@ sqlite3_free(db); return SQLITE_OK; } /* -** Rollback all database files. +** Rollback all database files. If tripCode is not SQLITE_OK, then +** any open cursors are invalidated ("tripped" - as in "tripping a circuit +** breaker") and made to return tripCode if there are any further +** attempts to use that cursor. */ -SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db){ +SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ int i; int inTrans = 0; assert( sqlite3_mutex_held(db->mutex) ); sqlite3BeginBenignMalloc(); for(i=0; inDb; i++){ - if( db->aDb[i].pBt ){ - if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){ + Btree *p = db->aDb[i].pBt; + if( p ){ + if( sqlite3BtreeIsInTrans(p) ){ inTrans = 1; } - sqlite3BtreeRollback(db->aDb[i].pBt); + sqlite3BtreeRollback(p, tripCode); db->aDb[i].inTrans = 0; } } sqlite3VtabRollback(db); sqlite3EndBenignMalloc(); @@ -113107,16 +113354,25 @@ /* SQLITE_AUTH */ "authorization denied", /* SQLITE_FORMAT */ "auxiliary database format error", /* SQLITE_RANGE */ "bind or column index out of range", /* SQLITE_NOTADB */ "file is encrypted or is not a database", }; - rc &= 0xff; - if( ALWAYS(rc>=0) && rc<(int)(sizeof(aMsg)/sizeof(aMsg[0])) && aMsg[rc]!=0 ){ - return aMsg[rc]; - }else{ - return "unknown error"; + const char *zErr = "unknown error"; + switch( rc ){ + case SQLITE_ABORT_ROLLBACK: { + zErr = "abort due to ROLLBACK"; + break; + } + default: { + rc &= 0xff; + if( ALWAYS(rc>=0) && rcmutex); return pOld; } #endif /* SQLITE_OMIT_TRACE */ -/*** EXPERIMENTAL *** -** -** Register a function to be invoked when a transaction comments. +/* +** Register a function to be invoked when a transaction commits. ** If the invoked function returns non-zero, then the commit becomes a ** rollback. */ SQLITE_API void *sqlite3_commit_hook( sqlite3 *db, /* Attach the hook to this database */ @@ -114883,39 +115138,31 @@ /* ** Invoke the xFileControl method on a particular database. */ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ int rc = SQLITE_ERROR; - int iDb; + Btree *pBtree; + sqlite3_mutex_enter(db->mutex); - if( zDbName==0 ){ - iDb = 0; - }else{ - for(iDb=0; iDbnDb; iDb++){ - if( strcmp(db->aDb[iDb].zName, zDbName)==0 ) break; - } - } - if( iDbnDb ){ - Btree *pBtree = db->aDb[iDb].pBt; - if( pBtree ){ - Pager *pPager; - sqlite3_file *fd; - sqlite3BtreeEnter(pBtree); - pPager = sqlite3BtreePager(pBtree); - assert( pPager!=0 ); - fd = sqlite3PagerFile(pPager); - assert( fd!=0 ); - if( op==SQLITE_FCNTL_FILE_POINTER ){ - *(sqlite3_file**)pArg = fd; - rc = SQLITE_OK; - }else if( fd->pMethods ){ - rc = sqlite3OsFileControl(fd, op, pArg); - }else{ - rc = SQLITE_NOTFOUND; - } - sqlite3BtreeLeave(pBtree); - } + pBtree = sqlite3DbNameToBtree(db, zDbName); + if( pBtree ){ + Pager *pPager; + sqlite3_file *fd; + sqlite3BtreeEnter(pBtree); + pPager = sqlite3BtreePager(pBtree); + assert( pPager!=0 ); + fd = sqlite3PagerFile(pPager); + assert( fd!=0 ); + if( op==SQLITE_FCNTL_FILE_POINTER ){ + *(sqlite3_file**)pArg = fd; + rc = SQLITE_OK; + }else if( fd->pMethods ){ + rc = sqlite3OsFileControl(fd, op, pArg); + }else{ + rc = SQLITE_NOTFOUND; + } + sqlite3BtreeLeave(pBtree); } sqlite3_mutex_leave(db->mutex); return rc; } @@ -115186,11 +115433,12 @@ /* ** Return a boolean value for a query parameter. */ SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ const char *z = sqlite3_uri_parameter(zFilename, zParam); - return z ? sqlite3GetBoolean(z) : (bDflt!=0); + bDflt = bDflt!=0; + return z ? sqlite3GetBoolean(z, bDflt) : bDflt; } /* ** Return a 64-bit integer value for a query parameter. */ @@ -115204,23 +115452,42 @@ if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ bDflt = v; } return bDflt; } + +/* +** Return the Btree pointer identified by zDbName. Return NULL if not found. +*/ +SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ + int i; + for(i=0; inDb; i++){ + if( db->aDb[i].pBt + && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zName)==0) + ){ + return db->aDb[i].pBt; + } + } + return 0; +} /* ** Return the filename of the database associated with a database ** connection. */ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ - int i; - for(i=0; inDb; i++){ - if( db->aDb[i].pBt && sqlite3StrICmp(zDbName, db->aDb[i].zName)==0 ){ - return sqlite3BtreeGetFilename(db->aDb[i].pBt); - } - } - return 0; + Btree *pBt = sqlite3DbNameToBtree(db, zDbName); + return pBt ? sqlite3BtreeGetFilename(pBt) : 0; +} + +/* +** Return 1 if database is read-only or 0 if read/write. Return -1 if +** no such database exists. +*/ +SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ + Btree *pBt = sqlite3DbNameToBtree(db, zDbName); + return pBt ? sqlite3PagerIsreadonly(sqlite3BtreePager(pBt)) : -1; } /************** End of main.c ************************************************/ /************** Begin file notify.c ******************************************/ /* @@ -115842,14 +116109,10 @@ ** we simply write the new doclist. Segment merges overwrite older ** data for a particular docid with newer data, so deletes or updates ** will eventually overtake the earlier data and knock it out. The ** query logic likewise merges doclists so that newer data knocks out ** older data. -** -** TODO(shess) Provide a VACUUM type operation to clear out all -** deletions and duplications. This would basically be a forced merge -** into a single segment. */ /************** Include fts3Int.h in the middle of fts3.c ********************/ /************** Begin file fts3Int.h *****************************************/ /* @@ -115941,11 +116204,11 @@ typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; struct sqlite3_tokenizer_module { /* - ** Structure version. Should always be set to 0. + ** Structure version. Should always be set to 0 or 1. */ int iVersion; /* ** Create a new tokenizer. The values in the argv[] array are the @@ -116022,10 +116285,19 @@ const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ int *piStartOffset, /* OUT: Byte offset of token in input buffer */ int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ int *piPosition /* OUT: Number of tokens returned before this one */ ); + + /*********************************************************************** + ** Methods below this point are only available if iVersion>=1. + */ + + /* + ** Configure the language id of a tokenizer cursor. + */ + int (*xLanguageid)(sqlite3_tokenizer_cursor *pCsr, int iLangid); }; struct sqlite3_tokenizer { const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ /* Tokenizer implementations will typically add additional fields */ @@ -116313,15 +116585,16 @@ const char *zName; /* virtual table name */ int nColumn; /* number of named columns in virtual table */ char **azColumn; /* column names. malloced */ sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ char *zContentTbl; /* content=xxx option, or NULL */ + char *zLanguageid; /* languageid=xxx option, or NULL */ /* Precompiled statements used by the implementation. Each of these ** statements is run and reset within a single virtual table API call. */ - sqlite3_stmt *aStmt[27]; + sqlite3_stmt *aStmt[28]; char *zReadExprlist; char *zWriteExprlist; int nNodeSize; /* Soft limit for node size */ @@ -116332,16 +116605,16 @@ char *zSegmentsTbl; /* Name of %_segments table */ sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ /* TODO: Fix the first paragraph of this comment. ** - ** The following hash table is used to buffer pending index updates during - ** transactions. Variable nPendingData estimates the memory size of the - ** pending data, including hash table overhead, but not malloc overhead. - ** When nPendingData exceeds nMaxPendingData, the buffer is flushed - ** automatically. Variable iPrevDocid is the docid of the most recently - ** inserted record. + ** The following array of hash tables is used to buffer pending index + ** updates during transactions. Variable nPendingData estimates the memory + ** size of the pending data, including hash table overhead, not including + ** malloc overhead. When nPendingData exceeds nMaxPendingData, the buffer + ** is flushed automatically. Variable iPrevDocid is the docid of the most + ** recently inserted record. ** ** A single FTS4 table may have multiple full-text indexes. For each index ** there is an entry in the aIndex[] array. Index 0 is an index of all the ** terms that appear in the document set. Each subsequent index in aIndex[] ** is an index of prefixes of a specific length. @@ -116352,16 +116625,17 @@ Fts3Hash hPending; /* Pending terms table for this index */ } *aIndex; int nMaxPendingData; /* Max pending data before flush to disk */ int nPendingData; /* Current bytes of pending data */ sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */ + int iPrevLangid; /* Langid of recently inserted document */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) /* State variables used for validating that the transaction control ** methods of the virtual table are called at appropriate times. These - ** values do not contribution to the FTS computation; they are used for - ** verifying the SQLite core. + ** values do not contribute to FTS functionality; they are used for + ** verifying the operation of the SQLite core. */ int inTransaction; /* True after xBegin but before xCommit/xRollback */ int mxSavepoint; /* Largest valid xSavepoint integer */ #endif }; @@ -116376,10 +116650,11 @@ i16 eSearch; /* Search strategy (see below) */ u8 isEof; /* True if at End Of Results */ u8 isRequireSeek; /* True if must seek pStmt to %_content row */ sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ Fts3Expr *pExpr; /* Parsed MATCH query string */ + int iLangid; /* Language being queried for */ int nPhrase; /* Number of matchable phrases in query */ Fts3DeferredToken *pDeferred; /* Deferred search tokens, if any */ sqlite3_int64 iPrevId; /* Previous id read from aDoclist */ char *pNextId; /* Pointer into the body of aDoclist */ char *aDoclist; /* List of docids for full-text queries */ @@ -116522,16 +116797,16 @@ /* fts3_write.c */ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*); SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *); SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *); SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *); -SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(int, sqlite3_int64, +SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(int, int, sqlite3_int64, sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**); SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( Fts3Table*,int,const char*,int,int,Fts3SegReader**); SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *); -SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, sqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **); SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *); SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*); SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **); SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); @@ -116548,12 +116823,12 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(Fts3Table*, Fts3MultiSegReader*, Fts3SegFilter*); SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(Fts3Table *, Fts3MultiSegReader *); SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish(Fts3MultiSegReader *); -SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor( - Fts3Table *, int, int, const char *, int, int, int, Fts3MultiSegReader *); +SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor(Fts3Table *, + int, int, int, const char *, int, int, int, Fts3MultiSegReader *); /* Flags allowed as part of the 4th argument to SegmentReaderIterate() */ #define FTS3_SEGMENT_REQUIRE_POS 0x00000001 #define FTS3_SEGMENT_IGNORE_EMPTY 0x00000002 #define FTS3_SEGMENT_COLUMN_FILTER 0x00000004 @@ -116616,18 +116891,22 @@ const char *, const char *, int, int ); SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *); /* fts3_expr.c */ -SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, +SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int, char **, int, int, int, const char *, int, Fts3Expr ** ); SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *); #ifdef SQLITE_TEST SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db); SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db); #endif + +SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int, + sqlite3_tokenizer_cursor ** +); /* fts3_aux.c */ SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db); SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *); @@ -116819,10 +117098,11 @@ } sqlite3_free(p->zSegmentsTbl); sqlite3_free(p->zReadExprlist); sqlite3_free(p->zWriteExprlist); sqlite3_free(p->zContentTbl); + sqlite3_free(p->zLanguageid); /* Invoke the tokenizer destructor to free the tokenizer. */ p->pTokenizer->pModule->xDestroy(p->pTokenizer); sqlite3_free(p); @@ -116895,11 +117175,13 @@ if( *pRc==SQLITE_OK ){ int i; /* Iterator variable */ int rc; /* Return code */ char *zSql; /* SQL statement passed to declare_vtab() */ char *zCols; /* List of user defined columns */ + const char *zLanguageid; + zLanguageid = (p->zLanguageid ? p->zLanguageid : "__langid"); sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); /* Create a list of user columns for the virtual table */ zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); for(i=1; zCols && inColumn; i++){ @@ -116906,11 +117188,12 @@ zCols = sqlite3_mprintf("%z%Q, ", zCols, p->azColumn[i]); } /* Create the whole "CREATE TABLE" statement to pass to SQLite */ zSql = sqlite3_mprintf( - "CREATE TABLE x(%s %Q HIDDEN, docid HIDDEN)", zCols, p->zName + "CREATE TABLE x(%s %Q HIDDEN, docid HIDDEN, %Q HIDDEN)", + zCols, p->zName, zLanguageid ); if( !zCols || !zSql ){ rc = SQLITE_NOMEM; }else{ rc = sqlite3_declare_vtab(p->db, zSql); @@ -116935,18 +117218,22 @@ int rc = SQLITE_OK; /* Return code */ int i; /* Iterator variable */ sqlite3 *db = p->db; /* The database connection */ if( p->zContentTbl==0 ){ + const char *zLanguageid = p->zLanguageid; char *zContentCols; /* Columns of %_content table */ /* Create a list of user columns for the content table */ zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY"); for(i=0; zContentCols && inColumn; i++){ char *z = p->azColumn[i]; zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z); } + if( zLanguageid && zContentCols ){ + zContentCols = sqlite3_mprintf("%z, langid", zContentCols, zLanguageid); + } if( zContentCols==0 ) rc = SQLITE_NOMEM; /* Create the content table */ fts3DbExec(&rc, db, "CREATE TABLE %Q.'%q_content'(%s)", @@ -117087,11 +117374,11 @@ ** memory. */ static char *fts3QuoteId(char const *zInput){ int nRet; char *zRet; - nRet = 2 + strlen(zInput)*2 + 1; + nRet = 2 + (int)strlen(zInput)*2 + 1; zRet = sqlite3_malloc(nRet); if( zRet ){ int i; char *z = zRet; *(z++) = '"'; @@ -117142,18 +117429,24 @@ } fts3Appendf(pRc, &zRet, "docid"); for(i=0; inColumn; i++){ fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]); } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", x.%Q", "langid"); + } sqlite3_free(zFree); }else{ fts3Appendf(pRc, &zRet, "rowid"); for(i=0; inColumn; i++){ fts3Appendf(pRc, &zRet, ", x.'%q'", p->azColumn[i]); } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", x.%Q", p->zLanguageid); + } } - fts3Appendf(pRc, &zRet, "FROM '%q'.'%q%s' AS x", + fts3Appendf(pRc, &zRet, " FROM '%q'.'%q%s' AS x", p->zDb, (p->zContentTbl ? p->zContentTbl : p->zName), (p->zContentTbl ? "" : "_content") ); return zRet; @@ -117192,10 +117485,13 @@ } fts3Appendf(pRc, &zRet, "?"); for(i=0; inColumn; i++){ fts3Appendf(pRc, &zRet, ",%s(?)", zFunction); } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", ?"); + } sqlite3_free(zFree); return zRet; } /* @@ -117334,11 +117630,11 @@ ** space required to store a copy of each column name, including the ** nul-terminator byte. */ nCol = sqlite3_column_count(pStmt); for(i=0; i MATCHINFO */ { "prefix", 6 }, /* 1 -> PREFIX */ { "compress", 8 }, /* 2 -> COMPRESS */ { "uncompress", 10 }, /* 3 -> UNCOMPRESS */ { "order", 5 }, /* 4 -> ORDER */ - { "content", 7 } /* 5 -> CONTENT */ + { "content", 7 }, /* 5 -> CONTENT */ + { "languageid", 10 } /* 6 -> LANGUAGEID */ }; int iOpt; if( !zVal ){ rc = SQLITE_NOMEM; @@ -117510,16 +117808,22 @@ rc = SQLITE_ERROR; } bDescIdx = (zVal[0]=='d' || zVal[0]=='D'); break; - default: /* CONTENT */ - assert( iOpt==5 ); - sqlite3_free(zUncompress); + case 5: /* CONTENT */ + sqlite3_free(zContent); zContent = zVal; zVal = 0; break; + + case 6: /* LANGUAGEID */ + assert( iOpt==6 ); + sqlite3_free(zLanguageid); + zLanguageid = zVal; + zVal = 0; + break; } } sqlite3_free(zVal); } } @@ -117545,12 +117849,25 @@ zUncompress = 0; if( nCol==0 ){ sqlite3_free((void*)aCol); aCol = 0; rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString); + + /* If a languageid= option was specified, remove the language id + ** column from the aCol[] array. */ + if( rc==SQLITE_OK && zLanguageid ){ + int j; + for(j=0; j0 ); } if( rc!=SQLITE_OK ) goto fts3_init_out; if( nCol==0 ){ assert( nString==0 ); @@ -117593,11 +117910,13 @@ p->nMaxPendingData = FTS3_MAX_PENDING_DATA; p->bHasDocsize = (isFts4 && bNoDocsize==0); p->bHasStat = isFts4; p->bDescIdx = bDescIdx; p->zContentTbl = zContent; + p->zLanguageid = zLanguageid; zContent = 0; + zLanguageid = 0; TESTONLY( p->inTransaction = -1 ); TESTONLY( p->mxSavepoint = -1 ); p->aIndex = (struct Fts3Index *)&p->azColumn[nCol]; memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex); @@ -117656,10 +117975,11 @@ sqlite3_free(zPrefix); sqlite3_free(aIndex); sqlite3_free(zCompress); sqlite3_free(zUncompress); sqlite3_free(zContent); + sqlite3_free(zLanguageid); sqlite3_free((void *)aCol); if( rc!=SQLITE_OK ){ if( p ){ fts3DisconnectMethod((sqlite3_vtab *)p); }else if( pTokenizer ){ @@ -117707,10 +118027,11 @@ */ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ Fts3Table *p = (Fts3Table *)pVTab; int i; /* Iterator variable */ int iCons = -1; /* Index of constraint to use */ + int iLangidCons = -1; /* Index of langid=x constraint, if present */ /* By default use a full table scan. This is an expensive option, ** so search through the constraints to see if a more efficient ** strategy is possible. */ @@ -117719,11 +118040,12 @@ for(i=0; inConstraint; i++){ struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i]; if( pCons->usable==0 ) continue; /* A direct lookup on the rowid or docid column. Assign a cost of 1.0. */ - if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ + if( iCons<0 + && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1 ) ){ pInfo->idxNum = FTS3_DOCID_SEARCH; pInfo->estimatedCost = 1.0; iCons = i; @@ -117742,18 +118064,27 @@ && pCons->iColumn>=0 && pCons->iColumn<=p->nColumn ){ pInfo->idxNum = FTS3_FULLTEXT_SEARCH + pCons->iColumn; pInfo->estimatedCost = 2.0; iCons = i; - break; + } + + /* Equality constraint on the langid column */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ + && pCons->iColumn==p->nColumn + 2 + ){ + iLangidCons = i; } } if( iCons>=0 ){ pInfo->aConstraintUsage[iCons].argvIndex = 1; pInfo->aConstraintUsage[iCons].omit = 1; } + if( iLangidCons>=0 ){ + pInfo->aConstraintUsage[iLangidCons].argvIndex = 2; + } /* Regardless of the strategy selected, FTS can deliver rows in rowid (or ** docid) order. Both ascending and descending are possible. */ if( pInfo->nOrderBy==1 ){ @@ -118633,11 +118964,11 @@ fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); } } *paOut = aOut; - *pnOut = (p-aOut); + *pnOut = (int)(p-aOut); assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 ); return SQLITE_OK; } /* @@ -118697,11 +119028,11 @@ fts3PoslistCopy(0, &p2); fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); } } - *pnRight = p - aOut; + *pnRight = (int)(p - aOut); } /* ** Argument pList points to a position list nList bytes in size. This ** function checks to see if the position list contains any entries for @@ -118899,10 +119230,11 @@ ** This function returns SQLITE_OK if successful, or an SQLite error code ** otherwise. */ static int fts3SegReaderCursor( Fts3Table *p, /* FTS3 table handle */ + int iLangid, /* Language id */ int iIndex, /* Index to search (from 0 to p->nIndex-1) */ int iLevel, /* Level of segments to scan */ const char *zTerm, /* Term to query for */ int nTerm, /* Size of zTerm in bytes */ int isPrefix, /* True for a prefix search */ @@ -118927,11 +119259,11 @@ } } if( iLevel!=FTS3_SEGCURSOR_PENDING ){ if( rc==SQLITE_OK ){ - rc = sqlite3Fts3AllSegdirs(p, iIndex, iLevel, &pStmt); + rc = sqlite3Fts3AllSegdirs(p, iLangid, iIndex, iLevel, &pStmt); } while( rc==SQLITE_OK && SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ Fts3SegReader *pSeg = 0; @@ -118950,11 +119282,13 @@ if( rc!=SQLITE_OK ) goto finished; if( isPrefix==0 && isScan==0 ) iLeavesEndBlock = iStartBlock; } rc = sqlite3Fts3SegReaderNew(pCsr->nSegment+1, - iStartBlock, iLeavesEndBlock, iEndBlock, zRoot, nRoot, &pSeg + (isPrefix==0 && isScan==0), + iStartBlock, iLeavesEndBlock, + iEndBlock, zRoot, nRoot, &pSeg ); if( rc!=SQLITE_OK ) goto finished; rc = fts3SegReaderCursorAppend(pCsr, pSeg); } } @@ -118970,10 +119304,11 @@ ** Set up a cursor object for iterating through a full-text index or a ** single level therein. */ SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor( Fts3Table *p, /* FTS3 table handle */ + int iLangid, int iIndex, /* Index to search (from 0 to p->nIndex-1) */ int iLevel, /* Level of segments to scan */ const char *zTerm, /* Term to query for */ int nTerm, /* Size of zTerm in bytes */ int isPrefix, /* True for a prefix search */ @@ -118994,11 +119329,11 @@ assert( isScan==0 || p->aIndex==0 ); memset(pCsr, 0, sizeof(Fts3MultiSegReader)); return fts3SegReaderCursor( - p, iIndex, iLevel, zTerm, nTerm, isPrefix, isScan, pCsr + p, iLangid, iIndex, iLevel, zTerm, nTerm, isPrefix, isScan, pCsr ); } /* ** In addition to its current configuration, have the Fts3MultiSegReader @@ -119006,15 +119341,18 @@ ** ** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. */ static int fts3SegReaderCursorAddZero( Fts3Table *p, /* FTS virtual table handle */ + int iLangid, const char *zTerm, /* Term to scan doclist of */ int nTerm, /* Number of bytes in zTerm */ Fts3MultiSegReader *pCsr /* Fts3MultiSegReader to modify */ ){ - return fts3SegReaderCursor(p, 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0,pCsr); + return fts3SegReaderCursor(p, + iLangid, 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0,pCsr + ); } /* ** Open an Fts3MultiSegReader to scan the doclist for term zTerm/nTerm. Or, ** if isPrefix is true, to scan the doclist for all terms for which @@ -119046,32 +119384,35 @@ if( isPrefix ){ for(i=1; bFound==0 && inIndex; i++){ if( p->aIndex[i].nPrefix==nTerm ){ bFound = 1; - rc = sqlite3Fts3SegReaderCursor( - p, i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0, pSegcsr); + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0, pSegcsr + ); pSegcsr->bLookup = 1; } } for(i=1; bFound==0 && inIndex; i++){ if( p->aIndex[i].nPrefix==nTerm+1 ){ bFound = 1; - rc = sqlite3Fts3SegReaderCursor( - p, i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 1, 0, pSegcsr + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 1, 0, pSegcsr ); if( rc==SQLITE_OK ){ - rc = fts3SegReaderCursorAddZero(p, zTerm, nTerm, pSegcsr); + rc = fts3SegReaderCursorAddZero( + p, pCsr->iLangid, zTerm, nTerm, pSegcsr + ); } } } } if( bFound==0 ){ - rc = sqlite3Fts3SegReaderCursor( - p, 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, isPrefix, 0, pSegcsr + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, isPrefix, 0, pSegcsr ); pSegcsr->bLookup = !isPrefix; } } @@ -119222,11 +119563,11 @@ UNUSED_PARAMETER(idxStr); UNUSED_PARAMETER(nVal); assert( idxNum>=0 && idxNum<=(FTS3_FULLTEXT_SEARCH+p->nColumn) ); - assert( nVal==0 || nVal==1 ); + assert( nVal==0 || nVal==1 || nVal==2 ); assert( (nVal==0)==(idxNum==FTS3_FULLSCAN_SEARCH) ); assert( p->pSegments==0 ); /* In case the cursor has been used before, clear it now. */ sqlite3_finalize(pCsr->pStmt); @@ -119247,12 +119588,15 @@ if( zQuery==0 && sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ return SQLITE_NOMEM; } - rc = sqlite3Fts3ExprParse(p->pTokenizer, p->azColumn, p->bHasStat, - p->nColumn, iCol, zQuery, -1, &pCsr->pExpr + pCsr->iLangid = 0; + if( nVal==2 ) pCsr->iLangid = sqlite3_value_int(apVal[1]); + + rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, + p->azColumn, p->bHasStat, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr ); if( rc!=SQLITE_OK ){ if( rc==SQLITE_ERROR ){ static const char *zErr = "malformed MATCH expression: [%s]"; p->base.zErrMsg = sqlite3_mprintf(zErr, zQuery); @@ -119319,37 +119663,56 @@ } /* ** This is the xColumn method, called by SQLite to request a value from ** the row that the supplied cursor currently points to. +** +** If: +** +** (iCol < p->nColumn) -> The value of the iCol'th user column. +** (iCol == p->nColumn) -> Magic column with the same name as the table. +** (iCol == p->nColumn+1) -> Docid column +** (iCol == p->nColumn+2) -> Langid column */ static int fts3ColumnMethod( sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ - sqlite3_context *pContext, /* Context for sqlite3_result_xxx() calls */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ int iCol /* Index of column to read value from */ ){ int rc = SQLITE_OK; /* Return Code */ Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; Fts3Table *p = (Fts3Table *)pCursor->pVtab; /* The column value supplied by SQLite must be in range. */ - assert( iCol>=0 && iCol<=p->nColumn+1 ); + assert( iCol>=0 && iCol<=p->nColumn+2 ); if( iCol==p->nColumn+1 ){ /* This call is a request for the "docid" column. Since "docid" is an ** alias for "rowid", use the xRowid() method to obtain the value. */ - sqlite3_result_int64(pContext, pCsr->iPrevId); + sqlite3_result_int64(pCtx, pCsr->iPrevId); }else if( iCol==p->nColumn ){ /* The extra column whose name is the same as the table. - ** Return a blob which is a pointer to the cursor. - */ - sqlite3_result_blob(pContext, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT); + ** Return a blob which is a pointer to the cursor. */ + sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT); + }else if( iCol==p->nColumn+2 && pCsr->pExpr ){ + sqlite3_result_int64(pCtx, pCsr->iLangid); }else{ + /* The requested column is either a user column (one that contains + ** indexed data), or the language-id column. */ rc = fts3CursorSeek(0, pCsr); - if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){ - sqlite3_result_value(pContext, sqlite3_column_value(pCsr->pStmt, iCol+1)); + + if( rc==SQLITE_OK ){ + if( iCol==p->nColumn+2 ){ + int iLangid = 0; + if( p->zLanguageid ){ + iLangid = sqlite3_column_int(pCsr->pStmt, p->nColumn+1); + } + sqlite3_result_int(pCtx, iLangid); + }else if( sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){ + sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); + } } } assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); return rc; @@ -120046,11 +120409,11 @@ assert( iPrev>=0 ); fts3PoslistPhraseMerge(&aOut, iToken-iPrev, 0, 1, &p1, &p2); sqlite3_free(aPoslist); aPoslist = pList; - nPoslist = aOut - aPoslist; + nPoslist = (int)(aOut - aPoslist); if( nPoslist==0 ){ sqlite3_free(aPoslist); pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; return SQLITE_OK; @@ -120090,11 +120453,11 @@ } pPhrase->doclist.pList = aOut; if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){ pPhrase->doclist.bFreeList = 1; - pPhrase->doclist.nList = (aOut - pPhrase->doclist.pList); + pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList); }else{ sqlite3_free(aOut); pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; } @@ -120186,11 +120549,11 @@ fts3PoslistCopy(0, &pDocid); while( pDocidiDocid -= iDelta; } pDL->pList = pIter; fts3PoslistCopy(0, &pIter); - pDL->nList = (pIter - pDL->pList); + pDL->nList = (int)(pIter - pDL->pList); /* pIter now points just past the 0x00 that terminates the position- ** list for document pDL->iDocid. However, if this position-list was ** edited in place by fts3EvalNearTrim(), then pIter may not actually ** point to the start of the next docid value. The following line deals @@ -120618,12 +120981,12 @@ int ii; Fts3TokenAndCost *pTC = aTC; Fts3Expr **ppOr = apOr; fts3EvalTokenCosts(pCsr, 0, pCsr->pExpr, &pTC, &ppOr, &rc); - nToken = pTC-aTC; - nOr = ppOr-apOr; + nToken = (int)(pTC-aTC); + nOr = (int)(ppOr-apOr); if( rc==SQLITE_OK ){ rc = fts3EvalSelectDeferred(pCsr, 0, aTC, nToken); for(ii=0; rc==SQLITE_OK && iidoclist.pList; res = fts3PoslistNearMerge( &pOut, aTmp, nParam1, nParam2, paPoslist, &p2 ); if( res ){ - nNew = (pOut - pPhrase->doclist.pList) - 1; + nNew = (int)(pOut - pPhrase->doclist.pList) - 1; assert( pPhrase->doclist.pList[nNew]=='\0' ); assert( nNew<=pPhrase->doclist.nList && nNew>0 ); memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew); pPhrase->doclist.nList = nNew; *paPoslist = pPhrase->doclist.pList; @@ -121524,13 +121887,13 @@ ); return SQLITE_ERROR; } zDb = argv[1]; - nDb = strlen(zDb); + nDb = (int)strlen(zDb); zFts3 = argv[3]; - nFts3 = strlen(zFts3); + nFts3 = (int)strlen(zFts3); rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA); if( rc!=SQLITE_OK ) return rc; nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2; @@ -121821,11 +122184,11 @@ pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iIdx])); pCsr->nStop = sqlite3_value_bytes(apVal[iIdx]); if( pCsr->zStop==0 ) return SQLITE_NOMEM; } - rc = sqlite3Fts3SegReaderCursor(pFts3, 0, FTS3_SEGCURSOR_ALL, + rc = sqlite3Fts3SegReaderCursor(pFts3, 0, 0, FTS3_SEGCURSOR_ALL, pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr ); if( rc==SQLITE_OK ){ rc = sqlite3Fts3SegReaderStart(pFts3, &pCsr->csr, &pCsr->filter); } @@ -122013,10 +122376,11 @@ ** zero. */ typedef struct ParseContext ParseContext; struct ParseContext { sqlite3_tokenizer *pTokenizer; /* Tokenizer module */ + int iLangid; /* Language id used with tokenizer */ const char **azCol; /* Array of column names for fts3 table */ int bFts4; /* True to allow FTS4-only syntax */ int nCol; /* Number of entries in azCol[] */ int iDefaultCol; /* Default column to query */ int isNot; /* True if getNextNode() sees a unary - */ @@ -122048,10 +122412,37 @@ void *pRet = sqlite3_malloc(nByte); if( pRet ) memset(pRet, 0, nByte); return pRet; } +SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer( + sqlite3_tokenizer *pTokenizer, + int iLangid, + const char *z, + int n, + sqlite3_tokenizer_cursor **ppCsr +){ + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + sqlite3_tokenizer_cursor *pCsr = 0; + int rc; + + rc = pModule->xOpen(pTokenizer, z, n, &pCsr); + assert( rc==SQLITE_OK || pCsr==0 ); + if( rc==SQLITE_OK ){ + pCsr->pTokenizer = pTokenizer; + if( pModule->iVersion>=1 ){ + rc = pModule->xLanguageid(pCsr, iLangid); + if( rc!=SQLITE_OK ){ + pModule->xClose(pCsr); + pCsr = 0; + } + } + } + *ppCsr = pCsr; + return rc; +} + /* ** Extract the next token from buffer z (length n) using the tokenizer ** and other information (column names etc.) in pParse. Create an Fts3Expr ** structure of type FTSQUERY_PHRASE containing a phrase consisting of this @@ -122075,19 +122466,17 @@ int rc; sqlite3_tokenizer_cursor *pCursor; Fts3Expr *pRet = 0; int nConsumed = 0; - rc = pModule->xOpen(pTokenizer, z, n, &pCursor); + rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor); if( rc==SQLITE_OK ){ const char *zToken; int nToken, iStart, iEnd, iPosition; int nByte; /* total space to allocate */ - pCursor->pTokenizer = pTokenizer; rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); - if( rc==SQLITE_OK ){ nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; pRet = (Fts3Expr *)fts3MallocZero(nByte); if( !pRet ){ rc = SQLITE_NOMEM; @@ -122189,14 +122578,14 @@ ** ** The second pass, in the block that begins "if( rc==SQLITE_DONE )" below, ** appends buffer zTemp to buffer p, and fills in the Fts3Expr and Fts3Phrase ** structures. */ - rc = pModule->xOpen(pTokenizer, zInput, nInput, &pCursor); + rc = sqlite3Fts3OpenTokenizer( + pTokenizer, pParse->iLangid, zInput, nInput, &pCursor); if( rc==SQLITE_OK ){ int ii; - pCursor->pTokenizer = pTokenizer; for(ii=0; rc==SQLITE_OK; ii++){ const char *zByte; int nByte, iBegin, iEnd, iPos; rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos); if( rc==SQLITE_OK ){ @@ -122666,10 +123055,11 @@ ** specified as part of the query string), or -1 if tokens may by default ** match any table column. */ SQLITE_PRIVATE int sqlite3Fts3ExprParse( sqlite3_tokenizer *pTokenizer, /* Tokenizer module */ + int iLangid, /* Language id for tokenizer */ char **azCol, /* Array of column names for fts3 table */ int bFts4, /* True to allow FTS4-only syntax */ int nCol, /* Number of entries in azCol[] */ int iDefaultCol, /* Default column to query */ const char *z, int n, /* Text of MATCH query */ @@ -122676,15 +123066,17 @@ Fts3Expr **ppExpr /* OUT: Parsed query structure */ ){ int nParsed; int rc; ParseContext sParse; + + memset(&sParse, 0, sizeof(ParseContext)); sParse.pTokenizer = pTokenizer; + sParse.iLangid = iLangid; sParse.azCol = (const char **)azCol; sParse.nCol = nCol; sParse.iDefaultCol = iDefaultCol; - sParse.nNest = 0; sParse.bFts4 = bFts4; if( z==0 ){ *ppExpr = 0; return SQLITE_OK; } @@ -122871,11 +123263,11 @@ for(ii=0; iixCreate(zArg ? 1 : 0, &zArg, &pTokenizer) ){ zErr = "error in xCreate()"; goto finish; } pTokenizer->pModule = p; - if( SQLITE_OK!=p->xOpen(pTokenizer, zInput, nInput, &pCsr) ){ + if( sqlite3Fts3OpenTokenizer(pTokenizer, 0, zInput, nInput, &pCsr) ){ zErr = "error in xOpen()"; goto finish; } - pCsr->pTokenizer = pTokenizer; while( SQLITE_OK==p->xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos) ){ Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(iPos)); Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken)); zToken = &zInput[iStart]; @@ -124645,10 +125037,11 @@ simpleCreate, simpleDestroy, simpleOpen, simpleClose, simpleNext, + 0, }; /* ** Allocate a new simple tokenizer. Return a pointer to the new ** tokenizer in *ppModule @@ -124772,10 +125165,11 @@ ** fts3SegReaderFirstDocid() ** fts3SegReaderNextDocid() */ struct Fts3SegReader { int iIdx; /* Index within level, or 0x7FFFFFFF for PT */ + int bLookup; /* True for a lookup only */ sqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */ sqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */ sqlite3_int64 iEndBlock; /* Rowid of final block in segment (or 0) */ sqlite3_int64 iCurrentBlock; /* Current leaf block (or 0) */ @@ -124893,10 +125287,12 @@ #define SQL_SELECT_ALL_PREFIX_LEVEL 24 #define SQL_DELETE_ALL_TERMS_SEGDIR 25 #define SQL_DELETE_SEGDIR_RANGE 26 +#define SQL_SELECT_ALL_LANGID 27 + /* ** This function is used to obtain an SQLite prepared statement handle ** for the statement identified by the second argument. If successful, ** *pp is set to the requested statement handle and SQLITE_OK returned. ** Otherwise, an SQLite error code is returned and *pp is set to 0. @@ -124946,10 +125342,11 @@ /* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(0,?)", /* 24 */ "", /* 25 */ "", /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", +/* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'", }; int rc = SQLITE_OK; sqlite3_stmt *pStmt; @@ -125091,10 +125488,49 @@ rc = SQLITE_OK; } return rc; } + +/* +** FTS maintains a separate indexes for each language-id (a 32-bit integer). +** Within each language id, a separate index is maintained to store the +** document terms, and each configured prefix size (configured the FTS +** "prefix=" option). And each index consists of multiple levels ("relative +** levels"). +** +** All three of these values (the language id, the specific index and the +** level within the index) are encoded in 64-bit integer values stored +** in the %_segdir table on disk. This function is used to convert three +** separate component values into the single 64-bit integer value that +** can be used to query the %_segdir table. +** +** Specifically, each language-id/index combination is allocated 1024 +** 64-bit integer level values ("absolute levels"). The main terms index +** for language-id 0 is allocate values 0-1023. The first prefix index +** (if any) for language-id 0 is allocated values 1024-2047. And so on. +** Language 1 indexes are allocated immediately following language 0. +** +** So, for a system with nPrefix prefix indexes configured, the block of +** absolute levels that corresponds to language-id iLangid and index +** iIndex starts at absolute level ((iLangid * (nPrefix+1) + iIndex) * 1024). +*/ +static sqlite3_int64 getAbsoluteLevel( + Fts3Table *p, + int iLangid, + int iIndex, + int iLevel +){ + sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */ + assert( iLangid>=0 ); + assert( p->nIndex>0 ); + assert( iIndex>=0 && iIndexnIndex ); + + iBase = ((sqlite3_int64)iLangid * p->nIndex + iIndex) * FTS3_SEGDIR_MAXLEVEL; + return iBase + iLevel; +} + /* ** Set *ppStmt to a statement handle that may be used to iterate through ** all rows in the %_segdir table, from oldest to newest. If successful, ** return SQLITE_OK. If an error occurs while preparing the statement, @@ -125111,12 +125547,13 @@ ** 3: end_block ** 4: root */ SQLITE_PRIVATE int sqlite3Fts3AllSegdirs( Fts3Table *p, /* FTS3 table */ + int iLangid, /* Language being queried */ int iIndex, /* Index for p->aIndex[] */ - int iLevel, /* Level to select */ + int iLevel, /* Level to select (relative level) */ sqlite3_stmt **ppStmt /* OUT: Compiled statement */ ){ int rc; sqlite3_stmt *pStmt = 0; @@ -125126,18 +125563,20 @@ if( iLevel<0 ){ /* "SELECT * FROM %_segdir WHERE level BETWEEN ? AND ? ORDER BY ..." */ rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE, &pStmt, 0); if( rc==SQLITE_OK ){ - sqlite3_bind_int(pStmt, 1, iIndex*FTS3_SEGDIR_MAXLEVEL); - sqlite3_bind_int(pStmt, 2, (iIndex+1)*FTS3_SEGDIR_MAXLEVEL-1); + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pStmt, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); } }else{ /* "SELECT * FROM %_segdir WHERE level = ? ORDER BY ..." */ rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0); if( rc==SQLITE_OK ){ - sqlite3_bind_int(pStmt, 1, iLevel+iIndex*FTS3_SEGDIR_MAXLEVEL); + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex,iLevel)); } } *ppStmt = pStmt; return rc; } @@ -125299,10 +125738,11 @@ ** ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. */ static int fts3PendingTermsAdd( Fts3Table *p, /* Table into which text will be inserted */ + int iLangid, /* Language id to use */ const char *zText, /* Text of document to be inserted */ int iCol, /* Column into which text is being inserted */ u32 *pnWord /* OUT: Number of tokens inserted */ ){ int rc; @@ -125328,15 +125768,14 @@ if( zText==0 ){ *pnWord = 0; return SQLITE_OK; } - rc = pModule->xOpen(pTokenizer, zText, -1, &pCsr); + rc = sqlite3Fts3OpenTokenizer(pTokenizer, iLangid, zText, -1, &pCsr); if( rc!=SQLITE_OK ){ return rc; } - pCsr->pTokenizer = pTokenizer; xNext = pModule->xNext; while( SQLITE_OK==rc && SQLITE_OK==(rc = xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos)) ){ @@ -125375,22 +125814,32 @@ /* ** Calling this function indicates that subsequent calls to ** fts3PendingTermsAdd() are to add term/position-list pairs for the ** contents of the document with docid iDocid. */ -static int fts3PendingTermsDocid(Fts3Table *p, sqlite_int64 iDocid){ +static int fts3PendingTermsDocid( + Fts3Table *p, /* Full-text table handle */ + int iLangid, /* Language id of row being written */ + sqlite_int64 iDocid /* Docid of row being written */ +){ + assert( iLangid>=0 ); + /* TODO(shess) Explore whether partially flushing the buffer on ** forced-flush would provide better performance. I suspect that if ** we ordered the doclists by size and flushed the largest until the ** buffer was half empty, that would let the less frequent terms ** generate longer doclists. */ - if( iDocid<=p->iPrevDocid || p->nPendingData>p->nMaxPendingData ){ + if( iDocid<=p->iPrevDocid + || p->iPrevLangid!=iLangid + || p->nPendingData>p->nMaxPendingData + ){ int rc = sqlite3Fts3PendingTermsFlush(p); if( rc!=SQLITE_OK ) return rc; } p->iPrevDocid = iDocid; + p->iPrevLangid = iLangid; return SQLITE_OK; } /* ** Discard the contents of the pending-terms hash tables. @@ -125415,15 +125864,20 @@ ** pendingTerms hash table. ** ** Argument apVal is the same as the similarly named argument passed to ** fts3InsertData(). Parameter iDocid is the docid of the new row. */ -static int fts3InsertTerms(Fts3Table *p, sqlite3_value **apVal, u32 *aSz){ +static int fts3InsertTerms( + Fts3Table *p, + int iLangid, + sqlite3_value **apVal, + u32 *aSz +){ int i; /* Iterator variable */ for(i=2; inColumn+2; i++){ const char *zText = (const char *)sqlite3_value_text(apVal[i]); - int rc = fts3PendingTermsAdd(p, zText, i-2, &aSz[i-2]); + int rc = fts3PendingTermsAdd(p, iLangid, zText, i-2, &aSz[i-2]); if( rc!=SQLITE_OK ){ return rc; } aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]); } @@ -125440,10 +125894,11 @@ ** apVal[2] Left-most user-defined column ** ... ** apVal[p->nColumn+1] Right-most user-defined column ** apVal[p->nColumn+2] Hidden column with same name as table ** apVal[p->nColumn+3] Hidden "docid" column (alias for rowid) +** apVal[p->nColumn+4] Hidden languageid column */ static int fts3InsertData( Fts3Table *p, /* Full-text table */ sqlite3_value **apVal, /* Array of values to insert */ sqlite3_int64 *piDocid /* OUT: Docid for row just inserted */ @@ -125470,13 +125925,17 @@ ** ** The statement features N '?' variables, where N is the number of user ** defined columns in the FTS3 table, plus one for the docid field. */ rc = fts3SqlStmt(p, SQL_CONTENT_INSERT, &pContentInsert, &apVal[1]); - if( rc!=SQLITE_OK ){ - return rc; + if( rc==SQLITE_OK && p->zLanguageid ){ + rc = sqlite3_bind_int( + pContentInsert, p->nColumn+2, + sqlite3_value_int(apVal[p->nColumn+4]) + ); } + if( rc!=SQLITE_OK ) return rc; /* There is a quirk here. The users INSERT statement may have specified ** a value for the "rowid" field, for the "docid" field, or for both. ** Which is a problem, since "rowid" and "docid" are aliases for the ** same value. For example: @@ -125531,10 +125990,19 @@ if( p->bHasStat ){ fts3SqlExec(&rc, p, SQL_DELETE_ALL_STAT, 0); } return rc; } + +/* +** +*/ +static int langidFromSelect(Fts3Table *p, sqlite3_stmt *pSelect){ + int iLangid = 0; + if( p->zLanguageid ) iLangid = sqlite3_column_int(pSelect, p->nColumn+1); + return iLangid; +} /* ** The first element in the apVal[] array is assumed to contain the docid ** (an integer) of a row about to be deleted. Remove all terms from the ** full-text index. @@ -125551,19 +126019,21 @@ if( *pRC ) return; rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid); if( rc==SQLITE_OK ){ if( SQLITE_ROW==sqlite3_step(pSelect) ){ int i; - for(i=1; i<=p->nColumn; i++){ + int iLangid = langidFromSelect(p, pSelect); + rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0)); + for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){ const char *zText = (const char *)sqlite3_column_text(pSelect, i); - rc = fts3PendingTermsAdd(p, zText, -1, &aSz[i-1]); - if( rc!=SQLITE_OK ){ - sqlite3_reset(pSelect); - *pRC = rc; - return; - } + rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[i-1]); aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); + } + if( rc!=SQLITE_OK ){ + sqlite3_reset(pSelect); + *pRC = rc; + return; } } rc = sqlite3_reset(pSelect); }else{ sqlite3_reset(pSelect); @@ -125573,11 +126043,11 @@ /* ** Forward declaration to account for the circular dependency between ** functions fts3SegmentMerge() and fts3AllocateSegdirIdx(). */ -static int fts3SegmentMerge(Fts3Table *, int, int); +static int fts3SegmentMerge(Fts3Table *, int, int, int); /* ** This function allocates a new level iLevel index in the segdir table. ** Usually, indexes are allocated within a level sequentially starting ** with 0, so the allocated index is one greater than the value returned @@ -125592,22 +126062,28 @@ ** If successful, *piIdx is set to the allocated index slot and SQLITE_OK ** returned. Otherwise, an SQLite error code is returned. */ static int fts3AllocateSegdirIdx( Fts3Table *p, + int iLangid, /* Language id */ int iIndex, /* Index for p->aIndex */ int iLevel, int *piIdx ){ int rc; /* Return Code */ sqlite3_stmt *pNextIdx; /* Query for next idx at level iLevel */ int iNext = 0; /* Result of query pNextIdx */ + assert( iLangid>=0 ); + assert( p->nIndex>=1 ); + /* Set variable iNext to the next available segdir index at level iLevel. */ rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pNextIdx, 0); if( rc==SQLITE_OK ){ - sqlite3_bind_int(pNextIdx, 1, iIndex*FTS3_SEGDIR_MAXLEVEL + iLevel); + sqlite3_bind_int64( + pNextIdx, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel) + ); if( SQLITE_ROW==sqlite3_step(pNextIdx) ){ iNext = sqlite3_column_int(pNextIdx, 0); } rc = sqlite3_reset(pNextIdx); } @@ -125617,11 +126093,11 @@ ** full, merge all segments in level iLevel into a single iLevel+1 ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise, ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext. */ if( iNext>=FTS3_MERGE_COUNT ){ - rc = fts3SegmentMerge(p, iIndex, iLevel); + rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel); *piIdx = 0; }else{ *piIdx = iNext; } } @@ -125749,10 +126225,22 @@ ){ rc = fts3SegReaderIncrRead(pReader); } return rc; } + +/* +** Set an Fts3SegReader cursor to point at EOF. +*/ +static void fts3SegReaderSetEof(Fts3SegReader *pSeg){ + if( !fts3SegReaderIsRootOnly(pSeg) ){ + sqlite3_free(pSeg->aNode); + sqlite3_blob_close(pSeg->pBlob); + pSeg->pBlob = 0; + } + pSeg->aNode = 0; +} /* ** Move the iterator passed as the first argument to the next term in the ** segment. If successful, SQLITE_OK is returned. If there is no next term, ** SQLITE_DONE. Otherwise, an SQLite error code. @@ -125789,16 +126277,11 @@ assert( pReader->aNode ); } return SQLITE_OK; } - if( !fts3SegReaderIsRootOnly(pReader) ){ - sqlite3_free(pReader->aNode); - sqlite3_blob_close(pReader->pBlob); - pReader->pBlob = 0; - } - pReader->aNode = 0; + fts3SegReaderSetEof(pReader); /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf ** blocks have already been traversed. */ assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock ); if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){ @@ -126041,10 +126524,11 @@ /* ** Allocate a new SegReader object. */ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( int iAge, /* Segment "age". */ + int bLookup, /* True for a lookup only */ sqlite3_int64 iStartLeaf, /* First leaf to traverse */ sqlite3_int64 iEndLeaf, /* Final leaf to traverse */ sqlite3_int64 iEndBlock, /* Final block of segment */ const char *zRoot, /* Buffer containing root node */ int nRoot, /* Size of buffer containing root node */ @@ -126062,10 +126546,11 @@ if( !pReader ){ return SQLITE_NOMEM; } memset(pReader, 0, sizeof(Fts3SegReader)); pReader->iIdx = iAge; + pReader->bLookup = bLookup; pReader->iStartBlock = iStartLeaf; pReader->iLeafEndBlock = iEndLeaf; pReader->iEndBlock = iEndBlock; if( nExtra ){ @@ -126359,11 +126844,11 @@ /* ** Insert a record into the %_segdir table. */ static int fts3WriteSegdir( Fts3Table *p, /* Virtual table handle */ - int iLevel, /* Value for "level" field */ + sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ int iIdx, /* Value for "idx" field */ sqlite3_int64 iStartBlock, /* Value for "start_block" field */ sqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */ sqlite3_int64 iEndBlock, /* Value for "end_block" field */ char *zRoot, /* Blob value for "root" field */ @@ -126370,11 +126855,11 @@ int nRoot /* Number of bytes in buffer zRoot */ ){ sqlite3_stmt *pStmt; int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0); if( rc==SQLITE_OK ){ - sqlite3_bind_int(pStmt, 1, iLevel); + sqlite3_bind_int64(pStmt, 1, iLevel); sqlite3_bind_int(pStmt, 2, iIdx); sqlite3_bind_int64(pStmt, 3, iStartBlock); sqlite3_bind_int64(pStmt, 4, iLeafEndBlock); sqlite3_bind_int64(pStmt, 5, iEndBlock); sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); @@ -126753,11 +127238,11 @@ ** returned. Otherwise, an SQLite error code. */ static int fts3SegWriterFlush( Fts3Table *p, /* Virtual table handle */ SegmentWriter *pWriter, /* SegmentWriter to flush to the db */ - int iLevel, /* Value for 'level' column of %_segdir */ + sqlite3_int64 iLevel, /* Value for 'level' column of %_segdir */ int iIdx /* Value for 'idx' column of %_segdir */ ){ int rc; /* Return code */ if( pWriter->pTree ){ sqlite3_int64 iLast = 0; /* Largest block id written to database */ @@ -126831,11 +127316,16 @@ ** ** Segment levels are stored in the 'level' column of the %_segdir table. ** ** Return SQLITE_OK if successful, or an SQLite error code if not. */ -static int fts3SegmentMaxLevel(Fts3Table *p, int iIndex, int *pnMax){ +static int fts3SegmentMaxLevel( + Fts3Table *p, + int iLangid, + int iIndex, + sqlite3_int64 *pnMax +){ sqlite3_stmt *pStmt; int rc; assert( iIndex>=0 && iIndexnIndex ); /* Set pStmt to the compiled version of: @@ -126844,14 +127334,16 @@ ** ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). */ rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); if( rc!=SQLITE_OK ) return rc; - sqlite3_bind_int(pStmt, 1, iIndex*FTS3_SEGDIR_MAXLEVEL); - sqlite3_bind_int(pStmt, 2, (iIndex+1)*FTS3_SEGDIR_MAXLEVEL - 1); + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pStmt, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); if( SQLITE_ROW==sqlite3_step(pStmt) ){ - *pnMax = sqlite3_column_int(pStmt, 0); + *pnMax = sqlite3_column_int64(pStmt, 0); } return sqlite3_reset(pStmt); } /* @@ -126868,10 +127360,11 @@ ** ** SQLITE_OK is returned if successful, otherwise an SQLite error code. */ static int fts3DeleteSegdir( Fts3Table *p, /* Virtual table handle */ + int iLangid, /* Language id */ int iIndex, /* Index for p->aIndex */ int iLevel, /* Level of %_segdir entries to delete */ Fts3SegReader **apSegment, /* Array of SegReader objects */ int nReader /* Size of array apSegment */ ){ @@ -126895,17 +127388,21 @@ assert( iLevel>=0 || iLevel==FTS3_SEGCURSOR_ALL ); if( iLevel==FTS3_SEGCURSOR_ALL ){ rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_RANGE, &pDelete, 0); if( rc==SQLITE_OK ){ - sqlite3_bind_int(pDelete, 1, iIndex*FTS3_SEGDIR_MAXLEVEL); - sqlite3_bind_int(pDelete, 2, (iIndex+1) * FTS3_SEGDIR_MAXLEVEL - 1); + sqlite3_bind_int64(pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pDelete, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); } }else{ rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pDelete, 0); if( rc==SQLITE_OK ){ - sqlite3_bind_int(pDelete, 1, iIndex*FTS3_SEGDIR_MAXLEVEL + iLevel); + sqlite3_bind_int64( + pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel) + ); } } if( rc==SQLITE_OK ){ sqlite3_step(pDelete); @@ -127064,15 +127561,20 @@ ** equal or greater value than the specified term. This prevents many ** unnecessary merge/sort operations for the case where single segment ** b-tree leaf nodes contain more than one term. */ for(i=0; pCsr->bRestart==0 && inSegment; i++){ + int res = 0; Fts3SegReader *pSeg = pCsr->apSegment[i]; do { int rc = fts3SegReaderNext(p, pSeg, 0); if( rc!=SQLITE_OK ) return rc; - }while( zTerm && fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 ); + }while( zTerm && (res = fts3SegReaderTermCmp(pSeg, zTerm, nTerm))<0 ); + + if( pSeg->bLookup && res!=0 ){ + fts3SegReaderSetEof(pSeg); + } } fts3SegReaderSort(pCsr->apSegment, nSeg, nSeg, fts3SegReaderCmp); return SQLITE_OK; } @@ -127189,11 +127691,16 @@ /* Advance the first pCsr->nAdvance entries in the apSegment[] array ** forward. Then sort the list in order of current term again. */ for(i=0; inAdvance; i++){ - rc = fts3SegReaderNext(p, apSegment[i], 0); + Fts3SegReader *pSeg = apSegment[i]; + if( pSeg->bLookup ){ + fts3SegReaderSetEof(pSeg); + }else{ + rc = fts3SegReaderNext(p, pSeg, 0); + } if( rc!=SQLITE_OK ) return rc; } fts3SegReaderSort(apSegment, nSegment, pCsr->nAdvance, fts3SegReaderCmp); pCsr->nAdvance = 0; @@ -127360,27 +127867,32 @@ ** If this function is called with iLevel<0, but there is only one ** segment in the database, SQLITE_DONE is returned immediately. ** Otherwise, if successful, SQLITE_OK is returned. If an error occurs, ** an SQLite error code is returned. */ -static int fts3SegmentMerge(Fts3Table *p, int iIndex, int iLevel){ +static int fts3SegmentMerge( + Fts3Table *p, + int iLangid, /* Language id to merge */ + int iIndex, /* Index in p->aIndex[] to merge */ + int iLevel /* Level to merge */ +){ int rc; /* Return code */ int iIdx = 0; /* Index of new segment */ - int iNewLevel = 0; /* Level/index to create new segment at */ + sqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */ SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */ Fts3SegFilter filter; /* Segment term filter condition */ - Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */ + Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */ int bIgnoreEmpty = 0; /* True to ignore empty segments */ assert( iLevel==FTS3_SEGCURSOR_ALL || iLevel==FTS3_SEGCURSOR_PENDING || iLevel>=0 ); assert( iLevel=0 && iIndexnIndex ); - rc = sqlite3Fts3SegReaderCursor(p, iIndex, iLevel, 0, 0, 1, 0, &csr); + rc = sqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr); if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished; if( iLevel==FTS3_SEGCURSOR_ALL ){ /* This call is to merge all segments in the database to a single ** segment. The level of the new segment is equal to the the numerically @@ -127388,28 +127900,28 @@ ** index. The idx of the new segment is always 0. */ if( csr.nSegment==1 ){ rc = SQLITE_DONE; goto finished; } - rc = fts3SegmentMaxLevel(p, iIndex, &iNewLevel); + rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iNewLevel); bIgnoreEmpty = 1; }else if( iLevel==FTS3_SEGCURSOR_PENDING ){ - iNewLevel = iIndex * FTS3_SEGDIR_MAXLEVEL; - rc = fts3AllocateSegdirIdx(p, iIndex, 0, &iIdx); + iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, 0); + rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, 0, &iIdx); }else{ /* This call is to merge all segments at level iLevel. find the next ** available segment index at level iLevel+1. The call to ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to ** a single iLevel+2 segment if necessary. */ - rc = fts3AllocateSegdirIdx(p, iIndex, iLevel+1, &iIdx); - iNewLevel = iIndex * FTS3_SEGDIR_MAXLEVEL + iLevel+1; + rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, iLevel+1, &iIdx); + iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, iLevel+1); } if( rc!=SQLITE_OK ) goto finished; assert( csr.nSegment>0 ); - assert( iNewLevel>=(iIndex*FTS3_SEGDIR_MAXLEVEL) ); - assert( iNewLevel<((iIndex+1)*FTS3_SEGDIR_MAXLEVEL) ); + assert( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) ); + assert( iNewLevelnIndex; i++){ - rc = fts3SegmentMerge(p, i, FTS3_SEGCURSOR_PENDING); + rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); if( rc==SQLITE_DONE ) rc = SQLITE_OK; } sqlite3Fts3PendingTermsClear(p); return rc; } @@ -127596,21 +128110,38 @@ sqlite3_step(pStmt); *pRC = sqlite3_reset(pStmt); sqlite3_free(a); } +/* +** Merge the entire database so that there is one segment for each +** iIndex/iLangid combination. +*/ static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ - int i; int bSeenDone = 0; - int rc = SQLITE_OK; - for(i=0; rc==SQLITE_OK && inIndex; i++){ - rc = fts3SegmentMerge(p, i, FTS3_SEGCURSOR_ALL); - if( rc==SQLITE_DONE ){ - bSeenDone = 1; - rc = SQLITE_OK; - } - } + int rc; + sqlite3_stmt *pAllLangid = 0; + + rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int(pAllLangid, 1, p->nIndex); + while( sqlite3_step(pAllLangid)==SQLITE_ROW ){ + int i; + int iLangid = sqlite3_column_int(pAllLangid, 0); + for(i=0; rc==SQLITE_OK && inIndex; i++){ + rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL); + if( rc==SQLITE_DONE ){ + bSeenDone = 1; + rc = SQLITE_OK; + } + } + } + rc2 = sqlite3_reset(pAllLangid); + if( rc==SQLITE_OK ) rc = rc2; + } + sqlite3Fts3SegmentsClose(p); sqlite3Fts3PendingTermsClear(p); return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc; } @@ -127657,15 +128188,16 @@ } } while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ int iCol; - rc = fts3PendingTermsDocid(p, sqlite3_column_int64(pStmt, 0)); + int iLangid = langidFromSelect(p, pStmt); + rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0)); aSz[p->nColumn] = 0; for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1); - rc = fts3PendingTermsAdd(p, z, iCol, &aSz[iCol]); + rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]); aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1); } if( p->bHasDocsize ){ fts3InsertDocsize(&rc, p, aSz); } @@ -127780,18 +128312,17 @@ for(i=0; inColumn && rc==SQLITE_OK; i++){ const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1); sqlite3_tokenizer_cursor *pTC = 0; - rc = pModule->xOpen(pT, zText, -1, &pTC); + rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); while( rc==SQLITE_OK ){ char const *zToken; /* Buffer containing token */ int nToken; /* Number of bytes in token */ int iDum1, iDum2; /* Dummy variables */ int iPos; /* Position of token in zText */ - pTC->pTokenizer = pT; rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ Fts3PhraseToken *pPT = pDef->pToken; if( (pDef->iCol>=p->nColumn || pDef->iCol==i) && (pPT->bFirst==0 || iPos==0) @@ -127887,12 +128418,10 @@ ** delete the contents of all three tables and throw away any ** data in the pendingTerms hash table. */ rc = fts3DeleteAll(p, 1); *pnDoc = *pnDoc - 1; }else{ - sqlite3_int64 iRemove = sqlite3_value_int64(pRowid); - rc = fts3PendingTermsDocid(p, iRemove); fts3DeleteTerms(&rc, p, pRowid, aSzDel); if( p->zContentTbl==0 ){ fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid); if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1; }else{ @@ -127907,11 +128436,20 @@ return rc; } /* ** This function does the work for the xUpdate method of FTS3 virtual -** tables. +** tables. The schema of the virtual table being: +** +** CREATE TABLE ( +** , +**
    HIDDEN, +** docid HIDDEN, +** HIDDEN +** ); +** +** */ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod( sqlite3_vtab *pVtab, /* FTS3 vtab object */ int nArg, /* Size of argument array */ sqlite3_value **apVal, /* Array of arguments */ @@ -127924,10 +128462,14 @@ u32 *aSzDel; /* Sizes of deleted documents */ int nChng = 0; /* Net change in number of documents */ int bInsertDone = 0; assert( p->pSegments==0 ); + assert( + nArg==1 /* DELETE operations */ + || nArg==(2 + p->nColumn + 3) /* INSERT or UPDATE operations */ + ); /* Check for a "special" INSERT operation. One of the form: ** ** INSERT INTO xyz(xyz) VALUES('command'); */ @@ -127936,10 +128478,15 @@ && sqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL ){ rc = fts3SpecialInsert(p, apVal[p->nColumn+2]); goto update_out; } + + if( nArg>1 && sqlite3_value_int(apVal[2 + p->nColumn + 2])<0 ){ + rc = SQLITE_CONSTRAINT; + goto update_out; + } /* Allocate space to hold the change in document sizes */ aSzIns = sqlite3_malloc( sizeof(aSzIns[0])*(p->nColumn+1)*2 ); if( aSzIns==0 ){ rc = SQLITE_NOMEM; @@ -128004,22 +128551,23 @@ isRemove = 1; } /* If this is an INSERT or UPDATE operation, insert the new record. */ if( nArg>1 && rc==SQLITE_OK ){ + int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]); if( bInsertDone==0 ){ rc = fts3InsertData(p, apVal, pRowid); if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){ rc = FTS_CORRUPT_VTAB; } } if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){ - rc = fts3PendingTermsDocid(p, *pRowid); + rc = fts3PendingTermsDocid(p, iLangid, *pRowid); } if( rc==SQLITE_OK ){ assert( p->iPrevDocid==*pRowid ); - rc = fts3InsertTerms(p, apVal, aSzIns); + rc = fts3InsertTerms(p, iLangid, apVal, aSzIns); } if( p->bHasDocsize ){ fts3InsertDocsize(&rc, p, aSzIns); } nChng++; @@ -128592,10 +129140,11 @@ ** is no way for fts3BestSnippet() to know whether or not the document ** actually contains terms that follow the final highlighted term. */ static int fts3SnippetShift( Fts3Table *pTab, /* FTS3 table snippet comes from */ + int iLangid, /* Language id to use in tokenizing */ int nSnippet, /* Number of tokens desired for snippet */ const char *zDoc, /* Document text to extract snippet from */ int nDoc, /* Size of buffer zDoc in bytes */ int *piPos, /* IN/OUT: First token of snippet */ u64 *pHlmask /* IN/OUT: Mask of tokens to highlight */ @@ -128627,15 +129176,14 @@ pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; /* Open a cursor on zDoc/nDoc. Check if there are (nSnippet+nDesired) ** or more tokens in zDoc/nDoc. */ - rc = pMod->xOpen(pTab->pTokenizer, zDoc, nDoc, &pC); + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, iLangid, zDoc, nDoc, &pC); if( rc!=SQLITE_OK ){ return rc; } - pC->pTokenizer = pTab->pTokenizer; while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){ const char *ZDUMMY; int DUMMY1, DUMMY2, DUMMY3; rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent); } pMod->xClose(pC); @@ -128691,15 +129239,14 @@ } nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol); /* Open a token cursor on the document. */ pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; - rc = pMod->xOpen(pTab->pTokenizer, zDoc, nDoc, &pC); + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, zDoc,nDoc,&pC); if( rc!=SQLITE_OK ){ return rc; } - pC->pTokenizer = pTab->pTokenizer; while( rc==SQLITE_OK ){ int iBegin; /* Offset in zDoc of start of token */ int iFin; /* Offset in zDoc of end of token */ int isHighlight; /* True for highlighted terms */ @@ -128717,11 +129264,13 @@ } if( iCurrentiLangid, nSnippet, &zDoc[iBegin], n, &iPos, &hlmask + ); isShiftDone = 1; /* Now that the shift has been done, check if the initial "..." are ** required. They are required if (a) this is not the first fragment, ** or (b) this fragment does not begin at position 0 of its column. @@ -129450,13 +129999,14 @@ rc = SQLITE_NOMEM; goto offsets_out; } /* Initialize a tokenizer iterator to iterate through column iCol. */ - rc = pMod->xOpen(pTab->pTokenizer, zDoc, nDoc, &pC); + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, + zDoc, nDoc, &pC + ); if( rc!=SQLITE_OK ) goto offsets_out; - pC->pTokenizer = pTab->pTokenizer; rc = pMod->xNext(pC, &ZDUMMY, &NDUMMY, &iStart, &iEnd, &iCurrent); while( rc==SQLITE_OK ){ int i; /* Used to loop through terms */ int iMinPos = 0x7FFFFFFF; /* Position of next token */ @@ -132617,12 +133167,12 @@ } sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); /* Allocate the sqlite3_vtab structure */ - nDb = strlen(argv[1]); - nName = strlen(argv[2]); + nDb = (int)strlen(argv[1]); + nName = (int)strlen(argv[2]); pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2); if( !pRtree ){ return SQLITE_NOMEM; } memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); @@ -132713,14 +133263,14 @@ RtreeCell cell; int jj; nodeGetCell(&tree, &node, ii, &cell); sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid); - nCell = strlen(zCell); + nCell = (int)strlen(zCell); for(jj=0; jj +**
  • [[SQLITE_FCNTL_SIZE_HINT]] ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS ** layer a hint of how large the database file will grow to be during the ** current transaction. This hint is not guaranteed to be accurate but it ** is often close. The underlying VFS might choose to preallocate database ** file space based on this hint in order to help writes to the database ** file run faster. ** +**
  • [[SQLITE_FCNTL_CHUNK_SIZE]] ** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS ** extends and truncates the database file in chunks of a size specified ** by the user. The fourth argument to [sqlite3_file_control()] should ** point to an integer (type int) containing the new chunk-size to use ** for the nominated database. Allocating database file space in large ** chunks (say 1MB at a time), may reduce file-system fragmentation and ** improve performance on some systems. ** +**
  • [[SQLITE_FCNTL_FILE_POINTER]] ** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer ** to the [sqlite3_file] object associated with a particular database ** connection. See the [sqlite3_file_control()] documentation for ** additional information. ** +**
  • [[SQLITE_FCNTL_SYNC_OMITTED]] ** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by ** SQLite and sent to all VFSes in place of a call to the xSync method ** when the database connection has [PRAGMA synchronous] set to OFF.)^ ** Some specialized VFSes need this signal in order to operate correctly ** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most @@ -745,10 +750,11 @@ ** VFSes do not need this signal and should silently ignore this opcode. ** Applications should not call [sqlite3_file_control()] with this ** opcode as doing so may disrupt the operation of the specialized VFSes ** that do require it. ** +**
  • [[SQLITE_FCNTL_WIN32_AV_RETRY]] ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic ** retry counts and intervals for certain disk I/O operations for the ** windows [VFS] in order to provide robustness in the presence of ** anti-virus programs. By default, the windows VFS will retry file read, ** file write, and file delete operations up to 10 times, with a delay @@ -761,10 +767,11 @@ ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** +**
  • [[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the ** persistent [WAL | Write AHead Log] setting. By default, the auxiliary ** write ahead log and shared memory files used for transaction control ** are automatically deleted when the latest connection to the database ** closes. Setting persistent WAL mode causes those files to persist after @@ -775,24 +782,27 @@ ** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. ** +**
  • [[SQLITE_FCNTL_POWERSAFE_OVERWRITE]] ** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the ** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting ** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the ** xDeviceCharacteristics methods. The fourth parameter to ** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage ** mode. If the integer is -1, then it is overwritten with the current ** zero-damage mode setting. ** +**
  • [[SQLITE_FCNTL_OVERWRITE]] ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. ** +**
  • [[SQLITE_FCNTL_VFSNAME]] ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of ** all [VFSes] in the VFS stack. The names are of all VFS shims and the ** final bottom-level VFS are written into memory obtained from ** [sqlite3_malloc()] and the result is stored in the char* variable ** that the fourth parameter of [sqlite3_file_control()] points to. @@ -799,10 +809,34 @@ ** The caller is responsible for freeing the memory when done. As with ** all file-control actions, there is no guarantee that this will actually ** do anything. Callers should initialize the char* variable to a NULL ** pointer in case this file-control is not implemented. This file-control ** is intended for diagnostic use only. +** +**
  • [[SQLITE_FCNTL_PRAGMA]] +** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] +** file control is sent to the open [sqlite3_file] object corresponding +** to the database file to which the pragma statement refers. ^The argument +** to the [SQLITE_FCNTL_PRAGMA] file control is an array of +** pointers to strings (char**) in which the second element of the array +** is the name of the pragma and the third element is the argument to the +** pragma or NULL if the pragma has no argument. ^The handler for an +** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element +** of the char** argument point to a string obtained from [sqlite3_mprintf()] +** or the equivalent and that string will become the result of the pragma or +** the error message if the pragma fails. ^If the +** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal +** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] +** file control returns [SQLITE_OK], then the parser assumes that the +** VFS has handled the PRAGMA itself and the parser generates a no-op +** prepared statement. ^If the [SQLITE_FCNTL_PRAGMA] file control returns +** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means +** that the VFS encountered an error while handling the [PRAGMA] and the +** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] +** file control occurs at the beginning of pragma statement analysis and so +** it is able to override built-in [PRAGMA] statements. +** */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 #define SQLITE_SET_LOCKPROXYFILE 3 #define SQLITE_LAST_ERRNO 4 @@ -813,10 +847,11 @@ #define SQLITE_FCNTL_WIN32_AV_RETRY 9 #define SQLITE_FCNTL_PERSIST_WAL 10 #define SQLITE_FCNTL_OVERWRITE 11 #define SQLITE_FCNTL_VFSNAME 12 #define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 +#define SQLITE_FCNTL_PRAGMA 14 /* ** CAPI3REF: Mutex Handle ** ** The mutex module within SQLite defines [sqlite3_mutex] to be an @@ -2642,13 +2677,18 @@ ** has no explicit value, then sqlite3_uri_parameter(F,P) returns ** a pointer to an empty string. ** ** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean ** parameter and returns true (1) or false (0) according to the value -** of P. The value of P is true if it is "yes" or "true" or "on" or -** a non-zero number and is false otherwise. If P is not a query parameter -** on F then sqlite3_uri_boolean(F,P,B) returns (B!=0). +** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the +** value of query parameter P is one of "yes", "true", or "on" in any +** case or if the value begins with a non-zero number. The +** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of +** query parameter P is one of "no", "false", or "off" in any case or +** if the value begins with a numeric zero. If P is not a query +** parameter on F or if the value of P is does not match any of the +** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0). ** ** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a ** 64-bit signed integer and returns that integer, or D if P does not ** exist. If the value of P is something other than an integer, then ** zero is returned. @@ -4457,10 +4497,19 @@ ** will be an absolute pathname, even if the filename used ** to open the database originally was a URI or relative pathname. */ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); +/* +** CAPI3REF: Determine if a database is read-only +** +** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N +** of connection D is read-only, 0 if it is read/write, or -1 if N is not +** the name of a database on connection D. +*/ +SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); + /* ** CAPI3REF: Find the next prepared statement ** ** ^This interface returns a pointer to the next [prepared statement] after ** pStmt associated with the [database connection] pDb. ^If pStmt is NULL @@ -6582,15 +6631,16 @@ /* ** CAPI3REF: String Comparison ** -** ^The [sqlite3_strnicmp()] API allows applications and extensions to -** compare the contents of two buffers containing UTF-8 strings in a -** case-independent fashion, using the same definition of case independence -** that SQLite uses internally when comparing identifiers. +** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications +** and extensions to compare the contents of two buffers containing UTF-8 +** strings in a case-independent fashion, using the same definition of "case +** independence" that SQLite uses internally when comparing identifiers. */ +SQLITE_API int sqlite3_stricmp(const char *, const char *); SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); /* ** CAPI3REF: Error Logging Interface ** Index: SQLite.Interop/src/win/crypt.c ================================================================== --- SQLite.Interop/src/win/crypt.c +++ SQLite.Interop/src/win/crypt.c @@ -375,11 +375,11 @@ } // If we failed, rollback if (rc) { - sqlite3BtreeRollback(pbt); + sqlite3BtreeRollback(pbt, SQLITE_OK); } // If we succeeded, destroy any previous read key this database used // and make the readkey equal to the writekey if (!rc) Index: SQLite.Interop/src/win/interop.c ================================================================== --- SQLite.Interop/src/win/interop.c +++ SQLite.Interop/src/win/interop.c @@ -1,11 +1,16 @@ #define SQLITE_API __declspec(dllexport) #include "../core/sqlite3.c" + +#if defined(INTEROP_EXTENSION_FUNCTIONS) #include "../contrib/extension-functions.c" -#include "crypt.c" - extern int RegisterExtensionFunctions(sqlite3 *db); +#endif + +#if defined(INTEROP_CODEC) +#include "crypt.c" +#endif #ifdef SQLITE_OS_WIN // Additional open flags, we use this one privately //#define SQLITE_OPEN_SHAREDCACHE 0x01000000 @@ -111,12 +116,14 @@ //sqlite3_enable_shared_cache(sharedcache); ret = sqlite3_open_v2(filename, ppdb, flags, NULL); //sqlite3_enable_shared_cache(0); +#if defined(INTEROP_EXTENSION_FUNCTIONS) if (ret == 0) RegisterExtensionFunctions(*ppdb); +#endif return ret; } SQLITE_API int WINAPI sqlite3_open16_interop(const char *filename, int flags, sqlite3 **ppdb) Index: SQLite.Interop/src/win/interop.h ================================================================== --- SQLite.Interop/src/win/interop.h +++ SQLite.Interop/src/win/interop.h @@ -6,7 +6,7 @@ * Released to the public domain, use at your own risk! * */ #ifndef INTEROP_VERSION -#define INTEROP_VERSION "1.0.78.0" +#define INTEROP_VERSION "1.0.81.0" #endif Index: SQLite.MSIL.nuspec ================================================================== --- SQLite.MSIL.nuspec +++ SQLite.MSIL.nuspec @@ -1,10 +1,10 @@ System.Data.SQLite.MSIL - 1.0.78.0 + 1.0.81.0 SQLite Development Team An ADO.NET provider for SQLite (managed-only). en-US http://system.data.sqlite.org/ http://system.data.sqlite.org/images/sqlite32.png ADDED SQLite.NET.2005.MSBuild.sln Index: SQLite.NET.2005.MSBuild.sln ================================================================== --- /dev/null +++ SQLite.NET.2005.MSBuild.sln @@ -0,0 +1,548 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{39A3B743-1EBD-4CC0-8E37-ACE3DD38B1C0}" + ProjectSection(SolutionItems) = preProject + readme.htm = readme.htm + SQLite.NET.Settings.targets = SQLite.NET.Settings.targets + System.Data.SQLite\System.Data.SQLite.Files.targets = System.Data.SQLite\System.Data.SQLite.Files.targets + System.Data.SQLite\System.Data.SQLite.Properties.targets = System.Data.SQLite\System.Data.SQLite.Properties.targets + System.Data.SQLite\System.Data.SQLite.References.targets = System.Data.SQLite\System.Data.SQLite.References.targets + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.2005", "System.Data.SQLite\System.Data.SQLite.2005.csproj", "{AC139952-261A-4463-B6FA-AEBC25283A66}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Module.2005", "System.Data.SQLite\System.Data.SQLite.Module.2005.csproj", "{AC139952-261A-4463-B6FA-AEBC25284A66}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test.2005", "test\test.2005.csproj", "{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.2005", "SQLite.Interop\SQLite.Interop.2005.vcproj", "{53784BC1-A8BC-4AC8-8A3E-158D6807345A}" + ProjectSection(ProjectDependencies) = postProject + {AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLite.Designer.2005", "SQLite.Designer\SQLite.Designer.2005.csproj", "{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Compact.2005", "System.Data.SQLite\System.Data.SQLite.Compact.2005.csproj", "{AC139951-261A-4463-B6FA-AEBC25283A66}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.CE.2005", "SQLite.Interop\SQLite.Interop.CE.2005.vcproj", "{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testce.2005", "testce\testce.2005.csproj", "{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.Static.2005", "SQLite.Interop\SQLite.Interop.Static.2005.vcproj", "{490CBC51-A3B2-4397-89F9-16E858DCB4F8}" + ProjectSection(ProjectDependencies) = postProject + {AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Installer.2005", "tools\install\Installer.2005.csproj", "{A41FE2A5-07AD-4CE7-B836-1544634816F5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Pocket PC 2003 (ARMV4) = Debug|Pocket PC 2003 (ARMV4) + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + DebugManagedOnly|Any CPU = DebugManagedOnly|Any CPU + DebugManagedOnly|Mixed Platforms = DebugManagedOnly|Mixed Platforms + DebugManagedOnly|Pocket PC 2003 (ARMV4) = DebugManagedOnly|Pocket PC 2003 (ARMV4) + DebugManagedOnly|Win32 = DebugManagedOnly|Win32 + DebugManagedOnly|x64 = DebugManagedOnly|x64 + DebugNativeOnly|Any CPU = DebugNativeOnly|Any CPU + DebugNativeOnly|Mixed Platforms = DebugNativeOnly|Mixed Platforms + DebugNativeOnly|Pocket PC 2003 (ARMV4) = DebugNativeOnly|Pocket PC 2003 (ARMV4) + DebugNativeOnly|Win32 = DebugNativeOnly|Win32 + DebugNativeOnly|x64 = DebugNativeOnly|x64 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Pocket PC 2003 (ARMV4) = Release|Pocket PC 2003 (ARMV4) + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseManagedOnly|Any CPU = ReleaseManagedOnly|Any CPU + ReleaseManagedOnly|Mixed Platforms = ReleaseManagedOnly|Mixed Platforms + ReleaseManagedOnly|Pocket PC 2003 (ARMV4) = ReleaseManagedOnly|Pocket PC 2003 (ARMV4) + ReleaseManagedOnly|Win32 = ReleaseManagedOnly|Win32 + ReleaseManagedOnly|x64 = ReleaseManagedOnly|x64 + ReleaseNativeOnly|Any CPU = ReleaseNativeOnly|Any CPU + ReleaseNativeOnly|Mixed Platforms = ReleaseNativeOnly|Mixed Platforms + ReleaseNativeOnly|Pocket PC 2003 (ARMV4) = ReleaseNativeOnly|Pocket PC 2003 (ARMV4) + ReleaseNativeOnly|Win32 = ReleaseNativeOnly|Win32 + ReleaseNativeOnly|x64 = ReleaseNativeOnly|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.Build.0 = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.ActiveCfg = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.Build.0 = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.ActiveCfg = Debug|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.Build.0 = Debug|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|Win32.ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugManagedOnly|x64.ActiveCfg = DebugNativeOnly|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.ActiveCfg = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.Build.0 = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.Build.0 = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.ActiveCfg = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.Build.0 = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.ActiveCfg = Release|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.Build.0 = Release|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseManagedOnly|x64.ActiveCfg = ReleaseNativeOnly|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64 + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Win32.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Win32.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|x64.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|x64.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Any CPU.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Win32.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Win32.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|x64.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|x64.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Any CPU.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Any CPU.Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Any CPU.Deploy.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Mixed Platforms.Deploy.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|x64.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugManagedOnly|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugManagedOnly|x64.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Any CPU.Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Any CPU.Deploy.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Mixed Platforms.Deploy.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|x64.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Any CPU.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Any CPU.Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Any CPU.Deploy.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Mixed Platforms.Deploy.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|x64.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseManagedOnly|x64.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Any CPU.Deploy.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Mixed Platforms.Deploy.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|x64.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|x64.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Any CPU.Deploy.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Mixed Platforms.Deploy.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Any CPU.Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Any CPU.Deploy.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Win32.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|x64.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Any CPU.Deploy.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Mixed Platforms.Deploy.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.Build.0 = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.Build.0 = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.ActiveCfg = Debug|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.Build.0 = Debug|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|Win32.ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugManagedOnly|x64.ActiveCfg = DebugNativeOnly|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.ActiveCfg = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.Build.0 = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.Build.0 = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.ActiveCfg = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.Build.0 = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.ActiveCfg = Release|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.Build.0 = Release|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseManagedOnly|x64.ActiveCfg = ReleaseNativeOnly|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64 + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Any CPU.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Any CPU.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Win32.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|Win32.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|x64.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugManagedOnly|x64.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Any CPU.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Any CPU.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Mixed Platforms.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Win32.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|Win32.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|x64.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseManagedOnly|x64.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal ADDED SQLite.NET.2005.sln Index: SQLite.NET.2005.sln ================================================================== --- /dev/null +++ SQLite.NET.2005.sln @@ -0,0 +1,425 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{39A3B743-1EBD-4CC0-8E37-ACE3DD38B1C0}" + ProjectSection(SolutionItems) = preProject + readme.htm = readme.htm + SQLite.NET.Settings.targets = SQLite.NET.Settings.targets + System.Data.SQLite\System.Data.SQLite.Files.targets = System.Data.SQLite\System.Data.SQLite.Files.targets + System.Data.SQLite\System.Data.SQLite.Properties.targets = System.Data.SQLite\System.Data.SQLite.Properties.targets + System.Data.SQLite\System.Data.SQLite.References.targets = System.Data.SQLite\System.Data.SQLite.References.targets + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.2005", "System.Data.SQLite\System.Data.SQLite.2005.csproj", "{AC139952-261A-4463-B6FA-AEBC25283A66}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Module.2005", "System.Data.SQLite\System.Data.SQLite.Module.2005.csproj", "{AC139952-261A-4463-B6FA-AEBC25284A66}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite.Compact.2005", "System.Data.SQLite\System.Data.SQLite.Compact.2005.csproj", "{AC139951-261A-4463-B6FA-AEBC25283A66}" + ProjectSection(ProjectDependencies) = postProject + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6} = {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test.2005", "test\test.2005.csproj", "{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.2005", "SQLite.Interop\SQLite.Interop.2005.vcproj", "{53784BC1-A8BC-4AC8-8A3E-158D6807345A}" + ProjectSection(ProjectDependencies) = postProject + {AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLite.Designer.2005", "SQLite.Designer\SQLite.Designer.2005.csproj", "{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testce.2005", "testce\testce.2005.csproj", "{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.CE.2005", "SQLite.Interop\SQLite.Interop.CE.2005.vcproj", "{9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop.Static.2005", "SQLite.Interop\SQLite.Interop.Static.2005.vcproj", "{490CBC51-A3B2-4397-89F9-16E858DCB4F8}" + ProjectSection(ProjectDependencies) = postProject + {AC139952-261A-4463-B6FA-AEBC25284A66} = {AC139952-261A-4463-B6FA-AEBC25284A66} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Installer.2005", "tools\install\Installer.2005.csproj", "{A41FE2A5-07AD-4CE7-B836-1544634816F5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Pocket PC 2003 (ARMV4) = Debug|Pocket PC 2003 (ARMV4) + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + DebugNativeOnly|Any CPU = DebugNativeOnly|Any CPU + DebugNativeOnly|Mixed Platforms = DebugNativeOnly|Mixed Platforms + DebugNativeOnly|Pocket PC 2003 (ARMV4) = DebugNativeOnly|Pocket PC 2003 (ARMV4) + DebugNativeOnly|Win32 = DebugNativeOnly|Win32 + DebugNativeOnly|x64 = DebugNativeOnly|x64 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Pocket PC 2003 (ARMV4) = Release|Pocket PC 2003 (ARMV4) + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseNativeOnly|Any CPU = ReleaseNativeOnly|Any CPU + ReleaseNativeOnly|Mixed Platforms = ReleaseNativeOnly|Mixed Platforms + ReleaseNativeOnly|Pocket PC 2003 (ARMV4) = ReleaseNativeOnly|Pocket PC 2003 (ARMV4) + ReleaseNativeOnly|Win32 = ReleaseNativeOnly|Win32 + ReleaseNativeOnly|x64 = ReleaseNativeOnly|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|Win32.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Debug|x64.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Any CPU.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|Win32.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.Release|x64.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {AC139952-261A-4463-B6FA-AEBC25284A66}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {AC139951-261A-4463-B6FA-AEBC25283A66}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Any CPU.Build.0 = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.ActiveCfg = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|Win32.Build.0 = Debug|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.ActiveCfg = Debug|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Debug|x64.Build.0 = Debug|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.ActiveCfg = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Any CPU.Build.0 = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Mixed Platforms.Build.0 = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.ActiveCfg = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|Win32.Build.0 = Release|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.ActiveCfg = Release|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.Release|x64.Build.0 = Release|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64 + {53784BC1-A8BC-4AC8-8A3E-158D6807345A}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64 + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Win32.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Win32.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|x64.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|x64.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Any CPU.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Win32.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Win32.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|x64.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|x64.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|x64.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Any CPU.Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Win32.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|x64.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Any CPU.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Any CPU.Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Debug|x64.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Any CPU.Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.DebugNativeOnly|x64.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Any CPU.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Any CPU.Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.Release|x64.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {9E5A8F20-5F04-4629-B2E1-27B5E30F2AF6}.ReleaseNativeOnly|x64.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Any CPU.Build.0 = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|Win32.Build.0 = Debug|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.ActiveCfg = Debug|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Debug|x64.Build.0 = Debug|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Any CPU.Build.0 = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Mixed Platforms.Build.0 = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.ActiveCfg = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|Win32.Build.0 = DebugNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.ActiveCfg = DebugNativeOnly|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.DebugNativeOnly|x64.Build.0 = DebugNativeOnly|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.ActiveCfg = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Any CPU.Build.0 = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Mixed Platforms.Build.0 = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.ActiveCfg = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|Win32.Build.0 = Release|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.ActiveCfg = Release|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.Release|x64.Build.0 = Release|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Any CPU.Build.0 = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Mixed Platforms.Build.0 = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.ActiveCfg = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|Win32.Build.0 = ReleaseNativeOnly|Win32 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.ActiveCfg = ReleaseNativeOnly|x64 + {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64 + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU + {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal Index: SQLite.NET.2010.sln ================================================================== --- SQLite.NET.2010.sln +++ SQLite.NET.2010.sln @@ -315,38 +315,34 @@ {490CBC51-A3B2-4397-89F9-16E858DCB4F8}.ReleaseNativeOnly|x64.Build.0 = ReleaseNativeOnly|x64 {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Any CPU.Build.0 = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.ActiveCfg = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|Win32.Build.0 = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.ActiveCfg = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Debug|x64.Build.0 = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Any CPU.ActiveCfg = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Any CPU.Build.0 = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Mixed Platforms.ActiveCfg = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Mixed Platforms.Build.0 = Debug|Any CPU - {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Win32.ActiveCfg = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|Win32.Build.0 = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|x64.ActiveCfg = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.DebugNativeOnly|x64.Build.0 = Debug|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.ActiveCfg = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Any CPU.Build.0 = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.ActiveCfg = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|Win32.Build.0 = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.ActiveCfg = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.Release|x64.Build.0 = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Any CPU.ActiveCfg = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Any CPU.Build.0 = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Mixed Platforms.ActiveCfg = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Mixed Platforms.Build.0 = Release|Any CPU - {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Win32.ActiveCfg = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|Win32.Build.0 = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|x64.ActiveCfg = Release|Any CPU {A41FE2A5-07AD-4CE7-B836-1544634816F5}.ReleaseNativeOnly|x64.Build.0 = Release|Any CPU EndGlobalSection Index: SQLite.NET.Settings.targets ================================================================== --- SQLite.NET.Settings.targets +++ SQLite.NET.Settings.targets @@ -112,10 +112,54 @@ default, this is enabled. If this is disabled, an exception will not be thrown when a SQLite object which has already been disposed is accessed. --> true + + + true + + + true + + + true + + + + + + + + + + + + + + + + Index: SQLite.nuspec ================================================================== --- SQLite.nuspec +++ SQLite.nuspec @@ -1,11 +1,11 @@ System.Data.SQLite System.Data.SQLite (x86) - 1.0.78.0 + 1.0.81.0 SQLite Development Team The official SQLite database engine combined with a complete ADO.NET provider all rolled into a single mixed-mode assembly for x86. en-US http://system.data.sqlite.org/ http://system.data.sqlite.org/images/sqlite32.png Index: SQLite.x64.nuspec ================================================================== --- SQLite.x64.nuspec +++ SQLite.x64.nuspec @@ -1,10 +1,10 @@ System.Data.SQLite.x64 - 1.0.78.0 + 1.0.81.0 SQLite Development Team The official SQLite database engine combined with a complete ADO.NET provider all rolled into a single mixed-mode assembly for x64. en-US http://system.data.sqlite.org/ http://system.data.sqlite.org/images/sqlite32.png Index: SQLite.x86.nuspec ================================================================== --- SQLite.x86.nuspec +++ SQLite.x86.nuspec @@ -1,10 +1,10 @@ System.Data.SQLite.x86 - 1.0.78.0 + 1.0.81.0 SQLite Development Team The official SQLite database engine combined with a complete ADO.NET provider all rolled into a single mixed-mode assembly for x86. en-US http://system.data.sqlite.org/ http://system.data.sqlite.org/images/sqlite32.png Index: Setup/SQLite.iss ================================================================== --- Setup/SQLite.iss +++ Setup/SQLite.iss @@ -15,11 +15,11 @@ #else #define InstallerCondition "Application\Core\MSIL and Application\Core\" + AppProcessor + " and Application\Designer and Application\Designer\Installer" #define AppVersion GetStringFileInfo("..\bin\" + Year + "\" + BaseConfiguration + "\bin\System.Data.SQLite.dll", PRODUCT_VERSION) #define OutputConfiguration StringChange(StringChange(BaseConfiguration, "Debug", "setup"), "Release", "setup") #endif - + [Setup] AllowNoIcons=true #if AppProcessor != "x86" ArchitecturesAllowed={#AppProcessor} @@ -54,38 +54,50 @@ [Components] Name: Application; Description: System.Data.SQLite components.; Types: custom compact full Name: Application\Core; Description: Core components.; Types: custom compact full Name: Application\Core\MSIL; Description: Core managed components.; Types: custom compact full -Name: Application\Core\{#AppProcessor}; Description: Core native components.; Types: custom compact full +Name: Application\Core\{#AppProcessor}; Description: Core native {#AppProcessor} components.; Types: custom compact full Name: Application\LINQ; Description: LINQ support components.; Types: custom compact full Name: Application\Designer; Description: Visual Studio designer components.; Types: custom full Name: Application\Designer\Installer; Description: Visual Studio designer installer components.; Types: custom full Name: Application\Symbols; Description: Debugging symbol components.; Types: custom compact full Name: Application\Documentation; Description: Documentation components.; Types: custom compact full Name: Application\Test; Description: Test components.; Types: custom compact full [Tasks] Components: Application\Core\MSIL Or Application\LINQ; Name: ngen; Description: Generate native images for the assemblies and install the images in the native image cache.; Check: CheckIsNetFx2Setup() or CheckIsNetFx4Setup() -Components: {#InstallerCondition}; Name: vs2008; Description: Install the designer components for Visual Studio 2008.; Check: CheckIsNetFx2Setup() -Components: {#InstallerCondition}; Name: vs2010; Description: Install the designer components for Visual Studio 2010.; Check: CheckIsNetFx4Setup() #if Pos("NativeOnly", AppConfiguration) == 0 Components: Application\Core\MSIL Or Application\LINQ; Name: gac; Description: Install the assemblies into the global assembly cache.; Flags: unchecked; Check: CheckIsNetFx2Setup() or CheckIsNetFx4Setup() + +#if AppProcessor == "x86" +Components: {#InstallerCondition}; Name: gac\vs2005; Description: Install the designer components for Visual Studio 2005.; Flags: unchecked; Check: CheckIsNetFx2Setup() +Components: {#InstallerCondition}; Name: gac\vs2008; Description: Install the designer components for Visual Studio 2008.; Flags: unchecked; Check: CheckIsNetFx2Setup() +Components: {#InstallerCondition}; Name: gac\vs2010; Description: Install the designer components for Visual Studio 2010.; Flags: unchecked; Check: CheckIsNetFx4Setup() +#endif #endif [Run] Components: Application\Core\MSIL; Tasks: ngen; Filename: {code:GetNetFx2InstallRoot|Ngen.exe}; Parameters: "install ""{app}\bin\System.Data.SQLite.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() Components: Application\Core\MSIL; Tasks: ngen; Filename: {code:GetNetFx4InstallRoot|Ngen.exe}; Parameters: "install ""{app}\bin\System.Data.SQLite.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup() Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx2InstallRoot|Ngen.exe}; Parameters: "install ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() and CheckForNetFx35(1) Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx4InstallRoot|Ngen.exe}; Parameters: "install ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup() -Components: {#InstallerCondition}; Tasks: vs2008; Filename: {app}\bin\Installer.exe; Parameters: "-install true -installFlags AllExceptGAC -tracePriority Lowest -verbose true -noCompact true -noNetFx40 true -noVs2010 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() -Components: {#InstallerCondition}; Tasks: vs2010; Filename: {app}\bin\Installer.exe; Parameters: "-install true -installFlags AllExceptGAC -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noVs2008 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup() + +#if Pos("NativeOnly", AppConfiguration) == 0 && AppProcessor == "x86" +Components: {#InstallerCondition}; Tasks: gac\vs2005; Filename: {app}\bin\Installer.exe; Parameters: "-install true -wow64 true -installFlags AllExceptGAC -tracePriority Lowest -verbose true -noCompact true -noNetFx40 true -noVs2008 true -noVs2010 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() +Components: {#InstallerCondition}; Tasks: gac\vs2008; Filename: {app}\bin\Installer.exe; Parameters: "-install true -wow64 true -installFlags AllExceptGAC -tracePriority Lowest -verbose true -noCompact true -noNetFx40 true -noVs2005 true -noVs2010 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() +Components: {#InstallerCondition}; Tasks: gac\vs2010; Filename: {app}\bin\Installer.exe; Parameters: "-install true -wow64 true -installFlags AllExceptGAC -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noVs2005 true -noVs2008 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup() +#endif [UninstallRun] -Components: {#InstallerCondition}; Tasks: vs2010; Filename: {app}\bin\Installer.exe; Parameters: "-install false -installFlags AllExceptGAC -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noVs2008 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup() -Components: {#InstallerCondition}; Tasks: vs2008; Filename: {app}\bin\Installer.exe; Parameters: "-install false -installFlags AllExceptGAC -tracePriority Lowest -verbose true -noCompact true -noNetFx40 true -noVs2010 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() +#if Pos("NativeOnly", AppConfiguration) == 0 && AppProcessor == "x86" +Components: {#InstallerCondition}; Tasks: gac\vs2010; Filename: {app}\bin\Installer.exe; Parameters: "-install false -wow64 true -installFlags AllExceptGAC -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noVs2005 true -noVs2008 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup() +Components: {#InstallerCondition}; Tasks: gac\vs2008; Filename: {app}\bin\Installer.exe; Parameters: "-install false -wow64 true -installFlags AllExceptGAC -tracePriority Lowest -verbose true -noCompact true -noNetFx40 true -noVs2005 true -noVs2010 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() +Components: {#InstallerCondition}; Tasks: gac\vs2005; Filename: {app}\bin\Installer.exe; Parameters: "-install false -wow64 true -installFlags AllExceptGAC -tracePriority Lowest -verbose true -noCompact true -noNetFx40 true -noVs2008 true -noVs2010 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() +#endif + Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx4InstallRoot|Ngen.exe}; Parameters: "uninstall ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup() Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx2InstallRoot|Ngen.exe}; Parameters: "uninstall ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() and CheckForNetFx35(1) Components: Application\Core\MSIL; Tasks: ngen; Filename: {code:GetNetFx4InstallRoot|Ngen.exe}; Parameters: "uninstall ""{app}\bin\System.Data.SQLite.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup() Components: Application\Core\MSIL; Tasks: ngen; Filename: {code:GetNetFx2InstallRoot|Ngen.exe}; Parameters: "uninstall ""{app}\bin\System.Data.SQLite.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() Index: Setup/archive.bat ================================================================== --- Setup/archive.bat +++ Setup/archive.bat @@ -9,11 +9,12 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO +REM SET __ECHO2=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -27,11 +28,11 @@ %_VECHO% Root = '%ROOT%' %_VECHO% Tools = '%TOOLS%' CALL :fn_ResetErrorLevel -%_ECHO% PUSHD "%ROOT%" +%__ECHO2% PUSHD "%ROOT%" IF ERRORLEVEL 1 ( ECHO Could not change directory to "%ROOT%". GOTO errors ) @@ -65,26 +66,26 @@ %_VECHO% Version = '%VERSION%' CALL :fn_ResetErrorLevel IF NOT EXIST Setup\Output ( - %_ECHO% MKDIR Setup\Output + %__ECHO% MKDIR Setup\Output IF ERRORLEVEL 1 ( ECHO Could not create directory "Setup\Output". GOTO errors ) ) -%_ECHO% zip.exe -v -r Setup\Output\sqlite-netFx-source-%VERSION%.zip * -x @exclude_src.txt +%__ECHO% zip.exe -v -r Setup\Output\sqlite-netFx-source-%VERSION%.zip * -x @exclude_src.txt IF ERRORLEVEL 1 ( ECHO Failed to archive source files. GOTO errors ) -%_ECHO% POPD +%__ECHO2% POPD IF ERRORLEVEL 1 ( ECHO Could not restore directory. GOTO errors ) @@ -118,6 +119,6 @@ ECHO. ECHO Archive success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% Index: Setup/bake.bat ================================================================== --- Setup/bake.bat +++ Setup/bake.bat @@ -9,11 +9,11 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -40,11 +40,11 @@ SET PATH=%ProgramFiles%\Inno Setup 5;%PATH% :set_path_done %_VECHO% Path = '%PATH%' -%_ECHO% ISCC.exe "%TOOLS%\SQLite.iss" "/dAppId=%APPID%" "/dAppPublicKey=%PUBLICKEY%" "/dAppURL=%URL%" "/dIsNetFx2=%ISNETFX2%" "/dVcRuntime=%VCRUNTIME%" "/dAppConfiguration=%CONFIGURATION%" "/dAppPlatform=%PLATFORM%" "/dAppProcessor=%PROCESSOR%" "/dFramework=%FRAMEWORK%" "/dYear=%YEAR%" +%__ECHO% ISCC.exe "%TOOLS%\SQLite.iss" "/dAppId=%APPID%" "/dAppPublicKey=%PUBLICKEY%" "/dAppURL=%URL%" "/dIsNetFx2=%ISNETFX2%" "/dVcRuntime=%VCRUNTIME%" "/dAppConfiguration=%CONFIGURATION%" "/dAppPlatform=%PLATFORM%" "/dAppProcessor=%PROCESSOR%" "/dFramework=%FRAMEWORK%" "/dYear=%YEAR%" IF %ERRORLEVEL% NEQ 0 ( ECHO Failed to compile setup. GOTO errors ) @@ -51,12 +51,12 @@ GOTO no_errors :fn_SetVariable SETLOCAL - SET _ECHO_CMD=ECHO %%%2%% - FOR /F "delims=" %%V IN ('%_ECHO_CMD%') DO ( + SET __ECHO_CMD=ECHO %%%2%% + FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO ( SET VALUE=%%V ) ENDLOCAL && ( SET %1=%VALUE% ) @@ -83,6 +83,6 @@ ECHO. ECHO Bake success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% Index: Setup/bake_all.bat ================================================================== --- Setup/bake_all.bat +++ Setup/bake_all.bat @@ -9,11 +9,12 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO +REM SET __ECHO3=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -23,18 +24,18 @@ %_VECHO% Tools = '%TOOLS%' CALL :fn_ResetErrorLevel -%_ECHO% CALL "%TOOLS%\vsSp.bat" +%__ECHO3% CALL "%TOOLS%\vsSp.bat" IF ERRORLEVEL 1 ( ECHO Could not detect Visual Studio. GOTO errors ) -%_ECHO% CALL "%TOOLS%\set_common.bat" +%__ECHO3% CALL "%TOOLS%\set_common.bat" IF ERRORLEVEL 1 ( ECHO Could not set common variables. GOTO errors ) @@ -58,18 +59,18 @@ %_VECHO% Years = '%YEARS%' FOR %%C IN (%BAKE_CONFIGURATIONS%) DO ( FOR %%P IN (%PROCESSORS%) DO ( FOR %%Y IN (%YEARS%) DO ( - %_ECHO% CALL "%TOOLS%\set_%%C_%%P_%%Y.bat" + %__ECHO3% CALL "%TOOLS%\set_%%C_%%P_%%Y.bat" IF ERRORLEVEL 1 ( ECHO Could not set variables for %%C/%%P/%%Y. GOTO errors ) - %_ECHO% CALL "%TOOLS%\bake.bat" + %__ECHO3% CALL "%TOOLS%\bake.bat" IF ERRORLEVEL 1 ( ECHO Could not bake setup for %%C/%%P/%%Y. GOTO errors ) @@ -100,6 +101,6 @@ ECHO. ECHO Success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% Index: Setup/build.bat ================================================================== --- Setup/build.bat +++ Setup/build.bat @@ -9,11 +9,13 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO +REM SET __ECHO2=ECHO +REM SET __ECHO3=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -52,11 +54,11 @@ IF EXIST "%TOOLS%\set_%CONFIGURATION%_%PLATFORM%.bat" ( CALL :fn_ResetErrorLevel %_AECHO% Running "%TOOLS%\set_%CONFIGURATION%_%PLATFORM%.bat"... - %_ECHO% CALL "%TOOLS%\set_%CONFIGURATION%_%PLATFORM%.bat" + %__ECHO3% CALL "%TOOLS%\set_%CONFIGURATION%_%PLATFORM%.bat" IF ERRORLEVEL 1 ( ECHO File "%TOOLS%\set_%CONFIGURATION%_%PLATFORM%.bat" failed. GOTO errors ) @@ -128,11 +130,11 @@ %_VECHO% Year = '%YEAR%' %_VECHO% FrameworkDir = '%FRAMEWORKDIR%' CALL :fn_ResetErrorLevel -%_ECHO% PUSHD "%ROOT%" +%__ECHO2% PUSHD "%ROOT%" IF ERRORLEVEL 1 ( ECHO Could not change directory to "%ROOT%". GOTO errors ) @@ -191,18 +193,18 @@ :skip_setLogging %_VECHO% Logging = '%LOGGING%' -%_ECHO% MSBuild.exe "%SOLUTION%" "/target:%TARGET%" "/property:Configuration=%CONFIGURATION%" "/property:Platform=%PLATFORM%" %LOGGING% %MSBUILD_ARGS% +%__ECHO% MSBuild.exe "%SOLUTION%" "/target:%TARGET%" "/property:Configuration=%CONFIGURATION%" "/property:Platform=%PLATFORM%" %LOGGING% %MSBUILD_ARGS% IF ERRORLEVEL 1 ( ECHO Build failed. GOTO errors ) -%_ECHO% POPD +%__ECHO2% POPD IF ERRORLEVEL 1 ( ECHO Could not restore directory. GOTO errors ) @@ -210,12 +212,12 @@ GOTO no_errors :fn_UnquoteVariable SETLOCAL IF NOT DEFINED %1 GOTO :EOF - SET _ECHO_CMD=ECHO %%%1%% - FOR /F "delims=" %%V IN ('%_ECHO_CMD%') DO ( + SET __ECHO_CMD=ECHO %%%1%% + FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO ( SET VALUE=%%V ) SET VALUE=%VALUE:"=% REM " ENDLOCAL && SET %1=%VALUE% @@ -255,6 +257,6 @@ ECHO. ECHO Build success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% Index: Setup/build_all.bat ================================================================== --- Setup/build_all.bat +++ Setup/build_all.bat @@ -9,11 +9,12 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO +REM SET __ECHO3=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -23,18 +24,18 @@ %_VECHO% Tools = '%TOOLS%' CALL :fn_ResetErrorLevel -%_ECHO% CALL "%TOOLS%\vsSp.bat" +%__ECHO3% CALL "%TOOLS%\vsSp.bat" IF ERRORLEVEL 1 ( ECHO Could not detect Visual Studio. GOTO errors ) -%_ECHO% CALL "%TOOLS%\set_common.bat" +%__ECHO3% CALL "%TOOLS%\set_common.bat" IF ERRORLEVEL 1 ( ECHO Could not set common variables. GOTO errors ) @@ -58,18 +59,18 @@ %_VECHO% Years = '%YEARS%' FOR %%C IN (%BUILD_CONFIGURATIONS%) DO ( FOR %%P IN (%PLATFORMS%) DO ( FOR %%Y IN (%YEARS%) DO ( - %_ECHO% CALL "%TOOLS%\set_%%Y.bat" + %__ECHO3% CALL "%TOOLS%\set_%%Y.bat" IF ERRORLEVEL 1 ( ECHO Could not set variables for %%Y. GOTO errors ) - %_ECHO% CALL "%TOOLS%\build.bat" %%C %%P + %__ECHO3% CALL "%TOOLS%\build.bat" %%C %%P IF ERRORLEVEL 1 ( ECHO Could not build binaries for %%C/%%P/%%Y. GOTO errors ) @@ -100,6 +101,6 @@ ECHO. ECHO Success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% Index: Setup/build_ce.bat ================================================================== --- Setup/build_ce.bat +++ Setup/build_ce.bat @@ -9,11 +9,12 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO +REM SET __ECHO3=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -30,11 +31,11 @@ SET YEARS=2008 SET BASE_PLATFORM=PocketPC CALL :fn_ResetErrorLevel -%_ECHO% CALL "%TOOLS%\build_all.bat" +%__ECHO3% CALL "%TOOLS%\build_all.bat" IF ERRORLEVEL 1 ( ECHO Failed to build PocketPC binaries. GOTO errors ) @@ -66,6 +67,6 @@ ECHO. ECHO Build success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% Index: Setup/clean.bat ================================================================== --- Setup/clean.bat +++ Setup/clean.bat @@ -9,11 +9,11 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -58,11 +58,11 @@ %_AECHO%. FOR %%D IN (%CLEANDIRS%) DO ( IF EXIST "%SOURCE%\%%D" ( - %_ECHO% RMDIR /S /Q "%SOURCE%\%%D" + %__ECHO% RMDIR /S /Q "%SOURCE%\%%D" IF ERRORLEVEL 1 ( ECHO Could not remove directory "%SOURCE%\%%D". ECHO. GOTO errors @@ -75,11 +75,11 @@ %_AECHO%. ) ) IF EXIST "%SOURCE%\*.nupkg" ( - %_ECHO% DEL /Q "%SOURCE%\*.nupkg" + %__ECHO% DEL /Q "%SOURCE%\*.nupkg" IF ERRORLEVEL 1 ( ECHO Could not delete "%SOURCE%\*.nupkg". ECHO. GOTO errors @@ -91,11 +91,11 @@ %_AECHO% No files matching "%SOURCE%\*.nupkg" exist. %_AECHO%. ) IF EXIST "%SOURCE%\Doc\SQLite.NET.chw" ( - %_ECHO% DEL /Q "%SOURCE%\Doc\SQLite.NET.chw" + %__ECHO% DEL /Q "%SOURCE%\Doc\SQLite.NET.chw" IF ERRORLEVEL 1 ( ECHO Could not delete "%SOURCE%\Doc\SQLite.NET.chw". ECHO. GOTO errors @@ -107,11 +107,11 @@ %_AECHO% No files matching "%SOURCE%\Doc\SQLite.NET.chw" exist. %_AECHO%. ) IF EXIST "%SOURCE%\Externals\Eagle\bin\sqlite3.*" ( - %_ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\sqlite3.*" + %__ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\sqlite3.*" IF ERRORLEVEL 1 ( ECHO Could not delete "%SOURCE%\Externals\Eagle\bin\sqlite3.*". ECHO. GOTO errors @@ -123,11 +123,11 @@ %_AECHO% No files matching "%SOURCE%\Externals\Eagle\bin\sqlite3.*" exist. %_AECHO%. ) IF EXIST "%SOURCE%\Externals\Eagle\bin\SQLite.Interop.*" ( - %_ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\SQLite.Interop.*" + %__ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\SQLite.Interop.*" IF ERRORLEVEL 1 ( ECHO Could not delete "%SOURCE%\Externals\Eagle\bin\SQLite.Interop.*". ECHO. GOTO errors @@ -139,11 +139,11 @@ %_AECHO% No files matching "%SOURCE%\Externals\Eagle\bin\SQLite.Interop.*" exist. %_AECHO%. ) IF EXIST "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.*" ( - %_ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.*" + %__ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.*" IF ERRORLEVEL 1 ( ECHO Could not delete "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.*". ECHO. GOTO errors @@ -155,11 +155,11 @@ %_AECHO% No files matching "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.*" exist. %_AECHO%. ) IF EXIST "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.Linq.*" ( - %_ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.Linq.*" + %__ECHO% DEL /Q "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.Linq.*" IF ERRORLEVEL 1 ( ECHO Could not delete "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.Linq.*". ECHO. GOTO errors @@ -171,11 +171,11 @@ %_AECHO% No files matching "%SOURCE%\Externals\Eagle\bin\System.Data.SQLite.Linq.*" exist. %_AECHO%. ) IF EXIST "%TEMP%\EagleShell.exe.test.*.log" ( - %_ECHO% DEL /Q "%TEMP%\EagleShell.exe.test.*.log" + %__ECHO% DEL /Q "%TEMP%\EagleShell.exe.test.*.log" IF ERRORLEVEL 1 ( ECHO Could not delete "%TEMP%\EagleShell.exe.test.*.log". ECHO. GOTO errors @@ -187,11 +187,11 @@ %_AECHO% No files matching "%TEMP%\EagleShell.exe.test.*.log" exist. %_AECHO%. ) IF EXIST "%TEMP%\mono.exe.test.*.log" ( - %_ECHO% DEL /Q "%TEMP%\mono.exe.test.*.log" + %__ECHO% DEL /Q "%TEMP%\mono.exe.test.*.log" IF ERRORLEVEL 1 ( ECHO Could not delete "%TEMP%\mono.exe.test.*.log". ECHO. GOTO errors @@ -203,11 +203,11 @@ %_AECHO% No files matching "%TEMP%\mono.exe.test.*.log" exist. %_AECHO%. ) IF EXIST "%TEMP%\tclsh*.exe.test.*.log" ( - %_ECHO% DEL /Q "%TEMP%\tclsh*.exe.test.*.log" + %__ECHO% DEL /Q "%TEMP%\tclsh*.exe.test.*.log" IF ERRORLEVEL 1 ( ECHO Could not delete "%TEMP%\tclsh*.exe.test.*.log". ECHO. GOTO errors @@ -251,6 +251,6 @@ ECHO. ECHO Clean success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% Index: Setup/release.bat ================================================================== --- Setup/release.bat +++ Setup/release.bat @@ -9,11 +9,13 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO +REM SET __ECHO2=ECHO +REM SET __ECHO3=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -80,11 +82,11 @@ %_VECHO% Type = '%TYPE%' CALL :fn_ResetErrorLevel -%_ECHO% CALL "%TOOLS%\set_common.bat" +%__ECHO3% CALL "%TOOLS%\set_common.bat" IF ERRORLEVEL 1 ( ECHO Could not set common variables. GOTO errors ) @@ -108,11 +110,11 @@ %_VECHO% Root = '%ROOT%' %_VECHO% Tools = '%TOOLS%' CALL :fn_ResetErrorLevel -%_ECHO% PUSHD "%ROOT%" +%__ECHO2% PUSHD "%ROOT%" IF ERRORLEVEL 1 ( ECHO Could not change directory to "%ROOT%". GOTO errors ) @@ -146,38 +148,44 @@ %_VECHO% Version = '%VERSION%' CALL :fn_ResetErrorLevel IF NOT EXIST Setup\Output ( - %_ECHO% MKDIR Setup\Output + %__ECHO% MKDIR Setup\Output IF ERRORLEVEL 1 ( ECHO Could not create directory "Setup\Output". GOTO errors ) ) IF DEFINED BASE_CONFIGURATIONSUFFIX ( - %_ECHO% zip.exe -v -j -r "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" "bin\%YEAR%\%BASE_CONFIGURATION%%BASE_CONFIGURATIONSUFFIX%\bin" -x @exclude_bin.txt + FOR /F "delims=" %%F IN ('DIR /B /S /AD "bin\%YEAR%\%BASE_CONFIGURATION%%BASE_CONFIGURATIONSUFFIX%\bin" 2^> NUL') DO ( + %__ECHO% RMDIR /S /Q "%%F" + ) + %__ECHO% zip.exe -v -j -r "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" "bin\%YEAR%\%BASE_CONFIGURATION%%BASE_CONFIGURATIONSUFFIX%\bin" -x @exclude_bin.txt ) ELSE ( - %_ECHO% zip.exe -v -j -r "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" "bin\%YEAR%\%BASE_CONFIGURATION%\bin" -x @exclude_bin.txt + FOR /F "delims=" %%F IN ('DIR /B /S /AD "bin\%YEAR%\%BASE_CONFIGURATION%\bin" 2^> NUL') DO ( + %__ECHO% RMDIR /S /Q "%%F" + ) + %__ECHO% zip.exe -v -j -r "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" "bin\%YEAR%\%BASE_CONFIGURATION%\bin" -x @exclude_bin.txt ) IF /I "%CONFIGURATION%" == "%BASE_CONFIGURATION%" ( IF NOT DEFINED BASE_CONFIGURATIONSUFFIX ( - %_ECHO% zip -v -d "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" SQLite.Interop.* + %__ECHO% zip -v -d "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" SQLite.Interop.* ) ) -%_ECHO% zip.exe -v -j -r "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" "bin\%YEAR%\%PLATFORM%\%CONFIGURATION%%CONFIGURATIONSUFFIX%" -x @exclude_bin.txt +%__ECHO% zip.exe -v -j -r "Setup\Output\sqlite-%FRAMEWORK%-%TYPE%-%BASE_PLATFORM%-%YEAR%-%VERSION%.zip" "bin\%YEAR%\%PLATFORM%\%CONFIGURATION%%CONFIGURATIONSUFFIX%" -x @exclude_bin.txt IF ERRORLEVEL 1 ( ECHO Failed to archive binary files. GOTO errors ) -%_ECHO% POPD +%__ECHO2% POPD IF ERRORLEVEL 1 ( ECHO Could not restore directory. GOTO errors ) @@ -184,12 +192,12 @@ GOTO no_errors :fn_SetVariable SETLOCAL - SET _ECHO_CMD=ECHO %%%2%% - FOR /F "delims=" %%V IN ('%_ECHO_CMD%') DO ( + SET __ECHO_CMD=ECHO %%%2%% + FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO ( SET VALUE=%%V ) ENDLOCAL && ( SET %1=%VALUE% ) @@ -196,12 +204,12 @@ GOTO :EOF :fn_UnquoteVariable SETLOCAL IF NOT DEFINED %1 GOTO :EOF - SET _ECHO_CMD=ECHO %%%1%% - FOR /F "delims=" %%V IN ('%_ECHO_CMD%') DO ( + SET __ECHO_CMD=ECHO %%%1%% + FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO ( SET VALUE=%%V ) SET VALUE=%VALUE:"=% REM " ENDLOCAL && SET %1=%VALUE% @@ -234,6 +242,6 @@ ECHO. ECHO Release success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% Index: Setup/release_all.bat ================================================================== --- Setup/release_all.bat +++ Setup/release_all.bat @@ -9,11 +9,12 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO +REM SET __ECHO3=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -23,18 +24,18 @@ %_VECHO% Tools = '%TOOLS%' CALL :fn_ResetErrorLevel -%_ECHO% CALL "%TOOLS%\vsSp.bat" +%__ECHO3% CALL "%TOOLS%\vsSp.bat" IF ERRORLEVEL 1 ( ECHO Could not detect Visual Studio. GOTO errors ) -%_ECHO% CALL "%TOOLS%\set_common.bat" +%__ECHO3% CALL "%TOOLS%\set_common.bat" IF ERRORLEVEL 1 ( ECHO Could not set common variables. GOTO errors ) @@ -58,11 +59,11 @@ %_VECHO% Years = '%YEARS%' FOR %%C IN (%RELEASE_CONFIGURATIONS%) DO ( FOR %%P IN (%PLATFORMS%) DO ( FOR %%Y IN (%YEARS%) DO ( - %_ECHO% CALL "%TOOLS%\release.bat" %%C %%P %%Y + %__ECHO3% CALL "%TOOLS%\release.bat" %%C %%P %%Y IF ERRORLEVEL 1 ( ECHO Could not build release archive for %%C/%%P/%%Y. GOTO errors ) @@ -93,6 +94,6 @@ ECHO. ECHO Success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% Index: Setup/release_ce.bat ================================================================== --- Setup/release_ce.bat +++ Setup/release_ce.bat @@ -9,11 +9,12 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO +REM SET __ECHO3=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -31,11 +32,11 @@ SET BASE_PLATFORM=PocketPC SET TYPE=binary CALL :fn_ResetErrorLevel -%_ECHO% CALL "%TOOLS%\release_all.bat" +%__ECHO3% CALL "%TOOLS%\release_all.bat" IF ERRORLEVEL 1 ( ECHO Failed to build PocketPC release files. GOTO errors ) @@ -67,6 +68,6 @@ ECHO. ECHO Release success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% Index: Setup/release_static.bat ================================================================== --- Setup/release_static.bat +++ Setup/release_static.bat @@ -9,11 +9,12 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO +REM SET __ECHO3=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -26,11 +27,11 @@ SET CONFIGURATIONSUFFIX=Static SET TYPE_PREFIX=static- CALL :fn_ResetErrorLevel -%_ECHO% CALL "%TOOLS%\release_all.bat" +%__ECHO3% CALL "%TOOLS%\release_all.bat" IF ERRORLEVEL 1 ( ECHO Failed to build static release files. GOTO errors ) @@ -62,6 +63,6 @@ ECHO. ECHO Release success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% DELETED Setup/set_default.bat Index: Setup/set_default.bat ================================================================== --- Setup/set_default.bat +++ /dev/null @@ -1,38 +0,0 @@ -@ECHO OFF - -:: -:: set_default.bat -- -:: -:: Written by Joe Mistachkin. -:: Released to the public domain, use at your own risk! -:: - -IF NOT DEFINED ISNETFX2 ( - SET ISNETFX2=True -) - -IF NOT DEFINED VCRUNTIME ( - SET VCRUNTIME=2008_SP1 -) - -IF NOT DEFINED CONFIGURATION ( - SET CONFIGURATION=Release -) - -IF NOT DEFINED PLATFORM ( - SET PLATFORM=Win32 -) - -IF NOT DEFINED PROCESSOR ( - SET PROCESSOR=x86 -) - -IF NOT DEFINED YEAR ( - SET YEAR=2008 -) - -IF NOT DEFINED FRAMEWORK ( - SET FRAMEWORK=netFx35 -) - -:end_of_file ADDED Setup/set_netFx20.bat Index: Setup/set_netFx20.bat ================================================================== --- /dev/null +++ Setup/set_netFx20.bat @@ -0,0 +1,38 @@ +@ECHO OFF + +:: +:: set_default.bat -- +:: +:: Written by Joe Mistachkin. +:: Released to the public domain, use at your own risk! +:: + +IF NOT DEFINED ISNETFX2 ( + SET ISNETFX2=True +) + +IF NOT DEFINED VCRUNTIME ( + SET VCRUNTIME=2008_SP1 +) + +IF NOT DEFINED CONFIGURATION ( + SET CONFIGURATION=Release +) + +IF NOT DEFINED PLATFORM ( + SET PLATFORM=Win32 +) + +IF NOT DEFINED PROCESSOR ( + SET PROCESSOR=x86 +) + +IF NOT DEFINED YEAR ( + SET YEAR=2008 +) + +IF NOT DEFINED FRAMEWORK ( + SET FRAMEWORK=netFx35 +) + +:end_of_file ADDED Setup/set_netFx40.bat Index: Setup/set_netFx40.bat ================================================================== --- /dev/null +++ Setup/set_netFx40.bat @@ -0,0 +1,38 @@ +@ECHO OFF + +:: +:: set_netFx40.bat -- +:: +:: Written by Joe Mistachkin. +:: Released to the public domain, use at your own risk! +:: + +IF NOT DEFINED ISNETFX2 ( + SET ISNETFX2=False +) + +IF NOT DEFINED VCRUNTIME ( + SET VCRUNTIME=2010_SP1 +) + +IF NOT DEFINED CONFIGURATION ( + SET CONFIGURATION=Release +) + +IF NOT DEFINED PLATFORM ( + SET PLATFORM=Win32 +) + +IF NOT DEFINED PROCESSOR ( + SET PROCESSOR=x86 +) + +IF NOT DEFINED YEAR ( + SET YEAR=2010 +) + +IF NOT DEFINED FRAMEWORK ( + SET FRAMEWORK=netFx40 +) + +:end_of_file Index: Setup/test_all.bat ================================================================== --- Setup/test_all.bat +++ Setup/test_all.bat @@ -9,11 +9,13 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO +REM SET __ECHO2=ECHO +REM SET __ECHO3=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* @@ -42,18 +44,18 @@ %_VECHO% Tools = '%TOOLS%' CALL :fn_ResetErrorLevel -%_ECHO% CALL "%TOOLS%\vsSp.bat" +%__ECHO3% CALL "%TOOLS%\vsSp.bat" IF ERRORLEVEL 1 ( ECHO Could not detect Visual Studio. GOTO errors ) -%_ECHO% CALL "%TOOLS%\set_common.bat" +%__ECHO3% CALL "%TOOLS%\set_common.bat" IF ERRORLEVEL 1 ( ECHO Could not set common variables. GOTO errors ) @@ -77,62 +79,82 @@ GOTO errors ) %_VECHO% Platform = '%PLATFORM%' -%_ECHO% PUSHD "%ROOT%" +%__ECHO2% PUSHD "%ROOT%" IF ERRORLEVEL 1 ( ECHO Could not change directory to "%ROOT%". GOTO errors ) FOR %%Y IN (%YEARS%) DO ( - %_ECHO% Externals\Eagle\bin\EagleShell.exe -preInitialize "set test_year {%%Y}" -file Tests\all.eagle - - IF ERRORLEVEL 1 ( - ECHO Testing of "%%Y" managed-only assembly failed. - GOTO errors - ) - - %_ECHO% XCOPY "bin\%%Y\Release\bin\test.*" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS% - - IF ERRORLEVEL 1 ( - ECHO Failed to copy "bin\%%Y\Release\bin\test.*" to "bin\%%Y\%PLATFORM%\Release". - GOTO errors - ) - - %_ECHO% XCOPY "bin\%%Y\Release\bin\System.Data.SQLite.Linq.*" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS% - - IF ERRORLEVEL 1 ( - ECHO Failed to copy "bin\%%Y\Release\bin\System.Data.SQLite.Linq.*" to "bin\%%Y\%PLATFORM%\Release". - GOTO errors - ) - - %_ECHO% XCOPY "bin\%%Y\Release\bin\testlinq.*" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS% - - IF ERRORLEVEL 1 ( - ECHO Failed to copy "bin\%%Y\Release\bin\testlinq.*" to "bin\%%Y\%PLATFORM%\Release". - GOTO errors - ) - - %_ECHO% XCOPY "bin\%%Y\Release\bin\northwindEF.db" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS% - - IF ERRORLEVEL 1 ( - ECHO Failed to copy "bin\%%Y\Release\bin\northwindEF.db" to "bin\%%Y\%PLATFORM%\Release". - GOTO errors - ) - - %_ECHO% Externals\Eagle\bin\EagleShell.exe -preInitialize "set test_year {%%Y}" -initialize -runtimeOption native -file Tests\all.eagle - - IF ERRORLEVEL 1 ( - ECHO Testing of "%%Y" mixed-mode assembly failed. - GOTO errors - ) -) - -%_ECHO% POPD + IF NOT DEFINED NOMANAGEDONLY ( + %__ECHO% Externals\Eagle\bin\EagleShell.exe -preInitialize "set test_year {%%Y}" -file Tests\all.eagle + + IF ERRORLEVEL 1 ( + ECHO Testing of "%%Y" managed-only assembly failed. + GOTO errors + ) + ) + + IF NOT DEFINED NOMIXEDMODE ( + IF NOT DEFINED NOXCOPY ( + %__ECHO% XCOPY "bin\%%Y\Release\bin\test.*" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS% + + IF ERRORLEVEL 1 ( + ECHO Failed to copy "bin\%%Y\Release\bin\test.*" to "bin\%%Y\%PLATFORM%\Release". + GOTO errors + ) + + %__ECHO% XCOPY "bin\%%Y\Release\bin\System.Data.SQLite.Linq.*" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS% + + IF ERRORLEVEL 1 ( + ECHO Failed to copy "bin\%%Y\Release\bin\System.Data.SQLite.Linq.*" to "bin\%%Y\%PLATFORM%\Release". + GOTO errors + ) + + %__ECHO% XCOPY "bin\%%Y\Release\bin\testlinq.*" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS% + + IF ERRORLEVEL 1 ( + ECHO Failed to copy "bin\%%Y\Release\bin\testlinq.*" to "bin\%%Y\%PLATFORM%\Release". + GOTO errors + ) + + %__ECHO% XCOPY "bin\%%Y\Release\bin\northwindEF.db" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS% + + IF ERRORLEVEL 1 ( + ECHO Failed to copy "bin\%%Y\Release\bin\northwindEF.db" to "bin\%%Y\%PLATFORM%\Release". + GOTO errors + ) + + %__ECHO% XCOPY "bin\%%Y\Release\bin\SQLite.Designer.*" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS% + + IF ERRORLEVEL 1 ( + ECHO Failed to copy "bin\%%Y\Release\bin\SQLite.Designer.*" to "bin\%%Y\%PLATFORM%\Release". + GOTO errors + ) + + %__ECHO% XCOPY "bin\%%Y\Release\bin\Installer.*" "bin\%%Y\%PLATFORM%\Release" %FFLAGS% %DFLAGS% + + IF ERRORLEVEL 1 ( + ECHO Failed to copy "bin\%%Y\Release\bin\Installer.*" to "bin\%%Y\%PLATFORM%\Release". + GOTO errors + ) + ) + + %__ECHO% Externals\Eagle\bin\EagleShell.exe -preInitialize "set test_year {%%Y}" -initialize -runtimeOption native -file Tests\all.eagle + + IF ERRORLEVEL 1 ( + ECHO Testing of "%%Y" mixed-mode assembly failed. + GOTO errors + ) + ) +) + +%__ECHO2% POPD IF ERRORLEVEL 1 ( ECHO Could not restore directory. GOTO errors ) @@ -165,6 +187,6 @@ ECHO. ECHO Test success, no errors were encountered. GOTO end_of_file :end_of_file -%_ECHO% EXIT /B %ERRORLEVEL% +%__ECHO% EXIT /B %ERRORLEVEL% Index: Setup/updateFileInfo.tcl ================================================================== --- Setup/updateFileInfo.tcl +++ Setup/updateFileInfo.tcl @@ -103,11 +103,11 @@ foreach {dummy fileName fileSize fileHash} \ [regexp -all -inline -nocase -- $pattern $data] { # # NOTE: Get the fully qualified file name based on the configured directory. # - set fullFileName [file join $directory $fileName] + set fullFileName [file join $directory [file tail $fileName]] # # NOTE: If the file does not exist, issue a warning and skip it. # if {![file exists $fullFileName]} then { ADDED Setup/verify.eagle Index: Setup/verify.eagle ================================================================== --- /dev/null +++ Setup/verify.eagle @@ -0,0 +1,194 @@ +############################################################################### +# +# verify.eagle -- Release Archive Verification Tool +# +# Written by Joe Mistachkin. +# Released to the public domain, use at your own risk! +# +############################################################################### + +package require Eagle + +proc usage { error } { + if {[string length $error] > 0} then {puts stdout $error} + + puts stdout "usage:\ +[file tail [info nameofexecutable]]\ +[file tail [info script]] " + + # + # NOTE: Indicate to the caller, if any, that we have failed. + # + exit 1 +} + +set argc [llength $argv] + +if {$argc == 1} then { + set directory [lindex $argv 0] + + if {[string length $directory] > 0} then { + set exitCode 0 + + set script [info script] + set path [file dirname $script] + set rootName [file rootname [file tail $script]] + + if {![info exists rar]} then { + if {[info exists env(UnRAR)]} then { + set rar $env(UnRAR) + } + + if {![info exists rar] || ![file exists $rar]} then { + set rar [file join $path UnRAR.exe] + } + } + + if {![info exists zip]} then { + if {[info exists env(UnZip)]} then { + set zip $env(UnZip) + } + + if {![info exists zip] || ![file exists $zip]} then { + set zip [file join $path UnZip.exe] + } + } + + source [file join $path [appendArgs $rootName .lst]] + + if {![array exists manifests]} then { + usage "master archive manifest is missing" + } + + set archiveFileNames [list] + + foreach extension [list exe rar zip] { + eval lappend archiveFileNames [findFilesRecursive \ + [file join $directory [appendArgs *. $extension]]] + } + + foreach archiveFileName $archiveFileNames { + set manifest [file tail $archiveFileName] + + # + # HACK: Skip all the Inno Setup files because we cannot + # easily validate them from this tool. + # + if {[string match -nocase *Setup*.exe $manifest]} then { + continue + } + + # + # NOTE: Attempt to extract the version and/or date/time + # information from the manifest file name. + # + regexp -- {(\d+)\.(\d+)\.(\d+)\.(\d+)} $manifest dummy \ + major minor build revision + + regexp -- {(\d{4})-(\d{2})-(\d{2})-(\d{2})} $manifest \ + dummy year month day sequence + + # + # HACK: Attempt to match and remove sub-strings from the + # manifest file name that look like a version number + # in the format "..." + # and/or a date/time string matching the format + # "YYYY-MM-DD-NN" (where the NN portion is a generic + # incrementing sequence number). + # + regsub -- {\d+\.\d+\.\d+\.\d+} $manifest {} manifest + regsub -- {\d{4}-\d{2}-\d{2}-\d{2}} $manifest {} manifest + + if {![info exists manifests($manifest)]} then { + puts stdout [appendArgs \ + "WARNING: Cannot find master manifest \"" \ + $manifest "\" for archive \"" $archiveFileName \ + "\", skipped."] + + continue + } + + set manifestFileNames [list] + + foreach list [lrange $manifests($manifest) 1 end] { + set rawManifestFileNames [set [appendArgs \ + [appendArgs [lindex $manifests($manifest) 0] \ + _manifests] ( $list )]] + + if {[info exists manifests($manifest,subst)]} then { + set rawManifestFileNames [subst $rawManifestFileNames] + } + + foreach manifestFileName $rawManifestFileNames { + lappend manifestFileNames $manifestFileName + } + } + + set listCommand [list] + lappend listCommand exec -success Success -nocarriagereturns -- + + if {[file extension $archiveFileName] eq ".zip"} then { + if {![file exists $zip]} then { + usage [appendArgs "tool \"" $zip "\" is missing"] + } + + lappend listCommand $zip -Z -1 $archiveFileName + } else { + if {![file exists $rar]} then { + usage [appendArgs "tool \"" $rar "\" is missing"] + } + + lappend listCommand $rar vb -- $archiveFileName + } + + if {[catch {eval $listCommand} result] == 0} then { + set containedFileNames [split [string map [list \\ /] \ + [string trim $result]] \n] + + foreach manifestFileName $manifestFileNames { + # + # TODO: Should we use -nocase here because Windows + # is the primary release platform? + # + if {[lsearch -exact -- $containedFileNames \ + $manifestFileName] == -1} then { + puts stdout [appendArgs \ + "ERROR: Archive \"" $archiveFileName \ + "\" missing file \"" $manifestFileName \ + "\" from manifest \"" $manifest "\"."] + + set exitCode 1 + } + } + + foreach containedFileName $containedFileNames { + # + # TODO: Should we use -nocase here because Windows + # is the primary release platform? + # + if {[lsearch -exact -- $manifestFileNames \ + $containedFileName] == -1} then { + puts stdout [appendArgs \ + "ERROR: Archive \"" $archiveFileName \ + "\" contains file \"" $containedFileName \ + "\" not in manifest \"" $manifest "\"."] + + set exitCode 1 + } + } + } else { + puts stdout [appendArgs \ + "ERROR: Failed to get list of files in archive \"" \ + $archiveFileName "\", error: " $result] + + set exitCode 1 + } + } + + exit $exitCode + } else { + usage "invalid directory" + } +} else { + usage "" +} ADDED Setup/verify.lst Index: Setup/verify.lst ================================================================== --- /dev/null +++ Setup/verify.lst @@ -0,0 +1,524 @@ +############################################################################### +# +# verify.lst -- Release Archive Manifest +# +# Written by Joe Mistachkin. +# Released to the public domain, use at your own risk! +# +############################################################################### +# +# NOTE: This file contains the master lists of all files that should be present +# in the various archives generated during the release process. +# +############################################################################### +# +# NOTE: This is the list of all files that should be present in the source code +# archive. +# +set sds_manifests(source) { + Doc/ + Doc/buildChm.tcl + Doc/Extra/ + Doc/Extra/dbfactorysupport.html + Doc/Extra/designer.html + Doc/Extra/lang_altertable.html + Doc/Extra/lang_analyze.html + Doc/Extra/lang_attach.html + Doc/Extra/lang_comment.html + Doc/Extra/lang_conflict.html + Doc/Extra/lang_createindex.html + Doc/Extra/lang_createtable.html + Doc/Extra/lang_createtrigger.html + Doc/Extra/lang_createview.html + Doc/Extra/lang_createvtab.html + Doc/Extra/lang_datetime.html + Doc/Extra/lang_delete.html + Doc/Extra/lang_detach.html + Doc/Extra/lang_dropindex.html + Doc/Extra/lang_droptable.html + Doc/Extra/lang_droptrigger.html + Doc/Extra/lang_dropview.html + Doc/Extra/lang_explain.html + Doc/Extra/lang_expr.html + Doc/Extra/lang_insert.html + Doc/Extra/lang_reindex.html + Doc/Extra/lang_replace.html + Doc/Extra/lang_select.html + Doc/Extra/lang_transaction.html + Doc/Extra/lang_types.html + Doc/Extra/lang_update.html + Doc/Extra/lang_vacuum.html + Doc/Extra/limitations.html + Doc/Extra/ndoc.css + Doc/Extra/optimizing.html + Doc/Extra/pragma.html + Doc/Extra/syntax.html + Doc/Extra/version.html + Doc/Extra/welcome.html + Doc/SQLite.NET.chm + Doc/SQLite.NET.hhc + Doc/SQLite.NET.hhp + Doc/SQLite.NET.ndoc + exclude_bin.txt + exclude_src.txt + Externals/ + Externals/Eagle/ + Externals/Eagle/bin/ + Externals/Eagle/bin/EagleShell.exe.config + Externals/Eagle/bin/EagleShell.exe.mda.config + Externals/Eagle/lib/ + Externals/Eagle/lib/Eagle1.0/ + Externals/Eagle/lib/Eagle1.0/vendor.eagle + Externals/Eagle/lib/Test1.0/ + readme.htm + Setup/ + Setup/archive.bat + Setup/bake.bat + Setup/bake_all.bat + Setup/build.bat + Setup/build_all.bat + Setup/build_ce.bat + Setup/CheckForNetFx.pas + Setup/clean.bat + Setup/InitializeSetup.pas + Setup/release.bat + Setup/release_all.bat + Setup/release_ce.bat + Setup/release_static.bat + Setup/set_2008.bat + Setup/set_2010.bat + Setup/set_common.bat + Setup/set_netFx20.bat + Setup/set_netFx40.bat + Setup/set_Release.bat + Setup/set_ReleaseNativeOnly.bat + "Setup/set_ReleaseNativeOnly_Pocket PC 2003 (ARMV4).bat" + Setup/set_ReleaseNativeOnly_Win32.bat + Setup/set_ReleaseNativeOnly_x64.bat + Setup/set_ReleaseNativeOnly_x64_2008.bat + Setup/set_ReleaseNativeOnly_x64_2010.bat + Setup/set_ReleaseNativeOnly_x86_2008.bat + Setup/set_ReleaseNativeOnly_x86_2010.bat + "Setup/set_Release_Pocket PC 2003 (ARMV4).bat" + Setup/set_Release_Win32.bat + Setup/set_Release_x64.bat + Setup/set_Release_x64_2008.bat + Setup/set_Release_x64_2010.bat + Setup/set_Release_x86_2008.bat + Setup/set_Release_x86_2010.bat + Setup/set_x64_2008.bat + Setup/set_x64_2010.bat + Setup/set_x86_2008.bat + Setup/set_x86_2010.bat + Setup/SQLite.iss + Setup/test_all.bat + Setup/updateFileInfo.tcl + Setup/verify.eagle + Setup/verify.lst + Setup/vsSp.bat + SQLite.Designer/ + SQLite.Designer/AssemblyInfo.cs + SQLite.Designer/ChangePasswordDialog.cs + SQLite.Designer/ChangePasswordDialog.Designer.cs + SQLite.Designer/ChangePasswordDialog.resx + SQLite.Designer/ChangeScriptDialog.cs + SQLite.Designer/ChangeScriptDialog.Designer.cs + SQLite.Designer/ChangeScriptDialog.resx + SQLite.Designer/CtcComponents/ + SQLite.Designer/CtcComponents/Guids.h + SQLite.Designer/CtcComponents/PkgCmd.ctc + SQLite.Designer/CtcComponents/PkgCmdID.h + SQLite.Designer/Design/ + SQLite.Designer/Design/Check.cs + SQLite.Designer/Design/Column.cs + SQLite.Designer/Design/ForeignKey.cs + SQLite.Designer/Design/Index.cs + SQLite.Designer/Design/PrimaryKey.cs + SQLite.Designer/Design/SimpleTokenizer.cs + SQLite.Designer/Design/Table.cs + SQLite.Designer/Design/Trigger.cs + SQLite.Designer/Design/Unique.cs + SQLite.Designer/Design/View.cs + SQLite.Designer/Editors/ + SQLite.Designer/Editors/AutoCompleteColumn.cs + SQLite.Designer/Editors/TableDesignerDoc.cs + SQLite.Designer/Editors/TableDesignerDoc.Designer.cs + SQLite.Designer/Editors/TableDesignerDoc.resx + SQLite.Designer/Editors/ViewDesignerDoc.cs + SQLite.Designer/Editors/ViewDesignerDoc.Designer.cs + SQLite.Designer/Editors/ViewDesignerDoc.resx + SQLite.Designer/Pkgcmd.h + SQLite.Designer/PkgCmd.vsct + SQLite.Designer/plk.txt + SQLite.Designer/Resources/ + SQLite.Designer/Resources/info.png + SQLite.Designer/Resources/ToolboxItems.txt + SQLite.Designer/source.extension.vsixmanifest + SQLite.Designer/SQLite.Designer.2005.csproj + SQLite.Designer/SQLite.Designer.2008.csproj + SQLite.Designer/SQLite.Designer.2010.csproj + SQLite.Designer/SQLiteAdapterDesigner.cs + SQLite.Designer/SQLiteCommandDesigner.cs + SQLite.Designer/SQLiteCommandHandler.cs + SQLite.Designer/SQLiteConnectionProperties.cs + SQLite.Designer/SQLiteConnectionStringEditor.cs + SQLite.Designer/SQLiteConnectionUIControl.cs + SQLite.Designer/SQLiteConnectionUIControl.Designer.cs + SQLite.Designer/SQLiteConnectionUIControl.resx + SQLite.Designer/SQLiteDataAdapterToolboxItem.cs + SQLite.Designer/SQLiteDataConnectionSupport.cs + SQLite.Designer/SQLiteDataObjectIdentifierResolver.cs + SQLite.Designer/SQLiteDataObjectSupport.cs + SQLite.Designer/SQLiteDataObjectSupport.xml + SQLite.Designer/SQLiteDataSourceInformation.cs + SQLite.Designer/SQLiteDataViewSupport.cs + SQLite.Designer/SQLiteDataViewSupport2005.xml + SQLite.Designer/SQLiteDataViewSupport2008.xml + SQLite.Designer/SQLiteDataViewSupport2010.xml + SQLite.Designer/SQLitePackage.cs + SQLite.Designer/SQLiteProviderObjectFactory.cs + SQLite.Designer/TableNameDialog.cs + SQLite.Designer/TableNameDialog.Designer.cs + SQLite.Designer/TableNameDialog.resx + SQLite.Designer/VSPackage.Designer.cs + SQLite.Designer/VSPackage.resx + SQLite.Interop/ + SQLite.Interop/props/ + SQLite.Interop/props/SQLite.Interop.2005.vsprops + SQLite.Interop/props/SQLite.Interop.2008.vsprops + SQLite.Interop/props/SQLite.Interop.2010.props + SQLite.Interop/props/sqlite3.props + SQLite.Interop/props/sqlite3.vsprops + SQLite.Interop/SQLite.Interop.2005.vcproj + SQLite.Interop/SQLite.Interop.2008.vcproj + SQLite.Interop/SQLite.Interop.2010.vcxproj + SQLite.Interop/SQLite.Interop.2010.vcxproj.filters + SQLite.Interop/SQLite.Interop.CE.2005.vcproj + SQLite.Interop/SQLite.Interop.CE.2008.vcproj + SQLite.Interop/SQLite.Interop.Static.2005.vcproj + SQLite.Interop/SQLite.Interop.Static.2008.vcproj + SQLite.Interop/SQLite.Interop.Static.2010.vcxproj + SQLite.Interop/SQLite.Interop.Static.2010.vcxproj.filters + SQLite.Interop/src/ + SQLite.Interop/src/contrib/ + SQLite.Interop/src/contrib/extension-functions.c + SQLite.Interop/src/core/ + SQLite.Interop/src/core/sqlite3.c + SQLite.Interop/src/core/sqlite3.h + SQLite.Interop/src/core/sqlite3ext.h + SQLite.Interop/src/win/ + SQLite.Interop/src/win/AssemblyInfo.cpp + SQLite.Interop/src/win/crypt.c + SQLite.Interop/src/win/interop.c + SQLite.Interop/src/win/interop.h + SQLite.Interop/src/win/SQLite.Interop.rc + SQLite.MSIL.nuspec + SQLite.NET.2005.MSBuild.sln + SQLite.NET.2005.sln + SQLite.NET.2008.MSBuild.sln + SQLite.NET.2008.sln + SQLite.NET.2010.MSBuild.sln + SQLite.NET.2010.sln + SQLite.NET.Settings.targets + SQLite.NET.targets + SQLite.nuspec + SQLite.x64.nuspec + SQLite.x86.nuspec + System.Data.SQLite/ + System.Data.SQLite/AssemblyInfo.cs + System.Data.SQLite/DataTypes.xml + System.Data.SQLite/LINQ/ + System.Data.SQLite/LINQ/SQLiteConnection_Linq.cs + System.Data.SQLite/LINQ/SQLiteFactory_Linq.cs + System.Data.SQLite/MetaDataCollections.xml + System.Data.SQLite/SQLite3.cs + System.Data.SQLite/SQLite3_UTF16.cs + System.Data.SQLite/SQLiteBackup.cs + System.Data.SQLite/SQLiteBase.cs + System.Data.SQLite/SQLiteCommand.bmp + System.Data.SQLite/SQLiteCommand.cs + System.Data.SQLite/SQLiteCommandBuilder.cs + System.Data.SQLite/SQLiteConnection.bmp + System.Data.SQLite/SQLiteConnection.cs + System.Data.SQLite/SQLiteConnectionPool.cs + System.Data.SQLite/SQLiteConnectionStringBuilder.cs + System.Data.SQLite/SQLiteConvert.cs + System.Data.SQLite/SQLiteDataAdapter.bmp + System.Data.SQLite/SQLiteDataAdapter.cs + System.Data.SQLite/SQLiteDataReader.cs + System.Data.SQLite/SQLiteDefineConstants.cs + System.Data.SQLite/SQLiteEnlistment.cs + System.Data.SQLite/SQLiteException.cs + System.Data.SQLite/SQLiteFactory.cs + System.Data.SQLite/SQLiteFunction.cs + System.Data.SQLite/SQLiteFunctionAttribute.cs + System.Data.SQLite/SQLiteKeyReader.cs + System.Data.SQLite/SQLiteLog.cs + System.Data.SQLite/SQLiteMetaDataCollectionNames.cs + System.Data.SQLite/SQLiteParameter.cs + System.Data.SQLite/SQLiteParameterCollection.cs + System.Data.SQLite/SQLiteStatement.cs + System.Data.SQLite/SQLiteTransaction.cs + System.Data.SQLite/SR.Designer.cs + System.Data.SQLite/SR.resx + System.Data.SQLite/System.Data.SQLite.2005.csproj + System.Data.SQLite/System.Data.SQLite.2008.csproj + System.Data.SQLite/System.Data.SQLite.2010.csproj + System.Data.SQLite/System.Data.SQLite.CF.snk + System.Data.SQLite/System.Data.SQLite.Compact.2005.csproj + System.Data.SQLite/System.Data.SQLite.Compact.2008.csproj + System.Data.SQLite/System.Data.SQLite.Files.targets + System.Data.SQLite/System.Data.SQLite.Module.2005.csproj + System.Data.SQLite/System.Data.SQLite.Module.2008.csproj + System.Data.SQLite/System.Data.SQLite.Module.2010.csproj + System.Data.SQLite/System.Data.SQLite.Properties.targets + System.Data.SQLite/System.Data.SQLite.References.targets + System.Data.SQLite/System.Data.SQLite.snk + System.Data.SQLite/UnsafeNativeMethods.cs + System.Data.SQLite.Linq/ + System.Data.SQLite.Linq/AssemblyInfo.cs + System.Data.SQLite.Linq/Properties/ + System.Data.SQLite.Linq/Properties/Resources.Designer.cs + System.Data.SQLite.Linq/Properties/Resources.resx + System.Data.SQLite.Linq/Resources/ + System.Data.SQLite.Linq/Resources/Common.ConceptualSchemaDefinition.csdl + System.Data.SQLite.Linq/Resources/Common.ProviderManifest.xsd + System.Data.SQLite.Linq/Resources/SQLiteProviderServices.ProviderManifest.xml + System.Data.SQLite.Linq/Resources/SQLiteProviderServices.StoreSchemaDefinition.ssdl + System.Data.SQLite.Linq/Resources/SQLiteProviderServices.StoreSchemaMapping.msl + System.Data.SQLite.Linq/Resources/System.Data.Resources.CodeGenerationSchema.xsd + System.Data.SQLite.Linq/Resources/System.Data.Resources.CSDLSchema.xsd + System.Data.SQLite.Linq/Resources/System.Data.Resources.CSMSL.xsd + System.Data.SQLite.Linq/Resources/System.Data.Resources.EntityStoreSchemaGenerator.xsd + System.Data.SQLite.Linq/Resources/System.Data.Resources.SSDLSchema.xsd + "System.Data.SQLite.Linq/SQL Generation/" + "System.Data.SQLite.Linq/SQL Generation/DmlSqlGenerator.cs" + "System.Data.SQLite.Linq/SQL Generation/InternalBase.cs" + "System.Data.SQLite.Linq/SQL Generation/ISqlFragment.cs" + "System.Data.SQLite.Linq/SQL Generation/JoinSymbol.cs" + "System.Data.SQLite.Linq/SQL Generation/KeyToListMap.cs" + "System.Data.SQLite.Linq/SQL Generation/License.txt" + "System.Data.SQLite.Linq/SQL Generation/MetadataHelpers.cs" + "System.Data.SQLite.Linq/SQL Generation/SkipClause.cs" + "System.Data.SQLite.Linq/SQL Generation/SqlBuilder.cs" + "System.Data.SQLite.Linq/SQL Generation/SqlChecker.cs" + "System.Data.SQLite.Linq/SQL Generation/SqlGenerator.cs" + "System.Data.SQLite.Linq/SQL Generation/SqlSelectStatement.cs" + "System.Data.SQLite.Linq/SQL Generation/SqlWriter.cs" + "System.Data.SQLite.Linq/SQL Generation/StringUtil.cs" + "System.Data.SQLite.Linq/SQL Generation/Symbol.cs" + "System.Data.SQLite.Linq/SQL Generation/SymbolPair.cs" + "System.Data.SQLite.Linq/SQL Generation/SymbolTable.cs" + "System.Data.SQLite.Linq/SQL Generation/TopClause.cs" + System.Data.SQLite.Linq/SQLiteProviderManifest.cs + System.Data.SQLite.Linq/SQLiteProviderServices.cs + System.Data.SQLite.Linq/System.Data.SQLite.Linq.2008.csproj + System.Data.SQLite.Linq/System.Data.SQLite.Linq.2010.csproj + test/ + test/app.config + test/AssemblyInfo.cs + test/Program.cs + test/Properties/ + test/Properties/Resources.Designer.cs + test/Properties/Resources.resx + test/test.2005.csproj + test/test.2008.csproj + test/test.2010.csproj + test/TestCases.cs + test/TestCasesDialog.cs + test/TestCasesDialog.Designer.cs + test/TestCasesDialog.resx + testce/ + testce/AssemblyInfo.cs + testce/Form1.cs + testce/Form1.Designer.cs + testce/Form1.resx + testce/Program.cs + testce/TestCases.cs + testce/testce.2005.csproj + testce/testce.2008.csproj + testlinq/ + testlinq/2008/ + testlinq/2008/App.config + testlinq/2010/ + testlinq/2010/App.config + testlinq/northwindEF.db + testlinq/NorthwindModel2008.Designer.cs + testlinq/NorthwindModel2008.edmx + testlinq/NorthwindModel2010.Designer.cs + testlinq/NorthwindModel2010.edmx + testlinq/Program.cs + testlinq/Properties/ + testlinq/Properties/AssemblyInfo.cs + testlinq/testlinq.2008.csproj + testlinq/testlinq.2010.csproj + Tests/ + Tests/all.eagle + Tests/backup.eagle + Tests/basic.eagle + Tests/common.eagle + Tests/installer.eagle + Tests/Installer_Test_Vs2005.log + Tests/Installer_Test_Vs2008.log + Tests/Installer_Test_Vs2010.log + Tests/nonWal.db + Tests/pkgIndex.eagle + Tests/testlinq.out + Tests/tkt-00f86f9739.eagle + Tests/tkt-0d5b1ef362.eagle + Tests/tkt-201128cc88.eagle + Tests/tkt-2c630bffa7.eagle + Tests/tkt-2ce0870fad.eagle + Tests/tkt-343d392b51.eagle + Tests/tkt-448d663d11.eagle + Tests/tkt-544dba0a2f.eagle + Tests/tkt-59edc1018b.eagle + Tests/tkt-72905c9a77.eagle + Tests/tkt-7e3fa93744.eagle + Tests/tkt-84718e79fa.eagle + Tests/tkt-8554170e09.eagle + Tests/tkt-8b7d179c3c.eagle + Tests/tkt-ac47dd230a.eagle + Tests/tkt-b4a7ddc83f.eagle + Tests/tkt-bb4b04d457.eagle + Tests/tkt-ccfa69fc32.eagle + Tests/tkt-e1b2e0f769.eagle + Tests/tkt-e30b820248.eagle + Tests/Uninstaller_Test_Vs2005.log + Tests/Uninstaller_Test_Vs2008.log + Tests/Uninstaller_Test_Vs2010.log + Tests/version.eagle + Tests/wal.db + tools/ + tools/install/ + tools/install/Installer.2005.csproj + tools/install/Installer.2008.csproj + tools/install/Installer.2010.csproj + tools/install/Installer.cs + tools/install/Properties/ + tools/install/Properties/AssemblyInfo.cs + tools/install/Resources/ + tools/install/Resources/manifest.xml +} + +############################################################################### +# +# NOTE: This is the list of all files that should be present in the standard +# binary archives (i.e. those not containing the mixed-mode assembly). +# +set sds_manifests(binary) { + Installer.exe + Installer.pdb + SQLite.Designer.dll + SQLite.Designer.pdb + SQLite.Designer.xml + SQLite.Interop.dll + SQLite.Interop.pdb + System.Data.SQLite.Linq.dll + System.Data.SQLite.Linq.pdb + System.Data.SQLite.Linq.xml + System.Data.SQLite.dll + System.Data.SQLite.pdb + System.Data.SQLite.xml + northwindEF.db + test.exe + test.exe.config + test.pdb + testlinq.exe + testlinq.exe.config + testlinq.pdb +} + +############################################################################### +# +# NOTE: This is the list of all files that should be present in the "bundle" +# binary archives (i.e. those not containing separate managed and native +# assemblies). +# +set sds_manifests(bundle) { + Installer.exe + Installer.pdb + SQLite.Designer.dll + SQLite.Designer.pdb + SQLite.Designer.xml + System.Data.SQLite.Linq.dll + System.Data.SQLite.Linq.pdb + System.Data.SQLite.Linq.xml + System.Data.SQLite.dll + System.Data.SQLite.pdb + System.Data.SQLite.xml + northwindEF.db + test.exe + test.exe.config + test.pdb + testlinq.exe + testlinq.exe.config + testlinq.pdb +} + +############################################################################### +# +# NOTE: This is the list of all files that should be present in the "PocketPC" +# binary archives (i.e. for the .NET Compact Framework). +# +set sds_manifests(compact) { + "SQLite.Interop.[format %03d $build].dll" + "SQLite.Interop.[format %03d $build].pdb" + System.Data.SQLite.dll + System.Data.SQLite.pdb + System.Data.SQLite.xml + testce.exe + testce.pdb +} + +############################################################################### +# +# NOTE: These are the master archive manifest groups, based on file name. The +# first element in each list is the array variable name prefix used to +# locate another array containing the named elements referenced by the +# remaining elements in each list. Here is an example: +# +# 1. First, the archive file name has the patch level removed from it. +# Next, it is mapped to the name of the array containing the file +# lists via the first element of the corresponding list. +# +# [lindex $manifests(EagleCore.exe) 0] ==> eagle ==> eagle_manifests +# +# 2. Next, the remaining elements are used to query the named file lists +# from the array discovered in the previous step. +# +# [lrange $manifests(EagleCore.exe) 1 end] ==> core library +# +# 3. Finally, the final list of files for this archive file name is built +# by combining all the file names in the file lists discovered in the +# previous step. Duplicate file names, if any, should be harmless. +# +# $result == $eagle_manifests(core) UNION $eagle_manifests(library) +# +############################################################################### + +set manifests(sqlite-netFx-source-.zip) [list sds source] + +############################################################################### + +set manifests(sqlite-netFx35-binary-Win32-2008-.zip) [list sds binary] +set manifests(sqlite-netFx35-binary-x64-2008-.zip) [list sds binary] +set manifests(sqlite-netFx35-binary-bundle-Win32-2008-.zip) [list sds bundle] +set manifests(sqlite-netFx35-binary-bundle-x64-2008-.zip) [list sds bundle] +set manifests(sqlite-netFx35-static-binary-Win32-2008-.zip) [list sds binary] +set manifests(sqlite-netFx35-static-binary-x64-2008-.zip) [list sds binary] +set manifests(sqlite-netFx35-static-binary-bundle-Win32-2008-.zip) [list sds bundle] +set manifests(sqlite-netFx35-static-binary-bundle-x64-2008-.zip) [list sds bundle] +set manifests(sqlite-netFx35-binary-PocketPC-2008-.zip) [list sds compact] +set manifests(sqlite-netFx35-binary-PocketPC-2008-.zip,subst) ""; # dynamic +set manifests(sqlite-netFx40-binary-Win32-2010-.zip) [list sds binary] +set manifests(sqlite-netFx40-binary-x64-2010-.zip) [list sds binary] +set manifests(sqlite-netFx40-binary-bundle-Win32-2010-.zip) [list sds bundle] +set manifests(sqlite-netFx40-binary-bundle-x64-2010-.zip) [list sds bundle] +set manifests(sqlite-netFx40-static-binary-Win32-2010-.zip) [list sds binary] +set manifests(sqlite-netFx40-static-binary-x64-2010-.zip) [list sds binary] +set manifests(sqlite-netFx40-static-binary-bundle-Win32-2010-.zip) [list sds bundle] +set manifests(sqlite-netFx40-static-binary-bundle-x64-2010-.zip) [list sds bundle] + +############################################################################### +# end of file Index: Setup/vsSp.bat ================================================================== --- Setup/vsSp.bat +++ Setup/vsSp.bat @@ -9,11 +9,11 @@ :: Released to the public domain, use at your own risk! :: SETLOCAL -REM SET _ECHO=ECHO +REM SET __ECHO=ECHO IF NOT DEFINED _AECHO (SET _AECHO=REM) IF NOT DEFINED _CECHO (SET _CECHO=REM) IF NOT DEFINED _VECHO (SET _VECHO=REM) %_AECHO% Running %0 %* Index: System.Data.SQLite.Linq/AssemblyInfo.cs ================================================================== --- System.Data.SQLite.Linq/AssemblyInfo.cs +++ System.Data.SQLite.Linq/AssemblyInfo.cs @@ -42,7 +42,7 @@ // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.78.0")] -[assembly: AssemblyFileVersion("1.0.78.0")] +[assembly: AssemblyVersion("1.0.81.0")] +[assembly: AssemblyFileVersion("1.0.81.0")] Index: System.Data.SQLite.Linq/Properties/Resources.Designer.cs ================================================================== --- System.Data.SQLite.Linq/Properties/Resources.Designer.cs +++ System.Data.SQLite.Linq/Properties/Resources.Designer.cs @@ -44,11 +44,11 @@ /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Data.SQLite.Properties.Resources", typeof(Resources).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Data.SQLite.Linq.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } Index: System.Data.SQLite.Linq/Properties/Resources.resx ================================================================== --- System.Data.SQLite.Linq/Properties/Resources.resx +++ System.Data.SQLite.Linq/Properties/Resources.resx @@ -1,19 +1,19 @@ - @@ -116,24 +116,69 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - CREATE TEMP VIEW SCHEMACONSTRAINTCOLUMNS AS -SELECT CONSTRAINT_CATALOG, NULL AS CONSTRAINT_SCHEMA, CONSTRAINT_NAME, TABLE_CATALOG, NULL AS TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME -FROM TEMP.SCHEMAINDEXCOLUMNS -UNION -SELECT CONSTRAINT_CATALOG, NULL, CONSTRAINT_NAME, TABLE_CATALOG, NULL, TABLE_NAME, FKEY_FROM_COLUMN -FROM TEMP.SCHEMAFOREIGNKEYS; + + CREATE TEMP VIEW SCHEMACONSTRAINTCOLUMNS AS + SELECT CONSTRAINT_CATALOG, + NULL AS CONSTRAINT_SCHEMA, + CONSTRAINT_NAME, + TABLE_CATALOG, + NULL AS TABLE_SCHEMA, + TABLE_NAME, + COLUMN_NAME + FROM TEMP.SCHEMAINDEXCOLUMNS + UNION + SELECT CONSTRAINT_CATALOG, + NULL, + CONSTRAINT_NAME, + TABLE_CATALOG, + NULL, + TABLE_NAME, + FKEY_FROM_COLUMN + FROM TEMP.SCHEMAFOREIGNKEYS; + - CREATE TEMP VIEW SCHEMACONSTRAINTS AS -SELECT INDEX_CATALOG AS CONSTRAINT_CATALOG, NULL AS CONSTRAINT_SCHEMA, INDEX_NAME AS CONSTRAINT_NAME, TABLE_CATALOG, NULL AS TABLE_SCHEMA, TABLE_NAME, 'PRIMARY KEY' AS CONSTRAINT_TYPE, 0 AS IS_DEFERRABLE, 0 AS INITIALLY_DEFERRED, NULL AS CHECK_CLAUSE -FROM TEMP.SCHEMAINDEXES WHERE PRIMARY_KEY = 1 -UNION -SELECT INDEX_CATALOG, NULL, INDEX_NAME, TABLE_CATALOG, NULL, TABLE_NAME, 'UNIQUE', 0, 0, NULL -FROM TEMP.SCHEMAINDEXES WHERE PRIMARY_KEY = 0 AND [UNIQUE] = 1 -UNION -SELECT CONSTRAINT_CATALOG, NULL, CONSTRAINT_NAME, TABLE_CATALOG, NULL, TABLE_NAME, CONSTRAINT_TYPE, IS_DEFERRABLE, INITIALLY_DEFERRED, NULL -FROM TEMP.SCHEMAFOREIGNKEYS; + + CREATE TEMP VIEW SCHEMACONSTRAINTS AS + SELECT INDEX_CATALOG AS CONSTRAINT_CATALOG, + NULL AS CONSTRAINT_SCHEMA, + INDEX_NAME AS CONSTRAINT_NAME, + TABLE_CATALOG, + NULL AS TABLE_SCHEMA, + TABLE_NAME, + 'PRIMARY KEY' AS CONSTRAINT_TYPE, + 0 AS IS_DEFERRABLE, + 0 AS INITIALLY_DEFERRED, + NULL AS CHECK_CLAUSE + FROM TEMP.SCHEMAINDEXES + WHERE PRIMARY_KEY = 1 + UNION + SELECT INDEX_CATALOG, + NULL, + INDEX_NAME, + TABLE_CATALOG, + NULL, + TABLE_NAME, + 'UNIQUE', + 0, + 0, + NULL + FROM TEMP.SCHEMAINDEXES + WHERE PRIMARY_KEY = 0 AND [UNIQUE] = 1 + UNION + SELECT CONSTRAINT_CATALOG, + NULL, + CONSTRAINT_NAME, + TABLE_CATALOG, + NULL, + TABLE_NAME, + CONSTRAINT_TYPE, + IS_DEFERRABLE, + INITIALLY_DEFERRED, + NULL + FROM TEMP.SCHEMAFOREIGNKEYS; + Index: System.Data.SQLite.Linq/SQL Generation/DmlSqlGenerator.cs ================================================================== --- System.Data.SQLite.Linq/SQL Generation/DmlSqlGenerator.cs +++ System.Data.SQLite.Linq/SQL Generation/DmlSqlGenerator.cs @@ -195,11 +195,15 @@ commandText.Append("FROM "); tree.Target.Expression.Accept(translator); commandText.AppendLine(); // where +#if INTEROP_EXTENSION_FUNCTIONS commandText.Append("WHERE last_rows_affected() > 0"); +#else + commandText.Append("WHERE changes() > 0"); +#endif EntitySetBase table = ((DbScanExpression)tree.Target.Expression).Target; bool identity = false; foreach (EdmMember keyMember in table.ElementType.KeyMembers) { commandText.Append(" AND "); Index: System.Data.SQLite.Linq/SQL Generation/SqlGenerator.cs ================================================================== --- System.Data.SQLite.Linq/SQL Generation/SqlGenerator.cs +++ System.Data.SQLite.Linq/SQL Generation/SqlGenerator.cs @@ -326,17 +326,22 @@ /// /// private static Dictionary InitializeCanonicalFunctionHandlers() { Dictionary functionHandlers = new Dictionary(16, StringComparer.Ordinal); + +#if INTEROP_EXTENSION_FUNCTIONS functionHandlers.Add("IndexOf", HandleCanonicalFunctionIndexOf); +#endif + functionHandlers.Add("Length", HandleCanonicalFunctionLength); functionHandlers.Add("NewGuid", HandleCanonicalFunctionNewGuid); functionHandlers.Add("Round", HandleCanonicalFunctionRound); functionHandlers.Add("ToLower", HandleCanonicalFunctionToLower); functionHandlers.Add("ToUpper", HandleCanonicalFunctionToUpper); functionHandlers.Add("Trim", HandleCanonicalFunctionTrim); + functionHandlers.Add("Left", HandleCanonicalFunctionLeft); functionHandlers.Add("Right", HandleCanonicalFunctionRight); functionHandlers.Add("CurrentDateTime", HandleGetDateFunction); functionHandlers.Add("CurrentUtcDateTime", HandleGetUtcDateFunction); //DatePartFunctions @@ -2858,10 +2863,11 @@ result.Append(") AS integer)"); return result; } +#if INTEROP_EXTENSION_FUNCTIONS /// /// Function rename IndexOf -> CHARINDEX /// /// /// @@ -2868,10 +2874,11 @@ /// private static ISqlFragment HandleCanonicalFunctionIndexOf(SqlGenerator sqlgen, DbFunctionExpression e) { return sqlgen.HandleFunctionDefaultGivenName(e, "CHARINDEX"); } +#endif /// /// Function rename NewGuid -> NEWID /// /// @@ -2942,10 +2949,31 @@ result.Append(")"); return result; } + + /// + /// LEFT(string, length) -> SUBSTR(string, 1, length) + /// + /// + /// + /// + private static ISqlFragment HandleCanonicalFunctionLeft(SqlGenerator sqlgen, DbFunctionExpression e) + { + SqlBuilder result = new SqlBuilder(); + + result.Append("SUBSTR("); + + Debug.Assert(e.Arguments.Count == 2, "Left should have two arguments"); + result.Append(e.Arguments[0].Accept(sqlgen)); + result.Append(", 1, "); + result.Append(e.Arguments[1].Accept(sqlgen)); + result.Append(")"); + + return result; + } /// /// RIGHT(string, length) -> SUBSTR(string, -(length), length) /// /// Index: System.Data.SQLite/AssemblyInfo.cs ================================================================== --- System.Data.SQLite/AssemblyInfo.cs +++ System.Data.SQLite/AssemblyInfo.cs @@ -62,9 +62,9 @@ // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.78.0")] +[assembly: AssemblyVersion("1.0.81.0")] #if !PLATFORM_COMPACTFRAMEWORK -[assembly: AssemblyFileVersion("1.0.78.0")] +[assembly: AssemblyFileVersion("1.0.81.0")] #endif Index: System.Data.SQLite/LINQ/SQLiteFactory_Linq.cs ================================================================== --- System.Data.SQLite/LINQ/SQLiteFactory_Linq.cs +++ System.Data.SQLite/LINQ/SQLiteFactory_Linq.cs @@ -19,10 +19,14 @@ private static Type _dbProviderServicesType; private static object _sqliteServices; static SQLiteFactory() { +#if (SQLITE_STANDARD || USE_INTEROP_DLL || PLATFORM_COMPACTFRAMEWORK) && PRELOAD_NATIVE_LIBRARY + UnsafeNativeMethods.Initialize(); +#endif + #if !PLATFORM_COMPACTFRAMEWORK SQLiteLog.Initialize(); #endif string version = Index: System.Data.SQLite/SQLite3.cs ================================================================== --- System.Data.SQLite/SQLite3.cs +++ System.Data.SQLite/SQLite3.cs @@ -6,14 +6,16 @@ ********************************************************/ namespace System.Data.SQLite { using System; + using System.Collections.Generic; #if DEBUG using System.Diagnostics; #endif using System.Runtime.InteropServices; + using System.Text; #if !PLATFORM_COMPACTFRAMEWORK [UnmanagedFunctionPointer(CallingConvention.Cdecl)] #endif internal delegate void SQLiteLogCallback(IntPtr puser, int err_code, IntPtr message); @@ -21,10 +23,12 @@ /// /// This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET /// internal class SQLite3 : SQLiteBase { + private static object syncRoot = new object(); + // // NOTE: This is the public key for the System.Data.SQLite assembly. If you change the // SNK file, you will need to change this as well. // internal const string PublicKey = @@ -32,11 +36,11 @@ "b621ddff5d844727418956997f475eb829429e411aff3e93f97b70de698b972640925bdd44280df0" + "a25a843266973704137cbb0e7441c1fe7cae4e2440ae91ab8cde3933febcb1ac48dd33b40e13c421" + "d8215c18a4349a436dd499e3c385cc683015f886f6c10bd90115eb2bd61b67750839e3a19941dc9c"; #if !PLATFORM_COMPACTFRAMEWORK - internal const string DesignerVersion = "1.0.78.0"; + internal const string DesignerVersion = "1.0.81.0"; #endif /// /// The opaque pointer returned to us by the sqlite provider /// @@ -111,12 +115,16 @@ { if (_sql != null) { if (_usePool) { - SQLiteBase.ResetConnection(_sql); + SQLiteBase.ResetConnection(_sql, _sql); SQLiteConnectionPool.Add(_fileName, _sql, _poolVersion); + +#if DEBUG && !NET_COMPACT_20 + Trace.WriteLine(String.Format("Close (Pool): {0}", _sql)); +#endif } else { _sql.Dispose(); } @@ -136,10 +144,35 @@ get { return SQLite3.SQLiteVersion; } } + + internal static string DefineConstants + { + get + { + StringBuilder result = new StringBuilder(); + IList list = SQLiteDefineConstants.OptionList; + + if (list != null) + { + foreach (string element in list) + { + if (element == null) + continue; + + if (result.Length > 0) + result.Append(' '); + + result.Append(element); + } + } + + return result.ToString(); + } + } internal static string SQLiteVersion { get { @@ -157,11 +190,11 @@ internal override bool AutoCommit { get { - return IsAutocommit(_sql); + return IsAutocommit(_sql, _sql); } } internal override long LastInsertRowId { @@ -209,54 +242,75 @@ internal override bool IsOpen() { return (_sql != null); } - internal override void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool) + internal override void Open(string strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool) { if (_sql != null) return; _usePool = usePool; + _fileName = strFilename; + if (usePool) { - _fileName = strFilename; _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion); + +#if DEBUG && !NET_COMPACT_20 + Trace.WriteLine(String.Format("Open (Pool): {0}", (_sql != null) ? _sql.ToString() : "")); +#endif } if (_sql == null) { IntPtr db; #if !SQLITE_STANDARD - int n = UnsafeNativeMethods.sqlite3_open_interop(ToUTF8(strFilename), (int)flags, out db); + int n = UnsafeNativeMethods.sqlite3_open_interop(ToUTF8(strFilename), (int)openFlags, out db); #else - int n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, (int)flags, IntPtr.Zero); + int n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, (int)openFlags, IntPtr.Zero); #endif -#if DEBUG +#if DEBUG && !NET_COMPACT_20 Trace.WriteLine(String.Format("Open: {0}", db)); #endif if (n > 0) throw new SQLiteException(n, null); - _sql = db; + _sql = new SQLiteConnectionHandle(db); + 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. - _functionsArray = SQLiteFunction.BindFunctions(this); + _functionsArray = SQLiteFunction.BindFunctions(this, connectionFlags); SetTimeout(0); + GC.KeepAlive(_sql); } internal override void ClearPool() { SQLiteConnectionPool.ClearPool(_fileName); } + + internal override int CountPool() + { + Dictionary counts = null; + int openCount = 0; + int closeCount = 0; + int totalCount = 0; + + SQLiteConnectionPool.GetCounts(_fileName, + ref counts, ref openCount, ref closeCount, + ref totalCount); + + return totalCount; + } internal override void SetTimeout(int nTimeoutMS) { int n = UnsafeNativeMethods.sqlite3_busy_timeout(_sql, nTimeoutMS); - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); + if (n > 0) throw new SQLiteException(n, GetLastError()); } internal override bool Step(SQLiteStatement stmt) { int n; @@ -279,11 +333,11 @@ // schema has changed, re-try the step again. If it errored our because the database // is locked, then keep retrying until the command timeout occurs. r = Reset(stmt); if (r == 0) - throw new SQLiteException(n, SQLiteLastError()); + throw new SQLiteException(n, GetLastError()); else if ((r == 6 || r == 5) && stmt._command != null) // SQLITE_LOCKED || SQLITE_BUSY { // Keep trying if (rnd == null) // First time we've encountered the lock @@ -290,11 +344,11 @@ rnd = new Random(); // If we've exceeded the command's timeout, give up and throw an error if ((uint)Environment.TickCount - starttick > timeout) { - throw new SQLiteException(r, SQLiteLastError()); + throw new SQLiteException(r, GetLastError()); } else { // Otherwise sleep for a random amount of time up to 150ms System.Threading.Thread.Sleep(rnd.Next(1, 150)); @@ -334,18 +388,18 @@ } else if (n == 6 || n == 5) // SQLITE_LOCKED || SQLITE_BUSY return n; if (n > 0) - throw new SQLiteException(n, SQLiteLastError()); + throw new SQLiteException(n, GetLastError()); return 0; // We reset OK, no schema changes } - internal override string SQLiteLastError() + internal override string GetLastError() { - return SQLiteBase.SQLiteLastError(_sql); + return SQLiteBase.GetLastError(_sql, _sql); } internal override SQLiteStatement Prepare(SQLiteConnection cnn, string strSql, SQLiteStatement previous, uint timeoutMS, out string strRemain) { if (!String.IsNullOrEmpty(strSql)) @@ -365,10 +419,23 @@ strSql = strSql.Replace( String.Format("{0}.", baseSchemaName), String.Empty); } } + + SQLiteConnectionFlags flags = + (cnn != null) ? cnn.Flags : SQLiteConnectionFlags.Default; + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogPrepare) == SQLiteConnectionFlags.LogPrepare) + { + if ((strSql == null) || (strSql.Length == 0) || (strSql.Trim().Length == 0)) + SQLiteLog.LogMessage(0, "Preparing {}..."); + else + SQLiteLog.LogMessage(0, String.Format("Preparing {{{0}}}...", strSql)); + } +#endif IntPtr stmt = IntPtr.Zero; IntPtr ptr = IntPtr.Zero; int len = 0; int n = 17; @@ -390,19 +457,19 @@ #else n = UnsafeNativeMethods.sqlite3_prepare(_sql, psql, b.Length - 1, out stmt, out ptr); len = -1; #endif -#if DEBUG +#if DEBUG && !NET_COMPACT_20 Trace.WriteLine(String.Format("Prepare: {0}", stmt)); #endif if (n == 17) retries++; else if (n == 1) { - if (String.Compare(SQLiteLastError(), "near \"TYPES\": syntax error", StringComparison.OrdinalIgnoreCase) == 0) + if (String.Compare(GetLastError(), "near \"TYPES\": syntax error", StringComparison.OrdinalIgnoreCase) == 0) { int pos = strSql.IndexOf(';'); if (pos == -1) pos = strSql.Length - 1; typedefs = strSql.Substring(0, pos + 1); @@ -420,11 +487,11 @@ cmd.SetTypes(typedefs); return cmd; } #if !PLATFORM_COMPACTFRAMEWORK - else if (_buildingSchema == false && String.Compare(SQLiteLastError(), 0, "no such table: TEMP.SCHEMA", 0, 26, StringComparison.OrdinalIgnoreCase) == 0) + else if (_buildingSchema == false && String.Compare(GetLastError(), 0, "no such table: TEMP.SCHEMA", 0, 26, StringComparison.OrdinalIgnoreCase) == 0) { strRemain = ""; _buildingSchema = true; try { @@ -455,163 +522,390 @@ rnd = new Random(); // If we've exceeded the command's timeout, give up and throw an error if ((uint)Environment.TickCount - starttick > timeoutMS) { - throw new SQLiteException(n, SQLiteLastError()); + throw new SQLiteException(n, GetLastError()); } else { // Otherwise sleep for a random amount of time up to 150ms System.Threading.Thread.Sleep(rnd.Next(1, 150)); } } } - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); + if (n > 0) throw new SQLiteException(n, GetLastError()); strRemain = UTF8ToString(ptr, len); - if (stmt != IntPtr.Zero) cmd = new SQLiteStatement(this, stmt, strSql.Substring(0, strSql.Length - strRemain.Length), previous); + if (stmt != IntPtr.Zero) cmd = new SQLiteStatement(this, flags, new SQLiteStatementHandle(_sql, stmt), strSql.Substring(0, strSql.Length - strRemain.Length), previous); return cmd; } finally { handle.Free(); } } - internal override void Bind_Double(SQLiteStatement stmt, int index, double value) - { -#if !PLATFORM_COMPACTFRAMEWORK - int n = UnsafeNativeMethods.sqlite3_bind_double(stmt._sqlite_stmt, index, value); -#else - int n = UnsafeNativeMethods.sqlite3_bind_double_interop(stmt._sqlite_stmt, index, ref value); -#endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - } - - internal override void Bind_Int32(SQLiteStatement stmt, int index, int value) - { - int n = UnsafeNativeMethods.sqlite3_bind_int(stmt._sqlite_stmt, index, value); - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - } - - internal override void Bind_UInt32(SQLiteStatement stmt, int index, uint value) - { - int n = UnsafeNativeMethods.sqlite3_bind_uint(stmt._sqlite_stmt, index, value); - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - } - - internal override void Bind_Int64(SQLiteStatement stmt, int index, long value) - { -#if !PLATFORM_COMPACTFRAMEWORK - int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value); -#else - int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value); -#endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - } - - internal override void Bind_UInt64(SQLiteStatement stmt, int index, ulong value) - { -#if !PLATFORM_COMPACTFRAMEWORK - int n = UnsafeNativeMethods.sqlite3_bind_uint64(stmt._sqlite_stmt, index, value); -#else - int n = UnsafeNativeMethods.sqlite3_bind_uint64_interop(stmt._sqlite_stmt, index, ref value); -#endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - } - - internal override void Bind_Text(SQLiteStatement stmt, int index, string value) - { - byte[] b = ToUTF8(value); - int n = UnsafeNativeMethods.sqlite3_bind_text(stmt._sqlite_stmt, index, b, b.Length - 1, (IntPtr)(-1)); - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - } - - internal override void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt) - { +#if !PLATFORM_COMPACTFRAMEWORK + protected static void LogBind(SQLiteStatementHandle handle, int index) + { + IntPtr handleIntPtr = handle; + + SQLiteLog.LogMessage(0, String.Format( + "Binding statement {0} paramter #{1} as NULL...", + handleIntPtr, index)); + } + + protected static void LogBind(SQLiteStatementHandle handle, int index, ValueType value) + { + IntPtr handleIntPtr = handle; + + SQLiteLog.LogMessage(0, String.Format( + "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...", + handleIntPtr, index, value.GetType(), value)); + } + + private static string FormatDateTime(DateTime value) + { + StringBuilder result = new StringBuilder(); + + result.Append(value.ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFK")); + result.Append(' '); + result.Append(value.Kind); + result.Append(' '); + result.Append(value.Ticks); + + return result.ToString(); + } + + protected static void LogBind(SQLiteStatementHandle handle, int index, DateTime value) + { + IntPtr handleIntPtr = handle; + + SQLiteLog.LogMessage(0, String.Format( + "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...", + handleIntPtr, index, typeof(DateTime), FormatDateTime(value))); + } + + protected static void LogBind(SQLiteStatementHandle handle, int index, string value) + { + IntPtr handleIntPtr = handle; + + SQLiteLog.LogMessage(0, String.Format( + "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...", + handleIntPtr, index, typeof(String), (value != null) ? value : "")); + } + + private static string ToHexadecimalString( + byte[] array + ) + { + if (array == null) + return null; + + StringBuilder result = new StringBuilder(array.Length * 2); + + int length = array.Length; + + for (int index = 0; index < length; index++) + result.Append(array[index].ToString("x2")); + + return result.ToString(); + } + + protected static void LogBind(SQLiteStatementHandle handle, int index, byte[] value) + { + IntPtr handleIntPtr = handle; + + SQLiteLog.LogMessage(0, String.Format( + "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...", + handleIntPtr, index, typeof(Byte[]), (value != null) ? ToHexadecimalString(value) : "")); + } +#endif + + internal override void Bind_Double(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, double value) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, value); + } + + int n = UnsafeNativeMethods.sqlite3_bind_double(handle, index, value); +#else + int n = UnsafeNativeMethods.sqlite3_bind_double_interop(handle, index, ref value); +#endif + if (n > 0) throw new SQLiteException(n, GetLastError()); + } + + internal override void Bind_Int32(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, int value) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, value); + } +#endif + + int n = UnsafeNativeMethods.sqlite3_bind_int(handle, index, value); + if (n > 0) throw new SQLiteException(n, GetLastError()); + } + + internal override void Bind_UInt32(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, uint value) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, value); + } +#endif + + int n = UnsafeNativeMethods.sqlite3_bind_uint(handle, index, value); + if (n > 0) throw new SQLiteException(n, GetLastError()); + } + + internal override void Bind_Int64(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, long value) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, value); + } + + int n = UnsafeNativeMethods.sqlite3_bind_int64(handle, index, value); +#else + int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(handle, index, ref value); +#endif + if (n > 0) throw new SQLiteException(n, GetLastError()); + } + + internal override void Bind_UInt64(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, ulong value) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, value); + } + + int n = UnsafeNativeMethods.sqlite3_bind_uint64(handle, index, value); +#else + int n = UnsafeNativeMethods.sqlite3_bind_uint64_interop(handle, index, ref value); +#endif + if (n > 0) throw new SQLiteException(n, GetLastError()); + } + + internal override void Bind_Text(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, string value) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, value); + } +#endif + + byte[] b = ToUTF8(value); + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, b); + } +#endif + + int n = UnsafeNativeMethods.sqlite3_bind_text(handle, index, b, b.Length - 1, (IntPtr)(-1)); + if (n > 0) throw new SQLiteException(n, GetLastError()); + } + + internal override void Bind_DateTime(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, DateTime dt) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, dt); + } +#endif + switch (_datetimeFormat) { case SQLiteDateFormats.Ticks: { long value = dt.Ticks; #if !PLATFORM_COMPACTFRAMEWORK - int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value); + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, value); + } + + int n = UnsafeNativeMethods.sqlite3_bind_int64(handle, index, value); #else - int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value); + int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(handle, index, ref value); #endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); + if (n > 0) throw new SQLiteException(n, GetLastError()); break; } case SQLiteDateFormats.JulianDay: { double value = ToJulianDay(dt); #if !PLATFORM_COMPACTFRAMEWORK - int n = UnsafeNativeMethods.sqlite3_bind_double(stmt._sqlite_stmt, index, value); + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, value); + } + + int n = UnsafeNativeMethods.sqlite3_bind_double(handle, index, value); #else - int n = UnsafeNativeMethods.sqlite3_bind_double_interop(stmt._sqlite_stmt, index, ref value); + int n = UnsafeNativeMethods.sqlite3_bind_double_interop(handle, index, ref value); #endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); + if (n > 0) throw new SQLiteException(n, GetLastError()); break; } case SQLiteDateFormats.UnixEpoch: { long value = Convert.ToInt64(dt.Subtract(UnixEpoch).TotalSeconds); #if !PLATFORM_COMPACTFRAMEWORK - int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value); + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, value); + } + + int n = UnsafeNativeMethods.sqlite3_bind_int64(handle, index, value); #else - int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value); + int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(handle, index, ref value); #endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); + if (n > 0) throw new SQLiteException(n, GetLastError()); break; } default: { byte[] b = ToUTF8(dt); - int n = UnsafeNativeMethods.sqlite3_bind_text(stmt._sqlite_stmt, index, b, b.Length - 1, (IntPtr)(-1)); - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, b); + } +#endif + + int n = UnsafeNativeMethods.sqlite3_bind_text(handle, index, b, b.Length - 1, (IntPtr)(-1)); + if (n > 0) throw new SQLiteException(n, GetLastError()); break; } } } - internal override void Bind_Blob(SQLiteStatement stmt, int index, byte[] blobData) - { - int n = UnsafeNativeMethods.sqlite3_bind_blob(stmt._sqlite_stmt, index, blobData, blobData.Length, (IntPtr)(-1)); - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - } - - internal override void Bind_Null(SQLiteStatement stmt, int index) - { - int n = UnsafeNativeMethods.sqlite3_bind_null(stmt._sqlite_stmt, index); - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - } - - internal override int Bind_ParamCount(SQLiteStatement stmt) - { - return UnsafeNativeMethods.sqlite3_bind_parameter_count(stmt._sqlite_stmt); - } - - internal override string Bind_ParamName(SQLiteStatement stmt, int index) - { + internal override void Bind_Blob(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, byte[] blobData) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, blobData); + } +#endif + + int n = UnsafeNativeMethods.sqlite3_bind_blob(handle, index, blobData, blobData.Length, (IntPtr)(-1)); + if (n > 0) throw new SQLiteException(n, GetLastError()); + } + + internal override void Bind_Null(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index); + } +#endif + + int n = UnsafeNativeMethods.sqlite3_bind_null(handle, index); + if (n > 0) throw new SQLiteException(n, GetLastError()); + } + + internal override int Bind_ParamCount(SQLiteStatement stmt, SQLiteConnectionFlags flags) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + int value = UnsafeNativeMethods.sqlite3_bind_parameter_count(handle); + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + IntPtr handleIntPtr = handle; + + SQLiteLog.LogMessage(0, String.Format( + "Statement {0} paramter count is {1}.", + handleIntPtr, value)); + } +#endif + + return value; + } + + internal override string Bind_ParamName(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + string name; + #if !SQLITE_STANDARD - int len; - return UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name_interop(stmt._sqlite_stmt, index, out len), len); + int len; + name = UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name_interop(handle, index, out len), len); #else - return UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name(stmt._sqlite_stmt, index), -1); + name = UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name(handle, index), -1); +#endif + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + IntPtr handleIntPtr = handle; + + SQLiteLog.LogMessage(0, String.Format( + "Statement {0} paramter #{1} name is {{{2}}}.", + handleIntPtr, index, name)); + } #endif + + return name; } - internal override int Bind_ParamIndex(SQLiteStatement stmt, string paramName) + internal override int Bind_ParamIndex(SQLiteStatement stmt, SQLiteConnectionFlags flags, string paramName) { - return UnsafeNativeMethods.sqlite3_bind_parameter_index(stmt._sqlite_stmt, ToUTF8(paramName)); + SQLiteStatementHandle handle = stmt._sqlite_stmt; + int index = UnsafeNativeMethods.sqlite3_bind_parameter_index(handle, ToUTF8(paramName)); + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + IntPtr handleIntPtr = handle; + + SQLiteLog.LogMessage(0, String.Format( + "Statement {0} paramter index of name {{{1}}} is #{2}.", + handleIntPtr, paramName, index)); + } +#endif + + return index; } internal override int ColumnCount(SQLiteStatement stmt) { return UnsafeNativeMethods.sqlite3_column_count(stmt._sqlite_stmt); @@ -727,11 +1021,11 @@ dtLen = -1; csLen = -1; n = UnsafeNativeMethods.sqlite3_table_column_metadata(_sql, ToUTF8(dataBase), ToUTF8(table), ToUTF8(column), out dataTypePtr, out collSeqPtr, out nnotNull, out nprimaryKey, out nautoInc); #endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); + if (n > 0) throw new SQLiteException(n, GetLastError()); dataType = UTF8ToString(dataTypePtr, dtLen); collateSequence = UTF8ToString(collSeqPtr, csLen); notNull = (nnotNull == 1); @@ -851,18 +1145,18 @@ if (n == 0) n = UnsafeNativeMethods.sqlite3_create_function_interop(_sql, ToUTF8(strFunction), nArgs, 1, IntPtr.Zero, func, funcstep, funcfinal, (needCollSeq == true) ? 1 : 0); #else n = UnsafeNativeMethods.sqlite3_create_function(_sql, ToUTF8(strFunction), nArgs, 4, IntPtr.Zero, func, funcstep, funcfinal); if (n == 0) n = UnsafeNativeMethods.sqlite3_create_function(_sql, ToUTF8(strFunction), nArgs, 1, IntPtr.Zero, func, funcstep, funcfinal); #endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); + if (n > 0) throw new SQLiteException(n, GetLastError()); } internal override void CreateCollation(string strCollation, SQLiteCollation func, SQLiteCollation func16) { int n = UnsafeNativeMethods.sqlite3_create_collation(_sql, ToUTF8(strCollation), 2, IntPtr.Zero, func16); if (n == 0) n = UnsafeNativeMethods.sqlite3_create_collation(_sql, ToUTF8(strCollation), 1, IntPtr.Zero, func); - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); + if (n > 0) throw new SQLiteException(n, GetLastError()); } internal override int ContextCollateCompare(CollationEncodingEnum enc, IntPtr context, string s1, string s2) { #if !SQLITE_STANDARD @@ -1078,21 +1372,23 @@ internal override void LogMessage(int iErrCode, string zMessage) { UnsafeNativeMethods.sqlite3_log(iErrCode, ToUTF8(zMessage)); } +#if INTEROP_CODEC internal override void SetPassword(byte[] passwordBytes) { int n = UnsafeNativeMethods.sqlite3_key(_sql, passwordBytes, passwordBytes.Length); - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); + if (n > 0) throw new SQLiteException(n, GetLastError()); } internal override void ChangePassword(byte[] newPasswordBytes) { int n = UnsafeNativeMethods.sqlite3_rekey(_sql, newPasswordBytes, (newPasswordBytes == null) ? 0 : newPasswordBytes.Length); - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); + if (n > 0) throw new SQLiteException(n, GetLastError()); } +#endif internal override void SetUpdateHook(SQLiteUpdateCallback func) { UnsafeNativeMethods.sqlite3_update_hook(_sql, func, IntPtr.Zero); } @@ -1125,10 +1421,202 @@ (int)SQLiteConfigOpsEnum.SQLITE_CONFIG_LOG, func, (IntPtr)0); return rc; } + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// + /// Creates a new SQLite backup object based on the provided destination + /// database connection. The source database connection is the one + /// associated with this object. The source and destination database + /// connections cannot be the same. + /// + /// The destination database connection. + /// The destination database name. + /// The source database name. + /// The newly created backup object. + internal override SQLiteBackup InitializeBackup( + SQLiteConnection destCnn, + string destName, + string sourceName + ) + { + if (destCnn == null) + throw new ArgumentNullException("destCnn"); + + if (destName == null) + throw new ArgumentNullException("destName"); + + if (sourceName == null) + throw new ArgumentNullException("sourceName"); + + SQLite3 destSqlite3 = destCnn._sql as SQLite3; + + if (destSqlite3 == null) + throw new ArgumentException( + "Destination connection has no wrapper.", + "destCnn"); + + SQLiteConnectionHandle destHandle = destSqlite3._sql; + + if (destHandle == null) + throw new ArgumentException( + "Destination connection has an invalid handle.", + "destCnn"); + + SQLiteConnectionHandle sourceHandle = _sql; + + if (sourceHandle == null) + throw new InvalidOperationException( + "Source connection has an invalid handle."); + + byte[] zDestName = ToUTF8(destName); + byte[] zSourceName = ToUTF8(sourceName); + + IntPtr backup = UnsafeNativeMethods.sqlite3_backup_init( + destHandle, zDestName, sourceHandle, zSourceName); + + if (backup == IntPtr.Zero) + throw new SQLiteException(ResultCode(), GetLastError()); + + return new SQLiteBackup( + this, new SQLiteBackupHandle(destHandle, backup), + destHandle, zDestName, sourceHandle, zSourceName); + } + + /// + /// Copies up to N pages from the source database to the destination + /// database associated with the specified backup object. + /// + /// The backup object to use. + /// + /// The number of pages to copy, negative to copy all remaining pages. + /// + /// + /// Set to true if the operation needs to be retried due to database + /// locking issues; otherwise, set to false. + /// + /// + /// True if there are more pages to be copied, false otherwise. + /// + internal override bool StepBackup( + SQLiteBackup backup, + int nPage, + out bool retry + ) + { + retry = false; + + if (backup == null) + throw new ArgumentNullException("backup"); + + SQLiteBackupHandle handle = backup._sqlite_backup; + + if (handle == null) + throw new InvalidOperationException( + "Backup object has an invalid handle."); + + int n = UnsafeNativeMethods.sqlite3_backup_step(handle, nPage); + backup._stepResult = n; /* NOTE: Save for use by FinishBackup. */ + + if (n == (int)SQLiteErrorCode.Ok) + { + return true; + } + else if (n == (int)SQLiteErrorCode.Busy) + { + retry = true; + return true; + } + else if (n == (int)SQLiteErrorCode.Locked) + { + retry = true; + return true; + } + else if (n == (int)SQLiteErrorCode.Done) + { + return false; + } + else + { + throw new SQLiteException(n, GetLastError()); + } + } + + /// + /// Returns the number of pages remaining to be copied from the source + /// database to the destination database associated with the specified + /// backup object. + /// + /// The backup object to check. + /// The number of pages remaining to be copied. + internal override int RemainingBackup( + SQLiteBackup backup + ) + { + if (backup == null) + throw new ArgumentNullException("backup"); + + SQLiteBackupHandle handle = backup._sqlite_backup; + + if (handle == null) + throw new InvalidOperationException( + "Backup object has an invalid handle."); + + return UnsafeNativeMethods.sqlite3_backup_remaining(handle); + } + + /// + /// Returns the total number of pages in the source database associated + /// with the specified backup object. + /// + /// The backup object to check. + /// The total number of pages in the source database. + internal override int PageCountBackup( + SQLiteBackup backup + ) + { + if (backup == null) + throw new ArgumentNullException("backup"); + + SQLiteBackupHandle handle = backup._sqlite_backup; + + if (handle == null) + throw new InvalidOperationException( + "Backup object has an invalid handle."); + + return UnsafeNativeMethods.sqlite3_backup_pagecount(handle); + } + + /// + /// Destroys the backup object, rolling back any backup that may be in + /// progess. + /// + /// The backup object to destroy. + internal override void FinishBackup( + SQLiteBackup backup + ) + { + if (backup == null) + throw new ArgumentNullException("backup"); + + SQLiteBackupHandle handle = backup._sqlite_backup; + + if (handle == null) + throw new InvalidOperationException( + "Backup object has an invalid handle."); + + int n = UnsafeNativeMethods.sqlite3_backup_finish(handle); + handle.SetHandleAsInvalid(); + + if ((n > 0) && (n != backup._stepResult)) + throw new SQLiteException(n, GetLastError()); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /// /// Determines if the SQLite core library has been initialized for the /// current process. /// /// @@ -1149,32 +1637,43 @@ /// initialized for the current process. /// internal static bool StaticIsInitialized() { // - // NOTE: Save the state of the logging class and then restore it - // after we are done to avoid logging too many false errors. - // - bool savedEnabled = SQLiteLog.Enabled; - SQLiteLog.Enabled = false; - - try - { - // - // NOTE: This method [ab]uses the fact that SQLite will always - // return SQLITE_ERROR for any unknown configuration option - // *unless* the SQLite library has already been initialized. - // In that case it will always return SQLITE_MISUSE. - // - int rc = UnsafeNativeMethods.sqlite3_config( - (int)SQLiteConfigOpsEnum.SQLITE_CONFIG_NONE, null, (IntPtr)0); - - return (rc == /* SQLITE_MISUSE */ 21); - } - finally - { - SQLiteLog.Enabled = savedEnabled; + // BUGFIX: Prevent races with other threads for this entire block, due + // to the try/finally semantics. See ticket [72905c9a77]. + // + lock (syncRoot) + { +#if !PLATFORM_COMPACTFRAMEWORK + // + // NOTE: Save the state of the logging class and then restore it + // after we are done to avoid logging too many false errors. + // + bool savedEnabled = SQLiteLog.Enabled; + SQLiteLog.Enabled = false; + + try + { +#endif + // + // NOTE: This method [ab]uses the fact that SQLite will always + // return SQLITE_ERROR for any unknown configuration option + // *unless* the SQLite library has already been initialized. + // In that case it will always return SQLITE_MISUSE. + // + int rc = UnsafeNativeMethods.sqlite3_config( + (int)SQLiteConfigOpsEnum.SQLITE_CONFIG_NONE, null, (IntPtr)0); + + return (rc == /* SQLITE_MISUSE */ 21); +#if !PLATFORM_COMPACTFRAMEWORK + } + finally + { + SQLiteLog.Enabled = savedEnabled; + } +#endif } } /// /// Helper function to retrieve a column of data from an active statement. Index: System.Data.SQLite/SQLite3_UTF16.cs ================================================================== --- System.Data.SQLite/SQLite3_UTF16.cs +++ System.Data.SQLite/SQLite3_UTF16.cs @@ -6,76 +6,76 @@ ********************************************************/ namespace System.Data.SQLite { using System; -#if DEBUG +#if DEBUG using System.Diagnostics; #endif using System.Runtime.InteropServices; /// /// Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode) /// internal class SQLite3_UTF16 : SQLite3 { - internal SQLite3_UTF16(SQLiteDateFormats fmt, DateTimeKind kind) - : base(fmt, kind) - { - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - - #region IDisposable "Pattern" Members - private bool disposed; - private void CheckDisposed() /* throw */ - { -#if THROW_ON_DISPOSED - if (disposed) - throw new ObjectDisposedException(typeof(SQLite3_UTF16).Name); -#endif - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - - protected override void Dispose(bool disposing) - { - try - { - if (!disposed) - { - //if (disposing) - //{ - // //////////////////////////////////// - // // dispose managed resources here... - // //////////////////////////////////// - //} - - ////////////////////////////////////// - // release unmanaged resources here... - ////////////////////////////////////// - - disposed = true; - } - } - finally - { - base.Dispose(disposing); - } - } - #endregion - - /////////////////////////////////////////////////////////////////////////////////////////////// - + internal SQLite3_UTF16(SQLiteDateFormats fmt, DateTimeKind kind) + : base(fmt, kind) + { + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + + #region IDisposable "Pattern" Members + private bool disposed; + private void CheckDisposed() /* throw */ + { +#if THROW_ON_DISPOSED + if (disposed) + throw new ObjectDisposedException(typeof(SQLite3_UTF16).Name); +#endif + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + + protected override void Dispose(bool disposing) + { + try + { + if (!disposed) + { + //if (disposing) + //{ + // //////////////////////////////////// + // // dispose managed resources here... + // //////////////////////////////////// + //} + + ////////////////////////////////////// + // release unmanaged resources here... + ////////////////////////////////////// + + disposed = true; + } + } + finally + { + base.Dispose(disposing); + } + } + #endregion + + /////////////////////////////////////////////////////////////////////////////////////////////// + /// /// Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 /// /// A pointer to a UTF-16 string /// The length (IN BYTES) of the string /// A .NET string public override string ToString(IntPtr b, int nbytelen) - { + { CheckDisposed(); return UTF16ToString(b, nbytelen); } public static string UTF16ToString(IntPtr b, int nbytelen) @@ -86,170 +86,168 @@ return Marshal.PtrToStringUni(b); else return Marshal.PtrToStringUni(b, nbytelen / 2); } - internal override void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool) - { + internal override void Open(string strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool) + { if (_sql != null) return; _usePool = usePool; + _fileName = strFilename; + if (usePool) { - _fileName = strFilename; _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion); + +#if DEBUG && !NET_COMPACT_20 + Trace.WriteLine(String.Format("Open (Pool): {0}", (_sql != null) ? _sql.ToString() : "")); +#endif } if (_sql == null) { IntPtr db; #if !SQLITE_STANDARD - int n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), (int)flags, out db); + int n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), (int)openFlags, out db); #else - if ((flags & SQLiteOpenFlagsEnum.Create) == 0 && System.IO.File.Exists(strFilename) == false) + if ((openFlags & SQLiteOpenFlagsEnum.Create) == 0 && System.IO.File.Exists(strFilename) == false) throw new SQLiteException((int)SQLiteErrorCode.CantOpen, strFilename); int n = UnsafeNativeMethods.sqlite3_open16(strFilename, out db); -#endif - -#if DEBUG - Trace.WriteLine(String.Format("Open: {0}", db)); -#endif - - if (n > 0) throw new SQLiteException(n, null); - - _sql = db; - } - _functionsArray = SQLiteFunction.BindFunctions(this); - } - - internal override void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt) - { - switch (_datetimeFormat) - { - case SQLiteDateFormats.Ticks: - { - long value = dt.Ticks; - -#if !PLATFORM_COMPACTFRAMEWORK - int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value); -#else - int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value); -#endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - break; - } - case SQLiteDateFormats.JulianDay: - { - double value = ToJulianDay(dt); - -#if !PLATFORM_COMPACTFRAMEWORK - int n = UnsafeNativeMethods.sqlite3_bind_double(stmt._sqlite_stmt, index, value); -#else - int n = UnsafeNativeMethods.sqlite3_bind_double_interop(stmt._sqlite_stmt, index, ref value); -#endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - break; - } - case SQLiteDateFormats.UnixEpoch: - { - long value = Convert.ToInt64(dt.Subtract(UnixEpoch).TotalSeconds); - -#if !PLATFORM_COMPACTFRAMEWORK - int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value); -#else - int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value); -#endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - break; - } - default: - { - Bind_Text(stmt, index, ToString(dt)); - break; - } - } - } - - internal override void Bind_Text(SQLiteStatement stmt, int index, string value) - { - int n = UnsafeNativeMethods.sqlite3_bind_text16(stmt._sqlite_stmt, index, value, value.Length * 2, (IntPtr)(-1)); - if (n > 0) throw new SQLiteException(n, SQLiteLastError()); - } - - internal override DateTime GetDateTime(SQLiteStatement stmt, int index) - { +#endif + +#if DEBUG && !NET_COMPACT_20 + Trace.WriteLine(String.Format("Open: {0}", db)); +#endif + + if (n > 0) throw new SQLiteException(n, null); + + _sql = new SQLiteConnectionHandle(db); + lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ } + } + _functionsArray = SQLiteFunction.BindFunctions(this, connectionFlags); + SetTimeout(0); + GC.KeepAlive(_sql); + } + + internal override void Bind_DateTime(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, DateTime dt) + { + switch (_datetimeFormat) + { + case SQLiteDateFormats.Ticks: + case SQLiteDateFormats.JulianDay: + case SQLiteDateFormats.UnixEpoch: + { + base.Bind_DateTime(stmt, flags, index, dt); + break; + } + default: + { +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + SQLiteStatementHandle handle = + (stmt != null) ? stmt._sqlite_stmt : null; + + LogBind(handle, index, dt); + } +#endif + + Bind_Text(stmt, flags, index, ToString(dt)); + break; + } + } + } + + internal override void Bind_Text(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, string value) + { + SQLiteStatementHandle handle = stmt._sqlite_stmt; + +#if !PLATFORM_COMPACTFRAMEWORK + if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind) + { + LogBind(handle, index, value); + } +#endif + + int n = UnsafeNativeMethods.sqlite3_bind_text16(handle, index, value, value.Length * 2, (IntPtr)(-1)); + if (n > 0) throw new SQLiteException(n, GetLastError()); + } + + internal override DateTime GetDateTime(SQLiteStatement stmt, int index) + { return ToDateTime(GetText(stmt, index)); } internal override string ColumnName(SQLiteStatement stmt, int index) - { + { #if !SQLITE_STANDARD int len; return UTF16ToString(UnsafeNativeMethods.sqlite3_column_name16_interop(stmt._sqlite_stmt, index, out len), len); #else return UTF16ToString(UnsafeNativeMethods.sqlite3_column_name16(stmt._sqlite_stmt, index), -1); #endif } internal override string GetText(SQLiteStatement stmt, int index) - { + { #if !SQLITE_STANDARD int len; return UTF16ToString(UnsafeNativeMethods.sqlite3_column_text16_interop(stmt._sqlite_stmt, index, out len), len); #else return UTF16ToString(UnsafeNativeMethods.sqlite3_column_text16(stmt._sqlite_stmt, index), -1); #endif } internal override string ColumnOriginalName(SQLiteStatement stmt, int index) - { + { #if !SQLITE_STANDARD int len; return UTF16ToString(UnsafeNativeMethods.sqlite3_column_origin_name16_interop(stmt._sqlite_stmt, index, out len), len); #else return UTF16ToString(UnsafeNativeMethods.sqlite3_column_origin_name16(stmt._sqlite_stmt, index), -1); #endif } internal override string ColumnDatabaseName(SQLiteStatement stmt, int index) - { + { #if !SQLITE_STANDARD int len; return UTF16ToString(UnsafeNativeMethods.sqlite3_column_database_name16_interop(stmt._sqlite_stmt, index, out len), len); #else return UTF16ToString(UnsafeNativeMethods.sqlite3_column_database_name16(stmt._sqlite_stmt, index), -1); #endif } internal override string ColumnTableName(SQLiteStatement stmt, int index) - { + { #if !SQLITE_STANDARD int len; return UTF16ToString(UnsafeNativeMethods.sqlite3_column_table_name16_interop(stmt._sqlite_stmt, index, out len), len); #else return UTF16ToString(UnsafeNativeMethods.sqlite3_column_table_name16(stmt._sqlite_stmt, index), -1); #endif } internal override string GetParamValueText(IntPtr ptr) - { + { #if !SQLITE_STANDARD int len; return UTF16ToString(UnsafeNativeMethods.sqlite3_value_text16_interop(ptr, out len), len); #else return UTF16ToString(UnsafeNativeMethods.sqlite3_value_text16(ptr), -1); #endif } internal override void ReturnError(IntPtr context, string value) - { + { UnsafeNativeMethods.sqlite3_result_error16(context, value, value.Length * 2); } - internal override void ReturnText(IntPtr context, string value) - { + internal override void ReturnText(IntPtr context, string value) + { UnsafeNativeMethods.sqlite3_result_text16(context, value, value.Length * 2, (IntPtr)(-1)); } } } ADDED System.Data.SQLite/SQLiteBackup.cs Index: System.Data.SQLite/SQLiteBackup.cs ================================================================== --- /dev/null +++ System.Data.SQLite/SQLiteBackup.cs @@ -0,0 +1,149 @@ +/******************************************************** + * ADO.NET 2.0 Data Provider for SQLite Version 3.X + * Written by Robert Simpson (robert@blackcastlesoft.com) + * + * Released to the public domain, use at your own risk! + ********************************************************/ + +namespace System.Data.SQLite +{ + using System; + + /// + /// Represents a single SQL backup in SQLite. + /// + internal sealed class SQLiteBackup : IDisposable + { + /// + /// The underlying SQLite object this backup is bound to. + /// + internal SQLiteBase _sql; + + /// + /// The actual backup handle. + /// + internal SQLiteBackupHandle _sqlite_backup; + + /// + /// The destination database for the backup. + /// + internal IntPtr _destDb; + + /// + /// The destination database name for the backup. + /// + internal byte[] _zDestName; + + /// + /// The source database for the backup. + /// + internal IntPtr _sourceDb; + + /// + /// The source database name for the backup. + /// + internal byte[] _zSourceName; + + /// + /// The last result from the StepBackup method of the SQLite3 class. + /// This is used to determine if the call to the FinishBackup method of + /// the SQLite3 class should throw an exception when it receives a non-Ok + /// return code from the core SQLite library. + /// + internal int _stepResult; + + /// + /// Initializes the backup. + /// + /// The base SQLite object. + /// The backup handle. + /// The destination database for the backup. + /// The destination database name for the backup. + /// The source database for the backup. + /// The source database name for the backup. + internal SQLiteBackup( + SQLiteBase sqlbase, + SQLiteBackupHandle backup, + IntPtr destDb, + byte[] zDestName, + IntPtr sourceDb, + byte[] zSourceName + ) + { + _sql = sqlbase; + _sqlite_backup = backup; + _destDb = destDb; + _zDestName = zDestName; + _sourceDb = sourceDb; + _zSourceName = zSourceName; + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + + #region IDisposable Members + /// + /// Disposes and finalizes the backup. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + + /////////////////////////////////////////////////////////////////////////////////////////////// + + #region IDisposable "Pattern" Members + private bool disposed; + private void CheckDisposed() /* throw */ + { +#if THROW_ON_DISPOSED + if (disposed) + throw new ObjectDisposedException(typeof(SQLiteBackup).Name); +#endif + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + + private void Dispose(bool disposing) + { + if (!disposed) + { + if (disposing) + { + //////////////////////////////////// + // dispose managed resources here... + //////////////////////////////////// + + if (_sqlite_backup != null) + { + _sqlite_backup.Dispose(); + _sqlite_backup = null; + } + + _zSourceName = null; + _sourceDb = IntPtr.Zero; + _zDestName = null; + _destDb = IntPtr.Zero; + _sql = null; + } + + ////////////////////////////////////// + // release unmanaged resources here... + ////////////////////////////////////// + + disposed = true; + } + } + #endregion + + /////////////////////////////////////////////////////////////////////////////////////////////// + + #region Destructor + ~SQLiteBackup() + { + Dispose(false); + } + #endregion + } +} Index: System.Data.SQLite/SQLiteBase.cs ================================================================== --- System.Data.SQLite/SQLiteBase.cs +++ System.Data.SQLite/SQLiteBase.cs @@ -16,12 +16,10 @@ internal abstract class SQLiteBase : SQLiteConvert, IDisposable { internal SQLiteBase(SQLiteDateFormats fmt, DateTimeKind kind) : base(fmt, kind) { } - static internal object _lock = new object(); - /// /// Returns a string representing the active version of SQLite /// internal abstract string Version { get; } /// @@ -56,14 +54,15 @@ /// /// Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection /// to bind all attributed user-defined functions and collating sequences to the new connection. /// /// The filename of the database to open. SQLite automatically creates it if it doesn't exist. - /// The open flags to use when creating the connection + /// The flags associated with the parent connection object + /// The open flags to use when creating the connection /// The maximum size of the pool for the given filename /// If true, the connection can be pulled from the connection pool - internal abstract void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool); + internal abstract void Open(string strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool); /// /// Closes the currently-open database. /// /// /// After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated @@ -77,17 +76,23 @@ internal abstract void SetTimeout(int nTimeoutMS); /// /// Returns the text of the last error issued by SQLite /// /// - internal abstract string SQLiteLastError(); + internal abstract string GetLastError(); /// /// When pooling is enabled, force this connection to be disposed rather than returned to the pool /// internal abstract void ClearPool(); + /// + /// When pooling is enabled, returns the number of pool entries matching the current file name. + /// + /// The number of pool entries matching the current file name. + internal abstract int CountPool(); + /// /// Prepares a SQL statement for execution. /// /// The source connection preparing the command. Can be null for any caller except LINQ /// The SQL command text to prepare @@ -111,23 +116,23 @@ /// The statement to reset /// Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock internal abstract int Reset(SQLiteStatement stmt); internal abstract void Cancel(); - internal abstract void Bind_Double(SQLiteStatement stmt, int index, double value); - internal abstract void Bind_Int32(SQLiteStatement stmt, int index, Int32 value); - internal abstract void Bind_UInt32(SQLiteStatement stmt, int index, UInt32 value); - internal abstract void Bind_Int64(SQLiteStatement stmt, int index, Int64 value); - internal abstract void Bind_UInt64(SQLiteStatement stmt, int index, UInt64 value); - internal abstract void Bind_Text(SQLiteStatement stmt, int index, string value); - internal abstract void Bind_Blob(SQLiteStatement stmt, int index, byte[] blobData); - internal abstract void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt); - internal abstract void Bind_Null(SQLiteStatement stmt, int index); - - internal abstract int Bind_ParamCount(SQLiteStatement stmt); - internal abstract string Bind_ParamName(SQLiteStatement stmt, int index); - internal abstract int Bind_ParamIndex(SQLiteStatement stmt, string paramName); + internal abstract void Bind_Double(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, double value); + internal abstract void Bind_Int32(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, Int32 value); + internal abstract void Bind_UInt32(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, UInt32 value); + internal abstract void Bind_Int64(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, Int64 value); + internal abstract void Bind_UInt64(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, UInt64 value); + internal abstract void Bind_Text(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, string value); + internal abstract void Bind_Blob(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, byte[] blobData); + internal abstract void Bind_DateTime(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, DateTime dt); + internal abstract void Bind_Null(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index); + + internal abstract int Bind_ParamCount(SQLiteStatement stmt, SQLiteConnectionFlags flags); + internal abstract string Bind_ParamName(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index); + internal abstract int Bind_ParamIndex(SQLiteStatement stmt, SQLiteConnectionFlags flags, string paramName); internal abstract int ColumnCount(SQLiteStatement stmt); internal abstract string ColumnName(SQLiteStatement stmt, int index); internal abstract TypeAffinity ColumnAffinity(SQLiteStatement stmt, int index); internal abstract string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity); @@ -198,12 +203,14 @@ /// interface, this should be pre-formatted. Consider using the /// String.Format() function. /// internal abstract void LogMessage(int iErrCode, string zMessage); +#if INTEROP_CODEC internal abstract void SetPassword(byte[] passwordBytes); internal abstract void ChangePassword(byte[] newPasswordBytes); +#endif internal abstract void SetUpdateHook(SQLiteUpdateCallback func); internal abstract void SetCommitHook(SQLiteCommitCallback func); internal abstract void SetTraceCallback(SQLiteTraceCallback func); internal abstract void SetRollbackHook(SQLiteRollbackCallback func); @@ -220,10 +227,65 @@ get; } internal abstract int FileControl(string zDbName, int op, IntPtr pArg); + /// + /// Creates a new SQLite backup object based on the provided destination + /// database connection. The source database connection is the one + /// associated with this object. The source and destination database + /// connections cannot be the same. + /// + /// The destination database connection. + /// The destination database name. + /// The source database name. + /// The newly created backup object. + internal abstract SQLiteBackup InitializeBackup( + SQLiteConnection destCnn, string destName, + string sourceName); + + /// + /// Copies up to N pages from the source database to the destination + /// database associated with the specified backup object. + /// + /// The backup object to use. + /// + /// The number of pages to copy or negative to copy all remaining pages. + /// + /// + /// Set to true if the operation needs to be retried due to database + /// locking issues. + /// + /// + /// True if there are more pages to be copied, false otherwise. + /// + internal abstract bool StepBackup(SQLiteBackup backup, int nPage, out bool retry); + + /// + /// Returns the number of pages remaining to be copied from the source + /// database to the destination database associated with the specified + /// backup object. + /// + /// The backup object to check. + /// The number of pages remaining to be copied. + internal abstract int RemainingBackup(SQLiteBackup backup); + + /// + /// Returns the total number of pages in the source database associated + /// with the specified backup object. + /// + /// The backup object to check. + /// The total number of pages in the source database. + internal abstract int PageCountBackup(SQLiteBackup backup); + + /// + /// Destroys the backup object, rolling back any backup that may be in + /// progess. + /// + /// The backup object to destroy. + internal abstract void FinishBackup(SQLiteBackup backup); + /////////////////////////////////////////////////////////////////////////////////////////////// #region IDisposable Members public void Dispose() { @@ -280,79 +342,114 @@ // These statics are here for lack of a better place to put them. // They exist here because they are called during the finalization of // a SQLiteStatementHandle, SQLiteConnectionHandle, and SQLiteFunctionCookieHandle. // Therefore these functions have to be static, and have to be low-level. - internal static string SQLiteLastError(SQLiteConnectionHandle db) - { -#if !SQLITE_STANDARD - int len; - return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(db, out len), len); -#else - return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1); -#endif - } - - internal static void FinalizeStatement(SQLiteStatementHandle stmt) - { - lock (_lock) - { -#if !SQLITE_STANDARD - int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt); -#else - int n = UnsafeNativeMethods.sqlite3_finalize(stmt); -#endif - if (n > 0) throw new SQLiteException(n, null); - } - } - - internal static void CloseConnection(SQLiteConnectionHandle db) - { - lock (_lock) - { -#if !SQLITE_STANDARD - int n = UnsafeNativeMethods.sqlite3_close_interop(db); -#else - ResetConnection(db); - int n = UnsafeNativeMethods.sqlite3_close(db); -#endif - if (n > 0) throw new SQLiteException(n, SQLiteLastError(db)); - } - } - - internal static void ResetConnection(SQLiteConnectionHandle db) - { - lock (_lock) - { - IntPtr stmt = IntPtr.Zero; - int n; - do - { - stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt); - if (stmt != IntPtr.Zero) - { -#if !SQLITE_STANDARD - n = UnsafeNativeMethods.sqlite3_reset_interop(stmt); -#else - n = UnsafeNativeMethods.sqlite3_reset(stmt); -#endif - } - } while (stmt != IntPtr.Zero); - - if (IsAutocommit(db) == false) // a transaction is pending on the connection - { - n = UnsafeNativeMethods.sqlite3_exec(db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero, out stmt); - if (n > 0) throw new SQLiteException(n, SQLiteLastError(db)); - } - } - } - - internal static bool IsAutocommit(SQLiteConnectionHandle hdl) - { - return (UnsafeNativeMethods.sqlite3_get_autocommit(hdl) == 1); - } - + internal static string GetLastError(SQLiteConnectionHandle hdl, IntPtr db) + { + if ((hdl == null) || (db == IntPtr.Zero)) + return "null connection or database handle"; + + lock (hdl) + { + if (hdl.IsClosed || hdl.IsInvalid) + return "closed or invalid connection handle"; + +#if !SQLITE_STANDARD + int len; + return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(db, out len), len); +#else + return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1); +#endif + } + +#pragma warning disable 162 + GC.KeepAlive(hdl); /* NOTE: Unreachable code. */ +#pragma warning restore 162 + } + + internal static void FinishBackup(SQLiteConnectionHandle hdl, IntPtr backup) + { + if ((hdl == null) || (backup == IntPtr.Zero)) return; + lock (hdl) + { + int n = UnsafeNativeMethods.sqlite3_backup_finish(backup); + if (n > 0) throw new SQLiteException(n, null); + } + } + + internal static void FinalizeStatement(SQLiteConnectionHandle hdl, IntPtr stmt) + { + if ((hdl == null) || (stmt == IntPtr.Zero)) return; + lock (hdl) + { +#if !SQLITE_STANDARD + int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt); +#else + int n = UnsafeNativeMethods.sqlite3_finalize(stmt); +#endif + if (n > 0) throw new SQLiteException(n, null); + } + } + + internal static void CloseConnection(SQLiteConnectionHandle hdl, IntPtr db) + { + if ((hdl == null) || (db == IntPtr.Zero)) return; + lock (hdl) + { +#if !SQLITE_STANDARD + int n = UnsafeNativeMethods.sqlite3_close_interop(db); +#else + ResetConnection(hdl, db); + int n = UnsafeNativeMethods.sqlite3_close(db); +#endif + if (n > 0) throw new SQLiteException(n, GetLastError(hdl, db)); + } + } + + internal static void ResetConnection(SQLiteConnectionHandle hdl, IntPtr db) + { + if ((hdl == null) || (db == IntPtr.Zero)) return; + if (hdl.IsClosed || hdl.IsInvalid) return; + lock (hdl) + { + IntPtr stmt = IntPtr.Zero; + int n; + do + { + stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt); + if (stmt != IntPtr.Zero) + { +#if !SQLITE_STANDARD + n = UnsafeNativeMethods.sqlite3_reset_interop(stmt); +#else + n = UnsafeNativeMethods.sqlite3_reset(stmt); +#endif + } + } while (stmt != IntPtr.Zero); + + if (IsAutocommit(hdl, db) == false) // a transaction is pending on the connection + { + n = UnsafeNativeMethods.sqlite3_exec(db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero, out stmt); + if (n > 0) throw new SQLiteException(n, GetLastError(hdl, db)); + } + } + GC.KeepAlive(hdl); + } + + internal static bool IsAutocommit(SQLiteConnectionHandle hdl, IntPtr db) + { + if (db == IntPtr.Zero) return false; + if (hdl.IsClosed || hdl.IsInvalid) return false; + lock (hdl) + { + return (UnsafeNativeMethods.sqlite3_get_autocommit(db) == 1); + } +#pragma warning disable 162 + GC.KeepAlive(hdl); /* NOTE: Unreachable code. */ +#pragma warning restore 162 + } } internal interface ISQLiteSchemaExtensions { void BuildTempSchema(SQLiteConnection cnn); @@ -366,10 +463,59 @@ ReadWrite = 0x02, Create = 0x04, SharedCache = 0x01000000, Default = 0x06, } + + /// + /// The extra behavioral flags that can be applied to a connection. + /// + [Flags()] + public enum SQLiteConnectionFlags + { + /// + /// No extra flags. + /// + None = 0x0, + + /// + /// Enable logging of all SQL statements to be prepared. + /// + LogPrepare = 0x1, + + /// + /// Enable logging of all bound parameter types and raw values. + /// + LogPreBind = 0x2, + + /// + /// Enable logging of all bound parameter strongly typed values. + /// + LogBind = 0x4, + + /// + /// Enable logging of all exceptions caught from user-provided + /// managed code called from native code via delegates. + /// + LogCallbackException = 0x8, + + /// + /// Enable logging of backup API errors. + /// + LogBackup = 0x10, + + /// + /// Enable all logging. + /// + LogAll = LogPrepare | LogPreBind | LogBind | + LogCallbackException | LogBackup, + + /// + /// The default extra flags for new connections. + /// + Default = LogCallbackException + } // These are the options to the internal sqlite3_config call. internal enum SQLiteConfigOpsEnum { SQLITE_CONFIG_NONE = 0, // nil Index: System.Data.SQLite/SQLiteConnection.cs ================================================================== --- System.Data.SQLite/SQLiteConnection.cs +++ System.Data.SQLite/SQLiteConnection.cs @@ -1,9 +1,9 @@ /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) - * + * * Released to the public domain, use at your own risk! ********************************************************/ namespace System.Data.SQLite { @@ -91,11 +91,11 @@ /// N /// 1024 /// /// /// Password - /// {password} + /// {password} - Using this parameter requires that the CryptoAPI based codec be enabled at compile-time for both the native interop assembly and the core managed assemblies; otherwise, using this parameter may result in an exception being thrown when attempting to open the connection. /// N /// /// /// /// Enlist @@ -161,10 +161,16 @@ /// Foreign Keys /// Enable foreign key constraints /// N /// False /// + /// + /// Flags + /// Extra behavioral flags for the connection. See the SQLiteConnectionFlags enumeration for possible values. + /// N + /// Default + /// /// /// public sealed partial class SQLiteConnection : DbConnection, ICloneable { /// @@ -212,20 +218,29 @@ internal SQLiteBase _sql; /// /// The database filename minus path and extension /// private string _dataSource; + +#if INTEROP_CODEC /// /// Temporary password storage, emptied after the database has been opened /// private byte[] _password; +#endif /// /// The "stub" (i.e. placeholder) base schema name to use when returning /// column schema information. /// - internal string _baseSchemaName; + internal string _baseSchemaName; + + /// + /// The extra behavioral flags for this connection, if any. See the + /// SQLiteConnectionFlags enumeration for a list of possible values. + /// + private SQLiteConnectionFlags _flags; /// /// Default command timeout /// private int _defaultTimeout = 30; @@ -264,14 +279,19 @@ /// Initializes the connection with the specified connection string /// /// The connection string to use on the connection public SQLiteConnection(string connectionString) { +#if (SQLITE_STANDARD || USE_INTEROP_DLL || PLATFORM_COMPACTFRAMEWORK) && PRELOAD_NATIVE_LIBRARY + UnsafeNativeMethods.Initialize(); +#endif + #if !PLATFORM_COMPACTFRAMEWORK SQLiteLog.Initialize(); #endif + _flags = SQLiteConnectionFlags.Default; _connectionState = ConnectionState.Closed; _connectionString = ""; //_commandList = new List(); if (connectionString != null) @@ -310,10 +330,127 @@ } } } } } + + /////////////////////////////////////////////////////////////////////////////////////////////// + + #region Backup API Members + /// + /// Backs up the database, using the specified database connection as the + /// destination. + /// + /// The destination database connection. + /// The destination database name. + /// The source database name. + /// + /// The number of pages to copy or negative to copy all remaining pages. + /// + /// + /// The method to invoke between each step of the backup process. This + /// parameter may be null (i.e. no callbacks will be performed). + /// + /// + /// The number of milliseconds to sleep after encountering a locking error + /// during the backup process. A value less than zero means that no sleep + /// should be performed. + /// + public void BackupDatabase( + SQLiteConnection destination, + string destinationName, + string sourceName, + int pages, + SQLiteBackupCallback callback, + int retryMilliseconds + ) + { + CheckDisposed(); + + if (_connectionState != ConnectionState.Open) + throw new InvalidOperationException( + "Source database is not open."); + + if (destination == null) + throw new ArgumentNullException("destination"); + + if (destination._connectionState != ConnectionState.Open) + throw new ArgumentException( + "Destination database is not open.", "destination"); + + if (destinationName == null) + throw new ArgumentNullException("destinationName"); + + if (sourceName == null) + throw new ArgumentNullException("sourceName"); + + SQLiteBase sqliteBase = _sql; + + if (sqliteBase == null) + throw new InvalidOperationException( + "Connection object has an invalid handle."); + + SQLiteBackup backup = null; + + try + { + backup = sqliteBase.InitializeBackup( + destination, destinationName, sourceName); /* throw */ + + bool retry; + + while (sqliteBase.StepBackup(backup, pages, out retry)) /* throw */ + { + // + // NOTE: If a callback was supplied by our caller, call it. + // If it returns false, halt the backup process. + // + if ((callback != null) && !callback(this, sourceName, + destination, destinationName, pages, + sqliteBase.RemainingBackup(backup), + sqliteBase.PageCountBackup(backup), retry)) + { + break; + } + + // + // NOTE: If we need to retry the previous operation, wait for + // the number of milliseconds specified by our caller + // unless the caller used a negative number, in that case + // skip sleeping at all because we do not want to block + // this thread forever. + // + if (retry && (retryMilliseconds >= 0)) + System.Threading.Thread.Sleep(retryMilliseconds); + + // + // NOTE: There is no point in calling the native API to copy + // zero pages as it does nothing; therefore, stop now. + // + if (pages == 0) + break; + } + } +#if !PLATFORM_COMPACTFRAMEWORK + catch (Exception e) + { + if ((_flags & SQLiteConnectionFlags.LogBackup) == SQLiteConnectionFlags.LogBackup) + { + SQLiteLog.LogMessage(0, String.Format( + "Caught exception while backing up database: {0}", e)); + } + + throw; + } +#endif + finally + { + if (backup != null) + sqliteBase.FinishBackup(backup); /* throw */ + } + } + #endregion /////////////////////////////////////////////////////////////////////////////////////////////// #region IDisposable "Pattern" Members private bool disposed; @@ -364,22 +501,24 @@ /// public override int ConnectionTimeout { get { + CheckDisposed(); return 30; } } #endif /// - /// Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection + /// Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection /// will also be opened. /// /// public object Clone() { + CheckDisposed(); return new SQLiteConnection(this); } /// /// Creates a database file. This just creates a zero-byte file which SQLite @@ -411,38 +550,40 @@ /// /// OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. /// /// This parameter is ignored. /// When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - /// When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer + /// When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. /// Returns a SQLiteTransaction object. [Obsolete("Use one of the standard BeginTransaction methods, this one will be removed soon")] public SQLiteTransaction BeginTransaction(IsolationLevel isolationLevel, bool deferredLock) { + CheckDisposed(); return (SQLiteTransaction)BeginDbTransaction(deferredLock == false ? IsolationLevel.Serializable : IsolationLevel.ReadCommitted); } /// /// OBSOLETE. Creates a new SQLiteTransaction if one isn't already active on the connection. /// /// When TRUE, SQLite defers obtaining a write lock until a write operation is requested. - /// When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer + /// When FALSE, a writelock is obtained immediately. The default is false, but in a multi-threaded multi-writer /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. /// Returns a SQLiteTransaction object. [Obsolete("Use one of the standard BeginTransaction methods, this one will be removed soon")] public SQLiteTransaction BeginTransaction(bool deferredLock) { + CheckDisposed(); return (SQLiteTransaction)BeginDbTransaction(deferredLock == false ? IsolationLevel.Serializable : IsolationLevel.ReadCommitted); } /// /// Creates a new SQLiteTransaction if one isn't already active on the connection. /// /// Supported isolation levels are Serializable, ReadCommitted and Unspecified. /// - /// Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the + /// Unspecified will use the default isolation level specified in the connection string. If no isolation level is specified in the /// connection string, Serializable is used. /// Serializable transactions are the default. In this mode, the engine gets an immediate lock on the database, and no other threads /// may begin a transaction. Other threads may read from the database, but not write. /// With a ReadCommitted isolation level, locks are deferred and elevated as needed. It is possible for multiple threads to start /// a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread @@ -449,19 +590,21 @@ /// has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached. /// /// Returns a SQLiteTransaction object. public new SQLiteTransaction BeginTransaction(IsolationLevel isolationLevel) { + CheckDisposed(); return (SQLiteTransaction)BeginDbTransaction(isolationLevel); } /// /// Creates a new SQLiteTransaction if one isn't already active on the connection. /// /// Returns a SQLiteTransaction object. public new SQLiteTransaction BeginTransaction() { + CheckDisposed(); return (SQLiteTransaction)BeginDbTransaction(_defaultIsolation); } /// /// Forwards to the local BeginTransaction() function @@ -485,25 +628,28 @@ /// Not implemented /// /// public override void ChangeDatabase(string databaseName) { + CheckDisposed(); throw new NotImplementedException(); } /// /// When the database connection is closed, all commands linked to this connection are automatically reset. /// public override void Close() { + CheckDisposed(); + if (_sql != null) { #if !PLATFORM_COMPACTFRAMEWORK if (_enlistment != null) { // If the connection is enlisted in a transaction scope and the scope is still active, - // we cannot truly shut down this connection until the scope has completed. Therefore make a + // we cannot truly shut down this connection until the scope has completed. Therefore make a // hidden connection temporarily to hold open the connection until the scope has completed. SQLiteConnection cnn = new SQLiteConnection(); cnn._sql = _sql; cnn._transactionLevel = _transactionLevel; cnn._enlistment = _enlistment; @@ -524,10 +670,22 @@ } _transactionLevel = 0; } OnStateChange(ConnectionState.Closed); } + + /// + /// Returns the number of pool entries for the file name associated with this connection. + /// + public int PoolCount + { + get + { + if (_sql == null) return 0; + return _sql.CountPool(); + } + } /// /// Clears the connection pool associated with the connection. Any other active connections using the same database file /// will be discarded instead of returned to the pool when they are closed. /// @@ -679,14 +837,17 @@ #endif public override string ConnectionString { get { + CheckDisposed(); return _connectionString; } set { + CheckDisposed(); + if (value == null) throw new ArgumentNullException(); else if (_connectionState != ConnectionState.Closed) throw new InvalidOperationException(); @@ -699,10 +860,11 @@ /// Create a new SQLiteCommand and associate it with this connection. /// /// Returns an instantiated SQLiteCommand object already assigned to this connection. public new SQLiteCommand CreateCommand() { + CheckDisposed(); return new SQLiteCommand(this); } /// /// Forwards to the local CreateCommand() function @@ -721,10 +883,11 @@ #endif public override string DataSource { get { + CheckDisposed(); return _dataSource; } } /// @@ -735,10 +898,11 @@ #endif public override string Database { get { + CheckDisposed(); return "main"; } } internal static string MapUriPath(string path) @@ -750,11 +914,11 @@ else if (path.StartsWith ("/", StringComparison.OrdinalIgnoreCase)) return path; else throw new InvalidOperationException ("Invalid connection string: invalid URI"); } - + /// /// Parses the connection string into component parts /// /// The connection string to parse /// An array of key-value pairs representing each parameter of the connection string @@ -788,10 +952,12 @@ /// Manual distributed transaction enlistment support /// /// The distributed transaction to enlist in public override void EnlistTransaction(System.Transactions.Transaction transaction) { + CheckDisposed(); + if (_enlistment != null && transaction == _enlistment._scope) return; else if (_enlistment != null) throw new ArgumentException("Already enlisted in a transaction"); @@ -823,16 +989,21 @@ /// /// Opens the connection using the parameters found in the ConnectionString /// public override void Open() { + CheckDisposed(); + if (_connectionState != ConnectionState.Closed) throw new InvalidOperationException(); Close(); SortedList opts = ParseConnectionString(_connectionString); + + _flags = (SQLiteConnectionFlags)Enum.Parse(typeof(SQLiteConnectionFlags), FindKey(opts, "Flags", "Default"), true); + string fileName; if (Convert.ToInt32(FindKey(opts, "Version", "3"), CultureInfo.InvariantCulture) != 3) throw new NotSupportedException("Only SQLite Version 3 is supported at this time"); @@ -904,21 +1075,23 @@ else { flags |= SQLiteOpenFlagsEnum.ReadWrite; } - _sql.Open(fileName, flags, maxPoolSize, usePooling); + _sql.Open(fileName, _flags, flags, maxPoolSize, usePooling); _binaryGuid = (SQLiteConvert.ToBoolean(FindKey(opts, "BinaryGUID", Boolean.TrueString)) == true); +#if INTEROP_CODEC string password = FindKey(opts, "Password", null); if (String.IsNullOrEmpty(password) == false) _sql.SetPassword(System.Text.UTF8Encoding.UTF8.GetBytes(password)); else if (_password != null) _sql.SetPassword(_password); _password = null; +#endif _dataSource = Path.GetFileNameWithoutExtension(fileName); _version++; @@ -1006,18 +1179,37 @@ throw; } } /// - /// Gets/sets the default command timeout for newly-created commands. This is especially useful for + /// Opens the connection using the parameters found in the ConnectionString and then returns it. + /// + /// The current connection object. + public SQLiteConnection OpenAndReturn() + { + CheckDisposed(); Open(); return this; + } + + /// + /// Gets/sets the default command timeout for newly-created commands. This is especially useful for /// commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible. /// This can also be set in the ConnectionString with "Default Timeout" /// public int DefaultTimeout { - get { return _defaultTimeout; } - set { _defaultTimeout = value; } + get { CheckDisposed(); return _defaultTimeout; } + set { CheckDisposed(); _defaultTimeout = value; } + } + + /// + /// Gets/sets the extra behavioral flags for this connection. See the + /// SQLiteConnectionFlags enumeration for a list of possible values. + /// + public SQLiteConnectionFlags Flags + { + get { CheckDisposed(); return _flags; } + set { CheckDisposed(); _flags = value; } } /// /// Returns the version of the underlying SQLite database engine /// @@ -1026,10 +1218,11 @@ #endif public override string ServerVersion { get { + CheckDisposed(); return SQLiteVersion; //if (_connectionState != ConnectionState.Open) // throw new InvalidOperationException(); //return _sql.Version; @@ -1044,10 +1237,12 @@ #endif public long LastInsertRowId { get { + CheckDisposed(); + if (_sql == null) throw new InvalidOperationException("Database connection not valid for getting last insert rowid."); return _sql.LastInsertRowId; } @@ -1062,10 +1257,12 @@ #endif public int Changes { get { + CheckDisposed(); + if (_sql == null) throw new InvalidOperationException("Database connection not valid for getting number of changes."); return _sql.Changes; } @@ -1079,10 +1276,12 @@ #endif public long MemoryUsed { get { + CheckDisposed(); + if (_sql == null) throw new InvalidOperationException("Database connection not valid for getting memory used."); return _sql.MemoryUsed; } @@ -1096,16 +1295,28 @@ #endif public long MemoryHighwater { get { + CheckDisposed(); + if (_sql == null) throw new InvalidOperationException("Database connection not valid for getting maximum memory used."); return _sql.MemoryHighwater; } } + + /// + /// Returns a string containing the define constants (i.e. compile-time + /// options) used to compile the core managed assembly, delimited with + /// spaces. + /// + public static string DefineConstants + { + get { return SQLite3.DefineConstants; } + } /// /// Returns the version of the underlying SQLite database engine /// public static string SQLiteVersion @@ -1131,17 +1342,20 @@ #endif public override ConnectionState State { get { + CheckDisposed(); return _connectionState; } } /// Passes a shutdown request off to SQLite. public int Shutdown() { + CheckDisposed(); + // make sure we have an instance of the base class if (_sql == null) { SortedList opts = ParseConnectionString(_connectionString); @@ -1163,33 +1377,45 @@ } /// Enables or disabled extended result codes returned by SQLite public void SetExtendedResultCodes(bool bOnOff) { + CheckDisposed(); + if (_sql != null) _sql.SetExtendedResultCodes(bOnOff); } /// Enables or disabled extended result codes returned by SQLite public int ResultCode() { - if (_sql == null) + CheckDisposed(); + + if (_sql == null) throw new InvalidOperationException("Database connection not valid for getting result code."); return _sql.ResultCode(); } /// Enables or disabled extended result codes returned by SQLite public int ExtendedResultCode() { + CheckDisposed(); + if (_sql == null) throw new InvalidOperationException("Database connection not valid for getting extended result code."); return _sql.ExtendedResultCode(); } /// Add a log message via the SQLite sqlite3_log interface. public void LogMessage(int iErrCode, string zMessage) { + CheckDisposed(); + + if (_sql == null) + throw new InvalidOperationException("Database connection not valid for logging message."); + _sql.LogMessage(iErrCode, zMessage); } +#if INTEROP_CODEC /// /// Change the password (or assign a password) to an open database. /// /// /// No readers or writers may be active for this process. The database must already be open @@ -1196,10 +1422,12 @@ /// and if it already was password protected, the existing password must already have been supplied. /// /// The new password to assign to the database public void ChangePassword(string newPassword) { + CheckDisposed(); + ChangePassword(String.IsNullOrEmpty(newPassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(newPassword)); } /// /// Change the password (or assign a password) to an open database. @@ -1209,10 +1437,12 @@ /// and if it already was password protected, the existing password must already have been supplied. /// /// The new password to assign to the database public void ChangePassword(byte[] newPassword) { + CheckDisposed(); + if (_connectionState != ConnectionState.Open) throw new InvalidOperationException("Database must be opened before changing the password."); _sql.ChangePassword(newPassword); } @@ -1222,10 +1452,12 @@ /// unusable for any operation until the password has been set. /// /// The password for the database public void SetPassword(string databasePassword) { + CheckDisposed(); + SetPassword(String.IsNullOrEmpty(databasePassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(databasePassword)); } /// /// Sets the password for a password-protected database. A password-protected database is @@ -1232,18 +1464,21 @@ /// unusable for any operation until the password has been set. /// /// The password for the database public void SetPassword(byte[] databasePassword) { + CheckDisposed(); + if (_connectionState != ConnectionState.Closed) throw new InvalidOperationException("Password can only be set before the database is opened."); if (databasePassword != null) if (databasePassword.Length == 0) databasePassword = null; _password = databasePassword; } +#endif /// /// Queries or modifies the number of retries or the retry interval (in milliseconds) for /// certain I/O operations that may fail due to anti-virus software. /// @@ -1254,10 +1489,12 @@ /// up with the final number of milliseconds to wait. A negative value will cause the /// current interval to be queried and replace that negative value. /// Zero for success, non-zero for error. public int SetAvRetry(ref int count, ref int interval) { + CheckDisposed(); + if (_connectionState != ConnectionState.Open) throw new InvalidOperationException( "Database must be opened before changing the AV retry parameters."); int rc; @@ -1363,10 +1600,11 @@ /// Returns the MetaDataCollections schema /// /// A DataTable of the MetaDataCollections schema public override DataTable GetSchema() { + CheckDisposed(); return GetSchema("MetaDataCollections", null); } /// /// Returns schema information of the specified collection @@ -1373,10 +1611,11 @@ /// /// The schema collection to retrieve /// A DataTable of the specified collection public override DataTable GetSchema(string collectionName) { + CheckDisposed(); return GetSchema(collectionName, new string[0]); } /// /// Retrieves schema information using the specified constraint(s) for the specified collection @@ -1384,10 +1623,12 @@ /// The collection to retrieve /// The restrictions to impose /// A DataTable of the specified collection public override DataTable GetSchema(string collectionName, string[] restrictionValues) { + CheckDisposed(); + if (_connectionState != ConnectionState.Open) throw new InvalidOperationException(); string[] parms = new string[5]; @@ -1685,11 +1926,11 @@ tbl.BeginLoadData(); if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main"; string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb; - + using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this)) using (SQLiteDataReader rdTables = cmdTables.ExecuteReader()) { while (rdTables.Read()) { @@ -2257,11 +2498,11 @@ tbl.Columns.Add("UNIQUE", typeof(bool)); if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main"; string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb; - + tbl.BeginLoadData(); using (SQLiteCommand cmdViews = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'view'", strCatalog, master), this)) using (SQLiteDataReader rdViews = cmdViews.ExecuteReader()) { @@ -2348,10 +2589,11 @@ tbl.Columns.Add("TABLE_SCHEMA", typeof(string)); tbl.Columns.Add("TABLE_NAME", typeof(string)); tbl.Columns.Add("CONSTRAINT_TYPE", typeof(string)); tbl.Columns.Add("IS_DEFERRABLE", typeof(bool)); tbl.Columns.Add("INITIALLY_DEFERRED", typeof(bool)); + tbl.Columns.Add("FKEY_ID", typeof(int)); tbl.Columns.Add("FKEY_FROM_COLUMN", typeof(string)); tbl.Columns.Add("FKEY_FROM_ORDINAL_POSITION", typeof(int)); tbl.Columns.Add("FKEY_TO_CATALOG", typeof(string)); tbl.Columns.Add("FKEY_TO_SCHEMA", typeof(string)); tbl.Columns.Add("FKEY_TO_TABLE", typeof(string)); @@ -2383,16 +2625,17 @@ { while (rdKey.Read()) { row = tbl.NewRow(); row["CONSTRAINT_CATALOG"] = strCatalog; - row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}", rdTables[2], rdKey.GetInt32(0)); + row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}_{2}", rdTables[2], rdKey.GetInt32(0), rdKey.GetInt32(1)); row["TABLE_CATALOG"] = strCatalog; row["TABLE_NAME"] = builder.UnquoteIdentifier(rdTables.GetString(2)); row["CONSTRAINT_TYPE"] = "FOREIGN KEY"; row["IS_DEFERRABLE"] = false; row["INITIALLY_DEFERRED"] = false; + row["FKEY_ID"] = rdKey[0]; row["FKEY_FROM_COLUMN"] = builder.UnquoteIdentifier(rdKey[3].ToString()); row["FKEY_TO_CATALOG"] = strCatalog; row["FKEY_TO_TABLE"] = builder.UnquoteIdentifier(rdKey[2].ToString()); row["FKEY_TO_COLUMN"] = builder.UnquoteIdentifier(rdKey[4].ToString()); row["FKEY_FROM_ORDINAL_POSITION"] = rdKey[1]; @@ -2424,19 +2667,23 @@ /// public event SQLiteUpdateEventHandler Update { add { + CheckDisposed(); + if (_updateHandler == null) { _updateCallback = new SQLiteUpdateCallback(UpdateCallback); if (_sql != null) _sql.SetUpdateHook(_updateCallback); } _updateHandler += value; } remove { + CheckDisposed(); + _updateHandler -= value; if (_updateHandler == null) { if (_sql != null) _sql.SetUpdateHook(null); _updateCallback = null; @@ -2459,19 +2706,23 @@ /// public event SQLiteCommitHandler Commit { add { + CheckDisposed(); + if (_commitHandler == null) { _commitCallback = new SQLiteCommitCallback(CommitCallback); if (_sql != null) _sql.SetCommitHook(_commitCallback); } _commitHandler += value; } remove { + CheckDisposed(); + _commitHandler -= value; if (_commitHandler == null) { if (_sql != null) _sql.SetCommitHook(null); _commitCallback = null; @@ -2485,19 +2736,23 @@ /// public event SQLiteTraceEventHandler Trace { add { + CheckDisposed(); + if (_traceHandler == null) { _traceCallback = new SQLiteTraceCallback(TraceCallback); if (_sql != null) _sql.SetTraceCallback(_traceCallback); } _traceHandler += value; } remove { + CheckDisposed(); + _traceHandler -= value; if (_traceHandler == null) { if (_sql != null) _sql.SetTraceCallback(null); _traceCallback = null; @@ -2517,19 +2772,23 @@ /// public event EventHandler RollBack { add { + CheckDisposed(); + if (_rollbackHandler == null) { _rollbackCallback = new SQLiteRollbackCallback(RollbackCallback); if (_sql != null) _sql.SetRollbackHook(_rollbackCallback); } _rollbackHandler += value; } remove { + CheckDisposed(); + _rollbackHandler -= value; if (_rollbackHandler == null) { if (_sql != null) _sql.SetRollbackHook(null); _rollbackCallback = null; @@ -2590,11 +2849,11 @@ [UnmanagedFunctionPointer(CallingConvention.Cdecl)] #endif internal delegate void SQLiteRollbackCallback(IntPtr puser); /// - /// Raised when a transaction is about to be committed. To roll back a transaction, set the + /// Raised when a transaction is about to be committed. To roll back a transaction, set the /// rollbackTrans boolean value to true. /// /// The connection committing the transaction /// Event arguments on the transaction public delegate void SQLiteCommitHandler(object sender, CommitEventArgs e); @@ -2610,10 +2869,59 @@ /// Raised when a statement first begins executing on a given connection /// /// The connection executing the statement /// Event arguments of the trace public delegate void SQLiteTraceEventHandler(object sender, TraceEventArgs e); + + /////////////////////////////////////////////////////////////////////////////////////////////// + + #region Backup API Members + /// + /// Raised between each backup step. + /// + /// + /// The source database connection. + /// + /// + /// The source database name. + /// + /// + /// The destination database connection. + /// + /// + /// The destination database name. + /// + /// + /// The number of pages copied with each step. + /// + /// + /// The number of pages remaining to be copied. + /// + /// + /// The total number of pages in the source database. + /// + /// + /// Set to true if the operation needs to be retried due to database + /// locking issues; otherwise, set to false. + /// + /// + /// True to continue with the backup process or false to halt the backup + /// process, rolling back any changes that have been made so far. + /// + public delegate bool SQLiteBackupCallback( + SQLiteConnection source, + string sourceName, + SQLiteConnection destination, + string destinationName, + int pages, + int remainingPages, + int totalPages, + bool retry + ); + #endregion + + /////////////////////////////////////////////////////////////////////////////////////////////// /// /// Whenever an update event is triggered on a connection, this enum will indicate /// exactly what type of operation is being performed. /// Index: System.Data.SQLite/SQLiteConnectionPool.cs ================================================================== --- System.Data.SQLite/SQLiteConnectionPool.cs +++ System.Data.SQLite/SQLiteConnectionPool.cs @@ -6,11 +6,12 @@ ********************************************************/ namespace System.Data.SQLite { using System; - using System.Collections.Generic; + using System.Collections.Generic; + using System.Threading; internal static class SQLiteConnectionPool { /// /// Keeps track of connections made on a specified file. The PoolVersion dictates whether old objects get @@ -35,57 +36,193 @@ private static SortedList _connections = new SortedList(StringComparer.OrdinalIgnoreCase); /// /// The default version number new pools will get /// - private static int _poolVersion = 1; + private static int _poolVersion = 1; + + /// + /// The number of connections successfully opened from any pool. + /// This value is incremented by the Remove method. + /// + private static int _poolOpened = 0; + + /// + /// The number of connections successfully closed from any pool. + /// This value is incremented by the Add method. + /// + private static int _poolClosed = 0; + + /// + /// Counts the number of pool entries matching the specified file name. + /// + /// The file name to match or null to match all files. + /// The pool entry counts for each matching file. + /// The total number of connections successfully opened from any pool. + /// The total number of connections successfully closed from any pool. + /// The total number of pool entries for all matching files. + internal static void GetCounts( + string fileName, + ref Dictionary counts, + ref int openCount, + ref int closeCount, + ref int totalCount + ) + { + lock (_connections) + { + openCount = _poolOpened; + closeCount = _poolClosed; + + if (counts == null) + { + counts = new Dictionary( + StringComparer.OrdinalIgnoreCase); + } + + if (fileName != null) + { + Pool queue; + + if (_connections.TryGetValue(fileName, out queue)) + { + Queue poolQueue = queue.Queue; + int count = (poolQueue != null) ? poolQueue.Count : 0; + + counts.Add(fileName, count); + totalCount += count; + } + } + else + { + foreach (KeyValuePair pair in _connections) + { + if (pair.Value == null) + continue; + + Queue poolQueue = pair.Value.Queue; + int count = (poolQueue != null) ? poolQueue.Count : 0; + + counts.Add(pair.Key, count); + totalCount += count; + } + } + } + } /// /// Attempt to pull a pooled connection out of the queue for active duty /// /// The filename for a desired connection - /// The maximum size the connection pool for the filename can be - /// The pool version the returned connection will belong to - /// Returns NULL if no connections were available. Even if none are, the poolversion will still be a valid pool version - internal static SQLiteConnectionHandle Remove(string fileName, int maxPoolSize, out int version) - { - lock (_connections) - { - Pool queue; - - // Default to the highest pool version - version = _poolVersion; - - // If we didn't find a pool for this file, create one even though it will be empty. - // We have to do this here because otherwise calling ClearPool() on the file will not work for active connections - // that have never seen the pool yet. - if (_connections.TryGetValue(fileName, out queue) == false) - { - queue = new Pool(_poolVersion, maxPoolSize); - _connections.Add(fileName, queue); - - return null; - } - - // We found a pool for this file, so use its version number - version = queue.PoolVersion; - queue.MaxPoolSize = maxPoolSize; - - ResizePool(queue, false); - - // Try and get a pooled connection from the queue - while (queue.Queue.Count > 0) - { - WeakReference cnn = queue.Queue.Dequeue(); - SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle; - if (hdl != null) - { - return hdl; - } - } - return null; - } + /// The maximum size the connection pool for the filename can be + /// The pool version the returned connection will belong to + /// Returns NULL if no connections were available. Even if none are, the poolversion will still be a valid pool version + internal static SQLiteConnectionHandle Remove(string fileName, int maxPoolSize, out int version) + { + Queue poolQueue; + + // + // NOTE: This lock cannot be held while checking the queue for available + // connections because other methods of this class are called from + // the GC finalizer thread and we use the WaitForPendingFinalizers + // method (below). Holding this lock while calling that method + // would therefore result in a deadlock. This lock is held while + // a temporary copy of the queue is created. + // + lock (_connections) + { + Pool queue; + + // Default to the highest pool version + version = _poolVersion; + + // If we didn't find a pool for this file, create one even though it will be empty. + // We have to do this here because otherwise calling ClearPool() on the file will not work for active connections + // that have never seen the pool yet. + if (_connections.TryGetValue(fileName, out queue) == false) + { + queue = new Pool(_poolVersion, maxPoolSize); + _connections.Add(fileName, queue); + + return null; + } + + // We found a pool for this file, so use its version number + version = queue.PoolVersion; + queue.MaxPoolSize = maxPoolSize; + + ResizePool(queue, false); + + // Try and get a pooled connection from the queue + poolQueue = new Queue(queue.Queue); + if (poolQueue == null) return null; + } + + while (poolQueue.Count > 0) + { + WeakReference cnn = poolQueue.Dequeue(); + if (cnn == null) continue; + + SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle; + if (hdl == null) continue; + + // + // BUGFIX: For ticket [996d13cd87], step #1. After this point, + // make sure that the finalizer for the connection handle + // just obtained from the queue cannot START running (i.e. + // it may still be pending but it will no longer start + // after this point). + // + GC.SuppressFinalize(hdl); + + try + { + // + // BUGFIX: For ticket [996d13cd87], step #2. Now, we must wait + // for all pending finalizers which have STARTED running + // and have not yet COMPLETED. This must be done just + // in case the finalizer for the connection handle just + // obtained from the queue has STARTED running at some + // point before SuppressFinalize was called on it. + // + // After this point, checking properties of the + // connection handle (e.g. IsClosed) should work + // reliably without having to worry that they will + // (due to the finalizer) change out from under us. + // + GC.WaitForPendingFinalizers(); + + // + // BUGFIX: For ticket [996d13cd87], step #3. Next, verify that + // the connection handle is actually valid and [still?] + // not closed prior to actually returning it to our + // caller. + // + if (!hdl.IsClosed && !hdl.IsInvalid) + { + Interlocked.Increment(ref _poolOpened); + return hdl; + } + } + finally + { + // + // BUGFIX: For ticket [996d13cd87], step #4. Finally, we must + // re-register the connection handle for finalization + // now that we have a strong reference to it (i.e. the + // finalizer run at least until the connection is + // subsequently closed). + // + GC.ReRegisterForFinalize(hdl); + } + +#pragma warning disable 162 + GC.KeepAlive(hdl); /* NOTE: Unreachable code. */ +#pragma warning restore 162 + } + + return null; } /// /// Clears out all pooled connections and rev's up the default pool version to force all old active objects /// not in the pool to get discarded rather than returned to their pools. @@ -93,19 +230,26 @@ internal static void ClearAllPools() { lock (_connections) { foreach (KeyValuePair pair in _connections) - { - while (pair.Value.Queue.Count > 0) - { - WeakReference cnn = pair.Value.Queue.Dequeue(); + { + if (pair.Value == null) + continue; + + Queue poolQueue = pair.Value.Queue; + + while (poolQueue.Count > 0) + { + WeakReference cnn = poolQueue.Dequeue(); + if (cnn == null) continue; SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle; if (hdl != null) { hdl.Dispose(); - } + } + GC.KeepAlive(hdl); } // Keep track of the highest revision so we can go one higher when we're finished if (_poolVersion <= pair.Value.PoolVersion) _poolVersion = pair.Value.PoolVersion + 1; @@ -128,19 +272,25 @@ lock (_connections) { Pool queue; if (_connections.TryGetValue(fileName, out queue) == true) { - queue.PoolVersion++; - while (queue.Queue.Count > 0) - { - WeakReference cnn = queue.Queue.Dequeue(); + queue.PoolVersion++; + + Queue poolQueue = queue.Queue; + if (poolQueue == null) return; + + while (poolQueue.Count > 0) + { + WeakReference cnn = poolQueue.Dequeue(); + if (cnn == null) continue; SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle; if (hdl != null) { hdl.Dispose(); - } + } + GC.KeepAlive(hdl); } } } } @@ -159,18 +309,23 @@ { // If the queue doesn't exist in the pool, then it must've been cleared sometime after the connection was created. Pool queue; if (_connections.TryGetValue(fileName, out queue) == true && version == queue.PoolVersion) { - ResizePool(queue, true); - queue.Queue.Enqueue(new WeakReference(hdl, false)); - GC.KeepAlive(hdl); + ResizePool(queue, true); + + Queue poolQueue = queue.Queue; + if (poolQueue == null) return; + + poolQueue.Enqueue(new WeakReference(hdl, false)); + Interlocked.Increment(ref _poolClosed); } else { hdl.Close(); - } + } + GC.KeepAlive(hdl); } } /// /// We don't have to thread-lock anything in this function, because it's only called by other functions above @@ -181,19 +336,24 @@ /// to take one more than it needs from the pool private static void ResizePool(Pool queue, bool forAdding) { int target = queue.MaxPoolSize; - if (forAdding && target > 0) target--; - - while (queue.Queue.Count > target) - { - WeakReference cnn = queue.Queue.Dequeue(); + if (forAdding && target > 0) target--; + + Queue poolQueue = queue.Queue; + if (poolQueue == null) return; + + while (poolQueue.Count > target) + { + WeakReference cnn = poolQueue.Dequeue(); + if (cnn == null) continue; SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle; if (hdl != null) { hdl.Dispose(); - } + } + GC.KeepAlive(hdl); } } } } Index: System.Data.SQLite/SQLiteConnectionStringBuilder.cs ================================================================== --- System.Data.SQLite/SQLiteConnectionStringBuilder.cs +++ System.Data.SQLite/SQLiteConnectionStringBuilder.cs @@ -535,11 +535,39 @@ } set { this["foreign keys"] = value; } - } + } + + /// + /// Gets/Sets the extra behavioral flags. + /// + [Browsable(true)] + [DefaultValue(SQLiteConnectionFlags.Default)] + public SQLiteConnectionFlags Flags + { + get + { + object value; + + if (TryGetValue("flags", out value)) + { + if (value is SQLiteConnectionFlags) + return (SQLiteConnectionFlags)value; + else if (value != null) + return (SQLiteConnectionFlags)TypeDescriptor.GetConverter( + typeof(SQLiteConnectionFlags)).ConvertFrom(value); + } + + return SQLiteConnectionFlags.Default; + } + set + { + this["flags"] = value; + } + } /// /// Helper function for retrieving values from the connectionstring /// /// The keyword to retrieve settings for Index: System.Data.SQLite/SQLiteConvert.cs ================================================================== --- System.Data.SQLite/SQLiteConvert.cs +++ System.Data.SQLite/SQLiteConvert.cs @@ -6,10 +6,15 @@ ********************************************************/ namespace System.Data.SQLite { using System; + +#if DEBUG + using System.Diagnostics; +#endif + using System.Runtime.InteropServices; using System.Collections.Generic; using System.Globalization; using System.Text; @@ -69,10 +74,22 @@ "yyyy-MM-dd", "yyyyMMdd", "yy-MM-dd" }; + /// + /// The internal default format for UTC DateTime values when converting + /// to a string. + /// + private static readonly string _datetimeFormatUtc = _datetimeFormats[5]; + + /// + /// The internal default format for local DateTime values when converting + /// to a string. + /// + private static readonly string _datetimeFormatLocal = _datetimeFormats[19]; + /// /// An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 /// private static Encoding _utf8 = new UTF8Encoding(); /// @@ -342,10 +359,34 @@ /// The JulianDay value the Datetime represents public static double ToJulianDay(DateTime value) { return value.ToOADate() + OleAutomationEpochAsJulianDay; } + + /// + /// Converts a DateTime struct to the whole number of seconds since the + /// Unix epoch. + /// + /// The DateTime to convert + /// The whole number of seconds since the Unix epoch + public static long ToUnixEpoch(DateTime value) + { + return (value.Subtract(UnixEpoch).Ticks / TimeSpan.TicksPerSecond); + } + + /// + /// Returns the default DateTime format string to use for the specified + /// DateTimeKind. + /// + /// The DateTimeKind to use. + /// + /// The default DateTime format string to use for the specified DateTimeKind. + /// + private static string GetDateTimeKindFormat(DateTimeKind kind) + { + return (kind == DateTimeKind.Utc) ? _datetimeFormatUtc : _datetimeFormatLocal; + } /// /// Converts a DateTime to a string value, using the current DateTimeFormat specified for the connection when it was opened. /// /// The DateTime value to convert @@ -352,27 +393,28 @@ /// Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a /// Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time /// string, a formatted date and time string in the current culture, or an ISO8601-format date/time string. public string ToString(DateTime dateValue) { - switch (_datetimeFormat) - { - case SQLiteDateFormats.Ticks: - return dateValue.Ticks.ToString(CultureInfo.InvariantCulture); - case SQLiteDateFormats.JulianDay: - return ToJulianDay(dateValue).ToString(CultureInfo.InvariantCulture); - case SQLiteDateFormats.UnixEpoch: - return ((long)(dateValue.Subtract(UnixEpoch).Ticks / TimeSpan.TicksPerSecond)).ToString(); - case SQLiteDateFormats.InvariantCulture: - return dateValue.ToString(FullFormat, CultureInfo.InvariantCulture); - case SQLiteDateFormats.CurrentCulture: - return dateValue.ToString(FullFormat, CultureInfo.CurrentCulture); - default: - return (dateValue.Kind == DateTimeKind.Utc) ? - dateValue.ToString(_datetimeFormats[5], CultureInfo.InvariantCulture) : // include "Z" - dateValue.ToString(_datetimeFormats[19], CultureInfo.InvariantCulture); - } + switch (_datetimeFormat) + { + case SQLiteDateFormats.Ticks: + return dateValue.Ticks.ToString(CultureInfo.InvariantCulture); + case SQLiteDateFormats.JulianDay: + return ToJulianDay(dateValue).ToString(CultureInfo.InvariantCulture); + case SQLiteDateFormats.UnixEpoch: + return ((long)(dateValue.Subtract(UnixEpoch).Ticks / TimeSpan.TicksPerSecond)).ToString(); + case SQLiteDateFormats.InvariantCulture: + return dateValue.ToString(FullFormat, CultureInfo.InvariantCulture); + case SQLiteDateFormats.CurrentCulture: + return dateValue.ToString(FullFormat, CultureInfo.CurrentCulture); + default: + return (dateValue.Kind == DateTimeKind.Unspecified) ? + DateTime.SpecifyKind(dateValue, _datetimeKind).ToString( + GetDateTimeKindFormat(_datetimeKind), CultureInfo.InvariantCulture) : + dateValue.ToString(GetDateTimeKindFormat(dateValue.Kind), CultureInfo.InvariantCulture); + } } /// /// Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. /// @@ -692,11 +734,19 @@ { if (_dbtypeNames[n].dataType == typ) return _dbtypeNames[n].typeName; } - return String.Empty; + string defaultTypeName = String.Empty; + +#if DEBUG && !NET_COMPACT_20 + Trace.WriteLine(String.Format( + "WARNING: Type mapping failed, returning default name \"{0}\" for type {1}.", + defaultTypeName, typ)); +#endif + + return defaultTypeName; } private static SQLiteTypeNames[] _dbtypeNames = { new SQLiteTypeNames("INTEGER", DbType.Int64), new SQLiteTypeNames("TINYINT", DbType.Byte), @@ -878,11 +928,19 @@ { return value.dataType; } } - return DbType.Object; + DbType defaultDbType = DbType.Object; + +#if DEBUG && !NET_COMPACT_20 + Trace.WriteLine(String.Format( + "WARNING: Type mapping failed, returning default type {0} for name \"{1}\".", + defaultDbType, Name)); +#endif + + return defaultDbType; } #endregion private static object _syncRoot = new object(); private static Dictionary _typeNames = null; Index: System.Data.SQLite/SQLiteDataReader.cs ================================================================== --- System.Data.SQLite/SQLiteDataReader.cs +++ System.Data.SQLite/SQLiteDataReader.cs @@ -7,10 +7,11 @@ namespace System.Data.SQLite { using System; using System.Collections.Generic; + using System.Collections.Specialized; using System.Data; using System.Data.Common; using System.Globalization; /// @@ -284,11 +285,11 @@ return _fieldCount + _keyInfo.Count; } } /// - /// Returns the number of visible fielsd in the current resultset + /// Returns the number of visible fields in the current resultset /// public override int VisibleFieldCount { get { @@ -1061,15 +1062,46 @@ { values[n] = GetValue(n); } return nMax; - } - - /// - /// Returns True if the resultset has rows that can be fetched - /// + } + + /// + /// Returns a collection containing all the column names and values for the + /// current row of data in the current resultset, if any. If there is no + /// current row or no current resultset, an exception may be thrown. + /// + /// + /// The collection containing the column name and value information for the + /// current row of data in the current resultset or null if this information + /// cannot be obtained. + /// + public NameValueCollection GetValues() + { + CheckDisposed(); + + if ((_activeStatement == null) || (_activeStatement._sql == null)) + throw new InvalidOperationException(); + + int nMax = VisibleFieldCount; + NameValueCollection result = new NameValueCollection(nMax); + + for (int n = 0; n < nMax; n++) + { + string name = _activeStatement._sql.ColumnName(_activeStatement, n); + string value = _activeStatement._sql.GetText(_activeStatement, n); + + result.Add(name, value); + } + + return result; + } + + /// + /// Returns True if the resultset has rows that can be fetched + /// public override bool HasRows { get { CheckDisposed(); ADDED System.Data.SQLite/SQLiteDefineConstants.cs Index: System.Data.SQLite/SQLiteDefineConstants.cs ================================================================== --- /dev/null +++ System.Data.SQLite/SQLiteDefineConstants.cs @@ -0,0 +1,66 @@ +/******************************************************** + * ADO.NET 2.0 Data Provider for SQLite Version 3.X + * Written by Robert Simpson (robert@blackcastlesoft.com) + * + * Released to the public domain, use at your own risk! + ********************************************************/ + +using System.Collections.Generic; + +namespace System.Data.SQLite +{ + internal static class SQLiteDefineConstants + { + public static readonly IList OptionList = new List(new string[] { +#if DEBUG + "DEBUG", +#endif + +#if INTEROP_CODEC + "INTEROP_CODEC", +#endif + +#if INTEROP_EXTENSION_FUNCTIONS + "INTEROP_EXTENSION_FUNCTIONS", +#endif + +#if NET_20 + "NET_20", +#endif + +#if NET_COMPACT_20 + "NET_COMPACT_20", +#endif + +#if PLATFORM_COMPACTFRAMEWORK + "PLATFORM_COMPACTFRAMEWORK", +#endif + +#if PRELOAD_NATIVE_LIBRARY + "PRELOAD_NATIVE_LIBRARY", +#endif + +#if RETARGETABLE + "RETARGETABLE", +#endif + +#if SQLITE_STANDARD + "SQLITE_STANDARD", +#endif + +#if THROW_ON_DISPOSED + "THROW_ON_DISPOSED", +#endif + +#if TRACE + "TRACE", +#endif + +#if USE_INTEROP_DLL + "USE_INTEROP_DLL", +#endif + + null + }); + } +} Index: System.Data.SQLite/SQLiteFunction.cs ================================================================== --- System.Data.SQLite/SQLiteFunction.cs +++ System.Data.SQLite/SQLiteFunction.cs @@ -32,21 +32,39 @@ { private class AggregateData { internal int _count = 1; internal object _data; - } + } + + ///////////////////////////////////////////////////////////////////////// + + #region Private Constants + /// + /// The error code used for logging exceptions caught in user-provided + /// code. + /// + private const int COR_E_EXCEPTION = unchecked((int)0x80131500); + #endregion + + ///////////////////////////////////////////////////////////////////////// /// /// The base connection this function is attached to /// internal SQLiteBase _base; /// /// Internal array used to keep track of aggregate function context data - /// - private Dictionary _contextDataList; + /// + private Dictionary _contextDataList; + + /// + /// The connection flags associated with this object (this should be the + /// same value as the flags associated with the parent connection object). + /// + private SQLiteConnectionFlags _flags; /// /// Holds a reference to the callback function for user functions /// private SQLiteCallback _InvokeFunc; @@ -78,11 +96,11 @@ /// /// Internal constructor, initializes the function's internal variables. /// protected SQLiteFunction() { - _contextDataList = new Dictionary(); + _contextDataList = new Dictionary(); } /////////////////////////////////////////////////////////////////////////////////////////////// #region IDisposable Members @@ -125,24 +143,26 @@ // dispose managed resources here... //////////////////////////////////// IDisposable disp; - foreach (KeyValuePair kv in _contextDataList) + foreach (KeyValuePair kv in _contextDataList) { disp = kv.Value._data as IDisposable; if (disp != null) disp.Dispose(); } _contextDataList.Clear(); + _contextDataList = null; + + _flags = SQLiteConnectionFlags.None; _InvokeFunc = null; _StepFunc = null; _FinalFunc = null; _CompareFunc = null; _base = null; - _contextDataList = null; } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// @@ -347,95 +367,285 @@ return; } } /// - /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. + /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. + /// WARNING: Must not throw exceptions. /// /// A raw context pointer /// Number of arguments passed in - /// A pointer to the array of arguments - internal void ScalarCallback(IntPtr context, int nArgs, IntPtr argsptr) - { - _context = context; - SetReturnValue(context, Invoke(ConvertParams(nArgs, argsptr))); + /// A pointer to the array of arguments + internal void ScalarCallback(IntPtr context, int nArgs, IntPtr argsptr) + { + try + { + _context = context; + SetReturnValue(context, + Invoke(ConvertParams(nArgs, argsptr))); /* throw */ + } +#if !PLATFORM_COMPACTFRAMEWORK + catch (Exception e) /* NOTE: Must catch ALL. */ + { + try + { + if ((_flags & SQLiteConnectionFlags.LogCallbackException) == + SQLiteConnectionFlags.LogCallbackException) + { + SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format( + "Caught exception in \"Invoke\" method: {0}", + e)); /* throw */ + } + } + catch + { + // do nothing. + } + } +#else + catch /* NOTE: Must catch ALL. */ + { + // do nothing (Windows CE). + } +#endif } /// - /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. + /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. + /// WARNING: Must not throw exceptions. /// /// Not used /// Length of the string pv1 /// Pointer to the first string to compare /// Length of the string pv2 /// Pointer to the second string to compare /// Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater - /// than the second. - internal int CompareCallback(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2) - { - return Compare(SQLiteConvert.UTF8ToString(ptr1, len1), SQLiteConvert.UTF8ToString(ptr2, len2)); - } - - internal int CompareCallback16(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2) - { - return Compare(SQLite3_UTF16.UTF16ToString(ptr1, len1), SQLite3_UTF16.UTF16ToString(ptr2, len2)); + /// than the second. Returns 0 if an exception is caught. + internal int CompareCallback(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2) + { + try + { + return Compare(SQLiteConvert.UTF8ToString(ptr1, len1), + SQLiteConvert.UTF8ToString(ptr2, len2)); /* throw */ + } +#if !PLATFORM_COMPACTFRAMEWORK + catch (Exception e) /* NOTE: Must catch ALL. */ + { + try + { + if ((_flags & SQLiteConnectionFlags.LogCallbackException) == + SQLiteConnectionFlags.LogCallbackException) + { + SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format( + "Caught exception in \"Compare\" (UTF8) method: {0}", + e)); /* throw */ + } + } + catch + { + // do nothing. + } + } +#else + catch /* NOTE: Must catch ALL. */ + { + // do nothing (Windows CE). + } +#endif + + // + // NOTE: This must be done to prevent the core SQLite library from + // using our (invalid) result. + // + if (_base != null) + _base.Cancel(); + + return 0; + } + + /// + /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. + /// WARNING: Must not throw exceptions. + /// + /// Not used + /// Length of the string pv1 + /// Pointer to the first string to compare + /// Length of the string pv2 + /// Pointer to the second string to compare + /// Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater + /// than the second. Returns 0 if an exception is caught. + internal int CompareCallback16(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2) + { + try + { + return Compare(SQLite3_UTF16.UTF16ToString(ptr1, len1), + SQLite3_UTF16.UTF16ToString(ptr2, len2)); /* throw */ + } +#if !PLATFORM_COMPACTFRAMEWORK + catch (Exception e) /* NOTE: Must catch ALL. */ + { + try + { + if ((_flags & SQLiteConnectionFlags.LogCallbackException) == + SQLiteConnectionFlags.LogCallbackException) + { + SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format( + "Caught exception in \"Compare\" (UTF16) method: {0}", + e)); /* throw */ + } + } + catch + { + // do nothing. + } + } +#else + catch /* NOTE: Must catch ALL. */ + { + // do nothing (Windows CE). + } +#endif + + // + // NOTE: This must be done to prevent the core SQLite library from + // using our (invalid) result. + // + if (_base != null) + _base.Cancel(); + + return 0; } /// - /// The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. + /// The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. + /// WARNING: Must not throw exceptions. /// /// /// This function takes care of doing the lookups and getting the important information put together to call the Step() function. /// That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so /// binary searches can be done to find the data. /// /// A raw context pointer /// Number of arguments passed in - /// A pointer to the array of arguments - internal void StepCallback(IntPtr context, int nArgs, IntPtr argsptr) - { - long nAux; - AggregateData data; - - nAux = (long)_base.AggregateContext(context); - if (_contextDataList.TryGetValue(nAux, out data) == false) - { - data = new AggregateData(); - _contextDataList[nAux] = data; - } - - try - { - _context = context; - Step(ConvertParams(nArgs, argsptr), data._count, ref data._data); - } - finally - { - data._count++; - } + /// A pointer to the array of arguments + internal void StepCallback(IntPtr context, int nArgs, IntPtr argsptr) + { + try + { + AggregateData data = null; + + if (_base != null) + { + IntPtr nAux = _base.AggregateContext(context); + + if ((_contextDataList != null) && + !_contextDataList.TryGetValue(nAux, out data)) + { + data = new AggregateData(); + _contextDataList[nAux] = data; + } + } + + if (data == null) + data = new AggregateData(); + + try + { + _context = context; + Step(ConvertParams(nArgs, argsptr), + data._count, ref data._data); /* throw */ + } + finally + { + data._count++; + } + } +#if !PLATFORM_COMPACTFRAMEWORK + catch (Exception e) /* NOTE: Must catch ALL. */ + { + try + { + if ((_flags & SQLiteConnectionFlags.LogCallbackException) == + SQLiteConnectionFlags.LogCallbackException) + { + SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format( + "Caught exception in \"Step\" method: {1}", + e)); /* throw */ + } + } + catch + { + // do nothing. + } + } +#else + catch /* NOTE: Must catch ALL. */ + { + // do nothing (Windows CE). + } +#endif } /// - /// An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. + /// An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. + /// WARNING: Must not throw exceptions. /// - /// A raw context pointer - internal void FinalCallback(IntPtr context) - { - long n = (long)_base.AggregateContext(context); - object obj = null; - - if (_contextDataList.ContainsKey(n)) - { - obj = _contextDataList[n]._data; - _contextDataList.Remove(n); - } - - _context = context; - SetReturnValue(context, Final(obj)); - - IDisposable disp = obj as IDisposable; - if (disp != null) disp.Dispose(); + /// A raw context pointer + internal void FinalCallback(IntPtr context) + { + try + { + object obj = null; + + if (_base != null) + { + IntPtr n = _base.AggregateContext(context); + AggregateData aggData; + + if ((_contextDataList != null) && + _contextDataList.TryGetValue(n, out aggData)) + { + obj = aggData._data; + _contextDataList.Remove(n); + } + } + + try + { + _context = context; + SetReturnValue(context, Final(obj)); /* throw */ + } + finally + { + IDisposable disp = obj as IDisposable; + if (disp != null) disp.Dispose(); /* throw */ + } + } +#if !PLATFORM_COMPACTFRAMEWORK + catch (Exception e) /* NOTE: Must catch ALL. */ + { + try + { + if ((_flags & SQLiteConnectionFlags.LogCallbackException) == + SQLiteConnectionFlags.LogCallbackException) + { + SQLiteLog.LogMessage(COR_E_EXCEPTION, String.Format( + "Caught exception in \"Final\" method: {1}", + e)); /* throw */ + } + } + catch + { + // do nothing. + } + } +#else + catch /* NOTE: Must catch ALL. */ + { + // do nothing (Windows CE). + } +#endif } /// /// Using reflection, enumerate all assemblies in the current appdomain looking for classes that /// have a SQLiteFunctionAttribute attribute, and registering them accordingly. @@ -537,21 +747,24 @@ /// /// /// The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to /// all the wrapped callback functions. The interop function uses it to map CDecl callbacks to StdCall callbacks. /// - /// The base object on which the functions are to bind + /// The base object on which the functions are to bind + /// The flags associated with the parent connection object /// Returns an array of functions which the connection object should retain until the connection is closed. - internal static SQLiteFunction[] BindFunctions(SQLiteBase sqlbase) + internal static SQLiteFunction[] BindFunctions(SQLiteBase sqlbase, SQLiteConnectionFlags flags) { SQLiteFunction f; List lFunctions = new List(); foreach (SQLiteFunctionAttribute pr in _registeredFunctions) { - f = (SQLiteFunction)Activator.CreateInstance(pr._instanceType); - f._base = sqlbase; + f = (SQLiteFunction)Activator.CreateInstance(pr._instanceType); + + f._base = sqlbase; + f._flags = flags; f._InvokeFunc = (pr.FuncType == FunctionType.Scalar) ? new SQLiteCallback(f.ScalarCallback) : null; f._StepFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.StepCallback) : null; f._FinalFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteFinalCallback(f.FinalCallback) : null; f._CompareFunc = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback) : null; f._CompareFunc16 = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback16) : null; @@ -770,8 +983,8 @@ /// The second array to compare /// -1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2 public int Compare(char[] c1, char[] c2) { return _func._base.ContextCollateCompare(Encoding, _func._context, c1, c2); - } - } + } + } } Index: System.Data.SQLite/SQLiteStatement.cs ================================================================== --- System.Data.SQLite/SQLiteStatement.cs +++ System.Data.SQLite/SQLiteStatement.cs @@ -40,30 +40,37 @@ /// internal SQLiteParameter[] _paramValues; /// /// Command this statement belongs to (if any) /// - internal SQLiteCommand _command; + internal SQLiteCommand _command; + + /// + /// The flags associated with the parent connection object. + /// + private SQLiteConnectionFlags _flags; private string[] _types; /// /// Initializes the statement and attempts to get all information about parameters in the statement - /// - /// The base SQLite object + /// + /// The base SQLite object + /// The flags associated with the parent connection object /// The statement /// The command text for this statement - /// The previous command in a multi-statement command - internal SQLiteStatement(SQLiteBase sqlbase, SQLiteStatementHandle stmt, string strCommand, SQLiteStatement previous) + /// The previous command in a multi-statement command + internal SQLiteStatement(SQLiteBase sqlbase, SQLiteConnectionFlags flags, SQLiteStatementHandle stmt, string strCommand, SQLiteStatement previous) { _sql = sqlbase; _sqlite_stmt = stmt; - _sqlStatement = strCommand; + _sqlStatement = strCommand; + _flags = flags; // Determine parameters for this statement (if any) and prepare space for them. int nCmdStart = 0; - int n = _sql.Bind_ParamCount(this); + int n = _sql.Bind_ParamCount(this, _flags); int x; string s; if (n > 0) { @@ -72,12 +79,12 @@ _paramNames = new string[n]; _paramValues = new SQLiteParameter[n]; for (x = 0; x < n; x++) - { - s = _sql.Bind_ParamName(this, x + 1); + { + s = _sql.Bind_ParamName(this, _flags, x + 1); if (String.IsNullOrEmpty(s)) { s = String.Format(CultureInfo.InvariantCulture, ";{0}", nCmdStart); nCmdStart++; _unnamedParameters++; @@ -186,18 +193,18 @@ return false; } /// /// Bind all parameters, making sure the caller didn't miss any - /// + /// internal void BindParameters() { if (_paramNames == null) return; int x = _paramNames.Length; for (int n = 0; n < x; n++) - { + { BindParameter(n + 1, _paramValues[n]); } } /// @@ -255,90 +262,101 @@ } } /// /// Perform the bind operation for an individual parameter - /// + /// /// The index of the parameter to bind - /// The parameter we're binding + /// The parameter we're binding private void BindParameter(int index, SQLiteParameter param) { if (param == null) throw new SQLiteException((int)SQLiteErrorCode.Error, "Insufficient parameters supplied to the command"); object obj = param.Value; - DbType objType = param.DbType; + DbType objType = param.DbType; + + if ((obj != null) && (objType == DbType.Object)) + objType = SQLiteConvert.TypeToDbType(obj.GetType()); + +#if !PLATFORM_COMPACTFRAMEWORK + if ((_flags & SQLiteConnectionFlags.LogPreBind) == SQLiteConnectionFlags.LogPreBind) + { + IntPtr handle = _sqlite_stmt; + + SQLiteLog.LogMessage(0, String.Format( + "Binding statement {0} paramter #{1} with database type {2} and raw value {{{3}}}...", + handle, index, objType, obj)); + } +#endif - if (Convert.IsDBNull(obj) || obj == null) - { - _sql.Bind_Null(this, index); + if ((obj == null) || Convert.IsDBNull(obj)) + { + _sql.Bind_Null(this, _flags, index); return; } - if (objType == DbType.Object) - objType = SQLiteConvert.TypeToDbType(obj.GetType()); - switch (objType) { case DbType.Date: case DbType.Time: case DbType.DateTime: // // NOTE: The old method (commented below) does not honor the selected date format // for the connection. - // _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj, CultureInfo.CurrentCulture)); - _sql.Bind_DateTime(this, index, (obj is string) ? + // _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj, CultureInfo.CurrentCulture)); + _sql.Bind_DateTime(this, _flags, index, (obj is string) ? _sql.ToDateTime((string)obj) : Convert.ToDateTime(obj, CultureInfo.CurrentCulture)); break; - case DbType.Boolean: - _sql.Bind_Int32(this, index, ToBoolean(obj, CultureInfo.CurrentCulture) ? 1 : 0); - break; - case DbType.SByte: - _sql.Bind_Int32(this, index, Convert.ToSByte(obj, CultureInfo.CurrentCulture)); - break; - case DbType.Int16: - _sql.Bind_Int32(this, index, Convert.ToInt16(obj, CultureInfo.CurrentCulture)); - break; - case DbType.Int32: - _sql.Bind_Int32(this, index, Convert.ToInt32(obj, CultureInfo.CurrentCulture)); - break; - case DbType.Int64: - _sql.Bind_Int64(this, index, Convert.ToInt64(obj, CultureInfo.CurrentCulture)); - break; - case DbType.Byte: - _sql.Bind_UInt32(this, index, Convert.ToByte(obj, CultureInfo.CurrentCulture)); - break; - case DbType.UInt16: - _sql.Bind_UInt32(this, index, Convert.ToUInt16(obj, CultureInfo.CurrentCulture)); - break; - case DbType.UInt32: - _sql.Bind_UInt32(this, index, Convert.ToUInt32(obj, CultureInfo.CurrentCulture)); - break; - case DbType.UInt64: - _sql.Bind_UInt64(this, index, Convert.ToUInt64(obj, CultureInfo.CurrentCulture)); + case DbType.Boolean: + _sql.Bind_Int32(this, _flags, index, ToBoolean(obj, CultureInfo.CurrentCulture) ? 1 : 0); + break; + case DbType.SByte: + _sql.Bind_Int32(this, _flags, index, Convert.ToSByte(obj, CultureInfo.CurrentCulture)); + break; + case DbType.Int16: + _sql.Bind_Int32(this, _flags, index, Convert.ToInt16(obj, CultureInfo.CurrentCulture)); + break; + case DbType.Int32: + _sql.Bind_Int32(this, _flags, index, Convert.ToInt32(obj, CultureInfo.CurrentCulture)); + break; + case DbType.Int64: + _sql.Bind_Int64(this, _flags, index, Convert.ToInt64(obj, CultureInfo.CurrentCulture)); + break; + case DbType.Byte: + _sql.Bind_UInt32(this, _flags, index, Convert.ToByte(obj, CultureInfo.CurrentCulture)); + break; + case DbType.UInt16: + _sql.Bind_UInt32(this, _flags, index, Convert.ToUInt16(obj, CultureInfo.CurrentCulture)); + break; + case DbType.UInt32: + _sql.Bind_UInt32(this, _flags, index, Convert.ToUInt32(obj, CultureInfo.CurrentCulture)); + break; + case DbType.UInt64: + _sql.Bind_UInt64(this, _flags, index, Convert.ToUInt64(obj, CultureInfo.CurrentCulture)); break; case DbType.Single: case DbType.Double: case DbType.Currency: - //case DbType.Decimal: // Dont store decimal as double ... loses precision - _sql.Bind_Double(this, index, Convert.ToDouble(obj, CultureInfo.CurrentCulture)); + //case DbType.Decimal: // Dont store decimal as double ... loses precision + _sql.Bind_Double(this, _flags, index, Convert.ToDouble(obj, CultureInfo.CurrentCulture)); break; - case DbType.Binary: - _sql.Bind_Blob(this, index, (byte[])obj); + case DbType.Binary: + _sql.Bind_Blob(this, _flags, index, (byte[])obj); break; case DbType.Guid: - if (_command.Connection._binaryGuid == true) - _sql.Bind_Blob(this, index, ((Guid)obj).ToByteArray()); - else - _sql.Bind_Text(this, index, obj.ToString()); + if (_command.Connection._binaryGuid == true) + _sql.Bind_Blob(this, _flags, index, ((Guid)obj).ToByteArray()); + else + _sql.Bind_Text(this, _flags, index, obj.ToString()); break; - case DbType.Decimal: // Dont store decimal as double ... loses precision - _sql.Bind_Text(this, index, Convert.ToDecimal(obj, CultureInfo.CurrentCulture).ToString(CultureInfo.InvariantCulture)); + case DbType.Decimal: // Dont store decimal as double ... loses precision + _sql.Bind_Text(this, _flags, index, Convert.ToDecimal(obj, CultureInfo.CurrentCulture).ToString(CultureInfo.InvariantCulture)); break; - default: - _sql.Bind_Text(this, index, obj.ToString()); + default: + _sql.Bind_Text(this, _flags, index, obj.ToString()); break; } } internal string[] TypeDefinitions Index: System.Data.SQLite/SQLiteTransaction.cs ================================================================== --- System.Data.SQLite/SQLiteTransaction.cs +++ System.Data.SQLite/SQLiteTransaction.cs @@ -88,11 +88,11 @@ // dispose managed resources here... //////////////////////////////////// if (IsValid(false)) { - IssueRollback(); + IssueRollback(false); } } ////////////////////////////////////// // release unmanaged resources here... @@ -159,23 +159,31 @@ /// public override void Rollback() { CheckDisposed(); IsValid(true); - IssueRollback(); - } - - internal void IssueRollback() + IssueRollback(true); + } + + internal void IssueRollback(bool throwError) { SQLiteConnection cnn = Interlocked.Exchange(ref _cnn, null); if (cnn != null) - { - using (SQLiteCommand cmd = cnn.CreateCommand()) - { - cmd.CommandText = "ROLLBACK"; - cmd.ExecuteNonQuery(); + { + try + { + using (SQLiteCommand cmd = cnn.CreateCommand()) + { + cmd.CommandText = "ROLLBACK"; + cmd.ExecuteNonQuery(); + } + } + catch + { + if (throwError) + throw; } cnn._transactionLevel = 0; } } Index: System.Data.SQLite/SR.Designer.cs ================================================================== --- System.Data.SQLite/SR.Designer.cs +++ System.Data.SQLite/SR.Designer.cs @@ -23,11 +23,13 @@ // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] +#if !NET_COMPACT_20 [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] +#endif internal class SR { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; Index: System.Data.SQLite/SR.resx ================================================================== --- System.Data.SQLite/SR.resx +++ System.Data.SQLite/SR.resx @@ -110,21 +110,21 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + - DataTypes.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + DataTypes.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE - MetaDataCollections.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + MetaDataCollections.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 ADDED System.Data.SQLite/System.Data.SQLite.2005.csproj Index: System.Data.SQLite/System.Data.SQLite.2005.csproj ================================================================== --- /dev/null +++ System.Data.SQLite/System.Data.SQLite.2005.csproj @@ -0,0 +1,54 @@ + + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {AC139952-261A-4463-B6FA-AEBC25283A66} + Library + Properties + System.Data.SQLite + System.Data.SQLite + $(MSBuildProjectDirectory)\.. + true + 2005 + + + + $(BinaryOutputPath) + $(BinaryOutputPath)System.Data.SQLite.xml + + + true + full + false + DEBUG;TRACE + prompt + + + pdbonly + true + TRACE + prompt + + + + + + + ADDED System.Data.SQLite/System.Data.SQLite.Compact.2005.csproj Index: System.Data.SQLite/System.Data.SQLite.Compact.2005.csproj ================================================================== --- /dev/null +++ System.Data.SQLite/System.Data.SQLite.Compact.2005.csproj @@ -0,0 +1,73 @@ + + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {AC139951-261A-4463-B6FA-AEBC25283A66} + Library + Properties + System.Data.SQLite + System.Data.SQLite + {4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + WindowsCE + E2BECB1F-8C8C-41ba-B736-9BE7D946A398 + 5.0 + v2.0 + Windows CE + + $(MSBuildProjectDirectory)\.. + true + false + false + true + 2005 + Compact + + + + $(BinaryOutputPath) + $(BinaryOutputPath)System.Data.SQLite.xml + + + true + full + false + DEBUG;TRACE;$(PlatformFamilyName) + true + true + prompt + off + + + pdbonly + true + TRACE;$(PlatformFamilyName) + true + true + prompt + off + + + + + + + + + + + + + + + Index: System.Data.SQLite/System.Data.SQLite.Files.targets ================================================================== --- System.Data.SQLite/System.Data.SQLite.Files.targets +++ System.Data.SQLite/System.Data.SQLite.Files.targets @@ -15,10 +15,11 @@ + Component @@ -32,10 +33,11 @@ Component + ADDED System.Data.SQLite/System.Data.SQLite.Module.2005.csproj Index: System.Data.SQLite/System.Data.SQLite.Module.2005.csproj ================================================================== --- /dev/null +++ System.Data.SQLite/System.Data.SQLite.Module.2005.csproj @@ -0,0 +1,58 @@ + + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {AC139952-261A-4463-B6FA-AEBC25284A66} + Module + Properties + System.Data.SQLite + System.Data.SQLite + false + $(MSBuildProjectDirectory)\.. + true + 2005 + Module + false + false + + + + $(BinaryOutputPath) + $(BinaryOutputPath)System.Data.SQLite.xml + + + true + full + false + DEBUG;TRACE + prompt + + + pdbonly + true + TRACE + prompt + + + + + + + Index: System.Data.SQLite/System.Data.SQLite.Properties.targets ================================================================== --- System.Data.SQLite/System.Data.SQLite.Properties.targets +++ System.Data.SQLite/System.Data.SQLite.Properties.targets @@ -18,10 +18,22 @@ '$(TargetFrameworkVersion)' == 'v2.0' Or '$(TargetFrameworkVersion)' == 'v3.5'"> $(DefineConstants);NET_20 + + + $(DefineConstants);NET_COMPACT_20 + + @@ -55,6 +67,29 @@ NOTE: Throw an exception when somebody tries to access a disposed object? --> $(DefineConstants);THROW_ON_DISPOSED + + + + $(DefineConstants);PRELOAD_NATIVE_LIBRARY + + + + + $(DefineConstants);INTEROP_EXTENSION_FUNCTIONS + + + + + $(DefineConstants);INTEROP_CODEC + Index: System.Data.SQLite/UnsafeNativeMethods.cs ================================================================== --- System.Data.SQLite/UnsafeNativeMethods.cs +++ System.Data.SQLite/UnsafeNativeMethods.cs @@ -6,33 +6,479 @@ ********************************************************/ namespace System.Data.SQLite { using System; -#if DEBUG +#if PRELOAD_NATIVE_LIBRARY || DEBUG using System.Diagnostics; #endif + +#if PRELOAD_NATIVE_LIBRARY + using System.Collections.Generic; + using System.IO; + using System.Reflection; +#endif #if !PLATFORM_COMPACTFRAMEWORK && !DEBUG using System.Security; #endif using System.Runtime.InteropServices; + +#if !PLATFORM_COMPACTFRAMEWORK + using System.Threading; +#endif #if !PLATFORM_COMPACTFRAMEWORK && !DEBUG [SuppressUnmanagedCodeSecurity] #endif internal static class UnsafeNativeMethods { + #region Optional Native SQLite Library Pre-Loading Code + // + // NOTE: If we are looking for the standard SQLite DLL ("sqlite3.dll"), + // the interop DLL ("SQLite.Interop.dll"), or we are running on the + // .NET Compact Framework, we should include this code (only if the + // feature has actually been enabled). This code would be totally + // redundant if this module has been bundled into the mixed-mode + // assembly. + // +#if SQLITE_STANDARD || USE_INTEROP_DLL || PLATFORM_COMPACTFRAMEWORK + + // + // NOTE: Only compile in the native library pre-load code if the feature + // has been enabled for this build. + // +#if PRELOAD_NATIVE_LIBRARY +#if !PLATFORM_COMPACTFRAMEWORK + /// + /// The name of the environment variable containing the processor + /// architecture of the current process. + /// + private static readonly string PROCESSOR_ARCHITECTURE = + "PROCESSOR_ARCHITECTURE"; +#endif + + ///////////////////////////////////////////////////////////////////////// + + private static readonly string DllFileExtension = ".dll"; + + ///////////////////////////////////////////////////////////////////////// + /// + /// This is the P/Invoke method that wraps the native Win32 LoadLibrary + /// function. See the MSDN documentation for full details on what it + /// does. + /// + /// + /// The name of the executable library. + /// + /// + /// The native module handle upon success -OR- IntPtr.Zero on failure. + /// + [DllImport("kernel32", + CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, +#if !PLATFORM_COMPACTFRAMEWORK + BestFitMapping = false, ThrowOnUnmappableChar = true, +#endif + SetLastError = true)] + private static extern IntPtr LoadLibrary(string fileName); + + /// + /// This lock is used to protect the static _SQLiteModule and + /// processorArchitecturePlatforms fields, below. + /// + private static readonly object staticSyncRoot = new object(); + + ///////////////////////////////////////////////////////////////////////// + /// + /// Stores the mappings between processor architecture names and platform + /// names. + /// + private static Dictionary processorArchitecturePlatforms; + + ///////////////////////////////////////////////////////////////////////// + /// + /// The native module handle for the native SQLite library or the value + /// IntPtr.Zero. + /// + private static IntPtr _SQLiteModule = IntPtr.Zero; + + ///////////////////////////////////////////////////////////////////////// + /// + /// For now, this method simply calls the Initialize method. + /// + static UnsafeNativeMethods() + { + Initialize(); + } + + ///////////////////////////////////////////////////////////////////////// + /// + /// Attempts to initialize this class by pre-loading the native SQLite + /// library for the processor architecture of the current process. + /// + internal static void Initialize() + { +#if !PLATFORM_COMPACTFRAMEWORK + // + // NOTE: If the "NoPreLoadSQLite" environment variable is set, skip + // all our special code and simply return. + // + if (Environment.GetEnvironmentVariable("No_PreLoadSQLite") != null) + return; +#endif + + lock (staticSyncRoot) + { + // + // TODO: Make sure this list is updated if the supported + // processor architecture names and/or platform names + // changes. + // + if (processorArchitecturePlatforms == null) + { + // + // NOTE: Create the map of processor architecture names + // to platform names using a case-insensitive string + // comparer. + // + processorArchitecturePlatforms = + new Dictionary( + StringComparer.OrdinalIgnoreCase); + + // + // NOTE: Setup the list of platform names associated with + // the supported processor architectures. + // + processorArchitecturePlatforms.Add("x86", "Win32"); + processorArchitecturePlatforms.Add("AMD64", "x64"); + processorArchitecturePlatforms.Add("IA64", "Itanium"); + } + + // + // BUGBUG: What about other application domains? + // + if (_SQLiteModule == IntPtr.Zero) + _SQLiteModule = PreLoadSQLiteDll(null, null); + } + } + + ///////////////////////////////////////////////////////////////////////// + /// + /// Queries and returns the base directory of the current application + /// domain. + /// + /// + /// The base directory for the current application domain -OR- null if it + /// cannot be determined. + /// + private static string GetBaseDirectory() + { +#if !PLATFORM_COMPACTFRAMEWORK + // + // NOTE: If the "PreLoadSQLite_BaseDirectory" environment variable + // is set, use it verbatim for the base directory. + // + string directory = Environment.GetEnvironmentVariable( + "PreLoadSQLite_BaseDirectory"); + + if (directory != null) + return directory; + + // + // NOTE: Otherwise, fallback on using the base directory of the + // current application domain. + // + return AppDomain.CurrentDomain.BaseDirectory; +#else + Assembly assembly = Assembly.GetExecutingAssembly(); + + if (assembly == null) + return null; + + AssemblyName assemblyName = assembly.GetName(); + + if (assemblyName == null) + return null; + + try + { + return Path.GetDirectoryName(assemblyName.CodeBase); + } + catch + { + // do nothing. + } + + return null; +#endif + } + + ///////////////////////////////////////////////////////////////////////// + /// + /// Determines if the dynamic link library file name requires a suffix + /// and adds it if necessary. + /// + /// + /// The original dynamic link library file name to inspect. + /// + /// + /// The dynamic link library file name, possibly modified to include an + /// extension. + /// + private static string FixUpDllFileName( + string fileName + ) + { + if (!String.IsNullOrEmpty(fileName)) + { + PlatformID platformId = Environment.OSVersion.Platform; + + if ((platformId == PlatformID.Win32S) || + (platformId == PlatformID.Win32Windows) || + (platformId == PlatformID.Win32NT) || + (platformId == PlatformID.WinCE)) + { + if (!fileName.EndsWith(DllFileExtension, + StringComparison.OrdinalIgnoreCase)) + { + return fileName + DllFileExtension; + } + } + } + + return fileName; + } + + ///////////////////////////////////////////////////////////////////////// + /// + /// Queries and returns the processor architecture of the current + /// process. + /// + /// + /// The processor architecture of the current process -OR- null if it + /// cannot be determined. Always returns an empty string when running on + /// the .NET Compact Framework. + /// + private static string GetProcessorArchitecture() + { +#if !PLATFORM_COMPACTFRAMEWORK + // + // NOTE: If the "PreLoadSQLite_ProcessorArchitecture" environment + // variable is set, use it verbatim for the current processor + // architecture. + // + string processorArchitecture = Environment.GetEnvironmentVariable( + "PreLoadSQLite_ProcessorArchitecture"); + + if (processorArchitecture != null) + return processorArchitecture; + + // + // BUGBUG: Will this always be reliable? + // + return Environment.GetEnvironmentVariable(PROCESSOR_ARCHITECTURE); +#else + // + // BUGBUG: No way to determine this value on the .NET Compact + // Framework (running on Windows CE, etc). + // + return String.Empty; +#endif + } + + ///////////////////////////////////////////////////////////////////////// + /// + /// Given the processor architecture, returns the name of the platform. + /// + /// + /// The processor architecture to be translated to a platform name. + /// + /// + /// The platform name for the specified processor architecture -OR- null + /// if it cannot be determined. + /// + private static string GetPlatformName( + string processorArchitecture + ) + { + if (String.IsNullOrEmpty(processorArchitecture)) + return null; + + lock (staticSyncRoot) + { + if (processorArchitecturePlatforms == null) + return null; + + string platformName; + + if (processorArchitecturePlatforms.TryGetValue( + processorArchitecture, out platformName)) + { + return platformName; + } + } + + return null; + } + + ///////////////////////////////////////////////////////////////////////// + /// + /// Attempts to load the native SQLite library based on the specified + /// directory and processor architecture. + /// + /// + /// The base directory to use, null for default (the base directory of + /// the current application domain). This directory should contain the + /// processor architecture specific sub-directories. + /// + /// + /// The requested processor architecture, null for default (the + /// processor architecture of the current process). This caller should + /// almost always specify null for this parameter. + /// + /// + /// The native module handle as returned by LoadLibrary -OR- IntPtr.Zero + /// if the loading fails for any reason. + /// + private static IntPtr PreLoadSQLiteDll( + string directory, + string processorArchitecture + ) + { + // + // NOTE: If the specified base directory is null, use the default. + // + if (directory == null) + directory = GetBaseDirectory(); + + // + // NOTE: If we failed to query the base directory, stop now. + // + if (directory == null) + return IntPtr.Zero; + + // + // NOTE: If the native SQLite library exists in the base directory + // itself, stop now. + // + string fileName = FixUpDllFileName(Path.Combine(directory, + SQLITE_DLL)); + + if (File.Exists(fileName)) + return IntPtr.Zero; + + // + // NOTE: If the specified processor architecture is null, use the + // default. + // + if (processorArchitecture == null) + processorArchitecture = GetProcessorArchitecture(); + + // + // NOTE: If we failed to query the processor architecture, stop now. + // + if (processorArchitecture == null) + return IntPtr.Zero; + + // + // NOTE: Build the full path and file name for the native SQLite + // library using the processor architecture name. + // + fileName = FixUpDllFileName(Path.Combine(Path.Combine(directory, + processorArchitecture), SQLITE_DLL)); + + // + // NOTE: If the file name based on the processor architecture name + // is not found, try using the associated platform name. + // + if (!File.Exists(fileName)) + { + // + // NOTE: Attempt to translate the processor architecture to a + // platform name. + // + string platformName = GetPlatformName(processorArchitecture); + + // + // NOTE: If we failed to translate the platform name, stop now. + // + if (platformName == null) + return IntPtr.Zero; + + // + // NOTE: Build the full path and file name for the native SQLite + // library using the platform name. + // + fileName = FixUpDllFileName(Path.Combine(Path.Combine(directory, + platformName), SQLITE_DLL)); + + // + // NOTE: If the file does not exist, skip trying to load it. + // + if (!File.Exists(fileName)) + return IntPtr.Zero; + } + + try + { + // + // NOTE: Show exactly where we are trying to load the native + // SQLite library from. + // + Trace.WriteLine(String.Format( + "Trying to load native SQLite library \"{0}\"...", + fileName)); + + // + // NOTE: Attempt to load the native library. This will either + // return a valid native module handle, return IntPtr.Zero, + // or throw an exception. + // + return LoadLibrary(fileName); + } + catch (Exception e) + { + try + { + // + // NOTE: First, grab the last Win32 error number. + // + int lastError = Marshal.GetLastWin32Error(); + + // + // NOTE: Show where we failed to load the native SQLite + // library from along with the Win32 error code and + // exception information. + // + Trace.WriteLine(String.Format( + "Failed to load native SQLite library \"{0}\" " + + "(getLastError = {1}): {2}", + fileName, lastError, e)); /* throw */ + } + catch + { + // do nothing. + } + } + + return IntPtr.Zero; + } +#endif +#endif + #endregion + + ///////////////////////////////////////////////////////////////////////// + #if !SQLITE_STANDARD #if !USE_INTEROP_DLL #if !PLATFORM_COMPACTFRAMEWORK private const string SQLITE_DLL = "System.Data.SQLite.dll"; #else - internal const string SQLITE_DLL = "SQLite.Interop.078.dll"; + internal const string SQLITE_DLL = "SQLite.Interop.081.dll"; #endif // PLATFORM_COMPACTFRAMEWORK #else private const string SQLITE_DLL = "SQLite.Interop.dll"; #endif // USE_INTEROP_DLL @@ -684,10 +1130,11 @@ #else [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)] #endif internal static extern void sqlite3_result_text16(IntPtr context, string strName, int nLen, IntPtr pvReserved); +#if INTEROP_CODEC #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif @@ -697,10 +1144,11 @@ [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] #endif internal static extern int sqlite3_rekey(IntPtr db, byte[] key, int keylen); +#endif #if !PLATFORM_COMPACTFRAMEWORK [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] #else [DllImport(SQLITE_DLL)] @@ -801,10 +1249,44 @@ #else [DllImport(SQLITE_DLL)] #endif internal static extern int sqlite3_file_control(IntPtr db, byte[] zDbName, int op, IntPtr pArg); +#if !PLATFORM_COMPACTFRAMEWORK + [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] +#else + [DllImport(SQLITE_DLL)] +#endif + internal static extern IntPtr sqlite3_backup_init(IntPtr destDb, byte[] zDestName, IntPtr sourceDb, byte[] zSourceName); + +#if !PLATFORM_COMPACTFRAMEWORK + [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] +#else + [DllImport(SQLITE_DLL)] +#endif + internal static extern int sqlite3_backup_step(IntPtr backup, int nPage); + +#if !PLATFORM_COMPACTFRAMEWORK + [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] +#else + [DllImport(SQLITE_DLL)] +#endif + internal static extern int sqlite3_backup_finish(IntPtr backup); + +#if !PLATFORM_COMPACTFRAMEWORK + [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] +#else + [DllImport(SQLITE_DLL)] +#endif + internal static extern int sqlite3_backup_remaining(IntPtr backup); + +#if !PLATFORM_COMPACTFRAMEWORK + [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)] +#else + [DllImport(SQLITE_DLL)] +#endif + internal static extern int sqlite3_backup_pagecount(IntPtr backup); #endregion } #if PLATFORM_COMPACTFRAMEWORK internal abstract class CriticalHandle : IDisposable @@ -881,57 +1363,64 @@ // Handles the unmanaged database pointer, and provides finalization support for it. internal class SQLiteConnectionHandle : CriticalHandle { public static implicit operator IntPtr(SQLiteConnectionHandle db) { - return db.handle; + return (db != null) ? db.handle : IntPtr.Zero; } - public static implicit operator SQLiteConnectionHandle(IntPtr db) - { - return new SQLiteConnectionHandle(db); - } - - private SQLiteConnectionHandle(IntPtr db) + internal SQLiteConnectionHandle(IntPtr db) : this() { SetHandle(db); } - internal SQLiteConnectionHandle() + private SQLiteConnectionHandle() : base(IntPtr.Zero) { } protected override bool ReleaseHandle() { try { - SQLiteBase.CloseConnection(this); +#if !PLATFORM_COMPACTFRAMEWORK + IntPtr localHandle = Interlocked.Exchange( + ref handle, IntPtr.Zero); + + if (localHandle != IntPtr.Zero) + SQLiteBase.CloseConnection(this, localHandle); -#if DEBUG +#if DEBUG && !NET_COMPACT_20 try { Trace.WriteLine(String.Format( - "CloseConnection: {0}", handle)); + "CloseConnection: {0}", localHandle)); } catch { } #endif +#else + if (handle != IntPtr.Zero) + { + SQLiteBase.CloseConnection(this, handle); + SetHandle(IntPtr.Zero); + } +#endif #if DEBUG return true; #endif } -#if DEBUG +#if DEBUG && !NET_COMPACT_20 catch (SQLiteException e) #else catch (SQLiteException) #endif { -#if DEBUG +#if DEBUG && !NET_COMPACT_20 try { Trace.WriteLine(String.Format( "CloseConnection: {0}, exception: {1}", handle, e)); @@ -939,10 +1428,14 @@ catch { } #endif } + finally + { + SetHandleAsInvalid(); + } #if DEBUG return false; #else return true; #endif @@ -950,64 +1443,81 @@ public override bool IsInvalid { get { return (handle == IntPtr.Zero); } } + +#if DEBUG + public override string ToString() + { + return handle.ToString(); + } +#endif } // Provides finalization support for unmanaged SQLite statements. internal class SQLiteStatementHandle : CriticalHandle { + private SQLiteConnectionHandle cnn; + public static implicit operator IntPtr(SQLiteStatementHandle stmt) { - return stmt.handle; + return (stmt != null) ? stmt.handle : IntPtr.Zero; } - public static implicit operator SQLiteStatementHandle(IntPtr stmt) - { - return new SQLiteStatementHandle(stmt); - } - - private SQLiteStatementHandle(IntPtr stmt) + internal SQLiteStatementHandle(SQLiteConnectionHandle cnn, IntPtr stmt) : this() { + this.cnn = cnn; SetHandle(stmt); } - internal SQLiteStatementHandle() + private SQLiteStatementHandle() : base(IntPtr.Zero) { } protected override bool ReleaseHandle() { try { - SQLiteBase.FinalizeStatement(this); +#if !PLATFORM_COMPACTFRAMEWORK + IntPtr localHandle = Interlocked.Exchange( + ref handle, IntPtr.Zero); + + if (localHandle != IntPtr.Zero) + SQLiteBase.FinalizeStatement(cnn, localHandle); -#if DEBUG +#if DEBUG && !NET_COMPACT_20 try { Trace.WriteLine(String.Format( - "FinalizeStatement: {0}", handle)); + "FinalizeStatement: {0}", localHandle)); } catch { } #endif +#else + if (handle != IntPtr.Zero) + { + SQLiteBase.FinalizeStatement(cnn, handle); + SetHandle(IntPtr.Zero); + } +#endif #if DEBUG return true; #endif } -#if DEBUG +#if DEBUG && !NET_COMPACT_20 catch (SQLiteException e) #else catch (SQLiteException) #endif { -#if DEBUG +#if DEBUG && !NET_COMPACT_20 try { Trace.WriteLine(String.Format( "FinalizeStatement: {0}, exception: {1}", handle, e)); @@ -1015,10 +1525,14 @@ catch { } #endif } + finally + { + SetHandleAsInvalid(); + } #if DEBUG return false; #else return true; #endif @@ -1026,7 +1540,111 @@ public override bool IsInvalid { get { return (handle == IntPtr.Zero); } } + +#if DEBUG + public override string ToString() + { + return handle.ToString(); + } +#endif + } + + // Provides finalization support for unmanaged SQLite backup objects. + internal class SQLiteBackupHandle : CriticalHandle + { + private SQLiteConnectionHandle cnn; + + public static implicit operator IntPtr(SQLiteBackupHandle backup) + { + return (backup != null) ? backup.handle : IntPtr.Zero; + } + + internal SQLiteBackupHandle(SQLiteConnectionHandle cnn, IntPtr backup) + : this() + { + this.cnn = cnn; + SetHandle(backup); + } + + private SQLiteBackupHandle() + : base(IntPtr.Zero) + { + } + + protected override bool ReleaseHandle() + { + try + { +#if !PLATFORM_COMPACTFRAMEWORK + IntPtr localHandle = Interlocked.Exchange( + ref handle, IntPtr.Zero); + + if (localHandle != IntPtr.Zero) + SQLiteBase.FinishBackup(cnn, localHandle); + +#if DEBUG && !NET_COMPACT_20 + try + { + Trace.WriteLine(String.Format( + "FinishBackup: {0}", localHandle)); + } + catch + { + } +#endif +#else + if (handle != IntPtr.Zero) + { + SQLiteBase.FinishBackup(cnn, handle); + SetHandle(IntPtr.Zero); + } +#endif + +#if DEBUG + return true; +#endif + } +#if DEBUG && !NET_COMPACT_20 + catch (SQLiteException e) +#else + catch (SQLiteException) +#endif + { +#if DEBUG && !NET_COMPACT_20 + try + { + Trace.WriteLine(String.Format( + "FinishBackup: {0}, exception: {1}", + handle, e)); + } + catch + { + } +#endif + } + finally + { + SetHandleAsInvalid(); + } +#if DEBUG + return false; +#else + return true; +#endif + } + + public override bool IsInvalid + { + get { return (handle == IntPtr.Zero); } + } + +#if DEBUG + public override string ToString() + { + return handle.ToString(); + } +#endif } } ADDED Tests/Installer_Test_Vs2005.log Index: Tests/Installer_Test_Vs2005.log ================================================================== --- /dev/null +++ Tests/Installer_Test_Vs2005.log @@ -0,0 +1,64 @@ +Installer.exe: #1: Configuration.Process: No actual changes will be made to this system because "what-if" mode is enabled. +Installer.exe: #2: Installer.Main: GacInstall: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.dll]]" +Installer.exe: #3: Installer.Main: GacInstall: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.Linq.dll]]" +Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727", writable = False +Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = True +Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "SQLite" +Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = True +Installer.exe: #10: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "System.Data.SQLite" +Installer.exe: #11: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\System.Data.SQLite", name = , value = "[file nativename [getBuildDirectory]]" +Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727", writable = False +Installer.exe: #13: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #14: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #17: Installer.RemoveDbProviderFactory: addElement = , removeElement = +Installer.exe: #18: Installer.AddDbProviderFactory: addElement = +Installer.exe: #19: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #20: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", name = "InstallDir", defaultValue = +Installer.exe: #21: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", subKeyName = "Packages", writable = True +Installer.exe: #23: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #24: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = , value = "System.Data.SQLite Designer Package" +Installer.exe: #25: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "Class", value = "SQLite.Designer.SQLitePackage" +Installer.exe: #26: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]" +Installer.exe: #27: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ID", value = 400 +Installer.exe: #28: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "InprocServer32", value = "[file nativename [file join $::env(windir) system32 mscoree.dll]]" +Installer.exe: #29: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CompanyName", value = "http://system.data.sqlite.org/" +Installer.exe: #30: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "MinEdition", value = "standard" +Installer.exe: #31: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductName", value = "System.Data.SQLite Designer Package" +Installer.exe: #32: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductVersion", value = "1.0" +Installer.exe: #33: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", subKeyName = "Toolbox" +Installer.exe: #34: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages\Toolbox", name = "Default Items", value = 3 +Installer.exe: #35: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", subKeyName = "Menus", writable = True +Installer.exe: #36: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", value = ", 1000, 3" +Installer.exe: #37: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", subKeyName = "Services", writable = True +Installer.exe: #38: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" +Installer.exe: #39: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = , value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #40: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = "Name", value = "System.Data.SQLite Designer Service" +Installer.exe: #41: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #42: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", name = "InstallDir", defaultValue = +Installer.exe: #43: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #44: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", subKeyName = "DataSources", writable = True +Installer.exe: #45: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}" +Installer.exe: #46: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", name = , value = "System.Data.SQLite Database File" +Installer.exe: #47: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", subKeyName = "SupportingProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" +Installer.exe: #48: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #49: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", name = "InstallDir", defaultValue = +Installer.exe: #50: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #51: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", subKeyName = "DataProviders", writable = True +Installer.exe: #52: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" +Installer.exe: #53: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = , value = ".NET Framework Data Provider for SQLite" +Installer.exe: #54: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "InvariantName", value = "System.Data.SQLite" +Installer.exe: #55: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "Technology", value = "{77ab9a9d-78b9-4ba7-91ac-873f5338f1d2}" +Installer.exe: #56: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]" +Installer.exe: #57: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "FactoryService", value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" +Installer.exe: #58: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionUIControl" +Installer.exe: #59: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionProperties" +Installer.exe: #60: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionSupport" +Installer.exe: #61: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataObjectSupport" +Installer.exe: #62: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataViewSupport" +Installer.exe: #63: Installer.Main: subKeysCreated = 12, subKeysDeleted = 1, keyValuesSet = 20, keyValuesDeleted = 0 +Installer.exe: #64: Installer.Main: Success. Index: Tests/Installer_Test_Vs2008.log ================================================================== --- Tests/Installer_Test_Vs2008.log +++ Tests/Installer_Test_Vs2008.log @@ -1,64 +1,64 @@ Installer.exe: #1: Configuration.Process: No actual changes will be made to this system because "what-if" mode is enabled. Installer.exe: #2: Installer.Main: GacInstall: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.dll]]" Installer.exe: #3: Installer.Main: GacInstall: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.Linq.dll]]" -Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727", writable = False -Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = True -Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "SQLite" -Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = True -Installer.exe: #10: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "System.Data.SQLite" -Installer.exe: #11: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\System.Data.SQLite", name = , value = "[file nativename [getBuildDirectory]]" -Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727", writable = False -Installer.exe: #13: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #14: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #17: Installer.RemoveDbProviderFactory: element = -Installer.exe: #18: Installer.AddDbProviderFactory: element = -Installer.exe: #19: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #20: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = -Installer.exe: #21: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Packages", writable = True -Installer.exe: #23: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" -Installer.exe: #24: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = , value = "System.Data.SQLite Designer Package" -Installer.exe: #25: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "Class", value = "SQLite.Designer.SQLitePackage" -Installer.exe: #26: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]" -Installer.exe: #27: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ID", value = 400 -Installer.exe: #28: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "InprocServer32", value = "[file nativename [file join $::env(windir) system32 mscoree.dll]]" -Installer.exe: #29: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CompanyName", value = "http://system.data.sqlite.org/" -Installer.exe: #30: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "MinEdition", value = "standard" -Installer.exe: #31: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductName", value = "System.Data.SQLite Designer Package" -Installer.exe: #32: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductVersion", value = "1.0" -Installer.exe: #33: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", subKeyName = "Toolbox" -Installer.exe: #34: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages\Toolbox", name = "Default Items", value = 3 -Installer.exe: #35: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Menus", writable = True -Installer.exe: #36: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", value = ", 1000, 3" -Installer.exe: #37: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Services", writable = True -Installer.exe: #38: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" -Installer.exe: #39: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = , value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" -Installer.exe: #40: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = "Name", value = "System.Data.SQLite Designer Service" -Installer.exe: #41: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #42: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = -Installer.exe: #43: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #44: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "DataSources", writable = True -Installer.exe: #45: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}" -Installer.exe: #46: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", name = , value = "System.Data.SQLite Database File" -Installer.exe: #47: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", subKeyName = "SupportingProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" -Installer.exe: #48: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #49: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = -Installer.exe: #50: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #51: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "DataProviders", writable = True -Installer.exe: #52: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" -Installer.exe: #53: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = , value = ".NET Framework Data Provider for SQLite" -Installer.exe: #54: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "InvariantName", value = "System.Data.SQLite" -Installer.exe: #55: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "Technology", value = "{77ab9a9d-78b9-4ba7-91ac-873f5338f1d2}" -Installer.exe: #56: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]" -Installer.exe: #57: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "FactoryService", value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" -Installer.exe: #58: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionUIControl" -Installer.exe: #59: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionProperties" -Installer.exe: #60: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionSupport" -Installer.exe: #61: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataObjectSupport" -Installer.exe: #62: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataViewSupport" +Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727", writable = False +Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = True +Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "SQLite" +Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = True +Installer.exe: #10: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "System.Data.SQLite" +Installer.exe: #11: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\System.Data.SQLite", name = , value = "[file nativename [getBuildDirectory]]" +Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727", writable = False +Installer.exe: #13: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #14: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #17: Installer.RemoveDbProviderFactory: addElement = , removeElement = +Installer.exe: #18: Installer.AddDbProviderFactory: addElement = +Installer.exe: #19: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #20: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = +Installer.exe: #21: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", subKeyName = "Packages", writable = True +Installer.exe: #23: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #24: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = , value = "System.Data.SQLite Designer Package" +Installer.exe: #25: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "Class", value = "SQLite.Designer.SQLitePackage" +Installer.exe: #26: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]" +Installer.exe: #27: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ID", value = 400 +Installer.exe: #28: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "InprocServer32", value = "[file nativename [file join $::env(windir) system32 mscoree.dll]]" +Installer.exe: #29: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CompanyName", value = "http://system.data.sqlite.org/" +Installer.exe: #30: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "MinEdition", value = "standard" +Installer.exe: #31: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductName", value = "System.Data.SQLite Designer Package" +Installer.exe: #32: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductVersion", value = "1.0" +Installer.exe: #33: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", subKeyName = "Toolbox" +Installer.exe: #34: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages\Toolbox", name = "Default Items", value = 3 +Installer.exe: #35: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", subKeyName = "Menus", writable = True +Installer.exe: #36: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", value = ", 1000, 3" +Installer.exe: #37: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", subKeyName = "Services", writable = True +Installer.exe: #38: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" +Installer.exe: #39: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = , value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #40: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = "Name", value = "System.Data.SQLite Designer Service" +Installer.exe: #41: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #42: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = +Installer.exe: #43: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #44: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", subKeyName = "DataSources", writable = True +Installer.exe: #45: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}" +Installer.exe: #46: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", name = , value = "System.Data.SQLite Database File" +Installer.exe: #47: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", subKeyName = "SupportingProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" +Installer.exe: #48: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #49: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = +Installer.exe: #50: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #51: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", subKeyName = "DataProviders", writable = True +Installer.exe: #52: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" +Installer.exe: #53: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = , value = ".NET Framework Data Provider for SQLite" +Installer.exe: #54: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "InvariantName", value = "System.Data.SQLite" +Installer.exe: #55: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "Technology", value = "{77ab9a9d-78b9-4ba7-91ac-873f5338f1d2}" +Installer.exe: #56: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]" +Installer.exe: #57: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "FactoryService", value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" +Installer.exe: #58: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionUIControl" +Installer.exe: #59: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionProperties" +Installer.exe: #60: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionSupport" +Installer.exe: #61: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataObjectSupport" +Installer.exe: #62: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataViewSupport" Installer.exe: #63: Installer.Main: subKeysCreated = 12, subKeysDeleted = 1, keyValuesSet = 20, keyValuesDeleted = 0 Installer.exe: #64: Installer.Main: Success. Index: Tests/Installer_Test_Vs2010.log ================================================================== --- Tests/Installer_Test_Vs2010.log +++ Tests/Installer_Test_Vs2010.log @@ -1,64 +1,64 @@ Installer.exe: #1: Configuration.Process: No actual changes will be made to this system because "what-if" mode is enabled. Installer.exe: #2: Installer.Main: GacInstall: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.dll]]" Installer.exe: #3: Installer.Main: GacInstall: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.Linq.dll]]" -Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319", writable = False -Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", writable = True -Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", subKeyName = "SQLite" -Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", writable = True -Installer.exe: #10: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", subKeyName = "System.Data.SQLite" -Installer.exe: #11: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\System.Data.SQLite", name = , value = "[file nativename [getBuildDirectory]]" -Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319", writable = False -Installer.exe: #13: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #14: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #17: Installer.RemoveDbProviderFactory: element = -Installer.exe: #18: Installer.AddDbProviderFactory: element = -Installer.exe: #19: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #20: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = -Installer.exe: #21: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Packages", writable = True -Installer.exe: #23: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" -Installer.exe: #24: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = , value = "System.Data.SQLite Designer Package" -Installer.exe: #25: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "Class", value = "SQLite.Designer.SQLitePackage" -Installer.exe: #26: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]" -Installer.exe: #27: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ID", value = 400 -Installer.exe: #28: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "InprocServer32", value = "[file nativename [file join $::env(windir) system32 mscoree.dll]]" -Installer.exe: #29: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CompanyName", value = "http://system.data.sqlite.org/" -Installer.exe: #30: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "MinEdition", value = "standard" -Installer.exe: #31: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductName", value = "System.Data.SQLite Designer Package" -Installer.exe: #32: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductVersion", value = "1.0" -Installer.exe: #33: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", subKeyName = "Toolbox" -Installer.exe: #34: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages\Toolbox", name = "Default Items", value = 3 -Installer.exe: #35: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Menus", writable = True -Installer.exe: #36: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", value = ", 1000, 3" -Installer.exe: #37: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Services", writable = True -Installer.exe: #38: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" -Installer.exe: #39: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = , value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" -Installer.exe: #40: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = "Name", value = "System.Data.SQLite Designer Service" -Installer.exe: #41: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #42: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = -Installer.exe: #43: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #44: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "DataSources", writable = True -Installer.exe: #45: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}" -Installer.exe: #46: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", name = , value = "System.Data.SQLite Database File" -Installer.exe: #47: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", subKeyName = "SupportingProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" -Installer.exe: #48: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #49: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = -Installer.exe: #50: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #51: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "DataProviders", writable = True -Installer.exe: #52: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" -Installer.exe: #53: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = , value = ".NET Framework Data Provider for SQLite" -Installer.exe: #54: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "InvariantName", value = "System.Data.SQLite" -Installer.exe: #55: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "Technology", value = "{77ab9a9d-78b9-4ba7-91ac-873f5338f1d2}" -Installer.exe: #56: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]" -Installer.exe: #57: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "FactoryService", value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" -Installer.exe: #58: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionUIControl" -Installer.exe: #59: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionProperties" -Installer.exe: #60: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionSupport" -Installer.exe: #61: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataObjectSupport" -Installer.exe: #62: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataViewSupport" +Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v4.0.30319", writable = False +Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", writable = True +Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", subKeyName = "SQLite" +Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", writable = True +Installer.exe: #10: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", subKeyName = "System.Data.SQLite" +Installer.exe: #11: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\System.Data.SQLite", name = , value = "[file nativename [getBuildDirectory]]" +Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v4.0.30319", writable = False +Installer.exe: #13: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #14: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #17: Installer.RemoveDbProviderFactory: addElement = , removeElement = +Installer.exe: #18: Installer.AddDbProviderFactory: addElement = +Installer.exe: #19: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #20: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = +Installer.exe: #21: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", subKeyName = "Packages", writable = True +Installer.exe: #23: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #24: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = , value = "System.Data.SQLite Designer Package" +Installer.exe: #25: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "Class", value = "SQLite.Designer.SQLitePackage" +Installer.exe: #26: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]" +Installer.exe: #27: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ID", value = 400 +Installer.exe: #28: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "InprocServer32", value = "[file nativename [file join $::env(windir) system32 mscoree.dll]]" +Installer.exe: #29: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "CompanyName", value = "http://system.data.sqlite.org/" +Installer.exe: #30: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "MinEdition", value = "standard" +Installer.exe: #31: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductName", value = "System.Data.SQLite Designer Package" +Installer.exe: #32: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", name = "ProductVersion", value = "1.0" +Installer.exe: #33: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages\{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", subKeyName = "Toolbox" +Installer.exe: #34: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages\Toolbox", name = "Default Items", value = 3 +Installer.exe: #35: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", subKeyName = "Menus", writable = True +Installer.exe: #36: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}", value = ", 1000, 3" +Installer.exe: #37: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", subKeyName = "Services", writable = True +Installer.exe: #38: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" +Installer.exe: #39: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = , value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #40: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Services\{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}", name = "Name", value = "System.Data.SQLite Designer Service" +Installer.exe: #41: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #42: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = +Installer.exe: #43: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #44: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", subKeyName = "DataSources", writable = True +Installer.exe: #45: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}" +Installer.exe: #46: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", name = , value = "System.Data.SQLite Database File" +Installer.exe: #47: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataSources\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}", subKeyName = "SupportingProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" +Installer.exe: #48: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #49: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = +Installer.exe: #50: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #51: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", subKeyName = "DataProviders", writable = True +Installer.exe: #52: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" +Installer.exe: #53: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = , value = ".NET Framework Data Provider for SQLite" +Installer.exe: #54: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "InvariantName", value = "System.Data.SQLite" +Installer.exe: #55: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "Technology", value = "{77ab9a9d-78b9-4ba7-91ac-873f5338f1d2}" +Installer.exe: #56: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "CodeBase", value = "[file nativename [file join [getBuildDirectory] SQLite.Designer.dll]]" +Installer.exe: #57: RegistryHelper.SetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", name = "FactoryService", value = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" +Installer.exe: #58: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionUIControl" +Installer.exe: #59: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionProperties" +Installer.exe: #60: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataConnectionSupport" +Installer.exe: #61: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataObjectSupport" +Installer.exe: #62: RegistryHelper.CreateSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders\{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}", subKeyName = "SupportedObjects\DataViewSupport" Installer.exe: #63: Installer.Main: subKeysCreated = 12, subKeysDeleted = 1, keyValuesSet = 20, keyValuesDeleted = 0 Installer.exe: #64: Installer.Main: Success. ADDED Tests/Uninstaller_Test_Vs2005.log Index: Tests/Uninstaller_Test_Vs2005.log ================================================================== --- /dev/null +++ Tests/Uninstaller_Test_Vs2005.log @@ -0,0 +1,35 @@ +Installer.exe: #1: Configuration.Process: No actual changes will be made to this system because "what-if" mode is enabled. +Installer.exe: #2: Installer.Main: GacRemove: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.Linq.dll]]" +Installer.exe: #3: Installer.Main: GacRemove: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.dll]]" +Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727", writable = False +Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = True +Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "System.Data.SQLite" +Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727", writable = False +Installer.exe: #10: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #11: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #13: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #14: Installer.RemoveDbProviderFactory: addElement = , removeElement = +Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", name = "InstallDir", defaultValue = +Installer.exe: #17: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #18: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", subKeyName = "Packages", writable = True +Installer.exe: #19: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #20: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", subKeyName = "Menus", writable = True +Installer.exe: #21: RegistryHelper.DeleteValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", subKeyName = "Services", writable = True +Installer.exe: #23: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" +Installer.exe: #24: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #25: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", name = "InstallDir", defaultValue = +Installer.exe: #26: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #27: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", subKeyName = "DataSources", writable = True +Installer.exe: #28: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}" +Installer.exe: #29: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #30: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", name = "InstallDir", defaultValue = +Installer.exe: #31: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\8.0", writable = False +Installer.exe: #32: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0", subKeyName = "DataProviders", writable = True +Installer.exe: #33: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\8.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" +Installer.exe: #34: Installer.Main: subKeysCreated = 0, subKeysDeleted = 5, keyValuesSet = 0, keyValuesDeleted = 1 +Installer.exe: #35: Installer.Main: Success. Index: Tests/Uninstaller_Test_Vs2008.log ================================================================== --- Tests/Uninstaller_Test_Vs2008.log +++ Tests/Uninstaller_Test_Vs2008.log @@ -1,35 +1,35 @@ Installer.exe: #1: Configuration.Process: No actual changes will be made to this system because "what-if" mode is enabled. Installer.exe: #2: Installer.Main: GacRemove: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.Linq.dll]]" Installer.exe: #3: Installer.Main: GacRemove: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.dll]]" -Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727", writable = False -Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = True -Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "System.Data.SQLite" -Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v2.0.50727", writable = False -Installer.exe: #10: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #11: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #13: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #14: Installer.RemoveDbProviderFactory: element = -Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = -Installer.exe: #17: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #18: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Packages", writable = True -Installer.exe: #19: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" -Installer.exe: #20: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Menus", writable = True -Installer.exe: #21: RegistryHelper.DeleteValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" -Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "Services", writable = True -Installer.exe: #23: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" -Installer.exe: #24: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #25: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = -Installer.exe: #26: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #27: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "DataSources", writable = True -Installer.exe: #28: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}" -Installer.exe: #29: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #30: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = -Installer.exe: #31: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\9.0", writable = False -Installer.exe: #32: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0", subKeyName = "DataProviders", writable = True -Installer.exe: #33: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\9.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" +Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727", writable = False +Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", writable = True +Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx", subKeyName = "System.Data.SQLite" +Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v2.0.50727", writable = False +Installer.exe: #10: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #11: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #13: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #14: Installer.RemoveDbProviderFactory: addElement = , removeElement = +Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = +Installer.exe: #17: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #18: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", subKeyName = "Packages", writable = True +Installer.exe: #19: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #20: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", subKeyName = "Menus", writable = True +Installer.exe: #21: RegistryHelper.DeleteValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", subKeyName = "Services", writable = True +Installer.exe: #23: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" +Installer.exe: #24: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #25: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = +Installer.exe: #26: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #27: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", subKeyName = "DataSources", writable = True +Installer.exe: #28: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}" +Installer.exe: #29: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #30: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", name = "InstallDir", defaultValue = +Installer.exe: #31: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\9.0", writable = False +Installer.exe: #32: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0", subKeyName = "DataProviders", writable = True +Installer.exe: #33: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\9.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" Installer.exe: #34: Installer.Main: subKeysCreated = 0, subKeysDeleted = 5, keyValuesSet = 0, keyValuesDeleted = 1 Installer.exe: #35: Installer.Main: Success. Index: Tests/Uninstaller_Test_Vs2010.log ================================================================== --- Tests/Uninstaller_Test_Vs2010.log +++ Tests/Uninstaller_Test_Vs2010.log @@ -1,35 +1,35 @@ Installer.exe: #1: Configuration.Process: No actual changes will be made to this system because "what-if" mode is enabled. Installer.exe: #2: Installer.Main: GacRemove: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.Linq.dll]]" Installer.exe: #3: Installer.Main: GacRemove: assemblyPath = "[file nativename [file join [getBuildDirectory] System.Data.SQLite.dll]]" -Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319", writable = False -Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", writable = True -Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", subKeyName = "System.Data.SQLite" -Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework\v4.0.30319", writable = False -Installer.exe: #10: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #11: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\.NETFramework", writable = False -Installer.exe: #13: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = -Installer.exe: #14: Installer.RemoveDbProviderFactory: element = -Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = -Installer.exe: #17: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #18: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Packages", writable = True -Installer.exe: #19: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" -Installer.exe: #20: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Menus", writable = True -Installer.exe: #21: RegistryHelper.DeleteValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" -Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "Services", writable = True -Installer.exe: #23: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" -Installer.exe: #24: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #25: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = -Installer.exe: #26: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #27: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "DataSources", writable = True -Installer.exe: #28: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}" -Installer.exe: #29: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #30: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = -Installer.exe: #31: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software\Microsoft\VisualStudio\10.0", writable = False -Installer.exe: #32: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0", subKeyName = "DataProviders", writable = True -Installer.exe: #33: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\10.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" +Installer.exe: #4: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v4.0.30319", writable = False +Installer.exe: #5: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #6: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #7: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", writable = True +Installer.exe: #8: RegistryHelper.DeleteSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx", subKeyName = "System.Data.SQLite" +Installer.exe: #9: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework\v4.0.30319", writable = False +Installer.exe: #10: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #11: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #12: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\.NETFramework", writable = False +Installer.exe: #13: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\.NETFramework", name = "InstallRoot", defaultValue = +Installer.exe: #14: Installer.RemoveDbProviderFactory: addElement = , removeElement = +Installer.exe: #15: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #16: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = +Installer.exe: #17: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #18: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", subKeyName = "Packages", writable = True +Installer.exe: #19: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Packages", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #20: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", subKeyName = "Menus", writable = True +Installer.exe: #21: RegistryHelper.DeleteValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Menus", name = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9c}" +Installer.exe: #22: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", subKeyName = "Services", writable = True +Installer.exe: #23: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\Services", subKeyName = "{dcbe6c8d-0e57-4099-a183-98ff74c64d9d}" +Installer.exe: #24: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #25: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = +Installer.exe: #26: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #27: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", subKeyName = "DataSources", writable = True +Installer.exe: #28: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataSources", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c71}" +Installer.exe: #29: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #30: RegistryHelper.GetValue: key = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", name = "InstallDir", defaultValue = +Installer.exe: #31: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE", subKeyName = "Software${wow64}\Microsoft\VisualStudio\10.0", writable = False +Installer.exe: #32: RegistryHelper.OpenSubKey: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0", subKeyName = "DataProviders", writable = True +Installer.exe: #33: RegistryHelper.DeleteSubKeyTree: rootKey = "HKEY_LOCAL_MACHINE\Software${wow64}\Microsoft\VisualStudio\10.0\DataProviders", subKeyName = "{0ebaab6e-ca80-4b4a-8ddf-cbe6bf058c70}" Installer.exe: #34: Installer.Main: subKeysCreated = 0, subKeysDeleted = 5, keyValuesSet = 0, keyValuesDeleted = 1 Installer.exe: #35: Installer.Main: Success. Index: Tests/all.eagle ================================================================== --- Tests/all.eagle +++ Tests/all.eagle @@ -12,12 +12,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### ADDED Tests/backup.eagle Index: Tests/backup.eagle ================================================================== --- /dev/null +++ Tests/backup.eagle @@ -0,0 +1,231 @@ +############################################################################### +# +# backup.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 + +############################################################################### + +set params(pages) [list -1 -1 0 0 1 1 2 2 1000 1000] + +set params(callbacks) [list null "new SQLiteBackupCallback(BackupCallback)" \ + null "new SQLiteBackupCallback(BackupCallback)" \ + null "new SQLiteBackupCallback(BackupCallback)" \ + null "new SQLiteBackupCallback(BackupCallback)" \ + null "new SQLiteBackupCallback(BackupCallback)"] + +set params(results) [list \ + "0 \\{1 1048576 1048576 1048576 1048576 1048576 1048576 1048576 1048576\ + 1048576 1048576 10\\} 0\$" \ + "0 \\{1 1048576 1048576 1048576 1048576 1048576 1048576 1048576 1048576\ + 1048576 1048576 10\\} 0\$" \ + "1 \\{System\\.Reflection\\.TargetInvocationException: Exception has been\ + thrown by the target of an invocation\\. --->\ + System\\.Data\\.SQLite\\.SQLiteException: SQLite error\\r\\nno such table:\ + t1\\r\\n.*?" \ + "1 \\{System\\.Reflection\\.TargetInvocationException: Exception has been\ + thrown by the target of an invocation\\. --->\ + System\\.Data\\.SQLite\\.SQLiteException: SQLite error\\r\\nno such table:\ + t1\\r\\n.*?" \ + "0 \\{1 1048576 1048576 1048576 1048576 1048576 1048576 1048576 1048576\ + 1048576 1048576 10\\} 0\$" \ + "0 \\{1 1048576 1048576 1048576 1048576 1048576 1048576 1048576 1048576\ + 1048576 1048576 10\\} 10283\$" \ + "0 \\{1 1048576 1048576 1048576 1048576 1048576 1048576 1048576 1048576\ + 1048576 1048576 10\\} 0\$" \ + "1 \\{System\\.Reflection\\.TargetInvocationException: Exception has been\ + thrown by the target of an invocation\\. --->\ + System\\.Data\\.SQLite\\.SQLiteException: SQLite error\\r\\nno such table:\ + t1\\r\\n.*?" \ + "0 \\{1 1048576 1048576 1048576 1048576 1048576 1048576 1048576 1048576\ + 1048576 1048576 10\\} \\{\\}\$" \ + "0 \\{1 1048576 1048576 1048576 1048576 1048576 1048576 1048576 1048576\ + 1048576 1048576 10\\} \\{System\\.Data\\.SQLite\\.SQLiteConnection main\ + System\\.Data\\.SQLite\\.SQLiteConnection main 1000 9284 10284 False\ + System\\.Data\\.SQLite\\.SQLiteConnection main\ + System\\.Data\\.SQLite\\.SQLiteConnection main 1000 8284 10284 False\ + System\\.Data\\.SQLite\\.SQLiteConnection main\ + System\\.Data\\.SQLite\\.SQLiteConnection main 1000 7284 10284 False\ + System\\.Data\\.SQLite\\.SQLiteConnection main\ + System\\.Data\\.SQLite\\.SQLiteConnection main 1000 6284 10284 False\ + System\\.Data\\.SQLite\\.SQLiteConnection main\ + System\\.Data\\.SQLite\\.SQLiteConnection main 1000 5284 10284 False\ + System\\.Data\\.SQLite\\.SQLiteConnection main\ + System\\.Data\\.SQLite\\.SQLiteConnection main 1000 4284 10284 False\ + System\\.Data\\.SQLite\\.SQLiteConnection main\ + System\\.Data\\.SQLite\\.SQLiteConnection main 1000 3284 10284 False\ + System\\.Data\\.SQLite\\.SQLiteConnection main\ + System\\.Data\\.SQLite\\.SQLiteConnection main 1000 2284 10284 False\ + System\\.Data\\.SQLite\\.SQLiteConnection main\ + System\\.Data\\.SQLite\\.SQLiteConnection main 1000 1284 10284 False\ + System\\.Data\\.SQLite\\.SQLiteConnection main\ + System\\.Data\\.SQLite\\.SQLiteConnection main 1000 284 10284 False\\}\$"] + +############################################################################### + +for {set i 0} {$i < [llength $params(pages)]} {incr i} { + set pages [lindex $params(pages) $i] + set callback [lindex $params(callbacks) $i] + + runTest {test [appendArgs backup-1. $i] {BackupDatabase method} -setup { + setupDb [set fileName(1) :memory:] "" "" "" "" "" false memDb + setupDb [set fileName(2) [appendArgs backup-1. $i .db]] + } -body { + set id [object invoke Interpreter.GetActive NextId] + set dataSource [file join [getDatabaseDirectory] $fileName(2)] + + sql execute $memDb { + CREATE TABLE t1(x TEXT); + } + + for {set index 0} {$index < 10} {incr index} { + sql execute $memDb [subst { + INSERT INTO t1 (x) VALUES('[string repeat ! 1048576]'); + }] + } + + set memSource [object invoke -flags +NonPublic -objectflags +NoDispose \ + Interpreter.GetActive.connections get_Item $memDb] + + unset -nocomplain results errors + + set code [compileCSharpWith [subst { + using System; + using System.Data.SQLite; + using System.Text; + using Eagle._Components.Public; + + namespace _Dynamic${id} + { + public static class Test${id} + { + public static int count = 0; + public static readonly StringBuilder results = new StringBuilder(); + + ///////////////////////////////////////////////////////////////////// + + public static bool BackupCallback( + SQLiteConnection source, + string sourceName, + SQLiteConnection destination, + string destinationName, + int pages, + int remainingPages, + int totalPages, + bool retry + ) + { + results.AppendFormat("{0} {1} {2} {3} {4} {5} {6} {7} ", source, + sourceName, destination, destinationName, pages, remainingPages, + totalPages, retry); + + count++; + + return (pages != 2); + } + + ///////////////////////////////////////////////////////////////////// + + public static string BackupAndGetData( + Interpreter interpreter, + SQLiteConnection source + ) + { + using (SQLiteConnection destination = new SQLiteConnection( + "Data Source=${dataSource};")) + { + destination.Open(); + + int pages = ${pages}; + + source.BackupDatabase(destination, "main", "main", pages, + ${callback}, 0); + + ReturnCode code; + Result error = null; + + code = interpreter.SetVariableValue( + VariableFlags.GlobalOnly, "callbackResults", (pages > 2) ? + results.ToString().Trim() : count.ToString(), null, + ref error); + + if (code != ReturnCode.Ok) + Utility.Complain(interpreter, code, error); + + using (SQLiteCommand command = new SQLiteCommand( + "SELECT length(x) FROM t1;", destination)) + { + using (SQLiteDataReader dataReader = command.ExecuteReader()) + { + StringBuilder builder = new StringBuilder(); + int rowCount = 0; + + builder.Append(dataReader.FieldCount); + builder.Append(' '); + + while (dataReader.Read()) + { + builder.Append(dataReader.GetInt64(0)); + builder.Append(' '); + rowCount++; + } + + builder.Append(rowCount); + return builder.ToString(); + } + } + } + } + + ///////////////////////////////////////////////////////////////////// + + public static void Main() + { + // do nothing. + } + } + } + }] true true true results errors [list System.Data.SQLite.dll Eagle.dll]] + + set callbackResults [list] + + list $code $results \ + [expr {[info exists errors] ? $errors : ""}] \ + [expr {$code eq "Ok" ? [catch { + object invoke _Dynamic${id}.Test${id} BackupAndGetData "" $memSource + } result] : [set result ""]}] $result $callbackResults + } -cleanup { + cleanupDb $fileName(2) + cleanupDb $fileName(1) memDb + + unset -nocomplain result results errors code index memSource dataSource \ + id memDb db fileName callbackResults + } -constraints \ +{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \ +-match regexp -result [appendArgs \ +"^Ok System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} " \ +[lindex $params(results) $i]]} +} + +############################################################################### + +unset -nocomplain i params pages callback + +############################################################################### + +runSQLiteTestEpilogue +runTestEpilogue Index: Tests/basic.eagle ================================================================== --- Tests/basic.eagle +++ Tests/basic.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -22,19 +22,31 @@ # # NOTE: Setup the variables that refer to the various files required by the # tests in this file. # +set systemDataSQLiteDllFile [getBuildFileName System.Data.SQLite.dll] +set systemDataSQLiteLinqDllFile [getBuildFileName System.Data.SQLite.Linq.dll] set testExeFile [getBuildFileName test.exe] set testLinqExeFile [getBuildFileName testlinq.exe] set testLinqOutFile [file nativename [file join $path testlinq.out]] set northwindEfDbFile [file nativename [file join [file dirname $path] \ testlinq northwindEF.db]] # # NOTE: Setup the test constraints specific to the tests in this file. # +if {![haveConstraint [appendArgs file_ \ + [file tail $systemDataSQLiteDllFile]]]} then { + checkForFile $test_channel $systemDataSQLiteDllFile +} + +if {![haveConstraint [appendArgs file_ \ + [file tail $systemDataSQLiteLinqDllFile]]]} then { + checkForFile $test_channel $systemDataSQLiteLinqDllFile +} + if {![haveConstraint [appendArgs file_ [file tail $testExeFile]]]} then { checkForFile $test_channel $testExeFile } if {![haveConstraint [appendArgs file_ [file tail $testLinqExeFile]]]} then { @@ -76,11 +88,11 @@ list $code [expr {$code == 0 ? "" : $error}] } -cleanup { cleanupDb $fileName unset -nocomplain code output error fileName -} -constraints {eagle file_test.exe} -result {0 {}}} +} -constraints {eagle file_System.Data.SQLite.dll file_test.exe} -result {0 {}}} ############################################################################### runTest {test data-1.2 {unit tests from the 'testlinq' project} -setup { # @@ -115,12 +127,12 @@ } -cleanup { catch {object invoke Console OutputEncoding $savedEncoding} unset -nocomplain code output error savedEncoding encoding } -constraints \ -{eagle monoToDo file_testlinq.exe file_northwindEF.db file_testlinq.out} \ --result {0 True {}}} +{eagle monoToDo file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\ +file_testlinq.exe file_northwindEF.db file_testlinq.out} -result {0 True {}}} ############################################################################### runTest {test data-1.3 {SELECT scalar/reader, CREATE, INSERT} -setup { setupDb [set fileName data-1.3.db] @@ -153,21 +165,21 @@ runTest {test data-1.4 {GetSchema with ReservedWords} -setup { setupDb [set fileName data-1.4.db] } -body { set id [object invoke Interpreter.GetActive NextId] - set dataSource [file join [getDatabaseDirectory] data-1.4.db] + set dataSource [file join [getDatabaseDirectory] $fileName] unset -nocomplain results errors set code [compileCSharpWith [subst { using System.Data; using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static DataTable GetReservedWords() { using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};")) @@ -175,10 +187,12 @@ connection.Open(); return connection.GetSchema("ReservedWords"); } } + + /////////////////////////////////////////////////////////////////////// public static void Main() { // do nothing. } @@ -191,10 +205,11 @@ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} GetReservedWords } result] : [set result ""]}] $result } -cleanup { cleanupDb $fileName + unset -nocomplain result results errors code dataSource id db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \ -match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\ System#Data#DataTable#\d+$}} @@ -213,21 +228,21 @@ } sql execute $db "CREATE TABLE t2(x INTEGER REFERENCES t3);" set id [object invoke Interpreter.GetActive NextId] - set dataSource [file join [getDatabaseDirectory] data-1.5.db] + set dataSource [file join [getDatabaseDirectory] $fileName] unset -nocomplain results errors set code [compileCSharpWith [subst { using System.Data; using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static DataRowCollection GetForeignKeys() { using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};")) @@ -235,10 +250,12 @@ connection.Open(); return connection.GetSchema("ForeignKeys").Rows; } } + + /////////////////////////////////////////////////////////////////////// public static void Main() { // do nothing. } @@ -259,10 +276,11 @@ [$foreignKey Item TABLE_CATALOG] \ [$foreignKey Item TABLE_NAME] \ [$foreignKey Item CONSTRAINT_TYPE] \ [$foreignKey Item IS_DEFERRABLE] \ [$foreignKey Item INITIALLY_DEFERRED] \ + [$foreignKey Item FKEY_ID] \ [$foreignKey Item FKEY_FROM_COLUMN] \ [$foreignKey Item FKEY_TO_CATALOG] \ [$foreignKey Item FKEY_TO_TABLE] \ [$foreignKey Item FKEY_TO_COLUMN] \ [$foreignKey Item FKEY_FROM_ORDINAL_POSITION] \ @@ -279,31 +297,31 @@ unset -nocomplain result rows foreignKey foreignKeys results errors code \ dataSource id db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \ -match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\ -\{\{main FK_t1_0 main t1 \{FOREIGN KEY\} False False x main t2 \{\} 0 \{SET\ -DEFAULT\} CASCADE NONE\} \{main FK_t2_0 main t2 \{FOREIGN KEY\} False False x\ -main t3 \{\} 0 \{NO ACTION\} \{NO ACTION\} NONE\}\}$}} +\{\{main FK_t1_0_0 main t1 \{FOREIGN KEY\} False False 0 x main t2 \{\} 0 \{SET\ +DEFAULT\} CASCADE NONE\} \{main FK_t2_0_0 main t2 \{FOREIGN KEY\} False False 0\ +x main t3 \{\} 0 \{NO ACTION\} \{NO ACTION\} NONE\}\}$}} ############################################################################### runTest {test data-1.6 {SQLITE_FCNTL_WIN32_AV_RETRY} -setup { setupDb [set fileName data-1.6.db] } -body { set id [object invoke Interpreter.GetActive NextId] - set dataSource [file join [getDatabaseDirectory] data-1.6.db] + set dataSource [file join [getDatabaseDirectory] $fileName] unset -nocomplain results errors set code [compileCSharpWith [subst { using System.Data; using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static bool TestSetAvRetry( ref int count, ref int interval ) @@ -331,10 +349,12 @@ // NOTE: Make sure the retry parameter values were set. // return (newCount == count && newInterval == interval); } } + + /////////////////////////////////////////////////////////////////////// public static void Main() { // do nothing. } @@ -395,11 +415,11 @@ set sql { \ BEGIN EXCLUSIVE TRANSACTION; \ CREATE TABLE t1(x INTEGER); \ INSERT INTO t1 (x) VALUES(1); \ - SELECT * FROM t1; \ + SELECT x FROM t1; \ } unset -nocomplain results errors set code [compileCSharpWith [subst { @@ -406,11 +426,11 @@ using System.Data; using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static void Main() { using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};")) @@ -453,11 +473,11 @@ set sql { \ BEGIN EXCLUSIVE TRANSACTION; \ CREATE TABLE t1(x INTEGER); \ INSERT INTO t1 (x) VALUES(1); \ - SELECT * FROM t1; \ + SELECT x FROM t1; \ } unset -nocomplain results errors set code [compileCSharpWith [subst { @@ -464,11 +484,11 @@ using System.Data; using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static void Main() { using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};")) @@ -514,11 +534,11 @@ set sql { \ BEGIN EXCLUSIVE TRANSACTION; \ CREATE TABLE t1(x INTEGER); \ INSERT INTO t1 (x) VALUES(1); \ - SELECT * FROM t1; \ + SELECT x FROM t1; \ } unset -nocomplain results errors set code [compileCSharpWith [subst { @@ -525,11 +545,11 @@ using System.Data; using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static void Main() { using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};")) @@ -848,11 +868,11 @@ set code [compileCSharpWith [subst { using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static string GetConnectionString( string format, string kind ) @@ -864,10 +884,12 @@ builder.Add("DateTimeFormat", format); builder.Add("DateTimeKind", kind); return builder.ToString(); } + + /////////////////////////////////////////////////////////////////////// public static void Main() { // do nothing. } @@ -896,13 +918,13 @@ } -cleanup { unset -nocomplain result results errors code id } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \ regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{Date\ -Source=test\.db\} 0 \{Date Source=test\.db;DateTimeFormat=ISO8601\} 0 \{Date\ -Source=test\.db;DateTimeKind=Unspecified\} 0 \{Date\ -Source=test\.db;DateTimeFormat=ISO8601;DateTimeKind=Utc\}$}} +Source=test\.db\} 0 \{Date Source=test\.db;DateTimeFormat=(?:Default|ISO8601)\}\ +0 \{Date Source=test\.db;DateTimeKind=Unspecified\} 0 \{Date\ +Source=test\.db;DateTimeFormat=(?:Default|ISO8601);DateTimeKind=Utc\}$}} ############################################################################### runTest {test data-1.16 {SQLiteConnectionStringBuilder properties} -body { set id [object invoke Interpreter.GetActive NextId] @@ -914,11 +936,11 @@ using System.Data.SQLite; using System.Reflection; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static string GetConnectionString( string key, string value, string propertyName @@ -940,10 +962,12 @@ } return String.Format("{0}, {1}", propertyValue, builder); } + /////////////////////////////////////////////////////////////////////// + public static void Main() { // do nothing. } } @@ -956,25 +980,28 @@ set keys [list null Version Synchronous UseUTF16Encoding Pooling \ BinaryGUID "Data Source" Uri "Default Timeout" \ Enlist FailIfMissing "Legacy Format" "Read Only" \ Password "Page Size" "Max Page Count" "Cache Size" \ DateTimeFormat DateTimeKind BaseSchemaName \ - "Journal Mode" "Default IsolationLevel" "Foreign Keys"] + "Journal Mode" "Default IsolationLevel" "Foreign Keys" \ + Flags] set values [list null 3 Full True False \ True test.db test.db 60 \ False True False True \ secret 4096 1024 8192 \ UnixEpoch Utc sqlite_schema \ - Memory Serializable False] + Memory Serializable False \ + Default] set propertyNames [list null Version SyncMode UseUTF16Encoding Pooling \ BinaryGUID DataSource Uri DefaultTimeout \ Enlist FailIfMissing LegacyFormat ReadOnly \ Password PageSize MaxPageCount CacheSize \ DateTimeFormat DateTimeKind BaseSchemaName \ - JournalMode DefaultIsolationLevel ForeignKeys] + JournalMode DefaultIsolationLevel ForeignKeys \ + Flags] foreach key $keys value $values propertyName $propertyNames { set code [catch { object invoke _Dynamic${id}.Test${id} GetConnectionString \ $key $value $propertyName @@ -998,11 +1025,12 @@ Format=False\} 0 \{True, Read Only=True\} 0 \{secret, Password=secret\} 0\ \{4096, Page Size=4096\} 0 \{1024, Max Page Count=1024\} 0 \{8192, Cache\ Size=8192\} 0 \{UnixEpoch, DateTimeFormat=UnixEpoch\} 0 \{Utc,\ DateTimeKind=Utc\} 0 \{sqlite_schema, BaseSchemaName=sqlite_schema\} 0\ \{Memory, Journal Mode=Memory\} 0 \{Serializable, Default\ -IsolationLevel=Serializable\} 0 \{False, Foreign Keys=False\}$}} +IsolationLevel=Serializable\} 0 \{False, Foreign Keys=False\} 0\ +\{LogCallbackException, Flags=(?:Default|LogCallbackException)\}$}} ############################################################################### runTest {test data-1.17 {SQLiteConvert ToDateTime (Julian Day)} -body { set dateTime [object invoke System.Data.SQLite.SQLiteConvert ToDateTime \ @@ -1020,11 +1048,376 @@ "2012-01-01 12:00:00Z"])} } -constraints {eagle System.Data.SQLite} -result {2455928}} ############################################################################### -unset -nocomplain testExeFile testLinqExeFile northwindEfDbFile testLinqOutFile +runTest {test data-1.19 {SQLiteConvert ToUnixEpoch (Utc)} -body { + # + # NOTE: At first, the test result here may not seem correct; however, the + # same result can be seen by compiling and running the following C# + # code fragment together with the ToUnixEpoch method: + # + # DateTime dateTime; + # Console.WriteLine("dateTime = {0}, unixTime = {1}", + # dateTime = DateTime.Parse("2012-01-01 12:00:00Z"), + # ToUnixEpoch(dateTime)); + # + # The basic problem here is that the Parse [and TryParse] methods of + # the DateTime structure seem to always return local time, even when + # string value clearly indicates otherwise (i.e. the trailing "Z", + # indicating UTC). + # + expr {round([object invoke System.Data.SQLite.SQLiteConvert ToUnixEpoch \ + "2012-01-01 12:00:00Z"])} +} -constraints {eagle System.Data.SQLite} -result {1325390400}} + +############################################################################### + +runTest {test data-1.20 {SQLiteConvert ToUnixEpoch (Local)} -body { + # + # NOTE: At first, the test result here may not seem correct; however, the + # same result can be seen by compiling and running the following C# + # code fragment together with the ToUnixEpoch method: + # + # DateTime dateTime; + # Console.WriteLine("dateTime = {0}, unixTime = {1}", + # dateTime = DateTime.Parse("2012-01-01 12:00:00"), + # ToUnixEpoch(dateTime)); + # + # The basic problem here is that the Parse [and TryParse] methods of + # the DateTime structure seem to always return local time, even when + # string value clearly indicates otherwise (i.e. the trailing "Z", + # indicating UTC). + # + expr {round([object invoke System.Data.SQLite.SQLiteConvert ToUnixEpoch \ + "2012-01-01 12:00:00"])} +} -constraints {eagle System.Data.SQLite} -result {1325419200}} + +############################################################################### + +runTest {test data-1.21 {SQLiteTransaction disposal behavior} -setup { + setupDb [set fileName data-1.21.db] +} -body { + sql execute $db "CREATE TABLE t1(x TEXT);" + + sql execute $db { + INSERT INTO t1 (x) VALUES('test1'); + INSERT INTO t1 (x) VALUES('test2'); + INSERT INTO t1 (x) VALUES('test3'); + } + + set sql "SELECT x FROM t1 ORDER BY x COLLATE DOTHROW;" + + set id [object invoke Interpreter.GetActive NextId] + set dataSource [file join [getDatabaseDirectory] $fileName] + + unset -nocomplain results errors + + set code [compileCSharpWith [subst { + using System; + using System.Data.SQLite; + + namespace _Dynamic${id} + { + \[SQLiteFunction(Name = "DOTHROW", FuncType = FunctionType.Collation)\] + public class Test${id} : SQLiteFunction + { + public override int Compare( + string param1, + string param2 + ) + { + throw new Exception("not implemented"); + } + + /////////////////////////////////////////////////////////////////////// + + public static void Main() + { + SQLiteFunction.RegisterFunction(typeof(Test${id})); + + using (SQLiteConnection connection = new SQLiteConnection( + "Data Source=${dataSource};")) + { + connection.Open(); + + using (SQLiteTransaction transaction = + connection.BeginTransaction()) + { + try + { + SQLiteCommand command = connection.CreateCommand(); + + command.CommandText = "${sql}"; + command.ExecuteNonQuery(); + } + catch + { + // do nothing. + } + } + } + } + } + } + }] true true true results errors System.Data.SQLite.dll] + + list $code $results \ + [expr {[info exists errors] ? $errors : ""}] \ + [expr {$code eq "Ok" ? [catch { + object invoke _Dynamic${id}.Test${id} Main + } result] : [set result ""]}] $result +} -cleanup { + cleanupDb $fileName + + unset -nocomplain result results errors code sql dataSource id db fileName +} -constraints \ +{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \ +regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}} + +############################################################################### + +runTest {test data-1.22 {SQLiteFunction collation exception} -setup { + setupDb [set fileName data-1.22.db] +} -body { + sql execute $db "CREATE TABLE t1(x TEXT);" + + sql execute $db { + INSERT INTO t1 (x) VALUES('test1'); + INSERT INTO t1 (x) VALUES('test2'); + INSERT INTO t1 (x) VALUES('test3'); + } + + set sql "SELECT x FROM t1 ORDER BY x COLLATE DOTHROW2;" + + set id [object invoke Interpreter.GetActive NextId] + set dataSource [file join [getDatabaseDirectory] $fileName] + + unset -nocomplain results errors + + set code [compileCSharpWith [subst { + using System; + using System.Data.SQLite; + + namespace _Dynamic${id} + { + \[SQLiteFunction(Name = "DOTHROW2", FuncType = FunctionType.Collation)\] + public class Test${id} : SQLiteFunction + { + public override int Compare( + string param1, + string param2 + ) + { + throw new Exception("not implemented"); + } + + /////////////////////////////////////////////////////////////////////// + + public static int Main() + { + SQLiteFunction.RegisterFunction(typeof(Test${id})); + + using (SQLiteConnection connection = new SQLiteConnection( + "Data Source=${dataSource};")) + { + connection.Open(); + + using (SQLiteTransaction transaction = + connection.BeginTransaction()) + { + SQLiteCommand command = connection.CreateCommand(); + + command.CommandText = "${sql}"; + + using (SQLiteDataReader dataReader = command.ExecuteReader()) + { + int count = 0; + + while (dataReader.Read()) + count++; + + return count; + } + } + } + } + } + } + }] true true true results errors System.Data.SQLite.dll] + + list $code $results \ + [expr {[info exists errors] ? $errors : ""}] \ + [expr {$code eq "Ok" ? [catch { + object invoke _Dynamic${id}.Test${id} Main + } result] : [set result ""]}] $result +} -cleanup { + cleanupDb $fileName + + unset -nocomplain result results errors code sql dataSource id db fileName +} -constraints \ +{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \ +regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 1\ +\{System\.Reflection\.TargetInvocationException: Exception has been thrown by\ +the target of an invocation\. ---> System\.Data\.SQLite\.SQLiteException:\ +Operation terminated by sqlite3_interrupt\(\).*$}} + +############################################################################### + +runTest {test data-1.23 {LINQ SQL_CONSTRAINTCOLUMNS resource} -body { + object invoke -flags +NonPublic System.Data.SQLite.Properties.Resources \ + SQL_CONSTRAINTCOLUMNS +} -constraints {eagle System.Data.SQLite System.Data.SQLite.Linq} -result { + CREATE TEMP VIEW SCHEMACONSTRAINTCOLUMNS AS + SELECT CONSTRAINT_CATALOG, + NULL AS CONSTRAINT_SCHEMA, + CONSTRAINT_NAME, + TABLE_CATALOG, + NULL AS TABLE_SCHEMA, + TABLE_NAME, + COLUMN_NAME + FROM TEMP.SCHEMAINDEXCOLUMNS + UNION + SELECT CONSTRAINT_CATALOG, + NULL, + CONSTRAINT_NAME, + TABLE_CATALOG, + NULL, + TABLE_NAME, + FKEY_FROM_COLUMN + FROM TEMP.SCHEMAFOREIGNKEYS; + }} + +############################################################################### + +runTest {test data-1.24 {LINQ SQL_CONSTRAINTS resource} -body { + object invoke -flags +NonPublic System.Data.SQLite.Properties.Resources \ + SQL_CONSTRAINTS +} -constraints {eagle System.Data.SQLite System.Data.SQLite.Linq} -result { + CREATE TEMP VIEW SCHEMACONSTRAINTS AS + SELECT INDEX_CATALOG AS CONSTRAINT_CATALOG, + NULL AS CONSTRAINT_SCHEMA, + INDEX_NAME AS CONSTRAINT_NAME, + TABLE_CATALOG, + NULL AS TABLE_SCHEMA, + TABLE_NAME, + 'PRIMARY KEY' AS CONSTRAINT_TYPE, + 0 AS IS_DEFERRABLE, + 0 AS INITIALLY_DEFERRED, + NULL AS CHECK_CLAUSE + FROM TEMP.SCHEMAINDEXES + WHERE PRIMARY_KEY = 1 + UNION + SELECT INDEX_CATALOG, + NULL, + INDEX_NAME, + TABLE_CATALOG, + NULL, + TABLE_NAME, + 'UNIQUE', + 0, + 0, + NULL + FROM TEMP.SCHEMAINDEXES + WHERE PRIMARY_KEY = 0 AND [UNIQUE] = 1 + UNION + SELECT CONSTRAINT_CATALOG, + NULL, + CONSTRAINT_NAME, + TABLE_CATALOG, + NULL, + TABLE_NAME, + CONSTRAINT_TYPE, + IS_DEFERRABLE, + INITIALLY_DEFERRED, + NULL + FROM TEMP.SCHEMAFOREIGNKEYS; + }} + +############################################################################### + +runTest {test data-1.25 {SQLiteDataReader GetValues w/collection} -setup { + setupDb [set fileName data-1.25.db] +} -body { + sql execute $db { + CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y TEXT); + INSERT INTO t1 (x, y) VALUES(1, 'aardvark'); + INSERT INTO t1 (x, y) VALUES(2, 'bear'); + INSERT INTO t1 (x, y) VALUES(3, 'chicken'); + INSERT INTO t1 (x, y) VALUES(4, 'duck'); + INSERT INTO t1 (x, y) VALUES(5, 'elephant'); + INSERT INTO t1 (x, y) VALUES(6, 'frog'); + INSERT INTO t1 (x, y) VALUES(7, 'goose'); + INSERT INTO t1 (x, y) VALUES(8, 'horse'); + INSERT INTO t1 (x, y) VALUES(9, 'iguana'); + INSERT INTO t1 (x, y) VALUES(10, 'jellyfish'); + INSERT INTO t1 (x, y) VALUES(11, 'kangaroo'); + INSERT INTO t1 (x, y) VALUES(12, 'llama'); + INSERT INTO t1 (x, y) VALUES(13, 'moose'); + INSERT INTO t1 (x, y) VALUES(14, 'newt'); + INSERT INTO t1 (x, y) VALUES(15, 'ostrich'); + INSERT INTO t1 (x, y) VALUES(16, 'pig'); + INSERT INTO t1 (x, y) VALUES(17, 'quail'); + INSERT INTO t1 (x, y) VALUES(18, 'rhinoceros'); + INSERT INTO t1 (x, y) VALUES(19, 'shark'); + INSERT INTO t1 (x, y) VALUES(20, 'tiger'); + INSERT INTO t1 (x, y) VALUES(21, 'unicorn'); + INSERT INTO t1 (x, y) VALUES(22, 'viper'); + INSERT INTO t1 (x, y) VALUES(23, 'weasel'); + INSERT INTO t1 (x, y) VALUES(24, 'xerus'); + INSERT INTO t1 (x, y) VALUES(25, 'yak'); + INSERT INTO t1 (x, y) VALUES(26, 'zebra'); + } + + set connection [object invoke -flags +NonPublic -objectflags +NoDispose \ + Interpreter.GetActive.connections get_Item $db] + + set command [object create -alias System.Data.SQLite.SQLiteCommand \ + "SELECT x, y, x, y FROM t1 ORDER BY y DESC;" $connection] + + set reader [$command -alias ExecuteReader] + set collection [$reader -alias GetValues] + set result [list] + + object foreach -alias item $collection { + lappend result [$collection GetValues $item] + } + + set result +} -cleanup { + cleanupDb $fileName + + unset -nocomplain result item collection reader command connection db \ + fileName +} -constraints \ +{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ +{{26 26} {zebra zebra}}} + +############################################################################### + +runTest {test data-1.26 {LINQ ISQLiteSchemaExtensions.BuildTempSchema} -setup { + setupDb [set fileName data-1.26.db] +} -body { + set connection [object invoke -flags +NonPublic -objectflags +NoDispose \ + Interpreter.GetActive.connections Item $db] + + set providerServices [object invoke -flags +NonPublic \ + System.Data.SQLite.SQLiteProviderServices Instance] + + object invoke -flags +NonPublic -type \ + System.Data.SQLite.ISQLiteSchemaExtensions $providerServices \ + BuildTempSchema $connection +} -cleanup { + cleanupDb $fileName + + unset -nocomplain providerServices connection db fileName +} -constraints {eagle System.Data.SQLite System.Data.SQLite.Linq} -result {}} + +############################################################################### + +unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \ + testExeFile testLinqExeFile northwindEfDbFile testLinqOutFile ############################################################################### runSQLiteTestEpilogue runTestEpilogue Index: Tests/common.eagle ================================================================== --- Tests/common.eagle +++ Tests/common.eagle @@ -20,14 +20,17 @@ proc getBuildYear {} { # # NOTE: See if the "year" setting has been overridden by the user (e.g. on # the command line). This helps control exactly which set of - # binaries we are testing, those produced using either the Visual - # Studio 2008 or Visual Studio 2010 build systems. To override this - # value via the command line, enter a command similar to one of the - # following (all on one line): + # binaries we are testing, those produced using the Visual Studio + # 2005, 2008, or 2010 build systems. To override this value via the + # command line, enter a command similar to one of the following (all + # on one line): + # + # EagleShell.exe -preInitialize "set test_year 2005" + # -file .\path\to\all.eagle # # EagleShell.exe -preInitialize "set test_year 2008" # -file .\path\to\all.eagle # # EagleShell.exe -preInitialize "set test_year 2010" @@ -44,13 +47,14 @@ # return $::test_year } else { # # NOTE: If Eagle has been compiled against the .NET Framework 4.0, use - # "2010" as the test year; otherwise, use "2008". If another - # major [incompatible] version of the .NET Framework is released, - # this check will have to be changed. + # "2010" as the test year; otherwise, use "2008" (we could use + # "2005" in that case as well). If another major [incompatible] + # version of the .NET Framework is released, this check will have + # to be changed. # return [expr {[haveConstraint imageRuntime40] ? "2010" : "2008"}] } } @@ -225,11 +229,11 @@ # directory, can be transferred to the interpreter in the isolated # application domain, making it able to successfully run tests that # require one or more of the files in the build directory. Callers # to this procedure should keep in mind that the test script being # returned cannot only rely on any script library procedures not - # included in the EagleLibrary package (i.e. "init.eagle"). Also, + # included in the Eagle.Library package (i.e. "init.eagle"). Also, # all variable references and all "nested" commands (i.e. those in # square brackets), unless they are specially quoted, will end up # being evaluated in the context of the calling interpreter and not # the test interpreter created in the isolated application domain. # @@ -310,11 +314,11 @@ proc tryLoadAssembly { fileName } { set fileName [getBinaryFileName $fileName] if {[catch {set assembly \ - [object load -loadtype File -alias $fileName]}] == 0} then { + [object load -loadtype File -alias $fileName]}] == 0} then { # # NOTE: Now, add the necessary test constraint. # addConstraint [file rootname [file tail $fileName]] @@ -359,10 +363,33 @@ tputs $channel [appendArgs "yes (" $version " " $sourceId ")\n"] } else { tputs $channel no\n } } + + proc checkForSQLiteDefineConstant { channel name } { + tputs $channel [appendArgs \ + "---- checking for System.Data.SQLite define constant \"" $name \ + "\"... "] + + if {[catch {object invoke -flags +NonPublic System.Data.SQLite.SQLite3 \ + DefineConstants} defineConstants] == 0} then { + if {[lsearch -exact -nocase $defineConstants $name] != -1} then { + # + # NOTE: Yes, this define constant was enabled when the managed + # assembly was compiled. + # + addConstraint [appendArgs defineConstant.System.Data.SQLite. $name] + + tputs $channel yes\n + } else { + tputs $channel no\n + } + } else { + tputs $channel error\n + } + } proc getDateTimeFormat {} { # # NOTE: This procedure simply returns the "default" DateTime format used # by the test suite. @@ -401,24 +428,29 @@ } proc compileCSharpWith { text memory symbols strict resultsVarName errorsVarName fileNames args } { + # + # NOTE: Since we are going to use this method name a lot, assign it to a + # variable first. + # + set add ReferencedAssemblies.Add + # # NOTE: Create the base command to evaluate and add the property settings # that are almost always needed by our unit tests (i.e. the System # and System.Data assembly references). # set command [list compileCSharp $text $memory $symbols $strict results \ - errors ReferencedAssemblies.Add System.dll ReferencedAssemblies.Add \ - System.Data.dll ReferencedAssemblies.Add System.Xml.dll] + errors $add System.dll $add System.Data.dll $add System.Xml.dll] # # NOTE: Add all the provided file names as assembly references. # foreach fileName $fileNames { - lappend command ReferencedAssemblies.Add [getBinaryFileName $fileName] + lappend command $add [getBinaryFileName $fileName] } # # NOTE: Add the extra arguments, if any, to the command to evaluate. # @@ -435,26 +467,40 @@ # NOTE: Evaluate the constructed [compileCSharp] command and return the # result. # eval $command } + + proc isMemoryDb { fileName } { + # + # NOTE: Is the specified database file name really an in-memory database? + # + return [expr {$fileName eq ":memory:"}] + } proc setupDb { - fileName {mode ""} {dateTimeFormat ""} {dateTimeKind ""} {extra ""} - {delete true} {varName db} } { + fileName {mode ""} {dateTimeFormat ""} {dateTimeKind ""} {flags ""} + {extra ""} {delete true} {varName db} } { + # + # NOTE: First, see if the caller has requested an in-memory database. + # + set isMemory [isMemoryDb $fileName] + # # NOTE: For now, all test databases used by the test suite are placed into # the temporary directory. Each database used by a test should be # cleaned up by that test using the "cleanupDb" procedure, below. # - set fileName [file join [getDatabaseDirectory] [file tail $fileName]] + if {!$isMemory} then { + set fileName [file join [getDatabaseDirectory] [file tail $fileName]] + } # # NOTE: By default, delete any pre-existing database with the same file # name if it currently exists. # - if {$delete && [file exists $fileName]} then { + if {!$isMemory && $delete && [file exists $fileName]} then { # # NOTE: Attempt to delete any pre-existing database with the same file # name. # if {[catch {file delete $fileName} error]} then { @@ -501,10 +547,41 @@ # if {[string length $dateTimeKind] > 0} then { append connection {;DateTimeKind=${dateTimeKind}} } + # + # NOTE: If there are any global (per test run) connection flags currently + # set, use them now (i.e. by combining them with the ones for this + # connection). + # + if {[info exists ::connection_flags] && \ + [string length $::connection_flags] > 0} then { + # + # NOTE: Show (and log) that we detected some global connection flags. + # + tputs $::test_channel [appendArgs \ + "---- global connection flags detected: " $::connection_flags \n] + + # + # NOTE: Combine and/or replace the connection flags and then show the + # new value. + # + set flags [combineFlags $flags $::connection_flags] + + tputs $::test_channel [appendArgs \ + "---- combined connection flags are: " $flags \n] + } + + # + # NOTE: If the caller specified a SQLiteConnectionFlags, add the necessary + # portion of the connection string now. + # + if {[string length $flags] > 0} then { + append connection {;Flags=${flags}} + } + # # NOTE: If the caller specified an extra payload to the connection string, # append it now. # if {[string length $extra] > 0} then { @@ -536,20 +613,27 @@ tputs $::test_channel [appendArgs \ "==== WARNING: failed to close database \"" $db "\", error: " \ \n\t $error \n] } + # + # NOTE: First, see if the caller has requested an in-memory database. + # + set isMemory [isMemoryDb $fileName] + # # NOTE: Build the full path to the database file name. For now, all test # database files are stored in the temporary directory. # - set fileName [file join [getDatabaseDirectory] [file tail $fileName]] + if {!$isMemory} then { + set fileName [file join [getDatabaseDirectory] [file tail $fileName]] + } # # NOTE: Check if the file still exists. # - if {[file exists $fileName]} then { + if {!$isMemory && [file exists $fileName]} then { # # NOTE: Skip deleting database files if somebody sets the global # variable to prevent it. # if {![info exists ::no(cleanupDb)]} then { @@ -721,13 +805,20 @@ # # NOTE: Skip trying to delete any files if we are so instructed. # if {![info exists ::no(deleteSqliteFiles)]} then { tryDeleteAssembly sqlite3.dll + removeConstraint file_sqlite3.dll + tryDeleteAssembly SQLite.Interop.dll + removeConstraint file_SQLite.Interop.dll + tryDeleteAssembly System.Data.SQLite.dll + removeConstraint file_System.Data.SQLite.dll + tryDeleteAssembly System.Data.SQLite.Linq.dll + removeConstraint file_System.Data.SQLite.Linq.dll } # # NOTE: Skip trying to copy any files if we are so instructed. # @@ -772,19 +863,40 @@ tputs $::test_channel [appendArgs \ "---- found assembly: " $assembly \n] } } + catch { + tputs $::test_channel \ + "---- define constants for \"System.Data.SQLite\"... " + + if {[catch {object invoke -flags +NonPublic \ + System.Data.SQLite.SQLite3 DefineConstants} \ + defineConstants] == 0} then { + tputs $::test_channel [appendArgs [formatList [lsort \ + $defineConstants]] \n] + } else { + tputs $::test_channel unknown\n + } + } + # # NOTE: Now, we need to know if the SQLite core library is available # (i.e. because the managed-only System.Data.SQLite assembly can # load without it; however, it cannot do anything useful without # it). If we are using the mixed-mode assembly and we already # found it (above), this should always succeed. # checkForSQLite $::test_channel + # + # NOTE: Attempt to determine if the custom extension functions were + # compiled into the SQLite interop assembly. + # + checkForSQLiteDefineConstant $::test_channel \ + INTEROP_EXTENSION_FUNCTIONS + # # NOTE: Report the resource usage prior to running any tests. # reportSQLiteResources $::test_channel @@ -791,18 +903,32 @@ # # NOTE: Show the active test constraints. # tputs $::test_channel [appendArgs "---- constraints: " \ [formatList [lsort [getConstraints]]] \n] + + # + # NOTE: Show when our tests actually began (now). + # + tputs $::test_channel [appendArgs \ + "---- System.Data.SQLite tests began at " \ + [clock format [clock seconds]] \n] } } proc runSQLiteTestEpilogue {} { # # NOTE: Skip running our custom epilogue if the main one has been skipped. # if {![info exists ::no(epilogue.eagle)]} then { + # + # NOTE: Show when our tests actually ended (now). + # + tputs $::test_channel [appendArgs \ + "---- System.Data.SQLite tests ended at " \ + [clock format [clock seconds]] \n] + # # NOTE: Also report the resource usage after running the tests. # reportSQLiteResources $::test_channel } Index: Tests/installer.eagle ================================================================== --- Tests/installer.eagle +++ Tests/installer.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -24,16 +24,30 @@ # NOTE: Setup the variables that refer to the various files required by the # tests in this file. # set systemDataSQLiteDllFile [getBuildFileName System.Data.SQLite.dll] set installerExeFile [getBuildFileName Installer.exe] + +# +# NOTE: The various install/uninstall log files used to test the design-time +# component installer. +# +set testInstallVs2005LogFile [file nativename [file join $path \ + Installer_Test_Vs2005.log]] + set testInstallVs2008LogFile [file nativename [file join $path \ Installer_Test_Vs2008.log]] + set testInstallVs2010LogFile [file nativename [file join $path \ Installer_Test_Vs2010.log]] + +set testUninstallVs2005LogFile [file nativename [file join $path \ + Uninstaller_Test_Vs2005.log]] + set testUninstallVs2008LogFile [file nativename [file join $path \ Uninstaller_Test_Vs2008.log]] + set testUninstallVs2010LogFile [file nativename [file join $path \ Uninstaller_Test_Vs2010.log]] # # NOTE: Setup the test constraints specific to the tests in this file. @@ -40,10 +54,15 @@ # if {![haveConstraint [appendArgs file_ \ [file tail $installerExeFile]]]} then { checkForFile $test_channel $installerExeFile } + +if {![haveConstraint [appendArgs file_ \ + [file tail $testInstallVs2005LogFile]]]} then { + checkForFile $test_channel $testInstallVs2005LogFile +} if {![haveConstraint [appendArgs file_ \ [file tail $testInstallVs2008LogFile]]]} then { checkForFile $test_channel $testInstallVs2008LogFile } @@ -50,10 +69,15 @@ if {![haveConstraint [appendArgs file_ \ [file tail $testInstallVs2010LogFile]]]} then { checkForFile $test_channel $testInstallVs2010LogFile } + +if {![haveConstraint [appendArgs file_ \ + [file tail $testUninstallVs2005LogFile]]]} then { + checkForFile $test_channel $testUninstallVs2005LogFile +} if {![haveConstraint [appendArgs file_ \ [file tail $testUninstallVs2008LogFile]]]} then { checkForFile $test_channel $testUninstallVs2008LogFile } @@ -63,11 +87,81 @@ checkForFile $test_channel $testUninstallVs2010LogFile } ############################################################################### -runTest {test installer-1.1 {installer tool / Visual Studio 2008} -setup { +runTest {test installer-1.1 {installer tool / Visual Studio 2005} -setup { + set fileName [file join [getTemporaryPath] [file tail [string map [list \ + .log [appendArgs _ [pid] .log]] $testInstallVs2005LogFile]]] + + cleanupFile $fileName +} -body { + set output "" + + set code [catch { + testClrExec $installerExeFile [list -eventflags Wait -stdout output \ + -success 0] -debugPriority Lowest -tracePriority MediumHigh \ + -noRuntimeVersion true -noCompact true -noNetFx40 true -noVs2008 true \ + -noVs2010 true -whatIf true -verbose true -confirm true -install true \ + -logFileName [appendArgs \" [file nativename $fileName] \"] \ + -traceFormat [appendArgs \" "#{0}: {2}" \"] -debug true -wow64 true + } error] + + tlog "---- BEGIN STDOUT OUTPUT\n" + tlog $output + tlog "\n---- END STDOUT OUTPUT\n" + + set wow64 [expr {[haveConstraint amd64.64bit] ? "\\Wow6432Node" : ""}] + + list $code [expr {$code == 0 ? [string equal [readFile $fileName] \ + [subst -nobackslashes [readFile $testInstallVs2005LogFile]]] : $error}] +} -cleanup { + cleanupFile $fileName + + unset -nocomplain wow64 code output error fileName +} -constraints {eagle administrator visualStudio2005\ +System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\ +file_Installer_Test_Vs2005.log} -result {0 True}} + +############################################################################### + +runTest {test installer-1.2 {uninstaller tool / Visual Studio 2005} -setup { + set fileName [file join [getTemporaryPath] [file tail [string map [list \ + .log [appendArgs _ [pid] .log]] $testUninstallVs2005LogFile]]] + + cleanupFile $fileName +} -body { + set output "" + + set code [catch { + testClrExec $installerExeFile [list -eventflags Wait -stdout output \ + -success 0] -debugPriority Lowest -tracePriority MediumHigh \ + -noRuntimeVersion true -noCompact true -noNetFx40 true -noVs2008 true \ + -noVs2010 true -whatIf true -verbose true -confirm true -install false \ + -logFileName [appendArgs \" [file nativename $fileName] \"] \ + -traceFormat [appendArgs \" "#{0}: {2}" \"] -debug true -wow64 true + } error] + + tlog "---- BEGIN STDOUT OUTPUT\n" + tlog $output + tlog "\n---- END STDOUT OUTPUT\n" + + set wow64 [expr {[haveConstraint amd64.64bit] ? "\\Wow6432Node" : ""}] + + list $code [expr {$code == 0 ? [string equal [readFile $fileName] \ + [subst -nobackslashes [readFile $testUninstallVs2005LogFile]]] : $error}] +} -cleanup { + cleanupFile $fileName + + unset -nocomplain wow64 code output error fileName +} -constraints {eagle administrator visualStudio2005\ +System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\ +file_Uninstaller_Test_Vs2005.log} -result {0 True}} + +############################################################################### + +runTest {test installer-1.3 {installer tool / Visual Studio 2008} -setup { set fileName [file join [getTemporaryPath] [file tail [string map [list \ .log [appendArgs _ [pid] .log]] $testInstallVs2008LogFile]]] cleanupFile $fileName } -body { @@ -74,33 +168,35 @@ set output "" set code [catch { testClrExec $installerExeFile [list -eventflags Wait -stdout output \ -success 0] -debugPriority Lowest -tracePriority MediumHigh \ - -noRuntimeVersion true -noCompact true -noNetFx40 true -noVs2010 true \ - -whatIf true -verbose true -confirm true -install true \ + -noRuntimeVersion true -noCompact true -noNetFx40 true -noVs2005 true \ + -noVs2010 true -whatIf true -verbose true -confirm true -install true \ -logFileName [appendArgs \" [file nativename $fileName] \"] \ - -traceFormat [appendArgs \" "#{0}: {2}" \"] + -traceFormat [appendArgs \" "#{0}: {2}" \"] -debug true -wow64 true } error] tlog "---- BEGIN STDOUT OUTPUT\n" tlog $output tlog "\n---- END STDOUT OUTPUT\n" + + set wow64 [expr {[haveConstraint amd64.64bit] ? "\\Wow6432Node" : ""}] list $code [expr {$code == 0 ? [string equal [readFile $fileName] \ [subst -nobackslashes [readFile $testInstallVs2008LogFile]]] : $error}] } -cleanup { cleanupFile $fileName - unset -nocomplain code output error fileName + unset -nocomplain wow64 code output error fileName } -constraints {eagle administrator visualStudio2008\ System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\ file_Installer_Test_Vs2008.log} -result {0 True}} ############################################################################### -runTest {test installer-1.2 {uninstaller tool / Visual Studio 2008} -setup { +runTest {test installer-1.4 {uninstaller tool / Visual Studio 2008} -setup { set fileName [file join [getTemporaryPath] [file tail [string map [list \ .log [appendArgs _ [pid] .log]] $testUninstallVs2008LogFile]]] cleanupFile $fileName } -body { @@ -107,33 +203,35 @@ set output "" set code [catch { testClrExec $installerExeFile [list -eventflags Wait -stdout output \ -success 0] -debugPriority Lowest -tracePriority MediumHigh \ - -noRuntimeVersion true -noCompact true -noNetFx40 true -noVs2010 true \ - -whatIf true -verbose true -confirm true -install false \ + -noRuntimeVersion true -noCompact true -noNetFx40 true -noVs2005 true \ + -noVs2010 true -whatIf true -verbose true -confirm true -install false \ -logFileName [appendArgs \" [file nativename $fileName] \"] \ - -traceFormat [appendArgs \" "#{0}: {2}" \"] + -traceFormat [appendArgs \" "#{0}: {2}" \"] -debug true -wow64 true } error] tlog "---- BEGIN STDOUT OUTPUT\n" tlog $output tlog "\n---- END STDOUT OUTPUT\n" + + set wow64 [expr {[haveConstraint amd64.64bit] ? "\\Wow6432Node" : ""}] list $code [expr {$code == 0 ? [string equal [readFile $fileName] \ [subst -nobackslashes [readFile $testUninstallVs2008LogFile]]] : $error}] } -cleanup { cleanupFile $fileName - unset -nocomplain code output error fileName + unset -nocomplain wow64 code output error fileName } -constraints {eagle administrator visualStudio2008\ System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\ file_Uninstaller_Test_Vs2008.log} -result {0 True}} ############################################################################### -runTest {test installer-1.3 {installer tool / Visual Studio 2010} -setup { +runTest {test installer-1.5 {installer tool / Visual Studio 2010} -setup { set fileName [file join [getTemporaryPath] [file tail [string map [list \ .log [appendArgs _ [pid] .log]] $testInstallVs2010LogFile]]] cleanupFile $fileName } -body { @@ -140,33 +238,35 @@ set output "" set code [catch { testClrExec $installerExeFile [list -eventflags Wait -stdout output \ -success 0] -debugPriority Lowest -tracePriority MediumHigh \ - -noRuntimeVersion true -noCompact true -noNetFx20 true -noVs2008 true \ - -whatIf true -verbose true -confirm true -install true \ + -noRuntimeVersion true -noCompact true -noNetFx20 true -noVs2005 true \ + -noVs2008 true -whatIf true -verbose true -confirm true -install true \ -logFileName [appendArgs \" [file nativename $fileName] \"] \ - -traceFormat [appendArgs \" "#{0}: {2}" \"] + -traceFormat [appendArgs \" "#{0}: {2}" \"] -debug true -wow64 true } error] tlog "---- BEGIN STDOUT OUTPUT\n" tlog $output tlog "\n---- END STDOUT OUTPUT\n" + + set wow64 [expr {[haveConstraint amd64.64bit] ? "\\Wow6432Node" : ""}] list $code [expr {$code == 0 ? [string equal [readFile $fileName] \ [subst -nobackslashes [readFile $testInstallVs2010LogFile]]] : $error}] } -cleanup { cleanupFile $fileName - unset -nocomplain code output error fileName + unset -nocomplain wow64 code output error fileName } -constraints {eagle administrator visualStudio2010\ System.Data.SQLite.dll_v4.0.30319 file_Installer.exe\ file_Installer_Test_Vs2010.log} -result {0 True}} ############################################################################### -runTest {test installer-1.4 {uninstaller tool / Visual Studio 2010} -setup { +runTest {test installer-1.6 {uninstaller tool / Visual Studio 2010} -setup { set fileName [file join [getTemporaryPath] [file tail [string map [list \ .log [appendArgs _ [pid] .log]] $testUninstallVs2010LogFile]]] cleanupFile $fileName } -body { @@ -173,35 +273,38 @@ set output "" set code [catch { testClrExec $installerExeFile [list -eventflags Wait -stdout output \ -success 0] -debugPriority Lowest -tracePriority MediumHigh \ - -noRuntimeVersion true -noCompact true -noNetFx20 true -noVs2008 true \ - -whatIf true -verbose true -confirm true -install false \ + -noRuntimeVersion true -noCompact true -noNetFx20 true -noVs2005 true \ + -noVs2008 true -whatIf true -verbose true -confirm true -install false \ -logFileName [appendArgs \" [file nativename $fileName] \"] \ - -traceFormat [appendArgs \" "#{0}: {2}" \"] + -traceFormat [appendArgs \" "#{0}: {2}" \"] -debug true -wow64 true } error] tlog "---- BEGIN STDOUT OUTPUT\n" tlog $output tlog "\n---- END STDOUT OUTPUT\n" + set wow64 [expr {[haveConstraint amd64.64bit] ? "\\Wow6432Node" : ""}] + list $code [expr {$code == 0 ? [string equal [readFile $fileName] \ [subst -nobackslashes [readFile $testUninstallVs2010LogFile]]] : $error}] } -cleanup { cleanupFile $fileName - unset -nocomplain code output error fileName + unset -nocomplain wow64 code output error fileName } -constraints {eagle administrator visualStudio2010\ System.Data.SQLite.dll_v4.0.30319 file_Installer.exe\ file_Uninstaller_Test_Vs2010.log} -result {0 True}} ############################################################################### unset -nocomplain testUninstallVs2010LogFile testUninstallVs2008LogFile \ - testInstallVs2010LogFile testInstallVs2008LogFile installerExeFile \ + testUninstallVs2005LogFile testInstallVs2010LogFile \ + testInstallVs2008LogFile testInstallVs2005LogFile installerExeFile \ systemDataSQLiteDllFile ############################################################################### runSQLiteTestEpilogue runTestEpilogue Index: Tests/tkt-00f86f9739.eagle ================================================================== --- Tests/tkt-00f86f9739.eagle +++ Tests/tkt-00f86f9739.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -22,17 +22,29 @@ # # NOTE: Setup the variables that refer to the various files required by the # tests in this file. # +set systemDataSQLiteDllFile [getBuildFileName System.Data.SQLite.dll] +set systemDataSQLiteLinqDllFile [getBuildFileName System.Data.SQLite.Linq.dll] set testLinqExeFile [getBuildFileName testlinq.exe] set northwindEfDbFile [file nativename [file join [file dirname $path] \ testlinq northwindEF.db]] # # NOTE: Setup the test constraints specific to the tests in this file. # +if {![haveConstraint [appendArgs file_ \ + [file tail $systemDataSQLiteDllFile]]]} then { + checkForFile $test_channel $systemDataSQLiteDllFile +} + +if {![haveConstraint [appendArgs file_ \ + [file tail $systemDataSQLiteLinqDllFile]]]} then { + checkForFile $test_channel $systemDataSQLiteLinqDllFile +} + if {![haveConstraint [appendArgs file_ [file tail $testLinqExeFile]]]} then { checkForFile $test_channel $testLinqExeFile } if {![haveConstraint [appendArgs file_ [file tail $northwindEfDbFile]]]} then { @@ -67,17 +79,21 @@ } set result } -cleanup { unset -nocomplain code output error result value -} -constraints {eagle monoToDo file_testlinq.exe file_northwindEF.db} -result \ -{0 {} 0 {DRACD OLDWO RATTC} 0 {ALFKI CACTU CHOPS FOLKO GALED KOENE LILAS MAGAA\ -MAISD OCEAN RANCH SAVEA THECR} 0 {} 0 {} 0 {} 0 {}}} +} -constraints \ +{eagle monoToDo defineConstant.System.Data.SQLite.INTEROP_EXTENSION_FUNCTIONS\ +file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll file_testlinq.exe\ +file_northwindEF.db} -result {0 {} 0 {DRACD OLDWO RATTC} 0 {ALFKI CACTU CHOPS\ +FOLKO GALED KOENE LILAS MAGAA MAISD OCEAN RANCH SAVEA THECR} 0 {} 0 {} 0 {} 0\ +{}}} ############################################################################### -unset -nocomplain testLinqExeFile northwindEfDbFile +unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \ + testLinqExeFile northwindEfDbFile ############################################################################### runSQLiteTestEpilogue runTestEpilogue Index: Tests/tkt-0d5b1ef362.eagle ================================================================== --- Tests/tkt-0d5b1ef362.eagle +++ Tests/tkt-0d5b1ef362.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -32,12 +32,12 @@ # else. # set x [object invoke -flags +NonPublic \ AppDomain.CurrentDomain._domainUnload.GetInvocationList Length] - package require EagleLibrary - package require EagleTest + package require Eagle.Library + package require Eagle.Test package require System.Data.SQLite.Test object load -loadtype File [file join [getBinaryDirectory] \ System.Data.SQLite.dll] Index: Tests/tkt-201128cc88.eagle ================================================================== --- Tests/tkt-201128cc88.eagle +++ Tests/tkt-201128cc88.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -34,11 +34,13 @@ namespace _Dynamic${id} { \[SQLiteFunction(Name = "Base64", FuncType = FunctionType.Scalar)\] public class Test${id} : SQLiteFunction { - public override object Invoke(object\[\] args) + public override object Invoke( + object\[\] args + ) { if (args == null) return null; if (args.Length != 1) @@ -59,10 +61,12 @@ return new ArgumentException(String.Format( "argument must be byte array, got {0}", type)); return Convert.ToBase64String((byte\[\]) arg); } + + /////////////////////////////////////////////////////////////////////// public static void Main() { SQLiteFunction.RegisterFunction(typeof(Test${id})); } Index: Tests/tkt-2c630bffa7.eagle ================================================================== --- Tests/tkt-2c630bffa7.eagle +++ Tests/tkt-2c630bffa7.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### Index: Tests/tkt-2ce0870fad.eagle ================================================================== --- Tests/tkt-2ce0870fad.eagle +++ Tests/tkt-2ce0870fad.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -46,12 +46,12 @@ set hadTestYear {[info exists ::test_year]} set hadTestConfiguration {[info exists ::test_configuration]} }] -body { set appDomainId(3) [object invoke AppDomain.CurrentDomain Id] - package require EagleLibrary - package require EagleTest + package require Eagle.Library + package require Eagle.Test package require System.Data.SQLite.Test set assembly [object load -loadtype File [file join [getBinaryDirectory] \ System.Data.SQLite.dll]] Index: Tests/tkt-343d392b51.eagle ================================================================== --- Tests/tkt-343d392b51.eagle +++ Tests/tkt-343d392b51.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -118,11 +118,11 @@ using System.Data; using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static void Main() { using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};")) @@ -224,11 +224,11 @@ using System.Data; using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static void Main() { using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};DateTimeFormat=JulianDay;")) @@ -371,11 +371,11 @@ using System.Data; using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static void Main() { using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};")) Index: Tests/tkt-448d663d11.eagle ================================================================== --- Tests/tkt-448d663d11.eagle +++ Tests/tkt-448d663d11.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -23,10 +23,11 @@ runTest {test tkt-448d663d11-1.1 {missing journal mode, new db} -body { setupDb [set fileName tkt-448d663d11-1.1.db] sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {delete}} @@ -34,14 +35,15 @@ runTest {test tkt-448d663d11-1.2 {missing journal mode, WAL db} -body { set fileName tkt-448d663d11-1.2.db file copy -force [file join $path wal.db] \ [file join [getDatabaseDirectory] $fileName] - setupDb $fileName "" "" "" "" false + setupDb $fileName "" "" "" "" "" false sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {wal}} @@ -49,14 +51,15 @@ runTest {test tkt-448d663d11-1.3 {missing journal mode, non-WAL db} -body { set fileName tkt-448d663d11-1.3.db file copy -force [file join $path nonWal.db] \ [file join [getDatabaseDirectory] $fileName] - setupDb $fileName "" "" "" "" false + setupDb $fileName "" "" "" "" "" false sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {delete}} @@ -65,10 +68,11 @@ runTest {test tkt-448d663d11-1.4 {'Default' journal mode, new db} -body { setupDb [set fileName tkt-448d663d11-1.4.db] Default sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {delete}} @@ -76,14 +80,15 @@ runTest {test tkt-448d663d11-1.5 {'Default' journal mode, WAL db} -body { set fileName tkt-448d663d11-1.5.db file copy -force [file join $path wal.db] \ [file join [getDatabaseDirectory] $fileName] - setupDb $fileName Default "" "" "" false + setupDb $fileName Default "" "" "" "" false sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {wal}} @@ -91,14 +96,15 @@ runTest {test tkt-448d663d11-1.6 {'Default' journal mode, non-WAL db} -body { set fileName tkt-448d663d11-1.6.db file copy -force [file join $path nonWal.db] \ [file join [getDatabaseDirectory] $fileName] - setupDb $fileName Default "" "" "" false + setupDb $fileName Default "" "" "" "" false sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {delete}} @@ -107,10 +113,11 @@ runTest {test tkt-448d663d11-1.7 {'Delete' journal mode, new db} -body { setupDb [set fileName tkt-448d663d11-1.7.db] Delete sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {delete}} @@ -118,14 +125,15 @@ runTest {test tkt-448d663d11-1.8 {'Delete' journal mode, WAL db} -body { set fileName tkt-448d663d11-1.8.db file copy -force [file join $path wal.db] \ [file join [getDatabaseDirectory] $fileName] - setupDb $fileName Delete "" "" "" false + setupDb $fileName Delete "" "" "" "" false sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {delete}} @@ -133,14 +141,15 @@ runTest {test tkt-448d663d11-1.9 {'Delete' journal mode, non-WAL db} -body { set fileName tkt-448d663d11-1.9.db file copy -force [file join $path nonWal.db] \ [file join [getDatabaseDirectory] $fileName] - setupDb $fileName Delete "" "" "" false + setupDb $fileName Delete "" "" "" "" false sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {delete}} @@ -149,10 +158,11 @@ runTest {test tkt-448d663d11-1.10 {'Persist' journal mode, new db} -body { setupDb [set fileName tkt-448d663d11-1.10.db] Persist sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {persist}} @@ -161,10 +171,11 @@ runTest {test tkt-448d663d11-1.11 {'Off' journal mode, new db} -body { setupDb [set fileName tkt-448d663d11-1.11.db] Off sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {off}} @@ -173,10 +184,11 @@ runTest {test tkt-448d663d11-1.12 {'Truncate' journal mode, new db} -body { setupDb [set fileName tkt-448d663d11-1.12.db] Truncate sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {truncate}} @@ -185,10 +197,11 @@ runTest {test tkt-448d663d11-1.13 {'Memory' journal mode, new db} -body { setupDb [set fileName tkt-448d663d11-1.13.db] Memory sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {memory}} @@ -197,10 +210,11 @@ runTest {test tkt-448d663d11-1.14 {'Wal' journal mode, new db} -body { setupDb [set fileName tkt-448d663d11-1.14.db] Wal sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {wal}} @@ -208,14 +222,15 @@ runTest {test tkt-448d663d11-1.15 {'Wal' journal mode, non-WAL db} -body { set fileName tkt-448d663d11-1.15.db file copy -force [file join $path nonWal.db] \ [file join [getDatabaseDirectory] $fileName] - setupDb $fileName Wal "" "" "" false + setupDb $fileName Wal "" "" "" "" false sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {wal}} @@ -223,14 +238,15 @@ runTest {test tkt-448d663d11-1.16 {'Wal' journal mode, WAL db} -body { set fileName tkt-448d663d11-1.16.db file copy -force [file join $path wal.db] \ [file join [getDatabaseDirectory] $fileName] - setupDb $fileName Wal "" "" "" false + setupDb $fileName Wal "" "" "" "" false sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {wal}} @@ -239,10 +255,11 @@ runTest {test tkt-448d663d11-1.17 {'Bad' journal mode, new db} -body { setupDb [set fileName tkt-448d663d11-1.17.db] Bad sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {delete}} @@ -250,14 +267,15 @@ runTest {test tkt-448d663d11-1.18 {'Bad' journal mode, non-WAL db} -body { set fileName tkt-448d663d11-1.18.db file copy -force [file join $path nonWal.db] \ [file join [getDatabaseDirectory] $fileName] - setupDb $fileName Bad "" "" "" false + setupDb $fileName Bad "" "" "" "" false sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {delete}} @@ -265,18 +283,19 @@ runTest {test tkt-448d663d11-1.19 {'Bad' journal mode, WAL db} -body { set fileName tkt-448d663d11-1.19.db file copy -force [file join $path wal.db] \ [file join [getDatabaseDirectory] $fileName] - setupDb $fileName Bad "" "" "" false + setupDb $fileName Bad "" "" "" "" false sql execute -execute scalar $db "PRAGMA journal_mode;" } -cleanup { cleanupDb $fileName + unset -nocomplain db fileName } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {wal}} ############################################################################### runSQLiteTestEpilogue runTestEpilogue Index: Tests/tkt-544dba0a2f.eagle ================================================================== --- Tests/tkt-544dba0a2f.eagle +++ Tests/tkt-544dba0a2f.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### Index: Tests/tkt-59edc1018b.eagle ================================================================== --- Tests/tkt-59edc1018b.eagle +++ Tests/tkt-59edc1018b.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -22,17 +22,29 @@ # # NOTE: Setup the variables that refer to the various files required by the # tests in this file. # +set systemDataSQLiteDllFile [getBuildFileName System.Data.SQLite.dll] +set systemDataSQLiteLinqDllFile [getBuildFileName System.Data.SQLite.Linq.dll] set testLinqExeFile [getBuildFileName testlinq.exe] set northwindEfDbFile [file nativename [file join [file dirname $path] \ testlinq northwindEF.db]] # # NOTE: Setup the test constraints specific to the tests in this file. # +if {![haveConstraint [appendArgs file_ \ + [file tail $systemDataSQLiteDllFile]]]} then { + checkForFile $test_channel $systemDataSQLiteDllFile +} + +if {![haveConstraint [appendArgs file_ \ + [file tail $systemDataSQLiteLinqDllFile]]]} then { + checkForFile $test_channel $systemDataSQLiteLinqDllFile +} + if {![haveConstraint [appendArgs file_ [file tail $testLinqExeFile]]]} then { checkForFile $test_channel $testLinqExeFile } if {![haveConstraint [appendArgs file_ [file tail $northwindEfDbFile]]]} then { @@ -67,17 +79,20 @@ } set result } -cleanup { unset -nocomplain code output error result value -} -constraints {eagle monoToDo file_testlinq.exe file_northwindEF.db} -result \ -{0 {} 0 {FURIB GALED GODOS LAZYK LINOD PRINI REGGC WOLZA} 0 {} 0 ERNSH 0 {} 0\ -{AROUT BSBEV CONSH EASTC NORTS SEVES} 0 {}}} +} -constraints \ +{eagle monoToDo defineConstant.System.Data.SQLite.INTEROP_EXTENSION_FUNCTIONS\ +file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll file_testlinq.exe\ +file_northwindEF.db} -result {0 {} 0 {FURIB GALED GODOS LAZYK LINOD PRINI REGGC\ +WOLZA} 0 {} 0 ERNSH 0 {} 0 {AROUT BSBEV CONSH EASTC NORTS SEVES} 0 {}}} ############################################################################### -unset -nocomplain testLinqExeFile northwindEfDbFile +unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \ + testLinqExeFile northwindEfDbFile ############################################################################### runSQLiteTestEpilogue runTestEpilogue ADDED Tests/tkt-72905c9a77.eagle Index: Tests/tkt-72905c9a77.eagle ================================================================== --- /dev/null +++ Tests/tkt-72905c9a77.eagle @@ -0,0 +1,280 @@ +############################################################################### +# +# tkt-72905c9a77.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 + +############################################################################### + +# +# NOTE: This value is needed as part of the test result; therefore, it must be +# set outside of the test setup. +# +set id [object invoke Interpreter.GetActive NextId] + +############################################################################### + +# +# NOTE: *WARNING* This test has been extremely carefully designed; however, it +# is still quite sensitive to machine timing, resource availability, etc. +# This test MAY pass even if the bug under test has not been fixed (or +# has been regressed somehow). However, due to the unpredictable nature +# of race conditions, it really is the best that can be done. This test +# will only work as intended if the version of System.Data.SQLite being +# tested is 1.0.77.0 or higher. +# +runTest {test tkt-72905c9a77-1.1 {StaticIsInitialized race condition} -setup { + set fileName tkt-72905c9a77-1.1.db +} -body { + set dataSource [file join [getDatabaseDirectory] $fileName] + + unset -nocomplain results errors + + set code [compileCSharpWith [subst { + using System; + using System.Data.SQLite; + using System.Diagnostics; + using System.IO; + using System.Reflection; + using System.Text; + using System.Threading; + + namespace _Dynamic${id} + { + public static class Test${id} + { + public static string GetTraceOutput() + { + // + // NOTE: Create a memory stream to capture all the trace output for + // this test. + // + MemoryStream memoryStream = new MemoryStream(); + + // + // NOTE: Create the trace listener using the memory stream we just + // created. + // + using (TraceListener listener = new TextWriterTraceListener( + memoryStream)) + { + // + // NOTE: Add the trace listener to the collection of active trace + // listeners (for this application domain). + // + Trace.Listeners.Add(listener); + + // + // NOTE: Attempt to lookup the type for the private SQLite3 class + // in the System.Data.SQLite assembly. We need the type in + // order to lookup the primary method used for this test (via + // reflection). This is only necessary because the method + // under test is private and cannot normally be executed from + // C# directly. If this fails, the following statement will + // throw a NullReferenceException, which is fine as that will + // cause the whole test to fail. + // + Type type = Type.GetType("System.Data.SQLite.SQLite3, " + + "System.Data.SQLite"); + + // + // NOTE: Attempt to lookup the method object for the private method + // we need for this test. If this fails, the first attempt + // to invoke the method using this variable will throw a + // NullReferenceException, which is fine as that will cause + // the whole test to fail. + // + MethodInfo methodInfo = type.GetMethod("StaticIsInitialized", + BindingFlags.Static | BindingFlags.NonPublic); + + // + // NOTE: Create the event that will be used to synchronize all the + // created threads so that they start doing their actual test + // "work" at approximately the same time. + // + using (ManualResetEvent goEvent = new ManualResetEvent(false)) + { + // + // NOTE: Create 4 threads for each processor on the machine. + // Under normal circumstances, this should give us a good + // chance of triggering the race condition being tested. + // + int count = 4 * Environment.ProcessorCount; + + // + // NOTE: Create a random number generator suitable for waiting a + // random number of milliseconds between each attempt to + // cause the race condition on a given thread. + // + Random random = new Random(); + + // + // NOTE: Create a (reusable) delegate that will contain the code + // that each created thread is to execute. + // + ThreadStart threadStart = delegate() + { + try + { + // + // NOTE: Wait forever for the "GO" signal so that all threads + // can start working at approximately the same time. + // + goEvent.WaitOne(); + + // + // NOTE: Force the SQLiteLog.StaticIsInitialized method to + // be repeatedly called on every thread right away to + // thoroughly test its locking semantics. Also, use a + // random delay, in milliseconds, between zero and the + // number of test threads squared after each attempt. + // + for (int index = 0; index < (count * count); index++) + { + methodInfo.Invoke(null, null); + Thread.Sleep(random.Next(0, (count * count))); + } + + // + // NOTE: Create and open a connection and use it to log a + // test message just to make sure that the logging + // system is initialized and in working order. + // + using (SQLiteConnection connection = new SQLiteConnection( + "Data Source=${dataSource};")) + { + connection.Open(); + connection.LogMessage(0, "TEST ${id}"); + } + } + catch (Exception e) + { + // + // NOTE: We caught an exception. Since this will impact the + // captured trace output, this will cause the test to + // fail (just as it should). + // + Trace.WriteLine(String.Format("CAUGHT: {0}", e)); + } + }; + + // + // NOTE: Create the array of thread objects. + // + Thread\[\] thread = new Thread\[count\]; + + // + // NOTE: Create each of the test threads with a suitable stack + // size. We must specify a stack size here because the + // default one for the process would be the same as the + // parent executable (the Eagle shell), which is 16MB, + // too large to be useful. + // + for (int index = 0; index < count; index++) + { + thread\[index\] = new Thread(threadStart, 1048576); + + // + // NOTE: Name each thread for a better debugging experience. + // + thread\[index\].Name = String.Format( + "[file rootname ${fileName}] #{0}", index); + } + + // + // NOTE: Force logging to be initialized now; otherwise, there is + // no way for the native SQLite library to impact the trace + // listener we are monitoring for output. + // + SQLiteLog.Initialize(); + + // + // NOTE: Start all the threads now. They should not actually do + // any of the test "work" until we signal the event. + // + for (int index = 0; index < count; index++) + thread\[index\].Start(); + + // + // NOTE: Send the signal that all threads should start doing + // their test "work" now. + // + goEvent.Set(); /* GO */ + + // + // NOTE: Wait forever for each thread to finish its test "work" + // and then die. + // + for (int index = 0; index < count; index++) + thread\[index\].Join(); + } + + // + // NOTE: *REQUIRED* Force all the trace listeners to be flushed to + // disk now so that we do not lose any output. Without this + // method call, loss of trace output was observed. + // + Trace.Flush(); + + // + // NOTE: The trace listener used by this test can be removed now + // as all the trace output should have been flushed to the + // memory stream now. + // + Trace.Listeners.Remove(listener); + + // + // NOTE: Return a string containing all the trace output we saw + // (from all threads) during the above test code. + // + return Encoding.UTF8.GetString(memoryStream.ToArray()); + } + } + + /////////////////////////////////////////////////////////////////////// + + public static void Main() + { + // do nothing. + } + } + } + }] true true true results errors System.Data.SQLite.dll] + + list $code $results \ + [expr {[info exists errors] ? $errors : ""}] \ + [expr {$code eq "Ok" ? [catch { + object invoke _Dynamic${id}.Test${id} GetTraceOutput + } result] : [set result ""]}] [string map [list \r\n \n] $result] +} -cleanup { + cleanupDb $fileName + + unset -nocomplain result code results errors dataSource fileName +} -constraints {eagle configuration.Release monoBug28 command.sql compile.DATA\ +SQLite System.Data.SQLite} -match regexp -result [appendArgs "^Ok\ +System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{" [string repeat \ +"SQLite message \\(0\\): TEST $id +" [expr {4 * [info processors]}]] "\\}\$"]} + +############################################################################### + +unset -nocomplain id + +############################################################################### + +runSQLiteTestEpilogue +runTestEpilogue Index: Tests/tkt-7e3fa93744.eagle ================================================================== --- Tests/tkt-7e3fa93744.eagle +++ Tests/tkt-7e3fa93744.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -90,11 +90,11 @@ using System.Data; using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static int Main() { using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};")) Index: Tests/tkt-84718e79fa.eagle ================================================================== --- Tests/tkt-84718e79fa.eagle +++ Tests/tkt-84718e79fa.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### Index: Tests/tkt-8554170e09.eagle ================================================================== --- Tests/tkt-8554170e09.eagle +++ Tests/tkt-8554170e09.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### Index: Tests/tkt-8b7d179c3c.eagle ================================================================== --- Tests/tkt-8b7d179c3c.eagle +++ Tests/tkt-8b7d179c3c.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -22,17 +22,29 @@ # # NOTE: Setup the variables that refer to the various files required by the # tests in this file. # +set systemDataSQLiteDllFile [getBuildFileName System.Data.SQLite.dll] +set systemDataSQLiteLinqDllFile [getBuildFileName System.Data.SQLite.Linq.dll] set testLinqExeFile [getBuildFileName testlinq.exe] set northwindEfDbFile [file nativename [file join [file dirname $path] \ testlinq northwindEF.db]] # # NOTE: Setup the test constraints specific to the tests in this file. # +if {![haveConstraint [appendArgs file_ \ + [file tail $systemDataSQLiteDllFile]]]} then { + checkForFile $test_channel $systemDataSQLiteDllFile +} + +if {![haveConstraint [appendArgs file_ \ + [file tail $systemDataSQLiteLinqDllFile]]]} then { + checkForFile $test_channel $systemDataSQLiteLinqDllFile +} + if {![haveConstraint [appendArgs file_ [file tail $testLinqExeFile]]]} then { checkForFile $test_channel $testLinqExeFile } if {![haveConstraint [appendArgs file_ [file tail $northwindEfDbFile]]]} then { @@ -67,30 +79,32 @@ } set result } -cleanup { unset -nocomplain code output error result pageSize -} -constraints {eagle monoToDo file_testlinq.exe file_northwindEF.db} -result \ -{0 {} 0 {DRACD RATTC OLDWO GALED LILAS MAGAA ALFKI CHOPS SAVEA KOENE MAISD\ -FOLKO CACTU OCEAN RANCH THECR GOURL GROSR SUPRD HUNGO ISLAT QUICK HUNGC GREAL\ -LEHMS RICSU ERNSH WILMK LINOD TRAIH SIMOB OTTIK SPLIR MORGK FOLIG FURIB PRINI\ -AROUT BSBEV CONSH EASTC NORTS SEVES BERGS VICTE BOLID FISSA ROMEY BLAUS BONAP\ -MEREP ANATR ANTON CENTC PERIC TORTU FRANK TOMSP DUMON FRANR WARTH PARIS SPECD\ -LONEP THEBI REGGC VINET WELLI HANAR QUEDE RICAR PICCO HILAA LETSS COMMI FAMIA\ -QUEEN TRADH WHITC GODOS SANTG BLONP WANDK FRANS LAMAI BOTTM LAUGB LACOR LAZYK\ -WOLZA VAFFE} 0 {DRACD RATTC OLDWO GALED LILAS MAGAA ALFKI CHOPS SAVEA KOENE\ +} -constraints {eagle monoToDo file_System.Data.SQLite.dll\ +file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db} \ +-result {0 {} 0 {DRACD RATTC OLDWO GALED LILAS MAGAA ALFKI CHOPS SAVEA KOENE\ MAISD FOLKO CACTU OCEAN RANCH THECR GOURL GROSR SUPRD HUNGO ISLAT QUICK HUNGC\ GREAL LEHMS RICSU ERNSH WILMK LINOD TRAIH SIMOB OTTIK SPLIR MORGK FOLIG FURIB\ PRINI AROUT BSBEV CONSH EASTC NORTS SEVES BERGS VICTE BOLID FISSA ROMEY BLAUS\ BONAP MEREP ANATR ANTON CENTC PERIC TORTU FRANK TOMSP DUMON FRANR WARTH PARIS\ SPECD LONEP THEBI REGGC VINET WELLI HANAR QUEDE RICAR PICCO HILAA LETSS COMMI\ FAMIA QUEEN TRADH WHITC GODOS SANTG BLONP WANDK FRANS LAMAI BOTTM LAUGB LACOR\ -LAZYK WOLZA VAFFE}}} +LAZYK WOLZA VAFFE} 0 {DRACD RATTC OLDWO GALED LILAS MAGAA ALFKI CHOPS SAVEA\ +KOENE MAISD FOLKO CACTU OCEAN RANCH THECR GOURL GROSR SUPRD HUNGO ISLAT QUICK\ +HUNGC GREAL LEHMS RICSU ERNSH WILMK LINOD TRAIH SIMOB OTTIK SPLIR MORGK FOLIG\ +FURIB PRINI AROUT BSBEV CONSH EASTC NORTS SEVES BERGS VICTE BOLID FISSA ROMEY\ +BLAUS BONAP MEREP ANATR ANTON CENTC PERIC TORTU FRANK TOMSP DUMON FRANR WARTH\ +PARIS SPECD LONEP THEBI REGGC VINET WELLI HANAR QUEDE RICAR PICCO HILAA LETSS\ +COMMI FAMIA QUEEN TRADH WHITC GODOS SANTG BLONP WANDK FRANS LAMAI BOTTM LAUGB\ +LACOR LAZYK WOLZA VAFFE}}} ############################################################################### -unset -nocomplain testLinqExeFile northwindEfDbFile +unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \ + testLinqExeFile northwindEfDbFile ############################################################################### runSQLiteTestEpilogue runTestEpilogue ADDED Tests/tkt-996d13cd87.eagle Index: Tests/tkt-996d13cd87.eagle ================================================================== --- /dev/null +++ Tests/tkt-996d13cd87.eagle @@ -0,0 +1,295 @@ +############################################################################### +# +# tkt-996d13cd87.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 + +############################################################################### + +for {set i 1} {$i < 11} {incr i} { + set pooling [expr {$i % 2 == 0 ? True : False}] + + runTest {test [appendArgs tkt-996d13cd87-1. $i] {SQLiteConnection stress} \ + -setup { + set fileName [appendArgs tkt-996d13cd87-1. $i .db] + + if {[catch { + object invoke -flags +NonPublic \ + System.Data.SQLite.SQLiteConnectionPool _poolOpened 0 + + object invoke -flags +NonPublic \ + System.Data.SQLite.SQLiteConnectionPool _poolClosed 0 + }] == 0} then { + set havePoolCounts true + } else { + set havePoolCounts false + + tputs $test_channel [appendArgs \ + "==== WARNING: connection pool counts are not available\n"] + } + + proc getPoolCounts {} { + # + # NOTE: If we have the ability to determine the opened/closed pool + # counts, fetch them now; otherwise, just set them to zero. + # + if {$::havePoolCounts} then { + set ::poolCounts(opened) [object invoke -flags +NonPublic \ + System.Data.SQLite.SQLiteConnectionPool _poolOpened] + + set ::poolCounts(closed) [object invoke -flags +NonPublic \ + System.Data.SQLite.SQLiteConnectionPool _poolClosed] + + tputs $::test_channel [appendArgs \ + "---- opened " $::poolCounts(opened) " connections from the pool\n"] + + tputs $::test_channel [appendArgs \ + "---- closed " $::poolCounts(closed) " connections to the pool\n"] + } else { + set ::poolCounts(opened) 0 + set ::poolCounts(closed) 0 + } + + return "" + } + } -body { + set id [object invoke Interpreter.GetActive NextId] + set dataSource [file join [getDatabaseDirectory] $fileName] + + set sql { \ + CREATE TABLE t1(x TEXT); \ + INSERT INTO t1 (x) VALUES(RANDOMBLOB(1000)); \ + } + + unset -nocomplain results errors + + set code [compileCSharpWith [subst { + using System; + using System.Data.SQLite; + using System.Diagnostics; + using System.Threading; + + namespace _Dynamic${id} + { + public static class Test${id} + { + public static int Main() + { + // + // NOTE: This is the total number of exceptions caught by all the + // test threads. + // + int errors = 0; + + // + // NOTE: This is the total number of test threads to create. + // + int count = 100; + + // + // NOTE: This is the total number of times we should force a full + // garbage collection. + // + int gcCount = 2; + + // + // NOTE: Create a random number generator suitable for waiting a + // random number of milliseconds between each attempt to + // cause the race condition on a given thread. + // + Random random = new Random(); + + // + // NOTE: Create the event that will be used to synchronize all the + // created threads so that they start doing their actual test + // "work" at approximately the same time. + // + using (ManualResetEvent goEvent = new ManualResetEvent(false)) + { + // + // NOTE: Create a (reusable) delegate that will contain the code + // that half the created threads are to execute. This code + // will repeatedly create, open, and close a single database + // connection with (or without) pooling enabled. + // + ThreadStart threadStart1 = delegate() + { + try + { + // + // NOTE: Wait forever for the "GO" signal so that all threads + // can start working at approximately the same time. + // + goEvent.WaitOne(); + + // + // NOTE: Repeatedly try to create, open, and close a pooled + // database connection and then wait a random number of + // milliseconds before doing it again. + // + Thread.Sleep(random.Next(0, 500)); + + SQLiteConnection connection = new SQLiteConnection( + "Data Source=${dataSource};Pooling=${pooling};"); + + connection.Open(); + + using (SQLiteCommand command = new SQLiteCommand("${sql}", + connection)) + { + command.ExecuteNonQuery(); + } + + connection.Close(); + connection = null; + } + catch (Exception e) + { + Interlocked.Increment(ref errors); + Trace.WriteLine(e); + } + }; + + // + // NOTE: Create a (reusable) delegate that will contain the code + // that half the created threads are to execute. This code + // will repeatedly force a full garbage collection. + // + ThreadStart threadStart2 = delegate() + { + try + { + // + // NOTE: Wait forever for the "GO" signal so that all threads + // can start working at approximately the same time. + // + goEvent.WaitOne(); + + // + // NOTE: Wait a random number of milliseconds before forcing + // a full garbage collection. + // + for (int index = 0; index < gcCount; index++) + { + Thread.Sleep(random.Next(0, 1000)); + GC.GetTotalMemory(true); + } + } + catch (Exception e) + { + Interlocked.Increment(ref errors); + Trace.WriteLine(e); + } + }; + + // + // NOTE: Create the array of thread objects. + // + Thread\[\] thread = new Thread\[count\]; + + // + // NOTE: Create each of the test threads with a suitable stack + // size. We must specify a stack size here because the + // default one for the process would be the same as the + // parent executable (the Eagle shell), which is 16MB, + // too large to be useful. + // + for (int index = 0; index < count; index++) + { + // + // NOTE: Figure out what kind of thread to create (i.e. one + // that uses a connection or one that calls the GC). + // + ThreadStart threadStart; + + if (index == 0) + threadStart = threadStart2; + else + threadStart = threadStart1; + + thread\[index\] = new Thread(threadStart, 1048576); + + // + // NOTE: Name each thread for a better debugging experience. + // + thread\[index\].Name = String.Format( + "[file rootname ${fileName}] #{0}", index); + } + + // + // NOTE: Start all the threads now. They should not actually do + // any of the test "work" until we signal the event. + // + for (int index = 0; index < count; index++) + thread\[index\].Start(); + + // + // NOTE: Send the signal that all threads should start doing + // their test "work" now. + // + goEvent.Set(); /* GO */ + + // + // NOTE: Wait forever for each thread to finish its test "work" + // and then die. + // + for (int index = 0; index < count; index++) + thread\[index\].Join(); + } + + // + // NOTE: Return the total number of exceptions caught by the test + // threads. + // + return errors; + } + } + } + }] true true true results errors System.Data.SQLite.dll] + + list $code $results \ + [expr {[info exists errors] ? $errors : ""}] \ + [expr {$code eq "Ok" ? [catch { + object invoke _Dynamic${id}.Test${id} Main + } result] : [set result ""]}] $result [getPoolCounts] \ + [expr {$havePoolCounts ? $pooling ? $poolCounts(opened) > 0 : \ + $poolCounts(opened) == 0} : True] \ + [expr {$havePoolCounts ? $pooling ? $poolCounts(closed) > 0 : \ + $poolCounts(closed) == 0} : True] + } -cleanup { + object invoke System.Data.SQLite.SQLiteConnection ClearAllPools + object invoke GC GetTotalMemory true + + cleanupDb $fileName + + unset -nocomplain result results errors code sql dataSource id db \ + poolCounts havePoolCounts fileName + + rename getPoolCounts "" + } -constraints {eagle monoBug28 command.sql compile.DATA\ +SQLite System.Data.SQLite} -match regexp -result {^Ok\ +System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \d+ \{\} True True$}} +} + +############################################################################### + +unset -nocomplain pooling i + +############################################################################### + +runSQLiteTestEpilogue +runTestEpilogue Index: Tests/tkt-ac47dd230a.eagle ================================================================== --- Tests/tkt-ac47dd230a.eagle +++ Tests/tkt-ac47dd230a.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -25,11 +25,11 @@ set appDomain($i) [object invoke AppDomain CreateDomain \ tkt-ac47dd230a-1.1.$i] set result null set interpreterHelper($i) [object invoke -alias InterpreterHelper \ - Create $appDomain($i) null Default null null null result] + Create $appDomain($i) null Default Default null null null result] if {[string length $interpreterHelper($i)] == 0} then { error [object invoke $result ToString] } @@ -46,12 +46,12 @@ set results [list] for {set i 1} {$i < 3} {incr i} { set result null set code [$interpreter($i) EvaluateScript { - package require EagleLibrary - package require EagleTest + package require Eagle.Library + package require Eagle.Test package require System.Data.SQLite.Test object load -loadtype File [file join [getBinaryDirectory] \ System.Data.SQLite.dll] @@ -65,11 +65,13 @@ set results } -cleanup { unset -nocomplain results code result interpreter interpreterHelper for {set i 1} {$i < 3} {incr i} { - object invoke AppDomain Unload $appDomain($i) + if {[info exists appDomain($i)]} then { + object invoke AppDomain Unload $appDomain($i) + } } unset -nocomplain appDomain i } -constraints {eagle monoBug28 command.sql compile.DATA\ compile.ISOLATED_INTERPRETERS SQLite System.Data.SQLite} -result {Ok 0 Ok 0}} Index: Tests/tkt-b4a7ddc83f.eagle ================================================================== --- Tests/tkt-b4a7ddc83f.eagle +++ Tests/tkt-b4a7ddc83f.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -37,12 +37,12 @@ set appDomainId(1) {[object invoke AppDomain.CurrentDomain Id]} set fileName {[appendArgs tkt-b4a7ddc83f-1. $i .db]} }] -body { set appDomainId(2) [object invoke AppDomain.CurrentDomain Id] - package require EagleLibrary - package require EagleTest + package require Eagle.Library + package require Eagle.Test package require System.Data.SQLite.Test object load -loadtype File [file join [getBinaryDirectory] \ System.Data.SQLite.dll] @@ -50,10 +50,11 @@ list $appDomainId(1) $appDomainId(2) \ [expr {$appDomainId(1) != $appDomainId(2)}] [setupDb $fileName] } -cleanup { cleanupDb $fileName + unset -nocomplain appDomainId db fileName } -constraints {eagle monoBug28 command.sql compile.DATA\ compile.ISOLATED_INTERPRETERS SQLite System.Data.SQLite} -isolationLevel \ AppDomain -match regexp -result {^\d+ \d+ True\ System#Data#SQLite#SQLiteConnection#\d+$}} Index: Tests/tkt-bb4b04d457.eagle ================================================================== --- Tests/tkt-bb4b04d457.eagle +++ Tests/tkt-bb4b04d457.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### Index: Tests/tkt-ccfa69fc32.eagle ================================================================== --- Tests/tkt-ccfa69fc32.eagle +++ Tests/tkt-ccfa69fc32.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -22,17 +22,29 @@ # # NOTE: Setup the variables that refer to the various files required by the # tests in this file. # +set systemDataSQLiteDllFile [getBuildFileName System.Data.SQLite.dll] +set systemDataSQLiteLinqDllFile [getBuildFileName System.Data.SQLite.Linq.dll] set testLinqExeFile [getBuildFileName testlinq.exe] set northwindEfDbFile [file nativename [file join [file dirname $path] \ testlinq northwindEF.db]] # # NOTE: Setup the test constraints specific to the tests in this file. # +if {![haveConstraint [appendArgs file_ \ + [file tail $systemDataSQLiteDllFile]]]} then { + checkForFile $test_channel $systemDataSQLiteDllFile +} + +if {![haveConstraint [appendArgs file_ \ + [file tail $systemDataSQLiteLinqDllFile]]]} then { + checkForFile $test_channel $systemDataSQLiteLinqDllFile +} + if {![haveConstraint [appendArgs file_ [file tail $testLinqExeFile]]]} then { checkForFile $test_channel $testLinqExeFile } if {![haveConstraint [appendArgs file_ [file tail $northwindEfDbFile]]]} then { @@ -67,19 +79,21 @@ } set result } -cleanup { unset -nocomplain code output error result add -} -constraints {eagle monoToDo file_testlinq.exe file_northwindEF.db} -match \ +} -constraints {eagle monoToDo file_System.Data.SQLite.dll\ +file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db} -match \ glob -result {0 {1581 1730 1833 2116 2139} 0 {System.Data.UpdateException: *\ ---> System.Data.SQLite.SQLiteException: Abort due to constraint violation PRIMARY KEY must be unique *} 0 {1 2 3 4 5 6 7 8 9 10 1576 1577 1578 1579 1580 1581 1730 1833 2116 2139}}} ############################################################################### -unset -nocomplain testLinqExeFile northwindEfDbFile +unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \ + testLinqExeFile northwindEfDbFile ############################################################################### runSQLiteTestEpilogue runTestEpilogue Index: Tests/tkt-e1b2e0f769.eagle ================================================================== --- Tests/tkt-e1b2e0f769.eagle +++ Tests/tkt-e1b2e0f769.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -29,11 +29,11 @@ foreach x [list 1 2 3] { sql execute $db "INSERT INTO t1 (x) VALUES($x);" } set result1 [list] - set dataSource [file join [getDatabaseDirectory] tkt-e1b2e0f769-1.1.db] + set dataSource [file join [getDatabaseDirectory] $fileName] foreach table [list t1 t2] { set id [object invoke Interpreter.GetActive NextId] set sql "SELECT x FROM $table ORDER BY x;" @@ -43,17 +43,20 @@ using System.Collections.Generic; using System.Data.SQLite; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { - public static List Tkt_e1b2e0f769(SQLiteConnection connection) + public static List Tkt_e1b2e0f769( + SQLiteConnection connection + ) { List result = new List(); - using (SQLiteTransaction transaction = connection.BeginTransaction()) + using (SQLiteTransaction transaction = + connection.BeginTransaction()) { using (SQLiteCommand command = connection.CreateCommand()) { command.CommandText = "${sql}"; @@ -88,10 +91,12 @@ } connection.Close(); return result; } + + ///////////////////////////////////////////////////////////////////// public static int Main() { using (SQLiteConnection connection = new SQLiteConnection( "Data Source=${dataSource};")) Index: Tests/tkt-e30b820248.eagle ================================================================== --- Tests/tkt-e30b820248.eagle +++ Tests/tkt-e30b820248.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -36,11 +36,11 @@ INSERT INTO t1 (id1) VALUES (1); \ INSERT INTO t1 (id1) VALUES (2); \ INSERT INTO t1 (id1) VALUES (?); \ INSERT INTO t1 (id1) VALUES (?); \ INSERT INTO t1 (id1) VALUES (?); \ - SELECT * FROM t1 ORDER BY id1; \ + SELECT id1 FROM t1 ORDER BY id1; \ } unset -nocomplain results errors set code [compileCSharpWith [subst { @@ -48,11 +48,11 @@ using System.Diagnostics; using System.IO; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { public static void Main() { using (TraceListener listener = new TextWriterTraceListener( new FileStream("${test_log}", FileMode.Append, @@ -105,11 +105,11 @@ } result] : [set result ""]}] $result \ [reportSQLiteResources $test_channel true] } -cleanup { cleanupDb $fileName - unset -nocomplain result code results errors sql dataSource id db fileName + unset -nocomplain result code results errors sql name dataSource id fileName } -constraints \ {eagle logFile monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \ -match regexp -result [appendArgs "^Ok\ System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{\\} " $memory_used \$]} @@ -132,11 +132,11 @@ INSERT INTO t1 (id1) VALUES (1); \ INSERT INTO t1 (id1) VALUES (2); \ INSERT INTO t1 (id1) VALUES (3); \ INSERT INTO t1 (id1) VALUES (4); \ INSERT INTO t1 (id1) VALUES (5); \ - SELECT * FROM t1 ORDER BY id1; \ + SELECT id1 FROM t1 ORDER BY id1; \ } unset -nocomplain results errors set code [compileCSharpWith [subst { @@ -145,11 +145,11 @@ using System.Diagnostics; using System.IO; namespace _Dynamic${id} { - public class Test${id} + public static class Test${id} { #region Private Static Data private static SQLiteConnection connection; #endregion @@ -163,30 +163,36 @@ connection.LogMessage(0, "Connection opened."); } ///////////////////////////////////////////////////////////////////// - public static SQLiteCommand CreateCommand(string sql) + public static SQLiteCommand CreateCommand( + string sql + ) { SQLiteCommand command = connection.CreateCommand(); command.CommandText = sql; connection.LogMessage(0, "Command created."); return command; } ///////////////////////////////////////////////////////////////////// - public static SQLiteDataReader ExecuteReader(SQLiteCommand command) + public static SQLiteDataReader ExecuteReader( + SQLiteCommand command + ) { SQLiteDataReader dataReader = command.ExecuteReader(); connection.LogMessage(0, "Command executed."); return dataReader; } ///////////////////////////////////////////////////////////////////// - public static SQLiteDataReader ExecuteReader(string sql) + public static SQLiteDataReader ExecuteReader( + string sql + ) { SQLiteCommand command = CreateCommand(sql); SQLiteDataReader dataReader = command.ExecuteReader(); connection.LogMessage(0, "Command executed."); return dataReader; @@ -252,11 +258,11 @@ } result] : [set result ""]}] $result \ [reportSQLiteResources $test_channel true] } -cleanup { cleanupDb $fileName - unset -nocomplain result code results errors sql name dataSource id db \ + unset -nocomplain result code results errors sql name dataSource id \ fileName } -constraints {eagle logFile monoBug28 command.sql compile.DATA SQLite\ System.Data.SQLite} -match regexp -result [appendArgs "^Ok\ System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{\\} " $memory_used \$]} } Index: Tests/version.eagle ================================================================== --- Tests/version.eagle +++ Tests/version.eagle @@ -6,12 +6,12 @@ # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle -package require EagleLibrary -package require EagleTest +package require Eagle.Library +package require Eagle.Test runTestPrologue ############################################################################### @@ -27,11 +27,11 @@ # numbers must be manually kept synchronized with the version numbers for # the source code files, the built binaries, and the release packages. # set version(major) 1 set version(minor) 0 -set version(build) 78; # NOTE: Incremented with each release. +set version(build) 81; # NOTE: Incremented with each release. set version(revision) 0 ############################################################################### # ********************* END VOLATILE VERSION INFORMATION ********************** ############################################################################### @@ -154,10 +154,15 @@ $version(full)] \"\\)] \ [appendArgs AssemblyVersion\\(\" [string map [list . \\.] \ $version(full)] \"\\)] \ [appendArgs AssemblyFileVersion\\(\" [string map [list . \\.] \ $version(full)] \"\\)] \ + [appendArgs [string map [list . \\.] \ + $version(full)] ] \ + [appendArgs Value=\" [format %03d $version(build)] \"] \ + [appendArgs Value=\" [string map [list . \\.] $version(full)] \"] \ + [appendArgs Value=\" [string map [list . ,] $version(full)] \"] \ [appendArgs Value=\" [format %03d $version(build)] \"] \ [appendArgs Value=\" [string map [list . \\.] $version(full)] \"] \ [appendArgs Value=\" [string map [list . ,] $version(full)] \"] \ [appendArgs [format %03d $version(build)] \ ] \ @@ -206,16 +211,20 @@ [file join Doc Extra welcome.html] \ [file join Membership Properties AssemblyInfo.cs] \ [file join Membership Properties AssemblyInfo.cs] \ [file join SQLite.Designer AssemblyInfo.cs] \ [file join SQLite.Designer AssemblyInfo.cs] \ - [file join SQLite.Interop props SQLite.Interop.vsprops] \ - [file join SQLite.Interop props SQLite.Interop.vsprops] \ - [file join SQLite.Interop props SQLite.Interop.vsprops] \ - [file join SQLite.Interop props SQLite.Interop.props] \ - [file join SQLite.Interop props SQLite.Interop.props] \ - [file join SQLite.Interop props SQLite.Interop.props] \ + [file join SQLite.Designer source.extension.vsixmanifest] \ + [file join SQLite.Interop props SQLite.Interop.2005.vsprops] \ + [file join SQLite.Interop props SQLite.Interop.2005.vsprops] \ + [file join SQLite.Interop props SQLite.Interop.2005.vsprops] \ + [file join SQLite.Interop props SQLite.Interop.2008.vsprops] \ + [file join SQLite.Interop props SQLite.Interop.2008.vsprops] \ + [file join SQLite.Interop props SQLite.Interop.2008.vsprops] \ + [file join SQLite.Interop props SQLite.Interop.2010.props] \ + [file join SQLite.Interop props SQLite.Interop.2010.props] \ + [file join SQLite.Interop props SQLite.Interop.2010.props] \ [file join SQLite.Interop src win interop.h] \ [file join System.Data.SQLite AssemblyInfo.cs] \ [file join System.Data.SQLite AssemblyInfo.cs] \ [file join System.Data.SQLite SQLite3.cs] \ [file join System.Data.SQLite UnsafeNativeMethods.cs] \ Index: exclude_bin.txt ================================================================== --- exclude_bin.txt +++ exclude_bin.txt @@ -1,5 +1,6 @@ +*.done *.exp *.lib *.map *EnvDTE.* *Microsoft.* Index: readme.htm ================================================================== --- readme.htm +++ readme.htm @@ -3,12 +3,12 @@ ADO.NET SQLite Data Provider
    -Version 1.0.78.0 January XX, 2012
    -Using SQLite 3.7.10 [ebd01a8def]
    +Version 1.0.81.0 June XX, 2012 (release scheduled)
    +Using SQLite 3.7.11
    Originally written by Robert Simpson
    Released to the public domain, use at your own risk!
    Official provider website: http://system.data.sqlite.org/
    Legacy versions: http://sqlite.phxsoftware.com/

    @@ -144,11 +144,11 @@ <configuration> <system.data> <DbProviderFactories> <remove invariant="System.Data.SQLite" /> <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" - type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.78.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /> + type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.81.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /> </DbProviderFactories> </system.data> </configuration>

    @@ -185,15 +185,69 @@

    Version History

    - 1.0.78.0 - January XX, 2012 + 1.0.81.0 - June XX, 2012 +

    +
      +
    • Support compiling the interop assembly without support for the custom extension functions and the CryptoAPI based codec.
    • +
    • Add DefineConstants property to the SQLiteConnection class to return the list of define constants used when compiling the core managed assembly.
    • +
    • Add release archive verification tool to the release automation.
    • +
    • Fix subtle race condition between threads fetching connection handles from the connection pool any garbage collection (GC) threads that may be running. Fix for [996d13cd87].
    • +
    • Add missing call to SetTimeout in the SQLite3_UTF16.Open method.
    • +
    • Add checks to prevent the SQLiteConnectionPool.Remove method from returning any connection handles that are closed or invalid.
    • +
    • Modify static SQLiteBase helper methods to prevent them from passing IntPtr.Zero to the SQLite native library.
    • +
    • Remove static locks from the static helper methods in the SQLiteBase class, replacing them with a lock on the connection handle instance being operated upon.
    • +
    • Revise CriticalHandle derived classes to make them more thread-safe.
    • +
    • Add connection pool related diagnostic messages when compiled with the DEBUG define constant.
    • +
    • Add PoolCount property to the SQLiteConnection class to return the number of pool entries for the file name associated with the connection.
    • +
    • Rename internal SQLiteLastError methods to GetLastError.
    • +
    • Add assembly file test constraints to all tests that execute the "test.exe" or "testlinq.exe" files.
    • +
    +

    + 1.0.80.0 - April 1, 2012 +

    +
      +
    • Updated to SQLite 3.7.11.
    • +
    • In the SQLiteFunction class, when calling user-provided methods from a delegate called by native code, avoid throwing exceptions, optionally tracing the caught exceptions. Fix for [8a426d12eb].
    • +
    • Add Visual Studio 2005 support to all the applicable solution/project files, their associated supporting files, and the test suite.
    • +
    • Add Visual Studio 2005 support to the redesigned designer support installer.
    • +
    • Add experimental support for "pre-loading" the native SQLite library based on the processor architecture of the current process. This feature is now enabled by default at compile-time.
    • +
    • Add support for the native SQLite Online Backup API. Fix for [c71846ed57].
    • +
    • Acquire and hold a static data lock while checking if the native SQLite library has been initialized to prevent a subtle race condition that can result in superfluous error messages. Fix for [72905c9a77].
    • +
    • Support tracing of all parameter binding activity and use the connection flags to control what is traced.
    • +
    • When converting a DateTime instance of an "Unspecified" kind to a string, use the same kind as the connection, if available.
    • +
    • Add overload of the SQLiteDataReader.GetValues method that returns a NameValueCollection.
    • +
    • Add static ToUnixEpoch method to the SQLiteConvert class to convert a DateTime value to the number of whole seconds since the Unix epoch.
    • +
    • In the implicit conversion operators (to IntPtr) for both the SQLiteConnectionHandle and SQLiteStatementHandle classes, return IntPtr.Zero if the instance being converted is null.
    • +
    • Write warning message to the active trace listeners (for the Debug build configuration only) if a column type or type name cannot be mapped properly. See [4bbf851fa5].
    • +
    • When tracing SQL statements to be prepared, bypass the internal length limit of the sqlite3_log function by using the SQLiteLog class directly instead. Also, detect null and/or empty strings and emit a special message in that case.
    • +
    • For the setup, the Visual Studio task should only be initially checked if the GAC task is available and vice-versa.
    • +
    • Improve compatibility with custom command processors by using __ECHO instead of _ECHO in batch tools.
    • +
    • Add OpenAndReturn method to the SQLiteConnection class to open a connection and return it.
    • +
    • Add missing CheckDisposed calls to the SQLiteConnection class.
    • +
    • Add missing throw statement to the SQLiteConnection class.
    • +
    • Make sure the interop project uses /fp:precise for Windows CE.
    • +
    • Regenerate package load key to support loading the designer package into Visual Studio 2008 without having the matching SDK installed.
    • +
    • Modify transaction object disposal so that it can never cause an exception to be thrown.
    • +
    +

    + 1.0.79.0 - January 28, 2012 +

    +
      +
    • Use the WoW64 registry keys when installing the VS designer components on 64-bit Windows. Fix for [d8491abd0b].
    • +
    • Correct resource name used by the LINQ assembly to locate several key string resources. Fix for [fbebb30da9].
    • +
    +

    + 1.0.78.0 - January 27, 2012

    • Updated to SQLite 3.7.10.
    • Redesign the VS designer support installer and integrate it into the setup packages.
    • +
    • When emitting SQL for foreign keys in the VS designer, be sure to take all returned schema rows into account. Remainder of fix for [b226147b37].
    • +
    • Add Flags connection string property to control extra behavioral flags for the connection.
    • Refactor all IDisposable implementations to conform to best practices, potentially eliminating leaks in certain circumstances.
    • Even more enhancements to the build and test automation.
    • Support parameter binding to more primitive types, including unsigned integer types.
    • Recognize the TIMESTAMP column data type as the DateTime type. Fix for [bb4b04d457].
    • Prevent logging superfluous messages having to do with library initialization checking. Fix for [3fc172d1be].
    • Index: test/AssemblyInfo.cs ================================================================== --- test/AssemblyInfo.cs +++ test/AssemblyInfo.cs @@ -36,7 +36,7 @@ // Major Version // Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("1.0.78.0")] -[assembly: AssemblyFileVersion("1.0.78.0")] +[assembly: AssemblyVersion("1.0.81.0")] +[assembly: AssemblyFileVersion("1.0.81.0")] Index: test/TestCases.cs ================================================================== --- test/TestCases.cs +++ test/TestCases.cs @@ -77,10 +77,11 @@ { if (_fact.GetType().Name.IndexOf("SQLite", StringComparison.OrdinalIgnoreCase) == -1) throw new InconclusiveException("Not a SQLite database"); } +#if INTEROP_CODEC /// /// Tests changing password on an encrypted database. /// [Test] internal void ChangePasswordTest() @@ -145,10 +146,11 @@ cnn.Open(); cnn.Close(); } } +#endif [Test(Sequence=1)] internal string VersionTest() { CheckSQLite(); @@ -217,10 +219,11 @@ reader.Read(); } } } +#if INTEROP_EXTENSION_FUNCTIONS [Test(Sequence = 8)] internal void FunctionWithCollation() { CheckSQLite(); using (DbCommand cmd = _cnn.CreateCommand()) @@ -232,10 +235,11 @@ if (reader.GetInt64(0) != reader.GetInt64(2) || reader.GetInt64(1) != 0 || reader.GetInt64(0) != 4) throw new Exception("CharIndex returned wrong results!"); } } } +#endif [Test(Sequence = 9)] internal void FunctionWithCollation2() { CheckSQLite(); @@ -1198,10 +1202,14 @@ { adp.SelectCommand = cmd; builder.DataAdapter = adp; builder.ConflictOption = ConflictOption.OverwriteChanges; + // + // NOTE: *MONO* This test fails on all recent versions of Mono (e.g. + // 2.10, 2.11) for reasons that are presently unknown. + // using (DbCommand updatecmd = builder.GetUpdateCommand()) { if (updatecmd.Parameters.Count != 4) throw new Exception("Wrong number of parameters in update command!"); } Index: test/app.config ================================================================== --- test/app.config +++ test/app.config @@ -1,8 +1,8 @@ - + ADDED test/test.2005.csproj Index: test/test.2005.csproj ================================================================== --- /dev/null +++ test/test.2005.csproj @@ -0,0 +1,93 @@ + + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {E27B1B1E-19C0-45E8-AA74-B6E1C041A130} + Properties + Exe + test + test + $(MSBuildProjectDirectory)\.. + true + 2005 + + + + $(BinaryOutputPath) + + + true + full + false + DEBUG;TRACE + prompt + + + pdbonly + true + TRACE + prompt + + + + {AC139952-261A-4463-B6FA-AEBC25283A66} + System.Data.SQLite.2005 + False + + + + + + + + + + + + + + + True + True + Resources.resx + + + + Form + + + TestCasesDialog.cs + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + TestCasesDialog.cs + + + + + + + + Index: testce/AssemblyInfo.cs ================================================================== --- testce/AssemblyInfo.cs +++ testce/AssemblyInfo.cs @@ -36,8 +36,8 @@ // Major Version // Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("1.0.78.0")] -// [assembly: AssemblyFileVersion("1.0.78.0")] +[assembly: AssemblyVersion("1.0.81.0")] +// [assembly: AssemblyFileVersion("1.0.81.0")] ADDED testce/testce.2005.csproj Index: testce/testce.2005.csproj ================================================================== --- /dev/null +++ testce/testce.2005.csproj @@ -0,0 +1,110 @@ + + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {B86CE504-C4E4-496F-A0F0-E613BCFD3DF7} + WinExe + Properties + test + testce + {4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + WindowsCE + E2BECB1F-8C8C-41ba-B736-9BE7D946A398 + 5.0 + v2.0 + Windows CE + + $(MSBuildProjectDirectory)\.. + true + 2005 + Compact + testce + %25CSIDL_PROGRAM_FILES%25 + + + + $(BinaryOutputPath) + + + true + full + false + DEBUG;TRACE;$(PlatformFamilyName) + true + true + prompt + off + + + pdbonly + true + TRACE;$(PlatformFamilyName) + true + true + prompt + off + + + + + False + + + False + + + False + + + False + + + False + + + + + + Form + + + Form1.cs + + + + + + + + Form1.cs + Designer + + + + + {AC139951-261A-4463-B6FA-AEBC25283A66} + System.Data.SQLite.Compact.2005 + + + + + + + + + + + + + Index: testlinq/2008/App.config ================================================================== --- testlinq/2008/App.config +++ testlinq/2008/App.config @@ -1,11 +1,11 @@ - + Index: testlinq/2010/App.config ================================================================== --- testlinq/2010/App.config +++ testlinq/2010/App.config @@ -1,11 +1,11 @@ - + Index: testlinq/Properties/AssemblyInfo.cs ================================================================== --- testlinq/Properties/AssemblyInfo.cs +++ testlinq/Properties/AssemblyInfo.cs @@ -39,7 +39,7 @@ // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.78.0")] -[assembly: AssemblyFileVersion("1.0.78.0")] +[assembly: AssemblyVersion("1.0.81.0")] +[assembly: AssemblyFileVersion("1.0.81.0")] Index: testlinq/testlinq.2008.csproj ================================================================== --- testlinq/testlinq.2008.csproj +++ testlinq/testlinq.2008.csproj @@ -72,11 +72,11 @@ - + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {A41FE2A5-07AD-4CE7-B836-1544634816F5} + Properties + Exe + Installer + Installer + true + $(MSBuildProjectDirectory)\..\.. + true + 2005 + + + + + $(BinaryOutputPath) + + + true + full + false + DEBUG;TRACE + prompt + + + pdbonly + true + TRACE + prompt + + + + + + + + + + + + + + + + + + $(BuildDependsOn); + EmbedExeManifest; + StrongNameSign; + + + + Index: tools/install/Installer.cs ================================================================== --- tools/install/Installer.cs +++ tools/install/Installer.cs @@ -33,10 +33,11 @@ string name, string description, string typeName, AssemblyName assemblyName, object clientData, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref bool saved, ref string error @@ -48,10 +49,11 @@ Installer.MockRegistryKey rootKey, string frameworkName, Version frameworkVersion, string platformName, object clientData, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref string error ); @@ -61,10 +63,11 @@ internal delegate bool VisualStudioRegistryCallback( Installer.MockRegistryKey rootKey, Version vsVersion, Installer.Package package, object clientData, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref string error ); @@ -227,10 +230,11 @@ #endregion /////////////////////////////////////////////////////////////////// #region Interactive Support Methods + [MethodImpl(MethodImplOptions.NoInlining)] public static DialogResult ShowMessage( TracePriority tracePriority, TraceCallback debugCallback, TraceCallback traceCallback, Assembly assembly, @@ -1369,10 +1373,11 @@ #endregion /////////////////////////////////////////////////////////////////// #region Public Static Methods + [MethodImpl(MethodImplOptions.NoInlining)] public static MockRegistryKey OpenSubKey( MockRegistryKey rootKey, string subKeyName, bool writable, bool whatIf, @@ -1401,10 +1406,11 @@ new MockRegistryKey(key, whatIf, false, false) : null; } /////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] public static MockRegistryKey CreateSubKey( MockRegistryKey rootKey, string subKeyName, bool whatIf, bool verbose @@ -1453,10 +1459,11 @@ } } /////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] public static void DeleteSubKey( MockRegistryKey rootKey, string subKeyName, bool throwOnMissing, bool whatIf, @@ -1479,10 +1486,11 @@ subKeysDeleted++; } /////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] public static void DeleteSubKeyTree( MockRegistryKey rootKey, string subKeyName, bool whatIf, bool verbose @@ -1504,10 +1512,11 @@ subKeysDeleted++; } /////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] public static string[] GetSubKeyNames( MockRegistryKey key, bool whatIf, bool verbose ) @@ -1523,10 +1532,11 @@ return key.GetSubKeyNames(); } /////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] public static object GetValue( MockRegistryKey key, string name, object defaultValue, bool whatIf, @@ -1546,10 +1556,11 @@ return key.GetValue(name, defaultValue); } /////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] public static void SetValue( MockRegistryKey key, string name, object value, bool whatIf, @@ -1572,10 +1583,11 @@ keyValuesSet++; } /////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] public static void DeleteValue( MockRegistryKey key, string name, bool throwOnMissing, bool whatIf, @@ -1757,15 +1769,17 @@ string traceFormat, InstallFlags installFlags, TracePriority debugPriority, TracePriority tracePriority, bool install, + bool wow64, bool noRuntimeVersion, bool noDesktop, bool noCompact, bool noNetFx20, bool noNetFx40, + bool noVs2005, bool noVs2008, bool noVs2010, bool noTrace, bool noConsole, bool noLog, @@ -1786,15 +1800,17 @@ this.traceFormat = traceFormat; this.installFlags = installFlags; this.debugPriority = debugPriority; this.tracePriority = tracePriority; this.install = install; + this.wow64 = wow64; this.noRuntimeVersion = noRuntimeVersion; this.noDesktop = noDesktop; this.noCompact = noCompact; this.noNetFx20 = noNetFx20; this.noNetFx40 = noNetFx40; + this.noVs2005 = noVs2005; this.noVs2008 = noVs2008; this.noVs2010 = noVs2010; this.noTrace = noTrace; this.noConsole = noConsole; this.noLog = noLog; @@ -1950,16 +1966,17 @@ return new Configuration(thisAssembly, null, directory, coreFileName, linqFileName, designerFileName, TraceOps.DebugFormat, TraceOps.TraceFormat, InstallFlags.Default, TracePriority.Default, TracePriority.Default, true, false, false, false, false, - false, false, false, false, false, false, true, true, - false, false, false); + false, false, false, false, false, false, false, false, + true, true, false, false, false); } /////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] public static bool FromArgs( string[] args, bool strict, ref Configuration configuration, ref string error @@ -2385,10 +2402,31 @@ continue; } configuration.noTrace = (bool)value; } + else if (MatchOption(newArg, "noVs2005")) + { + bool? value = ParseBoolean(text); + + if (value == null) + { + error = TraceOps.DebugAndTrace( + TracePriority.Lowest, debugCallback, + traceCallback, String.Format( + "Invalid {0} boolean value: {1}", + ForDisplay(arg), ForDisplay(text)), + traceCategory); + + if (strict) + return false; + + continue; + } + + configuration.noVs2005 = (bool)value; + } else if (MatchOption(newArg, "noVs2008")) { bool? value = ParseBoolean(text); if (value == null) @@ -2544,10 +2582,31 @@ continue; } configuration.whatIf = (bool)value; } + else if (MatchOption(newArg, "wow64")) + { + bool? value = ParseBoolean(text); + + if (value == null) + { + error = TraceOps.DebugAndTrace( + TracePriority.Lowest, debugCallback, + traceCallback, String.Format( + "Invalid {0} boolean value: {1}", + ForDisplay(arg), ForDisplay(text)), + traceCategory); + + if (strict) + return false; + + continue; + } + + configuration.wow64 = (bool)value; + } else { error = TraceOps.DebugAndTrace( TracePriority.Lowest, debugCallback, traceCallback, String.Format( @@ -2572,10 +2631,11 @@ return false; } /////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] public static bool Process( string[] args, Configuration configuration, bool strict, ref string error @@ -2677,10 +2737,15 @@ TraceOps.DebugAndTrace(TracePriority.MediumLow, debugCallback, traceCallback, String.Format( "Original command line is: {0}", Environment.CommandLine), traceCategory); + TraceOps.DebugAndTrace(TracePriority.MediumLow, + debugCallback, traceCallback, String.Format( + "Running process is {0}.", Is64BitProcess() ? + "64-bit" : "32-bit"), traceCategory); + if (!configuration.whatIf) { // // NOTE: If the debugger is attached and What-If mode // is [now] disabled, issue a warning. @@ -2729,10 +2794,11 @@ return false; } /////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] public static bool CheckRuntimeVersion( Configuration configuration, bool strict, ref string error ) @@ -2782,11 +2848,11 @@ error = "invalid core file image runtime version"; return false; } else if (String.Equals( coreImageRuntimeVersion, CLRv2ImageRuntimeVersion, - StringComparison.InvariantCulture)) + StringComparison.Ordinal)) { // // NOTE: For the CLR v2.0 runtime, make sure we disable // any attempt to use it for things that require // an assembly compiled for the CLR v4.0. It is @@ -2806,18 +2872,19 @@ CLRv2ImageRuntimeVersion, CLRv4ImageRuntimeVersion), traceCategory); } else if (String.Equals( coreImageRuntimeVersion, CLRv4ImageRuntimeVersion, - StringComparison.InvariantCulture)) + StringComparison.Ordinal)) { // // NOTE: For the CLR v4.0 runtime, make sure we disable // any attempt to use it for things that require // an assembly compiled for the CLR v2.0. // configuration.noNetFx20 = true; + configuration.noVs2005 = true; configuration.noVs2008 = true; TraceOps.DebugAndTrace(TracePriority.Medium, debugCallback, traceCallback, String.Format( "Assembly is compiled for the .NET Framework {0}, " + @@ -2919,10 +2986,14 @@ traceCategory); traceCallback(String.Format(NameAndValueFormat, "Install", ForDisplay(install)), traceCategory); + + traceCallback(String.Format(NameAndValueFormat, + "Wow64", ForDisplay(wow64)), + traceCategory); traceCallback(String.Format(NameAndValueFormat, "NoRuntimeVersion", ForDisplay(noRuntimeVersion)), traceCategory); @@ -2939,10 +3010,14 @@ traceCategory); traceCallback(String.Format(NameAndValueFormat, "NoNetFx40", ForDisplay(noNetFx40)), traceCategory); + + traceCallback(String.Format(NameAndValueFormat, + "NoVs2005", ForDisplay(noVs2005)), + traceCategory); traceCallback(String.Format(NameAndValueFormat, "NoVs2008", ForDisplay(noVs2008)), traceCategory); @@ -3109,10 +3184,19 @@ set { install = value; } } /////////////////////////////////////////////////////////////////// + private bool wow64; + public bool Wow64 + { + get { return wow64; } + set { wow64 = value; } + } + + /////////////////////////////////////////////////////////////////// + private bool noRuntimeVersion; public bool NoRuntimeVersion { get { return noRuntimeVersion; } set { noRuntimeVersion = value; } @@ -3151,10 +3235,19 @@ public bool NoNetFx40 { get { return noNetFx40; } set { noNetFx40 = value; } } + + /////////////////////////////////////////////////////////////////// + + private bool noVs2005; + public bool NoVs2005 + { + get { return noVs2005; } + set { noVs2005 = value; } + } /////////////////////////////////////////////////////////////////// private bool noVs2008; public bool NoVs2008 @@ -3357,16 +3450,30 @@ private const string NameAndValueFormat = "{0}: {1}"; private const string LogFileSuffix = ".log"; /////////////////////////////////////////////////////////////////////// - private static readonly string VsIdFormat = "B"; + private const string RootKeyName = "Software"; + private const string Wow64SubKeyName = "Wow6432Node"; + + /////////////////////////////////////////////////////////////////////// + + // + // NOTE: The .NET Framework has both 32-bit and 64-bit editions. + // + private static readonly bool NetFxIs32BitOnly = false; + + /////////////////////////////////////////////////////////////////////// + + // + // NOTE: For now, Visual Studio is always a 32-bit application. + // + private static readonly bool VsIs32BitOnly = true; /////////////////////////////////////////////////////////////////////// - private static readonly string FrameworkKeyName = - "Software\\Microsoft\\.NETFramework"; + private static readonly string VsIdFormat = "B"; /////////////////////////////////////////////////////////////////////// private static readonly string XPathForAddElement = "configuration/system.data/DbProviderFactories/add[@invariant=\"{0}\"]"; @@ -3430,10 +3537,37 @@ TraceOps.TraceCore(String.Format( TraceOps.TraceFormat, TraceOps.NextTraceId(), TraceOps.TimeStamp(DateTime.UtcNow), message), category); } #endregion + + /////////////////////////////////////////////////////////////////////// + + #region Generic Platform Handling + private static bool Is64BitProcess() + { + // + // NOTE: Returns true if the current process is 64-bit. If this + // is true, we *know* that we must be running on a 64-bit + // operating system as well. However, if this is false, we + // do not necessarily know that we are running on a 32-bit + // operating system, due to WoW64 (Win32-on-Win64), etc. + // + return (IntPtr.Size == sizeof(long)); // NOTE: Pointer is 64-bits? + } + + /////////////////////////////////////////////////////////////////////// + + private static string GetRootKeyName( + bool wow64 + ) + { + return String.Format("{0}{1}", RootKeyName, + wow64 && Is64BitProcess() ? + "\\" + Wow64SubKeyName : String.Empty); + } + #endregion /////////////////////////////////////////////////////////////////////// #region Generic String Handling private static string ForDisplay( @@ -3538,10 +3672,37 @@ #endregion /////////////////////////////////////////////////////////////////////// #region .NET Framework Handling + private static string GetFrameworkRootKeyName( + bool wow64 + ) + { + return String.Format("{0}\\Microsoft\\.NETFramework", + GetRootKeyName(wow64)); + } + + /////////////////////////////////////////////////////////////////////// + + private static string GetFrameworkKeyName( + string frameworkName, + Version frameworkVersion, + string platformName, + bool wow64 + ) + { + string format = !String.IsNullOrEmpty(platformName) ? + "{0}\\Microsoft\\{1}\\v{2}\\{3}" : + "{0}\\Microsoft\\{1}\\v{2}"; + + return String.Format(format, GetRootKeyName(wow64), + frameworkName, frameworkVersion, platformName); + } + + /////////////////////////////////////////////////////////////////////// + private static string GetImageRuntimeVersion( string fileName ) { try @@ -3563,16 +3724,18 @@ /////////////////////////////////////////////////////////////////////// private static string GetFrameworkDirectory( MockRegistryKey rootKey, Version frameworkVersion, + bool wow64, bool whatIf, bool verbose ) { using (MockRegistryKey key = RegistryHelper.OpenSubKey( - rootKey, FrameworkKeyName, false, whatIf, verbose)) + rootKey, GetFrameworkRootKeyName(wow64), false, + whatIf, verbose)) { if (key == null) return null; object value = RegistryHelper.GetValue( @@ -3671,20 +3834,17 @@ private static bool HaveFramework( MockRegistryKey rootKey, string frameworkName, Version frameworkVersion, string platformName, + bool wow64, bool whatIf, bool verbose ) { - string format = !String.IsNullOrEmpty(platformName) ? - "Software\\Microsoft\\{0}\\v{1}\\{2}" : - "Software\\Microsoft\\{0}\\v{1}"; - - string keyName = String.Format( - format, frameworkName, frameworkVersion, platformName); + string keyName = GetFrameworkKeyName( + frameworkName, frameworkVersion, platformName, wow64); using (MockRegistryKey key = RegistryHelper.OpenSubKey( rootKey, keyName, false, whatIf, verbose)) { if (key == null) @@ -3692,24 +3852,31 @@ if (platformName != null) // NOTE: Skip non-desktop. return true; string directory = GetFrameworkDirectory( - rootKey, frameworkVersion, whatIf, verbose); + rootKey, frameworkVersion, wow64, whatIf, verbose); if (String.IsNullOrEmpty(directory)) return false; if (!Directory.Exists(directory)) return false; + TraceOps.DebugAndTrace(TracePriority.Lower, + debugCallback, traceCallback, String.Format( + ".NET Framework {0} found in directory {1}.", + ForDisplay(frameworkVersion), ForDisplay(directory)), + traceCategory); + return true; } } /////////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] private static bool ForEachFrameworkConfig( MockRegistry registry, FrameworkList frameworkList, FrameworkConfigCallback callback, string invariant, @@ -3716,10 +3883,11 @@ string name, string description, string typeName, AssemblyName assemblyName, object clientData, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref bool saved, ref string error @@ -3817,11 +3985,11 @@ ForDisplay(frameworkVersion), ForDisplay(platformName)), traceCategory); if (!HaveFramework( rootKey, frameworkName, frameworkVersion, - platformName, whatIf, verbose)) + platformName, wow64, whatIf, verbose)) { TraceOps.DebugAndTrace(TracePriority.Low, debugCallback, traceCallback, ".NET Framework not found, skipping...", traceCategory); @@ -3831,11 +3999,11 @@ if (callback == null) continue; string directory = GetFrameworkDirectory( - rootKey, frameworkVersion, whatIf, verbose); + rootKey, frameworkVersion, wow64, whatIf, verbose); if (String.IsNullOrEmpty(directory)) { TraceOps.DebugAndTrace(TracePriority.Low, debugCallback, traceCallback, String.Format( @@ -3874,12 +4042,12 @@ bool localSaved = false; if (!callback( fileName, invariant, name, description, typeName, - assemblyName, clientData, throwOnMissing, whatIf, - verbose, ref localSaved, ref error)) + assemblyName, clientData, wow64, throwOnMissing, + whatIf, verbose, ref localSaved, ref error)) { return false; } else { @@ -3899,15 +4067,17 @@ return true; } /////////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] private static bool ForEachFrameworkRegistry( MockRegistry registry, FrameworkList frameworkList, FrameworkRegistryCallback callback, object clientData, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref string error ) @@ -3997,11 +4167,11 @@ ForDisplay(frameworkVersion), ForDisplay(platformName)), traceCategory); if (!HaveFramework( rootKey, frameworkName, frameworkVersion, - platformName, whatIf, verbose)) + platformName, wow64, whatIf, verbose)) { TraceOps.DebugAndTrace(TracePriority.Low, debugCallback, traceCallback, ".NET Framework not found, skipping...", traceCategory); @@ -4012,11 +4182,11 @@ if (callback == null) continue; if (!callback( rootKey, frameworkName, frameworkVersion, - platformName, clientData, throwOnMissing, + platformName, clientData, wow64, throwOnMissing, whatIf, verbose, ref error)) { return false; } } @@ -4043,11 +4213,12 @@ if (vsList.Versions == null) { vsList.Versions = new VersionList(); - // vsList.Versions.Add(new Version(8, 0)); // Visual Studio 2005 + if ((configuration == null) || !configuration.NoVs2005) + vsList.Versions.Add(new Version(8, 0)); // Visual Studio 2005 if ((configuration == null) || !configuration.NoVs2008) vsList.Versions.Add(new Version(9, 0)); // Visual Studio 2008 if ((configuration == null) || !configuration.NoVs2010) @@ -4058,19 +4229,19 @@ /////////////////////////////////////////////////////////////////////// private static bool HaveVsVersion( MockRegistryKey rootKey, Version vsVersion, + bool wow64, bool whatIf, bool verbose ) { if (vsVersion == null) return false; - string format = "Software\\Microsoft\\VisualStudio\\{0}"; - string keyName = String.Format(format, vsVersion); + string keyName = GetVsKeyName(vsVersion, wow64); using (MockRegistryKey key = RegistryHelper.OpenSubKey( rootKey, keyName, false, whatIf, verbose)) { if (key == null) @@ -4088,22 +4259,30 @@ return false; if (!Directory.Exists(directory)) return false; + TraceOps.DebugAndTrace(TracePriority.Lower, + debugCallback, traceCallback, String.Format( + "Visual Studio {0} found in directory {1}.", + ForDisplay(vsVersion), ForDisplay(directory)), + traceCategory); + return true; } } /////////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] private static bool ForEachVsVersionRegistry( MockRegistry registry, VsList vsList, VisualStudioRegistryCallback callback, Package package, object clientData, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref string error ) @@ -4146,11 +4325,11 @@ TraceOps.DebugAndTrace(TracePriority.Lower, debugCallback, traceCallback, String.Format( "vsVersion = {0}", ForDisplay(vsVersion)), traceCategory); - if (!HaveVsVersion(rootKey, vsVersion, whatIf, verbose)) + if (!HaveVsVersion(rootKey, vsVersion, wow64, whatIf, verbose)) { TraceOps.DebugAndTrace(TracePriority.Low, debugCallback, traceCallback, "Visual Studio version not found, skipping...", traceCategory); @@ -4160,11 +4339,11 @@ if (callback == null) continue; if (!callback( - rootKey, vsVersion, package, clientData, + rootKey, vsVersion, package, clientData, wow64, throwOnMissing, whatIf, verbose, ref error)) { return false; } } @@ -4174,10 +4353,11 @@ #endregion /////////////////////////////////////////////////////////////////////// #region Configuration File Handling + [MethodImpl(MethodImplOptions.NoInlining)] private static bool AddDbProviderFactory( string fileName, string invariant, string name, string description, @@ -4193,14 +4373,14 @@ XmlDocument document = new XmlDocument(); document.PreserveWhitespace = true; document.Load(fileName); - XmlElement element = document.SelectSingleNode(String.Format( - XPathForAddElement, invariant)) as XmlElement; + XmlElement addElement = document.SelectSingleNode( + String.Format(XPathForAddElement, invariant)) as XmlElement; - if (element == null) + if (addElement == null) { string[] elementNames = { "system.data", "DbProviderFactories" }; @@ -4207,69 +4387,69 @@ XmlElement previousElement = document.DocumentElement; /* configuration */ foreach (string elementName in elementNames) { - element = previousElement.SelectSingleNode( - elementName) as XmlElement; - - if (element == null) - { - element = document.CreateElement( - elementName, String.Empty); - - previousElement.AppendChild(element); - } - - previousElement = element; - } - - element = document.CreateElement( - "add", String.Empty); - - previousElement.AppendChild(element); - - dirty = true; - } - - if (!String.Equals(element.GetAttribute("name"), - name, StringComparison.InvariantCulture)) - { - element.SetAttribute("name", name); - dirty = true; - } - - if (!String.Equals(element.GetAttribute("invariant"), - invariant, StringComparison.InvariantCulture)) - { - element.SetAttribute("invariant", invariant); - dirty = true; - } - - if (!String.Equals(element.GetAttribute("description"), - description, StringComparison.InvariantCulture)) - { - element.SetAttribute("description", description); + addElement = previousElement.SelectSingleNode( + elementName) as XmlElement; + + if (addElement == null) + { + addElement = document.CreateElement( + elementName, String.Empty); + + previousElement.AppendChild(addElement); + } + + previousElement = addElement; + } + + addElement = document.CreateElement( + "add", String.Empty); + + previousElement.AppendChild(addElement); + + dirty = true; + } + + if (!String.Equals(addElement.GetAttribute("name"), + name, StringComparison.Ordinal)) + { + addElement.SetAttribute("name", name); + dirty = true; + } + + if (!String.Equals(addElement.GetAttribute("invariant"), + invariant, StringComparison.Ordinal)) + { + addElement.SetAttribute("invariant", invariant); + dirty = true; + } + + if (!String.Equals(addElement.GetAttribute("description"), + description, StringComparison.Ordinal)) + { + addElement.SetAttribute("description", description); dirty = true; } string fullTypeName = String.Format("{0}, {1}", typeName, assemblyName); - if (!String.Equals(element.GetAttribute("type"), - fullTypeName, StringComparison.InvariantCulture)) + if (!String.Equals(addElement.GetAttribute("type"), + fullTypeName, StringComparison.Ordinal)) { - element.SetAttribute("type", fullTypeName); + addElement.SetAttribute("type", fullTypeName); dirty = true; } if (dirty || whatIf) { if (verbose) TraceOps.DebugAndTrace(TracePriority.Highest, debugCallback, traceCallback, String.Format( - "element = {0}", ForDisplay(element)), + "addElement = {0}", ForDisplay(addElement)), traceCategory); if (!whatIf) document.Save(fileName); @@ -4279,10 +4459,11 @@ return true; } /////////////////////////////////////////////////////////////////////// + [MethodImpl(MethodImplOptions.NoInlining)] private static bool RemoveDbProviderFactory( string fileName, string invariant, bool whatIf, bool verbose, @@ -4294,34 +4475,35 @@ XmlDocument document = new XmlDocument(); document.PreserveWhitespace = true; document.Load(fileName); - XmlElement element = document.SelectSingleNode(String.Format( - XPathForAddElement, invariant)) as XmlElement; + XmlElement addElement = document.SelectSingleNode( + String.Format(XPathForAddElement, invariant)) as XmlElement; - if (element != null) + if (addElement != null) { - element.ParentNode.RemoveChild(element); + addElement.ParentNode.RemoveChild(addElement); dirty = true; } - element = document.SelectSingleNode(String.Format( - XPathForRemoveElement, invariant)) as XmlElement; + XmlElement removeElement = document.SelectSingleNode( + String.Format(XPathForRemoveElement, invariant)) as XmlElement; - if (element != null) + if (removeElement != null) { - element.ParentNode.RemoveChild(element); + removeElement.ParentNode.RemoveChild(removeElement); dirty = true; } if (dirty || whatIf) { if (verbose) TraceOps.DebugAndTrace(TracePriority.Highest, debugCallback, traceCallback, String.Format( - "element = {0}", ForDisplay(element)), + "addElement = {0}, removeElement = {1}", + ForDisplay(addElement), ForDisplay(removeElement)), traceCategory); if (!whatIf) document.Save(fileName); @@ -4339,10 +4521,11 @@ string name, string description, string typeName, AssemblyName assemblyName, object clientData, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref bool saved, ref string error @@ -4378,19 +4561,25 @@ #region Assembly Folders Handling private static string GetAssemblyFoldersKeyName( string frameworkName, Version frameworkVersion, - string platformName + string platformName, + bool wow64 ) { + // + // NOTE: This registry key appears to always be 32-bit only + // (i.e. probably because it is only used by Visual + // Studio, which is currently always 32-bit only). + // string format = !String.IsNullOrEmpty(platformName) ? - "Software\\Microsoft\\{0}\\v{1}\\{2}\\AssemblyFoldersEx" : - "Software\\Microsoft\\{0}\\v{1}\\AssemblyFoldersEx"; + "{0}\\Microsoft\\{1}\\v{2}\\{3}\\AssemblyFoldersEx" : + "{0}\\Microsoft\\{1}\\v{2}\\AssemblyFoldersEx"; - return String.Format(format, frameworkName, frameworkVersion, - platformName); + return String.Format(format, GetRootKeyName(wow64), + frameworkName, frameworkVersion, platformName); } /////////////////////////////////////////////////////////////////////// private static bool AddToAssemblyFolders( @@ -4398,17 +4587,18 @@ string frameworkName, Version frameworkVersion, string platformName, string subKeyName, string directory, + bool wow64, bool whatIf, bool verbose, ref string error ) { string keyName = GetAssemblyFoldersKeyName( - frameworkName, frameworkVersion, platformName); + frameworkName, frameworkVersion, platformName, wow64); using (MockRegistryKey key = RegistryHelper.OpenSubKey( rootKey, keyName, true, whatIf, verbose)) { if (key == null) @@ -4446,18 +4636,19 @@ MockRegistryKey rootKey, string frameworkName, Version frameworkVersion, string platformName, string subKeyName, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref string error ) { string keyName = GetAssemblyFoldersKeyName( - frameworkName, frameworkVersion, platformName); + frameworkName, frameworkVersion, platformName, wow64); using (MockRegistryKey key = RegistryHelper.OpenSubKey( rootKey, keyName, true, whatIf, verbose)) { if (key == null) @@ -4482,10 +4673,11 @@ MockRegistryKey rootKey, string frameworkName, Version frameworkVersion, string platformName, object clientData, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref string error ) @@ -4500,45 +4692,59 @@ if (pair.Y) { return RemoveFromAssemblyFolders( rootKey, frameworkName, frameworkVersion, platformName, - LegacyProjectName, false, whatIf, verbose, ref error) && + LegacyProjectName, wow64, false, whatIf, verbose, + ref error) && AddToAssemblyFolders( rootKey, frameworkName, frameworkVersion, platformName, - ProjectName, pair.X, whatIf, verbose, ref error); + ProjectName, pair.X, wow64, whatIf, verbose, ref error); } else { return RemoveFromAssemblyFolders( rootKey, frameworkName, frameworkVersion, platformName, - ProjectName, throwOnMissing, whatIf, verbose, ref error); + ProjectName, wow64, throwOnMissing, whatIf, verbose, + ref error); } } #endregion /////////////////////////////////////////////////////////////////////// #region Visual Studio Handling + private static string GetVsRootKeyName( + bool wow64 + ) + { + return String.Format("{0}\\Microsoft\\VisualStudio", + GetRootKeyName(wow64)); + } + + /////////////////////////////////////////////////////////////////////// + private static string GetVsKeyName( - Version vsVersion + Version vsVersion, + bool wow64 ) { if (vsVersion == null) return null; - return String.Format("Software\\Microsoft\\VisualStudio\\{0}", - vsVersion); + return String.Format( + "{0}\\{1}", GetVsRootKeyName(wow64), vsVersion); } /////////////////////////////////////////////////////////////////////// #region Visual Studio Data Source Handling private static bool AddVsDataSource( MockRegistryKey rootKey, Version vsVersion, Package package, + bool wow64, bool whatIf, bool verbose, ref string error ) { @@ -4552,11 +4758,11 @@ { error = "invalid VS package"; return false; } - string keyName = GetVsKeyName(vsVersion); + string keyName = GetVsKeyName(vsVersion, wow64); using (MockRegistryKey key = RegistryHelper.OpenSubKey( rootKey, keyName, false, whatIf, verbose)) { if (key == null) @@ -4614,10 +4820,11 @@ private static bool RemoveVsDataSource( MockRegistryKey rootKey, Version vsVersion, Package package, + bool wow64, bool whatIf, bool verbose, ref string error ) { @@ -4631,11 +4838,11 @@ { error = "invalid VS package"; return false; } - string keyName = GetVsKeyName(vsVersion); + string keyName = GetVsKeyName(vsVersion, wow64); using (MockRegistryKey key = RegistryHelper.OpenSubKey( rootKey, keyName, false, whatIf, verbose)) { if (key == null) @@ -4673,10 +4880,11 @@ private static bool ProcessVsDataSource( MockRegistryKey rootKey, Version vsVersion, Package package, object clientData, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref string error ) @@ -4696,16 +4904,18 @@ } if (pair.Y) { return AddVsDataSource( - rootKey, vsVersion, package, whatIf, verbose, ref error); + rootKey, vsVersion, package, wow64, whatIf, verbose, + ref error); } else { return RemoveVsDataSource( - rootKey, vsVersion, package, whatIf, verbose, ref error); + rootKey, vsVersion, package, wow64, whatIf, verbose, + ref error); } } #endregion /////////////////////////////////////////////////////////////////////// @@ -4714,10 +4924,11 @@ private static bool AddVsDataProvider( MockRegistryKey rootKey, Version vsVersion, Package package, string fileName, + bool wow64, bool whatIf, bool verbose, ref string error ) { @@ -4731,11 +4942,11 @@ { error = "invalid VS package"; return false; } - string keyName = GetVsKeyName(vsVersion); + string keyName = GetVsKeyName(vsVersion, wow64); using (MockRegistryKey key = RegistryHelper.OpenSubKey( rootKey, keyName, false, whatIf, verbose)) { if (key == null) @@ -4825,10 +5036,11 @@ private static bool RemoveVsDataProvider( MockRegistryKey rootKey, Version vsVersion, Package package, + bool wow64, bool whatIf, bool verbose, ref string error ) { @@ -4836,11 +5048,11 @@ { error = "invalid VS version"; return false; } - string keyName = GetVsKeyName(vsVersion); + string keyName = GetVsKeyName(vsVersion, wow64); using (MockRegistryKey key = RegistryHelper.OpenSubKey( rootKey, keyName, false, whatIf, verbose)) { if (key == null) @@ -4878,10 +5090,11 @@ private static bool ProcessVsDataProvider( MockRegistryKey rootKey, Version vsVersion, Package package, object clientData, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref string error ) @@ -4895,18 +5108,18 @@ } if (pair.Y) { return AddVsDataProvider( - rootKey, vsVersion, package, pair.X, - whatIf, verbose, ref error); + rootKey, vsVersion, package, pair.X, wow64, whatIf, + verbose, ref error); } else { return RemoveVsDataProvider( - rootKey, vsVersion, package, whatIf, - verbose, ref error); + rootKey, vsVersion, package, wow64, whatIf, verbose, + ref error); } } #endregion /////////////////////////////////////////////////////////////////////// @@ -4942,10 +5155,11 @@ private static bool AddVsPackage( MockRegistryKey rootKey, Version vsVersion, Package package, string fileName, + bool wow64, bool whatIf, bool verbose, ref string error ) { @@ -4959,11 +5173,11 @@ { error = "invalid VS package"; return false; } - string keyName = GetVsKeyName(vsVersion); + string keyName = GetVsKeyName(vsVersion, wow64); using (MockRegistryKey key = RegistryHelper.OpenSubKey( rootKey, keyName, false, whatIf, verbose)) { if (key == null) @@ -4985,10 +5199,29 @@ key); return false; } + // + // NOTE: *WARNING* Changing any of these values will likely + // require a new "package load key" (PLK) to be + // generated in order to properly support loading the + // package into Visual Studio 2008 and earlier without + // the matching Visual Studio SDK being installed. + // Please refer to the "SQLite.Designer\plk.txt" file + // for the existing official values and update them if + // necessary. Also, the newly generated package load + // key itself, which is a 128 character alphanumeric + // string, must be placed in the resource string named + // "400" in the "SQLite.Designer\VSPackage.resx" file + // and then the designer assembly itself must be + // recompiled. As of this writing (in February 2012), + // the following URL is the proper place to generate + // package load keys: + // + // http://msdn.microsoft.com/en-us/vstudio/cc655795 + // using (MockRegistryKey packageKey = RegistryHelper.CreateSubKey(subKey, package.PackageId.ToString(VsIdFormat), whatIf, verbose)) { @@ -5112,10 +5345,11 @@ private static bool RemoveVsPackage( MockRegistryKey rootKey, Version vsVersion, Package package, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref string error ) @@ -5130,11 +5364,11 @@ { error = "invalid VS package"; return false; } - string keyName = GetVsKeyName(vsVersion); + string keyName = GetVsKeyName(vsVersion, wow64); using (MockRegistryKey key = RegistryHelper.OpenSubKey( rootKey, keyName, false, whatIf, verbose)) { if (key == null) @@ -5206,10 +5440,11 @@ private static bool ProcessVsPackage( MockRegistryKey rootKey, Version vsVersion, Package package, object clientData, + bool wow64, bool throwOnMissing, bool whatIf, bool verbose, ref string error ) @@ -5223,34 +5458,58 @@ } if (pair.Y) { return AddVsPackage( - rootKey, vsVersion, package, pair.X, whatIf, verbose, - ref error); + rootKey, vsVersion, package, pair.X, wow64, whatIf, + verbose, ref error); } else { return RemoveVsPackage( - rootKey, vsVersion, package, throwOnMissing, whatIf, - verbose, ref error); + rootKey, vsVersion, package, wow64, throwOnMissing, + whatIf, verbose, ref error); } } #endregion #endregion /////////////////////////////////////////////////////////////////////// #region Application Entry Point + [MethodImpl(MethodImplOptions.NoInlining)] private static int Main( string[] args ) { try { Configuration configuration = null; string error = null; + + /////////////////////////////////////////////////////////////// + + #region Debugger Hook + if (Environment.GetEnvironmentVariable("Break") != null) + { + Console.WriteLine( + "Attach a debugger to process {0} and " + + "press any key to continue.", + Process.GetCurrentProcess().Id); + + try + { + Console.ReadKey(true); /* throw */ + } + catch (InvalidOperationException) // Console.ReadKey + { + // do nothing. + } + + Debugger.Break(); + } + #endregion /////////////////////////////////////////////////////////////// #region Command Line Processing if (!Configuration.FromArgs( @@ -5382,11 +5641,13 @@ if (configuration.HasFlags( InstallFlags.AssemblyFolders, true)) { if (!ForEachFrameworkRegistry(registry, frameworkList, ProcessAssemblyFolders, - directoryData, configuration.ThrowOnMissing, + directoryData, + NetFxIs32BitOnly || configuration.Wow64, + configuration.ThrowOnMissing, configuration.WhatIf, configuration.Verbose, ref error)) { TraceOps.ShowMessage(TracePriority.Highest, debugCallback, traceCallback, thisAssembly, @@ -5411,12 +5672,13 @@ bool saved = false; if (!ForEachFrameworkConfig(registry, frameworkList, ProcessDbProviderFactory, InvariantName, ProviderName, Description, - FactoryTypeName, assemblyName, - directoryData, configuration.ThrowOnMissing, + FactoryTypeName, assemblyName, directoryData, + NetFxIs32BitOnly || configuration.Wow64, + configuration.ThrowOnMissing, configuration.WhatIf, configuration.Verbose, ref saved, ref error)) { TraceOps.ShowMessage(TracePriority.Highest, debugCallback, traceCallback, thisAssembly, @@ -5438,11 +5700,13 @@ if (configuration.HasFlags( InstallFlags.VsPackage, true)) { if (!ForEachVsVersionRegistry(registry, vsList, ProcessVsPackage, package, - fileNameData, configuration.ThrowOnMissing, + fileNameData, + VsIs32BitOnly || configuration.Wow64, + configuration.ThrowOnMissing, configuration.WhatIf, configuration.Verbose, ref error)) { TraceOps.ShowMessage(TracePriority.Highest, debugCallback, traceCallback, thisAssembly, @@ -5464,11 +5728,13 @@ if (configuration.HasFlags( InstallFlags.VsDataSource, true)) { if (!ForEachVsVersionRegistry(registry, vsList, ProcessVsDataSource, package, - fileNameData, configuration.ThrowOnMissing, + fileNameData, + VsIs32BitOnly || configuration.Wow64, + configuration.ThrowOnMissing, configuration.WhatIf, configuration.Verbose, ref error)) { TraceOps.ShowMessage(TracePriority.Highest, debugCallback, traceCallback, thisAssembly, @@ -5490,11 +5756,13 @@ if (configuration.HasFlags( InstallFlags.VsDataProvider, true)) { if (!ForEachVsVersionRegistry(registry, vsList, ProcessVsDataProvider, package, - fileNameData, configuration.ThrowOnMissing, + fileNameData, + VsIs32BitOnly || configuration.Wow64, + configuration.ThrowOnMissing, configuration.WhatIf, configuration.Verbose, ref error)) { TraceOps.ShowMessage(TracePriority.Highest, debugCallback, traceCallback, thisAssembly, Index: tools/install/Properties/AssemblyInfo.cs ================================================================== --- tools/install/Properties/AssemblyInfo.cs +++ tools/install/Properties/AssemblyInfo.cs @@ -26,7 +26,7 @@ // Major Version // Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("1.0.78.0")] -[assembly: AssemblyFileVersion("1.0.78.0")] +[assembly: AssemblyVersion("1.0.81.0")] +[assembly: AssemblyFileVersion("1.0.81.0")] Index: www/build.wiki ================================================================== --- www/build.wiki +++ www/build.wiki @@ -124,12 +124,14 @@
    • <root>\SQLite.x64.nuspec
    • <root>\Doc\Extra\dbfactorysupport.html
    • <root>\Doc\Extra\welcome.html
    • <root>\Membership\Properties\AssemblyInfo.cs
    • <root>\SQLite.Designer\AssemblyInfo.cs
    • -
    • <root>\SQLite.Interop\props\SQLite.Interop.vsprops
    • -
    • <root>\SQLite.Interop\props\SQLite.Interop.props
    • +
    • <root>\SQLite.Designer\source.extension.vsixmanifest
    • +
    • <root>\SQLite.Interop\props\SQLite.Interop.2005.vsprops
    • +
    • <root>\SQLite.Interop\props\SQLite.Interop.2008.vsprops
    • +
    • <root>\SQLite.Interop\props\SQLite.Interop.2010.props
    • <root>\SQLite.Interop\src\win\interop.h
    • <root>\System.Data.SQLite\AssemblyInfo.cs
    • <root>\System.Data.SQLite\SQLite3.cs
    • <root>\System.Data.SQLite\UnsafeNativeMethods.cs
    • <root>\System.Data.SQLite.Linq\AssemblyInfo.cs
    • Index: www/checkin.wiki ================================================================== --- www/checkin.wiki +++ www/checkin.wiki @@ -1,16 +1,16 @@ Check-in Checklist Before every check-in: - 1. fossil diff → no stray changes + 1. fossil diff → No stray changes. - 2. fossil extra → no unmanaged files need to be added. + 2. fossil extra → No unmanaged files need to be added. 3. The check-in will go onto the desired branch. - 4. "Autosync" is enabled → + 4. The "autosync" setting is enabled. →
      1. The check-in will not cause a unintentional fork.
      2. The local system clock is set correctly.
      @@ -17,5 +17,9 @@ Before every check-in to trunk: 5. No compiler warnings on the development machine. 6. Changes will not cause problems on a future bisect. + + 7. Build binaries as outlined on the [./build.wiki | build procedures] page. + + 8. Run unit tests as outlined on the [./test.wiki | test procedures] page. Index: www/downloads.wiki ================================================================== --- www/downloads.wiki +++ www/downloads.wiki @@ -9,21 +9,21 @@
  • - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - sqlite-netFx-source-1.0.77.0.zip + + sqlite-netFx-source-1.0.80.0.zip
    - (2.57 MiB) + (2.68 MiB)
    This ZIP archive contains all current source code for System.Data.SQLite - 1.0.77.0 (3.7.9) combined into a single archive file. + 1.0.80.0 (3.7.11) combined into a single archive file.
    - (sha1: 84e9b80b767118caf06206c3e83cb53eddb89a08) + (sha1: 96e37d1d9146f9cd6721ef273eb3973d1612c0ad)
    @@ -31,41 +31,41 @@
      - sqlite-netFx35-setup-bundle-x86-2008-1.0.77.0.exe + + sqlite-netFx35-setup-bundle-x86-2008-1.0.80.0.exe
    - (5.88 MiB) + (6.04 MiB)
    This setup package features the mixed-mode assembly and will install all the necessary runtime components and dependencies for the x86 version of - the System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2008 + the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2008 SP1 runtime for x86 is included. The .NET Framework 3.5 SP1 is required.
    - (sha1: d772f21988d166e25b21ea73d645de249f083883) + (sha1: a4b9b35779ae85ce02f0e0a622f3039163335858)
      - sqlite-netFx35-setup-x86-2008-1.0.77.0.exe + + sqlite-netFx35-setup-x86-2008-1.0.80.0.exe
    - (5.88 MiB) + (6.03 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x86 version of the System.Data.SQLite 1.0.77.0 - (3.7.9) package. The Visual C++ 2008 SP1 runtime for x86 is included. + dependencies for the x86 version of the System.Data.SQLite 1.0.80.0 + (3.7.11) package. The Visual C++ 2008 SP1 runtime for x86 is included. The .NET Framework 3.5 SP1 is required.
    - (sha1: 6257afc0cc2fefb7c4f72ffe52fe12941ee1c053) + (sha1: d8ddde29f3fc0ded715d632501809158c174fd4a)
    @@ -73,41 +73,41 @@
      - sqlite-netFx35-setup-bundle-x64-2008-1.0.77.0.exe + + sqlite-netFx35-setup-bundle-x64-2008-1.0.80.0.exe
    - (6.62 MiB) + (6.77 MiB)
    This setup package features the mixed-mode assembly and will install all the necessary runtime components and dependencies for the x64 version of - the System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2008 + the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2008 SP1 runtime for x64 is included. The .NET Framework 3.5 SP1 is required.
    - (sha1: 3e503a9292b361e24d46ee814bf3ff4c1d0bbaa2) + (sha1: 65d6b88e6180f0956ed189de2e8595fb70d90970)
      - sqlite-netFx35-setup-x64-2008-1.0.77.0.exe + + sqlite-netFx35-setup-x64-2008-1.0.80.0.exe
    - (6.61 MiB) + (6.77 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x64 version of the System.Data.SQLite 1.0.77.0 - (3.7.9) package. The Visual C++ 2008 SP1 runtime for x64 is included. + dependencies for the x64 version of the System.Data.SQLite 1.0.80.0 + (3.7.11) package. The Visual C++ 2008 SP1 runtime for x64 is included. The .NET Framework 3.5 SP1 is required.
    - (sha1: 344e03e91c5f95e09e4dbaa8336dfbe75ece875b) + (sha1: 93da8e2d4e556c232587251f826d8e87da4969c9)
    @@ -115,41 +115,41 @@
      - sqlite-netFx40-setup-bundle-x86-2010-1.0.77.0.exe + + sqlite-netFx40-setup-bundle-x86-2010-1.0.80.0.exe
    - (10.25 MiB) + (10.36 MiB)
    This setup package features the mixed-mode assembly and will install all the necessary runtime components and dependencies for the x86 version of - the System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2010 + the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2010 SP1 runtime for x86 is included. The .NET Framework 4.0 is required.
    - (sha1: c1f51270764c2d694a6e19ef0200243a4212c021) + (sha1: 0d7a51989eb3f23bbf3d695c9af264666031e7c3)
      - sqlite-netFx40-setup-x86-2010-1.0.77.0.exe + + sqlite-netFx40-setup-x86-2010-1.0.80.0.exe
    - (10.24 MiB) + (10.36 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x86 version of the System.Data.SQLite 1.0.77.0 - (3.7.9) package. The Visual C++ 2010 SP1 runtime for x86 is included. + dependencies for the x86 version of the System.Data.SQLite 1.0.80.0 + (3.7.11) package. The Visual C++ 2010 SP1 runtime for x86 is included. The .NET Framework 4.0 is required.
    - (sha1: c80d75dab1c3692be27f47c5db7d4b55af2891c3) + (sha1: ee2a4dde8f470eee99d1a616c5c2eab0dd2e245e)
    @@ -157,41 +157,41 @@
      - sqlite-netFx40-setup-bundle-x64-2010-1.0.77.0.exe + + sqlite-netFx40-setup-bundle-x64-2010-1.0.80.0.exe
    - (12.04 MiB) + (11.62 MiB)
    This setup package features the mixed-mode assembly and will install all the necessary runtime components and dependencies for the x64 version of - the System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2010 + the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2010 SP1 runtime for x64 is included. The .NET Framework 4.0 is required.
    - (sha1: 34a56eaee1d876278f42a3626b12ac6eb5713b3d) + (sha1: e2a1b48e4e743d0224f2a6607be6b067426ab34b)
      - sqlite-netFx40-setup-x64-2010-1.0.77.0.exe + + sqlite-netFx40-setup-x64-2010-1.0.80.0.exe
    - (12.03 MiB) + (11.61 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x64 version of the System.Data.SQLite 1.0.77.0 - (3.7.9) package. The Visual C++ 2010 SP1 runtime for x64 is included. + dependencies for the x64 version of the System.Data.SQLite 1.0.80.0 + (3.7.11) package. The Visual C++ 2010 SP1 runtime for x64 is included. The .NET Framework 4.0 is required.
    - (sha1: aabcb26ed62540968d27a441995053b5260e9b74) + (sha1: 6e9fcd43446d88238875b8a1d83ec28e831fb0be)
    @@ -199,40 +199,40 @@
      - sqlite-netFx35-binary-bundle-Win32-2008-1.0.77.0.zip + + sqlite-netFx35-binary-bundle-Win32-2008-1.0.80.0.zip
    - (1.97 MiB) + (1.61 MiB)
    This binary package features the mixed-mode assembly and contains all the - binaries for the x86 version of the System.Data.SQLite 1.0.77.0 (3.7.9) + binaries for the x86 version of the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2008 SP1 runtime for x86 and the .NET Framework 3.5 SP1 are required.
    - (sha1: e7103c196e725196c0b591386ec34c7a80c9eb83) + (sha1: 63240eacb4af8c507a6957e177de1a375db32e18)
      - sqlite-netFx35-binary-Win32-2008-1.0.77.0.zip + + sqlite-netFx35-binary-Win32-2008-1.0.80.0.zip
    - (1.97 MiB) + (1.62 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2008 SP1 + System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2008 SP1 runtime for x86 and the .NET Framework 3.5 SP1 are required.
    - (sha1: 0c36eaf45c99b4e0a56f00711bce04b30b979578) + (sha1: 3159f8d2df5473ea1c42c603ec7a43f9d3aaf939)
    @@ -240,40 +240,40 @@
      - sqlite-netFx35-binary-bundle-x64-2008-1.0.77.0.zip + + sqlite-netFx35-binary-bundle-x64-2008-1.0.80.0.zip
    - (2.04 MiB) + (1.68 MiB)
    This binary package features the mixed-mode assembly and contains all the - binaries for the x64 version of the System.Data.SQLite 1.0.77.0 (3.7.9) + binaries for the x64 version of the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2008 SP1 runtime for x64 and the .NET Framework 3.5 SP1 are required.
    - (sha1: ac39f8a600c846ce957b17380636b5b6ce2155c4) + (sha1: 188f4fd49c9199474e7dec951d1702869f6b7bed)
      - sqlite-netFx35-binary-x64-2008-1.0.77.0.zip + + sqlite-netFx35-binary-x64-2008-1.0.80.0.zip
    - (2.03 MiB) + (1.69 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2008 SP1 + System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2008 SP1 runtime for x64 and the .NET Framework 3.5 SP1 are required.
    - (sha1: b2595aaf38de226241567cbfa9d6402b92de6658) + (sha1: 2d841e8f28cbbb95942afffde159b9beb8ecb9d0)
    @@ -281,40 +281,40 @@
      - sqlite-netFx40-binary-bundle-Win32-2010-1.0.77.0.zip + + sqlite-netFx40-binary-bundle-Win32-2010-1.0.80.0.zip
    - (2.02 MiB) + (1.69 MiB)
    This binary package features the mixed-mode assembly and contains all the - binaries for the x86 version of the System.Data.SQLite 1.0.77.0 (3.7.9) + binaries for the x86 version of the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2010 SP1 runtime for x86 and the .NET Framework 4.0 are required.
    - (sha1: c74d1bc4f15c98a717706e6c3dcafb74e161d373) + (sha1: f29643dd4be2876487c054ee5f2dca87e46f80a4)
      - sqlite-netFx40-binary-Win32-2010-1.0.77.0.zip + + sqlite-netFx40-binary-Win32-2010-1.0.80.0.zip
    - (2.01 MiB) + (1.66 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2010 SP1 + System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2010 SP1 runtime for x86 and the .NET Framework 4.0 are required.
    - (sha1: 5467fbd64d2e9a108c479e8449496270f082f9bb) + (sha1: 0c88572b2794ca75d08c8a6ab66fe1edce9ae825)
    @@ -322,40 +322,40 @@
      - sqlite-netFx40-binary-bundle-x64-2010-1.0.77.0.zip + + sqlite-netFx40-binary-bundle-x64-2010-1.0.80.0.zip
    - (1.46 MiB) + (1.68 MiB)
    This binary package features the mixed-mode assembly and contains all the - binaries for the x64 version of the System.Data.SQLite 1.0.77.0 (3.7.9) + binaries for the x64 version of the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2010 SP1 runtime for x64 and the .NET Framework 4.0 are required.
    - (sha1: 16cd8e7e7de4c0786aafbae5ee3a7587ac431cc7) + (sha1: 32b30e7430d92ce7192ce83451e8a9862f1e5d97)
      - sqlite-netFx40-binary-x64-2010-1.0.77.0.zip + + sqlite-netFx40-binary-x64-2010-1.0.80.0.zip
    - (1.45 MiB) + (1.67 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2010 SP1 + System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2010 SP1 runtime for x64 and the .NET Framework 4.0 are required.
    - (sha1: 01746a35858f6df8430335042b0ccb3edb38b7a9) + (sha1: 81d53e5b515b8906b875d994c0d8a60224b842fc)
    @@ -363,41 +363,41 @@
      - sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.77.0.zip + + sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.80.0.zip
    - (2.19 MiB) + (1.88 MiB)
    This binary package features the mixed-mode assembly and contains all the - binaries for the x86 version of the System.Data.SQLite 1.0.77.0 (3.7.9) + binaries for the x86 version of the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2008 SP1 runtime for x86 is statically linked. The .NET Framework 3.5 SP1 is required.
    - (sha1: e24120452d888aa19fde8409bba58f00b888ea19) + (sha1: 62e17ad898954b884c78f331f03376dfa7cb15c2)
      - sqlite-netFx35-static-binary-Win32-2008-1.0.77.0.zip + + sqlite-netFx35-static-binary-Win32-2008-1.0.80.0.zip
    - (2.18 MiB) + (1.83 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2008 SP1 + System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2008 SP1 runtime for x86 is statically linked. The .NET Framework 3.5 SP1 is required.
    - (sha1: 371ae4d78b3fd28d46e2ee03c0cdf4fc0c305be7) + (sha1: aa5d46057977a99e1eb275526bf0b5baea087026)
    @@ -405,41 +405,41 @@
      - sqlite-netFx35-static-binary-bundle-x64-2008-1.0.77.0.zip + + sqlite-netFx35-static-binary-bundle-x64-2008-1.0.80.0.zip
    - (2.22 MiB) + (1.89 MiB)
    This binary package features the mixed-mode assembly and contains all the - binaries for the x64 version of the System.Data.SQLite 1.0.77.0 (3.7.9) + binaries for the x64 version of the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2008 SP1 runtime for x64 is statically linked. The .NET Framework 3.5 SP1 is required.
    - (sha1: fa689fa65fe2477b9fb9aeeddc5b73849cdb5147) + (sha1: 4a3863c15848fae10c4521c6c30c630f1a5e07d4)
      - sqlite-netFx35-static-binary-x64-2008-1.0.77.0.zip + + sqlite-netFx35-static-binary-x64-2008-1.0.80.0.zip
    - (2.21 MiB) + (1.84 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2008 SP1 + System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2008 SP1 runtime for x64 is statically linked. The .NET Framework 3.5 SP1 is required.
    - (sha1: 497b8cd02cd92fc597e852db2bc36ed77dca0659) + (sha1: 098caf7d4adab54d8c20cd0bfb5553b353b236c4)
    @@ -447,40 +447,40 @@
      - sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.77.0.zip + + sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.80.0.zip
    - (2.24 MiB) + (1.89 MiB)
    This binary package features the mixed-mode assembly and contains all the - binaries for the x86 version of the System.Data.SQLite 1.0.77.0 (3.7.9) + binaries for the x86 version of the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2010 SP1 runtime for x86 is statically linked. The .NET Framework 4.0 is required.
    - (sha1: 984cbc9b831b67ea4c7417ee6c041bc5e6bb2b45) + (sha1: ce97513d2fa7ba9b7dec0f3c45c58b0ba3e749c3)
      - sqlite-netFx40-static-binary-Win32-2010-1.0.77.0.zip + + sqlite-netFx40-static-binary-Win32-2010-1.0.80.0.zip
    - (2.23 MiB) + (1.88 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2010 SP1 + System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2010 SP1 runtime for x86 is statically linked. The .NET Framework 4.0 is required.
    - (sha1: 53489a918aa53823c2b82608548486d1a1c030f6) + (sha1: 50acae4e4f60ecc4e9a992191c2e8df47d6145e0)
    @@ -488,40 +488,40 @@
      - sqlite-netFx40-static-binary-bundle-x64-2010-1.0.77.0.zip + + sqlite-netFx40-static-binary-bundle-x64-2010-1.0.80.0.zip
    - (2.24 MiB) + (1.87 MiB)
    This binary package features the mixed-mode assembly and contains all the - binaries for the x64 version of the System.Data.SQLite 1.0.77.0 (3.7.9) + binaries for the x64 version of the System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2010 SP1 runtime for x64 is statically linked. The .NET Framework 4.0 is required.
    - (sha1: 4fe5b9bf86ec6b602af981a477be1e7942199f1c) + (sha1: 9b412b19857bf123683e15dac3fa89bdabf59bc5)
      - sqlite-netFx40-static-binary-x64-2010-1.0.77.0.zip + + sqlite-netFx40-static-binary-x64-2010-1.0.80.0.zip
    - (2.23 MiB) + (1.86 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.77.0 (3.7.9) package. The Visual C++ 2010 SP1 + System.Data.SQLite 1.0.80.0 (3.7.11) package. The Visual C++ 2010 SP1 runtime for x64 is statically linked. The .NET Framework 4.0 is required.
    - (sha1: 2efbfc06e126eb49deda6799124921111e427d2a) + (sha1: 4e3bcc6a28813fa57bfd6b63a85406a3beb0de79)
    @@ -529,22 +529,22 @@
      - sqlite-netFx35-binary-PocketPC-2008-1.0.77.0.zip + + sqlite-netFx35-binary-PocketPC-2008-1.0.80.0.zip
    - (0.80 MiB) + (0.82 MiB)
    This binary package contains all the binaries for the PocketPC version of - the System.Data.SQLite 1.0.77.0 (3.7.9) package. The .NET Compact + the System.Data.SQLite 1.0.80.0 (3.7.11) package. The .NET Compact Framework 3.5 is required.
    - (sha1: c7227c3b968028f4b1260b5d1bd244c950f7fbac) + (sha1: 14f204b9a842623be3a514372b810d3eb64edae0)
    @@ -552,20 +552,20 @@
      + SQLite-1.0.66.0-setup.exe
    (3.2 MiB)
    Legacy versions, as well as the original support forums, may still be - found at [http://sqlite.phxsoftware.com/], though there have been no updates - to this version since April of 2010. + found at [http://sqlite.phxsoftware.com/], though there have been no + updates to this version since April of 2010.

    Build Product Names

    @@ -600,31 +600,35 @@ statically linked to the Visual C++ runtime. Template (9) is used for unofficial pre-release "snapshots" of source code.

    - The framework in templates (3), (4), (5), (6), (7), and (8) will be one of netFx35, netFx40. + The framework in templates (3), (4), (5), (6), (7), and (8) will be + one of netFx35, netFx40. +

    + +

    + The cpu in templates (3) and (4) will be one of x86, x64, arm, ia64. +

    + +

    + The platform in templates (5), (6), (7), and (8) will be one of Win32, + x64, PocketPC.

    - The cpu in templates (3) and (4) will be one of x86, x64, arm, ia64. + The year in templates (3), (4), (5), (6), (7), and (8) will be one of + 2008, 2010.

    - The platform in templates (5), (6), (7), and (8) will be one of Win32, x64, PocketPC. + The version in templates (1), (2), (3), (4), (5), (6), (7), and (8) is + the dot-delimited version number of the primary System.Data.SQLite assembly.

    - The year in templates (3), (4), (5), (6), (7), and (8) will be one of 2008, 2010. -

    - -

    - The version in templates (1), (2), (3), (4), (5), (6), (7), and (8) is the dot-delimited version number of the primary System.Data.SQLite assembly. -

    - -

    - The date in template (9) is of the form: YYYYMMDDHHMM + The date in template (9) is of the form: YYYYMMDDHHMM

    Canonical Source Code

    @@ -634,8 +638,8 @@ or ZIP archives of historical check-ins.

    The complete source tree for any [/timeline?n=20&y=ci | check-in] may always - be downloaded using the "ZIP archive" link available from the - check-in detail page. + be downloaded using the "Tarball" or "ZIP archive" links + available from the check-in detail page.

    Index: www/faq.wiki ================================================================== --- www/faq.wiki +++ www/faq.wiki @@ -94,10 +94,18 @@
  • When the solution is loaded in Visual Studio, why do no files show up for several of the projects in the Solution Explorer window?
  • +
    +
  • + When the System.Data.SQLite project is compiled and run from + inside Visual Studio, why do I get a DllNotFoundException or a + BadImageFormatException (for "sqlite3.dll" or + "SQLite.Interop.dll") when trying to run or debug the application? + +

  • @@ -442,5 +450,35 @@ design-time, the C# source code files do not show up in the Solution Explorer window. This limitation is largely cosmetic and does not impact the correctness of the build process itself, whether in Visual Studio or when using MSBuild on the command line.

    + +
    + +

    + (20) When the System.Data.SQLite project is compiled and run from inside + Visual Studio, why do I get a DllNotFoundException or a BadImageFormatException + (for "sqlite3.dll" or "SQLite.Interop.dll") when trying to + run or debug the application? +

    + +

    + When compiling and running a solution from within Visual Studio that uses the + System.Data.SQLite project (including the test project), it is very important + to select the correct build configuration and platform. First, managed + applications to be debugged inside Visual Studio cannot use the mixed-mode + assembly (i.e. because it is always compiled to the platform-specific build + output directory). This is necessary to properly support building binaries + for multiple platforms using the same source project files. Therefore, only + the "DebugNativeOnly" or "ReleaseNativeOnly" build + configurations should be selected when running a managed application from + inside Visual Studio that relies upon the System.Data.SQLite assembly. These + build configurations contain a custom post-build step that copies the required + native assembly to the managed output directory (i.e. to enable running the + managed binaries in-place). However, this post-build step will only be + performed if the selected platform matches that of the operating system (e.g. + "Win32" for 32-bit Windows and "x64" for 64-bit Windows). + Therefore, it is good practice to double-check the selected build platform + against the operating system prior to attempting to run a managed project in + the solution. +

    Index: www/features.wiki ================================================================== --- www/features.wiki +++ www/features.wiki @@ -37,13 +37,12 @@ 2005/2008/2010. You can add a SQLite database to the Servers list, design queries with the Query Designer, drag-and-drop tables onto a Typed DataSet, etc.
    - Currently not included. We are still updating the design-time support - installer. Due to Visual Studio licensing restrictions, the Express - Editions can no longer be supported. + Due to Visual Studio licensing restrictions, the Express Editions can no + longer be supported.
  • Full SQLite schema editing inside Visual Studio. You can create/edit tables, Index: www/news.wiki ================================================================== --- www/news.wiki +++ www/news.wiki @@ -1,15 +1,69 @@ News Version History

    - 1.0.78.0 - January XX, 2012 (release pending) + 1.0.81.0 - June XX, 2012 (release scheduled) +

    +
      +
    • Support compiling the interop assembly without support for the custom extension functions and the CryptoAPI based codec.
    • +
    • Add DefineConstants property to the SQLiteConnection class to return the list of define constants used when compiling the core managed assembly.
    • +
    • Add release archive verification tool to the release automation.
    • +
    • Fix subtle race condition between threads fetching connection handles from the connection pool any garbage collection (GC) threads that may be running. Fix for [996d13cd87].
    • +
    • Add missing call to SetTimeout in the SQLite3_UTF16.Open method.
    • +
    • Add checks to prevent the SQLiteConnectionPool.Remove method from returning any connection handles that are closed or invalid.
    • +
    • Modify static SQLiteBase helper methods to prevent them from passing IntPtr.Zero to the SQLite native library.
    • +
    • Remove static locks from the static helper methods in the SQLiteBase class, replacing them with a lock on the connection handle instance being operated upon.
    • +
    • Revise CriticalHandle derived classes to make them more thread-safe.
    • +
    • Add connection pool related diagnostic messages when compiled with the DEBUG define constant.
    • +
    • Add PoolCount property to the SQLiteConnection class to return the number of pool entries for the file name associated with the connection.
    • +
    • Rename internal SQLiteLastError methods to GetLastError.
    • +
    • Add assembly file test constraints to all tests that execute the "test.exe" or "testlinq.exe" files.
    • +
    +

    + 1.0.80.0 - April 1, 2012 +

    +
      +
    • Updated to [http://www.sqlite.org/releaselog/3_7_11.html|SQLite 3.7.11].
    • +
    • In the SQLiteFunction class, when calling user-provided methods from a delegate called by native code, avoid throwing exceptions, optionally tracing the caught exceptions. Fix for [8a426d12eb].
    • +
    • Add Visual Studio 2005 support to all the applicable solution/project files, their associated supporting files, and the test suite.
    • +
    • Add Visual Studio 2005 support to the redesigned designer support installer.
    • +
    • Add experimental support for "pre-loading" the native SQLite library based on the processor architecture of the current process. This feature is now enabled by default at compile-time.
    • +
    • Add support for the native [http://www.sqlite.org/backup.html|SQLite Online Backup API]. Fix for [c71846ed57].
    • +
    • Acquire and hold a static data lock while checking if the native SQLite library has been initialized to prevent a subtle race condition that can result in superfluous error messages. Fix for [72905c9a77].
    • +
    • Support tracing of all parameter binding activity and use the connection flags to control what is traced.
    • +
    • When converting a DateTime instance of an "Unspecified" kind to a string, use the same kind as the connection, if available.
    • +
    • Add overload of the SQLiteDataReader.GetValues method that returns a NameValueCollection.
    • +
    • Add static ToUnixEpoch method to the SQLiteConvert class to convert a DateTime value to the number of whole seconds since the Unix epoch.
    • +
    • In the implicit conversion operators (to IntPtr) for both the SQLiteConnectionHandle and SQLiteStatementHandle classes, return IntPtr.Zero if the instance being converted is null.
    • +
    • Write warning message to the active trace listeners (for the Debug build configuration only) if a column type or type name cannot be mapped properly. See [4bbf851fa5].
    • +
    • When tracing SQL statements to be prepared, bypass the internal length limit of the sqlite3_log function by using the SQLiteLog class directly instead. Also, detect null and/or empty strings and emit a special message in that case.
    • +
    • For the setup, the Visual Studio task should only be initially checked if the GAC task is available and vice-versa.
    • +
    • Improve compatibility with custom command processors by using __ECHO instead of _ECHO in batch tools.
    • +
    • Add OpenAndReturn method to the SQLiteConnection class to open a connection and return it.
    • +
    • Add missing CheckDisposed calls to the SQLiteConnection class.
    • +
    • Add missing throw statement to the SQLiteConnection class.
    • +
    • Make sure the interop project uses /fp:precise for Windows CE.
    • +
    • Regenerate package load key to support loading the designer package into Visual Studio 2008 without having the matching SDK installed.
    • +
    • Modify transaction object disposal so that it can never cause an exception to be thrown.
    • +
    +

    + 1.0.79.0 - January 28, 2012 +

    +
      +
    • Use the WoW64 registry keys when installing the VS designer components on 64-bit Windows. Fix for [d8491abd0b].
    • +
    • Correct resource name used by the LINQ assembly to locate several key string resources. Fix for [fbebb30da9].
    • +
    +

    + 1.0.78.0 - January 27, 2012

    • Updated to [http://www.sqlite.org/releaselog/3_7_10.html|SQLite 3.7.10]
    • Redesign the VS designer support installer and integrate it into the setup packages.
    • +
    • When emitting SQL for foreign keys in the VS designer, be sure to take all returned schema rows into account. Remainder of fix for [b226147b37].
    • +
    • Add Flags connection string property to control extra behavioral flags for the connection.
    • Refactor all IDisposable implementations to conform to best practices, potentially eliminating leaks in certain circumstances.
    • Even more enhancements to the build and test automation.
    • Support parameter binding to more primitive types, including unsigned integer types.
    • Recognize the TIMESTAMP column data type as the DateTime type. Fix for [bb4b04d457].
    • Prevent logging superfluous messages having to do with library initialization checking. Fix for [3fc172d1be].
    • Index: www/release.wiki ================================================================== --- www/release.wiki +++ www/release.wiki @@ -25,10 +25,36 @@
    • Enter the following command to build all the x86 and x64 binaries:  build_all.bat
    • + + +

      Test x86 & x64 Binaries

      + +
        +
      1. + The binaries for all supported architectures and platforms must be tested + using procedures very similar to those documented in the normal + [./test.wiki | test procedures]. +
      2. + +
      3. Open a normal command prompt window with "cmd.exe".
      4. + +
      5. Change the current directory to "<root>\Setup".
      6. + +
      7. + Enter the following command to test all the x86 or x64 binaries, depending + on the processor architecture of the current machine:  + test_all.bat
        +
      8. + +
      9. + Locate a machine with a processor architecture different from the one tested + in the previous step and then repeat all the previous steps. +
      10. +

      Build Windows CE Binaries

        @@ -39,10 +65,60 @@
      1. Enter the following command to build all the binaries available for Windows CE: build_ce.bat
      + + +

      Test Windows CE Binaries

      + +
        +
      1. + Launch Visual Studio 2008, "Professional" edition or + "better". As of this writing, in January 2012, Visual Studio + 2010 and later will not work as they do not include the necessary + built-in support for Windows CE and the .NET Compact Framework. +
      2. + +
      3. + Open the "SQLite.NET.2008.sln" solution file in the + "<root>" directory. +
      4. + +
      5. + Change the active solution configuration to "Debug". +
      6. + +
      7. + Change the active solution platform to "Pocket PC 2003 + (ARMV4)". +
      8. + +
      9. + Right-click the "testce" project in the Solution Explorer + window and select "Set as StartUp Project". +
      10. + +
      11. + Select "Start Debugging" from the "Debug" + menu. +
      12. + +
      13. + If any rebuild prompts appear (e.g. "SQLite.Interop.CE.2008", + "Would you like to build it?"), select "Yes". +
      14. + +
      15. + When prompted for the device type to deploy the application to, select the + "Pocket PC 2003 SE Emulator" device. +
      16. + +
      17. + Make sure all that the tests pass (i.e. they emit "SUCCESS"). +
      18. +

      Update Documentation

        @@ -144,19 +220,42 @@
      1. Enter the following command to build all the source release packages:  archive.bat
      + + +

      Verify All Release Packages

      + +
        +
      1. Open a normal command prompt window with "cmd.exe".
      2. + +
      3. Change the current directory to "<root>\Setup".
      4. + +
      5. + Enter the following command to build all the source release packages:  + ..\Externals\Eagle\bin\EagleShell.exe -file verify.eagle Output
        + If errors are generated, the file "<root>\Setup\verify.lst" + may need to be updated to account for the files that have been added and/or + removed from the release archives since the previous release. +
      6. +

      Update Downloads Page

      1. Open a normal command prompt window with "cmd.exe".
      2. Change the current directory to "<root>\Setup".
      3. +
      4. + Replace the version numbers for the previous release in the local working + copy of the [./downloads.wiki | downloads page] with the new version numbers + for System.Data.SQLite and the SQLite core. +
      5. +
      6. Enter the following command to update the sizes and hashes on the downloads page based on all the built release packages: tclsh.exe  updateFileInfo.tcl
        This assumes that [http://www.activestate.com/activetcl | ActiveTcl] version 8.4 or later has