Ola pessoal,
Esses dias estava em casa acompanhando uma lista de discussão sobre Flex, e entraram no mérito do AIR com o SQLite. Confesso que já tinha dado uma olhada por cima, mas me empolguei com a discussão e resolvi fazer um teste com ele para ver como funcionaria. Confesso que fiquei surpreso com sua facilidade e estou disponibilizando um tutorial comentado de como fazer uma conexáo, inserção simples e uma consulta usando esses recursos.
A versão utilizada para o desenvolvimento foi o FlexBuilder com o SDK 3.2.
Bom, vamos lá…. Para quem nunca criou um projeto no Flex para a plataforma AIR, ou ainda não conhece o ambiente Flex, a tela de criação do projeto em File -> New -> Flex Project, iniciamos um projeto com o nome SQLiteDemo.

Criado o projeto, o FlexBuilder irá abri-lo como default, e irá disponibilzar os arquivos SQLiteDemo.mxml e SQLiteDemo-app.xml. Na imagem abaixo, irá aparecer um arquivo chamado Usuario.as, que será criado mais tarde no decorrer do tutorial.

No memo File -> New -> ActionScript Class, iremos criar uma classe AS para representação da tabela que iremos criar no SQLite para persistencia de usuários. No decorrer, iremos ver que os atributos desta classe são os campos que iremos criar no SQLite para a persistência.
package
{
public class Usuario
{
public var cd_usuario : Number;
public var nm_usuario : String;
public var ds_login : String;
public var ds_senha : String;
public function Usuario()
{
}
}
}
Para quem nunca ouviu falar em SQLite, o SQLite é um banco de dados para o uso em aplicações com o banco "embarcado", ou seja, não é necessário a instalação de um SGDB e demais configurações para o seu funcionamento.
O AIR tem suporte nativo ao SQLite, dessa forma, é possivel criar uma aplicação com banco de dados embarcado e toda sua instalação ocorre de maneira transparente para o usuário final, sem precisar fazer nenhuma parametrização adicional, basta rodar o instalador padrão de uma aplicação AIR e o sistema estará pronto para o uso.
A tabela que será persistida será criada em tempo de execução quando a aplicação for executada pela primeira vez. Vale lembrar que, esse é um tutorial para demonstrar o funcionamento do AIR com SQLite e não um tutorial de padrão de projeto com a utilização AIR + SQLite.
Dentro do arquivo principal da nossa aplicação, iremos criar um evento para que ao finalizar a criação da aplicação seja feita a conexão com o banco de dados, e a criação da tabela que utilizaremos.
import mx.events.FlexEvent;
import mx.controls.Alert;
private var sqlConn : SQLConnection;
private var dbFile : File;
private var sqlStm : SQLStatement;
private var dbPath : String ="SQLiteDemo.sqlite";
private var usuario : Usuario = new Usuario();
private function initApp() : void
{
this.dbFile = File.documentsDirectory.resolvePath(this.dbPath);
this.sqlConn = new SQLConnection();
this.sqlConn.addEventListener(SQLEvent.OPEN, onSQLOpenEvent);
this.sqlConn.addEventListener(SQLErrorEvent.ERROR, onSQLErroEvent);
this.sqlConn.open(this.dbFile);
}
Nesse momento, no evento creationComplete(), a função initApp() foi executada, sua função é abrir uma conexão com o banco de dados, e em caso de sucesso ou falha, disparar seu respectivo evento.
Nesse tutorial, não vou entrar em detalhes sobre eventos, uma vez que o objetivo do mesmo é o uso do SQLite e não sobre ActionScript.
Algumas variaveis foram declaradas no inicio da aplicação, vamos a uma breve descrição sobre cada uma delas:
sqlConn: Usada para a conexão com o banco de dados;
dbFile: Usada para armazenar o arquivo aonde esta o banco de dados;
sqlStm: SQLStatement padrao para executar querys no banco de dados;
dbPath: Path do banco de dados;
usuario: Variavel para armazenar o usuário logado no sistema;
Caso a conexão com o banco de dados ocorra com sucesso, a função onSQLOpenEvent() é disparada:
private function onSQLOpenEvent(event:SQLEvent) : void
{
var sqlQuery : String = "CREATE TABLE IF NOT EXISTS [usuario] ([cd_usuario] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, [nm_usuario] VARCHAR(100) NULL, [ds_login] VARCHAR(30) NULL, [ds_senha] VARCHAR(30) NULL);";
this.sqlStm = new SQLStatement();
this.sqlStm.sqlConnection = this.sqlConn;
this.sqlStm.text = sqlQuery;
this.sqlStm.addEventListener(SQLEvent.RESULT, onIniciaTabelaResult);
this.sqlStm.execute();
}
private function onIniciaTabelaResult(event:SQLEvent) : void
{
Alert.show('App disponivel para o uso');
}
Ao ser disparada, a tabela que usaremos nesse exemplo é criada. Para isso, utilizamos pela primeira vez, o SQLStatement, para que uma instrução SQL fosse enviada ao banco de dados. Apenas dois atributos foram utilizados, o text para a instrução SQL, e o sqlConnection, aonde informamos nossa conexão com o SQLite.
Também foi adicionado um eventListner ao SQLStatement, caso ocorra um sucesso, a função onIniciaTabelaResult() é disparada, apenas com o objetivo de alertar ao usuário que a aplicação está disponivel para o uso.
Bom, agora, iremos criar nossa mini-aplicação, que consiste no seguinte: Será criado um ViewStack, para que seja o principal container da aplicação e faça a gerência de qual canvas deve ser apresentado ao usuário de acordo com sua navegação.
A aplicação terá 3 canvas, o primeiro, com o objetivo de que o usuário do sistema possa fazer um login, o segundo, com uma tela para que seja possível seu cadastro, e por ultimo, um canvas contendo uma saudação caso seu login tenha sido feito com sucesso.
Bom, em alguns botões foram adicionados alguns eventos, e iremos comentar agora cada um deles.
O botão com o label "Entrar", do canvas "cvnLogin", tem um evento adicionado ao click do mouse, aonde é responsavel por disparar a função btnEntrar_clickHandler();.
private function btnEntrar_clickHandler() : void
{
var sqlQuery : String = "select " +
"* from [usuario] " +
"where " +
"[ds_login] = '" + this.txtLogin.text + "' and " +
"[ds_senha] = '" + this.txtSenha.text + "'";
this.sqlStm = new SQLStatement();
this.sqlStm.sqlConnection = this.sqlConn;
this.sqlStm.text = sqlQuery;
this.sqlStm.addEventListener(SQLEvent.RESULT, onQueryResult);
this.sqlStm.execute();
}
private function onQueryResult(event:SQLEvent) : void
{
var resultado : SQLResult = this.sqlStm.getResult();
if (resultado != null) {
if (resultado.data != null)
{
this.vwStack.selectedIndex = 2;
var obj : Object = resultado.data[0] as Object;
this.usuario.cd_usuario = obj['cd_usuario'];
this.usuario.nm_usuario = obj['nm_usuario'];
this.usuario.ds_login = obj['ds_login'];
this.usuario.ds_senha = obj['ds_senha'];
} else {
Alert.show('Login incorreto');
}
}
}
Basicamente o processo de login ocorre da mesma forma que a criação de tabelas ao iniciar o programa visto anteriormente. Um SQLStatement é instanciado e alimentado com as mesmas propriedades, agora voltadas para o login da aplicação com um SELECT, ao invéz do CREATE TABLE utilizado para criação da tabela anteriormente. Foi adicionado também um eventListner, caso ocorra o sucesso na busca, disparando a função onQueryResult();.
A função onQueryResult é responsavel por verificar se o resultado da busca, é valido ou não para o login e senha informados. Utilizando o método getResult() do SQLStatement, é possivel que voce obtenha os resultados que a consulta SQL processada resultou.
O botão com o label Cadastrar no canvas cnvReg possui um evento no click do mouse, e esse evento é responsável por disparar uma função chamada btnCadastro_clickHandler, que será responsável pelo cadastro do usuário no sistema.
public function btnCadastro_clickHandler() : void
{
var sqlQuery : String = "insert into [usuario] " +
"([nm_usuario], [ds_login], [ds_senha])" +
" values" +
"('" + this.txtCadNome.text + "', " +
"'" + this.txtCadUsuario.text + "'," +
"'" + this.txtCadSenha.text + "')";
this.sqlStm = new SQLStatement();
this.sqlStm.sqlConnection = this.sqlConn;
this.sqlStm.text = sqlQuery;
this.sqlStm.addEventListener(SQLEvent.RESULT, onQueryCadastroResult);
this.sqlStm.execute();
}
private function onQueryCadastroResult(event:SQLEvent) : void
{
Alert.show('Cadastro efetuado com sucesso');
this.vwStack.selectedIndex = 0;
}
Novamente, seguindo o padrão já apresentado nas outras duas situacões, a função basicamente é responsavel por informar a uma nova instância do SQLStatement, a nova instrução SQL a ser executada no banco de dados, e através de um eventListner, você poder personalizar o sucesso ou a falha da execução da SQL.
Nesse caso, implementamos o sucesso da instrução com o método onQueryCadastroResult(), aonde ele é responsável por informar o usuário do sucesso do cadastro e o envia novamente ao canvas de login.
Basicamente, dessa forma, você poderá ter uma aplicação rodando através do AIR com o uso de um banco de dados embarcado. Espero ter sido claro nas explanações sobre o processo, deixando claro que esse é um exemplo de como podemos usar o SQLite com o AIR, e não um padrão a vir a ser adotado para o desenvolvimento AIR + SQLite.
Abaixo, segue na integra todo o fonte da aplicação, com alguns metódos que não foram comentados neste tutorial.
import mx.events.FlexEvent;
import mx.controls.Alert;
private var sqlConn : SQLConnection;
private var dbFile : File;
private var sqlStm : SQLStatement;
private var dbPath : String ="SQLiteDemo.sqlite";
private var usuario : Usuario = new Usuario();
private function initApp() : void
{
this.dbFile = File.documentsDirectory.resolvePath(this.dbPath);
this.sqlConn = new SQLConnection();
this.sqlConn.addEventListener(SQLEvent.OPEN, onSQLOpenEvent);
this.sqlConn.addEventListener(SQLErrorEvent.ERROR, onSQLErroEvent);
this.sqlConn.open(this.dbFile);
}
private function onSQLOpenEvent(event:SQLEvent) : void
{
var sqlQuery : String = "CREATE TABLE IF NOT EXISTS [usuario] ([cd_usuario] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, [nm_usuario] VARCHAR(100) NULL, [ds_login] VARCHAR(30) NULL, [ds_senha] VARCHAR(30) NULL);";
this.sqlStm = new SQLStatement();
this.sqlStm.sqlConnection = this.sqlConn;
this.sqlStm.text = sqlQuery;
this.sqlStm.addEventListener(SQLEvent.RESULT, onIniciaTabelaResult);
this.sqlStm.execute();
}
private function onIniciaTabelaResult(event:SQLEvent) : void
{
Alert.show('App disponivel para o uso');
}
private function onSQLErroEvent(event:SQLErrorEvent) : void
{
Alert.show('App não disponivel');
this.vwStack.selectedIndex = -1;
}
private function btnRegistro_clickHandler() : void
{
this.vwStack.selectedIndex = 1;
}
private function btnEntrar_clickHandler() : void
{
var sqlQuery : String = "select " +
"* from [usuario] " +
"where " +
"[ds_login] = '" + this.txtLogin.text + "' and " +
"[ds_senha] = '" + this.txtSenha.text + "'";
this.sqlStm = new SQLStatement();
this.sqlStm.sqlConnection = this.sqlConn;
this.sqlStm.text = sqlQuery;
this.sqlStm.addEventListener(SQLEvent.RESULT, onQueryResult);
this.sqlStm.execute();
}
private function onQueryResult(event:SQLEvent) : void
{
var resultado : SQLResult = this.sqlStm.getResult();
if (resultado != null) {
if (resultado.data != null)
{
this.vwStack.selectedIndex = 2;
var obj : Object = resultado.data[0] as Object;
this.usuario.cd_usuario = obj['cd_usuario'];
this.usuario.nm_usuario = obj['nm_usuario'];
this.usuario.ds_login = obj['ds_login'];
this.usuario.ds_senha = obj['ds_senha'];
} else {
Alert.show('Login incorreto');
}
}
}
public function btnTelaLogin_clickHandler() : void
{
this.vwStack.selectedIndex = 0;
}
public function btnCadastro_clickHandler() : void
{
var sqlQuery : String = "insert into [usuario] " +
"([nm_usuario], [ds_login], [ds_senha])" +
" values" +
"('" + this.txtCadNome.text + "', " +
"'" + this.txtCadUsuario.text + "'," +
"'" + this.txtCadSenha.text + "')";
this.sqlStm = new SQLStatement();
this.sqlStm.sqlConnection = this.sqlConn;
this.sqlStm.text = sqlQuery;
this.sqlStm.addEventListener(SQLEvent.RESULT, onQueryCadastroResult);
this.sqlStm.execute();
}
private function onQueryCadastroResult(event:SQLEvent) : void
{
Alert.show('Cadastro efetuado com sucesso');
this.vwStack.selectedIndex = 0;
}
]]>
Comentários