Lazarus Tdbf Tutorial/pt

From Lazarus wiki
Jump to navigationJump to search

Deutsch (de) English (en) español (es) français (fr) português (pt) русский (ru) 中文(中国大陆)‎ (zh_CN)

Visão Geral

Este tutorial é sobre desenvolvimento básico de banco de dados usando o componente TDbf (de Micha Nelissen) no Lazarus. Doumentação adicional para o TDbf está disponível. Esta página foi criada por Tony Maro, mas outros contribuidores são bem-vindos!

Para a documentação em PDF vá ao SourceForge. Isto pode ser útil para manter esse PDF ao lado desta documntação enquanto a lê.

Do que você vai precisar

Sem dúvida logo vai ser mais fácil quando o Free Pascal publicar a próxima versão 2.0, no entanto atualmente você vai precisar de uma edição CVS recente do FPC 1.9.x para usar adequadamente o componente TDbf. Isto pode ser feito baixando só o componente TDbf e usando-o com a versão 1.1 do Free Pascal, mas esta documentação foi escrita com a versão 1.9.x em mente, parcialmente por causa dos consertos de bug para que os componentes de banco de dados pudessem ser usados no Lazarus.

O pacote DbfLaz é agora (versão 0.9.13) instalado por padrão.

O que a TDbf fornece

A TDbf fornece acesso às tabelas de banco de dados do dBase e do FoxPro para Lazarus (e outros). Isto permite ler, escrever e criar tabelas de dBase III+, dBase IIV, Visual dBase VII e FoxPro. Ela faz tudo isso sem precisar de bibliotecas adicionais ou engines de bancos de dados. Simplesmente coloque-a no seu formulário e você vai ter acesso instantâneo a um ambiente de banco de dados multiplataforma. A TDbf funciona em Windows e Linux usando o Lazarus.

Como criar tabelas de banco de dados

Como não existe uma aplicação "Database Desktop" para Lazarus ainda, nós precisamos criar um novo banco de dados por código.

Configurando o caminho

É uma boa idéia dar ao banco de dados da sua aplicação um diretório próprio. Isto simplifica a feitura de backups dos dados. Existem duas maneiras de configurar o caminho. Você pode configurar o caminho completo usando a propriedade FilePathFull ou pode configurar um caminho relativo ao caminho atual da aplicação com FilePath. Por exemplo, configurar FilePath em tempo de execução como "data/" usaria um subdiretório de dados bem abaixo do executável. Configurar a propriedade FilePathFull como "/var/data/" colocaria tudo nesta pasta, ignorando a localização da aplicação.

Escolhendo um TableLevel

Por padrão, o TDbf criará tabelas dBase IV. Enquanto isto é muito compatível, existe características que você pode querer usar que não são suportadas. Para suportar campos auto-incrementados, você precisa usar alguma coisa mais recente. Os tipos de campo são:

  • 3 dBase III+
  • 4 dBase IV
  • 7 Visual dBase VII
  • 25 FoxPro

Você escolhe o tipo de tabela configurando a propriedade TableLevel adequadamente.

Adicionando campos

Criar campos para a sua nova tabela em tempo de execução segue bastante o antigo padrão do Delphi. Uma vez que você tenha configurado as propriedades FilePath, TableLevel e TableName, manipule a propriedade FieldDefs para configurar a estrutura. Por exemplo:

MyDbf.FilePathFull := '/location/to/my/data';
MyDbf.TableLevel := 7;
MyDbf.TableName := 'customers.dbf'; // note: is the .dbf really required?
With MyDbf.FieldDefs do begin
  Add('Id', ftAutoInc, 0, True);
  Add('Name', ftString, 80, True);
End;

Os tipos de campo estão definidos como:

  • ftUnknown
  • ftString
  • ftSmallInt
  • ftInteger
  • ftWord
  • ftBoolean
  • ftFloat
  • ftCurrency (TableLevel 25)
  • ftBCD (TableLevel 25)
  • ftDate
  • ftTime
  • ftDateTime
  • ftBytes (TableLevel 25)
  • ftVarBytes
  • ftAutoInc (TableLevel 7 or 25)
  • ftBlob
  • ftMemo
  • ftGraphic
  • ftFmtMemo
  • ftParadoxOle
  • ftDBaseOle
  • ftTypedBinary
  • ftCursor
  • ftFixedChar
  • ftWideString
  • ftLargeInt
  • ftADT
  • ftArray
  • ftReference
  • ftDataSet
  • ftOraBlob
  • ftOraClob
  • ftVariant
  • ftInterface
  • ftIDispatch
  • ftGuid
  • ftTimeStamp
  • ftFMTBcd

Os tipos em negrito são atualmente suportados.

Vá em frente e crie-o!

Once you have defined the fields you wish to use in your new table, you can go ahead and create it with:

   MyDbf.CreateTable;

Como adicionar índices a uma tabela

Se sua base de dados for maior do que alguns registros, você deverá ter índices definidos para fazer procuras mais rapidamente. Para mudar a estrutura do índice de uma tabela, precisamos ter o acesso exclusivo à tabela - que nós teríamos ao criar de qualquer maneira.

       MyDbf.Exclusive := True;
       MyDbf.Open;

Agora, nos só temos que adicionar o indice.

       MyDbf.AddIndex('custid', 'Id', [ixPrimary, ixUnique]);
       MyDbf.AddIndex('custname','Name', [ixCaseInsensitive]);
       MyDbf.Close;

Junte tudo e o resultado é...

O fragmento de código a seguir cria uma nova tabela chamada "customers" (clientes) no código. Isso, é claro, precisa ser feito somente uma vez, e depois que você abre uma tabela não precisa criá-la novamente. ;-)

{ Precisaremos que as seguintes unidades estejam na cláusula USES: }
{ uses Dbf, db, Dbf_Common                                   }
{ A uniadde Dbf é colocada ali quando você põe a TBDF em um formulário. }
{ No entanto, você precisará do banco de dados para o objeto DataSet e de Dbf_Common }
{ para coisas como as definições de campo. }
var
  MyDbf: TDbf;
begin
  MyDbf := TDbf.Create(nil);
  try
    { use o caminho relativo para o diretório "data }
    MyDbf.FilePath := 'data/'; 
    { queremos utilizar tabelas compatíveis com Visual dBase VII }
    MyDbf.TableLevel := 7;
    MyDbf.Exclusive := True;
    MyDbf.TableName := 'customers.dbf';
    With MyDbf.FieldDefs do begin
      Add('Id', ftAutoInc, 0, True);
      Add('Name', ftString, 80, True);
    End;
    MyDbf.CreateTable;
    MyDbf.Open;
    MyDbf.AddIndex('custid', 'Id', [ixPrimary, ixUnique]);
    { add a secondary index }
    MyDbf.AddIndex('custname','Name', [ixCaseInsensitive]);
    MyDbf.Close;
  finally
    MyDbf.Free;
  end;
end;


Arquivos de índice externos

A TDbf também possibilita o armazenamento de índices secundários em um arquivo separado. Isso pode ser útil caso se espere que o banco de dados seja grande. Índices secundários são muito similares aos índices normais, com a adição da extensão de arquivos '.ndx'.

    MyDbf.AddIndex('custname.ndx','Name', [ixCaseInsensitive]);


O índice precisa ser recarregado todas as vezes que a TDdf é aberta.

    MyDbf.OpenIndexFile('custname.ndx');


Além disso, índices precisam ser chamados com o nome completo (incluindo a exntesão).

    MyDbf.IndexName := 'custname.ndx';


Esses arquivos também são empacotados separadamente, usando:

    MyDbf.CompactIndexFile('custname.ndx');

Como ligar a TDbf aos componentes que acessam os dados

Os exemplos abaixo mostram como criar uma nova tabela de banco de dados no código. Usá-la é ainda mais simples.

Esses componentes no Lazarus (como exemplo o controle TDbEdit) se ligam a um componente TDataSource usando suas propriedades "DataSource" e "DataField". O componente TDataSource cuida da comunicação entre o motor (engine) do banco de dados e dos componentes acessados. Uma TDataSource então se liga à TDbf usando sua propriedade "DataSet". A conexão se parece com isso:


TDbEdit-------
             |
TDbEdit------|-->TDataSource-->TDbf
             |
TDbNavigator--


Certifique-se de configurar as propriedades "caminho do arquivo" (FilePath, ou FilePathFull), o "nível da tabela" (TableLevel) e o "nome da tabela" (TableName)da sua TDbf antes de chamá-la.

TDbf.Active := True;

Há muito mais que pode ser dito sobre programar com bancos de dados no Lazarus, e eu recomendaria um ou dois bons livros de programação de banco de dados em Delphi, já que os conceitos por trás disso tudo são os mesmos. Eu constantemente refiro-me à minha cópia de "Delphi 2 Unleashed" [nome do livro em português] porquê os conceitos e o código básico não mudam muito há 8 anos.

Empacotando e reconstruindo as tabelas

Quando um campo é apagado, ele não é de fato removido da tabela física. Periodicamente, você precisa "empacotar" uma tabela para recuperar o espaço perdido. Isso deve ser feito com o modo exclusivo acionado.

MyDbf.Exclusive := True;
MyDbf.Open;
MyDbf.PackTable;
// vamos reconstruir todos os índices também
MyDbf.RegenerateIndexes;
MyDbf.Close;
MyDbf.Exclusive := False;

Relações entre tabelas-mestras

O verdadeiro poder em programar com banco de dados começa quando você tem tabelas múltiplas que chamam umas às outras. Enquanto a TDbf ainda não possui integridade referencial, ela possui uma relação mestre / detalhe entre TDbfs [Última frase confusa].

Um exemplo disso é quando duas tabelas estão interligadas:

[fregueses]
Id       <----| Número de identidade
Name          | Nome
Phone         | Telefone
Address       | Endereço
              |  
[lista de     | O número do freguês em listas de compras ("CustID") faz 
 compras ]    | referência a um campo primário de freguês
Id            | Identidade
Amount        | Quantidade
CustID   -----| [Identidade do freguês?] * Esse último campo é indexado como "idxcustid" 

Se você quisesse mostrar todas as listas de compras para um determinado freguês, a tabela em detalhe (invoices) poderia ficar em sincronia com a tabela-mestra de fregueses (customers) automaticamente.

Nos componentes de listas de compras TDbf, coloque os seguintes valores:

InvDbf.IndexName := 'idxcustid'; // Nosso campo que servirá para pesquisar a tabela
                                 // de identidade dos fregueses.
InvDbf.MasterSource := dsCustomers; // Base de dados ligada aos fregueses em TDbf.
InvDbf.MasterFields := 'Id'; // Campo na tabela dos fregueses que nós usaremos para 
                             // pesquisar no índice.

Amostra de aplicativo - Navegador que utiliza um banco de dados

Escrevi um aplicativo bem simples que usará a TDbf para abrir e mostrar tabelas de bancos de dados usando o controle dbGrid. O executável Linux, junto com o código-fonte dos projetos que provavelmente compilarão bem no Windows estão disponíveis em:

tony.maro.net

Coisas às quais você precisa estar atento

Atualmente não há suporte para integridade referencial ou arquivos .dbf internamente codificados.