ScalaSQL: Interfaz sencilla para JDBC desde Scala

Desde hace tiempo que Groovy es mi lenguaje favorito para hacer scripts que a veces necesito para interactuar con bases de datos (algunos reportes o modificar ciertos datos, procesamiento por lotes, etc).

Son principalmente dos razones por las que me gusta tanto usar Groovy para este tipo de scripts:

  1. Tengo a mi disposición todo un arsenal de componentes de Java (simplemente con el JDK tengo un montón de cosas) y además todo lo que me ofrece Groovy como lenguaje, encima del JDK de Java (closures, comprehensión de listas, etc).
  2. El componente groovy.sql.Sql me permite interactuar con bases de datos de manera muy sencilla.

En Scala aún no hay un componente similar. Y aunque lo hubiera, no usaría Scala para scripting (ya he escrito al respecto anteriormente). Pero creo que sí hace falta. Si bien existe el hiperútil componente JdbcTemplate de Spring, para el cual además ya existen unas adiciones para Scala (junto con otras cosas de bean factories) en el proyecto ScalaPrimavera, no siempre es posible o deseable comenzar a depender de Spring.

Así que me propuse desarrollar un componente similar al Sql de Groovy, con algunas cosas adicionales que me han resultado muy útiles de JdbcTemplate, con la finalidad de usarlo en aplicaciones Scala, de modo que debe ser seguro su uso en ambientes multi-hilo, debe tener buen performance, debe manejar bien la transaccionalidad y sobre todo debe ser sencillo de usar.

Primero empecé imaginándome el uso:

//Crearlo con un DataSource para poder usarlo desde varios hilos
//con distintas conexiones
val sql = new ScalaSql(algunDataSource)
//Obtener un solo registro; siendo Scala, esto debería ser un Option
val row = sql.firstRow("SELECT * FROM usuario WHERE clave=?", clave)
//Obtener una lista de registros
val rows = sql.rows("SELECT * FROM usuario WHERE fecha_alta > ?", new Date)
//Pasamos un closure que recibe un renglón y se invoca con cada
//registro obtenido; el renglón debe ser un mapa inmutable
sql.eachRow("SELECT * FROM cuenta WHERE saldo > ?", saldo) { row =>
  //Hacer algo con el mapa
  //Si alguna columna tiene NULL en la base de datos, debemos tener None
  //Si conoces los nombres de columnas, no habrá problema en obtener los valores
  if (row("nombre") == None) { //no trae nombre
  } else { //si trae nombre
  }
  row("saldo") match {
    case s:BigDecimal => //Manejar BigDecimal de Scala, no Java
    case None => No viene saldo
  }
}
//Hacer operaciones dentro de una transaccion
sql.withTransaction { conn => //idealmente no necesitas nada con la conexion
  //Con esto obtenemos llaves autogeneradas
  val nuevaClave = sql.executeInsert("INSERT INTO usuario (nombre,saldo) VALUES (?, ?, ?)", row("nombre"), row("saldo"))
  //Dentro de la transaccion invocamos al mismo componente
  sql.executeUpdate("DELETE FROM usuario WHERE clave=?", row("clave"))
  //Si al final no hubo excepciones, se hace commit
}

En fin, esa es la idea. El código ya está disponible en GitHub y conforme lo utilice, iré agregándole funcionalidad. De entrada no me parece necesario que pueda ser creado o utilizado con una sola conexión, por diversas razones:

  • El esquema de una sola conexión es útil únicamente en scripts y programas de procesamiento por lotes (y a veces ni en esos casos).
  • Se complica bastante el código para poder soportar tanto DataSource como conexión simple en el mismo componente (hay que cerrar conexiones cuando es DataSource pero no cuando es una sola conexión, consideraciones adicionales para transaccionalidad, etc).
  • Para poder usar un solo componente desde varios hilos distintos, es necesario que cada hilo use su propia conexión, por lo tanto se necesita Datasource.

Como lo menciono en la página del proyecto, encontré algo similar ya existente, que incluso sospecho que también está inspirado en el Groovy SQL ya que sí tiene soporte para usarse con una conexión directamente (similar a cuando se crea el Groovy SQL con el puro URL, usuario, password y nombre de la clase del driver JDBC), pero no hay transaccionalidad ni obtención de llaves autogeneradas (aunque esto depende en última instancia de que el driver JDBC lo soporte realmente).

Pero bueno, pues ya hay una opción más para lidiar con bases de datos SQL desde Scala.

UPDATE: Ya está disponible ScalaSQL desde Maven Central, bajo grupo com.solab.scalasql, artefacto ScalaSQL, versión 0.8. Espero subir pronto la 0.9 que ya tiene llamadas a Stored Procedures/funciones (callable statements en realidad) y en cuanto tenga bien probada la parte de concurrencia (que está probada de manera implícita porque las pruebas de aceptación están en specs2 que corre las pruebas en paralelo), y de llamadas anidadas, ya podré ponerle 1.0.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Sr. Negativo

JDBC en Scala (+1)

Muy buen post (como siempre).

Alguna vez alguien me dijo que existen dos tipos de informáticos:

  1. Los que usan la tecnología (la mayoría)
  2. Los que CREAN la tecnología

He aprendido más leyendo tus post que en toda mi etapa en la escuela. Muy bien.

Imagen de ezamudio

Gracias

Es muy alentador leer comentarios de este tipo.

Algo que no mencioné en el post porque espero que cambie pronto es que realmente no considero que este componente ya esté listo para usarse en producción; apenas lo hice y lo subí a GitHub, tengo el esqueleto de pruebas para saber todo lo que tengo que probar pero aún no las he escrito (no, no hice BDD, notifiquen a las autoridades).

Conforme escriba las pruebas seguramente saldrán errores, mismos que corregiré lo más pronto posible, y entonces sí estará listo para usarse. Tengo en mente un componente más que puedo agregar a este proyecto pero quiero darle bien forma primero y ver si realmente será de utilidad o no (una especie de administrador de las sentencias SQL que se utilizan en una aplicación, para tenerlas en un solo lugar todas, es poco más que un mapa de cadenas que se carga de un archivo properties).

EDIT: Ya terminé de hacer las pruebas y todas pasan OK, así que ya quedó listo para usarse. No descarto que haya algunos bugs por ahí pero las pruebas están bastante completas. Y sirven de ejemplo para ver cómo se hacen pruebas de aceptación con Specs2 en Scala.

Imagen de echan

otra opcion

se ve interesante para el hackeo rapido de sql ... en el mismo sentido se encuentra la libreria hecha por los cuates de twtter (https://github.com/nkallen/querulous), personalmente no lo he usado pero lo tengo en los bookmarks desde hace rato.
Saludos.

Imagen de ezamudio

querulous

Orale, no habia visto Querulous, está interesante, sobretodo por los reintentos y timeouts, similar al manejo de conexiones en Finagle.

Imagen de domix

Esta bastante chido, lo que

Esta bastante chido, lo que buscaba esta aqui¡ vientos

Imagen de Sr. Negativo

Iniciativa


Así que me propuse desarrollar un componente similar al Sql de Groovy, con algunas cosas adicionales que me han resultado muy útiles de JdbcTemplate, con la finalidad de usarlo en aplicaciones Scala, de modo que debe ser seguro su uso en ambientes multi-hilo, debe tener buen performance, debe manejar bien la transaccionalidad y sobre todo debe ser sencillo de usar.

A eso le llamó tener Iniciativa.

¿Cuántos de nosotros (me incluyo) nos falta tenerla?

Imagen de greeneyed

kudos

Yo también uso Groovy para ese tipo de cosas precisamente por la sencillez que mencionas, y me parece una gran idea portar esa sencillez a otros lenguajes para que todos se beneficien. Scala no es mi "cup of tea", pero es una iniciativa muy loable.

OT: En cuanto a la iniciativa o falta de ella, yo creo como opinión personal que hay una actitud diferente entre los que empezaron (empezamos) con Internet y los que han empezado con Internet "ya hecho" y creo que no hemos sabido trasladar/comunicar el espíritu a los que han encontrado tantas cosas hechas. Siempre generalizando, lo que implica equivocarse para casos concretos.

Imagen de Andres villamayor

Quiero aprender

Hola A todos, estoy leyendo sobre Scala, baje un manual pero en verdad no se por donde empezar
si alguien puede educarme sobre Scala por favor, desde ya muchas gracias a todos .
Saludos

Si alguien es tan amable de enviarme algun link a mi direccion de correo
andres.villamayor@gmail.com

Nuevamente Gracias

Imagen de bferro

¿No sabes por donde empezar?

De Scala hay muchos recursos, como sucede con otros lenguajes. Para los que empiezan con el lenguaje esto puede ser a veces contraproducente pues cuesta trabajo apostarle a alguno de esos recursos y al comienzo "olvidarse" de la existencia de otros.
Casi todos los recursos están en inglés (en español, "El Quijote") por lo que es necesario leer en inglés para aprovechar lo disponible.
Uno de los libros gratis lo encuentras en http://ofps.oreilly.com/titles/9780596155957/index.html. Sigue ese libro, y realiza todos los ejercicios. No es el mejor ni el peor libro, pero creo te puede servir.

También puedes leer tooooodos

También puedes leer tooooodos los post que aquí tanto bferro como ezamudio han escrito sobre Scala:

http://www.javamexico.org/categorias/lenguajes_jvm/scala

Te recomiendo que empieces... desde el principio :P ( o sea dale click en "ultima" en el paginador )

Imagen de ezamudio

Para impacientes

Typesafe también ofrece un ebook gratuito, Scala for the impatient, es una buena intro al lenguaje si ya conoces Java/C/C#/etc y quieres conocer las características principales de Scala. No es un tratado del lenguaje, no es exhaustivo, pero en poco tiempo llegas a conocer lo principal.

Guau!! y la versión PDF va de

Guau!! y la versión PDF va de regalo.. +1

Imagen de Andres villamayor

Gracias por la Ayuda

Agradecido por la ayuda que me brindan
un abrazo