Comunidad de diseño web y desarrollo en internet online

Cómo conectar AIR con una base de datos SQLite

En este tip explicaré brevemente cómo interactúa Adobe AIR con una base de datos SQLite, que es la que viene embebida con él. Gracias a ella, tenemos una herramienta potente para manejar datos en el sistema local sin tener que usar programas como MDMZinc o un lenguaje de servidor. Para explicar este tip crearé una simple aplicación AIR con Flex que insertara, y mostrara datos de una BD.

Lo primero será establecer conexión con la BD. Para ello, usaremos el siguiente código, que está explicado en los comentarios:

Código :

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
   creationComplete="init()" width="439" height="406" xmlns:local="*">
   <mx:Script>
      <![CDATA[
                import mx.controls.Alert; 
                import mx.collections.ArrayCollection;
                import flash.events.SQLEvent; //Evento que maneja las operaciones de los objetos SQLConnection o SQLStatement

                private var conn:SQLConnection; //Objeto que me permite hacer abrir la conexion con la BD.
                private var BDFile:File; //Variable que abrira y/o creara la bd.
                [Bindable] public var myDP:ArrayCollection;

                public function init()
                {
                         conn = new SQLConnection(); //Creo el objeto de conexion
   
                        //Listener del objeto connection para cuando se abrio la conexion con éxito
                       conn.addEventListener(SQLEvent.OPEN, 
                       function(event:SQLEvent):void
              {
               Alert.show("La conexion se realizo con exito :-)");
                    });
                       //Listener para cuando la conexion fallo
                  conn.addEventListener(SQLErrorEvent.ERROR, 
             function(event:SQLErrorEvent):void
             {
                Alert.show("Error de conexion --> "+event.error.message);
             });            

                      //Esta instruccion lo que me permite es abrir[si existe] o crear el fichero en el directorio de la aplicación.
                      BDFile = new File(File.applicationResourceDirectory.nativePath+"\\agenda.db"); 

                      conn.open(BDFile); //Le digo al objeto connection que abra el File.
}
</mx:WindowedApplication>



Si todo ha ido bien, el resultado debería ser el siguiente.



Noten que si el fichero agenda.db no existe, AIR lo crea, y si no, lo abre.

Ahora crearemos una función que nos construirá la estructura de la BD cuando el fichero no exista, es decir, para cuando se crea por primera vez.

Primero importamos un par de clases que nos harán falta para eso.

Código :

// Se usa para ejecutar una sentencia SQL en una BD que esta abierta con SQLConnection
                        import flash.data.SQLStatement;
                        private function createTable():void{
            
            var createObj:SQLStatement = new SQLStatement();  
            var strSQL:String = new String(); //Query de crear tabla
            strSQL = "CREATE TABLE IF NOT EXISTS datos(";
            strSQL += "user_id INTEGER PRIMARY KEY AUTOINCREMENT,";
            strSQL += "name TEXT,";
            strSQL += "adress TEXT,";
            strSQL += "phone NUMERIC";
            strSQL += ")";
            createObj.text = strSQL; //paso la query a SQLStatement.
                        
            createObj.sqlConnection = conn; //Paso la conexión.
            createObj.addEventListener(SQLEvent.RESULT,
               function(event:SQLEvent):void
               {
                  showData();
               });   
            createObj.addEventListener(SQLErrorEvent.ERROR, 
               function(event:SQLErrorEvent):void
               {
                  Alert.show("No se pudo crear la tabla ---> "+event.error.message);
               });         
                     
         createObj.execute(); //Ejecuto la query [la de crear tabla]
         }


A esta función debes llamarla desde el SQLEvent.OPEN de la función init.

Creamos una clase llamada datosVO, que no es mas que un valueObject que nos servirá solo para puro tramite de datos.

datosVo.as :

Código :

package
{
[Bindable]   
   public class datosVO
   {
      public var _name:String;
      public var _adress:String;
      public var _phone:uint;
   }
}


Ahora haremos un par de funciones más, una para hacer el INSERT y otra que nos hará el SELECT para llenar a myDB y mostrarlo en la vista:

Código :

              private function showData():void{
            var selectObj:SQLStatement = new SQLStatement();
            selectObj.sqlConnection = conn;  
            var strSQL:String = "SELECT user_id, name,adress, phone FROM datos"; 
            selectObj.text = strSQL; 
            
            selectObj.addEventListener(SQLEvent.RESULT,
               function(event:SQLEvent):void
               {
                  var res = (event.target as SQLStatement).getResult();
                  myDP = new ArrayCollection(res.data);
               });
            selectObj.addEventListener(SQLErrorEvent.ERROR, 
               function(event:SQLErrorEvent):void
               {
                  Alert.show("Result Error - "+event.error.message);
               });   
            selectObj.execute();
         }
         
         private function insertData(data:datosVO):void
         {
            var insertObj:SQLStatement = new SQLStatement(); //Creo el objeto SQLStatement.
            insertObj.sqlConnection = conn; //Le paso la conexion al objeto SQLStatement.
            var strSQL:String = new String();
            //Asigno el query...
            strSQL = "INSERT INTO datos (name, adress, phone) ";
            strSQL += "VALUES ('"+data._name+"','"+data._adress+"',"+data._phone+")";
            insertObj.text = strSQL; //le asigno la query al objeto SQLStatement.
            
            //Si paso algo, se ejecuta esta funcion.
            insertObj.addEventListener(SQLErrorEvent.ERROR,
               function(event:SQLErrorEvent):void{
                  Alert.show("No se pudo insertar los datos ---> "+event.error.message);
               }
            );         
            //Si se pudo efectuar la operacion se ejecuta esta funcion
            insertObj.addEventListener(SQLEvent.RESULT,
               function(event:SQLEvent):void{
                  //Como se que se inserto correctamente, actualizo el provider local..
                  myDP.addItem({name:data._name, adress:data._adress, phone:data._phone});
                  //Borro el formulario.. :-)
                  name_txt.text = "";
                  adress_txt.text = "";
                  phone_txt.text = "";
               }
            );      
            insertObj.execute(); //Ejecuto la query
         }


Bien ahora vayamos al mxml y hagamos nuestra simple vista.

Código :

<local:datosVO id="datosTemp">
      <local:_adress>{ adress_txt.text }</local:_adress>
      <local:_name>{ name_txt.text }</local:_name>
      <local:_phone>{ int(phone_txt.text) }</local:_phone>
   </local:datosVO>
   
   <mx:DataGrid x="10" y="10" width="399" height="248" id="datos" dataProvider="{ myDP }">
      <mx:columns>
         <mx:DataGridColumn headerText="Column 1" dataField="name"/>
         <mx:DataGridColumn headerText="Column 2" dataField="adress"/>
         <mx:DataGridColumn headerText="Column 3" dataField="phone"/>
      </mx:columns>
   </mx:DataGrid>
   <mx:Button x="10" y="362" label="Insertar" click="{ insertData(datosTemp) }" />
   <mx:TextInput x="87.5" y="266" id="name_txt"/>
   <mx:TextInput x="87.5" y="296" id="adress_txt"/>
   <mx:TextInput x="87.5" y="328" id="phone_txt"/>
   <mx:Label x="10" y="268" text="Nombre"/>
   <mx:Label x="10" y="298" text="Direccion"/>
   <mx:Label x="10" y="330" text="Telefono"/>


Y todo listo.

Codigo completo:

Código :

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
   creationComplete="init()" width="439" height="406" xmlns:local="*">
   <mx:Script>
      <![CDATA[
         import mx.controls.Alert; 
         import mx.collections.ArrayCollection;
         //Evento que maneja las operaciones de los objetos SQLConnection o SQLStatement
         import flash.events.SQLEvent; 
         
         //Objeto que me permite hacer abrir la conexion con la BD.
         private var conn:SQLConnection;
         
         //Variable que abrira y/o creara la bd.
         private var BDFile:File;
         
         [Bindable] public var myDP:ArrayCollection;
         
         public function init()
         {
         conn = new SQLConnection(); //Creo el objeto de conexion
            
            //Listener del objeto connection para cuando se abrio la conexion con éxito se vaya a la función onSuccess
            conn.addEventListener(SQLEvent.OPEN, 
               function(event:SQLEvent):void
               {
                  createTable();
               });
            //Listener para cuando la conexion fallo se vaya a la función onError
            conn.addEventListener(SQLErrorEvent.ERROR, 
               function(event:SQLErrorEvent):void
               {
                  Alert.show("Error de conexion --> "+event.error.message);
               });            
         //Esta instruccion lo que me permite es abrir[si existe] o crear el fichero en el directorio de la aplicación.
         BDFile = new File(File.applicationResourceDirectory.nativePath+"\\agenda.db");
         
         //Le digo al objeto connection que abra el File.
         conn.open(BDFile);
         }         
         
         private function showData():void{
            var selectObj:SQLStatement = new SQLStatement();
            selectObj.sqlConnection = conn;  
            var strSQL:String = "SELECT user_id, name,adress, phone FROM datos"; 
            selectObj.text = strSQL; 
            
            selectObj.addEventListener(SQLEvent.RESULT,
               function(event:SQLEvent):void
               {
                  var res = (event.target as SQLStatement).getResult();
                  myDP = new ArrayCollection(res.data);
               });
            selectObj.addEventListener(SQLErrorEvent.ERROR, 
               function(event:SQLErrorEvent):void
               {
                  Alert.show("Result Error - "+event.error.message);
               });   
            selectObj.execute();
         }
         
         private function insertData(data:datosVO):void
         {
            var insertObj:SQLStatement = new SQLStatement(); //Creo el objeto SQLStatement.
            insertObj.sqlConnection = conn; //Le paso la conexion al objeto SQLStatement.
            var strSQL:String = new String();
            //Asigno el query...
            strSQL = "INSERT INTO datos (name, adress, phone) ";
            strSQL += "VALUES ('"+data._name+"','"+data._adress+"',"+data._phone+")";
            insertObj.text = strSQL; //le asigno la query al objeto SQLStatement.
            
            //Si paso algo, se ejecuta esta funcion.
            insertObj.addEventListener(SQLErrorEvent.ERROR,
               function(event:SQLErrorEvent):void{
                  Alert.show("No se pudo insertar los datos ---> "+event.error.message);
               }
            );         
            //Si se pudo efectuar la operacion se ejecuta esta funcion
            insertObj.addEventListener(SQLEvent.RESULT,
               function(event:SQLEvent):void{
                  //Como se que se inserto correctamente, actualizo el provider local..
                  myDP.addItem({name:data._name, adress:data._adress, phone:data._phone});
                  //Borro el formulario.. :-)
                  name_txt.text = "";
                  adress_txt.text = "";
                  phone_txt.text = "";
               }
            );      
            insertObj.execute(); //Ejecuto la query
         }
         
         private function createTable():void{
            
            var createObj:SQLStatement = new SQLStatement();  
            var strSQL:String = new String(); //Query de crear tabla
            strSQL = "CREATE TABLE IF NOT EXISTS datos(";
            strSQL += "user_id INTEGER PRIMARY KEY AUTOINCREMENT,";
            strSQL += "name TEXT,";
            strSQL += "adress TEXT,";
            strSQL += "phone NUMERIC";
            strSQL += ")";
            createObj.text = strSQL; //paso la query a SQLStatement.
                        
            createObj.sqlConnection = conn; //Paso la conexión.
            createObj.addEventListener(SQLEvent.RESULT,
               function(event:SQLEvent):void
               {
                  showData();
               });   
            createObj.addEventListener(SQLErrorEvent.ERROR, 
               function(event:SQLErrorEvent):void
               {
                  Alert.show("No se pudo crear la tabla ---> "+event.error.message);
               });         
                     
         createObj.execute(); //Ejecuto la query [la de crear tabla]
         }

      ]]>
   </mx:Script>
   
   <local:datosVO id="datosTemp">
      <local:_adress>{ adress_txt.text }</local:_adress>
      <local:_name>{ name_txt.text }</local:_name>
      <local:_phone>{ int(phone_txt.text) }</local:_phone>
   </local:datosVO>
   
   <mx:DataGrid x="10" y="10" width="399" height="248" id="datos" dataProvider="{ myDP }">
      <mx:columns>
         <mx:DataGridColumn headerText="Column 1" dataField="name"/>
         <mx:DataGridColumn headerText="Column 2" dataField="adress"/>
         <mx:DataGridColumn headerText="Column 3" dataField="phone"/>
      </mx:columns>
   </mx:DataGrid>
   <mx:Button x="10" y="362" label="Insertar" click="{ insertData(datosTemp) }" />
   <mx:TextInput x="87.5" y="266" id="name_txt"/>
   <mx:TextInput x="87.5" y="296" id="adress_txt"/>
   <mx:TextInput x="87.5" y="328" id="phone_txt"/>
   <mx:Label x="10" y="268" text="Nombre"/>
   <mx:Label x="10" y="298" text="Direccion"/>
   <mx:Label x="10" y="330" text="Telefono"/>
</mx:WindowedApplication>


Espero les sirva de base para continuar con este tema.

Aquí tienen algunos links para investigar mas:


Saludos.

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate