Introducción
Las bases de datos web son nuevas en HTML5. Las bases de datos web se alojan y persisten en el navegador del usuario. Al permitir que los desarrolladores creen aplicaciones con capacidades de consulta enriquecidas, se prevé que surgirá una nueva generación de aplicaciones web que tendrán la capacidad de funcionar en línea y sin conexión.
En el código de ejemplo de este artículo, se muestra cómo crear un administrador de listas de tareas pendientes muy sencillo. Es un recorrido de muy alto nivel por algunas de las funciones disponibles en HTML5.
Requisitos previos
En este ejemplo, se usa un espacio de nombres para encapsular la lógica de la base de datos.
var html5rocks = {};
html5rocks.webdb = {};
Asíncrono y transaccional
En la mayoría de los casos en los que uses la compatibilidad con la base de datos web, utilizarás la API asíncrona. La API asíncrona es un sistema sin bloqueo y, como tal, no obtendrá datos a través de valores mostrados, sino que los datos se entregarán a una función de devolución de llamada definida.
La compatibilidad con la base de datos web a través de HTML es transaccional. No es posible ejecutar sentencias de SQL fuera de una transacción.
Hay dos tipos de transacciones: de lectura y escritura (transaction()) y de solo lectura (readTransaction()). Ten en cuenta que las de lectura y escritura bloquearán toda la base de datos.
Paso 1: Abre la base de datos
Se debe abrir la base de datos para poder acceder a ella.
Debes definir el nombre, la versión, la descripción y el tamaño de la base de datos.
html5rocks.webdb.db = null;
html5rocks.webdb.open = function() {
var dbSize = 5 * 1024 * 1024; // 5MB
html5rocks.webdb.db = openDatabase("Todo", "1", "Todo manager", dbSize);
}
html5rocks.webdb.onError = function(tx, e) {
alert("There has been an error: " + e.message);
}
html5rocks.webdb.onSuccess = function(tx, r) {
// re-render the data.
// loadTodoItems is defined in Step 4a
html5rocks.webdb.getAllTodoItems(loadTodoItems);
}
Paso 2: Crea una tabla
Solo puedes crear una tabla ejecutando una sentencia de SQL CREATE TABLE dentro de una transacción.
Definimos una función que creará una tabla en el evento onload del cuerpo. Si la tabla aún no existe, se creará una.
La tabla se llama todo y tiene 3 columnas.
- ID: una columna de ID secuencial incremental
- todo: una columna de texto que es el cuerpo del elemento
- added_on: la hora en la que se creó el elemento de tareas pendientes
html5rocks.webdb.createTable = function() {
var db = html5rocks.webdb.db;
db.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS " +
"todo(ID INTEGER PRIMARY KEY ASC, todo TEXT, added_on DATETIME)", []);
});
}
Paso 3: Agrega datos a una tabla
Estamos creando un administrador de listas de tareas pendientes, por lo que es muy importante que podamos agregar elementos de tareas pendientes a la base de datos.
Se crea una transacción y, dentro de ella, se realiza una operación INSERT en la tabla todo.
executeSql toma varios parámetros: el SQL que se ejecutará y los valores de los parámetros para vincular la consulta.
html5rocks.webdb.addTodo = function(todoText) {
var db = html5rocks.webdb.db;
db.transaction(function(tx){
var addedOn = new Date();
tx.executeSql("INSERT INTO todo(todo, added_on) VALUES (?,?)",
[todoText, addedOn],
html5rocks.webdb.onSuccess,
html5rocks.webdb.onError);
});
}
Paso 4: Selecciona datos de una tabla
Ahora que los datos están en la base de datos, necesitas una función que los recupere. En Chrome, las bases de datos web usan consultas SELECT de SQLite estándar.
html5rocks.webdb.getAllTodoItems = function(renderFunc) {
var db = html5rocks.webdb.db;
db.transaction(function(tx) {
tx.executeSql("SELECT * FROM todo", [], renderFunc,
html5rocks.webdb.onError);
});
}
Ten en cuenta que todos estos comandos que se usan en este ejemplo son asíncronos y, por lo tanto, los datos no se devuelven desde la transacción ni la llamada a executeSql. Los resultados se pasan a la devolución de llamada correcta.
Paso 4a. Renderiza datos de una tabla
Una vez que se hayan recuperado los datos de la tabla, se llamará al método loadTodoItems.
La devolución de llamada onSuccess toma dos parámetros. La primera es la transacción de la consulta y la segunda es el conjunto de resultados. Es bastante sencillo iterar en los datos:
function loadTodoItems(tx, rs) {
var rowOutput = "";
var todoItems = document.getElementById("todoItems");
for (var i=0; i < rs.rows.length; i++) {
rowOutput += renderTodo(rs.rows.item(i));
}
todoItems.innerHTML = rowOutput;
}
function renderTodo(row) {
return "<li>" + row.todo +
" [<a href='javascript:void(0);' onclick=\'html5rocks.webdb.deleteTodo(" +
row.ID +");\'>Delete</a>]</li>";
}
El efecto de esta llamada de método es que la lista de tareas pendientes se renderiza en un elemento del DOM llamado "todoItems".
Paso 5: Borra datos de una tabla
html5rocks.webdb.deleteTodo = function(id) {
var db = html5rocks.webdb.db;
db.transaction(function(tx){
tx.executeSql("DELETE FROM todo WHERE ID=?", [id],
html5rocks.webdb.onSuccess,
html5rocks.webdb.onError);
});
}
Paso 6: Cómo conectar todo
Cuando se cargue la página, abre la base de datos y crea la tabla (si es necesario) y renderiza los elementos de tareas pendientes que ya estén en la base de datos.
....
function init() {
html5rocks.webdb.open();
html5rocks.webdb.createTable();
html5rocks.webdb.getAllTodoItems(loadTodoItems);
}
</script>
<body onload="init();">
Se necesita una función que extraiga los datos del DOM, por lo que se llama al método html5rocks.webdb.addTodo.
function addTodo() {
var todo = document.getElementById("todo");
html5rocks.webdb.addTodo(todo.value);
todo.value = "";
}