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);
}