internal static FdoClassCopyOptions FromElement(FdoCopyTaskElement el, FeatureSchemaCache cache, FdoConnection sourceConn, FdoConnection targetConn, out TargetClassModificationItem mod)
        {
            mod = null;
            if (!cache.HasConnection(el.Source.connection))
                throw new TaskLoaderException("The referenced source connection is not defined");

            if (!cache.HasConnection(el.Target.connection))
                throw new TaskLoaderException("The referenced target connection is not defined");

            FdoClassCopyOptions opts = new FdoClassCopyOptions(el.Source.connection, el.Target.connection, el.Source.schema, el.Source.@class, el.Target.schema, el.Target.@class);
            opts.DeleteTarget = el.Options.DeleteTarget;
            opts.SourceFilter = el.Options.Filter;
            if (!el.Options.FlattenGeometriesSpecified)
                opts.FlattenGeometries = false;
            else
                opts.FlattenGeometries = el.Options.FlattenGeometries;

            if (!el.Options.ForceWKBSpecified)
                opts.ForceWkb = false;
            else
                opts.ForceWkb = el.Options.ForceWKB;

            if (!string.IsNullOrEmpty(el.Options.BatchSize))
                opts.BatchSize = Convert.ToInt32(el.Options.BatchSize);
            opts.Name = el.name;
            opts.CreateIfNotExists = el.createIfNotExists;

            ClassDefinition srcClass = cache.GetClassByName(el.Source.connection, el.Source.schema, el.Source.@class);
            ClassDefinition dstClass = cache.GetClassByName(el.Target.connection, el.Target.schema, el.Target.@class);

            if (!el.createIfNotExists && dstClass == null)
                throw new InvalidOperationException("Target class " + el.Target.@class + " does not exist and the createIfNotExist option is false");

            SpatialContextInfo defaultSc = null;
            FunctionDefinitionCollection availableFunctions = (FunctionDefinitionCollection)sourceConn.Capability.GetObjectCapability(CapabilityType.FdoCapabilityType_ExpressionFunctions);

            using (var svc = targetConn.CreateFeatureService())
            {
                defaultSc = svc.GetActiveSpatialContext();
            }

            if (dstClass != null)
            {
                foreach (FdoPropertyMappingElement propMap in el.PropertyMappings)
                {
                    if (srcClass.Properties.IndexOf(propMap.source) < 0)
                        throw new TaskLoaderException("The property mapping (" + propMap.source + " -> " + propMap.target + ") in task (" + el.name + ") contains a source property not found in the source class definition (" + el.Source.@class + ")");

                    //Add to list of properties to check for
                    if (propMap.createIfNotExists && dstClass.Properties.IndexOf(propMap.target) < 0)
                    {
                        if (mod == null)
                            mod = new UpdateTargetClass(dstClass.Name);

                        opts.AddSourcePropertyToCheck(propMap.source);

                        //Clone copy of source property of same name
                        var srcProp = srcClass.Properties[srcClass.Properties.IndexOf(propMap.source)];
                        srcProp = FdoSchemaUtil.CloneProperty(srcProp);
                        mod.AddProperty(srcProp);
                    }
                    else
                    {
                        if (dstClass.Properties.IndexOf(propMap.target) < 0)
                            throw new TaskLoaderException("The property mapping (" + propMap.source + " -> " + propMap.target + ") in task (" + el.name + ") contains a target property not found in the target class definition (" + el.Target.@class + ")");

                        PropertyDefinition sp = srcClass.Properties[propMap.source];
                        PropertyDefinition tp = dstClass.Properties[propMap.target];

                        if (sp.PropertyType != tp.PropertyType)
                            throw new TaskLoaderException("The properties in the mapping (" + propMap.source + " -> " + propMap.target + ") are of different types");

                        //if (sp.PropertyType != PropertyType.PropertyType_DataProperty)
                        //    throw new TaskLoaderException("One or more properties in the mapping (" + propMap.source + " -> " + propMap.target + ") is not a data property");

                        DataPropertyDefinition sdp = sp as DataPropertyDefinition;
                        DataPropertyDefinition tdp = tp as DataPropertyDefinition;

                        opts.AddPropertyMapping(propMap.source, propMap.target);

                        //Property mapping is between two data properties
                        if (sdp != null && tdp != null)
                        {
                            //Types not equal, so add a conversion rule
                            if (sdp.DataType != tdp.DataType)
                            {
                                FdoDataPropertyConversionRule rule = new FdoDataPropertyConversionRule(
                                    propMap.source,
                                    propMap.target,
                                    sdp.DataType,
                                    tdp.DataType,
                                    propMap.nullOnFailedConversion,
                                    propMap.truncate);
                                opts.AddDataConversionRule(propMap.source, rule);
                            }
                        }
                    }
                }

                //
                foreach (FdoExpressionMappingElement exprMap in el.ExpressionMappings)
                {
                    if (string.IsNullOrEmpty(exprMap.target))
                        continue;

                    opts.AddSourceExpression(exprMap.alias, exprMap.Expression, exprMap.target);
                    //Add to list of properties to check for
                    if (exprMap.createIfNotExists)
                    {
                        //Class exists but property doesn't
                        if (dstClass.Properties.IndexOf(exprMap.target) < 0)
                        {
                            if (mod == null)
                            {
                                mod = new UpdateTargetClass(el.Target.@class);
                            }

                            var prop = FdoSchemaUtil.CreatePropertyFromExpressionType(exprMap.Expression, srcClass, availableFunctions, defaultSc.Name);
                            if (prop == null)
                            {
                                throw new InvalidOperationException("Could not derive a property definition from the expression: " + exprMap.Expression);
                            }

                            prop.Name = exprMap.target;
                            mod.AddProperty(prop);
                        }
                    }
                    else //Conversion rules can only apply if both properties exist.
                    {
                        FdoPropertyType? pt = ExpressionUtility.ParseExpressionType(exprMap.Expression, sourceConn);
                        if (pt.HasValue)
                        {
                            DataType? srcDt = ValueConverter.GetDataType(pt.Value);
                            if (srcDt.HasValue)
                            {
                                PropertyDefinition tp = dstClass.Properties[exprMap.target];
                                DataPropertyDefinition tdp = tp as DataPropertyDefinition;
                                if (tdp != null)
                                {
                                    if (srcDt.Value != tdp.DataType)
                                    {
                                        FdoDataPropertyConversionRule rule = new FdoDataPropertyConversionRule(
                                            exprMap.alias,
                                            exprMap.target,
                                            srcDt.Value,
                                            tdp.DataType,
                                            exprMap.nullOnFailedConversion,
                                            exprMap.truncate);
                                        opts.AddDataConversionRule(exprMap.alias, rule);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else //class doesn't exist
            {
                mod = new CreateTargetClassFromSource(el.Source.schema, el.Target.@class);

                foreach (var propMap in el.PropertyMappings)
                {
                    opts.AddPropertyMapping(propMap.source, propMap.target);

                    if (propMap.createIfNotExists)
                    {
                        opts.AddSourcePropertyToCheck(propMap.source);
                    }
                }

                foreach (var exprMap in el.ExpressionMappings)
                {
                    opts.AddSourceExpression(exprMap.alias, exprMap.Expression, exprMap.target);

                    if (exprMap.createIfNotExists)
                        opts.AddSourcePropertyToCheck(exprMap.alias);

                    var prop = FdoSchemaUtil.CreatePropertyFromExpressionType(exprMap.Expression, srcClass, availableFunctions, defaultSc.Name);
                    if (prop == null)
                    {
                        throw new InvalidOperationException("Could not derive a property definition from the expression: " + exprMap.Expression);
                    }
                    prop.Name = exprMap.target;
                    mod.AddProperty(prop);
                }
            }

            return opts;
        }
Esempio n. 2
0
        internal static FdoClassCopyOptions FromElement(FdoCopyTaskElement el, FeatureSchemaCache cache, FdoConnection sourceConn, FdoConnection targetConn, out TargetClassModificationItem mod)
        {
            mod = null;
            if (!cache.HasConnection(el.Source.connection))
            {
                throw new TaskLoaderException("The referenced source connection is not defined");
            }

            if (!cache.HasConnection(el.Target.connection))
            {
                throw new TaskLoaderException("The referenced target connection is not defined");
            }

            FdoClassCopyOptions opts = new FdoClassCopyOptions(el.Source.connection, el.Target.connection, el.Source.schema, el.Source.@class, el.Target.schema, el.Target.@class);

            opts.DeleteTarget = el.Options.DeleteTarget;
            opts.SourceFilter = el.Options.Filter;
            if (!el.Options.FlattenGeometriesSpecified)
            {
                opts.FlattenGeometries = false;
            }
            else
            {
                opts.FlattenGeometries = el.Options.FlattenGeometries;
            }

            if (!el.Options.ForceWKBSpecified)
            {
                opts.ForceWkb = false;
            }
            else
            {
                opts.ForceWkb = el.Options.ForceWKB;
            }

            if (!string.IsNullOrEmpty(el.Options.BatchSize))
            {
                opts.BatchSize = Convert.ToInt32(el.Options.BatchSize);
            }
            opts.Name = el.name;
            opts.CreateIfNotExists = el.createIfNotExists;

            ClassDefinition srcClass = cache.GetClassByName(el.Source.connection, el.Source.schema, el.Source.@class);
            ClassDefinition dstClass = cache.GetClassByName(el.Target.connection, el.Target.schema, el.Target.@class);

            if (!el.createIfNotExists && dstClass == null)
            {
                throw new InvalidOperationException("Target class " + el.Target.@class + " does not exist and the createIfNotExist option is false");
            }

            SpatialContextInfo           defaultSc          = null;
            FunctionDefinitionCollection availableFunctions = (FunctionDefinitionCollection)sourceConn.Capability.GetObjectCapability(CapabilityType.FdoCapabilityType_ExpressionFunctions);

            using (var svc = targetConn.CreateFeatureService())
            {
                defaultSc = svc.GetActiveSpatialContext();
            }

            if (dstClass != null)
            {
                foreach (FdoPropertyMappingElement propMap in el.PropertyMappings)
                {
                    if (srcClass.Properties.IndexOf(propMap.source) < 0)
                    {
                        throw new TaskLoaderException("The property mapping (" + propMap.source + " -> " + propMap.target + ") in task (" + el.name + ") contains a source property not found in the source class definition (" + el.Source.@class + ")");
                    }

                    //Add to list of properties to check for
                    if (propMap.createIfNotExists && dstClass.Properties.IndexOf(propMap.target) < 0)
                    {
                        if (mod == null)
                        {
                            mod = new UpdateTargetClass(dstClass.Name);
                        }

                        opts.AddSourcePropertyToCheck(propMap.source);

                        //Clone copy of source property of same name
                        var srcProp = srcClass.Properties[srcClass.Properties.IndexOf(propMap.source)];
                        srcProp = FdoSchemaUtil.CloneProperty(srcProp);
                        mod.AddProperty(srcProp);
                    }
                    else
                    {
                        if (dstClass.Properties.IndexOf(propMap.target) < 0)
                        {
                            throw new TaskLoaderException("The property mapping (" + propMap.source + " -> " + propMap.target + ") in task (" + el.name + ") contains a target property not found in the target class definition (" + el.Target.@class + ")");
                        }

                        PropertyDefinition sp = srcClass.Properties[propMap.source];
                        PropertyDefinition tp = dstClass.Properties[propMap.target];

                        if (sp.PropertyType != tp.PropertyType)
                        {
                            throw new TaskLoaderException("The properties in the mapping (" + propMap.source + " -> " + propMap.target + ") are of different types");
                        }

                        //if (sp.PropertyType != PropertyType.PropertyType_DataProperty)
                        //    throw new TaskLoaderException("One or more properties in the mapping (" + propMap.source + " -> " + propMap.target + ") is not a data property");

                        DataPropertyDefinition sdp = sp as DataPropertyDefinition;
                        DataPropertyDefinition tdp = tp as DataPropertyDefinition;

                        opts.AddPropertyMapping(propMap.source, propMap.target);

                        //Property mapping is between two data properties
                        if (sdp != null && tdp != null)
                        {
                            //Types not equal, so add a conversion rule
                            if (sdp.DataType != tdp.DataType)
                            {
                                FdoDataPropertyConversionRule rule = new FdoDataPropertyConversionRule(
                                    propMap.source,
                                    propMap.target,
                                    sdp.DataType,
                                    tdp.DataType,
                                    propMap.nullOnFailedConversion,
                                    propMap.truncate);
                                opts.AddDataConversionRule(propMap.source, rule);
                            }
                        }
                    }
                }

                //
                foreach (FdoExpressionMappingElement exprMap in el.ExpressionMappings)
                {
                    if (string.IsNullOrEmpty(exprMap.target))
                    {
                        continue;
                    }

                    opts.AddSourceExpression(exprMap.alias, exprMap.Expression, exprMap.target);
                    //Add to list of properties to check for
                    if (exprMap.createIfNotExists)
                    {
                        //Class exists but property doesn't
                        if (dstClass.Properties.IndexOf(exprMap.target) < 0)
                        {
                            if (mod == null)
                            {
                                mod = new UpdateTargetClass(el.Target.@class);
                            }

                            var prop = FdoSchemaUtil.CreatePropertyFromExpressionType(exprMap.Expression, srcClass, availableFunctions, defaultSc.Name);
                            if (prop == null)
                            {
                                throw new InvalidOperationException("Could not derive a property definition from the expression: " + exprMap.Expression);
                            }

                            prop.Name = exprMap.target;
                            mod.AddProperty(prop);
                        }
                    }
                    else //Conversion rules can only apply if both properties exist.
                    {
                        FdoPropertyType?pt = ExpressionUtility.ParseExpressionType(exprMap.Expression, sourceConn);
                        if (pt.HasValue)
                        {
                            DataType?srcDt = ValueConverter.GetDataType(pt.Value);
                            if (srcDt.HasValue)
                            {
                                PropertyDefinition     tp  = dstClass.Properties[exprMap.target];
                                DataPropertyDefinition tdp = tp as DataPropertyDefinition;
                                if (tdp != null)
                                {
                                    if (srcDt.Value != tdp.DataType)
                                    {
                                        FdoDataPropertyConversionRule rule = new FdoDataPropertyConversionRule(
                                            exprMap.alias,
                                            exprMap.target,
                                            srcDt.Value,
                                            tdp.DataType,
                                            exprMap.nullOnFailedConversion,
                                            exprMap.truncate);
                                        opts.AddDataConversionRule(exprMap.alias, rule);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else //class doesn't exist
            {
                mod = new CreateTargetClassFromSource(el.Source.schema, el.Target.@class);

                foreach (var propMap in el.PropertyMappings)
                {
                    opts.AddPropertyMapping(propMap.source, propMap.target);

                    if (propMap.createIfNotExists)
                    {
                        opts.AddSourcePropertyToCheck(propMap.source);
                    }
                }

                foreach (var exprMap in el.ExpressionMappings)
                {
                    opts.AddSourceExpression(exprMap.alias, exprMap.Expression, exprMap.target);

                    if (exprMap.createIfNotExists)
                    {
                        opts.AddSourcePropertyToCheck(exprMap.alias);
                    }

                    var prop = FdoSchemaUtil.CreatePropertyFromExpressionType(exprMap.Expression, srcClass, availableFunctions, defaultSc.Name);
                    if (prop == null)
                    {
                        throw new InvalidOperationException("Could not derive a property definition from the expression: " + exprMap.Expression);
                    }
                    prop.Name = exprMap.target;
                    mod.AddProperty(prop);
                }
            }

            return(opts);
        }