-//
-// 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)
- {
- return Marshal.PtrToStringAuto (nativestring);
- }
-
-
- #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 Mono.Data.Sqlite\r
+{\r
+ using System;\r
+ using System.Data;\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
+ /// The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC).\r
+ /// </summary>\r
+ protected static readonly DateTime UnixEpoch =\r
+ new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);\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
+ case SQLiteDateFormats.UnixEpoch:\r
+ return UnixEpoch.AddSeconds(Convert.ToInt32(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
+ case SQLiteDateFormats.UnixEpoch:\r
+ return ((long)(dateValue.Subtract(UnixEpoch).Ticks / TimeSpan.TicksPerSecond)).ToString();\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, _typeNames[n].typeName, 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("BOOLEAN", 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("GUIDBLOB", 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
+ new SQLiteTypeNames("TIMESTAMP", DbType.DateTime),\r
+ new SQLiteTypeNames("DATETIME", DbType.DateTime),\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
+ /// <summary>\r
+ /// The whole number of seconds since the Unix epoch (January 1, 1970).\r
+ /// </summary>\r
+ UnixEpoch = 3,\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