Lazarus Tdbf Tutorial/pt
│
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 documentaçã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 reparos no código, para que os componentes de banco de dados pudessem ser usados no Lazarus.
O pacote DbfLaz (versão 0.9.13) é agora 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 nível de tabela ("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 caminho de arquivo ("FilePath"), nível de tabela ("TableLevel") e nome de tabela "(TableName"), manipule a propriedade definição de campos ("FieldDefs") para configurar a estrutura. Por exemplo:
MyDbf.FilePathFull := '/lugar/em que/meus arquivos/estão'; MyDbf.TableLevel := 7; MyDbf.TableName := 'customers.dbf'; // observação: a extensão .dbf é realmente necessária? 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 (Nível de tabela 25)
- ftBCD (Nível de tabela 25)
- ftDate
- ftTime
- ftDateTime
- ftBytes (Nível de tabela 25)
- ftVarBytes
- ftAutoInc (Nível de tabela 7 ou 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 os que estão implementados atualmente.
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. ;-)
Observação: crie o diretório relativo "data" antes de rodar este exemplo, ou a execução falhará.
{$MODE OBJFPC} Program Database; { 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.
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:
Coisas em que você precisa estar atento
Atualmente não há suporte para integridade referencial ou arquivos .dbf internamente codificados.