Imported version 1.0.61.0 of SQLite.NET
authorMarek Habersack <grendel@twistedcode.net>
Wed, 3 Jun 2009 21:32:15 +0000 (21:32 -0000)
committerMarek Habersack <grendel@twistedcode.net>
Wed, 3 Jun 2009 21:32:15 +0000 (21:32 -0000)
svn path=/trunk/mcs/; revision=135354

34 files changed:
mcs/class/Mono.Data.Sqlite/Assembly/AssemblyInfo.cs
mcs/class/Mono.Data.Sqlite/Assembly/AssemblyInfo_1.1.cs [new file with mode: 0644]
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/LINQ/SQLiteConnection_Linq.cs [new file with mode: 0644]
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/LINQ/SQLiteFactory_Linq.cs [new file with mode: 0644]
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3_UTF16.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteBase.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteCommand.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteCommandBuilder.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConnection.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConnectionPool.cs [new file with mode: 0644]
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConnectionStringBuilder.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConvert.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteDataAdapter.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteDataReader.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteEnlistment.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteException.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteFactory.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteFunction.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteFunctionAttribute.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteKeyReader.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteMetaDataCollectionNames.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteParameter.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteParameterCollection.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteStatement.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteTransaction.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SR.Designer.cs
mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/UnsafeNativeMethods.cs
mcs/class/Mono.Data.Sqlite/resources/DataTypes.xml
mcs/class/Mono.Data.Sqlite/resources/MetaDataCollections.xml
mcs/class/Mono.Data.Sqlite/resources/SQLiteCommand.bmp [new file with mode: 0644]
mcs/class/Mono.Data.Sqlite/resources/SQLiteConnection.bmp [new file with mode: 0644]
mcs/class/Mono.Data.Sqlite/resources/SQLiteDataAdapter.bmp [new file with mode: 0644]
mcs/class/Mono.Data.Sqlite/resources/SR.resx

index e06154cd236d29f4ae10704010f4cc9a7b63d9cd..08654add38a78e19b5083c11ed357d494c444edf 100644 (file)
@@ -1,31 +1,53 @@
-//
-// AssemblyInfo.cs
-//
-// Author:
-//   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
-//
-// (C) 2003 Ximian, Inc.  http://www.ximian.com
-// (C) 2004 Novell (http://www.novell.com)
-//
-
-using System;
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyVersion (Consts.FxVersion)]
-
-/* TODO COMPLETE INFORMATION
-
-[assembly: AssemblyTitle ("")]
-[assembly: AssemblyDescription ("")]
-
-[assembly: CLSCompliant (true)]
-[assembly: AssemblyFileVersion ("0.0.0.1")]
-
-[assembly: ComVisible (false)]
-
-*/
-
-[assembly: AssemblyDelaySign (true)]
-[assembly: AssemblyKeyFile ("../mono.pub")]
-
+using System;\r
+using System.Reflection;\r
+using System.Runtime.CompilerServices;\r
+using System.Runtime.InteropServices;\r
+using System.Security.Permissions;\r
+using System.Security;\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+using System.Runtime.ConstrainedExecution;\r
+#endif\r
+\r
+// General Information about an assembly is controlled through the following \r
+// set of attributes. Change these attribute values to modify the information\r
+// associated with an assembly.\r
+[assembly: AssemblyTitle("System.Data.SQLite")]\r
+[assembly: AssemblyDescription("ADO.NET 2.0 Data Provider for SQLite")]\r
+[assembly: AssemblyConfiguration("")]\r
+[assembly: AssemblyCompany("http://sqlite.phxsoftware.com")]\r
+[assembly: AssemblyProduct("System.Data.SQLite")]\r
+[assembly: AssemblyCopyright("Public Domain")]\r
+[assembly: AssemblyTrademark("")]\r
+[assembly: AssemblyCulture("")]\r
+\r
+#if PLATFORM_COMPACTFRAMEWORK && RETARGETABLE\r
+[assembly: AssemblyFlags(AssemblyNameFlags.Retargetable)]\r
+#endif\r
+\r
+//  Setting ComVisible to false makes the types in this assembly not visible \r
+//  to COM componenets.  If you need to access a type in this assembly from \r
+//  COM, set the ComVisible attribute to true on that type.\r
+[assembly: ComVisible(false)]\r
+[assembly: CLSCompliant(true)]\r
+[assembly: InternalsVisibleTo("System.Data.SQLite.Linq, PublicKey=002400000480000094000000060200000024000052534131000400000100010005a288de5687c4e1b621ddff5d844727418956997f475eb829429e411aff3e93f97b70de698b972640925bdd44280df0a25a843266973704137cbb0e7441c1fe7cae4e2440ae91ab8cde3933febcb1ac48dd33b40e13c421d8215c18a4349a436dd499e3c385cc683015f886f6c10bd90115eb2bd61b67750839e3a19941dc9c")]\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+[assembly: AllowPartiallyTrustedCallers]\r
+[assembly: ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]\r
+[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]\r
+#endif\r
+\r
+// Version information for an assembly consists of the following four values:\r
+//\r
+//      Major Version\r
+//      Minor Version \r
+//      Build Number\r
+//      Revision\r
+//\r
+// You can specify all the values or you can default the Revision and Build Numbers \r
+// by using the '*' as shown below:\r
+[assembly: AssemblyVersion("1.0.61.0")]\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+[assembly: AssemblyFileVersion("1.0.61.0")]\r
+#endif\r
diff --git a/mcs/class/Mono.Data.Sqlite/Assembly/AssemblyInfo_1.1.cs b/mcs/class/Mono.Data.Sqlite/Assembly/AssemblyInfo_1.1.cs
new file mode 100644 (file)
index 0000000..e06154c
--- /dev/null
@@ -0,0 +1,31 @@
+//
+// AssemblyInfo.cs
+//
+// Author:
+//   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
+//
+// (C) 2003 Ximian, Inc.  http://www.ximian.com
+// (C) 2004 Novell (http://www.novell.com)
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyVersion (Consts.FxVersion)]
+
+/* TODO COMPLETE INFORMATION
+
+[assembly: AssemblyTitle ("")]
+[assembly: AssemblyDescription ("")]
+
+[assembly: CLSCompliant (true)]
+[assembly: AssemblyFileVersion ("0.0.0.1")]
+
+[assembly: ComVisible (false)]
+
+*/
+
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../mono.pub")]
+
diff --git a/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/LINQ/SQLiteConnection_Linq.cs b/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/LINQ/SQLiteConnection_Linq.cs
new file mode 100644 (file)
index 0000000..0c60494
--- /dev/null
@@ -0,0 +1,28 @@
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Data.Common;\r
+  using System.Collections.Generic;\r
+  using System.Globalization;\r
+  using System.ComponentModel;\r
+\r
+  public sealed partial class SQLiteConnection\r
+  {\r
+    /// <summary>\r
+    /// Returns a SQLiteProviderFactory object.\r
+    /// </summary>\r
+    protected override DbProviderFactory DbProviderFactory\r
+    {\r
+      get { return SQLiteFactory.Instance; }\r
+    }\r
+  }\r
+}\r
+\r
diff --git a/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/LINQ/SQLiteFactory_Linq.cs b/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/LINQ/SQLiteFactory_Linq.cs
new file mode 100644 (file)
index 0000000..6f494a8
--- /dev/null
@@ -0,0 +1,58 @@
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data.Common;\r
+  using System.Reflection;\r
+  using System.Security.Permissions;\r
+\r
+  /// <summary>\r
+  /// SQLite implementation of DbProviderFactory.\r
+  /// </summary>\r
+  public sealed partial class SQLiteFactory : IServiceProvider\r
+  {\r
+    private static Type _dbProviderServicesType;\r
+    private static object _sqliteServices;\r
+\r
+    static SQLiteFactory()\r
+    {\r
+      _dbProviderServicesType = Type.GetType("System.Data.Common.DbProviderServices, System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", false);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Will provide a DbProviderServices object in .NET 3.5\r
+    /// </summary>\r
+    /// <param name="serviceType">The class or interface type to query for</param>\r
+    /// <returns></returns>\r
+    object IServiceProvider.GetService(Type serviceType)\r
+    {\r
+      if (serviceType == typeof(ISQLiteSchemaExtensions) ||\r
+        (_dbProviderServicesType != null && serviceType == _dbProviderServicesType))\r
+      {\r
+        return GetSQLiteProviderServicesInstance();\r
+      }\r
+      return null;\r
+    }\r
+\r
+    [ReflectionPermission(SecurityAction.Assert, MemberAccess = true)]\r
+    private object GetSQLiteProviderServicesInstance()\r
+    {\r
+      if (_sqliteServices == null)\r
+      {\r
+        Type type = Type.GetType("System.Data.SQLite.SQLiteProviderServices, System.Data.SQLite.Linq, Version=2.0.38.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139", false);\r
+        if (type != null)\r
+        {\r
+          FieldInfo field = type.GetField("Instance", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);\r
+          _sqliteServices = field.GetValue(null);\r
+        }\r
+      }\r
+      return _sqliteServices;\r
+    }\r
+  }\r
+}\r
index 95f20f4644ac64a8afdcac0b6a7b75db54750109..d6ee87d284020fae4755478c3efb973c54dfdc35 100644 (file)
-//
-// Mono.Data.Sqlite.SQLite3.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Runtime.InteropServices;
-  using System.Collections.Generic;
-  using System.Globalization;
-
-  /// <summary>
-  /// This class implements SqliteBase completely, and is the guts of the code that interop's Sqlite with .NET
-  /// </summary>
-  internal class Sqlite3 : SqliteBase
-  {
-    /// <summary>
-    /// The opaque pointer returned to us by the sqlite provider
-    /// </summary>
-    protected IntPtr              _sql;
-    /// <summary>
-    /// The user-defined functions registered on this connection
-    /// </summary>
-    protected SqliteFunction[] _functionsArray;
-
-    internal Sqlite3(SqliteDateFormats fmt)
-      : base(fmt)
-    {
-    }
-
-    protected override void Dispose(bool bDisposing)
-    {
-      Close();
-    }
-
-    internal override void Close()
-    {
-      if (_sql != IntPtr.Zero)
-      {
-        int n = UnsafeNativeMethods.sqlite3_close(_sql);
-        if (n > 0) throw new SqliteException(n, SqliteLastError());
-      }
-      _sql = IntPtr.Zero;
-    }
-
-    internal override void Cancel()
-    {
-      UnsafeNativeMethods.sqlite3_interrupt(_sql);
-    }
-
-    internal override string Version
-    {
-      get
-      {
-             return ToString (UnsafeNativeMethods.sqlite3_libversion());
-      }
-    }
-
-    internal override int Changes
-    {
-      get
-      {
-        return UnsafeNativeMethods.sqlite3_changes(_sql);
-      }
-    }
-
-    internal override void Open(string strFilename)
-    {
-      if (_sql != IntPtr.Zero) return;
-      int n = UnsafeNativeMethods.sqlite3_open(ToUTF8(strFilename), out _sql);
-      if (n > 0) throw new SqliteException(n, SqliteLastError());
-
-      _functionsArray = SqliteFunction.BindFunctions(this);
-    }
-
-    internal override void SetTimeout(int nTimeoutMS)
-    {
-      int n = UnsafeNativeMethods.sqlite3_busy_timeout(_sql, nTimeoutMS);
-      if (n > 0) throw new SqliteException(n, SqliteLastError());
-    }
-
-    internal override bool Step(SqliteStatement stmt)
-    {
-      int n;
-      long timeout = 0;
-      Random rnd = null;
-
-      while (true)
-      {
-        n = UnsafeNativeMethods.sqlite3_step(stmt._sqlite_stmt);
-
-        if (n == 100) return true;
-        if (n == 101) return false;
-
-        if (n > 0)
-        {
-          int r;
-
-          // An error occurred, attempt to reset the statement.  If the reset worked because the
-          // schema has changed, re-try the step again.  If it errored our because the database
-          // is locked, then keep retrying until the command timeout occurs.
-          r = Reset(stmt);
-
-          if (r == 0)
-            throw new SqliteException(n, SqliteLastError());
-
-          else if (r == 6 && stmt._command != null) // SQLITE_LOCKED
-          {
-            // Keep trying
-            if (timeout == 0) // First time we've encountered the lock
-            {
-              timeout = Environment.TickCount + (stmt._command._commandTimeout * 1000);
-              rnd = new Random();
-            }
-            // If we've exceeded the command's timeout, give up and throw an error
-            if (Environment.TickCount - timeout > 0)
-            {
-              throw new SqliteException(r, SqliteLastError());
-            }
-            else
-            {
-              // Otherwise sleep for a random amount of time up to 250ms
-              UnsafeNativeMethods.sqlite3_sleep((uint)rnd.Next(1, 250));
-            }
-          }
-
-        }
-      }
-    }
-
-    internal override void FinalizeStatement(SqliteStatement stmt)
-    {
-      if (stmt._sqlite_stmt != IntPtr.Zero)
-      {
-        int n = UnsafeNativeMethods.sqlite3_finalize(stmt._sqlite_stmt);
-        if (n > 0) throw new SqliteException(n, SqliteLastError());
-      }
-      stmt._sqlite_stmt = IntPtr.Zero;
-    }
-
-    internal override int Reset(SqliteStatement stmt)
-    {
-      int n;
-
-      n = UnsafeNativeMethods.sqlite3_reset(stmt._sqlite_stmt);
-
-      // If the schema changed, try and re-prepare it
-      if (n == 17) // SQLITE_SCHEMA
-      {
-        // Recreate a dummy statement
-        string str;
-        using (SqliteStatement tmp = Prepare(stmt._sqlStatement, null, out str))
-        {
-          // Finalize the existing statement
-          FinalizeStatement(stmt);
-
-          // Reassign a new statement pointer to the old statement and clear the temporary one
-          stmt._sqlite_stmt = tmp._sqlite_stmt;
-          tmp._sqlite_stmt = IntPtr.Zero;
-
-          // Reapply parameters
-          stmt.BindParameters();
-        }
-        return -1; // Reset was OK, with schema change
-      }
-      else if (n == 6) // SQLITE_LOCKED
-        return n;
-
-      if (n > 0)
-        throw new SqliteException(n, SqliteLastError());
-
-      return 0; // We reset OK, no schema changes
-    }
-
-    internal override string SqliteLastError()
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_errmsg(_sql));
-    }
-
-    internal override SqliteStatement Prepare(string strSql, SqliteStatement previous, out string strRemain)
-    {
-      IntPtr stmt = IntPtr.Zero;
-      IntPtr ptr = IntPtr.Zero;
-      int n = 17;
-      int retries = 0;
-      byte[] b = ToUTF8(strSql);
-      string typedefs = null;
-      SqliteStatement cmd = null;
-      GCHandle handle = GCHandle.Alloc(b, GCHandleType.Pinned);
-      IntPtr psql = handle.AddrOfPinnedObject();
-
-      try
-      {
-        while (n == 17 && retries < 3)
-        {
-               try {
-                       n = UnsafeNativeMethods.sqlite3_prepare_v2(_sql, psql, b.Length - 1, out stmt, out ptr);
-               } catch (EntryPointNotFoundException) {
-                       n = UnsafeNativeMethods.sqlite3_prepare (_sql, psql, b.Length - 1, out stmt, out ptr);
-               }
-               
-          retries++;
-
-          if (n == 1)
-          {
-            if (String.Compare(SqliteLastError(), "near \"TYPES\": syntax error", StringComparison.OrdinalIgnoreCase) == 0)
-            {
-              int pos = strSql.IndexOf(';');
-              if (pos == -1) pos = strSql.Length - 1;
-
-              typedefs = strSql.Substring(0, pos + 1);
-              strSql = strSql.Substring(pos + 1);
-
-              strRemain = "";
-
-              while (cmd == null && strSql.Length > 0)
-              {
-                cmd = Prepare(strSql, previous, out strRemain);
-                strSql = strRemain;
-              }
-
-              if (cmd != null)
-                cmd.SetTypes(typedefs);
-
-              return cmd;
-            }
-          }
-        }
-
-        if (n > 0) throw new SqliteException(n, SqliteLastError());
-
-        strRemain = UTF8ToString(ptr);
-
-        if (stmt != IntPtr.Zero) cmd = new SqliteStatement(this, 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)
-    {
-      int n = UnsafeNativeMethods.sqlite3_bind_double(stmt._sqlite_stmt, index, value);
-      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_Int64(SqliteStatement stmt, int index, long value)
-    {
-      int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value);
-      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)
-    {
-      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());
-    }
-
-    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)
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name(stmt._sqlite_stmt, index));
-    }
-
-    internal override int Bind_ParamIndex(SqliteStatement stmt, string paramName)
-    {
-      return UnsafeNativeMethods.sqlite3_bind_parameter_index(stmt._sqlite_stmt, ToUTF8(paramName));
-    }
-
-    internal override int ColumnCount(SqliteStatement stmt)
-    {
-      return UnsafeNativeMethods.sqlite3_column_count(stmt._sqlite_stmt);
-    }
-
-    internal override string ColumnName(SqliteStatement stmt, int index)
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_column_name(stmt._sqlite_stmt, index));
-    }
-
-    internal override TypeAffinity ColumnAffinity(SqliteStatement stmt, int index)
-    {
-      return UnsafeNativeMethods.sqlite3_column_type(stmt._sqlite_stmt, index);
-    }
-
-    internal override string ColumnType(SqliteStatement stmt, int index, out TypeAffinity nAffinity)
-    {
-      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype(stmt._sqlite_stmt, index);
-      nAffinity = ColumnAffinity(stmt, index);
-
-      if (p != IntPtr.Zero) return base.ToString(p);
-      else
-      {
-        string[] ar = stmt.TypeDefinitions;
-        if (ar != null)
-        {
-          if (index < ar.Length)
-            return ar[index];
-        }
-
-        switch (nAffinity)
-        {
-          case TypeAffinity.Int64:
-            return "BIGINT";
-          case TypeAffinity.Double:
-            return "DOUBLE";
-          case TypeAffinity.Blob:
-            return "BLOB";
-          default:
-            return "TEXT";
-        }
-      }
-    }
-
-    internal override int ColumnIndex(SqliteStatement stmt, string columnName)
-    {
-      int x = ColumnCount(stmt);
-
-      for (int n = 0; n < x; n++)
-      {
-        if (String.Compare(columnName, ColumnName(stmt, n), true, CultureInfo.InvariantCulture) == 0)
-          return n;
-      }
-      return -1;
-    }
-
-    internal override string ColumnOriginalName(SqliteStatement stmt, int index)
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_column_origin_name(stmt._sqlite_stmt, index));
-    }
-
-    internal override string ColumnDatabaseName(SqliteStatement stmt, int index)
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_column_database_name(stmt._sqlite_stmt, index));
-    }
-
-    internal override string ColumnTableName(SqliteStatement stmt, int index)
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_column_table_name(stmt._sqlite_stmt, index));
-    }
-
-    internal override void ColumnMetaData(string dataBase, string table, string column, out string dataType,
-                                         out string collateSequence, out bool notNull, out bool primaryKey,
-                                         out bool autoIncrement)
-    {
-      IntPtr dataTypePtr;
-      IntPtr collSeqPtr;
-      int nnotNull;
-      int nprimaryKey;
-      int nautoInc;
-      int n;
-
-      n = UnsafeNativeMethods.sqlite3_table_column_metadata(_sql, ToUTF8(dataBase), ToUTF8(table), ToUTF8(column),
-                                                           out dataTypePtr, out collSeqPtr, out nnotNull,
-                                                           out nprimaryKey, out nautoInc);
-      if (n > 0) throw new SqliteException(n, SqliteLastError());
-
-      dataType = base.ToString(dataTypePtr);
-      collateSequence = base.ToString(collSeqPtr);
-
-      notNull = (nnotNull == 1);
-      primaryKey = (nprimaryKey == 1);
-      autoIncrement = (nautoInc == 1);
-    }
-
-    internal override double GetDouble(SqliteStatement stmt, int index)
-    {
-      return UnsafeNativeMethods.sqlite3_column_double(stmt._sqlite_stmt, index);
-    }
-
-    internal override int GetInt32(SqliteStatement stmt, int index)
-    {
-      return UnsafeNativeMethods.sqlite3_column_int(stmt._sqlite_stmt, index);
-    }
-
-    internal override long GetInt64(SqliteStatement stmt, int index)
-    {
-      return UnsafeNativeMethods.sqlite3_column_int64(stmt._sqlite_stmt, index);
-    }
-
-    internal override string GetText(SqliteStatement stmt, int index)
-    {
-           return ToString (UnsafeNativeMethods.sqlite3_column_text(stmt._sqlite_stmt, index));
-    }
-
-    internal override DateTime GetDateTime(SqliteStatement stmt, int index)
-    {
-           return ToDateTime(GetText (stmt, index));
-    }
-
-    internal override long GetBytes(SqliteStatement stmt, int index, int nDataOffset, byte[] bDest, int nStart, int nLength)
-    {
-      IntPtr ptr;
-      int nlen;
-      int nCopied = nLength;
-
-      nlen = UnsafeNativeMethods.sqlite3_column_bytes(stmt._sqlite_stmt, index);
-      ptr = UnsafeNativeMethods.sqlite3_column_blob(stmt._sqlite_stmt, index);
-
-      if (bDest == null) return nlen;
-
-      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;
-      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;
-
-         unsafe {
-                 if (nCopied > 0)
-                         Marshal.Copy((IntPtr)((byte*)ptr + nDataOffset), bDest, nStart, nCopied);
-                 else nCopied = 0;
-         }
-
-      return nCopied;
-    }
-
-    internal override long GetChars(SqliteStatement stmt, int index, int nDataOffset, char[] bDest, int nStart, int nLength)
-    {
-      int nlen;
-      int nCopied = nLength;
-
-      string str = GetText(stmt, index);
-      nlen = str.Length;
-
-      if (bDest == null) return nlen;
-
-      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;
-      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;
-
-      if (nCopied > 0)
-        str.CopyTo(nDataOffset, bDest, nStart, nCopied);
-      else nCopied = 0;
-
-      return nCopied;
-    }
-
-    internal override bool IsNull(SqliteStatement stmt, int index)
-    {
-      return (ColumnAffinity(stmt, index) == TypeAffinity.Null);
-    }
-
-    internal override int AggregateCount(IntPtr context)
-    {
-      return UnsafeNativeMethods.sqlite3_aggregate_count(context);
-    }
-
-    internal override void CreateFunction(string strFunction, int nArgs, SqliteCallback func, SqliteCallback funcstep, SqliteFinalCallback funcfinal)
-    {
-      int n = UnsafeNativeMethods.sqlite3_create_function(_sql, ToUTF8(strFunction), nArgs, 1, IntPtr.Zero, func, funcstep, funcfinal);
-      if (n > 0) throw new SqliteException(n, SqliteLastError());
-    }
-
-    internal override void CreateCollation(string strCollation, SqliteCollation func)
-    {
-      int n = UnsafeNativeMethods.sqlite3_create_collation(_sql, ToUTF8(strCollation), 1, IntPtr.Zero, func);
-      if (n > 0) throw new SqliteException(n, SqliteLastError());
-    }
-
-    internal override long GetParamValueBytes(IntPtr p, int nDataOffset, byte[] bDest, int nStart, int nLength)
-    {
-      IntPtr ptr;
-      int nlen;
-      int nCopied = nLength;
-
-      nlen = UnsafeNativeMethods.sqlite3_value_bytes(p);
-      ptr = UnsafeNativeMethods.sqlite3_value_blob(p);
-
-      if (bDest == null) return nlen;
-
-      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;
-      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;
-
-         unsafe {
-                 if (nCopied > 0)
-                         Marshal.Copy((IntPtr)((byte*)ptr + nDataOffset), bDest, nStart, nCopied);
-                 else nCopied = 0;
-         }
-
-      return nCopied;
-    }
-
-    internal override double GetParamValueDouble(IntPtr ptr)
-    {
-      return UnsafeNativeMethods.sqlite3_value_double(ptr);
-    }
-
-    internal override int GetParamValueInt32(IntPtr ptr)
-    {
-      return UnsafeNativeMethods.sqlite3_value_int(ptr);
-    }
-
-    internal override long GetParamValueInt64(IntPtr ptr)
-    {
-      return UnsafeNativeMethods.sqlite3_value_int64(ptr);
-    }
-
-    internal override string GetParamValueText(IntPtr ptr)
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_value_text(ptr));
-    }
-
-    internal override TypeAffinity GetParamValueType(IntPtr ptr)
-    {
-      return UnsafeNativeMethods.sqlite3_value_type(ptr);
-    }
-
-    internal override void ReturnBlob(IntPtr context, byte[] value)
-    {
-      UnsafeNativeMethods.sqlite3_result_blob(context, value, value.Length, (IntPtr)(-1));
-    }
-
-    internal override void ReturnDouble(IntPtr context, double value)
-    {
-      UnsafeNativeMethods.sqlite3_result_double(context, value);
-    }
-
-    internal override void ReturnError(IntPtr context, string value)
-    {
-      UnsafeNativeMethods.sqlite3_result_error(context, ToUTF8(value), value.Length);
-    }
-
-    internal override void ReturnInt32(IntPtr context, int value)
-    {
-      UnsafeNativeMethods.sqlite3_result_int(context, value);
-    }
-
-    internal override void ReturnInt64(IntPtr context, long value)
-    {
-      UnsafeNativeMethods.sqlite3_result_int64(context, value);
-    }
-
-    internal override void ReturnNull(IntPtr context)
-    {
-      UnsafeNativeMethods.sqlite3_result_null(context);
-    }
-
-    internal override void ReturnText(IntPtr context, string value)
-    {
-      byte[] b = ToUTF8(value);
-      UnsafeNativeMethods.sqlite3_result_text(context, ToUTF8(value), b.Length - 1, (IntPtr)(-1));
-    }
-
-    internal override IntPtr AggregateContext(IntPtr context)
-    {
-      return UnsafeNativeMethods.sqlite3_aggregate_context(context, 1);
-    }
-
-    internal override void SetUpdateHook(SqliteUpdateCallback func)
-    {
-      UnsafeNativeMethods.sqlite3_update_hook(_sql, func);
-    }
-
-    internal override void SetCommitHook(SqliteCommitCallback func)
-    {
-      UnsafeNativeMethods.sqlite3_commit_hook(_sql, func);
-    }
-
-    internal override void SetRollbackHook(SqliteRollbackCallback func)
-    {
-      UnsafeNativeMethods.sqlite3_rollback_hook(_sql, func);
-    }
-
-    /// <summary>
-    /// Helper function to retrieve a column of data from an active statement.
-    /// </summary>
-    /// <param name="stmt">The statement being step()'d through</param>
-    /// <param name="index">The column index to retrieve</param>
-    /// <param name="typ">The type of data contained in the column.  If Uninitialized, this function will retrieve the datatype information.</param>
-    /// <returns>Returns the data in the column</returns>
-    internal override object GetValue(SqliteStatement stmt, int index, ref SqliteType typ)
-    {
-      if (typ.Affinity == 0) typ = SqliteConvert.ColumnToType(stmt, index);
-      if (IsNull(stmt, index)) return DBNull.Value;
-
-      Type t = SqliteConvert.SqliteTypeToType(typ);
-
-      switch (TypeToAffinity(t))
-      {
-        case TypeAffinity.Blob:
-          if (typ.Type == DbType.Guid && typ.Affinity == TypeAffinity.Text)
-            return new Guid(GetText(stmt, index));
-
-          int n = (int)GetBytes(stmt, index, 0, null, 0, 0);
-          byte[] b = new byte[n];
-          GetBytes(stmt, index, 0, b, 0, n);
-
-          if (typ.Type == DbType.Guid && n == 16)
-            return new Guid(b);
-
-          return b;
-        case TypeAffinity.DateTime:
-          return GetDateTime(stmt, index);
-        case TypeAffinity.Double:
-          return Convert.ChangeType(GetDouble(stmt, index), t, null);
-        case TypeAffinity.Int64:
-          return Convert.ChangeType(GetInt64(stmt, index), t, null);
-        default:
-          return GetText(stmt, index);
-      }
-    }
-
-    internal override int GetLastInsertRowId ()
-    {
-           return UnsafeNativeMethods.sqlite3_last_insert_rowid (_sql);
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Runtime.InteropServices;\r
+  using System.Collections.Generic;\r
+  using System.Globalization;\r
+\r
+  /// <summary>\r
+  /// This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET\r
+  /// </summary>\r
+  internal class SQLite3 : SQLiteBase\r
+  {\r
+    /// <summary>\r
+    /// The opaque pointer returned to us by the sqlite provider\r
+    /// </summary>\r
+    protected SQLiteConnectionHandle _sql;\r
+    protected string _fileName;\r
+    protected bool _usePool;\r
+    protected int _poolVersion = 0;\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    private bool _buildingSchema = false;\r
+#endif\r
+    /// <summary>\r
+    /// The user-defined functions registered on this connection\r
+    /// </summary>\r
+    protected SQLiteFunction[] _functionsArray;\r
+\r
+    internal SQLite3(SQLiteDateFormats fmt)\r
+      : base(fmt)\r
+    {\r
+    }\r
+\r
+    protected override void Dispose(bool bDisposing)\r
+    {\r
+      if (bDisposing)\r
+        Close();\r
+    }\r
+\r
+    // It isn't necessary to cleanup any functions we've registered.  If the connection\r
+    // goes to the pool and is resurrected later, re-registered functions will overwrite the\r
+    // previous functions.  The SQLiteFunctionCookieHandle will take care of freeing unmanaged\r
+    // resources belonging to the previously-registered functions.\r
+    internal override void Close()\r
+    {\r
+      if (_sql != null)\r
+      {\r
+        if (_usePool)\r
+        {\r
+          SQLiteBase.ResetConnection(_sql);\r
+          SQLiteConnectionPool.Add(_fileName, _sql, _poolVersion);\r
+        }\r
+        else\r
+          _sql.Dispose();\r
+      }\r
+\r
+      _sql = null;\r
+    }\r
+\r
+    internal override void Cancel()\r
+    {\r
+      UnsafeNativeMethods.sqlite3_interrupt(_sql);\r
+    }\r
+\r
+    internal override string Version\r
+    {\r
+      get\r
+      {\r
+        return SQLite3.SQLiteVersion;\r
+      }\r
+    }\r
+\r
+    internal static string SQLiteVersion\r
+    {\r
+      get\r
+      {\r
+        return UTF8ToString(UnsafeNativeMethods.sqlite3_libversion(), -1);\r
+      }\r
+    }\r
+\r
+    internal override int Changes\r
+    {\r
+      get\r
+      {\r
+        return UnsafeNativeMethods.sqlite3_changes(_sql);\r
+      }\r
+    }\r
+\r
+    internal override void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool)\r
+    {\r
+      if (_sql != null) return;\r
+\r
+      _usePool = usePool;\r
+      if (usePool)\r
+      {\r
+        _fileName = strFilename;\r
+        _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion);\r
+      }\r
+\r
+      if (_sql == null)\r
+      {\r
+        IntPtr db;\r
+\r
+#if !SQLITE_STANDARD\r
+        int n = UnsafeNativeMethods.sqlite3_open_interop(ToUTF8(strFilename), (int)flags, out db);\r
+#else\r
+        int n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, (int)flags, IntPtr.Zero);\r
+#endif\r
+        if (n > 0) throw new SQLiteException(n, null);\r
+\r
+        _sql = db;\r
+      }\r
+      // Bind functions to this connection.  If any previous functions of the same name\r
+      // were already bound, then the new bindings replace the old.\r
+      _functionsArray = SQLiteFunction.BindFunctions(this);\r
+      SetTimeout(0);\r
+    }\r
+\r
+    internal override void ClearPool()\r
+    {\r
+      SQLiteConnectionPool.ClearPool(_fileName);\r
+    }\r
+\r
+    internal override void SetTimeout(int nTimeoutMS)\r
+    {\r
+      int n = UnsafeNativeMethods.sqlite3_busy_timeout(_sql, nTimeoutMS);\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override bool Step(SQLiteStatement stmt)\r
+    {\r
+      int n;\r
+      Random rnd = null;\r
+      uint starttick = (uint)Environment.TickCount;\r
+      uint timeout = (uint)(stmt._command._commandTimeout * 1000);\r
+\r
+      while (true)\r
+      {\r
+        n = UnsafeNativeMethods.sqlite3_step(stmt._sqlite_stmt);\r
+\r
+        if (n == 100) return true;\r
+        if (n == 101) return false;\r
+\r
+        if (n > 0)\r
+        {\r
+          int r;\r
+\r
+          // An error occurred, attempt to reset the statement.  If the reset worked because the\r
+          // schema has changed, re-try the step again.  If it errored our because the database\r
+          // is locked, then keep retrying until the command timeout occurs.\r
+          r = Reset(stmt);\r
+\r
+          if (r == 0)\r
+            throw new SQLiteException(n, SQLiteLastError());\r
+\r
+          else if ((r == 6 || r == 5) && stmt._command != null) // SQLITE_LOCKED || SQLITE_BUSY\r
+          {\r
+            // Keep trying\r
+            if (rnd == null) // First time we've encountered the lock\r
+              rnd = new Random();\r
+\r
+            // If we've exceeded the command's timeout, give up and throw an error\r
+            if ((uint)Environment.TickCount - starttick > timeout)\r
+            {\r
+              throw new SQLiteException(r, SQLiteLastError());\r
+            }\r
+            else\r
+            {\r
+              // Otherwise sleep for a random amount of time up to 150ms\r
+              System.Threading.Thread.CurrentThread.Join(rnd.Next(1, 150));\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+\r
+    internal override int Reset(SQLiteStatement stmt)\r
+    {\r
+      int n;\r
+\r
+#if !SQLITE_STANDARD\r
+      n = UnsafeNativeMethods.sqlite3_reset_interop(stmt._sqlite_stmt);\r
+#else\r
+      n = UnsafeNativeMethods.sqlite3_reset(stmt._sqlite_stmt);\r
+#endif\r
+\r
+      // If the schema changed, try and re-prepare it\r
+      if (n == 17) // SQLITE_SCHEMA\r
+      {\r
+        // Recreate a dummy statement\r
+        string str;\r
+        using (SQLiteStatement tmp = Prepare(null, stmt._sqlStatement, null, (uint)(stmt._command._commandTimeout * 1000), out str))\r
+        {\r
+          // Finalize the existing statement\r
+          stmt._sqlite_stmt.Dispose();\r
+          // Reassign a new statement pointer to the old statement and clear the temporary one\r
+          stmt._sqlite_stmt = tmp._sqlite_stmt;\r
+          tmp._sqlite_stmt = null;\r
+\r
+          // Reapply parameters\r
+          stmt.BindParameters();\r
+        }\r
+        return -1; // Reset was OK, with schema change\r
+      }\r
+      else if (n == 6 || n == 5) // SQLITE_LOCKED || SQLITE_BUSY\r
+        return n;\r
+\r
+      if (n > 0)\r
+        throw new SQLiteException(n, SQLiteLastError());\r
+\r
+      return 0; // We reset OK, no schema changes\r
+    }\r
+\r
+    internal override string SQLiteLastError()\r
+    {\r
+      return SQLiteBase.SQLiteLastError(_sql);\r
+    }\r
+\r
+    internal override SQLiteStatement Prepare(SQLiteConnection cnn, string strSql, SQLiteStatement previous, uint timeoutMS, out string strRemain)\r
+    {\r
+      IntPtr stmt = IntPtr.Zero;\r
+      IntPtr ptr = IntPtr.Zero;\r
+      int len = 0;\r
+      int n = 17;\r
+      int retries = 0;\r
+      byte[] b = ToUTF8(strSql);\r
+      string typedefs = null;\r
+      SQLiteStatement cmd = null;\r
+      Random rnd = null;\r
+      uint starttick = (uint)Environment.TickCount;\r
+\r
+      GCHandle handle = GCHandle.Alloc(b, GCHandleType.Pinned);\r
+      IntPtr psql = handle.AddrOfPinnedObject();\r
+      try\r
+      {\r
+        while ((n == 17 || n == 6 || n == 5) && retries < 3)\r
+        {\r
+#if !SQLITE_STANDARD\r
+          n = UnsafeNativeMethods.sqlite3_prepare_interop(_sql, psql, b.Length - 1, out stmt, out ptr, out len);\r
+#else\r
+          n = UnsafeNativeMethods.sqlite3_prepare(_sql, psql, b.Length - 1, out stmt, out ptr);\r
+          len = -1;\r
+#endif\r
+\r
+          if (n == 17)\r
+            retries++;\r
+          else if (n == 1)\r
+          {\r
+            if (String.Compare(SQLiteLastError(), "near \"TYPES\": syntax error", StringComparison.OrdinalIgnoreCase) == 0)\r
+            {\r
+              int pos = strSql.IndexOf(';');\r
+              if (pos == -1) pos = strSql.Length - 1;\r
+\r
+              typedefs = strSql.Substring(0, pos + 1);\r
+              strSql = strSql.Substring(pos + 1);\r
+\r
+              strRemain = "";\r
+\r
+              while (cmd == null && strSql.Length > 0)\r
+              {\r
+                cmd = Prepare(cnn, strSql, previous, timeoutMS, out strRemain);\r
+                strSql = strRemain;\r
+              }\r
+\r
+              if (cmd != null)\r
+                cmd.SetTypes(typedefs);\r
+\r
+              return cmd;\r
+            }\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+            else if (_buildingSchema == false && String.Compare(SQLiteLastError(), 0, "no such table: TEMP.SCHEMA", 0, 26, StringComparison.OrdinalIgnoreCase) == 0)\r
+            {\r
+              strRemain = "";\r
+              _buildingSchema = true;\r
+              try\r
+              {\r
+                ISQLiteSchemaExtensions ext = ((IServiceProvider)SQLiteFactory.Instance).GetService(typeof(ISQLiteSchemaExtensions)) as ISQLiteSchemaExtensions;\r
+\r
+                if (ext != null)\r
+                  ext.BuildTempSchema(cnn);\r
+\r
+                while (cmd == null && strSql.Length > 0)\r
+                {\r
+                  cmd = Prepare(cnn, strSql, previous, timeoutMS, out strRemain);\r
+                  strSql = strRemain;\r
+                }\r
+\r
+                return cmd;\r
+              }\r
+              finally\r
+              {\r
+                _buildingSchema = false;\r
+              }\r
+            }\r
+#endif\r
+          }\r
+          else if (n == 6 || n == 5) // Locked -- delay a small amount before retrying\r
+          {\r
+            // Keep trying\r
+            if (rnd == null) // First time we've encountered the lock\r
+              rnd = new Random();\r
+\r
+            // If we've exceeded the command's timeout, give up and throw an error\r
+            if ((uint)Environment.TickCount - starttick > timeoutMS)\r
+            {\r
+              throw new SQLiteException(n, SQLiteLastError());\r
+            }\r
+            else\r
+            {\r
+              // Otherwise sleep for a random amount of time up to 150ms\r
+              System.Threading.Thread.CurrentThread.Join(rnd.Next(1, 150));\r
+            }\r
+          }\r
+        }\r
+\r
+        if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+\r
+        strRemain = UTF8ToString(ptr, len);\r
+\r
+        if (stmt != IntPtr.Zero) cmd = new SQLiteStatement(this, stmt, strSql.Substring(0, strSql.Length - strRemain.Length), previous);\r
+\r
+        return cmd;\r
+      }\r
+      finally\r
+      {\r
+        handle.Free();\r
+      }\r
+    }\r
+\r
+    internal override void Bind_Double(SQLiteStatement stmt, int index, double value)\r
+    {\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+      int n = UnsafeNativeMethods.sqlite3_bind_double(stmt._sqlite_stmt, index, value);\r
+#else\r
+      int n = UnsafeNativeMethods.sqlite3_bind_double_interop(stmt._sqlite_stmt, index, ref value);\r
+#endif\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override void Bind_Int32(SQLiteStatement stmt, int index, int value)\r
+    {\r
+      int n = UnsafeNativeMethods.sqlite3_bind_int(stmt._sqlite_stmt, index, value);\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override void Bind_Int64(SQLiteStatement stmt, int index, long value)\r
+    {\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+      int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value);\r
+#else\r
+      int n = UnsafeNativeMethods.sqlite3_bind_int64_interop(stmt._sqlite_stmt, index, ref value);\r
+#endif\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override void Bind_Text(SQLiteStatement stmt, int index, string value)\r
+    {\r
+      byte[] b = ToUTF8(value);\r
+      int n = UnsafeNativeMethods.sqlite3_bind_text(stmt._sqlite_stmt, index, b, b.Length - 1, (IntPtr)(-1));\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt)\r
+    {\r
+      byte[] b = ToUTF8(dt);\r
+      int n = UnsafeNativeMethods.sqlite3_bind_text(stmt._sqlite_stmt, index, b, b.Length - 1, (IntPtr)(-1));\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override void Bind_Blob(SQLiteStatement stmt, int index, byte[] blobData)\r
+    {\r
+      int n = UnsafeNativeMethods.sqlite3_bind_blob(stmt._sqlite_stmt, index, blobData, blobData.Length, (IntPtr)(-1));\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override void Bind_Null(SQLiteStatement stmt, int index)\r
+    {\r
+      int n = UnsafeNativeMethods.sqlite3_bind_null(stmt._sqlite_stmt, index);\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override int Bind_ParamCount(SQLiteStatement stmt)\r
+    {\r
+      return UnsafeNativeMethods.sqlite3_bind_parameter_count(stmt._sqlite_stmt);\r
+    }\r
+\r
+    internal override string Bind_ParamName(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override int Bind_ParamIndex(SQLiteStatement stmt, string paramName)\r
+    {\r
+      return UnsafeNativeMethods.sqlite3_bind_parameter_index(stmt._sqlite_stmt, ToUTF8(paramName));\r
+    }\r
+\r
+    internal override int ColumnCount(SQLiteStatement stmt)\r
+    {\r
+      return UnsafeNativeMethods.sqlite3_column_count(stmt._sqlite_stmt);\r
+    }\r
+\r
+    internal override string ColumnName(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_name_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_name(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override TypeAffinity ColumnAffinity(SQLiteStatement stmt, int index)\r
+    {\r
+      return UnsafeNativeMethods.sqlite3_column_type(stmt._sqlite_stmt, index);\r
+    }\r
+\r
+    internal override string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity)\r
+    {\r
+      int len;\r
+#if !SQLITE_STANDARD\r
+      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype_interop(stmt._sqlite_stmt, index, out len);\r
+#else\r
+      len = -1;\r
+      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype(stmt._sqlite_stmt, index);\r
+#endif\r
+      nAffinity = ColumnAffinity(stmt, index);\r
+\r
+      if (p != IntPtr.Zero) return UTF8ToString(p, len);\r
+      else\r
+      {\r
+        string[] ar = stmt.TypeDefinitions;\r
+        if (ar != null)\r
+        {\r
+          if (index < ar.Length && ar[index] != null)\r
+            return ar[index];\r
+        }\r
+        return String.Empty;\r
+\r
+        //switch (nAffinity)\r
+        //{\r
+        //  case TypeAffinity.Int64:\r
+        //    return "BIGINT";\r
+        //  case TypeAffinity.Double:\r
+        //    return "DOUBLE";\r
+        //  case TypeAffinity.Blob:\r
+        //    return "BLOB";\r
+        //  default:\r
+        //    return "TEXT";\r
+        //}\r
+      }\r
+    }\r
+\r
+    internal override int ColumnIndex(SQLiteStatement stmt, string columnName)\r
+    {\r
+      int x = ColumnCount(stmt);\r
+\r
+      for (int n = 0; n < x; n++)\r
+      {\r
+        if (String.Compare(columnName, ColumnName(stmt, n), true, CultureInfo.InvariantCulture) == 0)\r
+          return n;\r
+      }\r
+      return -1;\r
+    }\r
+\r
+    internal override string ColumnOriginalName(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_origin_name_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_origin_name(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override string ColumnDatabaseName(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_database_name_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_database_name(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override string ColumnTableName(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_table_name_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_table_name(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override void ColumnMetaData(string dataBase, string table, string column, out string dataType, out string collateSequence, out bool notNull, out bool primaryKey, out bool autoIncrement)\r
+    {\r
+      IntPtr dataTypePtr;\r
+      IntPtr collSeqPtr;\r
+      int nnotNull;\r
+      int nprimaryKey;\r
+      int nautoInc;\r
+      int n;\r
+      int dtLen;\r
+      int csLen;\r
+\r
+#if !SQLITE_STANDARD\r
+      n = UnsafeNativeMethods.sqlite3_table_column_metadata_interop(_sql, ToUTF8(dataBase), ToUTF8(table), ToUTF8(column), out dataTypePtr, out collSeqPtr, out nnotNull, out nprimaryKey, out nautoInc, out dtLen, out csLen);\r
+#else\r
+      dtLen = -1;\r
+      csLen = -1;\r
+      n = UnsafeNativeMethods.sqlite3_table_column_metadata(_sql, ToUTF8(dataBase), ToUTF8(table), ToUTF8(column), out dataTypePtr, out collSeqPtr, out nnotNull, out nprimaryKey, out nautoInc);\r
+#endif\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+\r
+      dataType = UTF8ToString(dataTypePtr, dtLen);\r
+      collateSequence = UTF8ToString(collSeqPtr, csLen);\r
+\r
+      notNull = (nnotNull == 1);\r
+      primaryKey = (nprimaryKey == 1);\r
+      autoIncrement = (nautoInc == 1);\r
+    }\r
+\r
+    internal override double GetDouble(SQLiteStatement stmt, int index)\r
+    {\r
+      double value;\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+      value = UnsafeNativeMethods.sqlite3_column_double(stmt._sqlite_stmt, index);\r
+#else\r
+      UnsafeNativeMethods.sqlite3_column_double_interop(stmt._sqlite_stmt, index, out value);\r
+#endif\r
+      return value;\r
+    }\r
+\r
+    internal override int GetInt32(SQLiteStatement stmt, int index)\r
+    {\r
+      return UnsafeNativeMethods.sqlite3_column_int(stmt._sqlite_stmt, index);\r
+    }\r
+\r
+    internal override long GetInt64(SQLiteStatement stmt, int index)\r
+    {\r
+      long value;\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+      value = UnsafeNativeMethods.sqlite3_column_int64(stmt._sqlite_stmt, index);\r
+#else\r
+      UnsafeNativeMethods.sqlite3_column_int64_interop(stmt._sqlite_stmt, index, out value);\r
+#endif\r
+      return value;\r
+    }\r
+\r
+    internal override string GetText(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_text_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_column_text(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override DateTime GetDateTime(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return ToDateTime(UnsafeNativeMethods.sqlite3_column_text_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return ToDateTime(UnsafeNativeMethods.sqlite3_column_text(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override long GetBytes(SQLiteStatement stmt, int index, int nDataOffset, byte[] bDest, int nStart, int nLength)\r
+    {\r
+      IntPtr ptr;\r
+      int nlen;\r
+      int nCopied = nLength;\r
+\r
+      nlen = UnsafeNativeMethods.sqlite3_column_bytes(stmt._sqlite_stmt, index);\r
+      ptr = UnsafeNativeMethods.sqlite3_column_blob(stmt._sqlite_stmt, index);\r
+\r
+      if (bDest == null) return nlen;\r
+\r
+      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;\r
+      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;\r
+\r
+      if (nCopied > 0)\r
+        Marshal.Copy((IntPtr)(ptr.ToInt32() + nDataOffset), bDest, nStart, nCopied);\r
+      else nCopied = 0;\r
+\r
+      return nCopied;\r
+    }\r
+\r
+    internal override long GetChars(SQLiteStatement stmt, int index, int nDataOffset, char[] bDest, int nStart, int nLength)\r
+    {\r
+      int nlen;\r
+      int nCopied = nLength;\r
+\r
+      string str = GetText(stmt, index);\r
+      nlen = str.Length;\r
+\r
+      if (bDest == null) return nlen;\r
+\r
+      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;\r
+      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;\r
+\r
+      if (nCopied > 0)\r
+        str.CopyTo(nDataOffset, bDest, nStart, nCopied);\r
+      else nCopied = 0;\r
+\r
+      return nCopied;\r
+    }\r
+\r
+    internal override bool IsNull(SQLiteStatement stmt, int index)\r
+    {\r
+      return (ColumnAffinity(stmt, index) == TypeAffinity.Null);\r
+    }\r
+\r
+    internal override int AggregateCount(IntPtr context)\r
+    {\r
+      return UnsafeNativeMethods.sqlite3_aggregate_count(context);\r
+    }\r
+\r
+    internal override void CreateFunction(string strFunction, int nArgs, bool needCollSeq, SQLiteCallback func, SQLiteCallback funcstep, SQLiteFinalCallback funcfinal)\r
+    {\r
+      int n;\r
+\r
+#if !SQLITE_STANDARD\r
+      n = UnsafeNativeMethods.sqlite3_create_function_interop(_sql, ToUTF8(strFunction), nArgs, 4, IntPtr.Zero, func, funcstep, funcfinal, (needCollSeq == true) ? 1 : 0);\r
+      if (n == 0) n = UnsafeNativeMethods.sqlite3_create_function_interop(_sql, ToUTF8(strFunction), nArgs, 1, IntPtr.Zero, func, funcstep, funcfinal, (needCollSeq == true) ? 1 : 0);\r
+#else\r
+      n = UnsafeNativeMethods.sqlite3_create_function(_sql, ToUTF8(strFunction), nArgs, 4, IntPtr.Zero, func, funcstep, funcfinal);\r
+      if (n == 0) n = UnsafeNativeMethods.sqlite3_create_function(_sql, ToUTF8(strFunction), nArgs, 1, IntPtr.Zero, func, funcstep, funcfinal);\r
+#endif\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override void CreateCollation(string strCollation, SQLiteCollation func, SQLiteCollation func16)\r
+    {\r
+      int n = UnsafeNativeMethods.sqlite3_create_collation(_sql, ToUTF8(strCollation), 2, IntPtr.Zero, func16);\r
+      if (n == 0) UnsafeNativeMethods.sqlite3_create_collation(_sql, ToUTF8(strCollation), 1, IntPtr.Zero, func);\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override int ContextCollateCompare(CollationEncodingEnum enc, IntPtr context, string s1, string s2)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      byte[] b1;\r
+      byte[] b2;\r
+      System.Text.Encoding converter = null;\r
+\r
+      switch (enc)\r
+      {\r
+        case CollationEncodingEnum.UTF8:\r
+          converter = System.Text.Encoding.UTF8;\r
+          break;\r
+        case CollationEncodingEnum.UTF16LE:\r
+          converter = System.Text.Encoding.Unicode;\r
+          break;\r
+        case CollationEncodingEnum.UTF16BE:\r
+          converter = System.Text.Encoding.BigEndianUnicode;\r
+          break;\r
+      }\r
+\r
+      b1 = converter.GetBytes(s1);\r
+      b2 = converter.GetBytes(s2);\r
+\r
+      return UnsafeNativeMethods.sqlite3_context_collcompare(context, b1, b1.Length, b2, b2.Length);\r
+#else\r
+      throw new NotImplementedException();\r
+#endif\r
+    }\r
+\r
+    internal override int ContextCollateCompare(CollationEncodingEnum enc, IntPtr context, char[] c1, char[] c2)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      byte[] b1;\r
+      byte[] b2;\r
+      System.Text.Encoding converter = null;\r
+\r
+      switch (enc)\r
+      {\r
+        case CollationEncodingEnum.UTF8:\r
+          converter = System.Text.Encoding.UTF8;\r
+          break;\r
+        case CollationEncodingEnum.UTF16LE:\r
+          converter = System.Text.Encoding.Unicode;\r
+          break;\r
+        case CollationEncodingEnum.UTF16BE:\r
+          converter = System.Text.Encoding.BigEndianUnicode;\r
+          break;\r
+      }\r
+\r
+      b1 = converter.GetBytes(c1);\r
+      b2 = converter.GetBytes(c2);\r
+\r
+      return UnsafeNativeMethods.sqlite3_context_collcompare(context, b1, b1.Length, b2, b2.Length);\r
+#else\r
+      throw new NotImplementedException();\r
+#endif\r
+    }\r
+\r
+    internal override CollationSequence GetCollationSequence(SQLiteFunction func, IntPtr context)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      CollationSequence seq = new CollationSequence();\r
+      int len;\r
+      int type;\r
+      int enc;\r
+      IntPtr p = UnsafeNativeMethods.sqlite3_context_collseq(context, out type, out enc, out len);\r
+\r
+      if (p != null) seq.Name = UTF8ToString(p, len);\r
+      seq.Type = (CollationTypeEnum)type;\r
+      seq._func = func;\r
+      seq.Encoding = (CollationEncodingEnum)enc;\r
+\r
+      return seq;\r
+#else\r
+      throw new NotImplementedException();\r
+#endif\r
+    }\r
+\r
+    internal override long GetParamValueBytes(IntPtr p, int nDataOffset, byte[] bDest, int nStart, int nLength)\r
+    {\r
+      IntPtr ptr;\r
+      int nlen;\r
+      int nCopied = nLength;\r
+\r
+      nlen = UnsafeNativeMethods.sqlite3_value_bytes(p);\r
+      ptr = UnsafeNativeMethods.sqlite3_value_blob(p);\r
+\r
+      if (bDest == null) return nlen;\r
+\r
+      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;\r
+      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;\r
+\r
+      if (nCopied > 0)\r
+        Marshal.Copy((IntPtr)(ptr.ToInt32() + nDataOffset), bDest, nStart, nCopied);\r
+      else nCopied = 0;\r
+\r
+      return nCopied;\r
+    }\r
+\r
+    internal override double GetParamValueDouble(IntPtr ptr)\r
+    {\r
+      double value;\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+      value = UnsafeNativeMethods.sqlite3_value_double(ptr);\r
+#else\r
+      UnsafeNativeMethods.sqlite3_value_double_interop(ptr, out value);\r
+#endif\r
+      return value;\r
+    }\r
+\r
+    internal override int GetParamValueInt32(IntPtr ptr)\r
+    {\r
+      return UnsafeNativeMethods.sqlite3_value_int(ptr);\r
+    }\r
+\r
+    internal override long GetParamValueInt64(IntPtr ptr)\r
+    {\r
+      Int64 value;\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+      value = UnsafeNativeMethods.sqlite3_value_int64(ptr);\r
+#else\r
+      UnsafeNativeMethods.sqlite3_value_int64_interop(ptr, out value);\r
+#endif\r
+      return value;\r
+    }\r
+\r
+    internal override string GetParamValueText(IntPtr ptr)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_value_text_interop(ptr, out len), len);\r
+#else\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_value_text(ptr), -1);\r
+#endif\r
+    }\r
+\r
+    internal override TypeAffinity GetParamValueType(IntPtr ptr)\r
+    {\r
+      return UnsafeNativeMethods.sqlite3_value_type(ptr);\r
+    }\r
+\r
+    internal override void ReturnBlob(IntPtr context, byte[] value)\r
+    {\r
+      UnsafeNativeMethods.sqlite3_result_blob(context, value, value.Length, (IntPtr)(-1));\r
+    }\r
+\r
+    internal override void ReturnDouble(IntPtr context, double value)\r
+    {\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+      UnsafeNativeMethods.sqlite3_result_double(context, value);\r
+#else\r
+      UnsafeNativeMethods.sqlite3_result_double_interop(context, ref value);\r
+#endif\r
+    }\r
+\r
+    internal override void ReturnError(IntPtr context, string value)\r
+    {\r
+      UnsafeNativeMethods.sqlite3_result_error(context, ToUTF8(value), value.Length);\r
+    }\r
+\r
+    internal override void ReturnInt32(IntPtr context, int value)\r
+    {\r
+      UnsafeNativeMethods.sqlite3_result_int(context, value);\r
+    }\r
+\r
+    internal override void ReturnInt64(IntPtr context, long value)\r
+    {\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+      UnsafeNativeMethods.sqlite3_result_int64(context, value);\r
+#else\r
+      UnsafeNativeMethods.sqlite3_result_int64_interop(context, ref value);\r
+#endif\r
+    }\r
+\r
+    internal override void ReturnNull(IntPtr context)\r
+    {\r
+      UnsafeNativeMethods.sqlite3_result_null(context);\r
+    }\r
+\r
+    internal override void ReturnText(IntPtr context, string value)\r
+    {\r
+      byte[] b = ToUTF8(value);\r
+      UnsafeNativeMethods.sqlite3_result_text(context, ToUTF8(value), b.Length - 1, (IntPtr)(-1));\r
+    }\r
+\r
+    internal override IntPtr AggregateContext(IntPtr context)\r
+    {\r
+      return UnsafeNativeMethods.sqlite3_aggregate_context(context, 1);\r
+    }\r
+\r
+    internal override void SetPassword(byte[] passwordBytes)\r
+    {\r
+      int n = UnsafeNativeMethods.sqlite3_key(_sql, passwordBytes, passwordBytes.Length);\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override void ChangePassword(byte[] newPasswordBytes)\r
+    {\r
+      int n = UnsafeNativeMethods.sqlite3_rekey(_sql, newPasswordBytes, (newPasswordBytes == null) ? 0 : newPasswordBytes.Length);\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override void SetUpdateHook(SQLiteUpdateCallback func)\r
+    {\r
+      UnsafeNativeMethods.sqlite3_update_hook(_sql, func, IntPtr.Zero);\r
+    }\r
+\r
+    internal override void SetCommitHook(SQLiteCommitCallback func)\r
+    {\r
+      UnsafeNativeMethods.sqlite3_commit_hook(_sql, func, IntPtr.Zero);\r
+    }\r
+\r
+    internal override void SetRollbackHook(SQLiteRollbackCallback func)\r
+    {\r
+      UnsafeNativeMethods.sqlite3_rollback_hook(_sql, func, IntPtr.Zero);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Helper function to retrieve a column of data from an active statement.\r
+    /// </summary>\r
+    /// <param name="stmt">The statement being step()'d through</param>\r
+    /// <param name="index">The column index to retrieve</param>\r
+    /// <param name="typ">The type of data contained in the column.  If Uninitialized, this function will retrieve the datatype information.</param>\r
+    /// <returns>Returns the data in the column</returns>\r
+    internal override object GetValue(SQLiteStatement stmt, int index, SQLiteType typ)\r
+    {\r
+      if (IsNull(stmt, index)) return DBNull.Value;\r
+      TypeAffinity aff = typ.Affinity;\r
+      Type t = null;\r
+\r
+      if (typ.Type != DbType.Object)\r
+      {\r
+        t = SQLiteConvert.SQLiteTypeToType(typ);\r
+        aff = TypeToAffinity(t);\r
+      }\r
+\r
+      switch (aff)\r
+      {\r
+        case TypeAffinity.Blob:\r
+          if (typ.Type == DbType.Guid && typ.Affinity == TypeAffinity.Text)\r
+            return new Guid(GetText(stmt, index));\r
+\r
+          int n = (int)GetBytes(stmt, index, 0, null, 0, 0);\r
+          byte[] b = new byte[n];\r
+          GetBytes(stmt, index, 0, b, 0, n);\r
+\r
+          if (typ.Type == DbType.Guid && n == 16)\r
+            return new Guid(b);\r
+\r
+          return b;\r
+        case TypeAffinity.DateTime:\r
+          return GetDateTime(stmt, index);\r
+        case TypeAffinity.Double:\r
+          if (t == null) return GetDouble(stmt, index);\r
+          else\r
+            return Convert.ChangeType(GetDouble(stmt, index), t, null);\r
+        case TypeAffinity.Int64:\r
+          if (t == null) return GetInt64(stmt, index);\r
+          else\r
+            return Convert.ChangeType(GetInt64(stmt, index), t, null);\r
+        default:\r
+          return GetText(stmt, index);\r
+      }\r
+    }\r
+\r
+    internal override int GetCursorForTable(SQLiteStatement stmt, int db, int rootPage)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      return UnsafeNativeMethods.sqlite3_table_cursor(stmt._sqlite_stmt, db, rootPage);\r
+#else\r
+      return -1;\r
+#endif\r
+    }\r
+\r
+    internal override long GetRowIdForCursor(SQLiteStatement stmt, int cursor)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      long rowid;\r
+      int rc = UnsafeNativeMethods.sqlite3_cursor_rowid(stmt._sqlite_stmt, cursor, out rowid);\r
+      if (rc == 0) return rowid;\r
+\r
+      return 0;\r
+#else\r
+      return 0;\r
+#endif\r
+    }\r
+\r
+    internal override void GetIndexColumnExtendedInfo(string database, string index, string column, out int sortMode, out int onError, out string collationSequence)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      IntPtr coll;\r
+      int colllen;\r
+      int rc;\r
+\r
+      rc = UnsafeNativeMethods.sqlite3_index_column_info_interop(_sql, ToUTF8(database), ToUTF8(index), ToUTF8(column), out sortMode, out onError, out coll, out colllen);\r
+      if (rc != 0) throw new SQLiteException(rc, "");\r
+\r
+      collationSequence = UTF8ToString(coll, colllen);\r
+#else\r
+      sortMode = 0;\r
+      onError = 2;\r
+      collationSequence = "BINARY";\r
+#endif\r
+    }\r
+  }\r
+}\r
index d109c963f4a473557139c2142a7d47f94620dfe4..afc36ea116933978a2be1d05a862bd74cf796db6 100644 (file)
-//
-// Mono.Data.Sqlite.SQLite3_UTF16.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Runtime.InteropServices;
-
-  /// <summary>
-  /// Alternate Sqlite3 object, overriding many text behaviors to support UTF-16 (Unicode)
-  /// </summary>
-  internal class Sqlite3_UTF16 : Sqlite3
-  {
-    internal Sqlite3_UTF16(SqliteDateFormats fmt)
-      : base(fmt)
-    {
-    }
-
-    /// <summary>
-    /// Overrides SqliteConvert.ToString() to marshal UTF-16 strings instead of UTF-8
-    /// </summary>
-    /// <param name="b">A pointer to a UTF-16 string</param>
-    /// <param name="nbytelen">The length (IN BYTES) of the string</param>
-    /// <returns>A .NET string</returns>
-    public override string ToString(IntPtr b)
-    {
-      return Marshal.PtrToStringUni(b);
-    }
-
-    internal override string Version
-    {
-      get
-      {
-        return base.ToString(UnsafeNativeMethods.sqlite3_libversion());
-      }
-    }
-
-    internal override void Open(string strFilename)
-    {
-      if (_sql != IntPtr.Zero) return;
-      int n = UnsafeNativeMethods.sqlite3_open16(strFilename, out _sql);
-      if (n > 0) throw new SqliteException(n, SqliteLastError());
-
-      _functionsArray = SqliteFunction.BindFunctions(this);
-    }
-
-    internal override string SqliteLastError()
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_errmsg16(_sql));
-    }
-
-    internal override void Bind_DateTime(SqliteStatement stmt, int index, DateTime dt)
-    {
-      Bind_Text(stmt, index, ToString(dt));
-    }
-
-    internal override string Bind_ParamName(SqliteStatement stmt, int index)
-    {
-      return base.ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name(stmt._sqlite_stmt, index));
-    }
-
-    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, -1);
-      if (n > 0) throw new SqliteException(n, SqliteLastError());
-    }
-
-    internal override string ColumnName(SqliteStatement stmt, int index)
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_column_name16(stmt._sqlite_stmt, index));
-    }
-
-    internal override DateTime GetDateTime(SqliteStatement stmt, int index)
-    {
-      return ToDateTime(GetText(stmt, index));
-    }
-    internal override string GetText(SqliteStatement stmt, int index)
-    {
-           return ToString (UnsafeNativeMethods.sqlite3_column_text16(stmt._sqlite_stmt, index));
-    }
-
-    internal override string ColumnOriginalName(SqliteStatement stmt, int index)
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_column_origin_name16(stmt._sqlite_stmt, index));
-    }
-
-    internal override string ColumnDatabaseName(SqliteStatement stmt, int index)
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_column_database_name16(stmt._sqlite_stmt, index));
-    }
-
-    internal override string ColumnTableName(SqliteStatement stmt, int index)
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_column_table_name16(stmt._sqlite_stmt, index));
-    }
-
-    internal override void CreateFunction(string strFunction, int nArgs, SqliteCallback func, SqliteCallback funcstep, SqliteFinalCallback funcfinal)
-    {
-      int n = UnsafeNativeMethods.sqlite3_create_function16(_sql, strFunction, nArgs, 4, IntPtr.Zero, func, funcstep, funcfinal);
-      if (n > 0) throw new SqliteException(n, SqliteLastError());
-    }
-
-    internal override void CreateCollation(string strCollation, SqliteCollation func)
-    {
-      int n = UnsafeNativeMethods.sqlite3_create_collation16(_sql, strCollation, 4, IntPtr.Zero, func);
-      if (n > 0) throw new SqliteException(n, SqliteLastError());
-    }
-
-    internal override string GetParamValueText(IntPtr ptr)
-    {
-      return ToString(UnsafeNativeMethods.sqlite3_value_text16(ptr));
-    }
-
-    internal override void ReturnError(IntPtr context, string value)
-    {
-      UnsafeNativeMethods.sqlite3_result_error16(context, value, value.Length);
-    }
-
-    internal override void ReturnText(IntPtr context, string value)
-    {
-      UnsafeNativeMethods.sqlite3_result_text16(context, value, value.Length, (IntPtr)(-1));
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Runtime.InteropServices;\r
+\r
+  /// <summary>\r
+  /// Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode)\r
+  /// </summary>\r
+  internal class SQLite3_UTF16 : SQLite3\r
+  {\r
+    internal SQLite3_UTF16(SQLiteDateFormats fmt)\r
+      : base(fmt)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8\r
+    /// </summary>\r
+    /// <param name="b">A pointer to a UTF-16 string</param>\r
+    /// <param name="nbytelen">The length (IN BYTES) of the string</param>\r
+    /// <returns>A .NET string</returns>\r
+    public override string ToString(IntPtr b, int nbytelen)\r
+    {\r
+      return UTF16ToString(b, nbytelen);\r
+    }\r
+\r
+    public static string UTF16ToString(IntPtr b, int nbytelen)\r
+    {\r
+      if (nbytelen == 0 || b == IntPtr.Zero) return "";\r
+\r
+      if (nbytelen == -1)\r
+        return Marshal.PtrToStringUni(b);\r
+      else\r
+        return Marshal.PtrToStringUni(b, nbytelen / 2);\r
+    }\r
+\r
+    internal override void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool)\r
+    {\r
+      if (_sql != null) return;\r
+\r
+      _usePool = usePool;\r
+      if (usePool)\r
+      {\r
+        _fileName = strFilename;\r
+        _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion);\r
+      }\r
+\r
+      if (_sql == null)\r
+      {\r
+        IntPtr db;\r
+\r
+#if !SQLITE_STANDARD\r
+        int n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), (int)flags, out db);\r
+#else\r
+        if ((flags & SQLiteOpenFlagsEnum.Create) == 0 && System.IO.File.Exists(strFilename) == false)\r
+          throw new SQLiteException((int)SQLiteErrorCode.CantOpen, strFilename);\r
+\r
+        int n = UnsafeNativeMethods.sqlite3_open16(strFilename, out db);\r
+#endif\r
+        if (n > 0) throw new SQLiteException(n, null);\r
+\r
+        _sql = db;\r
+      }\r
+      _functionsArray = SQLiteFunction.BindFunctions(this);\r
+    }\r
+\r
+    internal override void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt)\r
+    {\r
+      Bind_Text(stmt, index, ToString(dt));\r
+    }\r
+\r
+    internal override void Bind_Text(SQLiteStatement stmt, int index, string value)\r
+    {\r
+      int n = UnsafeNativeMethods.sqlite3_bind_text16(stmt._sqlite_stmt, index, value, value.Length * 2, (IntPtr)(-1));\r
+      if (n > 0) throw new SQLiteException(n, SQLiteLastError());\r
+    }\r
+\r
+    internal override DateTime GetDateTime(SQLiteStatement stmt, int index)\r
+    {\r
+      return ToDateTime(GetText(stmt, index));\r
+    }\r
+\r
+    internal override string ColumnName(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_name16_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_name16(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override string GetText(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_text16_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_text16(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override string ColumnOriginalName(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_origin_name16_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_origin_name16(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override string ColumnDatabaseName(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_database_name16_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_database_name16(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override string ColumnTableName(SQLiteStatement stmt, int index)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_table_name16_interop(stmt._sqlite_stmt, index, out len), len);\r
+#else\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_table_name16(stmt._sqlite_stmt, index), -1);\r
+#endif\r
+    }\r
+\r
+    internal override string GetParamValueText(IntPtr ptr)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_value_text16_interop(ptr, out len), len);\r
+#else\r
+      return UTF16ToString(UnsafeNativeMethods.sqlite3_value_text16(ptr), -1);\r
+#endif\r
+    }\r
+\r
+    internal override void ReturnError(IntPtr context, string value)\r
+    {\r
+      UnsafeNativeMethods.sqlite3_result_error16(context, value, value.Length * 2);\r
+    }\r
+\r
+    internal override void ReturnText(IntPtr context, string value)\r
+    {\r
+      UnsafeNativeMethods.sqlite3_result_text16(context, value, value.Length * 2, (IntPtr)(-1));\r
+    }\r
+  }\r
+}\r
index 42d3ad3eba4bd60425019002fbcbc8b4d26e5fef..44bd675d89d9167145ba1ed586afe27f13f615a4 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteBase.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Runtime.InteropServices;
-  using System.Collections.Generic;
-
-  /// <summary>
-  /// This internal class provides the foundation of Sqlite support.  It defines all the abstract members needed to implement
-  /// a Sqlite data provider, and inherits from SqliteConvert which allows for simple translations of string to and from Sqlite.
-  /// </summary>
-  internal abstract class SqliteBase : SqliteConvert, IDisposable
-  {
-    internal SqliteBase(SqliteDateFormats fmt)
-      : base(fmt) {}
-
-    /// <summary>
-    /// Returns a string representing the active version of Sqlite
-    /// </summary>
-    internal abstract string Version { get; }
-    /// <summary>
-    /// Returns the number of changes the last executing insert/update caused.
-    /// </summary>
-    internal abstract int    Changes { get; }
-    /// <summary>
-    /// Opens a database.
-    /// </summary>
-    /// <remarks>
-    /// 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.
-    /// </remarks>
-    /// <param name="strFilename">The filename of the database to open.  Sqlite automatically creates it if it doesn't exist.</param>
-    internal abstract void   Open(string strFilename);
-    /// <summary>
-    /// Closes the currently-open database.
-    /// </summary>
-    /// <remarks>
-    /// After the database has been closed implemeters should call SqliteFunction.UnbindFunctions() to deallocate all interop allocated
-    /// memory associated with the user-defined functions and collating sequences tied to the closed connection.
-    /// </remarks>
-    internal abstract void   Close();
-    /// <summary>
-    /// Sets the busy timeout on the connection.  SqliteCommand will call this before executing any command.
-    /// </summary>
-    /// <param name="nTimeoutMS">The number of milliseconds to wait before returning SQLITE_BUSY</param>
-    internal abstract void   SetTimeout(int nTimeoutMS);
-    /// <summary>
-    /// Returns the text of the last error issued by Sqlite
-    /// </summary>
-    /// <returns></returns>
-    internal abstract string SqliteLastError();
-
-    /// <summary>
-    /// Prepares a SQL statement for execution.
-    /// </summary>
-    /// <param name="strSql">The SQL command text to prepare</param>
-    /// <param name="previous">The previous statement in a multi-statement command, or null if no previous statement exists</param>
-    /// <param name="strRemain">The remainder of the statement that was not processed.  Each call to prepare parses the
-    /// SQL up to to either the end of the text or to the first semi-colon delimiter.  The remaining text is returned
-    /// here for a subsequent call to Prepare() until all the text has been processed.</param>
-    /// <returns>Returns an initialized SqliteStatement.</returns>
-    internal abstract SqliteStatement Prepare(string strSql, SqliteStatement previous, out string strRemain);
-    /// <summary>
-    /// Steps through a prepared statement.
-    /// </summary>
-    /// <param name="stmt">The SqliteStatement to step through</param>
-    /// <returns>True if a row was returned, False if not.</returns>
-    internal abstract bool Step(SqliteStatement stmt);
-    /// <summary>
-    /// Finalizes a prepared statement.
-    /// </summary>
-    /// <param name="stmt">The statement to finalize</param>
-    internal abstract void FinalizeStatement(SqliteStatement stmt);
-    /// <summary>
-    /// Resets a prepared statement so it can be executed again.  If the error returned is SQLITE_SCHEMA, 
-    /// transparently attempt to rebuild the SQL statement and throw an error if that was not possible.
-    /// </summary>
-    /// <param name="stmt">The statement to reset</param>
-    /// <returns>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</returns>
-    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_Int64(SqliteStatement stmt, int index, Int64 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 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);
-    internal abstract int    ColumnIndex(SqliteStatement stmt, string columnName);
-    internal abstract string ColumnOriginalName(SqliteStatement stmt, int index);
-    internal abstract string ColumnDatabaseName(SqliteStatement stmt, int index);
-    internal abstract string ColumnTableName(SqliteStatement stmt, int index);
-    internal abstract void ColumnMetaData(string dataBase, string table, string column, out string dataType, out string collateSequence, out bool notNull, out bool primaryKey, out bool autoIncrement);
-
-    internal abstract double   GetDouble(SqliteStatement stmt, int index);
-    internal abstract Int32    GetInt32(SqliteStatement stmt, int index);
-    internal abstract Int64    GetInt64(SqliteStatement stmt, int index);
-    internal abstract string   GetText(SqliteStatement stmt, int index);
-    internal abstract long     GetBytes(SqliteStatement stmt, int index, int nDataoffset, byte[] bDest, int nStart, int nLength);
-    internal abstract long     GetChars(SqliteStatement stmt, int index, int nDataoffset, char[] bDest, int nStart, int nLength);
-    internal abstract DateTime GetDateTime(SqliteStatement stmt, int index);
-    internal abstract bool     IsNull(SqliteStatement stmt, int index);
-
-    internal abstract void  CreateCollation(string strCollation, SqliteCollation func);
-    internal abstract void  CreateFunction(string strFunction, int nArgs, SqliteCallback func, SqliteCallback funcstep, SqliteFinalCallback funcfinal);
-
-    internal abstract int AggregateCount(IntPtr context);
-    internal abstract IntPtr AggregateContext(IntPtr context);
-
-    internal abstract long   GetParamValueBytes(IntPtr ptr, int nDataOffset, byte[] bDest, int nStart, int nLength);
-    internal abstract double GetParamValueDouble(IntPtr ptr);
-    internal abstract int    GetParamValueInt32(IntPtr ptr);
-    internal abstract Int64  GetParamValueInt64(IntPtr ptr);
-    internal abstract string GetParamValueText(IntPtr ptr);
-    internal abstract TypeAffinity GetParamValueType(IntPtr ptr);
-
-    internal abstract void ReturnBlob(IntPtr context, byte[] value);
-    internal abstract void ReturnDouble(IntPtr context, double value);
-    internal abstract void ReturnError(IntPtr context, string value);
-    internal abstract void ReturnInt32(IntPtr context, Int32 value);
-    internal abstract void ReturnInt64(IntPtr context, Int64 value);
-    internal abstract void ReturnNull(IntPtr context);
-    internal abstract void ReturnText(IntPtr context, string value);
-
-    internal abstract void SetUpdateHook(SqliteUpdateCallback func);
-    internal abstract void SetCommitHook(SqliteCommitCallback func);
-    internal abstract void SetRollbackHook(SqliteRollbackCallback func);
-
-    internal abstract int GetLastInsertRowId ();
-    
-    internal abstract object GetValue(SqliteStatement stmt, int index, ref SqliteType typ);
-
-    protected virtual void Dispose(bool bDisposing)
-    {
-    }
-
-    public void Dispose()
-    {
-      Dispose(true);
-      GC.SuppressFinalize(this);
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Runtime.InteropServices;\r
+  using System.Collections.Generic;\r
+\r
+  /// <summary>\r
+  /// This internal class provides the foundation of SQLite support.  It defines all the abstract members needed to implement\r
+  /// a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite.\r
+  /// </summary>\r
+  internal abstract class SQLiteBase : SQLiteConvert, IDisposable\r
+  {\r
+    internal SQLiteBase(SQLiteDateFormats fmt)\r
+      : base(fmt) { }\r
+\r
+    static internal object _lock = new object();\r
+\r
+    /// <summary>\r
+    /// Returns a string representing the active version of SQLite\r
+    /// </summary>\r
+    internal abstract string Version { get; }\r
+    /// <summary>\r
+    /// Returns the number of changes the last executing insert/update caused.\r
+    /// </summary>\r
+    internal abstract int Changes { get; }\r
+    /// <summary>\r
+    /// Opens a database.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection\r
+    /// to bind all attributed user-defined functions and collating sequences to the new connection.\r
+    /// </remarks>\r
+    /// <param name="strFilename">The filename of the database to open.  SQLite automatically creates it if it doesn't exist.</param>\r
+    /// <param name="flags">The open flags to use when creating the connection</param>\r
+    /// <param name="maxPoolSize">The maximum size of the pool for the given filename</param>\r
+    /// <param name="usePool">If true, the connection can be pulled from the connection pool</param>\r
+    internal abstract void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool);\r
+    /// <summary>\r
+    /// Closes the currently-open database.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated\r
+    /// memory associated with the user-defined functions and collating sequences tied to the closed connection.\r
+    /// </remarks>\r
+    internal abstract void Close();\r
+    /// <summary>\r
+    /// Sets the busy timeout on the connection.  SQLiteCommand will call this before executing any command.\r
+    /// </summary>\r
+    /// <param name="nTimeoutMS">The number of milliseconds to wait before returning SQLITE_BUSY</param>\r
+    internal abstract void SetTimeout(int nTimeoutMS);\r
+    /// <summary>\r
+    /// Returns the text of the last error issued by SQLite\r
+    /// </summary>\r
+    /// <returns></returns>\r
+    internal abstract string SQLiteLastError();\r
+\r
+    /// <summary>\r
+    /// When pooling is enabled, force this connection to be disposed rather than returned to the pool\r
+    /// </summary>\r
+    internal abstract void ClearPool();\r
+\r
+    /// <summary>\r
+    /// Prepares a SQL statement for execution.\r
+    /// </summary>\r
+    /// <param name="cnn">The source connection preparing the command.  Can be null for any caller except LINQ</param>\r
+    /// <param name="strSql">The SQL command text to prepare</param>\r
+    /// <param name="previous">The previous statement in a multi-statement command, or null if no previous statement exists</param>\r
+    /// <param name="timeoutMS">The timeout to wait before aborting the prepare</param>\r
+    /// <param name="strRemain">The remainder of the statement that was not processed.  Each call to prepare parses the\r
+    /// SQL up to to either the end of the text or to the first semi-colon delimiter.  The remaining text is returned\r
+    /// here for a subsequent call to Prepare() until all the text has been processed.</param>\r
+    /// <returns>Returns an initialized SQLiteStatement.</returns>\r
+    internal abstract SQLiteStatement Prepare(SQLiteConnection cnn, string strSql, SQLiteStatement previous, uint timeoutMS, out string strRemain);\r
+    /// <summary>\r
+    /// Steps through a prepared statement.\r
+    /// </summary>\r
+    /// <param name="stmt">The SQLiteStatement to step through</param>\r
+    /// <returns>True if a row was returned, False if not.</returns>\r
+    internal abstract bool Step(SQLiteStatement stmt);\r
+    /// <summary>\r
+    /// Resets a prepared statement so it can be executed again.  If the error returned is SQLITE_SCHEMA, \r
+    /// transparently attempt to rebuild the SQL statement and throw an error if that was not possible.\r
+    /// </summary>\r
+    /// <param name="stmt">The statement to reset</param>\r
+    /// <returns>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</returns>\r
+    internal abstract int Reset(SQLiteStatement stmt);\r
+    internal abstract void Cancel();\r
+\r
+    internal abstract void Bind_Double(SQLiteStatement stmt, int index, double value);\r
+    internal abstract void Bind_Int32(SQLiteStatement stmt, int index, Int32 value);\r
+    internal abstract void Bind_Int64(SQLiteStatement stmt, int index, Int64 value);\r
+    internal abstract void Bind_Text(SQLiteStatement stmt, int index, string value);\r
+    internal abstract void Bind_Blob(SQLiteStatement stmt, int index, byte[] blobData);\r
+    internal abstract void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt);\r
+    internal abstract void Bind_Null(SQLiteStatement stmt, int index);\r
+\r
+    internal abstract int Bind_ParamCount(SQLiteStatement stmt);\r
+    internal abstract string Bind_ParamName(SQLiteStatement stmt, int index);\r
+    internal abstract int Bind_ParamIndex(SQLiteStatement stmt, string paramName);\r
+\r
+    internal abstract int ColumnCount(SQLiteStatement stmt);\r
+    internal abstract string ColumnName(SQLiteStatement stmt, int index);\r
+    internal abstract TypeAffinity ColumnAffinity(SQLiteStatement stmt, int index);\r
+    internal abstract string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity);\r
+    internal abstract int ColumnIndex(SQLiteStatement stmt, string columnName);\r
+    internal abstract string ColumnOriginalName(SQLiteStatement stmt, int index);\r
+    internal abstract string ColumnDatabaseName(SQLiteStatement stmt, int index);\r
+    internal abstract string ColumnTableName(SQLiteStatement stmt, int index);\r
+    internal abstract void ColumnMetaData(string dataBase, string table, string column, out string dataType, out string collateSequence, out bool notNull, out bool primaryKey, out bool autoIncrement);\r
+    internal abstract void GetIndexColumnExtendedInfo(string database, string index, string column, out int sortMode, out int onError, out string collationSequence);\r
+\r
+    internal abstract double GetDouble(SQLiteStatement stmt, int index);\r
+    internal abstract Int32 GetInt32(SQLiteStatement stmt, int index);\r
+    internal abstract Int64 GetInt64(SQLiteStatement stmt, int index);\r
+    internal abstract string GetText(SQLiteStatement stmt, int index);\r
+    internal abstract long GetBytes(SQLiteStatement stmt, int index, int nDataoffset, byte[] bDest, int nStart, int nLength);\r
+    internal abstract long GetChars(SQLiteStatement stmt, int index, int nDataoffset, char[] bDest, int nStart, int nLength);\r
+    internal abstract DateTime GetDateTime(SQLiteStatement stmt, int index);\r
+    internal abstract bool IsNull(SQLiteStatement stmt, int index);\r
+\r
+    internal abstract void CreateCollation(string strCollation, SQLiteCollation func, SQLiteCollation func16);\r
+    internal abstract void CreateFunction(string strFunction, int nArgs, bool needCollSeq, SQLiteCallback func, SQLiteCallback funcstep, SQLiteFinalCallback funcfinal);\r
+    internal abstract CollationSequence GetCollationSequence(SQLiteFunction func, IntPtr context);\r
+    internal abstract int ContextCollateCompare(CollationEncodingEnum enc, IntPtr context, string s1, string s2);\r
+    internal abstract int ContextCollateCompare(CollationEncodingEnum enc, IntPtr context, char[] c1, char[] c2);\r
+\r
+    internal abstract int AggregateCount(IntPtr context);\r
+    internal abstract IntPtr AggregateContext(IntPtr context);\r
+\r
+    internal abstract long GetParamValueBytes(IntPtr ptr, int nDataOffset, byte[] bDest, int nStart, int nLength);\r
+    internal abstract double GetParamValueDouble(IntPtr ptr);\r
+    internal abstract int GetParamValueInt32(IntPtr ptr);\r
+    internal abstract Int64 GetParamValueInt64(IntPtr ptr);\r
+    internal abstract string GetParamValueText(IntPtr ptr);\r
+    internal abstract TypeAffinity GetParamValueType(IntPtr ptr);\r
+\r
+    internal abstract void ReturnBlob(IntPtr context, byte[] value);\r
+    internal abstract void ReturnDouble(IntPtr context, double value);\r
+    internal abstract void ReturnError(IntPtr context, string value);\r
+    internal abstract void ReturnInt32(IntPtr context, Int32 value);\r
+    internal abstract void ReturnInt64(IntPtr context, Int64 value);\r
+    internal abstract void ReturnNull(IntPtr context);\r
+    internal abstract void ReturnText(IntPtr context, string value);\r
+\r
+    internal abstract void SetPassword(byte[] passwordBytes);\r
+    internal abstract void ChangePassword(byte[] newPasswordBytes);\r
+\r
+    internal abstract void SetUpdateHook(SQLiteUpdateCallback func);\r
+    internal abstract void SetCommitHook(SQLiteCommitCallback func);\r
+    internal abstract void SetRollbackHook(SQLiteRollbackCallback func);\r
+\r
+    internal abstract int GetCursorForTable(SQLiteStatement stmt, int database, int rootPage);\r
+    internal abstract long GetRowIdForCursor(SQLiteStatement stmt, int cursor);\r
+\r
+    internal abstract object GetValue(SQLiteStatement stmt, int index, SQLiteType typ);\r
+\r
+    protected virtual void Dispose(bool bDisposing)\r
+    {\r
+    }\r
+\r
+    public void Dispose()\r
+    {\r
+      Dispose(true);\r
+    }\r
+\r
+    // These statics are here for lack of a better place to put them.\r
+    // They exist here because they are called during the finalization of\r
+    // a SQLiteStatementHandle, SQLiteConnectionHandle, and SQLiteFunctionCookieHandle.\r
+    // Therefore these functions have to be static, and have to be low-level.\r
+\r
+    internal static string SQLiteLastError(SQLiteConnectionHandle db)\r
+    {\r
+#if !SQLITE_STANDARD\r
+      int len;\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(db, out len), len);\r
+#else\r
+      return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1);\r
+#endif\r
+    }\r
+\r
+    internal static void FinalizeStatement(SQLiteStatementHandle stmt)\r
+    {\r
+      lock (_lock)\r
+      {\r
+#if !SQLITE_STANDARD\r
+        int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt);\r
+#else\r
+      int n = UnsafeNativeMethods.sqlite3_finalize(stmt);\r
+#endif\r
+        if (n > 0) throw new SQLiteException(n, null);\r
+      }\r
+    }\r
+\r
+    internal static void CloseConnection(SQLiteConnectionHandle db)\r
+    {\r
+      lock (_lock)\r
+      {\r
+#if !SQLITE_STANDARD\r
+        int n = UnsafeNativeMethods.sqlite3_close_interop(db);\r
+#else\r
+      ResetConnection(db);\r
+      int n = UnsafeNativeMethods.sqlite3_close(db);\r
+#endif\r
+        if (n > 0) throw new SQLiteException(n, SQLiteLastError(db));\r
+      }\r
+    }\r
+\r
+    internal static void ResetConnection(SQLiteConnectionHandle db)\r
+    {\r
+      lock (_lock)\r
+      {\r
+        IntPtr stmt = IntPtr.Zero;\r
+\r
+        do\r
+        {\r
+          stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt);\r
+          if (stmt != IntPtr.Zero)\r
+          {\r
+#if !SQLITE_STANDARD\r
+            UnsafeNativeMethods.sqlite3_reset_interop(stmt);\r
+#else\r
+          UnsafeNativeMethods.sqlite3_reset(stmt);\r
+#endif\r
+          }\r
+        } while (stmt != IntPtr.Zero);\r
+\r
+        // Not overly concerned with the return value from a rollback.\r
+        UnsafeNativeMethods.sqlite3_exec(db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero, out stmt);\r
+      }\r
+    }\r
+  }\r
+\r
+  internal interface ISQLiteSchemaExtensions\r
+  {\r
+    void BuildTempSchema(SQLiteConnection cnn);\r
+  }\r
+\r
+  [Flags]\r
+  internal enum SQLiteOpenFlagsEnum\r
+  {\r
+    None = 0,\r
+    ReadOnly = 0x01,\r
+    ReadWrite = 0x02,\r
+    Create = 0x04,\r
+    SharedCache = 0x01000000,\r
+    Default = 0x06,\r
+  }\r
+}\r
index 1dae2a3d645aeca343fa4614c5925793966e6ca2..7f4bebe6a10e252d00c321be321611cba64b92d7 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteCommand.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Data.Common;
-  using System.Collections.Generic;
-  using System.ComponentModel;
-
-  /// <summary>
-  /// Sqlite implementation of DbCommand.
-  /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-  [Designer("Sqlite.Designer.SqliteCommandDesigner, Sqlite.Designer, Version=1.0.31.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139"), ToolboxItem(true)]
-#endif
-  public sealed class SqliteCommand : DbCommand, ICloneable
-  {
-    /// <summary>
-    /// The command text this command is based on
-    /// </summary>
-    private string _commandText;
-    /// <summary>
-    /// The connection the command is associated with
-    /// </summary>
-    private SqliteConnection _cnn;
-    /// <summary>
-    /// Indicates whether or not a DataReader is active on the command.
-    /// </summary>
-    private SqliteDataReader _activeReader;
-    /// <summary>
-    /// The timeout for the command, kludged because Sqlite doesn't support per-command timeout values
-    /// </summary>
-    internal int _commandTimeout;
-    /// <summary>
-    /// Designer support
-    /// </summary>
-    private bool _designTimeVisible;
-    /// <summary>
-    /// Used by DbDataAdapter to determine updating behavior
-    /// </summary>
-    private UpdateRowSource _updateRowSource;
-    /// <summary>
-    /// The collection of parameters for the command
-    /// </summary>
-    private SqliteParameterCollection _parameterCollection;
-    /// <summary>
-    /// The SQL command text, broken into individual SQL statements as they are executed
-    /// </summary>
-    internal List<SqliteStatement> _statementList;
-    /// <summary>
-    /// Unprocessed SQL text that has not been executed
-    /// </summary>
-    internal string _remainingText;
-    /// <summary>
-    /// Transaction associated with this command
-    /// </summary>
-    private SqliteTransaction _transaction;
-
-    ///<overloads>
-    /// Constructs a new SqliteCommand
-    /// </overloads>
-    /// <summary>
-    /// Default constructor
-    /// </summary>
-    public SqliteCommand() :this(null, null)
-    {
-    }
-
-    /// <summary>
-    /// Initializes the command with the given command text
-    /// </summary>
-    /// <param name="commandText">The SQL command text</param>
-    public SqliteCommand(string commandText) 
-      : this(commandText, null, null)
-    {
-    }
-
-    /// <summary>
-    /// Initializes the command with the given SQL command text and attach the command to the specified
-    /// connection.
-    /// </summary>
-    /// <param name="commandText">The SQL command text</param>
-    /// <param name="connection">The connection to associate with the command</param>
-    public SqliteCommand(string commandText, SqliteConnection connection)
-      : this(commandText, connection, null)
-    {
-    }
-
-    /// <summary>
-    /// Initializes the command and associates it with the specified connection.
-    /// </summary>
-    /// <param name="connection">The connection to associate with the command</param>
-    public SqliteCommand(SqliteConnection connection) 
-      : this(null, connection, null)
-    {
-    }
-
-    private SqliteCommand(SqliteCommand source) : this(source.CommandText, source.Connection, source.Transaction)
-    {
-      CommandTimeout = source.CommandTimeout;
-      DesignTimeVisible = source.DesignTimeVisible;
-      UpdatedRowSource = source.UpdatedRowSource;
-
-      foreach (SqliteParameter param in source._parameterCollection)
-      {
-        Parameters.Add(param.Clone());
-      }
-    }
-
-    /// <summary>
-    /// Initializes a command with the given SQL, connection and transaction
-    /// </summary>
-    /// <param name="commandText">The SQL command text</param>
-    /// <param name="connection">The connection to associate with the command</param>
-    /// <param name="transaction">The transaction the command should be associated with</param>
-    public SqliteCommand(string commandText, SqliteConnection connection, SqliteTransaction transaction)
-    {
-      _statementList = null;
-      _activeReader = null;
-      _commandTimeout = connection != null ? connection._busyTimeout : 30;
-      _parameterCollection = new SqliteParameterCollection(this);
-      _designTimeVisible = true;
-      _updateRowSource = UpdateRowSource.FirstReturnedRecord;
-      _transaction = null;
-
-      if (commandText != null)
-        CommandText = commandText;
-
-      if (connection != null)
-        DbConnection = connection;
-
-      if (transaction != null)
-        Transaction = transaction;
-    }
-
-    /// <summary>
-    /// Disposes of the command and clears all member variables
-    /// </summary>
-    /// <param name="disposing">Whether or not the class is being explicitly or implicitly disposed</param>
-    protected override void Dispose(bool disposing)
-    {
-      base.Dispose(disposing);
-
-      // If a reader is active on this command, don't destroy it completely
-      if (_activeReader != null)
-      {
-        _activeReader._disposeCommand = true;
-        return;
-      }
-
-      Connection = null;
-      _parameterCollection.Clear();
-      _commandText = null;
-    }
-
-    /// <summary>
-    /// Clears and destroys all statements currently prepared
-    /// </summary>
-    internal void ClearCommands()
-    {
-      if (_activeReader != null)
-        _activeReader.Close();
-
-      if (_statementList == null) return;
-
-      int x = _statementList.Count;
-      for (int n = 0; n < x; n++)
-        _statementList[n].Dispose();
-
-      _statementList = null;
-
-      _parameterCollection.Unbind();
-    }
-
-    /// <summary>
-    /// Builds an array of prepared statements for each complete SQL statement in the command text
-    /// </summary>
-    internal SqliteStatement BuildNextCommand()
-    {
-      SqliteStatement stmt = null;
-
-      try
-      {
-        if (_statementList == null)
-          _remainingText = _commandText;
-
-        stmt = _cnn._sql.Prepare(_remainingText, (_statementList == null) ? null : _statementList[_statementList.Count - 1], out _remainingText);
-        if (stmt != null)
-        {
-          stmt._command = this;
-          if (_statementList == null)
-            _statementList = new List<SqliteStatement>();
-
-          _statementList.Add(stmt);
-
-          _parameterCollection.MapParameters(stmt);
-          stmt.BindParameters();
-        }        
-        return stmt;
-      }
-      catch (Exception)
-      {
-        if (stmt != null)
-        {
-          if (_statementList.Contains(stmt))
-            _statementList.Remove(stmt);
-
-          stmt.Dispose();
-        }
-
-        // If we threw an error compiling the statement, we cannot continue on so set the remaining text to null.
-        _remainingText = null;
-
-        throw;
-      }
-    }
-
-    internal SqliteStatement GetStatement(int index)
-    {
-      // Haven't built any statements yet
-      if (_statementList == null) return BuildNextCommand();
-
-      // If we're at the last built statement and want the next unbuilt statement, then build it
-      if (index == _statementList.Count)
-      {
-        if (String.IsNullOrEmpty(_remainingText) == false) return BuildNextCommand();
-        else return null; // No more commands
-      }
-
-      SqliteStatement stmt = _statementList[index];
-      stmt.BindParameters();
-
-      return stmt;
-    }
-
-    /// <summary>
-    /// Not implemented
-    /// </summary>
-    public override void Cancel()
-    {
-    }
-
-    /// <summary>
-    /// The SQL command text associated with the command
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DefaultValue(""), RefreshProperties(RefreshProperties.All), Editor("Microsoft.VSDesigner.Data.SQL.Design.SqlCommandTextEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
-#endif
-    public override string CommandText
-    {
-      get
-      {
-        return _commandText;
-      }
-      set
-      {
-        if (_commandText == value) return;
-
-        if (_activeReader != null)
-        {
-          throw new InvalidOperationException("Cannot set CommandText while a DataReader is active");
-        }
-
-        ClearCommands();
-        _commandText = value;
-
-        if (_cnn == null) return;
-      }
-    }
-
-    /// <summary>
-    /// The amount of time to wait for the connection to become available before erroring out
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DefaultValue((int)30)]
-#endif
-    public override int CommandTimeout
-    {
-      get
-      {
-        return _commandTimeout;
-      }
-      set
-      {
-        _commandTimeout = value;
-      }
-    }
-
-    /// <summary>
-    /// The type of the command.  Sqlite only supports CommandType.Text
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [RefreshProperties(RefreshProperties.All), DefaultValue(CommandType.Text)]
-#endif
-    public override CommandType CommandType
-    {
-      get
-      {
-        return CommandType.Text;
-      }
-      set
-      {
-        if (value != CommandType.Text)
-        {
-          throw new NotSupportedException();
-        }
-      }
-    }
-
-    /// <summary>
-    /// Forwards to the local CreateParameter() function
-    /// </summary>
-    /// <returns></returns>
-    protected override DbParameter CreateDbParameter()
-    {
-      return CreateParameter();
-    }
-
-    /// <summary>
-    /// Create a new parameter
-    /// </summary>
-    /// <returns></returns>
-    public new SqliteParameter CreateParameter()
-    {
-      return new SqliteParameter();
-    }
-
-    /// <summary>
-    /// The connection associated with this command
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
-#endif
-    public new SqliteConnection Connection
-    {
-      get { return _cnn; }
-      set
-      {
-        if (_activeReader != null)
-          throw new InvalidOperationException("Cannot set Connection while a DataReader is active");
-
-        if (_cnn != null)
-        {
-          ClearCommands();
-          _cnn.RemoveCommand(this);
-        }
-
-        _cnn = value;
-
-        if (_cnn != null)
-          _cnn.AddCommand(this);
-      }
-    }
-
-    /// <summary>
-    /// Forwards to the local Connection property
-    /// </summary>
-    protected override DbConnection DbConnection
-    {
-      get
-      {
-        return Connection;
-      }
-      set
-      {
-        Connection = (SqliteConnection)value;
-      }
-    }
-
-    /// <summary>
-    /// Returns the SqliteParameterCollection for the given command
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
-#endif
-    public new SqliteParameterCollection Parameters
-    {
-      get { return _parameterCollection; }
-    }
-
-    /// <summary>
-    /// Forwards to the local Parameters property
-    /// </summary>
-    protected override DbParameterCollection DbParameterCollection
-    {
-      get
-      {
-        return Parameters;
-      }
-    }
-
-    /// <summary>
-    /// The transaction associated with this command.  Sqlite only supports one transaction per connection, so this property forwards to the
-    /// command's underlying connection.
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
-#endif
-    public new SqliteTransaction Transaction
-    {
-      get { return _transaction; }
-      set
-      {
-        if (_cnn != null)
-        {
-          if (_activeReader != null)
-            throw new InvalidOperationException("Cannot set Transaction while a DataReader is active");
-
-          if (value != null)
-          {
-            if (value._cnn != _cnn)
-              throw new ArgumentException("Transaction is not associated with the command's connection");
-          }
-          _transaction = value;
-        }
-        else if (value != null)
-          throw new ArgumentOutOfRangeException("SqliteTransaction", "Not associated with a connection");
-      }
-    }
-
-    /// <summary>
-    /// Forwards to the local Transaction property
-    /// </summary>
-    protected override DbTransaction DbTransaction
-    {
-      get
-      {
-        return Transaction;
-      }
-      set
-      {
-        Transaction = (SqliteTransaction)value;
-      }
-    }
-
-    /// <summary>
-    /// This function ensures there are no active readers, that we have a valid connection,
-    /// that the connection is open, that all statements are prepared and all parameters are assigned
-    /// in preparation for allocating a data reader.
-    /// </summary>
-    private void InitializeForReader()
-    {
-      if (_activeReader != null)
-        throw new InvalidOperationException("DataReader already active on this command");
-
-      if (_cnn == null)
-        throw new InvalidOperationException("No connection associated with this command");
-
-      if (_cnn.State != ConnectionState.Open)
-        throw new InvalidOperationException("Database is not open");
-
-      // Map all parameters for statements already built
-      _parameterCollection.MapParameters(null);
-
-      // Set the default command timeout
-      _cnn._sql.SetTimeout(_commandTimeout * 1000);
-    }
-
-    /// <summary>
-    /// Creates a new SqliteDataReader to execute/iterate the array of Sqlite prepared statements
-    /// </summary>
-    /// <param name="behavior">The behavior the data reader should adopt</param>
-    /// <returns>Returns a SqliteDataReader object</returns>
-    protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
-    {
-      return ExecuteReader(behavior);
-    }
-
-    /// <summary>
-    /// Overrides the default behavior to return a SqliteDataReader specialization class
-    /// </summary>
-    /// <param name="behavior">The flags to be associated with the reader</param>
-    /// <returns>A SqliteDataReader</returns>
-    public new SqliteDataReader ExecuteReader(CommandBehavior behavior)
-    {
-      InitializeForReader();
-
-      SqliteDataReader rd = new SqliteDataReader(this, behavior);
-      _activeReader = rd;
-
-      return rd;
-    }
-
-    /// <summary>
-    /// Overrides the default behavior of DbDataReader to return a specialized SqliteDataReader class
-    /// </summary>
-    /// <returns>A SqliteDataReader</returns>
-    public new SqliteDataReader ExecuteReader()
-    {
-      return ExecuteReader(CommandBehavior.Default);
-    }
-
-    /// <summary>
-    /// Called by the SqliteDataReader when the data reader is closed.
-    /// </summary>
-    internal void ClearDataReader()
-    {
-      _activeReader = null;
-    }
-
-    /// <summary>
-    /// Execute the command and return the number of rows inserted/updated affected by it.
-    /// </summary>
-    /// <returns></returns>
-    public override int ExecuteNonQuery()
-    {
-      InitializeForReader();
-
-      int nAffected = 0;
-      int x = 0;
-      SqliteStatement stmt;
-
-      for(;;)
-      {
-        stmt = GetStatement(x);
-        x++;
-        if (stmt == null) break;
-
-        _cnn._sql.Step(stmt);
-        nAffected += _cnn._sql.Changes;
-        _cnn._sql.Reset(stmt);
-      }
-
-      return nAffected;
-    }
-
-    /// <summary>
-    /// Execute the command and return the first column of the first row of the resultset
-    /// (if present), or null if no resultset was returned.
-    /// </summary>
-    /// <returns>The first column of the first row of the first resultset from the query</returns>
-    public override object ExecuteScalar()
-    {
-      InitializeForReader();
-
-      int x = 0;
-      object ret = null;
-      SqliteType typ = new SqliteType();
-      SqliteStatement stmt;
-
-      // We step through every statement in the command, but only grab the first row of the first resultset.
-      // We keep going even after obtaining it.
-      for (;;)
-      {
-        stmt = GetStatement(x);
-        x++;
-        if (stmt == null) break;
-
-        if (_cnn._sql.Step(stmt) == true && ret == null)
-        {
-          ret = _cnn._sql.GetValue(stmt, 0, ref typ);
-        }
-        _cnn._sql.Reset(stmt);
-      }
-
-      return ret;
-    }
-
-    /// <summary>
-    /// Does nothing.  Commands are prepared as they are executed the first time, and kept in prepared state afterwards.
-    /// </summary>
-    public override void Prepare()
-    {
-    }
-
-    /// <summary>
-    /// Sets the method the SqliteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable.
-    /// </summary>
-    [DefaultValue(UpdateRowSource.FirstReturnedRecord)]
-    public override UpdateRowSource UpdatedRowSource
-    {
-      get
-      {
-        return _updateRowSource;
-      }
-      set
-      {
-        _updateRowSource = value;
-      }
-    }
-
-    /// <summary>
-    /// Determines if the command is visible at design time.  Defaults to True.
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DesignOnly(true), Browsable(false), DefaultValue(true), EditorBrowsable(EditorBrowsableState.Never)]
-#endif
-    public override bool DesignTimeVisible
-    {
-      get
-      {
-        return _designTimeVisible;
-      }
-      set
-      {
-        _designTimeVisible = value;
-#if !PLATFORM_COMPACTFRAMEWORK
-        TypeDescriptor.Refresh(this);
-#endif
-      }
-    }
-
-    /// <summary>
-    /// Clones a command, including all its parameters
-    /// </summary>
-    /// <returns>A new SqliteCommand with the same commandtext, connection and parameters</returns>
-    public object Clone()
-    {
-      return new SqliteCommand(this);
-    }
-
-    public int LastInsertRowID ()
-    {
-           return _cnn.LastInsertRowId;
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Data.Common;\r
+  using System.Collections.Generic;\r
+  using System.ComponentModel;\r
+\r
+  /// <summary>\r
+  /// SQLite implementation of DbCommand.\r
+  /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  [Designer("SQLite.Designer.SQLiteCommandDesigner, SQLite.Designer, Version=1.0.36.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139"), ToolboxItem(true)]\r
+#endif\r
+  public sealed class SQLiteCommand : DbCommand, ICloneable\r
+  {\r
+    /// <summary>\r
+    /// The command text this command is based on\r
+    /// </summary>\r
+    private string _commandText;\r
+    /// <summary>\r
+    /// The connection the command is associated with\r
+    /// </summary>\r
+    private SQLiteConnection _cnn;\r
+    /// <summary>\r
+    /// The version of the connection the command is associated with\r
+    /// </summary>\r
+    private long _version;\r
+    /// <summary>\r
+    /// Indicates whether or not a DataReader is active on the command.\r
+    /// </summary>\r
+    private WeakReference _activeReader;\r
+    /// <summary>\r
+    /// The timeout for the command, kludged because SQLite doesn't support per-command timeout values\r
+    /// </summary>\r
+    internal int _commandTimeout;\r
+    /// <summary>\r
+    /// Designer support\r
+    /// </summary>\r
+    private bool _designTimeVisible;\r
+    /// <summary>\r
+    /// Used by DbDataAdapter to determine updating behavior\r
+    /// </summary>\r
+    private UpdateRowSource _updateRowSource;\r
+    /// <summary>\r
+    /// The collection of parameters for the command\r
+    /// </summary>\r
+    private SQLiteParameterCollection _parameterCollection;\r
+    /// <summary>\r
+    /// The SQL command text, broken into individual SQL statements as they are executed\r
+    /// </summary>\r
+    internal List<SQLiteStatement> _statementList;\r
+    /// <summary>\r
+    /// Unprocessed SQL text that has not been executed\r
+    /// </summary>\r
+    internal string _remainingText;\r
+    /// <summary>\r
+    /// Transaction associated with this command\r
+    /// </summary>\r
+    private SQLiteTransaction _transaction;\r
+\r
+    ///<overloads>\r
+    /// Constructs a new SQLiteCommand\r
+    /// </overloads>\r
+    /// <summary>\r
+    /// Default constructor\r
+    /// </summary>\r
+    public SQLiteCommand() :this(null, null)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Initializes the command with the given command text\r
+    /// </summary>\r
+    /// <param name="commandText">The SQL command text</param>\r
+    public SQLiteCommand(string commandText) \r
+      : this(commandText, null, null)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Initializes the command with the given SQL command text and attach the command to the specified\r
+    /// connection.\r
+    /// </summary>\r
+    /// <param name="commandText">The SQL command text</param>\r
+    /// <param name="connection">The connection to associate with the command</param>\r
+    public SQLiteCommand(string commandText, SQLiteConnection connection)\r
+      : this(commandText, connection, null)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Initializes the command and associates it with the specified connection.\r
+    /// </summary>\r
+    /// <param name="connection">The connection to associate with the command</param>\r
+    public SQLiteCommand(SQLiteConnection connection) \r
+      : this(null, connection, null)\r
+    {\r
+    }\r
+\r
+    private SQLiteCommand(SQLiteCommand source) : this(source.CommandText, source.Connection, source.Transaction)\r
+    {\r
+      CommandTimeout = source.CommandTimeout;\r
+      DesignTimeVisible = source.DesignTimeVisible;\r
+      UpdatedRowSource = source.UpdatedRowSource;\r
+\r
+      foreach (SQLiteParameter param in source._parameterCollection)\r
+      {\r
+        Parameters.Add(param.Clone());\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Initializes a command with the given SQL, connection and transaction\r
+    /// </summary>\r
+    /// <param name="commandText">The SQL command text</param>\r
+    /// <param name="connection">The connection to associate with the command</param>\r
+    /// <param name="transaction">The transaction the command should be associated with</param>\r
+    public SQLiteCommand(string commandText, SQLiteConnection connection, SQLiteTransaction transaction)\r
+    {\r
+      _statementList = null;\r
+      _activeReader = null;\r
+      _commandTimeout = 30;\r
+      _parameterCollection = new SQLiteParameterCollection(this);\r
+      _designTimeVisible = true;\r
+      _updateRowSource = UpdateRowSource.None;\r
+      _transaction = null;\r
+\r
+      if (commandText != null)\r
+        CommandText = commandText;\r
+\r
+      if (connection != null)\r
+      {\r
+        DbConnection = connection;\r
+        _commandTimeout = connection.DefaultTimeout;\r
+      }\r
+\r
+      if (transaction != null)\r
+        Transaction = transaction;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Disposes of the command and clears all member variables\r
+    /// </summary>\r
+    /// <param name="disposing">Whether or not the class is being explicitly or implicitly disposed</param>\r
+    protected override void Dispose(bool disposing)\r
+    {\r
+      base.Dispose(disposing);\r
+\r
+      if (disposing)\r
+      {\r
+        // If a reader is active on this command, don't destroy the command, instead let the reader do it\r
+        SQLiteDataReader reader = null;\r
+        if (_activeReader != null)\r
+        {\r
+          try\r
+          {\r
+            reader = _activeReader.Target as SQLiteDataReader;\r
+          }\r
+          catch\r
+          {\r
+          }\r
+        }\r
+\r
+        if (reader != null)\r
+        {\r
+          reader._disposeCommand = true;\r
+          _activeReader = null;\r
+          return;\r
+        }\r
+\r
+        Connection = null;\r
+        _parameterCollection.Clear();\r
+        _commandText = null;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Clears and destroys all statements currently prepared\r
+    /// </summary>\r
+    internal void ClearCommands()\r
+    {\r
+      if (_activeReader != null)\r
+      {\r
+        SQLiteDataReader reader = null;\r
+        try\r
+        {\r
+          reader = _activeReader.Target as SQLiteDataReader;\r
+        }\r
+        catch\r
+        {\r
+        }\r
+\r
+        if (reader != null)\r
+          reader.Close();\r
+\r
+        _activeReader = null;\r
+      }\r
+\r
+      if (_statementList == null) return;\r
+\r
+      int x = _statementList.Count;\r
+      for (int n = 0; n < x; n++)\r
+        _statementList[n].Dispose();\r
+\r
+      _statementList = null;\r
+\r
+      _parameterCollection.Unbind();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Builds an array of prepared statements for each complete SQL statement in the command text\r
+    /// </summary>\r
+    internal SQLiteStatement BuildNextCommand()\r
+    {\r
+      SQLiteStatement stmt = null;\r
+\r
+      try\r
+      {\r
+        if (_statementList == null)\r
+          _remainingText = _commandText;\r
+\r
+        stmt = _cnn._sql.Prepare(_cnn, _remainingText, (_statementList == null) ? null : _statementList[_statementList.Count - 1], (uint)(_commandTimeout * 1000), out _remainingText);\r
+        if (stmt != null)\r
+        {\r
+          stmt._command = this;\r
+          if (_statementList == null)\r
+            _statementList = new List<SQLiteStatement>();\r
+\r
+          _statementList.Add(stmt);\r
+\r
+          _parameterCollection.MapParameters(stmt);\r
+          stmt.BindParameters();\r
+        }        \r
+        return stmt;\r
+      }\r
+      catch (Exception)\r
+      {\r
+        if (stmt != null)\r
+        {\r
+          if (_statementList.Contains(stmt))\r
+            _statementList.Remove(stmt);\r
+\r
+          stmt.Dispose();\r
+        }\r
+\r
+        // If we threw an error compiling the statement, we cannot continue on so set the remaining text to null.\r
+        _remainingText = null;\r
+\r
+        throw;\r
+      }\r
+    }\r
+\r
+    internal SQLiteStatement GetStatement(int index)\r
+    {\r
+      // Haven't built any statements yet\r
+      if (_statementList == null) return BuildNextCommand();\r
+\r
+      // If we're at the last built statement and want the next unbuilt statement, then build it\r
+      if (index == _statementList.Count)\r
+      {\r
+        if (String.IsNullOrEmpty(_remainingText) == false) return BuildNextCommand();\r
+        else return null; // No more commands\r
+      }\r
+\r
+      SQLiteStatement stmt = _statementList[index];\r
+      stmt.BindParameters();\r
+\r
+      return stmt;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Not implemented\r
+    /// </summary>\r
+    public override void Cancel()\r
+    {\r
+      if (_activeReader != null)\r
+      {\r
+        SQLiteDataReader reader = _activeReader.Target as SQLiteDataReader;\r
+        if (reader != null)\r
+          reader.Cancel();\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// The SQL command text associated with the command\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DefaultValue(""), RefreshProperties(RefreshProperties.All), Editor("Microsoft.VSDesigner.Data.SQL.Design.SqlCommandTextEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+#endif\r
+    public override string CommandText\r
+    {\r
+      get\r
+      {\r
+        return _commandText;\r
+      }\r
+      set\r
+      {\r
+        if (_commandText == value) return;\r
+\r
+        if (_activeReader != null && _activeReader.IsAlive)\r
+        {\r
+          throw new InvalidOperationException("Cannot set CommandText while a DataReader is active");\r
+        }\r
+\r
+        ClearCommands();\r
+        _commandText = value;\r
+\r
+        if (_cnn == null) return;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// The amount of time to wait for the connection to become available before erroring out\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DefaultValue((int)30)]\r
+#endif\r
+    public override int CommandTimeout\r
+    {\r
+      get\r
+      {\r
+        return _commandTimeout;\r
+      }\r
+      set\r
+      {\r
+        _commandTimeout = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// The type of the command.  SQLite only supports CommandType.Text\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [RefreshProperties(RefreshProperties.All), DefaultValue(CommandType.Text)]\r
+#endif\r
+    public override CommandType CommandType\r
+    {\r
+      get\r
+      {\r
+        return CommandType.Text;\r
+      }\r
+      set\r
+      {\r
+        if (value != CommandType.Text)\r
+        {\r
+          throw new NotSupportedException();\r
+        }\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Forwards to the local CreateParameter() function\r
+    /// </summary>\r
+    /// <returns></returns>\r
+    protected override DbParameter CreateDbParameter()\r
+    {\r
+      return CreateParameter();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Create a new parameter\r
+    /// </summary>\r
+    /// <returns></returns>\r
+    public new SQLiteParameter CreateParameter()\r
+    {\r
+      return new SQLiteParameter();\r
+    }\r
+\r
+    /// <summary>\r
+    /// The connection associated with this command\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+#endif\r
+    public new SQLiteConnection Connection\r
+    {\r
+      get { return _cnn; }\r
+      set\r
+      {\r
+        if (_activeReader != null && _activeReader.IsAlive)\r
+          throw new InvalidOperationException("Cannot set Connection while a DataReader is active");\r
+\r
+        if (_cnn != null)\r
+        {\r
+          ClearCommands();\r
+          //_cnn.RemoveCommand(this);\r
+        }\r
+\r
+        _cnn = value;\r
+        if (_cnn != null)\r
+          _version = _cnn._version;\r
+\r
+        //if (_cnn != null)\r
+        //  _cnn.AddCommand(this);\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Forwards to the local Connection property\r
+    /// </summary>\r
+    protected override DbConnection DbConnection\r
+    {\r
+      get\r
+      {\r
+        return Connection;\r
+      }\r
+      set\r
+      {\r
+        Connection = (SQLiteConnection)value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the SQLiteParameterCollection for the given command\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]\r
+#endif\r
+    public new SQLiteParameterCollection Parameters\r
+    {\r
+      get { return _parameterCollection; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Forwards to the local Parameters property\r
+    /// </summary>\r
+    protected override DbParameterCollection DbParameterCollection\r
+    {\r
+      get\r
+      {\r
+        return Parameters;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// The transaction associated with this command.  SQLite only supports one transaction per connection, so this property forwards to the\r
+    /// command's underlying connection.\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\r
+#endif\r
+    public new SQLiteTransaction Transaction\r
+    {\r
+      get { return _transaction; }\r
+      set\r
+      {\r
+        if (_cnn != null)\r
+        {\r
+          if (_activeReader != null && _activeReader.IsAlive)\r
+            throw new InvalidOperationException("Cannot set Transaction while a DataReader is active");\r
+\r
+          if (value != null)\r
+          {\r
+            if (value._cnn != _cnn)\r
+              throw new ArgumentException("Transaction is not associated with the command's connection");\r
+          }\r
+          _transaction = value;\r
+        }\r
+        else\r
+        {\r
+          Connection = value.Connection;\r
+          _transaction = value;\r
+        }\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Forwards to the local Transaction property\r
+    /// </summary>\r
+    protected override DbTransaction DbTransaction\r
+    {\r
+      get\r
+      {\r
+        return Transaction;\r
+      }\r
+      set\r
+      {\r
+        Transaction = (SQLiteTransaction)value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// This function ensures there are no active readers, that we have a valid connection,\r
+    /// that the connection is open, that all statements are prepared and all parameters are assigned\r
+    /// in preparation for allocating a data reader.\r
+    /// </summary>\r
+    private void InitializeForReader()\r
+    {\r
+      if (_activeReader != null && _activeReader.IsAlive)\r
+        throw new InvalidOperationException("DataReader already active on this command");\r
+\r
+      if (_cnn == null)\r
+        throw new InvalidOperationException("No connection associated with this command");\r
+\r
+      if (_cnn.State != ConnectionState.Open)\r
+        throw new InvalidOperationException("Database is not open");\r
+\r
+      // If the version of the connection has changed, clear out any previous commands before starting\r
+      if (_cnn._version != _version)\r
+      {\r
+        _version = _cnn._version;\r
+        ClearCommands();\r
+      }\r
+\r
+      // Map all parameters for statements already built\r
+      _parameterCollection.MapParameters(null);\r
+\r
+      //// Set the default command timeout\r
+      //_cnn._sql.SetTimeout(_commandTimeout * 1000);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements\r
+    /// </summary>\r
+    /// <param name="behavior">The behavior the data reader should adopt</param>\r
+    /// <returns>Returns a SQLiteDataReader object</returns>\r
+    protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)\r
+    {\r
+      return ExecuteReader(behavior);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Overrides the default behavior to return a SQLiteDataReader specialization class\r
+    /// </summary>\r
+    /// <param name="behavior">The flags to be associated with the reader</param>\r
+    /// <returns>A SQLiteDataReader</returns>\r
+    public new SQLiteDataReader ExecuteReader(CommandBehavior behavior)\r
+    {\r
+      InitializeForReader();\r
+\r
+      SQLiteDataReader rd = new SQLiteDataReader(this, behavior);\r
+      _activeReader = new WeakReference(rd, false);\r
+\r
+      return rd;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class\r
+    /// </summary>\r
+    /// <returns>A SQLiteDataReader</returns>\r
+    public new SQLiteDataReader ExecuteReader()\r
+    {\r
+      return ExecuteReader(CommandBehavior.Default);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Called by the SQLiteDataReader when the data reader is closed.\r
+    /// </summary>\r
+    internal void ClearDataReader()\r
+    {\r
+      _activeReader = null;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Execute the command and return the number of rows inserted/updated affected by it.\r
+    /// </summary>\r
+    /// <returns></returns>\r
+    public override int ExecuteNonQuery()\r
+    {\r
+      using (SQLiteDataReader reader = ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.SingleResult))\r
+      {\r
+        while (reader.NextResult()) ;\r
+        return reader.RecordsAffected;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Execute the command and return the first column of the first row of the resultset\r
+    /// (if present), or null if no resultset was returned.\r
+    /// </summary>\r
+    /// <returns>The first column of the first row of the first resultset from the query</returns>\r
+    public override object ExecuteScalar()\r
+    {\r
+      using (SQLiteDataReader reader = ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.SingleResult))\r
+      {\r
+        if (reader.Read())\r
+          return reader[0];\r
+      }\r
+      return null;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Does nothing.  Commands are prepared as they are executed the first time, and kept in prepared state afterwards.\r
+    /// </summary>\r
+    public override void Prepare()\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable.\r
+    /// </summary>\r
+    [DefaultValue(UpdateRowSource.None)]\r
+    public override UpdateRowSource UpdatedRowSource\r
+    {\r
+      get\r
+      {\r
+        return _updateRowSource;\r
+      }\r
+      set\r
+      {\r
+        _updateRowSource = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Determines if the command is visible at design time.  Defaults to True.\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DesignOnly(true), Browsable(false), DefaultValue(true), EditorBrowsable(EditorBrowsableState.Never)]\r
+#endif\r
+    public override bool DesignTimeVisible\r
+    {\r
+      get\r
+      {\r
+        return _designTimeVisible;\r
+      }\r
+      set\r
+      {\r
+        _designTimeVisible = value;\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+        TypeDescriptor.Refresh(this);\r
+#endif\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Clones a command, including all its parameters\r
+    /// </summary>\r
+    /// <returns>A new SQLiteCommand with the same commandtext, connection and parameters</returns>\r
+    public object Clone()\r
+    {\r
+      return new SQLiteCommand(this);\r
+    }\r
+  }\r
+}
\ No newline at end of file
index 4a3a18c0e2f556fe01c2411f289795b325ba18b5..53529dd735b9d32d7eb50f851bef9b204266bfdf 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteCommandBuilder.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Data.Common;
-  using System.Globalization;
-  using System.ComponentModel;
-
-  /// <summary>
-  /// Sqlite implementation of DbCommandBuilder.
-  /// </summary>
-  public sealed class SqliteCommandBuilder : DbCommandBuilder
-  {
-    private EventHandler<RowUpdatingEventArgs> _handler;
-
-    /// <summary>
-    /// Default constructor
-    /// </summary>
-    public SqliteCommandBuilder() : this(null)
-    {
-    }
-
-    /// <summary>
-    /// Initializes the command builder and associates it with the specified data adapter.
-    /// </summary>
-    /// <param name="adp"></param>
-    public SqliteCommandBuilder(SqliteDataAdapter adp)
-    {
-      QuotePrefix = "[";
-      QuoteSuffix = "]";
-      DataAdapter = adp;
-    }
-
-    /// <summary>
-    /// Minimal amount of parameter processing.  Primarily sets the DbType for the parameter equal to the provider type in the schema
-    /// </summary>
-    /// <param name="parameter">The parameter to use in applying custom behaviors to a row</param>
-    /// <param name="row">The row to apply the parameter to</param>
-    /// <param name="statementType">The type of statement</param>
-    /// <param name="whereClause">Whether the application of the parameter is part of a WHERE clause</param>
-    protected override void ApplyParameterInfo(DbParameter parameter, DataRow row, StatementType statementType, bool whereClause)
-    {
-      SqliteParameter param = (SqliteParameter)parameter;
-      param.DbType = (DbType)row[SchemaTableColumn.ProviderType];
-    }
-
-    /// <summary>
-    /// Returns a valid named parameter
-    /// </summary>
-    /// <param name="parameterName">The name of the parameter</param>
-    /// <returns>Error</returns>
-    protected override string GetParameterName(string parameterName)
-    {
-      return String.Format(CultureInfo.InvariantCulture, "@{0}", parameterName);
-    }
-
-    /// <summary>
-    /// Returns a named parameter for the given ordinal
-    /// </summary>
-    /// <param name="parameterOrdinal">The i of the parameter</param>
-    /// <returns>Error</returns>
-    protected override string GetParameterName(int parameterOrdinal)
-    {
-      return String.Format(CultureInfo.InvariantCulture, "@param{0}", parameterOrdinal);
-    }
-
-    /// <summary>
-    /// Returns a placeholder character for the specified parameter i.
-    /// </summary>
-    /// <param name="parameterOrdinal">The index of the parameter to provide a placeholder for</param>
-    /// <returns>Returns a named parameter</returns>
-    protected override string GetParameterPlaceholder(int parameterOrdinal)
-    {
-      return GetParameterName(parameterOrdinal);
-    }
-
-    /// <summary>
-    /// Sets the handler for receiving row updating events.  Used by the DbCommandBuilder to autogenerate SQL
-    /// statements that may not have previously been generated.
-    /// </summary>
-    /// <param name="adapter">A data adapter to receive events on.</param>
-    protected override void SetRowUpdatingHandler(DbDataAdapter adapter)
-    {
-      SqliteDataAdapter adp = (SqliteDataAdapter)adapter;
-
-      _handler = new EventHandler<RowUpdatingEventArgs>(RowUpdatingEventHandler);
-      adp.RowUpdating += _handler;
-    }
-
-    private void RowUpdatingEventHandler(object sender, RowUpdatingEventArgs e)
-    {
-      base.RowUpdatingHandler(e);
-    }
-
-    /// <summary>
-    /// Gets/sets the DataAdapter for this CommandBuilder
-    /// </summary>
-    public new SqliteDataAdapter DataAdapter
-    {
-      get { return (SqliteDataAdapter)base.DataAdapter; }
-      set { base.DataAdapter = value; }
-    }
-
-    /// <summary>
-    /// Returns the automatically-generated Sqlite command to delete rows from the database
-    /// </summary>
-    /// <returns></returns>
-    public new SqliteCommand GetDeleteCommand()
-    {
-      return (SqliteCommand)base.GetDeleteCommand();
-    }
-
-    /// <summary>
-    /// Returns the automatically-generated Sqlite command to delete rows from the database
-    /// </summary>
-    /// <param name="useColumnsForParameterNames"></param>
-    /// <returns></returns>
-    public new SqliteCommand GetDeleteCommand(bool useColumnsForParameterNames)
-    {
-      return (SqliteCommand)base.GetDeleteCommand(useColumnsForParameterNames);
-    }
-
-    /// <summary>
-    /// Returns the automatically-generated Sqlite command to update rows in the database
-    /// </summary>
-    /// <returns></returns>
-    public new SqliteCommand GetUpdateCommand()
-    {
-      return (SqliteCommand)base.GetUpdateCommand();
-    }
-
-    /// <summary>
-    /// Returns the automatically-generated Sqlite command to update rows in the database
-    /// </summary>
-    /// <param name="useColumnsForParameterNames"></param>
-    /// <returns></returns>
-    public new SqliteCommand GetUpdateCommand(bool useColumnsForParameterNames)
-    {
-      return (SqliteCommand)base.GetUpdateCommand(useColumnsForParameterNames);
-    }
-
-    /// <summary>
-    /// Returns the automatically-generated Sqlite command to insert rows into the database
-    /// </summary>
-    /// <returns></returns>
-    public new SqliteCommand GetInsertCommand()
-    {
-      return (SqliteCommand)base.GetInsertCommand();
-    }
-
-    /// <summary>
-    /// Returns the automatically-generated Sqlite command to insert rows into the database
-    /// </summary>
-    /// <param name="useColumnsForParameterNames"></param>
-    /// <returns></returns>
-    public new SqliteCommand GetInsertCommand(bool useColumnsForParameterNames)
-    {
-      return (SqliteCommand)base.GetInsertCommand(useColumnsForParameterNames);
-    }
-
-    /// <summary>
-    /// Overridden to hide its property from the designer
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [Browsable(false)]
-#endif
-    public override CatalogLocation CatalogLocation
-    {
-      get
-      {
-        return base.CatalogLocation;
-      }
-      set
-      {
-        base.CatalogLocation = value;
-      }
-    }
-
-    /// <summary>
-    /// Overridden to hide its property from the designer
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [Browsable(false)]
-#endif
-    public override string CatalogSeparator
-    {
-      get
-      {
-        return base.CatalogSeparator;
-      }
-      set
-      {
-        base.CatalogSeparator = value;
-      }
-    }
-
-    /// <summary>
-    /// Overridden to hide its property from the designer
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [Browsable(false)]
-#endif
-    [DefaultValue("[")]
-    public override string QuotePrefix
-    {
-      get
-      {
-        return base.QuotePrefix;
-      }
-      set
-      {
-        base.QuotePrefix = value;
-      }
-    }
-
-    /// <summary>
-    /// Overridden to hide its property from the designer
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [Browsable(false)]
-#endif
-    public override string QuoteSuffix
-    {
-      get
-      {
-        return base.QuoteSuffix;
-      }
-      set
-      {
-        base.QuoteSuffix = value;
-      }
-    }
-
-    /// <summary>
-    /// Places brackets around an identifier
-    /// </summary>
-    /// <param name="unquotedIdentifier">The identifier to quote</param>
-    /// <returns>The bracketed identifier</returns>
-    public override string QuoteIdentifier(string unquotedIdentifier)
-    {
-      if (String.IsNullOrEmpty(QuotePrefix)
-        || String.IsNullOrEmpty(QuoteSuffix)
-        || String.IsNullOrEmpty(unquotedIdentifier))
-        return unquotedIdentifier;
-
-      return QuotePrefix + unquotedIdentifier.Replace(QuoteSuffix, QuoteSuffix + QuoteSuffix) + QuoteSuffix;
-    }
-
-    /// <summary>
-    /// Removes brackets around an identifier
-    /// </summary>
-    /// <param name="quotedIdentifier">The quoted (bracketed) identifier</param>
-    /// <returns>The undecorated identifier</returns>
-    public override string UnquoteIdentifier(string quotedIdentifier)
-    {
-      if (String.IsNullOrEmpty(QuotePrefix)
-        || String.IsNullOrEmpty(QuoteSuffix)
-        || String.IsNullOrEmpty(quotedIdentifier))
-        return quotedIdentifier;
-
-      if (quotedIdentifier.StartsWith(QuotePrefix, StringComparison.InvariantCultureIgnoreCase) == false
-        || quotedIdentifier.EndsWith(QuoteSuffix, StringComparison.InvariantCultureIgnoreCase) == false)
-        return quotedIdentifier;
-
-      return quotedIdentifier.Substring(QuotePrefix.Length, quotedIdentifier.Length - (QuotePrefix.Length + QuoteSuffix.Length)).Replace(QuoteSuffix + QuoteSuffix, QuoteSuffix);
-    }
-
-    /// <summary>
-    /// Overridden to hide its property from the designer
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [Browsable(false)]
-#endif
-    public override string SchemaSeparator
-    {
-      get
-      {
-        return base.SchemaSeparator;
-      }
-      set
-      {
-        base.SchemaSeparator = value;
-      }
-    }
-
-    /// <summary>
-    /// Override helper, which can help the base command builder choose the right keys for the given query
-    /// </summary>
-    /// <param name="sourceCommand"></param>
-    /// <returns></returns>
-    protected override DataTable GetSchemaTable(DbCommand sourceCommand)
-    {
-      using (IDataReader reader = sourceCommand.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
-      {
-        DataTable schema = reader.GetSchemaTable();
-
-        // If the query contains a primary key, turn off the IsUnique property
-        // for all the non-key columns
-        if (HasSchemaPrimaryKey(schema))
-          ResetIsUniqueSchemaColumn(schema);
-
-        // if table has no primary key we use unique columns as a fall back
-        return schema;
-      }
-    }
-
-    private bool HasSchemaPrimaryKey(DataTable schema)
-    {
-      DataColumn IsKeyColumn = schema.Columns[SchemaTableColumn.IsKey];
-      
-      foreach (DataRow schemaRow in schema.Rows)
-      {
-        if ((bool)schemaRow[IsKeyColumn] == true)
-          return true;
-      }
-
-      return false;
-    }
-
-    private void ResetIsUniqueSchemaColumn(DataTable schema)
-    {
-      DataColumn IsUniqueColumn = schema.Columns[SchemaTableColumn.IsUnique];
-      DataColumn IsKeyColumn = schema.Columns[SchemaTableColumn.IsKey];
-
-      foreach (DataRow schemaRow in schema.Rows)
-      {
-        if ((bool)schemaRow[IsKeyColumn] == false)
-          schemaRow[IsUniqueColumn] = false;
-      }
-
-      schema.AcceptChanges();
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Data.Common;\r
+  using System.Globalization;\r
+  using System.ComponentModel;\r
+\r
+  /// <summary>\r
+  /// SQLite implementation of DbCommandBuilder.\r
+  /// </summary>\r
+  public sealed class SQLiteCommandBuilder : DbCommandBuilder\r
+  {\r
+    /// <summary>\r
+    /// Default constructor\r
+    /// </summary>\r
+    public SQLiteCommandBuilder() : this(null)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Initializes the command builder and associates it with the specified data adapter.\r
+    /// </summary>\r
+    /// <param name="adp"></param>\r
+    public SQLiteCommandBuilder(SQLiteDataAdapter adp)\r
+    {\r
+      QuotePrefix = "[";\r
+      QuoteSuffix = "]";\r
+      DataAdapter = adp;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Minimal amount of parameter processing.  Primarily sets the DbType for the parameter equal to the provider type in the schema\r
+    /// </summary>\r
+    /// <param name="parameter">The parameter to use in applying custom behaviors to a row</param>\r
+    /// <param name="row">The row to apply the parameter to</param>\r
+    /// <param name="statementType">The type of statement</param>\r
+    /// <param name="whereClause">Whether the application of the parameter is part of a WHERE clause</param>\r
+    protected override void ApplyParameterInfo(DbParameter parameter, DataRow row, StatementType statementType, bool whereClause)\r
+    {\r
+      SQLiteParameter param = (SQLiteParameter)parameter;\r
+      param.DbType = (DbType)row[SchemaTableColumn.ProviderType];\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns a valid named parameter\r
+    /// </summary>\r
+    /// <param name="parameterName">The name of the parameter</param>\r
+    /// <returns>Error</returns>\r
+    protected override string GetParameterName(string parameterName)\r
+    {\r
+      return String.Format(CultureInfo.InvariantCulture, "@{0}", parameterName);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns a named parameter for the given ordinal\r
+    /// </summary>\r
+    /// <param name="parameterOrdinal">The i of the parameter</param>\r
+    /// <returns>Error</returns>\r
+    protected override string GetParameterName(int parameterOrdinal)\r
+    {\r
+      return String.Format(CultureInfo.InvariantCulture, "@param{0}", parameterOrdinal);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns a placeholder character for the specified parameter i.\r
+    /// </summary>\r
+    /// <param name="parameterOrdinal">The index of the parameter to provide a placeholder for</param>\r
+    /// <returns>Returns a named parameter</returns>\r
+    protected override string GetParameterPlaceholder(int parameterOrdinal)\r
+    {\r
+      return GetParameterName(parameterOrdinal);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Sets the handler for receiving row updating events.  Used by the DbCommandBuilder to autogenerate SQL\r
+    /// statements that may not have previously been generated.\r
+    /// </summary>\r
+    /// <param name="adapter">A data adapter to receive events on.</param>\r
+    protected override void SetRowUpdatingHandler(DbDataAdapter adapter)\r
+    {\r
+      if (adapter == base.DataAdapter)\r
+      {\r
+        ((SQLiteDataAdapter)adapter).RowUpdating -= new EventHandler<RowUpdatingEventArgs>(RowUpdatingEventHandler);\r
+      }\r
+      else\r
+      {\r
+        ((SQLiteDataAdapter)adapter).RowUpdating += new EventHandler<RowUpdatingEventArgs>(RowUpdatingEventHandler);\r
+      }\r
+    }\r
+\r
+    private void RowUpdatingEventHandler(object sender, RowUpdatingEventArgs e)\r
+    {\r
+      base.RowUpdatingHandler(e);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/sets the DataAdapter for this CommandBuilder\r
+    /// </summary>\r
+    public new SQLiteDataAdapter DataAdapter\r
+    {\r
+      get { return (SQLiteDataAdapter)base.DataAdapter; }\r
+      set { base.DataAdapter = value; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the automatically-generated SQLite command to delete rows from the database\r
+    /// </summary>\r
+    /// <returns></returns>\r
+    public new SQLiteCommand GetDeleteCommand()\r
+    {\r
+      return (SQLiteCommand)base.GetDeleteCommand();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the automatically-generated SQLite command to delete rows from the database\r
+    /// </summary>\r
+    /// <param name="useColumnsForParameterNames"></param>\r
+    /// <returns></returns>\r
+    public new SQLiteCommand GetDeleteCommand(bool useColumnsForParameterNames)\r
+    {\r
+      return (SQLiteCommand)base.GetDeleteCommand(useColumnsForParameterNames);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the automatically-generated SQLite command to update rows in the database\r
+    /// </summary>\r
+    /// <returns></returns>\r
+    public new SQLiteCommand GetUpdateCommand()\r
+    {\r
+      return (SQLiteCommand)base.GetUpdateCommand();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the automatically-generated SQLite command to update rows in the database\r
+    /// </summary>\r
+    /// <param name="useColumnsForParameterNames"></param>\r
+    /// <returns></returns>\r
+    public new SQLiteCommand GetUpdateCommand(bool useColumnsForParameterNames)\r
+    {\r
+      return (SQLiteCommand)base.GetUpdateCommand(useColumnsForParameterNames);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the automatically-generated SQLite command to insert rows into the database\r
+    /// </summary>\r
+    /// <returns></returns>\r
+    public new SQLiteCommand GetInsertCommand()\r
+    {\r
+      return (SQLiteCommand)base.GetInsertCommand();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the automatically-generated SQLite command to insert rows into the database\r
+    /// </summary>\r
+    /// <param name="useColumnsForParameterNames"></param>\r
+    /// <returns></returns>\r
+    public new SQLiteCommand GetInsertCommand(bool useColumnsForParameterNames)\r
+    {\r
+      return (SQLiteCommand)base.GetInsertCommand(useColumnsForParameterNames);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Overridden to hide its property from the designer\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [Browsable(false)]\r
+#endif\r
+    public override CatalogLocation CatalogLocation\r
+    {\r
+      get\r
+      {\r
+        return base.CatalogLocation;\r
+      }\r
+      set\r
+      {\r
+        base.CatalogLocation = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Overridden to hide its property from the designer\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [Browsable(false)]\r
+#endif\r
+    public override string CatalogSeparator\r
+    {\r
+      get\r
+      {\r
+        return base.CatalogSeparator;\r
+      }\r
+      set\r
+      {\r
+        base.CatalogSeparator = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Overridden to hide its property from the designer\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [Browsable(false)]\r
+#endif\r
+    [DefaultValue("[")]\r
+    public override string QuotePrefix\r
+    {\r
+      get\r
+      {\r
+        return base.QuotePrefix;\r
+      }\r
+      set\r
+      {\r
+        base.QuotePrefix = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Overridden to hide its property from the designer\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [Browsable(false)]\r
+#endif\r
+    public override string QuoteSuffix\r
+    {\r
+      get\r
+      {\r
+        return base.QuoteSuffix;\r
+      }\r
+      set\r
+      {\r
+        base.QuoteSuffix = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Places brackets around an identifier\r
+    /// </summary>\r
+    /// <param name="unquotedIdentifier">The identifier to quote</param>\r
+    /// <returns>The bracketed identifier</returns>\r
+    public override string QuoteIdentifier(string unquotedIdentifier)\r
+    {\r
+      if (String.IsNullOrEmpty(QuotePrefix)\r
+        || String.IsNullOrEmpty(QuoteSuffix)\r
+        || String.IsNullOrEmpty(unquotedIdentifier))\r
+        return unquotedIdentifier;\r
+\r
+      return QuotePrefix + unquotedIdentifier.Replace(QuoteSuffix, QuoteSuffix + QuoteSuffix) + QuoteSuffix;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Removes brackets around an identifier\r
+    /// </summary>\r
+    /// <param name="quotedIdentifier">The quoted (bracketed) identifier</param>\r
+    /// <returns>The undecorated identifier</returns>\r
+    public override string UnquoteIdentifier(string quotedIdentifier)\r
+    {\r
+      if (String.IsNullOrEmpty(QuotePrefix)\r
+        || String.IsNullOrEmpty(QuoteSuffix)\r
+        || String.IsNullOrEmpty(quotedIdentifier))\r
+        return quotedIdentifier;\r
+\r
+      if (quotedIdentifier.StartsWith(QuotePrefix, StringComparison.InvariantCultureIgnoreCase) == false\r
+        || quotedIdentifier.EndsWith(QuoteSuffix, StringComparison.InvariantCultureIgnoreCase) == false)\r
+        return quotedIdentifier;\r
+\r
+      return quotedIdentifier.Substring(QuotePrefix.Length, quotedIdentifier.Length - (QuotePrefix.Length + QuoteSuffix.Length)).Replace(QuoteSuffix + QuoteSuffix, QuoteSuffix);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Overridden to hide its property from the designer\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [Browsable(false)]\r
+#endif\r
+    public override string SchemaSeparator\r
+    {\r
+      get\r
+      {\r
+        return base.SchemaSeparator;\r
+      }\r
+      set\r
+      {\r
+        base.SchemaSeparator = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Override helper, which can help the base command builder choose the right keys for the given query\r
+    /// </summary>\r
+    /// <param name="sourceCommand"></param>\r
+    /// <returns></returns>\r
+    protected override DataTable GetSchemaTable(DbCommand sourceCommand)\r
+    {\r
+      using (IDataReader reader = sourceCommand.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))\r
+      {\r
+        DataTable schema = reader.GetSchemaTable();\r
+\r
+        // If the query contains a primary key, turn off the IsUnique property\r
+        // for all the non-key columns\r
+        if (HasSchemaPrimaryKey(schema))\r
+          ResetIsUniqueSchemaColumn(schema);\r
+\r
+        // if table has no primary key we use unique columns as a fall back\r
+        return schema;\r
+      }\r
+    }\r
+\r
+    private bool HasSchemaPrimaryKey(DataTable schema)\r
+    {\r
+      DataColumn IsKeyColumn = schema.Columns[SchemaTableColumn.IsKey];\r
+      \r
+      foreach (DataRow schemaRow in schema.Rows)\r
+      {\r
+        if ((bool)schemaRow[IsKeyColumn] == true)\r
+          return true;\r
+      }\r
+\r
+      return false;\r
+    }\r
+\r
+    private void ResetIsUniqueSchemaColumn(DataTable schema)\r
+    {\r
+      DataColumn IsUniqueColumn = schema.Columns[SchemaTableColumn.IsUnique];\r
+      DataColumn IsKeyColumn = schema.Columns[SchemaTableColumn.IsKey];\r
+\r
+      foreach (DataRow schemaRow in schema.Rows)\r
+      {\r
+        if ((bool)schemaRow[IsKeyColumn] == false)\r
+          schemaRow[IsUniqueColumn] = false;\r
+      }\r
+\r
+      schema.AcceptChanges();\r
+    }\r
+  }\r
+}\r
index aa9b0edf2efec2a0b015fa97df7fe093f6011911..8e2b5ac4660a88b22d64d3e34598174ff3c9954c 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteConnection.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Data.Common;
-  using System.Collections.Generic;
-  using System.Globalization;
-  using System.ComponentModel;
-       
-  /// <summary>
-  /// Sqlite implentation of DbConnection.
-  /// </summary>
-  /// <remarks>
-  /// The <see cref="ConnectionString">ConnectionString</see> property of the SqliteConnection class can contain the following parameter(s), delimited with a semi-colon:
-  /// <list type="table">
-  /// <listheader>
-  /// <term>Parameter</term>
-  /// <term>Values</term>
-  /// <term>Required</term>
-  /// <term>Default</term>
-  /// </listheader>
-  /// <item>
-  /// <description>Data Source</description>
-  /// <description>{filename}</description>
-  /// <description>Y</description>
-  /// <description></description>
-  /// </item>
-  /// <item>
-  /// <description>Version</description>
-  /// <description>3</description>
-  /// <description>N</description>
-  /// <description>3</description>
-  /// </item>
-  /// <item>
-  /// <description>UseUTF16Encoding</description>
-  /// <description><b>True</b><br/><b>False</b></description>
-  /// <description>N</description>
-  /// <description>False</description>
-  /// </item>
-  /// <item>
-  /// <description>DateTimeFormat</description>
-  /// <description><b>Ticks</b> - Use DateTime.Ticks<br/><b>ISO8601</b> - Use ISO8601 DateTime format</description>
-  /// <description>N</description>
-  /// <description>ISO8601</description>
-  /// </item>
-  /// <item>
-  /// <description>BinaryGUID</description>
-  /// <description><b>True</b> - Store GUID columns in binary form<br/><b>False</b> - Store GUID columns as text</description>
-  /// <description>N</description>
-  /// <description>True</description>
-  /// </item>
-  /// <item>
-  /// <description>Cache Size</description>
-  /// <description>{size in bytes}</description>
-  /// <description>N</description>
-  /// <description>2000</description>
-  /// </item>
-  /// <item>
-  /// <description>Synchronous</description>
-  /// <description><b>Normal</b> - Normal file flushing behavior<br/><b>Full</b> - Full flushing after all writes<br/><b>Off</b> - Underlying OS flushes I/O's</description>
-  /// <description>N</description>
-  /// <description>Normal</description>
-  /// </item>
-  /// <item>
-  /// <description>Page Size</description>
-  /// <description>{size in bytes}</description>
-  /// <description>N</description>
-  /// <description>1024</description>
-  /// </item>
-  /// <item>
-  /// <description>Password</description>
-  /// <description>{password}</description>
-  /// <description>N</description>
-  /// <description></description>
-  /// </item>
-  /// <item>
-  /// <description>Enlist</description>
-  /// <description><B>Y</B> - Automatically enlist in distributed transactions<br/><b>N</b> - No automatic enlistment</description>
-  /// <description>N</description>
-  /// <description>Y</description>
-  /// </item>
-  /// </list>
-  /// </remarks>
-  public sealed class SqliteConnection : DbConnection, ICloneable
-  {
-    private const string _dataDirectory = "|DataDirectory|";
-
-    /// <summary>
-    /// State of the current connection
-    /// </summary>
-    private ConnectionState      _connectionState;
-    /// <summary>
-    /// The connection string
-    /// </summary>
-    private string               _connectionString;
-    /// <summary>
-    /// Nesting level of the transactions open on the connection
-    /// </summary>
-    internal int                 _transactionLevel;
-    /// <summary>
-    /// Busy command timeout value. Defaults to 30
-    /// </summary>
-    internal int                 _busyTimeout;
-    
-#if !PLATFORM_COMPACTFRAMEWORK
-    /// <summary>
-    /// Whether or not the connection is enlisted in a distrubuted transaction
-    /// </summary>
-    internal SqliteEnlistment    _enlistment;
-#endif
-    /// <summary>
-    /// The base Sqlite object to interop with
-    /// </summary>
-    internal SqliteBase          _sql;
-    /// <summary>
-    /// Commands associated with this connection
-    /// </summary>
-    internal List<SqliteCommand> _commandList;
-    /// <summary>
-    /// The database filename minus path and extension
-    /// </summary>
-    private string               _dataSource;
-#if MONO_SUPPORT_PASSWORDS
-    /// <summary>
-    /// Temporary password storage, emptied after the database has been opened
-    /// </summary>
-    private byte[]               _password;
-#endif
-    
-    internal bool                _binaryGuid;
-
-    internal long                _version;
-
-    private event SqliteUpdateEventHandler _updateHandler;
-    private event SqliteCommitHandler      _commitHandler;
-    private event EventHandler             _rollbackHandler;
-
-    private SqliteUpdateCallback   _updateCallback;
-    private SqliteCommitCallback   _commitCallback;
-    private SqliteRollbackCallback _rollbackCallback;
-
-    /// <summary>
-    /// This event is raised whenever the database is opened or closed.
-    /// </summary>
-    //public override event StateChangeEventHandler StateChange;
-
-    /// <summary>
-    /// This event is raised whenever Sqlite makes an update/delete/insert into the database on
-    /// this connection.  It only applies to the given connection.
-    /// </summary>
-    public event SqliteUpdateEventHandler Update
-    {
-      add
-      {
-        if (_updateHandler == null)
-        {
-          _updateCallback = new SqliteUpdateCallback(UpdateCallback);
-          _sql.SetUpdateHook(_updateCallback);
-        }
-        _updateHandler += value;
-      }
-      remove
-      {
-        _updateHandler -= value;
-        if (_updateHandler == null)
-        {
-          _sql.SetUpdateHook(null);
-          _updateCallback = null;
-        }
-      }
-    }
-
-    private void UpdateCallback(int type, IntPtr database, int databaseLen, IntPtr table, int tableLen, Int64 rowid)
-    {
-      _updateHandler(this, new UpdateEventArgs(
-        _sql.UTF8ToString(database),
-        _sql.UTF8ToString(table),
-        (UpdateEventType)type,
-        rowid));
-    }
-
-    /// <summary>
-    /// This event is raised whenever Sqlite is committing a transaction.
-    /// Return non-zero to trigger a rollback
-    /// </summary>
-    public event SqliteCommitHandler Commit
-    {
-      add
-      {
-        if (_commitHandler == null)
-        {
-          _commitCallback = new SqliteCommitCallback(CommitCallback);
-          _sql.SetCommitHook(_commitCallback);
-        }
-        _commitHandler += value;
-      }
-      remove
-      {
-        _commitHandler -= value;
-        if (_commitHandler == null)
-        {
-          _sql.SetCommitHook(null);
-          _commitCallback = null;
-        }
-      }
-    }
-
-    /// <summary>
-    /// This event is raised whenever Sqlite is committing a transaction.
-    /// Return non-zero to trigger a rollback
-    /// </summary>
-    public event EventHandler RollBack
-    {
-      add
-      {
-        if (_rollbackHandler == null)
-        {
-          _rollbackCallback = new SqliteRollbackCallback(RollbackCallback);
-          _sql.SetRollbackHook(_rollbackCallback);
-        }
-        _rollbackHandler += value;
-      }
-      remove
-      {
-        _rollbackHandler -= value;
-        if (_rollbackHandler == null)
-        {
-          _sql.SetRollbackHook(null);
-          _rollbackCallback = null;
-        }
-      }
-    }
-
-
-    private int CommitCallback()
-    {
-      CommitEventArgs e = new CommitEventArgs();
-      _commitHandler(this, e);
-      return (e.AbortTransaction == true) ? 1 : 0;
-    }
-
-    private void RollbackCallback()
-    {
-      _rollbackHandler(this, EventArgs.Empty);
-    }
-
-    ///<overloads>
-    /// Constructs a new SqliteConnection object
-    /// </overloads>
-    /// <summary>
-    /// Default constructor
-    /// </summary>
-    public SqliteConnection() : this("")
-    {
-    }
-
-    /// <summary>
-    /// Initializes the connection with the specified connection string
-    /// </summary>
-    /// <param name="connectionString">The connection string to use on the connection</param>
-    public SqliteConnection(string connectionString)
-    {
-      _sql = null;
-      _connectionState = ConnectionState.Closed;
-      _connectionString = "";
-      _transactionLevel = 0;
-      _busyTimeout = 30;
-      _version = 0;
-      _commandList = new List<SqliteCommand>();
-
-      if (connectionString != null)
-        ConnectionString = connectionString;
-    }
-
-    /// <summary>
-    /// Clones the settings and connection string from an existing connection.  If the existing connection is already open, this
-    /// function will open its own connection, enumerate any attached databases of the original connection, and automatically
-    /// attach to them.
-    /// </summary>
-    /// <param name="connection"></param>
-    public SqliteConnection(SqliteConnection connection) : this(connection.ConnectionString)
-    {
-      string str;
-
-      if (connection.State == ConnectionState.Open)
-      {
-        Open();
-
-        // Reattach all attached databases from the existing connection
-        using (DataTable tbl = connection.GetSchema("Catalogs"))
-        {
-          foreach (DataRow row in tbl.Rows)
-          {
-            str = row[0].ToString();
-            if (String.Compare(str, "main", true, CultureInfo.InvariantCulture) != 0
-              && String.Compare(str, "temp", true, CultureInfo.InvariantCulture) != 0)
-            {
-              using (SqliteCommand cmd = CreateCommand())
-              {
-                cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "ATTACH DATABASE '{0}' AS [{1}]", row[1], row[0]);
-                cmd.ExecuteNonQuery();
-              }
-            }
-          }
-        }
-      }
-    }
-
-    /// <summary>
-    /// 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.
-    /// </summary>
-    /// <returns></returns>
-    public object Clone()
-    {
-      return new SqliteConnection(this);
-    }
-
-    /// <summary>
-    /// Disposes of the SqliteConnection, closing it if it is active.
-    /// </summary>
-    /// <param name="disposing">True if the connection is being explicitly closed.</param>
-    protected override void Dispose(bool disposing)
-    {
-      base.Dispose(disposing);
-      Close();
-    }
-
-    /// <summary>
-    /// Creates a database file.  This just creates a zero-byte file which Sqlite
-    /// will turn into a database when the file is opened properly.
-    /// </summary>
-    /// <param name="databaseFileName">The file to create</param>
-    static public void CreateFile(string databaseFileName)
-    {
-      System.IO.FileStream fs = System.IO.File.Create(databaseFileName);
-      fs.Close();
-    }
-
-    /// <summary>
-    /// On NTFS volumes, this function turns on the compression attribute for the given file.
-    /// It must not be open or referenced at the time of the function call.
-    /// </summary>
-    /// <param name="databaseFileName">The file to compress</param>
-    static public void CompressFile(string databaseFileName)
-    {
-      UnsafeNativeMethods.sqlite3_compressfile(databaseFileName);
-    }
-
-    /// <summary>
-    /// On NTFS volumes, this function removes the compression attribute for the given file.
-    /// It must not be open or referenced at the time of the function call.
-    /// </summary>
-    /// <param name="databaseFileName">The file to decompress</param>
-    static public void DecompressFile(string databaseFileName)
-    {
-      UnsafeNativeMethods.sqlite3_decompressfile(databaseFileName);
-    }
-
-    /// <summary>
-    /// Raises the state change event when the state of the connection changes
-    /// </summary>
-    /// <param name="newState">The new state.  If it is different from the previous state, an event is raised.</param>
-    internal void OnStateChange(ConnectionState newState)
-    {
-      // FIXME: breaks when the commented out code is used
-      ConnectionState oldState = _connectionState;
-      _connectionState = newState;
-
-//      if (StateChange != null && oldState != newState)
-      if (oldState != newState)
-      {
-        StateChangeEventArgs e = new StateChangeEventArgs(oldState, newState);
-        //StateChange(this, e);
-       base.OnStateChange (e);
-      }
-    }
-
-    /// <summary>
-    /// Creates a new SqliteTransaction if one isn't already active on the connection.
-    /// </summary>
-    /// <param name="isolationLevel">Sqlite doesn't support varying isolation levels, so this parameter is ignored.</param>
-    /// <param name="deferredLock">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 
-    /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock.</param>
-    /// <returns>Returns a SqliteTransaction object.</returns>
-    public SqliteTransaction BeginTransaction(System.Data.IsolationLevel isolationLevel, bool deferredLock)
-    {
-      return BeginTransaction(deferredLock);
-    }
-
-    /// <summary>
-    /// Creates a new SqliteTransaction if one isn't already active on the connection.
-    /// </summary>
-    /// <param name="deferredLock">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 
-    /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock.</param>
-    /// <returns>Returns a SqliteTransaction object.</returns>
-    public SqliteTransaction BeginTransaction(bool deferredLock)
-    {
-      if (_connectionState != ConnectionState.Open)
-        throw new InvalidOperationException();
-
-      return new SqliteTransaction(this, deferredLock);
-    }
-
-    /// <summary>
-    /// Creates a new SqliteTransaction if one isn't already active on the connection.
-    /// </summary>
-    /// <param name="isolationLevel">Sqlite supports only serializable transactions.</param>
-    /// <returns>Returns a SqliteTransaction object.</returns>
-    public new SqliteTransaction BeginTransaction(System.Data.IsolationLevel isolationLevel)
-    {
-      return BeginTransaction(false);
-    }
-
-    /// <summary>
-    /// Creates a new SqliteTransaction if one isn't already active on the connection.
-    /// </summary>
-    /// <returns>Returns a SqliteTransaction object.</returns>
-    public new SqliteTransaction BeginTransaction()
-    {
-      return BeginTransaction(false);
-    }
-
-    /// <summary>
-    /// Forwards to the local BeginTransaction() function
-    /// </summary>
-    /// <param name="isolationLevel"></param>
-    /// <returns></returns>
-    protected override DbTransaction BeginDbTransaction(System.Data.IsolationLevel isolationLevel)
-    {
-      return BeginTransaction(false);
-    }
-
-    /// <summary>
-    /// Not implemented
-    /// </summary>
-    /// <param name="databaseName"></param>
-    public override void ChangeDatabase(string databaseName)
-    {
-      throw new NotImplementedException();
-    }
-
-    /// <summary>
-    /// When the database connection is closed, all commands linked to this connection are automatically reset.
-    /// </summary>
-    public override void Close()
-    {
-      if (_sql != null)
-      {
-        // Force any commands associated with this connection to release their unmanaged
-        // resources.  The commands are still valid and will automatically re-acquire the
-        // unmanaged resources the next time they are run -- provided this connection is
-        // re-opened before then.
-        lock (_commandList)
-        {
-          foreach (SqliteCommand cmd in _commandList)
-            cmd.ClearCommands();
-        }
-
-#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 
-          // 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;
-          cnn._connectionState = _connectionState;
-          cnn._version = _version;
-          
-          cnn._enlistment._transaction._cnn = cnn;
-          cnn._enlistment._disposeConnection = true;
-        }
-        else
-        {
-          _sql.Close();
-        }
-        _enlistment = null;
-#else
-        _sql.Close();
-#endif
-        _sql = null;
-        _transactionLevel = 0;
-      }
-
-      OnStateChange(ConnectionState.Closed);
-    }
-
-    /// <summary>
-    /// The connection string containing the parameters for the connection
-    /// </summary>
-    /// <remarks>
-    /// <list type="table">
-    /// <listheader>
-    /// <term>Parameter</term>
-    /// <term>Values</term>
-    /// <term>Required</term>
-    /// <term>Default</term>
-    /// </listheader>
-    /// <item>
-    /// <description>Data Source</description>
-    /// <description>{filename}</description>
-    /// <description>Y</description>
-    /// <description></description>
-    /// </item>
-    /// <item>
-    /// <description>Version</description>
-    /// <description>3</description>
-    /// <description>N</description>
-    /// <description>3</description>
-    /// </item>
-    /// <item>
-    /// <description>UseUTF16Encoding</description>
-    /// <description><b>True</b><br/><b>False</b></description>
-    /// <description>N</description>
-    /// <description>False</description>
-    /// </item>
-    /// <item>
-    /// <description>DateTimeFormat</description>
-    /// <description><b>Ticks</b> - Use DateTime.Ticks<br/><b>ISO8601</b> - Use ISO8601 DateTime format</description>
-    /// <description>N</description>
-    /// <description>ISO8601</description>
-    /// </item>
-    /// <item>
-    /// <description>BinaryGUID</description>
-    /// <description><b>Yes/On/1</b> - Store GUID columns in binary form<br/><b>No/Off/0</b> - Store GUID columns as text</description>
-    /// <description>N</description>
-    /// <description>On</description>
-    /// </item>
-    /// <item>
-    /// <description>Cache Size</description>
-    /// <description>{size in bytes}</description>
-    /// <description>N</description>
-    /// <description>2000</description>
-    /// </item>
-    /// <item>
-    /// <description>Synchronous</description>
-    /// <description><b>Normal</b> - Normal file flushing behavior<br/><b>Full</b> - Full flushing after all writes<br/><b>Off</b> - Underlying OS flushes I/O's</description>
-    /// <description>N</description>
-    /// <description>Normal</description>
-    /// </item>
-    /// <item>
-    /// <description>Page Size</description>
-    /// <description>{size in bytes}</description>
-    /// <description>N</description>
-    /// <description>1024</description>
-    /// </item>
-    /// <item>
-    /// <description>Password</description>
-    /// <description>{password}</description>
-    /// <description>N</description>
-    /// <description></description>
-    /// </item>
-    /// <item>
-    /// <description>Enlist</description>
-    /// <description><B>Y</B> - Automatically enlist in distributed transactions<br/><b>N</b> - No automatic enlistment</description>
-    /// <description>N</description>
-    /// <description>Y</description>
-    /// </item>
-    /// </list>
-    /// </remarks>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [RefreshProperties(RefreshProperties.All), DefaultValue("")]
-    [Editor("Sqlite.Designer.SqliteConnectionStringEditor, Sqlite.Designer, Version=1.0.31.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
-#endif
-    public override string ConnectionString
-    {
-      get
-      {
-        return _connectionString;
-      }
-      set
-      {
-        if (value == null)
-          throw new ArgumentNullException();
-
-        else if (_connectionState != ConnectionState.Closed)
-          throw new InvalidOperationException();
-
-        _connectionString = value;
-      }
-    }
-
-    /// <summary>
-    /// Create a new SqliteCommand and associate it with this connection.
-    /// </summary>
-    /// <returns>Returns an instantiated SqliteCommand object already assigned to this connection.</returns>
-    public new SqliteCommand CreateCommand()
-    {
-      return new SqliteCommand(this);
-    }
-
-    /// <summary>
-    /// Forwards to the local CreateCommand() function
-    /// </summary>
-    /// <returns></returns>
-    protected override DbCommand CreateDbCommand()
-    {
-      return CreateCommand();
-    }
-
-    /// <summary>
-    /// Returns the filename without extension or path
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
-#endif
-    public override string DataSource
-    {
-      get 
-      {
-        return _dataSource;
-      }
-    }
-
-    /// <summary>
-    /// Returns "main'
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
-#endif
-    public override string Database
-    {
-      get
-      {
-        return "main";
-      }
-    }
-
-    /// <summary>
-    /// Maps mono-specific connection string keywords to the standard ones
-    /// </summary>
-    /// <returns>The mapped keyword name</returns>
-    internal void MapMonoKeyword (string[] arPiece, List<KeyValuePair<string, string>> ls)
-    {
-           string keyword, value;
-           
-           switch (arPiece[0].ToLower (CultureInfo.InvariantCulture)) {
-                   case "uri":
-                           keyword = "Data Source";
-                           value = MapMonoUriPath (arPiece[1]);
-                           break;
-                           
-                   default:
-                           keyword = arPiece[0];
-                           value = arPiece[1];
-                           break;
-           }
-
-           ls.Add(new KeyValuePair<string, string>(keyword, value));
-    }
-
-    internal string MapMonoUriPath (string path)
-    {
-           if (path.StartsWith ("file://")) {
-                   return path.Substring (7);
-           } else if (path.StartsWith ("file:")) {
-                   return path.Substring (5);
-           } else if (path.StartsWith ("/")) {
-                   return path;
-           } else {
-                   throw new InvalidOperationException ("Invalid connection string: invalid URI");
-           }
-    }
-    
-    /// <summary>
-    /// Parses the connection string into component parts
-    /// </summary>
-    /// <returns>An array of key-value pairs representing each parameter of the connection string</returns>
-    internal KeyValuePair<string, string>[] ParseConnectionString()
-    {
-      string s = _connectionString.Replace (',', ';'); // Mono compatibility
-      int n;
-      List<KeyValuePair<string, string>> ls = new List<KeyValuePair<string, string>>();
-
-      // First split into semi-colon delimited values.  The Split() function of SqliteBase accounts for and properly
-      // skips semi-colons in quoted strings
-      string[] arParts = SqliteConvert.Split(s, ';');
-      string[] arPiece;
-
-      int x = arParts.Length;
-      // For each semi-colon piece, split into key and value pairs by the presence of the = sign
-      for (n = 0; n < x; n++)
-      {
-        arPiece = SqliteConvert.Split(arParts[n], '=');
-        if (arPiece.Length == 2)
-         MapMonoKeyword (arPiece, ls);
-        else throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Invalid ConnectionString format for parameter \"{0}\"", (arPiece.Length > 0) ? arPiece[0] : "null"));
-      }
-      KeyValuePair<string, string>[] ar = new KeyValuePair<string, string>[ls.Count];
-      ls.CopyTo(ar, 0);
-
-      // Return the array of key-value pairs
-      return ar;
-    }
-
-#if !PLATFORM_COMPACTFRAMEWORK
-    /// <summary>
-    /// Manual distributed transaction enlistment support
-    /// </summary>
-    /// <param name="transaction">The distributed transaction to enlist in</param>
-    public override void EnlistTransaction(System.Transactions.Transaction transaction)
-    {
-      if (_transactionLevel > 0 && transaction != null)
-        throw new ArgumentException("Unable to enlist in transaction, a local transaction already exists");
-
-      if (_enlistment != null && transaction != _enlistment._scope)
-        throw new ArgumentException("Already enlisted in a transaction");
-
-      _enlistment = new SqliteEnlistment(this, transaction);
-    }
-#endif
-
-    /// <summary>
-    /// Looks for a key in the array of key/values of the parameter string.  If not found, return the specified default value
-    /// </summary>
-    /// <param name="opts">The Key/Value pair array to look in</param>
-    /// <param name="key">The key to find</param>
-    /// <param name="defValue">The default value to return if the key is not found</param>
-    /// <returns>The value corresponding to the specified key, or the default value if not found.</returns>
-    static internal string FindKey(KeyValuePair<string, string>[] opts, string key, string defValue)
-    {
-      int x = opts.Length;
-      for (int n = 0; n < x; n++)
-      {
-        if (String.Compare(opts[n].Key, key, true, CultureInfo.InvariantCulture) == 0)
-        {
-          return opts[n].Value;
-        }
-      }
-      return defValue;
-    }
-
-    /// <summary>
-    /// Opens the connection using the parameters found in the <see cref="ConnectionString">ConnectionString</see>
-    /// </summary>
-    public override void Open()
-    {
-      if (_connectionState != ConnectionState.Closed)
-        throw new InvalidOperationException();
-
-      Close();
-
-      KeyValuePair<string, string>[] opts = ParseConnectionString();
-      string fileName;
-
-      if (Convert.ToInt32(FindKey(opts, "Version", "3"), CultureInfo.InvariantCulture) != 3)
-        throw new NotSupportedException("Only Sqlite Version 3 is supported at this time");
-
-      fileName = FindKey(opts, "Data Source", "");
-
-      if (String.IsNullOrEmpty(fileName))
-        throw new ArgumentException("Data Source cannot be empty.  Use :memory: to open an in-memory database");
-
-      if (String.Compare(fileName, ":MEMORY:", true, CultureInfo.InvariantCulture) == 0)
-        fileName = ":memory:";
-#if PLATFORM_COMPACTFRAMEWORK
-      else if (fileName.StartsWith(".\\"))
-        fileName = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase) + fileName.Substring(1);
-#endif
-      string bt = FindKey (opts, "busy_timeout", "30");
-      try {
-             _busyTimeout = Int32.Parse (bt);
-      } catch (Exception) {
-             // ignore
-      }
-      
-      try
-      {
-        bool bUTF16 = (Convert.ToBoolean(FindKey(opts, "UseUTF16Encoding", "False"), CultureInfo.InvariantCulture) == true);
-        SqliteDateFormats dateFormat = String.Compare(FindKey(opts, "DateTimeFormat", "ISO8601"), "ticks", true, CultureInfo.InvariantCulture) == 0 ? SqliteDateFormats.Ticks : SqliteDateFormats.ISO8601;
-
-        if (bUTF16) // Sqlite automatically sets the encoding of the database to UTF16 if called from sqlite3_open16()
-          _sql = new Sqlite3_UTF16(dateFormat);
-        else
-          _sql = new Sqlite3(dateFormat);
-
-        fileName = ExpandFileName(fileName);
-
-        try
-        {
-          if (System.IO.File.Exists(fileName) == false)
-            throw new System.IO.FileNotFoundException(String.Format(CultureInfo.CurrentCulture, "Unable to locate file \"{0}\", creating new database.", fileName));
-        }
-        catch
-        {
-        }
-
-        _sql.Open(fileName);
-
-        _binaryGuid = (Convert.ToBoolean(FindKey(opts, "BinaryGUID", "True"), CultureInfo.InvariantCulture) == true);
-
-#if MONO_SUPPORT_PASSWORDS
-       // Not used under mono now
-        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 = System.IO.Path.GetFileNameWithoutExtension(fileName);
-
-        OnStateChange(ConnectionState.Open);
-        _version++;
-
-        using (SqliteCommand cmd = CreateCommand())
-        {
-          string defValue;
-
-          defValue = FindKey(opts, "Synchronous", "Normal");
-          if (String.Compare(defValue, "Normal", true, CultureInfo.InvariantCulture) != 0)
-          {
-            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Synchronous={0}", defValue);
-            cmd.ExecuteNonQuery();
-          }
-
-          defValue = FindKey(opts, "Cache Size", "2000");
-          if (Convert.ToInt32(defValue) != 2000)
-          {
-            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Cache_Size={0}", defValue);
-            cmd.ExecuteNonQuery();
-          }
-
-          if (fileName != ":memory:")
-          {
-            defValue = FindKey(opts, "Page Size", "1024");
-            if (Convert.ToInt32(defValue) != 1024)
-            {
-              cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Page_Size={0}", defValue);
-              cmd.ExecuteNonQuery();
-            }
-          }
-        }
-
-#if !PLATFORM_COMPACTFRAMEWORK
-        if (FindKey(opts, "Enlist", "Y").ToUpper()[0] == 'Y' && System.Transactions.Transaction.Current != null)
-          EnlistTransaction(System.Transactions.Transaction.Current);
-#endif
-      }
-      catch (SqliteException)
-      {
-        OnStateChange(ConnectionState.Broken);
-        throw;
-      }
-    }
-
-    /// <summary>
-    /// Returns the version of the underlying Sqlite database engine
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
-#endif
-    public override string ServerVersion
-    {
-      get
-      {
-        if (_connectionState != ConnectionState.Open)
-          throw new InvalidOperationException();
-
-        return _sql.Version;
-      }
-    }
-
-    /// <summary>
-    /// Returns the state of the connection.
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
-#endif
-    public override ConnectionState State
-    {
-      get
-      {
-        return _connectionState;
-      }
-    }
-
-#if MONO_SUPPORT_PASSWORDS // Not used on mono now
-    /// <summary>
-    /// Change the password (or assign a password) to an open database.
-    /// </summary>
-    /// <remarks>
-    /// No readers or writers may be active for this process.  The database must already be open
-    /// and if it already was password protected, the existing password must already have been supplied.
-    /// </remarks>
-    /// <param name="newPassword">The new password to assign to the database</param>
-    public void ChangePassword(string newPassword)
-    {
-      ChangePassword(String.IsNullOrEmpty(newPassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(newPassword));
-    }
-
-    /// <summary>
-    /// Change the password (or assign a password) to an open database.
-    /// </summary>
-    /// <remarks>
-    /// No readers or writers may be active for this process.  The database must already be open
-    /// and if it already was password protected, the existing password must already have been supplied.
-    /// </remarks>
-    /// <param name="newPassword">The new password to assign to the database</param>
-    public void ChangePassword(byte[] newPassword)
-    {
-      if (_connectionState != ConnectionState.Open)
-        throw new InvalidOperationException("Database must be opened before changing the password.");
-
-      _sql.ChangePassword(newPassword);
-    }
-
-    /// <summary>
-    /// Sets the password for a password-protected database.  A password-protected database is
-    /// unusable for any operation until the password has been set.
-    /// </summary>
-    /// <param name="databasePassword">The password for the database</param>
-    public void SetPassword(string databasePassword)
-    {
-      SetPassword(String.IsNullOrEmpty(databasePassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(databasePassword));
-    }
-    
-    /// <summary>
-    /// Sets the password for a password-protected database.  A password-protected database is
-    /// unusable for any operation until the password has been set.
-    /// </summary>
-    /// <param name="databasePassword">The password for the database</param>
-    public void SetPassword(byte[] databasePassword)
-    {
-      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
-    
-    /// <summary>
-    /// Expand the filename of the data source, resolving the |DataDirectory| macro as appropriate.
-    /// </summary>
-    /// <param name="sourceFile">The database filename to expand</param>
-    /// <returns>The expanded path and filename of the filename</returns>
-    private string ExpandFileName(string sourceFile)
-    {
-      if (String.IsNullOrEmpty(sourceFile)) return sourceFile;
-
-      if (sourceFile.StartsWith(_dataDirectory, StringComparison.OrdinalIgnoreCase))
-      {
-        string dataDirectory;
-
-#if PLATFORM_COMPACTFRAMEWORK
-        dataDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase);
-#else
-        dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory") as string;
-        if (String.IsNullOrEmpty(dataDirectory))
-          dataDirectory = AppDomain.CurrentDomain.BaseDirectory;
-#endif
-
-        if (sourceFile.Length > _dataDirectory.Length)
-        {
-          if (sourceFile[_dataDirectory.Length] == System.IO.Path.DirectorySeparatorChar ||
-              sourceFile[_dataDirectory.Length] == System.IO.Path.AltDirectorySeparatorChar)
-            sourceFile = sourceFile.Remove(_dataDirectory.Length, 1);
-        }
-        sourceFile = System.IO.Path.Combine(dataDirectory, sourceFile.Substring(_dataDirectory.Length));
-      }
-
-      return sourceFile;
-    }
-    ///<overloads>
-    /// The following commands are used to extract schema information out of the database.  Valid schema types are:
-    /// <list type="bullet">
-    /// <item>
-    /// <description>MetaDataCollections</description>
-    /// </item>
-    /// <item>
-    /// <description>DataSourceInformation</description>
-    /// </item>
-    /// <item>
-    /// <description>Catalogs</description>
-    /// </item>
-    /// <item>
-    /// <description>Columns</description>
-    /// </item>
-    /// <item>
-    /// <description>ForeignKeys</description>
-    /// </item>
-    /// <item>
-    /// <description>Indexes</description>
-    /// </item>
-    /// <item>
-    /// <description>IndexColumns</description>
-    /// </item>
-    /// <item>
-    /// <description>Tables</description>
-    /// </item>
-    /// <item>
-    /// <description>Views</description>
-    /// </item>
-    /// <item>
-    /// <description>ViewColumns</description>
-    /// </item>
-    /// </list>
-    /// </overloads>
-    /// <summary>
-    /// Returns the MetaDataCollections schema
-    /// </summary>
-    /// <returns>A DataTable of the MetaDataCollections schema</returns>
-    public override DataTable GetSchema()
-    {
-      return GetSchema("MetaDataCollections", null);
-    }
-
-    /// <summary>
-    /// Returns schema information of the specified collection
-    /// </summary>
-    /// <param name="collectionName">The schema collection to retrieve</param>
-    /// <returns>A DataTable of the specified collection</returns>
-    public override DataTable GetSchema(string collectionName)
-    {
-      return GetSchema(collectionName, new string[0]);
-    }
-
-    /// <summary>
-    /// Retrieves schema information using the specified constraint(s) for the specified collection
-    /// </summary>
-    /// <param name="collectionName">The collection to retrieve</param>
-    /// <param name="restrictionValues">The restrictions to impose</param>
-    /// <returns>A DataTable of the specified collection</returns>
-    public override DataTable GetSchema(string collectionName, string[] restrictionValues)
-    {
-      if (_connectionState != ConnectionState.Open)
-        throw new InvalidOperationException();
-
-      string[] parms = new string[5];
-
-      if (restrictionValues == null) restrictionValues = new string[0];
-      restrictionValues.CopyTo(parms, 0);
-
-      switch (collectionName.ToUpper(CultureInfo.InvariantCulture))
-      {
-        case "METADATACOLLECTIONS":
-          return Schema_MetaDataCollections();
-        case "DATASOURCEINFORMATION":
-          return Schema_DataSourceInformation();
-        case "DATATYPES":
-          return Schema_DataTypes();
-        case "COLUMNS":
-          return Schema_Columns(parms[0], parms[2], parms[3]);
-        case "INDEXES":
-          return Schema_Indexes(parms[0], parms[2], parms[4]);
-        case "INDEXCOLUMNS":
-          return Schema_IndexColumns(parms[0], parms[2], parms[3], parms[4]);
-        case "TABLES":
-          return Schema_Tables(parms[0], parms[2], parms[3]);
-        case "VIEWS":
-          return Schema_Views(parms[0], parms[2]);
-        case "VIEWCOLUMNS":
-          return Schema_ViewColumns(parms[0], parms[2], parms[3]);
-        case "FOREIGNKEYS":
-          return Schema_ForeignKeys(parms[0], parms[2], parms[3]);
-        case "CATALOGS":
-          return Schema_Catalogs(parms[0]);
-        case "RESERVEDWORDS":
-          return Schema_ReservedWords();
-      }
-      throw new NotSupportedException();
-    }
-
-    private static DataTable Schema_ReservedWords()
-    {
-      DataTable tbl = new DataTable("MetaDataCollections");
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add("ReservedWord", typeof(string));
-      tbl.Columns.Add("MaximumVersion", typeof(string));
-      tbl.Columns.Add("MinimumVersion", typeof(string));
-
-      tbl.BeginLoadData();
-      DataRow row;
-      foreach (string word in SR.Keywords.Split(new char[] { ',' }))
-      {
-        row = tbl.NewRow();
-        row[0] = word;
-        tbl.Rows.Add(row);
-      }
-
-      tbl.AcceptChanges();
-      tbl.EndLoadData();
-
-      return tbl;
-    }
-
-    /// <summary>
-    /// Builds a MetaDataCollections schema datatable
-    /// </summary>
-    /// <returns>DataTable</returns>
-    private static DataTable Schema_MetaDataCollections()
-    {
-      DataTable tbl = new DataTable("MetaDataCollections");
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add("CollectionName", typeof(string));
-      tbl.Columns.Add("NumberOfRestrictions", typeof(int));
-      tbl.Columns.Add("NumberOfIdentifierParts", typeof(int));
-
-      tbl.BeginLoadData();
-
-      System.IO.StringReader reader = new System.IO.StringReader(SR.MetaDataCollections);
-      tbl.ReadXml(reader);
-      reader.Close();
-
-      tbl.AcceptChanges();
-      tbl.EndLoadData();
-
-      return tbl;
-    }
-
-    /// <summary>
-    /// Builds a DataSourceInformation datatable
-    /// </summary>
-    /// <returns>DataTable</returns>
-    private DataTable Schema_DataSourceInformation()
-    {
-      DataTable tbl = new DataTable("DataSourceInformation");
-      DataRow row;
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add(DbMetaDataColumnNames.CompositeIdentifierSeparatorPattern, typeof(string));
-      tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductName, typeof(string));
-      tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductVersion, typeof(string));
-      tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductVersionNormalized, typeof(string));
-      tbl.Columns.Add(DbMetaDataColumnNames.GroupByBehavior, typeof(int));
-      tbl.Columns.Add(DbMetaDataColumnNames.IdentifierPattern, typeof(string));
-      tbl.Columns.Add(DbMetaDataColumnNames.IdentifierCase, typeof(int));
-      tbl.Columns.Add(DbMetaDataColumnNames.OrderByColumnsInSelect, typeof(bool));
-      tbl.Columns.Add(DbMetaDataColumnNames.ParameterMarkerFormat, typeof(string));
-      tbl.Columns.Add(DbMetaDataColumnNames.ParameterMarkerPattern, typeof(string));
-      tbl.Columns.Add(DbMetaDataColumnNames.ParameterNameMaxLength, typeof(int));
-      tbl.Columns.Add(DbMetaDataColumnNames.ParameterNamePattern, typeof(string));
-      tbl.Columns.Add(DbMetaDataColumnNames.QuotedIdentifierPattern, typeof(string));
-      tbl.Columns.Add(DbMetaDataColumnNames.QuotedIdentifierCase, typeof(int));
-      tbl.Columns.Add(DbMetaDataColumnNames.StatementSeparatorPattern, typeof(string));
-      tbl.Columns.Add(DbMetaDataColumnNames.StringLiteralPattern, typeof(string));
-      tbl.Columns.Add(DbMetaDataColumnNames.SupportedJoinOperators, typeof(int));
-
-      tbl.BeginLoadData();
-
-      row = tbl.NewRow();
-      row.ItemArray = new object[] {
-        null,
-        "Sqlite",
-        _sql.Version,
-        _sql.Version,
-        3,
-        @"(^\[\p{Lo}\p{Lu}\p{Ll}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Nd}@$#_]*$)|(^\[[^\]\0]|\]\]+\]$)|(^\""[^\""\0]|\""\""+\""$)",
-        1,
-        false,
-        "{0}",
-        @"@[\p{Lo}\p{Lu}\p{Ll}\p{Lm}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_@#\$]*(?=\s+|$)",
-        255,
-        @"^[\p{Lo}\p{Lu}\p{Ll}\p{Lm}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_@#\$]*(?=\s+|$)",
-        @"(([^\[]|\]\])*)",
-        1,
-        ";",
-        @"'(([^']|'')*)'", // ' a bug in c-sharp mode for emacs
-        15
-      };
-      tbl.Rows.Add(row);
-
-      tbl.AcceptChanges();
-      tbl.EndLoadData();
-
-      return tbl;
-    }
-
-    /// <summary>
-    /// Build a Columns schema
-    /// </summary>
-    /// <param name="strCatalog">The catalog (attached database) to query, can be null</param>
-    /// <param name="strTable">The table to retrieve schema information for, must not be null</param>
-    /// <param name="strColumn">The column to retrieve schema information for, can be null</param>
-    /// <returns>DataTable</returns>
-    private DataTable Schema_Columns(string strCatalog, string strTable, string strColumn)
-    {
-      DataTable tbl = new DataTable("Columns");
-      DataRow row;
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
-      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
-      tbl.Columns.Add("TABLE_NAME", typeof(string));
-      tbl.Columns.Add("COLUMN_NAME", typeof(string));
-      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));
-      tbl.Columns.Add("COLUMN_PROPID", typeof(long));
-      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));
-      tbl.Columns.Add("COLUMN_HASDEFAULT", typeof(bool));
-      tbl.Columns.Add("COLUMN_DEFAULT", typeof(string));
-      tbl.Columns.Add("COLUMN_FLAGS", typeof(long));
-      tbl.Columns.Add("IS_NULLABLE", typeof(bool));
-      tbl.Columns.Add("DATA_TYPE", typeof(string));
-      tbl.Columns.Add("TYPE_GUID", typeof(Guid));
-      tbl.Columns.Add("CHARACTER_MAXIMUM_LENGTH", typeof(int));
-      tbl.Columns.Add("CHARACTER_OCTET_LENGTH", typeof(int));
-      tbl.Columns.Add("NUMERIC_PRECISION", typeof(int));
-      tbl.Columns.Add("NUMERIC_SCALE", typeof(int));
-      tbl.Columns.Add("DATETIME_PRECISION", typeof(long));
-      tbl.Columns.Add("CHARACTER_SET_CATALOG", typeof(string));
-      tbl.Columns.Add("CHARACTER_SET_SCHEMA", typeof(string));
-      tbl.Columns.Add("CHARACTER_SET_NAME", typeof(string));
-      tbl.Columns.Add("COLLATION_CATALOG", typeof(string));
-      tbl.Columns.Add("COLLATION_SCHEMA", typeof(string));
-      tbl.Columns.Add("COLLATION_NAME", typeof(string));
-      tbl.Columns.Add("DOMAIN_CATALOG", typeof(string));
-      tbl.Columns.Add("DOMAIN_NAME", typeof(string));
-      tbl.Columns.Add("DESCRIPTION", typeof(string));
-      tbl.Columns.Add("PRIMARY_KEY", typeof(bool));
-
-      tbl.BeginLoadData();
-
-      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
-
-      using (SqliteCommand cmdTables = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table' OR [type] LIKE 'view'", strCatalog), this))
-      using (SqliteDataReader rdTables = cmdTables.ExecuteReader())
-      {
-        while (rdTables.Read())
-        {
-          if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), true, CultureInfo.InvariantCulture) == 0)
-          {
-            using (SqliteCommand cmd = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdTables.GetString(2)), this))
-            using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader(CommandBehavior.SchemaOnly))
-            using (DataTable tblSchema = rd.GetSchemaTable(false, true))
-            {
-              foreach (DataRow schemaRow in tblSchema.Rows)
-              {
-                if (String.Compare(schemaRow[SchemaTableColumn.ColumnName].ToString(), strColumn, true, CultureInfo.InvariantCulture) == 0
-                  || strColumn == null)
-                {
-                  row = tbl.NewRow();
-
-                  row["TABLE_NAME"] = rdTables.GetString(2);
-                  row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.ColumnName];
-                  row["TABLE_CATALOG"] = strCatalog;
-                  row["ORDINAL_POSITION"] = schemaRow[SchemaTableColumn.ColumnOrdinal];
-                  row["COLUMN_HASDEFAULT"] = (schemaRow[SchemaTableOptionalColumn.DefaultValue] != DBNull.Value);
-                  row["COLUMN_DEFAULT"] = schemaRow[SchemaTableOptionalColumn.DefaultValue];
-                  row["IS_NULLABLE"] = schemaRow[SchemaTableColumn.AllowDBNull];
-                  row["DATA_TYPE"] = schemaRow["DataTypeName"]; // SqliteConvert.DbTypeToType((DbType)schemaRow[SchemaTableColumn.ProviderType]).ToString();
-                  row["CHARACTER_MAXIMUM_LENGTH"] = schemaRow[SchemaTableColumn.ColumnSize];
-                  row["TABLE_SCHEMA"] = schemaRow[SchemaTableColumn.BaseSchemaName];
-                  row["PRIMARY_KEY"] = schemaRow[SchemaTableColumn.IsKey];
-
-                  tbl.Rows.Add(row);
-                }
-              }
-            }
-          }
-        }
-      }
-
-      tbl.AcceptChanges();
-      tbl.EndLoadData();
-
-      return tbl;
-    }
-
-    /// <summary>
-    /// Returns index information for the given database and catalog
-    /// </summary>
-    /// <param name="strCatalog">The catalog (attached database) to query, can be null</param>
-    /// <param name="strIndex">The name of the index to retrieve information for, can be null</param>
-    /// <param name="strTable">The table to retrieve index information for, can be null</param>
-    /// <returns>DataTable</returns>
-    private DataTable Schema_Indexes(string strCatalog, string strTable, string strIndex)
-    {
-      DataTable tbl = new DataTable("Indexes");
-      DataRow row;
-      System.Collections.Generic.List<int> primaryKeys = new List<int>();
-      bool maybeRowId;
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
-      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
-      tbl.Columns.Add("TABLE_NAME", typeof(string));
-      tbl.Columns.Add("INDEX_CATALOG", typeof(string));
-      tbl.Columns.Add("INDEX_SCHEMA", typeof(string));
-      tbl.Columns.Add("INDEX_NAME", typeof(string));
-      tbl.Columns.Add("PRIMARY_KEY", typeof(bool));
-      tbl.Columns.Add("UNIQUE", typeof(bool));
-      tbl.Columns.Add("CLUSTERED", typeof(bool));
-      tbl.Columns.Add("TYPE", typeof(int));
-      tbl.Columns.Add("FILL_FACTOR", typeof(int));
-      tbl.Columns.Add("INITIAL_SIZE", typeof(int));
-      tbl.Columns.Add("NULLS", typeof(int));
-      tbl.Columns.Add("SORT_BOOKMARKS", typeof(bool));
-      tbl.Columns.Add("AUTO_UPDATE", typeof(bool));
-      tbl.Columns.Add("NULL_COLLATION", typeof(int));
-      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));
-      tbl.Columns.Add("COLUMN_NAME", typeof(string));
-      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));
-      tbl.Columns.Add("COLUMN_PROPID", typeof(long));
-      tbl.Columns.Add("COLLATION", typeof(short));
-      tbl.Columns.Add("CARDINALITY", typeof(Decimal));
-      tbl.Columns.Add("PAGES", typeof(int));
-      tbl.Columns.Add("FILTER_CONDITION", typeof(string));
-      tbl.Columns.Add("INTEGRATED", typeof(bool));
-
-      tbl.BeginLoadData();
-
-      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
-
-      using (SqliteCommand cmdTables = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table'", strCatalog), this))
-      using (SqliteDataReader rdTables = cmdTables.ExecuteReader())
-      {
-        while (rdTables.Read())
-        {
-          maybeRowId = false;
-          primaryKeys.Clear();
-          if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0)
-          {
-            // First, look for any rowid indexes -- which sqlite defines are INTEGER PRIMARY KEY columns.
-            // Such indexes are not listed in the indexes list but count as indexes just the same.
-            using (SqliteCommand cmdTable = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this))
-            using (SqliteDataReader rdTable = cmdTable.ExecuteReader())
-            {
-              while (rdTable.Read())
-              {
-                if (rdTable.GetInt32(5) == 1)
-                {
-                  primaryKeys.Add(rdTable.GetInt32(0));
-
-                  // If the primary key is of type INTEGER, then its a rowid and we need to make a fake index entry for it.
-                  if (String.Compare(rdTable.GetString(2), "INTEGER", true, CultureInfo.InvariantCulture) == 0)
-                    maybeRowId = true;
-                }
-              }
-            }
-
-            if (primaryKeys.Count == 1 && maybeRowId == true)
-            {
-              row = tbl.NewRow();
-
-              row["TABLE_CATALOG"] = strCatalog;
-              row["TABLE_NAME"] = rdTables.GetString(2);
-              row["INDEX_CATALOG"] = strCatalog;
-              row["PRIMARY_KEY"] = true;
-              row["INDEX_NAME"] = String.Format(CultureInfo.InvariantCulture, "sqlite_master_PK_{0}", rdTables.GetString(2));
-              row["UNIQUE"] = true;
-
-              if (String.Compare((string)row["INDEX_NAME"], strIndex, true, CultureInfo.InvariantCulture) == 0
-              || strIndex == null)
-              {
-                tbl.Rows.Add(row);
-              }
-
-              primaryKeys.Clear();
-            }
-
-            // Now fetch all the rest of the indexes.
-            using (SqliteCommand cmd = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_list([{1}])", strCatalog, rdTables.GetString(2)), this))
-            using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader())
-            {
-              while (rd.Read())
-              {
-                if (String.Compare(rd.GetString(1), strIndex, true, CultureInfo.InvariantCulture) == 0
-                || strIndex == null)
-                {
-                  row = tbl.NewRow();
-
-                  row["TABLE_CATALOG"] = strCatalog;
-                  row["TABLE_NAME"] = rdTables.GetString(2);
-                  row["INDEX_CATALOG"] = strCatalog;
-                  row["INDEX_NAME"] = rd.GetString(1);
-                  row["UNIQUE"] = rd.GetBoolean(2);
-                  row["PRIMARY_KEY"] = false;
-
-                  // Now for the really hard work.  Figure out which index is the primary key index.
-                  // The only way to figure it out is to check if the index was an autoindex and if we have a non-rowid
-                  // primary key, and all the columns in the given index match the primary key columns
-                  if (primaryKeys.Count > 0 && rd.GetString(1).StartsWith("sqlite_autoindex_" + rdTables.GetString(2), StringComparison.InvariantCultureIgnoreCase) == true)
-                  {
-                    using (SqliteCommand cmdDetails = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rd.GetString(1)), this))
-                    using (SqliteDataReader rdDetails = cmdDetails.ExecuteReader())
-                    {
-                      int nMatches = 0;
-                      while (rdDetails.Read())
-                      {
-                        if (primaryKeys.Contains(rdDetails.GetInt32(1)) == false)
-                        {
-                          nMatches = 0;
-                          break;
-                        }
-                        nMatches++;
-                      }
-                      if (nMatches == primaryKeys.Count)
-                      {
-                        row["PRIMARY_KEY"] = true;
-                        primaryKeys.Clear();
-                      }
-                    }
-                  }
-
-                  tbl.Rows.Add(row);
-                }
-              }
-            }
-          }
-        }
-      }
-
-      tbl.AcceptChanges();
-      tbl.EndLoadData();
-
-      return tbl;
-    }
-
-    /// <summary>
-    /// Retrieves table schema information for the database and catalog
-    /// </summary>
-    /// <param name="strCatalog">The catalog (attached database) to retrieve tables on</param>
-    /// <param name="strTable">The table to retrieve, can be null</param>
-    /// <param name="strType">The table type, can be null</param>
-    /// <returns>DataTable</returns>
-    private DataTable Schema_Tables(string strCatalog, string strTable, string strType)
-    {
-      DataTable tbl = new DataTable("Tables");
-      DataRow row;
-      string strItem;
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
-      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
-      tbl.Columns.Add("TABLE_NAME", typeof(string));
-      tbl.Columns.Add("TABLE_TYPE", typeof(string));
-      tbl.Columns.Add("TABLE_ID", typeof(long));
-      tbl.Columns.Add("TABLE_ROOTPAGE", typeof(int));
-
-      tbl.BeginLoadData();
-
-      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
-
-      using (SqliteCommand cmd = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT [type], [name], [tbl_name], [rootpage], [sql], [rowid] FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table'", strCatalog), this))
-      using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader())
-      {
-        while (rd.Read())
-        {
-          strItem = rd.GetString(0);
-          if (String.Compare(rd.GetString(2), 0, "SQLITE_", 0, 7, true, CultureInfo.InvariantCulture) == 0)
-            strItem = "SYSTEM_TABLE";
-
-          if (String.Compare(strType, strItem, true, CultureInfo.InvariantCulture) == 0
-            || strType == null)
-          {
-            if (String.Compare(rd.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0
-              || strTable == null)
-            {
-              row = tbl.NewRow();
-
-              row["TABLE_CATALOG"] = strCatalog;
-              row["TABLE_NAME"] = rd.GetString(2);
-              row["TABLE_TYPE"] = strItem;
-              row["TABLE_ID"] = rd.GetInt64(5);
-              row["TABLE_ROOTPAGE"] = rd.GetInt32(3);
-
-              tbl.Rows.Add(row);
-            }
-          }
-        }
-      }
-
-      tbl.AcceptChanges();
-      tbl.EndLoadData();
-
-      return tbl;
-    }
-
-    /// <summary>
-    /// Retrieves view schema information for the database
-    /// </summary>
-    /// <param name="strCatalog">The catalog (attached database) to retrieve views on</param>
-    /// <param name="strView">The view name, can be null</param>
-    /// <returns>DataTable</returns>
-    private DataTable Schema_Views(string strCatalog, string strView)
-    {
-      DataTable tbl = new DataTable("Views");
-      DataRow row;
-      string strItem;
-      int nPos;
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
-      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
-      tbl.Columns.Add("TABLE_NAME", typeof(string));
-      tbl.Columns.Add("VIEW_DEFINITION", typeof(string));
-      tbl.Columns.Add("CHECK_OPTION", typeof(bool));
-      tbl.Columns.Add("IS_UPDATABLE", typeof(bool));
-      tbl.Columns.Add("DESCRIPTION", typeof(string));
-      tbl.Columns.Add("DATE_CREATED", typeof(DateTime));
-      tbl.Columns.Add("DATE_MODIFIED", typeof(DateTime));
-
-      tbl.BeginLoadData();
-
-      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
-
-      using (SqliteCommand cmd = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'view'", strCatalog), this))
-      using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader())
-      {
-        while (rd.Read())
-        {
-          if (String.Compare(rd.GetString(1), strView, true, CultureInfo.InvariantCulture) == 0
-            || String.IsNullOrEmpty(strView))
-          {
-            strItem = rd.GetString(4).Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' ');
-            nPos = System.Globalization.CultureInfo.InvariantCulture.CompareInfo.IndexOf(strItem, " AS ", CompareOptions.IgnoreCase);
-            if (nPos > -1)
-            {
-              strItem = strItem.Substring(nPos + 4).Trim();
-              row = tbl.NewRow();
-
-              row["TABLE_CATALOG"] = strCatalog;
-              row["TABLE_NAME"] = rd.GetString(2);
-              row["IS_UPDATABLE"] = false;
-              row["VIEW_DEFINITION"] = strItem;
-
-              tbl.Rows.Add(row);
-            }
-          }
-        }
-      }
-
-      tbl.AcceptChanges();
-      tbl.EndLoadData();
-
-      return tbl;
-    }
-
-    /// <summary>
-    /// Retrieves catalog (attached databases) schema information for the database
-    /// </summary>
-    /// <param name="strCatalog">The catalog to retrieve, can be null</param>
-    /// <returns>DataTable</returns>
-    private DataTable Schema_Catalogs(string strCatalog)
-    {
-      DataTable tbl = new DataTable("Catalogs");
-      DataRow row;
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add("CATALOG_NAME", typeof(string));
-      tbl.Columns.Add("DESCRIPTION", typeof(string));
-      tbl.Columns.Add("ID", typeof(long));
-
-      tbl.BeginLoadData();
-
-      using (SqliteCommand cmd = new SqliteCommand("PRAGMA database_list", this))
-      using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader())
-      {
-        while (rd.Read())
-        {
-          if (String.Compare(rd.GetString(1), strCatalog, true, CultureInfo.InvariantCulture) == 0
-            || strCatalog == null)
-          {
-            row = tbl.NewRow();
-
-            row["CATALOG_NAME"] = rd.GetString(1);
-            row["DESCRIPTION"] = rd.GetString(2);
-            row["ID"] = rd.GetInt64(0);
-
-            tbl.Rows.Add(row);
-          }
-        }
-      }
-
-      tbl.AcceptChanges();
-      tbl.EndLoadData();
-
-      return tbl;
-    }
-
-    private DataTable Schema_DataTypes()
-    {
-      DataTable tbl = new DataTable("DataTypes");
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add("TypeName", typeof(String));
-      tbl.Columns.Add("ProviderDbType", typeof(int));
-      tbl.Columns.Add("ColumnSize", typeof(long));
-      tbl.Columns.Add("CreateFormat", typeof(String));
-      tbl.Columns.Add("CreateParameters", typeof(String));
-      tbl.Columns.Add("DataType", typeof(String));
-      tbl.Columns.Add("IsAutoIncrementable", typeof(bool));
-      tbl.Columns.Add("IsBestMatch", typeof(bool));
-      tbl.Columns.Add("IsCaseSensitive", typeof(bool));
-      tbl.Columns.Add("IsFixedLength", typeof(bool));
-      tbl.Columns.Add("IsFixedPrecisionScale", typeof(bool));
-      tbl.Columns.Add("IsLong", typeof(bool));
-      tbl.Columns.Add("IsNullable", typeof(bool));
-      tbl.Columns.Add("IsSearchable", typeof(bool));
-      tbl.Columns.Add("IsSearchableWithLike", typeof(bool));
-      tbl.Columns.Add("IsLiteralSupported", typeof(bool));
-      tbl.Columns.Add("LiteralPrefix", typeof(String));
-      tbl.Columns.Add("LiteralSuffix", typeof(String));
-      tbl.Columns.Add("IsUnsigned", typeof(bool));
-      tbl.Columns.Add("MaximumScale", typeof(short));
-      tbl.Columns.Add("MinimumScale", typeof(short));
-      tbl.Columns.Add("IsConcurrencyType", typeof(bool));
-
-      tbl.BeginLoadData();
-
-      System.IO.StringReader reader = new System.IO.StringReader(SR.DataTypes);
-      tbl.ReadXml(reader);
-      reader.Close();
-
-      tbl.AcceptChanges();
-      tbl.EndLoadData();
-
-      return tbl;
-    }
-
-    /// <summary>
-    /// Returns the base column information for indexes in a database
-    /// </summary>
-    /// <param name="strCatalog">The catalog to retrieve indexes for (can be null)</param>
-    /// <param name="strTable">The table to restrict index information by (can be null)</param>
-    /// <param name="strIndex">The index to restrict index information by (can be null)</param>
-    /// <param name="strColumn">The source column to restrict index information by (can be null)</param>
-    /// <returns>A DataTable containing the results</returns>
-    private DataTable Schema_IndexColumns(string strCatalog, string strTable, string strIndex, string strColumn)
-    {
-      DataTable tbl = new DataTable("IndexColumns");
-      DataRow row;
-      List<KeyValuePair<int, string>> primaryKeys = new List<KeyValuePair<int, string>>();
-      bool maybeRowId;
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add("CONSTRAINT_CATALOG", typeof(string));
-      tbl.Columns.Add("CONSTRAINT_SCHEMA", typeof(string));
-      tbl.Columns.Add("CONSTRAINT_NAME", typeof(string));
-      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
-      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
-      tbl.Columns.Add("TABLE_NAME", typeof(string));
-      tbl.Columns.Add("COLUMN_NAME", typeof(string));
-      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));
-      tbl.Columns.Add("INDEX_NAME", typeof(string));
-
-      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
-
-      tbl.BeginLoadData();
-
-      using (SqliteCommand cmdTables = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table'", strCatalog), this))
-      using (SqliteDataReader rdTables = cmdTables.ExecuteReader())
-      {
-        while (rdTables.Read())
-        {
-          maybeRowId = false;
-          primaryKeys.Clear();
-          if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0)
-          {
-            using (SqliteCommand cmdTable = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this))
-            using (SqliteDataReader rdTable = cmdTable.ExecuteReader())
-            {
-              while (rdTable.Read())
-              {
-                if (rdTable.GetInt32(5) == 1) // is a primary key
-                {
-                  primaryKeys.Add(new KeyValuePair<int, string>(rdTable.GetInt32(0), rdTable.GetString(1)));
-                  // Is an integer -- could be a rowid if no other primary keys exist in the table
-                  if (String.Compare(rdTable.GetString(2), "INTEGER", true, CultureInfo.InvariantCulture) == 0)
-                    maybeRowId = true;
-                }
-              }
-            }
-            if (primaryKeys.Count == 1 && maybeRowId == true)
-            {
-              row = tbl.NewRow();
-              row["CONSTRAINT_CATALOG"] = strCatalog;
-              row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "sqlite_master_PK_{0}", rdTables.GetString(2));
-              row["TABLE_CATALOG"] = strCatalog;
-              row["TABLE_NAME"] = rdTables.GetString(2);
-              row["COLUMN_NAME"] = primaryKeys[0].Value;
-              row["INDEX_NAME"] = row["CONSTRAINT_NAME"];
-              row["ORDINAL_POSITION"] = primaryKeys[0].Key;
-
-              if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, (string)row["INDEX_NAME"], true, CultureInfo.InvariantCulture) == 0)
-                tbl.Rows.Add(row);
-            }
-
-            using (SqliteCommand cmdIndexes = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'index' AND [tbl_name] LIKE '{1}'", strCatalog, rdTables.GetString(2).Replace("'", "''")), this))
-            using (SqliteDataReader rdIndexes = cmdIndexes.ExecuteReader())
-            {
-              while (rdIndexes.Read())
-              {
-                if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, rdIndexes.GetString(1), true, CultureInfo.InvariantCulture) == 0)
-                {
-                  using (SqliteCommand cmdIndex = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rdIndexes.GetString(1)), this))
-                  using (SqliteDataReader rdIndex = cmdIndex.ExecuteReader())
-                  {
-                    while (rdIndex.Read())
-                    {
-                      row = tbl.NewRow();
-                      row["CONSTRAINT_CATALOG"] = strCatalog;
-                      row["CONSTRAINT_NAME"] = rdIndexes.GetString(1);
-                      row["TABLE_CATALOG"] = strCatalog;
-                      row["TABLE_NAME"] = rdIndexes.GetString(2);
-                      row["COLUMN_NAME"] = rdIndex.GetString(2);
-                      row["INDEX_NAME"] = rdIndexes.GetString(1);
-                      row["ORDINAL_POSITION"] = rdIndex.GetInt32(1);
-
-                      if (String.IsNullOrEmpty(strColumn) || String.Compare(strColumn, row["COLUMN_NAME"].ToString(), true, CultureInfo.InvariantCulture) == 0)
-                        tbl.Rows.Add(row);
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-
-      tbl.EndLoadData();
-      tbl.AcceptChanges();
-
-      return tbl;
-    }
-
-    /// <summary>
-    /// Returns detailed column information for a specified view
-    /// </summary>
-    /// <param name="strCatalog">The catalog to retrieve columns for (can be null)</param>
-    /// <param name="strView">The view to restrict column information by (can be null)</param>
-    /// <param name="strColumn">The source column to restrict column information by (can be null)</param>
-    /// <returns>A DataTable containing the results</returns>
-    private DataTable Schema_ViewColumns(string strCatalog, string strView, string strColumn)
-    {
-      DataTable tbl = new DataTable("ViewColumns");
-      DataRow row;
-      string strSql;
-      int n;
-      DataRow schemaRow;
-      DataRow viewRow;
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add("VIEW_CATALOG", typeof(string));
-      tbl.Columns.Add("VIEW_SCHEMA", typeof(string));
-      tbl.Columns.Add("VIEW_NAME", typeof(string));
-      tbl.Columns.Add("VIEW_COLUMN_NAME", typeof(String));
-      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
-      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
-      tbl.Columns.Add("TABLE_NAME", typeof(string));
-      tbl.Columns.Add("COLUMN_NAME", typeof(string));
-
-      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
-
-      tbl.BeginLoadData();
-
-      using (SqliteCommand cmdViews = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'view'", strCatalog), this))
-      using (SqliteDataReader rdViews = cmdViews.ExecuteReader())
-      {
-        while (rdViews.Read())
-        {
-          if (String.IsNullOrEmpty(strView) || String.Compare(strView, rdViews.GetString(2), true, CultureInfo.InvariantCulture) == 0)
-          {
-            using (SqliteCommand cmdViewSelect = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdViews.GetString(2)), this))
-            {
-              strSql = rdViews.GetString(4).Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' ');
-              n = CultureInfo.InvariantCulture.CompareInfo.IndexOf(strSql, " AS ", CompareOptions.IgnoreCase);
-              if (n < 0)
-                continue;
-
-              strSql = strSql.Substring(n + 4);
-
-              using (SqliteCommand cmd = new SqliteCommand(strSql, this))
-              using (SqliteDataReader rdViewSelect = cmdViewSelect.ExecuteReader(CommandBehavior.SchemaOnly))
-              using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader(CommandBehavior.SchemaOnly))
-              using (DataTable tblSchemaView = rdViewSelect.GetSchemaTable(false, false))
-              using (DataTable tblSchema = rd.GetSchemaTable(false, false))
-              {
-                for (n = 0; n < tblSchema.Rows.Count; n++)
-                {
-                  viewRow = tblSchemaView.Rows[n];
-                  schemaRow = tblSchema.Rows[n];
-
-                  if (String.Compare(viewRow[SchemaTableColumn.ColumnName].ToString(), strColumn, true, CultureInfo.InvariantCulture) == 0
-                    || strColumn == null)
-                  {
-                    row = tbl.NewRow();
-
-                    row["VIEW_CATALOG"] = strCatalog;
-                    row["VIEW_NAME"] = rdViews.GetString(2);
-                    row["TABLE_CATALOG"] = strCatalog;
-                    row["TABLE_SCHEMA"] = schemaRow[SchemaTableColumn.BaseSchemaName];
-                    row["TABLE_NAME"] = schemaRow[SchemaTableColumn.BaseTableName];
-                    row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.ColumnName];
-                    row["VIEW_COLUMN_NAME"] = viewRow[SchemaTableColumn.ColumnName];
-
-                    tbl.Rows.Add(row);
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-
-      tbl.EndLoadData();
-      tbl.AcceptChanges();
-
-      return tbl;
-    }
-
-    /// <summary>
-    /// Retrieves foreign key information from the specified set of filters
-    /// </summary>
-    /// <param name="strCatalog">An optional catalog to restrict results on</param>
-    /// <param name="strTable">An optional table to restrict results on</param>
-    /// <param name="strKeyName">An optional foreign key name to restrict results on</param>
-    /// <returns>A DataTable with the results of the query</returns>
-    private DataTable Schema_ForeignKeys(string strCatalog, string strTable, string strKeyName)
-    {
-      DataTable tbl = new DataTable("ForeignKeys");
-      DataRow row;
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add("CONSTRAINT_CATALOG", typeof(string));
-      tbl.Columns.Add("CONSTRAINT_SCHEMA", typeof(string));
-      tbl.Columns.Add("CONSTRAINT_NAME", typeof(string));
-      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
-      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_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));
-      tbl.Columns.Add("FKEY_TO_COLUMN", typeof(string));
-
-      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
-
-      tbl.BeginLoadData();
-
-      using (SqliteCommand cmdTables = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table'", strCatalog), this))
-      using (SqliteDataReader rdTables = cmdTables.ExecuteReader())
-      {
-        while (rdTables.Read())
-        {
-          if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), true, CultureInfo.InvariantCulture) == 0)
-          {
-            using (SqliteCommand cmdTable = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdTables.GetString(2)), this))
-            using (SqliteDataReader rdTable = cmdTable.ExecuteReader(CommandBehavior.SchemaOnly))
-            using (SqliteCommand cmdKey = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].foreign_key_list([{1}])", strCatalog, rdTables.GetString(2)), this))
-            using (SqliteDataReader rdKey = cmdKey.ExecuteReader())
-            {
-              while (rdKey.Read())
-              {
-                row = tbl.NewRow();
-                row["CONSTRAINT_CATALOG"] = strCatalog;
-                row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}_{2}", rdTables.GetString(2), rdKey.GetString(3), rdKey.GetString(4));
-                row["TABLE_CATALOG"] = strCatalog;
-                row["TABLE_NAME"] = rdTables.GetString(2);
-                row["CONSTRAINT_TYPE"] = "FOREIGN KEY";
-                row["IS_DEFERRABLE"] = false;
-                row["INITIALLY_DEFERRED"] = false;
-                row["FKEY_FROM_COLUMN"] = rdKey.GetString(3);
-                row["FKEY_FROM_ORDINAL_POSITION"] = rdTable.GetOrdinal(row["FKEY_FROM_COLUMN"].ToString());
-                row["FKEY_TO_CATALOG"] = strCatalog;
-                row["FKEY_TO_TABLE"] = rdKey.GetString(2);
-                row["FKEY_TO_COLUMN"] = rdKey.GetString(4);
-
-                if (String.IsNullOrEmpty(strKeyName) || String.Compare(strKeyName, row["CONSTRAINT_NAME"].ToString(), true, CultureInfo.InvariantCulture) == 0)
-                  tbl.Rows.Add(row);
-              }
-            }
-          }
-        }
-      }
-
-      tbl.EndLoadData();
-      tbl.AcceptChanges();
-
-      return tbl;
-    }
-
-    internal void AddCommand(SqliteCommand cmd)
-    {
-      lock (_commandList)
-      {
-        _commandList.Add(cmd);
-      }
-    }
-
-    internal void RemoveCommand(SqliteCommand cmd)
-    {
-      lock (_commandList)
-      {
-        _commandList.Remove(cmd);
-      }
-    }
-
-#if MONO_BACKWARD_COMPAT
-    /// <summary>
-    /// Obsolete
-    /// </summary>
-    public override int ConnectionTimeout
-    {
-      get
-      {
-        return 30;
-      }
-    }
-
-    public int Version {
-      get { return 3; }
-    }
-
-    public int LastInsertRowId {
-       get { return _sql.GetLastInsertRowId (); }
-    }
-
-    public int BusyTimeout {
-           get { return _busyTimeout; }
-    }
-#endif
-  }
-
-  /// <summary>
-  /// The I/O file cache flushing behavior for the connection
-  /// </summary>
-  public enum SynchronizationModes
-  {
-    /// <summary>
-    /// Normal file flushing at critical sections of the code
-    /// </summary>
-    Normal = 0,
-    /// <summary>
-    /// Full file flushing after every write operation
-    /// </summary>
-    Full = 1,
-    /// <summary>
-    /// Use the default operating system's file flushing, Sqlite does not explicitly flush the file buffers after writing
-    /// </summary>
-    Off = 2,
-  }
-
-  internal delegate void SqliteUpdateCallback(int type, IntPtr database, int databaseLen, IntPtr table, int tableLen, Int64 rowid);
-  internal delegate int SqliteCommitCallback();
-  internal delegate void SqliteRollbackCallback();
-
-  /// <summary>
-  /// Raised when a transaction is about to be committed.  To roll back a transaction, set the 
-  /// rollbackTrans boolean value to true.
-  /// </summary>
-  /// <param name="sender">The connection committing the transaction</param>
-  /// <param name="e">Event arguments on the transaction</param>
-  public delegate void SqliteCommitHandler(object sender, CommitEventArgs e);
-
-  /// <summary>
-  /// Raised when data is inserted, updated and deleted on a given connection
-  /// </summary>
-  /// <param name="sender">The connection committing the transaction</param>
-  /// <param name="e">The event parameters which triggered the event</param>
-  public delegate void SqliteUpdateEventHandler(object sender, UpdateEventArgs e);
-
-  /// <summary>
-  /// Whenever an update event is triggered on a connection, this enum will indicate
-  /// exactly what type of operation is being performed.
-  /// </summary>
-  public enum UpdateEventType
-  {
-    /// <summary>
-    /// A row is being deleted from the given database and table
-    /// </summary>
-    Delete = 9,
-    /// <summary>
-    /// A row is being inserted into the table.
-    /// </summary>
-    Insert = 18,
-    /// <summary>
-    /// A row is being updated in the table.
-    /// </summary>
-    Update = 23,
-  }
-
-  /// <summary>
-  /// Passed during an Update callback, these event arguments detail the type of update operation being performed
-  /// on the given connection.
-  /// </summary>
-  public class UpdateEventArgs : EventArgs
-  {
-    /// <summary>
-    /// The name of the database being updated (usually "main" but can be any attached or temporary database)
-    /// </summary>
-    public readonly string Database;
-
-    /// <summary>
-    /// The name of the table being updated
-    /// </summary>
-    public readonly string Table;
-
-    /// <summary>
-    /// The type of update being performed (insert/update/delete)
-    /// </summary>
-    public readonly UpdateEventType Event;
-
-    /// <summary>
-    /// The RowId affected by this update.
-    /// </summary>
-    public readonly Int64 RowId;
-
-    internal UpdateEventArgs(string database, string table, UpdateEventType eventType, Int64 rowid)
-    {
-      Database = database;
-      Table = table;
-      Event = eventType;
-      RowId = rowid;
-    }
-  }
-
-  /// <summary>
-  /// Event arguments raised when a transaction is being committed
-  /// </summary>
-  public class CommitEventArgs : EventArgs
-  {
-    internal CommitEventArgs()
-    {
-    }
-
-    /// <summary>
-    /// Set to true to abort the transaction and trigger a rollback
-    /// </summary>
-    public bool AbortTransaction;
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Data.Common;\r
+  using System.Collections.Generic;\r
+  using System.Globalization;\r
+  using System.ComponentModel;\r
+  using System.Text;\r
+  using System.Runtime.InteropServices;\r
+  using System.IO;\r
+\r
+  /// <summary>\r
+  /// SQLite implentation of DbConnection.\r
+  /// </summary>\r
+  /// <remarks>\r
+  /// The <see cref="ConnectionString">ConnectionString</see> property of the SQLiteConnection class can contain the following parameter(s), delimited with a semi-colon:\r
+  /// <list type="table">\r
+  /// <listheader>\r
+  /// <term>Parameter</term>\r
+  /// <term>Values</term>\r
+  /// <term>Required</term>\r
+  /// <term>Default</term>\r
+  /// </listheader>\r
+  /// <item>\r
+  /// <description>Data Source</description>\r
+  /// <description>{filename}</description>\r
+  /// <description>Y</description>\r
+  /// <description></description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Version</description>\r
+  /// <description>3</description>\r
+  /// <description>N</description>\r
+  /// <description>3</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>UseUTF16Encoding</description>\r
+  /// <description><b>True</b><br/><b>False</b></description>\r
+  /// <description>N</description>\r
+  /// <description>False</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>DateTimeFormat</description>\r
+  /// <description><b>Ticks</b> - Use DateTime.Ticks<br/><b>ISO8601</b> - Use ISO8601 DateTime format</description>\r
+  /// <description>N</description>\r
+  /// <description>ISO8601</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>BinaryGUID</description>\r
+  /// <description><b>True</b> - Store GUID columns in binary form<br/><b>False</b> - Store GUID columns as text</description>\r
+  /// <description>N</description>\r
+  /// <description>True</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Cache Size</description>\r
+  /// <description>{size in bytes}</description>\r
+  /// <description>N</description>\r
+  /// <description>2000</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Synchronous</description>\r
+  /// <description><b>Normal</b> - Normal file flushing behavior<br/><b>Full</b> - Full flushing after all writes<br/><b>Off</b> - Underlying OS flushes I/O's</description>\r
+  /// <description>N</description>\r
+  /// <description>Normal</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Page Size</description>\r
+  /// <description>{size in bytes}</description>\r
+  /// <description>N</description>\r
+  /// <description>1024</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Password</description>\r
+  /// <description>{password}</description>\r
+  /// <description>N</description>\r
+  /// <description></description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Enlist</description>\r
+  /// <description><b>Y</b> - Automatically enlist in distributed transactions<br/><b>N</b> - No automatic enlistment</description>\r
+  /// <description>N</description>\r
+  /// <description>Y</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Pooling</description>\r
+  /// <description><b>True</b> - Use connection pooling<br/><b>False</b> - Do not use connection pooling</description>\r
+  /// <description>N</description>\r
+  /// <description>False</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>FailIfMissing</description>\r
+  /// <description><b>True</b> - Don't create the database if it does not exist, throw an error instead<br/><b>False</b> - Automatically create the database if it does not exist</description>\r
+  /// <description>N</description>\r
+  /// <description>False</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Max Page Count</description>\r
+  /// <description>{size in pages} - Limits the maximum number of pages (limits the size) of the database</description>\r
+  /// <description>N</description>\r
+  /// <description>0</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Legacy Format</description>\r
+  /// <description><b>True</b> - Use the more compatible legacy 3.x database format<br/><b>False</b> - Use the newer 3.3x database format which compresses numbers more effectively</description>\r
+  /// <description>N</description>\r
+  /// <description>False</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Default Timeout</description>\r
+  /// <description>{time in seconds}<br/>The default command timeout</description>\r
+  /// <description>N</description>\r
+  /// <description>30</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Journal Mode</description>\r
+  /// <description><b>Delete</b> - Delete the journal file after a commit<br/><b>Persist</b> - Zero out and leave the journal file on disk after a commit<br/><b>Off</b> - Disable the rollback journal entirely</description>\r
+  /// <description>N</description>\r
+  /// <description>Delete</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Read Only</description>\r
+  /// <description><b>True</b> - Open the database for read only access<br/><b>False</b> - Open the database for normal read/write access</description>\r
+  /// <description>N</description>\r
+  /// <description>False</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Max Pool Size</description>\r
+  /// <description>The maximum number of connections for the given connection string that can be in the connection pool</description>\r
+  /// <description>N</description>\r
+  /// <description>100</description>\r
+  /// </item>\r
+  /// <item>\r
+  /// <description>Default IsolationLevel</description>\r
+  /// <description>The default transaciton isolation level</description>\r
+  /// <description>N</description>\r
+  /// <description>Serializable</description>\r
+  /// </item>\r
+  /// </list>\r
+  /// </remarks>\r
+  public sealed partial class SQLiteConnection : DbConnection, ICloneable\r
+  {\r
+    private const string _dataDirectory = "|DataDirectory|";\r
+    private const string _masterdb = "sqlite_master";\r
+    private const string _tempmasterdb = "sqlite_temp_master";\r
+\r
+    /// <summary>\r
+    /// State of the current connection\r
+    /// </summary>\r
+    private ConnectionState _connectionState;\r
+    /// <summary>\r
+    /// The connection string\r
+    /// </summary>\r
+    private string _connectionString;\r
+    /// <summary>\r
+    /// Nesting level of the transactions open on the connection\r
+    /// </summary>\r
+    internal int _transactionLevel;\r
+\r
+    /// <summary>\r
+    /// The default isolation level for new transactions\r
+    /// </summary>\r
+    private IsolationLevel _defaultIsolation;\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    /// <summary>\r
+    /// Whether or not the connection is enlisted in a distrubuted transaction\r
+    /// </summary>\r
+    internal SQLiteEnlistment _enlistment;\r
+#endif\r
+    /// <summary>\r
+    /// The base SQLite object to interop with\r
+    /// </summary>\r
+    internal SQLiteBase _sql;\r
+    /// <summary>\r
+    /// The database filename minus path and extension\r
+    /// </summary>\r
+    private string _dataSource;\r
+    /// <summary>\r
+    /// Temporary password storage, emptied after the database has been opened\r
+    /// </summary>\r
+    private byte[] _password;\r
+\r
+    /// <summary>\r
+    /// Default command timeout\r
+    /// </summary>\r
+    private int _defaultTimeout = 30;\r
+\r
+    internal bool _binaryGuid;\r
+\r
+    internal long _version;\r
+\r
+    private event SQLiteUpdateEventHandler _updateHandler;\r
+    private event SQLiteCommitHandler _commitHandler;\r
+    private event EventHandler _rollbackHandler;\r
+\r
+    private SQLiteUpdateCallback _updateCallback;\r
+    private SQLiteCommitCallback _commitCallback;\r
+    private SQLiteRollbackCallback _rollbackCallback;\r
+\r
+    /// <summary>\r
+    /// This event is raised whenever the database is opened or closed.\r
+    /// </summary>\r
+    public override event StateChangeEventHandler StateChange;\r
+\r
+    ///<overloads>\r
+    /// Constructs a new SQLiteConnection object\r
+    /// </overloads>\r
+    /// <summary>\r
+    /// Default constructor\r
+    /// </summary>\r
+    public SQLiteConnection()\r
+      : this("")\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Initializes the connection with the specified connection string\r
+    /// </summary>\r
+    /// <param name="connectionString">The connection string to use on the connection</param>\r
+    public SQLiteConnection(string connectionString)\r
+    {\r
+      _sql = null;\r
+      _connectionState = ConnectionState.Closed;\r
+      _connectionString = "";\r
+      _transactionLevel = 0;\r
+      _version = 0;\r
+      //_commandList = new List<WeakReference>();\r
+\r
+      if (connectionString != null)\r
+        ConnectionString = connectionString;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Clones the settings and connection string from an existing connection.  If the existing connection is already open, this\r
+    /// function will open its own connection, enumerate any attached databases of the original connection, and automatically\r
+    /// attach to them.\r
+    /// </summary>\r
+    /// <param name="connection"></param>\r
+    public SQLiteConnection(SQLiteConnection connection)\r
+      : this(connection.ConnectionString)\r
+    {\r
+      string str;\r
+\r
+      if (connection.State == ConnectionState.Open)\r
+      {\r
+        Open();\r
+\r
+        // Reattach all attached databases from the existing connection\r
+        using (DataTable tbl = connection.GetSchema("Catalogs"))\r
+        {\r
+          foreach (DataRow row in tbl.Rows)\r
+          {\r
+            str = row[0].ToString();\r
+            if (String.Compare(str, "main", true, CultureInfo.InvariantCulture) != 0\r
+              && String.Compare(str, "temp", true, CultureInfo.InvariantCulture) != 0)\r
+            {\r
+              using (SQLiteCommand cmd = CreateCommand())\r
+              {\r
+                cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "ATTACH DATABASE '{0}' AS [{1}]", row[1], row[0]);\r
+                cmd.ExecuteNonQuery();\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+\r
+#if PLATFORM_COMPACTFRAMEWORK\r
+    /// <summary>\r
+    /// Obsolete\r
+    /// </summary>\r
+    public override int ConnectionTimeout\r
+    {\r
+      get\r
+      {\r
+        return 30;\r
+      }\r
+    }\r
+#endif\r
+\r
+    /// <summary>\r
+    /// Creates a clone of the connection.  All attached databases and user-defined functions are cloned.  If the existing connection is open, the cloned connection \r
+    /// will also be opened.\r
+    /// </summary>\r
+    /// <returns></returns>\r
+    public object Clone()\r
+    {\r
+      return new SQLiteConnection(this);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Disposes of the SQLiteConnection, closing it if it is active.\r
+    /// </summary>\r
+    /// <param name="disposing">True if the connection is being explicitly closed.</param>\r
+    protected override void Dispose(bool disposing)\r
+    {\r
+      base.Dispose(disposing);\r
+\r
+      if (disposing)\r
+        Close();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Creates a database file.  This just creates a zero-byte file which SQLite\r
+    /// will turn into a database when the file is opened properly.\r
+    /// </summary>\r
+    /// <param name="databaseFileName">The file to create</param>\r
+    static public void CreateFile(string databaseFileName)\r
+    {\r
+      FileStream fs = File.Create(databaseFileName);\r
+      fs.Close();\r
+    }\r
+\r
+#if !SQLITE_STANDARD\r
+    /// <summary>\r
+    /// On NTFS volumes, this function turns on the compression attribute for the given file.\r
+    /// It must not be open or referenced at the time of the function call.\r
+    /// </summary>\r
+    /// <param name="databaseFileName">The file to compress</param>\r
+    [Obsolete("This functionality is being removed from a future version of the SQLite provider")]\r
+    static public void CompressFile(string databaseFileName)\r
+    {\r
+      UnsafeNativeMethods.sqlite3_compressfile(databaseFileName);\r
+    }\r
+#endif\r
+\r
+#if !SQLITE_STANDARD\r
+    /// <summary>\r
+    /// On NTFS volumes, this function removes the compression attribute for the given file.\r
+    /// It must not be open or referenced at the time of the function call.\r
+    /// </summary>\r
+    /// <param name="databaseFileName">The file to decompress</param>\r
+    [Obsolete("This functionality is being removed from a future version of the SQLite provider")]\r
+    static public void DecompressFile(string databaseFileName)\r
+    {\r
+      UnsafeNativeMethods.sqlite3_decompressfile(databaseFileName);\r
+    }\r
+#endif\r
+\r
+    /// <summary>\r
+    /// Raises the state change event when the state of the connection changes\r
+    /// </summary>\r
+    /// <param name="newState">The new state.  If it is different from the previous state, an event is raised.</param>\r
+    internal void OnStateChange(ConnectionState newState)\r
+    {\r
+      ConnectionState oldState = _connectionState;\r
+      _connectionState = newState;\r
+\r
+      if (StateChange != null && oldState != newState)\r
+      {\r
+        StateChangeEventArgs e = new StateChangeEventArgs(oldState, newState);\r
+        StateChange(this, e);\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// OBSOLETE.  Creates a new SQLiteTransaction if one isn't already active on the connection.\r
+    /// </summary>\r
+    /// <param name="isolationLevel">This parameter is ignored.</param>\r
+    /// <param name="deferredLock">When TRUE, SQLite defers obtaining a write lock until a write operation is requested.\r
+    /// When FALSE, a writelock is obtained immediately.  The default is TRUE, but in a multi-threaded multi-writer \r
+    /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock.</param>\r
+    /// <returns>Returns a SQLiteTransaction object.</returns>\r
+    [Obsolete("Use one of the standard BeginTransaction methods, this one will be removed soon")]\r
+    public SQLiteTransaction BeginTransaction(IsolationLevel isolationLevel, bool deferredLock)\r
+    {\r
+      return (SQLiteTransaction)BeginDbTransaction(deferredLock == false ? IsolationLevel.Serializable : IsolationLevel.ReadCommitted);\r
+    }\r
+\r
+    /// <summary>\r
+    /// OBSOLETE.  Creates a new SQLiteTransaction if one isn't already active on the connection.\r
+    /// </summary>\r
+    /// <param name="deferredLock">When TRUE, SQLite defers obtaining a write lock until a write operation is requested.\r
+    /// When FALSE, a writelock is obtained immediately.  The default is false, but in a multi-threaded multi-writer \r
+    /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock.</param>\r
+    /// <returns>Returns a SQLiteTransaction object.</returns>\r
+    [Obsolete("Use one of the standard BeginTransaction methods, this one will be removed soon")]\r
+    public SQLiteTransaction BeginTransaction(bool deferredLock)\r
+    {\r
+      return (SQLiteTransaction)BeginDbTransaction(deferredLock == false ? IsolationLevel.Serializable : IsolationLevel.ReadCommitted);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Creates a new SQLiteTransaction if one isn't already active on the connection.\r
+    /// </summary>\r
+    /// <param name="isolationLevel">Supported isolation levels are Serializable, ReadCommitted and Unspecified.</param>\r
+    /// <remarks>\r
+    /// Unspecified will use the default isolation level specified in the connection string.  If no isolation level is specified in the \r
+    /// connection string, Serializable is used.\r
+    /// Serializable transactions are the default.  In this mode, the engine gets an immediate lock on the database, and no other threads\r
+    /// may begin a transaction.  Other threads may read from the database, but not write.\r
+    /// With a ReadCommitted isolation level, locks are deferred and elevated as needed.  It is possible for multiple threads to start\r
+    /// a transaction in ReadCommitted mode, but if a thread attempts to commit a transaction while another thread\r
+    /// has a ReadCommitted lock, it may timeout or cause a deadlock on both threads until both threads' CommandTimeout's are reached.\r
+    /// </remarks>\r
+    /// <returns>Returns a SQLiteTransaction object.</returns>\r
+    public new SQLiteTransaction BeginTransaction(IsolationLevel isolationLevel)\r
+    {\r
+      return (SQLiteTransaction)BeginDbTransaction(isolationLevel);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Creates a new SQLiteTransaction if one isn't already active on the connection.\r
+    /// </summary>\r
+    /// <returns>Returns a SQLiteTransaction object.</returns>\r
+    public new SQLiteTransaction BeginTransaction()\r
+    {\r
+      return (SQLiteTransaction)BeginDbTransaction(_defaultIsolation);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Forwards to the local BeginTransaction() function\r
+    /// </summary>\r
+    /// <param name="isolationLevel">Supported isolation levels are Unspecified, Serializable, and ReadCommitted</param>\r
+    /// <returns></returns>\r
+    protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)\r
+    {\r
+      if (_connectionState != ConnectionState.Open)\r
+        throw new InvalidOperationException();\r
+\r
+      if (isolationLevel == IsolationLevel.Unspecified) isolationLevel = _defaultIsolation;\r
+\r
+      if (isolationLevel != IsolationLevel.Serializable && isolationLevel != IsolationLevel.ReadCommitted)\r
+        throw new ArgumentException("isolationLevel");\r
+\r
+      return new SQLiteTransaction(this, isolationLevel != IsolationLevel.Serializable);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Not implemented\r
+    /// </summary>\r
+    /// <param name="databaseName"></param>\r
+    public override void ChangeDatabase(string databaseName)\r
+    {\r
+      throw new NotImplementedException();\r
+    }\r
+\r
+    /// <summary>\r
+    /// When the database connection is closed, all commands linked to this connection are automatically reset.\r
+    /// </summary>\r
+    public override void Close()\r
+    {\r
+      if (_sql != null)\r
+      {\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+        if (_enlistment != null)\r
+        {\r
+          // If the connection is enlisted in a transaction scope and the scope is still active,\r
+          // we cannot truly shut down this connection until the scope has completed.  Therefore make a \r
+          // hidden connection temporarily to hold open the connection until the scope has completed.\r
+          SQLiteConnection cnn = new SQLiteConnection();\r
+          cnn._sql = _sql;\r
+          cnn._transactionLevel = _transactionLevel;\r
+          cnn._enlistment = _enlistment;\r
+          cnn._connectionState = _connectionState;\r
+          cnn._version = _version;\r
+\r
+          cnn._enlistment._transaction._cnn = cnn;\r
+          cnn._enlistment._disposeConnection = true;\r
+          _sql = null;\r
+          _enlistment = null;\r
+        }\r
+#endif\r
+        if (_sql != null)\r
+        {\r
+          _sql.Close();\r
+        }\r
+        _sql = null;\r
+        _transactionLevel = 0;\r
+      }\r
+      OnStateChange(ConnectionState.Closed);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Clears the connection pool associated with the connection.  Any other active connections using the same database file\r
+    /// will be discarded instead of returned to the pool when they are closed.\r
+    /// </summary>\r
+    /// <param name="connection"></param>\r
+    public static void ClearPool(SQLiteConnection connection)\r
+    {\r
+      if (connection._sql == null) return;\r
+      connection._sql.ClearPool();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Clears all connection pools.  Any active connections will be discarded instead of sent to the pool when they are closed.\r
+    /// </summary>\r
+    public static void ClearAllPools()\r
+    {\r
+      SQLiteConnectionPool.ClearAllPools();\r
+    }\r
+\r
+    /// <summary>\r
+    /// The connection string containing the parameters for the connection\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// <list type="table">\r
+    /// <listheader>\r
+    /// <term>Parameter</term>\r
+    /// <term>Values</term>\r
+    /// <term>Required</term>\r
+    /// <term>Default</term>\r
+    /// </listheader>\r
+    /// <item>\r
+    /// <description>Data Source</description>\r
+    /// <description>{filename}</description>\r
+    /// <description>Y</description>\r
+    /// <description></description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Version</description>\r
+    /// <description>3</description>\r
+    /// <description>N</description>\r
+    /// <description>3</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>UseUTF16Encoding</description>\r
+    /// <description><b>True</b><br/><b>False</b></description>\r
+    /// <description>N</description>\r
+    /// <description>False</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>DateTimeFormat</description>\r
+    /// <description><b>Ticks</b> - Use DateTime.Ticks<br/><b>ISO8601</b> - Use ISO8601 DateTime format<br/><b>JulianDay</b> - Use JulianDay format</description>\r
+    /// <description>N</description>\r
+    /// <description>ISO8601</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>BinaryGUID</description>\r
+    /// <description><b>Yes/On/1</b> - Store GUID columns in binary form<br/><b>No/Off/0</b> - Store GUID columns as text</description>\r
+    /// <description>N</description>\r
+    /// <description>On</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Cache Size</description>\r
+    /// <description>{size in bytes}</description>\r
+    /// <description>N</description>\r
+    /// <description>2000</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Synchronous</description>\r
+    /// <description><b>Normal</b> - Normal file flushing behavior<br/><b>Full</b> - Full flushing after all writes<br/><b>Off</b> - Underlying OS flushes I/O's</description>\r
+    /// <description>N</description>\r
+    /// <description>Normal</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Page Size</description>\r
+    /// <description>{size in bytes}</description>\r
+    /// <description>N</description>\r
+    /// <description>1024</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Password</description>\r
+    /// <description>{password}</description>\r
+    /// <description>N</description>\r
+    /// <description></description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Enlist</description>\r
+    /// <description><B>Y</B> - Automatically enlist in distributed transactions<br/><b>N</b> - No automatic enlistment</description>\r
+    /// <description>N</description>\r
+    /// <description>Y</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Pooling</description>\r
+    /// <description><b>True</b> - Use connection pooling<br/><b>False</b> - Do not use connection pooling</description>\r
+    /// <description>N</description>\r
+    /// <description>False</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>FailIfMissing</description>\r
+    /// <description><b>True</b> - Don't create the database if it does not exist, throw an error instead<br/><b>False</b> - Automatically create the database if it does not exist</description>\r
+    /// <description>N</description>\r
+    /// <description>False</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Max Page Count</description>\r
+    /// <description>{size in pages} - Limits the maximum number of pages (limits the size) of the database</description>\r
+    /// <description>N</description>\r
+    /// <description>0</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Legacy Format</description>\r
+    /// <description><b>True</b> - Use the more compatible legacy 3.x database format<br/><b>False</b> - Use the newer 3.3x database format which compresses numbers more effectively</description>\r
+    /// <description>N</description>\r
+    /// <description>False</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Default Timeout</description>\r
+    /// <description>{time in seconds}<br/>The default command timeout</description>\r
+    /// <description>N</description>\r
+    /// <description>30</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Journal Mode</description>\r
+    /// <description><b>Delete</b> - Delete the journal file after a commit<br/><b>Persist</b> - Zero out and leave the journal file on disk after a commit<br/><b>Off</b> - Disable the rollback journal entirely</description>\r
+    /// <description>N</description>\r
+    /// <description>Delete</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Read Only</description>\r
+    /// <description><b>True</b> - Open the database for read only access<br/><b>False</b> - Open the database for normal read/write access</description>\r
+    /// <description>N</description>\r
+    /// <description>False</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Max Pool Size</description>\r
+    /// <description>The maximum number of connections for the given connection string that can be in the connection pool</description>\r
+    /// <description>N</description>\r
+    /// <description>100</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Default IsolationLevel</description>\r
+    /// <description>The default transaciton isolation level</description>\r
+    /// <description>N</description>\r
+    /// <description>Serializable</description>\r
+    /// </item>\r
+    /// </list>\r
+    /// </remarks>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [RefreshProperties(RefreshProperties.All), DefaultValue("")]\r
+    [Editor("SQLite.Designer.SQLiteConnectionStringEditor, SQLite.Designer, Version=1.0.36.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+#endif\r
+    public override string ConnectionString\r
+    {\r
+      get\r
+      {\r
+        return _connectionString;\r
+      }\r
+      set\r
+      {\r
+        if (value == null)\r
+          throw new ArgumentNullException();\r
+\r
+        else if (_connectionState != ConnectionState.Closed)\r
+          throw new InvalidOperationException();\r
+\r
+        _connectionString = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Create a new SQLiteCommand and associate it with this connection.\r
+    /// </summary>\r
+    /// <returns>Returns an instantiated SQLiteCommand object already assigned to this connection.</returns>\r
+    public new SQLiteCommand CreateCommand()\r
+    {\r
+      return new SQLiteCommand(this);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Forwards to the local CreateCommand() function\r
+    /// </summary>\r
+    /// <returns></returns>\r
+    protected override DbCommand CreateDbCommand()\r
+    {\r
+      return CreateCommand();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the filename without extension or path\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\r
+#endif\r
+    public override string DataSource\r
+    {\r
+      get\r
+      {\r
+        return _dataSource;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns an empty string\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\r
+#endif\r
+    public override string Database\r
+    {\r
+      get\r
+      {\r
+        return "main";\r
+      }\r
+    }\r
+\r
+    internal static string MapUriPath(string path)\r
+    {\r
+           if (path.StartsWith ("file://"))\r
+                   return path.Substring (7);\r
+      else if (path.StartsWith ("file:"))\r
+                   return path.Substring (5);\r
+      else if (path.StartsWith ("/"))\r
+                   return path;\r
+      else\r
+                   throw new InvalidOperationException ("Invalid connection string: invalid URI");\r
+    }\r
+    \r
+    /// <summary>\r
+    /// Parses the connection string into component parts\r
+    /// </summary>\r
+    /// <param name="connectionString">The connection string to parse</param>\r
+    /// <returns>An array of key-value pairs representing each parameter of the connection string</returns>\r
+    internal static SortedList<string, string> ParseConnectionString(string connectionString)\r
+    {\r
+      string s = connectionString;\r
+      int n;\r
+      SortedList<string, string> ls = new SortedList<string, string>(StringComparer.OrdinalIgnoreCase);\r
+\r
+      // First split into semi-colon delimited values.  The Split() function of SQLiteBase accounts for and properly\r
+      // skips semi-colons in quoted strings\r
+      string[] arParts = SQLiteConvert.Split(s, ';');\r
+      string[] arPiece;\r
+\r
+      int x = arParts.Length;\r
+      // For each semi-colon piece, split into key and value pairs by the presence of the = sign\r
+      for (n = 0; n < x; n++)\r
+      {\r
+        arPiece = SQLiteConvert.Split(arParts[n], '=');\r
+        if (arPiece.Length == 2)\r
+        {\r
+          ls.Add(arPiece[0], arPiece[1]);\r
+        }\r
+        else throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Invalid ConnectionString format for parameter \"{0}\"", (arPiece.Length > 0) ? arPiece[0] : "null"));\r
+      }\r
+      return ls;\r
+    }\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    /// <summary>\r
+    /// Manual distributed transaction enlistment support\r
+    /// </summary>\r
+    /// <param name="transaction">The distributed transaction to enlist in</param>\r
+    public override void EnlistTransaction(System.Transactions.Transaction transaction)\r
+    {\r
+      if (_transactionLevel > 0 && transaction != null)\r
+        throw new ArgumentException("Unable to enlist in transaction, a local transaction already exists");\r
+\r
+      if (_enlistment != null && transaction != _enlistment._scope)\r
+        throw new ArgumentException("Already enlisted in a transaction");\r
+\r
+      _enlistment = new SQLiteEnlistment(this, transaction);\r
+    }\r
+#endif\r
+\r
+    /// <summary>\r
+    /// Looks for a key in the array of key/values of the parameter string.  If not found, return the specified default value\r
+    /// </summary>\r
+    /// <param name="items">The list to look in</param>\r
+    /// <param name="key">The key to find</param>\r
+    /// <param name="defValue">The default value to return if the key is not found</param>\r
+    /// <returns>The value corresponding to the specified key, or the default value if not found.</returns>\r
+    static internal string FindKey(SortedList<string, string> items, string key, string defValue)\r
+    {\r
+      string ret;\r
+\r
+      if (items.TryGetValue(key, out ret)) return ret;\r
+\r
+      return defValue;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Opens the connection using the parameters found in the <see cref="ConnectionString">ConnectionString</see>\r
+    /// </summary>\r
+    public override void Open()\r
+    {\r
+      if (_connectionState != ConnectionState.Closed)\r
+        throw new InvalidOperationException();\r
+\r
+      Close();\r
+\r
+      SortedList<string, string> opts = ParseConnectionString(_connectionString);\r
+      string fileName;\r
+\r
+      if (Convert.ToInt32(FindKey(opts, "Version", "3"), CultureInfo.InvariantCulture) != 3)\r
+        throw new NotSupportedException("Only SQLite Version 3 is supported at this time");\r
+\r
+      fileName = FindKey(opts, "Data Source", "");\r
+\r
+      if (String.IsNullOrEmpty(fileName))\r
+      {\r
+        fileName = FindKey(opts, "Uri", "");\r
+        if (String.IsNullOrEmpty(fileName))\r
+          throw new ArgumentException("Data Source cannot be empty.  Use :memory: to open an in-memory database");\r
+        else\r
+          fileName = MapUriPath(fileName);\r
+      }\r
+\r
+      if (String.Compare(fileName, ":MEMORY:", true, CultureInfo.InvariantCulture) == 0)\r
+        fileName = ":memory:";\r
+      else\r
+      {\r
+#if PLATFORM_COMPACTFRAMEWORK\r
+       if (fileName.StartsWith(".\\"))\r
+         fileName = Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase) + fileName.Substring(1);\r
+#endif\r
+       fileName = ExpandFileName(fileName);\r
+      }\r
+      try\r
+      {\r
+        bool usePooling = (SQLiteConvert.ToBoolean(FindKey(opts, "Pooling", Boolean.FalseString)) == true);\r
+        bool bUTF16 = (SQLiteConvert.ToBoolean(FindKey(opts, "UseUTF16Encoding", Boolean.FalseString)) == true);\r
+        int maxPoolSize = Convert.ToInt32(FindKey(opts, "Max Pool Size", "100"));\r
+\r
+        _defaultTimeout = Convert.ToInt32(FindKey(opts, "Default Timeout", "30"), CultureInfo.CurrentCulture);\r
+\r
+        _defaultIsolation = (IsolationLevel)Enum.Parse(typeof(IsolationLevel), FindKey(opts, "Default IsolationLevel", "Serializable"), true);\r
+        if (_defaultIsolation != IsolationLevel.Serializable && _defaultIsolation != IsolationLevel.ReadCommitted)\r
+          throw new NotSupportedException("Invalid Default IsolationLevel specified");\r
+\r
+        SQLiteDateFormats dateFormat = (SQLiteDateFormats)Enum.Parse(typeof(SQLiteDateFormats), FindKey(opts, "DateTimeFormat", "ISO8601"), true);\r
+        //string temp = FindKey(opts, "DateTimeFormat", "ISO8601");\r
+        //if (String.Compare(temp, "ticks", true, CultureInfo.InvariantCulture) == 0) dateFormat = SQLiteDateFormats.Ticks;\r
+        //else if (String.Compare(temp, "julianday", true, CultureInfo.InvariantCulture) == 0) dateFormat = SQLiteDateFormats.JulianDay;\r
+\r
+        if (bUTF16) // SQLite automatically sets the encoding of the database to UTF16 if called from sqlite3_open16()\r
+          _sql = new SQLite3_UTF16(dateFormat);\r
+        else\r
+          _sql = new SQLite3(dateFormat);\r
+\r
+        SQLiteOpenFlagsEnum flags = SQLiteOpenFlagsEnum.None;\r
+\r
+        if (SQLiteConvert.ToBoolean(FindKey(opts, "FailIfMissing", Boolean.FalseString)) == false)\r
+          flags |= SQLiteOpenFlagsEnum.Create;\r
+\r
+        if (SQLiteConvert.ToBoolean(FindKey(opts, "Read Only", Boolean.FalseString)) == true)\r
+          flags |= SQLiteOpenFlagsEnum.ReadOnly;\r
+        else\r
+          flags |= SQLiteOpenFlagsEnum.ReadWrite;\r
+\r
+        _sql.Open(fileName, flags, maxPoolSize, usePooling);\r
+\r
+        _binaryGuid = (SQLiteConvert.ToBoolean(FindKey(opts, "BinaryGUID", Boolean.TrueString)) == true);\r
+\r
+        string password = FindKey(opts, "Password", null);\r
+\r
+        if (String.IsNullOrEmpty(password) == false)\r
+          _sql.SetPassword(System.Text.UTF8Encoding.UTF8.GetBytes(password));\r
+        else if (_password != null)\r
+          _sql.SetPassword(_password);\r
+        _password = null;\r
+\r
+        _dataSource = Path.GetFileNameWithoutExtension(fileName);\r
+\r
+        OnStateChange(ConnectionState.Open);\r
+        _version++;\r
+\r
+        using (SQLiteCommand cmd = CreateCommand())\r
+        {\r
+          string defValue;\r
+\r
+          if (fileName != ":memory:")\r
+          {\r
+            defValue = FindKey(opts, "Page Size", "1024");\r
+            if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 1024)\r
+            {\r
+              cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA page_size={0}", defValue);\r
+              cmd.ExecuteNonQuery();\r
+            }\r
+          }\r
+\r
+          defValue = FindKey(opts, "Max Page Count", "0");\r
+          if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 0)\r
+          {\r
+            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA max_page_count={0}", defValue);\r
+            cmd.ExecuteNonQuery();\r
+          }\r
+\r
+          defValue = FindKey(opts, "Legacy Format", Boolean.FalseString);\r
+          cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA legacy_file_format={0}", SQLiteConvert.ToBoolean(defValue) == true ? "ON" : "OFF");\r
+          cmd.ExecuteNonQuery();\r
+\r
+          defValue = FindKey(opts, "Synchronous", "Normal");\r
+          if (String.Compare(defValue, "Full", StringComparison.OrdinalIgnoreCase) != 0)\r
+          {\r
+            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA synchronous={0}", defValue);\r
+            cmd.ExecuteNonQuery();\r
+          }\r
+\r
+          defValue = FindKey(opts, "Cache Size", "2000");\r
+          if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 2000)\r
+          {\r
+            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA cache_size={0}", defValue);\r
+            cmd.ExecuteNonQuery();\r
+          }\r
+\r
+          defValue = FindKey(opts, "Journal Mode", "Delete");\r
+          if (String.Compare(defValue, "Default", StringComparison.OrdinalIgnoreCase) != 0)\r
+          {\r
+            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA journal_mode={0}", defValue);\r
+            cmd.ExecuteNonQuery();\r
+          }\r
+        }\r
+\r
+        if (_commitHandler != null)\r
+          _sql.SetCommitHook(_commitCallback);\r
+\r
+        if (_updateHandler != null)\r
+          _sql.SetUpdateHook(_updateCallback);\r
+\r
+        if (_rollbackHandler != null)\r
+          _sql.SetRollbackHook(_rollbackCallback);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+        if (Transactions.Transaction.Current != null && SQLiteConvert.ToBoolean(FindKey(opts, "Enlist", Boolean.TrueString)) == true)\r
+          EnlistTransaction(Transactions.Transaction.Current);\r
+#endif\r
+      }\r
+      catch (SQLiteException)\r
+      {\r
+        Close();\r
+        throw;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/sets the default command timeout for newly-created commands.  This is especially useful for \r
+    /// commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible.\r
+    /// This can also be set in the ConnectionString with "Default Timeout"\r
+    /// </summary>\r
+    public int DefaultTimeout\r
+    {\r
+      get { return _defaultTimeout; }\r
+      set { _defaultTimeout = value; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the version of the underlying SQLite database engine\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\r
+#endif\r
+    public override string ServerVersion\r
+    {\r
+      get\r
+      {\r
+        if (_connectionState != ConnectionState.Open)\r
+          throw new InvalidOperationException();\r
+\r
+        return _sql.Version;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the version of the underlying SQLite database engine\r
+    /// </summary>\r
+    public static string SQLiteVersion\r
+    {\r
+      get { return SQLite3.SQLiteVersion; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the state of the connection.\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\r
+#endif\r
+    public override ConnectionState State\r
+    {\r
+      get\r
+      {\r
+        return _connectionState;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Change the password (or assign a password) to an open database.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// No readers or writers may be active for this process.  The database must already be open\r
+    /// and if it already was password protected, the existing password must already have been supplied.\r
+    /// </remarks>\r
+    /// <param name="newPassword">The new password to assign to the database</param>\r
+    public void ChangePassword(string newPassword)\r
+    {\r
+      ChangePassword(String.IsNullOrEmpty(newPassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(newPassword));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Change the password (or assign a password) to an open database.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// No readers or writers may be active for this process.  The database must already be open\r
+    /// and if it already was password protected, the existing password must already have been supplied.\r
+    /// </remarks>\r
+    /// <param name="newPassword">The new password to assign to the database</param>\r
+    public void ChangePassword(byte[] newPassword)\r
+    {\r
+      if (_connectionState != ConnectionState.Open)\r
+        throw new InvalidOperationException("Database must be opened before changing the password.");\r
+\r
+      _sql.ChangePassword(newPassword);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Sets the password for a password-protected database.  A password-protected database is\r
+    /// unusable for any operation until the password has been set.\r
+    /// </summary>\r
+    /// <param name="databasePassword">The password for the database</param>\r
+    public void SetPassword(string databasePassword)\r
+    {\r
+      SetPassword(String.IsNullOrEmpty(databasePassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(databasePassword));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Sets the password for a password-protected database.  A password-protected database is\r
+    /// unusable for any operation until the password has been set.\r
+    /// </summary>\r
+    /// <param name="databasePassword">The password for the database</param>\r
+    public void SetPassword(byte[] databasePassword)\r
+    {\r
+      if (_connectionState != ConnectionState.Closed)\r
+        throw new InvalidOperationException("Password can only be set before the database is opened.");\r
+\r
+      if (databasePassword != null)\r
+        if (databasePassword.Length == 0) databasePassword = null;\r
+\r
+      _password = databasePassword;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Expand the filename of the data source, resolving the |DataDirectory| macro as appropriate.\r
+    /// </summary>\r
+    /// <param name="sourceFile">The database filename to expand</param>\r
+    /// <returns>The expanded path and filename of the filename</returns>\r
+    private string ExpandFileName(string sourceFile)\r
+    {\r
+      if (String.IsNullOrEmpty(sourceFile)) return sourceFile;\r
+\r
+      if (sourceFile.StartsWith(_dataDirectory, StringComparison.OrdinalIgnoreCase))\r
+      {\r
+        string dataDirectory;\r
+\r
+#if PLATFORM_COMPACTFRAMEWORK\r
+        dataDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase);\r
+#else\r
+        dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory") as string;\r
+        if (String.IsNullOrEmpty(dataDirectory))\r
+          dataDirectory = AppDomain.CurrentDomain.BaseDirectory;\r
+#endif\r
+\r
+        if (sourceFile.Length > _dataDirectory.Length)\r
+        {\r
+          if (sourceFile[_dataDirectory.Length] == Path.DirectorySeparatorChar ||\r
+              sourceFile[_dataDirectory.Length] == Path.AltDirectorySeparatorChar)\r
+            sourceFile = sourceFile.Remove(_dataDirectory.Length, 1);\r
+        }\r
+        sourceFile = Path.Combine(dataDirectory, sourceFile.Substring(_dataDirectory.Length));\r
+      }\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+      sourceFile = Path.GetFullPath(sourceFile);\r
+#endif\r
+\r
+      return sourceFile;\r
+    }\r
+\r
+    ///<overloads>\r
+    /// The following commands are used to extract schema information out of the database.  Valid schema types are:\r
+    /// <list type="bullet">\r
+    /// <item>\r
+    /// <description>MetaDataCollections</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>DataSourceInformation</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Catalogs</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Columns</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>ForeignKeys</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Indexes</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>IndexColumns</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Tables</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>Views</description>\r
+    /// </item>\r
+    /// <item>\r
+    /// <description>ViewColumns</description>\r
+    /// </item>\r
+    /// </list>\r
+    /// </overloads>\r
+    /// <summary>\r
+    /// Returns the MetaDataCollections schema\r
+    /// </summary>\r
+    /// <returns>A DataTable of the MetaDataCollections schema</returns>\r
+    public override DataTable GetSchema()\r
+    {\r
+      return GetSchema("MetaDataCollections", null);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns schema information of the specified collection\r
+    /// </summary>\r
+    /// <param name="collectionName">The schema collection to retrieve</param>\r
+    /// <returns>A DataTable of the specified collection</returns>\r
+    public override DataTable GetSchema(string collectionName)\r
+    {\r
+      return GetSchema(collectionName, new string[0]);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves schema information using the specified constraint(s) for the specified collection\r
+    /// </summary>\r
+    /// <param name="collectionName">The collection to retrieve</param>\r
+    /// <param name="restrictionValues">The restrictions to impose</param>\r
+    /// <returns>A DataTable of the specified collection</returns>\r
+    public override DataTable GetSchema(string collectionName, string[] restrictionValues)\r
+    {\r
+      if (_connectionState != ConnectionState.Open)\r
+        throw new InvalidOperationException();\r
+\r
+      string[] parms = new string[5];\r
+\r
+      if (restrictionValues == null) restrictionValues = new string[0];\r
+      restrictionValues.CopyTo(parms, 0);\r
+\r
+      switch (collectionName.ToUpper(CultureInfo.InvariantCulture))\r
+      {\r
+        case "METADATACOLLECTIONS":\r
+          return Schema_MetaDataCollections();\r
+        case "DATASOURCEINFORMATION":\r
+          return Schema_DataSourceInformation();\r
+        case "DATATYPES":\r
+          return Schema_DataTypes();\r
+        case "COLUMNS":\r
+        case "TABLECOLUMNS":\r
+          return Schema_Columns(parms[0], parms[2], parms[3]);\r
+        case "INDEXES":\r
+          return Schema_Indexes(parms[0], parms[2], parms[3]);\r
+        case "TRIGGERS":\r
+          return Schema_Triggers(parms[0], parms[2], parms[3]);\r
+        case "INDEXCOLUMNS":\r
+          return Schema_IndexColumns(parms[0], parms[2], parms[3], parms[4]);\r
+        case "TABLES":\r
+          return Schema_Tables(parms[0], parms[2], parms[3]);\r
+        case "VIEWS":\r
+          return Schema_Views(parms[0], parms[2]);\r
+        case "VIEWCOLUMNS":\r
+          return Schema_ViewColumns(parms[0], parms[2], parms[3]);\r
+        case "FOREIGNKEYS":\r
+          return Schema_ForeignKeys(parms[0], parms[2], parms[3]);\r
+        case "CATALOGS":\r
+          return Schema_Catalogs(parms[0]);\r
+        case "RESERVEDWORDS":\r
+          return Schema_ReservedWords();\r
+      }\r
+      throw new NotSupportedException();\r
+    }\r
+\r
+    private static DataTable Schema_ReservedWords()\r
+    {\r
+      DataTable tbl = new DataTable("MetaDataCollections");\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("ReservedWord", typeof(string));\r
+      tbl.Columns.Add("MaximumVersion", typeof(string));\r
+      tbl.Columns.Add("MinimumVersion", typeof(string));\r
+\r
+      tbl.BeginLoadData();\r
+      DataRow row;\r
+      foreach (string word in SR.Keywords.Split(new char[] { ',' }))\r
+      {\r
+        row = tbl.NewRow();\r
+        row[0] = word;\r
+        tbl.Rows.Add(row);\r
+      }\r
+\r
+      tbl.AcceptChanges();\r
+      tbl.EndLoadData();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Builds a MetaDataCollections schema datatable\r
+    /// </summary>\r
+    /// <returns>DataTable</returns>\r
+    private static DataTable Schema_MetaDataCollections()\r
+    {\r
+      DataTable tbl = new DataTable("MetaDataCollections");\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("CollectionName", typeof(string));\r
+      tbl.Columns.Add("NumberOfRestrictions", typeof(int));\r
+      tbl.Columns.Add("NumberOfIdentifierParts", typeof(int));\r
+\r
+      tbl.BeginLoadData();\r
+\r
+      StringReader reader = new StringReader(SR.MetaDataCollections);\r
+      tbl.ReadXml(reader);\r
+      reader.Close();\r
+\r
+      tbl.AcceptChanges();\r
+      tbl.EndLoadData();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Builds a DataSourceInformation datatable\r
+    /// </summary>\r
+    /// <returns>DataTable</returns>\r
+    private DataTable Schema_DataSourceInformation()\r
+    {\r
+      DataTable tbl = new DataTable("DataSourceInformation");\r
+      DataRow row;\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add(DbMetaDataColumnNames.CompositeIdentifierSeparatorPattern, typeof(string));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductName, typeof(string));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductVersion, typeof(string));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductVersionNormalized, typeof(string));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.GroupByBehavior, typeof(int));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.IdentifierPattern, typeof(string));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.IdentifierCase, typeof(int));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.OrderByColumnsInSelect, typeof(bool));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.ParameterMarkerFormat, typeof(string));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.ParameterMarkerPattern, typeof(string));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.ParameterNameMaxLength, typeof(int));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.ParameterNamePattern, typeof(string));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.QuotedIdentifierPattern, typeof(string));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.QuotedIdentifierCase, typeof(int));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.StatementSeparatorPattern, typeof(string));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.StringLiteralPattern, typeof(string));\r
+      tbl.Columns.Add(DbMetaDataColumnNames.SupportedJoinOperators, typeof(int));\r
+\r
+      tbl.BeginLoadData();\r
+\r
+      row = tbl.NewRow();\r
+      row.ItemArray = new object[] {\r
+        null,\r
+        "SQLite",\r
+        _sql.Version,\r
+        _sql.Version,\r
+        3,\r
+        @"(^\[\p{Lo}\p{Lu}\p{Ll}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Nd}@$#_]*$)|(^\[[^\]\0]|\]\]+\]$)|(^\""[^\""\0]|\""\""+\""$)",\r
+        1,\r
+        false,\r
+        "{0}",\r
+        @"@[\p{Lo}\p{Lu}\p{Ll}\p{Lm}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_@#\$]*(?=\s+|$)",\r
+        255,\r
+        @"^[\p{Lo}\p{Lu}\p{Ll}\p{Lm}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_@#\$]*(?=\s+|$)",\r
+        @"(([^\[]|\]\])*)",\r
+        1,\r
+        ";",\r
+        @"'(([^']|'')*)'",\r
+        15\r
+      };\r
+      tbl.Rows.Add(row);\r
+\r
+      tbl.AcceptChanges();\r
+      tbl.EndLoadData();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Build a Columns schema\r
+    /// </summary>\r
+    /// <param name="strCatalog">The catalog (attached database) to query, can be null</param>\r
+    /// <param name="strTable">The table to retrieve schema information for, must not be null</param>\r
+    /// <param name="strColumn">The column to retrieve schema information for, can be null</param>\r
+    /// <returns>DataTable</returns>\r
+    private DataTable Schema_Columns(string strCatalog, string strTable, string strColumn)\r
+    {\r
+      DataTable tbl = new DataTable("Columns");\r
+      DataRow row;\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("TABLE_CATALOG", typeof(string));\r
+      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("TABLE_NAME", typeof(string));\r
+      tbl.Columns.Add("COLUMN_NAME", typeof(string));\r
+      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));\r
+      tbl.Columns.Add("COLUMN_PROPID", typeof(long));\r
+      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));\r
+      tbl.Columns.Add("COLUMN_HASDEFAULT", typeof(bool));\r
+      tbl.Columns.Add("COLUMN_DEFAULT", typeof(string));\r
+      tbl.Columns.Add("COLUMN_FLAGS", typeof(long));\r
+      tbl.Columns.Add("IS_NULLABLE", typeof(bool));\r
+      tbl.Columns.Add("DATA_TYPE", typeof(string));\r
+      tbl.Columns.Add("TYPE_GUID", typeof(Guid));\r
+      tbl.Columns.Add("CHARACTER_MAXIMUM_LENGTH", typeof(int));\r
+      tbl.Columns.Add("CHARACTER_OCTET_LENGTH", typeof(int));\r
+      tbl.Columns.Add("NUMERIC_PRECISION", typeof(int));\r
+      tbl.Columns.Add("NUMERIC_SCALE", typeof(int));\r
+      tbl.Columns.Add("DATETIME_PRECISION", typeof(long));\r
+      tbl.Columns.Add("CHARACTER_SET_CATALOG", typeof(string));\r
+      tbl.Columns.Add("CHARACTER_SET_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("CHARACTER_SET_NAME", typeof(string));\r
+      tbl.Columns.Add("COLLATION_CATALOG", typeof(string));\r
+      tbl.Columns.Add("COLLATION_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("COLLATION_NAME", typeof(string));\r
+      tbl.Columns.Add("DOMAIN_CATALOG", typeof(string));\r
+      tbl.Columns.Add("DOMAIN_NAME", typeof(string));\r
+      tbl.Columns.Add("DESCRIPTION", typeof(string));\r
+      tbl.Columns.Add("PRIMARY_KEY", typeof(bool));\r
+      tbl.Columns.Add("EDM_TYPE", typeof(string));\r
+      tbl.Columns.Add("AUTOINCREMENT", typeof(bool));\r
+      tbl.Columns.Add("UNIQUE", typeof(bool));\r
+\r
+      tbl.BeginLoadData();\r
+\r
+      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";\r
+\r
+      string master = (String.Compare(strCatalog, "temp", true, CultureInfo.InvariantCulture) == 0) ? _tempmasterdb : _masterdb;\r
+\r
+      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table' OR [type] LIKE 'view'", strCatalog, master), this))\r
+      using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())\r
+      {\r
+        while (rdTables.Read())\r
+        {\r
+          if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), true, CultureInfo.InvariantCulture) == 0)\r
+          {\r
+            try\r
+            {\r
+              using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdTables.GetString(2)), this))\r
+              using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader(CommandBehavior.SchemaOnly))\r
+              using (DataTable tblSchema = rd.GetSchemaTable(true, true))\r
+              {\r
+                foreach (DataRow schemaRow in tblSchema.Rows)\r
+                {\r
+                  if (String.Compare(schemaRow[SchemaTableColumn.ColumnName].ToString(), strColumn, true, CultureInfo.InvariantCulture) == 0\r
+                    || strColumn == null)\r
+                  {\r
+                    row = tbl.NewRow();\r
+\r
+                    row["NUMERIC_PRECISION"] = schemaRow[SchemaTableColumn.NumericPrecision];\r
+                    row["NUMERIC_SCALE"] = schemaRow[SchemaTableColumn.NumericScale];\r
+                    row["TABLE_NAME"] = rdTables.GetString(2);\r
+                    row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.ColumnName];\r
+                    row["TABLE_CATALOG"] = strCatalog;\r
+                    row["ORDINAL_POSITION"] = schemaRow[SchemaTableColumn.ColumnOrdinal];\r
+                    row["COLUMN_HASDEFAULT"] = (schemaRow[SchemaTableOptionalColumn.DefaultValue] != DBNull.Value);\r
+                    row["COLUMN_DEFAULT"] = schemaRow[SchemaTableOptionalColumn.DefaultValue];\r
+                    row["IS_NULLABLE"] = schemaRow[SchemaTableColumn.AllowDBNull];\r
+                    row["DATA_TYPE"] = schemaRow["DataTypeName"].ToString().ToLower(CultureInfo.InvariantCulture);\r
+                    row["EDM_TYPE"] = SQLiteConvert.DbTypeToTypeName((DbType)schemaRow[SchemaTableColumn.ProviderType]).ToString().ToLower(CultureInfo.InvariantCulture);\r
+                    row["CHARACTER_MAXIMUM_LENGTH"] = schemaRow[SchemaTableColumn.ColumnSize];\r
+                    row["TABLE_SCHEMA"] = schemaRow[SchemaTableColumn.BaseSchemaName];\r
+                    row["PRIMARY_KEY"] = schemaRow[SchemaTableColumn.IsKey];\r
+                    row["AUTOINCREMENT"] = schemaRow[SchemaTableOptionalColumn.IsAutoIncrement];\r
+                    row["COLLATION_NAME"] = schemaRow["CollationType"];\r
+                    row["UNIQUE"] = schemaRow[SchemaTableColumn.IsUnique];\r
+                    tbl.Rows.Add(row);\r
+                  }\r
+                }\r
+              }\r
+            }\r
+            catch(SQLiteException)\r
+            {\r
+            }\r
+          }\r
+        }\r
+      }\r
+\r
+      tbl.AcceptChanges();\r
+      tbl.EndLoadData();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns index information for the given database and catalog\r
+    /// </summary>\r
+    /// <param name="strCatalog">The catalog (attached database) to query, can be null</param>\r
+    /// <param name="strIndex">The name of the index to retrieve information for, can be null</param>\r
+    /// <param name="strTable">The table to retrieve index information for, can be null</param>\r
+    /// <returns>DataTable</returns>\r
+    private DataTable Schema_Indexes(string strCatalog, string strTable, string strIndex)\r
+    {\r
+      DataTable tbl = new DataTable("Indexes");\r
+      DataRow row;\r
+      List<int> primaryKeys = new List<int>();\r
+      bool maybeRowId;\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("TABLE_CATALOG", typeof(string));\r
+      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("TABLE_NAME", typeof(string));\r
+      tbl.Columns.Add("INDEX_CATALOG", typeof(string));\r
+      tbl.Columns.Add("INDEX_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("INDEX_NAME", typeof(string));\r
+      tbl.Columns.Add("PRIMARY_KEY", typeof(bool));\r
+      tbl.Columns.Add("UNIQUE", typeof(bool));\r
+      tbl.Columns.Add("CLUSTERED", typeof(bool));\r
+      tbl.Columns.Add("TYPE", typeof(int));\r
+      tbl.Columns.Add("FILL_FACTOR", typeof(int));\r
+      tbl.Columns.Add("INITIAL_SIZE", typeof(int));\r
+      tbl.Columns.Add("NULLS", typeof(int));\r
+      tbl.Columns.Add("SORT_BOOKMARKS", typeof(bool));\r
+      tbl.Columns.Add("AUTO_UPDATE", typeof(bool));\r
+      tbl.Columns.Add("NULL_COLLATION", typeof(int));\r
+      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));\r
+      tbl.Columns.Add("COLUMN_NAME", typeof(string));\r
+      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));\r
+      tbl.Columns.Add("COLUMN_PROPID", typeof(long));\r
+      tbl.Columns.Add("COLLATION", typeof(short));\r
+      tbl.Columns.Add("CARDINALITY", typeof(Decimal));\r
+      tbl.Columns.Add("PAGES", typeof(int));\r
+      tbl.Columns.Add("FILTER_CONDITION", typeof(string));\r
+      tbl.Columns.Add("INTEGRATED", typeof(bool));\r
+      tbl.Columns.Add("INDEX_DEFINITION", typeof(string));\r
+\r
+      tbl.BeginLoadData();\r
+\r
+      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";\r
+\r
+      string master = (String.Compare(strCatalog, "temp", true, CultureInfo.InvariantCulture) == 0) ? _tempmasterdb : _masterdb;\r
+      \r
+      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))\r
+      using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())\r
+      {\r
+        while (rdTables.Read())\r
+        {\r
+          maybeRowId = false;\r
+          primaryKeys.Clear();\r
+          if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0)\r
+          {\r
+            // First, look for any rowid indexes -- which sqlite defines are INTEGER PRIMARY KEY columns.\r
+            // Such indexes are not listed in the indexes list but count as indexes just the same.\r
+            try\r
+            {\r
+              using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this))\r
+              using (SQLiteDataReader rdTable = cmdTable.ExecuteReader())\r
+              {\r
+                while (rdTable.Read())\r
+                {\r
+                  if (rdTable.GetInt32(5) == 1)\r
+                  {\r
+                    primaryKeys.Add(rdTable.GetInt32(0));\r
+\r
+                    // If the primary key is of type INTEGER, then its a rowid and we need to make a fake index entry for it.\r
+                    if (String.Compare(rdTable.GetString(2), "INTEGER", true, CultureInfo.InvariantCulture) == 0)\r
+                      maybeRowId = true;\r
+                  }\r
+                }\r
+              }\r
+            }\r
+            catch (SQLiteException)\r
+            {\r
+            }\r
+            if (primaryKeys.Count == 1 && maybeRowId == true)\r
+            {\r
+              row = tbl.NewRow();\r
+\r
+              row["TABLE_CATALOG"] = strCatalog;\r
+              row["TABLE_NAME"] = rdTables.GetString(2);\r
+              row["INDEX_CATALOG"] = strCatalog;\r
+              row["PRIMARY_KEY"] = true;\r
+              row["INDEX_NAME"] = String.Format(CultureInfo.InvariantCulture, "{1}_PK_{0}", rdTables.GetString(2), master);\r
+              row["UNIQUE"] = true;\r
+\r
+              if (String.Compare((string)row["INDEX_NAME"], strIndex, true, CultureInfo.InvariantCulture) == 0\r
+              || strIndex == null)\r
+              {\r
+                tbl.Rows.Add(row);\r
+              }\r
+\r
+              primaryKeys.Clear();\r
+            }\r
+\r
+            // Now fetch all the rest of the indexes.\r
+            try\r
+            {\r
+              using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_list([{1}])", strCatalog, rdTables.GetString(2)), this))\r
+              using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())\r
+              {\r
+                while (rd.Read())\r
+                {\r
+                  if (String.Compare(rd.GetString(1), strIndex, true, CultureInfo.InvariantCulture) == 0\r
+                  || strIndex == null)\r
+                  {\r
+                    row = tbl.NewRow();\r
+\r
+                    row["TABLE_CATALOG"] = strCatalog;\r
+                    row["TABLE_NAME"] = rdTables.GetString(2);\r
+                    row["INDEX_CATALOG"] = strCatalog;\r
+                    row["INDEX_NAME"] = rd.GetString(1);\r
+                    row["UNIQUE"] = rd.GetBoolean(2);\r
+                    row["PRIMARY_KEY"] = false;\r
+\r
+                    // get the index definition\r
+                    using (SQLiteCommand cmdIndexes = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{2}] WHERE [type] LIKE 'index' AND [name] LIKE '{1}'", strCatalog, rd.GetString(1).Replace("'", "''"), master), this))\r
+                    using (SQLiteDataReader rdIndexes = cmdIndexes.ExecuteReader())\r
+                    {\r
+                      while (rdIndexes.Read())\r
+                      {\r
+                        if (rdIndexes.IsDBNull(4) == false)\r
+                          row["INDEX_DEFINITION"] = rdIndexes.GetString(4);\r
+                        break;\r
+                      }\r
+                    }\r
+\r
+                    // Now for the really hard work.  Figure out which index is the primary key index.\r
+                    // The only way to figure it out is to check if the index was an autoindex and if we have a non-rowid\r
+                    // primary key, and all the columns in the given index match the primary key columns\r
+                    if (primaryKeys.Count > 0 && rd.GetString(1).StartsWith("sqlite_autoindex_" + rdTables.GetString(2), StringComparison.InvariantCultureIgnoreCase) == true)\r
+                    {\r
+                      using (SQLiteCommand cmdDetails = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rd.GetString(1)), this))\r
+                      using (SQLiteDataReader rdDetails = cmdDetails.ExecuteReader())\r
+                      {\r
+                        int nMatches = 0;\r
+                        while (rdDetails.Read())\r
+                        {\r
+                          if (primaryKeys.Contains(rdDetails.GetInt32(1)) == false)\r
+                          {\r
+                            nMatches = 0;\r
+                            break;\r
+                          }\r
+                          nMatches++;\r
+                        }\r
+                        if (nMatches == primaryKeys.Count)\r
+                        {\r
+                          row["PRIMARY_KEY"] = true;\r
+                          primaryKeys.Clear();\r
+                        }\r
+                      }\r
+                    }\r
+\r
+                    tbl.Rows.Add(row);\r
+                  }\r
+                }\r
+              }\r
+            }\r
+            catch (SQLiteException)\r
+            {\r
+            }\r
+          }\r
+        }\r
+      }\r
+\r
+      tbl.AcceptChanges();\r
+      tbl.EndLoadData();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    private DataTable Schema_Triggers(string catalog, string table, string triggerName)\r
+    {\r
+      DataTable tbl = new DataTable("Triggers");\r
+      DataRow row;\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("TABLE_CATALOG", typeof(string));\r
+      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("TABLE_NAME", typeof(string));\r
+      tbl.Columns.Add("TRIGGER_NAME", typeof(string));\r
+      tbl.Columns.Add("TRIGGER_DEFINITION", typeof(string));\r
+\r
+      tbl.BeginLoadData();\r
+\r
+      if (String.IsNullOrEmpty(table)) table = null;\r
+      if (String.IsNullOrEmpty(catalog)) catalog = "main";\r
+      string master = (String.Compare(catalog, "temp", true, CultureInfo.InvariantCulture) == 0) ? _tempmasterdb : _masterdb;\r
+\r
+      using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT [type], [name], [tbl_name], [rootpage], [sql], [rowid] FROM [{0}].[{1}] WHERE [type] LIKE 'trigger'", catalog, master), this))\r
+      using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())\r
+      {\r
+        while (rd.Read())\r
+        {\r
+          if (String.Compare(rd.GetString(1), triggerName, true, CultureInfo.InvariantCulture) == 0\r
+            || triggerName == null)\r
+          {\r
+            if (table == null || String.Compare(table, rd.GetString(2), true, CultureInfo.InvariantCulture) == 0)\r
+            {\r
+              row = tbl.NewRow();\r
+\r
+              row["TABLE_CATALOG"] = catalog;\r
+              row["TABLE_NAME"] = rd.GetString(2);\r
+              row["TRIGGER_NAME"] = rd.GetString(1);\r
+              row["TRIGGER_DEFINITION"] = rd.GetString(4);\r
+\r
+              tbl.Rows.Add(row);\r
+            }\r
+          }\r
+        }\r
+      }\r
+      tbl.AcceptChanges();\r
+      tbl.EndLoadData();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves table schema information for the database and catalog\r
+    /// </summary>\r
+    /// <param name="strCatalog">The catalog (attached database) to retrieve tables on</param>\r
+    /// <param name="strTable">The table to retrieve, can be null</param>\r
+    /// <param name="strType">The table type, can be null</param>\r
+    /// <returns>DataTable</returns>\r
+    private DataTable Schema_Tables(string strCatalog, string strTable, string strType)\r
+    {\r
+      DataTable tbl = new DataTable("Tables");\r
+      DataRow row;\r
+      string strItem;\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("TABLE_CATALOG", typeof(string));\r
+      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("TABLE_NAME", typeof(string));\r
+      tbl.Columns.Add("TABLE_TYPE", typeof(string));\r
+      tbl.Columns.Add("TABLE_ID", typeof(long));\r
+      tbl.Columns.Add("TABLE_ROOTPAGE", typeof(int));\r
+      tbl.Columns.Add("TABLE_DEFINITION", typeof(string));\r
+      tbl.BeginLoadData();\r
+\r
+      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";\r
+\r
+      string master = (String.Compare(strCatalog, "temp", true, CultureInfo.InvariantCulture) == 0) ? _tempmasterdb : _masterdb;\r
+\r
+      using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT [type], [name], [tbl_name], [rootpage], [sql], [rowid] FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))\r
+      using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())\r
+      {\r
+        while (rd.Read())\r
+        {\r
+          strItem = rd.GetString(0);\r
+          if (String.Compare(rd.GetString(2), 0, "SQLITE_", 0, 7, true, CultureInfo.InvariantCulture) == 0)\r
+            strItem = "SYSTEM_TABLE";\r
+\r
+          if (String.Compare(strType, strItem, true, CultureInfo.InvariantCulture) == 0\r
+            || strType == null)\r
+          {\r
+            if (String.Compare(rd.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0\r
+              || strTable == null)\r
+            {\r
+              row = tbl.NewRow();\r
+\r
+              row["TABLE_CATALOG"] = strCatalog;\r
+              row["TABLE_NAME"] = rd.GetString(2);\r
+              row["TABLE_TYPE"] = strItem;\r
+              row["TABLE_ID"] = rd.GetInt64(5);\r
+              row["TABLE_ROOTPAGE"] = rd.GetInt32(3);\r
+              row["TABLE_DEFINITION"] = rd.GetString(4);\r
+\r
+              tbl.Rows.Add(row);\r
+            }\r
+          }\r
+        }\r
+      }\r
+\r
+      tbl.AcceptChanges();\r
+      tbl.EndLoadData();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves view schema information for the database\r
+    /// </summary>\r
+    /// <param name="strCatalog">The catalog (attached database) to retrieve views on</param>\r
+    /// <param name="strView">The view name, can be null</param>\r
+    /// <returns>DataTable</returns>\r
+    private DataTable Schema_Views(string strCatalog, string strView)\r
+    {\r
+      DataTable tbl = new DataTable("Views");\r
+      DataRow row;\r
+      string strItem;\r
+      int nPos;\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("TABLE_CATALOG", typeof(string));\r
+      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("TABLE_NAME", typeof(string));\r
+      tbl.Columns.Add("VIEW_DEFINITION", typeof(string));\r
+      tbl.Columns.Add("CHECK_OPTION", typeof(bool));\r
+      tbl.Columns.Add("IS_UPDATABLE", typeof(bool));\r
+      tbl.Columns.Add("DESCRIPTION", typeof(string));\r
+      tbl.Columns.Add("DATE_CREATED", typeof(DateTime));\r
+      tbl.Columns.Add("DATE_MODIFIED", typeof(DateTime));\r
+\r
+      tbl.BeginLoadData();\r
+\r
+      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";\r
+\r
+      string master = (String.Compare(strCatalog, "temp", true, CultureInfo.InvariantCulture) == 0) ? _tempmasterdb : _masterdb;\r
+\r
+      using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'view'", strCatalog, master), this))\r
+      using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())\r
+      {\r
+        while (rd.Read())\r
+        {\r
+          if (String.Compare(rd.GetString(1), strView, true, CultureInfo.InvariantCulture) == 0\r
+            || String.IsNullOrEmpty(strView))\r
+          {\r
+            strItem = rd.GetString(4).Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' ');\r
+            nPos = CultureInfo.InvariantCulture.CompareInfo.IndexOf(strItem, " AS ", CompareOptions.IgnoreCase);\r
+            if (nPos > -1)\r
+            {\r
+              strItem = strItem.Substring(nPos + 4).Trim();\r
+              row = tbl.NewRow();\r
+\r
+              row["TABLE_CATALOG"] = strCatalog;\r
+              row["TABLE_NAME"] = rd.GetString(2);\r
+              row["IS_UPDATABLE"] = false;\r
+              row["VIEW_DEFINITION"] = strItem;\r
+\r
+              tbl.Rows.Add(row);\r
+            }\r
+          }\r
+        }\r
+      }\r
+\r
+      tbl.AcceptChanges();\r
+      tbl.EndLoadData();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves catalog (attached databases) schema information for the database\r
+    /// </summary>\r
+    /// <param name="strCatalog">The catalog to retrieve, can be null</param>\r
+    /// <returns>DataTable</returns>\r
+    private DataTable Schema_Catalogs(string strCatalog)\r
+    {\r
+      DataTable tbl = new DataTable("Catalogs");\r
+      DataRow row;\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("CATALOG_NAME", typeof(string));\r
+      tbl.Columns.Add("DESCRIPTION", typeof(string));\r
+      tbl.Columns.Add("ID", typeof(long));\r
+\r
+      tbl.BeginLoadData();\r
+\r
+      using (SQLiteCommand cmd = new SQLiteCommand("PRAGMA database_list", this))\r
+      using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())\r
+      {\r
+        while (rd.Read())\r
+        {\r
+          if (String.Compare(rd.GetString(1), strCatalog, true, CultureInfo.InvariantCulture) == 0\r
+            || strCatalog == null)\r
+          {\r
+            row = tbl.NewRow();\r
+\r
+            row["CATALOG_NAME"] = rd.GetString(1);\r
+            row["DESCRIPTION"] = rd.GetString(2);\r
+            row["ID"] = rd.GetInt64(0);\r
+\r
+            tbl.Rows.Add(row);\r
+          }\r
+        }\r
+      }\r
+\r
+      tbl.AcceptChanges();\r
+      tbl.EndLoadData();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    private DataTable Schema_DataTypes()\r
+    {\r
+      DataTable tbl = new DataTable("DataTypes");\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("TypeName", typeof(String));\r
+      tbl.Columns.Add("ProviderDbType", typeof(int));\r
+      tbl.Columns.Add("ColumnSize", typeof(long));\r
+      tbl.Columns.Add("CreateFormat", typeof(String));\r
+      tbl.Columns.Add("CreateParameters", typeof(String));\r
+      tbl.Columns.Add("DataType", typeof(String));\r
+      tbl.Columns.Add("IsAutoIncrementable", typeof(bool));\r
+      tbl.Columns.Add("IsBestMatch", typeof(bool));\r
+      tbl.Columns.Add("IsCaseSensitive", typeof(bool));\r
+      tbl.Columns.Add("IsFixedLength", typeof(bool));\r
+      tbl.Columns.Add("IsFixedPrecisionScale", typeof(bool));\r
+      tbl.Columns.Add("IsLong", typeof(bool));\r
+      tbl.Columns.Add("IsNullable", typeof(bool));\r
+      tbl.Columns.Add("IsSearchable", typeof(bool));\r
+      tbl.Columns.Add("IsSearchableWithLike", typeof(bool));\r
+      tbl.Columns.Add("IsLiteralSupported", typeof(bool));\r
+      tbl.Columns.Add("LiteralPrefix", typeof(String));\r
+      tbl.Columns.Add("LiteralSuffix", typeof(String));\r
+      tbl.Columns.Add("IsUnsigned", typeof(bool));\r
+      tbl.Columns.Add("MaximumScale", typeof(short));\r
+      tbl.Columns.Add("MinimumScale", typeof(short));\r
+      tbl.Columns.Add("IsConcurrencyType", typeof(bool));\r
+\r
+      tbl.BeginLoadData();\r
+\r
+      StringReader reader = new StringReader(SR.DataTypes);\r
+      tbl.ReadXml(reader);\r
+      reader.Close();\r
+\r
+      tbl.AcceptChanges();\r
+      tbl.EndLoadData();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the base column information for indexes in a database\r
+    /// </summary>\r
+    /// <param name="strCatalog">The catalog to retrieve indexes for (can be null)</param>\r
+    /// <param name="strTable">The table to restrict index information by (can be null)</param>\r
+    /// <param name="strIndex">The index to restrict index information by (can be null)</param>\r
+    /// <param name="strColumn">The source column to restrict index information by (can be null)</param>\r
+    /// <returns>A DataTable containing the results</returns>\r
+    private DataTable Schema_IndexColumns(string strCatalog, string strTable, string strIndex, string strColumn)\r
+    {\r
+      DataTable tbl = new DataTable("IndexColumns");\r
+      DataRow row;\r
+      List<KeyValuePair<int, string>> primaryKeys = new List<KeyValuePair<int, string>>();\r
+      bool maybeRowId;\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("CONSTRAINT_CATALOG", typeof(string));\r
+      tbl.Columns.Add("CONSTRAINT_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("CONSTRAINT_NAME", typeof(string));\r
+      tbl.Columns.Add("TABLE_CATALOG", typeof(string));\r
+      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("TABLE_NAME", typeof(string));\r
+      tbl.Columns.Add("COLUMN_NAME", typeof(string));\r
+      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));\r
+      tbl.Columns.Add("INDEX_NAME", typeof(string));\r
+      tbl.Columns.Add("COLLATION_NAME", typeof(string));\r
+      tbl.Columns.Add("SORT_MODE", typeof(string));\r
+      tbl.Columns.Add("CONFLICT_OPTION", typeof(int));\r
+\r
+      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";\r
+\r
+      string master = (String.Compare(strCatalog, "temp", true, CultureInfo.InvariantCulture) == 0) ? _tempmasterdb : _masterdb;\r
+\r
+      tbl.BeginLoadData();\r
+\r
+      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))\r
+      using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())\r
+      {\r
+        while (rdTables.Read())\r
+        {\r
+          maybeRowId = false;\r
+          primaryKeys.Clear();\r
+          if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0)\r
+          {\r
+            try\r
+            {\r
+              using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this))\r
+              using (SQLiteDataReader rdTable = cmdTable.ExecuteReader())\r
+              {\r
+                while (rdTable.Read())\r
+                {\r
+                  if (rdTable.GetInt32(5) == 1) // is a primary key\r
+                  {\r
+                    primaryKeys.Add(new KeyValuePair<int, string>(rdTable.GetInt32(0), rdTable.GetString(1)));\r
+                    // Is an integer -- could be a rowid if no other primary keys exist in the table\r
+                    if (String.Compare(rdTable.GetString(2), "INTEGER", true, CultureInfo.InvariantCulture) == 0)\r
+                      maybeRowId = true;\r
+                  }\r
+                }\r
+              }\r
+            }\r
+            catch (SQLiteException)\r
+            {\r
+            }\r
+            // This is a rowid row\r
+            if (primaryKeys.Count == 1 && maybeRowId == true)\r
+            {\r
+              row = tbl.NewRow();\r
+              row["CONSTRAINT_CATALOG"] = strCatalog;\r
+              row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "{1}_PK_{0}", rdTables.GetString(2), master);\r
+              row["TABLE_CATALOG"] = strCatalog;\r
+              row["TABLE_NAME"] = rdTables.GetString(2);\r
+              row["COLUMN_NAME"] = primaryKeys[0].Value;\r
+              row["INDEX_NAME"] = row["CONSTRAINT_NAME"];\r
+              row["ORDINAL_POSITION"] = 0; // primaryKeys[0].Key;\r
+              row["COLLATION_NAME"] = "BINARY";\r
+              row["SORT_MODE"] = "ASC";\r
+              row["CONFLICT_OPTION"] = 2;\r
+\r
+              if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, (string)row["INDEX_NAME"], true, CultureInfo.InvariantCulture) == 0)\r
+                tbl.Rows.Add(row);\r
+            }\r
+\r
+            using (SQLiteCommand cmdIndexes = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{2}] WHERE [type] LIKE 'index' AND [tbl_name] LIKE '{1}'", strCatalog, rdTables.GetString(2).Replace("'", "''"), master), this))\r
+            using (SQLiteDataReader rdIndexes = cmdIndexes.ExecuteReader())\r
+            {\r
+              while (rdIndexes.Read())\r
+              {\r
+                int ordinal = 0;\r
+                if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, rdIndexes.GetString(1), true, CultureInfo.InvariantCulture) == 0)\r
+                {\r
+                  try\r
+                  {\r
+                    using (SQLiteCommand cmdIndex = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rdIndexes.GetString(1)), this))\r
+                    using (SQLiteDataReader rdIndex = cmdIndex.ExecuteReader())\r
+                    {\r
+                      while (rdIndex.Read())\r
+                      {\r
+                        row = tbl.NewRow();\r
+                        row["CONSTRAINT_CATALOG"] = strCatalog;\r
+                        row["CONSTRAINT_NAME"] = rdIndexes.GetString(1);\r
+                        row["TABLE_CATALOG"] = strCatalog;\r
+                        row["TABLE_NAME"] = rdIndexes.GetString(2);\r
+                        row["COLUMN_NAME"] = rdIndex.GetString(2);\r
+                        row["INDEX_NAME"] = rdIndexes.GetString(1);\r
+                        row["ORDINAL_POSITION"] = ordinal; // rdIndex.GetInt32(1);\r
+\r
+                        string collationSequence;\r
+                        int sortMode;\r
+                        int onError;\r
+                        _sql.GetIndexColumnExtendedInfo(strCatalog, rdIndexes.GetString(1), rdIndex.GetString(2), out sortMode, out onError, out collationSequence);\r
+\r
+                        if (String.IsNullOrEmpty(collationSequence) == false)\r
+                          row["COLLATION_NAME"] = collationSequence;\r
+\r
+                        row["SORT_MODE"] = (sortMode == 0) ? "ASC" : "DESC";\r
+                        row["CONFLICT_OPTION"] = onError;\r
+\r
+                        ordinal++;\r
+\r
+                        if (String.IsNullOrEmpty(strColumn) || String.Compare(strColumn, row["COLUMN_NAME"].ToString(), true, CultureInfo.InvariantCulture) == 0)\r
+                          tbl.Rows.Add(row);\r
+                      }\r
+                    }\r
+                  }\r
+                  catch (SQLiteException)\r
+                  {\r
+                  }\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+\r
+      tbl.EndLoadData();\r
+      tbl.AcceptChanges();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns detailed column information for a specified view\r
+    /// </summary>\r
+    /// <param name="strCatalog">The catalog to retrieve columns for (can be null)</param>\r
+    /// <param name="strView">The view to restrict column information by (can be null)</param>\r
+    /// <param name="strColumn">The source column to restrict column information by (can be null)</param>\r
+    /// <returns>A DataTable containing the results</returns>\r
+    private DataTable Schema_ViewColumns(string strCatalog, string strView, string strColumn)\r
+    {\r
+      DataTable tbl = new DataTable("ViewColumns");\r
+      DataRow row;\r
+      string strSql;\r
+      int n;\r
+      DataRow schemaRow;\r
+      DataRow viewRow;\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("VIEW_CATALOG", typeof(string));\r
+      tbl.Columns.Add("VIEW_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("VIEW_NAME", typeof(string));\r
+      tbl.Columns.Add("VIEW_COLUMN_NAME", typeof(String));\r
+      tbl.Columns.Add("TABLE_CATALOG", typeof(string));\r
+      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("TABLE_NAME", typeof(string));\r
+      tbl.Columns.Add("COLUMN_NAME", typeof(string));\r
+      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));\r
+      tbl.Columns.Add("COLUMN_HASDEFAULT", typeof(bool));\r
+      tbl.Columns.Add("COLUMN_DEFAULT", typeof(string));\r
+      tbl.Columns.Add("COLUMN_FLAGS", typeof(long));\r
+      tbl.Columns.Add("IS_NULLABLE", typeof(bool));\r
+      tbl.Columns.Add("DATA_TYPE", typeof(string));\r
+      tbl.Columns.Add("CHARACTER_MAXIMUM_LENGTH", typeof(int));\r
+      tbl.Columns.Add("NUMERIC_PRECISION", typeof(int));\r
+      tbl.Columns.Add("NUMERIC_SCALE", typeof(int));\r
+      tbl.Columns.Add("DATETIME_PRECISION", typeof(long));\r
+      tbl.Columns.Add("CHARACTER_SET_CATALOG", typeof(string));\r
+      tbl.Columns.Add("CHARACTER_SET_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("CHARACTER_SET_NAME", typeof(string));\r
+      tbl.Columns.Add("COLLATION_CATALOG", typeof(string));\r
+      tbl.Columns.Add("COLLATION_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("COLLATION_NAME", typeof(string));\r
+      tbl.Columns.Add("PRIMARY_KEY", typeof(bool));\r
+      tbl.Columns.Add("EDM_TYPE", typeof(string));\r
+      tbl.Columns.Add("AUTOINCREMENT", typeof(bool));\r
+      tbl.Columns.Add("UNIQUE", typeof(bool));\r
+\r
+      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";\r
+\r
+      string master = (String.Compare(strCatalog, "temp", true, CultureInfo.InvariantCulture) == 0) ? _tempmasterdb : _masterdb;\r
+      \r
+      tbl.BeginLoadData();\r
+\r
+      using (SQLiteCommand cmdViews = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'view'", strCatalog, master), this))\r
+      using (SQLiteDataReader rdViews = cmdViews.ExecuteReader())\r
+      {\r
+        while (rdViews.Read())\r
+        {\r
+          if (String.IsNullOrEmpty(strView) || String.Compare(strView, rdViews.GetString(2), true, CultureInfo.InvariantCulture) == 0)\r
+          {\r
+            using (SQLiteCommand cmdViewSelect = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdViews.GetString(2)), this))\r
+            {\r
+              strSql = rdViews.GetString(4).Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' ');\r
+              n = CultureInfo.InvariantCulture.CompareInfo.IndexOf(strSql, " AS ", CompareOptions.IgnoreCase);\r
+              if (n < 0)\r
+                continue;\r
+\r
+              strSql = strSql.Substring(n + 4);\r
+\r
+              using (SQLiteCommand cmd = new SQLiteCommand(strSql, this))\r
+              using (SQLiteDataReader rdViewSelect = cmdViewSelect.ExecuteReader(CommandBehavior.SchemaOnly))\r
+              using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader(CommandBehavior.SchemaOnly))\r
+              using (DataTable tblSchemaView = rdViewSelect.GetSchemaTable(false, false))\r
+              using (DataTable tblSchema = rd.GetSchemaTable(false, false))\r
+              {\r
+                for (n = 0; n < tblSchema.Rows.Count; n++)\r
+                {\r
+                  viewRow = tblSchemaView.Rows[n];\r
+                  schemaRow = tblSchema.Rows[n];\r
+\r
+                  if (String.Compare(viewRow[SchemaTableColumn.ColumnName].ToString(), strColumn, true, CultureInfo.InvariantCulture) == 0\r
+                    || strColumn == null)\r
+                  {\r
+                    row = tbl.NewRow();\r
+\r
+                    row["VIEW_CATALOG"] = strCatalog;\r
+                    row["VIEW_NAME"] = rdViews.GetString(2);\r
+                    row["TABLE_CATALOG"] = strCatalog;\r
+                    row["TABLE_SCHEMA"] = schemaRow[SchemaTableColumn.BaseSchemaName];\r
+                    row["TABLE_NAME"] = schemaRow[SchemaTableColumn.BaseTableName];\r
+                    row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.BaseColumnName];\r
+                    row["VIEW_COLUMN_NAME"] = viewRow[SchemaTableColumn.ColumnName];\r
+                    row["COLUMN_HASDEFAULT"] = (viewRow[SchemaTableOptionalColumn.DefaultValue] != DBNull.Value);\r
+                    row["COLUMN_DEFAULT"] = viewRow[SchemaTableOptionalColumn.DefaultValue];\r
+                    row["ORDINAL_POSITION"] = viewRow[SchemaTableColumn.ColumnOrdinal];\r
+                    row["IS_NULLABLE"] = viewRow[SchemaTableColumn.AllowDBNull];\r
+                    row["DATA_TYPE"] = viewRow["DataTypeName"]; // SQLiteConvert.DbTypeToType((DbType)viewRow[SchemaTableColumn.ProviderType]).ToString();\r
+                    row["EDM_TYPE"] = SQLiteConvert.DbTypeToTypeName((DbType)viewRow[SchemaTableColumn.ProviderType]).ToString().ToLower(CultureInfo.InvariantCulture);\r
+                    row["CHARACTER_MAXIMUM_LENGTH"] = viewRow[SchemaTableColumn.ColumnSize];\r
+                    row["TABLE_SCHEMA"] = viewRow[SchemaTableColumn.BaseSchemaName];\r
+                    row["PRIMARY_KEY"] = viewRow[SchemaTableColumn.IsKey];\r
+                    row["AUTOINCREMENT"] = viewRow[SchemaTableOptionalColumn.IsAutoIncrement];\r
+                    row["COLLATION_NAME"] = viewRow["CollationType"];\r
+                    row["UNIQUE"] = viewRow[SchemaTableColumn.IsUnique];\r
+                    tbl.Rows.Add(row);\r
+                  }\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+\r
+      tbl.EndLoadData();\r
+      tbl.AcceptChanges();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves foreign key information from the specified set of filters\r
+    /// </summary>\r
+    /// <param name="strCatalog">An optional catalog to restrict results on</param>\r
+    /// <param name="strTable">An optional table to restrict results on</param>\r
+    /// <param name="strKeyName">An optional foreign key name to restrict results on</param>\r
+    /// <returns>A DataTable with the results of the query</returns>\r
+    private DataTable Schema_ForeignKeys(string strCatalog, string strTable, string strKeyName)\r
+    {\r
+      DataTable tbl = new DataTable("ForeignKeys");\r
+      DataRow row;\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add("CONSTRAINT_CATALOG", typeof(string));\r
+      tbl.Columns.Add("CONSTRAINT_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("CONSTRAINT_NAME", typeof(string));\r
+      tbl.Columns.Add("TABLE_CATALOG", typeof(string));\r
+      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("TABLE_NAME", typeof(string));\r
+      tbl.Columns.Add("CONSTRAINT_TYPE", typeof(string));\r
+      tbl.Columns.Add("IS_DEFERRABLE", typeof(bool));\r
+      tbl.Columns.Add("INITIALLY_DEFERRED", typeof(bool));\r
+      tbl.Columns.Add("FKEY_FROM_COLUMN", typeof(string));\r
+      tbl.Columns.Add("FKEY_FROM_ORDINAL_POSITION", typeof(int));\r
+      tbl.Columns.Add("FKEY_TO_CATALOG", typeof(string));\r
+      tbl.Columns.Add("FKEY_TO_SCHEMA", typeof(string));\r
+      tbl.Columns.Add("FKEY_TO_TABLE", typeof(string));\r
+      tbl.Columns.Add("FKEY_TO_COLUMN", typeof(string));\r
+\r
+      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";\r
+\r
+      string master = (String.Compare(strCatalog, "temp", true, CultureInfo.InvariantCulture) == 0) ? _tempmasterdb : _masterdb;\r
+\r
+      tbl.BeginLoadData();\r
+\r
+      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))\r
+      using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())\r
+      {\r
+        while (rdTables.Read())\r
+        {\r
+          if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), true, CultureInfo.InvariantCulture) == 0)\r
+          {\r
+            try\r
+            {\r
+              using (SQLiteCommandBuilder builder = new SQLiteCommandBuilder())\r
+              //using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdTables.GetString(2)), this))\r
+              //using (SQLiteDataReader rdTable = cmdTable.ExecuteReader(CommandBehavior.SchemaOnly))\r
+              using (SQLiteCommand cmdKey = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].foreign_key_list([{1}])", strCatalog, rdTables.GetString(2)), this))\r
+              using (SQLiteDataReader rdKey = cmdKey.ExecuteReader())\r
+              {\r
+                while (rdKey.Read())\r
+                {\r
+                  row = tbl.NewRow();\r
+                  row["CONSTRAINT_CATALOG"] = strCatalog;\r
+                  row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}", rdTables[2], rdKey.GetInt32(0));\r
+                  row["TABLE_CATALOG"] = strCatalog;\r
+                  row["TABLE_NAME"] = builder.UnquoteIdentifier(rdTables.GetString(2));\r
+                  row["CONSTRAINT_TYPE"] = "FOREIGN KEY";\r
+                  row["IS_DEFERRABLE"] = false;\r
+                  row["INITIALLY_DEFERRED"] = false;\r
+                  row["FKEY_FROM_COLUMN"] = builder.UnquoteIdentifier(rdKey[3].ToString());\r
+                  row["FKEY_TO_CATALOG"] = strCatalog;\r
+                  row["FKEY_TO_TABLE"] = builder.UnquoteIdentifier(rdKey[2].ToString());\r
+                  row["FKEY_TO_COLUMN"] = builder.UnquoteIdentifier(rdKey[4].ToString());\r
+                  row["FKEY_FROM_ORDINAL_POSITION"] = rdKey[1];\r
+\r
+                  if (String.IsNullOrEmpty(strKeyName) || String.Compare(strKeyName, row["CONSTRAINT_NAME"].ToString(), true, CultureInfo.InvariantCulture) == 0)\r
+                    tbl.Rows.Add(row);\r
+                }\r
+              }\r
+            }\r
+            catch (SQLiteException)\r
+            {\r
+            }\r
+          }\r
+        }\r
+      }\r
+\r
+      tbl.EndLoadData();\r
+      tbl.AcceptChanges();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// This event is raised whenever SQLite makes an update/delete/insert into the database on\r
+    /// this connection.  It only applies to the given connection.\r
+    /// </summary>\r
+    public event SQLiteUpdateEventHandler Update\r
+    {\r
+      add\r
+      {\r
+        if (_updateHandler == null)\r
+        {\r
+          _updateCallback = new SQLiteUpdateCallback(UpdateCallback);\r
+          if (_sql != null) _sql.SetUpdateHook(_updateCallback);\r
+        }\r
+        _updateHandler += value;\r
+      }\r
+      remove\r
+      {\r
+        _updateHandler -= value;\r
+        if (_updateHandler == null)\r
+        {\r
+          if (_sql != null) _sql.SetUpdateHook(null);\r
+          _updateCallback = null;\r
+        }\r
+      }\r
+    }\r
+\r
+    private void UpdateCallback(IntPtr puser, int type, IntPtr database, IntPtr table, Int64 rowid)\r
+    {\r
+      _updateHandler(this, new UpdateEventArgs(\r
+        SQLiteBase.UTF8ToString(database, -1),\r
+        SQLiteBase.UTF8ToString(table, -1),\r
+        (UpdateEventType)type,\r
+        rowid));\r
+    }\r
+\r
+    /// <summary>\r
+    /// This event is raised whenever SQLite is committing a transaction.\r
+    /// Return non-zero to trigger a rollback\r
+    /// </summary>\r
+    public event SQLiteCommitHandler Commit\r
+    {\r
+      add\r
+      {\r
+        if (_commitHandler == null)\r
+        {\r
+          _commitCallback = new SQLiteCommitCallback(CommitCallback);\r
+          if (_sql != null) _sql.SetCommitHook(_commitCallback);\r
+        }\r
+        _commitHandler += value;\r
+      }\r
+      remove\r
+      {\r
+        _commitHandler -= value;\r
+        if (_commitHandler == null)\r
+        {\r
+          if (_sql != null) _sql.SetCommitHook(null);\r
+          _commitCallback = null;\r
+        }\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// This event is raised whenever SQLite is committing a transaction.\r
+    /// Return non-zero to trigger a rollback\r
+    /// </summary>\r
+    public event EventHandler RollBack\r
+    {\r
+      add\r
+      {\r
+        if (_rollbackHandler == null)\r
+        {\r
+          _rollbackCallback = new SQLiteRollbackCallback(RollbackCallback);\r
+          if (_sql != null) _sql.SetRollbackHook(_rollbackCallback);\r
+        }\r
+        _rollbackHandler += value;\r
+      }\r
+      remove\r
+      {\r
+        _rollbackHandler -= value;\r
+        if (_rollbackHandler == null)\r
+        {\r
+          if (_sql != null) _sql.SetRollbackHook(null);\r
+          _rollbackCallback = null;\r
+        }\r
+      }\r
+    }\r
+\r
+\r
+    private int CommitCallback(IntPtr parg)\r
+    {\r
+      CommitEventArgs e = new CommitEventArgs();\r
+      _commitHandler(this, e);\r
+      return (e.AbortTransaction == true) ? 1 : 0;\r
+    }\r
+\r
+    private void RollbackCallback(IntPtr parg)\r
+    {\r
+      _rollbackHandler(this, EventArgs.Empty);\r
+    }\r
+  }\r
+\r
+  /// <summary>\r
+  /// The I/O file cache flushing behavior for the connection\r
+  /// </summary>\r
+  public enum SynchronizationModes\r
+  {\r
+    /// <summary>\r
+    /// Normal file flushing at critical sections of the code\r
+    /// </summary>\r
+    Normal = 0,\r
+    /// <summary>\r
+    /// Full file flushing after every write operation\r
+    /// </summary>\r
+    Full = 1,\r
+    /// <summary>\r
+    /// Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing\r
+    /// </summary>\r
+    Off = 2,\r
+  }\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\r
+#endif\r
+  internal delegate void SQLiteUpdateCallback(IntPtr puser, int type, IntPtr database, IntPtr table, Int64 rowid);\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\r
+#endif\r
+  internal delegate int SQLiteCommitCallback(IntPtr puser);\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\r
+#endif\r
+  internal delegate void SQLiteRollbackCallback(IntPtr puser);\r
+\r
+  /// <summary>\r
+  /// Raised when a transaction is about to be committed.  To roll back a transaction, set the \r
+  /// rollbackTrans boolean value to true.\r
+  /// </summary>\r
+  /// <param name="sender">The connection committing the transaction</param>\r
+  /// <param name="e">Event arguments on the transaction</param>\r
+  public delegate void SQLiteCommitHandler(object sender, CommitEventArgs e);\r
+\r
+  /// <summary>\r
+  /// Raised when data is inserted, updated and deleted on a given connection\r
+  /// </summary>\r
+  /// <param name="sender">The connection committing the transaction</param>\r
+  /// <param name="e">The event parameters which triggered the event</param>\r
+  public delegate void SQLiteUpdateEventHandler(object sender, UpdateEventArgs e);\r
+\r
+  /// <summary>\r
+  /// Whenever an update event is triggered on a connection, this enum will indicate\r
+  /// exactly what type of operation is being performed.\r
+  /// </summary>\r
+  public enum UpdateEventType\r
+  {\r
+    /// <summary>\r
+    /// A row is being deleted from the given database and table\r
+    /// </summary>\r
+    Delete = 9,\r
+    /// <summary>\r
+    /// A row is being inserted into the table.\r
+    /// </summary>\r
+    Insert = 18,\r
+    /// <summary>\r
+    /// A row is being updated in the table.\r
+    /// </summary>\r
+    Update = 23,\r
+  }\r
+\r
+  /// <summary>\r
+  /// Passed during an Update callback, these event arguments detail the type of update operation being performed\r
+  /// on the given connection.\r
+  /// </summary>\r
+  public class UpdateEventArgs : EventArgs\r
+  {\r
+    /// <summary>\r
+    /// The name of the database being updated (usually "main" but can be any attached or temporary database)\r
+    /// </summary>\r
+    public readonly string Database;\r
+\r
+    /// <summary>\r
+    /// The name of the table being updated\r
+    /// </summary>\r
+    public readonly string Table;\r
+\r
+    /// <summary>\r
+    /// The type of update being performed (insert/update/delete)\r
+    /// </summary>\r
+    public readonly UpdateEventType Event;\r
+\r
+    /// <summary>\r
+    /// The RowId affected by this update.\r
+    /// </summary>\r
+    public readonly Int64 RowId;\r
+\r
+    internal UpdateEventArgs(string database, string table, UpdateEventType eventType, Int64 rowid)\r
+    {\r
+      Database = database;\r
+      Table = table;\r
+      Event = eventType;\r
+      RowId = rowid;\r
+    }\r
+  }\r
+\r
+  /// <summary>\r
+  /// Event arguments raised when a transaction is being committed\r
+  /// </summary>\r
+  public class CommitEventArgs : EventArgs\r
+  {\r
+    internal CommitEventArgs()\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Set to true to abort the transaction and trigger a rollback\r
+    /// </summary>\r
+    public bool AbortTransaction;\r
+  }\r
+\r
+}\r
diff --git a/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConnectionPool.cs b/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConnectionPool.cs
new file mode 100644 (file)
index 0000000..5408b52
--- /dev/null
@@ -0,0 +1,192 @@
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Collections.Generic;\r
+\r
+  internal static class SQLiteConnectionPool\r
+  {\r
+    /// <summary>\r
+    /// Keeps track of connections made on a specified file.  The PoolVersion dictates whether old objects get\r
+    /// returned to the pool or discarded when no longer in use.\r
+    /// </summary>\r
+    internal class Pool\r
+    {\r
+      internal readonly Queue<WeakReference> Queue = new Queue<WeakReference>();\r
+      internal int PoolVersion;\r
+      internal int MaxPoolSize;\r
+\r
+      internal Pool(int version, int maxSize)\r
+      {\r
+        PoolVersion = version;\r
+        MaxPoolSize = maxSize;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// The connection pool object\r
+    /// </summary>\r
+    private static SortedList<string, Pool> _connections = new SortedList<string, Pool>(StringComparer.OrdinalIgnoreCase);\r
+\r
+    /// <summary>\r
+    /// The default version number new pools will get\r
+    /// </summary>\r
+    private static int _poolVersion = 1;\r
+\r
+    /// <summary>\r
+    /// Attempt to pull a pooled connection out of the queue for active duty\r
+    /// </summary>\r
+    /// <param name="fileName">The filename for a desired connection</param>\r
+    /// <param name="maxPoolSize">The maximum size the connection pool for the filename can be</param>\r
+    /// <param name="version">The pool version the returned connection will belong to</param>\r
+    /// <returns>Returns NULL if no connections were available.  Even if none are, the poolversion will still be a valid pool version</returns>\r
+    internal static SQLiteConnectionHandle Remove(string fileName, int maxPoolSize, out int version)\r
+    {\r
+      lock (_connections)\r
+      {\r
+        Pool queue;\r
+\r
+        // Default to the highest pool version\r
+        version = _poolVersion;\r
+\r
+        // If we didn't find a pool for this file, create one even though it will be empty.\r
+        // We have to do this here because otherwise calling ClearPool() on the file will not work for active connections\r
+        // that have never seen the pool yet.\r
+        if (_connections.TryGetValue(fileName, out queue) == false)\r
+        {\r
+          queue = new Pool(_poolVersion, maxPoolSize);\r
+          _connections.Add(fileName, queue);\r
+\r
+          return null;\r
+        }\r
+\r
+        // We found a pool for this file, so use its version number\r
+        version = queue.PoolVersion;\r
+        queue.MaxPoolSize = maxPoolSize;\r
+\r
+        ResizePool(queue, false);\r
+\r
+        // Try and get a pooled connection from the queue\r
+        while (queue.Queue.Count > 0)\r
+        {\r
+          WeakReference cnn = queue.Queue.Dequeue();\r
+          SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle;\r
+          if (hdl != null)\r
+          {\r
+            return hdl;\r
+          }\r
+        }\r
+        return null;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Clears out all pooled connections and rev's up the default pool version to force all old active objects\r
+    /// not in the pool to get discarded rather than returned to their pools.\r
+    /// </summary>\r
+    internal static void ClearAllPools()\r
+    {\r
+      lock (_connections)\r
+      {\r
+        foreach (KeyValuePair<string, Pool> pair in _connections)\r
+        {\r
+          while (pair.Value.Queue.Count > 0)\r
+          {\r
+            WeakReference cnn = pair.Value.Queue.Dequeue();\r
+            SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle;\r
+            if (hdl != null)\r
+            {\r
+              hdl.Dispose();\r
+            }\r
+          }\r
+          \r
+          // Keep track of the highest revision so we can go one higher when we're finished\r
+          if (_poolVersion <= pair.Value.PoolVersion)\r
+            _poolVersion = pair.Value.PoolVersion + 1;\r
+        }\r
+        // All pools are cleared and we have a new highest version number to force all old version active items to get discarded\r
+        // instead of going back to the queue when they are closed.\r
+        // We can get away with this because we're pumped up the _poolVersion out of range of all active connections, so they\r
+        // will all get discarded when they try to put themselves back in their pool.\r
+        _connections.Clear();\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Clear a given pool for a given filename.  Discards anything in the pool for the given file, and revs the pool\r
+    /// version so current active objects on the old version of the pool will get discarded rather than be returned to the pool.\r
+    /// </summary>\r
+    /// <param name="fileName">The filename of the pool to clear</param>\r
+    internal static void ClearPool(string fileName)\r
+    {\r
+      lock (_connections)\r
+      {\r
+        Pool queue;\r
+        if (_connections.TryGetValue(fileName, out queue) == true)\r
+        {\r
+          queue.PoolVersion++;\r
+          while (queue.Queue.Count > 0)\r
+          {\r
+            WeakReference cnn = queue.Queue.Dequeue();\r
+            SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle;\r
+            if (hdl != null)\r
+            {\r
+              hdl.Dispose();\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Return a connection to the pool for someone else to use.\r
+    /// </summary>\r
+    /// <param name="fileName">The filename of the pool to use</param>\r
+    /// <param name="hdl">The connection handle to pool</param>\r
+    /// <param name="version">The pool version the handle was created under</param>\r
+    /// <remarks>\r
+    /// If the version numbers don't match between the connection and the pool, then the handle is discarded.\r
+    /// </remarks>\r
+    internal static void Add(string fileName, SQLiteConnectionHandle hdl, int version)\r
+    {\r
+      lock (_connections)\r
+      {\r
+        // If the queue doesn't exist in the pool, then it must've been cleared sometime after the connection was created.\r
+        Pool queue;\r
+        if (_connections.TryGetValue(fileName, out queue) == true && version == queue.PoolVersion)\r
+        {\r
+          ResizePool(queue, true);\r
+          queue.Queue.Enqueue(new WeakReference(hdl, false));\r
+          GC.KeepAlive(hdl);\r
+        }\r
+        else\r
+        {\r
+          hdl.Close();\r
+        }\r
+      }\r
+    }\r
+\r
+    private static void ResizePool(Pool queue, bool forAdding)\r
+    {\r
+      int target = queue.MaxPoolSize;\r
+\r
+      if (forAdding && target > 0) target--;\r
+\r
+      while (queue.Queue.Count > target)\r
+      {\r
+        WeakReference cnn = queue.Queue.Dequeue();\r
+        SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle;\r
+        if (hdl != null)\r
+        {\r
+          hdl.Dispose();\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
index 2fa72cedc7a7738b1c231d825d5c0c37af16c445..927d3eb33e81bebc7742599d14c953f48ca4c053 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteConnectionStringBuilder.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data.Common;
-  using System.ComponentModel;
-  using System.Collections;
-  using System.Globalization;
-  using System.Reflection;
-
-#if !PLATFORM_COMPACTFRAMEWORK
-  using System.ComponentModel.Design;
-
-  /// <summary>
-  /// Sqlite implementation of DbConnectionStringBuilder.
-  /// </summary>
-  [DefaultProperty("DataSource")]
-  [DefaultMember("Item")]
-  public sealed class SqliteConnectionStringBuilder : DbConnectionStringBuilder
-  {
-    /// <summary>
-    /// Properties of this class
-    /// </summary>
-    private Hashtable _properties;
-
-    /// <overloads>
-    /// Constructs a new instance of the class
-    /// </overloads>
-    /// <summary>
-    /// Default constructor
-    /// </summary>
-    public SqliteConnectionStringBuilder()
-    {
-      Initialize(null);
-    }
-
-    /// <summary>
-    /// Constructs a new instance of the class using the specified connection string.
-    /// </summary>
-    /// <param name="connectionString">The connection string to parse</param>
-    public SqliteConnectionStringBuilder(string connectionString)
-    {
-      Initialize(connectionString);
-    }
-
-    /// <summary>
-    /// Private initializer, which assigns the connection string and resets the builder
-    /// </summary>
-    /// <param name="cnnString">The connection string to assign</param>
-    private void Initialize(string cnnString)
-    {
-      _properties = new Hashtable();
-      base.GetProperties(_properties);
-
-      if (String.IsNullOrEmpty(cnnString) == false)
-        ConnectionString = cnnString;
-    }
-
-    /// <summary>
-    /// Gets/Sets the default version of the Sqlite engine to instantiate.  Currently the only valid value is 3, indicating version 3 of the sqlite library.
-    /// </summary>
-    [Browsable(true)]
-    [DefaultValue(3)]
-    public int Version
-    {
-      get
-      {
-        if (ContainsKey("Version") == false) return 3;
-
-        return Convert.ToInt32(this["Version"], CultureInfo.CurrentCulture);
-      }
-      set
-      {
-        if (value != 3)
-          throw new NotSupportedException();
-
-        this["Version"] = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets/Sets the synchronous mode of the connection string.  Default is "Normal".
-    /// </summary>
-    [DisplayName("Synchronous")]
-    [Browsable(true)]
-    [DefaultValue(SynchronizationModes.Normal)]
-    public SynchronizationModes SyncMode
-    {
-      get
-      {
-        return (SynchronizationModes)TypeDescriptor.GetConverter(typeof(SynchronizationModes)).ConvertFrom(this["Synchronous"]);
-      }
-      set
-      {
-        this["Synchronous"] = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets/Sets the encoding for the connection string.  The default is "False" which indicates UTF-8 encoding.
-    /// </summary>
-    [Browsable(true)]
-    [DefaultValue(false)]
-    public bool UseUTF16Encoding
-    {
-      get
-      {
-        return Convert.ToBoolean(this["UseUTF16Encoding"], CultureInfo.CurrentCulture);
-      }
-      set
-      {
-        this["UseUTF16Encoding"] = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets/Sets the filename to open on the connection string.
-    /// </summary>
-    [DisplayName("Data Source")]
-    [Browsable(true)]
-    public string DataSource
-    {
-      get
-      {
-        if (ContainsKey("Data Source") == false) return "";
-
-        return this["Data Source"].ToString();
-      }
-      set
-      {
-        this["Data Source"] = value;
-      }
-    }
-
-#region Mono-specific
-    /// <summary>
-    /// Gets/Sets the filename to open on the connection string (Mono-specific, uses DataSource).
-    /// </summary>
-    [DisplayName("Data Source")]
-    [Browsable(true)]
-    public string Uri
-    {
-      get
-      {
-       return DataSource;
-      }
-      set
-      {
-        DataSource = value;
-      }
-    }
-#endregion
-    
-    /// <summary>
-    /// Determines whether or not the connection will automatically participate
-    /// in the current distributed transaction (if one exists)
-    /// </summary>
-    [DisplayName("Automatic Enlistment")]
-    [Browsable(true)]
-    [DefaultValue(true)]
-    public bool Enlist
-    {
-      get
-      {
-        if (ContainsKey("Enlist") == false) return true;
-
-        return (this["Enlist"].ToString() == "Y");
-      }
-      set
-      {
-        this["Enlist"] = (value == true) ? "Y" : "N";
-      }
-    }
-    /// <summary>
-    /// Gets/sets the database encryption password
-    /// </summary>
-    [Browsable(true)]
-    [PasswordPropertyText(true)]
-    public string Password
-    {
-      get
-      {
-        if (ContainsKey("Password") == false) return "";
-
-        return this["Password"].ToString();
-      }
-      set
-      {
-        this["Password"] = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets/Sets the page size for the connection.
-    /// </summary>
-    [DisplayName("Page Size")]
-    [Browsable(true)]
-    [DefaultValue(1024)]
-    public int PageSize
-    {
-      get
-      {
-        if (ContainsKey("Page Size") == false) return 1024;
-        return Convert.ToInt32(this["Page Size"], CultureInfo.InvariantCulture);
-      }
-      set
-      {
-        this["Page Size"] = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets/Sets the cache size for the connection.
-    /// </summary>
-    [DisplayName("Cache Size")]
-    [Browsable(true)]
-    [DefaultValue(2000)]
-    public int CacheSize
-    {
-      get
-      {
-        if (ContainsKey("Cache Size") == false) return 2000;
-        return Convert.ToInt32(this["Cache Size"], CultureInfo.InvariantCulture);
-      }
-      set
-      {
-        this["Cache Size"] = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets/Sets the datetime format for the connection.
-    /// </summary>
-    [Browsable(true)]
-    [DefaultValue(SqliteDateFormats.ISO8601)]
-    public SqliteDateFormats DateTimeFormat
-    {
-      get
-      {
-        if (ContainsKey("DateTimeFormat") == false) return SqliteDateFormats.ISO8601;
-
-        return (SqliteDateFormats)TypeDescriptor.GetConverter(typeof(SqliteDateFormats)).ConvertFrom(this["DateTimeFormat"]);
-      }
-      set
-      {
-        this["DateTimeFormat"] = value;
-      }
-    }
-
-    /// <summary>
-    /// Helper function for retrieving values from the connectionstring
-    /// </summary>
-    /// <param name="keyword">The keyword to retrieve settings for</param>
-    /// <param name="value">The resulting parameter value</param>
-    /// <returns>Returns true if the value was found and returned</returns>
-    public override bool TryGetValue(string keyword, out object value)
-    {
-      bool b = base.TryGetValue(keyword, out value);
-
-      if (!_properties.ContainsKey(keyword)) return b;
-
-      PropertyDescriptor pd = _properties[keyword] as PropertyDescriptor;
-
-      if (pd == null) return b;
-
-      if (b)
-      {
-        value = TypeDescriptor.GetConverter(pd.PropertyType).ConvertFrom(value);
-      }
-      else
-      {
-        DefaultValueAttribute att = pd.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;
-        if (att != null)
-        {
-          value = att.Value;
-          b = true;
-        }
-      }
-      return b;
-    }
-  }
-#endif
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data.Common;\r
+  using System.ComponentModel;\r
+  using System.Collections;\r
+  using System.Globalization;\r
+  using System.Reflection;\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  using System.ComponentModel.Design;\r
+\r
+  /// <summary>\r
+  /// SQLite implementation of DbConnectionStringBuilder.\r
+  /// </summary>\r
+  [DefaultProperty("DataSource")]\r
+  [DefaultMember("Item")]\r
+  public sealed class SQLiteConnectionStringBuilder : DbConnectionStringBuilder\r
+  {\r
+    /// <summary>\r
+    /// Properties of this class\r
+    /// </summary>\r
+    private Hashtable _properties;\r
+\r
+    /// <overloads>\r
+    /// Constructs a new instance of the class\r
+    /// </overloads>\r
+    /// <summary>\r
+    /// Default constructor\r
+    /// </summary>\r
+    public SQLiteConnectionStringBuilder()\r
+    {\r
+      Initialize(null);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a new instance of the class using the specified connection string.\r
+    /// </summary>\r
+    /// <param name="connectionString">The connection string to parse</param>\r
+    public SQLiteConnectionStringBuilder(string connectionString)\r
+    {\r
+      Initialize(connectionString);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Private initializer, which assigns the connection string and resets the builder\r
+    /// </summary>\r
+    /// <param name="cnnString">The connection string to assign</param>\r
+    private void Initialize(string cnnString)\r
+    {\r
+      _properties = new Hashtable(StringComparer.InvariantCultureIgnoreCase);\r
+      try\r
+      {\r
+        base.GetProperties(_properties);\r
+      }\r
+      catch(NotImplementedException)\r
+      {\r
+        FallbackGetProperties(_properties);\r
+      }\r
+\r
+      if (String.IsNullOrEmpty(cnnString) == false)\r
+        ConnectionString = cnnString;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/Sets the default version of the SQLite engine to instantiate.  Currently the only valid value is 3, indicating version 3 of the sqlite library.\r
+    /// </summary>\r
+    [Browsable(true)]\r
+    [DefaultValue(3)]\r
+    public int Version\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("version", out value);\r
+        return Convert.ToInt32(value, CultureInfo.CurrentCulture);\r
+      }\r
+      set\r
+      {\r
+        if (value != 3)\r
+          throw new NotSupportedException();\r
+\r
+        this["version"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/Sets the synchronization mode (file flushing) of the connection string.  Default is "Normal".\r
+    /// </summary>\r
+    [DisplayName("Synchronous")]\r
+    [Browsable(true)]\r
+    [DefaultValue(SynchronizationModes.Normal)]\r
+    public SynchronizationModes SyncMode\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("synchronous", out value);\r
+        if (value is string)\r
+          return (SynchronizationModes)TypeDescriptor.GetConverter(typeof(SynchronizationModes)).ConvertFrom(value);\r
+        else return (SynchronizationModes)value;\r
+      }\r
+      set\r
+      {\r
+        this["synchronous"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/Sets the encoding for the connection string.  The default is "False" which indicates UTF-8 encoding.\r
+    /// </summary>\r
+    [Browsable(true)]\r
+    [DefaultValue(false)]\r
+    public bool UseUTF16Encoding\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("useutf16encoding", out value);\r
+        return SQLiteConvert.ToBoolean(value);\r
+      }\r
+      set\r
+      {\r
+        this["useutf16encoding"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/Sets whether or not to use connection pooling.  The default is "False"\r
+    /// </summary>\r
+    [Browsable(true)]\r
+    [DefaultValue(false)]\r
+    public bool Pooling\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("pooling", out value);\r
+        return SQLiteConvert.ToBoolean(value);\r
+      }\r
+      set\r
+      {\r
+        this["pooling"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/Sets whethor not to store GUID's in binary format.  The default is True\r
+    /// which saves space in the database.\r
+    /// </summary>\r
+    [Browsable(true)]\r
+    [DefaultValue(true)]\r
+    public bool BinaryGUID\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("binaryguid", out value);\r
+        return SQLiteConvert.ToBoolean(value);\r
+      }\r
+      set\r
+      {\r
+        this["binaryguid"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/Sets the filename to open on the connection string.\r
+    /// </summary>\r
+    [DisplayName("Data Source")]\r
+    [Browsable(true)]\r
+    [DefaultValue("")]\r
+    public string DataSource\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("data source", out value);\r
+        return value.ToString();\r
+      }\r
+      set\r
+      {\r
+        this["data source"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// An alternate to the data source property\r
+    /// </summary>\r
+    [Browsable(false)]\r
+    public string Uri\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("uri", out value);\r
+        return value.ToString();\r
+      }\r
+      set\r
+      {\r
+        this["uri"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/sets the default command timeout for newly-created commands.  This is especially useful for \r
+    /// commands used internally such as inside a SQLiteTransaction, where setting the timeout is not possible.\r
+    /// </summary>\r
+    [DisplayName("Default Timeout")]\r
+    [Browsable(true)]\r
+    [DefaultValue(30)]\r
+    public int DefaultTimeout\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("default timeout", out value);\r
+        return Convert.ToInt32(value, CultureInfo.CurrentCulture);\r
+      }\r
+      set\r
+      {\r
+        this["default timeout"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Determines whether or not the connection will automatically participate\r
+    /// in the current distributed transaction (if one exists)\r
+    /// </summary>\r
+    [Browsable(true)]\r
+    [DefaultValue(true)]\r
+    public bool Enlist\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("enlist", out value);\r
+        return SQLiteConvert.ToBoolean(value);\r
+      }\r
+      set\r
+      {\r
+        this["enlist"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// If set to true, will throw an exception if the database specified in the connection\r
+    /// string does not exist.  If false, the database will be created automatically.\r
+    /// </summary>\r
+    [Browsable(true)]\r
+    [DefaultValue(false)]\r
+    public bool FailIfMissing\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("failifmissing", out value);\r
+        return SQLiteConvert.ToBoolean(value);\r
+      }\r
+      set\r
+      {\r
+        this["failifmissing"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// If enabled, uses the legacy 3.xx format for maximum compatibility, but results in larger\r
+    /// database sizes.\r
+    /// </summary>\r
+    [DisplayName("Legacy Format")]\r
+    [Browsable(true)]\r
+    [DefaultValue(false)]\r
+    public bool LegacyFormat\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("legacy format", out value);\r
+        return SQLiteConvert.ToBoolean(value);\r
+      }\r
+      set\r
+      {\r
+        this["legacy format"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// When enabled, the database will be opened for read-only access and writing will be disabled.\r
+    /// </summary>\r
+    [DisplayName("Read Only")]\r
+    [Browsable(true)]\r
+    [DefaultValue(false)]\r
+    public bool ReadOnly\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("read only", out value);\r
+        return SQLiteConvert.ToBoolean(value);\r
+      }\r
+      set\r
+      {\r
+        this["read only"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/sets the database encryption password\r
+    /// </summary>\r
+    [Browsable(true)]\r
+    [PasswordPropertyText(true)]\r
+    [DefaultValue("")]\r
+    public string Password\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("password", out value);\r
+        return value.ToString();\r
+      }\r
+      set\r
+      {\r
+        this["password"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/Sets the page size for the connection.\r
+    /// </summary>\r
+    [DisplayName("Page Size")]\r
+    [Browsable(true)]\r
+    [DefaultValue(1024)]\r
+    public int PageSize\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("page size", out value);\r
+        return Convert.ToInt32(value, CultureInfo.CurrentCulture);\r
+      }\r
+      set\r
+      {\r
+        this["page size"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/Sets the maximum number of pages the database may hold\r
+    /// </summary>\r
+    [DisplayName("Max Page Count")]\r
+    [Browsable(true)]\r
+    [DefaultValue(0)]\r
+    public int MaxPageCount\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("max page count", out value);\r
+        return Convert.ToInt32(value, CultureInfo.CurrentCulture);\r
+      }\r
+      set\r
+      {\r
+        this["max page count"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/Sets the cache size for the connection.\r
+    /// </summary>\r
+    [DisplayName("Cache Size")]\r
+    [Browsable(true)]\r
+    [DefaultValue(2000)]\r
+    public int CacheSize\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("cache size", out value);\r
+        return Convert.ToInt32(value, CultureInfo.CurrentCulture);\r
+      }\r
+      set\r
+      {\r
+        this["cache size"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/Sets the datetime format for the connection.\r
+    /// </summary>\r
+    [Browsable(true)]\r
+    [DefaultValue(SQLiteDateFormats.ISO8601)]\r
+    public SQLiteDateFormats DateTimeFormat\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("datetimeformat", out value);\r
+        if (value is string)\r
+          return (SQLiteDateFormats)TypeDescriptor.GetConverter(typeof(SQLiteDateFormats)).ConvertFrom(value);\r
+        else return (SQLiteDateFormats)value;\r
+      }\r
+      set\r
+      {\r
+        this["datetimeformat"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Determines how SQLite handles the transaction journal file.\r
+    /// </summary>\r
+    [Browsable(true)]\r
+    [DefaultValue(SQLiteJournalModeEnum.Delete)]\r
+    [DisplayName("Journal Mode")]\r
+    public SQLiteJournalModeEnum JournalMode\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("journal mode", out value);\r
+        if (value is string)\r
+          return (SQLiteJournalModeEnum)TypeDescriptor.GetConverter(typeof(SQLiteJournalModeEnum)).ConvertFrom(value);\r
+        else\r
+          return (SQLiteJournalModeEnum)value;\r
+      }\r
+      set\r
+      {\r
+        this["journal mode"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Sets the default isolation level for transactions on the connection.\r
+    /// </summary>\r
+    [Browsable(true)]\r
+    [DefaultValue(IsolationLevel.Serializable)]\r
+    [DisplayName("Default Isolation Level")]\r
+    public IsolationLevel DefaultIsolationLevel\r
+    {\r
+      get\r
+      {\r
+        object value;\r
+        TryGetValue("default isolationlevel", out value);\r
+        if (value is string)\r
+          return (IsolationLevel)TypeDescriptor.GetConverter(typeof(IsolationLevel)).ConvertFrom(value);\r
+        else\r
+          return (IsolationLevel)value;\r
+      }\r
+      set\r
+      {\r
+        this["default isolationlevel"] = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Helper function for retrieving values from the connectionstring\r
+    /// </summary>\r
+    /// <param name="keyword">The keyword to retrieve settings for</param>\r
+    /// <param name="value">The resulting parameter value</param>\r
+    /// <returns>Returns true if the value was found and returned</returns>\r
+    public override bool TryGetValue(string keyword, out object value)\r
+    {\r
+      bool b = base.TryGetValue(keyword, out value);\r
+\r
+      if (!_properties.ContainsKey(keyword)) return b;\r
+\r
+      PropertyDescriptor pd = _properties[keyword] as PropertyDescriptor;\r
+\r
+      if (pd == null) return b;\r
+\r
+      // Attempt to coerce the value into something more solid\r
+      if (b)\r
+      {\r
+        if (pd.PropertyType == typeof(Boolean))\r
+          value = SQLiteConvert.ToBoolean(value);\r
+        else\r
+          value = TypeDescriptor.GetConverter(pd.PropertyType).ConvertFrom(value);\r
+      }\r
+      else\r
+      {\r
+        DefaultValueAttribute att = pd.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;\r
+        if (att != null)\r
+        {\r
+          value = att.Value;\r
+          b = true;\r
+        }\r
+      }\r
+      return b;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Fallback method for MONO, which doesn't implement DbConnectionStringBuilder.GetProperties()\r
+    /// </summary>\r
+    /// <param name="propertyList">The hashtable to fill with property descriptors</param>\r
+    private void FallbackGetProperties(Hashtable propertyList)\r
+    {\r
+      foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(this, true))\r
+      {\r
+        if (descriptor.Name != "ConnectionString" && propertyList.ContainsKey(descriptor.DisplayName) == false)\r
+        {\r
+          propertyList.Add(descriptor.DisplayName, descriptor);\r
+        }\r
+      }\r
+    }\r
+  }\r
+#endif\r
+}\r
index 92d2fee1707705a2bcdb756dd57a10177f202ada..802cfbae8862b9659b43d8bcbd9b93a3145622c2 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteConvert.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Runtime.InteropServices;
-  using System.Collections.Generic;
-  using System.ComponentModel;
-  using System.Globalization;
-  using System.Text;
-
-#if !PLATFORM_COMPACTFRAMEWORK 
-  using System.ComponentModel.Design;
-#endif
-
-  /// <summary>
-  /// Sqlite has very limited types, and is inherently text-based.  The first 5 types below represent the sum of all types Sqlite
-  /// understands.  The DateTime extension to the spec is for internal use only.
-  /// </summary>
-  public enum TypeAffinity
-  {
-    /// <summary>
-    /// Not used
-    /// </summary>
-    Uninitialized = 0,
-    /// <summary>
-    /// All integers in Sqlite default to Int64
-    /// </summary>
-    Int64 = 1,
-    /// <summary>
-    /// All floating point numbers in Sqlite default to double
-    /// </summary>
-    Double = 2,
-    /// <summary>
-    /// The default data type of Sqlite is text
-    /// </summary>
-    Text = 3,
-    /// <summary>
-    /// Typically blob types are only seen when returned from a function
-    /// </summary>
-    Blob = 4,
-    /// <summary>
-    /// Null types can be returned from functions
-    /// </summary>
-    Null = 5,
-    /// <summary>
-    /// Used internally by this provider
-    /// </summary>
-    DateTime = 10,
-    /// <summary>
-    /// Used internally
-    /// </summary>
-    None = 11,
-  }
-
-  /// <summary>
-  /// This implementation of Sqlite for ADO.NET can process date/time fields in databases in only one of two formats.  Ticks and ISO8601.
-  /// Ticks is inherently more accurate, but less compatible with 3rd party tools that query the database, and renders the DateTime field
-  /// unreadable without post-processing.
-  /// ISO8601 is more compatible, readable, fully-processable, but less accurate as it doesn't provide time down to fractions of a second.
-  /// </summary>
-  public enum SqliteDateFormats
-  {
-    /// <summary>
-    /// Using ticks is more accurate but less compatible with other viewers and utilities that access your database.
-    /// </summary>
-    Ticks = 0,
-    /// <summary>
-    /// The default format for this provider.
-    /// </summary>
-    ISO8601 = 1,
-  }
-
-  /// <summary>
-  /// Struct used internally to determine the datatype of a column in a resultset
-  /// </summary>
-  internal struct SqliteType
-  {
-    /// <summary>
-    /// The DbType of the column, or DbType.Object if it cannot be determined
-    /// </summary>
-    internal DbType Type;
-    /// <summary>
-    /// The affinity of a column, used for expressions or when Type is DbType.Object
-    /// </summary>
-    internal TypeAffinity Affinity;
-  }
-
-  internal struct SqliteTypeNames
-  {
-    internal SqliteTypeNames(string newtypeName, DbType newdataType)
-    {
-      typeName = newtypeName;
-      dataType = newdataType;
-    }
-
-    internal string typeName;
-    internal DbType dataType;
-  }
-
-  /// <summary>
-  /// This base class provides datatype conversion services for the Sqlite provider.
-  /// </summary>
-  public abstract class SqliteConvert
-  {
-    /// <summary>
-    /// An array of ISO8601 datetime formats we support conversion from
-    /// </summary>
-    private static string[] _datetimeFormats = new string[] {
-      "yyyy-MM-dd HH:mm:ss.fffffff",
-      "yyyy-MM-dd HH:mm:ss",
-      "yyyy-MM-dd HH:mm",                               
-      "yyyyMMddHHmmss",
-      "yyyyMMddHHmm",
-      "yyyyMMddTHHmmssfffffff",
-      "yyyy-MM-dd",
-      "yy-MM-dd",
-      "yyyyMMdd",
-      "HH:mm:ss",
-      "HH:mm",
-      "THHmmss",
-      "THHmm",
-      "yyyy-MM-dd HH:mm:ss.fff",
-      "yyyy-MM-ddTHH:mm",
-      "yyyy-MM-ddTHH:mm:ss",
-      "yyyy-MM-ddTHH:mm:ss.fff",
-      "yyyy-MM-ddTHH:mm:ss.ffffff",
-      "HH:mm:ss.fff"
-    };
-
-    /// <summary>
-    /// An UTF-8 Encoding instance, so we can convert strings to and from UTF-8
-    /// </summary>
-    private Encoding _utf8 = new UTF8Encoding();
-    /// <summary>
-    /// The default DateTime format for this instance
-    /// </summary>
-    internal SqliteDateFormats _datetimeFormat;
-    /// <summary>
-    /// Initializes the conversion class
-    /// </summary>
-    /// <param name="fmt">The default date/time format to use for this instance</param>
-    internal SqliteConvert(SqliteDateFormats fmt)
-    {
-      _datetimeFormat = fmt;
-    }
-
-    #region UTF-8 Conversion Functions
-    /// <summary>
-    /// Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character.
-    /// </summary>
-    /// <param name="sourceText">The string to convert to UTF-8</param>
-    /// <returns>A byte array containing the converted string plus an extra 0 terminating byte at the end of the array.</returns>
-    public byte[] ToUTF8(string sourceText)
-    {
-      Byte[] byteArray;
-      int nlen = _utf8.GetByteCount(sourceText) + 1;
-
-      byteArray = new byte[nlen];
-      nlen = _utf8.GetBytes(sourceText, 0, sourceText.Length, byteArray, 0);
-      byteArray[nlen] = 0;
-
-      return byteArray;
-    }
-
-    /// <summary>
-    /// Convert a DateTime to a UTF-8 encoded, zero-terminated byte array.
-    /// </summary>
-    /// <remarks>
-    /// This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the
-    /// string result.
-    /// </remarks>
-    /// <param name="dateTimeValue">The DateTime to convert.</param>
-    /// <returns>The UTF-8 encoded string, including a 0 terminating byte at the end of the array.</returns>
-    public byte[] ToUTF8(DateTime dateTimeValue)
-    {
-      return ToUTF8(ToString(dateTimeValue));
-    }
-
-    /// <summary>
-    /// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string
-    /// </summary>
-    /// <param name="nativestring">The pointer to the memory where the UTF-8 string is encoded</param>
-    /// <param name="nativestringlen">The number of bytes to decode</param>
-    /// <returns>A string containing the translated character(s)</returns>
-    public virtual string ToString(IntPtr nativestring)
-    {
-      return UTF8ToString(nativestring);
-    }
-
-    /// <summary>
-    /// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string
-    /// </summary>
-    /// <param name="nativestring">The pointer to the memory where the UTF-8 string is encoded</param>
-    /// <param name="nativestringlen">The number of bytes to decode</param>
-    /// <returns>A string containing the translated character(s)</returns>
-    public virtual string UTF8ToString(IntPtr nativestring)
-    {
-      if (nativestring == IntPtr.Zero)
-        return null;
-    
-      // This assumes a single byte terminates the string.
-
-      int len = 0;
-      while (Marshal.ReadByte (nativestring, len) != 0)
-        checked {++len;}
-\r
-      unsafe { \r
-        string s = new string ((sbyte*) nativestring, 0, len, _utf8);
-        len = s.Length;
-        while (len > 0 && s [len-1] == 0)
-          --len;
-        if (len == s.Length) 
-          return s;
-        return s.Substring (0, len);\r
-      }
-    }
-
-
-    #endregion
-
-    #region DateTime Conversion Functions
-    /// <summary>
-    /// Converts a string into a DateTime, using the current DateTimeFormat specified for the connection when it was opened.
-    /// </summary>
-    /// <remarks>
-    /// Acceptable ISO8601 DateTime formats are:
-    ///   yyyy-MM-dd HH:mm:ss
-    ///   yyyyMMddHHmmss
-    ///   yyyyMMddTHHmmssfffffff
-    ///   yyyy-MM-dd
-    ///   yy-MM-dd
-    ///   yyyyMMdd
-    ///   HH:mm:ss
-    ///   THHmmss
-    /// </remarks>
-    /// <param name="dateText">The string containing either a Tick value or an ISO8601-format string</param>
-    /// <returns>A DateTime value</returns>
-    public DateTime ToDateTime(string dateText)
-    {
-      switch (_datetimeFormat)
-      {
-        case SqliteDateFormats.Ticks:
-          return new DateTime(Convert.ToInt64(dateText, CultureInfo.InvariantCulture));
-        default:
-          return DateTime.ParseExact(dateText, _datetimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);
-      }
-    }
-
-    /// <summary>
-    /// Converts a DateTime to a string value, using the current DateTimeFormat specified for the connection when it was opened.
-    /// </summary>
-    /// <param name="dateValue">The DateTime value to convert</param>
-    /// <returns>Either a string consisting of the tick count for DateTimeFormat.Ticks, or a date/time in ISO8601 format.</returns>
-    public string ToString(DateTime dateValue)
-    {
-      switch (_datetimeFormat)
-      {
-        case SqliteDateFormats.Ticks:
-          return dateValue.Ticks.ToString(CultureInfo.InvariantCulture);
-        default:
-          return dateValue.ToString(_datetimeFormats[0], CultureInfo.InvariantCulture);
-      }
-    }
-
-    /// <summary>
-    /// Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime.
-    /// </summary>
-    /// <remarks>
-    /// This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls
-    /// ToDateTime() on the string to return a DateTime.
-    /// </remarks>
-    /// <param name="ptr">A pointer to the UTF-8 encoded string</param>
-    /// <param name="len">The length in bytes of the string</param>
-    /// <returns>The parsed DateTime value</returns>
-    internal DateTime ToDateTime(IntPtr ptr)
-    {
-      return ToDateTime(ToString(ptr));
-    }
-    #endregion
-
-    /// <summary>
-    /// Smart method of splitting a string.  Skips quoted elements, removes the quotes.
-    /// </summary>
-    /// <remarks>
-    /// This split function works somewhat like the String.Split() function in that it breaks apart a string into
-    /// pieces and returns the pieces as an array.  The primary differences are:
-    /// <list type="bullet">
-    /// <item><description>Only one character can be provided as a separator character</description></item>
-    /// <item><description>Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed.</description></item>
-    /// </list>
-    /// Thus, if splitting the following string looking for a comma:<br/>
-    /// One,Two, "Three, Four", Five<br/>
-    /// <br/>
-    /// The resulting array would contain<br/>
-    /// [0] One<br/>
-    /// [1] Two<br/>
-    /// [2] Three, Four<br/>
-    /// [3] Five<br/>
-    /// <br/>
-    /// Note that the leading and trailing spaces were removed from each item during the split.
-    /// </remarks>
-    /// <param name="source">Source string to split apart</param>
-    /// <param name="separator">Separator character</param>
-    /// <returns>A string array of the split up elements</returns>
-    public static string[] Split(string source, char separator)
-    {
-      char[] toks = new char[2] { '\"', separator };
-      char[] quot = new char[1] { '\"' };
-      int n = 0;
-      List<string> ls = new List<string>();
-      string s;
-
-      while (source.Length > 0)
-      {
-        n = source.IndexOfAny(toks, n);
-        if (n == -1) break;
-        if (source[n] == toks[0])
-        {
-          source = source.Remove(n, 1);
-          n = source.IndexOfAny(quot, n);
-          if (n == -1)
-          {
-            source = "\"" + source;
-            break;
-          }
-          source = source.Remove(n, 1);
-        }
-        else
-        {
-          s = source.Substring(0, n).Trim();
-          source = source.Substring(n + 1).Trim();
-          if (s.Length > 0) ls.Add(s);
-          n = 0;
-        }
-      }
-      if (source.Length > 0) ls.Add(source);
-
-      string[] ar = new string[ls.Count];
-      ls.CopyTo(ar, 0);
-
-      return ar;
-    }
-
-    #region Type Conversions
-    /// <summary>
-    /// Determines the data type of a column in a statement
-    /// </summary>
-    /// <param name="stmt">The statement to retrieve information for</param>
-    /// <param name="i">The column to retrieve type information on</param>
-    /// <returns>Returns a SqliteType struct</returns>
-    internal static SqliteType ColumnToType(SqliteStatement stmt, int i)
-    {
-      SqliteType typ;
-
-      typ.Type = TypeNameToDbType(stmt._sql.ColumnType(stmt, i, out typ.Affinity));
-
-      return typ;
-    }
-
-    /// <summary>
-    /// Converts a SqliteType to a .NET Type object
-    /// </summary>
-    /// <param name="t">The SqliteType to convert</param>
-    /// <returns>Returns a .NET Type object</returns>
-    internal static Type SqliteTypeToType(SqliteType t)
-    {
-      if (t.Type != DbType.Object)
-        return SqliteConvert.DbTypeToType(t.Type);
-
-      return _typeaffinities[(int)t.Affinity];
-    }
-
-    static Type[] _typeaffinities = {
-      null,
-      typeof(Int64),
-      typeof(Double),
-      typeof(string),
-      typeof(byte[]),
-      typeof(DBNull),
-      null,
-      null,
-      null,
-      null,
-      typeof(DateTime),
-      null,
-    };
-
-    /// <summary>
-    /// For a given intrinsic type, return a DbType
-    /// </summary>
-    /// <param name="typ">The native type to convert</param>
-    /// <returns>The corresponding (closest match) DbType</returns>
-    internal static DbType TypeToDbType(Type typ)
-    {
-      TypeCode tc = Type.GetTypeCode(typ);
-      if (tc == TypeCode.Object)
-      {
-        if (typ == typeof(byte[])) return DbType.Binary;
-        if (typ == typeof(Guid)) return DbType.Guid;
-        return DbType.String;
-      }
-      return _typetodbtype[(int)tc];
-    }
-
-    private static DbType[] _typetodbtype = {
-      DbType.Object,
-      DbType.Binary,
-      DbType.Object,
-      DbType.Boolean,
-      DbType.SByte,
-      DbType.SByte,
-      DbType.Byte,
-      DbType.Int16, // 7
-      DbType.UInt16,
-      DbType.Int32,
-      DbType.UInt32,
-      DbType.Int64, // 11
-      DbType.UInt64,
-      DbType.Single,
-      DbType.Double,
-      DbType.Decimal,
-      DbType.DateTime,
-      DbType.Object,
-      DbType.String,
-    };
-
-    /// <summary>
-    /// Returns the ColumnSize for the given DbType
-    /// </summary>
-    /// <param name="typ">The DbType to get the size of</param>
-    /// <returns></returns>
-    internal static int DbTypeToColumnSize(DbType typ)
-    {
-      return _dbtypetocolumnsize[(int)typ];
-    }
-
-    private static int[] _dbtypetocolumnsize = {
-      2147483647,   // 0
-      2147483647,   // 1
-      1,     // 2
-      1,     // 3
-      8,  // 4
-      8, // 5
-      8, // 6
-      8,  // 7
-      8,   // 8
-      16,     // 9
-      2,
-      4,
-      8,
-      2147483647,
-      1,
-      4,
-      2147483647,
-      8,
-      2,
-      4,
-      8,
-      8,
-      2147483647,
-      2147483647,
-      2147483647,
-      2147483647,   // 25 (Xml)
-    };
-
-    /// <summary>
-    /// Convert a DbType to a Type
-    /// </summary>
-    /// <param name="typ">The DbType to convert from</param>
-    /// <returns>The closest-match .NET type</returns>
-    internal static Type DbTypeToType(DbType typ)
-    {
-      return _dbtypeToType[(int)typ];
-    }
-
-    private static Type[] _dbtypeToType = {
-      typeof(string),   // 0
-      typeof(byte[]),   // 1
-      typeof(byte),     // 2
-      typeof(bool),     // 3
-      typeof(decimal),  // 4
-      typeof(DateTime), // 5
-      typeof(DateTime), // 6
-      typeof(decimal),  // 7
-      typeof(double),   // 8
-      typeof(Guid),     // 9
-      typeof(Int16),
-      typeof(Int32),
-      typeof(Int64),
-      typeof(object),
-      typeof(sbyte),
-      typeof(float),
-      typeof(string),
-      typeof(DateTime),
-      typeof(UInt16),
-      typeof(UInt32),
-      typeof(UInt64),
-      typeof(double),
-      typeof(string),
-      typeof(string),
-      typeof(string),
-      typeof(string),   // 25 (Xml)
-    };
-
-    /// <summary>
-    /// For a given type, return the closest-match Sqlite TypeAffinity, which only understands a very limited subset of types.
-    /// </summary>
-    /// <param name="typ">The type to evaluate</param>
-    /// <returns>The Sqlite type affinity for that type.</returns>
-    internal static TypeAffinity TypeToAffinity(Type typ)
-    {
-      TypeCode tc = Type.GetTypeCode(typ);
-      if (tc == TypeCode.Object)
-      {
-        if (typ == typeof(byte[]) || typ == typeof(Guid))
-          return TypeAffinity.Blob;
-        else
-          return TypeAffinity.Text;
-      }
-      return _typecodeAffinities[(int)tc];
-    }
-
-    private static TypeAffinity[] _typecodeAffinities = {
-      TypeAffinity.Null,
-      TypeAffinity.Blob,
-      TypeAffinity.Null,
-      TypeAffinity.Int64,
-      TypeAffinity.Int64,
-      TypeAffinity.Int64,
-      TypeAffinity.Int64,
-      TypeAffinity.Int64, // 7
-      TypeAffinity.Int64,
-      TypeAffinity.Int64,
-      TypeAffinity.Int64,
-      TypeAffinity.Int64, // 11
-      TypeAffinity.Int64,
-      TypeAffinity.Double,
-      TypeAffinity.Double,
-      TypeAffinity.Double,
-      TypeAffinity.DateTime,
-      TypeAffinity.Null,
-      TypeAffinity.Text,
-    };
-
-    /// <summary>
-    /// For a given type name, return a closest-match .NET type
-    /// </summary>
-    /// <param name="Name">The name of the type to match</param>
-    /// <returns>The .NET DBType the text evaluates to.</returns>
-    internal static DbType TypeNameToDbType(string Name)
-    {
-      if (String.IsNullOrEmpty(Name)) return DbType.Object;
-
-      int x = _typeNames.Length;
-      for (int n = 0; n < x; n++)
-      {
-        if (String.Compare(Name, 0, _typeNames[n].typeName, 0, _typeNames[n].typeName.Length, true, CultureInfo.InvariantCulture) == 0)
-          return _typeNames[n].dataType; 
-      }
-      return DbType.Object;
-    }
-    #endregion
-
-    private static SqliteTypeNames[] _typeNames = {
-      new SqliteTypeNames("COUNTER", DbType.Int64),
-      new SqliteTypeNames("AUTOINCREMENT", DbType.Int64),
-      new SqliteTypeNames("IDENTITY", DbType.Int64),
-      new SqliteTypeNames("LONGTEXT", DbType.String),
-      new SqliteTypeNames("LONGCHAR", DbType.String),
-      new SqliteTypeNames("LONGVARCHAR", DbType.String),
-      new SqliteTypeNames("LONG", DbType.Int64),
-      new SqliteTypeNames("TINYINT", DbType.Byte),
-      new SqliteTypeNames("INTEGER", DbType.Int64),
-      new SqliteTypeNames("INT", DbType.Int32),
-      new SqliteTypeNames("VARCHAR", DbType.String),
-      new SqliteTypeNames("NVARCHAR", DbType.String),
-      new SqliteTypeNames("CHAR", DbType.String),
-      new SqliteTypeNames("NCHAR", DbType.String),
-      new SqliteTypeNames("TEXT", DbType.String),
-      new SqliteTypeNames("NTEXT", DbType.String),
-      new SqliteTypeNames("STRING", DbType.String),
-      new SqliteTypeNames("DOUBLE", DbType.Double),
-      new SqliteTypeNames("FLOAT", DbType.Double),
-      new SqliteTypeNames("REAL", DbType.Single),          
-      new SqliteTypeNames("BIT", DbType.Boolean),
-      new SqliteTypeNames("YESNO", DbType.Boolean),
-      new SqliteTypeNames("LOGICAL", DbType.Boolean),
-      new SqliteTypeNames("BOOL", DbType.Boolean),
-      new SqliteTypeNames("NUMERIC", DbType.Decimal),
-      new SqliteTypeNames("DECIMAL", DbType.Decimal),
-      new SqliteTypeNames("MONEY", DbType.Decimal),
-      new SqliteTypeNames("CURRENCY", DbType.Decimal),
-      new SqliteTypeNames("TIME", DbType.DateTime),
-      new SqliteTypeNames("DATE", DbType.DateTime),
-      new SqliteTypeNames("SMALLDATE", DbType.DateTime),
-      new SqliteTypeNames("BLOB", DbType.Binary),
-      new SqliteTypeNames("BINARY", DbType.Binary),
-      new SqliteTypeNames("VARBINARY", DbType.Binary),
-      new SqliteTypeNames("IMAGE", DbType.Binary),
-      new SqliteTypeNames("GENERAL", DbType.Binary),
-      new SqliteTypeNames("OLEOBJECT", DbType.Binary),
-      new SqliteTypeNames("GUID", DbType.Guid),
-      new SqliteTypeNames("UNIQUEIDENTIFIER", DbType.Guid),
-      new SqliteTypeNames("MEMO", DbType.String),
-      new SqliteTypeNames("NOTE", DbType.String),
-      new SqliteTypeNames("SMALLINT", DbType.Int16),
-      new SqliteTypeNames("BIGINT", DbType.Int64),
-    };
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Runtime.InteropServices;\r
+  using System.Collections.Generic;\r
+  using System.ComponentModel;\r
+  using System.Globalization;\r
+  using System.Text;\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK \r
+  using System.ComponentModel.Design;\r
+#endif\r
+\r
+  /// <summary>\r
+  /// This base class provides datatype conversion services for the SQLite provider.\r
+  /// </summary>\r
+  public abstract class SQLiteConvert\r
+  {\r
+    /// <summary>\r
+    /// An array of ISO8601 datetime formats we support conversion from\r
+    /// </summary>\r
+    private static string[] _datetimeFormats = new string[] {\r
+      "THHmmss",\r
+      "THHmm",\r
+      "HH:mm:ss",\r
+      "HH:mm",\r
+      "HH:mm:ss.FFFFFFF",\r
+      "yy-MM-dd",\r
+      "yyyy-MM-dd",\r
+      "yyyy-MM-dd HH:mm:ss.FFFFFFF",\r
+      "yyyy-MM-dd HH:mm:ss",\r
+      "yyyy-MM-dd HH:mm",                               \r
+      "yyyy-MM-ddTHH:mm:ss.FFFFFFF",\r
+      "yyyy-MM-ddTHH:mm",\r
+      "yyyy-MM-ddTHH:mm:ss",\r
+      "yyyyMMddHHmmss",\r
+      "yyyyMMddHHmm",\r
+      "yyyyMMddTHHmmssFFFFFFF",\r
+      "yyyyMMdd"\r
+    };\r
+\r
+    /// <summary>\r
+    /// An UTF-8 Encoding instance, so we can convert strings to and from UTF-8\r
+    /// </summary>\r
+    private static Encoding _utf8 = new UTF8Encoding();\r
+    /// <summary>\r
+    /// The default DateTime format for this instance\r
+    /// </summary>\r
+    internal SQLiteDateFormats _datetimeFormat;\r
+    /// <summary>\r
+    /// Initializes the conversion class\r
+    /// </summary>\r
+    /// <param name="fmt">The default date/time format to use for this instance</param>\r
+    internal SQLiteConvert(SQLiteDateFormats fmt)\r
+    {\r
+      _datetimeFormat = fmt;\r
+    }\r
+\r
+    #region UTF-8 Conversion Functions\r
+    /// <summary>\r
+    /// Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character.\r
+    /// </summary>\r
+    /// <param name="sourceText">The string to convert to UTF-8</param>\r
+    /// <returns>A byte array containing the converted string plus an extra 0 terminating byte at the end of the array.</returns>\r
+    public static byte[] ToUTF8(string sourceText)\r
+    {\r
+      Byte[] byteArray;\r
+      int nlen = _utf8.GetByteCount(sourceText) + 1;\r
+\r
+      byteArray = new byte[nlen];\r
+      nlen = _utf8.GetBytes(sourceText, 0, sourceText.Length, byteArray, 0);\r
+      byteArray[nlen] = 0;\r
+\r
+      return byteArray;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Convert a DateTime to a UTF-8 encoded, zero-terminated byte array.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the\r
+    /// string result.\r
+    /// </remarks>\r
+    /// <param name="dateTimeValue">The DateTime to convert.</param>\r
+    /// <returns>The UTF-8 encoded string, including a 0 terminating byte at the end of the array.</returns>\r
+    public byte[] ToUTF8(DateTime dateTimeValue)\r
+    {\r
+      return ToUTF8(ToString(dateTimeValue));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string\r
+    /// </summary>\r
+    /// <param name="nativestring">The pointer to the memory where the UTF-8 string is encoded</param>\r
+    /// <param name="nativestringlen">The number of bytes to decode</param>\r
+    /// <returns>A string containing the translated character(s)</returns>\r
+    public virtual string ToString(IntPtr nativestring, int nativestringlen)\r
+    {\r
+      return UTF8ToString(nativestring, nativestringlen);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string\r
+    /// </summary>\r
+    /// <param name="nativestring">The pointer to the memory where the UTF-8 string is encoded</param>\r
+    /// <param name="nativestringlen">The number of bytes to decode</param>\r
+    /// <returns>A string containing the translated character(s)</returns>\r
+    public static string UTF8ToString(IntPtr nativestring, int nativestringlen)\r
+    {\r
+      if (nativestringlen == 0 || nativestring == IntPtr.Zero) return "";\r
+      if (nativestringlen == -1)\r
+      {\r
+        do\r
+        {\r
+          nativestringlen++;\r
+        } while (Marshal.ReadByte(nativestring, nativestringlen) != 0);\r
+      }\r
+\r
+      byte[] byteArray = new byte[nativestringlen];\r
+      \r
+      Marshal.Copy(nativestring, byteArray, 0, nativestringlen);\r
+\r
+      return _utf8.GetString(byteArray, 0, nativestringlen);\r
+    }\r
+\r
+\r
+    #endregion\r
+\r
+    #region DateTime Conversion Functions\r
+    /// <summary>\r
+    /// Converts a string into a DateTime, using the current DateTimeFormat specified for the connection when it was opened.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// Acceptable ISO8601 DateTime formats are:\r
+    ///   yyyy-MM-dd HH:mm:ss\r
+    ///   yyyyMMddHHmmss\r
+    ///   yyyyMMddTHHmmssfffffff\r
+    ///   yyyy-MM-dd\r
+    ///   yy-MM-dd\r
+    ///   yyyyMMdd\r
+    ///   HH:mm:ss\r
+    ///   THHmmss\r
+    /// </remarks>\r
+    /// <param name="dateText">The string containing either a Tick value, a JulianDay double, or an ISO8601-format string</param>\r
+    /// <returns>A DateTime value</returns>\r
+    public DateTime ToDateTime(string dateText)\r
+    {\r
+      switch (_datetimeFormat)\r
+      {\r
+        case SQLiteDateFormats.Ticks:\r
+          return new DateTime(Convert.ToInt64(dateText, CultureInfo.InvariantCulture));\r
+        case SQLiteDateFormats.JulianDay:\r
+          return ToDateTime(Convert.ToDouble(dateText, CultureInfo.InvariantCulture));\r
+        default:\r
+          return DateTime.ParseExact(dateText, _datetimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Converts a julianday value into a DateTime\r
+    /// </summary>\r
+    /// <param name="julianDay">The value to convert</param>\r
+    /// <returns>A .NET DateTime</returns>\r
+    public DateTime ToDateTime(double julianDay)\r
+    {\r
+      return DateTime.FromOADate(julianDay - 2415018.5);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Converts a DateTime struct to a JulianDay double\r
+    /// </summary>\r
+    /// <param name="value">The DateTime to convert</param>\r
+    /// <returns>The JulianDay value the Datetime represents</returns>\r
+    public double ToJulianDay(DateTime value)\r
+    {\r
+      return value.ToOADate() + 2415018.5;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Converts a DateTime to a string value, using the current DateTimeFormat specified for the connection when it was opened.\r
+    /// </summary>\r
+    /// <param name="dateValue">The DateTime value to convert</param>\r
+    /// <returns>Either a string consisting of the tick count for DateTimeFormat.Ticks, a JulianDay double, or a date/time in ISO8601 format.</returns>\r
+    public string ToString(DateTime dateValue)\r
+    {\r
+      switch (_datetimeFormat)\r
+      {\r
+        case SQLiteDateFormats.Ticks:\r
+          return dateValue.Ticks.ToString(CultureInfo.InvariantCulture);\r
+        case SQLiteDateFormats.JulianDay:\r
+          return ToJulianDay(dateValue).ToString(CultureInfo.InvariantCulture);\r
+        default:\r
+          return dateValue.ToString(_datetimeFormats[7], CultureInfo.InvariantCulture);\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls\r
+    /// ToDateTime() on the string to return a DateTime.\r
+    /// </remarks>\r
+    /// <param name="ptr">A pointer to the UTF-8 encoded string</param>\r
+    /// <param name="len">The length in bytes of the string</param>\r
+    /// <returns>The parsed DateTime value</returns>\r
+    internal DateTime ToDateTime(IntPtr ptr, int len)\r
+    {\r
+      return ToDateTime(ToString(ptr, len));\r
+    }\r
+\r
+    #endregion\r
+\r
+    /// <summary>\r
+    /// Smart method of splitting a string.  Skips quoted elements, removes the quotes.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// This split function works somewhat like the String.Split() function in that it breaks apart a string into\r
+    /// pieces and returns the pieces as an array.  The primary differences are:\r
+    /// <list type="bullet">\r
+    /// <item><description>Only one character can be provided as a separator character</description></item>\r
+    /// <item><description>Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed.</description></item>\r
+    /// </list>\r
+    /// Thus, if splitting the following string looking for a comma:<br/>\r
+    /// One,Two, "Three, Four", Five<br/>\r
+    /// <br/>\r
+    /// The resulting array would contain<br/>\r
+    /// [0] One<br/>\r
+    /// [1] Two<br/>\r
+    /// [2] Three, Four<br/>\r
+    /// [3] Five<br/>\r
+    /// <br/>\r
+    /// Note that the leading and trailing spaces were removed from each item during the split.\r
+    /// </remarks>\r
+    /// <param name="source">Source string to split apart</param>\r
+    /// <param name="separator">Separator character</param>\r
+    /// <returns>A string array of the split up elements</returns>\r
+    public static string[] Split(string source, char separator)\r
+    {\r
+      char[] toks = new char[2] { '\"', separator };\r
+      char[] quot = new char[1] { '\"' };\r
+      int n = 0;\r
+      List<string> ls = new List<string>();\r
+      string s;\r
+\r
+      while (source.Length > 0)\r
+      {\r
+        n = source.IndexOfAny(toks, n);\r
+        if (n == -1) break;\r
+        if (source[n] == toks[0])\r
+        {\r
+          //source = source.Remove(n, 1);\r
+          n = source.IndexOfAny(quot, n + 1);\r
+          if (n == -1)\r
+          {\r
+            //source = "\"" + source;\r
+            break;\r
+          }\r
+          n++;\r
+          //source = source.Remove(n, 1);\r
+        }\r
+        else\r
+        {\r
+          s = source.Substring(0, n).Trim();\r
+          if (s.Length > 1 && s[0] == quot[0] && s[s.Length - 1] == s[0])\r
+            s = s.Substring(1, s.Length - 2);\r
+\r
+          source = source.Substring(n + 1).Trim();\r
+          if (s.Length > 0) ls.Add(s);\r
+          n = 0;\r
+        }\r
+      }\r
+      if (source.Length > 0)\r
+      {\r
+        s = source.Trim();\r
+        if (s.Length > 1 && s[0] == quot[0] && s[s.Length - 1] == s[0])\r
+          s = s.Substring(1, s.Length - 2);\r
+        ls.Add(s);\r
+      }\r
+\r
+      string[] ar = new string[ls.Count];\r
+      ls.CopyTo(ar, 0);\r
+\r
+      return ar;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Convert a value to true or false.\r
+    /// </summary>\r
+    /// <param name="source">A string or number representing true or false</param>\r
+    /// <returns></returns>\r
+    public static bool ToBoolean(object source)\r
+    {\r
+      if (source is bool) return (bool)source;\r
+\r
+      return ToBoolean(source.ToString());\r
+    }\r
+\r
+    /// <summary>\r
+    /// Convert a string to true or false.\r
+    /// </summary>\r
+    /// <param name="source">A string representing true or false</param>\r
+    /// <returns></returns>\r
+    /// <remarks>\r
+    /// "yes", "no", "y", "n", "0", "1", "on", "off" as well as Boolean.FalseString and Boolean.TrueString will all be\r
+    /// converted to a proper boolean value.\r
+    /// </remarks>\r
+    public static bool ToBoolean(string source)\r
+    {\r
+      if (String.Compare(source, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0) return true;\r
+      else if (String.Compare(source, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0) return false;\r
+\r
+      switch(source.ToLower())\r
+      {\r
+        case "yes":\r
+        case "y":\r
+        case "1":\r
+        case "on":\r
+          return true;\r
+        case "no":\r
+        case "n":\r
+        case "0":\r
+        case "off":\r
+          return false;\r
+        default:\r
+          throw new ArgumentException("source");\r
+      }\r
+    }\r
+\r
+    #region Type Conversions\r
+    /// <summary>\r
+    /// Determines the data type of a column in a statement\r
+    /// </summary>\r
+    /// <param name="stmt">The statement to retrieve information for</param>\r
+    /// <param name="i">The column to retrieve type information on</param>\r
+    /// <param name="typ">The SQLiteType to receive the affinity for the given column</param>\r
+    internal static void ColumnToType(SQLiteStatement stmt, int i, SQLiteType typ)\r
+    {\r
+      typ.Type = TypeNameToDbType(stmt._sql.ColumnType(stmt, i, out typ.Affinity));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Converts a SQLiteType to a .NET Type object\r
+    /// </summary>\r
+    /// <param name="t">The SQLiteType to convert</param>\r
+    /// <returns>Returns a .NET Type object</returns>\r
+    internal static Type SQLiteTypeToType(SQLiteType t)\r
+    {\r
+      if (t.Type == DbType.Object)\r
+        return _affinitytotype[(int)t.Affinity];\r
+      else\r
+        return SQLiteConvert.DbTypeToType(t.Type);\r
+    }\r
+\r
+    private static Type[] _affinitytotype = {\r
+      typeof(object),\r
+      typeof(Int64),\r
+      typeof(Double),\r
+      typeof(string),\r
+      typeof(byte[]),\r
+      typeof(object),\r
+      typeof(DateTime),\r
+      typeof(object)\r
+    };\r
+\r
+    /// <summary>\r
+    /// For a given intrinsic type, return a DbType\r
+    /// </summary>\r
+    /// <param name="typ">The native type to convert</param>\r
+    /// <returns>The corresponding (closest match) DbType</returns>\r
+    internal static DbType TypeToDbType(Type typ)\r
+    {\r
+      TypeCode tc = Type.GetTypeCode(typ);\r
+      if (tc == TypeCode.Object)\r
+      {\r
+        if (typ == typeof(byte[])) return DbType.Binary;\r
+        if (typ == typeof(Guid)) return DbType.Guid;\r
+        return DbType.String;\r
+      }\r
+      return _typetodbtype[(int)tc];\r
+    }\r
+\r
+    private static DbType[] _typetodbtype = {\r
+      DbType.Object,\r
+      DbType.Binary,\r
+      DbType.Object,\r
+      DbType.Boolean,\r
+      DbType.SByte,\r
+      DbType.SByte,\r
+      DbType.Byte,\r
+      DbType.Int16, // 7\r
+      DbType.UInt16,\r
+      DbType.Int32,\r
+      DbType.UInt32,\r
+      DbType.Int64, // 11\r
+      DbType.UInt64,\r
+      DbType.Single,\r
+      DbType.Double,\r
+      DbType.Decimal,\r
+      DbType.DateTime,\r
+      DbType.Object,\r
+      DbType.String,\r
+    };\r
+\r
+    /// <summary>\r
+    /// Returns the ColumnSize for the given DbType\r
+    /// </summary>\r
+    /// <param name="typ">The DbType to get the size of</param>\r
+    /// <returns></returns>\r
+    internal static int DbTypeToColumnSize(DbType typ)\r
+    {\r
+      return _dbtypetocolumnsize[(int)typ];\r
+    }\r
+\r
+    private static int[] _dbtypetocolumnsize = {\r
+      2147483647,   // 0\r
+      2147483647,   // 1\r
+      1,     // 2\r
+      1,     // 3\r
+      8,  // 4\r
+      8, // 5\r
+      8, // 6\r
+      8,  // 7\r
+      8,   // 8\r
+      16,     // 9\r
+      2,\r
+      4,\r
+      8,\r
+      2147483647,\r
+      1,\r
+      4,\r
+      2147483647,\r
+      8,\r
+      2,\r
+      4,\r
+      8,\r
+      8,\r
+      2147483647,\r
+      2147483647,\r
+      2147483647,\r
+      2147483647,   // 25 (Xml)\r
+    };\r
+\r
+    internal static object DbTypeToNumericPrecision(DbType typ)\r
+    {\r
+      return _dbtypetonumericprecision[(int)typ];\r
+    }\r
+\r
+    private static object[] _dbtypetonumericprecision = {\r
+      DBNull.Value, // 0\r
+      DBNull.Value, // 1\r
+      3,\r
+      DBNull.Value,\r
+      19,\r
+      DBNull.Value, // 5\r
+      DBNull.Value, // 6\r
+      53,\r
+      53,\r
+      DBNull.Value,\r
+      5,\r
+      10,\r
+      19,\r
+      DBNull.Value,\r
+      3,\r
+      24,\r
+      DBNull.Value,\r
+      DBNull.Value,\r
+      5,\r
+      10,\r
+      19,\r
+      53,\r
+      DBNull.Value,\r
+      DBNull.Value,\r
+      DBNull.Value\r
+    };\r
+\r
+    internal static object DbTypeToNumericScale(DbType typ)\r
+    {\r
+      return _dbtypetonumericscale[(int)typ];\r
+    }\r
+\r
+    private static object[] _dbtypetonumericscale = {\r
+      DBNull.Value, // 0\r
+      DBNull.Value, // 1\r
+      0,\r
+      DBNull.Value,\r
+      4,\r
+      DBNull.Value, // 5\r
+      DBNull.Value, // 6\r
+      DBNull.Value,\r
+      DBNull.Value,\r
+      DBNull.Value,\r
+      0,\r
+      0,\r
+      0,\r
+      DBNull.Value,\r
+      0,\r
+      DBNull.Value,\r
+      DBNull.Value,\r
+      DBNull.Value,\r
+      0,\r
+      0,\r
+      0,\r
+      0,\r
+      DBNull.Value,\r
+      DBNull.Value,\r
+      DBNull.Value\r
+    };\r
+\r
+    internal static string DbTypeToTypeName(DbType typ)\r
+    {\r
+      for (int n = 0; n < _dbtypeNames.Length; n++)\r
+      {\r
+        if (_dbtypeNames[n].dataType == typ)\r
+          return _dbtypeNames[n].typeName;\r
+      }\r
+\r
+      return String.Empty;\r
+    }\r
+\r
+    private static SQLiteTypeNames[] _dbtypeNames = {\r
+      new SQLiteTypeNames("INTEGER", DbType.Int64),\r
+      new SQLiteTypeNames("TINYINT", DbType.Byte),\r
+      new SQLiteTypeNames("INT", DbType.Int32),\r
+      new SQLiteTypeNames("VARCHAR", DbType.AnsiString),\r
+      new SQLiteTypeNames("NVARCHAR", DbType.String),\r
+      new SQLiteTypeNames("CHAR", DbType.AnsiStringFixedLength),\r
+      new SQLiteTypeNames("NCHAR", DbType.StringFixedLength),\r
+      new SQLiteTypeNames("FLOAT", DbType.Double),\r
+      new SQLiteTypeNames("REAL", DbType.Single),          \r
+      new SQLiteTypeNames("BIT", DbType.Boolean),\r
+      new SQLiteTypeNames("DECIMAL", DbType.Decimal),\r
+      new SQLiteTypeNames("DATETIME", DbType.DateTime),\r
+      new SQLiteTypeNames("BLOB", DbType.Binary),\r
+      new SQLiteTypeNames("UNIQUEIDENTIFIER", DbType.Guid),\r
+      new SQLiteTypeNames("SMALLINT", DbType.Int16),\r
+    };\r
+    /// <summary>\r
+    /// Convert a DbType to a Type\r
+    /// </summary>\r
+    /// <param name="typ">The DbType to convert from</param>\r
+    /// <returns>The closest-match .NET type</returns>\r
+    internal static Type DbTypeToType(DbType typ)\r
+    {\r
+      return _dbtypeToType[(int)typ];\r
+    }\r
+\r
+    private static Type[] _dbtypeToType = {\r
+      typeof(string),   // 0\r
+      typeof(byte[]),   // 1\r
+      typeof(byte),     // 2\r
+      typeof(bool),     // 3\r
+      typeof(decimal),  // 4\r
+      typeof(DateTime), // 5\r
+      typeof(DateTime), // 6\r
+      typeof(decimal),  // 7\r
+      typeof(double),   // 8\r
+      typeof(Guid),     // 9\r
+      typeof(Int16),\r
+      typeof(Int32),\r
+      typeof(Int64),\r
+      typeof(object),\r
+      typeof(sbyte),\r
+      typeof(float),\r
+      typeof(string),\r
+      typeof(DateTime),\r
+      typeof(UInt16),\r
+      typeof(UInt32),\r
+      typeof(UInt64),\r
+      typeof(double),\r
+      typeof(string),\r
+      typeof(string),\r
+      typeof(string),\r
+      typeof(string),   // 25 (Xml)\r
+    };\r
+\r
+    /// <summary>\r
+    /// For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types.\r
+    /// </summary>\r
+    /// <param name="typ">The type to evaluate</param>\r
+    /// <returns>The SQLite type affinity for that type.</returns>\r
+    internal static TypeAffinity TypeToAffinity(Type typ)\r
+    {\r
+      TypeCode tc = Type.GetTypeCode(typ);\r
+      if (tc == TypeCode.Object)\r
+      {\r
+        if (typ == typeof(byte[]) || typ == typeof(Guid))\r
+          return TypeAffinity.Blob;\r
+        else\r
+          return TypeAffinity.Text;\r
+      }\r
+      return _typecodeAffinities[(int)tc];\r
+    }\r
+\r
+    private static TypeAffinity[] _typecodeAffinities = {\r
+      TypeAffinity.Null,\r
+      TypeAffinity.Blob,\r
+      TypeAffinity.Null,\r
+      TypeAffinity.Int64,\r
+      TypeAffinity.Int64,\r
+      TypeAffinity.Int64,\r
+      TypeAffinity.Int64,\r
+      TypeAffinity.Int64, // 7\r
+      TypeAffinity.Int64,\r
+      TypeAffinity.Int64,\r
+      TypeAffinity.Int64,\r
+      TypeAffinity.Int64, // 11\r
+      TypeAffinity.Int64,\r
+      TypeAffinity.Double,\r
+      TypeAffinity.Double,\r
+      TypeAffinity.Double,\r
+      TypeAffinity.DateTime,\r
+      TypeAffinity.Null,\r
+      TypeAffinity.Text,\r
+    };\r
+\r
+    /// <summary>\r
+    /// For a given type name, return a closest-match .NET type\r
+    /// </summary>\r
+    /// <param name="Name">The name of the type to match</param>\r
+    /// <returns>The .NET DBType the text evaluates to.</returns>\r
+    internal static DbType TypeNameToDbType(string Name)\r
+    {\r
+      if (String.IsNullOrEmpty(Name)) return DbType.Object;\r
+\r
+      int x = _typeNames.Length;\r
+      for (int n = 0; n < x; n++)\r
+      {\r
+        if (String.Compare(Name, 0, _typeNames[n].typeName, 0, _typeNames[n].typeName.Length, true, CultureInfo.InvariantCulture) == 0)\r
+          return _typeNames[n].dataType; \r
+      }\r
+      return DbType.Object;\r
+    }\r
+    #endregion\r
+\r
+    private static SQLiteTypeNames[] _typeNames = {\r
+      new SQLiteTypeNames("COUNTER", DbType.Int64),\r
+      new SQLiteTypeNames("AUTOINCREMENT", DbType.Int64),\r
+      new SQLiteTypeNames("IDENTITY", DbType.Int64),\r
+      new SQLiteTypeNames("LONGTEXT", DbType.String),\r
+      new SQLiteTypeNames("LONGCHAR", DbType.String),\r
+      new SQLiteTypeNames("LONGVARCHAR", DbType.String),\r
+      new SQLiteTypeNames("LONG", DbType.Int64),\r
+      new SQLiteTypeNames("TINYINT", DbType.Byte),\r
+      new SQLiteTypeNames("INTEGER", DbType.Int64),\r
+      new SQLiteTypeNames("INT", DbType.Int32),\r
+      new SQLiteTypeNames("VARCHAR", DbType.String),\r
+      new SQLiteTypeNames("NVARCHAR", DbType.String),\r
+      new SQLiteTypeNames("CHAR", DbType.String),\r
+      new SQLiteTypeNames("NCHAR", DbType.String),\r
+      new SQLiteTypeNames("TEXT", DbType.String),\r
+      new SQLiteTypeNames("NTEXT", DbType.String),\r
+      new SQLiteTypeNames("STRING", DbType.String),\r
+      new SQLiteTypeNames("DOUBLE", DbType.Double),\r
+      new SQLiteTypeNames("FLOAT", DbType.Double),\r
+      new SQLiteTypeNames("REAL", DbType.Single),          \r
+      new SQLiteTypeNames("BIT", DbType.Boolean),\r
+      new SQLiteTypeNames("YESNO", DbType.Boolean),\r
+      new SQLiteTypeNames("LOGICAL", DbType.Boolean),\r
+      new SQLiteTypeNames("BOOL", DbType.Boolean),\r
+      new SQLiteTypeNames("NUMERIC", DbType.Decimal),\r
+      new SQLiteTypeNames("DECIMAL", DbType.Decimal),\r
+      new SQLiteTypeNames("MONEY", DbType.Decimal),\r
+      new SQLiteTypeNames("CURRENCY", DbType.Decimal),\r
+      new SQLiteTypeNames("TIME", DbType.DateTime),\r
+      new SQLiteTypeNames("DATE", DbType.DateTime),\r
+      new SQLiteTypeNames("SMALLDATE", DbType.DateTime),\r
+      new SQLiteTypeNames("BLOB", DbType.Binary),\r
+      new SQLiteTypeNames("BINARY", DbType.Binary),\r
+      new SQLiteTypeNames("VARBINARY", DbType.Binary),\r
+      new SQLiteTypeNames("IMAGE", DbType.Binary),\r
+      new SQLiteTypeNames("GENERAL", DbType.Binary),\r
+      new SQLiteTypeNames("OLEOBJECT", DbType.Binary),\r
+      new SQLiteTypeNames("GUID", DbType.Guid),\r
+      new SQLiteTypeNames("UNIQUEIDENTIFIER", DbType.Guid),\r
+      new SQLiteTypeNames("MEMO", DbType.String),\r
+      new SQLiteTypeNames("NOTE", DbType.String),\r
+      new SQLiteTypeNames("SMALLINT", DbType.Int16),\r
+      new SQLiteTypeNames("BIGINT", DbType.Int64),\r
+    };\r
+  }\r
+\r
+  /// <summary>\r
+  /// SQLite has very limited types, and is inherently text-based.  The first 5 types below represent the sum of all types SQLite\r
+  /// understands.  The DateTime extension to the spec is for internal use only.\r
+  /// </summary>\r
+  public enum TypeAffinity\r
+  {\r
+    /// <summary>\r
+    /// Not used\r
+    /// </summary>\r
+    Uninitialized = 0,\r
+    /// <summary>\r
+    /// All integers in SQLite default to Int64\r
+    /// </summary>\r
+    Int64 = 1,\r
+    /// <summary>\r
+    /// All floating point numbers in SQLite default to double\r
+    /// </summary>\r
+    Double = 2,\r
+    /// <summary>\r
+    /// The default data type of SQLite is text\r
+    /// </summary>\r
+    Text = 3,\r
+    /// <summary>\r
+    /// Typically blob types are only seen when returned from a function\r
+    /// </summary>\r
+    Blob = 4,\r
+    /// <summary>\r
+    /// Null types can be returned from functions\r
+    /// </summary>\r
+    Null = 5,\r
+    /// <summary>\r
+    /// Used internally by this provider\r
+    /// </summary>\r
+    DateTime = 10,\r
+    /// <summary>\r
+    /// Used internally\r
+    /// </summary>\r
+    None = 11,\r
+  }\r
+\r
+  /// <summary>\r
+  /// This implementation of SQLite for ADO.NET can process date/time fields in databases in only one of three formats.  Ticks, ISO8601\r
+  /// and JulianDay.\r
+  /// </summary>\r
+  /// <remarks>\r
+  /// ISO8601 is more compatible, readable, fully-processable, but less accurate as it doesn't provide time down to fractions of a second.\r
+  /// JulianDay is the numeric format the SQLite uses internally and is arguably the most compatible with 3rd party tools.  It is\r
+  /// not readable as text without post-processing.\r
+  /// Ticks less compatible with 3rd party tools that query the database, and renders the DateTime field unreadable as text without post-processing.\r
+  /// \r
+  /// The preferred order of choosing a datetime format is JulianDay, ISO8601, and then Ticks.  Ticks is mainly present for legacy \r
+  /// code support.\r
+  /// </remarks>\r
+  public enum SQLiteDateFormats\r
+  {\r
+    /// <summary>\r
+    /// Using ticks is not recommended and is not well supported with LINQ.\r
+    /// </summary>\r
+    Ticks = 0,\r
+    /// <summary>\r
+    /// The default format for this provider.\r
+    /// </summary>\r
+    ISO8601 = 1,\r
+    /// <summary>\r
+    /// JulianDay format, which is what SQLite uses internally\r
+    /// </summary>\r
+    JulianDay = 2\r
+  }\r
+\r
+  /// <summary>\r
+  /// This enum determines how SQLite treats its journal file.\r
+  /// </summary>\r
+  /// <remarks>\r
+  /// By default SQLite will create and delete the journal file when needed during a transaction.\r
+  /// However, for some computers running certain filesystem monitoring tools, the rapid\r
+  /// creation and deletion of the journal file can cause those programs to fail, or to interfere with SQLite.\r
+  /// \r
+  /// If a program or virus scanner is interfering with SQLite's journal file, you may receive errors like "unable to open database file"\r
+  /// when starting a transaction.  If this is happening, you may want to change the default journal mode to Persist.\r
+  /// </remarks>\r
+  public enum SQLiteJournalModeEnum\r
+  {\r
+    /// <summary>\r
+    /// The default mode, this causes SQLite to create and destroy the journal file as-needed.\r
+    /// </summary>\r
+    Delete = 0,\r
+    /// <summary>\r
+    /// When this is set, SQLite will keep the journal file even after a transaction has completed.  It's contents will be erased,\r
+    /// and the journal re-used as often as needed.  If it is deleted, it will be recreated the next time it is needed.\r
+    /// </summary>\r
+    Persist = 1,\r
+    /// <summary>\r
+    /// This option disables the rollback journal entirely.  Interrupted transactions or a program crash can cause database\r
+    /// corruption in this mode!\r
+    /// </summary>\r
+    Off = 2\r
+  }\r
+\r
+  /// <summary>\r
+  /// Struct used internally to determine the datatype of a column in a resultset\r
+  /// </summary>\r
+  internal class SQLiteType\r
+  {\r
+    /// <summary>\r
+    /// The DbType of the column, or DbType.Object if it cannot be determined\r
+    /// </summary>\r
+    internal DbType Type;\r
+    /// <summary>\r
+    /// The affinity of a column, used for expressions or when Type is DbType.Object\r
+    /// </summary>\r
+    internal TypeAffinity Affinity;\r
+  }\r
+\r
+  internal struct SQLiteTypeNames\r
+  {\r
+    internal SQLiteTypeNames(string newtypeName, DbType newdataType)\r
+    {\r
+      typeName = newtypeName;\r
+      dataType = newdataType;\r
+    }\r
+\r
+    internal string typeName;\r
+    internal DbType dataType;\r
+  }\r
+}\r
index 60bb1d8b52b6d1b7288cddbd73bc0a4c29dbb24e..4bae9a302c779b759efc0d4e5a52189c3ba3f4d0 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteDataAdapter.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Data.Common;
-  using System.ComponentModel;
-
-  /// <summary>
-  /// Sqlite implementation of DbDataAdapter.
-  /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-  [DefaultEvent("RowUpdated")]
-  [ToolboxItem("Sqlite.Designer.SqliteDataAdapterToolboxItem, Sqlite.Designer, Version=1.0.31.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139")]
-  [Designer("Microsoft.VSDesigner.Data.VS.SqlDataAdapterDesigner, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
-#endif
-  public sealed class SqliteDataAdapter : DbDataAdapter
-  {
-    private static object _updatingEventPH = new object();
-    private static object _updatedEventPH = new object();
-
-    /// <overloads>
-    /// This class is just a shell around the DbDataAdapter.  Nothing from DbDataAdapter is overridden here, just a few constructors are defined.
-    /// </overloads>
-    /// <summary>
-    /// Default constructor.
-    /// </summary>
-    public SqliteDataAdapter()
-    {
-    }
-
-    /// <summary>
-    /// Constructs a data adapter using the specified select command.
-    /// </summary>
-    /// <param name="cmd">The select command to associate with the adapter.</param>
-    public SqliteDataAdapter(SqliteCommand cmd)
-    {
-      SelectCommand = cmd;
-    }
-
-    /// <summary>
-    /// Constructs a data adapter with the supplied select command text and associated with the specified connection.
-    /// </summary>
-    /// <param name="commandText">The select command text to associate with the data adapter.</param>
-    /// <param name="connection">The connection to associate with the select command.</param>
-    public SqliteDataAdapter(string commandText, SqliteConnection connection)
-    {
-      SelectCommand = new SqliteCommand(commandText, connection);
-    }
-
-    /// <summary>
-    /// Constructs a data adapter with the specified select command text, and using the specified database connection string.
-    /// </summary>
-    /// <param name="commandText">The select command text to use to construct a select command.</param>
-    /// <param name="connectionString">A connection string suitable for passing to a new SqliteConnection, which is associated with the select command.</param>
-    public SqliteDataAdapter(string commandText, string connectionString)
-    {
-      SqliteConnection cnn = new SqliteConnection(connectionString);
-      SelectCommand = new SqliteCommand(commandText, cnn);
-    }
-
-    /// <summary>
-    /// Row updating event handler
-    /// </summary>
-    public event EventHandler<RowUpdatingEventArgs> RowUpdating
-    {
-      add { base.Events.AddHandler(_updatingEventPH, value); }
-      remove { base.Events.RemoveHandler(_updatingEventPH, value); }
-    }
-
-    /// <summary>
-    /// Row updated event handler
-    /// </summary>
-    public event EventHandler<RowUpdatedEventArgs> RowUpdated
-    {
-      add { base.Events.AddHandler(_updatedEventPH, value); }
-      remove { base.Events.RemoveHandler(_updatedEventPH, value); }
-    }
-
-    /// <summary>
-    /// Raised by the underlying DbDataAdapter when a row is being updated
-    /// </summary>
-    /// <param name="value">The event's specifics</param>
-    protected override void OnRowUpdating(RowUpdatingEventArgs value)
-    {
-      EventHandler<RowUpdatingEventArgs> handler = base.Events[_updatingEventPH] as EventHandler<RowUpdatingEventArgs>;
-
-      if (handler != null)
-        handler(this, value);
-    }
-
-    /// <summary>
-    /// Raised by DbDataAdapter after a row is updated
-    /// </summary>
-    /// <param name="value">The event's specifics</param>
-    protected override void OnRowUpdated(RowUpdatedEventArgs value)
-    {
-      EventHandler<RowUpdatedEventArgs> handler = base.Events[_updatedEventPH] as EventHandler<RowUpdatedEventArgs>;
-
-      if (handler != null)
-        handler(this, value);
-    }
-
-    /// <summary>
-    /// Gets/sets the select command for this DataAdapter
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
-#endif
-    public new SqliteCommand SelectCommand
-    {
-      get { return (SqliteCommand)base.SelectCommand; }
-      set { base.SelectCommand = value; }
-    }
-
-    /// <summary>
-    /// Gets/sets the insert command for this DataAdapter
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
-#endif
-    public new SqliteCommand InsertCommand
-    {
-      get { return (SqliteCommand)base.InsertCommand; }
-      set { base.InsertCommand = value; }
-    }
-
-    /// <summary>
-    /// Gets/sets the update command for this DataAdapter
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
-#endif
-    public new SqliteCommand UpdateCommand
-    {
-      get { return (SqliteCommand)base.UpdateCommand; }
-      set { base.UpdateCommand = value; }
-    }
-
-    /// <summary>
-    /// Gets/sets the delete command for this DataAdapter
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
-#endif
-    public new SqliteCommand DeleteCommand
-    {
-      get { return (SqliteCommand)base.DeleteCommand; }
-      set { base.DeleteCommand = value; }
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Data.Common;\r
+  using System.ComponentModel;\r
+\r
+  /// <summary>\r
+  /// SQLite implementation of DbDataAdapter.\r
+  /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  [DefaultEvent("RowUpdated")]\r
+  [ToolboxItem("SQLite.Designer.SQLiteDataAdapterToolboxItem, SQLite.Designer, Version=1.0.36.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139")]\r
+  [Designer("Microsoft.VSDesigner.Data.VS.SqlDataAdapterDesigner, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+#endif\r
+  public sealed class SQLiteDataAdapter : DbDataAdapter\r
+  {\r
+    private static object _updatingEventPH = new object();\r
+    private static object _updatedEventPH = new object();\r
+\r
+    /// <overloads>\r
+    /// This class is just a shell around the DbDataAdapter.  Nothing from DbDataAdapter is overridden here, just a few constructors are defined.\r
+    /// </overloads>\r
+    /// <summary>\r
+    /// Default constructor.\r
+    /// </summary>\r
+    public SQLiteDataAdapter()\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a data adapter using the specified select command.\r
+    /// </summary>\r
+    /// <param name="cmd">The select command to associate with the adapter.</param>\r
+    public SQLiteDataAdapter(SQLiteCommand cmd)\r
+    {\r
+      SelectCommand = cmd;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a data adapter with the supplied select command text and associated with the specified connection.\r
+    /// </summary>\r
+    /// <param name="commandText">The select command text to associate with the data adapter.</param>\r
+    /// <param name="connection">The connection to associate with the select command.</param>\r
+    public SQLiteDataAdapter(string commandText, SQLiteConnection connection)\r
+    {\r
+      SelectCommand = new SQLiteCommand(commandText, connection);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a data adapter with the specified select command text, and using the specified database connection string.\r
+    /// </summary>\r
+    /// <param name="commandText">The select command text to use to construct a select command.</param>\r
+    /// <param name="connectionString">A connection string suitable for passing to a new SQLiteConnection, which is associated with the select command.</param>\r
+    public SQLiteDataAdapter(string commandText, string connectionString)\r
+    {\r
+      SQLiteConnection cnn = new SQLiteConnection(connectionString);\r
+      SelectCommand = new SQLiteCommand(commandText, cnn);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Row updating event handler\r
+    /// </summary>\r
+    public event EventHandler<RowUpdatingEventArgs> RowUpdating\r
+    {\r
+      add\r
+      {\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+        EventHandler<RowUpdatingEventArgs> previous = (EventHandler<RowUpdatingEventArgs>)base.Events[_updatingEventPH];\r
+        if ((previous != null) && (value.Target is DbCommandBuilder))\r
+        {\r
+          EventHandler<RowUpdatingEventArgs> handler = (EventHandler<RowUpdatingEventArgs>)FindBuilder(previous);\r
+          if (handler != null)\r
+          {\r
+            base.Events.RemoveHandler(_updatingEventPH, handler);\r
+          }\r
+        }\r
+#endif\r
+        base.Events.AddHandler(_updatingEventPH, value); \r
+      }\r
+      remove { base.Events.RemoveHandler(_updatingEventPH, value); }\r
+    }\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    internal static Delegate FindBuilder(MulticastDelegate mcd)\r
+    {\r
+      if (mcd != null)\r
+      {\r
+        Delegate[] invocationList = mcd.GetInvocationList();\r
+        for (int i = 0; i < invocationList.Length; i++)\r
+        {\r
+          if (invocationList[i].Target is DbCommandBuilder)\r
+          {\r
+            return invocationList[i];\r
+          }\r
+        }\r
+      }\r
+      return null;\r
+    }\r
+#endif\r
+\r
+    /// <summary>\r
+    /// Row updated event handler\r
+    /// </summary>\r
+    public event EventHandler<RowUpdatedEventArgs> RowUpdated\r
+    {\r
+      add { base.Events.AddHandler(_updatedEventPH, value); }\r
+      remove { base.Events.RemoveHandler(_updatedEventPH, value); }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Raised by the underlying DbDataAdapter when a row is being updated\r
+    /// </summary>\r
+    /// <param name="value">The event's specifics</param>\r
+    protected override void OnRowUpdating(RowUpdatingEventArgs value)\r
+    {\r
+      EventHandler<RowUpdatingEventArgs> handler = base.Events[_updatingEventPH] as EventHandler<RowUpdatingEventArgs>;\r
+\r
+      if (handler != null)\r
+        handler(this, value);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Raised by DbDataAdapter after a row is updated\r
+    /// </summary>\r
+    /// <param name="value">The event's specifics</param>\r
+    protected override void OnRowUpdated(RowUpdatedEventArgs value)\r
+    {\r
+      EventHandler<RowUpdatedEventArgs> handler = base.Events[_updatedEventPH] as EventHandler<RowUpdatedEventArgs>;\r
+\r
+      if (handler != null)\r
+        handler(this, value);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/sets the select command for this DataAdapter\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+#endif\r
+    public new SQLiteCommand SelectCommand\r
+    {\r
+      get { return (SQLiteCommand)base.SelectCommand; }\r
+      set { base.SelectCommand = value; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/sets the insert command for this DataAdapter\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+#endif\r
+    public new SQLiteCommand InsertCommand\r
+    {\r
+      get { return (SQLiteCommand)base.InsertCommand; }\r
+      set { base.InsertCommand = value; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/sets the update command for this DataAdapter\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+#endif\r
+    public new SQLiteCommand UpdateCommand\r
+    {\r
+      get { return (SQLiteCommand)base.UpdateCommand; }\r
+      set { base.UpdateCommand = value; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/sets the delete command for this DataAdapter\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]\r
+#endif\r
+    public new SQLiteCommand DeleteCommand\r
+    {\r
+      get { return (SQLiteCommand)base.DeleteCommand; }\r
+      set { base.DeleteCommand = value; }\r
+    }\r
+  }\r
+}\r
index 2bae3581a7415bba0d19c39ee954f0d7283290c5..4a42355423328942f674e3bb245845ef2c159072 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteDataReader.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Data.Common;
-  using System.Collections;
-  using System.Collections.Generic;
-  using System.Globalization;
-  using System.Reflection;
-
-  /// <summary>
-  /// Sqlite implementation of DbDataReader.
-  /// </summary>
-  public class SqliteDataReader : DbDataReader
-  {
-    /// <summary>
-    /// Underlying command this reader is attached to
-    /// </summary>
-    private SqliteCommand   _command;
-    /// <summary>
-    /// Index of the current statement in the command being processed
-    /// </summary>
-    private int             _activeStatementIndex;
-    /// <summary>
-    /// Current statement being Read()
-    /// </summary>
-    private SqliteStatement _activeStatement;
-    /// <summary>
-    /// State of the current statement being processed.
-    /// -1 = First Step() executed, so the first Read() will be ignored
-    ///  0 = Actively reading
-    ///  1 = Finished reading
-    ///  2 = Non-row-returning statement, no records
-    /// </summary>
-    private int             _readingState;
-    /// <summary>
-    /// Number of records affected by the insert/update statements executed on the command
-    /// </summary>
-    private int             _rowsAffected;
-    /// <summary>
-    /// Count of fields (columns) in the row-returning statement currently being processed
-    /// </summary>
-    private int             _fieldCount;
-    /// <summary>
-    /// Datatypes of active fields (columns) in the current statement, used for type-restricting data
-    /// </summary>
-    private SqliteType[]    _fieldTypeArray;
-
-    /// <summary>
-    /// The behavior of the datareader
-    /// </summary>
-    private CommandBehavior _commandBehavior;
-
-    /// <summary>
-    /// If set, then dispose of the command object when the reader is finished
-    /// </summary>
-    internal bool           _disposeCommand;
-
-#if MONO_SUPPORT_KEYREADER
-    /// <summary>
-    /// An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified
-    /// </summary>
-    private SqliteKeyReader _keyInfo;
-#endif
-    
-    /// <summary>
-    /// Internal constructor, initializes the datareader and sets up to begin executing statements
-    /// </summary>
-    /// <param name="cmd">The SqliteCommand this data reader is for</param>
-    /// <param name="behave">The expected behavior of the data reader</param>
-    internal SqliteDataReader(SqliteCommand cmd, CommandBehavior behave)
-    {
-      _command = cmd;
-      _commandBehavior = behave;
-      _activeStatementIndex = -1;
-      _activeStatement = null;
-      _rowsAffected = -1;
-      _fieldCount = -1;
-
-      if (_command != null)
-        NextResult();
-    }
-
-    /// <summary>
-    /// Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified.
-    /// </summary>
-    public override void Close()
-    {
-      if (_command != null)
-      {
-        while (NextResult())
-        {
-        }
-        _command.ClearDataReader();
-
-        // If the datareader's behavior includes closing the connection, then do so here.
-        if ((_commandBehavior & CommandBehavior.CloseConnection) != 0 && _command.Connection != null)
-          _command.Connection.Close();
-
-        if (_disposeCommand)
-          ((IDisposable)_command).Dispose();
-      }
-
-      _command = null;
-      _activeStatement = null;
-      _fieldTypeArray = null;
-
-#if MONO_SUPPORT_KEYREADER
-      if (_keyInfo != null)
-      {
-        _keyInfo.Dispose();
-        _keyInfo = null;
-      }
-#endif
-    }
-
-    /// <summary>
-    /// Disposes the datareader.  Calls Close() to ensure everything is cleaned up.
-    /// </summary>
-    protected override void Dispose(bool disposing)
-    {
-      base.Dispose(disposing);
-      GC.SuppressFinalize(this);
-    }
-
-    /// <summary>
-    /// Throw an error if the datareader is closed
-    /// </summary>
-    private void CheckClosed()
-    {
-      if (_command == null)
-        throw new InvalidOperationException("DataReader has been closed");
-    }
-
-    /// <summary>
-    /// Throw an error if a row is not loaded
-    /// </summary>
-    private void CheckValidRow()
-    {
-      if (_readingState != 0)
-        throw new InvalidOperationException("No current row");
-    }
-
-    /// <summary>
-    /// Enumerator support
-    /// </summary>
-    /// <returns>Returns a DbEnumerator object.</returns>
-    public override System.Collections.IEnumerator GetEnumerator()
-    {
-      return new DbEnumerator(this);
-    }
-
-    /// <summary>
-    /// Not implemented.  Returns 0
-    /// </summary>
-    public override int Depth
-    {
-      get
-      {
-        CheckClosed();
-        return 0;
-      }
-    }
-
-    /// <summary>
-    /// Returns the number of columns in the current resultset
-    /// </summary>
-    public override int FieldCount
-    {
-      get
-      {
-        CheckClosed();
-#if MONO_SUPPORT_KEYREADER
-        if (_keyInfo == null)
-          return _fieldCount;
-
-        return _fieldCount + _keyInfo.Count;
-#else
-       return _fieldCount;
-#endif
-      }
-    }
-
-    /// <summary>
-    /// Returns the number of visible fielsd in the current resultset
-    /// </summary>
-    public override int VisibleFieldCount
-    {
-      get
-      {
-        CheckClosed();
-        return _fieldCount;
-      }
-    }
-
-    /// <summary>
-    /// Sqlite is inherently un-typed.  All datatypes in Sqlite are natively strings.  The definition of the columns of a table
-    /// and the affinity of returned types are all we have to go on to type-restrict data in the reader.
-    /// 
-    /// This function attempts to verify that the type of data being requested of a column matches the datatype of the column.  In
-    /// the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob)
-    /// to a set of known types that closely match that affinity.  It's not an exact science, but its the best we can do.
-    /// </summary>
-    /// <returns>
-    /// This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity.
-    /// </returns>
-    /// <param name="i">The index of the column to type-check</param>
-    /// <param name="typ">The type we want to get out of the column</param>
-    private TypeAffinity VerifyType(int i, DbType typ)
-    {
-      CheckClosed();
-      CheckValidRow();
-      TypeAffinity affinity;
-
-      affinity = _activeStatement._sql.ColumnAffinity(_activeStatement, i);
-
-      switch (affinity)
-      {
-        case TypeAffinity.Int64:
-          if (typ == DbType.Int16) return affinity;
-          if (typ == DbType.Int32) return affinity;
-          if (typ == DbType.Int64) return affinity;
-          if (typ == DbType.Boolean) return affinity;
-          if (typ == DbType.Byte) return affinity;
-          if (typ == DbType.DateTime && _command.Connection._sql._datetimeFormat == SqliteDateFormats.Ticks) return affinity;
-          if (typ == DbType.Single) return affinity;
-          if (typ == DbType.Double) return affinity;
-          if (typ == DbType.Decimal) return affinity;
-          break;
-        case TypeAffinity.Double:
-          if (typ == DbType.Single) return affinity;
-          if (typ == DbType.Double) return affinity;
-          if (typ == DbType.Decimal) return affinity;
-          break;
-        case TypeAffinity.Text:
-          if (typ == DbType.SByte) return affinity;
-          if (typ == DbType.String) return affinity;
-          if (typ == DbType.SByte) return affinity;
-          if (typ == DbType.Guid) return affinity;
-          if (typ == DbType.DateTime) return affinity;
-          break;
-        case TypeAffinity.Blob:
-          if (typ == DbType.Guid) return affinity;
-          if (typ == DbType.String) return affinity;
-          if (typ == DbType.Binary) return affinity;
-          break;
-      }
-
-      throw new InvalidCastException();
-    }
-
-    /// <summary>
-    /// Retrieves the column as a boolean value
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>bool</returns>
-    public override bool GetBoolean(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetBoolean(i - VisibleFieldCount);
-#endif
-      
-      VerifyType(i, DbType.Boolean);
-      return Convert.ToBoolean(GetValue(i), CultureInfo.CurrentCulture);
-    }
-
-    /// <summary>
-    /// Retrieves the column as a single byte value
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>byte</returns>
-    public override byte GetByte(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetByte(i - VisibleFieldCount);
-#endif
-      
-      VerifyType(i, DbType.Byte);
-      return Convert.ToByte(_activeStatement._sql.GetInt32(_activeStatement, i));
-    }
-
-    /// <summary>
-    /// Retrieves a column as an array of bytes (blob)
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <param name="fieldOffset">The zero-based index of where to begin reading the data</param>
-    /// <param name="buffer">The buffer to write the bytes into</param>
-    /// <param name="bufferoffset">The zero-based index of where to begin writing into the array</param>
-    /// <param name="length">The number of bytes to retrieve</param>
-    /// <returns>The actual number of bytes written into the array</returns>
-    /// <remarks>
-    /// To determine the number of bytes in the column, pass a null value for the buffer.  The total length will be returned.
-    /// </remarks>
-    public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetBytes(i - VisibleFieldCount, fieldOffset, buffer, bufferoffset, length);
-#endif
-      
-      VerifyType(i, DbType.Binary);
-      return _activeStatement._sql.GetBytes(_activeStatement, i, (int)fieldOffset, buffer, bufferoffset, length);
-    }
-
-    /// <summary>
-    /// Returns the column as a single character
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>char</returns>
-    public override char GetChar(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetChar(i - VisibleFieldCount);
-#endif
-      
-      VerifyType(i, DbType.SByte);
-      return Convert.ToChar(_activeStatement._sql.GetInt32(_activeStatement, i));
-    }
-
-    /// <summary>
-    /// Retrieves a column as an array of chars (blob)
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <param name="fieldoffset">The zero-based index of where to begin reading the data</param>
-    /// <param name="buffer">The buffer to write the characters into</param>
-    /// <param name="bufferoffset">The zero-based index of where to begin writing into the array</param>
-    /// <param name="length">The number of bytes to retrieve</param>
-    /// <returns>The actual number of characters written into the array</returns>
-    /// <remarks>
-    /// To determine the number of characters in the column, pass a null value for the buffer.  The total length will be returned.
-    /// </remarks>
-    public override long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetChars(i - VisibleFieldCount, fieldoffset, buffer, bufferoffset, length);
-#endif
-      
-      VerifyType(i, DbType.String);
-      return _activeStatement._sql.GetChars(_activeStatement, i, (int)fieldoffset, buffer, bufferoffset, length);
-    }
-
-    /// <summary>
-    /// Retrieves the name of the back-end datatype of the column
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>string</returns>
-    public override string GetDataTypeName(int i)
-    {
-      CheckClosed();
-
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetDataTypeName(i - VisibleFieldCount);
-#endif
-      
-      SqliteType typ = GetSqliteType(i);
-      if (typ.Type == DbType.Object) return SqliteConvert.SqliteTypeToType(typ).Name;
-      return _activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity);
-    }
-
-    /// <summary>
-    /// Retrieve the column as a date/time value
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>DateTime</returns>
-    public override DateTime GetDateTime(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetDateTime(i - VisibleFieldCount);
-#endif
-      
-      VerifyType(i, DbType.DateTime);
-      return _activeStatement._sql.GetDateTime(_activeStatement, i);
-    }
-
-    /// <summary>
-    /// Retrieve the column as a decimal value
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>decimal</returns>
-    public override decimal GetDecimal(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetDecimal(i - VisibleFieldCount);
-#endif
-      
-      VerifyType(i, DbType.Decimal);
-      return Convert.ToDecimal(_activeStatement._sql.GetDouble(_activeStatement, i));
-    }
-
-    /// <summary>
-    /// Returns the column as a double
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>double</returns>
-    public override double GetDouble(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetDouble(i - VisibleFieldCount);
-#endif
-      
-      VerifyType(i, DbType.Double);
-      return _activeStatement._sql.GetDouble(_activeStatement, i);
-    }
-
-    /// <summary>
-    /// Returns the .NET type of a given column
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>Type</returns>
-    public override Type GetFieldType(int i)
-    {
-      CheckClosed();
-
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetFieldType(i - VisibleFieldCount);
-#endif
-      
-      return SqliteConvert.SqliteTypeToType(GetSqliteType(i));
-    }
-
-    /// <summary>
-    /// Returns a column as a float value
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>float</returns>
-    public override float GetFloat(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetFloat(i - VisibleFieldCount);
-#endif
-      
-      VerifyType(i, DbType.Single);
-      return Convert.ToSingle(_activeStatement._sql.GetDouble(_activeStatement, i));
-    }
-
-    /// <summary>
-    /// Returns the column as a Guid
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>Guid</returns>
-    public override Guid GetGuid(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetGuid(i - VisibleFieldCount);
-#endif
-      
-      TypeAffinity affinity = VerifyType(i, DbType.Guid);
-      if (affinity == TypeAffinity.Blob)
-      {
-        byte[] buffer = new byte[16];
-        _activeStatement._sql.GetBytes(_activeStatement, i, 0, buffer, 0, 16);
-        return new Guid(buffer);
-      }
-      else
-        return new Guid(_activeStatement._sql.GetText(_activeStatement, i));
-    }
-
-    /// <summary>
-    /// Returns the column as a short
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>Int16</returns>
-    public override Int16 GetInt16(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetInt16(i - VisibleFieldCount);
-#endif
-      
-      VerifyType(i, DbType.Int16);
-      return Convert.ToInt16(_activeStatement._sql.GetInt32(_activeStatement, i));
-    }
-
-    /// <summary>
-    /// Retrieves the column as an int
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>Int32</returns>
-    public override Int32 GetInt32(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetInt32(i - VisibleFieldCount);
-#endif
-      
-      VerifyType(i, DbType.Int32);
-      return _activeStatement._sql.GetInt32(_activeStatement, i);
-    }
-
-    /// <summary>
-    /// Retrieves the column as a long
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>Int64</returns>
-    public override Int64 GetInt64(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetInt64(i - VisibleFieldCount);
-#endif
-      
-      VerifyType(i, DbType.Int64);
-      return _activeStatement._sql.GetInt64(_activeStatement, i);
-    }
-
-    /// <summary>
-    /// Retrieves the name of the column
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>string</returns>
-    public override string GetName(int i)
-    {
-      CheckClosed();
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetName(i - VisibleFieldCount);
-#endif
-      
-      return _activeStatement._sql.ColumnName(_activeStatement, i);
-    }
-
-    /// <summary>
-    /// Retrieves the i of a column, given its name
-    /// </summary>
-    /// <param name="name">The name of the column to retrieve</param>
-    /// <returns>The int i of the column</returns>
-    public override int GetOrdinal(string name)
-    {
-      CheckClosed();
-      int r = _activeStatement._sql.ColumnIndex(_activeStatement, name);
-#if MONO_SUPPORT_KEYREADER
-      if (r == -1 && _keyInfo != null)
-      {
-        r = _keyInfo.GetOrdinal(name);
-        if (r > -1) r += VisibleFieldCount;
-      }
-#endif
-      
-      return r;
-    }
-
-    /// <summary>
-    /// Schema information in Sqlite is difficult to map into .NET conventions, so a lot of work must be done
-    /// to gather the necessary information so it can be represented in an ADO.NET manner.
-    /// </summary>
-    /// <returns>Returns a DataTable containing the schema information for the active SELECT statement being processed.</returns>
-    public override DataTable GetSchemaTable()
-    {
-      return GetSchemaTable(true, false);
-    }
-
-    internal DataTable GetSchemaTable(bool wantUniqueInfo, bool wantDefaultValue)
-    {
-      CheckClosed();
-
-      DataTable tbl = new DataTable("SchemaTable");
-      DataTable tblIndexes = null;
-      DataTable tblIndexColumns;
-      DataRow row;
-      string temp;
-      string strCatalog = "";
-      string strTable = "";
-      string strColumn = "";
-
-      tbl.Locale = CultureInfo.InvariantCulture;
-      tbl.Columns.Add(SchemaTableColumn.ColumnName, typeof(String));
-      tbl.Columns.Add(SchemaTableColumn.ColumnOrdinal, typeof(int));
-      tbl.Columns.Add(SchemaTableColumn.ColumnSize, typeof(int));
-      tbl.Columns.Add(SchemaTableColumn.NumericPrecision, typeof(short));
-      tbl.Columns.Add(SchemaTableColumn.NumericScale, typeof(short));
-      tbl.Columns.Add(SchemaTableColumn.IsUnique, typeof(Boolean));
-      tbl.Columns.Add(SchemaTableColumn.IsKey, typeof(Boolean));
-      tbl.Columns.Add(SchemaTableOptionalColumn.BaseServerName, typeof(string));
-      tbl.Columns.Add(SchemaTableOptionalColumn.BaseCatalogName, typeof(String));
-      tbl.Columns.Add(SchemaTableColumn.BaseColumnName, typeof(String));
-      tbl.Columns.Add(SchemaTableColumn.BaseSchemaName, typeof(String));
-      tbl.Columns.Add(SchemaTableColumn.BaseTableName, typeof(String));
-      tbl.Columns.Add(SchemaTableColumn.DataType, typeof(Type));
-      tbl.Columns.Add(SchemaTableColumn.AllowDBNull, typeof(Boolean));
-      tbl.Columns.Add(SchemaTableColumn.ProviderType, typeof(int));
-      tbl.Columns.Add(SchemaTableColumn.IsAliased, typeof(Boolean));
-      tbl.Columns.Add(SchemaTableColumn.IsExpression, typeof(Boolean));
-      tbl.Columns.Add(SchemaTableOptionalColumn.IsAutoIncrement, typeof(Boolean));
-      tbl.Columns.Add(SchemaTableOptionalColumn.IsRowVersion, typeof(Boolean));
-      tbl.Columns.Add(SchemaTableOptionalColumn.IsHidden, typeof(Boolean));
-      tbl.Columns.Add(SchemaTableColumn.IsLong, typeof(Boolean));
-      tbl.Columns.Add(SchemaTableOptionalColumn.IsReadOnly, typeof(Boolean));
-      tbl.Columns.Add(SchemaTableOptionalColumn.ProviderSpecificDataType, typeof(Type));
-      tbl.Columns.Add(SchemaTableOptionalColumn.DefaultValue, typeof(object));
-      tbl.Columns.Add("DataTypeName", typeof(string));
-
-      tbl.BeginLoadData();
-
-      for (int n = 0; n < _fieldCount; n++)
-      {
-        row = tbl.NewRow();
-
-        // Default settings for the column
-        row[SchemaTableColumn.ColumnName] = GetName(n);
-        row[SchemaTableColumn.ColumnOrdinal] = n;
-        row[SchemaTableColumn.ColumnSize] = SqliteConvert.DbTypeToColumnSize(GetSqliteType(n).Type);
-        row[SchemaTableColumn.NumericPrecision] = 255;
-        row[SchemaTableColumn.NumericScale] = 255;
-        row[SchemaTableColumn.ProviderType] = GetSqliteType(n).Type;
-        row[SchemaTableColumn.IsLong] = (GetSqliteType(n).Type == DbType.Binary);
-        row[SchemaTableColumn.AllowDBNull] = true;
-        row[SchemaTableOptionalColumn.IsReadOnly] = false;
-        row[SchemaTableOptionalColumn.IsRowVersion] = false;
-        row[SchemaTableColumn.IsUnique] = false;
-        row[SchemaTableColumn.IsKey] = false;
-        row[SchemaTableOptionalColumn.IsAutoIncrement] = false;
-        row[SchemaTableOptionalColumn.IsReadOnly] = false;
-        row[SchemaTableColumn.DataType] = GetFieldType(n);
-        row[SchemaTableOptionalColumn.IsHidden] = false;
-
-        strColumn = _command.Connection._sql.ColumnOriginalName(_activeStatement, n);
-        if (String.IsNullOrEmpty(strColumn) == false) row[SchemaTableColumn.BaseColumnName] = strColumn;
-        
-        row[SchemaTableColumn.IsExpression] = String.IsNullOrEmpty(strColumn);
-        row[SchemaTableColumn.IsAliased] = (String.Compare(GetName(n), strColumn, true, CultureInfo.InvariantCulture) != 0);
-
-        temp = _command.Connection._sql.ColumnTableName(_activeStatement, n);
-        if (String.IsNullOrEmpty(temp) == false) row[SchemaTableColumn.BaseTableName] = temp;
-
-        temp = _command.Connection._sql.ColumnDatabaseName(_activeStatement, n);
-        if (String.IsNullOrEmpty(temp) == false) row[SchemaTableOptionalColumn.BaseCatalogName] = temp;
-
-        string dataType = null;
-        // If we have a table-bound column, extract the extra information from it
-        if (String.IsNullOrEmpty(strColumn) == false)
-        {
-          string collSeq;
-          bool bNotNull;
-          bool bPrimaryKey;
-          bool bAutoIncrement;
-          string[] arSize;
-
-          // Get the column meta data
-          _command.Connection._sql.ColumnMetaData(
-            (string)row[SchemaTableOptionalColumn.BaseCatalogName],
-            (string)row[SchemaTableColumn.BaseTableName],
-            strColumn,
-            out dataType, out collSeq, out bNotNull, out bPrimaryKey, out bAutoIncrement);
-
-          if (bNotNull || bPrimaryKey) row[SchemaTableColumn.AllowDBNull] = false;
-
-          row[SchemaTableColumn.IsKey] = bPrimaryKey;
-          row[SchemaTableOptionalColumn.IsAutoIncrement] = bAutoIncrement;
-
-          // For types like varchar(50) and such, extract the size
-          arSize = dataType.Split('(');
-          if (arSize.Length > 1)
-          {
-            dataType = arSize[0];
-            arSize = arSize[1].Split(')');
-            if (arSize.Length > 1)
-            {
-              arSize = arSize[0].Split(',', '.');
-              if (GetSqliteType(n).Type == DbType.String || GetSqliteType(n).Type == DbType.Binary)
-              {
-                row[SchemaTableColumn.ColumnSize] = Convert.ToInt32(arSize[0], CultureInfo.InvariantCulture);
-              }
-              else
-              {
-                row[SchemaTableColumn.NumericPrecision] = Convert.ToInt32(arSize[0], CultureInfo.InvariantCulture);
-                if (arSize.Length > 1)
-                  row[SchemaTableColumn.NumericScale] = Convert.ToInt32(arSize[1], CultureInfo.InvariantCulture);
-              }
-            }
-          }
-
-          if (wantDefaultValue)
-          {
-            // Determine the default value for the column, which sucks because we have to query the schema for each column
-            using (SqliteCommand cmdTable = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].TABLE_INFO([{1}])",
-              row[SchemaTableOptionalColumn.BaseCatalogName],
-              row[SchemaTableColumn.BaseTableName]
-              ), _command.Connection))
-            using (DbDataReader rdTable = cmdTable.ExecuteReader())
-            {
-              // Find the matching column
-              while (rdTable.Read())
-              {
-                if (String.Compare((string)row[SchemaTableColumn.BaseColumnName], rdTable.GetString(1), true, CultureInfo.InvariantCulture) == 0)
-                {
-                  if (rdTable.IsDBNull(4) == false)
-                    row[SchemaTableOptionalColumn.DefaultValue] = rdTable[4];
-
-                  break;
-                }
-              }
-            }
-          }
-
-          // Determine IsUnique properly, which is a pain in the butt!
-          if (wantUniqueInfo)
-          {
-            if ((string)row[SchemaTableOptionalColumn.BaseCatalogName] != strCatalog
-              || (string)row[SchemaTableColumn.BaseTableName] != strTable)
-            {
-              strCatalog = (string)row[SchemaTableOptionalColumn.BaseCatalogName];
-              strTable = (string)row[SchemaTableColumn.BaseTableName];
-
-              tblIndexes = _command.Connection.GetSchema("Indexes", new string[] {
-                (string)row[SchemaTableOptionalColumn.BaseCatalogName],
-                null,
-                (string)row[SchemaTableColumn.BaseTableName],
-                null });
-            }
-
-            foreach (DataRow rowIndexes in tblIndexes.Rows)
-            {
-              tblIndexColumns = _command.Connection.GetSchema("IndexColumns", new string[] {
-                (string)row[SchemaTableOptionalColumn.BaseCatalogName],
-                null,
-                (string)row[SchemaTableColumn.BaseTableName],
-                (string)rowIndexes["INDEX_NAME"],
-                null
-                });
-              foreach (DataRow rowColumnIndex in tblIndexColumns.Rows)
-              {
-                if (String.Compare((string)rowColumnIndex["COLUMN_NAME"], strColumn, true, CultureInfo.InvariantCulture) == 0)
-                {
-                  if (tblIndexColumns.Rows.Count == 1 && (bool)row[SchemaTableColumn.AllowDBNull] == false)
-                    row[SchemaTableColumn.IsUnique] = rowIndexes["UNIQUE"];
-
-                  break;
-                }
-              }
-            }
-          }
-        }
-        
-        if (String.IsNullOrEmpty(dataType))
-        {
-          TypeAffinity affin;
-          dataType = _activeStatement._sql.ColumnType(_activeStatement, n, out affin);
-        }
-
-        if (String.IsNullOrEmpty(dataType) == false)
-          row["DataTypeName"] = dataType;
-
-        tbl.Rows.Add(row);
-      }
-
-#if MONO_SUPPORT_KEYREADER
-      if (_keyInfo != null)
-        _keyInfo.AppendSchemaTable(tbl);
-#endif
-      
-      tbl.AcceptChanges();
-      tbl.EndLoadData();
-
-      return tbl;
-    }
-
-    /// <summary>
-    /// Retrieves the column as a string
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>string</returns>
-    public override string GetString(int i)
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetString(i - VisibleFieldCount);
-#endif
-      
-      VerifyType(i, DbType.String);
-      return _activeStatement._sql.GetText(_activeStatement, i);
-    }
-
-    /// <summary>
-    /// Retrieves the column as an object corresponding to the underlying datatype of the column
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>object</returns>
-    public override object GetValue(int i)
-    {
-      CheckClosed();
-
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.GetValue(i - VisibleFieldCount);
-#endif
-      SqliteType typ = GetSqliteType(i);
-      typ.Affinity = _activeStatement._sql.ColumnAffinity(_activeStatement, i);
-      return _activeStatement._sql.GetValue(_activeStatement, i, ref typ);
-    }
-
-    /// <summary>
-    /// Retreives the values of multiple columns, up to the size of the supplied array
-    /// </summary>
-    /// <param name="values">The array to fill with values from the columns in the current resultset</param>
-    /// <returns>The number of columns retrieved</returns>
-    public override int GetValues(object[] values)
-    {
-      int nMax = FieldCount;
-      if (values.Length < nMax) nMax = values.Length;
-
-      for (int n = 0; n < nMax; n++)
-      {
-        values[n] = GetValue(n);
-      }
-
-      return nMax;
-    }
-
-    /// <summary>
-    /// Returns True if the resultset has rows that can be fetched
-    /// </summary>
-    public override bool HasRows
-    {
-      get
-      {
-        CheckClosed();
-        return (_readingState != 1);
-      }
-    }
-
-    /// <summary>
-    /// Returns True if the data reader is closed
-    /// </summary>
-    public override bool IsClosed
-    {
-      get { return (_command == null); }
-    }
-
-    /// <summary>
-    /// Returns True if the specified column is null
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>True or False</returns>
-    public override bool IsDBNull(int i)
-    {
-      CheckClosed();
-#if MONO_SUPPORT_KEYREADER
-      if (i >= VisibleFieldCount && _keyInfo != null)
-        return _keyInfo.IsDBNull(i - VisibleFieldCount);
-#endif
-      return _activeStatement._sql.IsNull(_activeStatement, i);
-    }
-
-    /// <summary>
-    /// Moves to the next resultset in multiple row-returning SQL command.
-    /// </summary>
-    /// <returns>True if the command was successful and a new resultset is available, False otherwise.</returns>
-    public override bool NextResult()
-    {
-      CheckClosed();
-
-      SqliteStatement stmt = null;
-      int fieldCount;
-
-      while (true)
-      {
-        if (_activeStatement != null && stmt == null)
-        {
-          // Reset the previously-executed statement
-          _activeStatement._sql.Reset(_activeStatement);
-          
-          // If we're only supposed to return a single rowset, step through all remaining statements once until
-          // they are all done and return false to indicate no more resultsets exist.
-          if ((_commandBehavior & CommandBehavior.SingleResult) != 0)
-          {
-            for (; ; )
-            {
-              stmt = _command.GetStatement(_activeStatementIndex + 1);
-              if (stmt == null) break;
-              _activeStatementIndex++;
-
-              stmt._sql.Step(stmt);
-              if (stmt._sql.ColumnCount(stmt) == 0)
-              {
-                if (_rowsAffected == -1) _rowsAffected = 0;
-                _rowsAffected += stmt._sql.Changes;
-              }
-              stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such!
-            }
-            return false;
-          }
-        }
-
-        // Get the next statement to execute
-        stmt = _command.GetStatement(_activeStatementIndex + 1);
-
-        // If we've reached the end of the statements, return false, no more resultsets
-        if (stmt == null)
-          return false;
-
-        // If we were on a current resultset, set the state to "done reading" for it
-        if (_readingState < 1)
-          _readingState = 1;
-
-        _activeStatementIndex++;
-
-        fieldCount = stmt._sql.ColumnCount(stmt);
-
-        // If the statement is not a select statement or we're not retrieving schema only, then perform the initial step
-        if ((_commandBehavior & CommandBehavior.SchemaOnly) == 0 || fieldCount == 0)
-        {
-          if (stmt._sql.Step(stmt))
-          {
-            _readingState = -1;
-          }
-          else if (fieldCount == 0) // No rows returned, if fieldCount is zero, skip to the next statement
-          {
-            if (_rowsAffected == -1) _rowsAffected = 0;
-            _rowsAffected += stmt._sql.Changes;
-            stmt._sql.Reset(stmt);
-            continue; // Skip this command and move to the next, it was not a row-returning resultset
-          }
-          else // No rows, fieldCount is non-zero so stop here
-          {
-            _readingState = 1; // This command returned columns but no rows, so return true, but HasRows = false and Read() returns false
-          }
-        }
-
-        // Ahh, we found a row-returning resultset eligible to be returned!
-        _activeStatement = stmt;
-        _fieldCount = fieldCount;
-        _fieldTypeArray = null;
-
-        if ((_commandBehavior & CommandBehavior.KeyInfo) != 0)
-          LoadKeyInfo();
-
-        return true;
-      }
-    }
-
-    /// <summary>
-    /// Retrieves the SqliteType for a given column, and caches it to avoid repetetive interop calls.
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>A SqliteType structure</returns>
-    private SqliteType GetSqliteType(int i)
-    {
-      if (_fieldTypeArray == null) _fieldTypeArray = new SqliteType[VisibleFieldCount];
-
-      if (_fieldTypeArray[i].Affinity == TypeAffinity.Uninitialized || _fieldTypeArray[i].Affinity == TypeAffinity.Null)
-        _fieldTypeArray[i].Type = SqliteConvert.TypeNameToDbType(_activeStatement._sql.ColumnType(_activeStatement, i, out _fieldTypeArray[i].Affinity));
-      return _fieldTypeArray[i];
-    }
-
-    /// <summary>
-    /// Reads the next row from the resultset
-    /// </summary>
-    /// <returns>True if a new row was successfully loaded and is ready for processing</returns>
-    public override bool Read()
-    {
-      CheckClosed();
-
-      if (_readingState == -1) // First step was already done at the NextResult() level, so don't step again, just return true.
-      {
-        _readingState = 0;
-        return true;
-      }
-      else if (_readingState == 0) // Actively reading rows
-      {
-        if (_activeStatement._sql.Step(_activeStatement) == true)
-        {
-#if MONO_SUPPORT_KEYREADER
-          if (_keyInfo != null)
-            _keyInfo.Reset();
-#endif
-         
-          return true;
-        }
-
-        _readingState = 1; // Finished reading rows
-      }
-
-      return false;
-    }
-
-    /// <summary>
-    /// Retrieve the count of records affected by an update/insert command.  Only valid once the data reader is closed!
-    /// </summary>
-    public override int RecordsAffected
-    {
-      get { return _rowsAffected; }
-    }
-
-    /// <summary>
-    /// Indexer to retrieve data from a column given its name
-    /// </summary>
-    /// <param name="name">The name of the column to retrieve data for</param>
-    /// <returns>The value contained in the column</returns>
-    public override object this[string name]
-    {
-      get { return GetValue(GetOrdinal(name)); }
-    }
-
-    /// <summary>
-    /// Indexer to retrieve data from a column given its i
-    /// </summary>
-    /// <param name="i">The index of the column to retrieve</param>
-    /// <returns>The value contained in the column</returns>
-    public override object this[int i]
-    {
-      get { return GetValue(i); }
-    }
-
-    private void LoadKeyInfo()
-    {
-#if MONO_SUPPORT_KEYREADER
-      if (_keyInfo != null)
-        _keyInfo.Dispose();
-
-      _keyInfo = new SqliteKeyReader(_command.Connection, this, _activeStatement);
-#endif
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Data.Common;\r
+  using System.Collections.Generic;\r
+  using System.Globalization;\r
+  using System.Reflection;\r
+\r
+  /// <summary>\r
+  /// SQLite implementation of DbDataReader.\r
+  /// </summary>\r
+  public sealed class SQLiteDataReader : DbDataReader\r
+  {\r
+    /// <summary>\r
+    /// Underlying command this reader is attached to\r
+    /// </summary>\r
+    private SQLiteCommand _command;\r
+    /// <summary>\r
+    /// Index of the current statement in the command being processed\r
+    /// </summary>\r
+    private int _activeStatementIndex;\r
+    /// <summary>\r
+    /// Current statement being Read()\r
+    /// </summary>\r
+    private SQLiteStatement _activeStatement;\r
+    /// <summary>\r
+    /// State of the current statement being processed.\r
+    /// -1 = First Step() executed, so the first Read() will be ignored\r
+    ///  0 = Actively reading\r
+    ///  1 = Finished reading\r
+    ///  2 = Non-row-returning statement, no records\r
+    /// </summary>\r
+    private int _readingState;\r
+    /// <summary>\r
+    /// Number of records affected by the insert/update statements executed on the command\r
+    /// </summary>\r
+    private int _rowsAffected;\r
+    /// <summary>\r
+    /// Count of fields (columns) in the row-returning statement currently being processed\r
+    /// </summary>\r
+    private int _fieldCount;\r
+    /// <summary>\r
+    /// Datatypes of active fields (columns) in the current statement, used for type-restricting data\r
+    /// </summary>\r
+    private SQLiteType[] _fieldTypeArray;\r
+\r
+    /// <summary>\r
+    /// The behavior of the datareader\r
+    /// </summary>\r
+    private CommandBehavior _commandBehavior;\r
+\r
+    /// <summary>\r
+    /// If set, then dispose of the command object when the reader is finished\r
+    /// </summary>\r
+    internal bool _disposeCommand;\r
+\r
+    /// <summary>\r
+    /// An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified\r
+    /// </summary>\r
+    private SQLiteKeyReader _keyInfo;\r
+\r
+    internal long _version; // Matches the version of the connection\r
+\r
+    /// <summary>\r
+    /// Internal constructor, initializes the datareader and sets up to begin executing statements\r
+    /// </summary>\r
+    /// <param name="cmd">The SQLiteCommand this data reader is for</param>\r
+    /// <param name="behave">The expected behavior of the data reader</param>\r
+    internal SQLiteDataReader(SQLiteCommand cmd, CommandBehavior behave)\r
+    {\r
+      _command = cmd;\r
+      _version = _command.Connection._version;\r
+\r
+      _commandBehavior = behave;\r
+      _activeStatementIndex = -1;\r
+      _activeStatement = null;\r
+      _rowsAffected = -1;\r
+      _fieldCount = 0;\r
+\r
+      if (_command != null)\r
+        NextResult();\r
+    }\r
+\r
+    internal void Cancel()\r
+    {\r
+      _version = 0;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified.\r
+    /// </summary>\r
+    public override void Close()\r
+    {\r
+      try\r
+      {\r
+        if (_command != null)\r
+        {\r
+          try\r
+          {\r
+            try\r
+            {\r
+              // Make sure we've not been canceled\r
+              if (_version != 0)\r
+              {\r
+                try\r
+                {\r
+                  while (NextResult())\r
+                  {\r
+                  }\r
+                }\r
+                catch\r
+                {\r
+                }\r
+              }\r
+              _command.ClearDataReader();\r
+            }\r
+            finally\r
+            {\r
+              // If the datareader's behavior includes closing the connection, then do so here.\r
+              if ((_commandBehavior & CommandBehavior.CloseConnection) != 0 && _command.Connection != null)\r
+                _command.Connection.Close();\r
+            }\r
+          }\r
+          finally\r
+          {\r
+            if (_disposeCommand)\r
+              _command.Dispose();\r
+          }\r
+        }\r
+\r
+        _command = null;\r
+        _activeStatement = null;\r
+        _fieldTypeArray = null;\r
+      }\r
+      finally\r
+      {\r
+        if (_keyInfo != null)\r
+        {\r
+          _keyInfo.Dispose();\r
+          _keyInfo = null;\r
+        }\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Throw an error if the datareader is closed\r
+    /// </summary>\r
+    private void CheckClosed()\r
+    {\r
+      if (_command == null)\r
+        throw new InvalidOperationException("DataReader has been closed");\r
+\r
+      if (_version == 0)\r
+        throw new SQLiteException((int)SQLiteErrorCode.Abort, "Execution was aborted by the user");\r
+\r
+      if (_command.Connection.State != ConnectionState.Open || _command.Connection._version != _version)\r
+        throw new InvalidOperationException("Connection was closed, statement was terminated");\r
+    }\r
+\r
+    /// <summary>\r
+    /// Throw an error if a row is not loaded\r
+    /// </summary>\r
+    private void CheckValidRow()\r
+    {\r
+      if (_readingState != 0)\r
+        throw new InvalidOperationException("No current row");\r
+    }\r
+\r
+    /// <summary>\r
+    /// Enumerator support\r
+    /// </summary>\r
+    /// <returns>Returns a DbEnumerator object.</returns>\r
+    public override Collections.IEnumerator GetEnumerator()\r
+    {\r
+      return new DbEnumerator(this, ((_commandBehavior & CommandBehavior.CloseConnection) == CommandBehavior.CloseConnection));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Not implemented.  Returns 0\r
+    /// </summary>\r
+    public override int Depth\r
+    {\r
+      get\r
+      {\r
+        CheckClosed();\r
+        return 0;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the number of columns in the current resultset\r
+    /// </summary>\r
+    public override int FieldCount\r
+    {\r
+      get\r
+      {\r
+        CheckClosed();\r
+        if (_keyInfo == null)\r
+          return _fieldCount;\r
+\r
+        return _fieldCount + _keyInfo.Count;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the number of visible fielsd in the current resultset\r
+    /// </summary>\r
+    public override int VisibleFieldCount\r
+    {\r
+      get\r
+      {\r
+        CheckClosed();\r
+        return _fieldCount;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// SQLite is inherently un-typed.  All datatypes in SQLite are natively strings.  The definition of the columns of a table\r
+    /// and the affinity of returned types are all we have to go on to type-restrict data in the reader.\r
+    /// \r
+    /// This function attempts to verify that the type of data being requested of a column matches the datatype of the column.  In\r
+    /// the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob)\r
+    /// to a set of known types that closely match that affinity.  It's not an exact science, but its the best we can do.\r
+    /// </summary>\r
+    /// <returns>\r
+    /// This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity.\r
+    /// </returns>\r
+    /// <param name="i">The index of the column to type-check</param>\r
+    /// <param name="typ">The type we want to get out of the column</param>\r
+    private TypeAffinity VerifyType(int i, DbType typ)\r
+    {\r
+      CheckClosed();\r
+      CheckValidRow();\r
+      TypeAffinity affinity = GetSQLiteType(i).Affinity;\r
+\r
+      switch (affinity)\r
+      {\r
+        case TypeAffinity.Int64:\r
+          if (typ == DbType.Int16) return affinity;\r
+          if (typ == DbType.Int32) return affinity;\r
+          if (typ == DbType.Int64) return affinity;\r
+          if (typ == DbType.Boolean) return affinity;\r
+          if (typ == DbType.Byte) return affinity;\r
+          if (typ == DbType.DateTime) return affinity;\r
+          if (typ == DbType.Single) return affinity;\r
+          if (typ == DbType.Double) return affinity;\r
+          if (typ == DbType.Decimal) return affinity;\r
+          break;\r
+        case TypeAffinity.Double:\r
+          if (typ == DbType.Single) return affinity;\r
+          if (typ == DbType.Double) return affinity;\r
+          if (typ == DbType.Decimal) return affinity;\r
+          if (typ == DbType.DateTime) return affinity;\r
+          break;\r
+        case TypeAffinity.Text:\r
+          if (typ == DbType.SByte) return affinity;\r
+          if (typ == DbType.String) return affinity;\r
+          if (typ == DbType.SByte) return affinity;\r
+          if (typ == DbType.Guid) return affinity;\r
+          if (typ == DbType.DateTime) return affinity;\r
+          if (typ == DbType.Decimal) return affinity;\r
+          break;\r
+        case TypeAffinity.Blob:\r
+          if (typ == DbType.Guid) return affinity;\r
+          if (typ == DbType.String) return affinity;\r
+          if (typ == DbType.Binary) return affinity;\r
+          break;\r
+      }\r
+\r
+      throw new InvalidCastException();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves the column as a boolean value\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>bool</returns>\r
+    public override bool GetBoolean(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetBoolean(i - VisibleFieldCount);\r
+\r
+      VerifyType(i, DbType.Boolean);\r
+      return Convert.ToBoolean(GetValue(i), CultureInfo.CurrentCulture);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves the column as a single byte value\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>byte</returns>\r
+    public override byte GetByte(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetByte(i - VisibleFieldCount);\r
+\r
+      VerifyType(i, DbType.Byte);\r
+      return Convert.ToByte(_activeStatement._sql.GetInt32(_activeStatement, i));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves a column as an array of bytes (blob)\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <param name="fieldOffset">The zero-based index of where to begin reading the data</param>\r
+    /// <param name="buffer">The buffer to write the bytes into</param>\r
+    /// <param name="bufferoffset">The zero-based index of where to begin writing into the array</param>\r
+    /// <param name="length">The number of bytes to retrieve</param>\r
+    /// <returns>The actual number of bytes written into the array</returns>\r
+    /// <remarks>\r
+    /// To determine the number of bytes in the column, pass a null value for the buffer.  The total length will be returned.\r
+    /// </remarks>\r
+    public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetBytes(i - VisibleFieldCount, fieldOffset, buffer, bufferoffset, length);\r
+\r
+      VerifyType(i, DbType.Binary);\r
+      return _activeStatement._sql.GetBytes(_activeStatement, i, (int)fieldOffset, buffer, bufferoffset, length);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the column as a single character\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>char</returns>\r
+    public override char GetChar(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetChar(i - VisibleFieldCount);\r
+\r
+      VerifyType(i, DbType.SByte);\r
+      return Convert.ToChar(_activeStatement._sql.GetInt32(_activeStatement, i));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves a column as an array of chars (blob)\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <param name="fieldoffset">The zero-based index of where to begin reading the data</param>\r
+    /// <param name="buffer">The buffer to write the characters into</param>\r
+    /// <param name="bufferoffset">The zero-based index of where to begin writing into the array</param>\r
+    /// <param name="length">The number of bytes to retrieve</param>\r
+    /// <returns>The actual number of characters written into the array</returns>\r
+    /// <remarks>\r
+    /// To determine the number of characters in the column, pass a null value for the buffer.  The total length will be returned.\r
+    /// </remarks>\r
+    public override long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetChars(i - VisibleFieldCount, fieldoffset, buffer, bufferoffset, length);\r
+\r
+      VerifyType(i, DbType.String);\r
+      return _activeStatement._sql.GetChars(_activeStatement, i, (int)fieldoffset, buffer, bufferoffset, length);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves the name of the back-end datatype of the column\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>string</returns>\r
+    public override string GetDataTypeName(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetDataTypeName(i - VisibleFieldCount);\r
+\r
+      SQLiteType typ = GetSQLiteType(i);\r
+      if (typ.Type == DbType.Object) return SQLiteConvert.SQLiteTypeToType(typ).Name;\r
+      return _activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieve the column as a date/time value\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>DateTime</returns>\r
+    public override DateTime GetDateTime(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetDateTime(i - VisibleFieldCount);\r
+\r
+      VerifyType(i, DbType.DateTime);\r
+      return _activeStatement._sql.GetDateTime(_activeStatement, i);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieve the column as a decimal value\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>decimal</returns>\r
+    public override decimal GetDecimal(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetDecimal(i - VisibleFieldCount);\r
+\r
+      VerifyType(i, DbType.Decimal);\r
+      return Decimal.Parse(_activeStatement._sql.GetText(_activeStatement, i), NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the column as a double\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>double</returns>\r
+    public override double GetDouble(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetDouble(i - VisibleFieldCount);\r
+\r
+      VerifyType(i, DbType.Double);\r
+      return _activeStatement._sql.GetDouble(_activeStatement, i);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the .NET type of a given column\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>Type</returns>\r
+    public override Type GetFieldType(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetFieldType(i - VisibleFieldCount);\r
+\r
+      return SQLiteConvert.SQLiteTypeToType(GetSQLiteType(i));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns a column as a float value\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>float</returns>\r
+    public override float GetFloat(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetFloat(i - VisibleFieldCount);\r
+\r
+      VerifyType(i, DbType.Single);\r
+      return Convert.ToSingle(_activeStatement._sql.GetDouble(_activeStatement, i));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the column as a Guid\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>Guid</returns>\r
+    public override Guid GetGuid(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetGuid(i - VisibleFieldCount);\r
+\r
+      TypeAffinity affinity = VerifyType(i, DbType.Guid);\r
+      if (affinity == TypeAffinity.Blob)\r
+      {\r
+        byte[] buffer = new byte[16];\r
+        _activeStatement._sql.GetBytes(_activeStatement, i, 0, buffer, 0, 16);\r
+        return new Guid(buffer);\r
+      }\r
+      else\r
+        return new Guid(_activeStatement._sql.GetText(_activeStatement, i));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the column as a short\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>Int16</returns>\r
+    public override Int16 GetInt16(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetInt16(i - VisibleFieldCount);\r
+\r
+      VerifyType(i, DbType.Int16);\r
+      return Convert.ToInt16(_activeStatement._sql.GetInt32(_activeStatement, i));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves the column as an int\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>Int32</returns>\r
+    public override Int32 GetInt32(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetInt32(i - VisibleFieldCount);\r
+\r
+      VerifyType(i, DbType.Int32);\r
+      return _activeStatement._sql.GetInt32(_activeStatement, i);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves the column as a long\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>Int64</returns>\r
+    public override Int64 GetInt64(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetInt64(i - VisibleFieldCount);\r
+\r
+      VerifyType(i, DbType.Int64);\r
+      return _activeStatement._sql.GetInt64(_activeStatement, i);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves the name of the column\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>string</returns>\r
+    public override string GetName(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetName(i - VisibleFieldCount);\r
+\r
+      return _activeStatement._sql.ColumnName(_activeStatement, i);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves the i of a column, given its name\r
+    /// </summary>\r
+    /// <param name="name">The name of the column to retrieve</param>\r
+    /// <returns>The int i of the column</returns>\r
+    public override int GetOrdinal(string name)\r
+    {\r
+      CheckClosed();\r
+      int r = _activeStatement._sql.ColumnIndex(_activeStatement, name);\r
+      if (r == -1 && _keyInfo != null)\r
+      {\r
+        r = _keyInfo.GetOrdinal(name);\r
+        if (r > -1) r += VisibleFieldCount;\r
+      }\r
+\r
+      return r;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Schema information in SQLite is difficult to map into .NET conventions, so a lot of work must be done\r
+    /// to gather the necessary information so it can be represented in an ADO.NET manner.\r
+    /// </summary>\r
+    /// <returns>Returns a DataTable containing the schema information for the active SELECT statement being processed.</returns>\r
+    public override DataTable GetSchemaTable()\r
+    {\r
+      return GetSchemaTable(true, false);\r
+    }\r
+\r
+    internal DataTable GetSchemaTable(bool wantUniqueInfo, bool wantDefaultValue)\r
+    {\r
+      CheckClosed();\r
+\r
+      DataTable tbl = new DataTable("SchemaTable");\r
+      DataTable tblIndexes = null;\r
+      DataTable tblIndexColumns;\r
+      DataRow row;\r
+      string temp;\r
+      string strCatalog = "";\r
+      string strTable = "";\r
+      string strColumn = "";\r
+\r
+      tbl.Locale = CultureInfo.InvariantCulture;\r
+      tbl.Columns.Add(SchemaTableColumn.ColumnName, typeof(String));\r
+      tbl.Columns.Add(SchemaTableColumn.ColumnOrdinal, typeof(int));\r
+      tbl.Columns.Add(SchemaTableColumn.ColumnSize, typeof(int));\r
+      tbl.Columns.Add(SchemaTableColumn.NumericPrecision, typeof(short));\r
+      tbl.Columns.Add(SchemaTableColumn.NumericScale, typeof(short));\r
+      tbl.Columns.Add(SchemaTableColumn.IsUnique, typeof(Boolean));\r
+      tbl.Columns.Add(SchemaTableColumn.IsKey, typeof(Boolean));\r
+      tbl.Columns.Add(SchemaTableOptionalColumn.BaseServerName, typeof(string));\r
+      tbl.Columns.Add(SchemaTableOptionalColumn.BaseCatalogName, typeof(String));\r
+      tbl.Columns.Add(SchemaTableColumn.BaseColumnName, typeof(String));\r
+      tbl.Columns.Add(SchemaTableColumn.BaseSchemaName, typeof(String));\r
+      tbl.Columns.Add(SchemaTableColumn.BaseTableName, typeof(String));\r
+      tbl.Columns.Add(SchemaTableColumn.DataType, typeof(Type));\r
+      tbl.Columns.Add(SchemaTableColumn.AllowDBNull, typeof(Boolean));\r
+      tbl.Columns.Add(SchemaTableColumn.ProviderType, typeof(int));\r
+      tbl.Columns.Add(SchemaTableColumn.IsAliased, typeof(Boolean));\r
+      tbl.Columns.Add(SchemaTableColumn.IsExpression, typeof(Boolean));\r
+      tbl.Columns.Add(SchemaTableOptionalColumn.IsAutoIncrement, typeof(Boolean));\r
+      tbl.Columns.Add(SchemaTableOptionalColumn.IsRowVersion, typeof(Boolean));\r
+      tbl.Columns.Add(SchemaTableOptionalColumn.IsHidden, typeof(Boolean));\r
+      tbl.Columns.Add(SchemaTableColumn.IsLong, typeof(Boolean));\r
+      tbl.Columns.Add(SchemaTableOptionalColumn.IsReadOnly, typeof(Boolean));\r
+      tbl.Columns.Add(SchemaTableOptionalColumn.ProviderSpecificDataType, typeof(Type));\r
+      tbl.Columns.Add(SchemaTableOptionalColumn.DefaultValue, typeof(object));\r
+      tbl.Columns.Add("DataTypeName", typeof(string));\r
+      tbl.Columns.Add("CollationType", typeof(string));\r
+      tbl.BeginLoadData();\r
+\r
+      for (int n = 0; n < _fieldCount; n++)\r
+      {\r
+        row = tbl.NewRow();\r
+\r
+        DbType typ = GetSQLiteType(n).Type;\r
+\r
+        // Default settings for the column\r
+        row[SchemaTableColumn.ColumnName] = GetName(n);\r
+        row[SchemaTableColumn.ColumnOrdinal] = n;\r
+        row[SchemaTableColumn.ColumnSize] = SQLiteConvert.DbTypeToColumnSize(typ);\r
+        row[SchemaTableColumn.NumericPrecision] = SQLiteConvert.DbTypeToNumericPrecision(typ);\r
+        row[SchemaTableColumn.NumericScale] = SQLiteConvert.DbTypeToNumericScale(typ);\r
+        row[SchemaTableColumn.ProviderType] = GetSQLiteType(n).Type;\r
+        row[SchemaTableColumn.IsLong] = false;\r
+        row[SchemaTableColumn.AllowDBNull] = true;\r
+        row[SchemaTableOptionalColumn.IsReadOnly] = false;\r
+        row[SchemaTableOptionalColumn.IsRowVersion] = false;\r
+        row[SchemaTableColumn.IsUnique] = false;\r
+        row[SchemaTableColumn.IsKey] = false;\r
+        row[SchemaTableOptionalColumn.IsAutoIncrement] = false;\r
+        row[SchemaTableColumn.DataType] = GetFieldType(n);\r
+        row[SchemaTableOptionalColumn.IsHidden] = false;\r
+\r
+        strColumn = _command.Connection._sql.ColumnOriginalName(_activeStatement, n);\r
+        if (String.IsNullOrEmpty(strColumn) == false) row[SchemaTableColumn.BaseColumnName] = strColumn;\r
+\r
+        row[SchemaTableColumn.IsExpression] = String.IsNullOrEmpty(strColumn);\r
+        row[SchemaTableColumn.IsAliased] = (String.Compare(GetName(n), strColumn, true, CultureInfo.InvariantCulture) != 0);\r
+\r
+        temp = _command.Connection._sql.ColumnTableName(_activeStatement, n);\r
+        if (String.IsNullOrEmpty(temp) == false) row[SchemaTableColumn.BaseTableName] = temp;\r
+\r
+        temp = _command.Connection._sql.ColumnDatabaseName(_activeStatement, n);\r
+        if (String.IsNullOrEmpty(temp) == false) row[SchemaTableOptionalColumn.BaseCatalogName] = temp;\r
+\r
+        string dataType = null;\r
+        // If we have a table-bound column, extract the extra information from it\r
+        if (String.IsNullOrEmpty(strColumn) == false)\r
+        {\r
+          string collSeq;\r
+          bool bNotNull;\r
+          bool bPrimaryKey;\r
+          bool bAutoIncrement;\r
+          string[] arSize;\r
+\r
+          // Get the column meta data\r
+          _command.Connection._sql.ColumnMetaData(\r
+            (string)row[SchemaTableOptionalColumn.BaseCatalogName],\r
+            (string)row[SchemaTableColumn.BaseTableName],\r
+            strColumn,\r
+            out dataType, out collSeq, out bNotNull, out bPrimaryKey, out bAutoIncrement);\r
+\r
+          if (bNotNull || bPrimaryKey) row[SchemaTableColumn.AllowDBNull] = false;\r
+\r
+          row[SchemaTableColumn.IsKey] = bPrimaryKey;\r
+          row[SchemaTableOptionalColumn.IsAutoIncrement] = bAutoIncrement;\r
+          row["CollationType"] = collSeq;\r
+\r
+          // For types like varchar(50) and such, extract the size\r
+          arSize = dataType.Split('(');\r
+          if (arSize.Length > 1)\r
+          {\r
+            dataType = arSize[0];\r
+            arSize = arSize[1].Split(')');\r
+            if (arSize.Length > 1)\r
+            {\r
+              arSize = arSize[0].Split(',', '.');\r
+              if (GetSQLiteType(n).Type == DbType.String || GetSQLiteType(n).Type == DbType.Binary)\r
+              {\r
+                row[SchemaTableColumn.ColumnSize] = Convert.ToInt32(arSize[0], CultureInfo.InvariantCulture);\r
+              }\r
+              else\r
+              {\r
+                row[SchemaTableColumn.NumericPrecision] = Convert.ToInt32(arSize[0], CultureInfo.InvariantCulture);\r
+                if (arSize.Length > 1)\r
+                  row[SchemaTableColumn.NumericScale] = Convert.ToInt32(arSize[1], CultureInfo.InvariantCulture);\r
+              }\r
+            }\r
+          }\r
+\r
+          if (wantDefaultValue)\r
+          {\r
+            // Determine the default value for the column, which sucks because we have to query the schema for each column\r
+            using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].TABLE_INFO([{1}])",\r
+              row[SchemaTableOptionalColumn.BaseCatalogName],\r
+              row[SchemaTableColumn.BaseTableName]\r
+              ), _command.Connection))\r
+            using (DbDataReader rdTable = cmdTable.ExecuteReader())\r
+            {\r
+              // Find the matching column\r
+              while (rdTable.Read())\r
+              {\r
+                if (String.Compare((string)row[SchemaTableColumn.BaseColumnName], rdTable.GetString(1), true, CultureInfo.InvariantCulture) == 0)\r
+                {\r
+                  if (rdTable.IsDBNull(4) == false)\r
+                    row[SchemaTableOptionalColumn.DefaultValue] = rdTable[4];\r
+\r
+                  break;\r
+                }\r
+              }\r
+            }\r
+          }\r
+\r
+          // Determine IsUnique properly, which is a pain in the butt!\r
+          if (wantUniqueInfo)\r
+          {\r
+            if ((string)row[SchemaTableOptionalColumn.BaseCatalogName] != strCatalog\r
+              || (string)row[SchemaTableColumn.BaseTableName] != strTable)\r
+            {\r
+              strCatalog = (string)row[SchemaTableOptionalColumn.BaseCatalogName];\r
+              strTable = (string)row[SchemaTableColumn.BaseTableName];\r
+\r
+              tblIndexes = _command.Connection.GetSchema("Indexes", new string[] {\r
+                (string)row[SchemaTableOptionalColumn.BaseCatalogName],\r
+                null,\r
+                (string)row[SchemaTableColumn.BaseTableName],\r
+                null });\r
+            }\r
+\r
+            foreach (DataRow rowIndexes in tblIndexes.Rows)\r
+            {\r
+              tblIndexColumns = _command.Connection.GetSchema("IndexColumns", new string[] {\r
+                (string)row[SchemaTableOptionalColumn.BaseCatalogName],\r
+                null,\r
+                (string)row[SchemaTableColumn.BaseTableName],\r
+                (string)rowIndexes["INDEX_NAME"],\r
+                null\r
+                });\r
+              foreach (DataRow rowColumnIndex in tblIndexColumns.Rows)\r
+              {\r
+                if (String.Compare((string)rowColumnIndex["COLUMN_NAME"], strColumn, true, CultureInfo.InvariantCulture) == 0)\r
+                {\r
+                  if (tblIndexColumns.Rows.Count == 1 && (bool)row[SchemaTableColumn.AllowDBNull] == false)\r
+                    row[SchemaTableColumn.IsUnique] = rowIndexes["UNIQUE"];\r
+\r
+                  // If its an integer primary key and the only primary key in the table, then its a rowid alias and is autoincrement\r
+                  // NOTE:  Currently commented out because this is not always the desired behavior.  For example, a 1:1 relationship with\r
+                  //        another table, where the other table is autoincrement, but this one is not, and uses the rowid from the other.\r
+                  //        It is safer to only set Autoincrement on tables where we're SURE the user specified AUTOINCREMENT, even if its a rowid column.\r
+\r
+                  if (tblIndexColumns.Rows.Count == 1 && (bool)rowIndexes["PRIMARY_KEY"] == true && String.IsNullOrEmpty(dataType) == false &&\r
+                    String.Compare(dataType, "integer", true, CultureInfo.InvariantCulture) == 0)\r
+                  {\r
+                    //  row[SchemaTableOptionalColumn.IsAutoIncrement] = true;\r
+                  }\r
+\r
+                  break;\r
+                }\r
+              }\r
+            }\r
+          }\r
+\r
+          if (String.IsNullOrEmpty(dataType))\r
+          {\r
+            TypeAffinity affin;\r
+            dataType = _activeStatement._sql.ColumnType(_activeStatement, n, out affin);\r
+          }\r
+\r
+          if (String.IsNullOrEmpty(dataType) == false)\r
+            row["DataTypeName"] = dataType;\r
+        }\r
+        tbl.Rows.Add(row);\r
+      }\r
+\r
+      if (_keyInfo != null)\r
+        _keyInfo.AppendSchemaTable(tbl);\r
+\r
+      tbl.AcceptChanges();\r
+      tbl.EndLoadData();\r
+\r
+      return tbl;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves the column as a string\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>string</returns>\r
+    public override string GetString(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetString(i - VisibleFieldCount);\r
+\r
+      VerifyType(i, DbType.String);\r
+      return _activeStatement._sql.GetText(_activeStatement, i);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves the column as an object corresponding to the underlying datatype of the column\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>object</returns>\r
+    public override object GetValue(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.GetValue(i - VisibleFieldCount);\r
+\r
+      SQLiteType typ = GetSQLiteType(i);\r
+\r
+      return _activeStatement._sql.GetValue(_activeStatement, i, typ);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retreives the values of multiple columns, up to the size of the supplied array\r
+    /// </summary>\r
+    /// <param name="values">The array to fill with values from the columns in the current resultset</param>\r
+    /// <returns>The number of columns retrieved</returns>\r
+    public override int GetValues(object[] values)\r
+    {\r
+      int nMax = FieldCount;\r
+      if (values.Length < nMax) nMax = values.Length;\r
+\r
+      for (int n = 0; n < nMax; n++)\r
+      {\r
+        values[n] = GetValue(n);\r
+      }\r
+\r
+      return nMax;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns True if the resultset has rows that can be fetched\r
+    /// </summary>\r
+    public override bool HasRows\r
+    {\r
+      get\r
+      {\r
+        CheckClosed();\r
+        return (_readingState != 1);\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns True if the data reader is closed\r
+    /// </summary>\r
+    public override bool IsClosed\r
+    {\r
+      get { return (_command == null); }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns True if the specified column is null\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>True or False</returns>\r
+    public override bool IsDBNull(int i)\r
+    {\r
+      if (i >= VisibleFieldCount && _keyInfo != null)\r
+        return _keyInfo.IsDBNull(i - VisibleFieldCount);\r
+\r
+      return _activeStatement._sql.IsNull(_activeStatement, i);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Moves to the next resultset in multiple row-returning SQL command.\r
+    /// </summary>\r
+    /// <returns>True if the command was successful and a new resultset is available, False otherwise.</returns>\r
+    public override bool NextResult()\r
+    {\r
+      CheckClosed();\r
+\r
+      SQLiteStatement stmt = null;\r
+      int fieldCount;\r
+\r
+      while (true)\r
+      {\r
+        if (_activeStatement != null && stmt == null)\r
+        {\r
+          // Reset the previously-executed statement\r
+          _activeStatement._sql.Reset(_activeStatement);\r
+\r
+          // If we're only supposed to return a single rowset, step through all remaining statements once until\r
+          // they are all done and return false to indicate no more resultsets exist.\r
+          if ((_commandBehavior & CommandBehavior.SingleResult) != 0)\r
+          {\r
+            for (; ; )\r
+            {\r
+              stmt = _command.GetStatement(_activeStatementIndex + 1);\r
+              if (stmt == null) break;\r
+              _activeStatementIndex++;\r
+\r
+              stmt._sql.Step(stmt);\r
+              if (stmt._sql.ColumnCount(stmt) == 0)\r
+              {\r
+                if (_rowsAffected == -1) _rowsAffected = 0;\r
+                _rowsAffected += stmt._sql.Changes;\r
+              }\r
+              stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such!\r
+            }\r
+            return false;\r
+          }\r
+        }\r
+\r
+        // Get the next statement to execute\r
+        stmt = _command.GetStatement(_activeStatementIndex + 1);\r
+\r
+        // If we've reached the end of the statements, return false, no more resultsets\r
+        if (stmt == null)\r
+          return false;\r
+\r
+        // If we were on a current resultset, set the state to "done reading" for it\r
+        if (_readingState < 1)\r
+          _readingState = 1;\r
+\r
+        _activeStatementIndex++;\r
+\r
+        fieldCount = stmt._sql.ColumnCount(stmt);\r
+\r
+        // If the statement is not a select statement or we're not retrieving schema only, then perform the initial step\r
+        if ((_commandBehavior & CommandBehavior.SchemaOnly) == 0 || fieldCount == 0)\r
+        {\r
+          if (stmt._sql.Step(stmt))\r
+          {\r
+            _readingState = -1;\r
+          }\r
+          else if (fieldCount == 0) // No rows returned, if fieldCount is zero, skip to the next statement\r
+          {\r
+            if (_rowsAffected == -1) _rowsAffected = 0;\r
+            _rowsAffected += stmt._sql.Changes;\r
+            stmt._sql.Reset(stmt);\r
+            continue; // Skip this command and move to the next, it was not a row-returning resultset\r
+          }\r
+          else // No rows, fieldCount is non-zero so stop here\r
+          {\r
+            _readingState = 1; // This command returned columns but no rows, so return true, but HasRows = false and Read() returns false\r
+          }\r
+        }\r
+\r
+        // Ahh, we found a row-returning resultset eligible to be returned!\r
+        _activeStatement = stmt;\r
+        _fieldCount = fieldCount;\r
+        _fieldTypeArray = null;\r
+\r
+        if ((_commandBehavior & CommandBehavior.KeyInfo) != 0)\r
+          LoadKeyInfo();\r
+\r
+        return true;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls.\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>A SQLiteType structure</returns>\r
+    private SQLiteType GetSQLiteType(int i)\r
+    {\r
+      SQLiteType typ;\r
+\r
+      // Initialize the field types array if not already initialized\r
+      if (_fieldTypeArray == null)\r
+        _fieldTypeArray = new SQLiteType[VisibleFieldCount];\r
+\r
+      // Initialize this column's field type instance\r
+      if (_fieldTypeArray[i] == null) _fieldTypeArray[i] = new SQLiteType();\r
+\r
+      typ = _fieldTypeArray[i];\r
+\r
+      // If not initialized, then fetch the declared column datatype and attempt to convert it \r
+      // to a known DbType.\r
+      if (typ.Affinity == TypeAffinity.Uninitialized)\r
+        typ.Type = SQLiteConvert.TypeNameToDbType(_activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity));\r
+      else\r
+        typ.Affinity = _activeStatement._sql.ColumnAffinity(_activeStatement, i);\r
+\r
+      return typ;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Reads the next row from the resultset\r
+    /// </summary>\r
+    /// <returns>True if a new row was successfully loaded and is ready for processing</returns>\r
+    public override bool Read()\r
+    {\r
+      CheckClosed();\r
+\r
+      if (_readingState == -1) // First step was already done at the NextResult() level, so don't step again, just return true.\r
+      {\r
+        _readingState = 0;\r
+        return true;\r
+      }\r
+      else if (_readingState == 0) // Actively reading rows\r
+      {\r
+        // Don't read a new row if the command behavior dictates SingleRow.  We've already read the first row.\r
+        if ((_commandBehavior & CommandBehavior.SingleRow) == 0)\r
+        {\r
+          if (_activeStatement._sql.Step(_activeStatement) == true)\r
+          {\r
+            if (_keyInfo != null)\r
+              _keyInfo.Reset();\r
+\r
+            return true;\r
+          }\r
+        }\r
+\r
+        _readingState = 1; // Finished reading rows\r
+      }\r
+\r
+      return false;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieve the count of records affected by an update/insert command.  Only valid once the data reader is closed!\r
+    /// </summary>\r
+    public override int RecordsAffected\r
+    {\r
+      get { return (_rowsAffected < 0) ? 0 : _rowsAffected; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Indexer to retrieve data from a column given its name\r
+    /// </summary>\r
+    /// <param name="name">The name of the column to retrieve data for</param>\r
+    /// <returns>The value contained in the column</returns>\r
+    public override object this[string name]\r
+    {\r
+      get { return GetValue(GetOrdinal(name)); }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Indexer to retrieve data from a column given its i\r
+    /// </summary>\r
+    /// <param name="i">The index of the column to retrieve</param>\r
+    /// <returns>The value contained in the column</returns>\r
+    public override object this[int i]\r
+    {\r
+      get { return GetValue(i); }\r
+    }\r
+\r
+    private void LoadKeyInfo()\r
+    {\r
+      if (_keyInfo != null)\r
+        _keyInfo.Dispose();\r
+\r
+      _keyInfo = new SQLiteKeyReader(_command.Connection, this, _activeStatement);\r
+    }\r
+  }\r
+}\r
index 864eaa126e5c545d9c856c253e859868b35347fe..6ba58adc1adea5dbac755d54b23ee1c488bdfc33 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteEnlistment.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/*******************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-#if !PLATFORM_COMPACTFRAMEWORK
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Data.Common;
-  using System.Transactions;
-
-  internal class SqliteEnlistment : IEnlistmentNotification
-  {
-    internal SqliteTransaction _transaction;
-    internal Transaction _scope;
-    internal bool _disposeConnection;
-
-    internal SqliteEnlistment(SqliteConnection cnn, Transaction scope)
-    {
-      _transaction = cnn.BeginTransaction();
-      _scope = scope;
-      _disposeConnection = false;
-
-      _scope.EnlistVolatile(this, System.Transactions.EnlistmentOptions.None);
-    }
-
-    private void Cleanup(SqliteConnection cnn)
-    {
-      if (_disposeConnection)
-        cnn.Dispose();
-
-      _transaction = null;
-      _scope = null;
-    }
-
-    #region IEnlistmentNotification Members
-
-    public void Commit(Enlistment enlistment)
-    {
-      SqliteConnection cnn = _transaction.Connection;
-      cnn._enlistment = null;
-
-      try
-      {
-        _transaction.IsValid(true);
-        _transaction.Connection._transactionLevel = 1;
-        _transaction.Commit();
-
-        enlistment.Done();
-      }
-      finally
-      {
-        Cleanup(cnn);
-      }
-    }
-
-    public void InDoubt(Enlistment enlistment)
-    {
-      enlistment.Done();
-    }
-
-    public void Prepare(PreparingEnlistment preparingEnlistment)
-    {
-      if (_transaction.IsValid(false) == false)
-        preparingEnlistment.ForceRollback();
-      else
-        preparingEnlistment.Prepared();
-    }
-
-    public void Rollback(Enlistment enlistment)
-    {
-      SqliteConnection cnn = _transaction.Connection;
-      cnn._enlistment = null;
-
-      try
-      {
-        _transaction.Rollback();
-        enlistment.Done();
-      }
-      finally
-      {
-        Cleanup(cnn);
-      }
-    }
-
-    #endregion
-  }
-}
-#endif // !PLATFORM_COMPACT_FRAMEWORK
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Data.Common;\r
+  using System.Transactions;\r
+\r
+  internal class SQLiteEnlistment : IEnlistmentNotification\r
+  {\r
+    internal SQLiteTransaction _transaction;\r
+    internal Transaction _scope;\r
+    internal bool _disposeConnection;\r
+\r
+    internal SQLiteEnlistment(SQLiteConnection cnn, Transaction scope)\r
+    {\r
+      _transaction = cnn.BeginTransaction();\r
+      _scope = scope;\r
+      _disposeConnection = false;\r
+\r
+      _scope.EnlistVolatile(this, System.Transactions.EnlistmentOptions.None);\r
+    }\r
+\r
+    private void Cleanup(SQLiteConnection cnn)\r
+    {\r
+      if (_disposeConnection)\r
+        cnn.Dispose();\r
+\r
+      _transaction = null;\r
+      _scope = null;\r
+    }\r
+\r
+    #region IEnlistmentNotification Members\r
+\r
+    public void Commit(Enlistment enlistment)\r
+    {\r
+      SQLiteConnection cnn = _transaction.Connection;\r
+      cnn._enlistment = null;\r
+\r
+      try\r
+      {\r
+        _transaction.IsValid(true);\r
+        _transaction.Connection._transactionLevel = 1;\r
+        _transaction.Commit();\r
+\r
+        enlistment.Done();\r
+      }\r
+      finally\r
+      {\r
+        Cleanup(cnn);\r
+      }\r
+    }\r
+\r
+    public void InDoubt(Enlistment enlistment)\r
+    {\r
+      enlistment.Done();\r
+    }\r
+\r
+    public void Prepare(PreparingEnlistment preparingEnlistment)\r
+    {\r
+      if (_transaction.IsValid(false) == false)\r
+        preparingEnlistment.ForceRollback();\r
+      else\r
+        preparingEnlistment.Prepared();\r
+    }\r
+\r
+    public void Rollback(Enlistment enlistment)\r
+    {\r
+      SQLiteConnection cnn = _transaction.Connection;\r
+      cnn._enlistment = null;\r
+\r
+      try\r
+      {\r
+        _transaction.Rollback();\r
+        enlistment.Done();\r
+      }\r
+      finally\r
+      {\r
+        Cleanup(cnn);\r
+      }\r
+    }\r
+\r
+    #endregion\r
+  }\r
+}\r
+#endif // !PLATFORM_COMPACT_FRAMEWORK
\ No newline at end of file
index 5f51ae3e8925c4661a7ae6dc15790ac1251c1870..0fbb2dd5bc2579f8d0e4587ee21330199ec62c09 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteException.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Collections.Generic;
-  using System.Text;
-  using System.Data.Common;
-
-#if !PLATFORM_COMPACTFRAMEWORK
-  using System.Runtime.Serialization;
-#endif
-
-  /// <summary>
-  /// Sqlite exception class.
-  /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-  [Serializable]
-  public class SqliteException : DbException
-#else
-  public class SqliteException : Exception
-#endif
-  {
-    private SqliteErrorCode _errorCode;
-
-#if !PLATFORM_COMPACTFRAMEWORK
-    private SqliteException(SerializationInfo info, StreamingContext context)
-      : base(info, context)
-    {
-    }
-#endif
-
-    /// <summary>
-    /// Public constructor for generating a Sqlite error given the base error code
-    /// </summary>
-    /// <param name="errorCode">The Sqlite error code to report</param>
-    /// <param name="extendedInformation">Extra text to go along with the error message text</param>
-    public SqliteException(int errorCode, string extendedInformation)
-      : base(GetStockErrorMessage(errorCode, extendedInformation))
-    {
-      _errorCode = (SqliteErrorCode)errorCode;
-    }
-
-    /// <summary>
-    /// Various public constructors that just pass along to the base Exception
-    /// </summary>
-    /// <param name="message">Passed verbatim to Exception</param>
-    public SqliteException(string message)
-      : base(message)
-    {
-    }
-
-    /// <summary>
-    /// Various public constructors that just pass along to the base Exception
-    /// </summary>
-    public SqliteException()
-    {
-    }
-
-    /// <summary>
-    /// Various public constructors that just pass along to the base Exception
-    /// <param name="message">Passed to Exception</param>
-    /// <param name="innerException">Passed to Exception</param>
-    /// </summary>
-    public SqliteException(string message, Exception innerException)
-      : base(message, innerException)
-    {
-    }
-
-    /// <summary>
-    /// Retrieves the underlying Sqlite error code for this exception
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    public new SqliteErrorCode ErrorCode
-#else
-    public SqliteErrorCode ErrorCode
-#endif
-    {
-      get { return _errorCode; }
-    }
-
-    /// <summary>
-    /// Initializes the exception class with the Sqlite error code.
-    /// </summary>
-    /// <param name="errorCode">The Sqlite error code</param>
-    /// <param name="errorMessage">A detailed error message</param>
-    /// <returns>An error message string</returns>
-    private static string GetStockErrorMessage(int errorCode, string errorMessage)
-    {
-      if (errorMessage == null) errorMessage = "";
-
-      if (errorMessage.Length > 0)
-        errorMessage = "\r\n" + errorMessage;
-
-      if (errorCode < 0 || errorCode >= _errorMessages.Length)
-        errorCode = 1;
-
-      return _errorMessages[errorCode] + errorMessage;
-    }
-
-    private static string[] _errorMessages = {
-      "Sqlite OK",
-      "Sqlite error",
-      "An internal logic error in Sqlite",
-      "Access permission denied",
-      "Callback routine requested an abort",
-      "The database file is locked",
-      "A table in the database is locked",
-      "malloc() failed",
-      "Attempt to write a read-only database",
-      "Operation terminated by sqlite3_interrupt()",
-      "Some kind of disk I/O error occurred",
-      "The database disk image is malformed",
-      "Table or record not found",
-      "Insertion failed because the database is full",
-      "Unable to open the database file",
-      "Database lock protocol error",
-      "Database is empty",
-      "The database schema changed",
-      "Too much data for one row of a table",
-      "Abort due to constraint violation",
-      "Data type mismatch",
-      "Library used incorrectly",
-      "Uses OS features not supported on host",
-      "Authorization denied",
-      "Auxiliary database format error",
-      "2nd parameter to sqlite3_bind() out of range",
-      "File opened that is not a database file",
-    };
-  }
-
-  /// <summary>
-  /// Sqlite error codes
-  /// </summary>
-  public enum SqliteErrorCode
-  {
-    /// <summary>
-    /// Success
-    /// </summary>
-    Ok = 0,
-    /// <summary>
-    /// SQL error or missing database
-    /// </summary>
-    Error,
-    /// <summary>
-    /// Internal logic error in Sqlite
-    /// </summary>
-    Internal,
-    /// <summary>
-    /// Access permission denied
-    /// </summary>
-    Perm,
-    /// <summary>
-    /// Callback routine requested an abort
-    /// </summary>
-    Abort,
-    /// <summary>
-    /// The database file is locked
-    /// </summary>
-    Busy,
-    /// <summary>
-    /// A table in the database is locked
-    /// </summary>
-    Locked,
-    /// <summary>
-    /// malloc() failed
-    /// </summary>
-    NoMem,
-    /// <summary>
-    /// Attempt to write a read-only database
-    /// </summary>
-    ReadOnly,
-    /// <summary>
-    /// Operation terminated by sqlite3_interrupt()
-    /// </summary>
-    Interrupt,
-    /// <summary>
-    /// Some kind of disk I/O error occurred
-    /// </summary>
-    IOErr,
-    /// <summary>
-    /// The database disk image is malformed
-    /// </summary>
-    Corrupt,
-    /// <summary>
-    /// Table or record not found
-    /// </summary>
-    NotFound,
-    /// <summary>
-    /// Insertion failed because database is full
-    /// </summary>
-    Full,
-    /// <summary>
-    /// Unable to open the database file
-    /// </summary>
-    CantOpen,
-    /// <summary>
-    /// Database lock protocol error
-    /// </summary>
-    Protocol,
-    /// <summary>
-    /// Database is empty
-    /// </summary>
-    Empty,
-    /// <summary>
-    /// The database schema changed
-    /// </summary>
-    Schema,
-    /// <summary>
-    /// Too much data for one row of a table
-    /// </summary>
-    TooBig,
-    /// <summary>
-    /// Abort due to constraint violation
-    /// </summary>
-    Constraint,
-    /// <summary>
-    /// Data type mismatch
-    /// </summary>
-    Mismatch,
-    /// <summary>
-    /// Library used incorrectly
-    /// </summary>
-    Misuse,
-    /// <summary>
-    /// Uses OS features not supported on host
-    /// </summary>
-    NOLFS,
-    /// <summary>
-    /// Authorization denied
-    /// </summary>
-    Auth,
-    /// <summary>
-    /// Auxiliary database format error
-    /// </summary>
-    Format,
-    /// <summary>
-    /// 2nd parameter to sqlite3_bind out of range
-    /// </summary>
-    Range,
-    /// <summary>
-    /// File opened that is not a database file
-    /// </summary>
-    NotADatabase,
-    /// <summary>
-    /// sqlite3_step() has another row ready
-    /// </summary>
-    Row = 100,
-    /// <summary>
-    /// sqlite3_step() has finished executing
-    /// </summary>
-    Done = 101,
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Collections.Generic;\r
+  using System.Text;\r
+  using System.Data.Common;\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  using System.Runtime.Serialization;\r
+#endif\r
+\r
+  /// <summary>\r
+  /// SQLite exception class.\r
+  /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  [Serializable]\r
+  public sealed class SQLiteException : DbException\r
+#else\r
+  public sealed class SQLiteException : Exception\r
+#endif\r
+  {\r
+    private SQLiteErrorCode _errorCode;\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    private SQLiteException(SerializationInfo info, StreamingContext context)\r
+      : base(info, context)\r
+    {\r
+    }\r
+#endif\r
+\r
+    /// <summary>\r
+    /// Public constructor for generating a SQLite error given the base error code\r
+    /// </summary>\r
+    /// <param name="errorCode">The SQLite error code to report</param>\r
+    /// <param name="extendedInformation">Extra text to go along with the error message text</param>\r
+    public SQLiteException(int errorCode, string extendedInformation)\r
+      : base(GetStockErrorMessage(errorCode, extendedInformation))\r
+    {\r
+      _errorCode = (SQLiteErrorCode)errorCode;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Various public constructors that just pass along to the base Exception\r
+    /// </summary>\r
+    /// <param name="message">Passed verbatim to Exception</param>\r
+    public SQLiteException(string message)\r
+      : base(message)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Various public constructors that just pass along to the base Exception\r
+    /// </summary>\r
+    public SQLiteException()\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Various public constructors that just pass along to the base Exception\r
+    /// <param name="message">Passed to Exception</param>\r
+    /// <param name="innerException">Passed to Exception</param>\r
+    /// </summary>\r
+    public SQLiteException(string message, Exception innerException)\r
+      : base(message, innerException)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves the underlying SQLite error code for this exception\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    public new SQLiteErrorCode ErrorCode\r
+#else\r
+    public SQLiteErrorCode ErrorCode\r
+#endif\r
+    {\r
+      get { return _errorCode; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Initializes the exception class with the SQLite error code.\r
+    /// </summary>\r
+    /// <param name="errorCode">The SQLite error code</param>\r
+    /// <param name="errorMessage">A detailed error message</param>\r
+    /// <returns>An error message string</returns>\r
+    private static string GetStockErrorMessage(int errorCode, string errorMessage)\r
+    {\r
+      if (errorMessage == null) errorMessage = "";\r
+\r
+      if (errorMessage.Length > 0)\r
+        errorMessage = "\r\n" + errorMessage;\r
+\r
+      if (errorCode < 0 || errorCode >= _errorMessages.Length)\r
+        errorCode = 1;\r
+\r
+      return _errorMessages[errorCode] + errorMessage;\r
+    }\r
+\r
+    private static string[] _errorMessages = {\r
+      "SQLite OK",\r
+      "SQLite error",\r
+      "An internal logic error in SQLite",\r
+      "Access permission denied",\r
+      "Callback routine requested an abort",\r
+      "The database file is locked",\r
+      "A table in the database is locked",\r
+      "malloc() failed",\r
+      "Attempt to write a read-only database",\r
+      "Operation terminated by sqlite3_interrupt()",\r
+      "Some kind of disk I/O error occurred",\r
+      "The database disk image is malformed",\r
+      "Table or record not found",\r
+      "Insertion failed because the database is full",\r
+      "Unable to open the database file",\r
+      "Database lock protocol error",\r
+      "Database is empty",\r
+      "The database schema changed",\r
+      "Too much data for one row of a table",\r
+      "Abort due to constraint violation",\r
+      "Data type mismatch",\r
+      "Library used incorrectly",\r
+      "Uses OS features not supported on host",\r
+      "Authorization denied",\r
+      "Auxiliary database format error",\r
+      "2nd parameter to sqlite3_bind() out of range",\r
+      "File opened that is not a database file",\r
+    };\r
+  }\r
+\r
+  /// <summary>\r
+  /// SQLite error codes\r
+  /// </summary>\r
+  public enum SQLiteErrorCode\r
+  {\r
+    /// <summary>\r
+    /// Success\r
+    /// </summary>\r
+    Ok = 0,\r
+    /// <summary>\r
+    /// SQL error or missing database\r
+    /// </summary>\r
+    Error,\r
+    /// <summary>\r
+    /// Internal logic error in SQLite\r
+    /// </summary>\r
+    Internal,\r
+    /// <summary>\r
+    /// Access permission denied\r
+    /// </summary>\r
+    Perm,\r
+    /// <summary>\r
+    /// Callback routine requested an abort\r
+    /// </summary>\r
+    Abort,\r
+    /// <summary>\r
+    /// The database file is locked\r
+    /// </summary>\r
+    Busy,\r
+    /// <summary>\r
+    /// A table in the database is locked\r
+    /// </summary>\r
+    Locked,\r
+    /// <summary>\r
+    /// malloc() failed\r
+    /// </summary>\r
+    NoMem,\r
+    /// <summary>\r
+    /// Attempt to write a read-only database\r
+    /// </summary>\r
+    ReadOnly,\r
+    /// <summary>\r
+    /// Operation terminated by sqlite3_interrupt()\r
+    /// </summary>\r
+    Interrupt,\r
+    /// <summary>\r
+    /// Some kind of disk I/O error occurred\r
+    /// </summary>\r
+    IOErr,\r
+    /// <summary>\r
+    /// The database disk image is malformed\r
+    /// </summary>\r
+    Corrupt,\r
+    /// <summary>\r
+    /// Table or record not found\r
+    /// </summary>\r
+    NotFound,\r
+    /// <summary>\r
+    /// Insertion failed because database is full\r
+    /// </summary>\r
+    Full,\r
+    /// <summary>\r
+    /// Unable to open the database file\r
+    /// </summary>\r
+    CantOpen,\r
+    /// <summary>\r
+    /// Database lock protocol error\r
+    /// </summary>\r
+    Protocol,\r
+    /// <summary>\r
+    /// Database is empty\r
+    /// </summary>\r
+    Empty,\r
+    /// <summary>\r
+    /// The database schema changed\r
+    /// </summary>\r
+    Schema,\r
+    /// <summary>\r
+    /// Too much data for one row of a table\r
+    /// </summary>\r
+    TooBig,\r
+    /// <summary>\r
+    /// Abort due to constraint violation\r
+    /// </summary>\r
+    Constraint,\r
+    /// <summary>\r
+    /// Data type mismatch\r
+    /// </summary>\r
+    Mismatch,\r
+    /// <summary>\r
+    /// Library used incorrectly\r
+    /// </summary>\r
+    Misuse,\r
+    /// <summary>\r
+    /// Uses OS features not supported on host\r
+    /// </summary>\r
+    NOLFS,\r
+    /// <summary>\r
+    /// Authorization denied\r
+    /// </summary>\r
+    Auth,\r
+    /// <summary>\r
+    /// Auxiliary database format error\r
+    /// </summary>\r
+    Format,\r
+    /// <summary>\r
+    /// 2nd parameter to sqlite3_bind out of range\r
+    /// </summary>\r
+    Range,\r
+    /// <summary>\r
+    /// File opened that is not a database file\r
+    /// </summary>\r
+    NotADatabase,\r
+    /// <summary>\r
+    /// sqlite3_step() has another row ready\r
+    /// </summary>\r
+    Row = 100,\r
+    /// <summary>\r
+    /// sqlite3_step() has finished executing\r
+    /// </summary>\r
+    Done = 101,\r
+  }\r
+}\r
index 7fe6f8ef4131ecdc759cb265d5783c09b2e007de..3027fe3fb289746e34ead16ec40d3781b64dc95e 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteFactory.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data.Common;
-
-#if !PLATFORM_COMPACTFRAMEWORK
-  /// <summary>
-  /// Sqlite implementation of DbProviderFactory.
-  /// </summary>
-  public sealed class SqliteFactory : DbProviderFactory
-  {
-    /// <summary>
-    /// Static instance member which returns an instanced SqliteFactory class.
-    /// </summary>
-    public static readonly SqliteFactory Instance = new SqliteFactory();
-
-    /// <summary>
-    /// Returns a new SqliteCommand object.
-    /// </summary>
-    /// <returns>A SqliteCommand object.</returns>
-    public override DbCommand CreateCommand()
-    {
-      return new SqliteCommand();
-    }
-
-    /// <summary>
-    /// Returns a new SqliteCommandBuilder object.
-    /// </summary>
-    /// <returns>A SqliteCommandBuilder object.</returns>
-    public override DbCommandBuilder CreateCommandBuilder()
-    {
-      return new SqliteCommandBuilder();
-    }
-
-    /// <summary>
-    /// Creates a new SqliteConnection.
-    /// </summary>
-    /// <returns>A SqliteConnection object.</returns>
-    public override DbConnection CreateConnection()
-    {
-      return new SqliteConnection();
-    }
-
-    /// <summary>
-    /// Creates a new SqliteConnectionStringBuilder.
-    /// </summary>
-    /// <returns>A SqliteConnectionStringBuilder object.</returns>
-    public override DbConnectionStringBuilder CreateConnectionStringBuilder()
-    {
-      return new SqliteConnectionStringBuilder();
-    }
-
-    /// <summary>
-    /// Creates a new SqliteDataAdapter.
-    /// </summary>
-    /// <returns>A SqliteDataAdapter object.</returns>
-    public override DbDataAdapter CreateDataAdapter()
-    {
-      return new SqliteDataAdapter();
-    }
-
-    /// <summary>
-    /// Creates a new SqliteParameter.
-    /// </summary>
-    /// <returns>A SqliteParameter object.</returns>
-    public override DbParameter CreateParameter()
-    {
-      return new SqliteParameter();
-    }
-  }
-#endif
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data.Common;\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  /// <summary>\r
+  /// SQLite implementation of DbProviderFactory.\r
+  /// </summary>\r
+  public sealed partial class SQLiteFactory : DbProviderFactory\r
+  {\r
+    /// <summary>\r
+    /// Static instance member which returns an instanced SQLiteFactory class.\r
+    /// </summary>\r
+    public static readonly SQLiteFactory Instance = new SQLiteFactory();\r
+\r
+    /// <summary>\r
+    /// Returns a new SQLiteCommand object.\r
+    /// </summary>\r
+    /// <returns>A SQLiteCommand object.</returns>\r
+    public override DbCommand CreateCommand()\r
+    {\r
+      return new SQLiteCommand();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns a new SQLiteCommandBuilder object.\r
+    /// </summary>\r
+    /// <returns>A SQLiteCommandBuilder object.</returns>\r
+    public override DbCommandBuilder CreateCommandBuilder()\r
+    {\r
+      return new SQLiteCommandBuilder();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Creates a new SQLiteConnection.\r
+    /// </summary>\r
+    /// <returns>A SQLiteConnection object.</returns>\r
+    public override DbConnection CreateConnection()\r
+    {\r
+      return new SQLiteConnection();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Creates a new SQLiteConnectionStringBuilder.\r
+    /// </summary>\r
+    /// <returns>A SQLiteConnectionStringBuilder object.</returns>\r
+    public override DbConnectionStringBuilder CreateConnectionStringBuilder()\r
+    {\r
+      return new SQLiteConnectionStringBuilder();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Creates a new SQLiteDataAdapter.\r
+    /// </summary>\r
+    /// <returns>A SQLiteDataAdapter object.</returns>\r
+    public override DbDataAdapter CreateDataAdapter()\r
+    {\r
+      return new SQLiteDataAdapter();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Creates a new SQLiteParameter.\r
+    /// </summary>\r
+    /// <returns>A SQLiteParameter object.</returns>\r
+    public override DbParameter CreateParameter()\r
+    {\r
+      return new SQLiteParameter();\r
+    }\r
+  }\r
+#endif\r
+}\r
index 5f3a5a67506eb91ee48c9c406866d6d36761a345..f5e9e75969f8b10b99c610c96674cdf20feb9f7f 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteFunction.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Collections;
-  using System.Collections.Generic;
-  using System.Runtime.InteropServices;
-  using System.Globalization;
-
-  /// <summary>
-  /// The type of user-defined function to declare
-  /// </summary>
-  public enum FunctionType
-  {
-    /// <summary>
-    /// Scalar functions are designed to be called and return a result immediately.  Examples include ABS(), Upper(), Lower(), etc.
-    /// </summary>
-    Scalar = 0,
-    /// <summary>
-    /// Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data.
-    /// Examples include SUM(), COUNT(), AVG(), etc.
-    /// </summary>
-    Aggregate = 1,
-    /// <summary>
-    /// Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause.  Typically text in an ORDER BY is
-    /// sorted using a straight case-insensitive comparison function.  Custom collating sequences can be used to alter the behavior of text sorting
-    /// in a user-defined manner.
-    /// </summary>
-    Collation = 2,
-  }
-
-  /// <summary>
-  /// An internal callback delegate declaration.
-  /// </summary>
-  /// <param name="context">Raw context pointer for the user function</param>
-  /// <param name="nArgs">Count of arguments to the function</param>
-  /// <param name="argsptr">A pointer to the array of argument pointers</param>
-  internal delegate void SqliteCallback(IntPtr context, int nArgs, IntPtr argsptr);
-  /// <summary>
-  /// An internal callback delegate declaration.
-  /// </summary>
-  /// <param name="context">Raw context pointer for the user function</param>
-  internal delegate void SqliteFinalCallback(IntPtr context);
-  /// <summary>
-  /// Internal callback delegate for implementing collation sequences
-  /// </summary>
-  /// <param name="len1">Length of the string pv1</param>
-  /// <param name="pv1">Pointer to the first string to compare</param>
-  /// <param name="len2">Length of the string pv2</param>
-  /// <param name="pv2">Pointer to the second string to compare</param>
-  /// <returns>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>
-  internal delegate int SqliteCollation(int len1, IntPtr pv1, int len2, IntPtr pv2);
-
-  /// <summary>
-  /// This abstract class is designed to handle user-defined functions easily.  An instance of the derived class is made for each
-  /// connection to the database.
-  /// </summary>
-  /// <remarks>
-  /// Although there is one instance of a class derived from SqliteFunction per database connection, the derived class has no access
-  /// to the underlying connection.  This is necessary to deter implementers from thinking it would be a good idea to make database
-  /// calls during processing.
-  /// 
-  /// It is important to distinguish between a per-connection instance, and a per-SQL statement context.  One instance of this class
-  /// services all SQL statements being stepped through on that connection, and there can be many.  One should never store per-statement
-  /// information in member variables of user-defined function classes.
-  /// 
-  /// For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step.  This data will
-  /// be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes.
-  /// </remarks>
-  public abstract class SqliteFunction : IDisposable
-  {
-    /// <summary>
-    /// The base connection this function is attached to
-    /// </summary>
-    private SqliteBase              _base;
-    /// <summary>
-    /// Internal array used to keep track of aggregate function context data
-    /// </summary>
-    private Dictionary<long, object> _contextDataList;
-
-    /// <summary>
-    /// Holds a reference to the callback function for user functions
-    /// </summary>
-    private SqliteCallback  _InvokeFunc;
-    /// <summary>
-    /// Holds a reference to the callbakc function for stepping in an aggregate function
-    /// </summary>
-    private SqliteCallback  _StepFunc;
-    /// <summary>
-    /// Holds a reference to the callback function for finalizing an aggregate function
-    /// </summary>
-    private SqliteFinalCallback  _FinalFunc;
-    /// <summary>
-    /// Holds a reference to the callback function for collation sequences
-    /// </summary>
-    private SqliteCollation _CompareFunc;
-
-    /// <summary>
-    /// This static list contains all the user-defined functions declared using the proper attributes.
-    /// </summary>
-    private static List<SqliteFunctionAttribute> _registeredFunctions = new List<SqliteFunctionAttribute>();
-
-    /// <summary>
-    /// Internal constructor, initializes the function's internal variables.
-    /// </summary>
-    protected SqliteFunction()
-    {
-      _contextDataList = new Dictionary<long, object>();
-    }
-
-    /// <summary>
-    /// Returns a reference to the underlying connection's SqliteConvert class, which can be used to convert
-    /// strings and DateTime's into the current connection's encoding schema.
-    /// </summary>
-    public SqliteConvert SqliteConvert
-    {
-      get
-      {
-        return _base;
-      }
-    }
-
-    /// <summary>
-    /// Scalar functions override this method to do their magic.
-    /// </summary>
-    /// <remarks>
-    /// Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available
-    /// to force them into a certain type.  Therefore the only types you will ever see as parameters are
-    /// DBNull.Value, Int64, Double, String or byte[] array.
-    /// </remarks>
-    /// <param name="args">The arguments for the command to process</param>
-    /// <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
-    /// you may return an Exception-derived class if you wish to return an error to Sqlite.  Do not actually throw the error,
-    /// just return it!</returns>
-    public virtual object Invoke(object[] args)
-    {
-      return null;
-    }
-
-    /// <summary>
-    /// Aggregate functions override this method to do their magic.
-    /// </summary>
-    /// <remarks>
-    /// Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible.
-    /// </remarks>
-    /// <param name="args">The arguments for the command to process</param>
-    /// <param name="stepNumber">The 1-based step number.  This is incrememted each time the step method is called.</param>
-    /// <param name="contextData">A placeholder for implementers to store contextual data pertaining to the current context.</param>
-    public virtual void Step(object[] args, int stepNumber, ref object contextData)
-    {
-    }
-
-    /// <summary>
-    /// Aggregate functions override this method to finish their aggregate processing.
-    /// </summary>
-    /// <remarks>
-    /// If you implemented your aggregate function properly,
-    /// you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have
-    /// all the information you need in there to figure out what to return.
-    /// NOTE:  It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will
-    /// be null.  This can happen when no rows were returned.  You can either return null, or 0 or some other custom return value
-    /// if that is the case.
-    /// </remarks>
-    /// <param name="contextData">Your own assigned contextData, provided for you so you can return your final results.</param>
-    /// <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
-    /// you may return an Exception-derived class if you wish to return an error to Sqlite.  Do not actually throw the error,
-    /// just return it!
-    /// </returns>
-    public virtual object Final(object contextData)
-    {
-      return null;
-    }
-
-    /// <summary>
-    /// User-defined collation sequences override this method to provide a custom string sorting algorithm.
-    /// </summary>
-    /// <param name="param1">The first string to compare</param>
-    /// <param name="param2">The second strnig to compare</param>
-    /// <returns>1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2</returns>
-    public virtual int Compare(string param1, string param2)
-    {
-      return 0;
-    }
-
-    /// <summary>
-    /// Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to.
-    /// </summary>
-    /// <remarks>
-    /// Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available
-    /// to force them into a certain type.  Therefore the only types you will ever see as parameters are
-    /// DBNull.Value, Int64, Double, String or byte[] array.
-    /// </remarks>
-    /// <param name="nArgs">The number of arguments</param>
-    /// <param name="argsptr">A pointer to the array of arguments</param>
-    /// <returns>An object array of the arguments once they've been converted to .NET values</returns>
-    internal object[] ConvertParams(int nArgs, IntPtr argsptr)
-    {
-      object[] parms = new object[nArgs];
-#if !PLATFORM_COMPACTFRAMEWORK
-      IntPtr[] argint = new IntPtr[nArgs];
-#else
-      int[] argint = new int[nArgs];
-#endif
-      Marshal.Copy(argsptr, argint, 0, nArgs);
-
-      for (int n = 0; n < nArgs; n++)
-      {
-        switch (_base.GetParamValueType((IntPtr)argint[n]))
-        {
-          case TypeAffinity.Null:
-            parms[n] = DBNull.Value;
-            break;
-          case TypeAffinity.Int64:
-            parms[n] = _base.GetParamValueInt64((IntPtr)argint[n]);
-            break;
-          case TypeAffinity.Double:
-            parms[n] = _base.GetParamValueDouble((IntPtr)argint[n]);
-            break;
-          case TypeAffinity.Text:
-            parms[n] = _base.GetParamValueText((IntPtr)argint[n]);
-            break;
-          case TypeAffinity.Blob:
-            {
-              int x;
-              byte[] blob;
-
-              x = (int)_base.GetParamValueBytes((IntPtr)argint[n], 0, null, 0, 0);
-              blob = new byte[x];
-              _base.GetParamValueBytes((IntPtr)argint[n], 0, blob, 0, x);
-              parms[n] = blob;
-            }
-            break;
-          case TypeAffinity.DateTime: // Never happens here but what the heck, maybe it will one day.
-            parms[n] = _base.ToDateTime(_base.GetParamValueText((IntPtr)argint[n]));
-            break;
-        }
-      }
-      return parms;
-    }
-
-    /// <summary>
-    /// Takes the return value from Invoke() and Final() and figures out how to return it to Sqlite's context.
-    /// </summary>
-    /// <param name="context">The context the return value applies to</param>
-    /// <param name="returnValue">The parameter to return to Sqlite</param>
-    void SetReturnValue(IntPtr context, object returnValue)
-    {
-      if (returnValue == null || returnValue == DBNull.Value)
-      {
-        _base.ReturnNull(context);
-        return;
-      }
-
-      Type t = returnValue.GetType();
-      if (t == typeof(DateTime))
-      {
-        _base.ReturnText(context, _base.ToString((DateTime)returnValue));
-        return;
-      }
-      else
-      {
-        Exception r = returnValue as Exception;
-
-        if (r != null)
-        {
-          _base.ReturnError(context, r.Message);
-          return;
-        }
-      }
-
-      switch (SqliteConvert.TypeToAffinity(t))
-      {
-        case TypeAffinity.Null:
-          _base.ReturnNull(context);
-          return;
-        case TypeAffinity.Int64:
-          _base.ReturnInt64(context, Convert.ToInt64(returnValue, CultureInfo.CurrentCulture));
-          return;
-        case TypeAffinity.Double:
-          _base.ReturnDouble(context, Convert.ToDouble(returnValue, CultureInfo.CurrentCulture));
-          return;
-        case TypeAffinity.Text:
-          _base.ReturnText(context, returnValue.ToString());
-          return;
-        case TypeAffinity.Blob:
-          _base.ReturnBlob(context, (byte[])returnValue);
-          return;
-      }
-    }
-
-    /// <summary>
-    /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method.
-    /// </summary>
-    /// <param name="context">A raw context pointer</param>
-    /// <param name="nArgs">Number of arguments passed in</param>
-    /// <param name="argsptr">A pointer to the array of arguments</param>
-    internal void ScalarCallback(IntPtr context, int nArgs, IntPtr argsptr)
-    {
-      SetReturnValue(context, Invoke(ConvertParams(nArgs, argsptr)));
-    }
-
-    /// <summary>
-    /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function.
-    /// </summary>
-    /// <param name="len1">Length of the string pv1</param>
-    /// <param name="ptr1">Pointer to the first string to compare</param>
-    /// <param name="len2">Length of the string pv2</param>
-    /// <param name="ptr2">Pointer to the second string to compare</param>
-    /// <returns>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>
-    internal int CompareCallback(int len1, IntPtr ptr1, int len2, IntPtr ptr2)
-    {
-      return Compare(_base.ToString(ptr1), _base.ToString(ptr2));
-    }
-
-    /// <summary>
-    /// The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method.
-    /// </summary>
-    /// <remarks>
-    /// 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.
-    /// </remarks>
-    /// <param name="context">A raw context pointer</param>
-    /// <param name="nArgs">Number of arguments passed in</param>
-    /// <param name="argsptr">A pointer to the array of arguments</param>
-    internal void StepCallback(IntPtr context, int nArgs, IntPtr argsptr)
-    {
-      int n = _base.AggregateCount(context);
-      long nAux;
-      object obj = null;
-
-      nAux = (long)_base.AggregateContext(context);
-      if (n > 1) obj = _contextDataList[nAux];
-
-      Step(ConvertParams(nArgs, argsptr), n, ref obj);
-      _contextDataList[nAux] = obj;      
-    }
-
-    /// <summary>
-    /// An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method.
-    /// </summary>
-    /// <param name="context">A raw context pointer</param>
-    internal void FinalCallback(IntPtr context)
-    {
-      long n = (long)_base.AggregateContext(context);
-      object obj = null;
-
-      if (_contextDataList.ContainsKey(n))
-      {
-        obj = _contextDataList[n];
-        _contextDataList.Remove(n);
-      }
-
-      SetReturnValue(context, Final(obj));
-
-      IDisposable disp = obj as IDisposable;
-      if (disp != null) disp.Dispose();
-    }
-
-    /// <summary>
-    /// Placeholder for a user-defined disposal routine
-    /// </summary>
-    /// <param name="disposing">True if the object is being disposed explicitly</param>
-    protected virtual void Dispose(bool disposing)
-    {
-    }
-
-    /// <summary>
-    /// Disposes of any active contextData variables that were not automatically cleaned up.  Sometimes this can happen if
-    /// someone closes the connection while a DataReader is open.
-    /// </summary>
-    public void Dispose()
-    {
-      Dispose(true);
-
-      IDisposable disp;
-
-      foreach (KeyValuePair<long, object> kv in _contextDataList)
-      {
-        disp = kv.Value as IDisposable;
-        if (disp != null)
-          disp.Dispose();
-      }
-      _contextDataList.Clear();
-
-      _InvokeFunc = null;
-      _StepFunc = null;
-      _FinalFunc = null;
-      _CompareFunc = null;
-      _base = null;
-      _contextDataList = null;
-
-      GC.SuppressFinalize(this);
-    }
-
-#if !PLATFORM_COMPACTFRAMEWORK
-    /// <summary>
-    /// Using reflection, enumerate all assemblies in the current appdomain looking for classes that
-    /// have a SqliteFunctionAttribute attribute, and registering them accordingly.
-    /// </summary>
-    static SqliteFunction()
-    {
-      SqliteFunctionAttribute at;
-      System.Reflection.Assembly[] arAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();
-      int w = arAssemblies.Length;
-      System.Reflection.AssemblyName sqlite = System.Reflection.Assembly.GetCallingAssembly().GetName();
-
-      for (int n = 0; n < w; n++)
-      {
-        Type[] arTypes;
-        bool found = false;
-        System.Reflection.AssemblyName[] references;
-        try
-        {
-          // Inspect only assemblies that reference SQLite
-          references = arAssemblies[n].GetReferencedAssemblies();
-          int t = references.Length;
-          for (int z = 0; z < t; z++)
-          {
-            if (references[z].Name == sqlite.Name)
-            {
-              found = true;
-              break;
-            }
-          }
-          
-          if (found == false)
-            continue;
-
-          arTypes = arAssemblies[n].GetTypes();
-        }
-        catch (System.Reflection.ReflectionTypeLoadException e)
-        {
-          arTypes = e.Types;
-        }
-
-        int v = arTypes.Length;
-        for (int x = 0; x < v; x++)
-        {
-          if (arTypes[x] == null) continue;
-
-          object[] arAtt = arTypes[x].GetCustomAttributes(typeof(SqliteFunctionAttribute), false);
-          int u = arAtt.Length;
-          for (int y = 0; y < u; y++)
-          {
-            at = arAtt[y] as SqliteFunctionAttribute;
-            if (at != null)
-            {
-              at._instanceType = arTypes[x];
-              _registeredFunctions.Add(at);
-            }
-          }
-        }
-      }
-    }
-#else
-    /// <summary>
-    /// Manual method of registering a function.  The type must still have the SqliteFunctionAttributes in order to work
-    /// properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported.
-    /// </summary>
-    /// <param name="typ">The type of the function to register</param>
-    public static void RegisterFunction(Type typ)
-    {
-      object[] arAtt = typ.GetCustomAttributes(typeof(SqliteFunctionAttribute), false);
-      int u = arAtt.Length;
-      SqliteFunctionAttribute at;
-
-      for (int y = 0; y < u; y++)
-      {
-        at = arAtt[y] as SqliteFunctionAttribute;
-        if (at != null)
-        {
-          at._instanceType = typ;
-          _registeredFunctions.Add(at);
-        }
-      }
-    }
-#endif
-
-    /// <summary>
-    /// Called by SqliteBase derived classes, this function binds all user-defined functions to a connection.
-    /// It is done this way so that all user-defined functions will access the database using the same encoding scheme
-    /// as the connection (UTF-8 or UTF-16).
-    /// </summary>
-    /// <param name="sqlbase">The base object on which the functions are to bind</param>
-    /// <returns>Returns an array of functions which the connection object should retain until the connection is closed.</returns>
-    internal static SqliteFunction[] BindFunctions(SqliteBase sqlbase)
-    {
-      SqliteFunction f;
-      List<SqliteFunction> lFunctions = new List<SqliteFunction>();
-
-      foreach (SqliteFunctionAttribute pr in _registeredFunctions)
-      {
-        f = (SqliteFunction)Activator.CreateInstance(pr._instanceType);
-        f._base = sqlbase;
-        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;
-
-        if (pr.FuncType != FunctionType.Collation)
-          sqlbase.CreateFunction(pr.Name, pr.Arguments, f._InvokeFunc, f._StepFunc, f._FinalFunc);
-        else
-          sqlbase.CreateCollation(pr.Name, f._CompareFunc);
-        lFunctions.Add(f);
-      }
-
-      SqliteFunction[] arFunctions = new SqliteFunction[lFunctions.Count];
-      lFunctions.CopyTo(arFunctions, 0);
-
-      return arFunctions;
-
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Collections;\r
+  using System.Collections.Generic;\r
+  using System.Runtime.InteropServices;\r
+  using System.Globalization;\r
+\r
+  /// <summary>\r
+  /// This abstract class is designed to handle user-defined functions easily.  An instance of the derived class is made for each\r
+  /// connection to the database.\r
+  /// </summary>\r
+  /// <remarks>\r
+  /// Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access\r
+  /// to the underlying connection.  This is necessary to deter implementers from thinking it would be a good idea to make database\r
+  /// calls during processing.\r
+  /// \r
+  /// It is important to distinguish between a per-connection instance, and a per-SQL statement context.  One instance of this class\r
+  /// services all SQL statements being stepped through on that connection, and there can be many.  One should never store per-statement\r
+  /// information in member variables of user-defined function classes.\r
+  /// \r
+  /// For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step.  This data will\r
+  /// be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes.\r
+  /// </remarks>\r
+  public abstract class SQLiteFunction : IDisposable\r
+  {\r
+    private class AggregateData\r
+    {\r
+      internal int _count = 1;\r
+      internal object _data = null;\r
+    }\r
+\r
+    /// <summary>\r
+    /// The base connection this function is attached to\r
+    /// </summary>\r
+    internal SQLiteBase              _base;\r
+\r
+    /// <summary>\r
+    /// Internal array used to keep track of aggregate function context data\r
+    /// </summary>\r
+    private Dictionary<long, AggregateData> _contextDataList;\r
+\r
+    /// <summary>\r
+    /// Holds a reference to the callback function for user functions\r
+    /// </summary>\r
+    private SQLiteCallback  _InvokeFunc;\r
+    /// <summary>\r
+    /// Holds a reference to the callbakc function for stepping in an aggregate function\r
+    /// </summary>\r
+    private SQLiteCallback  _StepFunc;\r
+    /// <summary>\r
+    /// Holds a reference to the callback function for finalizing an aggregate function\r
+    /// </summary>\r
+    private SQLiteFinalCallback  _FinalFunc;\r
+    /// <summary>\r
+    /// Holds a reference to the callback function for collation sequences\r
+    /// </summary>\r
+    private SQLiteCollation _CompareFunc;\r
+\r
+    private SQLiteCollation _CompareFunc16;\r
+\r
+    /// <summary>\r
+    /// Current context of the current callback.  Only valid during a callback\r
+    /// </summary>\r
+    internal IntPtr _context;\r
+\r
+    /// <summary>\r
+    /// This static list contains all the user-defined functions declared using the proper attributes.\r
+    /// </summary>\r
+    private static List<SQLiteFunctionAttribute> _registeredFunctions = new List<SQLiteFunctionAttribute>();\r
+\r
+    /// <summary>\r
+    /// Internal constructor, initializes the function's internal variables.\r
+    /// </summary>\r
+    protected SQLiteFunction()\r
+    {\r
+      _contextDataList = new Dictionary<long, AggregateData>();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert\r
+    /// strings and DateTime's into the current connection's encoding schema.\r
+    /// </summary>\r
+    public SQLiteConvert SQLiteConvert\r
+    {\r
+      get\r
+      {\r
+        return _base;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Scalar functions override this method to do their magic.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available\r
+    /// to force them into a certain type.  Therefore the only types you will ever see as parameters are\r
+    /// DBNull.Value, Int64, Double, String or byte[] array.\r
+    /// </remarks>\r
+    /// <param name="args">The arguments for the command to process</param>\r
+    /// <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or\r
+    /// you may return an Exception-derived class if you wish to return an error to SQLite.  Do not actually throw the error,\r
+    /// just return it!</returns>\r
+    public virtual object Invoke(object[] args)\r
+    {\r
+      return null;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Aggregate functions override this method to do their magic.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible.\r
+    /// </remarks>\r
+    /// <param name="args">The arguments for the command to process</param>\r
+    /// <param name="stepNumber">The 1-based step number.  This is incrememted each time the step method is called.</param>\r
+    /// <param name="contextData">A placeholder for implementers to store contextual data pertaining to the current context.</param>\r
+    public virtual void Step(object[] args, int stepNumber, ref object contextData)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Aggregate functions override this method to finish their aggregate processing.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// If you implemented your aggregate function properly,\r
+    /// you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have\r
+    /// all the information you need in there to figure out what to return.\r
+    /// NOTE:  It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will\r
+    /// be null.  This can happen when no rows were returned.  You can either return null, or 0 or some other custom return value\r
+    /// if that is the case.\r
+    /// </remarks>\r
+    /// <param name="contextData">Your own assigned contextData, provided for you so you can return your final results.</param>\r
+    /// <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or\r
+    /// you may return an Exception-derived class if you wish to return an error to SQLite.  Do not actually throw the error,\r
+    /// just return it!\r
+    /// </returns>\r
+    public virtual object Final(object contextData)\r
+    {\r
+      return null;\r
+    }\r
+\r
+    /// <summary>\r
+    /// User-defined collation sequences override this method to provide a custom string sorting algorithm.\r
+    /// </summary>\r
+    /// <param name="param1">The first string to compare</param>\r
+    /// <param name="param2">The second strnig to compare</param>\r
+    /// <returns>1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2</returns>\r
+    public virtual int Compare(string param1, string param2)\r
+    {\r
+      return 0;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available\r
+    /// to force them into a certain type.  Therefore the only types you will ever see as parameters are\r
+    /// DBNull.Value, Int64, Double, String or byte[] array.\r
+    /// </remarks>\r
+    /// <param name="nArgs">The number of arguments</param>\r
+    /// <param name="argsptr">A pointer to the array of arguments</param>\r
+    /// <returns>An object array of the arguments once they've been converted to .NET values</returns>\r
+    internal object[] ConvertParams(int nArgs, IntPtr argsptr)\r
+    {\r
+      object[] parms = new object[nArgs];\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+      IntPtr[] argint = new IntPtr[nArgs];\r
+#else\r
+      int[] argint = new int[nArgs];\r
+#endif\r
+      Marshal.Copy(argsptr, argint, 0, nArgs);\r
+\r
+      for (int n = 0; n < nArgs; n++)\r
+      {\r
+        switch (_base.GetParamValueType((IntPtr)argint[n]))\r
+        {\r
+          case TypeAffinity.Null:\r
+            parms[n] = DBNull.Value;\r
+            break;\r
+          case TypeAffinity.Int64:\r
+            parms[n] = _base.GetParamValueInt64((IntPtr)argint[n]);\r
+            break;\r
+          case TypeAffinity.Double:\r
+            parms[n] = _base.GetParamValueDouble((IntPtr)argint[n]);\r
+            break;\r
+          case TypeAffinity.Text:\r
+            parms[n] = _base.GetParamValueText((IntPtr)argint[n]);\r
+            break;\r
+          case TypeAffinity.Blob:\r
+            {\r
+              int x;\r
+              byte[] blob;\r
+\r
+              x = (int)_base.GetParamValueBytes((IntPtr)argint[n], 0, null, 0, 0);\r
+              blob = new byte[x];\r
+              _base.GetParamValueBytes((IntPtr)argint[n], 0, blob, 0, x);\r
+              parms[n] = blob;\r
+            }\r
+            break;\r
+          case TypeAffinity.DateTime: // Never happens here but what the heck, maybe it will one day.\r
+            parms[n] = _base.ToDateTime(_base.GetParamValueText((IntPtr)argint[n]));\r
+            break;\r
+        }\r
+      }\r
+      return parms;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context.\r
+    /// </summary>\r
+    /// <param name="context">The context the return value applies to</param>\r
+    /// <param name="returnValue">The parameter to return to SQLite</param>\r
+    void SetReturnValue(IntPtr context, object returnValue)\r
+    {\r
+      if (returnValue == null || returnValue == DBNull.Value)\r
+      {\r
+        _base.ReturnNull(context);\r
+        return;\r
+      }\r
+\r
+      Type t = returnValue.GetType();\r
+      if (t == typeof(DateTime))\r
+      {\r
+        _base.ReturnText(context, _base.ToString((DateTime)returnValue));\r
+        return;\r
+      }\r
+      else\r
+      {\r
+        Exception r = returnValue as Exception;\r
+\r
+        if (r != null)\r
+        {\r
+          _base.ReturnError(context, r.Message);\r
+          return;\r
+        }\r
+      }\r
+\r
+      switch (SQLiteConvert.TypeToAffinity(t))\r
+      {\r
+        case TypeAffinity.Null:\r
+          _base.ReturnNull(context);\r
+          return;\r
+        case TypeAffinity.Int64:\r
+          _base.ReturnInt64(context, Convert.ToInt64(returnValue, CultureInfo.CurrentCulture));\r
+          return;\r
+        case TypeAffinity.Double:\r
+          _base.ReturnDouble(context, Convert.ToDouble(returnValue, CultureInfo.CurrentCulture));\r
+          return;\r
+        case TypeAffinity.Text:\r
+          _base.ReturnText(context, returnValue.ToString());\r
+          return;\r
+        case TypeAffinity.Blob:\r
+          _base.ReturnBlob(context, (byte[])returnValue);\r
+          return;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method.\r
+    /// </summary>\r
+    /// <param name="context">A raw context pointer</param>\r
+    /// <param name="nArgs">Number of arguments passed in</param>\r
+    /// <param name="argsptr">A pointer to the array of arguments</param>\r
+    internal void ScalarCallback(IntPtr context, int nArgs, IntPtr argsptr)\r
+    {\r
+      _context = context;\r
+      SetReturnValue(context, Invoke(ConvertParams(nArgs, argsptr)));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function.\r
+    /// </summary>\r
+    /// <param name="ptr">Not used</param>\r
+    /// <param name="len1">Length of the string pv1</param>\r
+    /// <param name="ptr1">Pointer to the first string to compare</param>\r
+    /// <param name="len2">Length of the string pv2</param>\r
+    /// <param name="ptr2">Pointer to the second string to compare</param>\r
+    /// <returns>Returns -1 if the first string is less than the second.  0 if they are equal, or 1 if the first string is greater\r
+    /// than the second.</returns>\r
+    internal int CompareCallback(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2)\r
+    {\r
+      return Compare(SQLiteConvert.UTF8ToString(ptr1, len1), SQLiteConvert.UTF8ToString(ptr2, len2));\r
+    }\r
+\r
+    internal int CompareCallback16(IntPtr ptr, int len1, IntPtr ptr1, int len2, IntPtr ptr2)\r
+    {\r
+      return Compare(SQLite3_UTF16.UTF16ToString(ptr1, len1), SQLite3_UTF16.UTF16ToString(ptr2, len2));\r
+    }\r
+\r
+    /// <summary>\r
+    /// The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method.\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// This function takes care of doing the lookups and getting the important information put together to call the Step() function.\r
+    /// That includes pulling out the user's contextData and updating it after the call is made.  We use a sorted list for this so\r
+    /// binary searches can be done to find the data.\r
+    /// </remarks>\r
+    /// <param name="context">A raw context pointer</param>\r
+    /// <param name="nArgs">Number of arguments passed in</param>\r
+    /// <param name="argsptr">A pointer to the array of arguments</param>\r
+    internal void StepCallback(IntPtr context, int nArgs, IntPtr argsptr)\r
+    {\r
+      long nAux;\r
+      AggregateData data;\r
+\r
+      nAux = (long)_base.AggregateContext(context);\r
+      if (_contextDataList.TryGetValue(nAux, out data) == false)\r
+      {\r
+        data = new AggregateData();\r
+        _contextDataList[nAux] = data;\r
+      }\r
+\r
+      try\r
+      {\r
+        _context = context;\r
+        Step(ConvertParams(nArgs, argsptr), data._count, ref data._data);\r
+      }\r
+      finally\r
+      {\r
+        data._count++;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method.\r
+    /// </summary>\r
+    /// <param name="context">A raw context pointer</param>\r
+    internal void FinalCallback(IntPtr context)\r
+    {\r
+      long n = (long)_base.AggregateContext(context);\r
+      object obj = null;\r
+\r
+      if (_contextDataList.ContainsKey(n))\r
+      {\r
+        obj = _contextDataList[n]._data;\r
+        _contextDataList.Remove(n);\r
+      }\r
+\r
+      _context = context;\r
+      SetReturnValue(context, Final(obj));\r
+\r
+      IDisposable disp = obj as IDisposable;\r
+      if (disp != null) disp.Dispose();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Placeholder for a user-defined disposal routine\r
+    /// </summary>\r
+    /// <param name="disposing">True if the object is being disposed explicitly</param>\r
+    protected virtual void Dispose(bool disposing)\r
+    {\r
+      if (disposing)\r
+      {\r
+        IDisposable disp;\r
+\r
+        foreach (KeyValuePair<long, AggregateData> kv in _contextDataList)\r
+        {\r
+          disp = kv.Value._data as IDisposable;\r
+          if (disp != null)\r
+            disp.Dispose();\r
+        }\r
+        _contextDataList.Clear();\r
+\r
+        _InvokeFunc = null;\r
+        _StepFunc = null;\r
+        _FinalFunc = null;\r
+        _CompareFunc = null;\r
+        _base = null;\r
+        _contextDataList = null;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Disposes of any active contextData variables that were not automatically cleaned up.  Sometimes this can happen if\r
+    /// someone closes the connection while a DataReader is open.\r
+    /// </summary>\r
+    public void Dispose()\r
+    {\r
+      Dispose(true);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Using reflection, enumerate all assemblies in the current appdomain looking for classes that\r
+    /// have a SQLiteFunctionAttribute attribute, and registering them accordingly.\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [Security.Permissions.FileIOPermission(Security.Permissions.SecurityAction.Assert, AllFiles = Security.Permissions.FileIOPermissionAccess.PathDiscovery)]\r
+#endif\r
+    static SQLiteFunction()\r
+    {\r
+      try\r
+      {\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+        SQLiteFunctionAttribute at;\r
+        System.Reflection.Assembly[] arAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();\r
+        int w = arAssemblies.Length;\r
+        System.Reflection.AssemblyName sqlite = System.Reflection.Assembly.GetCallingAssembly().GetName();\r
+\r
+        for (int n = 0; n < w; n++)\r
+        {\r
+          Type[] arTypes;\r
+          bool found = false;\r
+          System.Reflection.AssemblyName[] references;\r
+          try\r
+          {\r
+            // Inspect only assemblies that reference SQLite\r
+            references = arAssemblies[n].GetReferencedAssemblies();\r
+            int t = references.Length;\r
+            for (int z = 0; z < t; z++)\r
+            {\r
+              if (references[z].Name == sqlite.Name)\r
+              {\r
+                found = true;\r
+                break;\r
+              }\r
+            }\r
+\r
+            if (found == false)\r
+              continue;\r
+\r
+            arTypes = arAssemblies[n].GetTypes();\r
+          }\r
+          catch (Reflection.ReflectionTypeLoadException e)\r
+          {\r
+            arTypes = e.Types;\r
+          }\r
+\r
+          int v = arTypes.Length;\r
+          for (int x = 0; x < v; x++)\r
+          {\r
+            if (arTypes[x] == null) continue;\r
+\r
+            object[] arAtt = arTypes[x].GetCustomAttributes(typeof(SQLiteFunctionAttribute), false);\r
+            int u = arAtt.Length;\r
+            for (int y = 0; y < u; y++)\r
+            {\r
+              at = arAtt[y] as SQLiteFunctionAttribute;\r
+              if (at != null)\r
+              {\r
+                at._instanceType = arTypes[x];\r
+                _registeredFunctions.Add(at);\r
+              }\r
+            }\r
+          }\r
+        }\r
+#endif\r
+      }\r
+      catch // SQLite provider can continue without being able to find built-in functions\r
+      {\r
+      }\r
+    }\r
+    /// <summary>\r
+    /// Manual method of registering a function.  The type must still have the SQLiteFunctionAttributes in order to work\r
+    /// properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported.\r
+    /// </summary>\r
+    /// <param name="typ">The type of the function to register</param>\r
+    public static void RegisterFunction(Type typ)\r
+    {\r
+      object[] arAtt = typ.GetCustomAttributes(typeof(SQLiteFunctionAttribute), false);\r
+      int u = arAtt.Length;\r
+      SQLiteFunctionAttribute at;\r
+\r
+      for (int y = 0; y < u; y++)\r
+      {\r
+        at = arAtt[y] as SQLiteFunctionAttribute;\r
+        if (at != null)\r
+        {\r
+          at._instanceType = typ;\r
+          _registeredFunctions.Add(at);\r
+        }\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection.\r
+    /// It is done this way so that all user-defined functions will access the database using the same encoding scheme\r
+    /// as the connection (UTF-8 or UTF-16).\r
+    /// </summary>\r
+    /// <remarks>\r
+    /// The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to\r
+    /// all the wrapped callback functions.  The interop function uses it to map CDecl callbacks to StdCall callbacks.\r
+    /// </remarks>\r
+    /// <param name="sqlbase">The base object on which the functions are to bind</param>\r
+    /// <returns>Returns an array of functions which the connection object should retain until the connection is closed.</returns>\r
+    internal static SQLiteFunction[] BindFunctions(SQLiteBase sqlbase)\r
+    {\r
+      SQLiteFunction f;\r
+      List<SQLiteFunction> lFunctions = new List<SQLiteFunction>();\r
+\r
+      foreach (SQLiteFunctionAttribute pr in _registeredFunctions)\r
+      {\r
+        f = (SQLiteFunction)Activator.CreateInstance(pr._instanceType);\r
+        f._base = sqlbase;\r
+        f._InvokeFunc = (pr.FuncType == FunctionType.Scalar) ? new SQLiteCallback(f.ScalarCallback) : null;\r
+        f._StepFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.StepCallback) : null;\r
+        f._FinalFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteFinalCallback(f.FinalCallback) : null;\r
+        f._CompareFunc = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback) : null;\r
+        f._CompareFunc16 = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback16) : null;\r
+\r
+        if (pr.FuncType != FunctionType.Collation)\r
+          sqlbase.CreateFunction(pr.Name, pr.Arguments, (f is SQLiteFunctionEx), f._InvokeFunc, f._StepFunc, f._FinalFunc);\r
+        else\r
+          sqlbase.CreateCollation(pr.Name, f._CompareFunc, f._CompareFunc16);\r
+\r
+\r
+        lFunctions.Add(f);\r
+      }\r
+\r
+      SQLiteFunction[] arFunctions = new SQLiteFunction[lFunctions.Count];\r
+      lFunctions.CopyTo(arFunctions, 0);\r
+\r
+      return arFunctions;\r
+    }\r
+  }\r
+\r
+  /// <summary>\r
+  /// Extends SQLiteFunction and allows an inherited class to obtain the collating sequence associated with a function call.\r
+  /// </summary>\r
+  /// <remarks>\r
+  /// User-defined functions can call the GetCollationSequence() method in this class and use it to compare strings and char arrays.\r
+  /// </remarks>\r
+  public class SQLiteFunctionEx : SQLiteFunction\r
+  {\r
+    /// <summary>\r
+    /// Obtains the collating sequence in effect for the given function.\r
+    /// </summary>\r
+    /// <returns></returns>\r
+    protected CollationSequence GetCollationSequence()\r
+    {\r
+      return _base.GetCollationSequence(this, _context);\r
+    }\r
+  }\r
+\r
+  /// <summary>\r
+  /// The type of user-defined function to declare\r
+  /// </summary>\r
+  public enum FunctionType\r
+  {\r
+    /// <summary>\r
+    /// Scalar functions are designed to be called and return a result immediately.  Examples include ABS(), Upper(), Lower(), etc.\r
+    /// </summary>\r
+    Scalar = 0,\r
+    /// <summary>\r
+    /// Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data.\r
+    /// Examples include SUM(), COUNT(), AVG(), etc.\r
+    /// </summary>\r
+    Aggregate = 1,\r
+    /// <summary>\r
+    /// Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause.  Typically text in an ORDER BY is\r
+    /// sorted using a straight case-insensitive comparison function.  Custom collating sequences can be used to alter the behavior of text sorting\r
+    /// in a user-defined manner.\r
+    /// </summary>\r
+    Collation = 2,\r
+  }\r
+\r
+  /// <summary>\r
+  /// An internal callback delegate declaration.\r
+  /// </summary>\r
+  /// <param name="context">Raw context pointer for the user function</param>\r
+  /// <param name="nArgs">Count of arguments to the function</param>\r
+  /// <param name="argsptr">A pointer to the array of argument pointers</param>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\r
+#endif\r
+  internal delegate void SQLiteCallback(IntPtr context, int nArgs, IntPtr argsptr);\r
+  /// <summary>\r
+  /// An internal final callback delegate declaration.\r
+  /// </summary>\r
+  /// <param name="context">Raw context pointer for the user function</param>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\r
+#endif\r
+  internal delegate void SQLiteFinalCallback(IntPtr context);\r
+  /// <summary>\r
+  /// Internal callback delegate for implementing collation sequences\r
+  /// </summary>\r
+  /// <param name="puser">Not used</param>\r
+  /// <param name="len1">Length of the string pv1</param>\r
+  /// <param name="pv1">Pointer to the first string to compare</param>\r
+  /// <param name="len2">Length of the string pv2</param>\r
+  /// <param name="pv2">Pointer to the second string to compare</param>\r
+  /// <returns>Returns -1 if the first string is less than the second.  0 if they are equal, or 1 if the first string is greater\r
+  /// than the second.</returns>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\r
+#endif\r
+  internal delegate int SQLiteCollation(IntPtr puser, int len1, IntPtr pv1, int len2, IntPtr pv2);\r
+\r
+  /// <summary>\r
+  /// The type of collating sequence\r
+  /// </summary>\r
+  public enum CollationTypeEnum\r
+  {\r
+    /// <summary>\r
+    /// The built-in BINARY collating sequence\r
+    /// </summary>\r
+    Binary = 1,\r
+    /// <summary>\r
+    /// The built-in NOCASE collating sequence\r
+    /// </summary>\r
+    NoCase = 2,\r
+    /// <summary>\r
+    /// The built-in REVERSE collating sequence\r
+    /// </summary>\r
+    Reverse = 3,\r
+    /// <summary>\r
+    /// A custom user-defined collating sequence\r
+    /// </summary>\r
+    Custom = 0,\r
+  }\r
+\r
+  /// <summary>\r
+  /// The encoding type the collation sequence uses\r
+  /// </summary>\r
+  public enum CollationEncodingEnum\r
+  {\r
+    /// <summary>\r
+    /// The collation sequence is UTF8\r
+    /// </summary>\r
+    UTF8 = 1,\r
+    /// <summary>\r
+    /// The collation sequence is UTF16 little-endian\r
+    /// </summary>\r
+    UTF16LE = 2,\r
+    /// <summary>\r
+    /// The collation sequence is UTF16 big-endian\r
+    /// </summary>\r
+    UTF16BE = 3,\r
+  }\r
+\r
+  /// <summary>\r
+  /// A struct describing the collating sequence a function is executing in\r
+  /// </summary>\r
+  public struct CollationSequence\r
+  {\r
+    /// <summary>\r
+    /// The name of the collating sequence\r
+    /// </summary>\r
+    public string Name;\r
+    /// <summary>\r
+    /// The type of collating sequence\r
+    /// </summary>\r
+    public CollationTypeEnum Type;\r
+\r
+    /// <summary>\r
+    /// The text encoding of the collation sequence\r
+    /// </summary>\r
+    public CollationEncodingEnum Encoding;\r
+\r
+    /// <summary>\r
+    /// Context of the function that requested the collating sequence\r
+    /// </summary>\r
+    internal SQLiteFunction _func;\r
+\r
+    /// <summary>\r
+    /// Calls the base collating sequence to compare two strings\r
+    /// </summary>\r
+    /// <param name="s1">The first string to compare</param>\r
+    /// <param name="s2">The second string to compare</param>\r
+    /// <returns>-1 if s1 is less than s2, 0 if s1 is equal to s2, and 1 if s1 is greater than s2</returns>\r
+    public int Compare(string s1, string s2)\r
+    {\r
+      return _func._base.ContextCollateCompare(Encoding, _func._context, s1, s2);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Calls the base collating sequence to compare two character arrays\r
+    /// </summary>\r
+    /// <param name="c1">The first array to compare</param>\r
+    /// <param name="c2">The second array to compare</param>\r
+    /// <returns>-1 if c1 is less than c2, 0 if c1 is equal to c2, and 1 if c1 is greater than c2</returns>\r
+    public int Compare(char[] c1, char[] c2)\r
+    {\r
+      return _func._base.ContextCollateCompare(Encoding, _func._context, c1, c2);\r
+    }\r
+  }\r
+}\r
index a455b936f60e58af76db5ff3f86c37cf81cb7302..b6f485b8a5f3582362e7c701898c4a6e9d1e8ba5 100644 (file)
@@ -1,96 +1,62 @@
-//
-// Mono.Data.Sqlite.SQLiteFunctionAttribute.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Runtime.InteropServices;
-
-  /// <summary>
-  /// A simple custom attribute to enable us to easily find user-defined functions in
-  /// the loaded assemblies and initialize them in Sqlite as connections are made.
-  /// </summary>
-  [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
-  public class SqliteFunctionAttribute : Attribute
-  {
-    private string       _name;
-    private int          _arguments;
-    private FunctionType _functionType;
-    internal Type        _instanceType;
-
-    /// <summary>
-    /// Default constructor, initializes the internal variables for the function.
-    /// </summary>
-    public SqliteFunctionAttribute()
-    {
-      Name = "";
-      Arguments = -1;
-      FuncType = FunctionType.Scalar;
-    }
-
-    /// <summary>
-    /// The function's name as it will be used in Sqlite command text.
-    /// </summary>
-    public string Name
-    {
-      get { return _name; }
-      set { _name = value; }
-    }
-
-    /// <summary>
-    /// The number of arguments this function expects.  -1 if the number of arguments is variable.
-    /// </summary>
-    public int Arguments
-    {
-      get { return _arguments; }
-      set { _arguments = value; }
-    }
-
-    /// <summary>
-    /// The type of function this implementation will be.
-    /// </summary>
-    public FunctionType FuncType
-    {
-      get { return _functionType; }
-      set { _functionType = value; }
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Runtime.InteropServices;\r
+\r
+  /// <summary>\r
+  /// A simple custom attribute to enable us to easily find user-defined functions in\r
+  /// the loaded assemblies and initialize them in SQLite as connections are made.\r
+  /// </summary>\r
+  [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]\r
+  public sealed class SQLiteFunctionAttribute : Attribute\r
+  {\r
+    private string       _name;\r
+    private int          _arguments;\r
+    private FunctionType _functionType;\r
+    internal Type        _instanceType;\r
+\r
+    /// <summary>\r
+    /// Default constructor, initializes the internal variables for the function.\r
+    /// </summary>\r
+    public SQLiteFunctionAttribute()\r
+    {\r
+      Name = "";\r
+      Arguments = -1;\r
+      FuncType = FunctionType.Scalar;\r
+    }\r
+\r
+    /// <summary>\r
+    /// The function's name as it will be used in SQLite command text.\r
+    /// </summary>\r
+    public string Name\r
+    {\r
+      get { return _name; }\r
+      set { _name = value; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// The number of arguments this function expects.  -1 if the number of arguments is variable.\r
+    /// </summary>\r
+    public int Arguments\r
+    {\r
+      get { return _arguments; }\r
+      set { _arguments = value; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// The type of function this implementation will be.\r
+    /// </summary>\r
+    public FunctionType FuncType\r
+    {\r
+      get { return _functionType; }\r
+      set { _functionType = value; }\r
+    }\r
+  }\r
+}\r
index ac8f305e630216932794f598347c7becf9c88d5c..828b68fc1c291840d5707d822ff43e677be8b806 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteKeyReader.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Data.Common;
-  using System.Collections.Generic;
-
-  /// <summary>
-  /// This class provides key info for a given Sqlite statement.
-  /// <remarks>
-  /// Providing key information for a given statement is non-trivial :(
-  /// </remarks>
-  /// </summary>
-  internal sealed class SqliteKeyReader : IDisposable
-  {
-    private KeyInfo[] _keyInfo;
-    private SqliteStatement _stmt;
-    private bool _isValid;
-
-    /// <summary>
-    /// Used to support CommandBehavior.KeyInfo
-    /// </summary>
-    private struct KeyInfo
-    {
-      internal string databaseName;
-      internal string tableName;
-      internal string columnName;
-      internal int database;
-      internal int rootPage;
-      internal int cursor;
-      internal KeyQuery query;
-      internal int column;
-    }
-
-    /// <summary>
-    /// A single sub-query for a given table/database.
-    /// </summary>
-    private class KeyQuery : IDisposable
-    {
-      private SqliteCommand _command;
-      internal SqliteDataReader _reader;
-
-      internal KeyQuery(SqliteConnection cnn, string database, string table, params string[] columns)
-      {
-        using (SqliteCommandBuilder builder = new SqliteCommandBuilder())
-        {
-          _command = cnn.CreateCommand();
-          for (int n = 0; n < columns.Length; n++)
-          {
-            columns[n] = builder.QuoteIdentifier(columns[n]);
-          }
-        }
-        _command.CommandText = String.Format("SELECT {0} FROM [{1}].[{2}] WHERE ROWID = ?", String.Join(",", columns), database, table);
-        _command.Parameters.AddWithValue(null, (long)0);
-      }
-
-      internal bool IsValid
-      {
-        get { return (_reader != null); }
-        set
-        {
-          if (value != false) throw new ArgumentException();
-          if (_reader != null)
-          {
-            _reader.Dispose();
-            _reader = null;
-          }
-        }
-      }
-
-      internal void Sync(long rowid)
-      {
-        IsValid = false;
-        _command.Parameters[0].Value = rowid;
-        _reader = _command.ExecuteReader();
-        _reader.Read();
-      }
-
-      public void Dispose()
-      {
-        IsValid = false;
-
-        if (_command != null) _command.Dispose();
-        _command = null;
-      }
-    }
-
-    /// <summary>
-    /// This function does all the nasty work at determining what keys need to be returned for
-    /// a given statement.
-    /// </summary>
-    /// <param name="cnn"></param>
-    /// <param name="reader"></param>
-    /// <param name="stmt"></param>
-    internal SqliteKeyReader(SqliteConnection cnn, SqliteDataReader reader, SqliteStatement stmt)
-    {
-      Dictionary<string, int> catalogs = new Dictionary<string, int>();
-      Dictionary<string, List<string>> tables = new Dictionary<string, List<string>>();
-      List<string> list;
-      List<KeyInfo> keys = new List<KeyInfo>();
-
-      // Record the statement so we can use it later for sync'ing
-      _stmt = stmt;
-
-      // Fetch all the attached databases on this connection
-      using (DataTable tbl = cnn.GetSchema("Catalogs"))
-      {
-        foreach (DataRow row in tbl.Rows)
-        {
-          catalogs.Add((string)row["CATALOG_NAME"], Convert.ToInt32(row["ID"]));
-        }
-      }
-
-      // Fetch all the unique tables and catalogs used by the current statement
-      using (DataTable schema = reader.GetSchemaTable(false, false))
-      {
-        foreach (DataRow row in schema.Rows)
-        {
-          // Check if column is backed to a table
-          if (row[SchemaTableOptionalColumn.BaseCatalogName] == DBNull.Value)
-            continue;
-
-          // Record the unique table so we can look up its keys
-          string catalog = (string)row[SchemaTableOptionalColumn.BaseCatalogName];
-          string table = (string)row[SchemaTableColumn.BaseTableName];
-
-          if (tables.ContainsKey(catalog) == false)
-          {
-            list = new List<string>();
-            tables.Add(catalog, list);
-          }
-          else
-            list = tables[catalog];
-
-          if (list.Contains(table) == false)
-            list.Add(table);
-        }
-
-        // For each catalog and each table, query the indexes for the table.
-        // Find a primary key index if there is one.  If not, find a unique index instead
-        foreach (KeyValuePair<string, List<string>> pair in tables)
-        {
-          for (int i = 0; i < pair.Value.Count; i++)
-          {
-            string table = pair.Value[i];
-            DataRow preferredRow = null;
-            using (DataTable tbl = cnn.GetSchema("Indexes", new string[] { pair.Key, null, table }))
-            {
-              // Loop twice.  The first time looking for a primary key index, 
-              // the second time looking for a unique index
-              for (int n = 0; n < 2 && preferredRow == null; n++)
-              {
-                foreach (DataRow row in tbl.Rows)
-                {
-                  if (n == 0 && (bool)row["PRIMARY_KEY"] == true)
-                  {
-                    preferredRow = row;
-                    break;
-                  }
-                  else if (n == 1 && (bool)row["UNIQUE"] == true)
-                  {
-                    preferredRow = row;
-                    break;
-                  }
-                }
-              }
-              if (preferredRow == null) // Unable to find any suitable index for this table so remove it
-              {
-                pair.Value.RemoveAt(i);
-                i--;
-              }
-              else // We found a usable index, so fetch the necessary table details
-              {
-                using (DataTable tblTables = cnn.GetSchema("Tables", new string[] { pair.Key, null, table }))
-                {
-                  // Find the root page of the table in the current statement and get the cursor that's iterating it
-                  int database = catalogs[pair.Key];
-                  int rootPage = Convert.ToInt32(tblTables.Rows[0]["TABLE_ROOTPAGE"]);
-                  int cursor = stmt._sql.GetCursorForTable(stmt, database, rootPage);
-
-                  // Now enumerate the members of the index we're going to use
-                  using (DataTable indexColumns = cnn.GetSchema("IndexColumns", new string[] { pair.Key, null, table, (string)preferredRow["INDEX_NAME"] }))
-                  {
-                    KeyQuery query = null;
-
-                    List<string> cols = new List<string>();
-                    for (int x = 0; x < indexColumns.Rows.Count; x++)
-                    {
-                      bool addKey = true;
-                      // If the column in the index already appears in the query, skip it
-                      foreach (DataRow row in schema.Rows)
-                      {
-                        if (row.IsNull(SchemaTableColumn.BaseColumnName))
-                          continue;
-
-                        if ((string)row[SchemaTableColumn.BaseColumnName] == (string)indexColumns.Rows[x]["COLUMN_NAME"] &&
-                            (string)row[SchemaTableColumn.BaseTableName] == table &&
-                            (string)row[SchemaTableOptionalColumn.BaseCatalogName] == pair.Key)
-                        {
-                          indexColumns.Rows.RemoveAt(x);
-                          x--;
-                          addKey = false;
-                          break;
-                        }
-                      }
-                      if (addKey == true)
-                        cols.Add((string)indexColumns.Rows[x]["COLUMN_NAME"]);
-                    }
-
-                    // If the index is not a rowid alias, record all the columns
-                    // needed to make up the unique index and construct a SQL query for it
-                    if ((string)preferredRow["INDEX_NAME"] != "sqlite_master_PK_" + table)
-                    {
-                      // Whatever remains of the columns we need that make up the index that are not
-                      // already in the query need to be queried separately, so construct a subquery
-                      if (cols.Count > 0)
-                      {
-                        string[] querycols = new string[cols.Count];
-                        cols.CopyTo(querycols);
-                        query = new KeyQuery(cnn, pair.Key, table, querycols);
-                      }
-                    }
-
-                    // Create a KeyInfo struct for each column of the index
-                    for (int x = 0; x < indexColumns.Rows.Count; x++)
-                    {
-                      string columnName = (string)indexColumns.Rows[x]["COLUMN_NAME"];
-                      KeyInfo key = new KeyInfo();
-
-                      key.rootPage = rootPage;
-                      key.cursor = cursor;
-                      key.database = database;
-                      key.databaseName = pair.Key;
-                      key.tableName = table;
-                      key.columnName = columnName;
-                      key.query = query;
-                      key.column = x;
-
-                      keys.Add(key);
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-
-      // Now we have all the additional columns we have to return in order to support
-      // CommandBehavior.KeyInfo
-      _keyInfo = new KeyInfo[keys.Count];
-      keys.CopyTo(_keyInfo);
-    }
-
-    /// <summary>
-    /// How many additional columns of keyinfo we're holding
-    /// </summary>
-    internal int Count
-    {
-      get { return (_keyInfo == null) ? 0 : _keyInfo.Length; }
-    }
-
-    internal void Sync(int i)
-    {
-      Sync();
-      if (_keyInfo[i].cursor == -1)
-        throw new InvalidCastException();
-    }
-
-    /// <summary>
-    /// Make sure all the subqueries are open and ready and sync'd with the current rowid
-    /// of the table they're supporting
-    /// </summary>
-    internal void Sync()
-    {
-      if (_isValid == true) return;
-
-      KeyQuery last = null;
-
-      for (int n = 0; n < _keyInfo.Length; n++)
-      {
-        if (_keyInfo[n].query == null || _keyInfo[n].query != last)
-        {
-          last = _keyInfo[n].query;
-
-          if (last != null)
-          {
-            last.Sync(_stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[n].cursor));
-          }
-        }
-      }
-      _isValid = true;
-    }
-
-    /// <summary>
-    /// Release any readers on any subqueries
-    /// </summary>
-    internal void Reset()
-    {
-      _isValid = false;
-      if (_keyInfo == null) return;
-
-      for (int n = 0; n < _keyInfo.Length; n++)
-      {
-        if (_keyInfo[n].query != null)
-          _keyInfo[n].query.IsValid = false;
-      }
-    }
-
-    public void Dispose()
-    {
-      _stmt = null;
-
-      if (_keyInfo == null) return;
-
-      for (int n = 0; n < _keyInfo.Length; n++)
-      {
-        if (_keyInfo[n].query != null)
-          _keyInfo[n].query.Dispose();
-      }
-      _keyInfo = null;
-    }
-
-    internal string GetDataTypeName(int i)
-    {
-      Sync();
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDataTypeName(_keyInfo[i].column);
-      else return "integer";
-    }
-
-    internal Type GetFieldType(int i)
-    {
-      Sync();
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetFieldType(_keyInfo[i].column);
-      else return typeof(Int64);
-    }
-
-    internal string GetName(int i)
-    {
-      return _keyInfo[i].columnName;
-    }
-
-    internal int GetOrdinal(string name)
-    {
-      for (int n = 0; n < _keyInfo.Length; n++)
-      {
-        if (String.Compare(name, _keyInfo[n].columnName, StringComparison.OrdinalIgnoreCase) == 0) return n;
-      }
-      return -1;
-    }
-
-    internal bool GetBoolean(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetBoolean(_keyInfo[i].column);
-      else throw new InvalidCastException();
-    }
-
-    internal byte GetByte(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetByte(_keyInfo[i].column);
-      else throw new InvalidCastException();
-    }
-
-    internal long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetBytes(_keyInfo[i].column, fieldOffset, buffer, bufferoffset, length);
-      else throw new InvalidCastException();
-    }
-
-    internal char GetChar(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetChar(_keyInfo[i].column);
-      else throw new InvalidCastException();
-    }
-
-    internal long GetChars(int i, long fieldOffset, char[] buffer, int bufferoffset, int length)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetChars(_keyInfo[i].column, fieldOffset, buffer, bufferoffset, length);
-      else throw new InvalidCastException();
-    }
-
-    internal DateTime GetDateTime(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDateTime(_keyInfo[i].column);
-      else throw new InvalidCastException();
-    }
-
-    internal decimal GetDecimal(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDecimal(_keyInfo[i].column);
-      else throw new InvalidCastException();
-    }
-
-    internal double GetDouble(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDouble(_keyInfo[i].column);
-      else throw new InvalidCastException();
-    }
-
-    internal float GetFloat(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetFloat(_keyInfo[i].column);
-      else throw new InvalidCastException();
-    }
-
-    internal Guid GetGuid(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetGuid(_keyInfo[i].column);
-      else throw new InvalidCastException();
-    }
-
-    internal Int16 GetInt16(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetInt16(_keyInfo[i].column);
-      else
-      {
-        long rowid = _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor);
-        if (rowid == 0) throw new InvalidCastException();
-        return Convert.ToInt16(rowid);
-      }
-    }
-
-    internal Int32 GetInt32(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetInt32(_keyInfo[i].column);
-      else
-      {
-        long rowid = _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor);
-        if (rowid == 0) throw new InvalidCastException();
-        return Convert.ToInt32(rowid);
-      }
-    }
-
-    internal Int64 GetInt64(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetInt64(_keyInfo[i].column);
-      else
-      {
-        long rowid = _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor);
-        if (rowid == 0) throw new InvalidCastException();
-        return Convert.ToInt64(rowid);
-      }
-    }
-
-    internal string GetString(int i)
-    {
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetString(_keyInfo[i].column);
-      else throw new InvalidCastException();
-    }
-
-    internal object GetValue(int i)
-    {
-      if (_keyInfo[i].cursor == -1) return DBNull.Value;
-
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetValue(_keyInfo[i].column);
-
-      if (IsDBNull(i) == true)
-        return DBNull.Value;
-      else return GetInt64(i);
-    }
-
-    internal bool IsDBNull(int i)
-    {
-      if (_keyInfo[i].cursor == -1) return true;
-
-      Sync(i);
-      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.IsDBNull(_keyInfo[i].column);
-      else return _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor) == 0;
-    }
-
-    /// <summary>
-    /// Append all the columns we've added to the original query to the schema
-    /// </summary>
-    /// <param name="tbl"></param>
-    internal void AppendSchemaTable(DataTable tbl)
-    {
-      KeyQuery last = null;
-
-      for (int n = 0; n < _keyInfo.Length; n++)
-      {
-        if (_keyInfo[n].query == null || _keyInfo[n].query != last)
-        {
-          last = _keyInfo[n].query;
-
-          if (last == null) // ROWID aliases are treated special
-          {
-            DataRow row = tbl.NewRow();
-            row[SchemaTableColumn.ColumnName] = _keyInfo[n].columnName;
-            row[SchemaTableColumn.ColumnOrdinal] = tbl.Rows.Count;
-            row[SchemaTableColumn.ColumnSize] = 8;
-            row[SchemaTableColumn.NumericPrecision] = 255;
-            row[SchemaTableColumn.NumericScale] = 255;
-            row[SchemaTableColumn.ProviderType] = DbType.Int64;
-            row[SchemaTableColumn.IsLong] = false;
-            row[SchemaTableColumn.AllowDBNull] = false;
-            row[SchemaTableOptionalColumn.IsReadOnly] = false;
-            row[SchemaTableOptionalColumn.IsRowVersion] = false;
-            row[SchemaTableColumn.IsUnique] = false;
-            row[SchemaTableColumn.IsKey] = true;
-            row[SchemaTableColumn.DataType] = typeof(Int64);
-            row[SchemaTableOptionalColumn.IsHidden] = true;
-            row[SchemaTableColumn.BaseColumnName] = _keyInfo[n].columnName;
-            row[SchemaTableColumn.IsExpression] = false;
-            row[SchemaTableColumn.IsAliased] = false;
-            row[SchemaTableColumn.BaseTableName] = _keyInfo[n].tableName;
-            row[SchemaTableOptionalColumn.BaseCatalogName] = _keyInfo[n].databaseName;
-            row[SchemaTableOptionalColumn.IsAutoIncrement] = true;
-            row["DataTypeName"] = "integer";
-
-            tbl.Rows.Add(row);
-          }
-          else
-          {
-            last.Sync(0);
-            using (DataTable tblSub = last._reader.GetSchemaTable())
-            {
-              foreach (DataRow row in tblSub.Rows)
-              {
-                object[] o = row.ItemArray;
-                DataRow newrow = tbl.Rows.Add(o);
-                newrow[SchemaTableOptionalColumn.IsHidden] = true;
-                newrow[SchemaTableColumn.ColumnOrdinal] = tbl.Rows.Count - 1;
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Data.Common;\r
+  using System.Collections.Generic;\r
+\r
+  /// <summary>\r
+  /// This class provides key info for a given SQLite statement.\r
+  /// <remarks>\r
+  /// Providing key information for a given statement is non-trivial :(\r
+  /// </remarks>\r
+  /// </summary>\r
+  internal sealed class SQLiteKeyReader : IDisposable\r
+  {\r
+    private KeyInfo[] _keyInfo;\r
+    private SQLiteStatement _stmt;\r
+    private bool _isValid;\r
+\r
+    /// <summary>\r
+    /// Used to support CommandBehavior.KeyInfo\r
+    /// </summary>\r
+    private struct KeyInfo\r
+    {\r
+      internal string databaseName;\r
+      internal string tableName;\r
+      internal string columnName;\r
+      internal int database;\r
+      internal int rootPage;\r
+      internal int cursor;\r
+      internal KeyQuery query;\r
+      internal int column;\r
+    }\r
+\r
+    /// <summary>\r
+    /// A single sub-query for a given table/database.\r
+    /// </summary>\r
+    private sealed class KeyQuery : IDisposable\r
+    {\r
+      private SQLiteCommand _command;\r
+      internal SQLiteDataReader _reader;\r
+\r
+      internal KeyQuery(SQLiteConnection cnn, string database, string table, params string[] columns)\r
+      {\r
+        using (SQLiteCommandBuilder builder = new SQLiteCommandBuilder())\r
+        {\r
+          _command = cnn.CreateCommand();\r
+          for (int n = 0; n < columns.Length; n++)\r
+          {\r
+            columns[n] = builder.QuoteIdentifier(columns[n]);\r
+          }\r
+        }\r
+        _command.CommandText = String.Format("SELECT {0} FROM [{1}].[{2}] WHERE ROWID = ?", String.Join(",", columns), database, table);\r
+        _command.Parameters.AddWithValue(null, (long)0);\r
+      }\r
+\r
+      internal bool IsValid\r
+      {\r
+        get { return (_reader != null); }\r
+        set\r
+        {\r
+          if (value != false) throw new ArgumentException();\r
+          if (_reader != null)\r
+          {\r
+            _reader.Dispose();\r
+            _reader = null;\r
+          }\r
+        }\r
+      }\r
+\r
+      internal void Sync(long rowid)\r
+      {\r
+        IsValid = false;\r
+        _command.Parameters[0].Value = rowid;\r
+        _reader = _command.ExecuteReader();\r
+        _reader.Read();\r
+      }\r
+\r
+      public void Dispose()\r
+      {\r
+        IsValid = false;\r
+\r
+        if (_command != null) _command.Dispose();\r
+        _command = null;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// This function does all the nasty work at determining what keys need to be returned for\r
+    /// a given statement.\r
+    /// </summary>\r
+    /// <param name="cnn"></param>\r
+    /// <param name="reader"></param>\r
+    /// <param name="stmt"></param>\r
+    internal SQLiteKeyReader(SQLiteConnection cnn, SQLiteDataReader reader, SQLiteStatement stmt)\r
+    {\r
+      Dictionary<string, int> catalogs = new Dictionary<string, int>();\r
+      Dictionary<string, List<string>> tables = new Dictionary<string, List<string>>();\r
+      List<string> list;\r
+      List<KeyInfo> keys = new List<KeyInfo>();\r
+\r
+      // Record the statement so we can use it later for sync'ing\r
+      _stmt = stmt;\r
+\r
+      // Fetch all the attached databases on this connection\r
+      using (DataTable tbl = cnn.GetSchema("Catalogs"))\r
+      {\r
+        foreach (DataRow row in tbl.Rows)\r
+        {\r
+          catalogs.Add((string)row["CATALOG_NAME"], Convert.ToInt32(row["ID"]));\r
+        }\r
+      }\r
+\r
+      // Fetch all the unique tables and catalogs used by the current statement\r
+      using (DataTable schema = reader.GetSchemaTable(false, false))\r
+      {\r
+        foreach (DataRow row in schema.Rows)\r
+        {\r
+          // Check if column is backed to a table\r
+          if (row[SchemaTableOptionalColumn.BaseCatalogName] == DBNull.Value)\r
+            continue;\r
+\r
+          // Record the unique table so we can look up its keys\r
+          string catalog = (string)row[SchemaTableOptionalColumn.BaseCatalogName];\r
+          string table = (string)row[SchemaTableColumn.BaseTableName];\r
+\r
+          if (tables.ContainsKey(catalog) == false)\r
+          {\r
+            list = new List<string>();\r
+            tables.Add(catalog, list);\r
+          }\r
+          else\r
+            list = tables[catalog];\r
+\r
+          if (list.Contains(table) == false)\r
+            list.Add(table);\r
+        }\r
+\r
+        // For each catalog and each table, query the indexes for the table.\r
+        // Find a primary key index if there is one.  If not, find a unique index instead\r
+        foreach (KeyValuePair<string, List<string>> pair in tables)\r
+        {\r
+          for (int i = 0; i < pair.Value.Count; i++)\r
+          {\r
+            string table = pair.Value[i];\r
+            DataRow preferredRow = null;\r
+            using (DataTable tbl = cnn.GetSchema("Indexes", new string[] { pair.Key, null, table }))\r
+            {\r
+              // Loop twice.  The first time looking for a primary key index, \r
+              // the second time looking for a unique index\r
+              for (int n = 0; n < 2 && preferredRow == null; n++)\r
+              {\r
+                foreach (DataRow row in tbl.Rows)\r
+                {\r
+                  if (n == 0 && (bool)row["PRIMARY_KEY"] == true)\r
+                  {\r
+                    preferredRow = row;\r
+                    break;\r
+                  }\r
+                  else if (n == 1 && (bool)row["UNIQUE"] == true)\r
+                  {\r
+                    preferredRow = row;\r
+                    break;\r
+                  }\r
+                }\r
+              }\r
+              if (preferredRow == null) // Unable to find any suitable index for this table so remove it\r
+              {\r
+                pair.Value.RemoveAt(i);\r
+                i--;\r
+              }\r
+              else // We found a usable index, so fetch the necessary table details\r
+              {\r
+                using (DataTable tblTables = cnn.GetSchema("Tables", new string[] { pair.Key, null, table }))\r
+                {\r
+                  // Find the root page of the table in the current statement and get the cursor that's iterating it\r
+                  int database = catalogs[pair.Key];\r
+                  int rootPage = Convert.ToInt32(tblTables.Rows[0]["TABLE_ROOTPAGE"]);\r
+                  int cursor = stmt._sql.GetCursorForTable(stmt, database, rootPage);\r
+\r
+                  // Now enumerate the members of the index we're going to use\r
+                  using (DataTable indexColumns = cnn.GetSchema("IndexColumns", new string[] { pair.Key, null, table, (string)preferredRow["INDEX_NAME"] }))\r
+                  {\r
+                    KeyQuery query = null;\r
+\r
+                    List<string> cols = new List<string>();\r
+                    for (int x = 0; x < indexColumns.Rows.Count; x++)\r
+                    {\r
+                      bool addKey = true;\r
+                      // If the column in the index already appears in the query, skip it\r
+                      foreach (DataRow row in schema.Rows)\r
+                      {\r
+                        if (row.IsNull(SchemaTableColumn.BaseColumnName))\r
+                          continue;\r
+\r
+                        if ((string)row[SchemaTableColumn.BaseColumnName] == (string)indexColumns.Rows[x]["COLUMN_NAME"] &&\r
+                            (string)row[SchemaTableColumn.BaseTableName] == table &&\r
+                            (string)row[SchemaTableOptionalColumn.BaseCatalogName] == pair.Key)\r
+                        {\r
+                          indexColumns.Rows.RemoveAt(x);\r
+                          x--;\r
+                          addKey = false;\r
+                          break;\r
+                        }\r
+                      }\r
+                      if (addKey == true)\r
+                        cols.Add((string)indexColumns.Rows[x]["COLUMN_NAME"]);\r
+                    }\r
+\r
+                    // If the index is not a rowid alias, record all the columns\r
+                    // needed to make up the unique index and construct a SQL query for it\r
+                    if ((string)preferredRow["INDEX_NAME"] != "sqlite_master_PK_" + table)\r
+                    {\r
+                      // Whatever remains of the columns we need that make up the index that are not\r
+                      // already in the query need to be queried separately, so construct a subquery\r
+                      if (cols.Count > 0)\r
+                      {\r
+                        string[] querycols = new string[cols.Count];\r
+                        cols.CopyTo(querycols);\r
+                        query = new KeyQuery(cnn, pair.Key, table, querycols);\r
+                      }\r
+                    }\r
+\r
+                    // Create a KeyInfo struct for each column of the index\r
+                    for (int x = 0; x < indexColumns.Rows.Count; x++)\r
+                    {\r
+                      string columnName = (string)indexColumns.Rows[x]["COLUMN_NAME"];\r
+                      KeyInfo key = new KeyInfo();\r
+\r
+                      key.rootPage = rootPage;\r
+                      key.cursor = cursor;\r
+                      key.database = database;\r
+                      key.databaseName = pair.Key;\r
+                      key.tableName = table;\r
+                      key.columnName = columnName;\r
+                      key.query = query;\r
+                      key.column = x;\r
+\r
+                      keys.Add(key);\r
+                    }\r
+                  }\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+\r
+      // Now we have all the additional columns we have to return in order to support\r
+      // CommandBehavior.KeyInfo\r
+      _keyInfo = new KeyInfo[keys.Count];\r
+      keys.CopyTo(_keyInfo);\r
+    }\r
+\r
+    /// <summary>\r
+    /// How many additional columns of keyinfo we're holding\r
+    /// </summary>\r
+    internal int Count\r
+    {\r
+      get { return (_keyInfo == null) ? 0 : _keyInfo.Length; }\r
+    }\r
+\r
+    internal void Sync(int i)\r
+    {\r
+      Sync();\r
+      if (_keyInfo[i].cursor == -1)\r
+        throw new InvalidCastException();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Make sure all the subqueries are open and ready and sync'd with the current rowid\r
+    /// of the table they're supporting\r
+    /// </summary>\r
+    internal void Sync()\r
+    {\r
+      if (_isValid == true) return;\r
+\r
+      KeyQuery last = null;\r
+\r
+      for (int n = 0; n < _keyInfo.Length; n++)\r
+      {\r
+        if (_keyInfo[n].query == null || _keyInfo[n].query != last)\r
+        {\r
+          last = _keyInfo[n].query;\r
+\r
+          if (last != null)\r
+          {\r
+            last.Sync(_stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[n].cursor));\r
+          }\r
+        }\r
+      }\r
+      _isValid = true;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Release any readers on any subqueries\r
+    /// </summary>\r
+    internal void Reset()\r
+    {\r
+      _isValid = false;\r
+      if (_keyInfo == null) return;\r
+\r
+      for (int n = 0; n < _keyInfo.Length; n++)\r
+      {\r
+        if (_keyInfo[n].query != null)\r
+          _keyInfo[n].query.IsValid = false;\r
+      }\r
+    }\r
+\r
+    public void Dispose()\r
+    {\r
+      _stmt = null;\r
+\r
+      if (_keyInfo == null) return;\r
+\r
+      for (int n = 0; n < _keyInfo.Length; n++)\r
+      {\r
+        if (_keyInfo[n].query != null)\r
+          _keyInfo[n].query.Dispose();\r
+      }\r
+      _keyInfo = null;\r
+    }\r
+\r
+    internal string GetDataTypeName(int i)\r
+    {\r
+      Sync();\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDataTypeName(_keyInfo[i].column);\r
+      else return "integer";\r
+    }\r
+\r
+    internal Type GetFieldType(int i)\r
+    {\r
+      Sync();\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetFieldType(_keyInfo[i].column);\r
+      else return typeof(Int64);\r
+    }\r
+\r
+    internal string GetName(int i)\r
+    {\r
+      return _keyInfo[i].columnName;\r
+    }\r
+\r
+    internal int GetOrdinal(string name)\r
+    {\r
+      for (int n = 0; n < _keyInfo.Length; n++)\r
+      {\r
+        if (String.Compare(name, _keyInfo[n].columnName, StringComparison.OrdinalIgnoreCase) == 0) return n;\r
+      }\r
+      return -1;\r
+    }\r
+\r
+    internal bool GetBoolean(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetBoolean(_keyInfo[i].column);\r
+      else throw new InvalidCastException();\r
+    }\r
+\r
+    internal byte GetByte(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetByte(_keyInfo[i].column);\r
+      else throw new InvalidCastException();\r
+    }\r
+\r
+    internal long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetBytes(_keyInfo[i].column, fieldOffset, buffer, bufferoffset, length);\r
+      else throw new InvalidCastException();\r
+    }\r
+\r
+    internal char GetChar(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetChar(_keyInfo[i].column);\r
+      else throw new InvalidCastException();\r
+    }\r
+\r
+    internal long GetChars(int i, long fieldOffset, char[] buffer, int bufferoffset, int length)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetChars(_keyInfo[i].column, fieldOffset, buffer, bufferoffset, length);\r
+      else throw new InvalidCastException();\r
+    }\r
+\r
+    internal DateTime GetDateTime(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDateTime(_keyInfo[i].column);\r
+      else throw new InvalidCastException();\r
+    }\r
+\r
+    internal decimal GetDecimal(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDecimal(_keyInfo[i].column);\r
+      else throw new InvalidCastException();\r
+    }\r
+\r
+    internal double GetDouble(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetDouble(_keyInfo[i].column);\r
+      else throw new InvalidCastException();\r
+    }\r
+\r
+    internal float GetFloat(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetFloat(_keyInfo[i].column);\r
+      else throw new InvalidCastException();\r
+    }\r
+\r
+    internal Guid GetGuid(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetGuid(_keyInfo[i].column);\r
+      else throw new InvalidCastException();\r
+    }\r
+\r
+    internal Int16 GetInt16(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetInt16(_keyInfo[i].column);\r
+      else\r
+      {\r
+        long rowid = _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor);\r
+        if (rowid == 0) throw new InvalidCastException();\r
+        return Convert.ToInt16(rowid);\r
+      }\r
+    }\r
+\r
+    internal Int32 GetInt32(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetInt32(_keyInfo[i].column);\r
+      else\r
+      {\r
+        long rowid = _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor);\r
+        if (rowid == 0) throw new InvalidCastException();\r
+        return Convert.ToInt32(rowid);\r
+      }\r
+    }\r
+\r
+    internal Int64 GetInt64(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetInt64(_keyInfo[i].column);\r
+      else\r
+      {\r
+        long rowid = _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor);\r
+        if (rowid == 0) throw new InvalidCastException();\r
+        return Convert.ToInt64(rowid);\r
+      }\r
+    }\r
+\r
+    internal string GetString(int i)\r
+    {\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetString(_keyInfo[i].column);\r
+      else throw new InvalidCastException();\r
+    }\r
+\r
+    internal object GetValue(int i)\r
+    {\r
+      if (_keyInfo[i].cursor == -1) return DBNull.Value;\r
+\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.GetValue(_keyInfo[i].column);\r
+\r
+      if (IsDBNull(i) == true)\r
+        return DBNull.Value;\r
+      else return GetInt64(i);\r
+    }\r
+\r
+    internal bool IsDBNull(int i)\r
+    {\r
+      if (_keyInfo[i].cursor == -1) return true;\r
+\r
+      Sync(i);\r
+      if (_keyInfo[i].query != null) return _keyInfo[i].query._reader.IsDBNull(_keyInfo[i].column);\r
+      else return _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor) == 0;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Append all the columns we've added to the original query to the schema\r
+    /// </summary>\r
+    /// <param name="tbl"></param>\r
+    internal void AppendSchemaTable(DataTable tbl)\r
+    {\r
+      KeyQuery last = null;\r
+\r
+      for (int n = 0; n < _keyInfo.Length; n++)\r
+      {\r
+        if (_keyInfo[n].query == null || _keyInfo[n].query != last)\r
+        {\r
+          last = _keyInfo[n].query;\r
+\r
+          if (last == null) // ROWID aliases are treated special\r
+          {\r
+            DataRow row = tbl.NewRow();\r
+            row[SchemaTableColumn.ColumnName] = _keyInfo[n].columnName;\r
+            row[SchemaTableColumn.ColumnOrdinal] = tbl.Rows.Count;\r
+            row[SchemaTableColumn.ColumnSize] = 8;\r
+            row[SchemaTableColumn.NumericPrecision] = 255;\r
+            row[SchemaTableColumn.NumericScale] = 255;\r
+            row[SchemaTableColumn.ProviderType] = DbType.Int64;\r
+            row[SchemaTableColumn.IsLong] = false;\r
+            row[SchemaTableColumn.AllowDBNull] = false;\r
+            row[SchemaTableOptionalColumn.IsReadOnly] = false;\r
+            row[SchemaTableOptionalColumn.IsRowVersion] = false;\r
+            row[SchemaTableColumn.IsUnique] = false;\r
+            row[SchemaTableColumn.IsKey] = true;\r
+            row[SchemaTableColumn.DataType] = typeof(Int64);\r
+            row[SchemaTableOptionalColumn.IsHidden] = true;\r
+            row[SchemaTableColumn.BaseColumnName] = _keyInfo[n].columnName;\r
+            row[SchemaTableColumn.IsExpression] = false;\r
+            row[SchemaTableColumn.IsAliased] = false;\r
+            row[SchemaTableColumn.BaseTableName] = _keyInfo[n].tableName;\r
+            row[SchemaTableOptionalColumn.BaseCatalogName] = _keyInfo[n].databaseName;\r
+            row[SchemaTableOptionalColumn.IsAutoIncrement] = true;\r
+            row["DataTypeName"] = "integer";\r
+\r
+            tbl.Rows.Add(row);\r
+          }\r
+          else\r
+          {\r
+            last.Sync(0);\r
+            using (DataTable tblSub = last._reader.GetSchemaTable())\r
+            {\r
+              foreach (DataRow row in tblSub.Rows)\r
+              {\r
+                object[] o = row.ItemArray;\r
+                DataRow newrow = tbl.Rows.Add(o);\r
+                newrow[SchemaTableOptionalColumn.IsHidden] = true;\r
+                newrow[SchemaTableColumn.ColumnOrdinal] = tbl.Rows.Count - 1;\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
index fab3e1a1fec654e8e28ff0f6a20acf279cfa18c1..1690c6844e8ee647b69752140e12668fe9c26e5a 100644 (file)
@@ -1,84 +1,54 @@
-//
-// Mono.Data.Sqlite.SQLiteMetaDataCollectionNames.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-
-  /// <summary>
-  /// MetaDataCollections specific to Sqlite
-  /// </summary>
-  public static class SqliteMetaDataCollectionNames
-  {
-    /// <summary>
-    /// Returns a list of databases attached to the connection
-    /// </summary>
-    public static readonly string Catalogs = "Catalogs";
-    /// <summary>
-    /// Returns column information for the specified table
-    /// </summary>
-    public static readonly string Columns = "Columns";
-    /// <summary>
-    /// Returns index information for the optionally-specified table
-    /// </summary>
-    public static readonly string Indexes = "Indexes";
-    /// <summary>
-    /// Returns base columns for the given index
-    /// </summary>
-    public static readonly string IndexColumns = "IndexColumns";
-    /// <summary>
-    /// Returns the tables in the given catalog
-    /// </summary>
-    public static readonly string Tables = "Tables";
-    /// <summary>
-    /// Returns user-defined views in the given catalog
-    /// </summary>
-    public static readonly string Views = "Views";
-    /// <summary>
-    /// Returns underlying column information on the given view
-    /// </summary>
-    public static readonly string ViewColumns = "ViewColumns";
-    /// <summary>
-    /// Returns foreign key information for the given catalog
-    /// </summary>
-    public static readonly string ForeignKeys = "ForeignKeys";
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+\r
+  /// <summary>\r
+  /// MetaDataCollections specific to SQLite\r
+  /// </summary>\r
+  public static class SQLiteMetaDataCollectionNames\r
+  {\r
+    /// <summary>\r
+    /// Returns a list of databases attached to the connection\r
+    /// </summary>\r
+    public static readonly string Catalogs = "Catalogs";\r
+    /// <summary>\r
+    /// Returns column information for the specified table\r
+    /// </summary>\r
+    public static readonly string Columns = "Columns";\r
+    /// <summary>\r
+    /// Returns index information for the optionally-specified table\r
+    /// </summary>\r
+    public static readonly string Indexes = "Indexes";\r
+    /// <summary>\r
+    /// Returns base columns for the given index\r
+    /// </summary>\r
+    public static readonly string IndexColumns = "IndexColumns";\r
+    /// <summary>\r
+    /// Returns the tables in the given catalog\r
+    /// </summary>\r
+    public static readonly string Tables = "Tables";\r
+    /// <summary>\r
+    /// Returns user-defined views in the given catalog\r
+    /// </summary>\r
+    public static readonly string Views = "Views";\r
+    /// <summary>\r
+    /// Returns underlying column information on the given view\r
+    /// </summary>\r
+    public static readonly string ViewColumns = "ViewColumns";\r
+    /// <summary>\r
+    /// Returns foreign key information for the given catalog\r
+    /// </summary>\r
+    public static readonly string ForeignKeys = "ForeignKeys";\r
+    /// <summary>\r
+    /// Returns the triggers on the database\r
+    /// </summary>\r
+    public static readonly string Triggers = "Triggers";\r
+  }\r
+}\r
index d85d574fdc51d5d7c605c2065ab55d86a373c645..b6cefddf31222dc0a8021badb3c0d3886d4e4f09 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteParameter.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Data.Common;
-  using System.ComponentModel;
-
-  /// <summary>
-  /// Sqlite implementation of DbParameter.
-  /// </summary>
-  public sealed class SqliteParameter : DbParameter, ICloneable
-  {
-    /// <summary>
-    /// The data type of the parameter
-    /// </summary>
-    internal int            _dbType;
-    /// <summary>
-    /// The version information for mapping the parameter
-    /// </summary>
-    private DataRowVersion _rowVersion;
-    /// <summary>
-    /// The value of the data in the parameter
-    /// </summary>
-    private Object         _objValue;
-    /// <summary>
-    /// The source column for the parameter
-    /// </summary>
-    private string         _sourceColumn;
-    /// <summary>
-    /// The column name
-    /// </summary>
-    private string         _parameterName;
-    /// <summary>
-    /// The data size, unused by Sqlite
-    /// </summary>
-    private int            _dataSize;
-
-    private bool           _nullable;
-    private bool           _nullMapping;
-
-    /// <summary>
-    /// Default constructor
-    /// </summary>
-    public SqliteParameter() 
-      : this(null, (DbType)(-1), 0, null, DataRowVersion.Current)
-    {
-    }
-
-    /// <summary>
-    /// Constructs a named parameter given the specified parameter name
-    /// </summary>
-    /// <param name="parameterName">The parameter name</param>
-    public SqliteParameter(string parameterName)
-      : this(parameterName, (DbType)(-1), 0, null, DataRowVersion.Current)
-    {
-    }
-
-    /// <summary>
-    /// Constructs a named parameter given the specified parameter name and initial value
-    /// </summary>
-    /// <param name="parameterName">The parameter name</param>
-    /// <param name="value">The initial value of the parameter</param>
-    public SqliteParameter(string parameterName, object value)
-      : this(parameterName, (DbType)(-1), 0, null, DataRowVersion.Current)
-    {
-      Value = value;
-    }
-
-    /// <summary>
-    /// Constructs a named parameter of the specified type
-    /// </summary>
-    /// <param name="parameterName">The parameter name</param>
-    /// <param name="dbType">The datatype of the parameter</param>
-    public SqliteParameter(string parameterName, DbType dbType)
-      : this(parameterName, dbType, 0, null, DataRowVersion.Current)
-    {
-    }
-
-    /// <summary>
-    /// Constructs a named parameter of the specified type and source column reference
-    /// </summary>
-    /// <param name="parameterName">The parameter name</param>
-    /// <param name="dbType">The data type</param>
-    /// <param name="sourceColumn">The source column</param>
-    public SqliteParameter(string parameterName, DbType dbType, string sourceColumn)
-      : this(parameterName, dbType, 0, sourceColumn, DataRowVersion.Current)
-    {
-    }
-
-    /// <summary>
-    /// Constructs a named parameter of the specified type, source column and row version
-    /// </summary>
-    /// <param name="parameterName">The parameter name</param>
-    /// <param name="dbType">The data type</param>
-    /// <param name="sourceColumn">The source column</param>
-    /// <param name="rowVersion">The row version information</param>
-    public SqliteParameter(string parameterName, DbType dbType, string sourceColumn, DataRowVersion rowVersion)
-      : this(parameterName, dbType, 0, sourceColumn, rowVersion)
-    {
-    }
-
-    /// <summary>
-    /// Constructs an unnamed parameter of the specified data type
-    /// </summary>
-    /// <param name="dbType">The datatype of the parameter</param>
-    public SqliteParameter(DbType dbType)
-      : this(null, dbType, 0, null, DataRowVersion.Current)
-    {
-    }
-
-    /// <summary>
-    /// Constructs an unnamed parameter of the specified data type and sets the initial value
-    /// </summary>
-    /// <param name="dbType">The datatype of the parameter</param>
-    /// <param name="value">The initial value of the parameter</param>
-    public SqliteParameter(DbType dbType, object value)
-      : this(null, dbType, 0, null, DataRowVersion.Current)
-    {
-      Value = value;
-    }
-
-    /// <summary>
-    /// Constructs an unnamed parameter of the specified data type and source column
-    /// </summary>
-    /// <param name="dbType">The datatype of the parameter</param>
-    /// <param name="sourceColumn">The source column</param>
-    public SqliteParameter(DbType dbType, string sourceColumn)
-      : this(null, dbType, 0, sourceColumn, DataRowVersion.Current)
-    {
-    }
-
-    /// <summary>
-    /// Constructs an unnamed parameter of the specified data type, source column and row version
-    /// </summary>
-    /// <param name="dbType">The data type</param>
-    /// <param name="sourceColumn">The source column</param>
-    /// <param name="rowVersion">The row version information</param>
-    public SqliteParameter(DbType dbType, string sourceColumn, DataRowVersion rowVersion)
-      : this(null, dbType, 0, sourceColumn, rowVersion)
-    {
-    }
-
-    /// <summary>
-    /// Constructs a named parameter of the specified type and size
-    /// </summary>
-    /// <param name="parameterName">The parameter name</param>
-    /// <param name="parameterType">The data type</param>
-    /// <param name="parameterSize">The size of the parameter</param>
-    public SqliteParameter(string parameterName, DbType parameterType, int parameterSize)
-      : this(parameterName, parameterType, parameterSize, null, DataRowVersion.Current)
-    {
-    }
-
-    /// <summary>
-    /// Constructs a named parameter of the specified type, size and source column
-    /// </summary>
-    /// <param name="parameterName">The name of the parameter</param>
-    /// <param name="parameterType">The data type</param>
-    /// <param name="parameterSize">The size of the parameter</param>
-    /// <param name="sourceColumn">The source column</param>
-    public SqliteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn)
-      : this(parameterName, parameterType, parameterSize, sourceColumn, DataRowVersion.Current)
-    {
-    }
-
-    /// <summary>
-    /// Constructs a named parameter of the specified type, size, source column and row version
-    /// </summary>
-    /// <param name="parameterName">The name of the parameter</param>
-    /// <param name="parameterType">The data type</param>
-    /// <param name="parameterSize">The size of the parameter</param>
-    /// <param name="sourceColumn">The source column</param>
-    /// <param name="rowVersion">The row version information</param>
-    public SqliteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion)      
-    {
-      _parameterName = parameterName;
-      _dbType = (int)parameterType;
-      _sourceColumn = sourceColumn;
-      _rowVersion = rowVersion;
-      _objValue = null;
-      _dataSize = parameterSize;
-      _nullMapping = false;
-      _nullable = true;
-    }
-
-    private SqliteParameter(SqliteParameter source)
-      : this(source.ParameterName, (DbType)source._dbType, 0, source.Direction, source.IsNullable, 0, 0, source.SourceColumn, source.SourceVersion, source.Value)
-    {
-      _nullMapping = source._nullMapping;
-    }
-
-    /// <summary>
-    /// Constructs a named parameter of the specified type, size, source column and row version
-    /// </summary>
-    /// <param name="parameterName">The name of the parameter</param>
-    /// <param name="parameterType">The data type</param>
-    /// <param name="parameterSize">The size of the parameter</param>
-    /// <param name="direction">Only input parameters are supported in Sqlite</param>
-    /// <param name="isNullable">Ignored</param>
-    /// <param name="precision">Ignored</param>
-    /// <param name="scale">Ignored</param>
-    /// <param name="sourceColumn">The source column</param>
-    /// <param name="rowVersion">The row version information</param>
-    /// <param name="value">The initial value to assign the parameter</param>   
-#if !PLATFORM_COMPACTFRAMEWORK
-    [EditorBrowsable(EditorBrowsableState.Advanced)]
-#endif
-    public SqliteParameter(string parameterName, DbType parameterType, int parameterSize, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion rowVersion, object value)
-      : this(parameterName, parameterType, parameterSize, sourceColumn, rowVersion)
-    {
-      Direction = direction;
-      IsNullable = isNullable;
-      Value = value;
-    }
-
-    /// <summary>
-    /// Constructs a named parameter, yet another flavor
-    /// </summary>
-    /// <param name="parameterName">The name of the parameter</param>
-    /// <param name="parameterType">The data type</param>
-    /// <param name="parameterSize">The size of the parameter</param>
-    /// <param name="direction">Only input parameters are supported in Sqlite</param>
-    /// <param name="precision">Ignored</param>
-    /// <param name="scale">Ignored</param>
-    /// <param name="sourceColumn">The source column</param>
-    /// <param name="rowVersion">The row version information</param>
-    /// <param name="sourceColumnNullMapping">Whether or not this parameter is for comparing NULL's</param>
-    /// <param name="value">The intial value to assign the parameter</param>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [EditorBrowsable(EditorBrowsableState.Advanced)]
-#endif
-    public SqliteParameter(string parameterName, DbType parameterType, int parameterSize, ParameterDirection direction, byte precision, byte scale, string sourceColumn, DataRowVersion rowVersion, bool sourceColumnNullMapping, object value)
-      : this(parameterName, parameterType, parameterSize, sourceColumn, rowVersion)
-    {
-      Direction = direction;
-      SourceColumnNullMapping = sourceColumnNullMapping;
-      Value = value;
-    }
-
-    /// <summary>
-    /// Constructs an unnamed parameter of the specified type and size
-    /// </summary>
-    /// <param name="parameterType">The data type</param>
-    /// <param name="parameterSize">The size of the parameter</param>
-    public SqliteParameter(DbType parameterType, int parameterSize)
-      : this(null, parameterType, parameterSize, null, DataRowVersion.Current)
-    {
-    }
-
-    /// <summary>
-    /// Constructs an unnamed parameter of the specified type, size, and source column
-    /// </summary>
-    /// <param name="parameterType">The data type</param>
-    /// <param name="parameterSize">The size of the parameter</param>
-    /// <param name="sourceColumn">The source column</param>
-    public SqliteParameter(DbType parameterType, int parameterSize, string sourceColumn)
-      : this(null, parameterType, parameterSize, sourceColumn, DataRowVersion.Current)
-    {
-    }
-
-    /// <summary>
-    /// Constructs an unnamed parameter of the specified type, size, source column and row version
-    /// </summary>
-    /// <param name="parameterType">The data type</param>
-    /// <param name="parameterSize">The size of the parameter</param>
-    /// <param name="sourceColumn">The source column</param>
-    /// <param name="rowVersion">The row version information</param>
-    public SqliteParameter(DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion)
-      : this(null, parameterType, parameterSize, sourceColumn, rowVersion)
-    {
-    }
-
-    /// <summary>
-    /// Whether or not the parameter can contain a null value
-    /// </summary>
-    public override bool IsNullable
-    {
-      get
-      {
-        return _nullable;
-      }
-      set 
-      {
-        _nullable = value;
-      }
-    }
-
-    /// <summary>
-    /// Returns the datatype of the parameter
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DbProviderSpecificTypeProperty(true)]
-    [RefreshProperties(RefreshProperties.All)]
-#endif
-    public override DbType DbType
-    {
-      get
-      {
-        if (_dbType == -1) return DbType.String; // Unassigned default value is String
-        return (DbType)_dbType;
-      }
-      set
-      {
-        _dbType = (int)value;
-      }
-    }
-
-    /// <summary>
-    /// Supports only input parameters
-    /// </summary>
-    public override ParameterDirection Direction
-    {
-      get
-      {
-        return ParameterDirection.Input;
-      }
-      set
-      {
-        if (value != ParameterDirection.Input)
-          throw new NotSupportedException();
-      }
-    }
-
-    /// <summary>
-    /// Returns the parameter name
-    /// </summary>
-    public override string ParameterName
-    {
-      get
-      {
-        return _parameterName;
-      }
-      set
-      {
-        _parameterName = value;
-      }
-    }
-
-    /// <summary>
-    /// Not implemented
-    /// </summary>
-    public override void ResetDbType()
-    {
-    }
-
-    /// <summary>
-    /// Returns the size of the parameter
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [DefaultValue((int)0)]
-#endif
-    public override int Size
-    {
-      get
-      {
-        return _dataSize;
-      }
-      set
-      {
-        _dataSize = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets/sets the source column
-    /// </summary>
-    public override string SourceColumn
-    {
-      get
-      {
-        return _sourceColumn;
-      }
-      set
-      {
-        _sourceColumn = value;
-      }
-    }
-
-    /// <summary>
-    /// Used by DbCommandBuilder to determine the mapping for nullable fields
-    /// </summary>
-    public override bool SourceColumnNullMapping
-    {
-      get
-      {
-        return _nullMapping;
-      }
-      set
-      {
-        _nullMapping = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets and sets the row version
-    /// </summary>
-    public override DataRowVersion SourceVersion
-    {
-      get
-      {
-        return _rowVersion;
-      }
-      set
-      {
-        _rowVersion = value;
-      }
-    }
-
-    /// <summary>
-    /// Gets and sets the parameter value.  If no datatype was specified, the datatype will assume the type from the value given.
-    /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [TypeConverter(typeof(StringConverter)), RefreshProperties(RefreshProperties.All)]
-#endif
-    public override object Value
-    {
-      get
-      {
-        return _objValue;
-      }
-      set
-      {
-        _objValue = value;
-        if (_dbType == -1 && _objValue != null && _objValue != DBNull.Value) // If the DbType has never been assigned, try to glean one from the value's datatype 
-          _dbType = (int)SqliteConvert.TypeToDbType(_objValue.GetType());
-      }
-    }
-
-    /// <summary>
-    /// Clones a parameter
-    /// </summary>
-    /// <returns>A new, unassociated SqliteParameter</returns>
-    public object Clone()
-    {
-      SqliteParameter newparam = new SqliteParameter(this);
-
-      return newparam;
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Data.Common;\r
+  using System.ComponentModel;\r
+\r
+  /// <summary>\r
+  /// SQLite implementation of DbParameter.\r
+  /// </summary>\r
+  public sealed class SQLiteParameter : DbParameter, ICloneable\r
+  {\r
+    /// <summary>\r
+    /// The data type of the parameter\r
+    /// </summary>\r
+    internal int            _dbType;\r
+    /// <summary>\r
+    /// The version information for mapping the parameter\r
+    /// </summary>\r
+    private DataRowVersion _rowVersion;\r
+    /// <summary>\r
+    /// The value of the data in the parameter\r
+    /// </summary>\r
+    private Object         _objValue;\r
+    /// <summary>\r
+    /// The source column for the parameter\r
+    /// </summary>\r
+    private string         _sourceColumn;\r
+    /// <summary>\r
+    /// The column name\r
+    /// </summary>\r
+    private string         _parameterName;\r
+    /// <summary>\r
+    /// The data size, unused by SQLite\r
+    /// </summary>\r
+    private int            _dataSize;\r
+\r
+    private bool           _nullable;\r
+    private bool           _nullMapping;\r
+\r
+    /// <summary>\r
+    /// Default constructor\r
+    /// </summary>\r
+    public SQLiteParameter() \r
+      : this(null, (DbType)(-1), 0, null, DataRowVersion.Current)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a named parameter given the specified parameter name\r
+    /// </summary>\r
+    /// <param name="parameterName">The parameter name</param>\r
+    public SQLiteParameter(string parameterName)\r
+      : this(parameterName, (DbType)(-1), 0, null, DataRowVersion.Current)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a named parameter given the specified parameter name and initial value\r
+    /// </summary>\r
+    /// <param name="parameterName">The parameter name</param>\r
+    /// <param name="value">The initial value of the parameter</param>\r
+    public SQLiteParameter(string parameterName, object value)\r
+      : this(parameterName, (DbType)(-1), 0, null, DataRowVersion.Current)\r
+    {\r
+      Value = value;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a named parameter of the specified type\r
+    /// </summary>\r
+    /// <param name="parameterName">The parameter name</param>\r
+    /// <param name="dbType">The datatype of the parameter</param>\r
+    public SQLiteParameter(string parameterName, DbType dbType)\r
+      : this(parameterName, dbType, 0, null, DataRowVersion.Current)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a named parameter of the specified type and source column reference\r
+    /// </summary>\r
+    /// <param name="parameterName">The parameter name</param>\r
+    /// <param name="dbType">The data type</param>\r
+    /// <param name="sourceColumn">The source column</param>\r
+    public SQLiteParameter(string parameterName, DbType dbType, string sourceColumn)\r
+      : this(parameterName, dbType, 0, sourceColumn, DataRowVersion.Current)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a named parameter of the specified type, source column and row version\r
+    /// </summary>\r
+    /// <param name="parameterName">The parameter name</param>\r
+    /// <param name="dbType">The data type</param>\r
+    /// <param name="sourceColumn">The source column</param>\r
+    /// <param name="rowVersion">The row version information</param>\r
+    public SQLiteParameter(string parameterName, DbType dbType, string sourceColumn, DataRowVersion rowVersion)\r
+      : this(parameterName, dbType, 0, sourceColumn, rowVersion)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs an unnamed parameter of the specified data type\r
+    /// </summary>\r
+    /// <param name="dbType">The datatype of the parameter</param>\r
+    public SQLiteParameter(DbType dbType)\r
+      : this(null, dbType, 0, null, DataRowVersion.Current)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs an unnamed parameter of the specified data type and sets the initial value\r
+    /// </summary>\r
+    /// <param name="dbType">The datatype of the parameter</param>\r
+    /// <param name="value">The initial value of the parameter</param>\r
+    public SQLiteParameter(DbType dbType, object value)\r
+      : this(null, dbType, 0, null, DataRowVersion.Current)\r
+    {\r
+      Value = value;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs an unnamed parameter of the specified data type and source column\r
+    /// </summary>\r
+    /// <param name="dbType">The datatype of the parameter</param>\r
+    /// <param name="sourceColumn">The source column</param>\r
+    public SQLiteParameter(DbType dbType, string sourceColumn)\r
+      : this(null, dbType, 0, sourceColumn, DataRowVersion.Current)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs an unnamed parameter of the specified data type, source column and row version\r
+    /// </summary>\r
+    /// <param name="dbType">The data type</param>\r
+    /// <param name="sourceColumn">The source column</param>\r
+    /// <param name="rowVersion">The row version information</param>\r
+    public SQLiteParameter(DbType dbType, string sourceColumn, DataRowVersion rowVersion)\r
+      : this(null, dbType, 0, sourceColumn, rowVersion)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a named parameter of the specified type and size\r
+    /// </summary>\r
+    /// <param name="parameterName">The parameter name</param>\r
+    /// <param name="parameterType">The data type</param>\r
+    /// <param name="parameterSize">The size of the parameter</param>\r
+    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize)\r
+      : this(parameterName, parameterType, parameterSize, null, DataRowVersion.Current)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a named parameter of the specified type, size and source column\r
+    /// </summary>\r
+    /// <param name="parameterName">The name of the parameter</param>\r
+    /// <param name="parameterType">The data type</param>\r
+    /// <param name="parameterSize">The size of the parameter</param>\r
+    /// <param name="sourceColumn">The source column</param>\r
+    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn)\r
+      : this(parameterName, parameterType, parameterSize, sourceColumn, DataRowVersion.Current)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a named parameter of the specified type, size, source column and row version\r
+    /// </summary>\r
+    /// <param name="parameterName">The name of the parameter</param>\r
+    /// <param name="parameterType">The data type</param>\r
+    /// <param name="parameterSize">The size of the parameter</param>\r
+    /// <param name="sourceColumn">The source column</param>\r
+    /// <param name="rowVersion">The row version information</param>\r
+    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion)      \r
+    {\r
+      _parameterName = parameterName;\r
+      _dbType = (int)parameterType;\r
+      _sourceColumn = sourceColumn;\r
+      _rowVersion = rowVersion;\r
+      _objValue = null;\r
+      _dataSize = parameterSize;\r
+      _nullMapping = false;\r
+      _nullable = true;\r
+    }\r
+\r
+    private SQLiteParameter(SQLiteParameter source)\r
+      : this(source.ParameterName, (DbType)source._dbType, 0, source.Direction, source.IsNullable, 0, 0, source.SourceColumn, source.SourceVersion, source.Value)\r
+    {\r
+      _nullMapping = source._nullMapping;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a named parameter of the specified type, size, source column and row version\r
+    /// </summary>\r
+    /// <param name="parameterName">The name of the parameter</param>\r
+    /// <param name="parameterType">The data type</param>\r
+    /// <param name="parameterSize">The size of the parameter</param>\r
+    /// <param name="direction">Only input parameters are supported in SQLite</param>\r
+    /// <param name="isNullable">Ignored</param>\r
+    /// <param name="precision">Ignored</param>\r
+    /// <param name="scale">Ignored</param>\r
+    /// <param name="sourceColumn">The source column</param>\r
+    /// <param name="rowVersion">The row version information</param>\r
+    /// <param name="value">The initial value to assign the parameter</param>   \r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [EditorBrowsable(EditorBrowsableState.Advanced)]\r
+#endif\r
+    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion rowVersion, object value)\r
+      : this(parameterName, parameterType, parameterSize, sourceColumn, rowVersion)\r
+    {\r
+      Direction = direction;\r
+      IsNullable = isNullable;\r
+      Value = value;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs a named parameter, yet another flavor\r
+    /// </summary>\r
+    /// <param name="parameterName">The name of the parameter</param>\r
+    /// <param name="parameterType">The data type</param>\r
+    /// <param name="parameterSize">The size of the parameter</param>\r
+    /// <param name="direction">Only input parameters are supported in SQLite</param>\r
+    /// <param name="precision">Ignored</param>\r
+    /// <param name="scale">Ignored</param>\r
+    /// <param name="sourceColumn">The source column</param>\r
+    /// <param name="rowVersion">The row version information</param>\r
+    /// <param name="sourceColumnNullMapping">Whether or not this parameter is for comparing NULL's</param>\r
+    /// <param name="value">The intial value to assign the parameter</param>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [EditorBrowsable(EditorBrowsableState.Advanced)]\r
+#endif\r
+    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, ParameterDirection direction, byte precision, byte scale, string sourceColumn, DataRowVersion rowVersion, bool sourceColumnNullMapping, object value)\r
+      : this(parameterName, parameterType, parameterSize, sourceColumn, rowVersion)\r
+    {\r
+      Direction = direction;\r
+      SourceColumnNullMapping = sourceColumnNullMapping;\r
+      Value = value;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs an unnamed parameter of the specified type and size\r
+    /// </summary>\r
+    /// <param name="parameterType">The data type</param>\r
+    /// <param name="parameterSize">The size of the parameter</param>\r
+    public SQLiteParameter(DbType parameterType, int parameterSize)\r
+      : this(null, parameterType, parameterSize, null, DataRowVersion.Current)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs an unnamed parameter of the specified type, size, and source column\r
+    /// </summary>\r
+    /// <param name="parameterType">The data type</param>\r
+    /// <param name="parameterSize">The size of the parameter</param>\r
+    /// <param name="sourceColumn">The source column</param>\r
+    public SQLiteParameter(DbType parameterType, int parameterSize, string sourceColumn)\r
+      : this(null, parameterType, parameterSize, sourceColumn, DataRowVersion.Current)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Constructs an unnamed parameter of the specified type, size, source column and row version\r
+    /// </summary>\r
+    /// <param name="parameterType">The data type</param>\r
+    /// <param name="parameterSize">The size of the parameter</param>\r
+    /// <param name="sourceColumn">The source column</param>\r
+    /// <param name="rowVersion">The row version information</param>\r
+    public SQLiteParameter(DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion)\r
+      : this(null, parameterType, parameterSize, sourceColumn, rowVersion)\r
+    {\r
+    }\r
+\r
+    /// <summary>\r
+    /// Whether or not the parameter can contain a null value\r
+    /// </summary>\r
+    public override bool IsNullable\r
+    {\r
+      get\r
+      {\r
+        return _nullable;\r
+      }\r
+      set \r
+      {\r
+        _nullable = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the datatype of the parameter\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DbProviderSpecificTypeProperty(true)]\r
+    [RefreshProperties(RefreshProperties.All)]\r
+#endif\r
+    public override DbType DbType\r
+    {\r
+      get\r
+      {\r
+        if (_dbType == -1)\r
+        {\r
+          if (_objValue != null && _objValue != DBNull.Value)\r
+          {\r
+            return SQLiteConvert.TypeToDbType(_objValue.GetType());\r
+          }\r
+          return DbType.String; // Unassigned default value is String\r
+        }\r
+        return (DbType)_dbType;\r
+      }\r
+      set\r
+      {\r
+        _dbType = (int)value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Supports only input parameters\r
+    /// </summary>\r
+    public override ParameterDirection Direction\r
+    {\r
+      get\r
+      {\r
+        return ParameterDirection.Input;\r
+      }\r
+      set\r
+      {\r
+        if (value != ParameterDirection.Input)\r
+          throw new NotSupportedException();\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the parameter name\r
+    /// </summary>\r
+    public override string ParameterName\r
+    {\r
+      get\r
+      {\r
+        return _parameterName;\r
+      }\r
+      set\r
+      {\r
+        _parameterName = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Resets the DbType of the parameter so it can be inferred from the value\r
+    /// </summary>\r
+    public override void ResetDbType()\r
+    {\r
+      _dbType = -1;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the size of the parameter\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DefaultValue((int)0)]\r
+#endif\r
+    public override int Size\r
+    {\r
+      get\r
+      {\r
+        return _dataSize;\r
+      }\r
+      set\r
+      {\r
+        _dataSize = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets/sets the source column\r
+    /// </summary>\r
+    public override string SourceColumn\r
+    {\r
+      get\r
+      {\r
+        return _sourceColumn;\r
+      }\r
+      set\r
+      {\r
+        _sourceColumn = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Used by DbCommandBuilder to determine the mapping for nullable fields\r
+    /// </summary>\r
+    public override bool SourceColumnNullMapping\r
+    {\r
+      get\r
+      {\r
+        return _nullMapping;\r
+      }\r
+      set\r
+      {\r
+        _nullMapping = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets and sets the row version\r
+    /// </summary>\r
+    public override DataRowVersion SourceVersion\r
+    {\r
+      get\r
+      {\r
+        return _rowVersion;\r
+      }\r
+      set\r
+      {\r
+        _rowVersion = value;\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets and sets the parameter value.  If no datatype was specified, the datatype will assume the type from the value given.\r
+    /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [TypeConverter(typeof(StringConverter)), RefreshProperties(RefreshProperties.All)]\r
+#endif\r
+    public override object Value\r
+    {\r
+      get\r
+      {\r
+        return _objValue;\r
+      }\r
+      set\r
+      {\r
+        _objValue = value;\r
+        if (_dbType == -1 && _objValue != null && _objValue != DBNull.Value) // If the DbType has never been assigned, try to glean one from the value's datatype \r
+          _dbType = (int)SQLiteConvert.TypeToDbType(_objValue.GetType());\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Clones a parameter\r
+    /// </summary>\r
+    /// <returns>A new, unassociated SQLiteParameter</returns>\r
+    public object Clone()\r
+    {\r
+      SQLiteParameter newparam = new SQLiteParameter(this);\r
+\r
+      return newparam;\r
+    }\r
+  }\r
+}\r
index 2267c2718d8cfdde1da18173909531c7f853f330..333e7250cc31a4e25b919fb69702597cdcca12ac 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteParameterCollection.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Data.Common;
-  using System.Collections.Generic;
-  using System.Globalization;
-  using System.ComponentModel;
-  using System.Reflection;
-
-  /// <summary>
-  /// Sqlite implementation of DbParameterCollection.
-  /// </summary>
-#if !PLATFORM_COMPACTFRAMEWORK
-  [Editor("Microsoft.VSDesigner.Data.Design.DBParametersEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), ListBindable(false)]
-#endif
-  public sealed class SqliteParameterCollection : DbParameterCollection
-  {
-    /// <summary>
-    /// The underlying command to which this collection belongs
-    /// </summary>
-    private SqliteCommand         _command;
-    /// <summary>
-    /// The internal array of parameters in this collection
-    /// </summary>
-    private List<SqliteParameter> _parameterList;
-    /// <summary>
-    /// Determines whether or not all parameters have been bound to their statement(s)
-    /// </summary>
-    private bool                  _unboundFlag;
-
-    /// <summary>
-    /// Initializes the collection
-    /// </summary>
-    /// <param name="cmd">The command to which the collection belongs</param>
-    internal SqliteParameterCollection(SqliteCommand cmd)
-    {
-      _command = cmd;
-      _parameterList = new List<SqliteParameter>();
-      _unboundFlag = true;
-    }
-
-    /// <summary>
-    /// Returns true
-    /// </summary>
-    public override bool IsSynchronized
-    {
-      get { return true; }
-    }
-
-    /// <summary>
-    /// Returns false
-    /// </summary>
-    public override bool IsFixedSize
-    {
-      get { return false; }
-    }
-
-    /// <summary>
-    /// Returns false
-    /// </summary>
-    public override bool IsReadOnly
-    {
-      get { return false; }
-    }
-
-    /// <summary>
-    /// Returns null
-    /// </summary>
-    public override object SyncRoot
-    {
-      get { return null; }
-    }
-
-    /// <summary>
-    /// Retrieves an enumerator for the collection
-    /// </summary>
-    /// <returns>An enumerator for the underlying array</returns>
-    public override System.Collections.IEnumerator GetEnumerator()
-    {
-      return _parameterList.GetEnumerator();
-    }
-
-    /// <summary>
-    /// Adds a parameter to the collection
-    /// </summary>
-    /// <param name="parameterName">The parameter name</param>
-    /// <param name="parameterType">The data type</param>
-    /// <param name="parameterSize">The size of the value</param>
-    /// <param name="sourceColumn">The source column</param>
-    /// <returns>A SqliteParameter object</returns>
-    public SqliteParameter Add(string parameterName, DbType parameterType, int parameterSize, string sourceColumn)
-    {
-      SqliteParameter param = new SqliteParameter(parameterName, parameterType, parameterSize, sourceColumn);
-      Add(param);
-
-      return param;
-    }
-
-    /// <summary>
-    /// Adds a parameter to the collection
-    /// </summary>
-    /// <param name="parameterName">The parameter name</param>
-    /// <param name="parameterType">The data type</param>
-    /// <param name="parameterSize">The size of the value</param>
-    /// <returns>A SqliteParameter object</returns>
-    public SqliteParameter Add(string parameterName, DbType parameterType, int parameterSize)
-    {
-      SqliteParameter param = new SqliteParameter(parameterName, parameterType, parameterSize);
-      Add(param);
-
-      return param;
-    }
-
-    /// <summary>
-    /// Adds a parameter to the collection
-    /// </summary>
-    /// <param name="parameterName">The parameter name</param>
-    /// <param name="parameterType">The data type</param>
-    /// <returns>A SqliteParameter object</returns>
-    public SqliteParameter Add(string parameterName, DbType parameterType)
-    {
-      SqliteParameter param = new SqliteParameter(parameterName, parameterType);
-      Add(param);
-
-      return param;
-    }
-
-    /// <summary>
-    /// Adds a parameter to the collection
-    /// </summary>
-    /// <param name="parameter">The parameter to add</param>
-    /// <returns>A zero-based index of where the parameter is located in the array</returns>
-    public int Add(SqliteParameter parameter)
-    {
-      int n = -1;
-
-      if (parameter.ParameterName != null)
-      {
-        n = IndexOf(parameter.ParameterName);
-      }
-
-      if (n == -1)
-      {
-        n = _parameterList.Count;
-        _parameterList.Add((SqliteParameter)parameter);
-      }
-
-      SetParameter(n, parameter);
-
-      return n;
-    }
-
-    /// <summary>
-    /// Adds a parameter to the collection
-    /// </summary>
-    /// <param name="value">The parameter to add</param>
-    /// <returns>A zero-based index of where the parameter is located in the array</returns>
-#if !PLATFORM_COMPACTFRAMEWORK
-    [EditorBrowsable(EditorBrowsableState.Never)]
-#endif
-    public override int Add(object value)
-    {
-      return Add((SqliteParameter)value);
-    }
-
-    /// <summary>
-    /// Adds a named/unnamed parameter and its value to the parameter collection.
-    /// </summary>
-    /// <param name="parameterName">Name of the parameter, or null to indicate an unnamed parameter</param>
-    /// <param name="value">The initial value of the parameter</param>
-    /// <returns>Returns the SqliteParameter object created during the call.</returns>
-    public SqliteParameter AddWithValue(string parameterName, object value)
-    {
-      SqliteParameter param = new SqliteParameter(parameterName, value);
-      Add(param);
-
-      return param;
-    }
-
-    /// <summary>
-    /// Adds an array of parameters to the collection
-    /// </summary>
-    /// <param name="values">The array of parameters to add</param>
-    public void AddRange(SqliteParameter[] values)
-    {
-      int x = values.Length;
-      for (int n = 0; n < x; n++)
-        Add(values[n]);
-    }
-
-    /// <summary>
-    /// Adds an array of parameters to the collection
-    /// </summary>
-    /// <param name="values">The array of parameters to add</param>
-    public override void AddRange(Array values)
-    {
-      int x = values.Length;
-      for (int n = 0; n < x; n++)
-        Add((SqliteParameter)(values.GetValue(n)));
-    }
-
-    /// <summary>
-    /// Clears the array and resets the collection
-    /// </summary>
-    public override void Clear()
-    {
-      _unboundFlag = true;
-      _parameterList.Clear();
-    }
-
-    /// <summary>
-    /// Determines if the named parameter exists in the collection
-    /// </summary>
-    /// <param name="parameterName">The name of the parameter to check</param>
-    /// <returns>True if the parameter is in the collection</returns>
-    public override bool Contains(string parameterName)
-    {
-      return (IndexOf(parameterName) != -1);
-    }
-
-    /// <summary>
-    /// Determines if the parameter exists in the collection
-    /// </summary>
-    /// <param name="value">The SqliteParameter to check</param>
-    /// <returns>True if the parameter is in the collection</returns>
-    public override bool Contains(object value)
-    {
-      return _parameterList.Contains((SqliteParameter)value);
-    }
-
-    /// <summary>
-    /// Not implemented
-    /// </summary>
-    /// <param name="array"></param>
-    /// <param name="index"></param>
-    public override void CopyTo(Array array, int index)
-    {
-      throw new NotImplementedException();
-    }
-
-    /// <summary>
-    /// Returns a count of parameters in the collection
-    /// </summary>
-    public override int Count
-    {
-      get { return _parameterList.Count; }
-    }
-
-    /// <summary>
-    /// Overloaded to specialize the return value of the default indexer
-    /// </summary>
-    /// <param name="parameterName">Name of the parameter to get/set</param>
-    /// <returns>The specified named Sqlite parameter</returns>
-    public new SqliteParameter this[string parameterName]
-    {
-      get
-      {
-        return (SqliteParameter)GetParameter(parameterName);
-      }
-      set
-      {
-        SetParameter(parameterName, value);
-      }
-    }
-
-    /// <summary>
-    /// Overloaded to specialize the return value of the default indexer
-    /// </summary>
-    /// <param name="index">The index of the parameter to get/set</param>
-    /// <returns>The specified Sqlite parameter</returns>
-    public new SqliteParameter this[int index]
-    {
-      get
-      {
-        return (SqliteParameter)GetParameter(index);
-      }
-      set
-      {
-        SetParameter(index, value);
-      }
-    }
-    /// <summary>
-    /// Retrieve a parameter by name from the collection
-    /// </summary>
-    /// <param name="parameterName">The name of the parameter to fetch</param>
-    /// <returns>A DbParameter object</returns>
-    protected override DbParameter GetParameter(string parameterName)
-    {
-      return GetParameter(IndexOf(parameterName));
-    }
-
-    /// <summary>
-    /// Retrieves a parameter by its index in the collection
-    /// </summary>
-    /// <param name="index">The index of the parameter to retrieve</param>
-    /// <returns>A DbParameter object</returns>
-    protected override DbParameter GetParameter(int index)
-    {
-      return _parameterList[index];
-    }
-
-    /// <summary>
-    /// Returns the index of a parameter given its name
-    /// </summary>
-    /// <param name="parameterName">The name of the parameter to find</param>
-    /// <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>
-    public override int IndexOf(string parameterName)
-    {
-      int x = _parameterList.Count;
-      for (int n = 0; n < x; n++)
-      {
-        if (String.Compare(parameterName, _parameterList[n].ParameterName, true, CultureInfo.InvariantCulture) == 0)
-          return n;
-      }
-      return -1;
-    }
-
-    /// <summary>
-    /// Returns the index of a parameter
-    /// </summary>
-    /// <param name="value">The parameter to find</param>
-    /// <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>
-    public override int IndexOf(object value)
-    {
-      return _parameterList.IndexOf((SqliteParameter)value);
-    }
-
-    /// <summary>
-    /// Inserts a parameter into the array at the specified location
-    /// </summary>
-    /// <param name="index">The zero-based index to insert the parameter at</param>
-    /// <param name="value">The parameter to insert</param>
-    public override void Insert(int index, object value)
-    {
-      _unboundFlag = true;
-      _parameterList.Insert(index, (SqliteParameter)value);
-    }
-
-    /// <summary>
-    /// Removes a parameter from the collection
-    /// </summary>
-    /// <param name="value">The parameter to remove</param>
-    public override void Remove(object value)
-    {
-      _unboundFlag = true;
-      _parameterList.Remove((SqliteParameter)value);
-    }
-
-    /// <summary>
-    /// Removes a parameter from the collection given its name
-    /// </summary>
-    /// <param name="parameterName">The name of the parameter to remove</param>
-    public override void RemoveAt(string parameterName)
-    {
-      RemoveAt(IndexOf(parameterName));
-    }
-
-    /// <summary>
-    /// Removes a parameter from the collection given its index
-    /// </summary>
-    /// <param name="index">The zero-based parameter index to remove</param>
-    public override void RemoveAt(int index)
-    {
-      _unboundFlag = true;
-      _parameterList.RemoveAt(index);
-    }
-
-    /// <summary>
-    /// Re-assign the named parameter to a new parameter object
-    /// </summary>
-    /// <param name="parameterName">The name of the parameter to replace</param>
-    /// <param name="value">The new parameter</param>
-    protected override void SetParameter(string parameterName, DbParameter value)
-    {
-      SetParameter(IndexOf(parameterName), value);
-    }
-
-    /// <summary>
-    /// Re-assign a parameter at the specified index
-    /// </summary>
-    /// <param name="index">The zero-based index of the parameter to replace</param>
-    /// <param name="value">The new parameter</param>
-    protected override void SetParameter(int index, DbParameter value)
-    {
-      _unboundFlag = true;
-      _parameterList[index] = (SqliteParameter)value;
-    }
-
-    /// <summary>
-    /// Un-binds all parameters from their statements
-    /// </summary>
-    internal void Unbind()
-    {
-      _unboundFlag = true;
-    }
-
-    /// <summary>
-    /// This function attempts to map all parameters in the collection to all statements in a Command.
-    /// Since named parameters may span multiple statements, this function makes sure all statements are bound
-    /// to the same named parameter.  Unnamed parameters are bound in sequence.
-    /// </summary>
-    internal void MapParameters(SqliteStatement activeStatement)
-    {
-      if (_unboundFlag == false || _parameterList.Count == 0 || _command._statementList == null) return;
-
-      int nUnnamed = 0;
-      string s;
-      int n;
-      int y = -1;
-      SqliteStatement stmt;
-
-      foreach(SqliteParameter p in _parameterList)
-      {
-        y ++;
-        s = p.ParameterName;
-        if (s == null)
-        {
-          s = String.Format(CultureInfo.InvariantCulture, ";{0}", nUnnamed);
-          nUnnamed++;
-        }
-
-        int x;
-        bool isMapped = false;
-
-        if (activeStatement == null)
-          x = _command._statementList.Count;
-        else
-          x = 1;
-
-        stmt = activeStatement;
-        for (n = 0; n < x; n++)
-        {
-          isMapped = false;
-          if (stmt == null) stmt = _command._statementList[n];
-          if (stmt._paramNames != null)
-          {
-            if (stmt.MapParameter(s, p) == true)
-              isMapped = true;
-          }
-          stmt = null;
-        }
-
-        // If the parameter has a name, but the SQL statement uses unnamed references, this can happen -- attempt to map
-        // the parameter by its index in the collection
-        if (isMapped == false)
-        {
-          s = String.Format(CultureInfo.InvariantCulture, ";{0}", y);
-
-          stmt = activeStatement;
-          for (n = 0; n < x; n++)
-          {
-            if (stmt == null) stmt = _command._statementList[n];
-            if (stmt._paramNames != null)
-            {
-              if (stmt.MapParameter(s, p) == true)
-                isMapped = true;
-            }
-            stmt = null;
-          }
-        }
-      }
-      if (activeStatement == null) _unboundFlag = false;
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Data.Common;\r
+  using System.Collections.Generic;\r
+  using System.Globalization;\r
+  using System.ComponentModel;\r
+  using System.Reflection;\r
+\r
+  /// <summary>\r
+  /// SQLite implementation of DbParameterCollection.\r
+  /// </summary>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  [Editor("Microsoft.VSDesigner.Data.Design.DBParametersEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), ListBindable(false)]\r
+#endif\r
+  public sealed class SQLiteParameterCollection : DbParameterCollection\r
+  {\r
+    /// <summary>\r
+    /// The underlying command to which this collection belongs\r
+    /// </summary>\r
+    private SQLiteCommand         _command;\r
+    /// <summary>\r
+    /// The internal array of parameters in this collection\r
+    /// </summary>\r
+    private List<SQLiteParameter> _parameterList;\r
+    /// <summary>\r
+    /// Determines whether or not all parameters have been bound to their statement(s)\r
+    /// </summary>\r
+    private bool                  _unboundFlag;\r
+\r
+    /// <summary>\r
+    /// Initializes the collection\r
+    /// </summary>\r
+    /// <param name="cmd">The command to which the collection belongs</param>\r
+    internal SQLiteParameterCollection(SQLiteCommand cmd)\r
+    {\r
+      _command = cmd;\r
+      _parameterList = new List<SQLiteParameter>();\r
+      _unboundFlag = true;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns true\r
+    /// </summary>\r
+    public override bool IsSynchronized\r
+    {\r
+      get { return true; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns false\r
+    /// </summary>\r
+    public override bool IsFixedSize\r
+    {\r
+      get { return false; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns false\r
+    /// </summary>\r
+    public override bool IsReadOnly\r
+    {\r
+      get { return false; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns null\r
+    /// </summary>\r
+    public override object SyncRoot\r
+    {\r
+      get { return null; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves an enumerator for the collection\r
+    /// </summary>\r
+    /// <returns>An enumerator for the underlying array</returns>\r
+    public override System.Collections.IEnumerator GetEnumerator()\r
+    {\r
+      return _parameterList.GetEnumerator();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Adds a parameter to the collection\r
+    /// </summary>\r
+    /// <param name="parameterName">The parameter name</param>\r
+    /// <param name="parameterType">The data type</param>\r
+    /// <param name="parameterSize">The size of the value</param>\r
+    /// <param name="sourceColumn">The source column</param>\r
+    /// <returns>A SQLiteParameter object</returns>\r
+    public SQLiteParameter Add(string parameterName, DbType parameterType, int parameterSize, string sourceColumn)\r
+    {\r
+      SQLiteParameter param = new SQLiteParameter(parameterName, parameterType, parameterSize, sourceColumn);\r
+      Add(param);\r
+\r
+      return param;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Adds a parameter to the collection\r
+    /// </summary>\r
+    /// <param name="parameterName">The parameter name</param>\r
+    /// <param name="parameterType">The data type</param>\r
+    /// <param name="parameterSize">The size of the value</param>\r
+    /// <returns>A SQLiteParameter object</returns>\r
+    public SQLiteParameter Add(string parameterName, DbType parameterType, int parameterSize)\r
+    {\r
+      SQLiteParameter param = new SQLiteParameter(parameterName, parameterType, parameterSize);\r
+      Add(param);\r
+\r
+      return param;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Adds a parameter to the collection\r
+    /// </summary>\r
+    /// <param name="parameterName">The parameter name</param>\r
+    /// <param name="parameterType">The data type</param>\r
+    /// <returns>A SQLiteParameter object</returns>\r
+    public SQLiteParameter Add(string parameterName, DbType parameterType)\r
+    {\r
+      SQLiteParameter param = new SQLiteParameter(parameterName, parameterType);\r
+      Add(param);\r
+\r
+      return param;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Adds a parameter to the collection\r
+    /// </summary>\r
+    /// <param name="parameter">The parameter to add</param>\r
+    /// <returns>A zero-based index of where the parameter is located in the array</returns>\r
+    public int Add(SQLiteParameter parameter)\r
+    {\r
+      int n = -1;\r
+\r
+      if (String.IsNullOrEmpty(parameter.ParameterName) == false)\r
+      {\r
+        n = IndexOf(parameter.ParameterName);\r
+      }\r
+\r
+      if (n == -1)\r
+      {\r
+        n = _parameterList.Count;\r
+        _parameterList.Add((SQLiteParameter)parameter);\r
+      }\r
+\r
+      SetParameter(n, parameter);\r
+\r
+      return n;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Adds a parameter to the collection\r
+    /// </summary>\r
+    /// <param name="value">The parameter to add</param>\r
+    /// <returns>A zero-based index of where the parameter is located in the array</returns>\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [EditorBrowsable(EditorBrowsableState.Never)]\r
+#endif\r
+    public override int Add(object value)\r
+    {\r
+      return Add((SQLiteParameter)value);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Adds a named/unnamed parameter and its value to the parameter collection.\r
+    /// </summary>\r
+    /// <param name="parameterName">Name of the parameter, or null to indicate an unnamed parameter</param>\r
+    /// <param name="value">The initial value of the parameter</param>\r
+    /// <returns>Returns the SQLiteParameter object created during the call.</returns>\r
+    public SQLiteParameter AddWithValue(string parameterName, object value)\r
+    {\r
+      SQLiteParameter param = new SQLiteParameter(parameterName, value);\r
+      Add(param);\r
+\r
+      return param;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Adds an array of parameters to the collection\r
+    /// </summary>\r
+    /// <param name="values">The array of parameters to add</param>\r
+    public void AddRange(SQLiteParameter[] values)\r
+    {\r
+      int x = values.Length;\r
+      for (int n = 0; n < x; n++)\r
+        Add(values[n]);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Adds an array of parameters to the collection\r
+    /// </summary>\r
+    /// <param name="values">The array of parameters to add</param>\r
+    public override void AddRange(Array values)\r
+    {\r
+      int x = values.Length;\r
+      for (int n = 0; n < x; n++)\r
+        Add((SQLiteParameter)(values.GetValue(n)));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Clears the array and resets the collection\r
+    /// </summary>\r
+    public override void Clear()\r
+    {\r
+      _unboundFlag = true;\r
+      _parameterList.Clear();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Determines if the named parameter exists in the collection\r
+    /// </summary>\r
+    /// <param name="parameterName">The name of the parameter to check</param>\r
+    /// <returns>True if the parameter is in the collection</returns>\r
+    public override bool Contains(string parameterName)\r
+    {\r
+      return (IndexOf(parameterName) != -1);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Determines if the parameter exists in the collection\r
+    /// </summary>\r
+    /// <param name="value">The SQLiteParameter to check</param>\r
+    /// <returns>True if the parameter is in the collection</returns>\r
+    public override bool Contains(object value)\r
+    {\r
+      return _parameterList.Contains((SQLiteParameter)value);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Not implemented\r
+    /// </summary>\r
+    /// <param name="array"></param>\r
+    /// <param name="index"></param>\r
+    public override void CopyTo(Array array, int index)\r
+    {\r
+      throw new NotImplementedException();\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns a count of parameters in the collection\r
+    /// </summary>\r
+    public override int Count\r
+    {\r
+      get { return _parameterList.Count; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Overloaded to specialize the return value of the default indexer\r
+    /// </summary>\r
+    /// <param name="parameterName">Name of the parameter to get/set</param>\r
+    /// <returns>The specified named SQLite parameter</returns>\r
+    public new SQLiteParameter this[string parameterName]\r
+    {\r
+      get\r
+      {\r
+        return (SQLiteParameter)GetParameter(parameterName);\r
+      }\r
+      set\r
+      {\r
+        SetParameter(parameterName, value);\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Overloaded to specialize the return value of the default indexer\r
+    /// </summary>\r
+    /// <param name="index">The index of the parameter to get/set</param>\r
+    /// <returns>The specified SQLite parameter</returns>\r
+    public new SQLiteParameter this[int index]\r
+    {\r
+      get\r
+      {\r
+        return (SQLiteParameter)GetParameter(index);\r
+      }\r
+      set\r
+      {\r
+        SetParameter(index, value);\r
+      }\r
+    }\r
+    /// <summary>\r
+    /// Retrieve a parameter by name from the collection\r
+    /// </summary>\r
+    /// <param name="parameterName">The name of the parameter to fetch</param>\r
+    /// <returns>A DbParameter object</returns>\r
+    protected override DbParameter GetParameter(string parameterName)\r
+    {\r
+      return GetParameter(IndexOf(parameterName));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Retrieves a parameter by its index in the collection\r
+    /// </summary>\r
+    /// <param name="index">The index of the parameter to retrieve</param>\r
+    /// <returns>A DbParameter object</returns>\r
+    protected override DbParameter GetParameter(int index)\r
+    {\r
+      return _parameterList[index];\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the index of a parameter given its name\r
+    /// </summary>\r
+    /// <param name="parameterName">The name of the parameter to find</param>\r
+    /// <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>\r
+    public override int IndexOf(string parameterName)\r
+    {\r
+      int x = _parameterList.Count;\r
+      for (int n = 0; n < x; n++)\r
+      {\r
+        if (String.Compare(parameterName, _parameterList[n].ParameterName, true, CultureInfo.InvariantCulture) == 0)\r
+          return n;\r
+      }\r
+      return -1;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the index of a parameter\r
+    /// </summary>\r
+    /// <param name="value">The parameter to find</param>\r
+    /// <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>\r
+    public override int IndexOf(object value)\r
+    {\r
+      return _parameterList.IndexOf((SQLiteParameter)value);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Inserts a parameter into the array at the specified location\r
+    /// </summary>\r
+    /// <param name="index">The zero-based index to insert the parameter at</param>\r
+    /// <param name="value">The parameter to insert</param>\r
+    public override void Insert(int index, object value)\r
+    {\r
+      _unboundFlag = true;\r
+      _parameterList.Insert(index, (SQLiteParameter)value);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Removes a parameter from the collection\r
+    /// </summary>\r
+    /// <param name="value">The parameter to remove</param>\r
+    public override void Remove(object value)\r
+    {\r
+      _unboundFlag = true;\r
+      _parameterList.Remove((SQLiteParameter)value);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Removes a parameter from the collection given its name\r
+    /// </summary>\r
+    /// <param name="parameterName">The name of the parameter to remove</param>\r
+    public override void RemoveAt(string parameterName)\r
+    {\r
+      RemoveAt(IndexOf(parameterName));\r
+    }\r
+\r
+    /// <summary>\r
+    /// Removes a parameter from the collection given its index\r
+    /// </summary>\r
+    /// <param name="index">The zero-based parameter index to remove</param>\r
+    public override void RemoveAt(int index)\r
+    {\r
+      _unboundFlag = true;\r
+      _parameterList.RemoveAt(index);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Re-assign the named parameter to a new parameter object\r
+    /// </summary>\r
+    /// <param name="parameterName">The name of the parameter to replace</param>\r
+    /// <param name="value">The new parameter</param>\r
+    protected override void SetParameter(string parameterName, DbParameter value)\r
+    {\r
+      SetParameter(IndexOf(parameterName), value);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Re-assign a parameter at the specified index\r
+    /// </summary>\r
+    /// <param name="index">The zero-based index of the parameter to replace</param>\r
+    /// <param name="value">The new parameter</param>\r
+    protected override void SetParameter(int index, DbParameter value)\r
+    {\r
+      _unboundFlag = true;\r
+      _parameterList[index] = (SQLiteParameter)value;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Un-binds all parameters from their statements\r
+    /// </summary>\r
+    internal void Unbind()\r
+    {\r
+      _unboundFlag = true;\r
+    }\r
+\r
+    /// <summary>\r
+    /// This function attempts to map all parameters in the collection to all statements in a Command.\r
+    /// Since named parameters may span multiple statements, this function makes sure all statements are bound\r
+    /// to the same named parameter.  Unnamed parameters are bound in sequence.\r
+    /// </summary>\r
+    internal void MapParameters(SQLiteStatement activeStatement)\r
+    {\r
+      if (_unboundFlag == false || _parameterList.Count == 0 || _command._statementList == null) return;\r
+\r
+      int nUnnamed = 0;\r
+      string s;\r
+      int n;\r
+      int y = -1;\r
+      SQLiteStatement stmt;\r
+\r
+      foreach(SQLiteParameter p in _parameterList)\r
+      {\r
+        y ++;\r
+        s = p.ParameterName;\r
+        if (s == null)\r
+        {\r
+          s = String.Format(CultureInfo.InvariantCulture, ";{0}", nUnnamed);\r
+          nUnnamed++;\r
+        }\r
+\r
+        int x;\r
+        bool isMapped = false;\r
+\r
+        if (activeStatement == null)\r
+          x = _command._statementList.Count;\r
+        else\r
+          x = 1;\r
+\r
+        stmt = activeStatement;\r
+        for (n = 0; n < x; n++)\r
+        {\r
+          isMapped = false;\r
+          if (stmt == null) stmt = _command._statementList[n];\r
+          if (stmt._paramNames != null)\r
+          {\r
+            if (stmt.MapParameter(s, p) == true)\r
+              isMapped = true;\r
+          }\r
+          stmt = null;\r
+        }\r
+\r
+        // If the parameter has a name, but the SQL statement uses unnamed references, this can happen -- attempt to map\r
+        // the parameter by its index in the collection\r
+        if (isMapped == false)\r
+        {\r
+          s = String.Format(CultureInfo.InvariantCulture, ";{0}", y);\r
+\r
+          stmt = activeStatement;\r
+          for (n = 0; n < x; n++)\r
+          {\r
+            if (stmt == null) stmt = _command._statementList[n];\r
+            if (stmt._paramNames != null)\r
+            {\r
+              if (stmt.MapParameter(s, p) == true)\r
+                isMapped = true;\r
+            }\r
+            stmt = null;\r
+          }\r
+        }\r
+      }\r
+      if (activeStatement == null) _unboundFlag = false;\r
+    }\r
+  }\r
+}\r
index 2ff1a20cd5bbf5b8bb548a15b39c7cf0c5739be9..48e722ad996b972460f44dcde6ee07584d23af79 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteStatement.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Collections.Generic;
-  using System.Globalization;
-
-  /// <summary>
-  /// Represents a single SQL statement in Sqlite.
-  /// </summary>
-  internal sealed class SqliteStatement : IDisposable
-  {
-    /// <summary>
-    /// The underlying Sqlite object this statement is bound to
-    /// </summary>
-    internal SqliteBase        _sql;
-    /// <summary>
-    /// The command text of this SQL statement
-    /// </summary>
-    internal string            _sqlStatement;
-    /// <summary>
-    /// The actual statement pointer
-    /// </summary>
-    internal IntPtr            _sqlite_stmt;
-    /// <summary>
-    /// An index from which unnamed parameters begin
-    /// </summary>
-    internal int               _unnamedParameters;
-    /// <summary>
-    /// Names of the parameters as Sqlite understands them to be
-    /// </summary>
-    internal string[]          _paramNames;
-    /// <summary>
-    /// Parameters for this statement
-    /// </summary>
-    internal SqliteParameter[] _paramValues;
-    /// <summary>
-    /// Command this statement belongs to (if any)
-    /// </summary>
-    internal SqliteCommand     _command;
-
-    private string[] _types;
-
-    /// <summary>
-    /// Initializes the statement and attempts to get all information about parameters in the statement
-    /// </summary>
-    /// <param name="sqlbase">The base Sqlite object</param>
-    /// <param name="stmt">The statement</param>
-    /// <param name="strCommand">The command text for this statement</param>
-    /// <param name="previous">The previous command in a multi-statement command</param>
-    internal SqliteStatement(SqliteBase sqlbase, IntPtr stmt, string strCommand, SqliteStatement previous)
-    {
-      _sql     = sqlbase;
-      _sqlite_stmt = stmt;
-      _sqlStatement  = strCommand;
-
-      // Determine parameters for this statement (if any) and prepare space for them.
-      int nCmdStart = 0;
-      int n = _sql.Bind_ParamCount(this);
-      int x;
-      string s;
-
-      if (n > 0)
-      {
-        if (previous != null)
-          nCmdStart = previous._unnamedParameters;
-
-        _paramNames = new string[n];
-        _paramValues = new SqliteParameter[n];
-
-        for (x = 0; x < n; x++)
-        {
-          s = _sql.Bind_ParamName(this, x + 1);
-          if (String.IsNullOrEmpty(s))
-          {
-            s = String.Format(CultureInfo.InvariantCulture, ";{0}", nCmdStart);
-            nCmdStart++;
-            _unnamedParameters++;
-          }
-          _paramNames[x] = s;
-          _paramValues[x] = null;
-        }
-      }
-    }
-
-    /// <summary>
-    /// Called by SqliteParameterCollection, this function determines if the specified parameter name belongs to
-    /// this statement, and if so, keeps a reference to the parameter so it can be bound later.
-    /// </summary>
-    /// <param name="s">The parameter name to map</param>
-    /// <param name="p">The parameter to assign it</param>
-    internal bool MapParameter(string s, SqliteParameter p)
-    {
-      if (_paramNames == null) return false;
-      
-      int startAt = 0;
-      if (s.Length > 0)
-      {
-        if (":$@;".IndexOf(s[0]) == -1)
-          startAt = 1;
-      }
-
-      int x = _paramNames.Length;
-      for (int n = 0; n < x; n++)
-      {
-        if (String.Compare(_paramNames[n], startAt, s, 0, Math.Max(_paramNames[n].Length - startAt, s.Length), true, CultureInfo.InvariantCulture) == 0)
-        {
-          _paramValues[n] = p;
-          return true;
-        }
-      }
-      return false;
-    }
-
-    #region IDisposable Members
-    /// <summary>
-    /// Disposes and finalizes the statement
-    /// </summary>
-    public void Dispose()
-    {
-      _sql.FinalizeStatement(this);
-      
-      _paramNames = null;
-      _paramValues = null;
-      _sql = null;
-      _sqlStatement = null;
-
-      GC.SuppressFinalize(this);
-    }
-    #endregion
-    
-    /// <summary>
-    ///  Bind all parameters, making sure the caller didn't miss any
-    /// </summary>
-    internal void BindParameters()
-    {
-      if (_paramNames == null) return;
-
-      int x = _paramNames.Length;
-      for (int n = 0; n < x; n++)
-      {
-        BindParameter(n + 1, _paramValues[n]);
-      }
-    }
-
-    /// <summary>
-    /// Perform the bind operation for an individual parameter
-    /// </summary>
-    /// <param name="index">The index of the parameter to bind</param>
-    /// <param name="param">The parameter we're binding</param>
-    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;
-
-      if (Convert.IsDBNull(obj) || obj == null)
-      {
-        _sql.Bind_Null(this, index);
-        return;
-      }
-
-      if (objType == DbType.Object)
-        objType = SqliteConvert.TypeToDbType(obj.GetType());
-
-      switch (objType)
-      {
-        case DbType.Date:
-        case DbType.Time:
-        case DbType.DateTime:
-          _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj, CultureInfo.CurrentCulture));
-          break;
-        case DbType.Int64:
-        case DbType.UInt64:
-          _sql.Bind_Int64(this, index, Convert.ToInt64(obj, CultureInfo.CurrentCulture));
-          break;
-        case DbType.Boolean:
-        case DbType.Int16:
-        case DbType.Int32:
-        case DbType.UInt16:
-        case DbType.UInt32:
-        case DbType.SByte:
-        case DbType.Byte:
-          _sql.Bind_Int32(this, index, Convert.ToInt32(obj, CultureInfo.CurrentCulture));
-          break;
-        case DbType.Single:
-        case DbType.Double:
-        case DbType.Currency:
-        case DbType.Decimal:
-          _sql.Bind_Double(this, index, Convert.ToDouble(obj, CultureInfo.CurrentCulture));
-          break;
-        case DbType.Binary:
-          _sql.Bind_Blob(this, 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());
-
-          break;
-        default:
-          _sql.Bind_Text(this, index, obj.ToString());
-          break;
-      }
-    }
-
-    internal string[] TypeDefinitions
-    {
-      get { return _types; }
-    }
-
-    internal void SetTypes(string typedefs)
-    {
-      int pos = typedefs.IndexOf("TYPES", 0, StringComparison.OrdinalIgnoreCase);
-      if (pos == -1) throw new ArgumentOutOfRangeException();
-
-      string[] types = typedefs.Substring(pos + 6).Replace(" ", "").Replace(";", "").Replace("\"", "").Replace("[", "").Replace("]", "").Split(',', '\r', '\n', '\t');
-
-      int cols = 0;
-      int n;
-      for (n = 0; n < types.Length; n++)
-      {
-        if (String.IsNullOrEmpty(types[n]) == false)
-          cols++;
-      }
-
-      _types = new string[cols];
-
-      cols = 0;
-      for (n = 0; n < types.Length; n++)
-      {
-        if (String.IsNullOrEmpty(types[n]) == false)
-          _types[cols++] = types[n];
-      }
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Collections.Generic;\r
+  using System.Globalization;\r
+\r
+  /// <summary>\r
+  /// Represents a single SQL statement in SQLite.\r
+  /// </summary>\r
+  internal sealed class SQLiteStatement : IDisposable\r
+  {\r
+    /// <summary>\r
+    /// The underlying SQLite object this statement is bound to\r
+    /// </summary>\r
+    internal SQLiteBase        _sql;\r
+    /// <summary>\r
+    /// The command text of this SQL statement\r
+    /// </summary>\r
+    internal string            _sqlStatement;\r
+    /// <summary>\r
+    /// The actual statement pointer\r
+    /// </summary>\r
+    internal SQLiteStatementHandle  _sqlite_stmt;\r
+    /// <summary>\r
+    /// An index from which unnamed parameters begin\r
+    /// </summary>\r
+    internal int               _unnamedParameters;\r
+    /// <summary>\r
+    /// Names of the parameters as SQLite understands them to be\r
+    /// </summary>\r
+    internal string[]          _paramNames;\r
+    /// <summary>\r
+    /// Parameters for this statement\r
+    /// </summary>\r
+    internal SQLiteParameter[] _paramValues;\r
+    /// <summary>\r
+    /// Command this statement belongs to (if any)\r
+    /// </summary>\r
+    internal SQLiteCommand     _command;\r
+\r
+    private string[] _types;\r
+\r
+    /// <summary>\r
+    /// Initializes the statement and attempts to get all information about parameters in the statement\r
+    /// </summary>\r
+    /// <param name="sqlbase">The base SQLite object</param>\r
+    /// <param name="stmt">The statement</param>\r
+    /// <param name="strCommand">The command text for this statement</param>\r
+    /// <param name="previous">The previous command in a multi-statement command</param>\r
+    internal SQLiteStatement(SQLiteBase sqlbase, SQLiteStatementHandle stmt, string strCommand, SQLiteStatement previous)\r
+    {\r
+      _sql     = sqlbase;\r
+      _sqlite_stmt = stmt;\r
+      _sqlStatement  = strCommand;\r
+\r
+      // Determine parameters for this statement (if any) and prepare space for them.\r
+      int nCmdStart = 0;\r
+      int n = _sql.Bind_ParamCount(this);\r
+      int x;\r
+      string s;\r
+\r
+      if (n > 0)\r
+      {\r
+        if (previous != null)\r
+          nCmdStart = previous._unnamedParameters;\r
+\r
+        _paramNames = new string[n];\r
+        _paramValues = new SQLiteParameter[n];\r
+\r
+        for (x = 0; x < n; x++)\r
+        {\r
+          s = _sql.Bind_ParamName(this, x + 1);\r
+          if (String.IsNullOrEmpty(s))\r
+          {\r
+            s = String.Format(CultureInfo.InvariantCulture, ";{0}", nCmdStart);\r
+            nCmdStart++;\r
+            _unnamedParameters++;\r
+          }\r
+          _paramNames[x] = s;\r
+          _paramValues[x] = null;\r
+        }\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to\r
+    /// this statement, and if so, keeps a reference to the parameter so it can be bound later.\r
+    /// </summary>\r
+    /// <param name="s">The parameter name to map</param>\r
+    /// <param name="p">The parameter to assign it</param>\r
+    internal bool MapParameter(string s, SQLiteParameter p)\r
+    {\r
+      if (_paramNames == null) return false;\r
+      \r
+      int startAt = 0;\r
+      if (s.Length > 0)\r
+      {\r
+        if (":$@;".IndexOf(s[0]) == -1)\r
+          startAt = 1;\r
+      }\r
+\r
+      int x = _paramNames.Length;\r
+      for (int n = 0; n < x; n++)\r
+      {\r
+        if (String.Compare(_paramNames[n], startAt, s, 0, Math.Max(_paramNames[n].Length - startAt, s.Length), true, CultureInfo.InvariantCulture) == 0)\r
+        {\r
+          _paramValues[n] = p;\r
+          return true;\r
+        }\r
+      }\r
+      return false;\r
+    }\r
+\r
+    #region IDisposable Members\r
+    /// <summary>\r
+    /// Disposes and finalizes the statement\r
+    /// </summary>\r
+    public void Dispose()\r
+    {\r
+      if (_sqlite_stmt != null)\r
+      {\r
+        _sqlite_stmt.Dispose();\r
+      }\r
+      _sqlite_stmt = null;\r
+      \r
+      _paramNames = null;\r
+      _paramValues = null;\r
+      _sql = null;\r
+      _sqlStatement = null;\r
+    }\r
+    #endregion\r
+    \r
+    /// <summary>\r
+    ///  Bind all parameters, making sure the caller didn't miss any\r
+    /// </summary>\r
+    internal void BindParameters()\r
+    {\r
+      if (_paramNames == null) return;\r
+\r
+      int x = _paramNames.Length;\r
+      for (int n = 0; n < x; n++)\r
+      {\r
+        BindParameter(n + 1, _paramValues[n]);\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Perform the bind operation for an individual parameter\r
+    /// </summary>\r
+    /// <param name="index">The index of the parameter to bind</param>\r
+    /// <param name="param">The parameter we're binding</param>\r
+    private void BindParameter(int index, SQLiteParameter param)\r
+    {\r
+      if (param == null)\r
+        throw new SQLiteException((int)SQLiteErrorCode.Error, "Insufficient parameters supplied to the command");\r
+\r
+      object obj = param.Value;\r
+      DbType objType = param.DbType;\r
+\r
+      if (Convert.IsDBNull(obj) || obj == null)\r
+      {\r
+        _sql.Bind_Null(this, index);\r
+        return;\r
+      }\r
+\r
+      if (objType == DbType.Object)\r
+        objType = SQLiteConvert.TypeToDbType(obj.GetType());\r
+\r
+      switch (objType)\r
+      {\r
+        case DbType.Date:\r
+        case DbType.Time:\r
+        case DbType.DateTime:\r
+          _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj, CultureInfo.CurrentCulture));\r
+          break;\r
+        case DbType.Int64:\r
+        case DbType.UInt64:\r
+          _sql.Bind_Int64(this, index, Convert.ToInt64(obj, CultureInfo.CurrentCulture));\r
+          break;\r
+        case DbType.Boolean:\r
+        case DbType.Int16:\r
+        case DbType.Int32:\r
+        case DbType.UInt16:\r
+        case DbType.UInt32:\r
+        case DbType.SByte:\r
+        case DbType.Byte:\r
+          _sql.Bind_Int32(this, index, Convert.ToInt32(obj, CultureInfo.CurrentCulture));\r
+          break;\r
+        case DbType.Single:\r
+        case DbType.Double:\r
+        case DbType.Currency:\r
+        //case DbType.Decimal: // Dont store decimal as double ... loses precision\r
+          _sql.Bind_Double(this, index, Convert.ToDouble(obj, CultureInfo.CurrentCulture));\r
+          break;\r
+        case DbType.Binary:\r
+          _sql.Bind_Blob(this, index, (byte[])obj);\r
+          break;\r
+        case DbType.Guid:\r
+          if (_command.Connection._binaryGuid == true)\r
+            _sql.Bind_Blob(this, index, ((Guid)obj).ToByteArray());\r
+          else\r
+            _sql.Bind_Text(this, index, obj.ToString());\r
+\r
+          break;\r
+        case DbType.Decimal: // Dont store decimal as double ... loses precision\r
+          _sql.Bind_Text(this, index, Convert.ToDecimal(obj, CultureInfo.CurrentCulture).ToString(CultureInfo.InvariantCulture));\r
+          break;\r
+        default:\r
+          _sql.Bind_Text(this, index, obj.ToString());\r
+          break;\r
+      }\r
+    }\r
+\r
+    internal string[] TypeDefinitions\r
+    {\r
+      get { return _types; }\r
+    }\r
+\r
+    internal void SetTypes(string typedefs)\r
+    {\r
+      int pos = typedefs.IndexOf("TYPES", 0, StringComparison.OrdinalIgnoreCase);\r
+      if (pos == -1) throw new ArgumentOutOfRangeException();\r
+\r
+      string[] types = typedefs.Substring(pos + 6).Replace(" ", "").Replace(";", "").Replace("\"", "").Replace("[", "").Replace("]", "").Replace("`","").Split(',', '\r', '\n', '\t');\r
+\r
+      int n;\r
+      for (n = 0; n < types.Length; n++)\r
+      {\r
+        if (String.IsNullOrEmpty(types[n]) == true)\r
+          types[n] = null;\r
+      }\r
+      _types = types;\r
+    }\r
+  }\r
+}\r
index dc79c8656b2132caa4e32f62a60d458d1e1d9cf3..23ea1292a083c17d46f433aa7ef15d8ca2ba2abe 100644 (file)
-//
-// Mono.Data.Sqlite.SQLiteTransaction.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Data;
-  using System.Data.Common;
-
-  /// <summary>
-  /// Sqlite implementation of DbTransaction.
-  /// </summary>
-  public sealed class SqliteTransaction : DbTransaction
-  {
-    /// <summary>
-    /// The connection to which this transaction is bound
-    /// </summary>
-    internal SqliteConnection _cnn;
-    internal long _version; // Matches the version of the connection
-
-    /// <summary>
-    /// Constructs the transaction object, binding it to the supplied connection
-    /// </summary>
-    /// <param name="connection">The connection to open a transaction on</param>
-    /// <param name="deferredLock">TRUE to defer the writelock, or FALSE to lock immediately</param>
-    internal SqliteTransaction(SqliteConnection connection, bool deferredLock)
-    {
-      _cnn = connection;
-      _version = _cnn._version;
-
-      if (_cnn._transactionLevel++ == 0)
-      {
-        try
-        {
-          using (SqliteCommand cmd = _cnn.CreateCommand())
-          {
-            if (!deferredLock)
-              cmd.CommandText = "BEGIN IMMEDIATE";
-            else
-              cmd.CommandText = "BEGIN";
-
-            cmd.ExecuteNonQuery();
-          }
-        }
-        catch (SqliteException)
-        {
-          _cnn._transactionLevel--;
-          _cnn = null;
-          throw;
-        }
-      }
-    }
-
-    /// <summary>
-    /// Commits the current transaction.
-    /// </summary>
-    public override void Commit()
-    {
-      IsValid(true);
-
-      if (--_cnn._transactionLevel == 0)
-      {
-        try
-        {
-          using (SqliteCommand cmd = _cnn.CreateCommand())
-          {
-            cmd.CommandText = "COMMIT";
-            cmd.ExecuteNonQuery();
-          }
-        }
-        finally
-        {
-          _cnn = null;
-        }
-      }
-      else
-      {
-        _cnn = null;
-      }
-    }
-
-    /// <summary>
-    /// Returns the underlying connection to which this transaction applies.
-    /// </summary>
-    public new SqliteConnection Connection
-    {
-      get { return _cnn; }
-    }
-
-    /// <summary>
-    /// Forwards to the local Connection property
-    /// </summary>
-    protected override DbConnection DbConnection
-    {
-      get { return Connection; }
-    }
-
-    /// <summary>
-    /// Disposes the transaction.  If it is currently active, any changes are rolled back.
-    /// </summary>
-    protected override void Dispose(bool disposing)
-    {
-      if (IsValid(false))
-        Rollback();
-
-      _cnn = null;
-
-      base.Dispose(disposing);
-    }
-
-    /// <summary>
-    /// Gets the isolation level of the transaction.  Sqlite only supports Serializable transactions.
-    /// </summary>
-    public override IsolationLevel IsolationLevel
-    {
-      get { return IsolationLevel.Serializable; }
-    }
-
-    /// <summary>
-    /// Rolls back the active transaction.
-    /// </summary>
-    public override void Rollback()
-    {
-      IsValid(true);
-
-      try
-      {
-        using (SqliteCommand cmd = _cnn.CreateCommand())
-        {
-          cmd.CommandText = "ROLLBACK";
-          cmd.ExecuteNonQuery();
-        }
-        _cnn._transactionLevel = 0;
-      }
-      finally
-      {
-        _cnn = null;
-      }
-    }
-
-    internal bool IsValid(bool throwError)
-    {
-      if (_cnn == null)
-      {
-        if (throwError == true) throw new ArgumentNullException("No connection associated with this transaction");
-        else return false;
-      }
-
-      if (_cnn._transactionLevel == 0)
-      {
-        if (throwError == true) throw new SqliteException((int)SqliteErrorCode.Misuse, "No transaction is active on this connection");
-        else return false;
-      }
-      if (_cnn._version != _version)
-      {
-        if (throwError == true) throw new SqliteException((int)SqliteErrorCode.Misuse, "The connection was closed and re-opened, changes were rolled back");
-        else return false;
-      }
-      if (_cnn.State != ConnectionState.Open)
-      {
-        if (throwError == true) throw new SqliteException((int)SqliteErrorCode.Misuse, "Connection was closed");
-        else return false;
-      }
-
-      return true;
-    }
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Data;\r
+  using System.Data.Common;\r
+\r
+  /// <summary>\r
+  /// SQLite implementation of DbTransaction.\r
+  /// </summary>\r
+  public sealed class SQLiteTransaction : DbTransaction\r
+  {\r
+    /// <summary>\r
+    /// The connection to which this transaction is bound\r
+    /// </summary>\r
+    internal SQLiteConnection _cnn;\r
+    internal long _version; // Matches the version of the connection\r
+    private IsolationLevel _level;\r
+\r
+    /// <summary>\r
+    /// Constructs the transaction object, binding it to the supplied connection\r
+    /// </summary>\r
+    /// <param name="connection">The connection to open a transaction on</param>\r
+    /// <param name="deferredLock">TRUE to defer the writelock, or FALSE to lock immediately</param>\r
+    internal SQLiteTransaction(SQLiteConnection connection, bool deferredLock)\r
+    {\r
+      _cnn = connection;\r
+      _version = _cnn._version;\r
+\r
+      _level = (deferredLock == true) ? IsolationLevel.ReadCommitted : IsolationLevel.Serializable;\r
+\r
+      if (_cnn._transactionLevel++ == 0)\r
+      {\r
+        try\r
+        {\r
+          using (SQLiteCommand cmd = _cnn.CreateCommand())\r
+          {\r
+            if (!deferredLock)\r
+              cmd.CommandText = "BEGIN IMMEDIATE";\r
+            else\r
+              cmd.CommandText = "BEGIN";\r
+\r
+            cmd.ExecuteNonQuery();\r
+          }\r
+        }\r
+        catch (SQLiteException)\r
+        {\r
+          _cnn._transactionLevel--;\r
+          _cnn = null;\r
+          throw;\r
+        }\r
+      }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Commits the current transaction.\r
+    /// </summary>\r
+    public override void Commit()\r
+    {\r
+      IsValid(true);\r
+\r
+      if (_cnn._transactionLevel - 1 == 0)\r
+      {\r
+        using (SQLiteCommand cmd = _cnn.CreateCommand())\r
+        {\r
+          cmd.CommandText = "COMMIT";\r
+          cmd.ExecuteNonQuery();\r
+        }\r
+      }\r
+      _cnn._transactionLevel--;\r
+      _cnn = null;\r
+    }\r
+\r
+    /// <summary>\r
+    /// Returns the underlying connection to which this transaction applies.\r
+    /// </summary>\r
+    public new SQLiteConnection Connection\r
+    {\r
+      get { return _cnn; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Forwards to the local Connection property\r
+    /// </summary>\r
+    protected override DbConnection DbConnection\r
+    {\r
+      get { return Connection; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Disposes the transaction.  If it is currently active, any changes are rolled back.\r
+    /// </summary>\r
+    protected override void Dispose(bool disposing)\r
+    {\r
+      if (disposing)\r
+      {\r
+        lock (this)\r
+        {\r
+          if (IsValid(false))\r
+            Rollback();\r
+\r
+          _cnn = null;\r
+        }\r
+      }\r
+      base.Dispose(disposing);\r
+    }\r
+\r
+    /// <summary>\r
+    /// Gets the isolation level of the transaction.  SQLite only supports Serializable transactions.\r
+    /// </summary>\r
+    public override IsolationLevel IsolationLevel\r
+    {\r
+      get { return _level; }\r
+    }\r
+\r
+    /// <summary>\r
+    /// Rolls back the active transaction.\r
+    /// </summary>\r
+    public override void Rollback()\r
+    {\r
+      IsValid(true);\r
+\r
+      IssueRollback(_cnn);\r
+\r
+      _cnn._transactionLevel = 0;\r
+      _cnn = null;\r
+    }\r
+\r
+    internal static void IssueRollback(SQLiteConnection cnn)\r
+    {\r
+      using (SQLiteCommand cmd = cnn.CreateCommand())\r
+      {\r
+        cmd.CommandText = "ROLLBACK";\r
+        cmd.ExecuteNonQuery();\r
+      }\r
+    }\r
+\r
+    internal bool IsValid(bool throwError)\r
+    {\r
+      if (_cnn == null)\r
+      {\r
+        if (throwError == true) throw new ArgumentNullException("No connection associated with this transaction");\r
+        else return false;\r
+      }\r
+\r
+      if (_cnn._transactionLevel == 0)\r
+      {\r
+        if (throwError == true) throw new SQLiteException((int)SQLiteErrorCode.Misuse, "No transaction is active on this connection");\r
+        else return false;\r
+      }\r
+      if (_cnn._version != _version)\r
+      {\r
+        if (throwError == true) throw new SQLiteException((int)SQLiteErrorCode.Misuse, "The connection was closed and re-opened, changes were rolled back");\r
+        else return false;\r
+      }\r
+      if (_cnn.State != ConnectionState.Open)\r
+      {\r
+        if (throwError == true) throw new SQLiteException((int)SQLiteErrorCode.Misuse, "Connection was closed");\r
+        else return false;\r
+      }\r
+\r
+      return true;\r
+    }\r
+  }\r
+}\r
index a78fcd21ba8de77c90d4d7b504fc88484ee3ff37..fcf40869f19954f8fc8e8b938d3ffc0c138832a1 100644 (file)
-//
-// Mono.Data.Sqlite.SR.Designer.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:2.0.50727.42
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-#if NET_2_0
-namespace Mono.Data.Sqlite {
-    using System;
-    
-    
-    /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
-    /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // 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", "2.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    internal class SR {
-        
-        private static global::System.Resources.ResourceManager resourceMan;
-        
-        private static global::System.Globalization.CultureInfo resourceCulture;
-        
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal SR() {
-        }
-        
-        /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
-        /// </summary>
-        [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("SR", typeof(SR).Assembly);
-                    resourceMan = temp;
-                }
-                return resourceMan;
-            }
-        }
-        
-        /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
-            get {
-                return resourceCulture;
-            }
-            set {
-                resourceCulture = value;
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; standalone=&quot;yes&quot;?&gt;
-        ///&lt;DocumentElement&gt;
-        ///  &lt;DataTypes&gt;
-        ///    &lt;TypeName&gt;smallint&lt;/TypeName&gt;
-        ///    &lt;ProviderDbType&gt;10&lt;/ProviderDbType&gt;
-        ///    &lt;ColumnSize&gt;5&lt;/ColumnSize&gt;
-        ///    &lt;DataType&gt;System.Int16&lt;/DataType&gt;
-        ///    &lt;CreateFormat&gt;smallint&lt;/CreateFormat&gt;
-        ///    &lt;IsAutoIncrementable&gt;false&lt;/IsAutoIncrementable&gt;
-        ///    &lt;IsCaseSensitive&gt;false&lt;/IsCaseSensitive&gt;
-        ///    &lt;IsFixedLength&gt;true&lt;/IsFixedLength&gt;
-        ///    &lt;IsFixedPrecisionScale&gt;true&lt;/IsFixedPrecisionScale&gt;
-        ///    &lt;IsLong&gt;false&lt;/IsLong&gt;
-        ///    &lt;IsNullable&gt;true&lt;/ [rest of string was truncated]&quot;;.
-        /// </summary>
-        internal static string DataTypes {
-            get {
-                return ResourceManager.GetString("DataTypes", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to 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.
-        /// </summary>
-        internal static string Keywords {
-            get {
-                return ResourceManager.GetString("Keywords", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
-        ///&lt;DocumentElement&gt;
-        ///  &lt;MetaDataCollections&gt;
-        ///    &lt;CollectionName&gt;MetaDataCollections&lt;/CollectionName&gt;
-        ///    &lt;NumberOfRestrictions&gt;0&lt;/NumberOfRestrictions&gt;
-        ///    &lt;NumberOfIdentifierParts&gt;0&lt;/NumberOfIdentifierParts&gt;
-        ///  &lt;/MetaDataCollections&gt;
-        ///  &lt;MetaDataCollections&gt;
-        ///    &lt;CollectionName&gt;DataSourceInformation&lt;/CollectionName&gt;
-        ///    &lt;NumberOfRestrictions&gt;0&lt;/NumberOfRestrictions&gt;
-        ///    &lt;NumberOfIdentifierParts&gt;0&lt;/NumberOfIdentifierParts&gt;
-        ///  &lt;/MetaDataCollections&gt;
-        ///  &lt;MetaDataC [rest of string was truncated]&quot;;.
-        /// </summary>
-        internal static string MetaDataCollections {
-            get {
-                return ResourceManager.GetString("MetaDataCollections", resourceCulture);
-            }
-        }
-    }
-}
-#endif
+//------------------------------------------------------------------------------\r
+// <auto-generated>\r
+//     This code was generated by a tool.\r
+//     Runtime Version:2.0.50727.3053\r
+//\r
+//     Changes to this file may cause incorrect behavior and will be lost if\r
+//     the code is regenerated.\r
+// </auto-generated>\r
+//------------------------------------------------------------------------------\r
+\r
+namespace System.Data.SQLite {\r
+    using System;\r
+    \r
+    \r
+    /// <summary>\r
+    ///   A strongly-typed resource class, for looking up localized strings, etc.\r
+    /// </summary>\r
+    // This class was auto-generated by the StronglyTypedResourceBuilder\r
+    // class via a tool like ResGen or Visual Studio.\r
+    // To add or remove a member, edit your .ResX file then rerun ResGen\r
+    // with the /str option, or rebuild your VS project.\r
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\r
+    internal class SR {\r
+        \r
+        private static global::System.Resources.ResourceManager resourceMan;\r
+        \r
+        private static global::System.Globalization.CultureInfo resourceCulture;\r
+        \r
+        internal SR() {\r
+        }\r
+        \r
+        /// <summary>\r
+        ///   Returns the cached ResourceManager instance used by this class.\r
+        /// </summary>\r
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r
+        internal static global::System.Resources.ResourceManager ResourceManager {\r
+            get {\r
+                if (object.ReferenceEquals(resourceMan, null)) {\r
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Data.SQLite.SR", typeof(SR).Assembly);\r
+                    resourceMan = temp;\r
+                }\r
+                return resourceMan;\r
+            }\r
+        }\r
+        \r
+        /// <summary>\r
+        ///   Overrides the current thread's CurrentUICulture property for all\r
+        ///   resource lookups using this strongly typed resource class.\r
+        /// </summary>\r
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\r
+        internal static global::System.Globalization.CultureInfo Culture {\r
+            get {\r
+                return resourceCulture;\r
+            }\r
+            set {\r
+                resourceCulture = value;\r
+            }\r
+        }\r
+        \r
+        /// <summary>\r
+        ///   Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; standalone=&quot;yes&quot;?&gt;\r
+        ///&lt;DocumentElement&gt;\r
+        ///  &lt;DataTypes&gt;\r
+        ///    &lt;TypeName&gt;smallint&lt;/TypeName&gt;\r
+        ///    &lt;ProviderDbType&gt;10&lt;/ProviderDbType&gt;\r
+        ///    &lt;ColumnSize&gt;5&lt;/ColumnSize&gt;\r
+        ///    &lt;DataType&gt;System.Int16&lt;/DataType&gt;\r
+        ///    &lt;CreateFormat&gt;smallint&lt;/CreateFormat&gt;\r
+        ///    &lt;IsAutoIncrementable&gt;false&lt;/IsAutoIncrementable&gt;\r
+        ///    &lt;IsCaseSensitive&gt;false&lt;/IsCaseSensitive&gt;\r
+        ///    &lt;IsFixedLength&gt;true&lt;/IsFixedLength&gt;\r
+        ///    &lt;IsFixedPrecisionScale&gt;true&lt;/IsFixedPrecisionScale&gt;\r
+        ///    &lt;IsLong&gt;false&lt;/IsLong&gt;\r
+        ///    &lt;IsNullable&gt;true&lt;/ [rest of string was truncated]&quot;;.\r
+        /// </summary>\r
+        internal static string DataTypes {\r
+            get {\r
+                return ResourceManager.GetString("DataTypes", resourceCulture);\r
+            }\r
+        }\r
+        \r
+        /// <summary>\r
+        ///   Looks up a localized string similar to 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.\r
+        /// </summary>\r
+        internal static string Keywords {\r
+            get {\r
+                return ResourceManager.GetString("Keywords", resourceCulture);\r
+            }\r
+        }\r
+        \r
+        /// <summary>\r
+        ///   Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;\r
+        ///&lt;DocumentElement&gt;\r
+        ///  &lt;MetaDataCollections&gt;\r
+        ///    &lt;CollectionName&gt;MetaDataCollections&lt;/CollectionName&gt;\r
+        ///    &lt;NumberOfRestrictions&gt;0&lt;/NumberOfRestrictions&gt;\r
+        ///    &lt;NumberOfIdentifierParts&gt;0&lt;/NumberOfIdentifierParts&gt;\r
+        ///  &lt;/MetaDataCollections&gt;\r
+        ///  &lt;MetaDataCollections&gt;\r
+        ///    &lt;CollectionName&gt;DataSourceInformation&lt;/CollectionName&gt;\r
+        ///    &lt;NumberOfRestrictions&gt;0&lt;/NumberOfRestrictions&gt;\r
+        ///    &lt;NumberOfIdentifierParts&gt;0&lt;/NumberOfIdentifierParts&gt;\r
+        ///  &lt;/MetaDataCollections&gt;\r
+        ///  &lt;MetaDataC [rest of string was truncated]&quot;;.\r
+        /// </summary>\r
+        internal static string MetaDataCollections {\r
+            get {\r
+                return ResourceManager.GetString("MetaDataCollections", resourceCulture);\r
+            }\r
+        }\r
+    }\r
+}\r
index 3ff2498ee128eff7a9d447c1d7162327d4c14dec..5e2b334f2312daab1feb60fc27debdff0ffdc437 100644 (file)
-//
-// Mono.Data.Sqlite.UnsafeNativeMethods.cs
-//
-// Author(s):
-//   Robert Simpson (robert@blackcastlesoft.com)
-//
-// Adapted and modified for the Mono Project by
-//   Marek Habersack (grendello@gmail.com)
-//
-//
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2007 Marek Habersack
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-/********************************************************
- * 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!
- ********************************************************/
-#if NET_2_0
-namespace Mono.Data.Sqlite
-{
-  using System;
-  using System.Security;
-  using System.Runtime.InteropServices;
-
-#if !PLATFORM_COMPACTFRAMEWORK
-  [SuppressUnmanagedCodeSecurity]
-#endif
-  internal sealed class UnsafeNativeMethods
-  {
-    private const string SQLITE_DLL = "sqlite3";
-
-    private UnsafeNativeMethods()
-    {
-    }
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern void sqlite3_sleep(uint dwMilliseconds);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_libversion();
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern void sqlite3_free(IntPtr p);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_open(byte[] utf8Filename, out IntPtr db);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern void sqlite3_interrupt(IntPtr db);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_close(IntPtr db);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_exec(IntPtr db, byte[] strSql, IntPtr pvCallback, IntPtr pvParam, out IntPtr errMsg, out int len);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_errmsg(IntPtr db);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_changes(IntPtr db);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_busy_timeout(IntPtr db, int ms);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_prepare_v2(IntPtr db, IntPtr pSql, int nBytes, out IntPtr stmt, out IntPtr ptrRemain);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_prepare(IntPtr db, IntPtr pSql, int nBytes, out IntPtr stmt, out IntPtr ptrRemain);
-         
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_bind_blob(IntPtr stmt, int index, Byte[] value, int nSize, IntPtr nTransient);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_bind_double(IntPtr stmt, int index, double value);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_bind_int(IntPtr stmt, int index, int value);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_bind_int64(IntPtr stmt, int index, long value);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_bind_null(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_bind_text(IntPtr stmt, int index, byte[] value, int nlen, IntPtr pvReserved);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_bind_parameter_count(IntPtr stmt);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_bind_parameter_name(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_bind_parameter_index(IntPtr stmt, byte[] strName);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_column_count(IntPtr stmt);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_name(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_decltype(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_step(IntPtr stmt);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern double sqlite3_column_double(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_column_int(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern Int64 sqlite3_column_int64(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_text(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_blob(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_column_bytes(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern TypeAffinity sqlite3_column_type(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_finalize(IntPtr stmt);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_reset(IntPtr stmt);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_create_collation(IntPtr db, byte[] strName, int eTextRep, IntPtr ctx, SqliteCollation fcompare);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_create_function(IntPtr db, byte[] strName, int nArgs, int eTextRep, IntPtr app, SqliteCallback func, SqliteCallback fstep, SqliteFinalCallback ffinal);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_aggregate_count(IntPtr context);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_value_blob(IntPtr p);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_value_bytes(IntPtr p);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern double sqlite3_value_double(IntPtr p);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_value_int(IntPtr p);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern Int64 sqlite3_value_int64(IntPtr p);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_value_text(IntPtr p);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern TypeAffinity sqlite3_value_type(IntPtr p);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern void sqlite3_result_blob(IntPtr context, byte[] value, int nSize, IntPtr pvReserved);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern void sqlite3_result_double(IntPtr context, double value);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern void sqlite3_result_error(IntPtr context, byte[] strErr, int nLen);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern void sqlite3_result_int(IntPtr context, int value);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern void sqlite3_result_int64(IntPtr context, Int64 value);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern void sqlite3_result_null(IntPtr context);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern void sqlite3_result_text(IntPtr context, byte[] value, int nLen, IntPtr pvReserved);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_aggregate_context(IntPtr context, int nBytes);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_table_column_metadata(IntPtr db, byte[] dbName, byte[] tblName, byte[] colName, out IntPtr ptrDataType, out IntPtr ptrCollSeq, out int notNull, out int primaryKey, out int autoInc);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_database_name(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_database_name16(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_table_name(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_table_name16(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_origin_name(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_origin_name16(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_text16(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
-    internal static extern int sqlite3_open16(string utf16Filename, out IntPtr db);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_errmsg16(IntPtr db);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
-    internal static extern int sqlite3_prepare16_v2(IntPtr db, IntPtr pSql, int sqlLen, out IntPtr stmt, out IntPtr ptrRemain);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
-    internal static extern int sqlite3_bind_text16(IntPtr stmt, int index, string value, int nlen, int nTransient);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_name16(IntPtr stmt, int index);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_column_decltype16(IntPtr stmt, int index, out int len);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
-    internal static extern int sqlite3_create_collation16(IntPtr db, string strName, int eTextRep, IntPtr ctx, SqliteCollation fcompare);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
-    internal static extern int sqlite3_create_function16(IntPtr db, string strName, int nArgs, int eTextRep, IntPtr app, SqliteCallback func, SqliteCallback funcstep, SqliteFinalCallback funcfinal);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_value_text16(IntPtr p);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
-    internal static extern void sqlite3_result_error16(IntPtr context, string strName, int nLen);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
-    internal static extern void sqlite3_result_text16(IntPtr context, string strName, int nLen, IntPtr pvReserved);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]
-    internal static extern int sqlite3_encryptfile(string fileName);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]
-    internal static extern int sqlite3_decryptfile(string fileName);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]
-    internal static extern int sqlite3_encryptedstatus(string fileName, out int fileStatus);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]
-    internal static extern int sqlite3_compressfile(string fileName);
-
-    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]
-    internal static extern int sqlite3_decompressfile(string fileName);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_key(IntPtr db, byte[] key, int keylen);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_rekey(IntPtr db, byte[] key, int keylen);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_update_hook(IntPtr db, SqliteUpdateCallback func);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_commit_hook(IntPtr db, SqliteCommitCallback func);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern IntPtr sqlite3_rollback_hook(IntPtr db, SqliteRollbackCallback func);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_cursor_rowid(IntPtr stmt, int cursor, out long rowid);
-
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_table_cursor(IntPtr stmt, int db, int tableRootPage);
-    
-    [DllImport(SQLITE_DLL)]
-    internal static extern int sqlite3_last_insert_rowid(IntPtr db);
-  }
-}
-#endif
+/********************************************************\r
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
+ * Written by Robert Simpson (robert@blackcastlesoft.com)\r
+ * \r
+ * Released to the public domain, use at your own risk!\r
+ ********************************************************/\r
+\r
+namespace System.Data.SQLite\r
+{\r
+  using System;\r
+  using System.Security;\r
+  using System.Runtime.InteropServices;\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+  [SuppressUnmanagedCodeSecurity]\r
+#endif\r
+  internal static class UnsafeNativeMethods\r
+  {\r
+#if !SQLITE_STANDARD\r
+\r
+#if !USE_INTEROP_DLL\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    private const string SQLITE_DLL = "System.Data.SQLite.DLL";\r
+#else\r
+    internal const string SQLITE_DLL = "SQLite.Interop.061.DLL";\r
+#endif // PLATFORM_COMPACTFRAMEWORK\r
+\r
+#else\r
+    private const string SQLITE_DLL = "SQLite.Interop.DLL";\r
+#endif // USE_INTEROP_DLL\r
+\r
+#else\r
+    private const string SQLITE_DLL = "sqlite3";\r
+#endif\r
+\r
+    // This section uses interop calls that also fetch text length to optimize conversion.  \r
+    // When using the standard dll, we can replace these calls with normal sqlite calls and do unoptimized conversions instead afterwards\r
+    #region interop added textlength calls\r
+\r
+#if !SQLITE_STANDARD\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_bind_parameter_name_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_database_name_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_database_name16_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_decltype_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_decltype16_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_name_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_name16_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_origin_name_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_origin_name16_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_table_name_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_table_name16_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_text_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_column_text16_interop(IntPtr stmt, int index, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_errmsg_interop(IntPtr db, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_prepare_interop(IntPtr db, IntPtr pSql, int nBytes, out IntPtr stmt, out IntPtr ptrRemain, out int nRemain);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_table_column_metadata_interop(IntPtr db, byte[] dbName, byte[] tblName, byte[] colName, out IntPtr ptrDataType, out IntPtr ptrCollSeq, out int notNull, out int primaryKey, out int autoInc, out int dtLen, out int csLen);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_value_text_interop(IntPtr p, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_value_text16_interop(IntPtr p, out int len);\r
+#endif\r
+\r
+    #endregion\r
+\r
+    // These functions add existing functionality on top of SQLite and require a little effort to\r
+    // get working when using the standard SQLite library.\r
+    #region interop added functionality\r
+\r
+#if !SQLITE_STANDARD\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_close_interop(IntPtr db);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_create_function_interop(IntPtr db, byte[] strName, int nArgs, int nType, IntPtr pvUser, SQLiteCallback func, SQLiteCallback fstep, SQLiteFinalCallback ffinal, int needCollSeq);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_finalize_interop(IntPtr stmt);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_open_interop(byte[] utf8Filename, int flags, out IntPtr db);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_open16_interop(byte[] utf8Filename, int flags, out IntPtr db);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_reset_interop(IntPtr stmt);\r
+\r
+#endif\r
+\r
+    #endregion\r
+\r
+    // The standard api call equivalents of the above interop calls\r
+    #region standard versions of interop functions\r
+\r
+#if SQLITE_STANDARD\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_close(IntPtr db);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_create_function(IntPtr db, byte[] strName, int nArgs, int nType, IntPtr pvUser, SQLiteCallback func, SQLiteCallback fstep, SQLiteFinalCallback ffinal);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_finalize(IntPtr stmt);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_open_v2(byte[] utf8Filename, out IntPtr db, int flags, IntPtr vfs);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]\r
+#else\r
+    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]\r
+#endif\r
+    internal static extern int sqlite3_open16(string fileName, out IntPtr db);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_reset(IntPtr stmt);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_bind_parameter_name(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_database_name(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_database_name16(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_decltype(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_decltype16(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_name(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_name16(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_origin_name(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_origin_name16(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_table_name(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_table_name16(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_text(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_text16(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_errmsg(IntPtr db);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_prepare(IntPtr db, IntPtr pSql, int nBytes, out IntPtr stmt, out IntPtr ptrRemain);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_table_column_metadata(IntPtr db, byte[] dbName, byte[] tblName, byte[] colName, out IntPtr ptrDataType, out IntPtr ptrCollSeq, out int notNull, out int primaryKey, out int autoInc);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_value_text(IntPtr p);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_value_text16(IntPtr p);\r
+#endif\r
+\r
+    #endregion\r
+\r
+    // These functions are custom and have no equivalent standard library method.\r
+    // All of them are "nice to haves" and not necessarily "need to haves".\r
+    #region no equivalent standard method\r
+\r
+#if !SQLITE_STANDARD\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern IntPtr sqlite3_context_collseq(IntPtr context, out int type, out int enc, out int len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_context_collcompare(IntPtr context, byte[] p1, int p1len, byte[] p2, int p2len);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_cursor_rowid(IntPtr stmt, int cursor, out long rowid);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_index_column_info_interop(IntPtr db, byte[] catalog, byte[] IndexName, byte[] ColumnName, out int sortOrder, out int onError, out IntPtr Collation, out int colllen);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern void sqlite3_resetall_interop(IntPtr db);\r
+\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_table_cursor(IntPtr stmt, int db, int tableRootPage);\r
+#endif\r
+\r
+    #endregion\r
+\r
+    // These are obsolete and will be removed in the future \r
+    #region windows ntfs filesystem only\r
+\r
+#if !SQLITE_STANDARD\r
+    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]\r
+    internal static extern int sqlite3_compressfile(string fileName);\r
+\r
+    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]\r
+    internal static extern int sqlite3_decompressfile(string fileName);\r
+#endif\r
+\r
+    #endregion\r
+\r
+    // Standard API calls global across versions.  There are a few instances of interop calls\r
+    // scattered in here, but they are only active when PLATFORM_COMPACTFRAMEWORK is declared.\r
+    #region standard sqlite api calls\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_libversion();\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern void sqlite3_interrupt(IntPtr db);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_changes(IntPtr db);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_busy_timeout(IntPtr db, int ms);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_bind_blob(IntPtr stmt, int index, Byte[] value, int nSize, IntPtr nTransient);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+    internal static extern int sqlite3_bind_double(IntPtr stmt, int index, double value);\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_bind_double_interop(IntPtr stmt, int index, ref double value);\r
+#endif\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_bind_int(IntPtr stmt, int index, int value);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+    internal static extern int sqlite3_bind_int64(IntPtr stmt, int index, long value);\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern int sqlite3_bind_int64_interop(IntPtr stmt, int index, ref long value);\r
+#endif\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_bind_null(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_bind_text(IntPtr stmt, int index, byte[] value, int nlen, IntPtr pvReserved);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_bind_parameter_count(IntPtr stmt);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_bind_parameter_index(IntPtr stmt, byte[] strName);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_column_count(IntPtr stmt);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_step(IntPtr stmt);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+    internal static extern double sqlite3_column_double(IntPtr stmt, int index);\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern void sqlite3_column_double_interop(IntPtr stmt, int index, out double value);\r
+#endif\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_column_int(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+    internal static extern long sqlite3_column_int64(IntPtr stmt, int index);\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern void sqlite3_column_int64_interop(IntPtr stmt, int index, out long value);\r
+#endif\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_column_blob(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_column_bytes(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern TypeAffinity sqlite3_column_type(IntPtr stmt, int index);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_create_collation(IntPtr db, byte[] strName, int nType, IntPtr pvUser, SQLiteCollation func);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_aggregate_count(IntPtr context);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_value_blob(IntPtr p);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_value_bytes(IntPtr p);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+    internal static extern double sqlite3_value_double(IntPtr p);\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern void sqlite3_value_double_interop(IntPtr p, out double value);\r
+#endif\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_value_int(IntPtr p);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+    internal static extern long sqlite3_value_int64(IntPtr p);\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern void sqlite3_value_int64_interop(IntPtr p, out Int64 value);\r
+#endif\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern TypeAffinity sqlite3_value_type(IntPtr p);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern void sqlite3_result_blob(IntPtr context, byte[] value, int nSize, IntPtr pvReserved);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+    internal static extern void sqlite3_result_double(IntPtr context, double value);\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern void sqlite3_result_double_interop(IntPtr context, ref double value);\r
+#endif\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern void sqlite3_result_error(IntPtr context, byte[] strErr, int nLen);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern void sqlite3_result_int(IntPtr context, int value);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+    internal static extern void sqlite3_result_int64(IntPtr context, long value);\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+    internal static extern void sqlite3_result_int64_interop(IntPtr context, ref Int64 value);\r
+#endif\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern void sqlite3_result_null(IntPtr context);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern void sqlite3_result_text(IntPtr context, byte[] value, int nLen, IntPtr pvReserved);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_aggregate_context(IntPtr context, int nBytes);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]\r
+#else\r
+    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]\r
+#endif\r
+    internal static extern int sqlite3_bind_text16(IntPtr stmt, int index, string value, int nlen, IntPtr pvReserved);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]\r
+#else\r
+    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]\r
+#endif\r
+    internal static extern void sqlite3_result_error16(IntPtr context, string strName, int nLen);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]\r
+#else\r
+    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]\r
+#endif\r
+    internal static extern void sqlite3_result_text16(IntPtr context, string strName, int nLen, IntPtr pvReserved);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_key(IntPtr db, byte[] key, int keylen);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_rekey(IntPtr db, byte[] key, int keylen);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_update_hook(IntPtr db, SQLiteUpdateCallback func, IntPtr pvUser);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_commit_hook(IntPtr db, SQLiteCommitCallback func, IntPtr pvUser);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_rollback_hook(IntPtr db, SQLiteRollbackCallback func, IntPtr pvUser);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_db_handle(IntPtr stmt);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern IntPtr sqlite3_next_stmt(IntPtr db, IntPtr stmt);\r
+\r
+#if !PLATFORM_COMPACTFRAMEWORK\r
+    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]\r
+#else\r
+    [DllImport(SQLITE_DLL)]\r
+#endif\r
+    internal static extern int sqlite3_exec(IntPtr db, byte[] strSql, IntPtr pvCallback, IntPtr pvParam, out IntPtr errMsg);\r
+\r
+    #endregion\r
+  }\r
+\r
+#if PLATFORM_COMPACTFRAMEWORK\r
+  internal abstract class CriticalHandle : IDisposable\r
+  {\r
+    private bool _isClosed;\r
+    protected IntPtr handle;\r
+    \r
+    protected CriticalHandle(IntPtr invalidHandleValue)\r
+    {\r
+      handle = invalidHandleValue;\r
+      _isClosed = false;\r
+    }\r
+\r
+    ~CriticalHandle()\r
+    {\r
+      Dispose(false);\r
+    }\r
+\r
+    private void Cleanup()\r
+    {\r
+      if (!IsClosed)\r
+      {\r
+        this._isClosed = true;\r
+        if (!IsInvalid)\r
+        {\r
+          ReleaseHandle();\r
+          GC.SuppressFinalize(this);\r
+        }\r
+      }\r
+    }\r
+\r
+    public void Close()\r
+    {\r
+      Dispose(true);\r
+    }\r
+\r
+    public void Dispose()\r
+    {\r
+      Dispose(true);\r
+    }\r
+\r
+    protected virtual void Dispose(bool disposing)\r
+    {\r
+      Cleanup();\r
+    }\r
+\r
+    protected abstract bool ReleaseHandle();\r
+\r
+    protected void SetHandle(IntPtr value)\r
+    {\r
+      handle = value;\r
+    }\r
+\r
+    public void SetHandleAsInvalid()\r
+    {\r
+      _isClosed = true;\r
+      GC.SuppressFinalize(this);\r
+    }\r
+\r
+    public bool IsClosed\r
+    {\r
+      get { return _isClosed; }\r
+    }\r
+\r
+    public abstract bool IsInvalid\r
+    {\r
+      get;\r
+    }\r
+\r
+  }\r
+\r
+#endif\r
+\r
+  // Handles the unmanaged database pointer, and provides finalization support for it.\r
+  internal class SQLiteConnectionHandle : CriticalHandle\r
+  {\r
+    public static implicit operator IntPtr(SQLiteConnectionHandle db)\r
+    {\r
+      return db.handle;\r
+    }\r
+\r
+    public static implicit operator SQLiteConnectionHandle(IntPtr db)\r
+    {\r
+      return new SQLiteConnectionHandle(db);\r
+    }\r
+\r
+    private SQLiteConnectionHandle(IntPtr db)\r
+      : this()\r
+    {\r
+      SetHandle(db);\r
+    }\r
+\r
+    internal SQLiteConnectionHandle()\r
+      : base(IntPtr.Zero)\r
+    {\r
+    }\r
+\r
+    protected override bool ReleaseHandle()\r
+    {\r
+      try\r
+      {\r
+        SQLiteBase.CloseConnection(this);\r
+      }\r
+      catch (SQLiteException)\r
+      {\r
+      }\r
+      return true;\r
+    }\r
+\r
+    public override bool IsInvalid\r
+    {\r
+      get { return (handle == IntPtr.Zero); }\r
+    }\r
+  }\r
+\r
+  // Provides finalization support for unmanaged SQLite statements.\r
+  internal class SQLiteStatementHandle : CriticalHandle\r
+  {\r
+    public static implicit operator IntPtr(SQLiteStatementHandle stmt)\r
+    {\r
+      return stmt.handle;\r
+    }\r
+\r
+    public static implicit operator SQLiteStatementHandle(IntPtr stmt)\r
+    {\r
+      return new SQLiteStatementHandle(stmt);\r
+    }\r
+\r
+    private SQLiteStatementHandle(IntPtr stmt)\r
+      : this()\r
+    {\r
+      SetHandle(stmt);\r
+    }\r
+\r
+    internal SQLiteStatementHandle()\r
+      : base(IntPtr.Zero)\r
+    {\r
+    }\r
+\r
+    protected override bool ReleaseHandle()\r
+    {\r
+      try\r
+      {\r
+        SQLiteBase.FinalizeStatement(this);\r
+      }\r
+      catch (SQLiteException)\r
+      {\r
+      }\r
+      return true;\r
+    }\r
+\r
+    public override bool IsInvalid\r
+    {\r
+      get { return (handle == IntPtr.Zero); }\r
+    }\r
+  }\r
+}\r
index d66dc5e12b41e7b2b0ce8e5d711cadd4bbee59e2..c7d96ca62412e67e50299091ca3b9b455eaac42b 100644 (file)
-<?xml version="1.0" standalone="yes"?>
-<DocumentElement>
-  <DataTypes>
-    <TypeName>smallint</TypeName>
-    <ProviderDbType>10</ProviderDbType>
-    <ColumnSize>5</ColumnSize>
-    <DataType>System.Int16</DataType>
-    <CreateFormat>smallint</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>int</TypeName>
-    <ProviderDbType>11</ProviderDbType>
-    <ColumnSize>10</ColumnSize>
-    <DataType>System.Int32</DataType>
-    <CreateFormat>int</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>real</TypeName>
-    <ProviderDbType>15</ProviderDbType>
-    <ColumnSize>7</ColumnSize>
-    <DataType>System.Single</DataType>
-    <CreateFormat>real</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>float</TypeName>
-    <ProviderDbType>8</ProviderDbType>
-    <ColumnSize>6</ColumnSize>
-    <DataType>System.Double</DataType>
-    <CreateFormat>float</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>double</TypeName>
-    <ProviderDbType>8</ProviderDbType>
-    <ColumnSize>6</ColumnSize>
-    <DataType>System.Double</DataType>
-    <CreateFormat>double</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>money</TypeName>
-    <ProviderDbType>7</ProviderDbType>
-    <ColumnSize>19</ColumnSize>
-    <DataType>System.Decimal</DataType>
-    <CreateFormat>money</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>currency</TypeName>
-    <ProviderDbType>7</ProviderDbType>
-    <ColumnSize>19</ColumnSize>
-    <DataType>System.Decimal</DataType>
-    <CreateFormat>currency</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>decimal</TypeName>
-    <ProviderDbType>7</ProviderDbType>
-    <ColumnSize>19</ColumnSize>
-    <DataType>System.Decimal</DataType>
-    <CreateFormat>decimal</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>numeric</TypeName>
-    <ProviderDbType>7</ProviderDbType>
-    <ColumnSize>19</ColumnSize>
-    <DataType>System.Decimal</DataType>
-    <CreateFormat>numeric</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>bit</TypeName>
-    <ProviderDbType>3</ProviderDbType>
-    <ColumnSize>1</ColumnSize>
-    <DataType>System.Boolean</DataType>
-    <CreateFormat>bit</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>yesno</TypeName>
-    <ProviderDbType>3</ProviderDbType>
-    <ColumnSize>1</ColumnSize>
-    <DataType>System.Boolean</DataType>
-    <CreateFormat>yesno</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>logical</TypeName>
-    <ProviderDbType>3</ProviderDbType>
-    <ColumnSize>1</ColumnSize>
-    <DataType>System.Boolean</DataType>
-    <CreateFormat>logical</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>bool</TypeName>
-    <ProviderDbType>3</ProviderDbType>
-    <ColumnSize>1</ColumnSize>
-    <DataType>System.Boolean</DataType>
-    <CreateFormat>bool</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>tinyint</TypeName>
-    <ProviderDbType>2</ProviderDbType>
-    <ColumnSize>3</ColumnSize>
-    <DataType>System.Byte</DataType>
-    <CreateFormat>tinyint</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>true</IsUnsigned>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>integer</TypeName>
-    <ProviderDbType>12</ProviderDbType>
-    <ColumnSize>19</ColumnSize>
-    <DataType>System.Int64</DataType>
-    <CreateFormat>integer</CreateFormat>
-    <IsAutoIncrementable>true</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>counter</TypeName>
-    <ProviderDbType>12</ProviderDbType>
-    <ColumnSize>19</ColumnSize>
-    <DataType>System.Int64</DataType>
-    <CreateFormat>counter</CreateFormat>
-    <IsAutoIncrementable>true</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>autoincrement</TypeName>
-    <ProviderDbType>12</ProviderDbType>
-    <ColumnSize>19</ColumnSize>
-    <DataType>System.Int64</DataType>
-    <CreateFormat>autoincrement</CreateFormat>
-    <IsAutoIncrementable>true</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>identity</TypeName>
-    <ProviderDbType>12</ProviderDbType>
-    <ColumnSize>19</ColumnSize>
-    <DataType>System.Int64</DataType>
-    <CreateFormat>identity</CreateFormat>
-    <IsAutoIncrementable>true</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>long</TypeName>
-    <ProviderDbType>12</ProviderDbType>
-    <ColumnSize>19</ColumnSize>
-    <DataType>System.Int64</DataType>
-    <CreateFormat>long</CreateFormat>
-    <IsAutoIncrementable>true</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>bigint</TypeName>
-    <ProviderDbType>12</ProviderDbType>
-    <ColumnSize>19</ColumnSize>
-    <DataType>System.Int64</DataType>
-    <CreateFormat>bigint</CreateFormat>
-    <IsAutoIncrementable>true</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <IsUnsigned>false</IsUnsigned>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>binary</TypeName>
-    <ProviderDbType>1</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <DataType>System.Byte[]</DataType>
-    <CreateFormat>binary</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>true</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>false</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <LiteralPrefix>X'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>varbinary</TypeName>
-    <ProviderDbType>1</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <DataType>System.Byte[]</DataType>
-    <CreateFormat>varbinary</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>true</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>false</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <LiteralPrefix>X'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>blob</TypeName>
-    <ProviderDbType>1</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <DataType>System.Byte[]</DataType>
-    <CreateFormat>blob</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>true</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>false</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <LiteralPrefix>X'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>image</TypeName>
-    <ProviderDbType>1</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <DataType>System.Byte[]</DataType>
-    <CreateFormat>image</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>true</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>false</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <LiteralPrefix>X'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>general</TypeName>
-    <ProviderDbType>1</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <DataType>System.Byte[]</DataType>
-    <CreateFormat>general</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>true</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>false</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <LiteralPrefix>X'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>oleobject</TypeName>
-    <ProviderDbType>1</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <DataType>System.Byte[]</DataType>
-    <CreateFormat>oleobject</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>true</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>false</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <LiteralPrefix>X'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>varchar</TypeName>
-    <ProviderDbType>16</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <CreateParameters>max length</CreateParameters>
-    <DataType>System.String</DataType>
-    <CreateFormat>varchar({0})</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>nvarchar</TypeName>
-    <ProviderDbType>16</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <CreateParameters>max length</CreateParameters>
-    <DataType>System.String</DataType>
-    <CreateFormat>nvarchar({0})</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>memo</TypeName>
-    <ProviderDbType>16</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <CreateParameters>max length</CreateParameters>
-    <DataType>System.String</DataType>
-    <CreateFormat>memo({0})</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>note</TypeName>
-    <ProviderDbType>16</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <CreateParameters>max length</CreateParameters>
-    <DataType>System.String</DataType>
-    <CreateFormat>note({0})</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>text</TypeName>
-    <ProviderDbType>16</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <CreateParameters>max length</CreateParameters>
-    <DataType>System.String</DataType>
-    <CreateFormat>text({0})</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>ntext</TypeName>
-    <ProviderDbType>16</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <CreateParameters>max length</CreateParameters>
-    <DataType>System.String</DataType>
-    <CreateFormat>ntext({0})</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>string</TypeName>
-    <ProviderDbType>16</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <CreateParameters>max length</CreateParameters>
-    <DataType>System.String</DataType>
-    <CreateFormat>string({0})</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>char</TypeName>
-    <ProviderDbType>16</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <CreateParameters>max length</CreateParameters>
-    <DataType>System.String</DataType>
-    <CreateFormat>char({0})</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>nchar</TypeName>
-    <ProviderDbType>16</ProviderDbType>
-    <ColumnSize>2147483647</ColumnSize>
-    <CreateParameters>max length</CreateParameters>
-    <DataType>System.String</DataType>
-    <CreateFormat>char({0})</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>false</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>datetime</TypeName>
-    <ProviderDbType>6</ProviderDbType>
-    <ColumnSize>23</ColumnSize>
-    <DataType>System.DateTime</DataType>
-    <CreateFormat>datetime</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>timestamp</TypeName>
-    <ProviderDbType>6</ProviderDbType>
-    <ColumnSize>23</ColumnSize>
-    <DataType>System.DateTime</DataType>
-    <CreateFormat>timestamp</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>date</TypeName>
-    <ProviderDbType>6</ProviderDbType>
-    <ColumnSize>23</ColumnSize>
-    <DataType>System.DateTime</DataType>
-    <CreateFormat>date</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>time</TypeName>
-    <ProviderDbType>6</ProviderDbType>
-    <ColumnSize>23</ColumnSize>
-    <DataType>System.DateTime</DataType>
-    <CreateFormat>time</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>true</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>uniqueidentifier</TypeName>
-    <ProviderDbType>4</ProviderDbType>
-    <ColumnSize>16</ColumnSize>
-    <DataType>System.Guid</DataType>
-    <CreateFormat>uniqueidentifier</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>true</IsBestMatch>
-  </DataTypes>
-  <DataTypes>
-    <TypeName>guid</TypeName>
-    <ProviderDbType>4</ProviderDbType>
-    <ColumnSize>16</ColumnSize>
-    <DataType>System.Guid</DataType>
-    <CreateFormat>guid</CreateFormat>
-    <IsAutoIncrementable>false</IsAutoIncrementable>
-    <IsCaseSensitive>false</IsCaseSensitive>
-    <IsFixedLength>true</IsFixedLength>
-    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
-    <IsLong>false</IsLong>
-    <IsNullable>true</IsNullable>
-    <IsSearchable>true</IsSearchable>
-    <IsSearchableWithLike>false</IsSearchableWithLike>
-    <LiteralPrefix>'</LiteralPrefix>
-    <LiteralSuffix>'</LiteralSuffix>
-    <IsBestMatch>false</IsBestMatch>
-  </DataTypes>
-</DocumentElement>
+<?xml version="1.0" standalone="yes"?>\r
+<DocumentElement>\r
+  <DataTypes>\r
+    <TypeName>smallint</TypeName>\r
+    <ProviderDbType>10</ProviderDbType>\r
+    <ColumnSize>5</ColumnSize>\r
+    <DataType>System.Int16</DataType>\r
+    <CreateFormat>smallint</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>int</TypeName>\r
+    <ProviderDbType>11</ProviderDbType>\r
+    <ColumnSize>10</ColumnSize>\r
+    <DataType>System.Int32</DataType>\r
+    <CreateFormat>int</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>real</TypeName>\r
+    <ProviderDbType>15</ProviderDbType>\r
+    <ColumnSize>7</ColumnSize>\r
+    <DataType>System.Single</DataType>\r
+    <CreateFormat>real</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>float</TypeName>\r
+    <ProviderDbType>8</ProviderDbType>\r
+    <ColumnSize>6</ColumnSize>\r
+    <DataType>System.Double</DataType>\r
+    <CreateFormat>float</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>double</TypeName>\r
+    <ProviderDbType>8</ProviderDbType>\r
+    <ColumnSize>6</ColumnSize>\r
+    <DataType>System.Double</DataType>\r
+    <CreateFormat>double</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>money</TypeName>\r
+    <ProviderDbType>7</ProviderDbType>\r
+    <ColumnSize>19</ColumnSize>\r
+    <DataType>System.Decimal</DataType>\r
+    <CreateFormat>money</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>currency</TypeName>\r
+    <ProviderDbType>7</ProviderDbType>\r
+    <ColumnSize>19</ColumnSize>\r
+    <DataType>System.Decimal</DataType>\r
+    <CreateFormat>currency</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>decimal</TypeName>\r
+    <ProviderDbType>7</ProviderDbType>\r
+    <ColumnSize>19</ColumnSize>\r
+    <DataType>System.Decimal</DataType>\r
+    <CreateFormat>decimal</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>numeric</TypeName>\r
+    <ProviderDbType>7</ProviderDbType>\r
+    <ColumnSize>19</ColumnSize>\r
+    <DataType>System.Decimal</DataType>\r
+    <CreateFormat>numeric</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>bit</TypeName>\r
+    <ProviderDbType>3</ProviderDbType>\r
+    <ColumnSize>1</ColumnSize>\r
+    <DataType>System.Boolean</DataType>\r
+    <CreateFormat>bit</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>yesno</TypeName>\r
+    <ProviderDbType>3</ProviderDbType>\r
+    <ColumnSize>1</ColumnSize>\r
+    <DataType>System.Boolean</DataType>\r
+    <CreateFormat>yesno</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>logical</TypeName>\r
+    <ProviderDbType>3</ProviderDbType>\r
+    <ColumnSize>1</ColumnSize>\r
+    <DataType>System.Boolean</DataType>\r
+    <CreateFormat>logical</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>bool</TypeName>\r
+    <ProviderDbType>3</ProviderDbType>\r
+    <ColumnSize>1</ColumnSize>\r
+    <DataType>System.Boolean</DataType>\r
+    <CreateFormat>bool</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>boolean</TypeName>\r
+    <ProviderDbType>3</ProviderDbType>\r
+    <ColumnSize>1</ColumnSize>\r
+    <DataType>System.Boolean</DataType>\r
+    <CreateFormat>boolean</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>tinyint</TypeName>\r
+    <ProviderDbType>2</ProviderDbType>\r
+    <ColumnSize>3</ColumnSize>\r
+    <DataType>System.Byte</DataType>\r
+    <CreateFormat>tinyint</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>true</IsUnsigned>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>integer</TypeName>\r
+    <ProviderDbType>12</ProviderDbType>\r
+    <ColumnSize>19</ColumnSize>\r
+    <DataType>System.Int64</DataType>\r
+    <CreateFormat>integer</CreateFormat>\r
+    <IsAutoIncrementable>true</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>counter</TypeName>\r
+    <ProviderDbType>12</ProviderDbType>\r
+    <ColumnSize>19</ColumnSize>\r
+    <DataType>System.Int64</DataType>\r
+    <CreateFormat>counter</CreateFormat>\r
+    <IsAutoIncrementable>true</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>autoincrement</TypeName>\r
+    <ProviderDbType>12</ProviderDbType>\r
+    <ColumnSize>19</ColumnSize>\r
+    <DataType>System.Int64</DataType>\r
+    <CreateFormat>autoincrement</CreateFormat>\r
+    <IsAutoIncrementable>true</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>identity</TypeName>\r
+    <ProviderDbType>12</ProviderDbType>\r
+    <ColumnSize>19</ColumnSize>\r
+    <DataType>System.Int64</DataType>\r
+    <CreateFormat>identity</CreateFormat>\r
+    <IsAutoIncrementable>true</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>long</TypeName>\r
+    <ProviderDbType>12</ProviderDbType>\r
+    <ColumnSize>19</ColumnSize>\r
+    <DataType>System.Int64</DataType>\r
+    <CreateFormat>long</CreateFormat>\r
+    <IsAutoIncrementable>true</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>bigint</TypeName>\r
+    <ProviderDbType>12</ProviderDbType>\r
+    <ColumnSize>19</ColumnSize>\r
+    <DataType>System.Int64</DataType>\r
+    <CreateFormat>bigint</CreateFormat>\r
+    <IsAutoIncrementable>true</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <IsUnsigned>false</IsUnsigned>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>binary</TypeName>\r
+    <ProviderDbType>1</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <DataType>System.Byte[]</DataType>\r
+    <CreateFormat>binary</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>false</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <LiteralPrefix>X'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>varbinary</TypeName>\r
+    <ProviderDbType>1</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <DataType>System.Byte[]</DataType>\r
+    <CreateFormat>varbinary</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>false</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <LiteralPrefix>X'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>blob</TypeName>\r
+    <ProviderDbType>1</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <DataType>System.Byte[]</DataType>\r
+    <CreateFormat>blob</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>false</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <LiteralPrefix>X'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>image</TypeName>\r
+    <ProviderDbType>1</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <DataType>System.Byte[]</DataType>\r
+    <CreateFormat>image</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>false</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <LiteralPrefix>X'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>general</TypeName>\r
+    <ProviderDbType>1</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <DataType>System.Byte[]</DataType>\r
+    <CreateFormat>general</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>false</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <LiteralPrefix>X'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>oleobject</TypeName>\r
+    <ProviderDbType>1</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <DataType>System.Byte[]</DataType>\r
+    <CreateFormat>oleobject</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>false</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <LiteralPrefix>X'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>varchar</TypeName>\r
+    <ProviderDbType>16</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <CreateParameters>max length</CreateParameters>\r
+    <DataType>System.String</DataType>\r
+    <CreateFormat>varchar({0})</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>nvarchar</TypeName>\r
+    <ProviderDbType>16</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <CreateParameters>max length</CreateParameters>\r
+    <DataType>System.String</DataType>\r
+    <CreateFormat>nvarchar({0})</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>memo</TypeName>\r
+    <ProviderDbType>16</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <CreateParameters>max length</CreateParameters>\r
+    <DataType>System.String</DataType>\r
+    <CreateFormat>memo({0})</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>longtext</TypeName>\r
+    <ProviderDbType>16</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <CreateParameters>max length</CreateParameters>\r
+    <DataType>System.String</DataType>\r
+    <CreateFormat>longtext({0})</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>note</TypeName>\r
+    <ProviderDbType>16</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <CreateParameters>max length</CreateParameters>\r
+    <DataType>System.String</DataType>\r
+    <CreateFormat>note({0})</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>text</TypeName>\r
+    <ProviderDbType>16</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <CreateParameters>max length</CreateParameters>\r
+    <DataType>System.String</DataType>\r
+    <CreateFormat>text({0})</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>ntext</TypeName>\r
+    <ProviderDbType>16</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <CreateParameters>max length</CreateParameters>\r
+    <DataType>System.String</DataType>\r
+    <CreateFormat>ntext({0})</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>string</TypeName>\r
+    <ProviderDbType>16</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <CreateParameters>max length</CreateParameters>\r
+    <DataType>System.String</DataType>\r
+    <CreateFormat>string({0})</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>char</TypeName>\r
+    <ProviderDbType>16</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <CreateParameters>max length</CreateParameters>\r
+    <DataType>System.String</DataType>\r
+    <CreateFormat>char({0})</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>nchar</TypeName>\r
+    <ProviderDbType>16</ProviderDbType>\r
+    <ColumnSize>2147483647</ColumnSize>\r
+    <CreateParameters>max length</CreateParameters>\r
+    <DataType>System.String</DataType>\r
+    <CreateFormat>char({0})</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>false</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>datetime</TypeName>\r
+    <ProviderDbType>6</ProviderDbType>\r
+    <ColumnSize>23</ColumnSize>\r
+    <DataType>System.DateTime</DataType>\r
+    <CreateFormat>datetime</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>smalldate</TypeName>\r
+    <ProviderDbType>6</ProviderDbType>\r
+    <ColumnSize>23</ColumnSize>\r
+    <DataType>System.DateTime</DataType>\r
+    <CreateFormat>smalldate</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>timestamp</TypeName>\r
+    <ProviderDbType>6</ProviderDbType>\r
+    <ColumnSize>23</ColumnSize>\r
+    <DataType>System.DateTime</DataType>\r
+    <CreateFormat>timestamp</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>date</TypeName>\r
+    <ProviderDbType>6</ProviderDbType>\r
+    <ColumnSize>23</ColumnSize>\r
+    <DataType>System.DateTime</DataType>\r
+    <CreateFormat>date</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>time</TypeName>\r
+    <ProviderDbType>6</ProviderDbType>\r
+    <ColumnSize>23</ColumnSize>\r
+    <DataType>System.DateTime</DataType>\r
+    <CreateFormat>time</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>true</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>uniqueidentifier</TypeName>\r
+    <ProviderDbType>4</ProviderDbType>\r
+    <ColumnSize>16</ColumnSize>\r
+    <DataType>System.Guid</DataType>\r
+    <CreateFormat>uniqueidentifier</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>true</IsBestMatch>\r
+  </DataTypes>\r
+  <DataTypes>\r
+    <TypeName>guid</TypeName>\r
+    <ProviderDbType>4</ProviderDbType>\r
+    <ColumnSize>16</ColumnSize>\r
+    <DataType>System.Guid</DataType>\r
+    <CreateFormat>guid</CreateFormat>\r
+    <IsAutoIncrementable>false</IsAutoIncrementable>\r
+    <IsCaseSensitive>false</IsCaseSensitive>\r
+    <IsFixedLength>true</IsFixedLength>\r
+    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>\r
+    <IsLong>false</IsLong>\r
+    <IsNullable>true</IsNullable>\r
+    <IsSearchable>true</IsSearchable>\r
+    <IsSearchableWithLike>false</IsSearchableWithLike>\r
+    <LiteralPrefix>'</LiteralPrefix>\r
+    <LiteralSuffix>'</LiteralSuffix>\r
+    <IsBestMatch>false</IsBestMatch>\r
+  </DataTypes>\r
+</DocumentElement>\r
index 5fd386e532a8e1a18a6f901cb1e693c452f27efb..f4239ed9b8db48d3bae536930a2c62ffb757cdad 100644 (file)
@@ -1,63 +1,68 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<DocumentElement>
-  <MetaDataCollections>
-    <CollectionName>MetaDataCollections</CollectionName>
-    <NumberOfRestrictions>0</NumberOfRestrictions>
-    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>
-  </MetaDataCollections>
-  <MetaDataCollections>
-    <CollectionName>DataSourceInformation</CollectionName>
-    <NumberOfRestrictions>0</NumberOfRestrictions>
-    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>
-  </MetaDataCollections>
-  <MetaDataCollections>
-    <CollectionName>DataTypes</CollectionName>
-    <NumberOfRestrictions>0</NumberOfRestrictions>
-    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>
-  </MetaDataCollections>
-  <MetaDataCollections>
-    <CollectionName>ReservedWords</CollectionName>
-    <NumberOfRestrictions>0</NumberOfRestrictions>
-    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>
-  </MetaDataCollections>
-  <MetaDataCollections>
-    <CollectionName>Catalogs</CollectionName>
-    <NumberOfRestrictions>1</NumberOfRestrictions>
-    <NumberOfIdentifierParts>1</NumberOfIdentifierParts>
-  </MetaDataCollections>
-  <MetaDataCollections>
-    <CollectionName>Columns</CollectionName>
-    <NumberOfRestrictions>4</NumberOfRestrictions>
-    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>
-  </MetaDataCollections>
-  <MetaDataCollections>
-    <CollectionName>Indexes</CollectionName>
-    <NumberOfRestrictions>5</NumberOfRestrictions>
-    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>
-  </MetaDataCollections>
-  <MetaDataCollections>
-    <CollectionName>IndexColumns</CollectionName>
-    <NumberOfRestrictions>5</NumberOfRestrictions>
-    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>
-  </MetaDataCollections>
-  <MetaDataCollections>
-    <CollectionName>Tables</CollectionName>
-    <NumberOfRestrictions>4</NumberOfRestrictions>
-    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>
-  </MetaDataCollections>
-  <MetaDataCollections>
-    <CollectionName>Views</CollectionName>
-    <NumberOfRestrictions>3</NumberOfRestrictions>
-    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>
-  </MetaDataCollections>
-  <MetaDataCollections>
-    <CollectionName>ViewColumns</CollectionName>
-    <NumberOfRestrictions>4</NumberOfRestrictions>
-    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>
-  </MetaDataCollections>
-  <MetaDataCollections>
-    <CollectionName>ForeignKeys</CollectionName>
-    <NumberOfRestrictions>4</NumberOfRestrictions>
-    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>
-  </MetaDataCollections>
-</DocumentElement>
+<?xml version="1.0" encoding="utf-8" ?>\r
+<DocumentElement>\r
+  <MetaDataCollections>\r
+    <CollectionName>MetaDataCollections</CollectionName>\r
+    <NumberOfRestrictions>0</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>DataSourceInformation</CollectionName>\r
+    <NumberOfRestrictions>0</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>DataTypes</CollectionName>\r
+    <NumberOfRestrictions>0</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>ReservedWords</CollectionName>\r
+    <NumberOfRestrictions>0</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>Catalogs</CollectionName>\r
+    <NumberOfRestrictions>1</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>1</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>Columns</CollectionName>\r
+    <NumberOfRestrictions>4</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>Indexes</CollectionName>\r
+    <NumberOfRestrictions>4</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>IndexColumns</CollectionName>\r
+    <NumberOfRestrictions>5</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>Tables</CollectionName>\r
+    <NumberOfRestrictions>4</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>Views</CollectionName>\r
+    <NumberOfRestrictions>3</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>ViewColumns</CollectionName>\r
+    <NumberOfRestrictions>4</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>ForeignKeys</CollectionName>\r
+    <NumberOfRestrictions>4</NumberOfRestrictions>\r
+    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>\r
+  </MetaDataCollections>\r
+  <MetaDataCollections>\r
+    <CollectionName>Triggers</CollectionName>\r
+    <NumberOfRestrictions>4</NumberOfRestrictions>\r
+    <NumberOfIndentifierParts>3</NumberOfIndentifierParts>\r
+  </MetaDataCollections>\r
+</DocumentElement>\r
diff --git a/mcs/class/Mono.Data.Sqlite/resources/SQLiteCommand.bmp b/mcs/class/Mono.Data.Sqlite/resources/SQLiteCommand.bmp
new file mode 100644 (file)
index 0000000..13dbda0
Binary files /dev/null and b/mcs/class/Mono.Data.Sqlite/resources/SQLiteCommand.bmp differ
diff --git a/mcs/class/Mono.Data.Sqlite/resources/SQLiteConnection.bmp b/mcs/class/Mono.Data.Sqlite/resources/SQLiteConnection.bmp
new file mode 100644 (file)
index 0000000..f787a2d
Binary files /dev/null and b/mcs/class/Mono.Data.Sqlite/resources/SQLiteConnection.bmp differ
diff --git a/mcs/class/Mono.Data.Sqlite/resources/SQLiteDataAdapter.bmp b/mcs/class/Mono.Data.Sqlite/resources/SQLiteDataAdapter.bmp
new file mode 100644 (file)
index 0000000..27186a0
Binary files /dev/null and b/mcs/class/Mono.Data.Sqlite/resources/SQLiteDataAdapter.bmp differ
index 1d8938749a55fc558194b7545809e57b02c8f2b8..054892995fe66abc5d811d454cf600326999c6bd 100644 (file)
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
-  <data name="DataTypes" type="System.Resources.ResXFileRef, System.Windows.Forms">
-    <value>resources/DataTypes.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
-  </data>
-  <data name="Keywords" xml:space="preserve">
-    <value>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</value>
-  </data>
-  <data name="MetaDataCollections" type="System.Resources.ResXFileRef, System.Windows.Forms">
-    <value>resources/MetaDataCollections.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
-  </data>
+<?xml version="1.0" encoding="utf-8"?>\r
+<root>\r
+  <!-- \r
+    Microsoft ResX Schema \r
+    \r
+    Version 2.0\r
+    \r
+    The primary goals of this format is to allow a simple XML format \r
+    that is mostly human readable. The generation and parsing of the \r
+    various data types are done through the TypeConverter classes \r
+    associated with the data types.\r
+    \r
+    Example:\r
+    \r
+    ... ado.net/XML headers & schema ...\r
+    <resheader name="resmimetype">text/microsoft-resx</resheader>\r
+    <resheader name="version">2.0</resheader>\r
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>\r
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>\r
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">\r
+        <value>[base64 mime encoded serialized .NET Framework object]</value>\r
+    </data>\r
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">\r
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r
+        <comment>This is a comment</comment>\r
+    </data>\r
+                \r
+    There are any number of "resheader" rows that contain simple \r
+    name/value pairs.\r
+    \r
+    Each data row contains a name, and value. The row also contains a \r
+    type or mimetype. Type corresponds to a .NET class that support \r
+    text/value conversion through the TypeConverter architecture. \r
+    Classes that don't support this are serialized and stored with the \r
+    mimetype set.\r
+    \r
+    The mimetype is used for serialized objects, and tells the \r
+    ResXResourceReader how to depersist the object. This is currently not \r
+    extensible. For a given mimetype the value must be set accordingly:\r
+    \r
+    Note - application/x-microsoft.net.object.binary.base64 is the format \r
+    that the ResXResourceWriter will generate, however the reader can \r
+    read any of the formats listed below.\r
+    \r
+    mimetype: application/x-microsoft.net.object.binary.base64\r
+    value   : The object must be serialized with \r
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r
+            : and then encoded with base64 encoding.\r
+    \r
+    mimetype: application/x-microsoft.net.object.soap.base64\r
+    value   : The object must be serialized with \r
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r
+            : and then encoded with base64 encoding.\r
+\r
+    mimetype: application/x-microsoft.net.object.bytearray.base64\r
+    value   : The object must be serialized into a byte array \r
+            : using a System.ComponentModel.TypeConverter\r
+            : and then encoded with base64 encoding.\r
+    -->\r
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">\r
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />\r
+    <xsd:element name="root" msdata:IsDataSet="true">\r
+      <xsd:complexType>\r
+        <xsd:choice maxOccurs="unbounded">\r
+          <xsd:element name="metadata">\r
+            <xsd:complexType>\r
+              <xsd:sequence>\r
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />\r
+              </xsd:sequence>\r
+              <xsd:attribute name="name" use="required" type="xsd:string" />\r
+              <xsd:attribute name="type" type="xsd:string" />\r
+              <xsd:attribute name="mimetype" type="xsd:string" />\r
+              <xsd:attribute ref="xml:space" />\r
+            </xsd:complexType>\r
+          </xsd:element>\r
+          <xsd:element name="assembly">\r
+            <xsd:complexType>\r
+              <xsd:attribute name="alias" type="xsd:string" />\r
+              <xsd:attribute name="name" type="xsd:string" />\r
+            </xsd:complexType>\r
+          </xsd:element>\r
+          <xsd:element name="data">\r
+            <xsd:complexType>\r
+              <xsd:sequence>\r
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />\r
+              </xsd:sequence>\r
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />\r
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />\r
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />\r
+              <xsd:attribute ref="xml:space" />\r
+            </xsd:complexType>\r
+          </xsd:element>\r
+          <xsd:element name="resheader">\r
+            <xsd:complexType>\r
+              <xsd:sequence>\r
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+              </xsd:sequence>\r
+              <xsd:attribute name="name" type="xsd:string" use="required" />\r
+            </xsd:complexType>\r
+          </xsd:element>\r
+        </xsd:choice>\r
+      </xsd:complexType>\r
+    </xsd:element>\r
+  </xsd:schema>\r
+  <resheader name="resmimetype">\r
+    <value>text/microsoft-resx</value>\r
+  </resheader>\r
+  <resheader name="version">\r
+    <value>2.0</value>\r
+  </resheader>\r
+  <resheader name="reader">\r
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+  </resheader>\r
+  <resheader name="writer">\r
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+  </resheader>\r
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />\r
+  <data name="DataTypes" type="System.Resources.ResXFileRef, System.Windows.Forms">\r
+    <value>datatypes.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>\r
+  </data>\r
+  <data name="Keywords" xml:space="preserve">\r
+    <value>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</value>\r
+  </data>\r
+  <data name="MetaDataCollections" type="System.Resources.ResXFileRef, System.Windows.Forms">\r
+    <value>metadatacollections.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>\r
+  </data>\r
 </root>
\ No newline at end of file