Você está na página 1de 4

:: Active Delphi Página 1 de 4

Backup com Firebird e Delphi


Data: Monday, September 14 @ 21:51:11
Tópico Administrador

Olá pessoal! Este artigo tem o intuito de mostrar como realizar a rotina de backup de bancos de dados Firebird, utilizando o
gbak, que é conhecidamente a melhor ferramenta de backup, apesar de ser através de linha de comando.

Vocês já devem estar calejados de rotinas e mais rotinas na internet com o mesmo tópico, mas a forma como eu irei
mostrar não irá fazer uso de nenhum componente “pronto” ou fórmulas milagrosas.

A inspiração para este artigo surgiu com o artigo de rotina de Backup com o MySQL publicado aqui no site, que utilizava a
ferramenta nativa do referido banco, mas usando um arquivo BAT e o WinExec, que no meu entender, torna o processo
meio obscuro, já que não sabemos o que esta por trás do processo.

Bom, chega de rodeios e vamos à rotina.

Primeiro, inicie um novo projeto, salve o form como frmBackup e a unit como untBackup e o projeto como Backup.

Na propriedade Caption do form escreva assim: Rotina de Realização de Backup

No form, coloque dois Edits e dois Labels, presentes na aba Standard, ou utilize o componente LabeledEdit, presente na aba
Additional (existente no Delphi 7 pra frente); No nosso artigo, estamos usando o Delphi 7, portanto utilizamos dois
LabelEdits.

No primeiro, mude o Name dele para edtOrigem, e o segundo como edtDestino.

Quem estiver usando Label, mude o caption do primeiro label para “Informe o caminho de origem”, e o segundo para
“Informe o caminho de destino”, e para quem estiver usando LabelEdit altere o Caption da mesma forma que com o uso de
Label.

Coloque dois componentes SpeedButon, mude o nome do primeiro para btnOrigem e o segundo para btnDestino. Coloque o
btnOrigem na margem direita do edtOrigem, e o btnDestino na margem direita do edtDestino.

Coloque um componente OpenDialog e um SaveDialog presentes na aba Dialogs. No opendialog, mude o name para
odOrigem, e no savedialog mude o name para sdDestino.

Coloque um componente Memo e mude o name dele para mmResult.

Coloque um componente BitBtn e mude o name dele para btnInicia. Mude o caption do botão para Inicia.

Adequei o tamanho do form para que ele fique igual a imagem abaixo:

http://www.activedelphi.com.br/print.php?sid=859 26/11/2009
:: Active Delphi Página 2 de 4

Figura 1 - Layout do formulário

Clique sobre o componente odOrigem, clique na propriedade Filter, depois clique no botão para abrir as opções de filtro,
como mostrado na figura abaixo:

Figura 2 - Opções de Filtro do OpenDialog

No campo FilterName coloque assim (*.fdb) e na mesma linha, em filter, coloque assim *.fdb

Faça a mesma operação no componente sdDestino, mas coloque (*.gbk) e *.gbk nos campos FilterName e filter.

No evento OnClick do botão edOrigem, coloque o código abaixo:

odOrigem.Execute;
edtOrigem.Text := odOrigem.FileName;

Esse código irá abrir a janela para que seja escolhido o arquivo de origem, e irá jogar o caminho do arquivo para o
edOrigem.

Agora no evento OnClick do botão edDestino, coloque o seguinte código:

http://www.activedelphi.com.br/print.php?sid=859 26/11/2009
:: Active Delphi Página 3 de 4

sdDestino.Execute;
edtDestino.Text := sdDestino.FileName;

Esse código alimenta o edtDestino com o nome do arquivo de destino, que será um .gbk

Para que possamos “ver” o progresso do processo de backup exatamente como ocorre no IBExpert, iremos utilizar uma
rotina que eu encontrei na internet que é responsável pela mágica de recuperar o que está em execução no DOS. No
“Private” do form, declare a seguinte função:

function GetDosOutput(const CommandLine, work: string): string;

O corpo da função esta descrito abaixo:

function TfrmBackup.GetDosOutput(const CommandLine, work: string): string;


var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of Char;
BytesRead: Cardinal;
WorkDir, Line, l: string;
begin
mmResult.Lines.Clear;
Application.ProcessMessages;
with SA do
begin
nLength := SizeOf(SA);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
//create pipe for standard output redirection
CreatePipe(StdOutPipeRead, // read handle
StdOutPipeWrite, // write handle
@SA, // security attributes
0); //, // number of bytes reserved for pipe - 0 default
//);
try
// Make child process use StdOutPipeWrite as standard out,
// and make sure it does not show on screen.
with SI do
begin
FillChar(SI, SizeOf(SI), 0);
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE;
hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect std input
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;

// launch the command line compiler


WorkDir := work; //ExtractFilePath(CommandLine);
// showmessage(workdir);
WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil,
PChar(WorkDir), SI, PI);

// Now that the handle has been inherited, close write to be safe.
// We don't want to read or write to it accidentally.
CloseHandle(StdOutPipeWrite);
// if process could be created then handle its output
if not WasOK then
raise Exception.Create('Could not execute command line!')
else
try
// get all output until dos app finishes
{panel2.caption := 'Aguarde...';
Panel2.Update;}
if not Showing then
show;
Line := '';

http://www.activedelphi.com.br/print.php?sid=859 26/11/2009
:: Active Delphi Página 4 de 4

repeat
// read block of characters (might contain carriage returns and line feeds)
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);

// has anything been read?


if BytesRead > 0 then
begin
// finish buffer to PChar
Buffer[BytesRead] := #0;
// combine the buffer with the rest of the last run
Line := Line + Buffer;
mmResult.text := mmResult.text + buffer;
mmResult.SelStart := length(mmResult.Text);
mmResult.SelLength := 1;
end;
until not WasOK or (BytesRead = 0);
// wait for console app to finish (should be already at this point)
WaitForSingleObject(PI.hProcess, INFINITE);
finally
// Close all remaining handles
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
{panel2.caption := 'Backup Terminado!';}
end;
finally
result := Line;
CloseHandle(StdOutPipeRead);
end;
end;

No evento onClick do botão Inicia, declare uma variável do tipo String, chamada LC, e coloque o seguinte código:

lc := 'gbak -g -b -v -t ' + edOrigem.text + ' ' + edDestino.text +


' -user SYSDBA -password masterkey';
GetDosOutput(lc, ExtractFilePath(Application.ExeName));
MessageDlg('Processo de backup efetuado com sucesso', mtInformation, [mbOk], 0);

Antes de ver o resultado, há a necessidade de se copiar o arquivo GBAK.EXE para dentro da pasta de destino no executável.
Esse arquivo está dentro da pasta BIN da instalação do firebird. A pasta padrão do firebird é C:\arquivos de
programas\firebird\firebird_X_X\bin.

Também é necessário na seção Uses do form, declarar a unit ShellApi.

Salve, compile e execute o código, lembrando que deverá ser escolhido o arquivo de origem e o de destino para que a
função funcione corretamente.

Algumas considerações

• Existem partes de código comentadas na rotina de execução do comando em DOS. Essa rotina eu tirei do meu
fonte, e depois do processo de backup eu compacto e salvo o arquivo compactado para dentro de uma pasta de
destino, que pode ser qualquer unidade da máquina ou mesmo um pen drive.
• Quem tiver algum problema com a rotina ou quiser mais informações a respeito pode entrar em contato comigo por
e-mail.

Abraço a todos!

Por: Osmar (Ghost_Rider)


Contato: osmar.mfe@hotmail.com

Digitado por :: Active Delphi


http://www.activedelphi.com.br/

A URL para esta notícia é:


http://www.activedelphi.com.br/modules.php?op=modload&name=News&file=article&sid=859

http://www.activedelphi.com.br/print.php?sid=859 26/11/2009

Você também pode gostar