domingo, junio 24, 2007

Conectando MySQL desde Mono::C#

Para lo que viene a continuación me basé en los tutoriales existentes en:

http://www.monohispano.es/index.php/Tutoriales
http://www.mono-project.com/Using_Databases


Pero durante la compilación, que aparece indicada como
mcs TestExample.cs -r:System.Data.dll -r:/ruta/a/MySql.Data.dll

Surgía el siguiente error

[Task:File=/home/s/Projects/Monos/prueba7/prueba7/Main.cs, Line=3, Column=2, Type=Error, Description=The type or namespace name `Data.MySqlClient' could not be found. Are you missing a using directive or an assembly reference?(CS0246)

Después de trastear mucho, y de cambiar de lugar la bendita MySql.Data.dll, descubrí que el error se repetía con los drivers de SQLite y Firebird. El problema estaba en otro lado.


En el principio de los tiempos...

El driver necesita un password real para conectar, de modo que cambiamos el password por defecto de MySQL:

s@zion:~$ mysqladmin -u root password mariscos

Creamos una base como la que figura en el tutorial:

s@zion:~$ mysql -u root -p

Enter password: mariscos


Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 10


mysql> create database prueba;

Query OK, 1 row affected (0.00 sec)


mysql> use prueba;

Database changed


mysql> create table employee (

-> firstname varchar(32),

-> lastname varchar(32)

-> );

Query OK, 0 rows affected (0.00 sec)


mysql> show tables;

+------------------+

| Tables_in_prueba |

+------------------+

| employee |

+------------------+

1 row in set (0.00 sec)


mysql> INSERT INTO employee VALUES ('coso','cosa');

Query OK, 1 row affected (0.02 sec)


mysql> select * from employee;

+-----------+----------+

| firstname | lastname |

+-----------+----------+

| coso | cosa |

+-----------+----------+

1 row in set (0.00 sec)


Instalamos los paquetes necesarios:

s@zion:~$ sudo apt-get install libfbclient1 libgecko2.0-cil libgtksourceview2.0-cil liblog4net1.2-cil libmono-accessibility2.0-cil libmono-bytefx0.7.6.2-cil libmono-cecil0.4-cil libmono-data-tds1.0-cil libmono-npgsql2.0-cil libmono-peapi1.0-cil libmono-relaxng1.0-cil libmono-security1.0-cil libmono-sharpzip0.84-cil libmono-system-data1.0-cil libmono-system-runtime1.0-cil libmono-system-runtime2.0-cil libmono-system-web1.0-cil libmono-winforms2.0-cil libmono1.0-cil mono mono-mcs monodevelop monodevelop-query libmono-microsoft-build2.0-cil libmono-peapi2.0-cil mono-gmcs


Este último paquete (mono-gmcs) es el runtime v2. En el tutorial les faltó mencionar este componente.

Para quienes quieran copiar / pegar, aquí en el Pastebin de Lugmen he dejado el código.



Copiado y pegado el código en un archivo, por ejemplo Main.cs, nos queda instalar el driver de la base de datos. Estos son los paquetes:
  • Firebird: libmono-firebirdsql1.7-cil
  • SQLite: libmono-sqlite2.0-cil y
  • Oracle: libmono-oracle2.0-cil

En el caso de Mysql lo tenemos que bajar aparte (¿WTF?) desde

http://dev.mysql.com/downloads/connector/net/5.0.html

Descomprimimos el archivo mysql-connector-net-5.0.7-noinstall.zip, y buscamos en la carpeta /Driver/bin/net-2.0/release/ el archivo MySql.Data.dll

Lo insertamos manualmente en el Global Assembly Cache (GAC), que es el mggfñmfalgo importante creo...

s@zion:~$ sudo gacutil -i MySql.Data.dll


También copiamos MySql.Data.dll en la carpeta donde reside el código



¡Mírame, mama, mamá! ¡estoy compilando!

Prestar atención, que no es igual al tutorial:

s@zion:~$ gmcs Main.cs -r:System.Data -r:MySql.Data.dll


Listo. Ahora lo ejecutamos como

s@zion:~$ ./Main.exe


o también:

s@zion:~$ mono Main.exe

Name: coso cosa


Charán!!!!

Eso es todo. Ahora lo interesante sería presentar los datos con GTK# o alguna librería gráfica.

6 comentarios:

Manuel Muradas dijo...

Hola,
Muy buenos los post (este y el anterior). Trabajo con .net (vb y c#) en windows, y al mono solo lo vi de reojo un par de veces. En el secundario y en la facultad vi algo de C, VB6 y JAVA. Y por hobby se muy poquito de python (definitivamente el mas lindo de todos).
Ultimamente le estoy agarrando mas amor a C#.
No se si lo de "hasta pareciera que .." era en broma, pero el GAC es un gestor de librerías que tiene el mono. Es la respuesta de M$ al archiconocido "dll's hell" que tenía Visual 6.
Cuando vos agregas algo al GAC, queda guardado ahí, y luego no necesitas tener la .dll, solo referenciarla desde tus aplicaciones. En el caso de que hubiese mas de una librería con el mismo nombre, podés especificar la versión puntual que querés usar.
En el caso de querer compilar algo sin agregar la dll al GAC, tendrías que especificar el path de la dll con el parametro "-L", y después nombrarla con el parametro "-R"
Quedaría una cosa así:
gmcs Main.cs -L:"/path/de/dlls" -r:System.Data -r:MySql.Data.dll

No te quiero mentir pero si dejás la dll en el mismo directorio donde están los fuentes, también debería funcionar sin necesidad de pasarle el parametro L.

Como te dije, todo esto es de oído, y realmente no lo probé. Por cierto, me encantaría saber que corno es IDbCommand, voy a tener que ponerme a leer el link que pasaste.

Espero haberte ayudado, y que sigas investigando mono así me hacés aprender a mi también =)

Manuel Muradas dijo...

Bueno, no hubo forma de hacer andar el mcs sin cargar la dll en el GAC.
En cambio, gmcs me anda de las siguientes maneras:
)Pasando el path completo en el argumento -r
)Dejando la dll en el mismo directorio que los fuentes
)Pasandole el path con el parametro "-L" (deprecated, tira un warning) o con el parametro "-lib:"

Me voy a dormir. Cuando pase el huracán "Parciales" sigo jugando con el mono jeje

Manuel Muradas dijo...

Me olvidé de la conclusión final:
No uses mcs, es viejo y no tiene sentido. Mejor usa gmcs que se banca la especificación completa de C# 2.0 (con generics y nullable types)

(Perdón por el spam :)

Bunker Blog dijo...

Jua! gracias por los comentario. En realidad la nota obedece a que siguiendo un tutorial oficial del Proyecto, ocurre un error que cuesta interpretarlo correctamente.

Aparentemente te dice que no encuentra una librería, cuando el problema es que se esta usando cms en lugar de gcms, es decir, dos días buscando la solución con datos falsos.

Por eso se me ocurrió mencionarlo en el blog.

Es cierto lo que comentas acerca del GAC. Parece una forma de cache de dll pero mas al estilo posix, es decir no existe la sobrescritura accidental de librerias. Ya era hora que las dlls fueran quedando guardadas en forma histórica, ya que cuando al usuario se le pregunta "¿quiere guardar esta dll?" el tipo se asusta y elige cualquier cosa.

Manuel Muradas dijo...

Exactactamente! Ahora que leo la wikipedia explica GAC mas lindo.
En su momento cuando me puse a ver al MONO la documentación era un desastre, por no decir casi nula.
Me volví loco haciendo un ejemplo pavote, y ni hablar cuando traté de hacer algo con GTK#.
Hasta ahora para lo único que me sirvió mono fue para robarle un assembly hecho por Novell para autenticarse contra un LDAP de Novell. Lo tengo andando en producción y anda barbaro (no les digas nada a los de Novell a ver si se ponen a revisar la licencia..)
Igual por lo que vi el tuto ese está bastante completito. Abría que sacar las referencias a cosas viejas y dejarlo andando solo para GMCS.

Javierin dijo...

Hola,
La solución que estaba buscando durante toda la mañana ;-) Muchas gracias!