sábado, 18 de agosto de 2012

Mongodb y Ruby, conexión a una base de datos

Trabajar con mongodb en Ruby es muy fácil. 

Basta con instalar la gema mongo, o driver de conexión a Ruby: 


gem install mongo

y listo. Empezar a trabajar: 


Para tener acceso a nuestras bases de datos en mongo debemos crear una instancia de conexión a la base de datos: 

@connection = Mongo::Connection.new


Si nuestra base de datos se llama: desarrollosimple, entonces para acceder a ella ejecutamos la siguiente instrucción: 

@db = @connection['desarrollosimple']

Nota: si no has creado aún la base de datos en mongo, abre una consola mongo y ejecuta: 

use desarrollosimple



sábado, 2 de junio de 2012

Comandos básicos en MongoDB

Estoy aprendiendo MongoDB con el libro MongoDB in Action; estos son algunos comandos útiles para el manejo de este excelente manejador de bases de datos no relacionales.

Ingresar a mongo

Desde la consola, escribir: 
mongo

Crear y utilizar bases de datos

Por defecto, mongo ingresa a la base de datos test. Si se quiere utlizar otra base de datos, utilizamos: 

use [nuestra_bd]

Ejemplo: 

use tutorial

NO!, no es necesario que se haya creado previamente la base de datos tutorial. La base de datos será creada realmente cuando se inserte un documento en ella. Según el libro, esta forma de usar las bases de datos es parte de la filosofía de mongodb en la que el dinamismo es lo más importante. 

Creación de documentos

Es tan simple como: 

db.users.insert({username:"mi_unico_lector"})

Donde, users se denomina una Colección. 

También se puede utilizar save. La sintaxis es la misma. 

Buscar todos los documentos de una colección

db.users.find()

Mucho más sencillo que el select * ....

Buscar un documento particular

db.users.find({username:"mi_unico_lector"})

Eliminar todos los documentos de una colección

db.users.remove()
db.users.count()

Eliminar un documento particular de una colección

db.libros.remove({"username":" mi_unico_lector "})


viernes, 1 de junio de 2012

Problemas instalando Linux en VirtualBox



Al iniciar la instalación de Ubuntu 12 en VirtualBox salía este error: 


This kernel requires an x86-64 CPU, but only detected an i686 CPU. Unable to boot – please use a kernel appropriate for your CPU


La solución, consiste en entrar a la BIOS y habilitar la opción del procesador Intel Virtualization Technology. Esto lo encontré acá:  http://hereirestinremorse.wordpress.com/virtualbox/this-kernel-requires-an-x86-64-cpu-but-only-detected-an-i686-cpu-unable-to-boot-please-use-a-kernel-appropriate-for-your-cpu/



jueves, 31 de mayo de 2012

Versiones de gemas en Ruby

¿Cómo conocer la versión disponible de una gema?



gem list -a --remote watir


-a permite ver todas las versiones disponibles de la gema (en este caso watir), no solo la última.
--remote indica que la búsqueda se hará en el repositorio remoto por defecto. Si se quiere hacer una búsqueda local, --local es la alternativa.



¿Cómo instalar una versión específica de una gema?

gem install --version 0.4 ruby-mp3info

En ruby es posible y válido instalar varias versiones de una gema.

Cuando se utiliza una gema en un programa, por defecto se obtiene la versión más reciente. Si se quiere una versión específica: 

gem 'ruby-mp3info', '=0.5'
require 'mp3info'

Lo anterior se escribiría en IRB o en un ejecutable de ruby. El parámetro de la versión acepta otros operadores como: >, <=, etc. 


martes, 29 de mayo de 2012

Accediendo a elementos sin id con Watir




Cuando estás automatizando la prueba sobre la GUI de una aplicación es muy posible que no puedas acceder a los elementos mediante su id por la simple razón de que no tienen id. Por ejemplo, queremos acceder al campo de texto del siguiente código: 


<tr>
<td class="tns-PanelFormTitleText">Nombre</td>
<td>
<input class="gwt-TextBox tns-TextBox" type="text">
</td>
</tr>

No hay un atributo name, tampoco un id. 

Una solución es utilizar XPath (presento solo el xpath asociado con la porción de código de arriba): 

ie.text_field(:xpath, "...tr/td[2]/input").set 'WATIR 1'

Al ejecutar la prueba con XPath el campo de texto recibió la cadena 'WATIR 1' pero después de una larga espera en la que cada 2 segundos aproximadamente se escribía un caracter. No conozco la implementación pero supongo que por cada caracter que será ingresado, se recorre el xpath.  

Una mejor solución, es aprovechar que el campo tiene un "label" asociado. O mejor, en la celda anterior a la que contiene el campo, hay un texto que al menos semánticamente se relaciona con nuestro campo objetivo. La estrategia entonces puede ser esta: 

Acceder a la celda con el texto "Nombre". 
A partir de esta celda, obtener la fila que la contiene. 
Acceder a la segunda celda de la fila, que contiene a nuestro campo objetivo. 

En código: 

nombreRow = ie.td(:text => 'Nombre').parent
# se ubica el campo de texto y se le asigna un valor
nombreRow.cells[1].text_field.set 'WATIR 1'

El tiempo de ejecución disminuye considerablemente, a la mitad o menos. 

Especificar el ID de un radio button en GWT

En el caso de algunos elementos GWT el id se puede especificar simplemente con la operación setId de Element. Por ejemplo, para un botón el id se puede establecer así: 


this.buttonSetEnvironment.getElement().setId("btnEstablecerAmbiente");


Sin embargo, otros componentes como los radio button o los check boxes requieren conocer su estructura GWT para asignarles un id. Esto implica que asignar el id a un radio button no funciona con una sentencia como: 


radioButton.getElement().setId("miRadioButton");


Cuando se genera el código HTML el id queda asociado con un elemento span que contiene a nuestro radio button: 



<span id="miRadioButton" class="gwt-RadioButton tns-CheckBox">
  <input id="gwt-uid-1" type="radio" name="Grupo" value="on" tabindex="0">
  <label for="gwt-uid-1">CENT2</label>
</span>

Como se puede apreciar en el código anterior, el span agrupa al radio button y su respectivo label. Esto implica que los objetos RadioButton de GWT están compuestos por dos hijos (cuando se genera su HTML): un input y un label.  Sabiendo esto, podemos utilizar la clase DOM para acceder a la estructura del radio button y asignar el id al elemento que deseamos: 

private void setId(RadioButton radioButton, String id){
  Element radoButton_input = DOM.getChild(radioButton.getElement(),0);
  DOM.setElementAttribute(radoButton_input, "id", id);
}

De igual forma, si quisiéramos asignar un id al label, accederíamos al child 1.


Dicen algo muy interesante para el label. Su asociación con el button se especifica diferente en IE que para los demás navegadores: 

DOM.setElementAttribute(e_label, "htmlFor", newID); // For IE 
DOM.setElementAttribute(e_label, "for", newID); // For other 


viernes, 25 de mayo de 2012

Ruby y Ubuntu - Trabajar con la versión correcta


Al parecer, no. con seguridad la combinación "No ser experto en Linux", "Ser nuevo en Ruby" es muy peligrosa si quieres programar con Ruby en Linux.

Esta es mi historia.

No sabía que ubuntu tiene por defecto una versión de ruby, en mi caso la 1.8.x. De todas maneras, aún sabiéndolo habría instalado la versión más reciente que para la fecha es la 1.9.3. La instalación fue sencilla:

sudo apt-get ruby

Y empieza el sufrimiento. Ubuntu simplemente no asocia la nueva instalación como el ruby por defecto.

¿Solución?, un enlace simbólico:

 sudo ln -s /usr/bin/ruby1.9.3 /usr/bin/ruby

En el cambio instalé una gema supuestamente recomendada pero que la verdad no sé para qué sirve a ciencia cierta. De todas maneras, ahí va:

sudo apt-get install ruby-dev

Finalmente, se presentó otro problema. IRB, la consola interactica de Ruby tampoco quedó asociada con la nueva versión de ruby. ¿Solución?, así es, enlaces simbólicos:

sudo ln -s /usr/bin/irb1.9.3 /usr/bin/irb

Nota: me di cuenta que irb apuntaba a una versión vieja de ruby porque al intentar usar watir me salía este error:


irb(main):003:0> require 'watir-webdriver'
LoadError: no such file to load -- watir-webdriver
from /usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
from /usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `require'
from (irb):3
from :0

IRB estaba accediente a la versión 1.8 (por defecto) de Ubuntu. 

También se puede verificar la versión a la que apunta irb con este comando: 
En IRB: 

puts $:

Muestra algo así: 

/usr/local/lib/site_ruby/1.9.1
/usr/local/lib/site_ruby/1.9.1/x86_64-linux
/usr/local/lib/site_ruby
/usr/lib/ruby/vendor_ruby/1.9.1
/usr/lib/ruby/vendor_ruby/1.9.1/x86_64-linux
/usr/lib/ruby/vendor_ruby
/usr/lib/ruby/1.9.1
/usr/lib/ruby/1.9.1/x86_64-linux
=> nil

Ahora sí, todo listo para trabajar. 

Se preguntará usted, único lector de mi blog, cómo encontré la solución. NO, no busqué por todo linux hasta encontrarla; recuerde que no soy experto en Linux. Después de horas y horas buscando en google llegué a esta solución, que seguramente no es la mejor, pero funcionó y con eso me basta. Igual, no quiero ser experto en linux, solo quería (hace unas 8 horas en total) hacer un pequeño programa en watir... por ahora creo que voy a dormir. 




sábado, 10 de marzo de 2012

Pool de conexiones JDBC en Glassfish

Objetivo: guardar un registro en base de datos desde un Stateless Session Bean utilizando JDBC.

Este es el código al que se quiere llegar:


package com.andres.beans;

import java.sql.Connection;
import java.sql.Statement;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.sql.DataSource;

/**
 * Session Bean implementation class BidManagerBean
 */
@Stateless
@LocalBean
public class BidManagerBean implements BidManager {

@Resource(name = "jdbc/pruebasmysql")
private DataSource datasource;

private Connection connection;

@PostConstruct
public void initialize() {
System.out.println("inicializando recursos de db");
try {
connection = datasource.getConnection();
if (connection == null) {
System.out.println("no se obtuvo la conexion");
}
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* Default constructor.
*/
public BidManagerBean() {
// TODO Auto-generated constructor stub
}

public void addBid() {
System.out.println("agregando bid");
try {
Statement statement = connection.createStatement();
statement.execute("insert into bids values (null, 34)");

} catch (Exception e) {
e.printStackTrace();
}

}
}

Para utilizar el datasource de conexiones es necesario configurar el servidor glassfish.

1. Agregar driver de conexión a mysql
2. Configurar datasource.

1. Agregar driver de conexión a mysql

Antes de agregar el driver, el servidor debe ser detenido.

En algunos sitios he visto que agregar el driver de conexión de mysql en la carpeta lib del directorio de instalación de glassfish. Sin embargo, o por lo menos en mi caso, esto es incorrecto. El driver de conexion debe agregarse a la carpeta ext del dominio. La ruta sería similar a esta:

[directorioInstalacionGlassfish]/domains/domain1/lib/ext

Luego de copiar el jar en esta ruta, se inicia el servidor.

2. Configurar datasource. 

La configuración del datasource se hace desde la consola de administración de Glassfish, que por defecto está en el puerto 4848 (http://localhost:4848/common/index.jsf). Allí se selecciona la opción Resources - JDBC.

Luego, seleccionar JDBC Connection Pools y la opción para crear un nuevo pool de conexiones.


Para este ejemplo el pool queda configurado con los siguientes datos: 
Pool Name: pruebasmysql 
Resource Type: javax.sql.ConnectionPoolDataSource
Database Driver Vendor: MySql

En la siguiente pantalla solo es necesario configurar algunos parámetros: 

User: root
Port: 3306
Password: [password]
URL: jdbc:mysql://localhost:3306/pruebas

Guardar el datasource y hacer ping para verificar que la configuración fue exitosa. 

Luego de esta configuración, se puede probar el código presentado.