Anda di halaman 1dari 5

Delphi Lazarus (linux) : MySQL

Objetivo
Ter o primeiro contato com banco de dados em Lazarus. Aprender a criar um banco de dados MySQL e a usar a API de programao para executar funes simples de acesso e consulta. if [ ! $? = 0 ]; then echo "Falhou." else echo "Feito." fi # Terminado 3. Compile o programa abaixo, que acessar o banco: (fpc testdb4.pp) program qtest; uses mysql4; const DataBase : Pchar = 'testdb'; Query : Pchar = 'Select * from FPdev'; host : Pchar = 'localhost'; user : Pchar = 'z-user'; passwd : Pchar = 'z-password'; var count, num : longint; code : integer; sock : PMYSQL; qmysql : TMYSQL; qbuf : string [160]; rowbuf : TMYSQL_ROW; dummy : string; recbuf : PMYSQL_RES; alloc : PMYSQL; begin if paramcount=1 then begin Dummy:=Paramstr(1)+#0; DataBase:=@Dummy[1]; end; Writeln ('Alocando Espao ...'); alloc := mysql_init (PMYSQL(@qmysql)); Write ('Conectando ao MySQL ...'); sock := mysql_real_connect (alloc, host, user, passwd, DataBase, 0, nil, 0); if sock=Nil then begin Writeln (stderr,'No foi possvel conectar ao MySQL.'); Writeln (stderr, 'O erro foi: ', mysql_error(@qmysql)); halt(1); end; Writeln ('Done.'); Writeln ('Connection data:'); {$ifdef Unix} writeln ('Mysql_port : ',mysql_port); writeln ('Mysql_unix_port : ',mysql_unix_port); {$endif} writeln ('Host info : ',mysql_get_host_info(sock)); writeln ('Server info : ',mysql_stat(sock)); writeln ('Client info : ',mysql_get_client_info); Writeln ('Selecionando o Banco',DataBase,'...'); if mysql_select_db (sock,DataBase) < 0 then begin Writeln (stderr,'No foi possvel selecionar o Banco', Database); Writeln (stderr,mysql_error (sock)); halt (1); end; Writeln ('Executando consulta: ',Query,'...'); if (mysql_query (sock,Query) < 0) then begin Writeln (stderr,'Query failed ');

Componentes Utilizados
Form, Label, Edit , Button e Memo.

MySQL
Este projeto ensina a conectar o Lazarus ao MySQL 4 e a executar consultas simples, usando apenas componentes bsicos do Lazarus.

Desenvolver o Projeto
Primeira Fase Linha de Comando 1. Crie um banco de dados MySQL, a partir de um shell unix. No esquea que o mysql server deve estar rodando:

/etc/rc.d/init.d/mysqld start (como root) Agora, acesse o servidor (o root do mysql no o mesmo root do linux). mysql -u root -p mysql> create database testdb; mysql> use mysql; mysql> grant all on testdb to z-user indentified by 'z-password'; mysql> flush privileges; mysql> quit
2. Rode o script mkdb, que criar a tabela FPdev, no banco testdb. #!/bin/sh # # Script para criar uma tabela 'FPdev' e preench-la com dados. # O script aceita um argumento opcional : # A que banco de dados se conectar (default 'testdb'). echo -n "Criando e populando a tabela FPdev do banco de dados ${1-testdb}..." mysql -u root ${1-testdb} -p << EOF >/dev/null # Elimina a tabela caso ela j exista. DROP TABLE IF EXISTS Fpdev; # Cria a tabela. CREATE TABLE FPdev ( id INT NOT NULL, UserName CHAR(255), InstEmail CHAR(255), PRIMARY KEY (id), INDEX (id) ); insert into FPdev values ('1','Michael Van Canneyt', 'Michael@tfdec1.fys.kuleuven.ac.be'); insert into FPdev values ('2','Florian Klaempfl', 'ba2395@fen.baynet.de'); insert into FPdev values ('3','Carl-Eric Codere', 'codc01@gel.usherb.ca'); insert into FPdev values ('4','Dani Mantione', 'd.s.p.mantione@twi.tudelft.nl'); insert into FPdev values ('5','Pierre Muller', 'muller@europe.u-strasbg.fr'); insert into FPdev values ('6','Jonas Maebe', 'jmaebe@mail.dma.be'); insert into FPdev values ('7','Peter Vreman', 'pfv@worldonline.nl'); insert into FPdev values ('8','Gerry Dubois', 'gerry@webworks.ml.org'); EOF # Em bash, o valor de retorno de um programa armazenado # numa varivel chamada $?

Pgina 1 de 5

Delphi Lazarus (linux) : MySQL


writeln (stderr,mysql_error (sock)); Halt(1); end; recbuf := mysql_store_result (sock); if RecBuf=Nil then begin Writeln ('Consulta retornou resultado nulo.'); mysql_close (sock); halt (1); end; Writeln ('Nmero de registros retornados: ',mysql_num_rows (recbuf)); Writeln ('Nmero de campos por registro: ',mysql_num_fields (recbuf)); rowbuf := mysql_fetch_row (recbuf); while (rowbuf <>nil) do begin Write ('(Id: ', rowbuf[0]); Write (', Name: ', rowbuf[1]); Writeln(', Email : ', rowbuf[2],')'); rowbuf := mysql_fetch_row (recbuf); end; Writeln ('Liberando a memria alocada pelo conjunto resultado ...'); mysql_free_result (recbuf); Writeln ('Fechando a conexo com o MySQL.'); mysql_close (sock); halt(0); end. 4. Rode o programa, que deve listar os nomes e emails de alguns do desenvolvedores do free pascal: testdb4 Connecting to MySQL...Done. Connection data: Mysql_port : 3306 Mysql_unix_port : /var/lib/mysql/mysql.sock Host info : Localhost via UNIX socket Server info : Uptime: 1341559 Threads: 1 Questions: 122 Slow queries: 0 Opens: 2 Flush tables: 5 Open tables: 1 Queries per second avg: 0.000 Client info : 4.1.14 Selecting Database testdb... Executing query : Select * from FPdev... Number of records returned : 8 Number of fields per record : 3 (Id: 1, Name: Michael Van Canneyt, Email : Michael@tfdec1.fys.kuleuven.ac.be) (Id: 2, Name: Florian Klaempfl, Email : ba2395@fen.baynet.de) (Id: 3, Name: Carl-Eric Codere, Email : codc01@gel.usherb.ca) (Id: 4, Name: Daniel Mantione, Email : d.s.p.mantione@twi.tudelft.nl) (Id: 5, Name: Pierre Muller, Email : muller@europe.u-strasbg.fr) (Id: 6, Name: Jonas Maebe, Email : jmaebe@mail.dma.be) (Id: 7, Name: Peter Vreman, Email : pfv@worldonline.nl) (Id: 8, Name: Gerry Dubois, Email : gerry@webworks.ml.org) Freeing memory occupied by result set... Closing connection with MySQL. 5. Lista das 11 funes do MySQL utilizadas (declaradas em C): 4) const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag) Tenta estabelecer uma conexo com um banco de dados MySQL rodando em host. Esta funo deve ser completada sem erro antes que se possa executar qualquer outra chamada de funo da API. Retorna um ponteiro (*MYSQL) para o handle da conexo em caso de sucesso ou NULL, em caso de fracasso. 3) int

mysql_query(
MYSQL *mysql, const char *query)

Executa a consulta SQL apontada pela string no nula query. A consulta deve consistir de um nico comando SQL. No deve ser adicionado um terminador ; ou \g ao comando. mysql_query() no pode ser usada para consultas que contenham dados binrios; neste caso, deve ser usada mysql_real_query() . (Dados binrios podem conter o caracter \0, que o mysql_query() interpreta como o final da string de consulta). Retorna zero se a consulta foi bem sucedida ou um valor diferente de zero, se ocorreu algum erro. MYSQL_ROW mysql_fetch_row (MYSQL_RES *result) Retorna a prxima linha de um conjunto resultado ou NULL, se no houver mais linhas. 5) MYSQL_RES *mysql_store_result (MYSQL *mysql) Deve-se chamar mysql_store_result() para cada consulta bem sucedida que retorne dados (Select, Show, Describe, Explain). O resultado completo de uma consulta do cliente lido, uma estrutura MYSQL_RES alocada e recebe o resultado. 6) void

mysql_free_result( MYSQL_RES *result )

Libera a memria alocada pelo conjunto resultado das funes mysql_store_result(), mysql_use_result(), mysql_list_dbs(), etc... 7) int mysql_select_db ( MYSQL *mysql, const char *db) Faz com que o Banco de Dados especificado por db seja o default (corrente) na conexo especificada por mysql. Em consultas subseqentes, este banco de dados o default em todas as referncias a tabelas que no incluam um especificador explicito. 8) unsigned long mysql_num_rows ( MYSQL_RES *result) Retorna o nmero de linhas (registros) de um conjunto resultado 9) unsigned int mysql_num_fields (

1)

MYSQL *mysql_init (MYSQL *mysql) Aloca ou inicia um objeto MYSQL adequado chamada da funo mysql_real_connect().

2)

MYSQL*

mysql_real_connect(
MYSQL *mysql, const char *host, const char *user,

Pgina 2 de 5

Delphi Lazarus (linux) : MySQL


MYSQL_RES *result) Retorna o nmero de colunas (campos) de um conjunto resultado. 10) const char *mysql_error (MYSQL *mysql) Para a conexo especificada por mysql, retorna uma string terminada por NULL, contendo a mensagem de erro para a funo da API invocada mais recentemente que falhou. 11) void mysql_close(MYSQL *mysql) Fecha uma conexo que foi aberta previamente, e desaloca o handle de conexo apontado por mysql, se este foi alocado automaticamente por mysql_init() ou mysql_connect(). Segunda Fase Interface Grfica

1.

Crie um novo projeto. Renomeie o formulrio para TryMYSQL e adicione trs EditBox: Host (HostLabel e HostEdit). Username (UserLabel e UserEdit). Password (PasswdLabel e PasswdEdit). Selecione o TEdit Passwd e encontre a propriedade PasswordChar. Mude-a para *, ou algum outro caracter, para que quando voc digite a senha os caracteres no apaream na tela, e apenas seja ecoado uma srie de *. Certifique-se de que a propriedade Text de cada EditBox esteja em branco. Coloque um outro EditBox e Label no topo do lado direito do formulrio. Mude o label para 'Enter SQL Command' e chame-o de CommandEdit. Coloque trs Botes no formulrio: altere a propriedade Text para 'Connect to Database' (ConnectButton), 'Exit' (ExitButton) e 'Send Query' (QueryButton). Adicione um MemoBox com Text 'Results' (ResultMemo). Encontre a propriedade ScrollBars e selecione ssAutoBoth, para que os scroll bars apaream automaticamente se o texto ocupar todo o espao. Torne verdadeira a propriedade WordWrap. Adicione um StatusBar (a partir do Common Controls tab) e mude a propriedade SimpleText para 'TryMySQL'. Declare as seguintes variveis na seo implementation: const DataBase : Pchar = 'testdb'; var sock : PMYSQL;

2.

3.

4.

5.

6.

7.

Pgina 3 de 5

Delphi Lazarus (linux) : MySQL


qmysql : TMYSQL; rowbuf : MYSQL_ROW; recbuf : PMYSQL_RES; alloc : PMYSQL; As respostas do banco de dados so convertidas em strings e exibidas no MemoBox. procedure showString (S: string); // exibe uma string em um MemoBox begin trymysqlForm1.ResultsMemo.Lines.Add (S) end; O evento do boto de conexo fica ento: procedure TtrymysqlForm1.ConnectButtonClick(Sender: TObject); // Conecta ao MySQL usando dados fornecidos nas caixas de // entrada de texto do formulrio principal (Main Form). var strg: string; dummy1, dummy2, dummy3: string; host, user, passwd: Pchar; begin dummy1 := trymysqlForm1.HostEdit.text+#0; host := @dummy1[1]; // endereo do primeiro caracter da string dummy2 := trymysqlForm1.UserEdit.text+#0; user := @dummy2[1]; // endereo do primeiro caracter da string dummy3 := trymysqlForm1.PasswdEdit.text+#0; passwd := @dummy3[1]; // endereo do primeiro caracter da string // tenta abrir uma conexao com o MySQL alloc := mysql_init (PMYSQL(@qmysql)); sock := mysql_real_connect (alloc, host, user, passwd, database, 0, nil, 0); if sock = Nil then begin strg := 'Nao foi possivel conectar ao MySQL.'; showstring (strg); Strg := 'O erro foi: '+ StrPas (mysql_error (@qmysql)); showstring (strg); end else begin trymysqlForm1.statusBar1.simpletext := 'Conectado ao MySQL'; strg := 'Escolhendo o banco de dados : ' + database; showstring (strg); // Imprime dados da conexao: porta, host, servidor, cliente {$ifdef Unix} strg := 'Mysql_port : ' + IntToStr (mysql_port); showstring (strg); strg := 'Mysql_unix_port : ' + StrPas (mysql_unix_port); showstring (strg); {$endif} strg := 'Host info : ' + StrPas (mysql_get_host_info (sock)); showstring (strg); Strg := 'Server info : ' + StrPas (mysql_stat (sock)); showstring (strg); Strg := ' Client info : ' + Strpas (mysql_get_client_info); showstring (strg); trymysqlForm1.statusbar1.simpletext := 'Selecionando o Banco de Dados ' + DataBase +'...'; if mysql_select_db (sock,DataBase) < 0 then begin strg := 'Nao foi possivel selecionar o banco de dados ' + Database; showString (strg); strg := mysql_error (sock); showString (strg); end end; end; // ConnectButtonClick O cdigo do evento click do SendQuery :

Pgina 4 de 5

Delphi Lazarus (linux) : MySQL


procedure TtrymysqlForm1.QueryButtonClick(Sender: TObject); var dumquery, strg: string; query: Pchar; begin dumquery := TrymysqlForm1.CommandEdit.text; dumquery := dumquery+#0; query := @dumquery[1]; trymysqlForm1.statusbar1.simpletext := 'Executando query : ' + dumQuery +'...'; strg := 'Executando query : ' + dumQuery; showstring (strg); if (mysql_query (sock,Query) < 0) then begin Strg := 'Query falhou ' + StrPas(mysql_error (sock)); showstring (strg); end else begin recbuf := mysql_store_result (sock); if RecBuf=Nil then begin Strg := 'Query produziu resultado nulo.'; showstring (strg); end else begin strg := 'Numero de registros retornados : ' + IntToStr(mysql_num_rows (recbuf)); showstring (strg); Strg := 'Numero de campos por registro : ' + IntToStr(mysql_num_fields (recbuf)); showstring (strg); // carrega um registro no buffer rowbuf := mysql_fetch_row (recbuf); // enquanto houver registros a tratar while (rowbuf <>nil) do begin // imprime o ID, Nome e Email Strg := '(Id: '+ rowbuf[0]+', Name: ' + rowbuf[1]+ ', Email : ' + rowbuf[2] +')'; showstring (strg); // pega o proximo registro rowbuf := mysql_fetch_row (recbuf); end; end; end; end; // QueryButtonClick procedure TtrymysqlForm1.ExitButtonClick (Sender: TObject); begin trymysqlForm1.StatusBar1.simpletext:= 'Liberando a memoria ocupada pelo conjunto resultado ...'; mysql_free_result (recbuf); trymysqlForm1.StatusBar1.simpletext:= 'Fechando a conexao com o MySQL.'; mysql_close (sock); close; end; Executar o Projeto 1. 2. Salvar e executar o projeto. Testar diferentes comandos MySQL. select * from FPdev; insert into FPdev (id, UserName, InstEmail) values ("9", "Edmundo A. De Souza "edmundo@land.ufrj.br"); update FPdev set InstEmail = 'edmundo@cos.ufrj.br' where id = "9"; delete from FPdev where id = "9"; 3. Explicar cada linha de cdigo do projeto acima.

Tarefa Acrescentar: 1. 2. 3. Permitir a seleo do banco de dados a ser manipulado. Permitir a execuo do comando Show tables; (formatao adequada das strings). Escrever cdigo para montar as consultas baseadas nos campos do banco de dados, sem a necessidade do usurio conhecer a sintaxe dos comandos MySQL (uma caixa de dados para cada campo).

Silva",

Pgina 5 de 5

Anda mungkin juga menyukai