public SchemaDesignContext(FdoConnection conn) { _spatialContexts = new BindingList <SpatialContextInfo>(); if (conn == null) { _schemas = new FeatureSchemaCollection(null); _mappings = new PhysicalSchemaMappingCollection(); } else { using (var svc = conn.CreateFeatureService()) { _schemas = svc.DescribeSchema(); _mappings = svc.DescribeSchemaMapping(true); if (_mappings == null) { _mappings = new PhysicalSchemaMappingCollection(); } var spatialContexts = svc.GetSpatialContexts(); foreach (var sc in spatialContexts) { _spatialContexts.Add(sc); } } } this.Connection = conn; EvaluateCapabilities(); }
public SchemaDesignContext(FdoConnection conn) { _spatialContexts = new BindingList<SpatialContextInfo>(); if (conn == null) { _schemas = new FeatureSchemaCollection(null); _mappings = new PhysicalSchemaMappingCollection(); } else { using (var svc = conn.CreateFeatureService()) { _schemas = svc.DescribeSchema(); _mappings = svc.DescribeSchemaMapping(true); if (_mappings == null) _mappings = new PhysicalSchemaMappingCollection(); var spatialContexts = svc.GetSpatialContexts(); foreach (var sc in spatialContexts) { _spatialContexts.Add(sc); } } } this.Connection = conn; EvaluateCapabilities(); }
/// <summary> /// Gets all class names from the specified flat-file data source /// </summary> /// <param name="sourceFile"></param> /// <returns></returns> public static string[] GetClassNames(string sourceFile) { List <string> classnames = new List <string>(); FdoConnection source = null; try { source = CreateFlatFileConnection(sourceFile); source.Open(); using (FdoFeatureService svc = source.CreateFeatureService()) { using (FeatureSchemaCollection schemas = svc.DescribeSchema()) { foreach (FeatureSchema sch in schemas) { foreach (ClassDefinition cd in sch.Classes) { classnames.Add(cd.Name); } } } } } catch (Exception ex) { } finally { if (source != null) { source.Dispose(); } } return(classnames.ToArray()); }
public override int Execute() { IConnection conn = null; try { conn = CreateConnection(_provider, _connstr); conn.Open(); } catch (OSGeo.FDO.Common.Exception ex) { WriteException(ex); return((int)CommandStatus.E_FAIL_CONNECT); } using (FdoFeatureService service = new FdoFeatureService(conn)) { using (FeatureSchemaCollection schemas = service.DescribeSchema()) { Console.WriteLine("\nSchemas in this connection: {0}", schemas.Count); foreach (FeatureSchema fs in schemas) { Console.WriteLine("\nName: {0}\n", fs.Name); Console.WriteLine("\tQualified Name: {0}", fs.QualifiedName); Console.WriteLine("\tAttributes:"); WriteAttributes(fs.Attributes); } } } conn.Close(); return((int)CommandStatus.E_OK); }
public void TestSchemaClone() { FeatureSchemaCollection schemas = new FeatureSchemaCollection(null); schemas.ReadXml(Path.Combine(TestHelper.CurrentPath, "Test.xml")); FeatureSchema cloned = FdoSchemaUtil.CloneSchema(schemas[0]); AssertHelper.EqualSchemas(schemas[0], cloned); }
public static int SetDefaultSpatialContextAssociation(FeatureSchemaCollection fsc, string name) { int modified = 0; foreach (FeatureSchema fs in fsc) { modified += SetDefaultSpatialContextAssociation(fs, name); } return modified; }
public static int SetDefaultSpatialContextAssociation(FeatureSchemaCollection fsc, string name) { int modified = 0; foreach (FeatureSchema fs in fsc) { modified += SetDefaultSpatialContextAssociation(fs, name); } return(modified); }
private void EnsureSchemaRetrieved() { if (_schemas == null) { using (var svc = _conn.CreateFeatureService()) { _schemas = svc.DescribeSchema(); } } }
void CreateSchemaNodes(TreeNode connNode) { Action <TimeSpan> act = (ts) => LoggingService.Info("Connection " + connNode.Name + ": Schema population completed in " + ts.TotalMilliseconds + "ms"); FdoConnection conn = _connMgr.GetConnection(connNode.Name); if (conn != null) { using (FdoFeatureService service = conn.CreateFeatureService()) { if (service.SupportsPartialSchemaDiscovery()) { using (var measure = new TimeMeasurement(act)) { List <string> schemaNames = service.GetSchemaNames(); //Pre-sort SortedList <string, string> sorted = new SortedList <string, string>(); foreach (string name in schemaNames) { sorted.Add(name, name); } foreach (string name in schemaNames) { TreeNode schemaNode = CreateSchemaNode(name, true); connNode.Nodes.Add(schemaNode); schemaNode.Nodes.Add(ResourceService.GetString("TEXT_LOADING")); } } } else { using (var measure = new TimeMeasurement(act)) { FeatureSchemaCollection schemas = service.DescribeSchema(); //Pre-sort SortedList <string, FeatureSchema> sorted = new SortedList <string, FeatureSchema>(); foreach (FeatureSchema schema in schemas) { sorted.Add(schema.Name, schema); } foreach (FeatureSchema schema in schemas) { TreeNode schemaNode = CreateSchemaNode(schema.Name, false); GetClassNodesFull(schema, schemaNode); connNode.Nodes.Add(schemaNode); schemaNode.Expand(); } } } } } }
private FeatureSchemaCollection CloneSchemas(FeatureSchemaCollection featureSchemaCollection) { var schemas = new FeatureSchemaCollection(null); foreach (FeatureSchema fsc in featureSchemaCollection) { var sc = FdoToolbox.Core.Utility.FdoSchemaUtil.CloneSchema(fsc, true); schemas.Add(sc); } return(schemas); }
/// <summary> /// Loads a FDO XML configuration document /// </summary> /// <param name="xmlFile"></param> /// <returns></returns> public static FdoDataStoreConfiguration FromFile(string xmlFile) { using (var fact = new FgfGeometryFactory()) using (var ios = new IoFileStream(xmlFile, "r")) { using (var reader = new XmlReader(ios)) { List <SpatialContextInfo> contexts = new List <SpatialContextInfo>(); using (var scReader = new XmlSpatialContextReader(reader)) { while (scReader.ReadNext()) { var sc = new SpatialContextInfo(); sc.CoordinateSystem = scReader.GetCoordinateSystem(); sc.CoordinateSystemWkt = scReader.GetCoordinateSystemWkt(); sc.Description = scReader.GetDescription(); sc.ExtentType = scReader.GetExtentType(); if (sc.ExtentType == OSGeo.FDO.Commands.SpatialContext.SpatialContextExtentType.SpatialContextExtentType_Static) { using (var geom = fact.CreateGeometryFromFgf(scReader.GetExtent())) { sc.ExtentGeometryText = geom.Text; } } sc.IsActive = scReader.IsActive(); sc.Name = scReader.GetName(); sc.XYTolerance = scReader.GetXYTolerance(); sc.ZTolerance = scReader.GetZTolerance(); contexts.Add(sc); } } ios.Reset(); var schemas = new FeatureSchemaCollection(null); schemas.ReadXml(ios); ios.Reset(); var mappings = new PhysicalSchemaMappingCollection(); mappings.ReadXml(ios); ios.Close(); return(new FdoDataStoreConfiguration(schemas, contexts.ToArray(), mappings)); } } }
private void ApplySchemas(FdoConnection conn) { using (var svc = conn.CreateFeatureService()) { using (FeatureSchemaCollection fsc = new FeatureSchemaCollection(null)) { fsc.ReadXml(_view.SchemaFile); int modified = FdoSchemaUtil.SetDefaultSpatialContextAssociation(fsc, "Default"); List <FeatureSchema> schemas = new List <FeatureSchema>(); if (_view.FixSchema) { foreach (FeatureSchema fs in fsc) { IncompatibleSchema inc; if (!svc.CanApplySchema(fs, out inc)) { FeatureSchema mod = svc.AlterSchema(fs, inc); schemas.Add(mod); } else { schemas.Add(fs); } } } else { foreach (FeatureSchema fs in fsc) { schemas.Add(fs); } } foreach (FeatureSchema fs in schemas) { svc.ApplySchema(fs); } } } }
public ClassDefinition GetClassByName(string name, string schemaName, string className) { if (!_cache.ContainsKey(name)) { return(null); } FeatureSchemaCollection item = _cache[name]; int sidx = item.IndexOf(schemaName); if (sidx >= 0) { var classes = item[sidx].Classes; int cidx = classes.IndexOf(className); if (cidx >= 0) { return(classes[cidx]); } } return(null); }
internal void SetConfiguration(FdoDataStoreConfiguration conf) { _schemas = conf.Schemas; _mappings = conf.Mappings; if (_schemas == null) { _schemas = new FeatureSchemaCollection(null); } if (_mappings == null) { _mappings = new PhysicalSchemaMappingCollection(); } _spatialContexts.Clear(); if (conf.SpatialContexts != null && conf.SpatialContexts.Length > 0) { foreach (var sc in conf.SpatialContexts) { _spatialContexts.Add(sc); } } }
internal void SetConfiguration(FdoDataStoreConfiguration conf) { _schemas = conf.Schemas; _mappings = conf.Mappings; if (_schemas == null) _schemas = new FeatureSchemaCollection(null); if (_mappings == null) _mappings = new PhysicalSchemaMappingCollection(); _spatialContexts.Clear(); if (conf.SpatialContexts != null && conf.SpatialContexts.Length > 0) { foreach (var sc in conf.SpatialContexts) { _spatialContexts.Add(sc); } } }
public void Init(FeatureSchemaCollection schemas) { _view.SchemaList = schemas; }
/// <summary> /// Constructor /// </summary> /// <param name="schemas"></param> /// <param name="contexts"></param> /// <param name="mappings"></param> public FdoDataStoreConfiguration(FeatureSchemaCollection schemas, SpatialContextInfo[] contexts, PhysicalSchemaMappingCollection mappings) { this.Schemas = schemas; this.SpatialContexts = contexts; this.Mappings = mappings; }
/// <summary> /// Creates a FDO bulk copy task. The target file will be created as part of /// this method call. If the target path is a directory, it is assumed that /// SHP files are to be created and copied to. /// </summary> /// <param name="sourceFile">The path to the source file.</param> /// <param name="targetPath"> /// The path to the target file/directory. If it is a directory, it is assumed /// that SHP files are to be created and copied to. /// </param> /// <param name="copySpatialContexts">If true, will also copy spatial contexts</param> /// <param name="fixIncompatibleSchema">If true, will try to fix the source schema to make it compatible with the target connection. If false, an exception will be thrown</param> /// <param name="flattenGeometries">If true, will strip all Z and M coordinates from all geometries that are copied</param> /// <returns></returns> public static FdoBulkCopy CreateBulkCopy(string sourceFile, string targetPath, bool copySpatialContexts, bool fixIncompatibleSchema, bool flattenGeometries) { FdoBulkCopyOptions options = null; FdoConnection source = null; FdoConnection target = null; try { //Is a directory. Implies a SHP connection if (IsShp(targetPath)) { //SHP doesn't actually support CreateDataStore. We use the following technique: // - Connect to base directory // - Clone source schema and apply to SHP connection. // - A SHP file and related files are created for each feature class. string shpdir = Directory.Exists(targetPath) ? targetPath : Path.GetDirectoryName(targetPath); source = CreateFlatFileConnection(sourceFile); target = new FdoConnection("OSGeo.SHP", "DefaultFileLocation=" + shpdir); source.Open(); //Verify source has only classes with single geometry storage and only one geometry using (FdoFeatureService svc = source.CreateFeatureService()) { using (FeatureSchemaCollection schemas = svc.DescribeSchema()) { foreach (FeatureSchema sch in schemas) { foreach (ClassDefinition cd in sch.Classes) { int geomProps = 0; foreach (PropertyDefinition pd in cd.Properties) { if (pd.PropertyType == PropertyType.PropertyType_GeometricProperty) { GeometricPropertyDefinition gp = pd as GeometricPropertyDefinition; GeometricType[] types = FdoGeometryUtil.GetGeometricTypes(gp.GeometryTypes); if (types.Length != 1 || (types.Length == 1 && types[0] == GeometricType.GeometricType_All)) { throw new FdoETLException(string.Format("Source file cannot be copied to a SHP file. {0}:{1}.{2} has more than one geometry storage type", sch.Name, cd.Name, pd.Name)); } geomProps++; } } if (geomProps > 1) { throw new FdoETLException("Source file cannot be copied to a SHP file. One or more feature classes have more than one geometry property"); } } } } } } else { if (!CreateFlatFileDataSource(targetPath)) { throw new FdoException("Unable to create data source on: " + targetPath); } source = CreateFlatFileConnection(sourceFile); target = CreateFlatFileConnection(targetPath); } //Source and target connections may have been opened before this point if (source.State == FdoConnectionState.Closed) { source.Open(); } if (target.State == FdoConnectionState.Closed) { target.Open(); } string srcName = "SOURCE"; string dstName = "TARGET"; Dictionary <string, FdoConnection> connections = new Dictionary <string, FdoConnection>(); connections.Add(srcName, source); connections.Add(dstName, target); options = new FdoBulkCopyOptions(connections, true); if (copySpatialContexts) { CopyAllSpatialContexts(source, target, true); } using (FdoFeatureService srcService = source.CreateFeatureService()) using (FdoFeatureService destService = target.CreateFeatureService()) { FeatureSchemaCollection schemas = srcService.DescribeSchema(); //Assume single-schema FeatureSchema fs = schemas[0]; //Clone and apply to target FeatureSchema targetSchema = FdoSchemaUtil.CloneSchema(fs); IncompatibleSchema incSchema; string sourceSchemaName = fs.Name; string targetSchemaName = string.Empty; bool canApply = destService.CanApplySchema(targetSchema, out incSchema); if (canApply) { destService.ApplySchema(targetSchema); targetSchemaName = targetSchema.Name; } else { if (fixIncompatibleSchema) { FeatureSchema fixedSchema = destService.AlterSchema(targetSchema, incSchema); destService.ApplySchema(fixedSchema); targetSchemaName = fixedSchema.Name; } else { throw new Exception(incSchema.ToString()); } } //Copy all classes foreach (ClassDefinition cd in fs.Classes) { FdoClassCopyOptions copt = new FdoClassCopyOptions(srcName, dstName, sourceSchemaName, cd.Name, targetSchemaName, cd.Name); copt.Name = "Copy source to target [" + cd.Name + "]"; copt.FlattenGeometries = flattenGeometries; options.AddClassCopyOption(copt); //Flick on batch support if we can if (destService.SupportsBatchInsertion()) { copt.BatchSize = 300; //Madness? THIS IS SPARTA! } } } } catch (Exception) { if (source != null) { source.Dispose(); } if (target != null) { target.Dispose(); } throw; } return(new FdoBulkCopy(options)); }
/// <summary> /// Loads a FDO XML configuration document /// </summary> /// <param name="xmlFile"></param> /// <returns></returns> public static FdoDataStoreConfiguration FromFile(string xmlFile) { using (var fact = new FgfGeometryFactory()) using (var ios = new IoFileStream(xmlFile, "r")) { using (var reader = new XmlReader(ios)) { List<SpatialContextInfo> contexts = new List<SpatialContextInfo>(); using (var scReader = new XmlSpatialContextReader(reader)) { while (scReader.ReadNext()) { var sc = new SpatialContextInfo(); sc.CoordinateSystem = scReader.GetCoordinateSystem(); sc.CoordinateSystemWkt = scReader.GetCoordinateSystemWkt(); sc.Description = scReader.GetDescription(); sc.ExtentType = scReader.GetExtentType(); if (sc.ExtentType == OSGeo.FDO.Commands.SpatialContext.SpatialContextExtentType.SpatialContextExtentType_Static) { using (var geom = fact.CreateGeometryFromFgf(scReader.GetExtent())) { sc.ExtentGeometryText = geom.Text; } } sc.IsActive = scReader.IsActive(); sc.Name = scReader.GetName(); sc.XYTolerance = scReader.GetXYTolerance(); sc.ZTolerance = scReader.GetZTolerance(); contexts.Add(sc); } } ios.Reset(); var schemas = new FeatureSchemaCollection(null); schemas.ReadXml(ios); ios.Reset(); var mappings = new PhysicalSchemaMappingCollection(); mappings.ReadXml(ios); ios.Close(); return new FdoDataStoreConfiguration(schemas, contexts.ToArray(), mappings); } } }
public void Add(string name, FeatureSchemaCollection schemas) { _cache[name] = schemas; }
/// <summary> /// Loads bulk copy options from deserialized xml /// </summary> /// <param name="def">The deserialized definition.</param> /// <param name="name">The name.</param> /// <param name="owner">if set to <c>true</c> [owner].</param> /// <returns></returns> public FdoBulkCopyOptions BulkCopyFromXml(FdoBulkCopyTaskDefinition def, ref string name, bool owner) { var nameMap = Prepare(def); // TODO/FIXME/HACK: // // The introduction of on-the-fly schema modifications before copying has introduced a // potential problem which will only occur when multiple copy tasks copy to the same target // feature class. // // What happens is because a target will be multiple sources copying to it, if we need // to create/update the target class definition, the current infrastructure will be confused // as to which source feature class to clone from. // // A possible solution is to return the first matching name. This will cause a "create" operation // to be queued. We then alter the pre-modification process so that subsequent "create" operations // becomes "update" operations instead. // // On second thought, the current infrastructure should be smart enought to prevent this, as // the UI only allows: // // 1. Mapping to an existing class // 2. Mapping to a class of the same name (create if necessary) // // It won't be possible to map to a class that doesn't exist, as the requirement for auto-create/update // is that the class name will be the same. // // ie. It won't be possible to create this mapping // // a. Foo -> Foo (create if necessary) // b. Bar -> Foo // // Rule 1 prevents mapping b) from happening // Rule 2 ensures that Foo will only ever be created once // // If multiple sources are mapped to the same target, I believe the bcp infrastructure should ensure // that target must already exist first. name = def.name; Dictionary<string, FdoConnection> connections = new Dictionary<string, FdoConnection>(); Dictionary<string, string> changeConnNames = new Dictionary<string, string>(); //TODO: Prepare() ensured that all connections have unique names that don't already exist //now in the effort to re-use existing connections, see which connection entries //already exist and can be renamed back to the old name foreach (FdoConnectionEntryElement entry in def.Connections) { string connName = entry.name; FdoConnection conn = CreateConnection(entry.provider, entry.ConnectionString, entry.configPath, ref connName); connections[connName] = conn; if (connName != entry.name) { changeConnNames[entry.name] = connName; } } foreach (string oldName in changeConnNames.Keys) { def.UpdateConnectionReferences(oldName, changeConnNames[oldName]); } //Compile the list of classes to be queried Dictionary<string, MultiSchemaQuery> queries = new Dictionary<string, MultiSchemaQuery>(); foreach (FdoCopyTaskElement task in def.CopyTasks) { MultiSchemaQuery src = null; MultiSchemaQuery dst = null; //Process source if (!queries.ContainsKey(task.Source.connection)) src = queries[task.Source.connection] = new MultiSchemaQuery(task.Source.connection, SchemaOrigin.Source); else src = queries[task.Source.connection]; var sq = src.TryGet(task.Source.schema); if (sq != null) { sq.AddClass(task.Source.@class); } else { sq = new SchemaQuery(task.Source.schema); sq.AddClass(task.Source.@class); src.Add(sq); } //Process target if (!queries.ContainsKey(task.Target.connection)) dst = queries[task.Target.connection] = new MultiSchemaQuery(task.Target.connection, SchemaOrigin.Target); else dst = queries[task.Target.connection]; var tq = dst.TryGet(task.Target.schema); if (tq != null) { tq.AddClass(task.Target.@class); } else { tq = new SchemaQuery(task.Target.schema); tq.AddClass(task.Target.@class); dst.Add(tq); } } List<TargetClassModificationItem> modifiers = new List<TargetClassModificationItem>(); using (var schemaCache = new FeatureSchemaCache()) { //Now populate the schema cache with source schemas foreach (string connName in queries.Keys) { if (connections.ContainsKey(connName)) { var mqry = queries[connName]; var conn = connections[connName]; FeatureSchemaCollection schemas = new FeatureSchemaCollection(null); using (var svc = conn.CreateFeatureService()) { foreach (var sq in mqry.SchemaQueries) { //Source schema queries are expected to fully check out so use original method if (mqry.Origin == SchemaOrigin.Source) { schemas.Add(svc.PartialDescribeSchema(sq.SchemaName, new List<string>(sq.ClassNames))); } } } if (schemas.Count > 0) schemaCache.Add(connName, schemas); } } //Now populate the schema cache with target schemas, taking note of any //classes that need to be created or updated. foreach (string connName in queries.Keys) { if (connections.ContainsKey(connName)) { var mqry = queries[connName]; var conn = connections[connName]; FeatureSchemaCollection schemas = new FeatureSchemaCollection(null); using (var svc = conn.CreateFeatureService()) { foreach (var sq in mqry.SchemaQueries) { //Source schema queries are expected to fully check out so use original method if (mqry.Origin == SchemaOrigin.Target) { //Because we may need to create new classes, the old method will break down on non-existent class names //So use the new method string[] notFound; var schema = svc.PartialDescribeSchema(sq.SchemaName, new List<string>(sq.ClassNames), out notFound); //if (notFound.Length > 0) //{ // //If we can't modify schemas we'll stop right here. This is caused by elements containing createIfNotExists = true // if (!conn.Capability.GetBooleanCapability(CapabilityType.FdoCapabilityType_SupportsSchemaModification)) // throw new NotSupportedException("The connection named " + connName + " does not support schema modification. Therefore, copy tasks and property/expression mappings cannot have createIfNotExists = true"); // //This cumbersome, but we need the parent schema name of the class that we will need to copy // string srcSchema = GetSourceSchemaForMapping(def, sq.SchemaName, notFound); // foreach (string className in notFound) // { // modifiers.Add(new CreateTargetClassFromSource(srcSchema, className)); // } //} schemas.Add(schema); } } } if (schemas.Count > 0) schemaCache.Add(connName, schemas); } } FdoBulkCopyOptions opts = new FdoBulkCopyOptions(connections, owner); foreach (FdoCopyTaskElement task in def.CopyTasks) { TargetClassModificationItem mod; FdoClassCopyOptions copt = FdoClassCopyOptions.FromElement(task, schemaCache, connections[task.Source.connection], connections[task.Target.connection], out mod); opts.AddClassCopyOption(copt); if (mod != null) copt.PreCopyTargetModifier = mod; //opts.AddClassModifier(mod); } return opts; } }
private void ApplySchemas(FdoConnection conn) { using (var svc = conn.CreateFeatureService()) { using (FeatureSchemaCollection fsc = new FeatureSchemaCollection(null)) { fsc.ReadXml(_view.SchemaFile); int modified = FdoSchemaUtil.SetDefaultSpatialContextAssociation(fsc, "Default"); List<FeatureSchema> schemas = new List<FeatureSchema>(); if (_view.FixSchema) { foreach (FeatureSchema fs in fsc) { IncompatibleSchema inc; if (!svc.CanApplySchema(fs, out inc)) { FeatureSchema mod = svc.AlterSchema(fs, inc); schemas.Add(mod); } else { schemas.Add(fs); } } } else { foreach (FeatureSchema fs in fsc) { schemas.Add(fs); } } foreach (FeatureSchema fs in schemas) { svc.ApplySchema(fs); } } } }
private FeatureSchemaCollection CloneSchemas(FeatureSchemaCollection featureSchemaCollection) { var schemas = new FeatureSchemaCollection(null); foreach (FeatureSchema fsc in featureSchemaCollection) { var sc = FdoToolbox.Core.Utility.FdoSchemaUtil.CloneSchema(fsc, true); schemas.Add(sc); } return schemas; }
/// <summary> /// Loads bulk copy options from deserialized xml /// </summary> /// <param name="def">The deserialized definition.</param> /// <param name="name">The name.</param> /// <param name="owner">if set to <c>true</c> [owner].</param> /// <returns></returns> public FdoBulkCopyOptions BulkCopyFromXml(FdoBulkCopyTaskDefinition def, ref string name, bool owner) { var nameMap = Prepare(def); // TODO/FIXME/HACK: // // The introduction of on-the-fly schema modifications before copying has introduced a // potential problem which will only occur when multiple copy tasks copy to the same target // feature class. // // What happens is because a target will be multiple sources copying to it, if we need // to create/update the target class definition, the current infrastructure will be confused // as to which source feature class to clone from. // // A possible solution is to return the first matching name. This will cause a "create" operation // to be queued. We then alter the pre-modification process so that subsequent "create" operations // becomes "update" operations instead. // // On second thought, the current infrastructure should be smart enought to prevent this, as // the UI only allows: // // 1. Mapping to an existing class // 2. Mapping to a class of the same name (create if necessary) // // It won't be possible to map to a class that doesn't exist, as the requirement for auto-create/update // is that the class name will be the same. // // ie. It won't be possible to create this mapping // // a. Foo -> Foo (create if necessary) // b. Bar -> Foo // // Rule 1 prevents mapping b) from happening // Rule 2 ensures that Foo will only ever be created once // // If multiple sources are mapped to the same target, I believe the bcp infrastructure should ensure // that target must already exist first. name = def.name; Dictionary <string, FdoConnection> connections = new Dictionary <string, FdoConnection>(); Dictionary <string, string> changeConnNames = new Dictionary <string, string>(); //TODO: Prepare() ensured that all connections have unique names that don't already exist //now in the effort to re-use existing connections, see which connection entries //already exist and can be renamed back to the old name foreach (FdoConnectionEntryElement entry in def.Connections) { string connName = entry.name; FdoConnection conn = CreateConnection(entry.provider, entry.ConnectionString, entry.configPath, ref connName); connections[connName] = conn; if (connName != entry.name) { changeConnNames[entry.name] = connName; } } foreach (string oldName in changeConnNames.Keys) { def.UpdateConnectionReferences(oldName, changeConnNames[oldName]); } //Compile the list of classes to be queried Dictionary <string, MultiSchemaQuery> queries = new Dictionary <string, MultiSchemaQuery>(); foreach (FdoCopyTaskElement task in def.CopyTasks) { MultiSchemaQuery src = null; MultiSchemaQuery dst = null; //Process source if (!queries.ContainsKey(task.Source.connection)) { src = queries[task.Source.connection] = new MultiSchemaQuery(task.Source.connection, SchemaOrigin.Source); } else { src = queries[task.Source.connection]; } var sq = src.TryGet(task.Source.schema); if (sq != null) { sq.AddClass(task.Source.@class); } else { sq = new SchemaQuery(task.Source.schema); sq.AddClass(task.Source.@class); src.Add(sq); } //Process target if (!queries.ContainsKey(task.Target.connection)) { dst = queries[task.Target.connection] = new MultiSchemaQuery(task.Target.connection, SchemaOrigin.Target); } else { dst = queries[task.Target.connection]; } var tq = dst.TryGet(task.Target.schema); if (tq != null) { tq.AddClass(task.Target.@class); } else { tq = new SchemaQuery(task.Target.schema); tq.AddClass(task.Target.@class); dst.Add(tq); } } List <TargetClassModificationItem> modifiers = new List <TargetClassModificationItem>(); using (var schemaCache = new FeatureSchemaCache()) { //Now populate the schema cache with source schemas foreach (string connName in queries.Keys) { if (connections.ContainsKey(connName)) { var mqry = queries[connName]; var conn = connections[connName]; FeatureSchemaCollection schemas = new FeatureSchemaCollection(null); using (var svc = conn.CreateFeatureService()) { foreach (var sq in mqry.SchemaQueries) { //Source schema queries are expected to fully check out so use original method if (mqry.Origin == SchemaOrigin.Source) { schemas.Add(svc.PartialDescribeSchema(sq.SchemaName, new List <string>(sq.ClassNames))); } } } if (schemas.Count > 0) { schemaCache.Add(connName, schemas); } } } //Now populate the schema cache with target schemas, taking note of any //classes that need to be created or updated. foreach (string connName in queries.Keys) { if (connections.ContainsKey(connName)) { var mqry = queries[connName]; var conn = connections[connName]; FeatureSchemaCollection schemas = new FeatureSchemaCollection(null); using (var svc = conn.CreateFeatureService()) { foreach (var sq in mqry.SchemaQueries) { //Source schema queries are expected to fully check out so use original method if (mqry.Origin == SchemaOrigin.Target) { //Because we may need to create new classes, the old method will break down on non-existent class names //So use the new method string[] notFound; var schema = svc.PartialDescribeSchema(sq.SchemaName, new List <string>(sq.ClassNames), out notFound); //if (notFound.Length > 0) //{ // //If we can't modify schemas we'll stop right here. This is caused by elements containing createIfNotExists = true // if (!conn.Capability.GetBooleanCapability(CapabilityType.FdoCapabilityType_SupportsSchemaModification)) // throw new NotSupportedException("The connection named " + connName + " does not support schema modification. Therefore, copy tasks and property/expression mappings cannot have createIfNotExists = true"); // //This cumbersome, but we need the parent schema name of the class that we will need to copy // string srcSchema = GetSourceSchemaForMapping(def, sq.SchemaName, notFound); // foreach (string className in notFound) // { // modifiers.Add(new CreateTargetClassFromSource(srcSchema, className)); // } //} schemas.Add(schema); } } } if (schemas.Count > 0) { schemaCache.Add(connName, schemas); } } } FdoBulkCopyOptions opts = new FdoBulkCopyOptions(connections, owner); foreach (FdoCopyTaskElement task in def.CopyTasks) { TargetClassModificationItem mod; FdoClassCopyOptions copt = FdoClassCopyOptions.FromElement(task, schemaCache, connections[task.Source.connection], connections[task.Target.connection], out mod); opts.AddClassCopyOption(copt); if (mod != null) { copt.PreCopyTargetModifier = mod; } //opts.AddClassModifier(mod); } return(opts); } }