/// <summary> /// Gets the insert case count. /// </summary> /// <param name="detail">The detail.</param> /// <param name="shortName">The short name.</param> /// <returns>the count</returns> public int GetInsertCaseCount(IConnectionDetail detail, IRulebaseConfiguration rule, int UKPRN) { Emitter.Publish(Indentation.FirstLevel, rule.InsertCount.Description); string command = rule.InsertCount.Command.Replace("{ukprn}", UKPRN.ToString()); return(Coordinate.GetAtom <int>(command, detail)); }
/// <summary> /// Gets the candidates. /// </summary> /// <param name="forContext">For context.</param> /// <returns> /// returns a list of verified input data sources /// </returns> public async Task <IReadOnlyCollection <IInputDataSource> > GetCandidates(IConnectionDetail forContext) { // had to restrict the async operations here as some of the threads didn't appear to // be returning properly. this may be due to the expectation of failure when interrogating // some data sources. // i suppose it could be a bug in the oepration manager, brought on by the context switching // pondering... return(await Task.Run(() => { var candidates = Collection.Empty <IInputDataSource>(); var script = GetScript(BatchProcessName.GetInputSourceCandidates); var candidateNames = Context.GetList <string>(script, forContext); candidateNames.ForEach(candidate => { var response = Load(forContext, candidate); if (response.IsSuccess()) { candidates.Add(response.Payload); } }); return candidates.AsSafeReadOnlyList(); })); }
/// <summary> /// Loads... /// </summary> /// <param name="usingDetail">using detail.</param> /// <param name="withCandidate">with candidate.</param> /// <returns> /// an operational response that may contain an input data source /// (depends on the success of the check) /// </returns> public IOperationResponse <IInputDataSource> Load(IConnectionDetail usingDetail, string withCandidate) { // we expect this to fail as not all data sources will contain // collection detail information. an execption is not a problem // when it forms part of the control flow return(OperationManager.RunSafe(() => CheckCandidate(usingDetail, withCandidate))); }
/// <summary> /// Gets the learner count. /// </summary> /// <param name="usingDetail">The using detail.</param> /// <param name="providerID">The provider identifier.</param> /// <returns>the learner count for this submission</returns> public int GetLearnerCount(IConnectionDetail usingDetail, int providerID) { var script = GetScript(BatchProcessName.GetLearnerCountForProvider, usingDetail.DBName); var temp = Token.DoSecondaryPass(script, providerID); return(Context.GetAtom <int>(temp, usingDetail)); }
/// <summary> /// Gets the list. /// </summary> /// <typeparam name="TReturn">The type of the return.</typeparam> /// <param name="usingThisCommand">using this command.</param> /// <param name="inThisContext">in this context.</param> /// <returns> /// an list of type <typeparamref name="TReturn" /> /// </returns> public ICollection <TReturn> GetList <TReturn>(string usingThisCommand, IConnectionDetail inThisContext) { It.IsEmpty(usingThisCommand) .AsGuard <ArgumentNullException>(nameof(usingThisCommand)); It.IsNull(inThisContext) .AsGuard <ArgumentNullException>(nameof(inThisContext)); return(UsingConnection(inThisContext, x => { var tempList = Collection.Empty <TReturn>(); using (var cmd = CreateCommand(usingThisCommand, x)) { using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { var candidate = reader.GetValue(0); tempList.Add(GetValue <TReturn>(candidate)); } } } return tempList; })); }
/// <summary> /// Checks the candidate. /// </summary> /// <param name="usingContext">using context.</param> /// <param name="withCandidate">with candidate.</param> /// <returns> /// an input data source on successful completion of the check /// </returns> public IInputDataSource CheckCandidate(IConnectionDetail usingDetail, string withCandidate) { var script = GetScript(BatchProcessName.GetOperatingYear, withCandidate); var yearTemp = Context.GetAtom <string>(script, usingDetail); script = GetScript(BatchProcessName.GetCollectionType, withCandidate); var collectionTemp = Context.GetAtom <string>(script, usingDetail); script = GetScript(BatchProcessName.GetProviders, withCandidate); var providerIDs = Context.GetList <int>(script, usingDetail); var providers = Collection.Empty <ILearningProvider>(); providerIDs.ForEach(x => providers.Add(new LearningProvider { ID = x })); return(new InputDataSource { Name = withCandidate, Container = usingDetail.Container, DBName = usingDetail.DBName, DBUser = usingDetail.DBUser, DBPassword = usingDetail.DBPassword, CollectionType = collectionTemp.AsOperationType(), OperatingYear = yearTemp.AsOperatingYear(), Providers = providers.AsSafeReadOnlyList() }); }
/// <summary> /// Exports to ILR /// </summary> /// <param name="usingSource">using source.</param> /// <param name="inContext">in context.</param> /// <param name="forProvider">for provider.</param> /// <returns> /// the currently running task /// </returns> public async Task Export(IInputDataSource usingSource, IConnectionDetail inContext, int forProvider) { It.IsNull(usingSource) .AsGuard <ArgumentNullException>(nameof(usingSource)); It.IsNull(inContext) .AsGuard <ArgumentNullException>(nameof(inContext)); await Task.Run(async() => { using (Timing.BeginScope($"Export file for {forProvider}")) { var schema = Schemas.GetSchema(usingSource.OperatingYear); var schemaPath = Path.Combine(Location.OfAssets, schema.Message); var templatePath = Path.Combine(Location.OfAssets, schema.BulkExport); var candidate = await FileManager.Load(templatePath); var batch = Batches.GetBatch(BatchProcessName.ExportSourceDataToILRFile, usingSource.OperatingYear); candidate = candidate.Replace(Token.ForNamespace, schema.Namespace); batch.Scripts .ForEach(script => RunScript(script, inContext, forProvider, ref candidate)); var outputPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "exportILR.xml"); await FileManager.Save(outputPath, candidate); await StripEmptyTags(outputPath); Emitter.Publish(Indentation.FirstLevel, CommonLocalised.Completed); //(!await Validator.IsValid(outputPath, schemaPath)) // .AsGuard<OperationCanceledException, CommonLocalised>(CommonLocalised.SchemaValidationFailed); } }); }
/// <summary> /// Runs... /// </summary> /// <param name="thisBatchFile">this batch file.</param> /// <param name="inThisContext">The in this context.</param> /// <param name="withSupplementaryTokenReplacements">with supplementary token replacements.</param> public void Run( ISQLBatchScript thisBatchScript, IConnectionDetail inThisContext, Func <string, string> withSupplementaryTokenReplacements) { It.IsNull(thisBatchScript) .AsGuard <ArgumentNullException>(nameof(thisBatchScript)); It.IsNull(inThisContext) .AsGuard <ArgumentNullException>(nameof(inThisContext)); if (It.IsInRange(thisBatchScript.Type, TypeOfBatchScript.Ignored)) { return; } Emitter.Publish(Indentation.FirstLevel, $"Running: '{thisBatchScript.Description}'"); if (It.IsInRange(thisBatchScript.Type, TypeOfBatchScript.Statement)) { var content = Pseudonyms.ReplaceTokensIn(thisBatchScript.Command, withSupplementaryTokenReplacements); UsingConnection(inThisContext, x => RunCommand(content, x)); return; } var batches = GetSQLOperations(thisBatchScript.Command, withSupplementaryTokenReplacements); Emitter.Publish(Indentation.FirstLevel, $"Batch contains {batches.Count} statement{(batches.Count > 1 ? "s" : string.Empty)}."); Run(batches.AsSafeReadOnlyList(), inThisContext); }
/// <summary> /// Creates a connection context. /// </summary> /// <param name="usingConnection">using connection.</param> /// <returns> /// a connection context /// </returns> public IConnectionContext Create(IConnectionDetail usingConnection) { return(new ConnectionContext { Connection = new SqlConnection(usingConnection.SQLDetail), Detail = usingConnection }); }
/// <summary> /// Drop the data store. /// </summary> /// <param name="usingStoreName">using the name of the store.</param> /// <param name="inThisContext">in this context.</param> public void DropDataStore(string usingStoreName, IConnectionDetail inThisContext) { It.IsEmpty(usingStoreName) .AsGuard <ArgumentNullException>(nameof(usingStoreName)); It.IsNull(inThisContext) .AsGuard <ArgumentNullException>(nameof(inThisContext)); var command = $"drop database [{usingStoreName}]"; UsingConnection(inThisContext, x => RunCommand(command, x)); }
/// <summary> /// Data store exists? /// </summary> /// <param name="usingStoreName">using the name of the store.</param> /// <param name="inThisContext">in this context.</param> /// <returns> /// the running task containing the result /// </returns> public bool DataStoreExists(string usingStoreName, IConnectionDetail inThisContext) { It.IsEmpty(usingStoreName) .AsGuard <ArgumentNullException>(nameof(usingStoreName)); It.IsNull(inThisContext) .AsGuard <ArgumentNullException>(nameof(inThisContext)); var usingCommand = $"if exists (select * from sys.databases where name = '{usingStoreName}') select 1 else select 0"; return(GetAtom <bool>(usingCommand, inThisContext)); }
/// <summary> /// Sets the learner counts. /// </summary> /// <param name="forConnection">for connection</param> /// <param name="usingProvider">using provider</param> public void SetLearnerCounts(IConnectionDetail forConnection, ILearningProvider usingProvider) { var valids = GetSchemaLearnerCount(forConnection, "valid"); //var invalids = GetSchemaLearnerCount(forConnection, "invalid"); Emitter.Publish(Indentation.FirstLevel, $"{valids} valid record(s) created"); //Emitter.Publish(Indentation.FirstLevel, $"{invalids} invalid record(s) created"); Monitor.SetLearnerCounts(valids, usingProvider.LearnerCount, valids); }
/// <summary> /// Loads... /// </summary> /// <param name="intoSource">into source.</param> /// <param name="onMaster">on master.</param> /// <param name="fromInputFile">from input file.</param> /// <returns> /// the currently running task /// </returns> public async Task Load(IConnectionDetail intoSource, IConnectionDetail onMaster, string fromInputFile) { await Task.Run(async () => { It.IsNull(intoSource) .AsGuard<ArgumentNullException>(nameof(intoSource)); It.IsNull(onMaster) .AsGuard<ArgumentNullException>(nameof(onMaster)); It.IsEmpty(fromInputFile) .AsGuard<ArgumentNullException>(nameof(fromInputFile)); //if (Context.DataStoreExists(intoSource.Name, onMaster)) //{ // Context.DropDataStore(intoSource.Name, onMaster); //} Emitter.Publish($"Creating data store: {intoSource.DBName}"); //Context.CreateDataStore(intoSource.Name, onMaster); var content = await FileManager.Load(fromInputFile); // <= very lazy and inefficient.. var messageNamespace = GetHeaderNameSpace(content); It.IsEmpty(messageNamespace) .AsGuard<ArgumentException, Localised>(Localised.UnableToRetrieveMessageNamespace); var buildSchema = await Schema.Generate( messageNamespace, intoSource, (inContext, loadSchemaPath, createTables) => { var loader = GetLoader(inContext, createTables); loader.Execute(loadSchemaPath, fromInputFile); }); Mediator.Publish(ChangeYearMessage.Create(buildSchema.Year, buildSchema.Collection)); var batchList = Batches.GetBatch(BatchProcessName.BuildSourceDataStore, buildSchema.Year); var s = batchList.Scripts.ElementAt(1).Command; if (s.Contains("ILR")) { s = Regex.Replace(s, @"[A-Z]\w+-[0-9]\w+-[0-9]\w+-[0-9]\w+-[0-9]\w+-[0-9]\w+", Path.GetFileNameWithoutExtension(fromInputFile)); } else { s = s.Replace("originalFileName", Path.GetFileNameWithoutExtension(fromInputFile)); } batchList.Scripts.ElementAt(1).Command = s; Emitter.Publish(batchList.Description); Context.Run(batchList.Scripts, intoSource); }); }
/// <summary> /// Store table exists. /// </summary> /// <param name="usingThisName">using this name.</param> /// <param name="inThisContext">in this context.</param> /// <returns> /// true if it does /// </returns> public bool StoreTableExists(string usingThisName, IConnectionDetail inThisContext) { It.IsEmpty(usingThisName) .AsGuard <ArgumentNullException>(nameof(usingThisName)); It.IsNull(inThisContext) .AsGuard <ArgumentNullException>(nameof(inThisContext)); var usingCommand = $"if object_id('{usingThisName}','u') is not null select 1 else select 0"; return(GetAtom <bool>(usingCommand, inThisContext)); }
/// <summary> /// Gets the provider details. /// </summary> /// <param name="usingDetail">using detail.</param> /// <param name="providerIDs">provider ids.</param> /// <returns> /// returns a list of enriched provider details /// </returns> public IReadOnlyCollection <IProviderDetails> GetProviderDetails(IConnectionDetail usingDetail, IReadOnlyCollection <int> providerIDs) { if (It.IsEmpty(providerIDs)) { return(Collection.EmptyAndReadOnly <IProviderDetails>()); } var script = GetScript(BatchProcessName.GetProviderDetails); script = Substitute.ReplaceTokensIn(script, x => x.Replace("${providerIDs}", string.Join(",", providerIDs))); return(Context.GetItems <ProviderDetails, IProviderDetails>(script, usingDetail, "Name")); }
/// <summary> /// Gets the loader. /// </summary> /// <param name="context">The context.</param> /// <param name="makeNew">if set to <c>true</c> [make new].</param> /// <returns> /// a bulk loader /// </returns> public ISQLXMLBulkLoad4 GetLoader(IConnectionDetail context, bool makeNew) { It.IsNull(context) .AsGuard<ArgumentNullException>(nameof(context)); return new SQLXMLBulkLoad4 { ConnectionString = context.COMDetail, ErrorLogFile = "LoadErrors.xml", KeepIdentity = false, SGDropTables = makeNew, SchemaGen = makeNew, }; }
/// <summary> /// Runs.. /// </summary> /// <param name="theseBatchItems">these batch items.</param> /// <param name="inThisContext">in this context.</param> /// <param name="withSupplementaryTokenReplacements">with supplementary token replacements.</param> public void Run( IReadOnlyCollection <ISQLBatchScript> theseBatchItems, IConnectionDetail inThisContext, Func <string, string> withSupplementaryTokenReplacements) { // note: empty is safe, null is not... It.IsNull(theseBatchItems) .AsGuard <ArgumentNullException>(nameof(theseBatchItems)); It.IsNull(inThisContext) .AsGuard <ArgumentNullException>(nameof(inThisContext)); theseBatchItems .ForEach(script => Run(script, inThisContext, withSupplementaryTokenReplacements)); }
/// <summary> /// Get atom... /// </summary> /// <typeparam name="TReturn">The type of the return.</typeparam> /// <param name="usingThisCommand">using this command.</param> /// <param name="inThisContext">in this context.</param> /// <returns> /// an atom of type <typeparamref name="TReturn" /> /// </returns> public TReturn GetAtom <TReturn>(string usingThisCommand, IConnectionDetail inThisContext) { It.IsEmpty(usingThisCommand) .AsGuard <ArgumentNullException>(nameof(usingThisCommand)); It.IsNull(inThisContext) .AsGuard <ArgumentNullException>(nameof(inThisContext)); return(UsingConnection(inThisContext, x => { using (var cmd = CreateCommand(usingThisCommand, x)) { var result = cmd.ExecuteScalar(); return GetValue <TReturn>(result); } })); }
/// <summary> /// Runs... /// </summary> /// <param name="script">The script.</param> /// <param name="inContext">in context.</param> /// <param name="forCandidate">for candidate.</param> public void RunScript(ISQLBatchScript script, IConnectionDetail inContext, int forProvider, ref string forCandidate) { var result = Task.Run(async() => { It.IsOutOfRange(script.Type, TypeOfBatchScript.File) .AsGuard <ArgumentException>($"{script.Type}"); Emitter.Publish(Localised.PerformingExportScript, script.Description); var commandPath = Path.Combine(Location.OfAssets, script.Command); var command = await FileManager.Load(commandPath); command = Token.DoSecondaryPass(command, forProvider); return(Context.GetAtom <string>(command, inContext)); }).Result; forCandidate = forCandidate.Replace(script.Description, result); Emitter.Publish(Indentation.FirstLevel, CommonLocalised.Completed); }
/// <summary> /// Generates the schema. /// </summary> /// <param name="forMessageNamespace">for message namespace.</param> /// <param name="inContext">in context.</param> /// <param name="andExecuteBulkload">and execute (a) bulk load</param> /// <returns> /// the schema map sued to generate the data source /// </returns> public async Task <ISchemaMap> Generate(string forMessageNamespace, IConnectionDetail inContext, Action <IConnectionDetail, string, bool> andExecuteBulkload) { It.IsEmpty(forMessageNamespace) .AsGuard <ArgumentNullException>(nameof(forMessageNamespace)); It.IsNull(andExecuteBulkload) .AsGuard <ArgumentNullException>(nameof(andExecuteBulkload)); return(await Task.Run(() => { var schemaMap = Schemas.GetSchema(forMessageNamespace); It.IsNull(schemaMap) .AsGuard <ArgumentException, Localised>(Localised.FailedToObtainSchemaMap); var loadSchemaPath = Path.Combine(Location.OfAssets, schemaMap.BulkLoad); var messageSchemaPath = Path.Combine(Location.OfAssets, schemaMap.Message); var relationshipsPath = Path.Combine(Location.OfAssets, "relationships.xml"); SQLDatabase.Open(inContext.SQLDetail); var sqlSchema = new SQLSchema(messageSchemaPath); var relations = GetRelations(relationshipsPath, sqlSchema.NameSpace); sqlSchema.SetRelationships(relations); var autoGenerateTables = false; //var newPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "newSchema.xml"); //var buildSchema = sqlSchema.GenerateBulkLoadSchemaWithIdentity(); //buildSchema.Save(newPath); if (!autoGenerateTables) { sqlSchema.CreateTables(); } andExecuteBulkload(inContext, loadSchemaPath, autoGenerateTables); SQLDatabase.Close(); return schemaMap; })); }
/// <summary> /// Using a connection. /// </summary> /// <param name="inThisContext">in this context; here meaning the connection details</param> /// <param name="runThisAction">run this action.</param> public void UsingConnection(IConnectionDetail inThisContext, Action <IConnectionContext> runThisAction) { It.IsNull(inThisContext) .AsGuard <ArgumentNullException>(nameof(inThisContext)); It.IsNull(runThisAction) .AsGuard <ArgumentNullException>(nameof(runThisAction)); using (var con = Factory.Create(inThisContext)) { try { con.OpenSafe(); runThisAction(con); } catch (Exception e) { Emitter.Publish(e.Message); throw; } } }
/// <summary> /// Using a connection. /// </summary> /// <typeparam name="TReturn">The type of the return.</typeparam> /// <param name="inThisContext">in this context; here meaning the connection details</param> /// <param name="runThisAction">run this action.</param> /// <returns> /// the result of the function call /// </returns> public TReturn UsingConnection <TReturn>(IConnectionDetail inThisContext, Func <IConnectionContext, TReturn> runThisAction) { It.IsNull(inThisContext) .AsGuard <ArgumentNullException>(nameof(inThisContext)); It.IsNull(runThisAction) .AsGuard <ArgumentNullException>(nameof(runThisAction)); using (var con = Factory.Create(inThisContext)) { try { Emitter.Publish($"UsingConnection"); con.OpenSafe(); return(runThisAction(con)); } catch (Exception) { throw; } } }
/// <summary> /// Builds the rules engine. /// </summary> /// <param name="session">The session.</param> /// <param name="context">The context.</param> /// <returns>the OPA rule engine wrapper</returns> public OPAWrapperLib BuildRulesEngine(IConnectionDetail context, IRulebaseConfiguration rulebase, bool depositXDSFiles) { var opaConfiguration = Configuration.GetOPAConfigurationFor(rulebase); var wrapper = new OPAWrapperLib(opaConfiguration.AsDocument()); wrapper.XslFile = Configuration.GetOPATransformationPathFor(rulebase); wrapper.SetLoggingLevel(LoggingType.Error); wrapper.EnableTiming = false; wrapper.Log2Console = false; if (depositXDSFiles) { var dumpPath = Manager.CreateOperatingFolder("Easy OPA Rulebase Files", rulebase.ShortName, rulebase.OperatingYear.AsString()).Result; wrapper.DumpXdsFileName = "UKPRN@global,LearnRefNumber@Learner"; wrapper.DumpXdsPath = dumpPath; } wrapper.AddConString("LoggingDB", context.SQLDetail); wrapper.AddConString("ILR", context.SQLDetail); // ??? wrapper.NumberOfThreads = rulebase.DegreeOfParallelism; return(wrapper); }
public string GetILRFileName(IConnectionDetail forConnection) { var command = "select TOP(1) concat('ILR-', UKPRN,'-', FORMAT([DateTime], 'ddMMyyyy'),'-',FORMAT([DateTime],'hhmmss'), '-' , SerialNo) from dbo.Source;"; return(RunSafe.Try(() => Coordinate.GetAtom <string>(command, forConnection))); }
public void ExecuteCommand(string command, IConnectionDetail context) { UsingConnection(context, x => RunCommand(command, x)); }
/// <summary> /// Creates the schema for... /// </summary> /// <param name="inContext">in context.</param> /// <param name="usingSchemaScripts">using schema scripts.</param> /// <param name="withSecondaryReplacements">with secondary replacements.</param> /// <returns></returns> public void CreateSchemaFor(IConnectionDetail inContext, IReadOnlyCollection <ISQLBatchScript> usingSchemaScripts, Func <string, string> withSecondaryReplacements) { Emitter.Publish(Indentation.FirstLevel, $"Adding structures to {inContext.DBName} data store"); Context.Run(usingSchemaScripts, inContext, withSecondaryReplacements); }
/// <summary> /// Gets the schema learner count. /// </summary> /// <param name="forConnection">For connection</param> /// <param name="thisSchema">(and) this schema</param> /// <returns>the count</returns> public int GetSchemaLearnerCount(IConnectionDetail forConnection, string thisSchema) { var command = $"select count(*) from {thisSchema}.Learner"; return(RunSafe.Try(() => Coordinate.GetAtom <int>(command, forConnection))); }
/// <summary> /// Gets the items. /// this is a very simple list hydration class /// </summary> /// <typeparam name="TReturn">The return type.</typeparam> /// <typeparam name="TContract">the returning contract type</typeparam> /// <param name="usingThisCommand">using this command.</param> /// <param name="inThisContext">in this context.</param> /// <param name="mappedProperties">with mapped properties.</param> /// <returns> /// an list of type <typeparamref name="TContract" /> /// </returns> public IReadOnlyCollection <TContract> GetItems <TReturn, TContract>(string usingThisCommand, IConnectionDetail inThisContext, params string[] mappedProperties) where TContract : class where TReturn : class, TContract, new() { It.IsEmpty(usingThisCommand) .AsGuard <ArgumentNullException>(nameof(usingThisCommand)); It.IsNull(inThisContext) .AsGuard <ArgumentNullException>(nameof(inThisContext)); return(UsingConnection(inThisContext, x => { using (var cmd = CreateCommand(usingThisCommand, x)) { using (var reader = cmd.ExecuteReader()) { return CollectionFromDataReader <TReturn, TContract>(reader, mappedProperties); } } })); }
/// <summary> /// Clone... /// </summary> /// <param name="usingMappings">using (table) mappings.</param> /// <param name="fromDataSource">from data source.</param> /// <param name="toDataTarget">to data target.</param> /// <param name="forProvider">for provider.</param> public void Clone(IReadOnlyCollection <IMapCloneEntityDetails> usingMappings, IConnectionDetail fromDataSource, IConnectionDetail toDataTarget, int forProvider) { using (var writeConnection = new SqlConnection(toDataTarget.SQLDetail)) { Emitter.Publish($"{this.ToString()}.Clone"); writeConnection.Open(); var sqlTransaction = writeConnection.BeginTransaction(); try { using (var readConnection = new SqlConnection(fromDataSource.SQLDetail)) { readConnection.Open(); using (var copier = Build(writeConnection, sqlTransaction)) { usingMappings.ForEach(mapping => { Configure(copier, mapping); Emitter.Publish(Indentation.FirstLevel, Localised.CloningDataFormat, mapping.Master); var command = $"select {string.Join(", ", mapping.Attributes.Select(x => x.Master))} from {mapping.Master} where UKPRN = {forProvider}"; Execute(command, readConnection, x => copier.WriteToServer(x)); }); } } sqlTransaction.Commit(); Emitter.Publish(Indentation.FirstLevel, CommonLocalised.Completed); } catch (Exception exception) { Emitter.Publish(exception.Message); sqlTransaction.Rollback(); throw (exception); } } }
/// <summary> /// Runs.. /// </summary> /// <param name="theseBatchItems">these batch items.</param> /// <param name="inThisContext">in this context.</param> public void Run(IReadOnlyCollection <string> theseBatchItems, IConnectionDetail inThisContext) { UsingConnection(inThisContext, x => theseBatchItems.ForEach(item => RunCommand(item, x))); }