Hoje vamos ver como inserir valores no banco de dados.
Primeiro, devemos entender como o processo de inserção será feito pelo programa:
Existem dois campos do tipo wxTextCtrl no wxFrame que controla a aplicação, nós pegaremos os valores dessas caixas de texto, veremos primeiro se o nome está em branco e se a idade realmente é um número, se as duas afirmações forem verdadeiras executamos a função que insere os valores no banco de dados, se não, cancelamos a função e avisamos o usuário que os dados estão incompletos ou errados.
Mas vamos lembrar uma coisa, quando clicamos no botão salvar, podemos ter uma ação de inserção ou de edição, para isto, temos a variável de controle chamada ID, que criamos no frame principal, veja que ela inicia com o valor -1, então, sempre que tivermos este valor, a ação será de inserção.
Vamos lembrar como ficaria o código SQL para inserirmos um valor na nossa tabela contatos:
INSERT INTO contatos(ID, NOME, IDADE) VALUES(NULL, 'NOME DO CONTATO', 1);
Vejam que uso apóstrofo entre valores do tipo VARCHAR, e passamos o ID que é chave primária como NULL.
O nome do contato, será o valor que foi digitado na caixa de texto Nome e sua idade será o valor que está na caixa de texto Idade.
Para fazer esta inserção vamos criar uma função que vai pegar estes dois valores e verificar se estão corretos e fazer a inserção, ficará assim:
Em sqlf.h digite:
sqlf.h
//Aqui escrevo uma função que vai receber o nome e a idade como parametros... void InsertInDB(wxString nome, wxString idade);
Agora vamos implementá-la em sqlf.cpp, digite:
sqlf.cpp
//Vamos Implementá-la void InsertInDB(wxString nome, wxString idade) { //Primeiro vejo se o nome ou idade estão em branco if(nome.IsEmpty() || idade.IsEmpty()) { //Aviso ao usuário que algum dado está em branco: wxMessageBox(wxT("Nenhum campo pode estar em branco!")); //Cancelo a função... return; } //Agora preciso ver se a idade é um número... //Crio um long int long int confere_idade; //Tento converter a string idade em um número... if(!idade.ToLong(&confere_idade)) { //Se não conseguir, significa que ele não é um inteiro... //Aviso o usuário... wxMessageBox(wxT("O valor da idade (") + idade + wxT(") não é um número")); //Cancelo a função... return; } //Se chegamos até aqui, é porque tudo está correto... //Vamos abrir o banco de dados: wxSQLite3Database *db = OpenDB(GetExecPath() + wxT("/agenda.db3")); //Agora vamos montar o sql para inserir os dados... wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES(NULL, '"); SQL += nome + wxT("', "); SQL += idade + wxT(");"); //Reparem que adiciono os apóstrofos apenas nos campos VARCHAR... //Tenham muito cuidado quando montarem comandos SQL, para não adicionarem //valores incorretos, como virgulas após o ultimo campo //esquecerem-se de fechar parenteses, etc... //uma maneira simples é fazer o seguinte... //Escreva o comando todo SQL... //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, 'NOME', IDADE);"); //Agora adicione as variáveis no lugar dos valores com os sinais de concatenação: //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, ' + nome + ', + idade + );"); //Antes de cada + à esquerda da variável adicione ") e depois de cada + à direita da variável adicione wxT(" //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, '") + nome + wxT("',") + idade + (");"); //Agora executo a função ExecuteUpdate, que vimos no tutorial anterior, passando como //parâmetro a wxString SQL... db->ExecuteUpdate(SQL); //Fecho db... CloseDB(db); }
E pra finalizarmos, vamos chamar esta função no evento OnClickSalvar() do frame principal:
Veja que já adicionei a estrutura condicional para sabermos se está em edição ou inserção:
Em framep.cpp digite:
framep.cpp
//Aqui eu inicio a implementação do evento para salvar ou editar um registro... void wxFramePrincipal::OnClickSalvar(wxCommandEvent& event) { //Vamos, primeiro, verificar qual operação será feita //Inserção ou Edição if(ID == -1) { //Se a variável ID for = -1, é porque estamos em inserção... //Vamos pegar os valores do campo nome... wxString get_nome = nome->GetValue(); //...agora pegamos a idade... wxString get_idade = idade->GetValue(); //E passamos as duas como parâmetros para a função InsertInDB()... InsertInDB(get_nome, get_idade); } else { } }
Vamos testar a função, abrindo o terminal ou o prompt de comando do Windows:
Abra o banco de dados com o comando:
Agora abra o sistema e adicione alguns valores, veja que após inserirmos os valores, os campos continuam preenchidos, iremos alterar isto nos próximos tutoriais.
Agora volte para o terminal e faça uma seleção na tabela contatos:
Vejam que os registros já estão lá.
Dúvidas, deixem nos comentários.
Os arquivos alterados completos:
sqlf.h
Os arquivos alterados completos:
sqlf.h
//ARQUIVO DO BLOG - http://wxnewbie.blogspot.com //TUTORIAL wxWidgets + sqlite3 usando wxSqlite3 #ifndef SQLF_H_INCLUDED #define SQLF_H_INCLUDED #include <wx/wx.h> #include <wx/wxsqlite3.h> #include <wx/stdpaths.h> wxString GetExecPath(); //Nesta primeira função, iremos abrir um banco de dados indicado pelo //parâmetro caminho e retornar um ponteiro para wxSQLite3Database... //Se o banco de dados não existir, será criado um... wxSQLite3Database *OpenDB(wxString caminho); //Aqui iremos apenas fechar o mesmo... //Isto é necessário, pois liberaremos o arquivo para novos acessos... void CloseDB(wxSQLite3Database* db); //Esta função será usada para criar o nosso banco de dados //e também para criar a tabela contatos. //Ela será executada apenas uma vez... void CreateDBAgenda(); //Aqui escrevo uma função que vai receber o nome e a idade como parametros... void InsertInDB(wxString nome, wxString idade); #endif // SQLF_H_INCLUDED
sqlf.cpp
framep.cpp
//ARQUIVO DO BLOG - http://wxnewbie.blogspot.com //TUTORIAL wxWidgets + sqlite3 usando wxSqlite3 #include "sqlf.h" //Função para pegar o diretório da aplicação, já explicada no blog... wxString GetExecPath() { wxString retorno; retorno = wxStandardPaths::Get().GetExecutablePath(); retorno = wxPathOnly(retorno); return retorno; } //Vamos implementar nossa função OpenDB... wxSQLite3Database *OpenDB(wxString caminho) { //Aqui eu crio um ponteiro para um wxSQLite3Database chamado db... //É ele que nós retornaremos na função... wxSQLite3Database *db = new wxSQLite3Database(); //Aqui uso a função Open, passando como parâmetro o caminho para o banco de dados... //O interessante aqui é vermos que se existir um banco de dados neste lugar a função //irá abrir o mesmo, se não existir o banco de dados será criado... db->Open(caminho); //Vocês poderão ter um problema ao executar esta função, dizendo que Open possui mais de //um parâmetro, se isto acontecer, basta usá-la desta maneira: //db->Open(caminho, wxEmptyString); //O segundo parametro seria a senha para o banco de dados, //se estivessemos usando criptografia no mesmo... //retornamos o db... return db; } //Aqui vamos fechar a "conexão" com o banco de dados... void CloseDB(wxSQLite3Database* db) { //Vemos se db é verdadeiro... assert(db != NULL); //Fechamos db com o comando Close(); db->Close(); //Deletamos db da memória... delete db; } void CreateDBAgenda() { //Primeiro, vamos pegar o diretório da aplicação mais o nome do banco de dados... wxString conf_path = GetExecPath() + wxT("/agenda.db3"); //Agora vamos verificar se o arquivo já existe... //Se existir, paro a execução da função... if(wxFileExists(conf_path)) { return; } //Se ele não existir crio um wxSQLite3Database com este caminho... wxSQLite3Database *db = OpenDB(conf_path); //Ok, agora criamos um sql com o comando de criação da nossa tabela //CREATE TABLE contatos( //ID INTEGER PRIMARY KEY, //NOME VARCHAR(50), //IDADE INTEGER //); //Vamos adicionar isto em uma wxString wxString SQL = wxT("CREATE TABLE contatos(\n"); SQL += wxT("ID INTEGER PRIMARY KEY,\n"); SQL += wxT("NOME VARCHAR(50),\n"); SQL += wxT("IDADE INTEGER\n"); SQL += wxT(");"); //Agora vamos usar ExecuteUpdate para executar este SQL... //Usamos ExecuteUpdate para criarmos tabelas, views, triggers... //Inserir registros no banco de dados... //Editar registros no banco de dados... //Excluir registros no banco de dados... //Não use ExecuteUpdate para seleções... db->ExecuteUpdate(SQL); //Fechamos a conexão com o banco de dados... CloseDB(db); } //Vamos Implementá-la void InsertInDB(wxString nome, wxString idade) { //Primeiro vejo se o nome ou idade estão em branco if(nome.IsEmpty() || idade.IsEmpty()) { //Aviso ao usuário que algum dado está em branco: wxMessageBox(wxT("Nenhum campo pode estar em branco!")); //Cancelo a função... return; } //Agora preciso ver se a idade é um número... //Crio um long int long int confere_idade; //Tento converter a string idade em um número... if(!idade.ToLong(&confere_idade)) { //Se não conseguir, significa que ele não é um inteiro... //Aviso o usuário... wxMessageBox(wxT("O valor da idade (") + idade + wxT(") não é um número")); //Cancelo a função... return; } //Se chegamos até aqui, é porque tudo está correto... //Vamos abrir o banco de dados: wxSQLite3Database *db = OpenDB(GetExecPath() + wxT("/agenda.db3")); //Agora vamos montar o sql para inserir os dados... wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES(NULL, '"); SQL += nome + wxT("', "); SQL += idade + wxT(");"); //Reparem que adiciono os apóstrofos apenas nos campos VARCHAR... //Tenham muito cuidado quando montarem comandos SQL, para não adicionarem //valores incorretos, como virgulas após o ultimo campo //esquecerem-se de fechar parenteses, etc... //uma maneira simples é fazer o seguinte... //Escreva o comando todo SQL... //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, 'NOME', IDADE);"); //Agora adicione as variáveis no lugar dos valores com os sinais de concatenação: //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, ' + nome + ', + idade + );"); //Antes de cada + à esquerda da variável adicione ") e depois de cada + à direita da variável adicione wxT(" //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, '") + nome + wxT("',") + idade + (");"); //Agora executo a função ExecuteUpdate, que vimos no tutorial anterior, passando como //parâmetro a wxString SQL... db->ExecuteUpdate(SQL); //Fecho db... CloseDB(db); }
framep.cpp
//ARQUIVO DO BLOG - http://wxnewbie.blogspot.com //TUTORIAL wxWidgets + sqlite3 usando wxSqlite3 #include "framep.h" #include "sqlf.h" wxFramePrincipal::wxFramePrincipal():wxFrame(NULL, wxID_ANY, wxT("Teste Tutorial Sqlite3")) { //Altero a cor do background do Frame this->SetBackgroundColour(*wxWHITE); //Meu BoxSizer Principal... wxBoxSizer *boxp = new wxBoxSizer(wxVERTICAL); //Inicio a construção do grid... lista_contatos = new wxGrid(this, ID_GRID); //Começo com 0 linhas e 3 colunas, lembre-se que o número de colunas deve ser igual ao numero de campos //Da view que iremos carregar ou do comando select que iremos carregar... lista_contatos->CreateGrid(0, 3); //Aqui altero o valor dos rótulos de cada coluna... //Nunca se esqueça, o vetor começa em 0, tanto para colunas como para linhas... lista_contatos->SetColLabelValue(0, wxT("ID")); lista_contatos->SetColLabelValue(1, wxT("Nome")); lista_contatos->SetColLabelValue(2, wxT("Idade")); //Altero a largura padrão do rótulo da linha para 25px... //Altero a altura padrão do rótulo da coluna para 25px... lista_contatos->SetRowLabelSize(25); lista_contatos->SetColLabelSize(25); //Desabilito a edição dos valores no grid, a alteração de valores será feita //pelos wxTextCtrl's lista_contatos->EnableEditing(false); //Adiciono o grid no BoxSizer principal... boxp->Add(lista_contatos, 1, wxEXPAND, 0); //Aqui eu adiciono um separador... boxp->Add(0, 0, 0, wxALL, 10); //Aqui crio um BoxSizer para arranjar os campos de preenchimento de valores... wxBoxSizer *box_texts = new wxBoxSizer(wxVERTICAL); //o rótulo para o campo nome... label_nome = new wxStaticText(this, wxID_ANY, wxT("Nome")); //adiciono o rótulo no box dos valores de preenchimento... box_texts->Add(label_nome, 0, wxALL, 2); //Faço o mesmo que fiz anteriormente para todos os outros campos... nome = new wxTextCtrl(this, wxID_ANY, wxEmptyString ,wxDefaultPosition, wxSize(200, -1)); box_texts->Add(nome, 0, wxALL, 5); label_idade = new wxStaticText(this, wxID_ANY, wxT("Idade")); box_texts->Add(label_idade, 0, wxALL, 2); idade = new wxTextCtrl(this, wxID_ANY, wxEmptyString ,wxDefaultPosition, wxSize(120, -1)); box_texts->Add(idade, 0, wxALL, 5); //Aqui adiciono o box dos campos de preenchimento no box principal... boxp->Add(box_texts, 0, wxLEFT, 40); //Agora um box para arranjar os botões... wxBoxSizer *box_btns = new wxBoxSizer(wxHORIZONTAL); //Um separador... box_btns->Add(0, 0, 0, wxLEFT, 40); //Botão salvar... salvar = new wxButton(this, ID_SALVAR, wxT("Salvar")); //Adiciono ao box dos botões... box_btns->Add(salvar, 0, wxALL, 5); limpar = new wxButton(this, ID_LIMPAR, wxT("Limpar Campos")); box_btns->Add(limpar, 0, wxALL, 5); deletar = new wxButton(this, ID_DELETAR, wxT("Deletar")); box_btns->Add(deletar, 0, wxALL, 5); //Adiciono o box dos botões ao box principal... boxp->Add(box_btns, 1, wxEXPAND, 0); //"Digo" ao meu frame que o boxp é o box principal... this->SetSizer(boxp); //Aqui apenas faço com que tudo seja arranjado de maneira correta... this->Layout(); //Seto o ID como -1 para saber que inicio em modo de inserção... ID = -1; } //Aqui minha tabela de eventos declarada... BEGIN_EVENT_TABLE(wxFramePrincipal, wxFrame) //Veja que digo para cada evento, que o controle que estiver com //determinado id, é o que será responsável por executá-lo //No exemplo de salvar: //Eu digo que é um evento do tipo EVT_BUTTON, ou seja, um evento executado por um botão... //O botão responsável pelo evento é o que tiver o identificador: ID_SALVAR //e o evento que ele vai executar é o OnClickSalvar... //É muito importante o entendimento desta parte para não acontecer nada de errado... EVT_BUTTON(ID_SALVAR, wxFramePrincipal::OnClickSalvar) EVT_BUTTON(ID_LIMPAR, wxFramePrincipal::OnClickLimpar) EVT_BUTTON(ID_DELETAR, wxFramePrincipal::OnClickDeletar) //Quando você for criar um evento para grid's repare que alguns levam um CMD no nome e outros não... //Se você estiver criando uma classe derivada de wxGrid, vc não usa o comando que contém o CMD //Veja que este comando sem CMD como é o caso de EVT_GRID_CELL_LEFT_DCLICK (comando que é executado //quando dou 2 cliques em uma célula) não recebe ID nenhum como parâmetro... //agora se eu for executar o mesmo comando usando um wxGrid como controle no meu frame ou dialogo //eu uso o comando com CMD como é o caso do evento abaixo... EVT_GRID_CMD_CELL_LEFT_DCLICK(ID_GRID, wxFramePrincipal::OnDoubleClickCell) END_EVENT_TABLE() //Aqui eu inicio a implementação do evento para salvar ou editar um registro... void wxFramePrincipal::OnClickSalvar(wxCommandEvent& event) { //Vamos, primeiro, verificar qual operação será feita //Inserção ou Edição if(ID == -1) { //Se a variável ID for = -1, é porque estamos em inserção... //Vamos pegar os valores do campo nome... wxString get_nome = nome->GetValue(); //...agora pegamos a idade... wxString get_idade = idade->GetValue(); //E passamos as duas como parâmetros para a função InsertInDB()... InsertInDB(get_nome, get_idade); } else { } } //Aqui o evento que vai limpar os campos... void wxFramePrincipal::OnClickLimpar(wxCommandEvent& event) { //...Os comandos que usaremos aqui, será escrito depois... } //Aqui o evento quando eu clicar no botão deletar... void wxFramePrincipal::OnClickDeletar(wxCommandEvent& event) { //...Os comandos que usaremos aqui, será escrito depois... } //Aqui o evento que será exxecutado //quando eu der 2 cliques em uma célula... void wxFramePrincipal::OnDoubleClickCell(wxGridEvent& event) { //...Os comandos que usaremos aqui, será escrito depois... } //Esta função eu vou usar para limpar os campos //como eu precisarei fazer isto sempre que eu completar uma alteração //vou escrever este código em uma função em separado... void wxFramePrincipal::LimparCampos() { //...Os comandos que usaremos aqui, será escrito depois... } //Aqui vou conferir os campos para ver se o usuário digitou algo errado... bool wxFramePrincipal::ConfereCampos() { //...Os comandos que usaremos aqui, será escrito depois... return true; }
No próximo tutorial, vamos exibir os valores inseridos no wxGrid.
Até a próxima.
0 comentários:
Postar um comentário