public override int Execute() { CommandStatus retCode; FdoConnection srcConn = new FdoConnection(_srcProvider, _srcConnStr); FdoConnection destConn = null; //Directory given, assume SHP if (Directory.Exists(_destPath)) { destConn = new FdoConnection("OSGeo.SHP", "DefaultFileLocation=" + _destPath); } else { if (ExpressUtility.CreateFlatFileDataSource(_destPath)) destConn = ExpressUtility.CreateFlatFileConnection(_destPath); else throw new FdoException("Could not create data source: " + _destPath); } try { srcConn.Open(); destConn.Open(); string srcName = "SOURCE"; string dstName = "TARGET"; FdoBulkCopyOptions options = new FdoBulkCopyOptions(); options.RegisterConnection(srcName, srcConn); options.RegisterConnection(dstName, destConn); using (FdoFeatureService srcService = srcConn.CreateFeatureService()) using (FdoFeatureService destService = destConn.CreateFeatureService()) { //See if spatial context needs to be copied to target if (!string.IsNullOrEmpty(_srcSpatialContext)) { SpatialContextInfo srcCtx = srcService.GetSpatialContext(_srcSpatialContext); if (srcCtx != null) { Console.WriteLine("Copying spatial context: " + srcCtx.Name); ExpressUtility.CopyAllSpatialContexts(new SpatialContextInfo[] { srcCtx }, destConn, true); } } else { //Copy all ExpressUtility.CopyAllSpatialContexts(srcConn, destConn, true); } FeatureSchema srcSchema = null; //See if partial class list is needed if (_srcClasses.Count > 0) { WriteLine("Checking if partial schema discovery is supported: " + srcService.SupportsPartialSchemaDiscovery()); srcSchema = srcService.PartialDescribeSchema(_srcSchema, _srcClasses); } else //Full copy { WriteLine("No classes specified, reading full source schema"); srcSchema = srcService.GetSchemaByName(_srcSchema); } if (srcSchema == null) { WriteError("Could not find source schema: " + _srcSchema); retCode = CommandStatus.E_FAIL_SCHEMA_NOT_FOUND; } else { WriteLine("Checking source schema for incompatibilities"); FeatureSchema targetSchema = null; IncompatibleSchema incSchema; if (destService.CanApplySchema(srcSchema, out incSchema)) { int clsCount = srcSchema.Classes.Count; WriteLine("Applying source schema (containing " + clsCount + " classes) to target"); destService.ApplySchema(srcSchema, null, true); targetSchema = srcSchema; } else { WriteWarning("Incompatibilities were detected in source schema. Applying a modified version to target"); FeatureSchema fixedSchema = destService.AlterSchema(srcSchema, incSchema); int clsCount = fixedSchema.Classes.Count; WriteLine("Applying modified source schema (containing " + clsCount + " classes) to target"); destService.ApplySchema(fixedSchema, null, true); targetSchema = fixedSchema; } //Now set class copy options foreach (ClassDefinition cd in srcSchema.Classes) { FdoClassCopyOptions copt = new FdoClassCopyOptions(srcName, dstName, srcSchema.Name, cd.Name, targetSchema.Name, cd.Name); copt.FlattenGeometries = _flatten; options.AddClassCopyOption(copt); } if (_flatten) { WriteWarning("The switch -flatten has been defined. Geometries that are copied will have any Z or M coordinates removed"); } FdoBulkCopy copy = new FdoBulkCopy(options); copy.ProcessMessage += new MessageEventHandler(OnMessage); copy.ProcessCompleted += new EventHandler(OnCompleted); Console.WriteLine("Executing bulk copy"); copy.Execute(); List<Exception> errors = new List<Exception>(copy.GetAllErrors()); if (errors.Count > 0) { string file = GenerateLogFileName("bcp-error-"); LogErrors(errors, file); base.WriteError("Errors were encountered during bulk copy."); retCode = CommandStatus.E_FAIL_BULK_COPY_WITH_ERRORS; } else { retCode = CommandStatus.E_OK; } retCode = CommandStatus.E_OK; } } } catch (Exception ex) { WriteException(ex); retCode = CommandStatus.E_FAIL_UNKNOWN; } finally { srcConn.Dispose(); destConn.Dispose(); } return (int)retCode; }
public override int Execute() { CommandStatus retCode; DefinitionLoader loader = new DefinitionLoader(); string name = null; if (TaskDefinitionHelper.IsBulkCopy(_file)) { FdoBulkCopyTaskDefinition def = null; using (var sr = new StreamReader(_file)) { XmlSerializer ser = new XmlSerializer(typeof(FdoBulkCopyTaskDefinition)); def = (FdoBulkCopyTaskDefinition)ser.Deserialize(sr); } if (def == null) { return (int)CommandStatus.E_FAIL_TASK_VALIDATION; } //If more than one task specified, load the default task and weed //out unneeded elements. if (_taskNames.Length > 0) { base.WriteLine("Certain tasks have been specified, only part of the bulk copy definition will execute"); var keepConnections = new Dictionary<string, FdoConnectionEntryElement>(); var keepTasks = new List<FdoCopyTaskElement>(); //Store needed tasks foreach (var task in def.CopyTasks) { if (Array.IndexOf(_taskNames, task.name) >= 0) { keepTasks.Add(task); } } //Store needed connections foreach (var task in keepTasks) { foreach (var conn in def.Connections) { //Is referenced as source/target connection? if (task.Source.connection == conn.name || task.Target.connection == conn.name) { if (!keepConnections.ContainsKey(conn.name)) keepConnections.Add(conn.name, conn); } } } if (keepTasks.Count != _taskNames.Length) { List<string> names = new List<string>(); foreach (var n in _taskNames) { bool found = false; foreach (var task in keepTasks) { if (task.name == n) { found = true; break; } } if (!found) names.Add(n); } base.WriteError("Could not find specified tasks in bulk copy definition: " + string.Join(",", names.ToArray())); return (int)CommandStatus.E_FAIL_MISSING_BULK_COPY_TASKS; } //Now replace def.Connections = new List<FdoConnectionEntryElement>(keepConnections.Values).ToArray(); def.CopyTasks = keepTasks.ToArray(); } using (FdoBulkCopyOptions opts = loader.BulkCopyFromXml(def, ref name, true)) { FdoBulkCopy copy = new FdoBulkCopy(opts); copy.ProcessMessage += delegate(object sender, MessageEventArgs e) { base.WriteLine(e.Message); }; copy.ProcessAborted += delegate(object sender, EventArgs e) { base.WriteLine("Bulk Copy Aborted"); }; copy.ProcessCompleted += delegate(object sender, EventArgs e) { base.WriteLine("Bulk Copy Completed"); }; copy.Execute(); List<Exception> errors = new List<Exception>(copy.GetAllErrors()); if (errors.Count > 0) { string file = GenerateLogFileName("bcp-error-"); LogErrors(errors, file); base.WriteError("Errors were encountered during bulk copy."); retCode = CommandStatus.E_FAIL_BULK_COPY_WITH_ERRORS; } else { retCode = CommandStatus.E_OK; } } } else if (TaskDefinitionHelper.IsJoin(_file)) { if (_taskNames.Length > 0) { base.WriteError("Parameter -bcptask is not applicable for join tasks"); return (int)CommandStatus.E_FAIL_INVALID_ARGUMENTS; } using (FdoJoinOptions opts = loader.JoinFromXml(_file, ref name, true)) { opts.Left.Connection.Open(); opts.Right.Connection.Open(); opts.Target.Connection.Open(); FdoJoin join = new FdoJoin(opts); join.ProcessMessage += delegate(object sender, MessageEventArgs e) { base.WriteLine(e.Message); }; join.Execute(); List<Exception> errors = new List<Exception>(join.GetAllErrors()); if (errors.Count > 0) { string file = GenerateLogFileName("join-error-"); LogErrors(errors, file); base.WriteError("Errors were encountered during join operation"); retCode = CommandStatus.E_FAIL_JOIN_WITH_ERRORS; } else { retCode = CommandStatus.E_OK; } } } else if (TaskDefinitionHelper.IsSequentialProcess(_file)) { var def = (SequentialProcessDefinition)SequentialProcessDefinition.Serializer.Deserialize(File.OpenRead(_file)); var proc = new FdoSequentialProcess(def); proc.ProcessMessage += delegate(object sender, MessageEventArgs e) { base.WriteLine(e.Message); }; proc.Execute(); List<Exception> errors = new List<Exception>(proc.GetAllErrors()); if (errors.Count > 0) { string file = GenerateLogFileName("seq-process-"); LogErrors(errors, file); base.WriteError("Errors were encountered during sequential process"); } //Why E_OK? the user should check the log for the underlying return codes //of individual FdoUtil.exe invocations! retCode = CommandStatus.E_OK; } else { retCode = CommandStatus.E_FAIL_UNRECOGNISED_TASK_FORMAT; } return (int)retCode; }