HTML5 - WebDB


SQL está presente en HTML5, el lenguaje de consultas estructuradas más utilizado ha sido incluido en HTML5 por el consorcio W3C, y está disponible en los navegadores basados en WebKit (Chrome, Safari) y  Opera, esperemos que Firefox lo haga pronto.

html5webdb

La implementación está enfocada en el cliente del usuario mas no en el servidor, es decir todo dato que se almacene se hará en el navegador del usuario.

Puede ser utilizada para almacenar correos electrónicos localmente para alguna aplicación webmail o para el carrito de compras en un sitio de ventas en línea. La interacción de la API y la Base de Datos es asíncrona lo cual asegura que la interfaz del usuario no sea afectada con retrasos. Y porque la interacción con las bases de datos pueden darse simultáneamente en múltiples ventanas, la API soporta transacciones.

Para crear un objeto de base de datos se utiliza la llamada a la función (método) openDatabase() en el objeto window. Se pasan cuatro parámetros: El nombre de la base de datos, la versión de la base de datos, un nombre a mostrar, y el tamaño estimado en bytes.

1 var db = openDatabase("notas","","Ejemplo de notas", 1048576);

Ahora, con esa instancia podemos utilizar el método transaction(). Este método toma uno a tres parámetros: un retrollamado (callback :  puntero a una función ) de transacción, otra función para error, y otra para un retrollamado de éxito. La primera función requiere que se le pasen objetos SQL transaction en el que se ha de ejecutar las consultas con executeSQL(). Éste último método toma de uno a cuatro parámetros: Una consulta SQL, parámetros, una función que se hará cargo de la llamada (callback), y otra función si se presenta errores. La función que se hará cargo de la llamada a executeSQL(), necesita de el objeto de transacción y el objeto resultante de la consulta SQL el cual da acceso a las filas, al último ID ingresado, etcétera.

El ejemplo de aplicación “notas” es como sigue:

1 var html5 = {}; 2 html5.db = null; 3 4 html5.open = function(){ 5 var dbsize = 1024 * 1024; //1MB 6 html5.db = openDatabase("notas", "1.0", "Mis notas", dbsize); 7 } 8 html5.onError = function(tx, error){ 9 alert('Error :'+error.message); 10 } 11 html5.onSuccess = function(tx, rs){ 12 // mostramos los datos nuevamente 13 html5.mostrarNotas(tx, rs); 14 } 15 html5.createTable = function(){ 16 html5.db.transaction(function(tx){ 17 tx.executeSql("CREATE TABLE IF NOT EXISTS notas(ID INTEGER PRIMARY KEY, titulo TEXT, cuerpo TEXT)", []); 18 }); 19 } 20 html5.addNote = function(titulo, nota){ 21 html5.db.transaction(function(tx){ 22 tx.executeSql("INSERT INTO notas(titulo, cuerpo) VALUES(?,?)",[titulo, nota],html5.onSuccess,html5.onError); 23 }); 24 } 25 html5.mostrarNotas = function(renderFunc){ 26 html5.db.transaction(function(tx){ 27 tx.executeSql("SELECT * FROM notas ORDER BY ID DESC",[],renderFunc, html5.onError); 28 }); 29 } 30 function mostrarNotas(tx, rs){ 31 var salida = ""; 32 for(var i = 0; i < rs.rows.length; i++){ 33 salida += mostrar(rs.rows.item(i)); 34 } 35 var notas = document.getElementById('notas'); 36 notas.innerHTML = salida; 37 } 38 function mostrar(fila){ 39 return "<li>"+fila.titulo + " <a title='borrar nota' style='cursor:pointer;' onclick='html5.borrarNota("+fila.ID+");'>&#x2612;</a><p>"+fila.cuerpo+"</p></li>"; 40 } 41 html5.borrarNota = function(id){ 42 if(!confirm('Eliminar esta nota?'))return false; 43 html5.db.transaction(function(tx){ 44 tx.executeSql("DELETE FROM notas WHERE ID=?",[id],mostrarNotas,html5.onError); 45 }); 46 html5.mostrarNotas(mostrarNotas); 47 } 48 function init(){ 49 html5.open(); 50 html5.createTable(); 51 html5.mostrarNotas(mostrarNotas); 52 } 53 function agregarNota(){ 54 var titulo = document.getElementById('titulo'); 55 var cuerpo= document.getElementById('cuerpo'); 56 html5.addNote(titulo.value, cuerpo.value); 57 titulo.value = ""; 58 cuerpo.value = ""; 59 html5.mostrarNotas(mostrarNotas); 60 }

demo

Veamos qué hace cada una de ellas:

Creamos una ámbito al cual llamaremos html5 para utilizarla más cómodamente.

1 var html5 = {}; 2 html5.db = null;

Luego le agregamos una función open() que nos permita abrir la base de datos.

1 html5.open = function(){ 2 var dbsize = 1024 * 1024; //1MB 3 html5.db = openDatabase("notas", "1.0", "Mis notas", dbsize); 4 }

Esta función onError() mostrará en una caja de alerta el error que se presente:

1 html5.onError = function(tx, error){ 2 alert('Error :'+error.message); 3 }

onSuccess será invocado cada vez que termine una consulta, siempre en cuando sea satisfactoria:

1 html5.onSuccess = function(tx, rs){ 2 // mostramos los datos nuevamente 3 html5.mostrarNotas(tx, rs); 4 }

createTable nos permitirá crear la tabla si ésta aún no exista  :

1 html5.createTable = function(){ 2 html5.db.transaction(function(tx){ 3 tx.executeSql("CREATE TABLE IF NOT EXISTS notas(ID INTEGER PRIMARY KEY, titulo TEXT, cuerpo TEXT)", []); 4 }); 5 }

addNote servirá para ingresar las notas, vea que se utiliza ? la misma que ha de ser reemplazada por los datos referidos entre corchetes “[]“:

1 html5.addNote = function(titulo, nota){ 2 html5.db.transaction(function(tx){ 3 tx.executeSql("INSERT INTO notas(titulo, cuerpo) VALUES(?,?)",[titulo, nota],html5.onSuccess,html5.onError); 4 }); 5 }

mostrarNotas realiza la consulta que obtendrá los datos de la tabla notas:

1 html5.mostrarNotas = function(renderFunc){ 2 html5.db.transaction(function(tx){ 3 tx.executeSql("SELECT * FROM notas ORDER BY ID DESC",[],renderFunc, html5.onError); 4 }); 5 }

Estas funciones “solas” que no pertenecen a var html5, procesa cada fila para poder generar una salida con formato, la misma que se muestra en el elemento div cuyo id es “notas”:

1 function mostrarNotas(tx, rs){ 2 var salida = ""; 3 for(var i = 0; i < rs.rows.length; i++){ 4 salida += mostrar(rs.rows.item(i)); 5 } 6 var notas = document.getElementById('notas'); 7 notas.innerHTML = salida; 8 } 9 function mostrar(fila){ 10 return "<li>"+fila.titulo + " <a title='borrar nota' style='cursor:pointer;' onclick='html5.borrarNota("+fila.ID+");'>&#x2612;</a><p>"+fila.cuerpo+"</p></li>"; 11 }

borrarNota se encargará de eliminar una nota en base al ID que corresponda:

1 html5.borrarNota = function(id){ 2 if(!confirm('Eliminar esta nota?'))return false; 3 html5.db.transaction(function(tx){ 4 tx.executeSql("DELETE FROM notas WHERE ID=?",[id],mostrarNotas,html5.onError); 5 }); 6 html5.mostrarNotas(mostrarNotas); 7 }

init() servirá para inicializar todo lo anterior, vemos que utilizando el ámbito var html5 el código es mucho más ordenado, init puede ser invocado al cargar el documento HTML (BODY) en respuesta al evento ONLOAD :

1 function init(){ 2 html5.open(); 3 html5.createTable(); 4 html5.mostrarNotas(mostrarNotas); 5 }

agregarNota() es una función que permite ingresar los valores de titulo y cuerpo en la tabla notas con addNote, pero es necesario notar que utiliza elementos cuyos IDs son titulo y cuerpo respectivamente, basta crear un botón cuyo evento ONCLICK llame a esta función:

1 function agregarNota(){ 2 var titulo = document.getElementById('titulo'); 3 var cuerpo= document.getElementById('cuerpo'); 4 html5.addNote(titulo.value, cuerpo.value); 5 titulo.value = ""; 6 cuerpo.value = ""; 7 html5.mostrarNotas(mostrarNotas); 8 }