-//
-// 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
--- /dev/null
+//
+// 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")]
+
--- /dev/null
+/********************************************************\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
--- /dev/null
+/********************************************************\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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
--- /dev/null
+/********************************************************\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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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
-//
-// 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 <?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</ [rest of string was truncated]";.
- /// </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 <?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>
- /// <MetaDataC [rest of string was truncated]";.
- /// </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 <?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</ [rest of string was truncated]";.\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 <?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
+ /// <MetaDataC [rest of string was truncated]";.\r
+ /// </summary>\r
+ internal static string MetaDataCollections {\r
+ get {\r
+ return ResourceManager.GetString("MetaDataCollections", resourceCulture);\r
+ }\r
+ }\r
+ }\r
+}\r
-//
-// 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
-<?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
-<?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
-<?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