6
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 programação para executar funções simples de acesso e consulta. 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 básicos do Lazarus. Desenvolver o Projeto Primeira Fase – Linha de Comando 1. Crie um banco de dados MySQL, a partir de um shell unix. Não esqueça que o mysql server deve estar rodando: /etc/rc.d/init.d/mysqld start (como root) Agora, acesse o servidor (o root do mysql não é 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', '[email protected]'); insert into FPdev values ('2','Florian Klaempfl', '[email protected]'); insert into FPdev values ('3','Carl-Eric Codere', '[email protected]'); insert into FPdev values ('4','Dani Mantione', '[email protected]'); insert into FPdev values ('5','Pierre Muller', '[email protected] strasbg.fr'); insert into FPdev values ('6','Jonas Maebe', '[email protected]'); insert into FPdev values ('7','Peter Vreman', '[email protected]'); insert into FPdev values ('8','Gerry Dubois', '[email protected]'); EOF # Em bash, o valor de retorno de um programa é armazenado # numa variável chamada $? 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; Página 1 de 6

Mysql Demo

Embed Size (px)

Citation preview

Page 1: Mysql Demo

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 programação para executar funções simples de acesso e consulta.

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 básicos do Lazarus.

Desenvolver o Projeto

Primeira Fase – Linha de Comando

1. Crie um banco de dados MySQL, a partir de um shell unix. Não esqueça que o mysql server deve estar rodando:

/etc/rc.d/init.d/mysqld start (como root)Agora, acesse o servidor (o root do mysql não é 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', '[email protected]');insert into FPdev values ('2','Florian Klaempfl', '[email protected]');insert into FPdev values ('3','Carl-Eric Codere', '[email protected]');insert into FPdev values ('4','Dani Mantione', '[email protected]');insert into FPdev values ('5','Pierre Muller', '[email protected]');insert into FPdev values ('6','Jonas Maebe',

'[email protected]');insert into FPdev values ('7','Peter Vreman', '[email protected]');insert into FPdev values ('8','Gerry Dubois', '[email protected]');EOF# Em bash, o valor de retorno de um programa é armazenado# numa variável chamada $?

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 Espaço ...'); 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,'Não foi possível 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,'Não foi possível 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 ');

Página 1 de 5

Page 2: Mysql Demo

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 ('Número de registros retornados: ',mysql_num_rows (recbuf)); Writeln ('Número 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 memória alocada pelo conjunto resultado ...'); mysql_free_result (recbuf);

Writeln ('Fechando a conexão 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 : 3306Mysql_unix_port : /var/lib/mysql/mysql.sockHost info : Localhost via UNIX socketServer info : Uptime: 1341559 Threads: 1 Questions: 122 Slow queries: 0 Opens: 2 Flush tables: 5 Open tables: 1 Queries per second avg: 0.000Client info : 4.1.14Selecting Database testdb...Executing query : Select * from FPdev...Number of records returned : 8Number of fields per record : 3(Id: 1, Name: Michael Van Canneyt, Email : [email protected])(Id: 2, Name: Florian Klaempfl, Email : [email protected])(Id: 3, Name: Carl-Eric Codere, Email : [email protected])(Id: 4, Name: Daniel Mantione, Email : [email protected])(Id: 5, Name: Pierre Muller, Email : [email protected])(Id: 6, Name: Jonas Maebe, Email : [email protected])(Id: 7, Name: Peter Vreman, Email : [email protected])(Id: 8, Name: Gerry Dubois, Email : [email protected])Freeing memory occupied by result set...Closing connection with MySQL.

5. Lista das 11 funções do MySQL utilizadas (declaradas em C):

1) MYSQL *mysql_init (MYSQL *mysql)

Aloca ou inicia um objeto MYSQL adequado à chamada da função mysql_real_connect().

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

const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)

Tenta estabelecer uma conexão com um banco de dados MySQL rodando em host. Esta função deve ser completada sem erro antes que se possa executar qualquer outra chamada de função da API. Retorna um ponteiro (*MYSQL) para o handle da conexão 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 não nula query. A consulta deve consistir de um único comando SQL. Não deve ser adicionado um terminador “;” ou \g ao comando.

mysql_query() não pode ser usada para consultas que contenham dados binários; neste caso, deve ser usada mysql_real_query() . (Dados binários 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.

4) MYSQL_ROW mysql_fetch_row (MYSQL_RES *result)

Retorna a próxima linha de um conjunto resultado ou NULL, se não 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 memória alocada pelo conjunto resultado das funções 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 conexão especificada por mysql. Em consultas subseqüentes, este banco de dados é o default em todas as referências a tabelas que não incluam um especificador explicito.

8) unsigned long mysql_num_rows ( MYSQL_RES *result)

Retorna o número de linhas (registros) de um conjunto resultado

9) unsigned int mysql_num_fields ( MYSQL_RES *result)

Retorna o número de colunas (campos) de um conjunto resultado.

Página 2 de 5

Page 3: Mysql Demo

Delphi – Lazarus (linux) : MySQL

10) const char *mysql_error (MYSQL *mysql)

Para a conexão especificada por mysql, retorna uma string terminada por NULL, contendo a mensagem de erro para a função da API invocada mais recentemente que falhou.

11) void mysql_close(MYSQL *mysql)

Fecha uma conexão que foi aberta previamente, e desaloca o handle de conexão apontado por mysql, se este foi alocado automaticamente por mysql_init() ou mysql_connect().

Segunda Fase – Interface Gráfica

1. Crie um novo projeto. Renomeie o formulário para TryMYSQL e adicione três EditBox: Host (HostLabel e HostEdit). Username (UserLabel e UserEdit). Password (PasswdLabel e PasswdEdit).

2. 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 não apareçam na tela, e apenas seja ecoado uma série de *. Certifique-se de que a propriedade Text de cada EditBox esteja em branco.

3. Coloque um outro EditBox e Label no topo do lado direito do formulário. Mude o label para 'Enter SQL Command' e chame-o de CommandEdit.

4. Coloque três Botões no formulário: altere a propriedade Text para 'Connect to Database' (ConnectButton), 'Exit' (ExitButton) e 'Send Query' (QueryButton).

5. Adicione um MemoBox com Text 'Results' (ResultMemo). Encontre a propriedade ScrollBars e selecione ssAutoBoth, para que os scroll bars apareçam automaticamente se o texto ocupar todo o espaço. Torne verdadeira a propriedade WordWrap.

6. Adicione um StatusBar (a partir do Common Controls tab) e mude a propriedade SimpleText para 'TryMySQL'.

7. Declare as seguintes variáveis na seção implementation:

const DataBase : Pchar = 'testdb';

var sock : PMYSQL;

Página 3 de 5

Page 4: Mysql Demo

Delphi – Lazarus (linux) : MySQL

qmysql : TMYSQL; rowbuf : MYSQL_ROW; recbuf : PMYSQL_RES; alloc : PMYSQL;

As respostas do banco de dados são convertidas em strings e exibidas no MemoBox.

procedure showString (S: string);// exibe uma string em um MemoBoxbegin trymysqlForm1.ResultsMemo.Lines.Add (S)end;

O evento do botão de conexão fica então:

procedure TtrymysqlForm1.ConnectButtonClick(Sender: TObject);// Conecta ao MySQL usando dados fornecidos nas caixas de// entrada de texto do formulário principal (Main Form).var strg: string; dummy1, dummy2, dummy3: string; host, user, passwd: Pchar; begin dummy1 := trymysqlForm1.HostEdit.text+#0; host := @dummy1[1]; // endereço do primeiro caracter da string dummy2 := trymysqlForm1.UserEdit.text+#0; user := @dummy2[1]; // endereço do primeiro caracter da string dummy3 := trymysqlForm1.PasswdEdit.text+#0; passwd := @dummy3[1]; // endereço 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);endelsebegin 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);

endend;end; // ConnectButtonClick

O código do evento click do SendQuery é:

Página 4 de 5

Page 5: Mysql Demo

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. Salvar e executar o projeto.

2. Testar diferentes comandos MySQL.

select * from FPdev; insert into FPdev (id, UserName, InstEmail) values

("9", "Edmundo A. De Souza e Silva", "[email protected]"); update FPdev set InstEmail = '[email protected]' where id = "9"; delete from FPdev where id = "9";

3. Explicar cada linha de código do projeto acima.

Tarefa – Acrescentar:

1. Permitir a seleção do banco de dados a ser manipulado.

2. Permitir a execução do comando Show tables; (formatação adequada das strings).

3. Escrever código para montar as consultas baseadas nos campos do banco de dados, sem a necessidade do usuário conhecer a sintaxe dos comandos MySQL (uma caixa de dados para cada campo).

Página 5 de 5