Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Morris <cmorris98@me.com>2013-10-11 23:54:49 +0400
committerCraig Morris <cmorris98@me.com>2013-11-27 22:11:11 +0400
commite5a83e68577ad5beb97028c7eead0d5846f42e7c (patch)
treee62f6bd4f63a7a42001dc8ff6f484e8ca153f113 /mcs/class/System.Data
parent24169a083ec528478244880c5b11550bb4197657 (diff)
SqlBulkCopy Implementation
This are the code changes to get the SqlBulkCopy procedure working on mono.
Diffstat (limited to 'mcs/class/System.Data')
-rw-r--r--mcs/class/System.Data/System.Data.SqlClient/SqlBulkCopy.cs145
1 files changed, 98 insertions, 47 deletions
diff --git a/mcs/class/System.Data/System.Data.SqlClient/SqlBulkCopy.cs b/mcs/class/System.Data/System.Data.SqlClient/SqlBulkCopy.cs
index 936e7d9ee8a..110ac095b5c 100644
--- a/mcs/class/System.Data/System.Data.SqlClient/SqlBulkCopy.cs
+++ b/mcs/class/System.Data/System.Data.SqlClient/SqlBulkCopy.cs
@@ -239,6 +239,18 @@ namespace System.Data.SqlClient {
if ((int)row ["ColumnSize"] != -1) {
param.Size = (int) row ["ColumnSize"];
}
+
+ short numericPresision = (short)row ["NumericPrecision"];
+ if (numericPresision != 255) {
+ param.Precision = (byte) numericPresision;
+ }
+
+ short numericScale = (short)row ["NumericScale"];
+ if (numericScale != 255) {
+ param.Scale = (byte) numericScale;
+ }
+
+ param.IsNullable = (bool)row ["AllowDBNull"];
tmpCmd.Parameters.Add (param);
break;
}
@@ -247,6 +259,7 @@ namespace System.Data.SqlClient {
flag = false;
bool insertSt = false;
foreach (DataRow row in colMetaData.Rows) {
+ SqlDbType sqlType = (SqlDbType) row ["ProviderType"];
if (_columnMappingCollection.Count > 0) {
i = 0;
insertSt = false;
@@ -278,21 +291,32 @@ namespace System.Data.SqlClient {
if ((bool)row ["IsReadOnly"]) {
continue;
}
+
+ int columnSize = (int)row ["ColumnSize"];
string columnInfo = "";
- if ((int)row ["ColumnSize"] != -1) {
+
+ if (columnSize >= TdsMetaParameter.maxVarCharCharacters && sqlType == SqlDbType.Text)
+ columnInfo = "VarChar(max)";
+ else if (columnSize >= TdsMetaParameter.maxNVarCharCharacters && sqlType == SqlDbType.NText)
+ columnInfo = "NVarChar(max)";
+ else if (IsTextType(sqlType) && columnSize != -1) {
columnInfo = string.Format ("{0}({1})",
- (SqlDbType) row ["ProviderType"],
- row ["ColumnSize"]);
+ sqlType,
+ columnSize.ToString());
} else {
- columnInfo = string.Format ("{0}", (SqlDbType) row ["ProviderType"]);
+ columnInfo = string.Format ("{0}", sqlType);
}
+
+ if ( sqlType == SqlDbType.Decimal)
+ columnInfo += String.Format("({0},{1})", row ["NumericPrecision"], row ["NumericScale"]);
+
if (flag)
statement += ", ";
string columnName = (string) row ["ColumnName"];
statement += string.Format ("[{0}] {1}", columnName, columnInfo);
if (flag == false)
flag = true;
- if (tableCollations != null) {
+ if (IsTextType(sqlType) && tableCollations != null) {
foreach (DataRow collationRow in tableCollations.Rows) {
if ((string)collationRow ["name"] == columnName) {
statement += string.Format (" COLLATE {0}", collationRow ["collation"]);
@@ -306,41 +330,48 @@ namespace System.Data.SqlClient {
private void ValidateColumnMapping (DataTable table, DataTable tableCollations)
{
- foreach (SqlBulkCopyColumnMapping _columnMapping in _columnMappingCollection) {
- if (ordinalMapping == false &&
- (_columnMapping.DestinationColumn == String.Empty ||
- _columnMapping.SourceColumn == String.Empty))
- throw new InvalidOperationException ("Mappings must be either all null or ordinal");
- if (ordinalMapping &&
- (_columnMapping.DestinationOrdinal == -1 ||
- _columnMapping.SourceOrdinal == -1))
- throw new InvalidOperationException ("Mappings must be either all null or ordinal");
- bool flag = false;
- if (ordinalMapping == false) {
- foreach (DataRow row in tableCollations.Rows) {
- if ((string)row ["name"] == _columnMapping.DestinationColumn) {
- flag = true;
- break;
- }
- }
- if (flag == false)
- throw new InvalidOperationException ("ColumnMapping does not match");
- flag = false;
- foreach (DataColumn col in table.Columns) {
- if (col.ColumnName == _columnMapping.SourceColumn) {
- flag = true;
- break;
- }
- }
- if (flag == false)
- throw new InvalidOperationException ("ColumnName " +
- _columnMapping.SourceColumn +
- " does not match");
- } else {
- if (_columnMapping.DestinationOrdinal >= tableCollations.Rows.Count)
- throw new InvalidOperationException ("ColumnMapping does not match");
- }
- }
+ // So the problem here is that temp tables will not have any table collations. This prevents
+ // us from bulk inserting into temp tables. So for now we will skip the validation and
+ // let SqlServer tell us there is an issue rather than trying to do it here.
+ // So for now we will simply return and do nothing.
+ // TODO: At some point we should remove this function if we all agree its the right thing to do
+ return;
+
+// foreach (SqlBulkCopyColumnMapping _columnMapping in _columnMappingCollection) {
+// if (ordinalMapping == false &&
+// (_columnMapping.DestinationColumn == String.Empty ||
+// _columnMapping.SourceColumn == String.Empty))
+// throw new InvalidOperationException ("Mappings must be either all null or ordinal");
+// if (ordinalMapping &&
+// (_columnMapping.DestinationOrdinal == -1 ||
+// _columnMapping.SourceOrdinal == -1))
+// throw new InvalidOperationException ("Mappings must be either all null or ordinal");
+// bool flag = false;
+// if (ordinalMapping == false) {
+// foreach (DataRow row in tableCollations.Rows) {
+// if ((string)row ["name"] == _columnMapping.DestinationColumn) {
+// flag = true;
+// break;
+// }
+// }
+// if (flag == false)
+// throw new InvalidOperationException ("ColumnMapping does not match");
+// flag = false;
+// foreach (DataColumn col in table.Columns) {
+// if (col.ColumnName == _columnMapping.SourceColumn) {
+// flag = true;
+// break;
+// }
+// }
+// if (flag == false)
+// throw new InvalidOperationException ("ColumnName " +
+// _columnMapping.SourceColumn +
+// " does not match");
+// } else {
+// if (_columnMapping.DestinationOrdinal >= tableCollations.Rows.Count)
+// throw new InvalidOperationException ("ColumnMapping does not match");
+// }
+// }
}
private void BulkCopyToServer (DataTable table, DataRowState state)
@@ -411,7 +442,7 @@ namespace System.Data.SqlClient {
statement += ")";
}
#endregion Check requested options and add corresponding modifiers to the statement
-
+
blkCopy.SendColumnMetaData (statement);
}
blkCopy.BulkCopyStart (tmpCmd.Parameters.MetaParameters);
@@ -439,11 +470,14 @@ namespace System.Data.SqlClient {
rowToCopy = parameter.Value = parameter.ConvertToFrameworkType (rowToCopy);
}
string colType = string.Format ("{0}", parameter.MetaParameter.TypeName);
- if (colType == "nvarchar") {
- if (row [i] != null) {
+ if (colType == "nvarchar" || colType == "ntext" || colType == "nchar") {
+ if (row [i] != null && row [i] != DBNull.Value) {
size = ((string) parameter.Value).Length;
size <<= 1;
}
+ } else if (colType == "varchar" || colType == "text" || colType == "char") {
+ if (row [i] != null && row [i] != DBNull.Value)
+ size = ((string) parameter.Value).Length;
} else {
size = parameter.Size;
}
@@ -461,11 +495,14 @@ namespace System.Data.SqlClient {
rowToCopy = parameter.Value = parameter.ConvertToFrameworkType (rowToCopy);
}
string colType = string.Format ("{0}", parameter.MetaParameter.TypeName);
- if (colType == "nvarchar") {
- if (row [mapping.SourceColumn] != null) {
+ if (colType == "nvarchar" || colType == "ntext" || colType == "nchar") {
+ if (row [mapping.SourceColumn] != null && row [mapping.SourceColumn] != DBNull.Value) {
size = ((string) rowToCopy).Length;
size <<= 1;
}
+ } else if (colType == "varchar" || colType == "text" || colType == "char") {
+ if (row [mapping.SourceColumn] != null && row [mapping.SourceColumn] != DBNull.Value)
+ size = ((string) rowToCopy).Length;
} else {
size = parameter.Size;
}
@@ -481,16 +518,20 @@ namespace System.Data.SqlClient {
If column type is SqlDbType.NVarChar the size of parameter is multiplied by 2
FIXME: Need to check for other types
*/
- if (colType == "nvarchar") {
+ if (colType == "nvarchar" || colType == "ntext" || colType == "nchar") {
size = ((string) row [param.ParameterName]).Length;
size <<= 1;
+ } else if (colType == "varchar" || colType == "text" || colType == "char") {
+ size = ((string) row [param.ParameterName]).Length;
} else {
size = param.Size;
}
}
if (rowToCopy == null)
continue;
- blkCopy.BulkCopyData (rowToCopy, size, isNewRow);
+
+ blkCopy.BulkCopyData (rowToCopy, isNewRow, size, param.MetaParameter);
+
if (isNewRow)
isNewRow = false;
} // foreach (SqlParameter)
@@ -505,6 +546,16 @@ namespace System.Data.SqlClient {
blkCopy.BulkCopyEnd ();
}
+ private bool IsTextType(SqlDbType sqlType)
+ {
+ return (sqlType == SqlDbType.NText ||
+ sqlType == SqlDbType.NVarChar ||
+ sqlType == SqlDbType.Text ||
+ sqlType == SqlDbType.VarChar ||
+ sqlType == SqlDbType.Char ||
+ sqlType == SqlDbType.NChar);
+ }
+
public void WriteToServer (DataRow [] rows)
{
if (rows == null)