software‎ > ‎módulos‎ > ‎engine‎ > ‎manuais‎ > ‎

Banco de Dados e Cache Local


  • Em um Banco de Dados Relacional:





  • Em Cache Local:

    • O cache local é uma cópia de algumas tabelas do banco de dados salvas localmente para se ter um acesso mais rápido a alguns dados.
    • A maioria dos sistemas, assim como o Sistema UNUM, usa o cache local para guardar os dados com maior frequência de leitura e menor incidência de alterações. No Sistema UNUM, a configuração que define se uma tabela deve ou não ir para o cache local fica em arquivos de mime-type application/x-class.
    • O cache será armazenado no local onde o Engine estiver em execução, ou seja, se um usuário possui o Engine executando em sua máquina, lá haverá um armazenamento em cache de algumas tabelas.
    • Devido ao seu tamanho e natureza de grande incidência de edições, as tabelas de movimentação (exemplo: PEDIDO, EVENTO, MOVDEPOS, etc.) não são armazenadas no cache. 
Vejamos, na figura abaixo, o fluxo que esquematiza o processo de uma requisição de uma consulta ao banco e um acesso ao cache local:




  • O cliente azul e o cliente vermelho, ambos estão submetendo uma query ao servidor. O cliente verde está fazendo uma consulta diretamente no cache local. Como podemos ver, a consulta localmente é bem mais rápida, pois não necessita de acesso externo.

Manipulando um DataSet

Criando um DataSet

Bem... começaremos com o básico. Criaremos um DataSet e colocaremos valores dentro dele. Sempre imagine o modelo de uma tabela.

  • Uma das formar de se criar um DataSet é instanciá-lo a partir da classe DataSet. Veja no exemplo a seguir:

        var teste = new DataSet();


  • Após a instância do dataset, precisamos definir sua estrutura, ou seja, os seus campos e respectivos tipos. Fazendo um paralelo do dataset com uma tabela, estamos criando as suas colunas, definindo o nome e o tipo de valor que será guardado em cada uma. Após montarmos a estrutura de nosso dataset, temos que finalizar a criação invocando o método create(). Observe:

        teste.createField("CODIGO", "integer");
        teste.createField("NOME", "string", 30);
        teste.createField("ABREVIACAO""string", 10);
        teste.createField("BANCO""integer");
        teste.createField("SALDO", "integer");
        teste.create("CLIENTES");


  • Após a estrutura definida, preencheremos os campos do nosso DataSet. A sintaxe é simples. Para adicionarmos uma nova linha (registro), utilizaremos o método append().
  • Para adicionarmos os valores nos campos do novo registro é fácil. Os campos definidos com o método createField, viram atributos desse objeto. Ou seja usamos a seguinte sintaxe: teste.<<nome do campo>>. Segue um exemplo mais abaixo.
  • Após cada inserção temos que confirmar as mudanças chamando o método post(). Toda chamada ao método append(), logo após a definição dos valores dos campos, tem que ser finalizada com uma chamada ao método post(), uma espécie de commit da inserção daquele registro.
  • Para melhor entendimento, analise o código abaixo: 

        teste.append();       // << Início da inserção do primeiro registro
        teste.codigo = 1;
        teste.nome = "Alberto Albuquerque";
        teste.abreviacao = "AA";
        teste.banco = 1;
        teste.saldo = 500;
        teste.post();         // << Fim da inserção do primeiro registro


        teste.append();       // << Início da inserção do segundo registro
        teste.codigo = 2;
        teste.nome = "Breno Angelo Camelo";
        teste.abreviacao = "BAC";
        teste.banco = 2;
        teste.saldo = -300;
        teste.post();         // << Fim da inserção do segundo registro


  • Ao final de todo esse processo, o DataSet estará igual a esse: 



Percorrendo um DataSet

Quando falamos em percorrer um DataSet, queremos dizer que "visitaremos" registro a registro do DataSet. Esse processo é usado para muitos usos como o de alterar valores, verificar se um determinado campo tem um valor esperado, etc.

Existem duas maneiras de se percorrer um DataSet usando as estruturas de laço da linguagem. Uma é com o while e a outra com o for. Veremos cada uma a seguir com exemplos diferentes.

1) Preparação
  • Nessa parte precisamos somente do DataSet preenchido para podermos trabalhar em cima dele. Utilizando um DataSet como o que foi criado na seção 3.1, preenchemos com os dados a seguir:  



2) Percorrendo com o While
  • Pronto, agora percorreremos todas os registros desse DataSet e apagaremos aqueles cujo campo ABREVIACAO é igual a "MA". Para fazer isso, usaremos uma estruturas de repetição while e algumas funções da classe DataSet. Acompanhe o exemplo abaixo:

  
            teste.first();   

            while (!teste.eof){
                if (teste.abreviacao == "MA"){
                    teste.del();
                } else {
                    teste.next();
                }
            }
                

  • Explicando mais detalhadamente o código acima: 
    • O método teste.first() posiciona o cursor no primeiro registro do DataSet.
    • O Atributo teste.eof, quando verdadeiro, indica que foi invocado um teste.last() ou que, estando no último registro, foi invocado um teste.next().
    • O método teste.next() posiciona o cursor no próximo registro do DataSet. Conforme vimos no item acima, se o registro posicionado já for o último, ao se invocar o teste.next(), o atributo teste.eof passa a ter valor lógico verdadeiro.
  • Observe que a função teste.del(), ao ser invocada, além de deletar o registro, já posiciona o cursor no próximo registro, dispensando a chamada de um teste.next() para esta finalidade.
  • Veja abaixo o resultado do delete que foi feito. A pessoa Maria Ana não consta mais na lista:



3) Percorrendo com o For 
  • Como exemplo, alteraremos os campos ABREVIACAO e NOME quando o campo CODIGO for maior que 5.

            for (teste.first(); !teste.eof; teste.next()) {
                if (teste.codigo > 5) {
                    teste.abreviacao = "CBP";
                    teste.nome = "Caio Barcelos Pereira";
                }
            }

  • Após a execução, a tabela deverá ter ficado como a figura abaixo:


A operação de pivot no DataSet

Alguns dos leitores deste artigo já devem conhecer a funcionalidade de tabelas dinâmicas, também conhecida como pivot table, do Microsoft Excel. Se não conhece, sugiro a leitura deste artigo http://office.microsoft.com/pt-br/excel/HA010346321046.aspx.

O DataSet da UNUM suporta a geração de tabelas pivot através do método ds.pivot().

Dado o seguinte DataSet:



Iremos gerar este outro:



Isso é feito através da operação de pivot no campo tamanho e totalizando o campo quantidade. Ou seja, suponhamos que o campo quantidade seja a quantidade de canetas existentes em uma livraria. O tamanho seria o tamanho de cada caneta. Após chamarmos o método pivot(), teremos um novo dataset que nos mostra a quantidade de canetas de cada tamanho de cada produto.

Segue abaixo o código que realiza a operação de pivot descrita acima:


                   //Necessário fazer este include porque o método pivot não é nativo.
                   //No contexto de um processo ou layout este arquivo já está incluso

                   includeOnce -1898146467; /* DataSet.js */

                   //Criando o DataSet
                   var ds = new DataSet();
                   ds.createField("PRODUTO", "string", 10);
                   ds.createField("TAMANHO", "number");
                   ds.createField("QUANTIDADE", "number");
                   ds.create();

                   //Preenchendo o DataSet
                   for (var prod = 1; prod <= 5; prod++) {
                       for (var tam = 10; tam <= 30; tam += 10) {
                           ds.append();
                           ds.produto = "Produto " + prod;
                           ds.tamanho = tam;
                           ds.quantidade = prod * tam;
                           ds.post();
                       }
                   }

                   ds.pivot("TAMANHO", "QUANTIDADE");           


Mais detalhes sobre o uso do método pivot consulte a sua documentação em: http://l.unum.com.br/jsdoc/symbols/DataSet.html#pivot e em http://l.unum.com.br/jsdoc/symbols/DataSetTransformer.html

Manipulando o Banco de Dados

Consultando o Banco de Dados

Nessa parte, ensinaremos a: 

  • Executar comandos sql que não retornam dados do BD; 
  • Executar comandos sql que retornam dados e capturá-los em um DataSet;
Temos dois métodos principais de comunicação com o banco de dados: 
  • database.query() 
    • Responsável por enviar queries ao banco e retornar um DataSet das consultas. Este método é utilizado para realizar o comando SELECT no banco de dados.
  • database.executeSQL()
    • Responsável por enviar queries ao banco e não retornar nenhum valor. Este método é útil quando se deseja enviar um comando do tipo INSERT, DELETE, CREATE, DROP, etc. Observem que estes comandos não retornam um DataSet como resultado de sua execução.
A seguir, utilizaremos o método database.executeSQL() afim de criar a tabela PESSOA_TREINAMENTO. O mesmo método será utilizado para inserirmos alguns registros nesta tabela.

OBS:  Esta não é a maneira padrão de se criar e popular uma tabela no Sistema UNUM.
          Esse é um exemplo apenas para aprendizado.


                   var qry = "Create Table PESSOA_TREINAMENTO (
                                                                                                 CHAVE integer,
                                                                                                 NOME varchar(30),
                                                                                                 DATANASCIMENTO date,
                                                                                                 NIVEL varchar(30)                                             
                                                                                              ) ";
                   database.executeSQL(qry);

                   qry = "Insert into PESSOA_TREINAMENTO Values ( 1, 'Pedro Nascimento', '05/05/1990', 'desenvolvedor' )";
                   database.executeSQL(qry);

                   qry = "Insert into PESSOA_TREINAMENTO Values ( 2, 'João Paulo', '10/03/1980', 'gerente' )";
                   database.executeSQL(qry);


  • Agora faremos um Select para retornar todos os registros da tabela PESSOA_TREINAMENTO em forma de um DataSet.  
var qry = "Select CHAVE, NOME, DATANASCIMENTO, NIVEL
                From PESSOA_TREINAMENTO";

var ds = database.query(qry);

  • Após executar o código acima no iDBC, podemos perceber que, na parte de baixo da área de código, aparece o DataSet resultado da sua consulta realizada.



Alterando informações do Banco de Dados através de DataSets

Conheceremos agora o método database.applyUpdates(). Neste exemplo, vamos assumir que a tabela ITESTE está vazia e que é uma tabela do Sistema UNUMA execução da consulta abaixo fará com que seja preparado um DataSet com a mesma estrutura da tabela ITESTE.

                var teste = database.query("Select * from ITESTE");
  • Como dito anteriormente, nossa tabela não possui nenhum registro, então o DataSet teste estará vazio. Um DataSet vazio equivale a uma tabela sem registros.
  • Adicionaremos um registro no DataSet vazio e, após criar este registro, utilizaremos o método database.applyUpdates() para refletir, no banco de dados, as ações que foram feitas no DataSet, criando finalmente o registro no banco de dados. 
  • A gravação ocorre na tabela correta pois o DataSet teste está vinculado à tabela ITESTE desde sua criação. Segue o exemplo completo abaixo:
  • OBS: Para usar este método de gravação, a tabela em uso precisa, necessariamente, ter sido definida dentro do Sistema UNUM, ou seja, através de um arquivo do tipo application/x-class. A definição do campo iKey é apenas para exemplo. Dentro de nosso Sistema, a definição do valor que ficará no campo iKey é feita de forma automática e transparente.
  
              
                var teste = database.query("Select * from ITESTE");

                teste.append();
                teste.ikey = 2;
                teste.iclass = 99;
                teste.icode = "RW";
                teste.iname = "Ricardo Wagner";
                teste.post();

                database.applyUpdates(teste);

  • Agora a consulta para conferir a criação do registro:

  • Para alterar e apagar um registro, os passos são os mesmos, ou seja:

    1 - Preparar o DataSet a partir 
    de uma consulta ao banco de dados;
    2 - Modificar o DataSet ao incluir, alterar ou apagar registros;
    3 - Invocar o método database.applyUpdates().

    Acompanhe o trecho abaixo em que editamos e apagamos o registro que inserimos na tabela ITESTE.

              // Modificando o registro inserido
              var teste = database.query("Select * from ITESTE Where iKey = 2");
              teste.iclass = 99;
              teste.icode = "PL";
              teste.iname = "Pedro de Lara";
              teste.post();
              database.applyUpdates(teste);

              // Apagando o registro adicionado  
              dsTeste = database.query("Select iKey, iVersion from ITESTE Where iKey = 2");
              dsTeste.del();
              database.applyUpdates(teste);

Manipulando o Cache Local

Antes de começarmos a falar do Cache Local, que tal você ler sobre alguns conceitos do engine?

O Cache Local não é como um banco de dados Oracle, Postgres ou SqlServer. Você não pode enviar consultas diretamente a ele como uma query normal a um banco de dados relacional. Todavia, podemos realizar as operações básicas, como criar tabela, pegar uma tabela, apagar uma tabela... etc. As tabelas retornadas do Cache Local serão tratadas como DataSets quando retornadas para a nossa aplicação. 


Tabelas do Sistema e Cache Local

Mostraremos abaixo, com base naquela nossa tabela criada no tutorial "manipulando o banco de dados - parte 2", como devemos, e o que podemos fazer, com o Cache Local. 
1) Pegaremos a nossa tabela iTESTE do Cache Local. A mesma, quando foi criada pelo X-Classe, foi definida que faria parte do cache. 

  • Para trazer a iTESTE do Cache, usaremos o objeto global dbCache, que é uma instancia da Classe DBCache.

        if( dbCache.hasTable( "ITESTE" ) )
        {
           ds = dbCache.getTable( "ITESTE" )
        }


  • No código acima verificamos se a nossa tabela iteste está gravada no cache local, caso esteja pegamos essa tabela como um DataSet e colocamos na variável ds.
  • Perceba que o tempo de busca ao DataSet foi mínimo. Já que não existe conexão com o banco de dados. 
  • Bom, após o retorno, temos um DataSet normal com todas as seus métodos e propriedades. Agora é só aprofundar um pouco mais os seus conhecimentos sobre DataSet.
Para manter o Cache sempre sincronizado com o banco de dados, há uma execução independente que é ativada depois que uma requisição é feita ao Engine que age como Servidor de Aplicação e a cada período de 30 segundos (este intervalo pode ser configurado).



Banco de Dados Local

O Cache também pode funcionar como um banco de dados local. Você pode criar, editar, deletar tabelas, bases de dados etc.. Tudo isso de uma maneira prática e rápida usando apenas duas classes: 
  • IdoDB 
    • Responsável pelas tabelas do banco local. Excluir, Pegar e Verificar se existe tabelas são algumas funções que essa classe exerce. 
  • IdoDBManager
    • Responsável pela base de dados. Excluir, Criar, Verificar se existe e Carregar são algumas das funções que essa classe exerce.

Após explicarmos o dever de cada classe veremos como criar uma base de dados e uma tabela no nosso cache local. 
  • Para começar criaremos uma base de dados invocando o método createDataBase() de um objeto já instanciado globalmente chamado de idoDBManager.        
        idoDBManager.createDatabase("TESTE")

  • Agora damos um load da base de dados para uma variável. Essa funcao retornará uma instancia da classe IdoDB.  
        var idoDB = idoDBManager.loadDatabase("TESTE")

  • Criaremos um DataSet passando como parametro o objeto idoDB.      
        var ds = new DataSet(idoDB) 
        ds.createField("Codigo", "Integer"
        ds.createField("Nome", "String", 10) 
        ds.createField("Valor", "Integer"
        ds.create("Clientes"

  • Inseriremos os registros no DataSet.      
        ds.append()
        ds.first()
        ds.codigo = 1
        ds.nome = "Rhuan"
        ds.valor = 100
        ds.post()

  • Pronto, temos uma tabela guardada no banco de dados local. Vamos deleta-la?
        idoDB.dropTable("Clientes")

  • Agora apagando a base de dados...
        idoDBManager.deleteDatabase("TESTE")




Exemplos mais complexos

Criando um DataSet


var arrayClientes = ["Pedro Albuquerque",
                     "Joana Pereira",
                     "Pedro André",
                     "Maria Ana",
                     "Carlos Kardozo Angelo"
                     "Meirelene Araújo Santos"]

var codigo = 0

var dsTeste = new DataSet()

dsTeste.createField( "Codigo", "Integer" )
dsTeste.createField( "Nome", "String", 30 )
dsTeste.createField( "Abreviacao", "String", 10 )
dsTeste.createField( "Banco", "Integer" )
dsTeste.createField( "Saldo", "Integer" )
dsTeste.create( "Clientes" )

function getAbreviacao( nomeCliente )
{
   var array = nomeCliente.split(" ")
   var abreviacao = ""
   for(var i = 0; i < array.length; i++)
   {
      abreviacao += array[i].charAt(0).toUpperCase()
   }
   
   return abreviacao
}

function getRandomNumberBase10( valorMaximo )
{
   var num = Math.round( Math.random()* Math.pow( 10, valorMaximo ) )
   return num
}


for(var j = 0; j < 3; j++ )
{
   for(var i = 0; i < arrayClientes.length; i++)
   {
      dsTeste.append()
         dsTeste.codigo = ++codigo
         dsTeste.nome = arrayClientes[i]
         dsTeste.abreviacao = getAbreviacao( arrayClientes[i] )
         dsTeste.banco = getRandomNumberBase10( 1 )
         dsTeste.saldo = getRandomNumberBase10( 2 )
      dsTeste.post()
   }
}


dsTeste.indexFieldNames = "CODIGO"

dsTeste



voltar ao topo