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 o TDbf fornece

O 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. Ele faz tudo isso sem precisar de bibliotecas adicionais ou engines de bancos de dados. Simplesmente coloque o componente TDbf no seu formulário e você vai ter acesso instantâneo a um ambiente de banco de dados cross-plataforma. O 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;

Field types are defined as:

  • 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');

How to link the TDbf to data-aware components

The above examples show how to create a new database table in code. Using that table is even more simple.

Data aware components in Lazarus (such as the TDbEdit control) link to a TDataSource component using their "DataSource" and "DataField" properties. The TDataSource component handles communication between the database engine and the data aware components. A TDataSource then links to the TDbf component using it's "DataSet" property. The connection looks like this:

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


Be sure to set the FilePath (or FilePathFulll), TableLevel, and TableName properties of your TDbf component before calling

TDbf.Active := True;


There is much more that can be said about programming with databases in Lazarus, and I would recommend a good Delphi database programming book or two as the underlying concepts are the same. I constantly refer to my copy of "Delphi 2 Unleashed" because the concepts and basic code haven't changed much in 8 years.

Packing and rebuilding the tables

When a record is deleted, it's not truly removed from the physical table. Periodically you must "pack" a table to recover that lost space. This should be done with exclusive mode set.

MyDbf.Exclusive := True;
MyDbf.Open;
MyDbf.PackTable;
// let's also rebuild all the indexes
MyDbf.RegenerateIndexes;
MyDbf.Close;
MyDbf.Exclusive := False;

Master table relations

Real power in database programming begins when you have multiple tables that reference each other. While TDbf does not yet support referential integrity, it does support a master / detail relationship between TDbf's.

When there are two tables related, for instance:

[customers]
Id       <----|
Name          |
Phone         |
Address       |
              |  The CustID in invoices references a customer primary  field
[invoices]    |
Id            |
Amount        |
CustID   -----|  * This field indexed as "idxcustid"


If you wanted to display all invoices for a given customer, the detail table (invoices) can stay in sync with the master table (customers) automatically.

On the invoices TDbf component set the following:

InvDbf.IndexName := 'idxcustid'; // our field that will match the customers table ID
InvDbf.MasterSource := dsCustomers; // datasource that is linked to the customers TDbf
InvDbf.MasterFields := 'Id'; // field on the customers table we are matching against our index


Sample application - DB Browser

I've written a simple application that will use the TDbf to open and display database tables using the dbGrid control. The Linux executable along with project sources which should compile fine in Windows is available from: tony.maro.net

Things you need to be aware of

Currently there is no support for referential integrity, or internally encrypted .dbf files.