private void WriteToServer(Feeder feeder) { if (this.tableName.Length == 0) { throw new ArgumentException("The name of the destination table hasn't been specified", "DestinationTableName"); } StringBuilder builder = new StringBuilder(); builder.Append("INSERT INTO `"); builder.Append(this.tableName.Replace("`", "``")); builder.Append("` "); if (mappings.Count == 0) { // the target table has the same number and names of the columns as in the specified input rows builder.Append("VALUES ("); for (int i = 0; i < feeder.FieldCount; i++) { if (i != 0) { builder.Append(", "); } builder.Append("?"); } builder.Append(")"); } else { DataRowCollection targetColumns = null; builder.Append(" ("); for (int i = 0; i < mappings.Count; i++) { NuoDbBulkLoaderColumnMapping mapping = mappings[i]; if (i != 0) { builder.Append(", "); } builder.Append("`"); if (mapping.DestinationColumn == null) { // we are requested to map to a target column that is identified with its ordinal number, so // fetch the schema of the target table to find out what is its name if (targetColumns == null) { // split the destination table into its different parts string[] parts = this.tableName.Split(new char[] { '.' }); DataTable targetSchema = this.connection.GetSchema("Columns", new string[] { null, // catalog parts.Length == 2 ? parts[0] : null, // schema parts.Length == 2 ? parts[1] : parts[0] // table }); targetColumns = targetSchema.Rows; } if (mapping.DestinationOrdinal < 0 || mapping.DestinationOrdinal > targetColumns.Count) { throw new IndexOutOfRangeException(String.Format("The specified ordinal of the target column ({0}) is outside the range of the column count ({1}) of table {2}", new object[] { mapping.DestinationOrdinal, targetColumns.Count, this.tableName })); } string columnName = (string)(targetColumns[mapping.DestinationOrdinal]["COLUMN_NAME"]); builder.Append(columnName.Replace("`", "``")); } else { builder.Append(mapping.DestinationColumn.Replace("`", "``")); } builder.Append("`"); } builder.Append(") VALUES ("); for (int i = 0; i < mappings.Count; i++) { if (i != 0) { builder.Append(", "); } builder.Append("?"); } builder.Append(")"); } string sqlString = builder.ToString(); #if DEBUG System.Diagnostics.Trace.WriteLine("NuoDbBulkLoader::WriteToServer: " + sqlString); #endif if (this.connection.State != ConnectionState.Open) { this.connection.Open(); } using (NuoDbCommand command = new NuoDbCommand(sqlString, this.connection)) { command.Prepare(); int totalSize = 0; // do the check for out-of-range values just once foreach (NuoDbBulkLoaderColumnMapping mapping in mappings) { if (mapping.SourceColumn == null && mapping.SourceOrdinal < 0 || mapping.SourceOrdinal > feeder.FieldCount) { throw new IndexOutOfRangeException(String.Format("The specified ordinal of the source column ({0}) is outside the range of the column count ({1})", new object[] { mapping.SourceOrdinal, feeder.FieldCount })); } } while (true) { EncodedDataStream dataStream = new RemEncodedStream(connection.InternalConnection.protocolVersion); dataStream.startMessage(Protocol.ExecuteBatchPreparedStatement); dataStream.encodeInt(command.handle); int batchCount = 0; for (; batchCount < this.batchSize && feeder.MoveNext(); batchCount++) { dataStream.encodeInt(command.Parameters.Count); if (mappings.Count == 0) { for (int i = 0; i < feeder.FieldCount; i++) { dataStream.encodeDotNetObject(feeder[i]); } } else { foreach (NuoDbBulkLoaderColumnMapping mapping in mappings) { if (mapping.SourceColumn == null) { dataStream.encodeDotNetObject(feeder[mapping.SourceOrdinal]); } else { dataStream.encodeDotNetObject(feeder[mapping.SourceColumn]); } } } } // the iterator hasn't found any more data to import, let's break out if (batchCount == 0) { break; } dataStream.encodeInt(-1); dataStream.encodeInt(batchCount); totalSize += batchCount; #if DEBUG System.Diagnostics.Trace.WriteLine("NuoDbBulkLoader::WriteToServer: sending a batch of " + batchCount + " rows"); #endif this.connection.InternalConnection.sendAndReceive(dataStream); bool hasErrors = false; string errorMessage = string.Empty; for (int i = 0; i < batchCount; i++) { int result = dataStream.getInt(); if (result == EXECUTE_FAILED) { if (this.connection.InternalConnection.protocolVersion >= Protocol.PROTOCOL_VERSION6) { int sqlCode = dataStream.getInt(); string message = dataStream.getString(); errorMessage = AppendError(errorMessage, message, i); } hasErrors = true; } } if (this.connection.InternalConnection.protocolVersion >= Protocol.PROTOCOL_VERSION3) { long txnId = dataStream.getLong(); int nodeId = dataStream.getInt(); long commitSequence = dataStream.getLong(); this.connection.InternalConnection.setLastTransaction(txnId, nodeId, commitSequence); } if (handlers.Count != 0) { BatchProcessedEventHandler[] tmpArray = new BatchProcessedEventHandler[handlers.Count]; handlers.CopyTo(tmpArray); BatchProcessedEventArgs args = new BatchProcessedEventArgs(); args.BatchSize = batchCount; args.TotalSize = totalSize; args.HasErrors = hasErrors; foreach (BatchProcessedEventHandler h in tmpArray) { h.Invoke(this, args); } } if (hasErrors) { throw new NuoDbSqlException(errorMessage, NuoDbSqlCode.FindError("BATCH_UPDATE_ERROR")); } } } }
public NuoDbBulkLoaderColumnMapping Add(NuoDbBulkLoaderColumnMapping mapping) { List.Add(mapping); return mapping; }
private void WriteToServer(DataFeeder feeder) { if (this.tableName.Length == 0) { throw new ArgumentException("The name of the destination table hasn't been specified", "DestinationTableName"); } StringBuilder builder = new StringBuilder(); builder.Append("INSERT INTO "); if (this.tableName.Contains(".")) { string[] parts = this.tableName.Split(new char[] { '.' }); bool first = true; foreach (string part in parts) { if (first) { first = false; } else { builder.Append("."); } builder.Append("`"); builder.Append(part.Replace("`", "``")); builder.Append("`"); } } else { builder.Append("`"); builder.Append(this.tableName.Replace("`", "``")); builder.Append("`"); } builder.Append(" "); if (mappings.Count == 0) { // the target table has the same number and names of the columns as in the specified input rows builder.Append("VALUES ("); for (int i = 0; i < feeder.FieldCount; i++) { if (i != 0) { builder.Append(", "); } builder.Append("?"); } builder.Append(")"); } else { DataRowCollection targetColumns = null; builder.Append(" ("); for (int i = 0; i < mappings.Count; i++) { NuoDbBulkLoaderColumnMapping mapping = mappings[i]; if (i != 0) { builder.Append(", "); } builder.Append("`"); if (mapping.DestinationColumn == null) { // we are requested to map to a target column that is identified with its ordinal number, so // fetch the schema of the target table to find out what is its name if (targetColumns == null) { // split the destination table into its different parts string[] parts = this.tableName.Split(new char[] { '.' }); DataTable targetSchema = this.connection.GetSchema("Columns", new string[] { null, // catalog parts.Length == 2 ? parts[0] : null, // schema parts.Length == 2 ? parts[1] : parts[0] // table }); targetColumns = targetSchema.Rows; } if (mapping.DestinationOrdinal < 0 || mapping.DestinationOrdinal > targetColumns.Count) { throw new IndexOutOfRangeException(String.Format("The specified ordinal of the target column ({0}) is outside the range of the column count ({1}) of table {2}", new object[] { mapping.DestinationOrdinal, targetColumns.Count, this.tableName })); } string columnName = (string)(targetColumns[mapping.DestinationOrdinal]["COLUMN_NAME"]); builder.Append(columnName.Replace("`", "``")); } else { builder.Append(mapping.DestinationColumn.Replace("`", "``")); } builder.Append("`"); } builder.Append(") VALUES ("); for (int i = 0; i < mappings.Count; i++) { if (i != 0) { builder.Append(", "); } builder.Append("?"); } builder.Append(")"); } string sqlString = builder.ToString(); #if DEBUG System.Diagnostics.Trace.WriteLine("NuoDbBulkLoader::WriteToServer: " + sqlString); #endif if (this.connection.State != ConnectionState.Open) { this.connection.Open(); } using (NuoDbCommand command = new NuoDbCommand(sqlString, this.connection)) { if (mappings.Count > 0) { // do the check for out-of-range values just once foreach (NuoDbBulkLoaderColumnMapping mapping in mappings) { if (mapping.SourceColumn == null && mapping.SourceOrdinal < 0 || mapping.SourceOrdinal > feeder.FieldCount) { throw new IndexOutOfRangeException(String.Format("The specified ordinal of the source column ({0}) is outside the range of the column count ({1})", mapping.SourceOrdinal, feeder.FieldCount)); } } feeder = new FeederOrderer(feeder, mappings); } int batchCount = 0; int totalSize = 0; while ((batchCount = command.ExecuteBatch(feeder, this.batchSize)) > 0) { totalSize += batchCount; #if DEBUG System.Diagnostics.Trace.WriteLine("NuoDbBulkLoader::WriteToServer: sent a batch of " + batchCount + " rows"); #endif if (handlers.Count != 0) { BatchProcessedEventHandler[] tmpArray = new BatchProcessedEventHandler[handlers.Count]; handlers.CopyTo(tmpArray); BatchProcessedEventArgs args = new BatchProcessedEventArgs(); args.BatchSize = batchCount; args.TotalSize = totalSize; args.HasErrors = false; foreach (BatchProcessedEventHandler h in tmpArray) { h.Invoke(this, args); } } } } }
public NuoDbBulkLoaderColumnMapping Add(NuoDbBulkLoaderColumnMapping mapping) { List.Add(mapping); return(mapping); }