CreateFeatureService() public method

Creates a new feature service bound to this connection
public CreateFeatureService ( ) : FdoFeatureService
return FdoFeatureService
        /// <summary>
        /// Copies the spatial contexts given in the list
        /// </summary>
        /// <param name="source">The source connection</param>
        /// <param name="target">The target connection</param>
        /// <param name="overwrite">If true will overwrite any existing spatial contexts</param>
        /// <param name="spatialContextNames">The list of spatial contexts to copy</param>
        public override void Execute(FdoConnection source, FdoConnection target, bool overwrite, string[] spatialContextNames)
        {
            if (spatialContextNames.Length == 0)
                return;

            FdoFeatureService srcService = source.CreateFeatureService();
            FdoFeatureService destService = target.CreateFeatureService();
            ReadOnlyCollection<SpatialContextInfo> srcContexts = srcService.GetSpatialContexts();
            ReadOnlyCollection<SpatialContextInfo> destContexts = destService.GetSpatialContexts();
            foreach (SpatialContextInfo ctx in srcContexts)
            {
                if (SpatialContextInSpecifiedList(ctx, spatialContextNames))
                {
                    try
                    {
                        //Find target spatial context of the same name
                        SpatialContextInfo sci = destService.GetSpatialContext(ctx.Name);
                        if (sci != null && overwrite)
                        {
                            //If found, destroy then create
                            destService.DestroySpatialContext(ctx.Name);
                            destService.CreateSpatialContext(ctx, false);
                        }
                        else
                        {
                            destService.CreateSpatialContext(ctx, false);
                        }
                    }
                    catch (Exception)
                    {

                    }
                }
            }
        }
        /// <summary>
        /// Copies all spatial contexts
        /// </summary>
        /// <param name="spatialContexts">The spatial contexts.</param>
        /// <param name="target">The target.</param>
        /// <param name="overwrite">if set to <c>true</c> [overwrite].</param>
        public override void Execute(ICollection<SpatialContextInfo> spatialContexts, FdoConnection target, bool overwrite)
        {
            //MySQL supports multiple spatial contexts and IDestorySpatialContext
            //so in this case if overwrite == true, we want to destroy any ones that
            //already exist in the target before creating new ones in its place. This does not
            //prevent creating a series of spatial contexts if overwrite == false and one of
            //the spatial contexts being copied already exists. This is an unfortunate leaky 
            //abstraction in the FDO API.

            using (FdoFeatureService service = target.CreateFeatureService())
            {
                if (overwrite)
                {
                    ReadOnlyCollection<SpatialContextInfo> targetContexts = service.GetSpatialContexts();

                    foreach (SpatialContextInfo sc in spatialContexts)
                    {
                        //Only destroy spatial context if it exists in target connection
                        if (SpatialContextExists(targetContexts, sc))
                            service.DestroySpatialContext(sc);
                    }
                }

                foreach (SpatialContextInfo sc in spatialContexts)
                {
                    service.CreateSpatialContext(sc, false);
                }
            }
        }
        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 FdoStandardQueryPresenter(IFdoStandardQueryView view, FdoConnection conn)
 {
     _view = view;
     _conn = conn;
     _service = _conn.CreateFeatureService();
     _view.OrderingEnabled = conn.Capability.GetBooleanCapability(CapabilityType.FdoCapabilityType_SupportsSelectOrdering);
     _walker = SchemaWalker.GetWalker(conn);
 }
 public FdoAggregateQueryPresenter(IFdoAggregateQueryView view, FdoConnection conn)
 {
     _view = view;
     _conn = conn;
     _service = _conn.CreateFeatureService();
     _view.OrderingEnabled = false;
     _walker = SchemaWalker.GetWalker(conn);
 }
 public FdoSpatialContextBrowserDlg(FdoConnection conn)
     : this()
 {
     using (FdoFeatureService service = conn.CreateFeatureService())
     {
         grdSpatialContexts.DataSource = service.GetSpatialContexts();
     }
 }
Example #7
0
 public static SchemaWalker GetWalker(FdoConnection conn)
 {
     using (var svc = conn.CreateFeatureService())
     {
         if (svc.SupportsPartialSchemaDiscovery())
             return new PartialSchemaWalker(conn);
         else
             return new FullSchemaWalker(conn);
     }
 }
Example #8
0
        /// <summary>
        /// Copies all spatial contexts
        /// </summary>
        /// <param name="spatialContexts">The spatial contexts.</param>
        /// <param name="target">The target.</param>
        /// <param name="overwrite">if set to <c>true</c> [overwrite].</param>
        public virtual void Execute(ICollection<SpatialContextInfo> spatialContexts, FdoConnection target, bool overwrite)
        {
            bool supportsMultipleScs = target.Capability.GetBooleanCapability(CapabilityType.FdoCapabilityType_SupportsMultipleSpatialContexts);
            bool supportsDestroySc = target.Capability.HasArrayCapability(CapabilityType.FdoCapabilityType_CommandList, (int)OSGeo.FDO.Commands.CommandType.CommandType_DestroySpatialContext);

            using (FdoFeatureService service = target.CreateFeatureService())
            {
                if (supportsMultipleScs)
                {
                    if (overwrite && supportsDestroySc)
                    {
                        ReadOnlyCollection<SpatialContextInfo> targetContexts = service.GetSpatialContexts();

                        foreach (SpatialContextInfo sc in spatialContexts)
                        {
                            //Only destroy spatial context if it exists in target connection
                            if(SpatialContextExists(targetContexts, sc))
                                service.DestroySpatialContext(sc);
                        }
                    }
                    foreach (SpatialContextInfo sc in spatialContexts)
                    {
                        service.CreateSpatialContext(sc, overwrite);
                    }
                }
                else
                {
                    List<SpatialContextInfo> contexts = new List<SpatialContextInfo>(spatialContexts);
                    //Copy either the active spatial context in the list or the first
                    //spatial context (if no active one is found)
                    SpatialContextInfo active = null;
                    if (contexts.Count > 0)
                    {
                        foreach (SpatialContextInfo sc in contexts)
                        {
                            if (sc.IsActive)
                            {
                                active = sc;
                                break;
                            }
                        }
                        if (active == null)
                            active = contexts[0];
                    }
                    if(active != null)
                        service.CreateSpatialContext(active, overwrite);
                }
            }
        }
Example #9
0
        /// <summary>
        /// Copies all spatial contexts
        /// </summary>
        /// <param name="source">The source connection</param>
        /// <param name="target">The target connection</param>
        /// <param name="overwrite">If true will overwrite any existing spatial contexts</param>
        public virtual void Execute(FdoConnection source, FdoConnection target, bool overwrite)
        {
            List<string> names = new List<string>();
            using (FdoFeatureService service = source.CreateFeatureService())
            {   
                ReadOnlyCollection<SpatialContextInfo> contexts = service.GetSpatialContexts();
                if (contexts.Count == 0)
                    return;

                foreach (SpatialContextInfo ctx in contexts)
                {
                    names.Add(ctx.Name);
                }
            }
            Execute(source, target, overwrite, names.ToArray());
        }
        /// <summary>
        /// Copies the spatial contexts given in the list
        /// </summary>
        /// <param name="source">The source connection</param>
        /// <param name="target">The target connection</param>
        /// <param name="overwrite">If true will overwrite any existing spatial contexts</param>
        /// <param name="spatialContextNames">The list of spatial contexts to copy</param>
        public override void Execute(FdoConnection source, FdoConnection target, bool overwrite, string [] spatialContextNames)
        {
            if (spatialContextNames.Length == 0)
                return;

            string srcName = spatialContextNames[0];
            FdoFeatureService srcService = source.CreateFeatureService();
            FdoFeatureService destService = target.CreateFeatureService();
            SpatialContextInfo context = srcService.GetSpatialContext(srcName);
            if (context != null)
            {
                //Make sure that CSName != Spatial Context Name
                WKTParser parser = new WKTParser(context.CoordinateSystemWkt);
                if (!string.IsNullOrEmpty(parser.CSName))
                {
                    context.CoordinateSystem = parser.CSName;
                    context.Name = parser.CSName;
                    destService.CreateSpatialContext(context, overwrite);
                }
            }
        }
        public override int Execute()
        {
            CommandStatus retCode;
            FdoConnection conn = null;
            try
            {
                conn = new FdoConnection(_provider, _connStr);
                conn.Open();
            }
            catch (OSGeo.FDO.Common.Exception ex)
            {
                WriteException(ex);
                retCode = CommandStatus.E_FAIL_CONNECT;
                return (int)retCode;
            }

            using (conn)
            {
                using (FdoFeatureService service = conn.CreateFeatureService())
                {
                    try
                    {
                        service.CreateDataStore(_dstoreStr);
                        WriteLine("Data Store Created!");
                        retCode = CommandStatus.E_OK;
                    }
                    catch (OSGeo.FDO.Common.Exception ex)
                    {
                        WriteException(ex);
                        retCode = CommandStatus.E_FAIL_CREATE_DATASTORE;
                        return (int)retCode;
                    }
                }
                if (conn.State != FdoConnectionState.Closed)
                    conn.Close();
            }
            return (int)retCode;
        }
Example #12
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="conn"></param>
 /// <param name="className"></param>
 public FdoOutputOperation(FdoConnection conn, string className)
 {
     _conn = conn;
     _service = conn.CreateFeatureService();
     this.ClassName = className;
 }
        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 static IList<OSGeo.FDO.Schema.ClassDefinition> GetClasses(string title, string message, FdoConnection conn)
 {
     OSGeo.FDO.Schema.FeatureSchemaCollection schemas = null;
     using (FdoFeatureService service = conn.CreateFeatureService())
     {
         schemas = service.DescribeSchema();
     }
     if (schemas != null)
     {
         FdoMultiClassPicker diag = new FdoMultiClassPicker(title, message, schemas);
         if (diag.ShowDialog() == DialogResult.OK)
         {
             return diag.SelectedClasses;
         }
     }
     return null;
 }
        public bool Create()
        {
            bool ok = true;
            FdoConnection conn = new FdoConnection(_view.Provider, GetBaseConnectionString());
            bool created = false;
            bool cleanup = true;
            try
            {
                using (var svc = conn.CreateFeatureService())
                {
                    try
                    {
                        CreateDataStore(svc);
                        created = true;
                    }
                    catch (Exception ex)
                    {
                        _view.ShowError(ex);
                        created = false;
                        ok = false;
                    }
                }

                if (created)
                {
                    //Amend the connection string to include the data store
                    var builder = new DbConnectionStringBuilder();
                    builder.ConnectionString = conn.ConnectionString;
                    builder[_view.DataStoreParameter] = _view.DataStoreName;
                    conn.ConnectionString = builder.ConnectionString;
                    conn.Open();

                    using (var svc = conn.CreateFeatureService())
                    {
                        CreateDefaultSpatialContext(svc);
                    }
                }
            }
            finally
            {
                if (created)
                {
                    if (File.Exists(_view.SchemaFile))
                    {
                        ApplySchemas(conn);
                    }

                    if (_view.ConnectOnCreate)
                    {
                        _connMgr.AddConnection(_view.ConnectionName, conn);
                        cleanup = false;
                    }
                }

                if (cleanup)
                {
                    conn.Close();
                    conn.Dispose();
                }
            }

            return ok;
        }
        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;
        }
        public FdoDataPreviewPresenter(IFdoDataPreviewView view, FdoConnection conn)
        {
            _timer = new Timer();
            _view = view;
            _connection = conn;
            _service = conn.CreateFeatureService();
            _queryViews = new Dictionary<QueryMode, IQuerySubView>();
            _queryWorker = new BackgroundWorker();
            _queryWorker.WorkerReportsProgress = true;
            _queryWorker.WorkerSupportsCancellation = true;
            _queryWorker.DoWork += new DoWorkEventHandler(DoWork);
            //_queryWorker.ProgressChanged += new ProgressChangedEventHandler(ProgressChanged);
            _queryWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted);

            _view.ElapsedMessage = string.Empty;
            _view.CancelEnabled = false;
            _view.ExecuteEnabled = true;

            insertSupported = (Array.IndexOf(conn.Capability.GetArrayCapability(CapabilityType.FdoCapabilityType_CommandList), OSGeo.FDO.Commands.CommandType.CommandType_Insert) >= 0);
            updateSupported = (Array.IndexOf(conn.Capability.GetArrayCapability(CapabilityType.FdoCapabilityType_CommandList), OSGeo.FDO.Commands.CommandType.CommandType_Update) >= 0);
            deleteSupported = (Array.IndexOf(conn.Capability.GetArrayCapability(CapabilityType.FdoCapabilityType_CommandList), OSGeo.FDO.Commands.CommandType.CommandType_Delete) >= 0);

            _view.DeleteEnabled = deleteSupported;
            _view.UpdateEnabled = updateSupported;

            _timer.Interval = 1000;
            _timer.Elapsed += new ElapsedEventHandler(OnTimerElapsed);
        }
 public FdoStandardQueryPresenter(IFdoStandardQueryView view, FdoConnection conn)
 {
     _view = view;
     _conn = conn;
     _service = _conn.CreateFeatureService();
     _view.UseExtendedSelectForOrdering = false;
     bool bExtended = Array.IndexOf(conn.Capability.GetArrayCapability(CapabilityType.FdoCapabilityType_CommandList), CommandType.CommandType_ExtendedSelect) >= 0;
     _view.OrderingEnabled = conn.Capability.GetBooleanCapability(CapabilityType.FdoCapabilityType_SupportsSelectOrdering) || bExtended;
     _view.UseExtendedSelectForOrdering = bExtended;
     _walker = SchemaWalker.GetWalker(conn);
 }
        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);
                    }
                }
            }
        }
Example #20
0
        /// <summary>
        /// Copies the spatial contexts given in the list
        /// </summary>
        /// <param name="source">The source connection</param>
        /// <param name="target">The target connection</param>
        /// <param name="overwrite">If true will overwrite any existing spatial contexts</param>
        /// <param name="spatialContextNames">The list of spatial contexts to copy</param>
        public virtual void Execute(FdoConnection source, FdoConnection target, bool overwrite, string[] spatialContextNames)
        {
            if (spatialContextNames.Length == 0)
                return;

            using (FdoFeatureService sService = source.CreateFeatureService())
            using (FdoFeatureService tService = target.CreateFeatureService())
            {
                bool supportsMultipleScs = target.Capability.GetBooleanCapability(CapabilityType.FdoCapabilityType_SupportsMultipleSpatialContexts);
                bool supportsDestroySc = target.Capability.HasArrayCapability(CapabilityType.FdoCapabilityType_CommandList, (int)OSGeo.FDO.Commands.CommandType.CommandType_DestroySpatialContext);
                if (supportsMultipleScs)
                {
                    //Get all contexts in target
                    ReadOnlyCollection<SpatialContextInfo> contexts = tService.GetSpatialContexts();

                    List<string> updated = new List<string>();
                    //Destroy any clashing ones
                    if (overwrite && supportsDestroySc)
                    {
                        foreach (SpatialContextInfo c in contexts)
                        {
                            if (SpatialContextInSpecifiedList(c, spatialContextNames))
                                tService.DestroySpatialContext(c);
                        }
                    }
                    
                    //Then overwrite them
                    foreach (SpatialContextInfo c in contexts)
                    {
                        if (SpatialContextInSpecifiedList(c, spatialContextNames))
                        {
                            tService.CreateSpatialContext(c, overwrite);
                            updated.Add(c.Name);
                        }
                    }

                    //Now create the rest
                    var sourceScs = sService.GetSpatialContexts();
                    foreach (var sc in sourceScs)
                    {
                        if (!updated.Contains(sc.Name))
                        {
                            tService.CreateSpatialContext(sc, overwrite);
                        }
                    }
                }
                else
                {
                    tService.CreateSpatialContext(sService.GetActiveSpatialContext(), true);
                }
            }
        }
Example #21
0
        /// <summary>
        /// Utility method to create a feature class dump bulk copy
        /// </summary>
        /// <param name="source"></param>
        /// <param name="schemaName"></param>
        /// <param name="className"></param>
        /// <param name="provider"></param>
        /// <param name="savePath"></param>
        /// <returns></returns>
        public static FdoBulkCopy CreateBulkCopy(FdoConnection source, string schemaName, string className, string provider, string savePath)
        {
            if (!ExpressUtility.CreateFlatFileDataSource(provider, savePath))
                throw new FdoException("Could not create " + savePath);

            ClassDefinition srcClass = null;
            using (var svc = source.CreateFeatureService())
            {
                srcClass = svc.GetClassByName(schemaName, className);
            }

            //Apply a copy of the source class to target
            ClassDefinition clone = FdoSchemaUtil.CloneClass(srcClass, true);
            FeatureSchema fs = null;

            FdoConnection target = ExpressUtility.CreateFlatFileConnection(provider, savePath);
            using (var svc = target.CreateFeatureService())
            {
                var schemas = svc.DescribeSchema();
                if (schemas != null && schemas.Count == 1)
                    fs = schemas[0];

                if (fs == null)
                    fs = new FeatureSchema("Default", "");

                var classes = fs.Classes;
                classes.Add(clone);

                svc.ApplySchema(fs, null, true);
            }

            //Setup mappings
            var mappings = new NameValueCollection();
            foreach (PropertyDefinition prop in srcClass.Properties)
            {
                if (prop.PropertyType == PropertyType.PropertyType_DataProperty ||
                    prop.PropertyType == PropertyType.PropertyType_GeometricProperty)
                {
                    mappings.Add(prop.Name, prop.Name);
                }
            }

            //Compile query
            var query = new FeatureQueryOptions(className);

            var bcp = CreateBulkCopy(source, target, schemaName, query, fs.Name, clone.Name, mappings);

            //The target connection needs to be cleaned up when done
            bcp.Options.MarkOwnerOfConnection("TARGET");

            return bcp;
        }
 private static void SetConnectionToolTip(TreeNode connNode, FdoConnection conn)
 {
     using (FdoFeatureService service = conn.CreateFeatureService())
     {
         List<string> ctxStrings = new List<string>();
         try
         {
             ICollection<SpatialContextInfo> contexts = service.GetSpatialContexts();
             foreach (SpatialContextInfo sci in contexts)
             {
                 if (sci.IsActive)
                     ctxStrings.Add("- " + sci.Name + " (Active)");
                 else
                     ctxStrings.Add("- " + sci.Name);
             }
         }
         catch
         {
             ctxStrings.Add("Could not retrieve spatial contexts");
         }
         string configStatus = conn.HasConfiguration ? "(This connection has custom configuration applied)" : string.Empty;
         connNode.ToolTipText = string.Format(
             "Provider: {0}{4}Type: {1}{4}Connection String: {2}{4}Spatial Contexts:{4}{3}{4}{5}",
             conn.Provider,
             conn.DataStoreType,
             conn.SafeConnectionString,
             ctxStrings.Count > 0 ? string.Join("\n", ctxStrings.ToArray()) : "none",
             Environment.NewLine,
             configStatus);
     }
 }
        /// <summary>
        /// Initializes this instance.
        /// </summary>
        protected override void Initialize()
        {
            SendMessage("Creating target data source");
            if (!ExpressUtility.CreateFlatFileDataSource(_outputFile))
                throw new FdoETLException(ResourceUtil.GetStringFormatted("ERR_CANNOT_CREATE_DATA_FILE", _outputFile));

            _outConn = ExpressUtility.CreateFlatFileConnection(_outputFile);
            _outConn.Open();

            ClassDefinition cd = _table.CreateClassDefinition(true);

            using (FdoFeatureService service = _outConn.CreateFeatureService())
            {
                SendMessage("Applying schema to target");
                FeatureSchema schema = new FeatureSchema("Schema1", "Default schema");
                schema.Classes.Add(cd);
                service.ApplySchema(schema);
            }

            SendMessage("Copying any attached spatial contexts");
            ExpressUtility.CopyAllSpatialContexts(_table.SpatialContexts, _outConn, true);

            Register(new FdoFeatureTableInputOperation(_table));
            Register(new FdoOutputOperation(_outConn, cd.Name));
        }
Example #24
0
        /// <summary>
        /// Initializes this instance.
        /// </summary>
        protected override void Initialize()
        {
            var sw = new Stopwatch();
            sw.Start();
            _options.Validate();

            SendMessage("Setting up left and right sides of the join");

            // Abstract:
            //
            // The current built-in join infrastructure is very naive as it uses nested
            // loops. Being a O(m*n) operation, the slowdown becomes readily apparent
            // as the size of the data you're working with increases. As such, the
            // current infrastructure is woefully inadequate for large datasets.
            //
            // How can we fix this problem? We could try to implement various join
            // algorithms for different scenarios, which would be a laborious exercise
            // in itself.
            //
            // Or, we can just delegate this problem to the universal swiss army-knife of
            // databases, SQLite.
            //
            // SQLite has many things going for it, including:
            //  - Support for common types of joins (important!)
            //  - LIGHTING FAST insert performance. The current FdoInputOperation is already optimised for SQLite
            //  - LIGHTING FAST read performance
            //  - Ability to use SQL to modify the database internals, such as creating indexes (FDO provider supports SQL commands)
            //
            // As such, SQLite is the perfect candidate for a temp data store to merge two
            // disparate data sources. The time spent setting up this temp SQLite database (ie. Copying "left" and
            // "right" side data into it) is negligible in the grand scheme of things.
            //
            // Process Overview:
            //
            // 1. Create temp SQLite database
            // 2. Pump left and right sides into this database
            // 3. Create indexes on join columns of both tables (IMPORTANT)
            // 4. Create a view encapsulating our join
            // 5. Copy this view out to our target
            //
            // Additional Notes:
            //
            // We will have to change our supported join types to line up with what SQLite supports, which
            // are:
            //  - INNER JOIN
            //  - LEFT OUTER JOIN
            //
            // SQLite does not support RIGHT OUTER JOINs but these could be emulated by inverting the
            // "left" and "right" tables for the LEFT OUTER JOIN. FULL OUTER JOIN is not supporte by
            // SQLite so this will be removed from our API.
            //
            // Since this SQLite database is temporary, we don't bother with putting
            // the right spatial context in there. Spatial contexts do not (should not) affect
            // the underlying coordinates of any geometries moving to and from the data store.
            //
            // SQLite views by default are represented as non-Feature classes. Geometry properties
            // default to BLOB data types. To "fix" this we need to add a new entry to the geometry_columns
            // metadata table. This may produce an incorrect feature class (ie. Has 1-n geometry properties
            // but no designated one), this is okay as we only care that the properties are there and the
            // temp-target property mappings check out.
            //
            // Although the implementation will change, the requirements remain the same, which are:
            //
            // 1. The target class must not already exist (as it will be created)
            // 2. If no designated geometry is specified, then the class definition will be FdoClass and not FdoFeatureClass

            ClassDefinition leftCls = null;
            ClassDefinition rightCls = null;
            ClassDefinition mergedCls = null;

            using (var leftSvc = _options.Left.Connection.CreateFeatureService())
            using (var rightSvc = _options.Right.Connection.CreateFeatureService())
            {
                leftCls = leftSvc.GetClassByName(_options.Left.SchemaName, _options.Left.ClassName);
                rightCls = rightSvc.GetClassByName(_options.Right.SchemaName, _options.Right.ClassName);

                if (leftCls == null)
                    throw new FdoETLException("Left class not found " + _options.Left.SchemaName + ":" + _options.Left.ClassName);

                if (rightCls == null)
                    throw new FdoETLException("Right class not found " + _options.Right.SchemaName + ":" + _options.Right.ClassName);

                var leftJoinProps = new List<string>(_options.JoinPairs.AllKeys);
                var rightJoinProps = new List<string>();
                foreach (var p in leftJoinProps)
                {
                    rightJoinProps.Add(_options.JoinPairs[p]);
                }

                var leftGeom = (!string.IsNullOrEmpty(_options.GeometryProperty) && _options.Side == JoinSide.Left) ? _options.GeometryProperty : null;
                var rightGeom = (!string.IsNullOrEmpty(_options.GeometryProperty) && _options.Side == JoinSide.Right) ? _options.GeometryProperty : null;

                PrepareClass(leftCls, _options.LeftProperties, leftJoinProps, _options.LeftPrefix, leftGeom);
                PrepareClass(rightCls, _options.RightProperties, rightJoinProps, _options.RightPrefix, rightGeom);

                mergedCls = CreateMergedClass(leftCls, rightCls);
            }

            var dprops = new NameValueCollection();
            dprops["File"] = Path.GetTempFileName();

            var tempSchema = new FeatureSchema("Default", "");
            var leftCopy = FdoSchemaUtil.CloneClass(leftCls);
            var rightCopy = FdoSchemaUtil.CloneClass(rightCls);

            string leftClassName = "LEFT_SIDE";
            string rightClassName = "RIGHT_SIDE";

            leftCopy.Name = leftClassName;
            rightCopy.Name = rightClassName;

            tempSchema.Classes.Add(leftCopy);
            tempSchema.Classes.Add(rightCopy);

            //Create SQLite database
            Register(new FdoCreateDataStoreOperation("OSGeo.SQLite", dprops, null));

            //Apply temp schema
            var tempConn = new FdoConnection("OSGeo.SQLite", "File=" + dprops["File"]);
            Register(new FdoApplySchemaOperation(tempConn, tempSchema));

            #if DEBUG
            Register(new FdoSingleActionOperation(() => { SendMessage("Temp db created in: " + dprops["File"]); }));
            #endif

            //Prep property mappings for bulk copy
            var leftMaps = new NameValueCollection();
            var rightMaps = new NameValueCollection();

            var leftQuery = new FeatureQueryOptions(leftCls.Name);
            var rightQuery = new FeatureQueryOptions(rightCls.Name);

            foreach (var leftp in _options.LeftProperties)
            {
                if (string.IsNullOrEmpty(_options.LeftPrefix))
                    leftMaps.Add(leftp, leftp);
                else
                    leftMaps.Add(leftp, _options.LeftPrefix + leftp);
                leftQuery.AddFeatureProperty(leftp);
            }
            foreach (var rightp in _options.RightProperties)
            {
                if (string.IsNullOrEmpty(_options.RightPrefix))
                    rightMaps.Add(rightp, rightp);
                else
                    rightMaps.Add(rightp, _options.RightPrefix + rightp);
                rightQuery.AddFeatureProperty(rightp);
            }

            if (!string.IsNullOrEmpty(_options.LeftFilter))
                leftQuery.Filter = _options.LeftFilter;

            if (!string.IsNullOrEmpty(_options.RightFilter))
                rightQuery.Filter = _options.RightFilter;

            //don't forget join keys
            foreach (string l in _options.JoinPairs.Keys)
            {
                string r = _options.JoinPairs[l];

                if (!_options.LeftProperties.Contains(l))
                {
                    leftQuery.AddFeatureProperty(l);

                    if (string.IsNullOrEmpty(_options.LeftPrefix))
                        leftMaps.Add(l, l);
                    else
                        leftMaps.Add(l, _options.LeftPrefix + l);
                }

                if (!_options.RightProperties.Contains(r))
                {
                    rightQuery.AddFeatureProperty(r);

                    if (string.IsNullOrEmpty(_options.RightPrefix))
                        rightMaps.Add(r, r);
                    else
                        rightMaps.Add(r, _options.RightPrefix + r);
                }

            }

            //don't forget geometry!
            if (!string.IsNullOrEmpty(_options.GeometryProperty))
            {
                if (_options.Side == JoinSide.Left)
                {
                    if (!leftQuery.PropertyList.Contains(_options.GeometryProperty))
                    {
                        leftQuery.AddFeatureProperty(_options.GeometryProperty);

                        if (string.IsNullOrEmpty(_options.LeftPrefix))
                            leftMaps.Add(_options.GeometryProperty, _options.GeometryProperty);
                        else
                            leftMaps.Add(_options.GeometryProperty, _options.LeftPrefix + _options.GeometryProperty);
                    }
                }
                else
                {
                    if (!rightQuery.PropertyList.Contains(_options.GeometryProperty))
                    {
                        rightQuery.AddFeatureProperty(_options.GeometryProperty);

                        if (string.IsNullOrEmpty(_options.RightPrefix))
                            rightMaps.Add(_options.GeometryProperty, _options.GeometryProperty);
                        else
                            rightMaps.Add(_options.GeometryProperty, _options.RightPrefix + _options.GeometryProperty);
                    }
                }
            }

            var copyLeftErrors = new List<Exception>();
            var copyRightErrors = new List<Exception>();
            var copyTargetErrors = new List<Exception>();

            //Copy left source
            ParameterlessAction copyLeft = () =>
            {
                SendMessage("Copying left source with filter: " + _options.LeftFilter);
                var copy = ExpressUtility.CreateBulkCopy(
                    _options.Left.Connection,
                    tempConn,
                    _options.Left.SchemaName,
                    leftQuery,
                    tempSchema.Name,    //temp sqlite schema name
                    leftClassName,      //sqlite "left" class name
                    leftMaps);

                copy.ProcessMessage += delegate(object sender, MessageEventArgs e)
                {
                    SendMessage(e.Message);
                };
                copy.Execute();
                copyLeftErrors.AddRange(copy.GetAllErrors());
            };
            Register(new FdoSingleActionOperation(copyLeft));

            //Register(new FdoInputOperation(_options.Left.Connection, leftQuery));
            //Register(new FdoOutputOperation(tempConn, leftClassName, leftMaps));

            //Copy right source
            ParameterlessAction copyRight = () =>
            {
                SendMessage("Copying right source with filter: " + _options.RightFilter);
                var copy = ExpressUtility.CreateBulkCopy(
                    _options.Right.Connection,
                    tempConn,
                    _options.Right.SchemaName,
                    rightQuery,
                    tempSchema.Name,    //temp sqlite schema name
                    rightClassName,      //sqlite "right" class name
                    rightMaps);

                copy.ProcessMessage += delegate(object sender, MessageEventArgs e)
                {
                    SendMessage(e.Message);
                };
                copy.Execute();
                copyRightErrors.AddRange(copy.GetAllErrors());
            };
            Register(new FdoSingleActionOperation(copyRight));

            //Register(new FdoInputOperation(_options.Right.Connection, rightQuery));
            //Register(new FdoOutputOperation(tempConn, rightClassName, rightMaps));

            string srcClass = "VIEW_INPUT";

            //Create indexes on left and right sides to optimize read performance
            ParameterlessAction indexLeft = () =>
            {
                using (var svc = tempConn.CreateFeatureService())
                {
                    SendMessage("Creating left side index in temp db");
                    string sql = "CREATE INDEX IDX_LEFT_ID ON " + leftClassName + "(";
                    var tokens = new List<string>();
                    foreach (string p in _options.JoinPairs.Keys)
                    {
                        if (!string.IsNullOrEmpty(_options.LeftPrefix))
                            tokens.Add(_options.LeftPrefix + p);
                        else
                            tokens.Add(p);
                    }
                    sql = sql + string.Join(", ", tokens.ToArray()) + ")";
                    SendMessage("Executing SQL: " + sql);
                    svc.ExecuteSQLNonQuery(sql);
                }
            };
            ParameterlessAction indexRight = () =>
            {
                using (var svc = tempConn.CreateFeatureService())
                {
                    SendMessage("Creating right side index in temp db");
                    string sql = "CREATE INDEX IDX_RIGHT_ID ON " + rightClassName + "(";
                    var tokens = new List<string>();
                    foreach (string p in _options.JoinPairs.Keys)
                    {
                        string prop = _options.JoinPairs[p];
                        if (!string.IsNullOrEmpty(_options.RightPrefix))
                            tokens.Add(_options.RightPrefix + prop);
                        else
                            tokens.Add(prop);
                    }
                    sql = sql + string.Join(", ", tokens.ToArray()) + ")";
                    SendMessage("Executing SQL: " + sql);
                    svc.ExecuteSQLNonQuery(sql);
                }
            };
            Register(new FdoSingleActionOperation(indexLeft));
            Register(new FdoSingleActionOperation(indexRight));

            //Create view
            ParameterlessAction createView = () =>
            {
                using (var svc = tempConn.CreateFeatureService())
                {
                    SendMessage("Creating view in temp db");
                    StringBuilder sql = new StringBuilder("CREATE VIEW ");
                    sql.Append(srcClass + " AS SELECT ");
                    foreach (var p in _options.LeftProperties)
                    {
                        if (!string.IsNullOrEmpty(_options.LeftPrefix))
                            sql.Append("l." + _options.LeftPrefix + p + ", ");
                        else
                            sql.Append("l." + p + ", ");
                    }

                    if (!string.IsNullOrEmpty(_options.GeometryProperty))
                    {
                        if (_options.Side == JoinSide.Left)
                        {
                            if (!_options.LeftProperties.Contains(_options.GeometryProperty))
                            {
                                if (!string.IsNullOrEmpty(_options.LeftPrefix))
                                    sql.Append("l." + _options.LeftPrefix + _options.GeometryProperty + ", ");
                                else
                                    sql.Append("l." + _options.GeometryProperty + ", ");
                            }
                        }
                        else
                        {
                            if (!_options.RightProperties.Contains(_options.GeometryProperty))
                            {
                                if (!string.IsNullOrEmpty(_options.RightPrefix))
                                    sql.Append("r." + _options.RightPrefix + _options.GeometryProperty + ", ");
                                else
                                    sql.Append("r." + _options.GeometryProperty + ", ");
                            }
                        }
                    }

                    int rc = _options.RightProperties.Count;
                    int i = 0;
                    foreach (var p in _options.RightProperties)
                    {
                        string pn = p;
                        if (!string.IsNullOrEmpty(_options.RightPrefix))
                            pn = _options.RightPrefix + pn;

                        if (i == rc - 1)
                            sql.Append("r." + pn + " FROM ");
                        else
                            sql.Append("r." + pn + ", ");
                        i++;
                    }
                    sql.Append(leftClassName + " l ");

                    switch (_options.JoinType)
                    {
                        case FdoJoinType.Inner:
                            sql.Append("INNER JOIN " + rightClassName + " r ON ");
                            break;
                        case FdoJoinType.Left:
                            sql.Append("LEFT OUTER JOIN " + rightClassName + " r ON ");
                            break;
                        default:
                            throw new FdoETLException("Unsupported join type: " + _options.JoinType);
                    }

                    rc = _options.JoinPairs.Count;
                    i = 0;
                    foreach (string l in _options.JoinPairs.Keys)
                    {
                        string r = _options.JoinPairs[l];

                        string left = l;
                        string right = r;

                        if (!string.IsNullOrEmpty(_options.LeftPrefix))
                            left = _options.LeftPrefix + left;

                        if (!string.IsNullOrEmpty(_options.RightPrefix))
                            right = _options.RightPrefix + right;

                        if (i == rc - 1)
                            sql.Append("l." + left + " = r." + right);
                        else
                            sql.Append("l." + left + " = r." + right + " AND ");

                        i++;
                    }
                    SendMessage("Executing SQL: " + sql.ToString());
                    svc.ExecuteSQLNonQuery(sql.ToString());
                }
            };
            Register(new FdoSingleActionOperation(createView));

            //Hack FDO metadata to make this a feature class
            if (!string.IsNullOrEmpty(_options.GeometryProperty))
            {
                ParameterlessAction reg = () =>
                {
                    using (var svc = tempConn.CreateFeatureService())
                    {
                        SendMessage("Exposing view as a FDO feature class");
                        string sql = "INSERT INTO geometry_columns(f_table_name, f_geometry_column, geometry_type, geometry_dettype, coord_dimension, srid, geometry_format) VALUES('" + srcClass + "','" + _options.GeometryProperty + "',15,7743,0,0,'FGF')";
                        SendMessage("Executing SQL: " + sql.ToString());
                        svc.ExecuteSQLNonQuery(sql);
                    }
                };
                Register(new FdoSingleActionOperation(reg));
            }

            //Copy view to target
            ParameterlessAction applyTarget = () =>
            {
                using (var svc = _options.Target.Connection.CreateFeatureService())
                {
                    SendMessage("Fetching target schema");
                    var schema = svc.GetSchemaByName(_options.Target.SchemaName);

                    IncompatibleClass cls;
                    if (!svc.CanApplyClass(mergedCls, out cls))
                    {
                        SendMessage("Fixing incompatibilities in merged class");
                        mergedCls = svc.AlterClassDefinition(mergedCls, cls);
                    }

                    SendMessage("Adding merged class to target schema");
                    schema.Classes.Add(mergedCls);
                    SendMessage("Applying modified target schema");
                    svc.ApplySchema(schema);
                }
            };
            Register(new FdoSingleActionOperation(applyTarget));

            var tempQuery = new FeatureQueryOptions("VIEW_INPUT");
            var targetMapping = new NameValueCollection();
            foreach(PropertyDefinition p in mergedCls.Properties)
            {
                tempQuery.AddFeatureProperty(p.Name);
                //Target class is a replica of the temp one, so all properties
                //have the same name in both source and target
                targetMapping[p.Name] = p.Name;
            }

            ParameterlessAction copyToTarget = () =>
            {
                var copy = ExpressUtility.CreateBulkCopy(
                    tempConn,
                    _options.Target.Connection,
                    tempSchema.Name,
                    tempQuery,
                    _options.Target.SchemaName,
                    _options.Target.ClassName,
                    targetMapping);

                copy.ProcessMessage += delegate(object sender, MessageEventArgs e)
                {
                    SendMessage(e.Message);
                };
                copy.Execute();
                copyTargetErrors.AddRange(copy.GetAllErrors());
                sw.Stop();
            };
            Register(new FdoSingleActionOperation(copyToTarget));

            //Log all errors
            ParameterlessAction logErrors = () =>
            {
                SendMessage(copyLeftErrors.Count + " errors encountered copying left source to temp db");
                _allErrors.AddRange(copyLeftErrors);
                SendMessage(copyRightErrors.Count + " errors encountered copying right source to temp db");
                _allErrors.AddRange(copyRightErrors);
                SendMessage(copyTargetErrors.Count + " errors encountered copying merged source to target");
                _allErrors.AddRange(copyTargetErrors);
                SendMessage("Join Operation completed in " + sw.Elapsed.ToString());
            };
            Register(new FdoSingleActionOperation(logErrors));
        }