System.Data.SQLite
Check-in [5b282efc5f]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a FormatException in the SQLiteConnection.Schema_Indexes method when the default type has been changed to String. Pursuant to [3c00ec5b52].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5b282efc5fd0118c9b78c50d80d560dbff792a22
User & Date: mistachkin 2014-05-15 23:44:22
References
2014-05-15
23:44 Ticket [3c00ec5b52] Columns without defined type are not identified as text status still Pending with 4 other changes artifact: f934850d88 user: mistachkin
Context
2014-05-20
23:38
Fix bug in documentation generator automation that prevented some internal documentation links from working. check-in: 531ddfa82a user: mistachkin tags: trunk
2014-05-18
06:57
Add experimental MapTextToAffinity connection flag to permit automatic attempts to map textual column values onto values with an appropriate type affinity. check-in: f5dd5dcfde user: mistachkin tags: tkt-3c00ec5b52
2014-05-17
01:33
For the System.Data.SQLite.EF6 assembly, rename the IsStoreGenerated metadata column in the SSDL to IsServerGenerated. Pursuant to [3c00ec5b52]. check-in: 7a7ec7f341 user: mistachkin tags: mistake
2014-05-15
23:44
Fix a FormatException in the SQLiteConnection.Schema_Indexes method when the default type has been changed to String. Pursuant to [3c00ec5b52]. check-in: 5b282efc5f user: mistachkin tags: trunk
18:58
Fix a usage inconsistency where Convert.ToBoolean was being called instead of SQLiteConvert.ToBoolean. check-in: 4ea6f54d61 user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to System.Data.SQLite/SQLiteConnection.cs.

  3773   3773                     {
  3774   3774                       row = tbl.NewRow();
  3775   3775   
  3776   3776                       row["TABLE_CATALOG"] = strCatalog;
  3777   3777                       row["TABLE_NAME"] = rdTables.GetString(2);
  3778   3778                       row["INDEX_CATALOG"] = strCatalog;
  3779   3779                       row["INDEX_NAME"] = rd.GetString(1);
  3780         -                    row["UNIQUE"] = rd.GetBoolean(2);
         3780  +                    row["UNIQUE"] = SQLiteConvert.ToBoolean(rd.GetValue(2), CultureInfo.InvariantCulture, false);
  3781   3781                       row["PRIMARY_KEY"] = false;
  3782   3782   
  3783   3783                       // get the index definition
  3784   3784                       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))
  3785   3785                       using (SQLiteDataReader rdIndexes = cmdIndexes.ExecuteReader())
  3786   3786                       {
  3787   3787                         while (rdIndexes.Read())

Changes to System.Data.SQLite/SQLiteConvert.cs.

   776    776           IConvertible convertible = obj as IConvertible;
   777    777   
   778    778           if (convertible != null)
   779    779               return convertible.ToString(provider);
   780    780   
   781    781           return obj.ToString(); /* not IConvertible */
   782    782       }
          783  +
          784  +    /// <summary>
          785  +    /// Attempts to convert an arbitrary object to the Boolean data type.
          786  +    /// Null object values are converted to false.  Throws an exception
          787  +    /// upon failure.
          788  +    /// </summary>
          789  +    /// <param name="obj">
          790  +    /// The object value to convert.
          791  +    /// </param>
          792  +    /// <param name="provider">
          793  +    /// The format provider to use.
          794  +    /// </param>
          795  +    /// <param name="viaFramework">
          796  +    /// If non-zero, a string value will be converted using the
          797  +    /// <see cref="Convert.ToBoolean(Object, IFormatProvider)" />
          798  +    /// method; otherwise, the <see cref="ToBoolean(String)" />
          799  +    /// method will be used.
          800  +    /// </param>
          801  +    /// <returns>
          802  +    /// The converted boolean value.
          803  +    /// </returns>
          804  +    internal static bool ToBoolean(
          805  +        object obj,
          806  +        IFormatProvider provider,
          807  +        bool viaFramework
          808  +        )
          809  +    {
          810  +        if (obj == null)
          811  +            return false;
          812  +
          813  +        TypeCode typeCode = Type.GetTypeCode(obj.GetType());
          814  +
          815  +        switch (typeCode)
          816  +        {
          817  +            case TypeCode.Empty:
          818  +            case TypeCode.DBNull:
          819  +                return false;
          820  +            case TypeCode.Boolean:
          821  +                return (bool)obj;
          822  +            case TypeCode.Char:
          823  +                return ((char)obj) != (char)0 ? true : false;
          824  +            case TypeCode.SByte:
          825  +                return ((sbyte)obj) != (sbyte)0 ? true : false;
          826  +            case TypeCode.Byte:
          827  +                return ((byte)obj) != (byte)0 ? true : false;
          828  +            case TypeCode.Int16:
          829  +                return ((short)obj) != (short)0 ? true : false;
          830  +            case TypeCode.UInt16:
          831  +                return ((ushort)obj) != (ushort)0 ? true : false;
          832  +            case TypeCode.Int32:
          833  +                return ((int)obj) != (int)0 ? true : false;
          834  +            case TypeCode.UInt32:
          835  +                return ((uint)obj) != (uint)0 ? true : false;
          836  +            case TypeCode.Int64:
          837  +                return ((long)obj) != (long)0 ? true : false;
          838  +            case TypeCode.UInt64:
          839  +                return ((ulong)obj) != (ulong)0 ? true : false;
          840  +            case TypeCode.Single:
          841  +                return ((float)obj) != (float)0.0 ? true : false;
          842  +            case TypeCode.Double:
          843  +                return ((double)obj) != (double)0.0 ? true : false;
          844  +            case TypeCode.Decimal:
          845  +                return ((decimal)obj) != Decimal.Zero ? true : false;
          846  +            case TypeCode.String:
          847  +                return viaFramework ?
          848  +                    Convert.ToBoolean(obj, provider) :
          849  +                    ToBoolean(ToStringWithProvider(obj, provider));
          850  +            default:
          851  +                throw new SQLiteException(String.Format(
          852  +                    CultureInfo.CurrentCulture,
          853  +                    "Cannot convert type {0} to boolean",
          854  +                    typeCode));
          855  +        }
          856  +    }
   783    857   
   784    858       /// <summary>
   785    859       /// Convert a value to true or false.
   786    860       /// </summary>
   787    861       /// <param name="source">A string or number representing true or false</param>
   788    862       /// <returns></returns>
   789    863       public static bool ToBoolean(object source)

Changes to System.Data.SQLite/SQLiteStatement.cs.

   225    225         int x = _paramNames.Length;
   226    226         for (int n = 0; n < x; n++)
   227    227         {
   228    228           BindParameter(n + 1, _paramValues[n]);
   229    229         }
   230    230       }
   231    231   
   232         -    /// <summary>
   233         -    /// Attempts to convert an arbitrary object to the Boolean data type.
   234         -    /// Null object values are converted to false.  Throws a SQLiteException
   235         -    /// upon failure.
   236         -    /// </summary>
   237         -    /// <param name="obj">The object value to convert.</param>
   238         -    /// <param name="provider">The format provider to use.</param>
   239         -    /// <returns>The converted boolean value.</returns>
   240         -    private static bool ToBoolean(object obj, IFormatProvider provider)
   241         -    {
   242         -        if (obj == null)
   243         -            return false;
   244         -
   245         -        TypeCode typeCode = Type.GetTypeCode(obj.GetType());
   246         -
   247         -        switch (typeCode)
   248         -        {
   249         -            case TypeCode.Empty:
   250         -            case TypeCode.DBNull:
   251         -                return false;
   252         -            case TypeCode.Boolean:
   253         -                return (bool)obj;
   254         -            case TypeCode.Char:
   255         -                return ((char)obj) != (char)0 ? true : false;
   256         -            case TypeCode.SByte:
   257         -                return ((sbyte)obj) != (sbyte)0 ? true : false;
   258         -            case TypeCode.Byte:
   259         -                return ((byte)obj) != (byte)0 ? true : false;
   260         -            case TypeCode.Int16:
   261         -                return ((short)obj) != (short)0 ? true : false;
   262         -            case TypeCode.UInt16:
   263         -                return ((ushort)obj) != (ushort)0 ? true : false;
   264         -            case TypeCode.Int32:
   265         -                return ((int)obj) != (int)0 ? true : false;
   266         -            case TypeCode.UInt32:
   267         -                return ((uint)obj) != (uint)0 ? true : false;
   268         -            case TypeCode.Int64:
   269         -                return ((long)obj) != (long)0 ? true : false;
   270         -            case TypeCode.UInt64:
   271         -                return ((ulong)obj) != (ulong)0 ? true : false;
   272         -            case TypeCode.Single:
   273         -                return ((float)obj) != (float)0.0 ? true : false;
   274         -            case TypeCode.Double:
   275         -                return ((double)obj) != (double)0.0 ? true : false;
   276         -            case TypeCode.Decimal:
   277         -                return ((decimal)obj) != Decimal.Zero ? true : false;
   278         -            case TypeCode.String:
   279         -                return Convert.ToBoolean(obj, provider);
   280         -            default:
   281         -                throw new SQLiteException(String.Format(
   282         -                    CultureInfo.CurrentCulture,
   283         -                    "Cannot convert type {0} to boolean",
   284         -                    typeCode));
   285         -        }
   286         -    }
   287         -
   288    232       /// <summary>
   289    233       /// Perform the bind operation for an individual parameter
   290    234       /// </summary>
   291    235       /// <param name="index">The index of the parameter to bind</param>
   292    236       /// <param name="param">The parameter we're binding</param>
   293    237       private void BindParameter(int index, SQLiteParameter param)
   294    238       {
................................................................................
   350    294             // NOTE: The old method (commented below) does not honor the selected date format
   351    295             //       for the connection.
   352    296             // _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj, cultureInfo));
   353    297               _sql.Bind_DateTime(this, _flags, index, (obj is string) ?
   354    298                 _sql.ToDateTime((string)obj) : Convert.ToDateTime(obj, cultureInfo));
   355    299             break;
   356    300           case DbType.Boolean:
   357         -          _sql.Bind_Int32(this, _flags, index, ToBoolean(obj, cultureInfo) ? 1 : 0);
          301  +          _sql.Bind_Int32(this, _flags, index, SQLiteConvert.ToBoolean(obj, cultureInfo, true) ? 1 : 0);
   358    302             break;
   359    303           case DbType.SByte:
   360    304             _sql.Bind_Int32(this, _flags, index, Convert.ToSByte(obj, cultureInfo));
   361    305             break;
   362    306           case DbType.Int16:
   363    307             _sql.Bind_Int32(this, _flags, index, Convert.ToInt16(obj, cultureInfo));
   364    308             break;

Changes to Tests/tkt-3c00ec5b52.eagle.

    54     54         uplevel 1 [list unset -nocomplain env($name)]
    55     55       }
    56     56     }
    57     57   }
    58     58   
    59     59   ###############################################################################
    60     60   
    61         -runTest {test tkt-3c00ec5b52-1.1 {per-connection default types} -setup {
           61  +runTest {test tkt-3c00ec5b52-1.1 {default types, via connection} -setup {
    62     62     setupDb [set fileName tkt-3c00ec5b52-1.1.db] "" "" "" UseConnectionTypes \
    63     63         "DefaultDbType=String;DefaultTypeName=TEXT;"
    64     64   } -body {
    65     65     set connection [getDbConnection]
    66     66     set result [list]
    67     67   
    68     68     lappend result [object invoke -flags +NonPublic \
................................................................................
    82     82     unset -nocomplain db fileName
    83     83   } -constraints \
    84     84   {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
    85     85   {String TEXT}}
    86     86   
    87     87   ###############################################################################
    88     88   
    89         -runTest {test tkt-3c00ec5b52-1.2 {per-connection default types} -setup {
           89  +runTest {test tkt-3c00ec5b52-1.2 {fallback default types w/flag} -setup {
    90     90     setupDb [set fileName tkt-3c00ec5b52-1.2.db] "" "" "" UseConnectionTypes
    91     91   } -body {
    92     92     set connection [getDbConnection]
    93     93     set result [list]
    94     94   
    95     95     lappend result [object invoke -flags +NonPublic \
    96     96         System.Data.SQLite.SQLiteConvert TypeNameToDbType $connection "" None]
................................................................................
   109    109     unset -nocomplain db fileName
   110    110   } -constraints \
   111    111   {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
   112    112   {Object {}}}
   113    113   
   114    114   ###############################################################################
   115    115   
   116         -runTest {test tkt-3c00ec5b52-1.3 {per-connection default types} -setup {
          116  +runTest {test tkt-3c00ec5b52-1.3 {fallback default types w/o flag} -setup {
   117    117     setupDb [set fileName tkt-3c00ec5b52-1.3.db]
   118    118   } -body {
   119    119     set connection [getDbConnection]
   120    120     set result [list]
   121    121   
   122    122     lappend result [object invoke -flags +NonPublic \
   123    123         System.Data.SQLite.SQLiteConvert TypeNameToDbType $connection "" None]
................................................................................
   136    136     unset -nocomplain db fileName
   137    137   } -constraints \
   138    138   {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
   139    139   {Object {}}}
   140    140   
   141    141   ###############################################################################
   142    142   
   143         -runTest {test tkt-3c00ec5b52-1.4 {per-connection default types} -setup {
          143  +runTest {test tkt-3c00ec5b52-1.4 {default types, via environment} -setup {
   144    144     saveSQLiteConvertEnvironment
   145    145   
   146    146     set env(Use_SQLiteConvert_DefaultDbType) String
   147    147     set env(Use_SQLiteConvert_DefaultTypeName) TEXT
   148    148   
   149    149     setupDb [set fileName tkt-3c00ec5b52-1.4.db]
   150    150   } -body {
................................................................................
   166    166     cleanupDb $fileName
   167    167     restoreSQLiteConvertEnvironment
   168    168   
   169    169     unset -nocomplain db fileName savedEnv
   170    170   } -constraints \
   171    171   {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
   172    172   {String TEXT}}
          173  +
          174  +###############################################################################
          175  +
          176  +runTest {test tkt-3c00ec5b52-1.5 {default types, with unique index} -setup {
          177  +  saveSQLiteConvertEnvironment
          178  +
          179  +  set env(Use_SQLiteConvert_DefaultDbType) String
          180  +  set env(Use_SQLiteConvert_DefaultTypeName) TEXT
          181  +
          182  +  setupDb [set fileName tkt-3c00ec5b52-1.5.db]
          183  +} -body {
          184  +  sql execute $db "CREATE TABLE t1(x UNIQUE);"
          185  +
          186  +  set connection [getDbConnection]
          187  +  set dataTable [$connection -alias GetSchema INDEXES]
          188  +  set results [list]
          189  +
          190  +  object foreach -alias dataRow [set dataRows [$dataTable -alias Rows]] {
          191  +    lappend results [list [$dataRow Item TABLE_NAME] \
          192  +        [$dataRow Item INDEX_NAME] [$dataRow Item UNIQUE]]
          193  +  }
          194  +
          195  +  set results
          196  +} -cleanup {
          197  +  freeDbConnection
          198  +
          199  +  unset -nocomplain results dataRow dataRows dataTable connection
          200  +
          201  +  cleanupDb $fileName
          202  +  restoreSQLiteConvertEnvironment
          203  +
          204  +  unset -nocomplain db fileName savedEnv
          205  +} -constraints \
          206  +{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
          207  +{{t1 sqlite_autoindex_t1_1 True}}}
   173    208   
   174    209   ###############################################################################
   175    210   
   176    211   rename restoreSQLiteConvertEnvironment ""
   177    212   rename saveSQLiteConvertEnvironment ""
   178    213   
   179    214   ###############################################################################
   180    215   
   181    216   runSQLiteTestEpilogue
   182    217   runTestEpilogue