Readers’ Choice Awards 2011

Y salieron los premios anuales de la revista Linux Journal, me topé con algunas sorpresas y otras no tanto, y puedo resaltar los ganadores de algunas categorías que me interesan:

  • Mejor distribución de Linux: Ubuntu (faltaba mas)
  • Mejor entorno de escritorio: Gnome 3 (de verdad no esta tan mal)
  • Mejor navegador: Firefox  :/
  • Mejor gestor de base de datos: MySQL (seguido muy de cerca por PostgreSQL)
  • Mejor lenguaje de programación: Python? (creo que es hora de empezar con «esa nota»)
  • Mejor juego: World of Goo (creo que vale la pena las 20 fichas que cuesta)

La lista es larga, son 45 categorías, les sugiero que le hechen un vistazo:

http://www.linuxjournal.com/slideshow/readers-choice-2011

 

Y pronto (abril 2012) Percona Live: MySQL Conference And Expo 2012

Pueden ver y descargar las conferencias del evento 2011 ahi mismo!

 

Probando UDFs para MySQL: Title Case

Conocemos «de sobra» lo que hacen las funciones LCASE y UCASE en MySQL, otros gestores también la implementan con alguna variación en el nombre pero con el mismo resultado.

Pero que pasa si queremos una función que convierta un texto al tipo Titulo, conocido también como title case, es decir convertir «un texto arbitrario» en «Un Texto Arbitrario«, para este caso no existe la función mágica que haga esa conversión y tenemos que escribir una propia.

No es necesario «reinventar la rueda» (aunque podría hacerlo), buscando encontré un repositorio de funciones UDF para MySQL: http://www.mysqludf.org/ , hay varias funciones agrupadas según el objetivo/funcionalidad, solo tienen que descargar el código fuente, compilarlo y agregarlo como funciones nuevas en vuestros servidores MySQL.

He aislado la función str_ucwords (que convierte un texto a «Title Case») en un archivo separado para mostrarles como es que podemos compilar una UDF para MySQL.Pero he modificado el archivo por que solo funcionaba con parámetros constantes, ahora la función acepta nombres de columnas como parámetros.

Pueden descargar el archivo fuente: ucwords.c

Para compilarlo necesitan unas tres instrucciones:

#Compilamos el programa
ivancp@ubuntu$ gcc ucwords.c -o ucwords.so -shared -lmysqlclient -I/usr/include/mysql

#Copiamos el archivo de salida en la carpeta de plugins de mysql
ivancp@ubuntu$ sudo cp ucwords.so /usr/lib/mysql/plugin

#Quitamos el permiso de ejecución del archivo
#para que pueda cargarlo correctamente
ivancp@ubuntu$ sudo chmod -x  /usr/lib/mysql/plugin/ucwords.so

 

  • La opción -shared compila el archivo para que pueda ser usado como librería.
  • La descripción del resto de parámetros van a encontrarla en la entrada: Leer datos de MySQL desde C

Ahora debemos agregar la función a MySQL:

mysql> create function str_ucwords returns string soname 'ucwords.so';
Query OK, 0 rows affected (0.00 sec)

mysql>

 

Ahora veamos algunas pruebas, esta es una consulta común (los datos están almacenados en mayúsculas o Upper Case):

mysql>select nombres from tabla;
+----------------------------------+
| nombres                          |
+----------------------------------+
| AGUILAR PALACIOS RICARDO         |
| ANDIA MARQUEZ LUIS MELITON       |
| CUYUBAMBA RAMOS VICTOR ALEJANDRO |
| FELICIANO VELAZCO VICTORIA       |
| FLORIDA EVANGELISTA LILA REYNA   |
| LEON LAULATE FERNANDO            |
| PALACIOS LOPEZ ROXANA BEATRIZ    |
| REATEGUI RAMIREZ CARLOS          |
| REINOSO MORI JORGE WILLY         |
| SALAZAR VALDIVIA WALTER          |
| SANCHEZ TUTUSIMA CARMEN ROSA     |
| VELAZCO BERROA PETRONA           |
+----------------------------------+
12 rows in set (0.00 sec)

 

Aquí esta lo que queremos ver, la consulta primero convierte a minúsculas todo el campo y luego convierte éste resultado a Title Case, vean:

mysql>select str_ucwords(lcase(nombres)) from tabla;
+----------------------------------+
| str_ucwords(lcase(nombres))      |
+----------------------------------+
| Aguilar Palacios Ricardo         |
| Andia Marquez Luis Meliton       |
| Cuyubamba Ramos Victor Alejandro |
| Feliciano Velazco Victoria       |
| Florida Evangelista Lila Reyna   |
| Leon Laulate Fernando            |
| Palacios Lopez Roxana Beatriz    |
| Reategui Ramirez Carlos          |
| Reinoso Mori Jorge Willy         |
| Salazar Valdivia Walter          |
| Sanchez Tutusima Carmen Rosa     |
| Velazco Berroa Petrona           |
+----------------------------------+
12 rows in set (0.00 sec)

 

Funciona a la perfección!

Por favor revisen la documentación, en otro post explicaré que deben tener en cuenta para elaborar sus propios UDF:

http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html

Activar el motor FEDERATED en MySQL

El motor FEDERATED de MySQL, aunque no es muy versátil, puede resultar útil, por ejemplo, para conectarnos directamente a una tabla en otro servidor MySQL sin necesidad de un intermediario, como un script PHP que copie/verifique/vea datos de otro servidor.

El motor FEDERATED no esta habilitado por defecto en instalaciones estándares sobre Linux, no hay que compilar nada, solo agregarle el parametro --federated en el archivo /etc/init/mysql.conf:

#Busquen esta linea en el archivo /etc/init/mysql.conf
exec /usr/sbin/mysqld --federated

Luego de reiniciar el servicio mysql, verán los resultados:

ivancp@ubuntu$ sudo service mysql restart

 

Para ver que motores están disponibles ejecuten SHOW ENGINES en la linea de comando MySQL:

mysql> show engines;
+------------+---------+-----------+--------------+------+------------+
| Engine     | Support | Comment   | Transactions | XA   | Savepoints |
+------------+---------+-----------+--------------+------+------------+
| InnoDB     | YES     | Supports t| YES          | YES  | YES        |
| MRG_MYISAM | YES     | Collection| NO           | NO   | NO         |
| BLACKHOLE  | YES     | /dev/null | NO           | NO   | NO         |
| CSV        | YES     | CSV storag| NO           | NO   | NO         |
| MEMORY     | YES     | Hash based| NO           | NO   | NO         |
| FEDERATED  | YES     | Federated | NO           | MO   | NO         |
| ARCHIVE    | YES     | Archive st| NO           | NO   | NO         |
| MyISAM     | DEFAULT | Default en| NO           | NO   | NO         |
+------------+---------+-----------+--------------+------+------------+
8 rows in set (0.00 sec)

 

Para conectarnos a una tabla remota y consultar que datos contiene, tenemos que crear la tabla, debe ser muy similar a la tabla remota, pueden ayudarse con el comando SHOW CREATE TABLE para ahorrar tiempo y agregar el parámetro CONNECTION al final.

-- Tabla con conexion a una base de datos remota
CREATE TABLE tabla_remota
(
    id     INT NOT NULL AUTO_INCREMENT,
    campo1  VARCHAR(32),
    campo2  INT,
    PRIMARY KEY  (id),
    INDEX campo1 (campo1)
)
ENGINE=FEDERATED
DEFAULT CHARSET=utf8
CONNECTION='mysql://usuario:contraseña@1952.168.6.5/base_datos/tabla';

 

Recomendaciones:

  • El único problema es que la consulta puede demorar un poco mas de lo debido, así es que traten de no hacer consultas cuyos resultados sean realmente grandes.
  • Es una pena que aun no esté disponible la posibilidad de conectarse a otros gestores de datos como PostgreSQL o SQL Server, eso sí que sería útil.
  • Deben crear un usuario sin contraseña en la base de datos de destino, para evitar poner la contraseña en la conexión, ya que es fácil de averiguar (con SHOW CREATE TABLE).
  • Las conexiones son permitidas incluso hacia servidores MySQL mas antiguos.
  • Leer la documentación para mas detalles:
    http://dev.mysql.com/doc/refman/5.1/en/federated-storage-engine.html
  • Pueden ayudarse con un Stored Procedure para crear estas tablas FEDERATED.

Espero les sirva.

Simplificar el acceso a MySQL CLI

¿No les ha dado pereza escribir, en la linea de comando, todo lo necesario para conectarse a un servidor MySQL?

Puede que tome menos de un minuto, pero algunas veces un minuto es vital (sobre todo si estamos cerca del fin del mundo).

ubuntu@ubuntu$ mysql -u root -p -h mysqlhost [base_datos]

 

Cuando uno esta apurado, estos comandos suelen fallar varias veces por minuto.

La solución: podemos ayudarnos creando atajos con alias en el archivo ~/.bashrc:

#archivo ~/.bashrc

#comando "my" para conectarse a un servidor local
alias my="mysql -u root -p"

#comando "my2" para conectarse a un servidor remoto
alias my2="mysql -u root -p  -h 192.168.1.56"

 

La proxima vez que queramos acceder al servidor local solo tendremos que escribir en la linea de comando my [base_datos], solamente nos pedirá el password del servidor.

Podemos ser mas osados y dejar el password en el mismo comando alias:

#archivo ~/.bashrc

#comando "my" para conectarse a un servidor local
alias my="mysql -u root --password=tupwd"

#comando "my2" para conectarse a un servidor remoto
alias my2="mysql -u root --password=tuotropwd  -h 192.168.1.56"

 

Pueden usar los acronimos que prefieran, para mi my y my2 son cortos y útiles.

Cada vez que quiero una linea de comando MySQL sólo tengo que cargar una nueva terminal (Super + T), escribir «my mi_base» y [enter]!

Ahora se presenta otro problema, como saber en que servidor me encuentro?

El acceso puede ser super veloz con los accesos directos via alias, pero todas las terminales tienen el mismo prompt por defecto: mysql> y no hay muchas luces a primera vista para saber en que conexión estamos. Para evitar desastres (por ejemplo ejecutar DROP en el lugar equivocado) podemos cambiar el prompt de la linea de comando de MySQL con la opcion --prompt, entonces, nuestra configuración finalmente quedará así:

#archivo ~/.bashrc mejorado

#comando 'my' para conectarse a un servidor local
alias my='mysql -u root --password=tupwd --prompt="local> "'

#comando "my2" para conectarse a un servidor remoto
alias my2='mysql -u root --password=tuotropwd  -h 192.168.1.56 --prompt="server 1> "'

 

Espero les sirva!

Ubuntu: Montar un directorio compartido automaticamente

Los usuarios Windows conocemos a la perfección como montar una unidad de red, pero en Linux la cosa es un tanto mas complicada, pero no difícil.

La primera opción que tenemos es abrir directamente la dirección: Presionamos Ctrl+L en Nautilus (o algún otro explorador de archivos) y escribimos:

smb://[ip_del_host]/carpeta/

Seguramente nos pedirá un usuario, contraseña y listo. Prefiero esta forma, a menos que no sepa el nombre/IP del host y esperar unos segundos mas a que descubra todos los hosts disponibles si es que llega a descubrirlos todos.

En el caso que queramos tener esa carpeta disponible cada vez que inicie Ubuntu tenemos que agregar una linea en el archivo /etc/fstab:

//192.168.1.45/ruta /media/carpeta_win  cifs  username=win_user,password=win_pass,rw,iocharset=utf8  0 0

Explico punto por punto:

  • //192.168.1.45/ruta Es la ruta de la carpeta remota, en caso de que se trate de una unidad de disco podemos poner //192.168.1.45/d$ , en general si es una carpeta oculta es necesario poner el signo de dolar al final.
  • /media/carpeta_win Es la carpeta local sonde va a montarse la carpeta remota, esta carpeta debe existir, pueden elegir otra ubicación para esta carpeta, eso queda a gusto de ustedes.
  • cifs Es el parametro que indica el sistema de archivos que vamos a montar, en este caso: Common Internet File System que tiene estos parámetros: (separados por comas)
    • username=win_user Nombre de usuario de la carpeta compartida (si lo requiere)
    • password=win_pass Password del usuario de la carpeta compartida
    • rw Indica que vamos a montar en lectura y escritura, para solo lectura es:  ro
    • iocharset=utf8 Indica que vamos a utilizar nombres con UTF8, con el que podremos ver los archivos con caracteres especiales como Imágenes, Mi Música

Es todo, para poder comprobarlo solo tienen que reiniciar el sistema y ver que pasa.

Si quieren montar la carpeta remota manualmente pueden ejecutar:

ivancp@ubuntu$ sudo mount -t cifs\ 
     -o username=win_user,password=win_pass,rw,iocharset=utf8 \
     //192.168.1.45/ruta /media/carpeta_win

Si hay algún problema deben ver los últimos mensajes de error con:

dmesg | tail

Nota: anteriormente se utilizaba smbfs como sistema de archivos, ese sistema de archivos se ha dejado de utilizar.

Espero les sirva!

Mi archivo .vimrc

Ha sido duro aprender a usar vim, sinceramente no es facil, pero cuando uno se acostumbra a la forma de trabajo de éste poderoso editor no puedes dejar de usarlo. No uso otro editor de texto a menos que sea completamente necesario, los archivos que son mas frecuentes para mi son archivos fuente de C/C++, PHP, Python, Texto plano, HTML, Bash, y archivos de configuración de Ubuntu.

Existen muchos editores para programar como Netbeans, Codeblocks, etc, etc… pero por alguna razón prefiero usar vim.

Quiero compartir con ustedes parte de mi archivo .vimrc que es cargado cuando el editor es invocado. Puede contener todo lo que necesiten, podría considerarse como un archivo de configuración, aquí les dejo mi archivo comentado.

"Habilitar el resaltado de la sintaxis
syntax enable

"Para que los tabs no ocupen mucho espacio
set shiftwidth=4
set tabstop=4

"Si estamos usando gVIM entonces cambiamos el
"esquema de colores (no me agrada el fondo blanco)
if has("gui_running")
	colorscheme torte
endif

"Muestra los comandos que estamos por ejecutar (para evitar desastres)
set showcmd

"Habilita la sangría automática para archivos fuente
autocmd BufRead,BufNewFile *.c,*.cpp,*.h,*.php,*.htm,*.html set cindent

"Plantillas de archivos: podemos tener archivos fuente como plantillas
"de tal modo que nos ahorramos en escribir unas cuentas lineas de codigo
"por ejemplo si creamos un nuevo archivo .cpp cargamos un Hola mundo

autocmd BufNewFile *.cpp 0read ~/apps/confs/template.cpp
autocmd BufNewFile *.php 0read ~/apps/confs/template.php

"Para ver los números de linea
set number

El archivo no esta completo, por que tengo varias funciones implementadas que amerita otro post.

MySQL: show table status mejorado

Desde la línea de comando ciertamente tenemos el control absoluto (siempre y cuando tengamos los privilegios) pero no siempre tenemos una visión general. En este caso cuando estamos logueados a una base de datos MySQL lo primero que solemos intentar averiguar es la lista de tablas y talvez la lista de funciones y procedimientos almacenados de una base de datos.

Este proceso suele ser doloroso por que en cuanto ejecutamos show table status; nos devuelve unas lineas que hasta da pereza interpretar. Lo que devuelve ese comando contiene varias columnas que vistas desde una herramienta visual como MySQL Workbench tienen mucho sentido, sin embargo desde la linea de comando no tanto. Pueden ver en la siguiente imagen como se ve un resultado en una ventana estándar de 80×25:

Para ver el detalle completo podemos agrandar la ventana y disminuir la fuente, pero suele tomar un poco de tiempo hacer eso, realmente es fastidioso.

Es por eso que hace mucho desarrollé un script para mostrar solo lo que necesito incluyendo a los procedimientos almacenados y funciones, recién esta semana que tengo  varias horas de ocio y puedo compartirla con ustedes.

El resultado de mi script es mucho mas comprensible:

Éste es código fuente del procedimiento almacenado:

DELIMITER $$

CREATE PROCEDURE `tools`.`sp_status`(dbname varchar(50))
BEGIN 

-- Obteniendo informacion de las tablas
SELECT
 TABLE_NAME as `Table Name`, 
 ENGINE as `Engine`,
 TABLE_ROWS as `Rows`,
 CONCAT(
    (FORMAT((DATA_LENGTH + INDEX_LENGTH) / POWER(1024,2),2))
    , ' Mb')
   as `Size`,
 TABLE_COLLATION as `Collation`
FROM information_schema.TABLES
WHERE TABLES.TABLE_SCHEMA = dbname; 

-- Obteniendo las funciones y procedimientos
SELECT ROUTINE_NAME as `Routine Name`, 
 ROUTINE_TYPE as `Type`,
 DATABASE_COLLATION as `Collation`
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = dbname
ORDER BY ROUTINES.ROUTINE_TYPE, ROUTINES.ROUTINE_NAME;
END$$

Para invocarlo pueden escribir:

mysql> call tools.sp_status(database());

Notarán que he creado el procedimiento dentro de la base de datos tools, esto para que puedan llamarlo desde cualquier parte. Lamentablemente dentro de los procedimientos almacenados no es posible determinar la base de datos actual, es por eso que necesita de un parámetro con el nombre de la base de datos.

He publicado el procedimento en MySQL custom show table status

Espero que les sea de mucha utilidad (como a mi).

`

Ubuntu: gnome-settings-daemon ocupa el 100% del procesador!

Ubuntu linux logoEstoy muy contento de haber cambiado a Ubuntu desde hace años (gracias a Waltico por ayudarme a tomar la desicion), lo que puedo resaltar (para éste post) es que mi modesta Laptop se mantiene fria con menos del 30% del procesador usándose casi todo el tiempo (salvo excepciones como algunos procesos por lotes o juegos). Tengo 3Gb de memoria y – tambien- casi siempre hay el  60-80% disponibles.

Hay decenas de ventajas (y algunas desventajas) que puedo mencionar, pero… en este momento quiero chancar a Ubuntu y decir: ¿por qué diablos el proceso gnome-settings-daemon ocupa el 100% del procesador? esto ocurre muy eventualmente pero hoy se pasó ocurrio 3 veces desde la madrugada de hoy. Me doy cuenta cuando empieza a calentar el lado izquierdo de mi maquina y el ventilador empieza a sonar haciendo su trabajo.

Solución: No recuerdo donde lo leí pero lo descubrí por mi mismo accidentalmente… no es una solución en sí es solamente un aliciente para que pare de sufrir nuestro procesador, por que si intentan matar ese proceso, perderán muchas características y tendrán que reiniciar, esta es la solución:

  1. Abrir Sistema -> Preferencias -> Teclado
    (yo prefiero gnome-do -> escribir T, E y listo)
  2. Restablecer los valores predeterminados, cerrar y esperar a que ocurra el milagro.
  3. Si esto no funciona, volver a añadir el idioma del teclado adicional que tienen configurado.

Molesta tener que hacer esto incluso si es muy eventualmente, pero no todo es perfecto… a todo esto… Ubuntu 11.04 esta cerca, solo faltan unos dias, veamos que nos espera con la nueva version lo unico molestoso es la migracion, la ultima vez me fue muy bien hice un script para mudar todo y no perdí casi nada, con Ubuntu 11.04 voy a hacer lo mismo.

Una vista a MySQL Workbench 5.2 – SQL Editor

Workbench About DialogNota previa: Esta no es una review minuciosa, es mas bien un tibio comentario sobre mi experiencia de usuario en las ultimas semanas con la herramienta MySQL Workbench 5.2.31 sobre Ubuntu 10.10.

Mi trabajo con MySQL aun no ha llegado al nivel de complejidad que quisiera, ya que tambien trabajo con SQL Server,  es propicia la ocasión para compartiles mis apreciaciones, respecto al Editor SQL (que antes fue MySQL Query Browser).

Si bien estoy muy acostumbrado a la linea de comando, éste no me permite guardar/recuperar un historial de consultas o advertirme de algún «horror», incluso ahora prefiero la linea de comando por que me cuesta menos «clicks» y pulsaciones del teclado. Pero cuando las cosas se ponen serias, o mas complejas, una herramienta como Workbenck se hace completamente necesaria.

Puedo resaltar las siguientes características que me agradan (o no tanto) y paso a comentarlas:

Workbench history tabEl Historial de consultas.
Definitivamente el historial de consultas es muy útil cuando realizas decenas -hasta cientos- de consultas por día. Sobre todo si alguna vez se han preguntado ¿por qué se ha estropeado esta tabla?
El historial recuerda casi todo lo que uno ejecuta, pero no recuerda la hora de ejecución, característica que espero que agreguen pronto.

Workbenck SQL EditorComandos SQL listos!
Todos sabemos que el lenguaje SQL  es muy difícil de escribir, pero algunas veces se hace tedioso incluso para hacer un simple SELECT, en este caso Workbench tiene opciones muy útiles para estos casos. Al hacer click derecho en una tabla (en general cualquier objeto) aparecen opciones como «Copy to clipboard -> Update statement» y zaz.. en memoria tenemos ya el comando SQL para actualizar la tabla, y si esta en el Clipboard, mejor, por que  podemos llevarlo a nuestro editor preferido para seguir programando. Siendo modesto esa opción puede ahorrar 5 valiosos minutos a cualquier programador.

Workbench SQL Editor - Showing errors and hide codeResaltado de errores y ocultado de código SQL
Cuando escribimos segmentos grandes de código SQL sobre todo en consultas anidadas, con llamadas a funciones, etc., suele ser difícil encontrar un error de anidamiento o bueno.. un error en resumidas cuentas, MySQL Workbench tiene la característica de mostrar los «horrores» de nuestro código, pero no siempre acierta pero sirve de mucho.
Al ocultar un segmento de código fastidioso, para entender mejor una consulta, en MySQL Workbench no es tan cómodo por el simple hecho de que no tienes mayores indicadores del código ocultado mas que un símbolo [+] y la secuencia numérica de lineas, a esta característica deberían agregarle algo al final para saber que algo continua y no eliminarlo por accidente.

Otras características que puedo comentar:

  • Impresionante!, es la palabra que merece el gestor de base de datos MySQL 5.1 , escribí numerosos procedimientos/funciones y consultas muy complejas, que antes eran imposibles, pero ahora las escribo con toda confianza y lo mejor de todo es que es super veloz!
  • SQL safe mode: es un modo de conexión que evita hacer modificaciones a toda la tabla con una consulta, por a si a alguien no le ha pasado alguna vez: eliminar toda una tabla/base de datos por accidente, el comando muy sencillo pero peligroso.
  • Todo esta a corta distancia: Todos los elementos de nuestra base de datos estan disponibles en el panel lateral y los tabs de la parte inferior, aun que quita espacio no deja de ser util, deberían optimizar esas vistas para tener mas espacio.
  • Los tabs siempre son utiles, donde quiera que estén.

Lo que mo ne gusta:

  • Con los procedimientos almacenados y funciones Workbench abre en un editor undividual por cada procedimiento/funcion para ser modificado/creado y para guardarlo hay que gastar mas de dos clicks innecesariamente, los clicks no cuestan nada pero fastidian. En este caso prefiero abrirlos directamente desde el editor (como lo hago en SQL Server).
  • Termina el programa cuando uno utiliza algun plugin de texto como los que cambian a mayusculas las palabras reservadaas. Tambien suele terminar el programa abruptamente en condiciones que aun desconozco, en cuanto tenga esa información voy a enviar el reporte de bug.
  • No hay mas plugins, hubiera esperado al menos uno pero lamentablemente no hay mas plugings (la pagina esta en mantenimiento).
  • Tabs: Workbench devuelve automaticamente un tab por resultado, es incomodo revisar cada tab si esque estamos haciendo un seguimiento.
  • No hay una funcion para imprimir un mensaje directamente (como el comando print en SQL Server),  para simular algo asi se puede utilizar una consulta de seleccion que incluya la variable para mostrarla.
  • Algunas veces en el panel de resultados uno ve el simbolo de [blob] cuando espera un resultado de menos de 100 caracteres, esto si que molesta por que sucede cuando utilizas la funcion CONCAT(…), la cadena de resultado no es muy grande para que Workbench lo considere como BLOB.

Algunos lectores seguramente me van a increpar la comparacion con SQL Server, pero debo decirles que Workbench me parece mucho mas util (en este caso) que el editor de consultas del Enterprise Manager, pero aun hay cosas que deben madurar.

Download!
Pueden descargar Workbench directamente desde:

http://dev.mysql.com/downloads/workbench/

Update 5-mar: Acaban de lanzar MySQL Workbech 5.2.32 hace unas horas, lo he descargado e instalado pero persiste un error que he reportado como bug: http://bugs.mysql.com/bug.php?id=60354