/// <summary> /// Turn a datatable into a table in the temporary database for the connection /// </summary> /// <param name="cnn">The connection to make the temporary table in</param> /// <param name="table">The table to write out</param> /// <param name="dest">The temporary table name to write to</param> private void DataTableToTable(SQLiteConnection cnn, DataTable table, string dest) { StringBuilder sql = new StringBuilder(); SQLiteCommandBuilder builder = new SQLiteCommandBuilder(); using (SQLiteCommand cmd = cnn.CreateCommand()) using (DataTable source = new DataTable()) { sql.AppendFormat(CultureInfo.InvariantCulture, "CREATE TEMP TABLE {0} (", builder.QuoteIdentifier(dest)); string separator = String.Empty; SQLiteConnectionFlags flags = cnn.Flags; foreach (DataColumn dc in table.Columns) { DbType dbtypeName = SQLiteConvert.TypeToDbType(dc.DataType); string typeName = SQLiteConvert.DbTypeToTypeName(dbtypeName, flags); sql.AppendFormat(CultureInfo.InvariantCulture, "{2}{0} {1} COLLATE NOCASE", builder.QuoteIdentifier(dc.ColumnName), typeName, separator); separator = ", "; } sql.Append(")"); cmd.CommandText = sql.ToString(); cmd.ExecuteNonQuery(); cmd.CommandText = String.Format("SELECT * FROM TEMP.{0} WHERE 1=2", builder.QuoteIdentifier(dest)); using (SQLiteDataAdapter adp = new SQLiteDataAdapter(cmd)) { builder.DataAdapter = adp; adp.Fill(source); foreach (DataRow row in table.Rows) { object[] arr = row.ItemArray; source.Rows.Add(arr); } adp.Update(source); } } }
/// <summary> /// Invokes the parameter binding callback configured for the database /// type name associated with the specified column. If no parameter /// binding callback is available for the database type name, do /// nothing. /// </summary> /// <param name="index"> /// The index of the column being read. /// </param> /// <param name="parameter"> /// The <see cref="SQLiteParameter" /> instance being bound to the /// command. /// </param> /// <param name="complete"> /// Non-zero if the default handling for the parameter binding call /// should be skipped (i.e. the parameter should not be bound at all). /// Great care should be used when setting this to non-zero. /// </param> private void InvokeBindValueCallback( int index, SQLiteParameter parameter, out bool complete ) { complete = false; SQLiteConnectionFlags oldFlags = _flags; _flags &= ~SQLiteConnectionFlags.UseConnectionBindValueCallbacks; try { if (parameter == null) { return; } SQLiteConnection connection = GetConnection(this); if (connection == null) { return; } // // NOTE: First, always look for an explicitly set database type // name. // string typeName = parameter.TypeName; if (typeName == null) { // // NOTE: Are we allowed to fallback to using the parameter name // as the basis for looking up the binding callback? // if (HelperMethods.HasFlags( _flags, SQLiteConnectionFlags.UseParameterNameForTypeName)) { typeName = parameter.ParameterName; } } if (typeName == null) { // // NOTE: Are we allowed to fallback to using the database type // name translated from the DbType as the basis for looking // up the binding callback? // if (HelperMethods.HasFlags( _flags, SQLiteConnectionFlags.UseParameterDbTypeForTypeName)) { typeName = SQLiteConvert.DbTypeToTypeName( connection, parameter.DbType, _flags); } } if (typeName == null) { return; } SQLiteTypeCallbacks callbacks; if (!connection.TryGetTypeCallbacks(typeName, out callbacks) || (callbacks == null)) { return; } SQLiteBindValueCallback callback = callbacks.BindValueCallback; if (callback == null) { return; } object userData = callbacks.BindValueUserData; callback( _sql, _command, oldFlags, parameter, typeName, index, userData, out complete); /* throw */ } finally { _flags |= SQLiteConnectionFlags.UseConnectionBindValueCallbacks; } }