/// <summary> /// Ejecuta el script /// </summary> internal async Task ExecuteScriptAsync(ConnectionModel connection, ArgumentListModel arguments, System.Threading.CancellationToken cancellationToken) { Solutions.Details.IDetailViewModel detailsViewModel = MainController.GetActiveDetails(); bool isExecuting = false; // Ejecuta sobre el ViewModel activo if (detailsViewModel != null) { switch (SelectedDetailsViewModel) { case Solutions.Details.Files.FileViewModel viewModel: await viewModel.ExecuteScriptAsync(connection, arguments, cancellationToken); isExecuting = true; break; case Solutions.Details.Connections.ExecuteFilesViewModel viewModel: await viewModel.ExecuteScriptAsync(connection, arguments, cancellationToken); isExecuting = true; break; } } // Si no se está ejecutando nada, muestra un mensaje al usuario if (!isExecuting) { MainController.HostController.SystemController.ShowMessage("Seleccione la ventana de ejecución"); } }
/// <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}"); } } }
public SqlScriptExecutor(DbScriptsManager manager, IDbProvider dbProvider, ArgumentListModel arguments, TimeSpan timeout) { Manager = manager; _dbProvider = dbProvider; _arguments = arguments; _timeout = timeout; }
/// <summary> /// Obtiene los parámetros de un archivo /// </summary> internal (ArgumentListModel arguments, string error) GetParameters() { ArgumentListModel arguments = new ArgumentListModel(); string error = string.Empty; // Carga los parámetros si es necesario if (!string.IsNullOrWhiteSpace(ConnectionParametersFileName)) { if (!System.IO.File.Exists(ConnectionParametersFileName)) { error = "No se encuentra el archivo de parámetros"; } else { try { System.Data.DataTable table = new LibJsonConversor.JsonToDataTableConversor() .ConvertToDataTable(LibHelper.Files.HelperFiles.LoadTextFile(ConnectionParametersFileName)); // Crea la colección de parámetros a partir de la tabla if (table.Rows.Count == 0) { error = "No se ha encontrado ningún parámetro en el archivo"; } else { foreach (System.Data.DataColumn column in table.Columns) { if (column.ColumnName.StartsWith("Constant.", StringComparison.CurrentCultureIgnoreCase)) { arguments.Constants.Add(column.ColumnName.Substring("Constant.".Length), table.Rows[0][column.Ordinal]); } else { arguments.Parameters.Add(column.ColumnName, table.Rows[0][column.Ordinal]); } } } } catch (Exception exception) { error = $"Error cuando se cargaba el archivo de parámetros. {exception.Message}"; } } } // Devuelve el resultado return(arguments, error); }
/// <summary> /// Ejecuta un archivo /// </summary> private async Task <bool> ExecuteFileAsync(BlockLogModel block, ExecuteFilesItemViewModel file, ConnectionModel connection, 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.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> /// Ejecuta una sentencia SQL /// </summary> public async Task <(bool executed, List <string> errors)> ExecuteAsync(string sql, Dictionary <string, object> parameters, CancellationToken cancellationToken) { // Ejecuta la sentencia using (BlockLogModel block = Manager.Logger.Default.CreateBlock(LogModel.LogType.Info, "Execute script")) { if (string.IsNullOrWhiteSpace(sql)) { Errors.Add("The query is empty"); } else { ArgumentListModel arguments = GetArguments(parameters); List <SqlSectionModel> scripts = new SqlParser().Tokenize(sql, arguments.Constants.ToDictionary(), out string error); if (!string.IsNullOrWhiteSpace(error)) { Errors.Add(error); } else { int scriptsExecuted = 0; // Ejecuta los scripts if (scripts.Count > 0) { scriptsExecuted = await ExecuteCommandsAsync(block, _dbProvider, scripts, ConvertParameters(_dbProvider, arguments.Parameters), _timeout, cancellationToken); } // Log if (scriptsExecuted == 0) { Errors.Add("The query is empty"); } else { block.Info($"{scriptsExecuted} command/s executed"); } } } } // Indica que se ha ejecutado return(Errors.Count == 0, Errors); }
/// <summary> /// Ejecuta el script /// </summary> internal async Task ExecuteScriptAsync(ConnectionModel connection, ArgumentListModel arguments, System.Threading.CancellationToken cancellationToken) { // Marca el estado de los scripts InitFileStatus(); // Ejecuta los archivos if (CountEnqueuedFiles() == 0) { SolutionViewModel.MainController.SystemController.ShowMessage("Seleccione al menos un archivo"); } else if (connection == null) { SolutionViewModel.MainController.SystemController.ShowMessage("Seleccione una conexión"); } else { using (BlockLogModel block = SolutionViewModel.Manager.Logger.Default.CreateBlock(LogModel.LogType.Info, "Comienza la ejecución de los archivos")) { System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); bool hasError = false; // Arranca el temporizador stopwatch.Start(); // Ejecuta los archivos foreach (ExecuteFilesItemViewModel file in Files) { if (file.State == ExecuteFilesItemViewModel.Status.Enqueued) { if (hasError) { file.SetStatus(ExecuteFilesItemViewModel.Status.Canceled, "Cancelado por un error anterior"); } else { hasError = await ExecuteFileAsync(block, file, connection, arguments, cancellationToken); } } } // Muestra el tiempo de ejecución stopwatch.Stop(); block.Info($"Tiempo de ejecución: {stopwatch.Elapsed.ToString()}"); SolutionViewModel.Manager.Logger.Flush(); } } }
/// <summary> /// Ejecuta el script /// </summary> internal async Task ExecuteSqlScriptAsync(ConnectionModel connection, ArgumentListModel arguments, System.Threading.CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(Content)) { SolutionViewModel.MainController.SystemController.ShowMessage("Introduzca una consulta para ejecutar"); } else if (connection == null) { SolutionViewModel.MainController.SystemController.ShowMessage("Seleccione una conexión"); } else { using (LibLogger.Models.Log.BlockLogModel block = SolutionViewModel.Manager.Logger.Default.CreateBlock(LibLogger.Models.Log.LogModel.LogType.Info, $"Comienza la ejecución de la consulta")) { string selectedText = GetEditorSelectedText(); // Si no hay nada seleccionado, se ejecuta todo el contenido if (string.IsNullOrWhiteSpace(selectedText)) { selectedText = Content; } // Ejecuta la consulta if (FileName.EndsWith(".sql", StringComparison.CurrentCultureIgnoreCase)) { await SolutionViewModel.Manager.ExecuteQueryAsync(connection, selectedText, arguments, connection.TimeoutExecuteScript, cancellationToken); } else if (FileName.EndsWith(".sqlx", StringComparison.CurrentCultureIgnoreCase)) { await SolutionViewModel.Manager.ExecuteInterpretedQueryAsync(connection, selectedText, arguments, cancellationToken); } else { block.Error("No se reconoce el tipo de archivo como SQL"); } // Muestra el tiempo de ejecución block.Info($"Tiempo de ejecución: {SolutionViewModel.ConnectionExecutionViewModel.ExecutionTime}"); } } }
/// <summary> /// Crea una lista de argumentos con los argumentos predeterminados y los parámetros pasados a la consulta /// </summary> private ArgumentListModel GetArguments(Dictionary <string, object> parameters) { ArgumentListModel arguments = new ArgumentListModel(); // Agrega las constantes iniciales foreach ((string key, object value) in _arguments.Constants.Enumerate()) { arguments.Constants.Add(key, value); } // Agrega los parámetros iniciales foreach ((string key, object value) in _arguments.Parameters.Enumerate()) { arguments.Parameters.Add(key, value); } // y agrega los parámetros obtenidos en la interpretación foreach (KeyValuePair <string, object> parameter in parameters) { arguments.Parameters.Add(parameter.Key, parameter.Value); } // Devuelve la lista de argumentos return(arguments); }
/// <summary> /// Obtiene un <see cref="DataTable"/> paginada con una consulta sobre una conexión /// </summary> public async Task <DataTable> GetDatatableQueryAsync(ConnectionModel connection, string query, ArgumentListModel arguments, int actualPage, int pageSize, TimeSpan timeout, CancellationToken cancellationToken) { return(await Task.Run(() => new SqlCommandController(this).GetDataTableAsync(GetDbProvider(connection), query, arguments, actualPage, pageSize, timeout, cancellationToken))); }
/// <summary> /// Ejecuta una consulta sobre una conexión /// </summary> public async Task ExecuteQueryAsync(ConnectionModel connection, string query, ArgumentListModel arguments, TimeSpan timeout, CancellationToken cancellationToken) { await Task.Run(() => new SqlCommandController(this).ExecuteAsync(GetDbProvider(connection), query, arguments, timeout, cancellationToken)); }
/// <summary> /// Ejecuta una consulta interpretada sobre una conexión /// </summary> public async Task ExecuteInterpretedQueryAsync(ConnectionModel connection, string query, ArgumentListModel arguments, CancellationToken cancellationToken) { await Task.Run(() => new SqlScriptInterpreter(this).ExecuteAsync(GetDbProvider(connection), query, arguments, connection.TimeoutExecuteScript, cancellationToken)); }
/// <summary> /// Obtiene un <see cref="DataTable"/> paginada con una consulta sobre una conexión /// </summary> public async Task <DataTable> GetDatatableQueryAsync(ConnectionModel connection, string query, ArgumentListModel arguments, int actualPage, int pageSize, TimeSpan timeout, CancellationToken cancellationToken) { return(await DbScriptsManager.GetDatatableQueryAsync(connection, query, arguments, actualPage, pageSize, timeout, cancellationToken)); }
/// <summary> /// Ejecuta una consulta interpretada sobre una conexión /// </summary> public async Task ExecuteInterpretedQueryAsync(ConnectionModel connection, string query, ArgumentListModel arguments, CancellationToken cancellationToken) { await DbScriptsManager.ExecuteInterpretedQueryAsync(connection, query, arguments, cancellationToken); }
/// <summary> /// Obtiene el datareader de una consulta /// </summary> public async Task <System.Data.Common.DbDataReader> ExecuteReaderAsync(ConnectionModel connection, string query, ArgumentListModel arguments, TimeSpan timeout, CancellationToken cancellationToken) { return(await DbScriptsManager.ExecuteReaderAsync(connection, query, arguments, timeout, cancellationToken)); }
/// <summary> /// Obtiene el plan de ejecución de una consulta /// </summary> public async Task <DataTable> GetExecutionPlanAsync(ConnectionModel connection, string query, ArgumentListModel arguments, TimeSpan timeout, CancellationToken cancellationToken) { return(await DbScriptsManager.GetExecutionPlanAsync(connection, query, arguments, timeout, cancellationToken)); }
/// <summary> /// Ejecuta el script /// </summary> private async Task ExecuteScriptSqlAsync(IDetailViewModel viewModel, ConnectionModel connection, ArgumentListModel arguments, CancellationToken cancellationToken) { bool isExecuting = false; // Ejecuta sobre el ViewModel activo switch (viewModel) { case Files.ScriptFileViewModel fileViewModel: await fileViewModel.ExecuteSqlScriptAsync(connection, arguments, cancellationToken); isExecuting = true; break; case ExecuteFilesViewModel fileViewModel: await fileViewModel.ExecuteScriptAsync(connection, arguments, cancellationToken); isExecuting = true; break; } // Si no se está ejecutando nada, muestra un mensaje al usuario if (!isExecuting) { SolutionViewModel.MainController.SystemController.ShowMessage("Seleccione la ventana de ejecución"); } }
/// <summary> /// Ejecuta una consulta sobre una conexión /// </summary> public async Task ExecuteQueryAsync(ConnectionModel connection, string query, ArgumentListModel arguments, TimeSpan timeout, CancellationToken cancellationToken) { await DbScriptsManager.ExecuteQueryAsync(connection, query, arguments, timeout, cancellationToken); }
/// <summary> /// Obtiene el datareader de una consulta /// </summary> public async Task <System.Data.Common.DbDataReader> ExecuteReaderAsync(ConnectionModel connection, string query, ArgumentListModel arguments, TimeSpan timeout, CancellationToken cancellationToken) { return(await Task.Run(() => new SqlCommandController(this).ExecuteReaderAsync(GetDbProvider(connection), query, arguments, timeout, cancellationToken))); }
/// <summary> /// Obtiene el plan de ejecución de una consulta /// </summary> public async Task <DataTable> GetExecutionPlanAsync(ConnectionModel connection, string query, ArgumentListModel arguments, TimeSpan timeout, CancellationToken cancellationToken) { return(await Task.Run(() => new SqlCommandController(this).GetExecutionPlanAsync(GetDbProvider(connection), query, arguments, timeout, cancellationToken))); }
/// <summary> /// Exporta el resultado de una consulta a un archivo /// </summary> private async Task <(bool exported, string error)> ExportAsync(ConnectionModel connection, ArgumentListModel arguments, string fileName, CancellationToken cancellationToken) { using (System.Data.Common.DbDataReader reader = await SolutionViewModel.Manager.ExecuteReaderAsync(connection, Query, arguments, connection.TimeoutExecuteScript, cancellationToken)) { return(await new ExportDataController().ExportAsync(SolutionViewModel.MainController.Logger, fileName, reader, cancellationToken)); } }