Index: System.Data.SQLite/SQLiteConnection.cs ================================================================== --- System.Data.SQLite/SQLiteConnection.cs +++ System.Data.SQLite/SQLiteConnection.cs @@ -3775,11 +3775,11 @@ 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["UNIQUE"] = SQLiteConvert.ToBoolean(rd.GetValue(2), CultureInfo.InvariantCulture, false); row["PRIMARY_KEY"] = false; // get the index definition 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)) using (SQLiteDataReader rdIndexes = cmdIndexes.ExecuteReader()) Index: System.Data.SQLite/SQLiteConvert.cs ================================================================== --- System.Data.SQLite/SQLiteConvert.cs +++ System.Data.SQLite/SQLiteConvert.cs @@ -778,10 +778,84 @@ if (convertible != null) return convertible.ToString(provider); return obj.ToString(); /* not IConvertible */ } + + /// + /// Attempts to convert an arbitrary object to the Boolean data type. + /// Null object values are converted to false. Throws an exception + /// upon failure. + /// + /// + /// The object value to convert. + /// + /// + /// The format provider to use. + /// + /// + /// If non-zero, a string value will be converted using the + /// + /// method; otherwise, the + /// method will be used. + /// + /// + /// The converted boolean value. + /// + internal static bool ToBoolean( + object obj, + IFormatProvider provider, + bool viaFramework + ) + { + if (obj == null) + return false; + + TypeCode typeCode = Type.GetTypeCode(obj.GetType()); + + switch (typeCode) + { + case TypeCode.Empty: + case TypeCode.DBNull: + return false; + case TypeCode.Boolean: + return (bool)obj; + case TypeCode.Char: + return ((char)obj) != (char)0 ? true : false; + case TypeCode.SByte: + return ((sbyte)obj) != (sbyte)0 ? true : false; + case TypeCode.Byte: + return ((byte)obj) != (byte)0 ? true : false; + case TypeCode.Int16: + return ((short)obj) != (short)0 ? true : false; + case TypeCode.UInt16: + return ((ushort)obj) != (ushort)0 ? true : false; + case TypeCode.Int32: + return ((int)obj) != (int)0 ? true : false; + case TypeCode.UInt32: + return ((uint)obj) != (uint)0 ? true : false; + case TypeCode.Int64: + return ((long)obj) != (long)0 ? true : false; + case TypeCode.UInt64: + return ((ulong)obj) != (ulong)0 ? true : false; + case TypeCode.Single: + return ((float)obj) != (float)0.0 ? true : false; + case TypeCode.Double: + return ((double)obj) != (double)0.0 ? true : false; + case TypeCode.Decimal: + return ((decimal)obj) != Decimal.Zero ? true : false; + case TypeCode.String: + return viaFramework ? + Convert.ToBoolean(obj, provider) : + ToBoolean(ToStringWithProvider(obj, provider)); + default: + throw new SQLiteException(String.Format( + CultureInfo.CurrentCulture, + "Cannot convert type {0} to boolean", + typeCode)); + } + } /// /// Convert a value to true or false. /// /// A string or number representing true or false Index: System.Data.SQLite/SQLiteStatement.cs ================================================================== --- System.Data.SQLite/SQLiteStatement.cs +++ System.Data.SQLite/SQLiteStatement.cs @@ -227,66 +227,10 @@ { BindParameter(n + 1, _paramValues[n]); } } - /// - /// Attempts to convert an arbitrary object to the Boolean data type. - /// Null object values are converted to false. Throws a SQLiteException - /// upon failure. - /// - /// The object value to convert. - /// The format provider to use. - /// The converted boolean value. - private static bool ToBoolean(object obj, IFormatProvider provider) - { - if (obj == null) - return false; - - TypeCode typeCode = Type.GetTypeCode(obj.GetType()); - - switch (typeCode) - { - case TypeCode.Empty: - case TypeCode.DBNull: - return false; - case TypeCode.Boolean: - return (bool)obj; - case TypeCode.Char: - return ((char)obj) != (char)0 ? true : false; - case TypeCode.SByte: - return ((sbyte)obj) != (sbyte)0 ? true : false; - case TypeCode.Byte: - return ((byte)obj) != (byte)0 ? true : false; - case TypeCode.Int16: - return ((short)obj) != (short)0 ? true : false; - case TypeCode.UInt16: - return ((ushort)obj) != (ushort)0 ? true : false; - case TypeCode.Int32: - return ((int)obj) != (int)0 ? true : false; - case TypeCode.UInt32: - return ((uint)obj) != (uint)0 ? true : false; - case TypeCode.Int64: - return ((long)obj) != (long)0 ? true : false; - case TypeCode.UInt64: - return ((ulong)obj) != (ulong)0 ? true : false; - case TypeCode.Single: - return ((float)obj) != (float)0.0 ? true : false; - case TypeCode.Double: - return ((double)obj) != (double)0.0 ? true : false; - case TypeCode.Decimal: - return ((decimal)obj) != Decimal.Zero ? true : false; - case TypeCode.String: - return Convert.ToBoolean(obj, provider); - default: - throw new SQLiteException(String.Format( - CultureInfo.CurrentCulture, - "Cannot convert type {0} to boolean", - typeCode)); - } - } - /// /// Perform the bind operation for an individual parameter /// /// The index of the parameter to bind /// The parameter we're binding @@ -352,11 +296,11 @@ // _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj, cultureInfo)); _sql.Bind_DateTime(this, _flags, index, (obj is string) ? _sql.ToDateTime((string)obj) : Convert.ToDateTime(obj, cultureInfo)); break; case DbType.Boolean: - _sql.Bind_Int32(this, _flags, index, ToBoolean(obj, cultureInfo) ? 1 : 0); + _sql.Bind_Int32(this, _flags, index, SQLiteConvert.ToBoolean(obj, cultureInfo, true) ? 1 : 0); break; case DbType.SByte: _sql.Bind_Int32(this, _flags, index, Convert.ToSByte(obj, cultureInfo)); break; case DbType.Int16: Index: Tests/tkt-3c00ec5b52.eagle ================================================================== --- Tests/tkt-3c00ec5b52.eagle +++ Tests/tkt-3c00ec5b52.eagle @@ -56,11 +56,11 @@ } } ############################################################################### -runTest {test tkt-3c00ec5b52-1.1 {per-connection default types} -setup { +runTest {test tkt-3c00ec5b52-1.1 {default types, via connection} -setup { setupDb [set fileName tkt-3c00ec5b52-1.1.db] "" "" "" UseConnectionTypes \ "DefaultDbType=String;DefaultTypeName=TEXT;" } -body { set connection [getDbConnection] set result [list] @@ -84,11 +84,11 @@ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {String TEXT}} ############################################################################### -runTest {test tkt-3c00ec5b52-1.2 {per-connection default types} -setup { +runTest {test tkt-3c00ec5b52-1.2 {fallback default types w/flag} -setup { setupDb [set fileName tkt-3c00ec5b52-1.2.db] "" "" "" UseConnectionTypes } -body { set connection [getDbConnection] set result [list] @@ -111,11 +111,11 @@ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {Object {}}} ############################################################################### -runTest {test tkt-3c00ec5b52-1.3 {per-connection default types} -setup { +runTest {test tkt-3c00ec5b52-1.3 {fallback default types w/o flag} -setup { setupDb [set fileName tkt-3c00ec5b52-1.3.db] } -body { set connection [getDbConnection] set result [list] @@ -138,11 +138,11 @@ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {Object {}}} ############################################################################### -runTest {test tkt-3c00ec5b52-1.4 {per-connection default types} -setup { +runTest {test tkt-3c00ec5b52-1.4 {default types, via environment} -setup { saveSQLiteConvertEnvironment set env(Use_SQLiteConvert_DefaultDbType) String set env(Use_SQLiteConvert_DefaultTypeName) TEXT @@ -168,10 +168,45 @@ unset -nocomplain db fileName savedEnv } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {String TEXT}} + +############################################################################### + +runTest {test tkt-3c00ec5b52-1.5 {default types, with unique index} -setup { + saveSQLiteConvertEnvironment + + set env(Use_SQLiteConvert_DefaultDbType) String + set env(Use_SQLiteConvert_DefaultTypeName) TEXT + + setupDb [set fileName tkt-3c00ec5b52-1.5.db] +} -body { + sql execute $db "CREATE TABLE t1(x UNIQUE);" + + set connection [getDbConnection] + set dataTable [$connection -alias GetSchema INDEXES] + set results [list] + + object foreach -alias dataRow [set dataRows [$dataTable -alias Rows]] { + lappend results [list [$dataRow Item TABLE_NAME] \ + [$dataRow Item INDEX_NAME] [$dataRow Item UNIQUE]] + } + + set results +} -cleanup { + freeDbConnection + + unset -nocomplain results dataRow dataRows dataTable connection + + cleanupDb $fileName + restoreSQLiteConvertEnvironment + + unset -nocomplain db fileName savedEnv +} -constraints \ +{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ +{{t1 sqlite_autoindex_t1_1 True}}} ############################################################################### rename restoreSQLiteConvertEnvironment "" rename saveSQLiteConvertEnvironment ""