using System.ComponentModel;
using System.Data;
+using System.Globalization;
using System.Text;
namespace System.Data.Common {
public abstract class DbCommandBuilder : Component
{
- bool _setAllValues = false;
- bool _disposed = false;
+ bool _setAllValues;
+ bool _disposed;
DataTable _dbSchemaTable;
- DbDataAdapter _dbDataAdapter = null;
+ DbDataAdapter _dbDataAdapter;
private CatalogLocation _catalogLocation = CatalogLocation.Start;
private ConflictOption _conflictOption = ConflictOption.CompareAllSearchableValues;
private string _tableName;
- private string _catalogSeperator = ".";
+ private string _catalogSeparator;
private string _quotePrefix;
private string _quoteSuffix;
- private string _schemaSeperator = ".";
- private DbCommand _dbCommand = null;
-
- // Used to construct WHERE clauses
- static readonly string clause1 = "({0} = 1 AND {1} IS NULL)";
- static readonly string clause2 = "({0} = {1})";
+ private string _schemaSeparator;
+ private DbCommand _dbCommand;
DbCommand _deleteCommand;
DbCommand _insertCommand;
DbCommand _updateCommand;
- #region Constructors
+ static readonly string SEPARATOR_DEFAULT = ".";
+ // Used to construct WHERE clauses
+ static readonly string clause1 = "({0} = 1 AND {1} IS NULL)";
+ static readonly string clause2 = "({0} = {1})";
protected DbCommandBuilder ()
{
}
- #endregion // Constructors
-
- #region Properties
-
private void BuildCache (bool closeConnection)
{
DbCommand sourceCommand = SourceCommand;
// If no table was found, then we can't do an delete
if (QuotedTableName == String.Empty)
return null;
-
+
CreateNewCommand (ref _deleteCommand);
string command = String.Format ("DELETE FROM {0}", QuotedTableName);
bool isKey = (bool) schemaRow ["IsKey"];
DbParameter parameter = null;
+ string sourceColumnName;
if (isKey)
keyFound = true;
if (!isKey && allowNull) {
parameter = _deleteCommand.CreateParameter ();
if (option) {
- parameter.ParameterName = String.Format ("@{0}",
+ parameter.ParameterName = String.Format ("@IsNull_{0}",
schemaRow ["BaseColumnName"]);
} else {
parameter.ParameterName = String.Format ("@p{0}", parmIndex++);
}
- String sourceColumnName = (string) schemaRow ["BaseColumnName"];
parameter.Value = 1;
-
+ parameter.DbType = DbType.Int32;
+ // This should be set for nullcheckparam
+ sourceColumnName = (string) schemaRow ["BaseColumnName"];
+ parameter.SourceColumn = sourceColumnName;
+ parameter.SourceColumnNullMapping = true;
+ parameter.SourceVersion = DataRowVersion.Original;
+ _deleteCommand.Parameters.Add (parameter);
+
whereClause.Append ("(");
whereClause.Append (String.Format (clause1, parameter.ParameterName,
GetQuotedString (sourceColumnName)));
whereClause.Append (" OR ");
}
- parameter = CreateParameter (_deleteCommand, String.Format ("@{0}", option ? schemaRow ["BaseColumnName"] : "p" + parmIndex++), schemaRow);
+ if (option)
+ parameter = CreateParameter (_deleteCommand, schemaRow, true);
+ else
+ parameter = CreateParameter (_deleteCommand, parmIndex++, schemaRow);
+
parameter.SourceVersion = DataRowVersion.Original;
+ ApplyParameterInfo (parameter, schemaRow, StatementType.Delete, true);
+ //parameter.IsNullable = allowNull;
whereClause.Append (String.Format (clause2, GetQuotedString (parameter.SourceColumn), parameter.ParameterName));
return _deleteCommand;
}
- private DbCommand CreateInsertCommand (bool option)
+ private DbCommand CreateInsertCommand (bool option, DataRow row)
{
if (QuotedTableName == String.Empty)
return null;
StringBuilder values = new StringBuilder ();
int parmIndex = 1;
+ DbParameter parameter = null;
foreach (DataRow schemaRow in _dbSchemaTable.Rows) {
if (!IncludedInInsert (schemaRow))
continue;
values.Append (", ");
}
- DbParameter parameter = CreateParameter (_insertCommand, String.Format ("@{0}", option ? schemaRow ["BaseColumnName"] : "p" + parmIndex++), schemaRow);
+ if (option)
+ parameter = CreateParameter (_insertCommand, schemaRow, false);
+ else
+ parameter = CreateParameter (_insertCommand, parmIndex++, schemaRow);
parameter.SourceVersion = DataRowVersion.Current;
-
+ ApplyParameterInfo (parameter, schemaRow, StatementType.Insert, false);
+
columns.Append (GetQuotedString (parameter.SourceColumn));
- values.Append (parameter.ParameterName);
+
+ // Workaround for columns that may have a default/bound value and for now,
+ // the framework, don't provide a mechanism to read these values yet
+ // AllowDBNull and DataRow is used to workaround #385028 by using DEFAULT
+ string colName = schemaRow ["ColumnName"] as string;
+ bool allowDBNull = !schemaRow.IsNull ("AllowDBNull") & (bool) schemaRow ["AllowDBNull"];
+ if (!allowDBNull && row != null &&
+ (row [colName] == DBNull.Value || row [colName] == null)) {
+ values.Append ("DEFAULT");
+ } else {
+ values.Append (parameter.ParameterName);
+ }
}
sql = String.Format ("{0} ({1}) VALUES ({2})", command, columns.ToString (), values.ToString ());
StringBuilder whereClause = new StringBuilder ();
int parmIndex = 1;
bool keyFound = false;
+ DbParameter parameter = null;
// First, create the X=Y list for UPDATE
foreach (DataRow schemaRow in _dbSchemaTable.Rows) {
if (columns.Length > 0)
columns.Append (", ");
- DbParameter parameter = CreateParameter (_updateCommand, String.Format ("@{0}", option ? schemaRow ["BaseColumnName"] : "p" + parmIndex++), schemaRow);
+ if (option)
+ parameter = CreateParameter (_updateCommand, schemaRow, false);
+ else
+ parameter = CreateParameter (_updateCommand, parmIndex++, schemaRow);
parameter.SourceVersion = DataRowVersion.Current;
-
+ ApplyParameterInfo (parameter, schemaRow, StatementType.Update, false);
+ //parameter.IsNullable = (bool) schemaRow ["AllowDBNull"];
columns.Append (String.Format ("{0} = {1}", GetQuotedString (parameter.SourceColumn), parameter.ParameterName));
}
whereClause.Append (" AND ");
bool isKey = (bool) schemaRow ["IsKey"];
- DbParameter parameter = null;
-
if (isKey)
keyFound = true;
if (!isKey && allowNull) {
parameter = _updateCommand.CreateParameter ();
if (option) {
- parameter.ParameterName = String.Format ("@{0} IS NULL",
+ parameter.ParameterName = String.Format ("@IsNull_{0}",
schemaRow ["BaseColumnName"]);
} else {
parameter.ParameterName = String.Format ("@p{0}", parmIndex++);
}
+ parameter.DbType = DbType.Int32;
parameter.Value = 1;
+ parameter.SourceColumn = (string) schemaRow ["BaseColumnName"];
+ parameter.SourceColumnNullMapping = true;
+ parameter.SourceVersion = DataRowVersion.Original;
whereClause.Append ("(");
whereClause.Append (String.Format (clause1, parameter.ParameterName,
GetQuotedString ((string) schemaRow ["BaseColumnName"])));
whereClause.Append (" OR ");
+ _updateCommand.Parameters.Add (parameter);
}
if (option)
- parameter = CreateParameter (_updateCommand, String.Format ("@Original_{0}", schemaRow ["BaseColumnName"]), schemaRow);
- else
- parameter = CreateParameter (_updateCommand, String.Format ("@p{0}", parmIndex++), schemaRow);
+ parameter = CreateParameter (_updateCommand, schemaRow, true);
+ else
+ parameter = CreateParameter (_updateCommand, parmIndex++, schemaRow);
parameter.SourceVersion = DataRowVersion.Original;
+ //parameter.IsNullable = allowNull;
+ ApplyParameterInfo (parameter, schemaRow, StatementType.Update, true);
whereClause.Append (String.Format (clause2, GetQuotedString (parameter.SourceColumn), parameter.ParameterName));
return _updateCommand;
}
- private DbParameter CreateParameter (DbCommand _dbCommand, string parameterName, DataRow schemaRow)
+ private DbParameter CreateParameter (DbCommand _dbCommand, DataRow schemaRow, bool whereClause)
{
+ string sourceColumn = (string) schemaRow ["BaseColumnName"];
DbParameter parameter = _dbCommand.CreateParameter ();
- parameter.ParameterName = parameterName;
- parameter.SourceColumn = (string) schemaRow ["BaseColumnName"];
- parameter.Size = (int) schemaRow ["ColumnSize"];
+ if (whereClause)
+ parameter.ParameterName = GetParameterName ("Original_" + sourceColumn);
+ else
+ parameter.ParameterName = GetParameterName (sourceColumn);
+ parameter.SourceColumn = sourceColumn;
+ //parameter.Size = (int) schemaRow ["ColumnSize"];
_dbCommand.Parameters.Add (parameter);
return parameter;
}
+ private DbParameter CreateParameter (DbCommand _dbCommand, int paramIndex, DataRow schemaRow)
+ {
+ string sourceColumn = (string) schemaRow ["BaseColumnName"];
+ DbParameter parameter = _dbCommand.CreateParameter ();
+ parameter.ParameterName = GetParameterName (paramIndex);
+ parameter.SourceColumn = sourceColumn;
+ //parameter.Size = (int) schemaRow ["ColumnSize"];
+ _dbCommand.Parameters.Add (parameter);
+ return parameter;
+ }
+
[DefaultValue (CatalogLocation.Start)]
public virtual CatalogLocation CatalogLocation {
get { return _catalogLocation; }
- set { _catalogLocation = value; }
+ set {
+ CheckEnumValue (typeof (CatalogLocation),
+ (int) value);
+ _catalogLocation = value;
+ }
}
[DefaultValue (".")]
public virtual string CatalogSeparator {
- get { return _catalogSeperator; }
- set { if (value != null) _catalogSeperator = value; }
+ get {
+ if (_catalogSeparator == null || _catalogSeparator.Length == 0)
+ return SEPARATOR_DEFAULT;
+ return _catalogSeparator;
+ }
+ set { _catalogSeparator = value; }
}
[DefaultValue (ConflictOption.CompareAllSearchableValues)]
public virtual ConflictOption ConflictOption {
get { return _conflictOption; }
- set { _conflictOption = value; }
+ set {
+ CheckEnumValue (typeof (ConflictOption),
+ (int) value);
+ _conflictOption = value;
+ }
}
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[Browsable (false)]
public DbDataAdapter DataAdapter {
get { return _dbDataAdapter; }
- set { if (value != null) _dbDataAdapter = value; }
+ set { if (value != null)
+ SetRowUpdatingHandler (value);
+ _dbDataAdapter = value;
+ }
}
[DefaultValue ("")]
[DefaultValue (".")]
public virtual string SchemaSeparator {
- get { return _schemaSeperator; }
- set { if (value != null) _schemaSeperator = value; }
+ get {
+ if (_schemaSeparator == null || _schemaSeparator.Length == 0)
+ return SEPARATOR_DEFAULT;
+ return _schemaSeparator;
+ }
+ set { _schemaSeparator = value; }
}
[DefaultValue (false)]
public bool SetAllValues {
get { return _setAllValues; }
set { _setAllValues = value; }
- }
+ }
private DbCommand SourceCommand {
get {
return null;
}
}
- #endregion // Properties
-
- #region Methods
protected abstract void ApplyParameterInfo (DbParameter parameter,
DataRow row,
public DbCommand GetDeleteCommand ()
{
- BuildCache (true);
- if (_deleteCommand == null)
- return CreateDeleteCommand (false);
- return _deleteCommand;
+ return GetDeleteCommand (false);
}
public DbCommand GetDeleteCommand (bool option)
{
BuildCache (true);
- if (_deleteCommand == null)
+ if (_deleteCommand == null || option)
return CreateDeleteCommand (option);
return _deleteCommand;
}
public DbCommand GetInsertCommand ()
{
- BuildCache (true);
- if (_insertCommand == null)
- return CreateInsertCommand (false);
- return _insertCommand;
+ return GetInsertCommand (false, null);
}
public DbCommand GetInsertCommand (bool option)
+ {
+ return GetInsertCommand (option, null);
+ }
+
+ internal DbCommand GetInsertCommand (bool option, DataRow row)
{
BuildCache (true);
- if (_insertCommand == null)
- return CreateInsertCommand (option);
+ if (_insertCommand == null || option)
+ return CreateInsertCommand (option, row);
return _insertCommand;
}
public DbCommand GetUpdateCommand ()
{
- BuildCache (true);
- if (_updateCommand == null)
- return CreateUpdateCommand (false);
- return _updateCommand;
+ return GetUpdateCommand (false);
}
public DbCommand GetUpdateCommand (bool option)
{
BuildCache (true);
- if (_updateCommand == null)
+ if (_updateCommand == null || option)
return CreateUpdateCommand (option);
return _updateCommand;
}
public virtual string QuoteIdentifier (string unquotedIdentifier)
{
- if (unquotedIdentifier == null) {
- throw new ArgumentNullException("Unquoted identifier parameter cannot be null");
- }
- return String.Format ("{0}{1}{2}", this.QuotePrefix, unquotedIdentifier, this.QuoteSuffix);
+ throw new NotSupportedException ();
}
public virtual string UnquoteIdentifier (string quotedIdentifier)
try {
switch (args.StatementType) {
case StatementType.Insert:
- args.Command = GetInsertCommand ();
+ args.Command = GetInsertCommand (false, args.Row);
break;
case StatementType.Update:
args.Command = GetUpdateCommand ();
return rdr.GetSchemaTable ();
}
- #endregion // Methods
+ static void CheckEnumValue (Type type, int value)
+ {
+ if (Enum.IsDefined (type, value))
+ return;
+
+ string typename = type.Name;
+ string msg = string.Format (CultureInfo.CurrentCulture,
+ "Value {0} is not valid for {1}.", value,
+ typename);
+ throw new ArgumentOutOfRangeException (typename, msg);
+ }
}
}