Controle de clientes em SQLITE3

Iniciado por adalberto, Março 06, 2017, 10:09:12 AM

tópico anterior - próximo tópico

adalberto

Venho disponibilizar mais um projeto aberto e exemplo de uso da nova biblioteca psqlite3 feito em Prisma. Gostaria que esse simples programa se tornasse um projeto comunitário. Quem sabe ele evolua para um sistema completo em que todos os usuários Prisma possam usar livremente para adaptar em seus próprios programas comerciais.

Necessário Prisma-1.0.99 ou superior. (Funciona em Linux e Windows);

Baixem e testem. Caso encontrem bugs postem aqui, ou se corrigirem postem o upgrade para que todos possam participar da evolução deste projeto.


adalberto

Pessoal, agora que eu vi, o programa Clientes.prisma no anexo anterior está incompleto, devo ter upado o errado,

este é o completo com todas as funções de sqlite3:



//Controle de clientes em Prisma com ig
/**programa livre, open-source, para qualquer fim a qualquer um que
o queira usar, para modificar, usar em outros programas, comercial,
sem precisar pagar ou mencionar o autor aqui presente: Adalberto.
O programa é dado como está, gratuito, mas sem garantias, o autor
não poderá ser responsabilizado por qualquer uso.
**///

local ig = inclua'ig' //biblioteca gráfica (janela, botoes etc.)
local sql = inclua'psqlite3' //biblioteca de banco de dados SQlite3
local nomebd = 'Clientes.bd'

funcao principal(Args) //funcao main do programa 
//criando a janela
  local jan = ig.janela('Controle de Clientes', 700,400);
  ig.conecte_funcao(jan,ig.destruido,ig.fimjanela); 
  cria_bd_e_tabelas(jan);   
  //criando o painel fixo para colocar os componentes:
  local fixo = ig.fixo();
  ig.ad(jan,fixo);
  //criando os componentes:
  local cabecalho = ig.rotulo'Controle de Clientes:';
  ig.fixo_ad(fixo,cabecalho,10,10);
  ig.componente_modifique_fonte(cabecalho,'Times New Roman',ig.NEGRITO,16);
 
  local rot_nome = ig.rotulo'Nome:';
  ig.fixo_ad(fixo,rot_nome,10,40);
  local txt_nome = ig.texto();
  ig.componente_def_tamanho(txt_nome,550,28);
  ig.fixo_ad(fixo,txt_nome,10,55);//col:10 x lin:80;

  local rot_endereco = ig.rotulo'Endereço:';
  ig.fixo_ad(fixo,rot_endereco,10,85);
  local txt_endereco = ig.texto();
  ig.componente_def_tamanho(txt_endereco,550,28);
  ig.fixo_ad(fixo,txt_endereco,10,100);
 
  local rot_tel = ig.rotulo'Telefone:';
  ig.fixo_ad(fixo,rot_tel,10,130);
  local txt_tel = ig.texto();
  ig.componente_def_tamanho(txt_tel,220,28);
  ig.fixo_ad(fixo,txt_tel,10,145);
 
  local rot_nasc = ig.rotulo'Data de nasc.:';
  ig.fixo_ad(fixo,rot_nasc,10,175);
  local txt_nasc = ig.texto();
  ig.fixo_ad(fixo,txt_nasc,10,190);
 
//criando o botao incluir
//é bastante código, mas isso te dá mais domínio sobre o componente!
  local bt_incluir = ig.botao();
  local caxh = ig.caixahorizontal();
  local img = ig.imagem_estoque(ig.ESTOQUE_OK,2);
  local rot = ig.rotulo(' Incluir');
  ig.ad(caxh,img);
  ig.ad(caxh,rot);
  ig.ad(bt_incluir,caxh);
  ig.fixo_ad(fixo,bt_incluir,10,220);
 
//criando o botao Alterar
  local bt_alterar = ig.botao();
  caxh = ig.caixahorizontal();//reaproveitamos as variaveis caxh,img e rot
  img = ig.imagem_estoque(ig.ESTOQUE_DISQUETE,2);
  rot = ig.rotulo(' Alterar');
  ig.ad(caxh,img);
  ig.ad(caxh,rot);
  ig.ad(bt_alterar,caxh);
  ig.fixo_ad(fixo,bt_alterar,100,220);
 
//criando o botao Excluir
  local bt_excluir = ig.botao();
  caxh = ig.caixahorizontal();//reaproveitamos as variaveis caxh,img e rot
  img = ig.imagem_estoque(ig.ESTOQUE_DELETAR,2);
  rot = ig.rotulo(' Excluir');
  ig.ad(caxh,img);
  ig.ad(caxh,rot);
  ig.ad(bt_excluir,caxh);
  ig.fixo_ad(fixo,bt_excluir,190,220);
 
//criando o botao Sair
  local bt_sair = ig.botao();
  caxh = ig.caixahorizontal();//reaproveitamos as variaveis caxh,img e rot
  img = ig.imagem_estoque(ig.ESTOQUE_SAIR,2);
  rot = ig.rotulo(' Sair');
  ig.ad(caxh,img);
  ig.ad(caxh,rot);
  ig.ad(bt_sair,caxh);
  ig.fixo_ad(fixo,bt_sair,280,220);
 
//criando botao Limpar banco de dados:
  local bt_limparbd = ig.botao(' Apagar todos os registros do bd ');
  ig.fixo_ad(fixo,bt_limparbd,360,220);
 
//criando uma janela de rolagem:
  local jan_rol = ig.janela_rolagem();
  ig.fixo_ad(fixo,jan_rol,10,250);
  ig.componente_def_tamanho(jan_rol,700,300);

//criando a caixa de listagem
  local list = ig.listagem(' Id ',' Nome ',' Endereço ',' Telefone ',' Data de nasc. ');
  ig.janela_rolagem_ad(jan_rol,list);
  para i=1,5 inicio
    ig.listagem_def_col_auto_ajuste(list,i,verdadeiro);//definido auto ajuste da col 1 ate 5
  fim
  ig.componente_modifique_fonte(list,'Arial',11);
  ig.componente_modifique_corletra(list,ig.cor_analise(ig.azul,'*t'));
 

 
//Terminamos a parte gráfica agora vamos às funções callbacks:
//criando tabela com todos os componentes criados para as callbacks:
local tab = {
  jan = jan,
  list = list,
  txt_nome = txt_nome,
  txt_endereco = txt_endereco;
  txt_tel = txt_tel;
  txt_nasc = txt_nasc
}

  //atualizando a listagem com dados do bd se houver.
  atualiza_listagem(tab);
  //conectando a listagem:
  ig.conecte_funcao(
    list,ig.clique_linha,
    list_clique, tab //passando tabela como dado extra.
    );
 
//conectando botao incluir
  ig.conecte_funcao(bt_incluir,ig.clique,incluir,tab);
  ig.conecte_funcao(bt_alterar,ig.clique,alterar,tab);
  ig.conecte_funcao(bt_excluir,ig.clique,excluir,tab);
  ig.conecte_funcao(bt_sair,ig.clique,sair,tab);
  ig.conecte_funcao(bt_limparbd,ig.clique,limpar_bd,tab);
  ig.conecte_funcao(jan,ig.evento_delete, sair,tab);
  ig.componente_mostre_todos(jan);
  ig.fimprograma();
  retorne 0;
fim


/*==========================================  Call backs ========================*/

funcao sair(comp,evento,dado)
  se nao dado entao dado = evento fim;
  local dialog = ig.dialogo_mensagem(dado.jan,'Atenção','Sair do programa?',
                                     ig.MSG_QUESTAO , //tipo de mensagem
                                     ig.BOTAO_SIM_NAO //tipos de botões
);   
  ig.botao_mostre_imagem(verdadeiro);   
  local ret = ig.dialogo_execute( dialog );
  ig.componente_destrua( dialog );   
  se ret == ig.RET_SIM entao
    ig.componente_destrua(dado.jan);
    ig.fimjanela();
  senao
    retorne verdadeiro;//para não fechar é necessário retornar verd.
  fim
fim


//=====================================================
funcao obt_valores_listagem(list,lin)
  local id = string.apare( ig.listagem_obt_texto(list, lin,1) );
  local Nome = string.apare(ig.listagem_obt_texto(list, lin,2));
  local End = string.apare(ig.listagem_obt_texto(list,lin,3));
  local Tel = string.apare(ig.listagem_obt_texto(list,lin,4));
  local Nasc = string.apare(ig.listagem_obt_texto(list,lin,5));
  retorne{id=id,Nome=Nome,End=End,Tel=Tel,Nasc=Nasc};
fim

//define os campos Nome, Endereço, Telefone etc.
funcao def_valores_campos(tab,Nome,End,Tel,Nasc)   
  ig.texto_def_texto(tab.txt_nome,Nome);
  ig.texto_def_texto(tab.txt_endereco,End);
  ig.texto_def_texto(tab.txt_tel,Tel);
  ig.texto_def_texto(tab.txt_nasc,Nasc);
fim

//limpa valores dos campos:
funcao limpe_campos(dado)
  ig.texto_def_texto(dado.txt_nome,'');
  ig.texto_def_texto(dado.txt_endereco,'');
  ig.texto_def_texto(dado.txt_tel,'');
  ig.texto_def_texto(dado.txt_nasc,'');
fim
//obtém valores dos campos:
funcao obt_valores_campos(dado)
  local Nome =string.apare( ig.texto_obt_texto(dado.txt_nome));
  local End = string.apare(ig.texto_obt_texto(dado.txt_endereco));
  local Tel = string.apare(ig.texto_obt_texto(dado.txt_tel));
  local Nasc = string.apare(ig.texto_obt_texto(dado.txt_nasc));
  retorne{ Nome=Nome,End=End,Tel=Tel,Nasc=Nasc};
  //retorna uma tabela com campos iguais aos nomes das variáveis
fim

funcao algum_campo_vazio(cmp)
  se cmp.Nome=='' ou cmp.End == '' ou cmp.Tel=='' ou cmp.Nasc=='' entao
    retorne verdadeiro;
  senao
    retorne falso;
  fim
fim

//======================================================


//ao clicar na listagem:
funcao list_clique(list,lin,col,evento,tab) 
  local lcmp = obt_valores_listagem(list,lin);// lcmp = listagem campos.
  def_valores_campos(tab,lcmp.Nome,lcmp.End,lcmp.Tel,lcmp.Nasc);
  tab.id_atual = lcmp.id; //este campo da tabela é adicionado para alterar ou excluir.
  //ao modificar a tabela aqui ela é modificada fora da função também 
fim


funcao incluir(comp,dado)
  cria_bd_e_tabelas(dado.jan); //criando o banco de dados e tabelas caso não existam.
  local ret , base = sql.abra( nomebd );//abre o banco de dados sqlite3
  se ret <> sql.SQLITE_OK entao //testando se base é o retorno é de sucesso
    ig.msg(dado.jan,'ERRO',  " ERRO, NAO FOI POSSIVEL ABRIR O BANCO DE DADOS " ..
       sql.mensagem_erro(base) //pega o ultimo erro contido em base.
    );
  fim   
                                                                      //(Nome,End,Tel,Nasc);   
  local str_sql = "INSERT INTO clientes(Nome,Endereco,Tel,Nasc) VALUES ('%s','%s','%s','%s');";//os `%s' serão substituídos depois:
  local cmp = obt_valores_campos(dado);//ret: cmp = campos (tabela);
  se algum_campo_vazio(cmp) entao//Campos vazios?
    ig.msg(dado.jan,'Atenção','Preencha todos os campos!');
  senao
    str_sql = string.formate(str_sql,cmp.Nome,cmp.End,cmp.Tel,cmp.Nasc);//formatando a string, poderia concatenar
                                                      //também se preferisse, mas eu acho bem mais fácil assim.
    ret = sql.exec(base, str_sql,funcao()es.escreva'*'fim);//funcao vazia para evitar erros.
   
    se ret == sql.SQLITE_OK entao
      ig.msg(dado.jan,'','Dados gravados com sucesso!');
      limpe_campos(dado);     
    senao
      ig.msg(dado.jan,'', sql.mensagem_erro(base));
    fim
 
  //finalmente, não se esqueça de fechar o bd aberto
    sql.feche(base);
    atualiza_listagem(dado);
  fim
fim


//cria banco de dados e tabelas se já não existirem:
funcao cria_bd_e_tabelas(jan)

  local ret , base = sql.abra(nomebd);

  se ret <> sql.SQLITE_OK entao
    ig.msg(jan,'Erro',sql.mensagem_erro(base)); 
  fim
  //
  local str_sql = [[CREATE TABLE IF NOT EXISTS clientes(
               id INTEGER PRIMARY KEY AUTOINCREMENT,
               Nome TEXT,
               Endereco TEXT,
               Tel TEXT,
               Nasc TEXT);]];
         
               
    local ret , erro_msg = sql.exec(base, str_sql,funcao()fim);
 
    se ret <> sql.SQLITE_OK entao
        ig.msg(jan,'Erro', erro_msg);
    fim
   
    sql.feche(base); //fechado a base de dados.
fim

//atualizando a caixa de listagem:
funcao atualiza_listagem(tab)//lendo o banco de dados novamente e inserindo na listagem. 
  ig.listagem_limpe(tab.list);//limpando a listagem;
  local ret , base = sql.abra(nomebd);
   
  se ret <> sql.SQLITE_OK entao//tratamento de erro
    ig.msg(tab.jan,"Erro: ", sql.mensagem_erro(base));
    sql.feche(base);
    retorne;
  fim //fim se ret <>
 
  local str_sql = "SELECT * FROM clientes;";//seleciona tudo de carros;
 
  local ret , res = sql.prepare_v2( base , str_sql ); //ret é o retorno de erro, res é o retorno da instancia da string compilada
  se ret == sql.SQLITE_OK entao
    local cont = 1;
    enquanto 1 inicio
      local pas = sql.passe(res); //executa a string compilada res.
      se (pas == sql.SQLITE_LIN) entao       
        //imprima (cont, sql.coluna_texto( res , 2),sql.coluna_texto( res , 3),sql.coluna_texto( res , 4) ,sql.coluna_texto( res , 5));       
        local id,Nome,End,Tel,Nasc = sql.coluna_texto(res,1), sql.coluna_texto( res , 2),sql.coluna_texto( res , 3),sql.coluna_texto( res , 4),sql.coluna_texto( res , 5);
       
        ig.listagem_anexe(tab.list,id, '  ' ..Nome..'  ','  '..End..'  ','  '..Tel,Nasc..'  ');
        se cont % 2 == 0 entao //se cont for par
          local Cor = ig.cor_analise(  ig.cinza,'*t' );  //definindo uma cor para letra
          ig.listagem_def_cor_fundo( tab.list , cont , Cor );
        fim //se i % 2
        cont = cont + 1;//contador para enumerar a sequencia da listagem
      senao
        quebre;
      fim 
    fim
    tab.id_atual = nulo;//reseta o valor do id atual para nao ser repetido em outra operação
    sql.finalize(res); /**finaliza o objeto sql**/
    sql.feche(base); 
  senao       
    ig.msg(tab.jan,'Erro', "Falha na execucao: " .. sql.mensagem_erro(base) );
    sql.feche(base); 
  fim
fim

//====================  ALTERAR DADOS =========================== //

funcao alterar(comp,dado)
  local cmp = obt_valores_campos(dado);
  se algum_campo_vazio(cmp) ou nao dado.id_atual entao
    ig.msg(dado.jan,'','Clique em um nome da lista abaixo para alterar');
  senao
    local str_sql =  "UPDATE clientes set Nome = '%s',Endereco = '%s',Tel = '%s',Nasc = '%s'  where Id = %s;"
    str_sql = string.formate(str_sql,cmp.Nome,cmp.End,cmp.Tel,cmp.Nasc, dado.id_atual); //troca os `%s' pelos valores dos campos
   
    //abrindo o bd
    local ret,bd = sql.abra(nomebd);//nomebd está definido no comeco do fonte principal();
    se ret <> sql.SQLITE_OK entao
      ig.msg(dado.jan,'Erro', sql.mensagem_erro(bd) );
      sql.feche(bd);
      retorne;
    fim
   
    //executando a string sql:
    ret = sql.exec(bd, str_sql, funcao()fim);
    se ret <> sql.SQLITE_OK entao
      ig.msg(dado.jan,'Erro', sql.mensagem_erro(bd) );
      sql.feche(bd);
       ig.msg(nulo,'', str_sql);
      retorne;
    senao
      ig.msg(dado.jan,'', 'Dados alterados com sucesso!' );
      sql.feche(bd);
      atualiza_listagem(dado);
      limpe_campos(dado);
    fim//fim se ret <> sql.
  fim//fim se algum_campo_vazio();
 
fim//fim função


//=================== EXCLUIR:

funcao excluir(comp,dado)
  local cmp = obt_valores_campos(dado);
  se algum_campo_vazio(cmp) ou nao dado.id_atual entao
    ig.msg(dado.jan,'','Clique em um nome da lista abaixo para excluir');
  senao
    local str_sql = 'DELETE from clientes where Id = %s;'//deleta da tabela Carros onde o Id for igual a 2;

    str_sql = string.formate(str_sql, dado.id_atual); //troca os `%s' pelos valores dos campos
   
    //abrindo o bd
    local ret,bd = sql.abra(nomebd);//nomebd está definido no comeco do fonte principal();
    se ret <> sql.SQLITE_OK entao
      ig.msg(dado.jan,'Erro', sql.mensagem_erro(bd) );
      sql.feche(bd);
      retorne;
    fim
   
    //executando a string sql:
    ret = sql.exec(bd, str_sql, funcao()fim);
    se ret <> sql.SQLITE_OK entao
      ig.msg(dado.jan,'Erro', sql.mensagem_erro(bd) );
      sql.feche(bd);
       ig.msg(nulo,'', str_sql);
      retorne;
    senao
      ig.msg(dado.jan,'', 'Dado excluído com sucesso!' );
      sql.feche(bd);
      atualiza_listagem(dado);
    fim//fim se ret <> sql.
  fim//fim se algum_campo_vazio();
  limpe_campos(dado);
fim//fim função


funcao limpar_bd(comp,dado)
  se sis.remova(nomebd) entao//apaga/deleta o arquivo de dados.
    ig.msg(dado.jan,'','Banco de dados excluído com sucesso!');
    atualiza_listagem(dado);
  fim
fim