This base class provides datatype conversion services for the SQLite provider.
        /// <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)
        {
            SQLiteType typ;

            // Initialize the field types array if not already initialized
            if (_fieldTypeArray == null)
            {
                _fieldTypeArray = new SQLiteType[VisibleFieldCount];
            }

            // Initialize this column's field type instance
            if (_fieldTypeArray[i] == null)
            {
                _fieldTypeArray[i] = new SQLiteType();
            }

            typ = _fieldTypeArray[i];

            // If not initialized, then fetch the declared column datatype and attempt to convert it
            // to a known DbType.
            if (typ.Affinity == TypeAffinity.Uninitialized)
            {
                typ.Type = SqliteConvert.TypeNameToDbType(_activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity));
            }
            else
            {
                typ.Affinity = _activeStatement._sql.ColumnAffinity(_activeStatement, i);
            }

            return(typ);
        }
        /// <summary>
        /// Parses the connection string into component parts
        /// </summary>
        /// <param name="connectionString">The connection string to parse</param>
        /// <returns>An array of key-value pairs representing each parameter of the connection string</returns>
        internal static Dictionary <string, string> ParseConnectionString(string connectionString)
        {
            string s = connectionString.Replace(',', ';'); // Mono compatibility
            int    n;
            var    ls = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            // 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, ';');

            // For each semi-colon piece, split into key and value pairs by the presence of the = sign
            for (n = 0; n < arParts.Length; n++)
            {
                string[] arPiece = SqliteConvert.Split(arParts[n], '=');
                if (arPiece.Length == 2)
                {
                    MapMonoKeyword(arPiece, ls);
                }
                else
                {
                    string message = String.Format(CultureInfo.CurrentCulture,
                                                   "Invalid ConnectionString format for parameter \"{0}\"",
                                                   arPiece.Length > 0 ? arPiece[0] : "null");
                    throw new ArgumentException(message);
                }
            }
            return(ls);
        }
        /// <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)
        {
            if (i >= VisibleFieldCount && _keyInfo != null)
            {
                return(_keyInfo.GetFieldType(i - VisibleFieldCount));
            }

            return(SqliteConvert.SQLiteTypeToType(GetSQLiteType(i)));
        }
Exemple #4
0
        /// <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]);
        }
Exemple #5
0
        /// <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)
        {
            SQLiteType typ = GetSQLiteType(i);

            if (typ.Type == DbType.Object)
            {
                return(SqliteConvert.SQLiteTypeToType(typ).Name);
            }
            return(_activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity));
        }
 /// <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(_affinitytotype[(int)t.Affinity]);
     }
     else
     {
         return(SqliteConvert.DbTypeToType(t.Type));
     }
 }
        /// <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>
        /// 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)
        {
            if (i >= VisibleFieldCount && _keyInfo != null)
            {
                return(_keyInfo.GetDataTypeName(i - VisibleFieldCount));
            }

            SQLiteType typ = GetSQLiteType(i);

            if (typ.Type == DbType.Object)
            {
                return(SqliteConvert.SQLiteTypeToType(typ).Name);
            }
            return(_activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity));
        }
Exemple #9
0
        /// <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, 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));
            }
        }
        /// <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));
        }
Exemple #11
0
        /// <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);
            }

            // Attempt to coerce the value into something more solid
            if (b)
            {
                if (pd.PropertyType == typeof(Boolean))
                {
                    value = SqliteConvert.ToBoolean(value);
                }
                else
                {
                    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);
        }
        /// <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);
            }

            var pd = _properties[keyword];

            if (pd == null)
            {
                return(b);
            }

            // Attempt to coerce the value into something more solid
            if (b)
            {
                if (pd.PropertyType == typeof(Boolean))
                {
                    value = SqliteConvert.ToBoolean(value);
                }
                else
                {
                    value = Convert.ChangeType(value, pd.PropertyType, CultureInfo.InvariantCulture);
                }
            }
            else
            {
                DefaultValueAttribute att = (DefaultValueAttribute)pd.GetCustomAttributes(typeof(DefaultValueAttribute), true).FirstOrDefault();
                if (att != null)
                {
                    value = att.Value;
                    b     = true;
                }
            }
            return(b);
        }
Exemple #13
0
        /// <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.UInt32:
            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.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: // Dont store decimal as double ... loses precision
                _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;

            case DbType.Decimal: // Dont store decimal as double ... loses precision
                _sql.Bind_Text(this, index, Convert.ToDecimal(obj, CultureInfo.CurrentCulture).ToString(CultureInfo.InvariantCulture));
                break;

            default:
                _sql.Bind_Text(this, index, obj.ToString());
                break;
            }
        }
        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.Columns.Add("CollationType", typeof(string));
            tbl.BeginLoadData();

            for (int n = 0; n < _fieldCount; n++)
            {
                row = tbl.NewRow();

                DbType typ = GetSQLiteType(n).Type;

                // Default settings for the column
                row[SchemaTableColumn.ColumnName]           = GetName(n);
                row[SchemaTableColumn.ColumnOrdinal]        = n;
                row[SchemaTableColumn.ColumnSize]           = SqliteConvert.DbTypeToColumnSize(typ);
                row[SchemaTableColumn.NumericPrecision]     = SqliteConvert.DbTypeToNumericPrecision(typ);
                row[SchemaTableColumn.NumericScale]         = SqliteConvert.DbTypeToNumericScale(typ);
                row[SchemaTableColumn.ProviderType]         = GetSQLiteType(n).Type;
                row[SchemaTableColumn.IsLong]               = false;
                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[SchemaTableColumn.DataType]         = GetFieldType(n);
                row[SchemaTableOptionalColumn.IsHidden] = false;

#if !MONOTOUCH
                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;
                }
#endif

                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;
                    row["CollationType"] = collSeq;

                    // 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"];
                                    }

                                    // If its an integer primary key and the only primary key in the table, then its a rowid alias and is autoincrement
                                    // NOTE:  Currently commented out because this is not always the desired behavior.  For example, a 1:1 relationship with
                                    //        another table, where the other table is autoincrement, but this one is not, and uses the rowid from the other.
                                    //        It is safer to only set Autoincrement on tables where we're SURE the user specified AUTOINCREMENT, even if its a rowid column.

                                    if (tblIndexColumns.Rows.Count == 1 && (bool)rowIndexes["PRIMARY_KEY"] == true && String.IsNullOrEmpty(dataType) == false &&
                                        String.Compare(dataType, "integer", true, CultureInfo.InvariantCulture) == 0)
                                    {
                                        //  row[SchemaTableOptionalColumn.IsAutoIncrement] = true;
                                    }

                                    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 (_keyInfo != null)
            {
                _keyInfo.AppendSchemaTable(tbl);
            }

            tbl.AcceptChanges();
            tbl.EndLoadData();

            return(tbl);
        }
        /// <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();

            Dictionary <string, string> opts = ParseConnectionString(_connectionString);

            if (Convert.ToInt32(FindKey(opts, "Version", "3"), CultureInfo.InvariantCulture) != 3)
            {
                throw new NotSupportedException("Only SQLite Version 3 is supported at this time");
            }

            string fileName = FindKey(opts, "Data Source", "");

            if (String.IsNullOrEmpty(fileName))
            {
                fileName = FindKey(opts, "Uri", "");
                if (String.IsNullOrEmpty(fileName))
                {
                    throw new ArgumentException("Data Source cannot be empty.  Use :memory: to open an in-memory database");
                }

                fileName = MapUriPath(fileName);
            }
            if (String.Compare(fileName, ":MEMORY:", StringComparison.OrdinalIgnoreCase) == 0)
            {
                fileName = ":memory:";
            }
            else
            {
                fileName = this.ExpandFileName(fileName);
            }

            try
            {
                bool usePooling  = SqliteConvert.ToBoolean(FindKey(opts, "Pooling", Boolean.FalseString));
                bool bUTF16      = SqliteConvert.ToBoolean(FindKey(opts, "UseUTF16Encoding", Boolean.FalseString));
                int  maxPoolSize = Convert.ToInt32(FindKey(opts, "Max Pool Size", "100"));

                _defaultTimeout = Convert.ToInt32(FindKey(opts, "Default Timeout", "30"), CultureInfo.CurrentCulture);

                _defaultIsolation =
                    (IsolationLevel)
                    Enum.Parse(typeof(IsolationLevel), FindKey(opts, "Default IsolationLevel", "Serializable"), true);
                if (_defaultIsolation != IsolationLevel.Serializable &&
                    _defaultIsolation != IsolationLevel.ReadCommitted)
                {
                    throw new NotSupportedException("Invalid Default IsolationLevel specified");
                }

                var dateFormat =
                    (SQLiteDateFormats)
                    Enum.Parse(typeof(SQLiteDateFormats), FindKey(opts, "DateTimeFormat", "ISO8601"), true);
                //string temp = FindKey(opts, "DateTimeFormat", "ISO8601");
                //if (String.Compare(temp, "ticks", true, CultureInfo.InvariantCulture) == 0) dateFormat = SQLiteDateFormats.Ticks;
                //else if (String.Compare(temp, "julianday", true, CultureInfo.InvariantCulture) == 0) dateFormat = SQLiteDateFormats.JulianDay;

                // SQLite automatically sets the encoding of the database to UTF16 if called from sqlite3_open16()
                this._sql = bUTF16 ? new SQLite3_UTF16(dateFormat) : new SQLite3(dateFormat);

                SQLiteOpenFlagsEnum flags = SQLiteOpenFlagsEnum.None;
                if (SqliteConvert.ToBoolean(FindKey(opts, "Read Only", Boolean.FalseString)))
                {
                    flags |= SQLiteOpenFlagsEnum.ReadOnly;
                }
                else
                {
                    flags |= SQLiteOpenFlagsEnum.ReadWrite;
                    if (SqliteConvert.ToBoolean(FindKey(opts, "FailIfMissing", Boolean.FalseString)) == false)
                    {
                        flags |= SQLiteOpenFlagsEnum.Create;
                    }
                }
                if (SqliteConvert.ToBoolean(FindKey(opts, "FileProtectionComplete", Boolean.FalseString)))
                {
                    flags |= SQLiteOpenFlagsEnum.FileProtectionComplete;
                }
                if (SqliteConvert.ToBoolean(FindKey(opts, "FileProtectionCompleteUnlessOpen", Boolean.FalseString)))
                {
                    flags |= SQLiteOpenFlagsEnum.FileProtectionCompleteUnlessOpen;
                }
                if (SqliteConvert.ToBoolean(FindKey(opts, "FileProtectionCompleteUntilFirstUserAuthentication", Boolean.FalseString)))
                {
                    flags |= SQLiteOpenFlagsEnum.FileProtectionCompleteUntilFirstUserAuthentication;
                }
                if (SqliteConvert.ToBoolean(FindKey(opts, "FileProtectionNone", Boolean.FalseString)))
                {
                    flags |= SQLiteOpenFlagsEnum.FileProtectionNone;
                }

                _sql.Open(fileName, flags, maxPoolSize, usePooling);

                _binaryGuid = SqliteConvert.ToBoolean(FindKey(opts, "BinaryGUID", Boolean.TrueString));

                string password = FindKey(opts, "Password", null);
                if (String.IsNullOrEmpty(password) == false)
                {
                    _sql.SetPassword(password);
                }
                else if (_password != null)
                {
                    _sql.SetPassword(_password);
                }
                _password = null;

                // TODO : _dataSource = Path.GetFileNameWithoutExtension(fileName);
                _dataSource = fileName;

                OnStateChange(ConnectionState.Open);
                _version++;

                using (SqliteCommand cmd = CreateCommand())
                {
                    string defValue;

                    if (fileName != ":memory:")
                    {
                        defValue = FindKey(opts, "Page Size", "1024");
                        if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 1024)
                        {
                            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA page_size={0}",
                                                            defValue);
                            cmd.ExecuteNonQuery();
                        }
                    }

                    defValue = FindKey(opts, "Max Page Count", "0");
                    if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 0)
                    {
                        cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA max_page_count={0}",
                                                        defValue);
                        cmd.ExecuteNonQuery();
                    }

                    defValue        = FindKey(opts, "Legacy Format", Boolean.FalseString);
                    cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA legacy_file_format={0}",
                                                    SqliteConvert.ToBoolean(defValue) ? "ON" : "OFF");
                    cmd.ExecuteNonQuery();

                    defValue = FindKey(opts, "Synchronous", "Normal");
                    if (String.Compare(defValue, "Full", StringComparison.OrdinalIgnoreCase) != 0)
                    {
                        cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA synchronous={0}", defValue);
                        cmd.ExecuteNonQuery();
                    }

                    defValue = FindKey(opts, "Cache Size", "2000");
                    if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 2000)
                    {
                        cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA cache_size={0}", defValue);
                        cmd.ExecuteNonQuery();
                    }

                    defValue = FindKey(opts, "Journal Mode", "Delete");
                    if (String.Compare(defValue, "Default", StringComparison.OrdinalIgnoreCase) != 0)
                    {
                        cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA journal_mode={0}",
                                                        defValue);
                        cmd.ExecuteNonQuery();
                    }
                }

                if (_commitHandler != null)
                {
                    _sql.SetCommitHook(_commitCallback);
                }

                if (_updateHandler != null)
                {
                    _sql.SetUpdateHook(_updateCallback);
                }

                if (_rollbackHandler != null)
                {
                    _sql.SetRollbackHook(_rollbackCallback);
                }

                if (global::System.Transactions.Transaction.Current != null &&
                    SqliteConvert.ToBoolean(FindKey(opts, "Enlist", Boolean.TrueString)))
                {
                    EnlistTransaction(global::System.Transactions.Transaction.Current);
                }
            }
            catch (SqliteException)
            {
                Close();

                throw;
            }
        }
Exemple #16
0
 /// <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)
 {
     return(SqliteConvert.SQLiteTypeToType(GetSQLiteType(i)));
 }