Alters

Mostrando entradas con la etiqueta Pseudo - capa. Mostrar todas las entradas
Mostrando entradas con la etiqueta Pseudo - capa. Mostrar todas las entradas

La pseudo-capa: conectar todo

Esta será la útlima entrada de la creación de nuestro bridge aplicación - base de datos.

Ahora explicaré de que sirve tener las cosas como lo he ido explicando. Para este caso lo haré únicamente con JAVA (ya que es el código más portable).

Conectar todo

Imaginad que, como me pasó a mí, tenéis que crear una aplicación que conecte VB.NET con MySQL.
Para hacer esto hay un método; se descarga un paquete, se instala, se referencia en el proyecto... ¿Pero a la hora de hacer un instalador? Pues ahí surgen las dudas...

Pero, si tenéis una clase que conecta con mysql, recupera datos, los mete en objetos, y más cosas (como crear un XML, escapar las consultas, recuperar id...), ¿para qué hace falta ese plug-in?

Tan sencillo como modificar ligeramente nuestro código java para que recupere los parámetros por línea de comando, creamos un jar (si queréis) y lo metemos en una ruta fija. Luego desde VB.NET hacemos una llamada a la línea de comandos y voliá.

Yo esto lo hago bastante con un sistema de intercambio de ficheros; mi JAR acepta los parámetros de entrada para la query (id, datos, ...), y también una ruta.

Desde VB creo un fichero temporal con la siguiente sentencia:

Dim temp As String = My.Computer.FileSystem.GetTempFileName.ToString

Con esta variable, llamo a la consola, así (esto es solo un ejemplo):

Shell("java -jar " + GlobalsVar.IDAPath + " 0 " + temp + " 0", AppWinStyle.Hide, True)

Esto inicia una shell y le pasaría la siguiente cadena:

java -jar *direccion/Bridge.jar* 0 *temp* 0

Lo que incluyo entre ** son variables. En este caso mi JAR recibe tres parámetros: 0, fichero, 0. Esto le indica que tiene que hacer cierto select, y plasmar el resultado en XML en el fichero pasado.

Finalmente, desde VB leo el XML y hago con él lo que necesite.

Es una forma rápida de conectar varias cosas a la vez.

Otra utilidad que tiene es la de kernel. Para hacer algo así solo tenemos que definir todas las querys, hacer varios métodos (parse a XML, rellenar selecciones, hacer updates, deletes, enviar correos...), los que hagan falta para que sea algo completo; una vez está el proyecto java, lo conectamos a cualquier aplicación que hagamos, así solo tenemos que preocuparnos del front-end.

Espero que os haya gustado

Hasta la próxima!

La pseudo-capa: abstracción

Buenas de nuevo!

En esta entrega veremos cómo sacarle algo más de partido a nuestras funciones.
En este caso, intentaré no hacer dos versiones, sino hacer una especie de "pseudocódigo" que pueda ser entendido y extrapolado al lenguaje de programación que uséis.

- Abstracción de conceptos
    · Clases auxiliares
    · Tablas auxiliares

Clases auxiliares:

Clase auxiliar, para mí, es toda aquella que apoya el desarrollo de un proyecto, pero es "secundaria"; es decir, podríamos prescindir de ella.

Un ejemplo sería una clase que solo tuviera variables globales, cadenas de formato, métodos para formatear, sacar diferencias (por ejemplo añadir un porcentaje - IVA - a una cantidad)... todos estos métodos se podrían incluir en diversas clases que lo necesitaran, pero los metemos en un utilitario para no replicar código. Ésta se convierte en una clase auxiliar.

Así, para el IDA, podemos crear la clase auxiliar esbozada en la entrega anterior.
Pero, aparte, podemos hacer una serie de métodos que agilicen el proceso de montar listas de objetos, las selecciones...

Para ello hay varias cosas que podríamos hacer. Es obvio que esto son solo algunas de las cosas que se podrían hacer, y siempre aceptaré nuevos aportes.

 - Lista de select:

 Se puede crear una lista de selects, updates... (de SQL me refiero) y usar un índice único para invocarlos.

Un ejemplo:

SelectList = array("select * from personas", "update personas set telefono = 0")

Entonces solo tendríamos que llamar a SelectList[0] para usar la primera selección.

No obstante, como habréis visto, cosas tan generales (como hacer un set a todos los registros de personas) pueden no servir. Para arreglar esto, se pueden hacer varias cosas:

   * Sublistas de select:

Se puede hacer algo similar a ésto:

Select1 = array("select nombre, telf from personas where nombre like('", "');
Select2 = array("update personas set telefono=", " where id=");
SelectList = array(Select1, Select2);

function getSelect(int id, array values){
  String ret = "";
  Array aux = SelectList[id]
  for(i=0;i<length(aux);i++)
     ret = concat(aux[i], values[i]);

 return ret;
}

Como veis, haciendo una lista de listas se pueden intercalar valores. Esto produciría sentencias personalizadas, lo que es más útil. AVISO que esta función es un prototipo. Al copiar esta función es posible que tengáis que retocar algo (añadir un if, quitar algo innecesario...). Esto está hecho de manera rápida y en una sintaxis propia más del pseudocódigo.

Retomando el ejemplo de objetos de la anterior entrada

/*
$bridge = new MyBridge(); //suponiendo que la clase la llaméis así
$array = $bridge->execute("select curdate() from dual");
$bridge->disconnect();
*/

y, si este método lo metemos en nuestra clase Utilities, podríamos modificar lo anterior, y hacer:

bridge = new MyBridge(); //para lanzar SQL
array = bridge.execute(Utilities.getSelect(0, {{David}}); //hacemos un select, los {{ }} indican un inicio y //fin de "array rápido"
bridge.disconnect();

No obstante, tendríamos que tener una lista de objetos e ir iterando sobre "array" para crear objetos...

- Generador de objetos

Esta parte es posible que no funcione con ciertos lenguajes de programación, aunque siempre se puede hacer algo parecido (desde luego, en php, que es donde más se usa la base de datos funciona).

Supongamos que tenemos el siguiente objeto

Class Persona{
  private String nombre;
  private String apellido;
  private String telf;
  private int id;
}

podemos añadir un método, al que podemos llamar "setVal", que sea así:

function setVal(Array values){
 vars = array(&this.nombre, &this.apellido, &this.telf, &this.id);

  for(i=0;i<length(vars);i++)
  vars[i] = value[$i];
}

y voliá, como pasamos la dirección de memoria (puntero) de los atributos de la clase (por eso el &), se modifican los valores de la propia clase, desde cualquier sitio.

Por tanto, podríamos hacer, siguiendo con el ejemplo anterior:

for(i=0;i<length(array);i++){
 per = new Persona();
 per.setVal({{array.next()}}); //en php se tendría que hacer un mysql_fetch_array y arreglarlo un poco
 objArray.add(per);
}

¡Pero vayámos un poco más allá!

- Generador de array dinámico

Podemos crear en Utilities una función así:

/*
params:

[0] ->id sql
[1] ->parámetros para el id
[2] ->tipo de objeto
[3] -> patrón de llenado
*/
fill(Array params){
  Object o = new Object();
  Array ret = new Array();
  bridge = new MyBridge(); 
  array = bridge.execute(this.getSelect(params[0], params[1]);
  bridge.disconnect();

  if(params[2] == 1){
     o = new Persona();
  }

  for(i=0;i<length(array);i++){
  aux = array(); 
    for(j=0;j<strlen(params[3];j++){
       val = "";

       if(substr(params[3], i, 1) == 1)
         val = array[j];

       aux.add(val);
    }

  o.setVal(aux);
  ret.add(o)
 } 

 return ret;
}

Bien, parece confuso, pero veamos un ejemplo:

objArray = Utilities.fill({{0, {{David}}, 1, 1010}});

Esto llenaría con una lista de personas (porque le paso un 1), y solamente nombre y telf (1010), con el select 0.

Como digo, puede parecer confuso. Es cuestión de mirar bien el código, adaptarlo a vuestro lenguaje favorito (recomiendo php en este caso) e ir probando.

Creo que sacar un array con una sola función es algo que puede servir...

Tablas auxiliares:

Para no cargar las clases con un montón de arrays, se pueden crear una serie de tablas en nuestra base de datos (incluso en una aparte), y que contenga las listas de sentencias, agrupadas por un id, por ejemplo.

Solo sería cosa de modificar la función getSelect para que conectase con la tabla y recuperase los fragmentos, el resto sería todo igual.

De momento termino esta entrega aquí.

Es posible que la próxima sea una continuación de ésta, ya veré...

Hasta la próxima!

La pseudo-capa: generalizando


Hola de nuevo,

Vamos a empezar una nueva entrega de cómo crear esta pseudo-capa con la que llevo dando la brasa desde el primer día.

En la entrada anterior vimos cómo se conecta, pide y recogen datos tanto desde java como desde php a una base de datos mysql.

En esta entrada, os voy a comentar un poco en detalle la generalización de los coneceptos vistos anteriormente. Esto es para poder desarrollar con más rapidez, ya que tener que ir poniendo todo el código cada vez resultaría engorroso.

Parto de la base de que todo aquel que lee esto sabe lo que es una función y cómo funcionan.

Sin más, empecemos el siguiente punto!


- Generalizar: funciones y objetos
   · Crear las funciones
   · Crear los objetos


Crear las funciones

Con php

$con = null;
$connection = null;
$H = "localhost";
$U = "user"; //el que tengáis vosotros
$P = "pass"; //el password
$D = "database"; //la base de datos
$started = false;

function execute($sql){
 if(!$started){
  return null;
 }

 return mysql_query($sql) or die($sql."<br />
".mysql_error());
}

function getId(){
 if(!$started){
  return null;
 }

 return mysql_insert_id($con);
}

function getRowNum(){
 if(!$started){
  return null;
 }

 return mysql_affected_rows($this-&gt;con);
}

function connect($host, $usr, $pass){
 if(!$started){
  return $conection = mysql_connect($host, $usr, $pass);
 }else{
    return $con;
 }
}

function setdb($name, $database){
 return mysql_select_db($name, $database);
}

function free($launched){
 if($started){
  mysql_free_result($launched);
 }
}

function disconnect(){
 if($started){
  mysql_close($con);
   $started = false;
 }
}

function start(){
 if(!$started){
  $con = $connect($H, $U, $P);
  $connection = $setdb($D, $con);
  $started = true;
 }
}

Como veis, he declarado varias variables, que uso en las funciones. Además he añadido algunas funcinoes que pueden ser útiles. A continuación explico todas:

 - execute: ejecuta una sentencia sql (de cualquier tipo)
 - getId: retorna el último id insertado
 - getRowNum: retorna el número de filas afectadas por la última sentencia
 - connect: conecta a la base de datos
 - setdb: establece una base de datos. Es llamada desde connect
 - free: libera los recursos usados por la última sentencia
 - disconnect: desconecta de la base de datos
 - start: conecta a una base de datos dada.

Seguramente hayáis visto que no tienen mucha conexión entre sí. Esto es porque estas funciones están diseñadas para estar dentro de un mismo objeto.

Yo he quitado el tema de encapsulamiento (private, public...) así como constructores y demás. En la siguiente sección (objetos) veremos qué hacemos con esto.

Como último apunte, fijaros que he añadido algo de control con la variable "started", para evitar que se haga una conexión dos veces.

Con java


Connection connect(){
 Connection con = null;

 try{
         Class.forName("com.mysql.jdbc.Driver");

  con = DriverManager.getConnection("jdbc:mysql://localhost/db", "user", "pass");
 }catch (ClassNotFoundException e){
  //ToDo
 }catch (SQLException e){
  //ToDo
 }

 return con;
}

ResultSet ask(String     sql,
           Connection con){
 ResultSet rs = null;

 try{
  rs = con.createStatement().executeQuery(sql);
 }catch (SQLException e){
  //ToDo
 }

 return rs;
}


void execute (String     sql,
            Connection con){
 try{
  con.createStatement().executeUpdate(sql);
 }catch (SQLException e){
  //ToDo
 }
}



Crear los objetos

Como había escrito antes, las funciones precedentes iban a ser parte de un objeto. Para aquellos que no estén familiarizados con las clases, decir que se tienen que crear en un fichero aparte.

La estructura básica es:

Class clase{
  atributo1;
  atributo2:

  funcion1(){}
  funcion2(){}
}

Con php

Solo tenemos que crear la clase, un constructor que llame a start, y encapsular las funciones y atributos. Mis recomendaciones son:

 - Declarar $con como public, y el resto de atributos como private
 - Declarar connect y setdb como private, el resto public

¿Y cómo usaríamos la clase? Así:

$bridge = new MyBridge(); //suponiendo que la clase la llaméis así
$array = $bridge-&gt;execute("select curdate() from dual");
$bridge-&gt;disconnect();

Como se ve, se elimina bastante código, ya que en 3 líneas se hace prácticamente todo.

Con java

Connection con = null;
ResultSet  rs  = null;
String     sql = "select curdate() from dual";

try{
 con = this.connect();
 rs  = this.ask(sql, con);
 
 try{
  while(rs.next())
   //ToDo
         }catch (SQLException e){
              //ToDo
         }
}catch (ParseErrorException e){
     //ToDo
}


Aquí el código también se ve más limpio y el desarrollo se puede hacer más rápido.

En la siguiente entrada entraré más en detalle en la creación de clases y tablas auxiliares para generalizar todo el código y hacer que la programación sea más fácil.

Hasta la próxima!

la pseudo-capa: primeros pasos


Aquí estoy de nuevo,

Voy a empezar con el bridge, tal como escribí en la anterior entrada.
Pero antes me gustaría hacer un poco de presentación.

Soy David, actualmente vivo en Cataluña. Soy técnico superior en desarrollo de aplicaciones informáticas; también poseo un título de técnico experto en COBOL. Actualmente estoy en proceso de obtener una certificación ISPA (Informatino Security Profesional Acreditation). En cuanto termine la acreditación (o incluso antes) empezaré un bachelor. Mi idea es terminarlo (son tres años), hacer un curso puente para conseguir el título de grado en ingeniería informática (esto es opcional), luego algún master(preferiblemente en IA), y finalmente doctorarme.

Se que es mucho suponer que todo saldrá así, pero bueno.

Empecemos con el bridge!

- Primeros pasos
   · Conectando una aplicación a mySql
     * php -> mySql
     * java -> mySql
   · Lanzar peticiones a mySql
   · Recuperar los datos

Conectarse a mySql

Lo primero es conectarse a mySql. Lo veremos desde dos lenguajes diferentes: php y java. Esta norma se aplicará a casi toda la construcción del puente.

Desde php:

$connection = mysql_select_db(nuestra_database, ($con = mysql_connect("localhost", user, pass)));

Una aclaración: normalmente siempre trabajamos en local, por eso conectamos en "localhost".

Desde java:

Para conectar desde java, primero tenemos que tener el driver de conexión (en la página de mysql está para bajar gratis).

Una vez bajado, añadimos una referencia a nuestro proyecto, e incluímos "import java.sql.*;" en la sección de imports de nuestra clase.

Para conectar, podemos hacer lo siguiente:


Connection con = null;

try{
Class.forName("com.mysql.jdbc.Driver");

con = DriverManager.getConnection("jdbc:mysql://localhost/database", user, pass);
}catch (ClassNotFoundException e){
//ToDo
}catch (SQLException e){
//ToDo
}

Lanzar peticiones

Con esto me refiero a ejecutar sentencias SQL, tanto select, como update, delete...

Lo primero, decir que las peticiones, dentro de php y java, se dividen en dos grupos: los SELECT, y el resto. Esto es debido a que el SELECT retorna algo, y el resto no (aunque luego se pueden recuperar datos de ellos, como el número de filas afectadas).

Desde php

$result = mysql_query(sentencia);

$result se pondría solo para los select. Para limpiar los resultados, tendríamos que ejecutar:

mysql_free_result($result);

Desde java


ResultSet rs = null;

try {
rs = con.createStatement().executeQuery(sql);
} catch (SQLException e) {
//ToDo
}

Para los select, y para el resto:


try{
con.createStatement().executeUpdate(sql);
}catch (SQLException e){
//ToDo
}

Recuperar datos

Los datos quedan recuperados, en el Select, en sendas variables "$result" y "rs".

Sin embargo, para accesar los datos tenemos que emplear métodos nativos de php y java:

Para este punto necesitamos una serie de datos concretos.

  - Sentencia ejecutada: "select nombre, apellido, telf from usuarios";
  - Estructura de datos:
      * nombre: varchar(100)
      * apellido: varchar(100)
      * telf: int(9)

Desde php

$nom = "";
$ape = "";
$tel = 0;

while($row = mysql_fetch_array($res)){
   $nom = $row[0];
   $ape = $row['apellido'];
   $tel = $row[2];
}

Como se ve, se puede acceder por índice (empezando de 0), o por el nombre del campo. Esto último, cabe remarcar que si, por ejemplo, escribirmos "select nombre, concat(apellido, ' ' coalesce(telf, 'no tiene')) from usuarios", el equvalente a "$row[1]" sería "$row['concat(apellido, ' ' coalesce(telf, 'no tiene'))']".

Desde java



try {
while(rs.next()){
            String name = new String(rs.getString(1));
            String sName = (String)rs.getObject(2);
            int telf = rs.getInt(3);
        }
}catch (SQLException e){
//ToDo
}

Como se ve, aquí se accede por índice, y mediante métodos varios: los getXXX. Si no sabemos exactamente qué recuperamos, podemos hacer un getObject, y luego hacer un cast. En caso de saberlo, podemos hacer un getString, o getInt, o getDate...

Remarcar que el índice de acceso empieza por 1, no por 0.


Aquí termina la primera parte, quizás la más corta. En la siguiente entrada trataremos las funciones y objetos.

Hasta la próxima!