public void CopySpatialContexts()
        {
            List <SpatialContextInfo> contexts   = new List <SpatialContextInfo>();
            FdoConnection             srcConn    = _connMgr.GetConnection(_view.SourceConnectionName);
            FdoConnection             targetConn = _connMgr.GetConnection(_view.SelectedTargetConnectionName);

            using (FdoFeatureService service = srcConn.CreateFeatureService())
            {
                foreach (string ctxName in _view.SpatialContexts)
                {
                    SpatialContextInfo sc = service.GetSpatialContext(ctxName);
                    if (sc != null)
                    {
                        contexts.Add(sc);
                    }
                }
            }

            if (contexts.Count == 0)
            {
                _view.ShowMessage(null, ResourceService.GetString("MSG_NO_SPATIAL_CONTEXTS_COPIED"));
                return;
            }

            ExpressUtility.CopyAllSpatialContexts(contexts, targetConn, _view.Overwrite);
            _view.ShowMessage(null, ResourceService.GetString("MSG_SPATIAL_CONTEXTS_COPIED"));
            _view.Close();
        }
        /// <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 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);
                }
            }
        }
        void DoWork(object sender, DoWorkEventArgs e)
        {
            IFdoReader reader = null;

            using (FdoFeatureService service = _connection.CreateFeatureService())
            {
                try
                {
                    if (e.Argument is FeatureAggregateOptions)
                    {
                        reader = service.SelectAggregates((FeatureAggregateOptions)e.Argument);
                    }
                    else if (e.Argument is StandardQuery)
                    {
                        var stdArg = (e.Argument as StandardQuery);
                        reader = service.SelectFeatures(stdArg.query, stdArg.Limit, stdArg.UseExtendedSelect);
                    }
                    else if (e.Argument is string)
                    {
                        reader = service.ExecuteSQLQuery(e.Argument.ToString());
                    }

                    //Init the data grid view
                    FdoFeatureTable table = new FdoFeatureTable();

                    table.RequestSpatialContext += delegate(object o, string name)
                    {
                        SpatialContextInfo c = service.GetSpatialContext(name);
                        if (c != null)
                        {
                            table.AddSpatialContext(c);
                        }
                    };

                    ClassDefinition clsDef   = null;
                    bool            hasJoins = false;
                    if (e.Argument is StandardQuery)
                    {
                        var qry = ((StandardQuery)e.Argument).query;
                        clsDef   = service.GetClassByName(qry.ClassName); //TODO: Should really qualify this, but our input parameters do not specify a schema
                        hasJoins = qry.JoinCriteria.Count > 0;
                    }
                    table.InitTable(reader, clsDef, hasJoins);

                    // need to store object class defn outside loop
                    ClassDefinition classDefObject = null;
                    ClassDefinition classDefAssoc  = null;

                    while (reader.ReadNext() && !_queryWorker.CancellationPending)
                    {
                        //Pass processed feature to data grid view
                        FdoFeature feat = table.NewRow();
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            string name = reader.GetName(i);
                            if (!reader.IsNull(name))
                            {
                                FdoPropertyType pt = reader.GetFdoPropertyType(name);

                                switch (pt)
                                {
                                case FdoPropertyType.Association:
                                    // TODO: how to handle for non-StandardQuery
                                    if (e.Argument is StandardQuery)
                                    {
                                        // because the original code used an iterator over the reader.FieldCount
                                        // it is a bit of a hack to get another definition of the class and check
                                        // we are at the right property with a name comparison
                                        // TODO: code review to see if this can be implemented better
                                        FdoFeatureReader readerFeature = (FdoFeatureReader)reader;
                                        ClassDefinition  classDef      = readerFeature.GetClassDefinition();

                                        foreach (PropertyDefinition propertyDef in classDef.Properties)
                                        {
                                            // only looking for the right association
                                            if ((PropertyType.PropertyType_AssociationProperty == propertyDef.PropertyType) &&
                                                (propertyDef.Name.Equals(name)))
                                            {
                                                AssociationPropertyDefinition assocProp = (AssociationPropertyDefinition)propertyDef;
                                                ClassDefinition classAssoc = assocProp.AssociatedClass;

                                                // get a reader from the association - nice!
                                                IFeatureReader readerAssoc = readerFeature.GetFeatureObject(name);
                                                if ((null != readerAssoc) && (readerAssoc.ReadNext()))
                                                {
                                                    // TODO: this should be an iterative function

                                                    // the simple reassignment on each instance fails
                                                    //  (classDefObject.Properties is always zero after first record)
                                                    //  so have set classDefObject higher-up and re-use/
                                                    //   - problem will occur if more than one association
                                                    // ClassDefinition classDefObject = readerObject.GetClassDefinition();
                                                    if (null == classDefAssoc)
                                                    {
                                                        classDefAssoc = readerAssoc.GetClassDefinition();
                                                    }

                                                    foreach (PropertyDefinition propertyDefAssoc in classDefAssoc.Properties)
                                                    {
                                                        String nameAssoc = propertyDefAssoc.Name;

                                                        // TODO: only "data" type handled at present
                                                        if (PropertyType.PropertyType_DataProperty == propertyDefAssoc.PropertyType)
                                                        {
                                                            DataPropertyDefinition datapropertyDefAssoc = (DataPropertyDefinition)propertyDefAssoc;

                                                            String   szFullName = name + "." + nameAssoc;
                                                            DataType ptAssoc    = datapropertyDefAssoc.DataType;
                                                            // TODO: handle all types
                                                            switch (ptAssoc)
                                                            {
                                                            case DataType.DataType_String:
                                                                feat[szFullName] = readerAssoc.GetString(nameAssoc);
                                                                break;

                                                            case DataType.DataType_Int16:
                                                                feat[szFullName] = readerAssoc.GetInt16(nameAssoc);
                                                                break;

                                                            case DataType.DataType_Int32:
                                                                feat[szFullName] = readerAssoc.GetInt32(nameAssoc);
                                                                break;

                                                            case DataType.DataType_Int64:
                                                                feat[szFullName] = readerAssoc.GetInt64(nameAssoc);
                                                                break;
                                                            }
                                                        }
                                                    }
                                                    readerAssoc.Close();
                                                }
                                            }
                                        }
                                    }
                                    break;

                                case FdoPropertyType.BLOB:
                                    feat[name] = reader.GetLOB(name).Data;
                                    break;

                                case FdoPropertyType.Boolean:
                                    feat[name] = reader.GetBoolean(name);
                                    break;

                                case FdoPropertyType.Byte:
                                    feat[name] = reader.GetByte(name);
                                    break;

                                case FdoPropertyType.CLOB:
                                    feat[name] = reader.GetLOB(name).Data;
                                    break;

                                case FdoPropertyType.DateTime:
                                {
                                    try
                                    {
                                        feat[name] = reader.GetDateTime(name);
                                    }
                                    catch         //Unrepresentable dates
                                    {
                                        feat[name] = DBNull.Value;
                                    }
                                }
                                break;

                                case FdoPropertyType.Decimal:     //We should probably remove this as FDO coerces decimals to doubles (otherwise why is there not a GetDecimal() method in FdoIReader?)
                                {
                                    double val = reader.GetDouble(name);
                                    if (Double.IsNaN(val))
                                    {
                                        feat[name] = DBNull.Value;
                                    }
                                    else
                                    {
                                        feat[name] = Convert.ToDecimal(val);
                                    }
                                }
                                break;

                                case FdoPropertyType.Double:
                                    feat[name] = reader.GetDouble(name);
                                    break;

                                case FdoPropertyType.Geometry:
                                {
                                    try
                                    {
                                        byte[] fgf = reader.GetGeometry(name);
                                        OSGeo.FDO.Geometry.IGeometry geom = service.GeometryFactory.CreateGeometryFromFgf(fgf);
                                        var fg = new FdoGeometry(geom);
                                        //OGR geometry trap
                                        using (var env = fg.Envelope) { }
                                        feat[name] = fg;
                                    }
                                    catch
                                    {
                                        feat[name] = DBNull.Value;
                                    }
                                }
                                break;

                                case FdoPropertyType.Int16:
                                    feat[name] = reader.GetInt16(name);
                                    break;

                                case FdoPropertyType.Int32:
                                    feat[name] = reader.GetInt32(name);
                                    break;

                                case FdoPropertyType.Int64:
                                    feat[name] = reader.GetInt64(name);
                                    break;

                                case FdoPropertyType.Object:
                                    // TODO: how to handle for non-StandardQuery
                                    if (e.Argument is StandardQuery)
                                    {
                                        // because the original code used an iterator over the reader.FieldCount
                                        // it is a bit of a hack to get another definition of the class and check
                                        // we are at the right property with a name comparison
                                        // TODO: code review to see if this can be implemented better
                                        FdoFeatureReader readerFeature = (FdoFeatureReader)reader;
                                        ClassDefinition  classDef      = readerFeature.GetClassDefinition();

                                        foreach (PropertyDefinition propertyDef in classDef.Properties)
                                        {
                                            // only looking for the right object
                                            if ((PropertyType.PropertyType_ObjectProperty == propertyDef.PropertyType) &&
                                                (propertyDef.Name.Equals(name)))
                                            {
                                                ObjectPropertyDefinition assocProp  = (ObjectPropertyDefinition)propertyDef;
                                                ClassDefinition          classAssoc = assocProp.Class;

                                                // get a reader from the object - nice!
                                                IFeatureReader readerObject = readerFeature.GetFeatureObject(name);
                                                if ((null != readerObject) && (readerObject.ReadNext()))
                                                {
                                                    // TODO: this should be an iterative function

                                                    // the simple reassignment on each instance fails
                                                    //  (classDefObject.Properties is always zero after first record)
                                                    //  so have set classDefObject higher-up and re-use/
                                                    //   - problem will occur if more than one association
                                                    // ClassDefinition classDefObject = readerObject.GetClassDefinition();
                                                    if (null == classDefObject)
                                                    {
                                                        classDefObject = readerObject.GetClassDefinition();
                                                    }

                                                    foreach (PropertyDefinition propertyDefObject in classDefObject.Properties)
                                                    {
                                                        String nameObject = propertyDefObject.Name;

                                                        // TODO: only "data" type handled at present
                                                        if (PropertyType.PropertyType_DataProperty == propertyDefObject.PropertyType)
                                                        {
                                                            DataPropertyDefinition datapropertyDefObject = (DataPropertyDefinition)propertyDefObject;

                                                            String   szFullName = name + "." + nameObject;
                                                            DataType ptAssoc    = datapropertyDefObject.DataType;
                                                            // TODO: handle all types
                                                            switch (ptAssoc)
                                                            {
                                                            case DataType.DataType_String:
                                                                feat[szFullName] = readerObject.GetString(nameObject);
                                                                break;

                                                            case DataType.DataType_Int16:
                                                                feat[szFullName] = readerObject.GetInt16(nameObject);
                                                                break;

                                                            case DataType.DataType_Int32:
                                                                feat[szFullName] = readerObject.GetInt32(nameObject);
                                                                break;

                                                            case DataType.DataType_Int64:
                                                                feat[szFullName] = readerObject.GetInt64(nameObject);
                                                                break;
                                                            }
                                                        }
                                                    }
                                                    readerObject.Close();
                                                    readerObject = null;
                                                }
                                            }
                                        }
                                    }
                                    break;

                                //case FdoPropertyType.Raster:
                                case FdoPropertyType.Single:
                                    feat[name] = reader.GetSingle(name);
                                    break;

                                case FdoPropertyType.String:
                                    feat[name] = reader.GetString(name);
                                    break;
                                }
                            }
                            else
                            {
                                feat[name] = DBNull.Value;
                            }
                        }
                        table.AddRow(feat);

                        if (table.Rows.Count % 50 == 0)
                        {
                            System.Threading.Thread.Sleep(50);
                        }
                    }

                    if (_queryWorker.CancellationPending)
                    {
                        e.Cancel      = true;
                        _cancelResult = table;
                    }
                    else
                    {
                        e.Result = table;
                    }
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                    }
                }
            }
        }
        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);
        }