Utilizamos cookies propias y de terceros. Al navegar entendemos que aceptas el uso de cookies. +Info.
Política de cookies
Proyecto AjpdSoft

· Inicio
· Buscar
· Contactar
· Cookies
· Descargas
· Foros
· Historia
· Nosotros
· Proponer
· Temas
· Top 10
· Trucos
· Tutoriales
· Usuario
· Wiki

Nick


Contraseña


Nuevo usuario


English

Delphi: AjpdSoft Copia Seguridad MySQL
AjpdSoft


Añadida a la sección Descargas la aplicación AjpdSoft Copia Seguridad MySQL: realiza copias de seguridad de las bases de datos (catálogos) de un servidor de MySQL Server. Permite establecer todos los parámetros de configuración de forma visual (usuario, contraseña, host, puerto, etc.). Permite realizar restauraciones de una copia previamente hecha. Liberamos el código fuente - source code en Borland Delphi 6 100% Open Source.



 

 

Características más importantes de AjpdSoft Copia Seguridad MySQL

  • Aplicación de muy sencillo manejo, muy fácil e intuitiva, todas las opciones están en una misma ventana.
  • La aplicación ha sido desarrollada en el lenguaje de programación Borland Delphi 6.
  • No necesita instalación, es suficiente con ejecutar el fichero copiaSeguridadMySQL.exe y disponer en la misma carpeta de los ficheros mysql.exe y mysqldump.exe.
  • Realiza copias de seguridad a fichero en formato SQL (copia lógica) de las bases de datos MySQL indicadas del servidor MySQL Server especificado. Realiza copias de seguridad tanto de servidores locales como externos (Internet).
  • Realiza restauraciones de copias de seguridad existentes. Permite restaurar de un fichero de copia de seguridad a un servidor de MySQL Server.
  • Genera el comando necesario para realizar la restauración o la copia de seguridad, permite modificar dicho comando directamente.
  • Para realizar las copias de seguridad y las restauraciones utiliza los comandos de MySQL mysqldump.exe y mysql.exe respectivamente.

 

AjpdSoft Copia Seguridad MySQL en funcionamiento

AjpdSoft Copia Seguridad MySQL realiza una copia de seguridad utilizando el comando mysqldump.exe (que se incluye en la descarga) de un servidor de MySQL Server. Permite establecer todos los parámetros de configuración de forma visual (usuario, contraseña, host, puerto, etc.), obtiene y muestra el resultado de la copia de seguridad de las bases de datos elegidas de MySQL y permite modificar el comando que se utilizará para la copia antes de ser ejecutado. Admite copia de seguridad tanto del servidor MySQL local como a través de la red o incluso de la conexión a Internet (teniendo el puerto de MySQL abierto en el router o cortafuegos). También permite realizar restauraciones de una copia previamente hecha mediante el comando mysql.exe.

 

Cómo realizar copia de seguridad de bases de datos de MySQL

Para realizar una copia de seguridad lógica (en formato de fichero SQL), AjpdSoft Copia Seguridad MySQL utiliza el comando mysqldump.exe del propio MySQL. Dicho comando se incluye en la descarga aunque se puede sustituir por otra versión que el usuario estime oportuna. El único requisito es que dicho comando ha de estar en la misma carpeta que el fichero de la aplicación.

Desde la pestaña "Realizar copia de seguridad", pulsaremos el botón "Configurar":

AjpdSoft Copia Seguridad MySQL

La aplicación mostrará la pestaña "Configuración" y, dentro de ésta, la pestaña "Copia seguridad":

AjpdSoft Copia Seguridad MySQL

Desde la pestaña anterior podremos elegir las opciones de la copia de seguridad, con las siguientes:

  • Copiar todas las bases de datos (catálogos): marcando esta opción la aplicación realizará copia de seguridad de todas las bases de datos (catálogos) del servidor indicado. Se añadiré el parámetro --all-databases.
  • Bases de datos (catálogos) a copiar: si no se marca la opción "Copiar todas las bases de datos (catálogos)" deberemos indicar aquí el nombre de los catálogos a copiar, si son varios los separaremos con un espacio en blanco. La aplicación añadirá el parámetro --databases y a continuación el nombre de las bases de datos a exportar.
  • Excluir las siguientes tablas: si queremos que no se realice copia de seguridad de una o varias tablas de uno o varios catálogos indicaremos aquí el nombre del catálogo que contiene la tabla que se excluirá, luego un punto y añadiremos el nombre de la tabla. Con el formato: nombre_catalogo.nombre_tabla. Separaremos con espacio en blanco para añadir más de una tabla. La aplicación añadirá el parámetro --ignore-table y las tablas que se ignorarán.
  • Datos de acceso: indicaremos el nombre de usuario y la contraseña de un usuario de SQL Server con permisos suficientes sobre los catálogos a copiar. Introduciremos en "Host" el nombre de red (hostname) o la dirección IP del equipo servidor de MySQL Server del que se hará copia de seguridad. En "Puerto" indicaremos el número de puerto de este servidor (por defecto 3306). Estos datos serán añadidos mediante los parámetros --user, --password, --host y --port.
  • En "Otros parámetros de configuración" podremos activar o desactivar las siguientes opciones:
    • --opt (--add-drop-table --add-locks --create-options --disable-keys --extended-insert --lock-tables --quick --set-charse): marcando esta opción la aplicación realizará la copia de seguridad activando las opciones que se indican entre paréntesis:
      • --add-drop-table: añadirá "drop table" antes de la consulta SQL de creación de cada tabla. Esto hará que si se ejecuta el fichero SQL resultante (en una restauración), antes de crear la tabla la eliminará (si existe).
      • --add-locks: añade LOCK TABLES al principio del volcado de cada tabla y UNLOCK TABLE al final del volcado. Esto hace que la recuperación sea más rápida pues bloquea el acceso a dicha tabla y sólo lo permite para la sesión que lo bloquea, el resto de usuarios no tendrá acceso a la tabla hasta que se ejecute el comando UNLOCK TABLE.
      • --create-options: incluye todas las opciones específicas de creación de tabla de MySQL.
      • --disable-keys: añade para cada tabla, al principio (antes del primer INSERT) la cláusula /*!40000 ALTER TABLE tbl_name DISABLE KEYS */; para desactivar los posibles índices, de esta forma se evitan errores en las inserciones. Después del último INSERT añadirá la línea /*!40000 ALTER TABLE tbl_name ENABLE KEYS */;. En realidad esta opción sólo será efectiva para el caso de tipos de tablas MyISAM con índices no únicos.
      • --extended-insert: esta opción permitirá que el fichero de volcado resultante sea más pequeño, por lo que será más rápida su futura restauración. En realidad lo que hace este parámetro es que cuando se añada una fila con un INSERT INTO nombre_tabla, si está este comando y no está --skip-extended-insert, al realizar un INSERT sólo utilizará un INSERT INTO nombre_tabla VALUES por cada tabla, separando con paréntesis y coma el siguiente INSERT. Mientras que si está el comando --skip-extended-insert se utilizar un INSERT INTO nombre_tabla VALUES por cada registro de cada tabla.
      • --lock-tables: para cada base de datos volcada, bloquea todas las tablas antes de que se produzca el volcado. Las tablas se bloquean pero con lectura local para permitir inserciones concurrentes en el caso de las tablas MyISAM. Para tablas transaccionales de tipo InnoDB es mejor utilizar --single-transaction ya que no necesita bloquear las tablas. Para el bloqueo añade la línea LOCK TABLES tabla WRITE al principio del volcado de cada tabla y UNLOCK TABLES al final para desbloquearla.
      • --quick: esta opción es útil para volcar tablas grandes. Fuerza a mysqldump para recuperar las filas de una tabla desde el servidor de una fila a la vez, en lugar de recibir el conjunto completo de registros y guardarlos en memoria antes de escribirlos.
      • --set-charse: añade las opciones de juego de caracteres al principio del fichero de volcado, con las líneas:

      /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
      /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
      /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
      /*!40101 SET NAMES utf8 */;

    • Copiar sólo definición de tablas, no copiar datos: añadirá el parámetro --no-data, de forma que sólo volcará la estructura de las tablas, no los datos (registros) que contengan.
    • Bloquear tablas antes de la copia: añade el parámetro --lock-tables, si se desmarca añadirá el parámetro --skip-lock-tables, ambos parámetros explicados anteriormente aquí.
    • Insert extendidos: añade el parámetro --lock-tables, si se desmarca añadirá el parámetro --skip-lock-tables, ambos parámetros explicados anteriormente aquí.
    • Exportar columnas de tipo binario en formato hexadecimal: añade el parámetro --hex-blob que indicará a mysqldump que escriba los datos de los campos de tipo binario en hexadecimal. Es recomendable utilizar este parámetro si tenemos campos de tipo de datos LONGBLOB o similiares.
    • Vacía los ficheros ib_logfile: añade el parámetro --flush-logs que permite vaciar los ficheros de log de MySQL antes de empezar el volcado de la copia de seguridad. Esta opción necesita el permiso RELOAD. Si utiliza esta opción en combinación con la opción --all-databases, los logs se vacían para cada base de datos que se copie. La excepción es cuando se usa --lock-all-tables o --master-data: en este caso, los logs se vuelcan sólo una vez, en el momento en que se cierran todas las tablas.
    • Modo verbose (mostrar información resultado ejecución): añade el parámetro --verbose que permite mostrar toda la información posible de lo que se está haciendo.
    • Compatible con otras versiones o sistemas de bases de datos: añade el parámetro --compatible, necesita que se indique el tipo de compatibilidad (ansi, db2, maxdb, mssql, mysql323, mysql40, no_key_options, no_table_options, or no_field_options, oracle, postgresql). Con esta opción mysqldump generará el fichero de forma que sea compatible con las opciones disponibles. Por ejemplo, si disponemos de un servidor con MySQL Server 5.0 y queremos exportar sus bases de datos a otro servidor con MySQL Server 4.0 podremos marcar esta opción y seleccionar "mysql40". Así, cuando restauremos la copia de seguridad en el servidor con MySQL 4.0 no dará error de compatibilidad.
    • Copiar sólo las siguientes tablas: marcando esta opción indicaremos a mysqldump que sólo exporte o haga copia de seguridad de las tablas indicadas. Esta opción es incompatible con la opción --all-databases.
  • Carpeta y fichero de destino: esta opción es fundamental, pues es necesario indicar en que fichero se volvará la copia de seguridad. Esta información se indica añadiendo al final del comando (después de todos los parámetros) el símbolo > y a continuación la ruta del fichero donde se exportará la copia.

Una vez seleccionadas las opciones de configuración volveremos a la pestaña "Realizar copia de seguridad" y podremos ver el comando mysqldump resultante, antes de hacer la copia podremos añadir o modificar los parámetros existentes directamente en el comando:

AjpdSoft Copia Seguridad MySQL

Ejemplo de comando resultante:

mysqldump.exe --user="root" --password="micontraseña" --host=localhost --port=3306 --all-databases --opt --lock-tables --extended-insert --ignore-table=facturacion.documento --hex-blob --verbose > "C:\AjpdSoft\copia_bd.sql"

Una vez que tengamos el comando deseado pulsaremos en el botón "Ejecutar" y se iniciará la copia de seguridad de MySQL con las opciones indicadas:

AjpdSoft Copia Seguridad MySQL

Antes de iniciar la copia nos mostrará un aviso como el siguiente:

AjpdSoft Copia Seguridad MySQL

Con el texto:

---------------------------
Aviso
---------------------------
Se va a realizar una copia de seguridad del servidor de MySQL [localhost] al fichero:

C:\Documents and Settings\alonso\Escritorio\AjpdSoft copia de seguridad\copia_bd.sql

El proceso se ejecutará en segundo plano por lo que puede tardar varios minutos (dependiendo del tamaño de las tablas elegidas) mientras no finalice no se podrá cerrar la aplicación. Si desea cancelar la copia acceda al administrador de tareas y finalice manualmente el proceso "mysqldump.exe" ¿desea continuar?
---------------------------
Sí No
---------------------------

Indicando que el proceso de copia de seguridad de MySQL se ejecutará de forma independiente a la aplicación, puesto que se ejecuta un comando externo (mysqldump). Por ello, la aplicación quedará a la espera de que el comando finalice por alguno de los siguientes motivos: haya dado error (de sintaxis o conexión), haya concluido o bien porque el usuario haya finalizado el proceso mysqldump.exe manualmente (desde el administrador de tareas).

Pulsaremos "Sí" en el mensaje para continuar con la copia. Si hay alguna incompatibilidad con los parámetros seleccionados la aplicación mostrará un mensaje como este:

AjpdSoft Copia Seguridad MySQL

Con el texto:

---------------------------
Aviso
---------------------------
El parámetro --all-databases (-A) es incompatible con el parámetro --tables. Si utiliza el parámetro --tables no debe utilizar el parámetro --all-databases.
---------------------------
Aceptar
---------------------------

Modificaremos el parámetro o las opciones de configuración incompatibles y volveremos a pulsar en "Ejecutar", si todo es correcto se iniciará la copia de seguridad:

AjpdSoft Copia Seguridad MySQL

Una vez finalizada, si hemos añadido el parámetro --verbose, la aplicación capturará la salida del comando mysqldump.exe y la mostrará en "Resultado ejecución":

AjpdSoft Copia Seguridad MySQL

Con el texto:

-- Connecting to localhost...
-- Retrieving table structure for table facturas...
-- Sending SELECT query...
-- Retrieving rows...
-- Retrieving table structure for table contabilidad...
-- Sending SELECT query...
-- Disconnecting from localhost...

Podremos ver el fichero sql generado:

AjpdSoft Copia Seguridad MySQL

Y el contenido del mismo (abriéndo con cualquier editor de texto plano como Notepad ó Notepad++):

AjpdSoft Copia Seguridad MySQL

 

Cómo realizar restauración de copia de seguridad de base de datos MySQL

Para realizar una restauración (recuperar) de una copia de seguridad previamente hecha abriremos AjpdSoft Copia Seguridad MySQL, accederemos a la pestaña "Recuperar/Restaurar copia". Pulsaremos el botón "Configurar" para modificar y añadir las opciones de configuración del parámetro mysql.exe (que es el que la aplicación utiliza para realizar la restauración de la copia de seguridad):

AjpdSoft Copia Seguridad MySQL

Desde esta pestaña de configuración de la restauración indicaremos los siguientes parámetros:

  • Restaurar todas las bases de datos (catálogos): marcando este check se añadirá el parámetro --all-databases que indicará al comando mysql.exe que se restauren todas las bases de datos (catálogos) del fichero origen de la copia de seguridad. Si queremos recuperar un único catálogo desmarcaremos esta opción e indicaremos, en "Nombre catálogo" el nombre del catálogo que queramos recuperar.
  • En "Datos de acceso" indicaremos el usuario, la contraseña, el host (ip o nombre de red del equipo con MySQL Server) y el puerto. La aplicación añadirá los parámetros --user, --password, --host, --port.
  • Modo verbose (mostrar información resultado ejecución): añade el parámetro --verbose que permite mostrar toda la información posible de lo que se está haciendo.
  • En "Fichero origen" es imprescindible seleccionar un fichero de copia de seguridad existente, que será el que tome el comando mysql.exe para realizar la restauración, exportación o recuperación de los datos, los pasará del fichero indicado al servidor de MySQL indicado. La aplicación añadirá, al final de todos los parámetros, el símbolo "<" y a continuación el nombre del fichero indicado.

AjpdSoft Copia Seguridad MySQL

Una vez seleccionadas las opciones de configuración de la restauración, pulsaremos en la pestaña "Recuperar/Restaurar copia" para ver el comando resultante. Desde esta ventana podremos modificar el comando antes de ejecutarlo. Una vez que tengamos el comando adecuado a nuestras necesidades pulsaremos "Ejecutar" para iniciar la restauración:

AjpdSoft Copia Seguridad MySQL

Ejemplo de comando mysql resultante:

mysql.exe --user="root" --password="contraseña" --host=localhost --port=3306 --all-databases < "C:\AjpdSoft\AjpdSoft copia de seguridad\copia_bd.sql"

La aplicación mostrará el siguiente mensaje de aviso que es IMPORTANTE leer y tener en cuenta, pues si existe un catálogo con el mismo nombre en el servidor de MySQL de destino de la restauración será REEMPLAZADO y se perderán los datos. Por lo que es importante proceder con precaución en este punto. Si estamos seguros de que queremos realizar la restauración en el servidor indicado del fichero indicado pulsaremos "Sï":

AjpdSoft Copia Seguridad MySQL

Con el texto:

---------------------------
Aviso
---------------------------
Se va a realizar una restauración del contenido del fichero:

C:\AjpdSoft\AjpdSoft copia de seguridad\copia_bd.sql

En el servidor: localhost

La restauración se ejecutará en segundo plano por lo que puede tardar varios minutos (dependiendo del tamaño de las tablas elegidas) mientras no finalice no se podrá cerrar la aplicación. Si desea cancelar la restauración acceda al administrador de tareas y finalice manualmente el proceso "mysql.exe".

ATENCIÓN: tenga en cuenta que este proceso reemplazará la base de datos actual por la que incluya el fichero seleccionado.

¿Desea continuar?
---------------------------
Sí No
---------------------------

Si se produce algún error podremos verlo en "Resultado ejecución". Por ejemplo si no existe MySQL Server en el servidor "localhost" o si el servicio no está iniciado mostrará este mensaje de error:

AjpdSoft Copia Seguridad MySQL

Con el texto: ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061).

 

Instalación y configuración de AjpdSoft Copia Seguridad MySQL

Podéis descargar el programa con el código fuente (freeware, gratuito) desde esta URL:

Descarga gratuita (freeware) de AjpdSoft Copia Seguridad MySQL

Para el correcto funcionamiento sólo son necesarios los ficheros copiaSeguridadMySQL.exe, mysql.exe y mysqldump.exe, el resto de ficheros corresponden al código fuente y no son necesarios para su ejecución.

La aplicación no necesita instalación, el fichero copiaSeguridadMySQL.exe se puede ejecutar directamente.

 

Datos técnicos de AjpdSoft Copia Seguridad MySQL

Esta aplicación ha sido desarrollada en el lenguaje de programación Borland Delphi 6.

Permite hacer copias de seguridad tanto de un servidor MySQL Server en Windows como de un servidor MySQL Server en GNU Linux (o en cualquier otro sistema operativo). Lógicamente, la aplicación de copia de seguridad sólo funciona en sistemas operativos Microsoft Windows.

Para realizar las copias de seguridad y las restauraciones utiliza los comandos de MySQL mysqldump.exe y mysql.exe respectivamente, tal y como se indica aquí.

Si eres desarrollador de software y te has registrado en nuestra web (si aún no te has registrado puedes hacerlo desde aquí gratuitamente) puedes descargar el código fuente 100% Open Source (completo y totalmente gratuito) en Borland (ahora Codegear) Delphi 6:

AjpdSoft Copia Seguridad MySQL (Código fuente Open Source en Borland Delphi 6)

AjpdSoft Copia Seguridad MySQL ha sido testeada y funciona correctamente en equipos con sistemas operativos: Windows 98, Windows XP, Windows 2000 Server, Windows Server 2003, Windows Vista y Windows Seven (7).

 

A quién va dirigida AjpdSoft Copia Seguridad MySQL

La aplicación va dirigida a administradores de sistemas y administradores de bases de datos que dispongan de servidores con MySQL Server y quieran programar copias de seguridad lógicas de sus bases de datos.

También puede ser útil para estudiantes que tengan que realizar algún proyecto de ejemplo de copia de seguridad de MySQL.

 

Anexo

  • Código fuente (source code) de la aplicación completa:

 

unit UnidadMenuPrincipal;

{$R WinXP.res} 

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ComCtrls, ExtCtrls, inifiles, shellapi,
  ThemeMgr, strutils;

type
  TformMenuprincipal = class(TForm)
    tab: TPageControl;
    tabEjecutar: TTabSheet;
    tabConfiguracion: TTabSheet;
    gComando: TGroupBox;
    btEjecutar: TBitBtn;
    txtComando: TMemo;
    gResultado: TGroupBox;
    Panel1: TPanel;
    txtResultado: TMemo;
    Label1: TLabel;
    be: TStatusBar;
    LWEB: TLabel;
    dlGuardar: TSaveDialog;
    bObtener: TBitBtn;
    btSalir: TButton;
    ThemeManager1: TThemeManager;
    tabRecuperar: TTabSheet;
    gComandoRes: TGroupBox;
    bEjecutarRestaurar: TBitBtn;
    txtComandoRestaurar: TMemo;
    bObtenerComandoRestaurar: TBitBtn;
    gResultadoRes: TGroupBox;
    Panel2: TPanel;
    txtResultadoRes: TMemo;
    dlAbrir: TOpenDialog;
    tabConf: TPageControl;
    tabConfCop: TTabSheet;
    tabConfRestaurar: TTabSheet;
    GroupBox1: TGroupBox;
    lbBD: TLabel;
    Label3: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    txtBD: TEdit;
    opCopiarBDTodas: TCheckBox;
    txtExcluirTablas: TEdit;
    GroupBox5: TGroupBox;
    Label2: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    txtUsuario: TEdit;
    txtContrasena: TEdit;
    txtPuerto: TEdit;
    txtHost: TEdit;
    GroupBox2: TGroupBox;
    opOPT: TCheckBox;
    opSoloDefinicion: TCheckBox;
    opBloquear: TCheckBox;
    opHexadecimal: TCheckBox;
    opLog: TCheckBox;
    GroupBox3: TGroupBox;
    Label8: TLabel;
    txtDestino: TEdit;
    bSelDestino: TButton;
    opModoVerbose: TCheckBox;
    GroupBox7: TGroupBox;
    Label9: TLabel;
    txtBDRes: TEdit;
    GroupBox8: TGroupBox;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    txtUsuarioRes: TEdit;
    txtContrasenaRes: TEdit;
    txtPuertoRes: TEdit;
    txtHostRes: TEdit;
    GroupBox9: TGroupBox;
    Label12: TLabel;
    txtOrigen: TEdit;
    bSelOrigen: TButton;
    opCompatible: TCheckBox;
    lsCompatibleLista: TComboBox;
    opCopiarTablas: TCheckBox;
    txtCopiarTablas: TEdit;
    Label17: TLabel;
    opResTodosCatalogos: TCheckBox;
    bConfigCopia: TBitBtn;
    bConfRes: TBitBtn;
    opInsertExtendidos: TCheckBox;
    GroupBox4: TGroupBox;
    opResVerbose: TCheckBox;
    procedure opCopiarBDTodasClick(Sender: TObject);
    procedure btEjecutarClick(Sender: TObject);
    procedure txtUbicacionComandoChange(Sender: TObject);
    procedure txtBDChange(Sender: TObject);
    procedure txtUsuarioChange(Sender: TObject);
    procedure txtHostChange(Sender: TObject);
    procedure txtContrasenaChange(Sender: TObject);
    procedure txtPuertoChange(Sender: TObject);
    procedure opOPTClick(Sender: TObject);
    procedure txtDestinoChange(Sender: TObject);
    procedure componerComando;
    procedure componerComandoRestaurar; 
    procedure opLogClick(Sender: TObject);
    procedure opHexadecimalClick(Sender: TObject);
    procedure opBloquearClick(Sender: TObject);
    procedure opSoloDefinicionClick(Sender: TObject);
    procedure txtExcluirTablasChange(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure LWEBClick(Sender: TObject);
    procedure bSelDestinoClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure bObtenerClick(Sender: TObject);
    procedure btSalirClick(Sender: TObject);
    procedure bEjecutarRestaurarClick(Sender: TObject);
    procedure bSelOrigenClick(Sender: TObject);
    procedure opModoVerboseClick(Sender: TObject);
    procedure txtBDResChange(Sender: TObject);
    procedure txtUsuarioResChange(Sender: TObject);
    procedure txtContrasenaResChange(Sender: TObject);
    procedure txtHostResChange(Sender: TObject);
    procedure txtPuertoResChange(Sender: TObject);
    procedure txtOrigenChange(Sender: TObject);
    procedure bObtenerComandoRestaurarClick(Sender: TObject);
    procedure opCompatibleClick(Sender: TObject);
    procedure opCopiarTablasClick(Sender: TObject);
    procedure lsCompatibleListaChange(Sender: TObject);
    procedure opResTodosCatalogosClick(Sender: TObject);
    procedure bConfigCopiaClick(Sender: TObject);
    procedure bConfResClick(Sender: TObject);
    procedure opInsertExtendidosClick(Sender: TObject);
    procedure opResVerboseClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  formMenuprincipal: TformMenuprincipal;

implementation

{$R *.dfm}

function obtenerFicheroComando (comando : string; caracterSeparador : string) : string;
var
  posicionCar : integer;
  nombreFichero : string;
begin
  Result := '';
  posicionCar := Pos(caracterSeparador, comando);
  if posicionCar > 0 then
  begin
    if posicionCar + 1 <= Length(comando) then
    begin
      nombreFichero := Trim(copy(comando, posicionCar + 1, length(comando)));
      //quitar comillas dobles
      while Pos('"', nombreFichero) > 0 do
      begin
        Delete(nombreFichero, Pos('"', nombreFichero), 1);
      end;
    end;
    Result := nombreFichero;
  end;
end;


//Lee un booleano de un INI
function leBoolINI (clave, cadena : string; defecto : boolean) : boolean;
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    result := readbool (clave, cadena, defecto);
  finally
    free;
  end;
end;


//Lee una cadena de texto de un INI
function leCadINI (clave, cadena : string; defecto : string) : string;
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    result := readString (clave, cadena, defecto);
  finally
    free;
  end;
end;

//escribe un Booleano en un INI
procedure esBoolINI (clave, cadena : string; valor : boolean);
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    writeBool (clave, cadena, valor);
  finally
    free;
  end;
end;



//escribe una cadena de texto en un INI
procedure esCadINI (clave, cadena, valor : string);
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    writeString (clave, cadena, valor);
  finally
    free;
  end;
end;


function IsWinNT: boolean;
var
  OSV: OSVERSIONINFO;
begin
  OSV.dwOSVersionInfoSize := sizeof(osv);
  GetVersionEx(OSV);
  result := OSV.dwPlatformId = VER_PLATFORM_WIN32_NT;
end;

function ejecutarComando (comando : string) : string;
var
  Buffer: array[0..4096] of Char;
  si: STARTUPINFO;
  sa: SECURITY_ATTRIBUTES;
  sd: SECURITY_DESCRIPTOR;
  pi: PROCESS_INFORMATION;
  newstdin, newstdout, read_stdout, write_stdin: THandle;
  exitcod, bread, avail: Cardinal;
begin
  Result:= '';
  if IsWinNT then
  begin
    InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(@sd, true, nil, false);
    sa.lpSecurityDescriptor := @sd;
  end
  else sa.lpSecurityDescriptor := nil;
  sa.nLength := sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle := TRUE;
  if CreatePipe(newstdin, write_stdin, @sa, 0) then
  begin
    if CreatePipe(read_stdout, newstdout, @sa, 0) then
    begin
      GetStartupInfo(si);
      with si do
      begin
        dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
        wShowWindow := SW_HIDE;
        hStdOutput := newstdout;
        hStdError := newstdout;
        hStdInput := newstdin;
      end;
      Fillchar(Buffer, SizeOf(Buffer), 0);
      GetEnvironmentVariable('COMSPEC', @Buffer, SizeOf(Buffer) - 1);
      StrCat(@Buffer,PChar(' /c ' + comando));
      if CreateProcess(nil, @Buffer, nil, nil,
          TRUE, CREATE_NEW_CONSOLE, nil, nil, si, pi) then
      begin
        repeat
          PeekNamedPipe(read_stdout, @Buffer, SizeOf(Buffer) - 1, @bread, @avail, nil);
          if bread > 0 then
          begin
            Fillchar(Buffer, SizeOf(Buffer), 0);
            ReadFile(read_stdout, Buffer, bread, bread, nil);
            Result:= Result + String(PChar(@Buffer));
          end;
          Application.ProcessMessages;
          GetExitCodeProcess(pi.hProcess, exitcod);
        until (exitcod <> STILL_ACTIVE) and (bread = 0);
      end;
      CloseHandle(read_stdout);
      CloseHandle(newstdout);
    end;
    CloseHandle(newstdin);
    CloseHandle(write_stdin);
  end;
end;

procedure TformMenuprincipal.componerComando ();
var
  comando : string;
begin
  comando := 'mysqldump.exe';
  if txtUsuario.Text <> '' then
    comando := comando + ' --user="' + txtUsuario.Text + '"';
  if txtContrasena.Text <> '' then
    comando := comando + ' --password="' + txtContrasena.Text + '"';
  if txtHost.Text <> '' then
    comando := comando + ' --host=' + txtHost.Text;
  if txtPuerto.Text <> '' then
    comando := comando + ' --port=' + txtPuerto.Text;
  if opCopiarBDTodas.Checked then
    comando := comando + ' --all-databases'
  else
    if txtBD.Text <> '' then
      comando := comando + ' --databases ' + txtBD.Text;
  if opSoloDefinicion.Checked then
    comando := comando + ' --no-data';
  if opOPT.Checked then
    comando := comando + ' --opt';
  if opBloquear.Checked then
    comando := comando + ' --lock-tables'
  else
    comando := comando + ' --skip-lock-tables';
  if opInsertExtendidos.Checked then
    comando := comando + ' --extended-insert'
  else
    comando := comando + ' --skip-extended-insert';
  if txtExcluirTablas.Text <> '' then
    comando := comando + ' --ignore-table=' + txtExcluirTablas.Text;
  if opHexadecimal.Checked then
    comando := comando + ' --hex-blob';
  if opLog.Checked then
    comando := comando + ' --flush-logs';
  if opModoVerbose.Checked then
    comando := comando + ' --verbose';
  if opCompatible.Checked then
    comando := comando + ' --compatible=' + lsCompatibleLista.Text;
  if opCopiarTablas.Checked then
    comando := comando + ' --tables ' + txtCopiarTablas.Text;
  if txtDestino.Text <> '' then
    comando := comando + ' > "' + txtDestino.Text + '"';
  txtComando.Text := comando;
end;

procedure TformMenuprincipal.componerComandoRestaurar ();
var
  comando : string;
begin
  comando := 'mysql.exe';
  if txtUsuarioRes.Text <> '' then
    comando := comando + ' --user="' + txtUsuarioRes.Text + '"';
  if txtContrasenaRes.Text <> '' then
    comando := comando + ' --password="' + txtContrasenaRes.Text + '"';
  if txtHostRes.Text <> '' then
    comando := comando + ' --host=' + txtHostRes.Text;
  if txtPuertoRes.Text <> '' then
    comando := comando + ' --port=' + txtPuertoRes.Text;
  if opResTodosCatalogos.Checked then
    comando := comando + ' --all-databases'
  else
    if txtBDRes.Text <> '' then
      comando := comando + ' --database ' + txtBDRes.Text;
  if opResVerbose.Checked then
    comando := comando + ' --verbose';
  if txtOrigen.Text <> '' then
    comando := comando + ' < "' + txtOrigen.Text + '"';
  txtComandoRestaurar.Text := comando;
end;

procedure TformMenuprincipal.opCopiarBDTodasClick(Sender: TObject);
begin
  if opCopiarBDTodas.Checked then
  begin
    txtBD.Enabled := false;
    lbBD.Enabled := false;
  end
  else
  begin
    lbBD.Enabled := true;
    txtBD.Enabled := true;
  end;
  componerComando;
end;

function buscarTexto (textoBuscar : string; textoCompleto : string) : boolean;
var
  posicion : integer;
begin
  result := false;
  posicion := Pos (AnsiUpperCase (textoBuscar), AnsiUpperCase (textoCompleto));
  if (posicion <> 0) then
  begin
    if (Length(textoCompleto) >= posicion + 1) then
    begin
      if (textoCompleto [posicion + length(textoBuscar)] = ' ') then
        Result := true
      else
        Result := false;
    end
    else
      Result := false;
  end;
end;

function verificarSintaxisComando (comando : string; copia : boolean;
    mostrarAvisos : boolean) : boolean;
begin
  Result := true;

  //si está el parámetro --tables debe estar el parámetro --databases (-B)
  if Result = true then
  begin
    if (buscarTexto ('--tables', comando)) then
    begin
      if not (buscarTexto ('--databases', comando)) and
          not (buscarTexto ('-b', comando))then
      begin
        Result := false;
        if mostrarAvisos then
          MessageDlg('El parámetro --tables necesita que se incluya ' +
              'el parámetro --databases ' +
              'para indicar el nombre de la base de datos de la que se ' +
              'copiarán las tablas indicadas.', mtWarning, [mbok], 0);
      end;
    end;
  end;


  //si está el parámetro --all-databases (-A) no debe estar --tables
  if Result = true then
  begin
    if (buscarTexto ('--all-databases', comando)) or
        (buscarTexto ('-a', comando)) then
    begin
      if (buscarTexto ('--tables', comando)) then
      begin
        Result := false;
        if mostrarAvisos then
          MessageDlg('El parámetro --all-databases (-A) es incompatible con ' +
              'el parámetro --tables. Si utiliza el parámetro --tables no ' +
              'debe utilizar el parámetro --all-databases.',
              mtWarning, [mbok], 0);
      end;
    end;
  end;


  //si está el parámetro --all-databases (-A) no debe estar --databases ni -B
  if Result = true then
  begin
    if (buscarTexto ('--all-databases', comando)) or
        (buscarTexto ('-a', comando)) then
    begin
      if (buscarTexto ('-b', comando)) or (buscarTexto ('--databases', comando)) then
      begin
        Result := false;
        if mostrarAvisos then
          MessageDlg('El parámetro --all-databases (-A) es incompatible con ' +
              'el parámetro --databases (-B). Si utiliza el ' +
              'parámetro --all-databases no ' +
              'debe utilizar el parámetro --databases.', mtWarning, [mbok], 0);
      end;
    end;
  end;
end;

function verificarSintaxisComandoRestaurar (comando : string; copia : boolean;
    mostrarAvisos : boolean) : boolean;
begin
  Result := true;

  //si está el parámetro --tables debe estar el parámetro --databases (-B)
{  if Result = true then
  begin
    if (buscarTexto ('--tables', comando)) then
    begin
      if not (buscarTexto ('--databases', comando)) and
          not (buscarTexto ('-b', comando))then
      begin
        Result := false;
        if mostrarAvisos then
          MessageDlg('El parámetro --tables necesita que se ' +
              'incluya el parámetro --databases ' +
              'para indicar el nombre de la base de datos de la que se ' +
              'copiarán las tablas indicadas.', mtWarning, [mbok], 0);
      end;
    end;
  end;}
end;

procedure insertarPATH (variable : string);
var
  pathOriginal : string;
begin
  //guardamos el valor de la variable path original
  pathOriginal := GetEnvironmentVariable(PCHar('PATH'));

  //añadimos el directorio actual a la variable PATH
  SetEnvironmentVariable(PChar('PATH'), PChar(pathOriginal + ';' + variable));

  //dejar valor anterior
  //SetEnvironmentVariable(PChar(variable),PChar(pathOriginal))
end;

procedure TformMenuprincipal.btEjecutarClick(Sender: TObject);
var
  seguir : boolean;
  procesoIniciado : boolean;
begin
  seguir := true;
  if not FileExists(IncludeTrailingBackslash(ExtractFilePath(Application.ExeName)) +
      'mysqldump.exe') then
  begin
    tabConfCop.Show;
    MessageDlg('Debe copiar el fichero "mysqldump.exe" a la carpeta de la ' +
        'aplicación (donde se encuentra el fichero "copiaSeguridadMySQL.exe".',
        mtInformation, [mbok], 0);
    seguir := false;
  end;

  if txtDestino.Text = '' then
  begin
    tabConfCop.Show;
    MessageDlg('Debe indicar una unidad, carpeta y fichero de destino ' +
        'para la copia de seguridad.', mtInformation, [mbok], 0);
    txtDestino.SetFocus;
    seguir := false;
  end;

  if not DirectoryExists (ExtractFilePath (obtenerFicheroComando(txtComando.Text, '>'))) then
  begin
    tabConfCop.Show;
    MessageDlg('Debe indicar una carpeta de destino existente.',
        mtInformation, [mbok], 0);
    txtDestino.SetFocus;
    seguir := false;
  end;


  if seguir then
  begin
    if MessageDlg('Se va a realizar una copia de seguridad del servidor ' +
        'de MySQL [' + txtHost.Text + '] al fichero: ' + chr(13) + chr(13) +
        obtenerFicheroComando(txtComando.Text, '>') +
        chr(13) + chr(13) + 'El proceso se ejecutará en ' +
        'segundo plano por lo que puede tardar varios minutos ' +
        '(dependiendo del tamaño de las tablas elegidas) mientras ' +
        'no finalice no se podrá cerrar la aplicación. Si desea cancelar ' +
        'la copia acceda al administrador de tareas y finalice manualmente el ' +
        'proceso "mysqldump.exe" ¿desea continuar?',
        mtWarning, [mbno, mbyes], 0) = mryes then
      begin
        if FileExists(obtenerFicheroComando(txtComando.Text, '>')) then
          seguir := MessageDlg('¡¡¡Atención!!! el fichero de destino: ' +
              chr(13) + chr(13) + obtenerFicheroComando(txtComando.Text, '>')
               + chr(13) + chr(13) +
              'Ya existe ¿desea reemplazarlo?', mtWarning, [mbyes, mbno], 0) = mryes;
        if seguir then
        begin
          if Pos('<', txtComando.Text) > 0 then
            MessageDlg('¡¡¡Atención!!! no puede utilizar el carácter "<" ' +
                'para realizar una copia de seguridad, pues este carácter ' +
                'es para restautar una copia de seguridad existente. Si ' +
                'quiere realizar una restauración acceda a la pestaña ' +
                '"Recuperar/Restaurar copia".',
                mtWarning, [mbok], 0)
          else
          begin
            if verificarSintaxisComando (txtComando.text, true, true) then
            begin
              gComando.Enabled := false;
              gResultado.Enabled := false;
              tabConfCop.Enabled := false;
              btEjecutar.Enabled := false;
              bObtener.Enabled := false;
              txtComando.Enabled := false;
              btSalir.Enabled := false;
              Screen.Cursor := crHourGlass;
              be.Panels[1].Text := 'Ejecutándose copia, espere por favor...';
              insertarPATH(ExtractFilePath(Application.ExeName));
              txtResultado.Text := ejecutarComando(txtComando.Text);
              gComando.Enabled := true;
              gResultado.Enabled := true;
              Screen.Cursor := crDefault;
              be.Panels[1].Text := 'Copia finalizada';
              tabConfCop.Enabled := true;
              btEjecutar.Enabled := true;
              bObtener.Enabled := true;
              txtComando.Enabled := true;
              btSalir.Enabled := true;
            end;
          end;
        end;
      end;
  end;
end;

procedure TformMenuprincipal.txtUbicacionComandoChange(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.txtBDChange(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.txtUsuarioChange(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.txtHostChange(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.txtContrasenaChange(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.txtPuertoChange(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.opOPTClick(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.txtDestinoChange(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.opLogClick(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.opHexadecimalClick(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.opBloquearClick(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.opSoloDefinicionClick(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.txtExcluirTablasChange(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  esBoolINI('Configuración', 'Copiar todas las bases de datos (catálogos)',
      opCopiarBDTodas.Checked);
  esCadINI('Configuración', 'Bases de datos (catálogos) a copiar', txtBD.Text);
  esCadINI('Configuración', 'Excluir tablas', txtExcluirTablas.Text);
  esCadINI('Datos acceso', 'Usuario', txtUsuario.Text);
  esCadINI('Datos acceso', 'Contraseña', txtContrasena.Text);
  esCadINI('Datos acceso', 'Host', txtHost.Text);
  esCadINI('Datos acceso', 'Puerto', txtPuerto.Text);
  esBoolINI('Configuración', 'OPT', opOPT.Checked);
  esBoolINI('Configuración', 'Sólo definición', opSoloDefinicion.Checked);
  esBoolINI('Configuración', 'Bloquear tablas', opBloquear.Checked);
  esBoolINI('Configuración', 'Hexadecimal', opHexadecimal.Checked);
  esBoolINI('Configuración', 'Vaciar log', opLog.Checked);
  esCadINI('Configuración', 'Destino', txtDestino.Text);
  esCadINI('Configuración', 'Comando', txtComando.Text);
  esBoolINI('Configuración', 'Comando', opModoVerbose.Checked);
  esBoolINI('Configuración', 'Copiar tablas', opCopiarTablas.Checked);
  esCadINI('Configuración', 'Tablas a copiar', txtCopiarTablas.Text);
  esBoolINI('Configuración', 'Compatibilidad', opCompatible.Checked);
  esCadINI('Configuración', 'Compatibilidad - Tipo', lsCompatibleLista.Text);
  esBoolINI('Configuración', 'Insert extendidos', opInsertExtendidos.Checked);

  esCadINI('Restauración', 'Catálogo', txtBDRes.Text);
  esCadINI('Restauración', 'Usuario', txtUsuarioRes.Text);
  esCadINI('Restauración', 'Contraseña', txtContrasenaRes.Text);
  esCadINI('Restauración', 'Host', txtHostRes.Text);
  esCadINI('Restauración', 'Puerto', txtPuertoRes.Text);
  esCadINI('Restauración', 'Origen', txtOrigen.Text);
  esCadINI('Restauración', 'Comando', txtComandoRestaurar.Text);
  esBoolINI('Restauración', 'Verbose', opResVerbose.Checked);
end;

procedure TformMenuprincipal.FormCreate(Sender: TObject);
begin
  opCopiarBDTodas.Checked :=
      leBoolINI('Configuración', 'Copiar todas las bases de datos (catálogos)', true);
  txtBD.Text := leCadINI('Configuración', 'Bases de datos (catálogos) a copiar', '');
  txtExcluirTablas.Text := leCadINI('Configuración', 'Excluir tablas', '');
  txtUsuario.Text := leCadINI('Datos acceso', 'Usuario', 'root');
  txtContrasena.Text := leCadINI('Datos acceso', 'Contraseña', '');
  txtHost.Text := leCadINI('Datos acceso', 'Host', 'localhost');
  txtPuerto.Text := leCadINI('Datos acceso', 'Puerto', '3306');
  opOPT.Checked := leBoolINI('Configuración', 'OPT', true);
  opSoloDefinicion.Checked := leBoolINI('Configuración', 'Sólo definición', false);
  opBloquear.Checked := leBoolINI('Configuración', 'Bloquear tablas', false);
  opHexadecimal.Checked := leBoolINI('Configuración', 'Hexadecimal', true);
  opLog.Checked := leBoolINI('Configuración', 'Vaciar log', false);
  txtDestino.Text := leCadINI('Configuración', 'Destino',
      IncludeTrailingBackslash(ExtractFilePath(Application.ExeName)) + 'copia_bd.sql');
  txtComando.Text := leCadINI('Configuración', 'Comando', '');
  opModoVerbose.Checked := leBoolINI('Configuración', 'Comando', true);
  opCopiarTablas.Checked := leBoolINI('Configuración', 'Copiar tablas', false);
  txtCopiarTablas.Text := leCadINI('Configuración', 'Tablas a copiar', '');
  opCompatible.Checked := leBoolINI('Configuración', 'Compatibilidad', false);
  lsCompatibleLista.Text := leCadINI('Configuración', 'Compatibilidad - Tipo', '');
  opInsertExtendidos.Checked := leBoolINI('Configuración', 'Insert extendidos', false);

  txtBDRes.Text := leCadINI('Restauración', 'Catálogo', '');
  txtUsuarioRes.Text := leCadINI('Restauración', 'Usuario', 'root');
  txtContrasenaRes.Text := leCadINI('Restauración', 'Contraseña', '');
  txtHostRes.Text := leCadINI('Restauración', 'Host', 'localhost');
  txtPuertoRes.Text := leCadINI('Restauración', 'Puerto', '3306');
  txtOrigen.Text := leCadINI('Restauración', 'Origen', '');
  txtComandoRestaurar.Text := leCadINI('Restauración', 'Comando', '');
  opResVerbose.Checked := leBoolINI('Restauración', 'Verbose', true);

  componerComandoRestaurar;
end;

procedure TformMenuprincipal.LWEBClick(Sender: TObject);
begin
  ShellExecute(Handle, Nil, PChar('http://www.ajpdsoft.com'),
      Nil, Nil, SW_SHOWNORMAL);
end;

procedure TformMenuprincipal.bSelDestinoClick(Sender: TObject);
begin
  if dlGuardar.Execute then
    txtDestino.Text := dlGuardar.FileName;
end;

procedure TformMenuprincipal.FormShow(Sender: TObject);
begin
  if txtComando.Text <> '' then
    tabEjecutar.Show
  else
    tabConfCop.Show;
end;


procedure TformMenuprincipal.bObtenerClick(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.btSalirClick(Sender: TObject);
begin
  close;
end;

procedure TformMenuprincipal.bEjecutarRestaurarClick(Sender: TObject);
var
  seguir : boolean;
  procesoIniciado : boolean;
begin
  seguir := true;
  if not FileExists(IncludeTrailingBackslash(ExtractFilePath(Application.ExeName)) +
      'mysql.exe') then
  begin
    tabConfiguracion.Show;
    tabConfRestaurar.Show;
    MessageDlg('Debe copiar el fichero "mysql.exe" a la carpeta de la ' +
        'aplicación (donde se encuentra el fichero "copiaSeguridadMySQL.exe".',
        mtInformation, [mbok], 0);
    seguir := false;
  end;

  if obtenerFicheroComando(txtComandoRestaurar.Text, '<') = '' then
  begin
    tabConfiguracion.Show;
    tabConfRestaurar.Show;
    MessageDlg('Debe indicar un fichero de origen ' +
        'para la restauración.', mtInformation, [mbok], 0);
    txtOrigen.SetFocus;
    seguir := false;
  end;

  if not FileExists (obtenerFicheroComando(txtComandoRestaurar.Text, '<')) then
  begin
    tabConfiguracion.Show;
    tabConfRestaurar.Show;
    MessageDlg('El fichero origen de la restauración no existe.',
        mtInformation, [mbok], 0);
    txtOrigen.SetFocus;
    seguir := false;
  end;


  if seguir then
  begin
    if MessageDlg('Se va a realizar una restauración del contenido del fichero:' +
        chr(13) + chr(13) + obtenerFicheroComando(txtComandoRestaurar.Text, '<') +
        chr(13) + chr(13) +
        'En el servidor: ' + txtHostRes.Text +  chr(13) + chr(13) +
        'La restauración se ejecutará en segundo plano por lo que ' +
        'puede tardar varios minutos ' +
        '(dependiendo del tamaño de las tablas elegidas) mientras ' +
        'no finalice no se podrá cerrar la aplicación. Si desea cancelar ' +
        'la restauración acceda al administrador de tareas y finalice manualmente el ' +
        'proceso "mysql.exe".' + chr(13) + chr(13) +
        'ATENCIÓN: tenga en cuenta que este proceso reemplazará la base '+
        'de datos actual por la que incluya el fichero seleccionado.' + chr(13) + chr(13) +
         '¿Desea continuar?',
        mtWarning, [mbno, mbyes], 0) = mryes then
      begin
        if Pos('>', txtComandoRestaurar.Text) > 0 then
          MessageDlg('¡¡¡Atención!!! no puede utilizar el carácter ">" ' +
              'para realizar una restauración, pues este carácter ' +
              'es para realizar una copia de seguridad. Si ' +
              'quiere realizar una copia de seguridad acceda a la pestaña ' +
              '"Realizar copia de seguridad".',
              mtWarning, [mbok], 0)
        else
        begin
          if verificarSintaxisComandoRestaurar (txtComandoRestaurar.text, true, true) then
          begin
            gComandoRes.Enabled := false;
            gResultadoRes.Enabled := false;
            tabRecuperar.Enabled := false;
            bObtenerComandoRestaurar.Enabled := false;
            bEjecutarRestaurar.Enabled := false;
            btSalir.Enabled := false;
            Screen.Cursor := crHourGlass;
            be.Panels[1].Text := 'Ejecutándose restauración, espere por favor...';
            insertarPATH(ExtractFilePath(Application.ExeName));
            txtResultadoRes.Text := ejecutarComando(txtComandoRestaurar.Text);
            gComandoRes.Enabled := True;
            gResultadoRes.Enabled := True;
            tabRecuperar.Enabled := True;
            bObtenerComandoRestaurar.Enabled := True;
            bEjecutarRestaurar.Enabled := True;
            btSalir.Enabled := True;
            be.Panels[1].Text := 'Restauración finalizada';
            Screen.Cursor := crDefault;            
          end;
        end;
      end;
  end;
end;

procedure TformMenuprincipal.bSelOrigenClick(Sender: TObject);
begin
  if dlAbrir.Execute then
    txtOrigen.Text := dlAbrir.FileName;
end;

procedure TformMenuprincipal.opModoVerboseClick(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.txtBDResChange(Sender: TObject);
begin
  componerComandoRestaurar;
end;

procedure TformMenuprincipal.txtUsuarioResChange(Sender: TObject);
begin
  componerComandoRestaurar;
end;

procedure TformMenuprincipal.txtContrasenaResChange(Sender: TObject);
begin
  componerComandoRestaurar;
end;

procedure TformMenuprincipal.txtHostResChange(Sender: TObject);
begin
  componerComandoRestaurar;
end;

procedure TformMenuprincipal.txtPuertoResChange(Sender: TObject);
begin
  componerComandoRestaurar;
end;

procedure TformMenuprincipal.txtOrigenChange(Sender: TObject);
begin
  componerComandoRestaurar;
end;

procedure TformMenuprincipal.bObtenerComandoRestaurarClick(
  Sender: TObject);
begin
  componerComandoRestaurar;
end;

procedure TformMenuprincipal.opCompatibleClick(Sender: TObject);
begin
  if opCompatible.Checked then
    lsCompatibleLista.Enabled := true
  else
    lsCompatibleLista.Enabled := false;
  componerComando;
end;

procedure TformMenuprincipal.opCopiarTablasClick(Sender: TObject);
begin
  if opCopiarTablas.Checked then
  begin
    txtCopiarTablas.Enabled := true;
    opCopiarBDTodas.Checked := false;
  end
  else
    txtCopiarTablas.Enabled := false;
  componerComando;
end;

procedure TformMenuprincipal.lsCompatibleListaChange(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.opResTodosCatalogosClick(Sender: TObject);
begin
  if opResTodosCatalogos.Checked then
  begin
    txtBDRes.Enabled := false;
  end
  else
  begin
    txtBDRes.Enabled := true;
  end;
  componerComandoRestaurar;
end;

procedure TformMenuprincipal.bConfigCopiaClick(Sender: TObject);
begin
  tabConfiguracion.Show;
  tabConfCop.Show;
end;

procedure TformMenuprincipal.bConfResClick(Sender: TObject);
begin
  tabConfiguracion.Show;
  tabConfRestaurar.Show;
end;

procedure TformMenuprincipal.opInsertExtendidosClick(Sender: TObject);
begin
  componerComando;
end;

procedure TformMenuprincipal.opResVerboseClick(Sender: TObject);
begin
  componerComandoRestaurar;
end;

end.
 

Artículos relacionados

 

Créditos

Artículo realizado íntegramente por Alonsojpd miembro fundador del proyecto AjpdSoft.


Anuncios


Enviado el Viernes, 08 enero a las 01:00:51 por ajpdsoft
Este sitio web NO CONTIENE malware, todos los programas con código fuente aquí. Autor: Alonso Javier Pérez Díaz Google+ Síguenos en Google+