Blog

a great conversation starts with a great topic

This is a public Blog  publicRSS

Entry

    • Tutorial parte I - Flex Air & SQLite
      424 Views, 0 Comments
      Title:
      Tutorial parte I - Flex Air & SQLite
      Entry:

      Esta é a primeira parte de uma série de três tutoriais que vou colocar sobre a integração de Flex com AIR e SQLite. A primeira (esta) vai centrar-se em uma breve introdução ao AIR com SQLite e vamos criar uma aplicação onde vamos adicionar uma base de dados local, inserir vários tipos de dados e depois coloca-los directamente em uma datagrid em Flex.

      A parte dois que será colocada mais tarde (estou a trabalhar nela) será centrada em criar uma form para adicionar dinamicamente informação à base de dados e em colocar várias tabelas a interagirem entre si em que a primeira tem dados e a segunda possui várias informações relativas aos items anteriores.

      A terceira será depois a integração das chamadas da base de dados com itemClasses e também ValueObjects.

      Espero que gostem! Mauro.

      Image:
      More:

      Sem dúvida que se há uma coisa que o Adobe AIR tem de interessante é a capacidade de ser possível criar base de dados locais sem a necessidade de nenhum servidor local como o wamp ou semelhante e com extrema facilidade.

      Ter a possibilidade de inserir, actualizar e retirar informação de uma estrutura de base de dados é sem dúvida mais fácil de gerir do que, por exemplo, a utilização de ficheiros de texto ou então ficheiros com estruturas em XML como por vezes acontece.

      Este tipo de interactividade entre o Flex ou Flash com estas estruturas permitem-nos fazer relações entre várias tabelas, podendo assim associar facilmente dados que poderão estar organizados nas famosas sequências “one-to-many” (uma entrada na tabela TAB_1 tem várias entradas associadas na tabela TAB_2). Isto torna a injecção de dados em componentes de Flex ou Flash numa acção simples e quase directa.

      Para começar a utilizar este tipo de estrutura e para podermos ter qualquer interacção com uma base de dados em SQLite através do AIR, são precisos ,no mínimo, três elementos: um ficheiro (base de dados), uma conexão e uma declaração (query).

      Este tutorial vai ser constituído por três partes sendo a primeira mais simples, com criação, adição e preenchimento de uma dataGrid em Flex. A segunda parte do tutorial terá também relação entre mais que uma tabela na mesma base de dados (realções on-to-many) e mais tarde, vamos utilizar itemClasses para termos um mapeamento perfeito e mais correcto da nossa aplicação.

      Passando ao código...

      // Criamos uma variável que vai guardar a referencia ao nosso ficheiro de base de dados
      private var dbFile:File;

      // Criamos uma nova conexão e abrimos o ficheiro que contem a base de dados
      private var conn:SQLConnection;

      // Método init para iniciar as nossas variáveis e associar-lhes valores
      private function init () : void {
          dbFile = File.applicationStorageDirectory.resolvePath("employees.db");
          conn = new SQLConnection();
          conn.open(dbFile);
          createDataBase();
          insertDataBase();
          selectDataBase();
      }

      // Primeiro criamos a nossa base de dados local
      private function createDataBase() : void
      {
          // Criamos a variável que vai executar a nossa query, atribuimos a nossa conexão, e criamos a query para depois executar
          var statement : SQLStatement = new SQLStatement();
          statement.sqlConnection = conn;
          statement.text = "CREATE TABLE employees (empId INTEGER PRIMARY KEY AUTOINCREMENT, empName VARCHAR(255))";
          statement.execute();
      }

      Da mesma forma que é fácil criar uma base de dados, também é fácil adicionarmos conteúdo à mesma bastanto quase copiar o código anterior mudando apenas a nossa query.

      private function insertDataBase():void
      {
          var dbStatement:SQLStatement = new SQLStatement();
          dbStatement.sqlConnection = conn;
          dbStatement.text = "INSERT INTO employees (empName) VALUES (:empName)";
          dbStatement.parameters[ ":empName" ] = "António";
          dbStatement.execute();
      }

      Agora que já temos conteúdo, podemos ir buscá-lo através de um SELECT à base de dados

      private function selectDataBase():void
      {
          var dbStatement:SQLStatement = new SQLStatement();
          dbStatement.sqlConnection = conn;

          dbStatement.text = "SELECT * FROM employees";
          dbStatement.execute();

          // Se quiserem ver o resultado da vossa query...
          var ac:ArrayCollection = new ArrayCollection(dbStatement.getResult().data);
          var acLength : Number = ac.length;
          for ( var i:uint; i < acLength; i++ )
          {
              trace( ac[i].empId + " - " + ac[i].empName );
          }

      }

      Já temos aqui uma primeira base mas ainda nos falta controlar várias acções, nomeadamente controlar a execução dos eventos e ter a certeza que estes ocorrem correctamente e só acedemos aos dados quando estes são recebidos / inseridos na nossa aplicação.

      Passando para um exemplo mais concreto, temos, nesta parte I deste tutorial, uma lista de trabalhadores de uma empresa que está guardada em uma base de dados SQLite.

      <?xml version="1.0" encoding="utf-8"?>
      <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
                              layout="absolute"
                              creationComplete="init()">

          <mx:Script>
              <![CDATA[
                  import mx.collections.ArrayCollection;

                  // Variável que vai ter a informação para o array e que bind para a nossa datagrid
                  [Bindable]
                  private var empArray : ArrayCollection;

                  // Variáveis de conexão
                  private var dbFile : File;
                  private var conn : SQLConnection;
                  private var dbStatement : SQLStatement;

                  // Variáveis para controlar as nossas queries
                  private var empNames : Array = new Array( "António Amaro", "Marco Silva", "Luis Ribeiro", "Salvador Mesquita", "Lourenço Pinto", "João Guimarães" );
                  private var empLoc : Array = new Array( "Financeira", "Desenvolvimento", "Recursos Humanos", "Transportes", "Desenvolvimento", "Vendas" );
                  private var empTel : Array = new Array( "351", "456", "745", "860", "254", "555" );
                  private var empPos : Number = 0;

                  /**
                   * INIT
                   */
                  private function init() : void
                  {
                      // Criamos a referência para o nosso ficheiro
                      dbFile = File.applicationStorageDirectory.resolvePath( "employees.db" );

                      // Criamos uma nova conexão que nos vai ligar à base de dados
                      conn = new SQLConnection();

                      // Se a base de dados existe abrimos, senão criamos uma nova
                      // Dependendo da acção atribuimos diferentes listeners para invocarmos diferentes métodos
                      if ( !dbFile.exists )
                      {
                          conn.addEventListener( SQLEvent.OPEN, connOpen );
                      } else
                      {
                          conn.addEventListener( SQLEvent.OPEN, selectDataBase );
                      }
                      // Abrimos a base de dados
                      conn.open( dbFile );
                  }

                  /**
                   * connOpen
                   */
                  private function connOpen( e : SQLEvent ) : void
                  {
                      // abriu a conexão, vai então criar a base de dados
                      createDataBase();
                  }

                  /**
                   * createDataBase
                   */
                  private function createDataBase() : void
                  {
                      // Criamos a variável que vai executar a nossa query, atribuimos a nossa conexão, e criamos a query para depois executar
                      dbStatement = new SQLStatement();
                      dbStatement.sqlConnection = conn;
                      dbStatement.addEventListener( SQLEvent.RESULT, insertEmpNames, false, 0, true );
                      dbStatement.text = "CREATE TABLE employees (empId INTEGER PRIMARY KEY AUTOINCREMENT, empName VARCHAR(255), empLoc VARCHAR(255), empTel INTEGER)";
                      dbStatement.execute();
                  }

                  /**
                   * insertEmpNames
                   */
                  private function insertEmpNames( e : SQLEvent ) : void
                  {
                      // Depois de criada a base de dados vamos preencher informação
                      insertDataBase();
                  }

                  /**
                   * insertDataBase
                   */
                  private function insertDataBase() : void
                  {

                      dbStatement = new SQLStatement();
                      dbStatement.sqlConnection = conn;

                      // Vamos inserindo novos elementos à base de dados até percorrermos todo o nosso array
                      if ( empPos < empNames.length - 1 )
                      {
                          dbStatement.addEventListener( SQLEvent.RESULT, insertEmpNames, false, 0, true );
                      } else
                      {
                          dbStatement.addEventListener( SQLEvent.RESULT, selectDataBase, false, 0, true );
                      }

                      // Agora vamos adicionar para cada campo, um objecto com o valor que queremos inserir na tabela
                      dbStatement.text = "INSERT INTO employees (empName, empLoc, empTel) VALUES (:empName, :empLoc, :empTel)";
                      dbStatement.parameters[ ":empName" ] = empNames[ empPos ];
                      dbStatement.parameters[ ":empLoc" ] = empLoc[ empPos ];
                      dbStatement.parameters[ ":empTel" ] = empTel[ empPos ];
                      empPos++;
                      dbStatement.execute();

                  }

                  /**
                   * selectDataBase
                   */
                  private function selectDataBase( e : SQLEvent ) : void
                  {
                      dbStatement = new SQLStatement();
                      dbStatement.sqlConnection = conn;
                      dbStatement.addEventListener( SQLEvent.RESULT, attribDataGrid, false, 0, true );

                      // Depois de inseridos todos os registos vamos seleccionar tudo que está na base de dados
                      dbStatement.text = "SELECT * FROM employees";
                      dbStatement.execute();
                  }

                  private function attribDataGrid( e : SQLEvent ) : void
                  {
                      // Vamos buscar o valor retornado pela base de dados e colocar directo num array collection
                      empArray = new ArrayCollection( dbStatement.getResult().data );
                  }
              ]]>
          </mx:Script>

          <mx:Panel width="100%"
                    paddingTop="10"
                    paddingBottom="10"
                    paddingLeft="10"
                    paddingRight="10"
                    title="TRABALHADORES DA SOFT S.A.">

              <mx:DataGrid width="100%"
                           dataProvider="{empArray}">
                  <mx:columns>
                      <mx:DataGridColumn headerText="Nome"
                                         dataField="empName"/>
                      <mx:DataGridColumn headerText="Departamento"
                                         dataField="empLoc"/>
                      <mx:DataGridColumn headerText="Telefone"
                                         dataField="empTel"/>
                  </mx:columns>
              </mx:DataGrid>
          </mx:Panel>

      </mx:WindowedApplication>

      Como podem ver, é bem simples criamos um sistema de base de dados que a cria, adiciona e mostra os resultados para uma datagrid. Como disse mais a cima, na parte dois do tutorial vamos avançar para relações entre várias tabelas na mesma base de dados para podermos associar a um só item de uma tabela, várias informações de outra.

      NOTA: Se quiserem ir testando a criação dos ficheiros de base de dados e não conseguem porque a base de dados já está criada podem apagar "à mão" os ficheiros que ficam guardados no vosso computador.

      WINDOWS: C:\Users\<user>\AppData\Roaming

      MAC: <user>\Libraries\

      Podem descarregar o projecto que está associado a este post.

      Para mais informações sobre SQLite no AIR:
      http://coenraets.org/blog/2008/02/sqlite-admin-for-air-10/
      http://livedocs.adobe.com/flex/3/langref/localDatabaseSQLSupport.html

      Uma ferramenta muito boa para poderem ver o que vai acontecendo e a estrutura da vossa base de dados, eu aconselhava a instalarem o Lita que foi referenciado num anterior post meu sobre As melhores aplicações AIR para Designers e Developer.

      Até à próxima e espero que tenham gostado!

      Mauro Martins.

      Keywords:
      adobe air, flex, sqlite, mauro martins, sqlconnection, database AIR, sqlresult, sqlstatement