/// <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(); } }
public static SchemaWalker GetWalker(FdoConnection conn) { using (var svc = conn.CreateFeatureService()) { if (svc.SupportsPartialSchemaDiscovery()) return new PartialSchemaWalker(conn); else return new FullSchemaWalker(conn); } }
/// <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); } } }
/// <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; }
/// <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); } } } }
/// <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); } } }
/// <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)); }
/// <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)); }