- EL CONOCIMIENTO ES Y DEBE SER LIBRE -

viernes, abril 09, 2010

Windows Communication Foundation una Vision Practica

En este pequeño ejemplo mostraremos como se consume un servicio WCF el libro de referencia que estoy utilizando es “Microsoft  .NET Framework 3.5 Windows Communication Foundation” del kit de entrenamiento, hay bastante teoría sobre este tema pero mi intención es mostrar la parte practica del asunto (mas que practica diria incentivadora!!! ).
  1. Primero crearemos una clase en c# le agregaremos algunas atributos ([servicecontract],[operationcontract], entre otros) y esta clase ya es un servicio.
  2.  Este servicio debe estar alojado en algún lugar, para que el cliente pueda consumir el servicio.  Hay varias formas de hospedar un servicio, yo usare la más sencilla que es utilizando una aplicación de consola (normalmente utilizado en la fase de desarrollo), acá caí la primera vez y se explicara con mayor detenimiento en las próximas entradas!!!
  3.  El Cliente tiene que consumir el servicio (mediante clases proxyes) .NET hace el consumo de un servicio extremadamente sencillo sola haciendo uso de una sencilla referencia al servicio y listo utilizamos un servicio como de una clase se tratara.
Debido que explicar esto en modo texto sería bastante complicado; ya que,  hago uso intensivo de las herramientas que me proporciona Visual Studio es que he decido colocarlo en un video este primer ejemplo.




Bueno tengo en mi libreria digital los siguiente libros electronicos WCF:
  1. "Inside Microsoft Windows Communication Foundation", Justin Smith, Ed. Microsoft Press.
  2. "Microsoft .NET Framework 3.5 Windows Communication Foundation (MCTS 70-503 Training Kit)", Ed. Microsoft Press. 
  3.  "Essential Windows Communication Foundation", Steve Resnick,Richard Crane, Ed. Addison Wesley
  4. "Pro WCF: Practical Microsoft SOA Implementation", Chris Peiris and Dennis Mulder, Ed. Apress
  5. "Microsoft Windows Communication Foundation Step by Step", Jhon Sharp, Ed. Microsoft Press.
  6. "Windows Communication Foundation Unleashed", Craig McMurty, Marc Mercuri, Nigel Waitling Matt Winklet, Ed. Sams Publishing.
  7. "Programming WCF Services". Juval Lowy, Ed. O'Really.
  8. "Professional WCF Programming: .NET Development with the Windows Communication Foundation", Scott Klein, Ed. Wiley Publishing, Inc.
  9. "Microsoft Windows Communication Foundation Hand On Beta Edition", Craig McMurty, Marc Mercuri, Nigel Watling, Ed. Sams
Desde luego que si necesitan alguno solo enviar a mi e-mail el respectivo requerimiento.

miércoles, febrero 03, 2010

Cargar múltiples modelos con Doctrine

Doctrine nos brinda la posibilidad de partir nuestro “modelo” en varios “sub-modelos” consiguiente con esto separar la lógica del negocio.
/******** Archivo bootstrap.php **********************/
require_once(dirname(__FILE__) . '/doctrine-1.2.1/Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));

$pathmodels=array();
array_push($pathmodels,dirname(__FILE__)."/models/cayetano");
array_push($pathmodels,dirname(__FILE__)."/models/plantillas");

Doctrine::loadModels($pathmodels);

$dsn = 'pgsql:dbname=cayetano;host=127.0.0.1';
$user='postgres';
$password='123456';

//$dbh = new PDO($dsn, $user, $password);
$conn = Doctrine_Manager::connection(array($dsn, $user, $password));

En el ejemplo anterior dentro de la carpeta "models” se ha creado la carpeta “cayetano” y la carpeta “plantillas”.

martes, febrero 02, 2010

Multiples Base de Datos con Doctrine

Cuando queremos intercambiar la conexión entre dos o más base de datos en la misma aplicación, lo podemos realizar modificando el archivo bootstrap.php:
/************** Archivo bootstrap.php **********************/
require_once(dirname(__FILE__) . '/doctrine-1.2.1/Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));

Doctrine::loadModels('models');

$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL); 
$manager->setAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, true);

$dsn = 'pgsql:dbname=cayetano;host=127.0.0.1';
$user='postgres';
$password='123456';
//nombramos a esta conexion como 'cayetano'
$conn = Doctrine_Manager::connection(array($dsn, $user, $password),'cayetano');

$dsn = 'pgsql:dbname=documentacion;host=127.0.0.1';
$user='postgres';
$password='123456';
//nombramos a esta conexion como 'documentacion'
$conn = Doctrine_Manager::connection(array($dsn, $user, $password)),'documentacion');

Para probar el uso lo podemos hacer del siguiento modo:

/************** archivo prueba.php **********************/
require_once('bootstrap.php');

$manager = Doctrine_Manager::getInstance();
$manager->setCurrentConnection('cayetano');
 //Accedemos a la BD cayetano
 $q = Doctrine_Query::create()
  ->select('t.*,u.log_usu,u.pass_usu')
  ->from('Trabajador t')
  ->innerJoin('t.UsuIntranet u');
    
 print_r($q->execute(array(),Doctrine::HYDRATE_ARRAY));
 
$manager = Doctrine_Manager::getInstance();
$manager->setCurrentConnection('documentacion');
 //Accedemos a la BD documentacion
 $q = Doctrine_Query::create()
    ->from('Empleado d')
    ->leftJoin('d.EmpleadoCargo g')    
    ->leftJoin('g.Cargo h')
    ->leftJoin('h.Oficina w')    
    ->where('d.idusuario = ?', $idUsuario)
    ->orderBy('w.descripcion,h.descripcion,g.id');
 
 print_r($q->execute(array(),Doctrine::HYDRATE_ARRAY));

jueves, enero 28, 2010

Modelando con Doctrine parte III

Teniendo el modelo de clases del post anterior procederemos a construir los métodos modificando el bootstrap.php y quedando del siguiente modo:
/***** bootstrap.php **********/
require_once(dirname(__FILE__) . '/doctrine-1.2.1/Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));

Doctrine::loadModels('models');

$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL); //ACTIVAMOS LAS VALIDACIONES DE DOCTRINE
$manager->setAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, true);//PARA LA CREACION DE LOS METODOS

$dsn = 'mysql:dbname=comercial;host=127.0.0.1';
$user='root';
$password='123456';

$conn = Doctrine_Manager::connection(array($dsn, $user, $password));

La línea 9 le dice a Doctrine que cargué unas clases que vamos a crear en donde implementaremos los métodos. Estas clases deben de tener la siguiente forma [nombreClase]Table y las colocaremos dentro de la carpeta “models”.
En nuestro ejemplo en particular crearemos la clase UsuarioTable.
/**** UsuarioTable.php *******/
class UsuarioTable extends Doctrine_Table
{
public function GetAllUsuarios()
{
$q=Doctrine_Query::create()
->from('Usuario u')
->execute();
return $q->toArray();
}
public function GetAllCargosByOficina($idUsuario,$idOficina)
{
$q=Doctrine_Query::create()

->from('Oficina o')
->leftJoin('o.Cargo c')
->leftJoin('c.Asignacion a')
->leftJoin('a.Empleado e')
->leftJoin('e.Usuario u')
->where('o.id=?',$idOficina)
->andWhere('u.id=?',$idUsuario) 
->execute();

return $q->toArray(true); 
}
public function GetAllCargos($idUsuario)
{
$q=Doctrine_Query::create()

->from('Cargo c')
->leftJoin('c.Asignacion a')
->leftJoin('a.Empleado e')
->leftJoin('e.Usuario u')
->where('u.id=?',$idUsuario)

->execute();
return $q->toArray(true); 
}
}

Para probar el funcionamiento crearemos un archivo pruebaUsuario.php
/******** pruebaUsuario.php***********/
require_once("bootstrap.php");

$obj= Doctrine::getTable("Usuario");

print_r($obj->GetAllCargos(1));

print_r($obj->GetAllCargosByOficina(1,1));

Haciendo uso de DQL podemos ver que la consultas son bastante sencillas y demandan poco esfuerzo, la clave aquí es el método “toArray()” este método es una forma de serializar (Hydration, en realidad hay muchas formas de hydration) los datos en forma de arrays(objetos). El método “toArray()” puede recibir un parámetro booleano si este es false, nos mostrara el resultado teniendo en cuenta los “join” realizados en la consulta DQL. En caso sea true ocurrirá lo contrario.
Si es que estas trabajando por capas estos resultados hidratados son los que fluyen entre capas.
En mi particular experiencia si estas utilizando el patrón MVP (Model View Presenter) a estos datos hidratados le pasas la función “encode_json()” y se lo envías a la Vista (DHTMLX, GWT,FLASH, etc)
figura 1: MVC vs MVP

Quiero contarles que ahora esto muy metido en GWT (Google Web Toolkit) espero empezar a postear acerca de esta maravillosa idea de la gente de Google.

jueves, enero 07, 2010

Modelando con Doctrine parte II

figura 1
El modelo de clases de la figura 1 debemos de traducirlo a un formato YAML (un esquema que te permite administrar tus modelos de mapeo) para que doctrine genere el modelo de mapeo respectivo a partir de este. Pero como la mayoría de las personas (me incluyo) inmediatamente creamos nuestro modelo E/R y lo reflejamos en la BD elegida, a partir de ahí realizamos la ingeniería inversa que nos generara el mapeo respectivo.
Si Uds. se fijaron en el modelo de clases hay una relación de uno a uno (entre Usuario y Empleado) eso evidentemente va a generar proble mas en algunas BD, nosotros queremos que nuestra aplicación sea independiente de la BD, además que también podríamos tener una relación de mucho a muchos. Entonces la solución está en crear un YAML y partir de este generar el modelo de mapeo y como último paso crear la BD que hayamos elegido.

Para continuar necesitamos definir un estructura de proyecto del siguiente modo:

figura 2

En "data" se encontrara la data a llenar a la BD ( te la bajas de aquí ), en "models" se encuentra el modelo a mapear, en "yaml" se encuentra el esquema(te lo bajas de aquí). El archivo cli.php debe de lucir así:
/***** ARCHIVO CLI.PHP *****/
require_once(dirname(__FILE__) . '/doctrine-1.2.1/Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));

$dsn = 'mysql:dbname=comercial;host=127.0.0.1';
$user='root';
$password='123456';

$conn = Doctrine_Manager::connection(array($dsn,$user,$password));

$config = array('data_fixtures_path' => 'data',
'models_path' => 'models',
'migrations_path' => '',
'sql_path' => '',
'yaml_schema_path' => 'yaml');

$cli = new Doctrine_Cli($config);
$cli->run($_SERVER['argv']);
Doctrine brinda una interfaz de línea de comandos (CLI) que nos va a facilitar la creación de la BD, así como la generación del esquema y también los modelos a mapear.
  • Generamos el modelo: "c:\appserv\www\blogspot\php cli.php generate-models-yaml"
  • Creamos la BD: "c:\appserv\www\blogspot\php cli.php create-db"
  • Creamos las Tablas: "c:\appserv\www\blogspot\php cli.php create-tables"
  • Llenamos con Data: "c:\appserv\www\blogspot\php cli.php load-data"
OJO: Cuando generes el modelo no te olvides de añadir los "require_once" correspondientes.
/*** ARCHIVO BOOTSTRAP.PHP *****/
require_once(dirname(__FILE__) . '/doctrine-1.2.1/Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));

$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL); //ACTIVAMOS LAS VALIDACIONES DE DOCTRINE
$manager->setAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, true);//PARA LA CREACION DE LOS METODOS

$dsn = 'mysql:dbname=comercial;host=127.0.0.1';
$user='root';
$password='123456';

$dbh = new PDO($dsn, $user, $password);
$conn = Doctrine_Manager::connection($dbh);

Los beneficios de generar la BD a partir de YAML son los siguientes:

  • Independencia de la BD.
  • Se esquematiza las relaciones uno a uno y mucho a muchos
  • Se esquematiza la herencia (podemos escoger como queremos que la herencia, de las múltiples formar que hay, sea implementada en la BD)
  • Se esquematiza la jerarquía de datos.


Debo de confesar que me da pereza aprender YAML ya me acostumbre a tratar el modelo mapeado directamente (clases php) yo normalmente hago lo siguiente:

  • Genero el Modelo E/R a partir del modelo de clases.
  • Creo la BD con sus respectivas relaciones y restricciones.
  • Creo el modelo de mapeado a partir de la BD.
  • Modifico a mano el modelo mapeado(relaciones one to one, many to many entre otros)

En el siguiente post implementaremos los métodos del modelo de clases

miércoles, diciembre 30, 2009

DHTMLX EN ACCION

Cuando programe por primera vez en la web (hasta ese momento solo lo había hecho en ambiente de escritorio) lo realice en una empresa que había hecho su propio framework Web UI, desde luego muy poderosos los componentes, pero esta carecía de documentación y ejemplos, creo que después de esa ingrata experiencia me aterraba programar con componentes Ajax, pero gracias a un amigo (Ivan Yaco) que me presento y convenció que estos componentes eran todo lo contrario y en verdad la experiencia fue muy grata, es por esto que invito a que lo prueben.

Los componentes javascript DHTMLX (la edición Standard tiene licencia GPL) nos permiten crear aplicaciones RIA bastante interesantes con muy poco esfuerzo. DHTMLX tiene una extensa documentación y muchos ejemplos en su website, que es lo que realmente necesitamos cuando queremos programar. Les recomiendo bajar toda la documentacion y sobre todo los ejemplos a la Pc. no me cansare de mencionar que los ejemplos son bastante explicativos y junto con Doctrine les facilitara la vida enormemente.
En mi experiencia personal al cabo de una semana ya tuve dominio de estos componentes.
El vídeo mostrado corresponde a una versión de prueba de un sistema de documentación que se realizo con DHMLX junto con Doctrine. En los siguientes posts mostrare un ejemplo completo de una aplicación.



miércoles, diciembre 09, 2009

Modelando con Doctrine Parte I

Si tenemos una Base de Datos relacional ya implementada podemos mapear la DB con Doctrine y empezar a utilizar toda su potencia (para verificar la instalacion de Doctrine dirigete aqui ).El archivo generarModels.php nos permitirá generar el mapeo correspondiente:

/*
Archivo generarModels.php
*/
require_once(dirname(__FILE__) . '/Doctrine-1.2.0/lib/Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));

/* Nos conectamos a la DB*/
$dsn = 'mysql:dbname=comercial;host=127.0.0.1';
$user='root';
$password='123456';
/* Conexion a postgre
$dsn = 'pqsql:dbname=comercial;host=127.0.0.1';
$user='postgres';
$password='123456';
*/
$dbh = new PDO($dsn, $user, $password);
$conn = Doctrine_Manager::connection($dbh);
/* Metodo que nos genera los modelos */
Doctrine_Core::generateModelsFromDb('carpetaDeModelos');


Enseguida procedemos a ejecutar el archivo generarModels.php (http://localhost/generarModels.php) y tendremos en la carpeta "carpetaDeModelos" los modelos para empezar a probar Doctrine.
Ahora procedemos a modificar el archivo bootstrap.php y creamos el archivo dqlTestDoctrine.php. Por Favor, antes de ejecutar dqlTestDoctrine.php dirígete a la clase generada y añade require_once según corresponda, en mi caso, quedo así:


/**
* Cliente
*
* This class has been auto-generated by the Doctrine ORM Framework
*
* @package    ##PACKAGE##
* @subpackage ##SUBPACKAGE##
* @author     ##NAME## <##EMAIL##>
* @version    SVN: $Id: Builder.php 6820 2009-11-30 17:27:49Z jwage $
*/
require_once('generated/BaseCliente.php');
class Cliente extends BaseCliente {  }  


/*
Archivo dqlTestDoctrine.php
*/
require_once('bootstrap.php')/*extremadamente importante*/
$q=Doctrine_Query::create()
->select('u.*')   /*todos los campos*/
->from('Cliente  u'); /*selecionamos la clase Cliente*/

print_r($q->execute()->toArray()); /*nos muestra el resultado como un array*/


/*
Archivo bootstrap.php
*/
require_once(dirname(__FILE__) . '/Doctrine-1.2.0/lib/Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'))

Doctrine::loadModels('carpetaDeModelos');

$dsn = 'mysql:dbname=comercial;host=127.0.0.1';
$user='root';
$password='123456';

$dbh = new PDO($dsn, $user, $password);
$conn = Doctrine_Manager::connection($dbh);


En mi particular experiencia esta ingeniería inversa tiene algunos inconveniente(por lo menos en postgreSQL) que son los siguientes:
  1. Cuando se encuentran claves primarias compuestas el modelo generado solo mapea una clave primaria, entonces hay que modificar a mano en el modelo generado colocando como clave primaria la clave que obvio Doctrine.
  2. Si están trabajando con PosgreSql y estas utilizando esquemas entonces tendrás que modificar en el modelo generado el nombre de la tabla mapeada anteponiendo el nombre del esquema.

Lo anteriormente mencionado no significa que Doctrine tenga bugs, lo que ocurre es que Doctrine esta optimizado para crear el modelo (que cuenta con relaciones de mucho a muchos, uno a mucho y uno a uno, entre otros elementos adicionales) y a partir del modelo crear la BD (Mysql, PostgreSql, Oracle, SqlServer, etc.)

En el siguiente post crearemos un modelo y empezaremos a utilizar DQL(Doctrine Query Language)





sábado, diciembre 05, 2009

Instalando Doctrine 1.2

Instalar Doctrine 1.2 es bastante sencillo.
  1. Bajamos el Appserv 2.5.9.
  2. Ejecutamos el Appserv 2.5.9 (que nos instala apache, php y mysql).
  3. Verificamos que la version de PHP>=5.2.3+
  4. Habilitamos PDO(Php Data Objects), nos dirigimos a php.ini y añadimos las siguientes lineas:
  5. extension=php_pdo.dll
    extension=php_pdo_pgsql.dll
    extension=php_pdo_mysql.dll
    
  6. Reiniciamos el Servidor Apache.
  7. Bajamos Doctrine 1.2 de aquí.
  8. Descomprimimos Doctrine 1.2 en c:\appserv\www
Siguiente los pasos anteriores ya se debió instalar Doctrine 1.2.
Para verificar la instalación creamos un archivo nombrandolo como bootstrap.php (c:\appserv\www\bootstrap.php)

/*
En los siguiente post haremos referencia a este archivo bootstrap.php
*/
require_once(dirname(__FILE__) . '/Doctrine-1.2.0/lib/Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));
$manager = Doctrine_Manager::getInstance();

Ahora que ya tenemos bootstrap.php procedemos a crear el archivo TestDoctrine.php (c:\appserv\www\TestDoctrine.php)
/*
Probamos que doctrine se instalo correctamente
*/
require_once('bootstrap.php');
echo Doctrine_Core::getPath();
Ahora ejecutamos el archivo TestDoctrine.php (http://localhost/TestDoctrine.php) y nos debe de mostrar la ruta de instalación de Doctrine. La cual significa que Doctrine se instalo satisfactoriamente.

martes, octubre 27, 2009

Doctrine ORM


En este post quiero hablar de un extraordinario ORM para PHP.
Me estoy refiriendo a Doctrine, los que vienen de .NET o Java me comprenderán.
Es que acaso existe la posibilidad de realizar sistemas con PHP, pues conocemos que PHP es un lenguaje bastante light enfocado para web site, principalmente.
Pero a medido que conozco Doctrine(object relational mapper) y Symfony(framework) puedo asegurar que si, es posible, con sus limitaciones pero posible. Si amigos no es tan descabellado.!!!!
Algunas cosas por la que elijo Doctrine son, entre otras, las siguientes:

  • DQL algo similar a HQL de Hibernate.
  • Zend Framework (Zend_Entity) se rindio ante Doctrine.
  • Una extraordinaria comunidad de desarrolladores.
  • Una documentación bastante completa a libre disponibilidad (free).


En fin, estoy muy emocionado por haber encontrado algo tan bien pensado que me facilito la vida enormemente en el desarrollo de una aplicación con capas cuyo cliente se desarrollo en JavaScript específicamente utilice DHTMLX cuya documentación también esta bastante extensa, luego hablaremos de estos componente Web UI.


Nota: Uno de los motivos por los que no posteo es precisamente mi ortografía y la vergüenza de cometer u ofender a algunos lectores espero su comprensión y desde luego la correcciones son bien acogidas.