Exemplo de uma aplicação escrita em C++/Qt com ligação a uma base de dados MySQL

bd

Este é o quarto de uma série de exemplos que preparei para demonstrar alguns aspectos relacionados com a ligação a uma base de dados MySQL, utilizando a linguagem C++/Qt.

No fundo limitei-me a criar uma versão mais simplificado do que tinha feito aqui.

Convém lembrar que este exemplo se liga ao “localhost”, à base de dados Qt, com o utilizador “qtuser” que utiliza a palavra passe “123″.

Se estas condições não forem satisfeitas, o primeiro semáforo(base de dados) nunca ficará verde.

O melhor é experimentarem que a “malta” dá as dicas que faltarem.

O código pode ser obtido aqui.

#7 Utilização elementar dos comandos MySQL do subconjunto DML

Nos pontos #1 a #6 falei sobre:

  • instalar um servidor/cliente MySQL;
  • criar uma base de dados;
  • criar utilizadores;
  • definir privilégios de acesso para os utilizadores;
  • criar tabelas

Se não se acreditarem basta carregar no golfinho para rever.

Mas de que serve tudo isto se eu não conseguir escrever /alterar/eliminar informação acerca de Jogadores e Equipas na minha base de dados?!

Por esta razão vou registar aqui uma versão reduzida do subconjunto DML ( Data Manipulation Language), cujos principais comandos são:

# SELECT

Permite obter dados a partir das tabelas.

Como neste momento as nossas tabelas ainda estão vazias o resultado é pouco esclarecedor, pelo que vamos reutilizar estes comandos mais para a frente.

mysql> SELECT * FROM Equipa;
Empty set (0.00 sec)

mysql> SELECT * FROM Jogador;
Empty set (0.00 sec)

# INSERT

Permite inserir os dados nas tabelas.

Vamos então inserir alguns dados relativos a equipas e jogadores.

mysql> DESCRIBE Equipa;
+-------------+-------------+------+-----+---------+-------+
| Field       | Type        | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| id          | tinyint(3)  | NO   | PRI | NULL    |       |
| nome        | varchar(15) | NO   |     | NULL    |       |
| nrsocios    | int(7)      | NO   |     | NULL    |       |
| campeonatos | tinyint(2)  | YES  |     | NULL    |       |
+-------------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

mysql> INSERT INTO Equipa(id, nome, nrsocios, campeonatos)
 -> VALUES(1, "SCP", 1000000, 45);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO Equipa VALUES(2, "FCP", 900000, 1);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO Equipa(id, nome, nrsocios)
 -> VALUES(3, "SLB", 12);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO Equipa(id, nome, nrsocios) VALUES(3, "ERRO", 0);
ERROR 1062 (23000): Duplicate entry '3' for key 1
mysql> SELECT * FROM Equipa;
+----+------+----------+-------------+
| id | nome | nrsocios | campeonatos |
+----+------+----------+-------------+
|  1 | SCP  |  1000000 |          45 |
|  2 | FCP  |   900000 |           1 |
|  3 | SLB  |       12 |        NULL |
+----+------+----------+-------------+
3 rows in set (0.00 sec)

# UPDATE

Permite alterar os dados previamente inseridos.

Vamos realizar algumas alterações aleatórias muito elementares.

mysql> UPDATE Equipa
 -> SET campeonatos = 1
 -> WHERE nome = 'SCP';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM Equipa;
+----+------+----------+-------------+
| id | nome | nrsocios | campeonatos |
+----+------+----------+-------------+
|  1 | SCP  |  1000000 |           1 |
|  2 | FCP  |   900000 |           0 |
|  3 | SLB  |       12 |           0 |
+----+------+----------+-------------+
3 rows in set (0.00 sec)

x

# DELETE

Permite eliminar linhas/registos de uma tabela que foram previamente inseridos.

Partindo do princípio que duas das rquipas deveriam ser erradicadas do nosso campeonato,  vamos realizar algumas alterações aleatórias muito elementares.

mysql> DELETE FROM Equipa
 -> WHERE nome <> 'SCP';
Query OK, 2 rows affected (0.00 sec)

mysql> SELECT * FROM Equipa;
+----+------+----------+-------------+
| id | nome | nrsocios | campeonatos |
+----+------+----------+-------------+
|  1 | SCP  |  1000000 |           1 |
+----+------+----------+-------------+
1 row in set (0.00 sec)

E que fique claro … NÃO SOU SPORTINGUISTA … sou futebolisticamente “ateu“.

principal100

Publicado em MySQL. Leave a Comment »

Como criar um Splash Screen para uma aplicação em Qt

f0

Um splashscreen é um elemento gráfico que é exibido quando uma aplicação é iniciada.
Estes podem ser utilizados por razões puramente “estéticas” mas tornam-se particularmente úteis quando a aplicação demora algum tempo a carregar. Nestas situações é possível ir fornecendo alguma informação ao utilizador, de forma a que este saiba que a aplicação está a ser carregada.
O ponto de partida para criarmos o nosso splashscreen em Qt deverá naturalmente ser a classe que possibilita a sua criação, ou seja, QSplashScreen.

De seguida, e  como um exemplo ajuda sempre, vou disponibilizar as experiências que realizei:

#1 – O básico

Surge o splashcreen enquanto a janela principal é carregada. Neste caso é tudo muito rápido pois a aplicação exemplo é minúscula.

Exemplo:

#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QSplashScreen>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QPixmap pixmap("f0.png");
    QSplashScreen splash;
    splash.setPixmap(pixmap);
    splash.show();
    MainWindow w;
    w.show();
    splash.finish(&w);
    return a.exec();
}

Download

#2 – Garantir que o splashscreen “sobrevive” por 5 segundos, enquanto exibo uma mensagem

Exemplo:

#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QSplashScreen>
#include <QTimer>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QPixmap pixmap("f0.png");
    QSplashScreen splash;
    splash.setPixmap(QPixmap("f0.png"));
    splash.show();
    splash.showMessage(QObject::trUtf8("A preparar a janela principal ..."), Qt::AlignRight|Qt::AlignTop, Qt::black);
    MainWindow w;
    QTimer::singleShot(5000, &splash, SLOT(close()));
    QTimer::singleShot(5000, &w, SLOT(show()));
    return a.exec();
}

Download

#3 – Tenho várias tarefas para executar, e quero ir mantendo o utilizador informado. Entretanto vou mostrando imagens diferentes.

Exemplo:

void operacao_03();

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QSplashScreen *splash = new QSplashScreen;
    splash->setPixmap(QPixmap(":/splash/f2"));
    splash->show();
    splash->showMessage(QObject::trUtf8("A executar a operação 01 ..."), Qt::AlignRight|Qt::AlignTop, Qt::black);
    operacao_01();
    splash->setPixmap(QPixmap(":/splash/f1"));
    splash->showMessage(QObject::trUtf8("A executar a operação 02 ..."), Qt::AlignRight|Qt::AlignBottom, Qt::black);
    operacao_02();
    splash->setPixmap(QPixmap(":/splash/f0"));
    splash->showMessage(QObject::trUtf8("A executar a operação 03 ..."), Qt::AlignRight|Qt::AlignTop, Qt::black);
    operacao_03();

    MainWindow w;
    w.show();
    splash->finish(&w);
    delete splash;
    return a.exec();
}

void operacao_01(){
    sleep(2);
}

void operacao_02(){
    sleep(2);
}

void operacao_03(){
    sleep(2);
}

Download

#6 Criar tabelas

Note que todas as operações foram realizadas como root.

A partir de agora deverá iniciar uma sessão com o utilizador “psi”, com o qual pode fazer “tudo o que lhe passar pela cabeça”, pois as alterações apenas irão incidir sobre a base de dados “exemplo”.

A sequência seguinte demonstra como podemos:

  1. criar a tabela Equipa (id, nome, nrsocios, campeonatos);
  2. criar a tabela Jogador (numero, nome, posicao, idade, equipa);
  3. criar a tabela Lixo (atributo1, atributo2, atributo3);
  4. visualizar estrutura da tabela “Lixo”;
  5. eliminar o “atributo3” da tabela “Lixo”;
  6. adicionar o “atributo4” à tabela “Lixo”;
  7. eliminar a tabela “Lixo”.
mysql> CREATE TABLE Equipa
 -> (
 -> id TINYINT(3) PRIMARY KEY,
 -> nome VARCHAR(15) NOT NULL,
 -> nrsocios INT(7) NOT NULL,
 -> campeonatos TINYINT(2)
 -> );
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE Jogador
 -> (
 -> nrid INT(8) PRIMARY KEY,
 -> nrcamisola TINYINT(2),
 -> nome varchar(30) NOT NULL,
 -> posicao VARCHAR(10) NOT NULL,
 -> idade TINYINT(2),
 -> equipa TINYINT(3) NOT NULL
 -> );
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE Lixo
 -> (
 -> atributo1 INT(8) PRIMARY KEY,
 -> atributo2 TINYINT(2),
 -> atributo3 varchar(30) NOT NULL
 -> );
Query OK, 0 rows affected (0.00 sec)

mysql> DESCRIBE Lixo;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| atributo1 | int(8)      | NO   | PRI | NULL    |       |
| atributo2 | tinyint(2)  | YES  |     | NULL    |       |
| atributo3 | varchar(30) | NO   |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> ALTER TABLE Lixo DROP COLUMN Atributo3;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> DESCRIBE Lixo;
+-----------+------------+------+-----+---------+-------+
| Field     | Type       | Null | Key | Default | Extra |
+-----------+------------+------+-----+---------+-------+
| atributo1 | int(8)     | NO   | PRI | NULL    |       |
| atributo2 | tinyint(2) | YES  |     | NULL    |       |
+-----------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> ALTER TABLE Lixo ADD COLUMN Atributo4 int(4);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> DESCRIBE Lixo;
+-----------+------------+------+-----+---------+-------+
| Field     | Type       | Null | Key | Default | Extra |
+-----------+------------+------+-----+---------+-------+
| atributo1 | int(8)     | NO   | PRI | NULL    |       |
| atributo2 | tinyint(2) | YES  |     | NULL    |       |
| Atributo4 | int(4)     | YES  |     | NULL    |       |
+-----------+------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> DROP TABLE Lixo;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW TABLES;
+-------------------+
| Tables_in_Exemplo |
+-------------------+
| Equipa            |
| Jogador           |
+-------------------+
2 rows in set (0.00 sec)

Saber mais:

http://dev.mysql.com/doc/refman/5.0/en/create-table.html

http://dev.mysql.com/doc/refman/5.0/en/getting-information.html

http://dev.mysql.com/doc/refman/5.0/en/alter-table.html

http://dev.mysql.com/doc/refman/5.0/en/drop-table.html

principal100

Publicado em MySQL. Leave a Comment »

MySQL – Instalação e preparação da Base de dados num sistema Debian

Imagine que é um utilizador de Debian GNU/Linux e está prestes a iniciar-se no estudo das bases de dados MySQL!
Como aluno aplicado que com certeza é, vai ter todo o interesse em poder realizar todos os exercícios também na sua máquina pessoal.
Neste artigo vou tentar resumir os aspectos mais práticos no que diz respeito à instalação e utilização de uma base de dados MySQL num sistema Debian GNU/Linux.
Não vou estar com preocupações de segurança nem performance da base de dados, focando-me apenas nos aspectos que permitem obter resultados rápidos e deixando o aprofundamento dos conteúdos abordados para uma fase posterior.
Pretendo apresentar um exemplo que abrange desde a instalação do servidor até à criação de uma Base de Dados Relacional muito simples, preocupando-me apenas com a utilização dos subconjuntos da linguagem SQL de Linguagem de definição de dados (LDD ou DDL, do Inglês Data Definition Language) e de Linguagem de Controle de Dados (LCD ou DCL do inglês Data Control Language).

No caso prático em estudo vamos falar de futebol, e o modelo correspondente é o seguinte:

diagrama1
Os atributos associados às duas entidades são os seguintes:

Equipa (id, nome, nrsocios, campeonatos)
Jogador (numero, nome, posicao, idade, equipa)

Para evitar que este artigo fique demasiado longo vou utilizar uma estratégia semelhante à que usei aqui.
Os vários passos a seguir são apresentados aqui, na forma de uma hiperligação para um subartigo que cobre apenas essa tarefa específica, nos quais terei o cuidado de deixar alguns links para páginas com informação mais detalhada.

#1 Instalação do servidor e cliente de MySQL
#2 Iniciar uma sessão em modo interactivo
#3 Criar utilizadores
#4 Criar/Eliminar uma base de dados
#5 Definir os privilégios de acesso dos utilizadores às bases de dados
#6 Criar tabelas

#7 Utilização elementar dos comandos MySQL do subconjunto DML

Publicado em MySQL. Leave a Comment »

#5 Definir os privilégios de acesso dos utilizadores às bases de dados

Por esta altura já temos a base de dados “exemplo” e o utilizador ”psi” criados.
Para que o utilizador “psi” possa utilizar a base de dados “exemplo” é necessário atribuir-lhe privilégios de acesso.
A sequência seguinte demonstra como podemos:

  1. verificar a existência da base de dados “exemplo”;
  2. verificar a existência do utilizador ‘psi’ e respectivos privilégios;
  3. atribuir ao utilizador “psi” privilégios totais sobre a base de dados “exemplo”;
  4. verificar os novos privilégios do utilizador;
  5. remover os privilégios do utilizador ‘psi’;
  6. verificar se tudo voltou à situação inicial.
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| exemplo            |
| mysql              |
+--------------------+
3 rows in set (0.00 sec)

mysql> SHOW GRANTS FOR 'psi';
+----------------------------------------------------------------------------------------------------+
| Grants for psi@%                                                                                   |
+----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'psi'@'%' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' |
+----------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON exemplo.* TO 'psi'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GRANTS FOR 'psi';
+----------------------------------------------------------------------------------------------------+
| Grants for psi@%                                                                                   |
+----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'psi'@'%' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' |
| GRANT ALL PRIVILEGES ON `exemplo`.* TO 'psi'@'%'                                                   |
+----------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> REVOKE ALL ON exemplo.* FROM 'psi'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GRANTS FOR 'psi';
+----------------------------------------------------------------------------------------------------+
| Grants for psi@%                                                                                   |
+----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'psi'@'%' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' |
+----------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

Nota: Após a utilização de GRANT ou REVOKE é necessário executar o seguinte comando de forma a que as alterações tenham efeito:

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Saber mais em:

http://dev.mysql.com/doc/refman/5.1/en/grant.html
http://dev.mysql.com/doc/refman/5.0/en/revoke.html

principal100

Publicado em MySQL. Leave a Comment »

#4 Criar/Eliminar uma base de dados

A criação de uma base de dados, na sua forma mais simples, passa pela execução de um comando muito simples:

mysql> CREATE DATABASE nome_bd;

Eliminar uma base de dados é igualmente simples, bastando executar:

mysql> DROP DATABASE nome_bd;

Nas linhas seguintes está representada uma sessão em que são realizadas três operações:

  1. é criada uma base de dados com o comando CREATE DATABASE exemplo;
  2. são visualizadas as bases de dados existentes com o comando SHOW DATABASES;
  3. é eliminada a base de dados com o comando DROP DATABASE exemplo;
  4. verificar se a base de dados foi eliminada.
mysql> CREATE DATABASE IF NOT EXISTS exemplo;
Query OK, 1 row affected (0.00 sec)

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| exemplo            |
| mysql              |
+--------------------+
3 rows in set (0.00 sec)

mysql> DROP DATABASE exemplo;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
+--------------------+
2 rows in set (0.00 sec)

Saber mais em:
http://dev.mysql.com/doc/refman/5.0/en/create-database.html
http://dev.mysql.com/doc/refman/5.0/en/drop-database.html

principal100
Publicado em MySQL. Leave a Comment »

#3 Criar utilizadores

Uma vez que é necessário garantir o controlo do acesso à base de dados, temos que proceder à criação de utilizadores, ao quais se associam posteriormente determinados privilégios de acesso.
Vamos apenas criar o utilizador e posteriormente, noutro tópico, associar-lhe alguns privilégios de acesso.
O nosso utilizador irá ter a designação “psi” e palavra-passe “123”.

A seguinte sequência de comandos permite:
1.criar o utilizador ‘psi’ que pode aceder ao servidor a partir de qualquer host (‘%’);
2.verificar que este utilizador não possui quaisquer privilégios ( USAGE );
3.eliminar o utilizador.

gt2009@debian:~$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 57
Server version: 5.0.51a-24+lenny2 (Debian)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> CREATE USER 'psi'@'%' IDENTIFIED BY '123';
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GRANTS FOR 'psi';
+----------------------------------------------------------------------------------------------------+
| Grants for psi@%                                                                                   |
+----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'psi'@'%' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257'|
+----------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> DROP USER 'psi';
Query OK, 0 rows affected (0.00 sec)

Saber mais em: http://dev.mysql.com/doc/refman/5.0/en/adding-users.html http://dev.mysql.com/doc/refman/5.0/en/show-grants.html http://dev.mysql.com/doc/refman/5.0/en/drop-user.html

Nota:Embora nesta fase não deseje ainda falar do comando SELECT, deixo aqui uma forma muito simples para se obter uma listagem dos utilizadores existentes.

mysql> SELECT user FROM mysql.user;
+------------------+
| user             |
+------------------+
| lixo             |
| lixo33           |
| psi              |
| user01           |
| user02           |
| user03           |
| root             |
| root             |
| debian-sys-maint |
| monty            |
| root             |
+------------------+
11 rows in set (0.00 sec)

principal100

Publicado em MySQL. Leave a Comment »

#2 Iniciar uma sessão em modo interactivo

1

Nesta fase já temos um SGBD mas ainda “sem” informação relevante. Para aceitar esta afirmação é necessário abstrair-se de alguma informação já existente, tal como é mostrado na figura.

O formato genérico para se iniciar a sessão segue a sintaxe seguinte:

mysql (opções) [nome_da_base_de_dados]

Nota:  (opções) é obrigatório e [nome_da_base_de_dados] é opcional.

Na prática basta algo do tipo:

#mysql -u root -p

Será pedida a palavra-passe do administrador e, caso tudo corra bem, estaremos perante a linha de comandos do programa mysql ( mysql>      ).

De seguida iremos digitar várias linhas de comandos de forma a realizarmos as tarefas pretendidas, uma vez que agora estamos em comunicação directa com o servidor.

Nesta fase convém ter presente que uma instrução SQL pode ocupar várias linhas, pelo que o fim da linha é assinalado de forma especial por (;) ou ( \g ), tal como exemplificado a seguir.

Formas de terminar uma instrução SQL :

select version();
select now();
select version()\g
select now()\g
select version()    ERRO!


No final, naturalmente que iremos desejar terminar a sessão, pelo que devemos executar o comando seguinte:

mysql> quit

A imagem utilizada mostra uma sequência muito simples que exemplifica o que aqui foi dito, sendo o comando showdatabases; meramente ilustrativo.

Quanto às várias opções do programa MySQL vou limitar-me apenas a referir um link para consulta:

http://dev.mysql.com/doc/refman/5.0/en/mysql-command-options.html

principal100

Publicado em MySQL. Leave a Comment »

#1 Instalação do servidor e cliente de MySQL

Partindo do princípio de que vamos fazer tudo na nossa máquina, teremos que instalar o servidor e um cliente de MySQL.
Para tal, basta executar como root o comando:

# apt-get install mysql-server mysql-client

Durante este processo vamos ter que definir uma palavra-passe de root para o MySQL mas, ATENÇÃO! Este root não tem nada a ver com o administrador de um sistema Linux, mas apenas com a administração do servidor MySQL.

principal100