public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity) { if (process == null) { return; } var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline; builder.Register(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); IPipeline pipeline; context.Debug(() => $"Registering {type} for entity {entity.Alias}."); var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController(); switch (type) { case "parallel.linq": pipeline = new ParallelPipeline(new DefaultPipeline(outputController, context)); break; default: pipeline = new DefaultPipeline(outputController, context); break; } var provider = process.Output().Provider; // TODO: rely on IInputProvider's Read method instead (after every provider has one) pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null); // transform if (!process.ReadOnly) { pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); } pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), context.GetAllEntityFields().Where(f => !f.System))); pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any()))); pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any()))); if (!process.ReadOnly) { pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); if (provider == "sqlserver") { pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1))); } } // writer, TODO: rely on IOutputProvider instead pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null); // updater pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key)); return(pipeline); }).Named <IPipeline>(entity.Key); }
public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity) { if (process == null) { return; } var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline; builder.Register(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); IPipeline pipeline; context.Debug(() => $"Registering {type} for entity {entity.Alias}."); switch (type) { case "parallel.linq": pipeline = new ParallelPipeline(new DefaultPipeline(ctx.ResolveNamed <IOutputController>(entity.Key), context)); break; default: pipeline = new DefaultPipeline(ctx.ResolveNamed <IOutputController>(entity.Key), context); break; } var provider = process.Output().Provider; // extract pipeline.Register(ctx.ResolveNamed <IRead>(entity.Key)); // transform pipeline.Register(new SetBatchId(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity, entity.TflBatchId()))); pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), context.GetAllEntityFields())); pipeline.Register(TransformFactory.GetTransforms(ctx, process, entity, entity.GetAllFields().Where(f => f.Transforms.Any()))); pipeline.Register(new SetKey(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity, entity.TflKey()))); pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); if (provider == "sqlserver") { pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1))); } //load pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : new NullWriter()); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? ctx.ResolveNamed <IUpdate>(entity.Key) : new NullUpdater()); return(pipeline); }).Named <IPipeline>(entity.Key); }
public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity) { if (process == null) { return; } var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline; builder.Register(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); IPipeline pipeline; context.Debug(() => $"Registering {type} for entity {entity.Alias}."); var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController(); pipeline = new DefaultPipeline(outputController, context); // TODO: rely on IInputProvider's Read method instead (after every provider has one) pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null); // transforms if (!process.ReadOnly) { pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); } // pipeline.Register(new CancelTransform(context)); may create a problem when canceling without the intention to run full init afterwards pipeline.Register(new IncrementTransform(context)); pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields().Where(f => !f.System))); pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any()))); pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any()))); if (!process.ReadOnly) { pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); } pipeline.Register(new LogTransform(context)); // writer, TODO: rely on IOutputProvider instead pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null); // updater pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key)); return(pipeline); }).Named <IPipeline>(entity.Key); }
public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity) { if (process == null) { return; } var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline; builder.Register(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); context.Debug(() => string.Format("Registering {0} for entity {1}.", type, entity.Alias)); var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController(); var pipeline = new DefaultPipeline(outputController, context); var output = process.Output(); // extract pipeline.Register(ctx.ResolveNamed <IRead>(entity.Key)); // transform if (!process.ReadOnly) { pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity, entity.TflBatchId()))); } pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), context.GetAllEntityFields().Where(f => !f.System))); pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any()))); pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any()))); if (!process.ReadOnly) { pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); if (output.Provider == "sqlserver") { pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1))); } } // writer, TODO: rely on IOutputProvider instead pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null); // updater pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key)); return(pipeline); }).Named <IPipeline>(entity.Key); }
protected override void Load(ContainerBuilder builder) { if (_process == null) { return; } // Connections foreach (var c in _process.Connections.Where(cn => cn.Provider == "lucene")) { switch (c.Provider) { case "lucene": // Analyzers builder.Register <Analyzer>(ctx => new KeywordAnalyzer()).Named <Analyzer>(DefaultAnalyzer); foreach (var analyzer in _process.SearchTypes.Where(st => st.Analyzer != string.Empty && st.Analyzer != DefaultAnalyzer).Select(st => st.Analyzer).Distinct()) { switch (analyzer) { case "simple": builder.Register <Analyzer>(ctx => new SimpleAnalyzer()).Named <Analyzer>(analyzer); break; case "whitespace": builder.Register <Analyzer>(ctx => new WhitespaceAnalyzer()).Named <Analyzer>(analyzer); break; case "standard": builder.Register <Analyzer>(ctx => new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30)).Named <Analyzer>(analyzer); break; default: builder.Register <Analyzer>(ctx => new KeywordAnalyzer()).Named <Analyzer>(analyzer); break; } } // entity index writers foreach (var e in _process.Entities) { // Directory builder.Register(ctx => new DirectoryFactory(Path.Combine(c.Folder, e.Alias))).Named <DirectoryFactory>(e.Key); // Per Field Analyzer builder.Register <Analyzer>(ctx => { var analyzers = new PerFieldAnalyzerWrapper(ctx.ResolveNamed <Analyzer>(DefaultAnalyzer)); var context = ctx.ResolveNamed <OutputContext>(e.Key); foreach (var field in new FieldSearchTypes(context.Process, context.OutputFields)) { if (field.SearchType.Name != "none") { analyzers.AddAnalyzer(field.Alias, ctx.ResolveNamed <Analyzer>(field.SearchType.Analyzer == string.Empty ? DefaultAnalyzer : field.SearchType.Analyzer)); } } return(analyzers); }).Named <Analyzer>(e.Key + ReadFrom.Output); builder.Register <Analyzer>(ctx => { var analyzers = new PerFieldAnalyzerWrapper(ctx.ResolveNamed <Analyzer>(DefaultAnalyzer)); var context = ctx.ResolveNamed <InputContext>(e.Key); foreach (var field in new FieldSearchTypes(context.Process, context.InputFields)) { if (field.SearchType.Name != "none") { analyzers.AddAnalyzer(field.Field.Name, ctx.ResolveNamed <Analyzer>(field.SearchType.Analyzer == string.Empty ? DefaultAnalyzer : field.SearchType.Analyzer)); } } return(analyzers); }).Named <Analyzer>(e.Key + ReadFrom.Input); // Index Writer Factory builder.Register(ctx => new IndexWriterFactory(ctx.ResolveNamed <DirectoryFactory>(e.Key), ctx.ResolveNamed <Analyzer>(e.Key + ReadFrom.Output))).Named <IndexWriterFactory>(e.Key); // Index Reader Factory builder.Register(ctx => new IndexReaderFactory(ctx.ResolveNamed <DirectoryFactory>(e.Key), ctx.ResolveNamed <IndexWriterFactory>(e.Key))).Named <IndexReaderFactory>(e.Key); // Index Searcher Factory builder.Register(ctx => new SearcherFactory(ctx.ResolveNamed <IndexReaderFactory>(e.Key))).Named <SearcherFactory>(e.Key); } break; } } // entity input foreach (var entity in _process.Entities.Where(e => _process.Connections.First(c => c.Name == e.Connection).Provider == "lucene")) { // INPUT VERSION DETECTOR builder.Register <IInputVersionDetector>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); switch (input.Connection.Provider) { case "lucene": return(new LuceneInputVersionDetector(input, ctx.ResolveNamed <SearcherFactory>(entity.Key))); default: return(new NullVersionDetector()); } }).Named <IInputVersionDetector>(entity.Key); // INPUT READER builder.Register <IRead>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity)); switch (input.Connection.Provider) { case "lucene": return(new LuceneReader(input, input.InputFields, ctx.ResolveNamed <SearcherFactory>(entity.Key), ctx.ResolveNamed <Analyzer>(entity.Key + ReadFrom.Input), ctx.ResolveNamed <IndexReaderFactory>(entity.Key), rowFactory, ReadFrom.Input)); default: return(new NullReader(input, false)); } }).Named <IRead>(entity.Key); } // entity output if (_process.Output().Provider == "lucene") { // PROCESS OUTPUT CONTROLLER builder.Register <IOutputController>(ctx => new NullOutputController()).As <IOutputController>(); // PROCESS INITIALIZER builder.Register <IInitializer>(ctx => { var output = ctx.Resolve <OutputContext>(); return(new LuceneInitializer(output)); }).As <IInitializer>(); foreach (var entity in _process.Entities) { // UPDATER builder.Register <IUpdate>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); output.Warn($"{output.Connection.Provider} does not denormalize."); return(new NullMasterUpdater()); }).Named <IUpdate>(entity.Key); // OUTPUT builder.Register <IOutputController>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "lucene": return(new LuceneOutputController( output, new NullInitializer(), ctx.ResolveNamed <IInputVersionDetector>(entity.Key), new LuceneOutputVersionDetector(output, ctx.ResolveNamed <SearcherFactory>(entity.Key)), ctx.ResolveNamed <SearcherFactory>(entity.Key), ctx.ResolveNamed <IndexReaderFactory>(entity.Key) )); default: return(new NullOutputController()); } }).Named <IOutputController>(entity.Key); // WRITER builder.Register <IWrite>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "lucene": return(new LuceneWriter(output, ctx.ResolveNamed <IndexWriterFactory>(entity.Key), ctx.ResolveNamed <SearcherFactory>(entity.Key))); default: return(new NullWriter(output)); } }).Named <IWrite>(entity.Key); // DELETE HANDLER if (entity.Delete) { builder.Register <IEntityDeleteHandler>(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); var inputContext = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", inputContext.RowCapacity)); IRead input = new NullReader(context); var primaryKey = entity.GetPrimaryKey(); switch (inputContext.Connection.Provider) { case "lucene": input = new LuceneReader( inputContext, primaryKey, ctx.ResolveNamed <SearcherFactory>(entity.Key), ctx.ResolveNamed <Analyzer>(entity.Key + ReadFrom.Input), ctx.ResolveNamed <IndexReaderFactory>(entity.Key), rowFactory, ReadFrom.Input); break; } IRead output = new NullReader(context); IDelete deleter = new NullDeleter(context); var outputConnection = _process.Output(); var outputContext = ctx.ResolveNamed <OutputContext>(entity.Key); switch (outputConnection.Provider) { case "lucene": output = new LuceneReader( outputContext, primaryKey, ctx.ResolveNamed <SearcherFactory>(entity.Key), ctx.ResolveNamed <Analyzer>(entity.Key + ReadFrom.Output), ctx.ResolveNamed <IndexReaderFactory>(entity.Key), rowFactory, ReadFrom.Output ); //TODO: need LuceneUpdater (update TflDeleted to true) break; } var handler = new DefaultDeleteHandler(context, input, output, deleter); // since the primary keys from the input may have been transformed into the output, you have to transform before comparing // feels a lot like entity pipeline on just the primary keys... may look at consolidating handler.Register(new DefaultTransform(context, entity.GetPrimaryKey().ToArray())); handler.Register(TransformFactory.GetTransforms(ctx, _process, entity, primaryKey)); handler.Register(new StringTruncateTransfom(context, primaryKey)); return(new ParallelDeleteHandler(handler)); }).Named <IEntityDeleteHandler>(entity.Key); } } } }
protected override void Load(ContainerBuilder builder) { if (_process == null) { return; } var calc = _process.ToCalculatedFieldsProcess(); var entity = calc.Entities.First(); // I need a process keyed pipeline builder.Register(ctx => { var context = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity); var outputContext = new OutputContext(context, new Incrementer(context)); IPipeline pipeline; context.Debug(() => $"Registering {_process.Pipeline} pipeline."); var outputController = ctx.IsRegistered <IOutputController>() ? ctx.Resolve <IOutputController>() : new NullOutputController(); switch (_process.Pipeline) { case "parallel.linq": pipeline = new ParallelPipeline(new DefaultPipeline(outputController, context)); break; default: pipeline = new DefaultPipeline(outputController, context); break; } // no updater necessary pipeline.Register(new NullUpdater(context, false)); if (!_process.CalculatedFields.Any()) { pipeline.Register(new NullReader(context, false)); pipeline.Register(new NullWriter(context, false)); return(pipeline); } // register transforms pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), entity.CalculatedFields)); pipeline.Register(TransformFactory.GetTransforms(ctx, calc, entity, entity.CalculatedFields)); pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity))); // register input and output switch (outputContext.Connection.Provider) { case "sqlserver": pipeline.Register(ctx.Resolve <IRead>()); pipeline.Register(ctx.Resolve <IWrite>()); pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), new DateTime(1753, 1, 1))); break; case "mysql": case "postgresql": case "sqlce": case "sqlite": pipeline.Register(ctx.Resolve <IRead>()); pipeline.Register(ctx.Resolve <IWrite>()); break; default: pipeline.Register(new NullReader(context)); pipeline.Register(new NullWriter(context)); break; } return(pipeline); }).As <IPipeline>(); }
protected override void Load(ContainerBuilder builder) { if (_process == null) { return; } //CONNECTIONS foreach (var connection in _process.Connections.Where(c => c.Provider.In("elasticsearch"))) { connection.Url = connection.BuildElasticUrl(); builder.Register <IConnectionPool>(ctx => new SingleNodeConnectionPool(new Uri(connection.Url))).Named <IConnectionPool>(connection.Key); // Elasticsearch.Net builder.Register(ctx => { var settings = new ConnectionConfiguration(ctx.ResolveNamed <IConnectionPool>(connection.Key)); if (_process.Mode != "init" && connection.RequestTimeout >= 0) { settings.RequestTimeout(new TimeSpan(0, 0, 0, connection.RequestTimeout * 1000)); } if (connection.Timeout > 0) { settings.PingTimeout(new TimeSpan(0, 0, connection.Timeout)); } return(new ElasticLowLevelClient(settings)); }).Named <IElasticLowLevelClient>(connection.Key); // Process-Level Schema Reader builder.Register <ISchemaReader>(ctx => new ElasticSchemaReader(ctx.ResolveNamed <IConnectionContext>(connection.Key), ctx.ResolveNamed <IElasticLowLevelClient>(connection.Key))).Named <ISchemaReader>(connection.Key); // Entity Level Schema Readers foreach (var entity in _process.Entities.Where(e => e.Connection == connection.Name)) { builder.Register <ISchemaReader>(ctx => new ElasticSchemaReader(ctx.ResolveNamed <IConnectionContext>(entity.Key), ctx.ResolveNamed <IElasticLowLevelClient>(connection.Key))).Named <ISchemaReader>(entity.Key); } } // Entity Input foreach (var entity in _process.Entities.Where(e => _process.Connections.First(c => c.Name == e.Connection).Provider == "elasticsearch")) { builder.Register <IInputVersionDetector>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); switch (input.Connection.Provider) { case "elasticsearch": return(new ElasticInputVersionDetector(input, ctx.ResolveNamed <IElasticLowLevelClient>(input.Connection.Key))); default: return(new NullVersionDetector()); } }).Named <IInputVersionDetector>(entity.Key); // INPUT READER builder.Register <IRead>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity)); switch (input.Connection.Provider) { case "elasticsearch": return(new ElasticReader(input, input.InputFields, ctx.ResolveNamed <IElasticLowLevelClient>(input.Connection.Key), rowFactory, ReadFrom.Input)); default: return(new NullReader(input, false)); } }).Named <IRead>(entity.Key); } // Entity Output if (_process.Output().Provider == "elasticsearch") { // PROCESS OUTPUT CONTROLLER builder.Register <IOutputController>(ctx => new NullOutputController()).As <IOutputController>(); // PROCESS INITIALIZER builder.Register <IInitializer>(ctx => { var output = ctx.Resolve <OutputContext>(); return(new ElasticInitializer(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key))); }).As <IInitializer>(); foreach (var entity in _process.Entities) { // UPDATER builder.Register <IUpdate>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); output.Warn($"{output.Connection.Provider} does not denormalize."); return(new NullMasterUpdater()); }).Named <IUpdate>(entity.Key); // OUTPUT builder.Register <IOutputController>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "elasticsearch": var initializer = _process.Mode == "init" ? (IAction) new ElasticEntityInitializer(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)) : new NullInitializer(); return(new ElasticOutputController( output, initializer, ctx.ResolveNamed <IInputVersionDetector>(entity.Key), new ElasticOutputVersionDetector(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)), ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key) )); default: return(new NullOutputController()); } }).Named <IOutputController>(entity.Key); // WRITER builder.Register <IWrite>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "elasticsearch": return(new ElasticWriter(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key))); default: return(new NullWriter(output)); } }).Named <IWrite>(entity.Key); // DELETE HANDLER if (entity.Delete) { builder.Register <IEntityDeleteHandler>(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); var inputContext = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", inputContext.RowCapacity)); IRead input = new NullReader(context); var primaryKey = entity.GetPrimaryKey(); switch (inputContext.Connection.Provider) { case "elasticsearch": input = new ElasticReader( inputContext, primaryKey, ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key), rowFactory, ReadFrom.Input ); break; } IRead output = new NullReader(context); IDelete deleter = new NullDeleter(context); var outputConnection = _process.Output(); var outputContext = ctx.ResolveNamed <OutputContext>(entity.Key); switch (outputConnection.Provider) { case "elasticsearch": output = new ElasticReader( outputContext, primaryKey, ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key), rowFactory, ReadFrom.Output ); deleter = new ElasticPartialUpdater( outputContext, new[] { context.Entity.TflDeleted() }, ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key) ); break; } var handler = new DefaultDeleteHandler(context, input, output, deleter); // since the primary keys from the input may have been transformed into the output, you have to transform before comparing // feels a lot like entity pipeline on just the primary keys... may look at consolidating handler.Register(new DefaultTransform(context, entity.GetPrimaryKey().ToArray())); handler.Register(TransformFactory.GetTransforms(ctx, _process, entity, primaryKey)); handler.Register(new StringTruncateTransfom(context, primaryKey)); return(new ParallelDeleteHandler(handler)); }).Named <IEntityDeleteHandler>(entity.Key); } } } }
public void Build() { //MAPS foreach (var map in _process.Maps.Where(m => m.Connection != string.Empty && m.Query != string.Empty)) { var connection = _process.Connections.First(c => c.Name == map.Connection); if (connection != null && connection.Provider == "elasticsearch") { _builder.Register <IMapReader>(ctx => new DefaultMapReader()).Named <IMapReader>(map.Name); } } //CONNECTIONS foreach (var connection in _process.Connections.Where(c => c.Provider == "elasticsearch")) { if (connection.Servers.Any(s => s.Url != "None")) { var uris = new List <Uri>(); foreach (var server in connection.Servers.Where(s => s.Url != "None")) { server.Url = server.GetElasticUrl(); uris.Add(new Uri(server.Url)); } // for now, just use static connection pool, there are 2 other types... _builder.Register <IConnectionPool>(ctx => new StaticConnectionPool(uris)).Named <IConnectionPool>(connection.Key); } else { connection.Url = connection.GetElasticUrl(); _builder.Register <IConnectionPool>(ctx => new SingleNodeConnectionPool(new Uri(connection.Url))).Named <IConnectionPool>(connection.Key); } // Elasticsearch.Net _builder.Register(ctx => { var settings = new ConnectionConfiguration(ctx.ResolveNamed <IConnectionPool>(connection.Key)); if (!string.IsNullOrEmpty(connection.User)) { settings.BasicAuthentication(connection.User, connection.Password); } if (_process.Mode != "init" && connection.RequestTimeout >= 0) { settings.RequestTimeout(new TimeSpan(0, 0, 0, connection.RequestTimeout * 1000)); } if (connection.Timeout > 0) { settings.PingTimeout(new TimeSpan(0, 0, connection.Timeout)); } return(new ElasticLowLevelClient(settings)); }).Named <IElasticLowLevelClient>(connection.Key); // Process-Level Schema Reader _builder.Register <ISchemaReader>(ctx => new ElasticSchemaReader(ctx.ResolveNamed <IConnectionContext>(connection.Key), ctx.ResolveNamed <IElasticLowLevelClient>(connection.Key))).Named <ISchemaReader>(connection.Key); // Entity Level Schema Readers foreach (var entity in _process.Entities.Where(e => e.Input == connection.Name)) { _builder.Register <ISchemaReader>(ctx => new ElasticSchemaReader(ctx.ResolveNamed <IConnectionContext>(entity.Key), ctx.ResolveNamed <IElasticLowLevelClient>(connection.Key))).Named <ISchemaReader>(entity.Key); } } // Entity Input foreach (var entity in _process.Entities.Where(e => _process.Connections.First(c => c.Name == e.Input).Provider == "elasticsearch")) { _builder.Register <IInputProvider>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); return(new ElasticInputProvider(input, ctx.ResolveNamed <IElasticLowLevelClient>(input.Connection.Key))); }).Named <IInputProvider>(entity.Key); // INPUT READER _builder.Register <IRead>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity)); if (entity.Query == string.Empty) { return(new ElasticReader(input, input.InputFields, ctx.ResolveNamed <IElasticLowLevelClient>(input.Connection.Key), rowFactory, ReadFrom.Input)); } return(new ElasticQueryReader(input, ctx.ResolveNamed <IElasticLowLevelClient>(input.Connection.Key), rowFactory)); }).Named <IRead>(entity.Key); } // Entity Output if (_process.GetOutputConnection().Provider == "elasticsearch") { // PROCESS OUTPUT CONTROLLER _builder.Register <IOutputController>(ctx => new NullOutputController()).As <IOutputController>(); // PROCESS INITIALIZER _builder.Register <IInitializer>(ctx => { var output = ctx.Resolve <OutputContext>(); return(new ElasticInitializer(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key))); }).As <IInitializer>(); foreach (var entity in _process.Entities) { // UPDATER _builder.Register <IUpdate>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); output.Debug(() => $"{output.Connection.Provider} does not denormalize."); return(new NullMasterUpdater()); }).Named <IUpdate>(entity.Key); // OUTPUT _builder.Register <IOutputController>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "elasticsearch": var initializer = _process.Mode == "init" ? (IAction) new ElasticEntityInitializer(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)) : new NullInitializer(); return(new ElasticOutputController( output, initializer, ctx.ResolveNamed <IInputProvider>(entity.Key), new ElasticOutputProvider(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key)), ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key) )); default: return(new NullOutputController()); } }).Named <IOutputController>(entity.Key); // WRITER _builder.Register <IWrite>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "elasticsearch": return(new ElasticWriter(output, ctx.ResolveNamed <IElasticLowLevelClient>(output.Connection.Key))); default: return(new NullWriter(output)); } }).Named <IWrite>(entity.Key); // DELETE HANDLER if (entity.Delete) { _builder.Register <IEntityDeleteHandler>(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); var inputContext = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", inputContext.RowCapacity)); IRead input = new NullReader(context); var primaryKey = entity.GetPrimaryKey(); switch (inputContext.Connection.Provider) { case "elasticsearch": input = new ElasticReader( inputContext, primaryKey, ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key), rowFactory, ReadFrom.Input ); break; } IRead output = new NullReader(context); IDelete deleter = new NullDeleter(context); var outputConnection = _process.GetOutputConnection(); var outputContext = ctx.ResolveNamed <OutputContext>(entity.Key); switch (outputConnection.Provider) { case "elasticsearch": output = new ElasticReader( outputContext, primaryKey, ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key), rowFactory, ReadFrom.Output ); deleter = new ElasticPartialUpdater( outputContext, new[] { context.Entity.TflDeleted() }, ctx.ResolveNamed <IElasticLowLevelClient>(inputContext.Connection.Key) ); break; } var handler = new DefaultDeleteHandler(context, input, output, deleter); // since the primary keys from the input may have been transformed into the output, you have to transform before comparing // feels a lot like entity pipeline on just the primary keys... may look at consolidating handler.Register(new DefaultTransform(context, entity.GetPrimaryKey().ToArray())); handler.Register(TransformFactory.GetTransforms(ctx, context, primaryKey)); handler.Register(new StringTruncateTransfom(context, primaryKey)); return(handler); }).Named <IEntityDeleteHandler>(entity.Key); } } } }
protected override void Load(ContainerBuilder builder) { if (_process == null) { return; } // connections foreach (var connection in _process.Connections.Where(c => c.Provider.In(_ado))) { // Connection Factory builder.Register <IConnectionFactory>(ctx => { switch (connection.Provider) { case "sqlserver": return(new SqlServerConnectionFactory(connection)); case "mysql": return(new MySqlConnectionFactory(connection)); case "postgresql": return(new PostgreSqlConnectionFactory(connection)); case "sqlite": return(new SqLiteConnectionFactory(connection)); default: return(new NullConnectionFactory()); } }).Named <IConnectionFactory>(connection.Key).InstancePerLifetimeScope(); // Schema Reader builder.Register <ISchemaReader>(ctx => { var factory = ctx.ResolveNamed <IConnectionFactory>(connection.Key); return(new AdoSchemaReader(ctx.ResolveNamed <IConnectionContext>(connection.Key), factory)); }).Named <ISchemaReader>(connection.Key); } //ISchemaReader //IOutputController //IRead (Process for Calculated Columns) //IWrite (Process for Calculated Columns) //IInitializer (Process) // Per Entity // IInputVersionDetector // IRead (Input, per Entity) // IOutputController // -- ITakeAndReturnRows (for matching) // -- IWriteMasterUpdateQuery (for updating) // IUpdate // IWrite // IEntityDeleteHandler // entitiy input foreach (var entity in _process.Entities.Where(e => _process.Connections.First(c => c.Name == e.Connection).Provider.In(_ado))) { // INPUT READER builder.Register <IRead>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity)); switch (input.Connection.Provider) { case "mysql": case "postgresql": case "sqlite": case "sqlserver": return(new AdoInputReader( input, input.InputFields, ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key), rowFactory )); default: return(new NullReader(input, false)); } }).Named <IRead>(entity.Key); // INPUT VERSION DETECTOR builder.Register <IInputVersionDetector>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); switch (input.Connection.Provider) { case "mysql": case "postgresql": case "sqlite": case "sqlserver": return(new AdoInputVersionDetector(input, ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key))); default: return(new NullVersionDetector()); } }).Named <IInputVersionDetector>(entity.Key); } // entity output if (_process.Output().Provider.In(_ado)) { var calc = _process.ToCalculatedFieldsProcess(); // PROCESS OUTPUT CONTROLLER builder.Register <IOutputController>(ctx => { var output = ctx.Resolve <OutputContext>(); if (_process.Mode != "init") { return(new NullOutputController()); } switch (output.Connection.Provider) { case "mysql": case "postgresql": case "sqlite": case "sqlserver": return(new AdoStarController(output, new AdoStarViewCreator(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)))); default: return(new NullOutputController()); } }).As <IOutputController>(); // PROCESS CALCULATED READER builder.Register <IRead>(ctx => { var calcContext = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First()); var outputContext = new OutputContext(calcContext, new Incrementer(calcContext)); var cf = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key); var capacity = outputContext.Entity.Fields.Count + outputContext.Entity.CalculatedFields.Count; var rowFactory = new RowFactory(capacity, false, false); return(new AdoStarParametersReader(outputContext, _process, cf, rowFactory)); }).As <IRead>(); // PROCESS CALCULATED FIELD WRITER builder.Register <IWrite>(ctx => { var calcContext = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First()); var outputContext = new OutputContext(calcContext, new Incrementer(calcContext)); var cf = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key); return(new AdoCalculatedFieldUpdater(outputContext, _process, cf)); }).As <IWrite>(); // PROCESS INITIALIZER builder.Register <IInitializer>(ctx => { var output = ctx.Resolve <OutputContext>(); return(new AdoInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key))); }).As <IInitializer>(); // ENTITIES foreach (var entity in _process.Entities) { // ENTITY OUTPUT CONTROLLER builder.Register <IOutputController>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "mysql": case "postgresql": case "sqlite": case "sqlserver": var initializer = _process.Mode == "init" ? (IAction) new AdoEntityInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)) : new NullInitializer(); return(new AdoOutputController( output, initializer, ctx.ResolveNamed <IInputVersionDetector>(entity.Key), new AdoOutputVersionDetector(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)), ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key) )); default: return(new NullOutputController()); } }).Named <IOutputController>(entity.Key); // OUTPUT ROW MATCHER builder.Register(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", output.GetAllEntityFields().Count())); var cf = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key); switch (output.Connection.Provider) { case "sqlite": return(new TypedEntityMatchingKeysReader(new AdoEntityMatchingKeysReader(output, cf, rowFactory), output)); default: return((ITakeAndReturnRows) new AdoEntityMatchingKeysReader(output, cf, rowFactory)); } }).Named <ITakeAndReturnRows>(entity.Key); // MASTER UPDATE QUERY builder.Register <IWriteMasterUpdateQuery>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); var factory = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key); switch (output.Connection.Provider) { case "mysql": return(new MySqlUpdateMasterKeysQueryWriter(output, factory)); case "postgresql": return(new PostgreSqlUpdateMasterKeysQueryWriter(output, factory)); default: return(new SqlServerUpdateMasterKeysQueryWriter(output, factory)); } }).Named <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys"); // UPDATER builder.Register <IUpdate>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "mysql": case "postgresql": case "sqlserver": return(new AdoMasterUpdater( output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key), ctx.ResolveNamed <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys") )); case "sqlite": return(new AdoTwoPartMasterUpdater(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key))); default: return(new NullMasterUpdater()); } }).Named <IUpdate>(entity.Key); // WRITER builder.Register <IWrite>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "sqlserver": return(new SqlServerWriter( output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key), ctx.ResolveNamed <ITakeAndReturnRows>(entity.Key), new AdoEntityUpdater(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)) )); case "mysql": case "postgresql": case "sqlite": var cf = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key); return(new AdoEntityWriter( output, ctx.ResolveNamed <ITakeAndReturnRows>(entity.Key), new AdoEntityInserter(output, cf), new AdoEntityUpdater(output, cf) )); default: return(new NullWriter(output)); } }).Named <IWrite>(entity.Key); // DELETE HANDLER if (entity.Delete) { builder.Register <IEntityDeleteHandler>(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); var inputContext = ctx.ResolveNamed <InputContext>(entity.Key); var rowCapacity = inputContext.Entity.GetPrimaryKey().Count(); var rowFactory = new RowFactory(rowCapacity, false, true); IRead input = new NullReader(context); var primaryKey = entity.GetPrimaryKey(); switch (inputContext.Connection.Provider) { case "mysql": case "postgresql": case "sqlite": case "sqlserver": input = new AdoReader( inputContext, primaryKey, ctx.ResolveNamed <IConnectionFactory>(inputContext.Connection.Key), rowFactory, ReadFrom.Input ); break; } IRead output = new NullReader(context); IDelete deleter = new NullDeleter(context); var outputConnection = _process.Output(); var outputContext = ctx.ResolveNamed <OutputContext>(entity.Key); switch (outputConnection.Provider) { case "mysql": case "postgresql": case "sqlite": case "sqlserver": var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key); output = new AdoReader(context, entity.GetPrimaryKey(), ocf, rowFactory, ReadFrom.Output); deleter = new AdoDeleter(outputContext, ocf); break; } var handler = new DefaultDeleteHandler(context, input, output, deleter); // since the primary keys from the input may have been transformed into the output, you have to transform before comparing // feels a lot like entity pipeline on just the primary keys... may look at consolidating handler.Register(new DefaultTransform(context, entity.GetPrimaryKey().ToArray())); handler.Register(TransformFactory.GetTransforms(ctx, _process, entity, primaryKey)); handler.Register(new StringTruncateTransfom(context, primaryKey)); return(new ParallelDeleteHandler(handler)); }).Named <IEntityDeleteHandler>(entity.Key); } } } }
protected override void Load(ContainerBuilder builder) { if (_process == null) { return; } // connections foreach (var connection in _process.Connections.Where(c => _ado.Contains(c.Provider))) { var cn = connection; // Connection Factory builder.Register <IConnectionFactory>(ctx => { switch (cn.Provider) { case "sqlserver": return(new SqlServerConnectionFactory(cn)); default: return(new NullConnectionFactory()); } }).Named <IConnectionFactory>(connection.Key).InstancePerLifetimeScope(); // Schema Reader builder.Register <ISchemaReader>(ctx => { var factory = ctx.ResolveNamed <IConnectionFactory>(cn.Key); return(new AdoSchemaReader(ctx.ResolveNamed <IConnectionContext>(cn.Key), factory)); }).Named <ISchemaReader>(connection.Key); } //ISchemaReader //IOutputController //IRead (Process for Calculated Columns) //IWrite (Process for Calculated Columns) //IInitializer (Process) // Per Entity // IInputVersionDetector // IRead (Input, per Entity) // IOutputController // -- IBatchReader (for matching) // -- IWriteMasterUpdateQuery (for updating) // IUpdate // IWrite // IEntityDeleteHandler // entitiy input foreach (var entity in _process.Entities.Where(e => _ado.Contains(_process.Connections.First(c => c.Name == e.Connection).Provider))) { // INPUT READER builder.Register(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity)); IRead dataReader; switch (input.Connection.Provider) { case "mysql": case "sqlserver": dataReader = new AdoInputReader( input, input.InputFields, ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key), rowFactory ); break; default: dataReader = new NullReader(input, false); break; } // "form" mode support if filter on primary key exists if (_process.Mode == "form" && entity.GetPrimaryKey().Any() && entity.GetPrimaryKey().All(f => entity.Filter.Any(i => i.Field == f.Alias || i.Field == f.Name))) { if (entity.GetPrimaryKey().All(pk => entity.Filter.First(i => i.Field == pk.Alias || i.Field == pk.Name).Value == (pk.Default == Constants.DefaultSetting ? Constants.StringDefaults()[pk.Type] : pk.Default))) { // primary key is default, don't read from database return(new ParameterRowReader(input, new DefaultRowReader(input, rowFactory))); } // read from database and update with parameters, otherwise just return the data reader if (HttpContext.Current.Request.HttpMethod == "POST") { return(new ParameterRowReader(input, dataReader, rowFactory)); } } return(dataReader); }).Named <IRead>(entity.Key); // INPUT VERSION DETECTOR builder.Register <IInputProvider>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); switch (input.Connection.Provider) { case "mysql": case "sqlserver": return(new AdoInputProvider(input, ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key))); default: return(new NullInputProvider()); } }).Named <IInputProvider>(entity.Key); } // entity output if (_ado.Contains(_process.Output().Provider)) { var calc = _process.ToCalculatedFieldsProcess(); // PROCESS OUTPUT CONTROLLER builder.Register <IOutputController>(ctx => { var output = ctx.Resolve <OutputContext>(); if (_process.Mode != "init") { return(new NullOutputController()); } switch (output.Connection.Provider) { case "mysql": case "sqlserver": var actions = new List <IAction> { new AdoStarViewCreator(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)) }; if (_process.Flatten) { actions.Add(new AdoFlatTableCreator(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key))); } return(new AdoStarController(output, actions)); default: return(new NullOutputController()); } }).As <IOutputController>(); // PROCESS CALCULATED READER builder.Register <IRead>(ctx => { var calcContext = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First()); var outputContext = new OutputContext(calcContext); var cf = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key); var capacity = outputContext.Entity.Fields.Count + outputContext.Entity.CalculatedFields.Count; var rowFactory = new RowFactory(capacity, false, false); return(new AdoStarParametersReader(outputContext, _process, cf, rowFactory)); }).As <IRead>(); // PROCESS CALCULATED FIELD WRITER builder.Register <IWrite>(ctx => { var calcContext = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First()); var outputContext = new OutputContext(calcContext); var cf = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key); return(new AdoCalculatedFieldUpdater(outputContext, _process, cf)); }).As <IWrite>(); // PROCESS INITIALIZER builder.Register <IInitializer>(ctx => { var output = ctx.Resolve <OutputContext>(); return(new AdoInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key))); }).As <IInitializer>(); // ENTITIES foreach (var e in _process.Entities) { var entity = e; // WRITER builder.Register <IWrite>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); var cf = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key); switch (output.Connection.Provider) { case "sqlserver": return(new SqlServerWriter( output, cf, ctx.ResolveNamed <IBatchReader>(entity.Key), new AdoEntityUpdater(output, cf) )); case "mysql": return(new AdoEntityWriter( output, ctx.ResolveNamed <IBatchReader>(entity.Key), new AdoEntityInserter(output, cf), entity.Update ? (IWrite) new AdoEntityUpdater(output, cf) : new NullWriter(output) )); default: return(new NullWriter(output)); } }).Named <IWrite>(entity.Key); builder.Register <IOutputProvider>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); return(new AdoOutputProvider(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key), ctx.ResolveNamed <IWrite>(entity.Key))); }).Named <IOutputProvider>(entity.Key); // ENTITY OUTPUT CONTROLLER builder.Register <IOutputController>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "mysql": case "sqlserver": var initializer = _process.Mode == "init" ? (IAction) new AdoEntityInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)) : new NullInitializer(); return(new AdoOutputController( output, initializer, ctx.ResolveNamed <IInputProvider>(entity.Key), ctx.ResolveNamed <IOutputProvider>(entity.Key), ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key) )); default: return(new NullOutputController()); } }).Named <IOutputController>(entity.Key); // OUTPUT ROW MATCHER builder.Register <IBatchReader>(ctx => { if (!entity.Update) { return(new NullBatchReader()); } var output = ctx.ResolveNamed <OutputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", output.GetAllEntityFields().Count())); var cf = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key); return(new AdoEntityMatchingKeysReader(output, cf, rowFactory)); }).Named <IBatchReader>(entity.Key); // MASTER UPDATE QUERY builder.Register <IWriteMasterUpdateQuery>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); var factory = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key); return(new SqlServerUpdateMasterKeysQueryWriter(output, factory)); }).Named <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys"); // MASTER UPDATER builder.Register <IUpdate>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "mysql": case "postgresql": case "sqlserver": return(new AdoMasterUpdater( output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key), ctx.ResolveNamed <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys") )); case "sqlite": case "sqlce": return(new AdoTwoPartMasterUpdater(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key))); default: return(new NullMasterUpdater()); } }).Named <IUpdate>(entity.Key); // DELETE HANDLER if (entity.Delete) { // register input keys and hashcode reader if necessary var provider = _process.Connections.First(c => c.Name == entity.Connection).Provider; if (_ado.Contains(provider)) { builder.Register <IReadInputKeysAndHashCodes>(ctx => { var inputContext = ctx.ResolveNamed <InputContext>(entity.Key); var rowCapacity = inputContext.Entity.GetPrimaryKey().Count(); var rowFactory = new RowFactory(rowCapacity, false, true); return(new AdoReader( inputContext, entity.GetPrimaryKey(), ctx.ResolveNamed <IConnectionFactory>(inputContext.Connection.Key), rowFactory, ReadFrom.Input )); }).Named <IReadInputKeysAndHashCodes>(entity.Key); } // register output keys and hash code reader if necessary builder.Register <IReadOutputKeysAndHashCodes>((ctx => { var context = ctx.ResolveNamed <OutputContext>(entity.Key); var rowCapacity = context.Entity.GetPrimaryKey().Count(); var rowFactory = new RowFactory(rowCapacity, false, true); var outputConnection = _process.Output(); switch (outputConnection.Provider) { case "mysql": case "sqlserver": var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key); return(new AdoReader(context, entity.GetPrimaryKey(), ocf, rowFactory, ReadFrom.Output)); default: return(new NullReader(context)); } })).Named <IReadOutputKeysAndHashCodes>(entity.Key); builder.Register((ctx) => { var outputConnection = _process.Output(); var outputContext = ctx.ResolveNamed <OutputContext>(entity.Key); switch (outputConnection.Provider) { case "mysql": case "sqlserver": var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key); return(new AdoDeleter(outputContext, ocf)); default: return(ctx.IsRegisteredWithName <IDelete>(entity.Key) ? ctx.ResolveNamed <IDelete>(entity.Key) : new NullDeleter(outputContext)); } }).Named <IDelete>(entity.Key); builder.Register <IEntityDeleteHandler>(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); var primaryKey = entity.GetPrimaryKey().ToArray(); var handler = new DefaultDeleteHandler( context, ctx.ResolveNamed <IReadInputKeysAndHashCodes>(entity.Key), ctx.ResolveNamed <IReadOutputKeysAndHashCodes>(entity.Key), ctx.ResolveNamed <IDelete>(entity.Key) ); // since the primary keys from the input may have been transformed into the output, you have to transform before comparing // feels a lot like entity pipeline on just the primary keys... may look at consolidating handler.Register(new DefaultTransform(context, primaryKey)); handler.Register(TransformFactory.GetTransforms(ctx, context, primaryKey)); handler.Register(new StringTruncateTransfom(context, primaryKey)); return(new ParallelDeleteHandler(handler)); }).Named <IEntityDeleteHandler>(entity.Key); } } } }
protected override void Load(ContainerBuilder builder) { if (!builder.Properties.ContainsKey("Process")) { return; } var process = (Process)builder.Properties["Process"]; // connections foreach (var connection in process.Connections.Where(c => c.Provider == Access)) { // Connection Factory builder.Register <IConnectionFactory>(ctx => { switch (connection.Provider) { case "access": return(new AccessConnectionFactory(connection)); default: return(new NullConnectionFactory()); } }).Named <IConnectionFactory>(connection.Key).InstancePerLifetimeScope(); // Schema Reader builder.Register <ISchemaReader>(ctx => { var factory = ctx.ResolveNamed <IConnectionFactory>(connection.Key); return(new AdoSchemaReader(ctx.ResolveNamed <IConnectionContext>(connection.Key), factory)); }).Named <ISchemaReader>(connection.Key); } // entity input foreach (var entity in process.Entities.Where(e => process.Connections.First(c => c.Name == e.Input).Provider == Access)) { // INPUT READER builder.Register <IRead>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity)); switch (input.Connection.Provider) { case "access": return(new AdoInputReader( input, input.InputFields, ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key), rowFactory )); default: return(new NullReader(input, false)); } }).Named <IRead>(entity.Key); // INPUT VERSION DETECTOR builder.Register <IInputProvider>(ctx => { var input = ctx.ResolveNamed <InputContext>(entity.Key); switch (input.Connection.Provider) { case "access": return(new AdoInputProvider(input, ctx.ResolveNamed <IConnectionFactory>(input.Connection.Key))); default: return(new NullInputProvider()); } }).Named <IInputProvider>(entity.Key); } // entity output if (process.GetOutputConnection().Provider == Access) { var calc = process.ToCalculatedFieldsProcess(); // PROCESS OUTPUT CONTROLLER builder.Register <IOutputController>(ctx => { var output = ctx.Resolve <OutputContext>(); if (process.Mode != "init") { return(new NullOutputController()); } switch (output.Connection.Provider) { case "access": var actions = new List <IAction> { new AdoStarViewCreator(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)) }; if (process.Flatten) { actions.Add(new AdoFlatTableCreator(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key))); } return(new AdoStarController(output, actions)); default: return(new NullOutputController()); } }).As <IOutputController>(); // PROCESS CALCULATED READER builder.Register <IRead>(ctx => { var calcContext = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First()); var outputContext = new OutputContext(calcContext); var cf = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key); var capacity = outputContext.Entity.Fields.Count + outputContext.Entity.CalculatedFields.Count; var rowFactory = new RowFactory(capacity, false, false); return(new AdoStarParametersReader(outputContext, process, cf, rowFactory)); }).As <IRead>(); // PROCESS CALCULATED FIELD WRITER builder.Register <IWrite>(ctx => { var calcContext = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, calc.Entities.First()); var outputContext = new OutputContext(calcContext); var cf = ctx.ResolveNamed <IConnectionFactory>(outputContext.Connection.Key); return(new AdoCalculatedFieldUpdater(outputContext, process, cf)); }).As <IWrite>(); // PROCESS INITIALIZER builder.Register <IInitializer>(ctx => { var output = ctx.Resolve <OutputContext>(); var adoInit = new AdoInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)); switch (output.Connection.Provider) { case "access": return(new AccessInitializer(adoInit, output)); default: return(adoInit); } }).As <IInitializer>(); // ENTITIES foreach (var entity in process.Entities) { builder.Register <IOutputProvider>(ctx => { IWrite writer; var output = ctx.ResolveNamed <OutputContext>(entity.Key); var cf = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", output.GetAllEntityFields().Count())); // matcher determines what's an update vs. and insert var matcher = entity.Update ? (IBatchReader) new AdoEntityMatchingKeysReader(output, cf, rowFactory) : new NullBatchReader(); switch (output.Connection.Provider) { case "access": writer = new AdoEntityWriter( output, matcher, new AdoEntityInserter(output, cf), entity.Update ? (IWrite) new AdoEntityUpdater(output, cf) : new NullWriter(output) ); break; default: writer = new NullWriter(output); break; } return(new AdoOutputProvider(output, cf, writer)); }).Named <IOutputProvider>(entity.Key); // ENTITY OUTPUT CONTROLLER builder.Register <IOutputController>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); var initializer = process.Mode == "init" ? (IAction) new AdoEntityInitializer(output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key)) : new NullInitializer(); switch (output.Connection.Provider) { case "access": return(new AdoOutputController( output, new AccessInitializer(initializer, output), ctx.ResolveNamed <IInputProvider>(entity.Key), ctx.ResolveNamed <IOutputProvider>(entity.Key), ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key) )); default: return(new NullOutputController()); } }).Named <IOutputController>(entity.Key); // MASTER UPDATE QUERY builder.Register <IWriteMasterUpdateQuery>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); var factory = ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key); return(new AccessUpdateMasterKeysQueryWriter(output, factory)); }).Named <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys"); // MASTER UPDATER builder.Register <IUpdate>(ctx => { var output = ctx.ResolveNamed <OutputContext>(entity.Key); switch (output.Connection.Provider) { case "access": return(new AdoMasterUpdater( output, ctx.ResolveNamed <IConnectionFactory>(output.Connection.Key), ctx.ResolveNamed <IWriteMasterUpdateQuery>(entity.Key + "MasterKeys") )); default: return(new NullMasterUpdater()); } }).Named <IUpdate>(entity.Key); // DELETE HANDLER if (entity.Delete) { // register input keys and hashcode reader if necessary builder.Register(ctx => { var inputContext = ctx.ResolveNamed <InputContext>(entity.Key); var rowCapacity = inputContext.Entity.GetPrimaryKey().Count(); var rowFactory = new RowFactory(rowCapacity, false, true); switch (inputContext.Connection.Provider) { case "access": return(new AdoReader( inputContext, entity.GetPrimaryKey(), ctx.ResolveNamed <IConnectionFactory>(inputContext.Connection.Key), rowFactory, ReadFrom.Input )); default: return(ctx.IsRegisteredWithName <IReadInputKeysAndHashCodes>(entity.Key) ? ctx.ResolveNamed <IReadInputKeysAndHashCodes>(entity.Key) : new NullReader(inputContext)); } }).Named <IReadInputKeysAndHashCodes>(entity.Key); // register output keys and hash code reader if necessary builder.Register((ctx => { var context = ctx.ResolveNamed <OutputContext>(entity.Key); var rowCapacity = context.Entity.GetPrimaryKey().Count(); var rowFactory = new RowFactory(rowCapacity, false, true); var outputConnection = process.GetOutputConnection(); switch (outputConnection.Provider) { case "access": var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key); return(new AdoReader(context, entity.GetPrimaryKey(), ocf, rowFactory, ReadFrom.Output)); default: return(ctx.IsRegisteredWithName <IReadOutputKeysAndHashCodes>(entity.Key) ? ctx.ResolveNamed <IReadOutputKeysAndHashCodes>(entity.Key) : new NullReader(context)); } })).Named <IReadOutputKeysAndHashCodes>(entity.Key); builder.Register(ctx => { var outputConnection = process.GetOutputConnection(); var outputContext = ctx.ResolveNamed <OutputContext>(entity.Key); switch (outputConnection.Provider) { case "access": var ocf = ctx.ResolveNamed <IConnectionFactory>(outputConnection.Key); return(new AdoDeleter(outputContext, ocf)); default: return(ctx.IsRegisteredWithName <IDelete>(entity.Key) ? ctx.ResolveNamed <IDelete>(entity.Key) : new NullDeleter(outputContext)); } }).Named <IDelete>(entity.Key); builder.Register <IEntityDeleteHandler>(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); var primaryKey = entity.GetPrimaryKey(); var handler = new DefaultDeleteHandler( context, ctx.ResolveNamed <IReadInputKeysAndHashCodes>(entity.Key), ctx.ResolveNamed <IReadOutputKeysAndHashCodes>(entity.Key), ctx.ResolveNamed <IDelete>(entity.Key) ); // since the primary keys from the input may have been transformed into the output, you have to transform before comparing // feels a lot like entity pipeline on just the primary keys... may look at consolidating handler.Register(new DefaultTransform(context, entity.GetPrimaryKey().ToArray())); handler.Register(TransformFactory.GetTransforms(ctx, context, primaryKey)); handler.Register(new StringTruncateTransfom(context, primaryKey)); return(handler); }).Named <IEntityDeleteHandler>(entity.Key); } } } }
public override void LoadEntity(ContainerBuilder builder, Process process, Entity entity) { if (process == null) { return; } var type = process.Pipeline == "defer" ? entity.Pipeline : process.Pipeline; builder.Register(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); IPipeline pipeline; context.Debug(() => $"Registering {type} for entity {entity.Alias}."); var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController(); switch (type) { case "parallel.linq": pipeline = new ParallelPipeline(new DefaultPipeline(outputController, context)); break; default: pipeline = new DefaultPipeline(outputController, context); break; } var output = process.Output(); // TODO: rely on IInputProvider's Read method instead (after every provider has one) pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null); // transforms if (!process.ReadOnly) { pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); } pipeline.Register(new CancelTransform(context)); pipeline.Register(new IncrementTransform(context)); pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields().Where(f => !f.System))); if (ctx.ResolveNamed <IConnectionContext>(entity.Key).Connection.Provider.In("internal", "file", Constants.DefaultSetting)) { foreach (var field in entity.Fields.Where(f => f.Input && f.Type != "string" && (!f.Transforms.Any() || f.Transforms.First().Method != "convert"))) { context.Debug(() => "Automatically adding convert transform"); pipeline.Register(new ConvertTransform(new PipelineContext(context.Logger, context.Process, entity, field, new Operation { Method = "convert" }))); } } pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any()))); pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any()))); if (!process.ReadOnly) { pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); if (output.Provider == "sqlserver") { pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity), new DateTime(1753, 1, 1))); } } pipeline.Register(new LogTransform(context)); // writer, TODO: rely on IOutputProvider instead pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null); // updater pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key)); return(pipeline); }).Named <IPipeline>(entity.Key); }
private static string TransformConfiguration(IComponentContext ctx) { // short hand for parameters is defined, try to transform parameters in advance if (!ctx.IsRegisteredWithName <IDependency>("shorthand-p")) { return(null); } if (!ctx.IsRegisteredWithName <string>("cfg")) { return(null); } var dependencies = new List <IDependency> { ctx.Resolve <IReader>(), new DateMathModifier(), new EnvironmentModifier(new NullPlaceHolderReplacer()), ctx.ResolveNamed <IDependency>("shorthand-p") }; var preCfg = ctx.ResolveNamed <string>("cfg"); var preProcess = new ConfigurationFacade.Process(preCfg, new Dictionary <string, string>(), dependencies.ToArray()); var parameters = preProcess.GetActiveParameters(); if (!parameters.Any(pr => pr.Transforms.Any())) { return(null); } var fields = parameters.Select(pr => new Field { Name = pr.Name, Alias = pr.Name, Default = pr.Value, Type = pr.Type, Transforms = pr.Transforms.Select(o => o.ToOperation()).ToList() }).ToList(); var len = fields.Count; var entity = new Entity { Name = "Parameters", Alias = "Parameters", Fields = fields }; var mini = new Process { Name = "ParameterTransform", ReadOnly = true, Entities = new List <Entity> { entity }, Maps = preProcess.Maps.Select(m => m.ToMap()).ToList(), // for map transforms Scripts = preProcess.Scripts.Select(s => s.ToScript()).ToList() // for transforms that use scripts (e.g. js) }; mini.Check(); // very important to check after creating, as it runs validation and even modifies! if (!mini.Errors().Any()) { // modification in Check() do not make it out to local variables so overwrite them fields = mini.Entities.First().Fields; entity = mini.Entities.First(); var transforms = TransformFactory.GetTransforms(ctx, new PipelineContext(ctx.Resolve <IPipelineLogger>(), mini, entity), fields); // make an input out of the parameters var input = new List <IRow>(); var row = new MasterRow(len); for (var i = 0; i < len; i++) { row[fields[i]] = parameters[i].Value; } input.Add(row); var output = transforms.Aggregate(input.AsEnumerable(), (rows, t) => t.Operate(rows)).ToList().First(); for (var i = 0; i < len; i++) { var parameter = parameters[i]; parameter.Value = output[fields[i]].ToString(); parameter.T = string.Empty; parameter.Transforms.Clear(); } return(preProcess.Serialize()); } var context = new PipelineContext(ctx.Resolve <IPipelineLogger>(), mini, entity); foreach (var error in mini.Errors()) { context.Error(error); } return(null); }
public ILifetimeScope CreateScope(Process process, IPipelineLogger logger) { var builder = new ContainerBuilder(); // the modules below rely on this process being there builder.Properties["Process"] = process; builder.Register(ctx => process).As <Process>(); builder.RegisterInstance(logger).As <IPipelineLogger>().SingleInstance(); // register short-hand for t attribute, allowing for additional transforms var tm = new TransformModule(process, _methods, _shortHand, logger) { Plugins = false }; // adding additional transforms here tm.AddTransform(new TransformHolder((c) => new UsernameTransform(_httpContext, c), new UsernameTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new UserIdTransform(_httpContext, _userService, c), new UserIdTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new UserEmailTransform(_httpContext, _userService, c), new UserEmailTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardRazorTransform(c, _memoryCache, _signal), new OrchardRazorTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardFluidTransform(c, _memoryCache, _signal), new OrchardFluidTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardJintTransform(c, new DefaultReader(new FileReader(), new WebReader()), _memoryCache, _signal), new OrchardJintTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new ToLocalTimeTransform(c, _clock, _localClock), new ToLocalTimeTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new GetEncodedUrlTransform(_httpContext, c), new GetEncodedUrlTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new GetDisplayUrlTransform(_httpContext, c), new GetDisplayUrlTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new OrchardTimeZoneTransform(c), new OrchardTimeZoneTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new GeocodeTransform(c), new GeocodeTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new PlaceTransform(c), new PlaceTransform().GetSignatures())); tm.AddTransform(new TransformHolder((c) => new FilePartTransform(c, _fileService), new FilePartTransform().GetSignatures())); builder.RegisterModule(tm); // register short-hand for v attribute, allowing for additional validators var vm = new ValidateModule(process, _methods, _shortHand, logger) { Plugins = false }; // adding additional validators here builder.RegisterModule(vm); // using custom internal module that does not handle the nested transformalize actions builder.RegisterModule(new OrchardInternalModule(process)); // handling nested transformalize actions here instead foreach (var action in process.Actions.Where(a => a.GetModes().Any(m => m == process.Mode || m == "*"))) { if (action.Type == "tfl") { builder.Register <IAction>(ctx => { return(new PipelineAction(action, _serviceProvider)); }).Named <IAction>(action.Key); } } // register providers var providers = new HashSet <string>(process.Connections.Select(c => c.Provider)); // relational databases builder.RegisterModule(new AdoProviderModule()); if (providers.Contains("sqlserver")) { builder.RegisterModule(new SqlServerModule() { ConnectionFactory = (c) => new ProfiledConnectionFactory(new SqlServerConnectionFactory(c)) }); } if (providers.Contains("postgresql")) { builder.RegisterModule(new PostgreSqlModule() { ConnectionFactory = (c) => new ProfiledConnectionFactory(new PostgreSqlConnectionFactory(c)) }); } if (providers.Contains("sqlite")) { builder.RegisterModule(new SqliteModule() { ConnectionFactory = (c) => new ProfiledConnectionFactory(new SqliteConnectionFactory(c)) }); } if (providers.Contains("mysql")) { builder.RegisterModule(new MySqlModule() { ConnectionFactory = (c) => new ProfiledConnectionFactory(new MySqlConnectionFactory(c)) }); } // search engines if (providers.Contains("elasticsearch")) { builder.RegisterModule(new ElasticsearchModule()); } // solr // lucene // importing, exporting var stream = _httpContext.HttpContext.Response.Body; if (providers.Contains("file")) { builder.RegisterModule(new CsvHelperProviderModule(stream)); } if (providers.Contains("excel")) { builder.RegisterModule(new OrchardExcelModule()); } // exporting if (providers.Contains("json")) { builder.RegisterModule(new JsonProviderModule(stream) { UseAsyncMethods = true }); } if (providers.Contains("geojson")) { builder.RegisterModule(new GeoJsonProviderModule(stream) { UseAsyncMethods = true }); } // misc if (providers.Contains("bogus")) { builder.RegisterModule(new BogusModule()); } if (providers.Contains("log") || process.Actions.Any(a => a.Type == "log")) { builder.RegisterModule(new OrchardLogModule(process)); } if (providers.Contains("mail")) { builder.RegisterModule(new MailModule()); } if (providers.Contains("aws")) { var services = new HashSet <string>(process.Connections.Where(c => c.Provider == "aws").Select(c => c.Service)); if (services.Contains("logs")) { builder.RegisterModule(new AwsCloudWatchProviderModule()); } if (services.Contains("connect")) { builder.RegisterModule(new AmazonConnectProviderModule()); } } // transform and validation modules need these properties builder.Properties["ShortHand"] = _shortHand; builder.Properties["Methods"] = _methods; // register transform modules here builder.RegisterModule(new JsonTransformModule()); builder.RegisterModule(new HumanizeModule()); builder.RegisterModule(new FileModule()); builder.RegisterModule(new AdoTransformModule()); builder.RegisterModule(new LambdaParserModule()); builder.RegisterModule(new AwsTransformModule()); // register validator modules here builder.RegisterModule(new JintValidateModule()); // process context builder.Register <IContext>((ctx, p) => new PipelineContext(logger, process)).As <IContext>(); // process output context builder.Register(ctx => { var context = ctx.Resolve <IContext>(); return(new OutputContext(context)); }).As <OutputContext>(); // connection and process level output context var formWriter = false; foreach (var connection in process.Connections) { builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(connection.Key); // there can only be one form writer if (!formWriter && connection.Table != "[default]" && connection.Provider != "[default]") { builder.Register(ctx => { var context = ctx.ResolveNamed <IConnectionContext>(connection.Key); var connectionFactory = ctx.ResolveNamed <IConnectionFactory>(connection.Key); return(new AdoFormCommandWriter(context, connectionFactory)); }).As <AdoFormCommandWriter>(); formWriter = true; } if (connection.Name != process.Output) { continue; } // register output for connection builder.Register(ctx => { var context = ctx.ResolveNamed <IConnectionContext>(connection.Key); return(new OutputContext(context)); }).Named <OutputContext>(connection.Key); } // entity context and rowFactory foreach (var entity in process.Entities) { builder.Register <IContext>((ctx, p) => new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity)).Named <IContext>(entity.Key); builder.Register(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); return(new InputContext(context)); }).Named <InputContext>(entity.Key); builder.Register <IRowFactory>((ctx, p) => new RowFactory(p.Named <int>("capacity"), entity.IsMaster, false)).Named <IRowFactory>(entity.Key); builder.Register(ctx => { var context = ctx.ResolveNamed <IContext>(entity.Key); return(new OutputContext(context)); }).Named <OutputContext>(entity.Key); var connection = process.Connections.First(c => c.Name == entity.Input); builder.Register(ctx => new ConnectionContext(ctx.Resolve <IContext>(), connection)).Named <IConnectionContext>(entity.Key); } // entity pipelines foreach (var entity in process.Entities) { builder.Register(ctx => { var output = process.GetOutputConnection(); var context = ctx.ResolveNamed <IContext>(entity.Key); var outputController = ctx.IsRegisteredWithName <IOutputController>(entity.Key) ? ctx.ResolveNamed <IOutputController>(entity.Key) : new NullOutputController(); var pipeline = new DefaultPipeline(outputController, context); if (entity.IsMaster) { if (GetReaderAlternate != null) { // Using an alternate reader (e.g. a ParameterRowReader that reads parameters into a row) var input = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity)); pipeline.Register(GetReaderAlternate(input, rowFactory)); } else if (GetReaderDecorator != null && ctx.IsRegisteredWithName(entity.Key, typeof(IRead))) { // Decorating the normally registered reader (e.g. ParameterRowReader updating a row from an AdoReader) // TODO: Support IInputProvider instead of just IRead var input = ctx.ResolveNamed <InputContext>(entity.Key); var rowFactory = ctx.ResolveNamed <IRowFactory>(entity.Key, new NamedParameter("capacity", input.RowCapacity)); pipeline.Register(GetReaderDecorator(ctx.ResolveNamed <IRead>(entity.Key), input, rowFactory)); } else { pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null); } } else { // TODO: rely on IInputProvider's Read method instead (after every provider has one) pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IRead)) ? ctx.ResolveNamed <IRead>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IInputProvider)) ? ctx.ResolveNamed <IInputProvider>(entity.Key) : null); } // transforms if (!process.ReadOnly) { pipeline.Register(new SetSystemFields(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); } pipeline.Register(new IncrementTransform(context)); pipeline.Register(new DefaultTransform(context, context.GetAllEntityFields().Where(f => !f.System))); pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.GetAllFields().Where(f => f.Transforms.Any()))); pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any()))); if (!process.ReadOnly && !output.Provider.In("internal", "log")) { pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), process, entity))); } pipeline.Register(new LogTransform(context)); // writer, TODO: rely on IOutputProvider instead pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IWrite)) ? ctx.ResolveNamed <IWrite>(entity.Key) : null); pipeline.Register(ctx.IsRegisteredWithName(entity.Key, typeof(IOutputProvider)) ? ctx.ResolveNamed <IOutputProvider>(entity.Key) : null); // updater pipeline.Register(process.ReadOnly || !ctx.IsRegisteredWithName(entity.Key, typeof(IUpdate)) ? new NullUpdater() : ctx.ResolveNamed <IUpdate>(entity.Key)); return(pipeline); }).Named <IPipeline>(entity.Key); } if (process.Entities.Count > 1 && process.Relationships.Any()) { // process pipeline builder.Register(ctx => { var calc = process.ToCalculatedFieldsProcess(); var entity = calc.Entities.First(); var context = new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity); var outputContext = new OutputContext(context); context.Debug(() => $"Registering {process.Pipeline} pipeline."); var outputController = ctx.IsRegistered <IOutputController>() ? ctx.Resolve <IOutputController>() : new NullOutputController(); var pipeline = new DefaultPipeline(outputController, context); // no updater necessary pipeline.Register(new NullUpdater(context, false)); if (!process.CalculatedFields.Any()) { pipeline.Register(new NullReader(context, false)); pipeline.Register(new NullWriter(context, false)); return(pipeline); } // register transforms pipeline.Register(new IncrementTransform(context)); pipeline.Register(new LogTransform(context)); pipeline.Register(new DefaultTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), entity.CalculatedFields)); pipeline.Register(TransformFactory.GetTransforms(ctx, context, entity.CalculatedFields)); pipeline.Register(ValidateFactory.GetValidators(ctx, context, entity.GetAllFields().Where(f => f.Validators.Any()))); pipeline.Register(new StringTruncateTransfom(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity))); // register input and output pipeline.Register(ctx.IsRegistered <IRead>() ? ctx.Resolve <IRead>() : new NullReader(context)); pipeline.Register(ctx.IsRegistered <IWrite>() ? ctx.Resolve <IWrite>() : new NullWriter(context)); if (outputContext.Connection.Provider == "sqlserver") { pipeline.Register(new MinDateTransform(new PipelineContext(ctx.Resolve <IPipelineLogger>(), calc, entity), new DateTime(1753, 1, 1))); } return(pipeline); }).As <IPipeline>(); } // process controller builder.Register <IProcessController>(ctx => { var pipelines = new List <IPipeline>(); // entity-level pipelines foreach (var entity in process.Entities) { var pipeline = ctx.ResolveNamed <IPipeline>(entity.Key); pipelines.Add(pipeline); if (entity.Delete && process.Mode != "init") { pipeline.Register(ctx.ResolveNamed <IEntityDeleteHandler>(entity.Key)); } } // process-level pipeline for process level calculated fields if (ctx.IsRegistered <IPipeline>()) { pipelines.Add(ctx.Resolve <IPipeline>()); } var context = ctx.Resolve <IContext>(); var controller = new ProcessController(pipelines, context); // output initialization if (process.Mode == "init" && ctx.IsRegistered <IInitializer>()) { controller.PreActions.Add(ctx.Resolve <IInitializer>()); } // flatten(ing) is first post-action var output = process.GetOutputConnection(); var isAdo = _adoProviders.Contains(output.Provider); if (process.Flatten && isAdo) { if (ctx.IsRegisteredWithName <IAction>(output.Key)) { controller.PostActions.Add(ctx.ResolveNamed <IAction>(output.Key)); } else { context.Error($"Could not find ADO Flatten Action for provider {output.Provider}."); } } // actions foreach (var action in process.Actions.Where(a => a.GetModes().Any(m => m == process.Mode || m == "*"))) { if (ctx.IsRegisteredWithName <IAction>(action.Key)) { if (action.Before) { controller.PreActions.Add(ctx.ResolveNamed <IAction>(action.Key)); } if (action.After) { controller.PostActions.Add(ctx.ResolveNamed <IAction>(action.Key)); } } else { if (action.Type != "internal") { _logger.Warn(() => $"The action {action.Name} with type {action.Type} isn't registered."); } } } foreach (var map in process.Maps.Where(m => !string.IsNullOrEmpty(m.Query))) { controller.PreActions.Add(new MapReaderAction(context, map, ctx.ResolveNamed <IMapReader>(map.Name))); } return(controller); }).As <IProcessController>(); var build = builder.Build(); return(build.BeginLifetimeScope()); }