HTML5 y Bases de Datos locales

Otra de las grandes novedades de HTML5 es las nuevas alternativas respecto a la forma de guardar información en el cliente por parte de una web. Hasta ahora, la única alternativa que se tenia desde una web era usar cookies. HTML5 introduce tres nuevas formas, «local» y «session» storage y por otro lado la posibilidad de manejar toda una base de datos relacional que reside en cada cliente. A diferencia del localstorage o sessionstorage, que son mas similares a las cookies, el hecho de manejar una base de datos totalmente funcional es una novedad bastante importante que puede ayudar a nuestras webs a guardar información de una forma mucho mas estructurada.

Como hemos dicho, la base de datos es de tipo relacional, por lo que el lenguaje para «hablar» con ella será enteramente SQL.

Aunque expresamente la W3 desaconseja ligar el estándar a una implementación concreta, en la practica, prácticamente la totalidad de navegadores han usado SQL lite para implementar la gestión de la base de datos.

Como sabemos, no el SQL que entiende todas las bases de datos es igual, existen lo que se denominan «dialectos», debido a que SQL lite es casi la opción «de-facto» podremos usar el «dialecto» del SQL lite en las sentencias. Aunque, al igual que el estándar desaconsejaba ligarse a una implementación, no es buena idea ligar el código a un dialecto, pues puede ser que en algún momento uno de los navegadores decida utilizar otro «backend» de bases de datos, y haga nuestro código incompatible. Lo ideal es usar, en la medida de lo posible, el SQL mas cercano al estándar.

Pese a todo esto, de momento y hasta que no se plantee una implementación independiente, el estándar de HTML5 respecto al «WebSQL» apunta a que el dialecto a seguir es del SQL lite.

Pasando ya a como usar la base de datos desde javascript, el primer paso es obtener una referencia a la base de datos para poder operar con ella. Para ello usaremos la función openDatabase() donde le pasaremos, el nombre de la base de datos, la versión del esquema y el tamaño estimado.

Una vez tenemos la referencia de la base de datos, vamos a ver que, prácticamente la totalidad de los métodos son asíncronos, por lo que típicamente los argumentos serán callbacks. En este caso Javascript sale a nuestra ayuda, como seguramente sabremos, en Javascript podemos encapsular en una variable la declaración de una función, por lo que la forma mas común de pasar los parámetros a las funciones que operan en la base de datos es incluir la declaración de los propios callbacks, ya que habitualmente, no será muy útil reutilizar dichos callbacks.

Las dos funciones más usadas sin duda van a ser «transaction» y «executeSql», con la primera crearemos una transacción que se ejecutará contra la base de datos de forma atómica (bueno, esa es la definición de transacción, no?), mientras que con la segunda, como su nombre indica ejecutaremos las propias sentencias sql.

A continuación veremos un simple ejemplo en el que creamos una base de datos de usuarios en el cliente, donde guardamos cosas como su nombre de usuario o password.

<html>
<head>
<script type="text/javascript">
    var db;
    function init() {
        db = openDatabase("DB Prueba", "0.1", "Database Prueba", 200000);
        if (db) {
            // Database opened
			db.transaction( function(tx) {
				tx.executeSql("CREATE TABLE IF NOT EXISTS usuarios(userid integer primary key autoincrement, username text, password text)")
			});
        }

		listUsers();

    }

	function showUsers(users) {
		var place = document.getElementById("usersDiv");
		if (place.getElementsByTagName("ul").length > 0 )
			place.removeChild(place.getElementsByTagName("ul")[0]);
		var list = document.createElement("ul");

		for ( var i = 0; i < users.length; i++) {
			var item = document.createElement("li");
			item.innerHTML += "<b>userId:</b>" + users[i][0] + " <b>userName:</b>"
					+ users[i][1] + " <b>password:</b>" + users[i][2] +
					"<button onclick='removeUser("+ users[i][0]+")'>Remove</button>";
			list.appendChild(item);
		}
		place.appendChild(list);
	}

	function listUsers() {
		db.transaction( function(tx) {
			tx.executeSql("SELECT * FROM usuarios", [],
				function(tx, result){
					var output = [];
					for(var i=0; i < result.rows.length; i++) {
						output.push([result.rows.item(i)['userid'],
								result.rows.item(i)['username'],
								result.rows.item(i)['password']]);
					}

					showUsers(output);

				});
		});
	}

	function addUser(username, password) {
		db.transaction( function(tx) {
			tx.executeSql("INSERT INTO usuarios(username, password) VALUES(?,?)", [username, password]);
		});
		listUsers();
	}

	function removeUser(userId) {
		db.transaction(function(tx) {
			tx.executeSql("DELETE FROM usuarios WHERE userId=?",[userId], listUsers);
		})
	}
</script>
</head>
<body onload="init()">
<div id="usersDiv">
	Usuarios en local
</div>
<div id="newuser">
	Crear nuevo usuario<br/>
	Usuario: <input type="text" id="username"/><br/>
	Password: <input type="password" id="password"/><br/>
	<button onclick="addUser(username.value, password.value)">Add User</button>
</div>
</body>

</html>

Desde luego es una gozada que sea tan sencillo trabajar con una base de datos de una forma tan sencilla 🙂

Además, tenemos que sumarle la gran calidad de las herramientas de depuración que nos aportan los navegadores, en la captura que encabeza la entrada podemos ver la que tiene Safari. Si somos usuarios de chrome veremos que la ventana es idéntica, esto es por que Chrome al igual que Safari se basa en webkit.

Después de leer el post, podemos sacar la conclusión de que es muy sencillo operar con bases de datos en cliente, y es totalmente cierto, pero ahora hay que pensar bien cuando esta opción es la mejor y cuando los datos solo se guardan en el servidor.

16 Responses to HTML5 y Bases de Datos locales

  1. miguel serra dice:

    Gracias, sólo me funciona con el chrome, ni siquiera con la beta del firefox 4.
    Todo el código para trabajar con datos lo maneja javascript, no veo código html diferente de versiones anteriores.

    No son críticas son comentarios, te estoy agradecido por el ejemplo, lo he modificado un poco para hacer una lista de tareas por hacer y borrarlas cuando estén acabadas.

    Seguiré investigando.

  2. davidsnbl dice:

    Impresionante!!

    Preguntas: ¿que motor de base de datos utiliza? ¿Se puede cambiar a MySQL o SQLServer? ¿Que límite de tamaño de datos tiene?

    Gracias.

    • robjperez dice:

      Gracias por el comentario 🙂

      Realmente lo que se nos proporciona es la API JS para acceder a la base de datos, el motor lo pone el browser por debajo y puede ser cualquiera que considere oportuno.

      En la realidad, la mayoria de browsers utilizan sqlite.

      Sobre lo de migrarlo a un servidor externo, una vez mas la responsabilidad recae en el browser, aunque no parece muy práctico el tener que hacer depender el browser de un sistema de base de datos.

      Respecto al tamaño, una vez mas es el browser quien pone la limitación, en teoría puede ser ilimitado, pero segun el browser nos puede limitar a 5Mb o 50Mb.

      La conclusión que hay que sacar es que nosotros utilizamos las funciones JS sin preocuparnos como el browser funciona por debajo.

  3. Nicolas dice:

    Excelente tu publicación ando buscando info sobre estos temas, para mejorar el funcionamiento de mis bases de datos (geograficas). Te digo gracias y próximamente veré como puedo implementar este codigo en mis web http://www.calles-de-tucuman.com.ar. saludos

  4. ceiboart dice:

    sql ite es una buena opción no solo para paginas Web, sino también para complejos programas de gestión
    😀

  5. ajimenezm dice:

    Donde queda almacenada la base de datos

  6. ¿existen problemas de dominio a la hora de acceder a la base de datos? Estuve intentando hacer algo parecido con el Local Storage pero el problema de dominios me lo impidio. Así pues me gustaría saber si las bases de datos que creamos están ligadas a un dominio o son accesibles desde cualquiera.

  7. ¿Son accesibles las bases de datos desde cualquier otro dominio?

  8. sebastian dice:

    no creo que sea aconsejable tener el codigo expuesto, info sobre tus tablas etc

  9. Ignacio dice:

    Hola como estas! buenisimo el script justo estoy empezando con esto de html5 y sus diferentes implementaciones… disculpa por la pregunta q te voy a hacer es que no estoy mucho en el tema..
    tome tu codigo y lo quiero ejecutar en mi chrome pero solo me muestra el codigo mismo que esta dentro.. tipo no lo compila o ejecuta.. porque es? estoy haciendo algo mal?
    saludos!

  10. Nesta dice:

    Buenas, tengo una duda. Esto es para acceder a bases de datos locales, ¿no? ¿Si tengo una base de datos alojada online podría acceder a ella? Entiendo que no porque javascript se ejecuta localmente en el equipo del navegador, no en el servidor, pero entonces el problema es que no se puede usar este método de acceso para publicar una web que acceda a nuestra base de datos, ¿no? Gracias de antemano.

    Saludos.

  11. Juan T dice:

    robjperez Excelente tu aporte!

    Pero estoy tratando de hacerlo con una base de datos que cree de ante mano y no me crea la tabla «usuarios», por lo que me surgen 2 preguntas.

    1) ¿A que se puede deber que no cree la tabla «usuarios» sobre mi base de datos, si ejecuto el comando
    tx.executeSql(«CREATE TABLE IF NOT EXISTS usuarios(userid integer primary key autoincrement, username text, password text)»)
    una vez ya abierta la conexión con la base de datos?
    2) ¿Donde crea la base «DB Prueba» ?

    • Bigo dice:

      Me pasa lo mismo,yo cree un archivo.sqlite y quiero manejar la info ahi dentro. Mi cliente solicita llevarse la web junto con el fichero y que lo pueda manejar en cualquier compu manteniendo la info guardada con anterioridad, es posible esto?

  12. malike dice:

    Echa un vistazo a una herramienta gratuita – Valentina Studio. Producto asombroso! OMI es el mejor gestor de SQLite para todas las plataformas. http://www.valentina-db.com/en/valentina-studio-overview

  13. Manuel Izquierdo dice:

    A fecha 05-2014 sigue sin funcionar en mozilla-firefox.
    Muy buen articulo. He encontrado una base datos hecha
    en javascript JSSQL. Si funciona ya te diré. Saludos.

  14. Corleone dice:

    Que buena publicación..!! pero necesito ayuda, tome tu código como ejemplo con mas tablas y mas conexiones, cuando inserto datos llega momentos en que no introduce datos a una determinada tabla, tal vez porque no cerra la conexión a la base de datos, me podrías dar una ayuda con eso.
    Gracias de antemano…!!

Deja un comentario