
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.
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, 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.
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.
<?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\preferences\
Podem descarregar o projecto aqui:
download do ficheiro
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.