RSS

Mono + NHibernate + SQLite

martes, 4 de noviembre de 2008


Después de usar por tanto tiempo Gentle.NET, un ORM que ha sido discontinuado, he decidido al fin comenzar a estudiar NHibernate. Los ejemplos que dan en los manuales y páginas son para Windows (con MS .NET) y SQL Server. Trabajando en GNU/Linux, hice las pruebas con SQLite.

El problema es que el driver utilizado por NHibernate para esta base de datos utiliza un binding desactualizado. Además Mono trae una implementación mejor, que soporta el standard ADO.NET 2.0, que es Mono.Data.Sqlite, disponible a partir de la versión 1.2.4.

El post es especialmente útil para aquellos que quieran utilizar en GNU/Linux (yo uso Ubuntu Gutsy), con Mono, NHibernate y SQLite, utilizando el binding Mono.Data.Sqlite. Si bien puede parecer esto tan fácil como seguir el documento QuickStart y cambiar las opciones correspondientes, no lo es si se intenta utilizar SQLite. Por eso, en este post no voy a explicar todas las cosas, ya que no me interesa y se pueden aprender en la documentación, sino que voy a desarrollar un ejemplo muy sencillo y mostrar cómo utilizar SQLite, ya que hay que solucionar unos problemas no muy triviales.

Cabe aclarar que, si bien todavía no lo he probado, los archivos de mapeo (hbm.xml) y el schema SQL se pueden autogenerar.

Primero creo la tabla que almacenerá los objetos en un archivo llamado, por ejemplo, data.db.sql:

DROP TABLE IF EXISTS personas;

CREATE TABLE personas (
id integer PRIMARY KEY,
nombre varchar(20),
apellido varchar(20)
);

Para el ejemplo utilicé la última versión de SQLite. Para crear la base de datos en el archivo data.db, ejecutamos:

$ sqlite3 data.db <>

La clase de ejemplo (Persona.cs):

using System;

namespace PruebaNHibernate
{
public class Persona
{
private int id;
private string nombre;
private string apellido;

public Persona()
{
}

public int Id {
get { return id; }
set { this.id = value; }
}

public string Nombre {
get { return nombre; }
set { this.nombre = value; }
}

public string Apellido { get { return apellido; } set { this.apellido = value; } } } }

Luego hay que escribir el archivo de mapeo, que es un XML.
version="1.0" encoding="utf-8" ?>
xmlns="urn:nhibernate-mapping-2.2"
namespace="PruebaNHibernate" assembly="PruebaNHibernate">


name="Persona" table="personas">
name="Id" column="id" type="Int32">
class="increment" />
>

name="Nombre" column="nombre" />
name="Apellido" column="apellido" />
>
>

Este archivo se debe agregar como recurso en MonoDevelop.

Luego escribimos el archivo de configuración para nuestra aplicación (app.config):

<?xml version="1.0" encoding="utf-8" ?>
>
>
name="nhibernate"
type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />

>

>

key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider"
/>


key="hibernate.dialect"
value="NHibernate.Dialect.SQLiteDialect"
/>


key="hibernate.connection.driver_class"
value="PruebaNHibernate.MonoDataSqliteDriver, PruebaNHibernate"
/>


key="hibernate.connection.connection_string"
value="Data Source=data.db,version=3"
/>


key="hibernate.query.substitutions"
value="true=1;false=0"
/>


key="hibernate.use_prox y_validator"
value="false"
/>

>
>

Nota: Debido a problemas con el hosting no puedo colocar, arriba, el string correcto en la última parte. La palabra prohibida “p r o x y” (sin espacios) tiene un espacio de más entre la “x” y la “y”. En fin, deshabilito en esas lineas la comprobación de clases p r o x y.

Luego en un archivo como Main.cs agrego código en el método principal Main para jugar con todo esto:

using System;
using NHibernate;
using NHibernate.Cfg;

namespace PruebaNHibernate
{
class MainClass
{
public static void Main (string[] args)
{
Configuration conf = new Configuration();
/* Con la siguiente línea leo todo los archivos con extensión
* hbm.xml embebidos como recurso en el assembly especificado */

conf.AddAssembly("PruebaNHibernate");

ISessionFactory sessionFactory = conf.BuildSessionFactory();

ISession s = sessionFactory.OpenSession();

ITransaction tx = s.BeginTransaction();

Persona p = new Persona();
p.Nombre = "Milton";
p.Apellido = "Pividori";
s.Save(p);
tx.Commit();

Console.WriteLine("p - Id: " + p.Id);
Console.WriteLine("p - Nombre: " + p.Nombre);
Console.WriteLine("p - Apellido: " + p.Apellido);
Console.WriteLine();

Persona p2 = (Persona)s.Load(typeof(Persona), p.Id);

Console.WriteLine("p2 - Id: " + p2.Id);
Console.WriteLine("p2 - Nombre: " + p2.Nombre);
Console.WriteLine("p2 - Apellido: " + p2.Apellido);
Console.WriteLine();

/* Verifico si son el mismo objeto p y p2, ya que estamos
* dentro de la misma sesión */

if (p == p2)
Console.WriteLine("p y p2 son el mismo objeto");

p2.Apellido = "Paduán";

s.Flush();

s.Close();
}
}
}

En el proyecto agregué estas referencias:

  • NHibernate.dll
  • System

Ahora vamos a lo que nos interesa. En el archivo app.config (que al compilar se traducirá a .exe.config en el directorio de salida), observemos estas lineas:

…
key="hibernate.connection.driver_class"
value="PruebaNHibernate.MonoDataSqliteDriver, PruebaNHibernate"
/>
…

NHibernate trae un driver para SQLite, como dije al principio, pero que utiliza un provider que fue discontinuado. Por lo tanto, para utilizar Mono.Data.Sqlite, cree una clase en mi assembly (PruebaNHibernate) con el nombre que se indica allí (MonoDataSqliteDriver):

using System;
using NHibernate.Driver;

namespace PruebaNHibernate
{
public class MonoDataSqliteDriver : ReflectionBasedDriver
{
public MonoDataSqliteDriver()
: base("Mono.Data.Sqlite",
"Mono.Data.Sqlite.SqliteConnection",
"Mono.Data.Sqlite.SqliteCommand")
{
}

public override bool UseNamedPrefixInSql
{
get { return true; }
}

public override bool UseNamedPrefixInParameter
{
get { return true; }
}

public override string NamedPrefix
{
get { return "@"; }
}

public override bool SupportsMultipleOpenReaders
{
get { return false; }
}
}
}

En el constructor de la misma le paso a mi clase padre los argumentos que necesita: nombre del assembly (en este caso “Mono.Data.Sqlite”), clase para crear la conexión y ejecutar comandos. Desconozco los detalles de SQLite, así que copié los métodos sobreescritos del driver viejo.

No pude hacer que NHibernate cargue el assembly “Mono.Data.Sqlite” desde el GAC, así que hay que copiarlo al directorio del ejecutable. Es necesario copiar otros archivos, como las dependencias de NHibernate y la base de datos (data.db). Se pueden bajar el proyecto completo para MonoDevelop aquí. El archivo obviamente no es un png, pero sino no lo puedo subir :)

Ahora bien, hay un problemita… el archivo System.Data.dll que viene con Mono 1.2.4 en Gutsy tiene un bug que hará que el ejemplo no funcione. El mismo ya fue solucionado en la versión 1.2.6. Así que, como workaround, pueden bajarse el paquete de Debian libmono-system-data2.0-cil correspondiente a la versión 1.2.6 de Mono y sobreeescribir ese archivo, que se ubica en /usr/lib/mono/gac/System.Data/2.0.0.0__b77a5c561934e089/. Reporté el problema en Ubuntu, así que quizá lo actualicen dentro de poco.

Con esto podremos utilizar SQLite con NHibernate, bajo Mono, con un binding actualizado.

Autor : Milton Pividori

FUENTE DEL ARTICULO : http://www.miltonpividori.com.ar/2007/12/30/mono-nhibernate-sqlite/


SQLite y Gambas2

domingo, 2 de noviembre de 2008

Gambas es otro de los tantos hacks recursivos que se usan, en si el significado es "Gambas Almost Means Basic", pensado como herramienta RAD y con Basic como lenguaje base, pero mejorado, vemos que tambien es multiprosito, en esta ocasión vamos a ver como hacer una conexión a una base de datos SQLite desde Gambas2.

Lo primero que debemos tener disponible para trabajar, ademas de SQLite, es Gambas2, en Debian y derivados:

#apt-get install gambas2

para otras distros podemos encontrar las fuentes en http://gambas.sourceforge.net/
la parte mas importante esta en saber cuales son las herramientas que nos provee el languaje, y los datos de conexión de almacenan en un solo botón, el codigo es el siguiente:

'Instanciamos un objeto de clase Connection
PRIVATE $hConn AS Connection

'Boton de conexión a la base de datos
PUBLIC SUB btnC
onnect_Click()

DIM sName AS String
DIM hTable AS Table

TRY $hConn.Close



sName = txtName.Text

IF sName <> "" THEN

'Asignamos valores a las pr
opiedades que vamos a usar
WITH $hConn

'Definimos el tipo de base de datos
.Type = "sqlite"


'Definimos el nombre del host
.Host = txtHost.Text

END WITH


'Asignamos el nombre de la conexion
$hConn.Name = sName

'Abrimos la
conexion para poder trabajar
$hConn.Open

'Habilitamos los otros formularios
frmDatabase.Enabled = TRUE
frmRequest.Enabled = TRUE

btnConnect.Enabled = FALSE
btnClose.Enabled
= TRUE
CATCH

Message.Error(DConv(Error.Text))
ENDIF

END
A continuación capturas de la aplicacion terminada y en diseño.



Antes de terminar debo aclarar que la base de datos debe estar creada, en caso contrario no se realiza la conexión, ademas se debe dar la ruta completa de la ubicación del archivo que contiene dicha base de datos. La aplicación completa para su descarga en el siquiente link:
Descarga

Generador de Trigger

martes, 30 de septiembre de 2008

Todos sabemos que sqlite, carese de integridad referencia, no obstante podemos definirla atraves de los trigger o disparador, su funcion dentro de la DB es ejecutar un evento cuando se cumple una condición establecida al realizar una operación de inserción (INSERT), actualización (UPDATE) o borrado (DELETE).
Aqui les dejamos un link donde puden mirar un par de ejemplos sobre la contruccion de trigger y un generador de triggers.
Si se pregunta por que estamos desaparecidos en Sqlite - Latino. , Nos econtramos preparando un par de sopresas.
Saludos
link data
"Genarador Triggers" :
http://www.rcs-comp.com/site/index.php/view/Utilities-SQLite_foreign_key_trigger_generator

"elserver" :
http://www.elserver.com/wiki/SQLite_relacionar_tablas_con_triggers
"Sqlite" :
http://www.sqlite.org/lang_createtrigger.html
"esteparioprogramador" :
http://esteparioprogramador.bligoo.com/content/view/228771
"justatheory":
http://www.justatheory.com/computers/databases/sqlite/foreign_key_triggers.html

Reunión de la Comunidad SQLite-Latino

lunes, 1 de septiembre de 2008


En el marco de las III Jornadas de Software Libre organizado por alumnos de la Universidad Nacional de Jujuy – UNJu, en la Provincia de Jujuy – Argentina, la Comunidad SQLite – Latno tuvo lugar a un encuentro en donde se organizaron algunas cuestiones propias del grupo.

La verdad que es la primera ves que estamos reunidos y charlando sobre los proyectos que se biene de acá en adelante.


Es por ello que la invitación de participar nuevamente se renueva con el fin de incorporar más seguidores y entusiastas a colaborar con esta pequeña comunidad que día a día y gracias a ustedes va creciendo.

Groovy + GSql + SQLite (Parte I)

lunes, 11 de agosto de 2008

Groovy
Es un lenguaje de programación orientado a objetos implementado sobre la plataforma Java. Tiene características similares a Python, Ruby, Perl y Smalltalk. por lo tanto permite escribir código "simple, limpio y corto" -mas info-

GSql Y SQLite

GSql simplifica el acceso a los JDBC, es capas de implementar SQLite, atraves de de la compatibilidad con las librerías de Java, esto lleva aprovechar algunas característica presente en Groovy.
Con estos sencillos pasos podremos llevar a cabo la conexión y previa consulta de datos utilizando Groovy + Gsql + Sqlite

1ro- Descargar las librerías de SQLiteJDBC desde el sitio http://www.zentus.com/sqlitejdbc/, las mismas son totalmente nativas y desarrolladas 100% Java.

2do- Agregar el JDBC sqlitejdbc-v052.jar dento de la configuración de groovy en ~/.groovy/lib. en mi caso

En GNU/Linux = /urs/share/groovy/lib/
En M$ Guindos = archivodeprograma\groovy\lib\

3ro- Se debe de crear la DB con SQLite - Review I y Review II -

4to- Ejecutamos GroovyConsole.

Una ves desplegada la consola de Groovy, lo que debemos de hacer es importar las librerías GSQL y se creara una nueva instanciar de la clase SQL o conexión con los driver JDBC, es muy importante definir la URL de la DB y el el nombre del Driver, como se muestra a continuación :


import groovy.sql.Sql
sql = groovy.sql.Sql.newInstance("jdbc:sqlite:/home/gerardo/sqlitelatino.db","org.sqlite.JDBC")


Ahora crearemos una nueva tabla la cual recibe el nombre de "prueba", dentro de groovy se utiliza el método execute, que se encuentra en la clase sql , este método recibe como parámetro un objeto string que es una sentencia SQL. En este caso Create :


sql.execute("create table prueba(ide,nombre,mail)")

Una ves creada la tabla , realizaremos la inserción de nuevos campos, para ello seguiremos utilizando el método execute, solo que cambiaremos la sentencia Create por Insert. como se muestra a continuación.


sql.execute("insert into comunidad(ide,nombre, mail) values('Gerardo', 'gerard@mail.com')")
sql.execute("insert into comunidad(ide,nombre, mail) values('Daniel',' dan@mail.com')")
sql.execute("insert into comunidad(ide,nombre, mail) values('Marcos', 'big@mail.com')")


Para poder dar un poco de vida a nuestro código, usaremos println para dejar carteles indicando que datos se están mostrando.


println 'SQlite Latino'
println ' Nombre Email '
println '+--------+--------+'


Ahora utilizaremos el método eachRow el cual me devuelve cada elemento de una consulta determinada y en cada iteración se visualizara el contendido del los elementos.


sql.eachRow('select * from comunidad?)
{ integrante ->println "${integrante.nombre} ${integrante.mail}"
}


Ahora solamente bastar con ir a la barra de menú de GroovyConsole y Ejecutar Run. el cual compilara y ejecuta nuestro código Groovy. Hasta aquí la entrega de Sqlite + Groovy. esperamos realizar muy pronto una nueva entrega.
Un Abrazo , Hasta la proxima...

Ruby - SQLite (Parte II)

sábado, 9 de agosto de 2008

Ahora luego de una pequeña demora, veamos como realizar nuestro primer ejemplo con el lenguaje de programación Ruby y nuestro ya conocido pseudomotor SQLite.

Si aún no tienes instalado el módulo de SQLite para Ruby, te recomiendo que leas el post anterior antes de continuar con este ejemplo.

Lo primero que vamos a realizar es crear un archivo para que lo ejecute luego el intérprete de Ruby, simplemente en nuestro editor de texto favorito creamos un archivo con extensión .rb por ejmplo "prueba01.rb" y vamos a utilizar la base de datos que utilizamos para aprender en las Review I y Review II de SQLite.

# Importamos las librerías de SQLite3
require 'sqlite3'

# Realizamos la correspondiente conexión con la Base de Datos.
# Para ello podemos colocar el Path donde se encuentra el mismo
db = SQLite3::Database.new("BaseDatos.db")

# En la variable sql, realizamos una consulta, simplemente
# por cuestiones de prolijidad y legibilidad.
sql = "SELECT apellido, nombre FROM personal order by id"

# Ejecutamos la consulta ingresada en la variable anterior
# recorriendo el contenido de la misma
db.execute(sql) do |fila|
p fila
end

# Por último cerramos la conexión
db.close


Por último solo nos va a quedar interpretar y ejecutar el archivo creado, esto es hace de la siguiente manera:

$ ruby prueba01.rb

SQLite 3.6.1

jueves, 7 de agosto de 2008

Hace algunos dias se encuentra libre la version de sqlite la 3.6.1 , la cual a solucionados algunos de los problemas de las antiguas versiones.

# Modificacion del Virtual File System

# La Busqueda ahora es un 15% mas Rapida


Ademas se esperan nuevas mejoras para la version 3.7 como :

1. Los nombres puede ser incluido en [...] para mantener la compatibilidad con Access
y SQLServer.

2. Los nombres puede ser incluido en los acentos graves para la compatibilidad con
MySQL.