Mostrando postagens com marcador SQLdb. Mostrar todas as postagens
Mostrando postagens com marcador SQLdb. Mostrar todas as postagens

Lazarus - Acessando banco de dados com SQLdb - Parte III

Muita coisa mudou no Lazarus desde que começamos a dedicar este blog à divulgação deste poderoso IDE. Quando iniciamos usávamos a versão 0.9.28 e publicamos dois artigos voltados para o uso do conjunto de componentes SQLdb:

Lazarus - Acessando banco de dados com SQLdb - Parte I
Lazarus - Acessando banco de dados com SQLdb - Parte II

Hoje estamos com a versão 0.9.31. Neste post iremos apresentar algumas mudanças para melhor na utilização desses componentes.

Referências aos campos de uma tabela - criação de TFields

Para criar os TFields ainda é necessário que a TSQLQuery esteja ativa. Dê um duplo clique na TSQLQuery e você verá uma janela como esta:

Esta janela oferece uma barra de ferramentas bastante intuitiva. O botão adicionar irá abrir uma nova janela onde você poderá selecionar os campos da tabela que se deseja adicionar. Após selecionar os campos pressione o botão Create. O botão novo campo permite criar um campo de dado, calculado ou lookup. O uso desse botão irá abrir a seguinte janela:
Aqui você escolhe o tipo do campo em Field Type. Em Field properties podemos definir os valores das propriedades do campo. Depois confirme tudo pressionando Ok. Esteja sempre atento que as tabelas envolvidas na criação dos campos devem estar abertas.
Note também que esse procedimento irá criar variáveis do tipo TField, que podem ser usadas no código do nosso programa. Essas variáveis são criadas abaixo do Data Module conforme podemos ver na figura:

A partir disso, podemos acessar os campos da tabela usando essas variáveis, lembrando que elas são objetos. Veja alguns exemplos de utilização desses objetos:

queCidadeidcidade.Value;  // lê o valor do campo, inteiro nesse caso
queCidadeidcidade.AsString;  // lê o valor do campo convertido para string

Criação de TFields não é uma novidade. Isso já existia nas versões anteriores. Apenas ficou um pouco mais intuitivo e fácil manipular a criação desses objetos.

Referência aos parâmetros de um comando SQL

Como sabemos, é possível escrever comandos SQL utilizando parâmetros. Um exemplo é mostrado no código abaixo:

procedure TfrmConsCidade.btnPesquisarClick(Sender: TObject);
begin
  with dmDados.queConsCidade do
  begin
    Close;
    SQL.Clear;
    if (rgCampo.ItemIndex = 0) then
    begin
      // pidcidade é um parâmetro
      SQL.Add('select * from cidade where idcidade = :pidcidade');
      // atribuição do valor do parâmetro
      ParamByName('pidcidade').Value := StrToInt(edValor.Text);
      //Params[0].Value := StrToInt(edValor.Text);
    end
    else
    begin
      SQL.Add('select * from cidade where nome like :pnome');
      ParamByName('pnome').Value := edValor.Text + '%';
    end;
    Open;
  end;
end;

Em versões anteriores não havia o método ParamByName(). O acesso a um parâmetro era feito usando Params[]. Isso é mostrado na linha de código 13, que aparece comentada. O uso de ParamByName() torna o código mais legível.
O SQLdb melhorou muito, mas ainda aconselhamos o uso de ZeosLib.

Lazarus - Conectando Oracle com SQLdb ou ZeosLib

A Oracle oferece uma versão free do Oracle Database 10g. É o Oracle Database 10g Express Edition. Utilizamos esta versão neste artigo. Além disso, utilizamos a versão 0.9.29 do Lazarus, Free Pascal 2.4.1 e ZeosLib 7.0.0.
Para os testes usamos o usuário do Oracle hr, que é criado em uma nova instalação. Depois de instalado o banco de dados, o usuário hr deve ser desbloqueado pelo DBA e definida uma senha. Esse usuário tem acesso às tabelas do schema hr, também instalado junto com o banco. No entanto criamos uma nova tabela para os testes, de forma a manter as tabelas originais inalteradas. Criamos então nossa famosa tabela CIDADE.

CREATE TABLE  "CIDADE" 
   ( "ID_CIDADE" NUMBER NOT NULL ENABLE, 
 "NOME" VARCHAR2(40), 
  CONSTRAINT "CIDADE_PK" PRIMARY KEY ("ID_CIDADE") ENABLE
   )

Existe ferramenta de administração visual na instalação do Oracle, mas não é objetivo deste artigo expor a utilização da mesma.

Conexão com SQLdb

Para fazer a conexão vamos usar como sempre um Data Module onde os componentes de banco de dados serão colocados.

Localize na aba SQLdb o componente TOracleConnection e coloque no Data Module. Defina suas propriedades como segue:

DatabaseName - informe aqui o SID do banco de dados. No nosso caso é XE, o SID do Oracle Database Express Edition.
Hostname - informe o nome ou IP da máquina onde está o servidor do banco de dados. Como meu teste foi feito na máquina onde está o servidor, eu informei localhost, ou poderia ter informado 127.0.0.1.
Password - informe a senha do usuário hr. Ou de qualquer usuário com acesso ao banco de dados.
UserName - informe hr, ou outro usuário com acesso ao banco de dados.
Para fazer um teste na conexão, mude a propriedade Connected para True. Depois volte para False.

Coloque um TSQLTransaction e defina a propriedade Database com o nome do TOracleConnection que foi colocado anteriormente.

Coloque um TSQLQuery. Defina suas propriedades como mostrado a seguir:

Database - selecione o TOracleConnection anterior.
SQL - informe SELECT * FROM CIDADE.

Finalize colocando um TDataSource da aba Data Access. Defina a propriedade DataSet com a SQLQuery colocada antes.
No evento AfterPost da TSQLQuery digite o código:

SQLQuery1.ApplyUpdates;
SQLTransaction1.CommitRetaining;

No evento AfterDelete selecione o mesmo método para não repetir código.
Pronto. Está feita a configuração de acesso, tanto para leitura quanto para escrita, em uma tabela do Oracle. Crie uma interface seguindo os passos descritos no post Lazarus - Acessando banco de dados com SQLdb - Parte I.
Lembre de abrir a conexão. Pode ser no evento OnCreate do Data Module, com o código:

OracleConnection1.Open;

Conexão com ZeosLib

Coloque um TZConnection no Data Module. Defina as propriedades:

AutoCommit - deixe em True para que as transações no banco sejam comitadas automaticamente.
Database - informe o nome ou IP da máquina do servidor do banco de dados, por exemplo: localhost se estiver na mesma máquina.
HostName - informe o SID do banco de dados. XE no nosso caso. Observe que as propriedades HostName e Database são informadas de forma invertida em relação ao SQLdb.
Password - informe a senha do usuário com acesso ao banco. Neste caso foi usado hr.
Protocol - informe oracle ou oracle-9i. Ambos funcionam.
User - informe o nome do usuário. Neste caso é hr.

Mude Connected para True para testar a conexão. Depois de conectar com sucesso volte Connected para False.

Coloque um TZQuery e um TZUpdateSQL e configure-os como foi feito no artigo Lazarus - Conectando PostegreSQL com ZeosLib.
No TZUpdateSQL defina essas propriedades assim:

DeleteSQL - DELETE FROM CIDADE WHERE ID_CIDADE = :OLD_ID_CIDADE;
InsertSQL - INSERT INTO CIDADE VALUES (:ID_CIDADE, :NOME);
ModifySQL - UPDATE CIDADE SET NOME = :NOME WHERE ID_CIDADE = :OLD_ID_CIDADE;


Coloque um TDataSource da aba Data Access e na propriedade DataSet selecione a TZQuery anterior. Está pronta nossa conexão e acesso a uma tabela. Agora crie a interface com nos posts anteriores. Não esqueça de abrir a conexão com o comando:

ZConnection1.Connect;

Pode ser no evento OnCreate do Data Module.

Lazarus - Conectando MySQL com SQLdb ou ZeosLib

Vamos mostrar duas maneiras de acessar MySQL no Lazarus. Uma usando os componentes nativos SQLdb e outra usando ZeosLib. Utilizamos no exemplo a versão 5.1.46 do MySQL. O SQLdb da versão 0.9.28.2 não funciona com essa versão do MySQL. Dessa forma, foi instalado o snapshot Lazarus-0.9.29-25198-fpc-2.4.1-20100505-win32.exe (usamos o Windows XP nos testes). Snapshots são builds noturnos do Lazarus compilados com os últimos códigos fonte, corrigindo alguns erros e provavelmente introduzindo outros.

Crie o banco dados no MySQL. Vamos usar o mesmo banco usado em artigos anteriores. Este é o script de criação das tabelas:

create table cidade (id_cidade int not null primary key, nome varchar(30));

create table cliente (id_cliente int not null primary key, nome varchar(40), endereco varchar(40), id_cidade integer references cidade(id_cidade), telefone varchar(14), tipo char(1));

Usando SQLdb

Selecione a aba SQLdb e coloque no Data Module um TMySQL50Connection. Ele que fará a conexão com o banco. Defina então as seguintes propriedades:

DatabaseName - informe o nome do banco de dados que foi criado.
HostName - informe o nome ou o IP do servidor de banco de dados.
Name
- informe um nome para a conexão. Por exemplo: dbCliente.
Password - informe a senha do usuário. Se usar root como nome de usuário, informe a senha definida no momento da instalação do MySQL.

UserName - informe o nome do usuário. Pode ser o root.

Coloque agora um TSQLTransaction e selecione dbCliente na propriedade Database, e na propriedade Name digite trCliente, por exemplo.
Volte ao TMySQL50Connection e informe trCliente na propriedade Transaction. Coloque a propriedade Connected em True para verificar se a conexão é feita. Se retornar uma mensagem de falta da dll libmySQL, localize a mesma no diretório bin do MySQL e copie-a para o diretório system32. Depois volte a propriedade para False.
Coloque um TSQLQuery no Data Module e defina suas propriedades:

Database - selecione dbCliente.
Name - defina queCidade.
SQL - informe SELECT * FROM CIDADE.
Transaction - selecione trCliente.

Coloque agora um TDataSource da aba Data Access e mude Name para dsCidade e em DataSet selecione queCidade.
No evento AfterPost de queCidade digite o código:

queCidade.ApplyUpdates;
trCliente.CommitRetaining;

No evento AfterDelete selecione o mesmo método para não repetir código.
Pronto. Está feita a configuração de acesso, tanto para leitura quanto para escrita, em uma tabela do MySQL. Crie uma interface seguindo os passos descritos no post Lazarus - Acessando banco de dados com SQLdb - Parte I.
Selecione o form principal e, no editor de código, digite abaixo de Implementation:

uses u_dmdados;

Localize o evento OnShow na aba Eventos do Inspetor de objetos.  Dê um duplo clique à direita e digite:

dmDados.dbCliente.Open;

Assim, sempre que o programa for iniciado a conexão com o banco de dados será aberta.

Usando ZeosLib

Usaremos a versão 7.0 do ZeosLib disponível no grupo Lazarus-BR. Para instalar o pacote siga as instruções apresentadas no post Lazarus - Conectando PostgreSQL com ZeosLib. Coloque um TZConnection no Data Module. Defina as propriedades:

AutoCommit - deixe em True para que as transações no banco sejam comitadas automaticamente.
Database - informe o nome do banco de dados criado anteriormente.
HostName - informe o nome ou IP do servidor do banco. Para máquina local informe localhost.
Name - digite dbCliente.
Password - informe a senha do usuário. Em geral a senha do usuário root.

Protocol - informe mysql-5. Observe a versão do MySQL que você está usando.
User - informe o nome do usuário. Geralmente é root.

TransactionIsolation - define o nível de isolamento da transação. No nosso caso vamos usar tiReadCommitted.
Mude Connected para True. No Windows deve ocorrer um erro de ausência de dll. Faça o download aqui e copie-a para system32 do Windows. Depois de conectar com sucesso volte Connected para False.

Coloque um TZQuery e um TZUpdateSQL e configure-os como foi feito no artigo Lazarus - Conectando PostegreSQL com ZeosLib.
No TZUpdateSQL defina essas propriedades assim:

DeleteSQL - DELETE FROM CIDADE WHERE ID_CIDADE = :OLD_ID_CIDADE;
InsertSQL - INSERT INTO CIDADE VALUES (:ID_CIDADE, :NOME);
ModifySQL - UPDATE CIDADE SET NOME = :NOME WHERE ID_CIDADE = :OLD_ID_CIDADE;


Coloque um TDataSource da aba Data Access e defina Name como dsCidade e em DataSet selecione a TZQuery anterior. Ai está. Agora crie a interface com nos posts anteriores.

Atualizado em 04/06/2010.

Lazarus - Conectando MSAccess com ODBC

Atualizei o Lazarus para a versão Lazarus-0.9.29-24055-fpc-2.4.1-20100317-win32. E foi usando esse snapshot que criei o exemplo usado neste post. Pode-se baixar o mais recente snapshot em http://www.hu.freepascal.org/lazarus/
Nem todas as fontes de dados estão contempladas pelo SQLdb ou pelo ZeosLib. Algumas vezes é necessário migrar ou mesmo atualizar fontes de dados como Paradox, Access e outros. Para essa nobre tarefa o Lazarus disponibiliza o componente TODBCConnection, encontrado na aba SQLdb. Ou seja, podemos acessar qualquer banco de dados (mesmo aqueles que não merecem essa denominação) através de ODBC, desde que tenhamos o driver específico. Devo observar que fiz esse exemplo no Windows.
Então o primeiro passo é criar uma fonte de dados ODBC e isso é feito no sistema operacional. Usei uma fonte MSAccess - o dbdemos.mdb que vem com o Delphi. Após isso vamos ao Lazarus.
No Data Module coloque um TODBCConnection. Mude a propriedade Name para dbAccess, por exemplo. Em DatabaseName digite o nome da fonte de dados criada no sistema anteriormente. Mude Connected para True para testar a conexão. Depois volte para False.
Coloque um TSQLTransaction, mude Name para trAccess e em Database selecione dbAccess. Feito isso coloque um TSQLQuery e mude Name para queEmployee, em Database selecione dbAccess. Na propriedade SQL informe SELECT * FROM EMPLOYEE e em Transaction selecione trAccess. Se você mudar a propriedade Active de queEmployee para True, ela deveria abrir sem erro. No meu caso não funcionou e, depois de muito apanhar, mudei a propriedade UsePrimaryKeyAsKey de queEmployee para False e deu certo. Não sei explicar porque. Na propriedade InsertSQL digite:

INSERT INTO EMPLOYEE VALUES (:EMPNO, :LASTNAME, :FIRSTNAME, :PHONEEXT, :HIREDATE, :SALARY);

Em UpdateSQL:

UPDATE EMPLOYEE SET LASTNAME = :LASTNAME, FIRSTNAME = :FIRSTNAME, PHONEEXT = :PHONEEXT, HIREDATE = :HIREDATE, SALARY = :SALARY WHERE EMPNO = :EMPNO;

E em DeleteSQL:

DELETE FROM EMPLOYEE WHERE EMPNO = :EMPNO;

Agora coloque um TDataSource da aba Data Access. Defina Name como dsEmployee e DataSet como tbEmployee.



Crie uma interface. Se tiver dúvida de como fazer isso, dê uma olhada nos posts Lazarus - Acessando banco de dados com SQLdb - Parte I e Parte II.
Lembre de abrir e fechar a conexão do TODBCConnection. Pode fazer isso nos eventos OnShow e OnClose de form, usando os métodos Open e Close. Abra e feche tbEmployee nos mesmos eventos. Para finalizar, no evento AfterPost de tbEmployee escreva o seguinte código:

tbEmployee.ApplyUpdates;

E ligue o evento AfterDelete a esse mesmo método. Clique aqui para fazer o download do exemplo. Qualquer dúvida ou sugestão comente.

Lazarus - Acessando banco de dados com SQLdb - Parte II

Form de Cliente

No DataModule já deve ter uma TSQLQuery e um TDataSource devidamente configurados para acesso à tabela Cliente. Vamos então inserir um novo form no programa definindo Name como frmCliente, Caption como Clientes. Mande salvar e informe u_cliente no nome da unit. Acesse o editor de código referente a esse form e abaixo de Implementation, para permitir que a unit u_cliente tenha acesso aos objetos do DataModule, digite:

uses u_dmdados;

Volte ao form e inclua um TPanel da mesma forma que foi feito para o form de Cidade. Selecione um TDBNavigator da aba Data Controls e coloque sobre o painel. Defina a propriedade DataSource como dsCliente. Insira um TSpeedButton da aba Additional no painel e o configure semelhante ao que fizemos no form de Cidade, inclusive definindo o código do evento OnClick para fechar o form. O form de Cliente deverá ter essa aparência:


Coloque dois TDBedit no form, o primeiro deve ter Name definido como edIdCliente, DataSource como dsCliente e DataField como ID_CLIENTE. No segundo defina Name como edNome, DataSource como dsCliente e DataField como NOME. Coloque dois TLabel para identificar esse campos e defina os Caption de acordo com a figura anterior.
O componente TDBLookupComboBox é usado para que, no caso de uma chave estrangeira (ID_CIDADE na tabela Cliente), o usuário possa escolher o registro na tabela referenciada (Cidade). Neste componente os dados da tabela referenciada são mostrados em uma lista. Pegue então um componente desses na aba Data Controls e coloque no form abaixo do segundo TDBEdit. Defina Name como dblIdCidade, DataSource como dsCliente e DataField como ID_CIDADE. Para definir a lista primeiramente defina a propriedade ListSource como dsCidade, na propriedade ListField (campo que será visualizado na lista) defina NOME e KeyField (campo chave) defina como ID_CIDADE. Existe ainda a propriedade Sorted que define se a lista estará ordenada e Style que define o comportamento do controle. Deixe Sorted como True e Style como dsDropDownList (o usuário não poderá digitar no controle, apenas selecionar da lista). Coloque um TLabel para identificar este campo.
Coloque mais um TDBEdit abaixo do LookupComboBox. Defina Name como edTelefone, DataSource como dsCliente e DataField como TELEFONE. Coloque um TLabel para fazer a identificação do campo.
O campo TIPO da tabela Cliente é usado para informar se o cliente é pessoa física - representado pela letra F - ou pessoa jurídica - representado pela letra J. Para este controle vamos usar um TDBRadioGroup, que permite que sejam definidas opções para serem selecionadas. Pegue um componente desses e o coloque no form. Defina a propriedade Caption como Tipo e Name como rgTipo. DataSource será dsCliente e DataField será TIPO. Clique no botão da propriedade Items. Será aberta uma janela com o editor de strings. Digite Pessoa física na primeira linha e Pessoa jurídica na segunda e pressione OK. Na propriedade Columns digite 2 para que as opções apareçam em linha. Clique no botão da propriedade Values - onde estão os valores correspondentes às opções definidas em Items. Digite F na primeria linha e J na segunda. Desta forma quando for selecionada a opção Pessoa física será gravado F no banco de dados, e J caso contrário. Redimensione o componente adequadamente.
Finalmente coloque um TDBCheckBox no form. Defina Caption como Ativo e Name como chxStatus. DataSource é definido como dsCliente e em DataField digite STATUS. As propriedades ValueChecked e ValueUnchecked são usadas para definir o que será gravado no campo quando o componente estiver marcado ou não marcado. Como nosso campo no banco de dados é boolean, não é necessário alterar nada.
Para programar a abertura e o fechamento da Query faça de forma análoga ao que foi feito no form de Cidade. Escreva os códigos correspondentes nos eventos OnShow e OnClose de frmCliente.
Mude para o DataModule e selecione queCliente. Selecione a aba Eventos do Inspetor de objetos e dê um duplo clique ao lado do evento AfterPost. Digite o código como na figura:



Note que esse código é ligeiramente diferente do que fizemos para queCidade. Em vez de usarmos CommitRetaining, agora usamos Commit. Commit fecha todas as tabelas abertas, por isso a Query é aberta na linha 68. Na linha 63 guardamos as chave primária do registro atual na variável chave. E depois que a Query é aberta, usamos Locate para localizar o registro correspondente à variável chave. Esta é outra forma de fazer o COMMIT na transação.
Localize o evento AfterDelete da Query. Clique no botão da caixa à direita para selecionar um método existente. Selecione queClienteAfterPost para que a transação seja encerrada da mesma forma quando um registro for excluído.
Agora vamos ao form principal. Na linha uses abaixo de Implementation acrescente u_cliente para que ela fique assim:

uses u_cidade, u_cliente;

Clique no menu Cadastros -> Clientes e no código do evento OnClick digite:

frmCliente.Show;

Execute o programa e chame o form de Cliente para fazer os testes.


Consultas

O próximo passo do desenvolvimento será criar as telas de consulta às tabelas Cidade e Cliente. Neste artigo mostraremos a criação da consulta de cidades. Supomos que a consulta de clientes é análoga e não haverá dificuldade em criá-la.
Para iniciar vamos ao DataModule inserir dois componentes necessários: um TSQLQuery e um TDataSource. Na Query mude Name para queConsCidade. Na propriedade Database selecione dbCliente. Certifique-se que a propriedade Transaction está corretamente definida como trGeral. No TDataSource mude Name para dsConsCidade e DataSet para queConsCidade.
Uma interface de consulta é necessária, portanto deve-se inserir um novo form. Defina Name como frmConsCidade e Caption como Consulta de cidades. Salve e digite u_conscidade no nome da unit.
A consulta irá oferecer duas opções de consulta - pela chave primária ou por parte do nome. Então insira um TRadioGroup da aba Standard. Defina Caption como Campo. Na propriedade Items inclua as linhas Código e Nome. Na propriedade Name digite rgCampo. Redimensione o componente adequadamente.


Observe a figura acima para orientar o seu desenho. Inclua um TEdit da aba Standard. Defina Name como edDado e delete o conteúdo da propriedade Text.
Coloque um TLabel para identificar o campo. Defina Caption como Dado a consultar.
Insira um TButton. Defina Name btnConsultar. Localize o componente TDBGrid na aba Data Controls. Insira um no form. Defina sua propriedade Name com dbgDados. Abra o editor de código e digite abaixo de Implementation:

uses u_dmdados;

Volte ao form e na propriedade DataSource da TDBGrid selecione dsConsCidade. Dê um duplo clique no botão btnConsultar e digite o código:

 

Analisando o código:
linha 39 - define que propriedades e métodos sem referência a um objeto são considerados como sendo de queConsCidade.
linha 41 - fecha a Query.
linha 42 - limpa o conteúdo da propriedade SQL.
linha 43 - verifica que campo foi selecionado no RadioGroup.
linhas 45 e 46 - definem um comando SELECT para buscar linhas na tabela pela chave primária. pIdCidade é um parâmetro definido na linha 46.
linhas 50 e 51 - definem um comando SELECT para buscar linhas na tabela por parte do nome da cidade.
linha 53 - abre a Query.

Mude para o form principal. No editor de código inclua a unit u_conscidade na linha uses abaixo de Implementation. Clique na opção Consultas -> Cidades. Digite o código:

frmConsCidade.Show;

Execute o programa e faça testes de consulta. Falta validar edDado para que aceite apenas dígitos numéricos quando a consulta for direcionada para o campo chave. Deixamos essa tarefa e a criação da consulta de clientes como um exercício.

Baixe aqui o código completo do programa.

Algumas considerações

Durante a criação dessa pequena aplicação encontramos dificuldade em achar relatos de experiências usando os componentes SQLdb. Já utilizamos outros componentes tanto em Lazarus quando no Delphi e sentimos algumas dificuldades principalmente no que diz respeito ao controle de transações. SQLdb só permite um objeto SQLTransaction na aplicação. Isso torna-se um obstáculo quando é necessário abrir mais de um form simultaneamente, pois quando fechamos uma transação todas as tabelas são fechadas. Outra dificuldade refere-se ao ponteiro TBookmark. Antes de encerrar uma transação guardamos o ponteiro do registro atual. Após encerrar a transação, quando o método GotoBookmark() é chamado para posicionar o registro no ponteiro salvo anteriormente ocorre uma exceção. Vale observar que chamar o GotoBookmark() antes de encerrar a transação funciona normalmente. Por esses motivos nos próximos artigos usaremos os componentes ZeosLib.

Lazarus - Acessando banco de dados com SQLdb - Parte I

Para fazer nossa primeira aplicação usando banco de dados no Lazarus vamos usar o SQLite e o conjunto de componentes nativo SQLdb. Inicialmente vamos apresentar passo como essa aplicação foi criada. Essa foi a maneira que eu fiz, e eu agradeço sugestões e questionamentos que pessoas que já passaram por essa experiência. Depois irei fazer algumas considerações sobre o uso do SQLdb.

SQLite

SQLite é uma biblioteca que implementa um motor de banco de dados SQL. É livre para qualquer finalidade, seja uso particular ou comercial. Lê e escreve em um único arquivo que pode ter além de tabelas, índices, gatilhos e visões. Executa em várias plataformas e é indicado para aplicações embarcadas. Maiores detalhes podem ser encontrados no site oficial. Para usá-lo, baixe-o do site e faça a instalação adequada para o seu sistema operacional. No Windows isso é muito simples, apenas copie sqlite3.dll para o system32 da pasta do sistema operacional.
Existe uma ferramenta de linha de comando chamada sqlite3 que podemos usar para criar o banco de dados e as tabelas. Pode ser baixada no próprio site oficial do SQLite. Depois de instaladas a dll e a ferramenta de criação do banco execute-a digitando o seguinte comando no console do sistema operacional:

sqlite3 banco.db

Se o banco já existir ele será aberto para operações como criar/alterar tabelas e consultar/inserir/atualizar/deletar dados nas tabelas existentes. Depois disso digite os comandos SQL para a criação de duas tabelas necessárias para nossa aplicação:

create table cidade (id_cidade integer primary key, nome varchar(30));
create table cliente (id_cliente integer primary key, nome varchar(40), endereco varchar(40), id_cidade integer, telefone varchar(14), tipo char(1), status boolean);

Feito isso digite .quit para sair e voltemos ao nosso IDE.

SQLdb

Esse é o pacote para acessar bancos de dados no Lazarus. Você o encontra na aba SQLdb. Algumas informações estão em http://wiki.freepascal.org/SQLdb_Package. Com esse pacote podemos conectar ao PostgreSQL, Oracle, MySQL, Firebird, SQLite e ODBC. Para cada um desses existe um componente TXXXConnection. Para conectar ao Firebird, por exemplo, existe o componente TIBConnection. Para executar as operações sobre tabelas temos o TSQLQuery e o TSQLTransaction. A seguir iremos criar a aplicação e mostraremos como utilizar esses componentes.

A aplicação exemplo

Vamos então iniciar o Lazarus e criar uma nova aplicação. No primeiro form crie um menu com a seguinte estrutura. Se for necessário leia o artigo sobre criação de menus em http://professorcarlos.blogspot.com/2010/01/lazarus-criando-menus.html:

Arquivo
    Sair
Cadastros
    Cidade
    Cliente
Consultas
    Cidade
    Cliente

Mude a propriedade Name desse form para frmPrincipal. Mande salvar tudo. Escolha u_principal para nome da unit e Clientes para nome do projeto.
É fortemente aconselhado que os componentes de conexão e acesso ao banco de dados estejam agrupados em um repositório denominado DataModule. Para criar um DataModule no Lazarus selecione o menu Arquivo -> Novo. Selecione Data Module abaixo do grupo Módulo e pressione o botão OK. Mude a propriedade Name para dmDados, mande salvar e dê o nome u_dmdados para esta unit.
Agora selecione a aba de componentes SQLdb e coloque um TSQLite3Connection no DataModule. Na propriedade DatabaseName informe o nome do arquivo do banco de dados com o caminho. Mude a propriedade Name para dbCliente. Neste momento podemos mudar a propriedade Connected para True. Se nenhum erro acontecer o componente de conexão está corretamente configurado. Volte a propriedade Connected para False. Coloque um componente TSQLTransaction no DataModule. Na propriedade Database selecione dbCliente e em Name digite trGeral. Retorne ao SQLite3Connection e selecione trGeral na propriedade Transaction. TSQLTransaction é o componente que controla as transações no banco de dados. Em um banco de dados as operações ocorrem no contexto de uma transação. Uma transação finaliza com sucesso através de um COMMIT e ROLLBACK desfaz as operações realizadas anteriormente.
Selecione um TSQLQuery e coloque no DataModule. Na propriedade Database selecione dbCliente. Na propriedade Name digite queCidade e em SQL informe select * from cidade. Na propriedade Transaction defina trGeral. Agora localize a aba Data Access. Selecione um componente TDataSource e coloque no DataModule. Defina Name como dsCidade e em DataSet selecione queCidade. Resumindo, fizemos a conexão com o banco de dados usando SQLite3Connection, em seguida definimos um componente para controlar as transações, definimos uma conexão com uma tabela do banco usando TSQLQuery, e criamos uma ligação entre a tabela e os componentes que terão a função de ler os campos dessa tabela usando TDataSource. Esse é um procedimento repetitivo para novas tabelas nessa aplicação e mesmo quando usarmos outros conjuntos de componentes. O DataModule terá essa aparência, já com os componentes para acesso à tabela Cliente.


Repita os mesmos passos para a tabela Cliente, inserindo mais um TSQLQuery e um TDataSource. Selecione o form principal e, no editor de código, digite abaixo de Implementation:

uses u_dmdados;

Localize o evento OnShow na aba Eventos do Inspetor de objetos.  Dê um duplo clique à direita e digite:

dmDados.dbCliente.Open;

Assim, sempre que o programa for iniciado a conexão com o banco de dados será aberta.

Form de Cidade

Insira um novo form na aplicação. Ele será desenhado para fazer as atualizações na tabela Cidade. Defina o Name do form como frmCidade e o Caption como Cidades. Salve a unit e defina seu nome como u_cidade. O desenho deste form deve ter a seguinte aparência.

 

Antes de começar a desenhar a janela, acesse o código da unit e insira o seguinte código abaixo de Implementation

uses u_dmdados;

Isso permite que esta unit acesse os objetos do DataModule.
Pegue um componente TPanel na aba Standard e coloque no form. Defina a propriedade Align como alTop. Exclua o conteúdo de Caption. As propriedades BevelInner e BevelOuter são usadas para definir contornos para o painel. Deixe, por exemplo, como bvLowered e bvRaised respectivamente.
Agora selecione um TDBNavigator na aba Data Controls e o coloque no form sobre o painel. Na propriedade DataSource do navegador selecione dsCidade.
Dessa mesma aba selecione TDBEdit e coloque dois deles no form. No primeiro defina Name como edIdCidade, em DataSource selecione dsCidade e em DataField digite ID_CIDADE. Essa última atribuição irá provocar um erro, mas isso não vai interferir no resultado. No segundo TDBEdit defina Name como edNome, DataSource como dsCidade e em DataField digite NOME. Selecione TLabel na aba Standard e coloque um à esquerda de cada TDBEdit para identificá-los. Defina suas propriedades Caption como ID e Nome, respectivamente. Para finalizar o desenho coloque um TSpeedButton da aba Additional sobre o painel. Defina Name como btnSair e escolha um ícone apropriado para ele usando a propriedade Glyph. No evento OnClick deste botão digite:

Close;

É necessário programar a abertura e o fechamento da Query no form. A abertura será programada no evento OnShow e o fechamento será programado no evento OnClose, ambos de form. Com o form selecionado selecione da aba Eventos no Inspetor de Objetos. Localize o evento OnShow, dê um duplo clique na caixa à direita e digite o seguinte:

dmDados.queCidade.Open;

Faça o mesmo para o evento OnClose e digite:

dmDados.queCidade.Close;

Agora precisamos programar a chamada do form frmCidade a partir no form principal. Selecione o form principal, mude para o editor de código e digite abaixo de Implementation:

uses u_cidade;

Volte para o form e clique no menu Cadastros -> Cidades. No editor de código digite:

frmCidade.Show;

Se você compilar e executar o programa verificará que não consegue ainda inserir dados na tabela Cidade. Todos os dados que são inseridos ficam em cache. É necessário enviar os dados para o banco e finalizar a transação.
Isso será feito no evento AfterPost da Query. Este evento ocorre após um registro ser gravado no banco. Selecione o DataModule e em seguida queCidade. Clique na aba Eventos do Inspetor de Objetos. Localize o evento AfterPost, dê um duplo clique à direita dele e digite o seguinte:


Vamos esclarecer o código:
linha 42 - declara um TBookMark, que é um ponteiro para um registro.
linha 45 - try, juntamente com except consiste em um tratamento de exceção. Se algo falhar no bloco try, o código em except é executado.
linha 46 - guarda o ponteiro do registro atual.

linha 47 - envia para o banco de dados o que estiver no cache.
linha 48 - verifica se existe uma transação ativa.
linha 50 - executa um COMMIT no banco, mas mantém a transação aberta.
linha 51 - desvia para o ponteiro salvo na linha 46.
linha 54 - executa um ROLLBACK se algo sair errado no bloco try.

Localize o evento AfterDelete da Query. Clique no botão da caixa à direita para selecionar um método existente. Selecione queCidadeAfterPost. Assim reaproveitamos o código que executa a mesma operação necessária no AfterDelete.
Compile e execute o programa. No post seguinte daremos seguimento ao desenvolvimento dessa aplicação.

Django - Composição de queries brutas (raw queries)

Django Rest Framework (DRF) é uma poderosa ferramenta para criar Web APIs. Ele requer o uso de Python e do framework Django. Mesmo o Django...