PDA

Ver la Versión Completa : Usar el Gbak desde mi aplicación


José Luis Garcí
03-07-2012, 17:03:28
Hola compañeros, tengo mucha información de como usar el gback desde la linea de comandos, pero lo que me gustaría es poder hacerlo desde mi aplicacíon, poniendo dos edits, el 1º para la bd, el segundo donde guardarlo (esta parte esta solucionada, pero luego como mando la orden desde el programa, estoy probando en una aplicación sin b.d., pero la idea es hacerla desde la misma aplicación, tendría que cerrar el Ibdatabase.

Como siempre muchas gracias por vuestra ayuda.

Casimiro Notevi
03-07-2012, 17:55:14
gbak no necesita que cierres la base de datos, puede hacer el backup mientras están trabajando, ya que usa transacciones, por lo que no le molesta lo que hagan otros mientras él trabaja :)

Descarga este (http://db.tt/iNP6BlbR) programita de backups que he compartido alguna vez en clubdelphi, échale un vistazo y verás cómo está hecho lo que quieres.
Y si tienes alguna duda... aquí estaré :)

ecfisa
03-07-2012, 17:56:39
Hola José.

Te pongo un ejemplo de una forma simple en que podrías hacerlo:

procedure TForm1.MakeBackup;
const
PATH_BACKUP = 'C:\...\Data\Backup\';
FILE_BACKUP = 'C:\...\Data\BASEDATOS.FDB ';
var
lpOperation, lpFile, lpParameters, lpDirectory: PChar;
Nombre: string;
begin
// Componer nombre de archivo (yyyymmdd.fbk)
Nombre:= StringOfChar('0',4-Length(IntToStr(YearOf(Now))))+IntToStr(YearOf(Now)) +
StringOfChar('0',2-Length(IntToStr(MonthOf(Now))))+IntToStr(MonthOf(Now)) +
StringOfChar('0',2-Length(IntToStr(DayOf(Now))))+IntToStr(DayOf(Now))+ '.FBK';
if not FileExists(PATH_BACKUP + Nombre) then
with TPanel.Create(nil) do
try
Caption:= 'Realizando copia de seguridad, aguarde un momento por favor...';
Font.Size:= 14;
Font.Name:= 'Arial';
Width:= 600;
Height:= 70;
Left:= (Self.ClientWidth - Width) div 2;
Top:= (Self.ClientHeight - Height) div 2;
BevelInner:= bvNone;
BevelOuter:= bvNone;
BevelWidth:= 1;
BorderStyle:= bsSingle;
Ctl3D:= False;
Parent:= Self;

lpOperation:= 'open';
lpFile:= 'gbak.exe';
lpParameters:= PChar('-v -t -user SYSDBA -password "masterkey" '+ FILE_BACKUP + PATH_BACKUP + Nombre);
lpDirectory:= PChar(GetEnvironmentVariable('ProgramFiles')+'\Firebird\Firebird_2_5\bin');
ShellExecute(Handle, lpOperation, lpFile, lpParameters, lpDirectory, SW_HIDE);
finally
Free;
end;
end;


Saludos.

Edito: Sin dudas nada tán elaborado como el código de Casimiro. Código que, con su permiso, voy a pasar a echarle una mirada :)

Casimiro Notevi
03-07-2012, 18:21:25
Edito: Sin dudas nada tán elaborado como el código de Casimiro. Código que, con su permiso, voy a pasar a echarle una mirada :)

Es un programita sencillo, sin florituras :)

José Luis Garcí
03-07-2012, 18:57:14
Casimiro Notevi
gbak no necesita que cierres la base de datos, puede hacer el backup mientras están trabajando, ya que usa transacciones, por lo que no le molesta lo que hagan otros mientras él trabaja

Descarga este programita de backups que he compartido alguna vez en clubdelphi, échale un vistazo y verás cómo está hecho lo que quieres.
Y si tienes alguna duda... aquí estaré

Muy bueno el programa, le he estado echando un vistazo en su momento y no me acordaba de el , hasta que lo has nombrado.

ecfisa
Te pongo un ejemplo de una forma simple en que podrías hacerlo:

Muchas gracias por el ejemplo lo pruebo en un rato.

Gracias a ambos.

Lepe
03-07-2012, 19:00:49
A colación:

Yo tengo código de internet que permite ejecutar una orden y recoger el resultado de la línea de comando en un String. Es útil para saber si ha dado algún error o no. Lo usé con gbak porque quería hacer un reparador de BBDD Firebird automático.

Si crees que te sirve, avisa y pego por aquí.

Básicamente hacía todos los pasos descritos en http://www.destructor.de/

José Luis Garcí
03-07-2012, 19:17:58
muchas gracias Lepe, por supuesto todo lo que ayude es de agradecer y lo que no también :D (por la intención)

ecfisa
03-07-2012, 20:07:04
Hola José Luis.

Hay un detalle en el código que te puse, que si bién no afecta el funcionamiento, es innecesario.

Donde dice:

StringOfChar('0',4-Length(IntToStr(YearOf(Now))))+IntToStr(YearOf(Now))


Bién podría decir

IntToStr(YearOf(Now))

con el mismo efecto... :o


Saludos.

José Luis Garcí
03-07-2012, 20:09:18
ecfisa, he probado el código pero no va, lo único que he cambiado son las constantes y que lo ejecuto en un boton, te pongo el código por si ves, que he cometido algún error.

procedure TForm1.SpeedButton4Click(Sender: TObject);
const
PATH_BACKUP = 'C:\TEBICA PROGRAMA\SEG BD\';
FILE_BACKUP = 'C:\TEBICA PROGRAMA\BD\TEBICA.FDB';
var
lpOperation, lpFile, lpParameters, lpDirectory: PChar;
Nombre: string;
begin
// Componer nombre de archivo (yyyymmdd.fbk)
Nombre:= StringOfChar('0',4-Length(IntToStr(YearOf(Now))))+IntToStr(YearOf(Now)) +
StringOfChar('0',2-Length(IntToStr(MonthOf(Now))))+IntToStr(MonthOf(Now)) +
StringOfChar('0',2-Length(IntToStr(DayOf(Now))))+IntToStr(DayOf(Now))+ '.FBK';
if not FileExists(Edit4.Text + Edit5.Text) then
with TPanel.Create(nil) do
try
Caption:= 'Realizando copia de seguridad, aguarde un momento por favor...';
Font.Size:= 14;
Font.Name:= 'Arial';
Width:= 600;
Height:= 70;
Left:= (Self.ClientWidth - Width) div 2;
Top:= (Self.ClientHeight - Height) div 2;
BevelInner:= bvNone;
BevelOuter:= bvNone;
BevelWidth:= 1;
BorderStyle:= bsSingle;
Ctl3D:= False;
Parent:= Self;

lpOperation:= 'open';
lpFile:= 'gbak.exe';
// lpParameters:= PChar('-v -t -user SYSDBA -password "masterkey" '+Edit3.Text + Edit4.Text + Edit5.Text);
lpParameters:= PChar('-v -t -user SYSDBA -password "masterkey" '+ FILE_BACKUP + PATH_BACKUP + Nombre);
lpDirectory:= PChar(GetEnvironmentVariable('ProgramFiles')+'\Firebird\Firebird_2_5\bin');
ShellExecute(Handle, lpOperation, lpFile, lpParameters, lpDirectory, SW_HIDE);
finally
Free;
end;
end;

Mi firebirrd es 2_5 y esta activo (Run) como un servicio y el (Start) en automático,por si te sirve de ayuda.

ecfisa
03-07-2012, 20:39:16
Hola José Luís.

Ahora voy a probar el código con el agregado de los Edits. Pero así, a vista de pájaro, pareciera que te falto un espacio al finalizar la constante FILE_BACKUP.

En un rato te pongo el resultado que obtuve.

Saludos. :)

ecfisa
03-07-2012, 22:03:07
Hola de nuevo José.

De este modo me funciona correcto:

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
lpOperation, lpFile, lpParameters, lpDirectory: PChar;
begin
if not FileExists(EditTargetName.Text) then
with TPanel.Create(nil) do
try
Caption:= 'Realizando copia de seguridad, aguarde un momento por favor...';
Font.Size:= 14;
Font.Name:= 'Arial';
Width:= 600;
Height:= 70;
Left:= (Self.ClientWidth - Width) div 2;
Top:= (Self.ClientHeight - Height) div 2;
BevelInner:= bvNone;
BevelOuter:= bvNone;
BevelWidth:= 1;
BorderStyle:= bsSingle;
Ctl3D:= False;
Parent:= Self;

lpOperation:= 'open';
lpFile:= 'gbak.exe';
EditPathAndBDName.Text:= EditPathAndBDName.Text + ' ';
lpParameters:= PChar('-v -t -user SYSDBA -password "masterkey" ' +
EditPathAndBDName.Text + EditTargetPath.Text + EditTargetName.Text);
lpDirectory:= PChar(GetEnvironmentVariable('ProgramFiles')+'\Firebird\Firebird_2_5\bin');
ShellExecute(Handle, lpOperation, lpFile, lpParameters, lpDirectory, SW_HIDE);
finally
Free;
end;
end;


Saludos.

MartinS
04-07-2012, 00:47:03
Hola: Entro solamente para agradecer a Jose Luis por la pregunta y al maestro ecfisa por la respuesta. Hace ya un tiempo que sabia que en algún momento iba a necesitar hacer un backup de firebird pero mientras estaba en desarrollo la aplicación general como que lo veia medio lejos o para no preocuparme (Creo recordar que hace menos de un año arranque con firebird lo que conlleva a aprender Sql, etc, etc y hacer un backup era lo siguiente en la lista). Tambien vi que el tema es mas o menos recurrente y seguramente yo iba a poner la pregunta exacta que hizo Jose Luis. (Simple, cortito y al pie :D ) un clik en un botón, el backup arranca y listo (Aunque todavia no lo probe pero seguramente va a funcionar).
No me quiero olvidar de Casimiro que aporta un programa donde él lo nombra como "programita" pero siempre que me propuse intentar interpretarlo me agarra un mareo y lo dejo (son demasiadas opciones del "programita" por lo que pagan :p ).-

Bueno, nada mas que eso y muchas gracias.- ;)

Saludos

ecfisa
04-07-2012, 04:37:12
Hola Martin.

Con solo comparar el código del "programita" de Casimiro con el mío queda bién claro que el maestro no soy yo... :o

Saludos.:)

MartinS
04-07-2012, 04:58:50
Entonces resumis muy bien. :D.
Saludos

José Luis Garcí
04-07-2012, 09:35:44
Hola compañeros, descubri el problema que tenia, resulta que si las rutas de orige o destino tiene espacios en blanco, debe ir entre comillas dobles. el código queda de la siguiente manera

procedure TForm1.Button3Click(Sender: TObject);
var
lpOperation, lpFile, lpParameters, lpDirectory: PChar;
varbPasado:Boolean;
begin
varbPasado:=False;
if not FileExists(Edit3.Text+'.FBK') then
with TPanel.Create(nil) do
try
Caption:= 'Realizando copia de seguridad, aguarde un momento por favor...';
Font.Size:= 14;
Font.Name:= 'Arial';
Width:= 600;
Height:= 70;
Left:= (Self.ClientWidth - Width) div 2;
Top:= (Self.ClientHeight - Height) div 2;
BevelInner:= bvNone;
BevelOuter:= bvNone;
BevelWidth:= 1;
BorderStyle:= bsSingle;
Ctl3D:= False;
Parent:= Self;

lpOperation:= 'open';
lpFile:= 'gbak.exe';
Edit1.Text:= '"'+Edit1.Text + '" ';
lpParameters:= PChar('-v -t -user SYSDBA -password "masterkey" '+
Edit1.Text +'"'+Edit2.Text+'"');
lpDirectory:= PChar(GetEnvironmentVariable('ProgramFiles')+'\Firebird\Firebird_2_1\bin');
Memo1.Lines.Clear;
Memo1.Lines.Add(lpParameters);
ShellExecute(Handle, lpOperation, lpFile, lpParameters, lpDirectory, SW_HIDE);
varbPasado:=true
finally
if varbPasado=true then ShowMessage('Proceso terminado')
else ShowMessage('El fichero ya existe');
Free;
end;
end;

Ahora abusando un poco, es logico que pase según mis pruebade de 125 Mb a 8.90 y de 3.40 Mb a 28.5K
y por último cual seria la sentencia correcta para una restauración.

Muchas gracias por ser siempre tan atento ecfisa

Casimiro Notevi
04-07-2012, 11:14:54
Con solo comparar el código del "programita" de Casimiro con el mío queda bién claro que el maestro no soy yo... :o
Eso se lo dirás a todos :D

y por último cual seria la sentencia correcta para una restauración.
El problema de los espacios en blanco y que debes poner la ruta entre comillas... puedes verlo en mi código ;)

Para restaurar es exactamente igual, con otros parámetros.

En lugar de gbak -b -t elorigen.fdb lacopia.fbk sería gbak -r -p 8192 lacopia.fbk elorigen.fdb

Eso sí, en este caso no puede haber nadie conectado a la BD, o mejor la restauras con otro nombre y luego sustituyes a la otra, o mejor la renombras... por si acaso hay algún problema en la restauración, no te vayas a quedar sin ninguna de las dos :)

José Luis Garcí
06-07-2012, 18:24:30
Hola compañeros, en primer lugar he tenido que poner el gbak en el directorio del ejecutable pero fuera de eso, me realiza bien las copias, creo que la diferencia de tamaño se debe a que debe eliminar los espacios en blanco, pero resulta que ahora estoy con la restauración de la copia de seguridad y este es el código que tengo

procedure TForm1.SpeedButton5Click(Sender: TObject);
//------------------------------------------------------------------------------
//*************************************************************[ Restaurar BD ]****
//------------------------------------------------------------------------------
function ProgressRoutine(TotalFileSize, TotalBytesTransferred, StreamSize, StreamBytesTransferred: LARGE_INTEGER; dwStreamNumber, dwCallbackReason: DWORD; hSourceFile, hDestinationFile: THandle; lpData: Pointer): DWORD; stdcall;
//------------------------------------------------------------------------------
// Funcion del compañero escafandra bajado de
// http://www.delphiaccess.com/forum/trucos-y-consejos-16/copiar-archivos-con-copyfileex-y-barra-de-progreso-en-delphi/
//------------------------------------------------------------------------------
var
Value: integer;
begin
Application.ProcessMessages();
if(dwCallbackReason = CALLBACK_CHUNK_FINISHED) then
Form1.ProgressBar1.Position:= (int64(TotalBytesTransferred) * 100) div int64(TotalFileSize);
Result:= PROGRESS_CONTINUE;
end;
var
lpOperation, lpFile, lpParameters, lpDirectory: PChar;
varbPasado:Boolean;
begin
varbPasado:=False;
if (Edit3.Text<>'') and (Edit4.Text<>'') then
begin
if CheckBox1.Checked then //Si deseamos hacer una copia del original
begin
Cancel:= false;
CopyFileEx(Fuente, Destino, @ProgressRoutine, nil, @Cancel, 0);
ShowMessage(SysErrorMessage(GetLastError()));
end;
with TPanel.Create(nil) do
try
Caption:= 'Restaurando copia de seguridad, aguarde un momento por favor...';
Font.Size:= 14;
Font.Name:= 'Arial';
Width:= 600;
Height:= 70;
Left:= (Self.ClientWidth - Width) div 2;
Top:= (Self.ClientHeight - Height) div 2;
BevelInner:= bvNone;
BevelOuter:= bvNone;
BevelWidth:= 1;
BorderStyle:= bsSingle;
Ctl3D:= False;
Parent:= Self;
lpOperation:= 'open';
lpFile:= 'gbak.exe';
// Edit3.Text:= '"'+Edit3.Text + '" ';
lpParameters:= PChar('-r -v -p 8192 -user SYSDBA -password "masterkey" "'+ Edit3.Text +'" "'+Edit4.Text+'"');
// if RadioGroup1.ItemIndex=0 then lpDirectory:= PChar(GetEnvironmentVariable('ProgramFiles')+'\Firebird\Firebird_2_1\bin')
// else lpDirectory:= PChar(GetEnvironmentVariable('ProgramFiles')+'\Firebird\Firebird_2_5\bin');
lpDirectory:=PChar(ExtractFilePath(Application.Name));
ShellExecute(Handle, lpOperation, lpFile, lpParameters, lpDirectory, SW_HIDE);
varbPasado:=true
finally
if varbPasado=true then ShowMessage('Proceso terminado')
else ShowMessage('El fichero ya existe');
Free;
end;
end;
end;

como podréis comprobar, lo primero que hago es una copia del fichero original, con una función de escafandra, luego restauro la base de datos, el problema es que quiero restaurar una base de datos de 126 Mb y al finalizar sigo teniendo una de 3,40 Mb, y el fichero backup (FBK) tiene un tamaño de 9,25 Mb.
Supongo que est mal , no he intentado abrir la BD ya que de momento lo que tengo es la B.D. del programa (126 Mb), la primera copia de esta (3,40 Mb), pero supongo que algo no va bien.

Como siempre gracias por vuestra ayuda.


Casimiro
El problema de los espacios en blanco y que debes poner la ruta entre comillas... puedes verlo en mi código

Lo comprobé, al igual que he estado mirando tus constantes, probando tú código, pero no encuentro ningún botón para hacer el backup sobre la marcha, se que el nombre es backupsPlanificados, pero echo en falta esto y la posibilidad de restaurar las copias ya echas. Eso si el programa es bueno y muy bien terminado.

Un saludo y gracias por vuestra colaboración y ayuda.

Casimiro Notevi
06-07-2012, 18:34:03
Recuerda que con una copia "normal" (sin gbak) no debe existir ninguna conexión abierta a la BD, ya que la copia tendría grandes posibilidades de tener defectos.

En cuanto al tamaño del backup, restáurala con otro nombre, conecta a ella y echa un vistazo :)

En cuanto al programita BPF, por eso lo llamo programita, porque es muy simple, se quedó en el tintero montones de cosas que quería ponerle, pero siempre había otras cosas más urgentes que hacer, así que lo fui dejando.

José Luis Garcí
06-07-2012, 18:50:42
Hola Caimiro

Recuerda que con una copia "normal" (sin gbak) no debe existir ninguna conexión abierta a la BD, ya que la copia tendría grandes posibilidades de tener defectos.
La idea es que el programa que se encargue de las copias de seguridad, este aparte del programa original, con lo cual no tendrá conectada ninguna base de datos. Aparte de Copiar y restaurar la base de datos, tambien permite copiar el directorio completo, con lo cual no interesa que este activo la BD. Como ya me indicarón en su día :o.

En cuanto al tamaño del backup, restáurala con otro nombre, conecta a ella y echa un vistazo
por fin lo logre restaura, primero haciendo el proceso a mano (con el Command.com), y descubrí que en vez de -r tenia que poner -REP (para que remplazara la Bd), lo curioso es que el resultado final es de 14.4Mb y no de 126 Mb, aparentemente están los datos (Sólo le he echado un vistazo por encima).

En cuanto al programita BPF, por eso lo llamo programita, porque es muy simple, se quedó en el tintero montones de cosas que quería ponerle, pero siempre había otras cosas más urgentes que hacer, así que lo fui dejando.

Primero de programita nada, es un señor programa, en cuanto a eso de "así que lo fui dejando", ¡Rápidamente dame el número de teléfono de tu jefe, vamos hombre, que es eso de ir dejando las cosas a medias! :D:D:D:D:D

José Luis Garcí
06-07-2012, 19:07:36
Para los que le puedan interesar, acabo de subir el programa (ejecutable y fuentes) al Ftp del Club, para que lo useis libremente, para criticarme, apalearme, etc, esas cosas tan cariñosas que sabeis hacer. :D

esta en el ftp del Club (http://terawiki.clubdelphi.com/Delphi/Tools/) con el nombre CDYCR_BD.zip.

Casimiro Notevi
06-07-2012, 19:27:29
por fin lo logre restaura, primero haciendo el proceso a mano (con el Command.com), y descubrí que en vez de -r tenia que poner -REP (para que remplazara la Bd), lo curioso es que el resultado final es de 14.4Mb y no de 126 Mb, aparentemente están los datos (Sólo le he echado un vistazo por encima).
Mira la imagen que te pongo, es de la última actualización del tutorial de gbak (http://www.intitec.com/varios/Firebird-gbak.pdf).

Primero de programita nada, es un señor programa, en cuanto a eso de "así que lo fui dejando", ¡Rápidamente dame el número de teléfono de tu jefe, vamos hombre, que es eso de ir dejando las cosas a medias! :D Ya no tengo jefe, soy libre como el viento :)

Para los que le puedan interesar, acabo de subir el programa (ejecutable y fuentes) al Ftp del Club, para que lo useis libremente, para criticarme, apalearme, etc, esas cosas tan cariñosas que sabeis hacer. :D
esta en el ftp del Club (http://terawiki.clubdelphi.com/Delphi/Tools/) con el nombre CDYCR_BD.zip.
Estupendo :)

José Luis Garcí
06-07-2012, 22:06:10
Casimiro
Mira la imagen que te pongo, es de la última actualización del tutorial de gbak.
Muchas gracias como siempre

Casimiro
Ya no tengo jefe, soy libre como el viento
lo se ya lo habías comentado en el foro, si no recuerdo mal ahora eres Frelance, pero no pensaras echarte a volar, sin el carnet de piloto. Je,Je.

Casimiro Notevi
06-07-2012, 22:24:18
lo se ya lo habías comentado en el foro, si no recuerdo mal ahora eres Frelance, pero no pensaras echarte a volar, sin el carnet de piloto. Je,Je.

Ahora mismo estoy poniéndome al día en programación para la web (programar es un vicio :)) y, sobre todo, dándole vueltas (muchas vueltas) a la cabeza, para ver qué voy a hacer a partir de ahora :)

luk2009
30-09-2015, 05:10:55
Hola Casimiro, estuve probando tu programa, el cual me parece una maravilla. Tiene todo lo que necesito, ya que deseo programar un backup diario. El problema es que me sale el mensaje no se encontro el registro

solo funciono una vez con una de mis bases de datos y despues ni siquiera con esa funciona y me sale ese mensaje.

Alguna Idea de porque pasa esto. Gracias de antemano

Casimiro Notevi
30-09-2015, 09:15:21
Pues así, sin más pistas, es díficil, puede que no tenga permisos para leer o guardar algún dato del registro. Supongo que se solucionará si lo instalas como administrador.
Pero ya digo, sin más pistas no sabría decirte más.
De todas formas, tienes el código fuente, síguelo con el depurador de delphi hasta que llegues a la línea que salte ese error.
Y luego nos cuentas qué era.

luk2009
01-10-2015, 07:00:10
me faltan los componentes que utilizaste para poder abrir los fuentes en mi delphi. Por otro lado lo he corrido como administrador y le he dado todos los permisos. seguire probando y tratare de instalar los componentes, para poder hacer las pruebas.

Casimiro Notevi
01-10-2015, 10:14:02
Hombre, tampoco es tan difícil encontrar el "problema", veo un poco de desgana o pereza ;)
Haces una búsqueda por "No se encontró el registro" y encuentras esto:
procedure TFmain.PosicionarRegistro(iID: Integer);
begin
MTBackups.IndexFieldNames := 'ID';
if not MTBackups.Locate('ID',iID,[]) then
Application.MessageBox('No se encontró el registro.','Backups',MB_OK+MB_ICONWARNING+MB_DEFBUTTON2);
end;
Ahí ves que no es un error, simplemente no tienes creado ningún registro, por lo que no se puede posicionar en ninguno. Crea uno (un backup) y se acabó el "problema".

luk2009
01-10-2015, 20:19:15
no es que este siendo vago, perdona , es que estoy un poco liado con otras cosas y la mente esta media bloqueada. No entiendo muy bien a lo que te refieres con crear un registro. Pero te explico, He presionado nuevo, escojo la base de datos, luego el directorio donde va a poner el archivo de backup, hora,intervalo, proximo backup y veo que la casilla activa este marcada.

En varias ocasiones, crea el primer backup correctamente, pero luego si cambio la hora y a 20 minutos despues, entonces cuando llega el momento salta el error y no hace el backup. pero ya el anterior esta hecho.

Pero nada, cuando tenga la cabeza mas fria lo reviso y te digo que encuentro. Gracias por responder de cualquier manera.

^\||/

Casimiro Notevi
01-10-2015, 20:26:23
Bueno, esperamos que estés más disponible y lo miramos con tranquilidad :)