/// <summary> /// Ejecuta los comandos de una cadena SQL /// </summary> internal async Task ExecuteAsync(IDbProvider provider, string sql, Models.ArgumentListModel arguments, TimeSpan timeout, CancellationToken cancellationToken) { using (BlockLogModel block = Manager.SolutionManager.Logger.Default.CreateBlock(LogModel.LogType.Info, "Execute script")) { if (string.IsNullOrWhiteSpace(sql)) { block.Error("The query is empty"); } else { List <ScriptSqlPartModel> scripts = new ScriptSqlTokenizer().Parse(sql, arguments.Constants); int scriptsExecuted = 0; // Ejecuta los scripts if (scripts.Count > 0) { scriptsExecuted = await ExecuteCommandsAsync(provider, block, scripts, ConvertParameters(arguments.Parameters), timeout, cancellationToken); } // Log if (scriptsExecuted == 0) { block.Error("The query is empty"); } else { block.Info($"{scriptsExecuted} command/s executed"); } } } }
/// <summary> /// Crea los scripts de validación de archivos /// </summary> private async Task CreateValidationScriptsAsync() { Details.EtlProjects.CreateValidationScriptsViewModel viewModel = new Details.EtlProjects.CreateValidationScriptsViewModel(this); if (MainController.OpenDialog(viewModel) == BauMvvm.ViewModels.Controllers.SystemControllerEnums.ResultType.Yes) { using (BlockLogModel block = MainController.Logger.Default.CreateBlock(LogModel.LogType.Info, "Comienzo de la creación de archivos de validación")) { ScriptsValidationOptions options = new ScriptsValidationOptions { Connection = viewModel.TreeConnection.Connection, Tables = viewModel.TreeConnection.GetSelectedTables(), OutputPath = viewModel.OutputPath, DataBaseComputeVariable = viewModel.DataBaseComputeVariable, DataBaseValidateVariable = viewModel.DataBaseValidateVariable, Mode = viewModel.ValidateFiles ? ScriptsValidationOptions.ValidationMode.Files : ScriptsValidationOptions.ValidationMode.Database, MountPathVariable = viewModel.MountPathVariable, MountPathContent = viewModel.MountPathContent, FormatType = viewModel.FormatType, SubpathValidate = viewModel.PathValidate, DatabaseTarget = viewModel.DataBaseTarget, GenerateQvs = viewModel.GenerateQvs, TablePrefixes = viewModel.TablePrefixes, CompareString = viewModel.CompareString, DateFormat = viewModel.DateFormat, DecimalSeparator = viewModel.DecimalSeparator, DecimalType = viewModel.DecimalType, BitFields = viewModel.BitFields, CompareOnlyAlphaAndDigits = viewModel.CompareOnlyAlphaAndDigits }; ScriptsValidationGenerator generator = new ScriptsValidationGenerator(Manager, options); // Crea los archivos de prueba try { if (!await generator.GenerateAsync(System.Threading.CancellationToken.None)) { block.Error($"Error en la generación de los archivos de validación. {generator.Errors.Concatenate()}"); } else { block.Info("Fin de la creación de archivos de validación"); MainController.MainWindowController .ShowNotification(BauMvvm.ViewModels.Controllers.SystemControllerEnums.NotificationType.Information, "Generación de archivos de validación", "Ha terminado correctamente la generación de los archivos de validación"); } } catch (Exception exception) { block.Error($"Error en la generación de archivos de validación {exception.Message}"); } // Log MainController.Logger.Flush(); } } }
/// <summary> /// Procesa un archivo de contexto con los archivos del directorio general /// </summary> private static async Task <bool> ProcessAsync(Dictionary <ArgumentType, string> parameters, System.Threading.CancellationToken cancellationToken) { string contextFileName = parameters[ArgumentType.Context].TrimIgnoreNull(); string projectFileName = parameters[ArgumentType.Project].TrimIgnoreNull(); bool processed = false; // Ejecuta el proyecto using (BlockLogModel block = Logger.Default.CreateBlock(LogModel.LogType.Info, $"Process '{projectFileName}'")) { if (string.IsNullOrWhiteSpace(projectFileName) || !System.IO.File.Exists(projectFileName)) { block.Error($"Can't find the project file '{projectFileName}'"); } else if (string.IsNullOrWhiteSpace(contextFileName) || !System.IO.File.Exists(contextFileName)) { block.Error($"Can't find the context file '{contextFileName}'"); } else { JobProjectManager manager = CreateManager(); // Ejecuta el proceso try { if (!await manager.ProcessAsync(projectFileName, contextFileName, cancellationToken)) { string error = string.Empty; // Añade los errores foreach (string innerError in manager.Errors) { error = error.AddWithSeparator(innerError, Environment.NewLine); } // Muestra el error block.Error(error.TrimIgnoreNull()); // Indica si se ha procesado correctamente if (manager.Errors.Count == 0) { processed = true; } } } catch (Exception exception) { block.Error($"Error when execute file '{projectFileName}' with context '{contextFileName}'", exception); } // Log block.Info($"End process '{projectFileName}' with context '{contextFileName}'"); } } // Devuelve el valor que indica si se ha procesado return(processed); }
/// <summary> /// Procesa una exportación de una consulta a CSV /// </summary> internal bool Execute(SentenceExportPartitionedCsv sentence) { bool exported = false; using (BlockLogModel block = Processor.Manager.Logger.Default.CreateBlock(LogModel.LogType.Info, $"Start exporting partitioned to {System.IO.Path.GetFileName(sentence.FileName)}")) { if (string.IsNullOrWhiteSpace(sentence.Command.Sql)) { block.Error("There is not command at export sentence"); } else { ProviderModel provider = Processor.GetProvider(sentence.Source); string baseFileName = Processor.Manager.Step.Project.GetFullFileName(sentence.FileName); if (provider == null) { block.Error($"Can't find the provider. Key: '{sentence.Source}'"); } else if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(baseFileName))) { block.Error($"Can't find the directory '{System.IO.Path.GetDirectoryName(baseFileName)}'"); } else { CommandModel command = Processor.ConvertProviderCommand(sentence.Command, out string error); if (!string.IsNullOrWhiteSpace(error)) { block.Error($"Error when convert export command. {error}"); } else { try { // Exporta los datos Export(provider, command, sentence, baseFileName, block); // Indica que se ha exportado correctamente exported = true; } catch (Exception exception) { block.Error($"Error when export '{sentence.FileName}'", exception); } } } } } // Devuelve el valor que indica si se ha exportado correctamente return(exported); }
/// <summary> /// Exporta las tablas de una base de datos a un directorio /// </summary> private async Task ExportDataBaseAsync() { if (IsExecuting) { SolutionViewModel.MainController.SystemController.ShowMessage("No se pueden exportar los datos en este momento. Espere que finalice la ejecución de los scripts"); } else { ExportDatabaseViewModel viewModel = new ExportDatabaseViewModel(SolutionViewModel); if (SolutionViewModel.MainController.OpenDialog(viewModel) == BauMvvm.ViewModels.Controllers.SystemControllerEnums.ResultType.Yes) { // Exporta los datos using (BlockLogModel block = SolutionViewModel.MainController.Logger.Default .CreateBlock(LogModel.LogType.Info, $"Exportando archivos de {viewModel.ComboConnections.GetSelectedConnection().Name} {viewModel.DataBase}")) { // Arranca la ejecución StartExecution(); // Ejecuta la exportación try { Application.Controllers.Export.ExportDataBaseGenerator generator = new Application.Controllers.Export.ExportDataBaseGenerator(SolutionViewModel.Manager); if (await generator.ExportAsync(block, viewModel.ComboConnections.GetSelectedConnection(), viewModel.DataBase, viewModel.OutputPath, viewModel.FormatType, viewModel.BlockSize, CancellationToken.None)) { block.Info($"Fin de la exportación de la base de datos {viewModel.DataBase}"); SolutionViewModel.MainController.MainWindowController .ShowNotification(BauMvvm.ViewModels.Controllers.SystemControllerEnums.NotificationType.Information, "Explotación de archivos", "Ha terminado correctamente la exportación de archivos"); } else { block.Error($"Error en la exportación de datos. {generator.Errors.Concatenate()}"); } } catch (Exception exception) { block.Error("Exception when create files", exception); } // Detiene la ejecución StopExecuting(); } // Log SolutionViewModel.MainController.Logger.Flush(); } } }
/// <summary> /// Procesa una exportación de una consulta a un archivo parquet /// </summary> internal bool Execute(SentenceExportParquet sentence) { string fileName = Processor.Manager.Step.Project.GetFullFileName(sentence.FileName); bool exported = false; // Procesa la sentencia using (BlockLogModel block = Processor.Manager.Logger.Default.CreateBlock(LogModel.LogType.Info, $"Start exporting to '{fileName}'")) { if (string.IsNullOrWhiteSpace(sentence.Command.Sql)) { block.Error("There is not command at export sentence"); } else { ProviderModel provider = Processor.GetProvider(sentence.Source); if (provider == null) { block.Error($"Can't find the provider. Key: '{sentence.Source}'"); } else { CommandModel command = Processor.ConvertProviderCommand(sentence.Command, out string error); if (!string.IsNullOrWhiteSpace(error)) { block.Error($"Error when convert export command. {error}"); } else { try { // Exporta al archivo Export(block, fileName, provider, command, sentence); // Indica que se ha exportado correctamente exported = true; } catch (Exception exception) { block.Error($"Error when export to '{fileName}'", exception); } } } } } // Devuelve el valor que indica si se ha exportado correctamente return(exported); }
/// <summary> /// Obtiene el plan de ejecución de una consulta /// </summary> internal async Task <DataTable> GetExecutionPlanAsync(IDbProvider provider, string query, Models.ArgumentListModel arguments, TimeSpan timeout, CancellationToken cancellationToken) { DataTable result = null; // Obtiene la tabla using (BlockLogModel block = Manager.Logger.Default.CreateBlock(LogModel.LogType.Info, "Get execution plan")) { if (string.IsNullOrWhiteSpace(query)) { block.Error("The query is empty"); } else { List <SqlSectionModel> scripts = new SqlParser().Tokenize(query, arguments.Constants.ToDictionary(), out string error); if (!string.IsNullOrWhiteSpace(error)) { block.Error(error); } else { ParametersDbCollection parametersDb = ConvertParameters(provider, arguments.Parameters); // Obtiene el datatable foreach (SqlSectionModel script in scripts) { if (script.Type == SqlSectionModel.SectionType.Sql) { string sql = provider.SqlHelper.ConvertSqlNoParameters(script.Content, parametersDb).TrimIgnoreNull(); if (!string.IsNullOrWhiteSpace(sql)) { // Log block.Info($"Get execution plan: {sql}"); // Obtiene el plan de ejecución result = await provider.GetExecutionPlanAsync(sql, null, CommandType.Text, timeout, cancellationToken); } } } // Log block.Info("End query"); } } } // Devuelve la última tabla obtenida return(result); }
/// <summary> /// Exporta las tablas de una conexión a una serie de archivos /// </summary> public async Task <bool> ExportAsync(BlockLogModel block, ConnectionModel connection, string dataBase, string path, SolutionManager.FormatType formatType, long blockSize, CancellationToken cancellationToken) { // Limpia los errores Errors.Clear(); // Carga el esquema await Manager.DbScriptsManager.LoadSchemaAsync(connection, cancellationToken); // Crea el directorio LibHelper.Files.HelperFiles.MakePath(path); // Genera los archivos foreach (ConnectionTableModel table in connection.Tables) { if (!cancellationToken.IsCancellationRequested && (string.IsNullOrWhiteSpace(dataBase) || dataBase.Equals(table.Schema, StringComparison.CurrentCultureIgnoreCase))) { try { // Log block.Info($"Start export table {table.FullName}"); // Exporta la tabla await Task.Run(() => ExportTable(block, connection, table, path, formatType, blockSize)); // Log block.Info($"End export table {table.FullName}"); } catch (Exception exception) { block.Error($"Error when export {table.FullName}", exception); } } } // Devuelve el valor que indica si la exportación ha sido correcta return(Errors.Count == 0); }
/// <summary> /// Crea los archivos SQL de creación de un esquema para reporting sobre una base de datos /// </summary> private void CreateSchemaReportingSql() { Details.Reporting.Tools.CreateScriptsSqlReportingViewModel viewModel = new Details.Reporting.Tools.CreateScriptsSqlReportingViewModel(this); if (MainController.OpenDialog(viewModel) == BauMvvm.ViewModels.Controllers.SystemControllerEnums.ResultType.Yes) { using (BlockLogModel block = MainController.Logger.Default.CreateBlock(LogModel.LogType.Info, "Comienzo de la creación de scripts SQL de reporting")) { // Crea los archivos de esquema try { LibReporting.Solution.ReportingSolutionManager manager = new LibReporting.Solution.ReportingSolutionManager(); // Graba el archivo manager.ConvertSchemaReportingToSql(viewModel.SchemaFileName, viewModel.OutputFileName); // Log block.Info("Fin de la creación de archivos de scripts SQL para informes"); MainController.MainWindowController .ShowNotification(BauMvvm.ViewModels.Controllers.SystemControllerEnums.NotificationType.Information, "Generación de archivos SQL para informes", "Ha terminado correctamente la generación de los archivos SQL de esquema para informes"); } catch (Exception exception) { block.Error($"Error en la generación de archivos de esquema. {exception.Message}"); } // Log MainController.Logger.Flush(); } } }
/// <summary> /// Crea los archivos XML de un esquema /// </summary> private async Task CreateSchemaXmlAsync() { Details.EtlProjects.CreateSchemaXmlViewModel viewModel = new Details.EtlProjects.CreateSchemaXmlViewModel(this); if (MainController.OpenDialog(viewModel) == BauMvvm.ViewModels.Controllers.SystemControllerEnums.ResultType.Yes) { using (BlockLogModel block = MainController.Logger.Default.CreateBlock(LogModel.LogType.Info, "Comienzo de la creación de archivos de esquema")) { // Crea los archivos de esquema try { // Crea los archivos await new Application.Controllers.Schema.SchemaManager(Manager).SaveAsync(viewModel.ComboConnections.GetSelectedConnection(), viewModel.OutputFileName); // Log block.Info("Fin de la creación de archivos de esquema"); MainController.MainWindowController .ShowNotification(BauMvvm.ViewModels.Controllers.SystemControllerEnums.NotificationType.Information, "Generación de archivos de esquema", "Ha terminado correctamente la generación de los archivos de esquema"); } catch (Exception exception) { block.Error($"Error en la generación de archivos de esqu{exception.Message}"); } // Log MainController.Logger.Flush(); } } }
/// <summary> /// Convierte un archivo Excel a parquet /// </summary> internal async Task <bool> ConvertAsync(BlockLogModel block, string source, string target, ExcelfileOptions options, CancellationToken cancellationToken) { bool converted = false; // Convierte el archivo try { LibParquetFiles.Writers.ParquetWriter writer = new LibParquetFiles.Writers.ParquetWriter(target); // Evita el error de await await Task.Delay(1); // Crea el directorio de salida LibHelper.Files.HelperFiles.MakePath(System.IO.Path.GetDirectoryName(target)); // Escribe el archivo using (System.Data.IDataReader reader = new LibExcelFiles.Data.ExcelDataTableReader().LoadFile(source, options.SheetIndex, 1, 10_000_000, options.WithHeader).CreateDataReader()) { writer.Write(reader); } // Indica que se ha convertido el archivo converted = true; } catch (Exception exception) { block.Error($"Error when convert '{source}' to '{target}'", exception); } // Devuelve el valor que indica si se ha convertido return(converted); }
/// <summary> /// Ejecuta un paso /// </summary> protected override async Task <bool> ProcessStepAsync(List <JobContextModel> contexts, JobStepModel step, NormalizedDictionary <object> parameters, CancellationToken cancellationToken) { bool processed = false; DbAggregatorManager dataProviderManager = GetProviderManager(contexts, step); // Procesa el paso using (BlockLogModel block = Logger.Default.CreateBlock(LogModel.LogType.Debug, $"Start execute step {step.Name}")) { if (string.IsNullOrEmpty(step.ScriptFileName) || !System.IO.File.Exists(step.ScriptFileName)) { block.Error($"Cant find the file {step.ScriptFileName}"); } else { DbScriptManager scriptManager = new DbScriptManager(step, dataProviderManager, parameters, Logger); // Ejecuta el paso if (System.IO.Path.GetExtension(step.ScriptFileName).EqualsIgnoreCase(".sql")) { processed = await scriptManager.ProcessBySqlScriptAsync(step.Target, step.ScriptFileName, cancellationToken); } else { processed = await scriptManager.ProcessByFileAsync(step.ScriptFileName, cancellationToken); } } } // Devuelve el valor que indica si se ha procesado correctamente return(processed); }
/// <summary> /// Procesa una importación de archivos CSV para las tablas de esquema de base de datos /// </summary> internal bool Execute(SentenceImportCsvSchema sentence) { bool imported = false; // Importa los archivos using (BlockLogModel block = Processor.Manager.Logger.Default.CreateBlock(LogModel.LogType.Info, $"Start importing tables from {sentence.Target}")) { ProviderModel provider = Processor.GetProvider(sentence.Target); if (provider == null) { block.Error($"Can't find the provider '{sentence.Target}'"); } else { // Supone que todo se importa correctamente imported = true; // Ejecuta las sentencias de importación obtenidas a partir del esquema y los archivos foreach (SentenceImportCsv sentenceCsv in GetImportFileSentences(block, provider, sentence)) { if (imported) { // Log block.Info($"Importing '{sentenceCsv.FileName}' in '{sentenceCsv.Table}'"); // Importa el archivo imported = new ImportCsvManager(Processor).Execute(sentenceCsv); } } } } // Devuelve el valor que indica si se ha importado return(imported); }
/// <summary> /// Exporta los archivos /// </summary> internal void Export(DeploymentModel deployment) { using (BlockLogModel block = Manager.Logger.Default.CreateBlock(LogModel.LogType.Info, $"Start deployment '{deployment.Name}'")) { (NormalizedDictionary <object> constants, string error) = GetParameters(deployment.JsonParameters); if (!string.IsNullOrWhiteSpace(error)) { block.Error(error); } else { ExporterOptions options = new ExporterOptions(deployment.SourcePath, deployment.TargetPath); // Asigna las propiedades options.WriteComments = deployment.WriteComments; options.LowcaseFileNames = deployment.LowcaseFileNames; options.ReplaceArguments = deployment.ReplaceArguments; // Añade los parámetros foreach ((string key, object value) in constants.Enumerate()) { options.AddParameter(key, value); } // Exporta los archivos new DatabrickExporter(Manager.Logger, options).Export(); } } }
/// <summary> /// Ejecuta un script de SQL /// </summary> internal async Task ExecuteAsync(IDbProvider dbProvider, string query, ArgumentListModel arguments, TimeSpan timeout, CancellationToken cancellationToken) { using (BlockLogModel block = Manager.Logger.Default.CreateBlock(LogModel.LogType.Info, "Start script execution")) { SqlScriptExecutor executor = new SqlScriptExecutor(Manager, dbProvider, arguments, timeout); DbScriptsInterpreter interpreter = new DbScriptsInterpreter(executor, Manager.Logger); // Ejecuta el archivo await interpreter.ExecuteAsync(query, null, cancellationToken); // Recopila los errores Errors.AddRange(interpreter.Errors); // y los pasa al log if (Errors.Count == 0) { block.Info("End script execution"); } else { string error = string.Empty; // Agrega los errores foreach (string inner in Errors) { error += inner + Environment.NewLine; } // log block.Error($"Error when execute sql script: {Environment.NewLine}{error}"); } } }
/// <summary> /// Convierte un archivo parquet a csv /// </summary> internal async Task <bool> ConvertAsync(BlockLogModel block, string source, string target, CancellationToken cancellationToken) { bool converted = false; // Convierte el archivo try { LibCsvFiles.Controllers.CsvDataReaderWriter writer = new LibCsvFiles.Controllers.CsvDataReaderWriter(); // Evita el error de await await Task.Delay(1); // Crea el directorio de salida LibHelper.Files.HelperFiles.MakePath(System.IO.Path.GetDirectoryName(target)); // Escribe el archivo using (LibParquetFiles.Readers.ParquetDataReader reader = new LibParquetFiles.Readers.ParquetDataReader(source)) { writer.Save(reader, target); } // Indica que se ha convertido converted = true; } catch (Exception exception) { block.Error($"Error when convert '{source}' to '{target}'", exception); } // Devuelve el valor que indica si se ha convertido return(converted); }
/// <summary> /// Ejecuta el proyecto /// </summary> private async Task ExecuteProjectAsync(BlockLogModel block, string project, string context, CancellationToken cancellationToken) { JobProjectManager manager = new JobProjectManager(Logger); // Añade los procesadores manager.AddProcessor(new LibJobProcessor.Cloud.JobCloudManager(Logger)); manager.AddProcessor(new LibJobProcessor.Database.JobDatabaseManager(Logger)); manager.AddProcessor(new LibJobProcessor.FilesShell.JobFileShellManager(Logger)); manager.AddProcessor(new LibJobProcessor.Rest.JobRestManager(Logger)); // Ejecuta el proyecto await manager.ProcessAsync(project, context, cancellationToken); // Asigna los errores if (manager.Errors.Count == 0) { block.Info("La ejecución del proyecto ha terminado correctamente"); } else { string errorTotal = "Error en la ejecución del proyecto"; // Añade los errores foreach (string error in manager.Errors) { if (!string.IsNullOrWhiteSpace(error)) { errorTotal += Environment.NewLine + error.Trim(); } } // Lanza el mensaje de error block.Error(errorTotal); } }
/// <summary> /// Procesa una exportación de las tablas de esquema a archivos CSV /// </summary> internal bool Execute(SentenceExportCsvSchema sentence) { bool exported = false; // Exporta los archivos using (BlockLogModel block = Processor.Manager.Logger.Default.CreateBlock(LogModel.LogType.Info, $"Start exporting tables from {sentence.Source}")) { ProviderModel provider = Processor.GetProvider(sentence.Source); if (provider == null) { block.Error($"Can't find the provider '{sentence.Source}'"); } else { // Supone que se ha exportado correctamente exported = true; // Elimina los archivos si es necesario if (sentence.DeleteOldFiles) { DeletePathFiles(block, Processor.Manager.Step.Project.GetFullFileName(sentence.Path)); } // Exporta las tablas del esquema (mientras no haya errores foreach (SentenceExportCsv sentenceCsv in GetExportFileSentences(block, provider, sentence)) { if (exported) { exported = new ExportCsvManager(Processor).Execute(sentenceCsv); } } } } // Devuelve el valor que indica si se ha exportado return(exported); }
/// <summary> /// Añade una serie de errores a la colección /// </summary> private void AddErrors(BlockLogModel block, List <string> errors) { foreach (string error in errors) { block.Error(error); Errors.Add(error); } }
/// <summary> /// Ejecuta un archivo /// </summary> private async Task <bool> ExecuteFileAsync(BlockLogModel block, ExecuteFilesItemViewModel file, ConnectionModel connection, Application.Connections.Models.ArgumentListModel arguments, System.Threading.CancellationToken cancellationToken) { bool executed = false; System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromMilliseconds(500).TotalMilliseconds); // Asigna el manejador de eventos al temporizador timer.Elapsed += (sender, args) => file.SetStatus(ExecuteFilesItemViewModel.Status.Start, "Ejecutando ..."); timer.Start(); // Ejecuta el archivo try { string content = LibHelper.Files.HelperFiles.LoadTextFile(System.IO.Path.Combine(file.Path, file.FileName)); // Ejecuta el contenido del archivo if (string.IsNullOrWhiteSpace(content)) { file.SetStatus(ExecuteFilesItemViewModel.Status.Error, "El archivo está vacío"); } else { // Arranca la ejecución file.SetStatus(ExecuteFilesItemViewModel.Status.Start, "Ejecutando ..."); // Ejecuta la consulta await SolutionViewModel.MainViewModel.Manager.ExecuteQueryAsync(connection, content, arguments, connection.TimeoutExecuteScript, cancellationToken); // Detiene la ejecución file.SetStatus(ExecuteFilesItemViewModel.Status.End, "Fin de ejecución"); } // Indica que se ha ejecutado correctamente executed = true; } catch (Exception exception) { block.Error($"Error al ejecutar el archivo '{file.FileName}'"); block.Error(exception.Message); file.SetStatus(ExecuteFilesItemViewModel.Status.Error, $"Error al ejecutar el archivo. {exception.Message}"); } // Detiene el reloj timer.Stop(); timer.Dispose(); // Devuelve el valor que indica si se ha ejecutado correctamente return(!executed); }
/// <summary> /// Crea los scripts de importación de archivos /// </summary> private async Task CreateImportFilesScriptsAsync() { Details.EtlProjects.CreateImportFilesScriptViewModel viewModel = new Details.EtlProjects.CreateImportFilesScriptViewModel(this); if (MainController.OpenDialog(viewModel) == BauMvvm.ViewModels.Controllers.SystemControllerEnums.ResultType.Yes) { using (BlockLogModel block = MainController.Logger.Default.CreateBlock(LogModel.LogType.Info, "Comienzo de la creación de archivos de importación")) { ScriptsImportOptions options = new ScriptsImportOptions { Connection = viewModel.ComboConnections.GetSelectedConnection(), DataBaseVariable = viewModel.DataBaseVariable, PrefixOutputTable = viewModel.PrefixOutputTable, MountPathVariable = viewModel.MountPathVariable, SubPath = viewModel.SubPath, PathInputFiles = viewModel.PathInputFiles, OutputFileName = viewModel.OutputFileName }; ScriptsImportGenerator generator = new ScriptsImportGenerator(Manager, options); // Crea los archivos de prueba try { if (!await generator.GenerateAsync(System.Threading.CancellationToken.None)) { block.Error($"Error en la generación de los archivos de importación. {generator.Errors.Concatenate()}"); } else { block.Info("Fin de la creación de archivos de importación"); MainController.MainWindowController .ShowNotification(BauMvvm.ViewModels.Controllers.SystemControllerEnums.NotificationType.Information, "Generación de archivos de importación", "Ha terminado correctamente la generación de los archivos de importación"); } } catch (Exception exception) { block.Error($"Error en la generación de archivos de importación {exception.Message}"); } // Log MainController.Logger.Flush(); } } }
/// <summary> /// Ejecuta un <see cref="JobModel"/> /// </summary> private async Task ExecuteJobAsync(JobProjectModel project, JobStepModel job, CancellationToken cancellationToken) { using (BlockLogModel block = Logger.Default.CreateBlock(LogModel.LogType.Debug, $"Start execute '{job.Name}'")) { IJobProcesor processor = GetProcessor(job); // Comprueba los datos antes de continuar if (processor == null) { block.Error($"Can't execute '{job.Name}' because can't find a procssor for '{job.ProcessorKey}'"); } else { try { List <JobContextModel> contexts = GetContexts(project, job); // Cambia el nombre de archivo job.ScriptFileName = project.GetFullFileName(job.ScriptFileName, contexts); // Procesa el archivo if (string.IsNullOrWhiteSpace(job.ScriptFileName) || !System.IO.File.Exists(job.ScriptFileName)) { block.Error($"Cant find the file '{job.ScriptFileName}'"); Errors.Add($"Cant find the file '{job.ScriptFileName}'"); } else { bool processed = await processor.ProcessAsync(contexts, job, cancellationToken); // Añade los errores de procesamiento if (!processed) { block.Error($"Error when execute '{job.Name}'{Environment.NewLine}{GetError(processor.Errors)}"); Errors.Add($"Error when execute '{job.Name}'"); Errors.AddRange(processor.Errors); } } } catch (Exception exception) { block.Error($"Error when execute '{job.Name}'", exception); } } } }
/// <summary> /// Obtiene el datatable de una consulta /// </summary> internal async Task <DataTable> GetDataTableAsync(IDbProvider provider, string query, Models.ArgumentListModel arguments, int actualPage, int pageSize, TimeSpan timeout, CancellationToken cancellationToken) { DataTable result = null; // Obtiene la tabla using (BlockLogModel block = Manager.SolutionManager.Logger.Default.CreateBlock(LogModel.LogType.Info, "Execute query")) { if (string.IsNullOrWhiteSpace(query)) { block.Error("The query is empty"); } else { List <ScriptSqlPartModel> scripts = new ScriptSqlTokenizer().Parse(query, arguments.Constants); SparkSqlTools sqlTools = new SparkSqlTools(); ParametersDbCollection parametersDb = ConvertParameters(arguments.Parameters); // Obtiene el datatable foreach (ScriptSqlPartModel script in scripts) { if (script.Type == ScriptSqlPartModel.PartType.Sql) { string sql = sqlTools.ConvertSqlNoParameters(script.Content, parametersDb, "$").TrimIgnoreNull(); if (!string.IsNullOrWhiteSpace(sql)) { // Log block.Info($"Executing: {sql}"); // Obtiene la consulta if (sql.TrimIgnoreNull().StartsWith("SELECT", StringComparison.CurrentCultureIgnoreCase)) { if (pageSize == 0) { result = await provider.GetDataTableAsync(sql, null, CommandType.Text, timeout, cancellationToken); } else { result = await provider.GetDataTableAsync(sql, null, CommandType.Text, actualPage, pageSize, timeout, cancellationToken); } } else { result = await ExecuteScalarQueryAsync(provider, sql, timeout, cancellationToken); } } } } // Log block.Info("End query"); } } // Devuelve la última tabla obtenida return(result); }
/// <summary> /// Procesa una importación de un archivo /// </summary> internal bool Execute(SentenceImportCsv sentence) { bool imported = false; // Recoge los datos necesarios e importa el archivo using (BlockLogModel block = Processor.Manager.Logger.Default.CreateBlock(LogModel.LogType.Info, $"Start import CSV {sentence.FileName}")) { ProviderModel provider = Processor.GetProvider(sentence.Target); // Ejecuta el comando if (provider == null) { block.Error($"Can't find the provider. Key: '{sentence.Target}'"); } else { string fileName = Processor.Manager.Step.Project.GetFullFileName(sentence.FileName); if (!System.IO.File.Exists(fileName)) { block.Error($"Cant find the file '{fileName}'"); } else { try { // Importa el archivo Import(provider, sentence, fileName, block); // Indica que se ha ejecutado correctamente imported = true; } catch (Exception exception) { block.Error($"Error when import CSV '{fileName}'", exception); } } } } // Devuelve el valor que indica si se ha importado return(imported); }
/// <summary> /// Abre la ventana de creación de archivos de pruebas /// </summary> private async Task CreateTestXmlAsync() { Details.EtlProjects.CreateTestXmlViewModel viewModel = new Details.EtlProjects.CreateTestXmlViewModel(this); if (MainController.OpenDialog(viewModel) == BauMvvm.ViewModels.Controllers.SystemControllerEnums.ResultType.Yes) { using (BlockLogModel block = MainController.Logger.Default.CreateBlock(LogModel.LogType.Info, "Comienzo de la creación de proyectos de pruebas")) { XmlTestProjectGenerator generator = new XmlTestProjectGenerator(Manager, viewModel.ComboConnections.GetSelectedConnection(), viewModel.DataBase, viewModel.OutputPath); // Genera los archivos try { if (!await generator.GenerateAsync(block, viewModel.Provider, viewModel.PathVariable, viewModel.DataBaseVariable, viewModel.SufixTestTables, viewModel.FileNameTest, viewModel.FileNameAssert, System.Threading.CancellationToken.None)) { block.Error($"Error en la generación de los archivos de pruebas. {generator.Errors.Concatenate()}"); } else { block.Info("Fin de la creación de proyectos de pruebas"); MainController.MainWindowController .ShowNotification(BauMvvm.ViewModels.Controllers.SystemControllerEnums.NotificationType.Information, "Generación de proyectos XML", "Ha terminado correctamente la generación del archivo de pruebas"); } } catch (Exception exception) { block.Error($"Error en la generación de los archivos de pruebas {exception.Message}"); } // Log MainController.Logger.Flush(); } } }
/// <summary> /// Ejecuta un proyecto /// </summary> public async Task <bool> ProcessAsync(JobProjectModel project, CancellationToken cancellationToken) { // Ejecuta el proyecto using (BlockLogModel block = Logger.Default.CreateBlock(LogModel.LogType.Debug, $"Start execute project '{project.Name}'")) { // Indica que por ahora no ha habido errores Errors.Clear(); // Ejecuta los trabajos if (!Validate(project, out string error)) { // Muestra el error block.Error(error); // Añade el error a la colección de errores Errors.Add(error); } else { // Asigna la fecha de inicio de proceso del proyecto project.StartExecution = DateTime.Now; // Ejecuta los pasos foreach (JobStepModel job in project.Jobs) { if (cancellationToken.IsCancellationRequested) { block.Debug($"The job '{job.Name}' is not processed because user canceled the execution"); } else if (!job.Enabled) { block.Debug($"The job '{job.Name}' is not processed because is disabled"); } else if (HasError) { block.Debug($"The job '{job.Name}' is not processed because there is a previous error"); } else { await ExecuteJobAsync(project, job, cancellationToken); } } } } // Devuelve el valor que indica si se ha procesado correctamente return(!HasError); }
/// <summary> /// Ejecuta un paso /// </summary> protected override async Task <bool> ProcessStepAsync(List <JobContextModel> contexts, JobStepModel step, NormalizedDictionary <object> parameters, CancellationToken cancellationToken) { bool processed = false; // Procesa el paso using (BlockLogModel block = Logger.Default.CreateBlock(LogModel.LogType.Debug, $"Start execute step {step.Name}")) { if (string.IsNullOrEmpty(step.ScriptFileName) || !System.IO.File.Exists(step.ScriptFileName)) { block.Error($"Cant find the file {step.ScriptFileName}"); } else { List <Models.Sentences.BaseSentence> program = new Repository.JobRestRepository().Load(step.ScriptFileName); // Ejecuta el paso processed = await new Manager.ScriptInterpreter(this, step).ProcessAsync(block, program, parameters, cancellationToken); } } // Devuelve el valor que indica si se ha procesado correctamente return(processed); }
/// <summary> /// Exporta los archivos /// </summary> internal void Export(Models.Deployments.DeploymentModel deployment) { using (BlockLogModel block = Manager.Logger.Default.CreateBlock(LogModel.LogType.Debug, "Comienzo de la copia de directorios")) { (NormalizedDictionary <object> parameters, string error) = GetParameters(deployment.JsonParameters); if (!string.IsNullOrWhiteSpace(error)) { block.Error(error); } else { // Elimina el directorio destino HelperFiles.KillPath(deployment.TargetPath); // Copia los directorios CopyPath(block, deployment.SourcePath, deployment.TargetPath, parameters); // Borra los directorios vacíos HelperFiles.KillEmptyPaths(deployment.TargetPath); // Log block.Debug("Fin de la copia de directorios"); } } }
/// <summary> /// Exporta una tabla de datos a un archivo /// </summary> internal async Task <(bool exported, string error)> ExportAsync(LibLogger.Core.LogManager logManager, string fileName, DbDataReader reader, CancellationToken cancellationToken) { string error = string.Empty; // Exporta el archivo using (BlockLogModel block = logManager.Default.CreateBlock(LogModel.LogType.Info, $"Comienzo de grabación del archivo {fileName}")) { // Exporta el archivo try { if (fileName.EndsWith(".csv", StringComparison.CurrentCultureIgnoreCase)) { await ExportToCsvAsync(block, fileName, reader, cancellationToken); } else if (fileName.EndsWith(".parquet", StringComparison.CurrentCultureIgnoreCase)) { await ExportToParquetAsync(block, fileName, reader, cancellationToken); } else { error = "No se reconoce la extensión del archivo"; } } catch (Exception exception) { error = $"Error al grabar el archivo {fileName}. {exception.Message}"; block.Error(error, exception); } // Log block.Info($"Fin de grabación del archivo {fileName}"); logManager.Flush(); } // Devuelve el valor que indica si se ha exportado el archivo return(string.IsNullOrEmpty(error), error); }
/// <summary> /// Añade un error a la colección /// </summary> private void AddError(BlockLogModel block, string message, Exception exception = null) { block.Error(message, exception); Errors.Add(message + Environment.NewLine + exception?.Message); }