Tutorial parte I – Flex Air e SQLite
Posted by Mauro | Posted in Flash / Flex | Posted on 01-10-2009
5

Introdução:
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.
Todo o código, explicação e exemplos depois de clicar aqui em baixo…
Parte I
Sem dúvida que se há uma coisa que o Adobe AIR tem de interessante é a capacidadede 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 (relaçõ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, vamos 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.
Exemplo
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.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.
creationComplete="init()">
import mx.collections.ArrayCollection;
// Variável que vai ter a informação 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
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 );
}
]]>
paddingBottom="10"
paddingLeft="10"
paddingRight="10"
title="TRABALHADORES DA SOFT S.A.">
Resultado final:

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 Developers e Designers.
PS: Estou a tentar resolver um problema com um plug-in do wordpress para colocar código e ser mais fácil a sua percepção por parte de quem o lê. Aquilo está a dar uma série de erros, mas já entrei em contacto com o criador do plug-in para ver como consigo corrigi-lo.
Até à próxima e espero que tenham gostado!
Mauro Martins.




Parabéns Mauro.
Muito bom post.
Abraços,
Silva Developer
Obrigado
A segunda parte do tutorial é capaz de ser mais interessante, esta é um pouco mais introdutória, no entanto fique atento às notícias!
[...] This post was mentioned on Twitter by Mauro Martins. Mauro Martins said: Novo no blog: FLEX, AIR & SQLite http://bit.ly/Lx8K8 riaPT – http://bit.ly/tw5es augPT – http://bit.ly/1itLOi redeRia – http://bit.ly/2stV5 [...]
Ola muito bom, porem nao encontrei a parte II, onde poderia encontra-la?
E outra coisa, sou iniciante e tenho uma duvida, onde eu digitaria este codigo? no corpo do mxml ou faria um AS?
vlw
Oi! Pois, realmente este foi um projecto que ficou para trás assim como muitos outros
No entanto estou a pensar retomar daqui a um tempo!
Pode colocar o código directo no ficheiro de mxml uma vez que tem já a diferenciação entre o que é código puro (as) e o que é a linguagem “visual” (mxml).