Air - ActionScript3 Clase para manejar SQLite.
25/03/2009
Voy compartir una clase que desarrollé que podría ser muy útil para todos los que trabajan con Air y SQLite (base local) o quieran hacerlo, ya que entre todos tenemos que hacer a esta maravillosa aplicacion conocida y destruir a Silverlight jaja (bromilla).. (o no..)

He estado rompiéndome la cabeza un poco para pasar los métodos que tengo de conexión de PHP a ActionScript 3, para poder manejar registros simples, como UPDATE, INSERT y SELECT desde una sola clase y lo he conseguido!!.

Voy a tratar de ser breve..
Desde ActionScript 3 la implementación es muuuuy simple.. en este caso trabajo desde Flex 3, vamos por pasos.

Primero, importamos la clase y hacemos la conexión, la clase automáticamente creará la base de datos si no existe:
import phoxer.DataManager.AirSqlManager;
 
private var database:AirSqlManager;
private function onComplete():void{
	database = new AirSqlManager("test.db");
}

----------------------------------------------

Segundo, creamos las tablas:
//CREAR LA TABLA
var campos:Object= new Object();
campos.id="INTEGER PRIMARY KEY  NOT NULL";
campos.titulo="TEXT";
campos.fecha="TEXT";
 
var tableTareasToCreate:Object= new Object();
tableTareasToCreate.tabla="tareas";
tableTareasToCreate.campos=campos;
database.createTable(tableTareasToCreate,insertTarea);
 

El metodo createTable(); utiliza 3 parametros.
1-El objeto con la información para crear la tabla.
2-La función a la que llama si se pudo crear la tabla o si ya existe.
3-La función a la que llama si se genero algun error en la creación de la tabla.
Terminaria devolviendo un query asi:
CREATE TABLE IF NOT EXISTS tareas (`titulo` TEXT,`id` INTEGER PRIMARY KEY NOT NULL,`fecha` TEXT)

----------------------------------------------

Tercero, Incertando un registro
//INSERTAR REGISTRO
var campos:Object= new Object();
campos.titulo="Registro 1";
campos.fecha="20/08/2009";
 
var dataToInsert:Object = new Object();
dataToInsert.tabla="tareas";
dataToInsert.datos=campos;
database.setInsert(dataToInsert,consultar);

el metodo setInsert(); utiliza 3 parametros.
1-El objeto con la información para hacer el insert.
2-La función a la que llama si se pudo hacer. (todabía no se como recuperar el ultimo id)
3-La función a la que llama si se genero algun error.
Terminaria devolviendo un query asi:
INSERT INTO tareas (titulo,fecha) VALUES ('Registro 1','20/08/2009')

----------------------------------------------

Cuarto, haciendo una consulta
//HACER UNA CONSULTA
var tableToConsult:Object= new Object();
tableToConsult.tabla="tareas";
tableToConsult.principal="id";
tableToConsult.orden="DESC";
database.setSelect(tableToConsult,leerDatos,onError);
 
 
private function leerDatos(dts:Array):void{
	for each(var dt:Object in dts){
		trace(dt.id+" "+dt.titulo+" "+dt.fecha);
	}
}
 
private function onError():void{
	trace("no se pudo hacer la consulta");
}
 

el metodo setSelect(); utiliza 3 parametros.
1-El objeto con la información para hacer la consulta.
2-La función a la que llama si se pudo hacer. devuelve un array de objetos con el resultado
3-La función a la que llama si se genero algun error.
Terminaria devolviendo un query asi:
SELECT * FROM tareas ORDER BY id DESC

Para hacer una consulta mas rigurosa:
//HACER UNA CONSULTA
var tableToConsult:Object= new Object();
tableToConsult.tabla="tareas";
tableToConsult.principal="id";
tableToConsult.orden="DESC";
tableToConsult.filtro="titulo";
tableToConsult.same="Registro";
database.setSelect(tableToConsult,leerDatos,onError);
 
 
private function leerDatos(dts:Array):void{
	for each(var dt:Object in dts){
		trace(dt.id+" "+dt.titulo+" "+dt.fecha);
	}
}
 
private function onError():void{
	trace("no se pudo hacer la consulta");
}
 

Si ven se agregaron dos opciones mas "filtro y same", esto nos va a devolver los registros cuando ejemplo: "titulo" sea igual a "Registro".
Terminaria devolviendo un query asi:
SELECT * FROM tareas WHERE titulo ='Registro' ORDER BY id DESC

----------------------------------------------

Quinto, haciendo una modificación:
//MODIFICAR UN REGISTRO
var datos:Object=new Object();
datos.titulo="Modificado";
datos.fecha="1/09/2009";
 
var registroAModificar:Object = new Object();
registroAModificar.tabla="tareas";
registroAModificar.datos=datos;
registroAModificar.campo="id";
registroAModificar.valor="3";
database.setUpdate(registroAModificar);

el metodo setUpdate(); utiliza 3 parametros.
1-El objeto con la información del registro que se va a modificar.
2-La función a la que llama si se pudo hacer.
3-La función a la que llama si se genero algun error.
Terminaria devolviendo un query asi:
UPDATE `tareas` SET `titulo`='Modificado',`fecha`='1/09/2009' WHERE id='3'

----------------------------------------------

Bien como vemos con esta clase se nos resulta muyyy facil conectarnos a una base de datos SQLite y manejarla, que les parece??..
Me faltan mas metodos a medida que voy mejorandola la voy subiendo.

haaa me olvidaba, aca esta la la clase AirSqlManager:
/**
Air SQLite Manager
By ::[PHOXER]::
http://www.phoxer.com
v 1.2;
*/
package phoxer.DataManager{
	import flash.data.SQLConnection;
	import flash.data.SQLResult;
	import flash.data.SQLStatement;
	import flash.errors.SQLError;
	import flash.events.SQLErrorEvent;
	import flash.events.SQLEvent;
	import flash.filesystem.File;
 
	public class AirSqlManager{
	private var conexion:SQLConnection;
	private var BDFile:File;
	private var State:SQLStatement = new SQLStatement();
	public function AirSqlManager(db:String,asy:Boolean=false){
		conexion = new SQLConnection();
		conexion.addEventListener(SQLEvent.OPEN,onDbOpen,false,0,true);
		conexion.addEventListener(SQLErrorEvent.ERROR,onDbError,false,0,true);
		BDFile=File.applicationStorageDirectory.resolvePath(db);
		trace("DB PATH: "+BDFile.nativePath)//path actual.
		trace("DB EXIST: "+BDFile.exists)//si existe la base.
		if(asy){
			conexion.openAsync(BDFile);
		}else{
			conexion.open(BDFile);
		}
	}
	private function onDbOpen(e:SQLEvent):void{
		trace("DB CONECTED")
		State.sqlConnection = conexion;
	}
	private function onDbError(e:SQLErrorEvent):void{
		trace("DB Error: SqlData: "+e)
	}
 
	public function createTable(Obj:Object,bk:Function=null,err:Function=null):void{
		var campos:Object=Obj.campos;
		var sql:String="CREATE TABLE IF NOT EXISTS "+Obj.tabla+" (";
		var cmp:String="";
		for(var dt:Object in campos){
			cmp+="`"+dt+"` "+campos[dt]+",";
		}
 
		cmp=quitarUltimaComa(cmp);
		sql+=cmp+")";
		trace(sql);
		State.text=sql;
		try{
			State.execute();
			if(bk!=null){
				bk();
			}
		}catch (e:SQLError){
			trace("CREATE ERROR: "+e);
			if(err!=null){
				err();
			}
		}
 
	}
 
	public function setSelect(Obj:Object,bk:Function=null,err:Function=null):void{
		var tabla:String=Obj.tabla;
		var principal:String=Obj.principal;
		var orden:String=Obj.orden;
		var filtro:String=Obj.filtro;
		var same:String=Obj.same;
		var like:String=Obj.like;
		var limite:String=Obj.limit;
		var select:String=Obj.select;
		//-limit
		limite=(limite!="" && limite!=null)? String(" LIMIT "+limite):"";
		//-Select
		select=(select!="" && select!=null)? String("`"+select+"`"):"*";
		//-SQL
		var sql:String;
		if(filtro!="" && filtro!=null && same!="" && same!=null) {
				sql="SELECT "+select+" FROM "+tabla+" WHERE "+filtro+" ='"+same+"' ORDER BY "+principal+" "+orden+" "+limite;
		}else if(filtro!="" && filtro!=null && like!="" && like!=null){
				sql="SELECT "+select+" FROM "+tabla+" WHERE "+filtro+" LIKE '%"+like+"%' ORDER BY "+principal+" "+orden+" "+limite;
		}else{
				sql="SELECT "+select+" FROM "+tabla+" ORDER BY "+principal+" "+orden+" "+limite;
		}
		trace(sql);
		State.text=sql;
		try{
			State.execute();
			if(bk!=null){
				var result:SQLResult = State.getResult();
				bk(result.data);
			}
		}catch (e:SQLError){
			trace("SELECT ERROR: "+e);
			if(err!=null){
				err();
			}
		}
	}
 
	public function setInsert(Obj:Object,bk:Function=null,err:Function=null):void{
		var datos:Object=Obj.datos;
		var sql:String="INSERT INTO "+Obj.tabla+" (";
		var campos:String="";
		var valores:String="";
		for(var dt:Object in datos){
			campos+=dt+",";
			valores+="'"+String(datos[dt])+"',";
		}
		campos=quitarUltimaComa(campos);
		valores=quitarUltimaComa(valores);
		sql+=campos+") VALUES ("+valores+")";
		trace(sql);
		State.text=sql;
		try{
			State.execute();
			if(bk!=null){
				bk();
			}
		}catch (e:SQLError){
			trace("INSERT ERROR: "+e);
			if(err!=null){
				err();
			}
		}
	}
 
	public function setUpdate(Obj:Object,bk:Function=null,err:Function=null):void{
		var tabla:String=Obj.tabla;
		var datos:Object=Obj.datos;
		var campo:String=Obj.campo;
		var valor:String=Obj.valor;
		var sql:String="UPDATE `"+tabla+"` SET "
		var sets:String="";
		for (var dt:Object in datos){
			sets+= "`"+dt+"`='"+String(datos[dt])+"',";
		}
		sets=quitarUltimaComa(sets);
		sql+=sets+" WHERE "+campo+"='"+valor+"'";
 
		trace(sql);
		State.text=sql;
		try{
			State.execute();
			if(bk!=null){
				bk();
			}
		}catch (e:SQLError){
			trace("INSERT ERROR: "+e);
			if(err!=null){
				err();
			}
		}
	}
 
	public function setDelete(Obj:Object,bk:Function=null,err:Function=null):void{
		var sql:String="DELETE FROM "+Obj.tabla+" WHERE "+Obj.campo+"='"+Obj.valor+"'";
		trace(sql);
		State.text=sql;
		try{
			State.execute();
			if(bk!=null){
				bk();
			}
		}catch (e:SQLError){
			trace("DELETE ERROR: "+e);
			if(err!=null){
				err();
			}
		}
	}
 
	private function quitarUltimaComa(st:String):String{
		return st.substr(0,-1);
	}
}
 



| ActionScript 3 | Air | SQLite
Share |


5 Comentarios.
26/03/2009

Excelente!!!! Muy buena! directo a mi repositorio de clases! muchas gracias por compartir!

Eliseo
07/04/2009

Hola Phoxer, te copy & paste un comentario mío escrito en CL

Reconozco que, igual que tiene buena pinta, no me gusta demasiado el modo de usar los argumentos. Personalmente (pero ya te digo que es sólo una opinión) haría que fueran muy parecidas a las instrucciones SQL, devolviendo valores, en lugar de estar "arriba y abajo" con las funciones. P.e.

public int function AirSqlManager(db:String,asy:Boolean=false)

devolvería 1 si se ha creado ó 0 si no se ha creado

Por otra parte me haría una Clase "Tabla", de modo que createTable sería más o menos

public Tabla function createTable(tabla:String,Obj:Object)

Devolviendo null caso de que no se haya podido crear la tabla.

A la hora de insertar/seleccionar/updatar usaríamos los objetos tabla y, de nuevo, devolvería argumentos. P.e.

//es un "método" de la clase Tabla.

public int function setInsert(Obj:Object)

//devuelve 1 si se ha insertado o 0 si no se ha insertado

Claro que cambia todo un poco, pero un programa podría...

Eliseo
07/04/2009

...quedar más o menos como

database:AirSqlManager = new AirSqlManager("test.db");

var campos:Object= new Object();

campos.id="INTEGER PRIMARY KEY NOT NULL";

campos.titulo="TEXT";

campos.fecha="TEXT";

titulos:Tabla=AirSqlManager.createTable("tareas",campos)

campos:Object= new Object();

campos.titulo="Registro 1";

campos.fecha="20/08/2009";

titulos.Insert(campos)

Pero ya te digo que es una "idea tocapelotas" (que quiere decir que sin ánimo de molestar, la "suelto" con el único fin de dar trabajo)

Slds.

07/04/2009

Gracias Eliseo, Te voy a mandar un mail y tambien te respondí en Cristalab.

Saludos.

enrique
31/03/2010

Hola Phoxer ! estoy tratando de hacer un programa q maneje BD con AIR, pero necesito que permita ejecutarse en una red, y con varios usuarios al mismo tiempo.

Sabes si esto es posible con AIR?

Saludos !


Canal Rss

Donar al blog de tutoriales de Phoxer.

----------------------------------------------


Si los tutoriales o los temas tratados en este blog te gustaron y quieres ayudarme a mantenerlos en linea puede hacer una donacion.
La donaciones son destinadas para mantener este blog y a los tutoriales Online.

Donar al blog de tutoriales de Phoxer.

Phoxer