Charlas de GNOME Hispano
CouchDB
Relator: Rodrigo Moya (rodrigo) Moderador: Sergio Infante (neosergio) Sabado 10 de octubre de 2009, 17:00 horas UTC
irc.gnome.org #gnome-hispano
- neosergio
Bienvenidos a la Charla IRC del Mes de Octubre
- neosergio
Hoy el tema sera CouchDB
- neosergio
y quien mejor para hablar del tema que Rodrigo Moya
- neosergio
aqui algunos datos sobre el http://es.gnome.org/RodrigoMoya
- neosergio
no se olviden que cualquier pregunta durante la charla, me la envian y yo en el momento adecuado la planteare
- neosergio
bueno sin mas preambulo, con ustedes Rodrigo
rodrigo
hola! :)
rodrigo
en cuanto a las preguntas, si no le importa a neosergio, yo no tengo problema en que me interrumpais cuando queráis hacer una
rodrigo
bueno, pues primero, vamos a ver qué es CouchDB
- neosergio
perfecto
rodrigo
http://couchdb.apache.org/
rodrigo
couchdb es un proyecto Apache, lo cual quiere decir, no que necesite de Apache para funcionar, sino que está apoyado por la fundación apache es una BBDD orientada a documentos, en formato JSON
rodrigo
aunque se llama BBDD, es algo distinta de lo que todos conocemos como BBDD, o sea las relacionales en un punto muy importante, que es que una BBDD couchdb puede tener registros con distintos campos es decir, está libre de todo esquema
rodrigo
por ejemplo, yo puedo tener una bbdd con un documento -> { "name": "rodrigo", "hobbies": "couchdb" } y otro -> { "descripcion": "hola", "date": "23-01-1985" } todo ello, en la misma BBDD
rodrigo
por cierto, si estáis en ubuntu y queréis seguir lo que haga -> apt-get install couchdb en otras distros no sé si está empaquetado
rodrigo
couchdb, de cara al exterior, es un servidor web (sin apache) que ofrece tanto un interfaz web como un API REST, para que las aplicaciones puedan acceder a la BBDD
rodrigo
si instalais couchdb en ubuntu, podéis arrancarlo con -> sudo /etc/init.d/couchdb start eso arranca una instancia de couchdb para todo el sistema, accesible por todos los usuarios del sistema, en http://localhost:5984/
rodrigo
vamos a ver primero el interfaz web http://localhost:5984/_utils/ permite acceder a un interfaz HTML para gestionar las BBDD y la configuración
rodrigo
no necesita mucha explicación, pero por encima:
rodrigo
1. puedes tener todas las BBDDs que quieras 2. cada BBDD se compone de documentos JSON
rodrigo
como decía antes, los documentos pueden tener la estructura que querais pero hay un tipo especial de documentos, que os voy a explicar por encima, de momento son las vistas
rodrigo
son documentos que contienen mini-scripts en javascript que permiten hacer consultas a la BBDD
rodrigo
lo bueno de estas vistas es que, una vez creadas, se cachean sus resultados, y así, el acceso a los documentos es mucho más rápido que si accedemos a todos los documentos uno por uno
rodrigo
alguna pregunta hasta ahora? no? ok
- neosergio
todo claro al parecer
rodrigo
bueno, pues pasamos a la 2ª, y más interesante, funcionalidad de couchdb que es la sincronización
rodrigo
esto funciona de una manera muy sencilla tú tienes una instancia de couchdb corriendo en tu máquina (en local normalmente) y puedes decirle que se sincronice con otra u otras instancias de couchdb en máquinas remotas
rodrigo
así, por ejemplo, una de las cosas en las que estoy trabajando, es el almacenamiento de contactos de evolution en una instancia por usuario (luego comento más de esto) que corre en local que se sincroniza con el servidor de Ubuntu One (https://one.ubuntu.com)
rodrigo
qué permite esto? pues sencillo, replicar tus datos en varios sitios y sincronizar los cambios entre las distintas instancias de couchdb
rodrigo
así, por ejemplo, yo puedo almacenar mis contactos en local, luego irme a un cibercafé, añadir o editar un contacto a través de un interfaz web y luego, por arte de magia, tener mi contacto automáticamente en evolution cuando vuelvo a mi PC
rodrigo
couchdb está preparado para lidiar con conflictos, y para sincronizar los datos entre BBDD sin ningún problema cada documento tiene como un pequeño control de revisiones que hace que couchdb sepa sin problemas cuáles han sido los cambios
rodrigo
es importante destacar que la sincronización es en 2 (o más sentidos) vamos, que puedo hacer cambios en todas las BBDD por separado, y todos esos cambios se sincronizan/replican en todas las BBDD
rodrigo
por defecto, como habéis visto, couchdb arranca una instancia por ssitema, sin autenticación de ningún tipo lo cual no es útil es sistemas multiusuario
- neosergio
pregunta
rodrigo
donde no quieres que tu jefe vea tus contactos con el mundo del porno, por ejemplo :) neosergio: si, dime
- neosergio
en cuanto al consumo de recursos, como capacidad de memoria y procesamiento, que tan eficiente es CouchDB en estas sincronizaciones?
rodrigo
no tengo datos científicos para enseñarte, pero con mis pruebas, la velocidad de respuesta es prácticamente la misma que acceder a ficheros locales, eso para instancias locales de couchdb para la sincronización, el consumo es mínimo en memoria y procesamiento
rodrigo
ya os digo que incluye algoritmos que permiten saber qué cambios ha habido, sin necesidad de comparar documentos, ni nada de eso en cuanto a la velocidad de red, depende de la red, claro :)
- neosergio
:)
rodrigo
couchdb está escrito en erlang, que hace que mucha gente piense que es muy pesado pero es todo lo contrario erlang es un lenguaje hecho para sistemas concurrentes, como couchdb
rodrigo
responde esto a la pregunta?
rodrigo
bueno, pues sigo
- neosergio
si, todo claro
rodrigo
estaba con los sistemas multiusuario couchdb puede arrancarse desde la línea de comandos pasándole los argumentos adecuados, se puede hacer que arranque una instancia de couchdb por usuario que es lo más interesante
rodrigo
además, es muy útil el activar la autenticación que puede ser o bien por usuario/contraseña o bien por OAuth
rodrigo
todo esto se puede hacer a mano, pero para facilitar las cosas, en el equipo en el que trabajo ha desarrollado desktopcouch -> https://launchpad.net/desktopcouch que no es más que un servicio dbus que, cuando se activa, arranca couchdb con los argumentos y configuración precisos para que sólo pueda ser accedido por el usuario que lo arranca
rodrigo
además, incluye todo lo necesario para replicar/sincronizar las BBDD automáticamente con ubuntu one o con cualquier otro couchdb que corra en la red en la que estás esto último es especialmente interesante, ya que, en una conferencia, por ejemplo, puedes arrancar la herramienta de sincronización, buscar en la red otros servidores couchdb, y sincronizar la BBDD local con otra remota
rodrigo
con esto acabamos la parte de teoría de couchdb
rodrigo
así que hagan sus preguntas ahora, si teneis alguna :)
- neosergio
todo muy claro rodrigo :)
- neosergio
a los asistentes pueden participar de manera libre e interrumpir con sus preguntas en el momento que deseen
rodrigo
ok, o que nadie está escuchando, aparte de neosergio :)
- neosergio
:) son timidos
rodrigo
bueno, pues ahora vamos a centrarnos en cómo usar esto en las aplicaciones de GNOME
rodrigo
existen a día de hoy 2 APIs, una en python (python-oauth) y otra en C (couchdb-glib) como esto es un canal de GNOME, vamos a centrarnos en couchdb-glib ya que python-oauth es genérico, aunque, evidentemente, muy útil para aplicaciones ya escritas en python
- neosergio
que tanta diferencia puede haber entre ambas?
rodrigo
python-oauth sólo implementa el acceso al interfaz REST de couchdb mientras que couchdb-glib hace lo mismo + varias cosas más:
rodrigo
* incluye GObject's con señales para recibir notificaciones de cambios python-oauth permite acceder a las notificaciones, que se opbtienen por medio del interfaz REST, pero hay que hacerlo a mano es decir, hay que conocer el protocolo
rodrigo
* couchdb-glib incluye también objetos de alto nivel para acceder a los distintos tipos de documentos estandarizados -> http://www.freedesktop.org/wiki/Specifications/desktopcouch por ejemplo, para contactos, se puede usar el objeto CouchDBDocumentContact que permite acceder/modificar un documento de tipo 'contact' con un API típica de libs GTK/GNOME además, esto permite abstraer la app de cualquier cambio que pudiera realizarse en el formato de los documentos ya que las apps usan el API, si quieren, en vez de modificar el documento JSON a mano
rodrigo
como podéis ver en http://www.freedesktop.org/wiki/Specifications/desktopcouch, hemos creado esa página para intentar estandarizar los tipos de documento más comunes
rodrigo
como no hay estructura fija en el formato de los documentos se ha hecho eso para que no acabemos con documentos tipo "contact" que unos usan "first_name" y otros "FirstName" que haría completamente inviable el compartir datos entre aplicaciones
rodrigo
como veis, tenemos, de momento, 3 tipos de documentos: * notas (para tomboy) * marcadores (https://launchpad.net/bindwood, una extensión de firefox que almacena todos los marcadores que creas en Firefox en tu couchdb local con el tiempo iremos creando más tipos de documentos, a saber, en breve, 'events' (calendario), 'tasks', etc y, a medio plazo, quizás configuraciones (que te permitiría grabar toda la conf de las apps en couchdb, replicarlo a un servidor, y al reinstalar/instalar tu distro en otra máquina, sincronizarla desde el servidor a la bbdd local, y así obtener toda la conf automáticamente) y otras cosas, que ya se irán viendo según surja la necesidad
rodrigo
bueno, pues vamos a ver cómo usar couchdb-glib en las apps es un API muy sencilla
rodrigo
para empezar, hay que crear un objeto CouchDB: couchdb = couchdb_new (url) -> url puede ser NULL, en cuyo caso se conecta a localhost:5984, o sea la instancia del sistema, o un URL cualquiera en el que haya una instancia de couchdb corriendo
- neosergio
para crear este objeto, es necesaria alguna interfaz en especial, o cual es la forma mas recomendable para crear un objeto CouchDB?
rodrigo
para listar las BBDD que hay -> GSList *couchdb_list_databases (CouchDB *couchdb, GError **error); neosergio: la interfaz es el API del objeto CouchDB couchdb_new lo crea estamos pensando en renombrarlo a CouchDBConnection, que quizás sea más claro
rodrigo
una vez que sabes el nombre de la BBDD a la que quieres acceder: GSList *couchdb_list_documents (CouchDB *couchdb, const char *dbname, GError **error); lista los documentos pero cierto, antes de listar bbdd y documentos, hay otros métodos muy útiles: gboolean couchdb_create_database (CouchDB *couchdb, const char *dbname, GError **error); -> para crear BBDD gboolean couchdb_delete_database (CouchDB *couchdb, const char *dbname, GError **error); -> para borrar BBDD o, para activar autenticación por OAuth -> gboolean couchdb_enable_oauth (CouchDB *couchdb, const char *consumer_key, const char *consumer_secret, const char *token_key, const char *token_secret);
rodrigo
en ubuntu OAuth se activa por defecto, y todos los datos para acceder se almacenan en el gnome-keyring así que si no se llama a la función couchdb_enable_oauth antes de cualquier otra petición, couchdb devolverá "401 unauthorized" para todas las peticiones quele hagamos
rodrigo
bueno, se almacena en gnome-keyring y en un fichero .ini -> ~/.config/desktop-couch/desktop-couchdb.ini
rodrigo
bueno, pues una vez que ya sabes a qué BBDD vas a acceder, se usa couchdb_list_documents, que devuelve una lista de todos los documentos (sus nombres y datos, como la revisión actual, su ID único, etc)
rodrigo
y, muy útil -> void couchdb_listen_for_changes (CouchDB *couchdb, const char *dbname); esta última función activa la escucha de cambios en la BBDD que indiques esto es muy importante, ya que si tienes configurado tu CouchDB para que sincronice con otro servidor, si no monitorizas los cambios, tu app no recibirá ninguna notificación
rodrigo
el objeto CouchDB incluye las señales: void (* database_created) (CouchDB *couchdb, const char *dbname); void (* database_deleted) (CouchDB *couchdb, const char *dbname); void (* document_created) (CouchDB *couchdb, const char *dbname, CouchDBDocument *document); void (* document_updated) (CouchDB *couchdb, const char *dbname, CouchDBDocument *document); void (* document_deleted) (CouchDB *couchdb, const char *dbname, const char *docid);
rodrigo
pero para realmente monitorizar los cambios en los documentos es necesaria la función couchdb_listen_for_changes si no la llamas, sólo recibirás notificaciones de los cambios hechos por tu app
rodrigo
una vez que se tiene la lista de documentos, se puede obtener cada documento con: CouchDBDocument *couchdb_document_get (CouchDB *couchdb, const char *dbname, const char *docid, GError **error);
rodrigo
así mismo, se puede crear un documento vacío con -> CouchDBDocument *couchdb_document_new (CouchDB *couchdb); el objeto CouchDBDocument permite manejar un documento desde tu app, de forma muy sencilla un documento en CouchDB se compone de distintos campos, que pueden ser de estos tipos: * entero * booleano * cadena * objeto, que no es más que el equivalente a una struct en C * arrays
rodrigo
estos campos se acceden de forma muy sencilla:
rodrigo
gint couchdb_document_get_int_field (CouchDBDocument *document, const char *field); gboolean couchdb_document_get_boolean_field (CouchDBDocument *document, const char *field); const char *couchdb_document_get_string_field (CouchDBDocument *document, const char *field); gdouble couchdb_document_get_double_field (CouchDBDocument *document, const char *field); CouchDBStructField *couchdb_document_get_struct_field (CouchDBDocument *document, const char *field);
rodrigo
los arrays no están soportados aún en couchdb-glib, más que nada porque no los he necesitado de momento pero añadirlos es cuestión de minutos, así que imaginaros que ya existe esta función: :) GArray *couchdb_document_get_array_field (CouchDBDocument *document, const char *field);
rodrigo
como veis, couchdb_document_get_struct_field devuelve un objeto CouchDBStructField, que no es más que una capa para implementar una struct en JSON: gboolean couchdb_struct_field_get_boolean_field (CouchDBStructField *sf, const char *field); gdouble couchdb_struct_field_get_double_field (CouchDBStructField *sf, const char *field); gint couchdb_struct_field_get_int_field (CouchDBStructField *sf, const char *field); const char *couchdb_struct_field_get_string_field (CouchDBStructField *sf, const char *field); CouchDBStructField *couchdb_struct_field_get_struct_field (CouchDBStructField *sf, const char *field);
rodrigo
como veis con couchdb_struct_field_get_struct_field se puede tener struct's dentro de struct's, etc, etc todos los niveles que querais así mismo, todas estas funciones *_get_*field tienen su correspondiente *_set_*_field
rodrigo
así, por ejemplo: CouchDBDocument *doc = couchdb_document_new (); couchdb_document_set_string_field (doc, "last_name", "Moya"); couchdb_document_set_boolean_field (doc, "is_dumb", TRU); TRUE :)
rodrigo
alguna pregunta? que no quiero saturaros de información :) aunque creo que el API es bien sencillo, no necesita mucha explicación
rodrigo
bueno, pues sigo, que ya estamos acabando
rodrigo
una vez que tenéis un objeto CouchDBDocument, almacenarlo en la BBDD es muy sencillo: gboolean couchdb_document_put (CouchDBDocument *document, const char *dbname, GError **error);
rodrigo
esa función se usa tanto para crear nuevos documentos como para actualizar documentos ya existentes el truco está en que, si el CouchDBDocument fue leido de la BBDD, incluye una serie de campos internos que CouchDB crea: * _id -> identificador único del documento * _rev -> revisión actual del documento
rodrigo
asímismo, para borrar un documento -> gboolean couchdb_document_delete (CouchDBDocument *document, GError **error);
rodrigo
y bueno, para terminar, os comento un poco sobre CouchDBDocumentContact
rodrigo
CouchDBDocumentContact no es más que uno de los múltiples objetos de alto nivel que se van a añadir a la lib, para facilitar la gestión de documentos estandarizados (ya sabéis -> http://www.freedesktop.org/wiki/Specifications/desktopcouch)
rodrigo
es una capa que permite gestionar documentos de tipo "contact" -> http://www.freedesktop.org/wiki/Specifications/desktopcouch/contact
rodrigo
se me había olvidado hablar del campo "record_type", que es el que especifica qué tipo de documento es por ejemplo, para contactos -> "record_type": "http://www.freedesktop.org/wiki/Specifications/desktopcouch/contact", y bueno, este CouchDBDocumentContact incluye un API para acceder a todos los campos definidos en http://www.freedesktop.org/wiki/Specifications/desktopcouch/contact
rodrigo
por ejemplo: const char *couchdb_document_contact_get_first_name (CouchDBDocument *document); void couchdb_document_contact_set_first_name (CouchDBDocument *document, const char *first_name); const char *couchdb_document_contact_get_last_name (CouchDBDocument *document); void couchdb_document_contact_set_last_name (CouchDBDocument *document, const char *last_name); ...
rodrigo
esto permite que no tengas que acordarte de los nombres de los campos y que tu app sea transparente a cualquier cambio que se haga en el formato del documento
rodrigo
y bueno, dle API creo que no os voy a contar más, si alguien quiere saber más, que me pregunte, ahora o por email, cuando quiera
rodrigo
el código está en el GIT de GNOME, en el modulo couchdb-glib, y ha sido propuesto para ser incluido en GNOME 2.30/3.0 junto con evolution-couchdb
rodrigo
lo que si os voy a contar es un poco qué permite todo esto
rodrigo
el plan de dominación mundial es que, por ejemplo, yo tenga mi móvil (o celular) con todos mis contactos, me vaya de viaje, haga amigos, sincronice los contactos con mi servidor de couchdb, y luego esos contactos aparezcan todos en evolution sin tener que sincronizar a mano
rodrigo
esto, imaginaroslo con cualquier tipo de datos las notas de tomboy (conboy en los nokia, tomdroid en los android), etc además, permite que apps totalmente diferentes compartan datos por ejemplo, akonadi, el equivalente a evolution en KDE, usa el formato http://www.freedesktop.org/wiki/Specifications/desktopcouch/contact
rodrigo
así que, por fin, los usuarios podrían cambiarse de app sin tener que hacer migraciones masivas de datos incluso sólo para eso, sin sincronización ni replicación, couchdb tiene muchísimo sentido
- jza
umm una pregunta, que relacion tiene couchdb-gnome con lo que se llamaba gnome-base o gnome-db en gnome 1.x Recuerdo que querian hacer gnome-db como una especie de estructura de datos utopica para las apps de gnome. Esto suena algo similar solo que mas en la red.
rodrigo
imaginad que tanto evolution como akonadi almacenan el correo, contactos, calendaro, etc en couchdb, eso permitiría cambia r de una a otra app sin problemas para los usuarios
rodrigo
jza: gnome-db es un API para acceder a bbd relacionales
rodrigo
se parece, pero no es lo mismo
rodrigo
couchdb es, por decirlo de alguna manera, un almacen de datos
rodrigo
por cierto, que se me ha olvidado comentar que los documents de couchdb pueden tener ficheros adjuntos
rodrigo
no todo tiene que ser JSON
- jza
lo otro que me suena muy similar es sobre google-gears de tener un banco de datos para las apps en web.
rodrigo
perdón, almacen de datos no, sino almacen de documentos jza: si, en eso si tienes razón, es algo parecido
rodrigo
lo que pasa es que esto, couchdb, es 100% libre y cualquiera se puede instalar su propio servidor cosa que no se si es posible con google-gears
rodrigo
alguna pregunta más?
- jza
la tercera es sobre akonadi pero es lo que estas ya explicando.
- jza
continua :)
rodrigo
no, ya he acabado, ahora preguntad :)
jza
erlang no es muy complejo? Por que eso si suena a una lata aprender un nuevo leenguaje.
rodrigo
erlang no es complejo, es "diferente" así que cuesta un poco aprenderlo pero vamos, no necesitas aprenderlo
rodrigo
erlang es el lenguaje en el que está implementado internamente couchdb así que no es necesario aprenderlo para usar couchdb
- jza
y para su uso lo puedes manipular desde? JSON?
- jza
ok javascript .... ok
rodrigo
si lo aprendes, nos das una charla aquí, que yo me he medio leido el libro, pero como te digo, cuesta, es un lenguaje totalmente distinto :)
rodrigo
jza: javascript es para escribir las vistas para acceder al interfaz REST HTTP, cualquier lenguaje que te guste
- jza
muy bien.
rodrigo
las vistas son muy sencillas por ejemplo: { "get_records_and_type": { "map": "function(doc) { emit(doc.record_type, doc) }" } }
rodrigo
o algo más complejo: function(doc) { if (doc.record_type == "http://www.freedesktop.org/wiki/Specifications/desktopcouch/contact") emit (NULL, doc); } para devolver todos los documentos de tipo "contact"
- jza
una pregunta mas, hay algunos sitios usando couchdb, o como se puede ver una implementacion de couchdb en accion?
rodrigo
el caso es que creo que van a soportar vistas en más lenguajes aparte de JS, pero no sé decirte a día de hoy cómo va la cosa
rodrigo
jza: https://one.ubuntu.com es uno
rodrigo
en http://couchdb.apache.org/ hay una lista, a ver si la encuentro
rodrigo
http://wiki.apache.org/couchdb/CouchDB_in_the_wild
rodrigo
como ves, hay hasta apps de facebook que lo usan :D
- jza
gracias
- neosergio
excelente recurso
rodrigo
bueno, alguna pregunta más?
rodrigo
ah, por cierto, hay un libro sobre couchdb en construcción -> http://couchdb.apache.org/docs/books.html
rodrigo
http://books.couchdb.org/relax/
- neosergio
que requisitos minimo debe tener una persona para que empiece a colaborar con couchDB?
- EGCdigital
no sabia que ubuntu one estaba implementado de esa manera!!! EGCdigital
rodrigo
bueno, con couchdb es complicado, ya que esa persona tiene que saber erlang, que es complicado
- EGCdigital
:)
rodrigo
pero para colaborar con couchdb-glib, evolution-couchdb, o en integrar couchdb-glib en apps ya existentes
rodrigo
cualquier persona que sepa algo de programar en GTK/GNOME, debería poder ponerse en marcha rápidamente
rodrigo
EGCdigital: la parte de los ficheros no usa couchdb, pero la de contactos, notas, etc, si
- neosergio
Con respecto al plan de dominacion mundial, ya se puede ver algun intento de aplicacion en moviles??
rodrigo
ah, por cierto, que Roberto Majadas ha escrito bindings de Vala para couchdb-glib, así que al que le guste Vala más que C, puede usar esos bindings
- neosergio
:)
rodrigo
neosergio: el sincronización de notas desde tomboy usa un protocolo definido por la gente de tomboy, que en breve implementarán (si no lo hacen ya) tomdroid (para android) y conboy (para los tablets nokia)
rodrigo
el tema de contactos estará probablemente en breve, para ubuntu one
rodrigo
y en cuanto reciba mi n900, pienso ponerme a integrar couchdb-glib ahí :)
- neosergio
genial :)
rodrigo
es una tecnología joven, en el sentido que hace muy poco que se ha empezado a mostrar interés en proyectos fuera de la web, sobre esta tecnología vamos, que hay un camino muy bonito por hacer aún :)
rodrigo
pero si, poco a poco van surgiendo cosas muy interesantes en la web couchdb es popular, incluso hasta el punto que mucha gente está reemplazando sus BBDD relacionales con couchdb pero en el tema de escritorios y móviles, queda muchísimo, y muy interesante por hacer así que es un proyecto muy interesante en el que embarcarse, de verdad :)
rodrigo
y bueno, si no hay más preguntas, lo dejamos aquí, ok?
- neosergio
me parece que ya no quedan preguntas
rodrigo
ok
- neosergio
el tema ha sido muy interesante y la charla muy clara
rodrigo
pues muchas gracias a todos, espero que os haya gustado
- neosergio
muchas gracias rodrigo por tu tiempo
- neosergio
clap clap clap clap clap
- jjardon
gracias por la charla rodrigo
- neosergio
aplausos por el excelente expositor
rodrigo
si quereis hablar conmigo, suelo estar en este canal, si no -> rodrigo@gnome-db.org así que espero recibir parches, ideas,etc en breve :D
- neosergio
:D mas ideas de dominacion mundial
rodrigo
:D
- neosergio
muchas gracias rodrigo nuevamente