Ejemplo de IndexedDB la BD de HTML5
HTML5 trae un montón de nuevas posibilidades al navegador. Se ha hablado mucho del formato de vídeo,
del canvas, los websockets, de los nuevos controles de formulario pero a mí en particular me ha interesado
especialmente aquello de una BD en el cliente. Es un tema que no está tan documentado como el resto
y que en muchos libros de HTML5 o ni se menciona o se hace de pasada. Y lo que es peor, hay información
en blogs pero a nada que esté desfasada los ejemplos no funcionan como la llamada a setVersion()
. Así que mucho ojo, si lees sobre este tema, procura que sea información reciente.
Pues parece que va en serio. Había un par de modelos en liza, uno basado en SQLite llamado WebSQL y otro más del estilo noSQL. Aunque WebSQL éstá soportado aún por Safari, Opera y Chrome el consorcio ha dicho que WebSQL no va a formar parte del estándar, por tanto el w3 se decanta por el otro modelo, llamado IndexedDB y que viene a ser un estilo CouchDB, MongoDB, etc... es decir, olvídate de SQL, da la bienvenida a los ObjectStores, Bases de datos que se lo ponen a huevo a las aplicaciones javascript.
Conexión y estilo
No voy a poner todo el código aquí pero sí la parte de la conexión que es lo más curioso junto con las consultas, que son algo durillas si estás acostumbrado al SQL. Esto es Javascript y en el caso de los métodos en torno a IndexedDB funcionan de forma asíncrona. Es decir, al dar la orden de abrir la BD el programa no se detiene para hacerlo, sino que deja una petición que debe ser recogida por un handler (onsuccess, onerror, etc...). Con las operaciones CRUD es lo mismo. Y por otro lado hay operaciones como la de crear el ObjectStore que solo se pueden llevar a cabo dentro de onupgradeneeded de lo contrario te salta una excepción de illegal state. Cosas así que francamente me han traido de cabeza y con la conclusión de que IndexedDB necesita un wrapper para todos los navegadores que nos haga la vida más fácil, que seguramente ya lo habrá.
Otra cosa curiosa con la que he jugado es con el cambio de versiones. Podemos pasarle un parámetro numérico a la llamada open para indicarla la versión de la BD. IndexedDB mantiene internamente un control de versiones por lo visto. Si cambiamos a una versión nueva se disparará el evento onupgradeneeded donde podremos ajustar la BD. Ese evento también se dispará la primera vez que se abre la BD y ahí es donde se deben crear tablas e índices.
var db; var openedDB; var database = "linksdb"; var description = "A database containing interesting links"; var objectStore = 'links'; var openDB; /** * openCreate * opens and/or creates an IndexedDB database */ function openCreate () { // We could open changing version ..open(database,3) var openDB = indexedDB.open(database); // This is how we pass the DB instance to our var openDB.onsuccess = function(event) { db = event.target.result; console.log('Database opened ' + db); }; // Very importante event fired when // 1. ObjectStore first time creation // 2. Version change openDB.onupgradeneeded = function (event) { // value of previous db instance is lost!! we get it back // using the event db = this.result; console.log("updgrade needed: " + db); try { //db.deleteObjectStore(objectStore); console.log("Object store deleted"); var store = db.createObjectStore(objectStore,{keyPath: 'id', autoIncrement:true}); console.log("Object store created"); store.createIndex("link", "link", { unique: false }); console.log("Index created on link"); store.createIndex("description", "description", { unique: false }); console.log("Index created on description"); } catch (e) { console.log("Exception creating object store: " + e); } } openDB.onerror = function(event) { console.log('Something went wrong...'); }; }
Demo CRUD
Bueno, basta de cháchara. Aquí debajo he metido todo el código de una BD indexedDB, que he comprobado y programado con la ayuda de Chrome (es donde me ha funcionado sin problema no he probado a actualizar el firefox y de explorer ya jejeje pa qué). Importante:
- Abre la consola de desarrollador la parte Console para los logs y Resource para ver la BD
- Pincha en el enlace de OPEN/CREATE, y prueba las operaciones
IndexedDB CRUD, tested successfully with win32 Chrome v28.0.1500.95 m
OPEN/CREATE DatabaseIndexedDB CRUD
CREATE
url description Create dataREAD one
id READ one recordREAD ALL
Link Search by link
UPDATE
id url description Update dataDELETE
id delete datadelete all
Drop Database