JavaScript - HTML5 - IndexedDb
-
Upload
eduard-tomas -
Category
Software
-
view
461 -
download
2
Transcript of JavaScript - HTML5 - IndexedDb
IndexedDbAlmacenamiento (de verdad) en local en HTML5
Eduard TomàsDeveloper @ Plain Concepts – http://plainconcepts.com
@eiximenis Escuela IT - http://escuela.it
Qué es IndexedDb
• Almacenamiento de datos en local
• No relacional (nada de “tablas”, “joins” o “SQL”)
• Almacena objetos JavaScript
• Rápido y válido para grandes volúmenes de datos
Conceptos IndexedDb
• IndexedDb usa almacenamiento (clave, valor)• Todas las operaciones son transaccionales• La API es totalmente asíncrona• Las peticiones asíncronas se modelan como objetos
“request”• Los objetos “request” usan eventos DOM para comunicar
éxito o fallo.• Los valores de IndexedDb son objetos JavaScript• Es un modelo no-relacional (no SQL)
Base de Datos
• Una base de datos contiene uno o más almacenes de objetos.
• Tiene un nombre y una versión
• IndexedDb está preparado para “cambios de esquema”
• Las BBDD son durables*
* Bueno... “casi durables”
Abrir una BBDD
• Método open de window.IndexedDB
• Devuelve una request• oncomplete
• En evt.target.result tenemos la BBDD (objecto IDBDatabase)• onerror
Borrar una BBDD
• El método deleteDatabase del objeto indexedDB borra una base de datos
• indexedDB.deleteDatabase(“my-db”).onsuccess = function(evt) {...}
Evento onupgradeneeded
• Cuando la versión local de la BBDD no coincide con la solicitada se ejecuta este evento.• En evt.target.result tenemos la BBDD (objecto IDBDatabase)
• Aquí debemos crear todos los almacenes necesarios según la versión indicada.
Evento onupgradeneeded
• En dicho evento no tenemos que recrearla toda en este evento.• Solo los cambios necesarios para pasar a la versión pedida.
• La función gestora de onupgradeneeded debe estar preparada para preguntar “qué hay en la BBDD” y actualizar lo que falte de almacenes y índices.
Evento onupgradeneeded
• La propiedad objectStoreNames de la base de datos devuelve los nombres de todos los object stores existentes.
• Para obtener un objectStore debemos hacerlo a través de la transacción de upgrade• var store = evt.currentTarget.transaction.o bjectStore(“xxx”)
Crear almacenes
• Obtener una referencia a la BBDD
• Usar método createObjectStore(“nombre”, opciones)• Opciones contiene keyPath o autoIncrement
• keyPath: ‘name’ -> Establece name como la propiedad indexada (única)• autoIncrement: ‘id’ -> Establece id como una propiedad autoincremental
createObjectStore("note", { keyPath: "id", autoIncrement:true });
• Eso devuelve una referencia al object store
Añadir datos
• Los datos se añaden a un almacen
• Debe crearse una transacción • db.transaction(stores, mode)
• stores -> String con nombre de store o array con nombre de n stores• Mode
• readonly• readwrite• readwriteFlush (FF only)
• Una vez se tiene la Tx se obtiene el objectstore con tx.objectstore(“name”)
Añadir datos
• Llamada al método add del objectstore
• Eso devuelve una request (asíncrono)
• Gestionar los eventos• onsuccess• onerror
Errores en transacciones
• Los eventos de IndexedDB “fluyen” hacia arriba
• Si hay un error insertando un dato• Se ejecuta onerror de la request correspondiente• Se ejecuta onerror de la transacción correspondiente• Se ejecuta onerror de la bbdd correspondiente
Lectura de datos
• Se realiza también en el contexto de una transacción
• Se usa el método get del almacén para obtener el elemento asociado a una clave• El método get devuelve una request (onsuccess, onerror)
• db.transaction(“store”).objectstore(“store”).get(“key-value”).onsuccess = function(evt) { var data = evt.target.value;}
Lectura de datos - cursores
• El cursor se usa para iterar sobre los elementos de un almacén
• Se obtiene a partir del método openCursor de un almacén• El método openCurso devuelve una request• Siempre dentro del contexto de una transacción
• var r = db.transaction(“store”).objectStore(“store”).openCursor();• r.onsuccess = function(evt) { var c = event.target.result;}
Lectura de datos - cursores
• cursor.value -> Valor actual del cursor• cursor.continue() -> Avanza al siguiente elemento• cursor.advance() -> Avanza al siguiente elemento n veces
Lectura de datos - índices
• Para buscar a sobre los valores de una propiedad se requiere un índice montado sobre esta propiedad
• El método createIndex del almacén permite definir un índice sobre él.• createIndex(name, path, options)
Lectura de datos - índices
• name -> Nombre del índice• path -> Propiedad sobre la que se crea el índice• options
• unique -> true / false (si el índice es único)• multiEntry -> Si vale true permite operar con índices sobre arrays
Lectura de datos - índices
• El método index del objectStore permite obtener un índice• store.index(“name”)
• El índice expone los métodos• get -> Obtiene el elemento con el valor del índice indicado (único)• openCursor -> Obtiene un cursor que itera sobre los elementos del
almacén pero según el índice.
Cursores - Rangos
• El método openCursor puede recibir un rango como parámetro. Eso devuelve un cursor que itera solamente dentro de ese rango.
• Para construir el rango se usa IDBKeyRange
Cursores - Rangos
Rango Code
Claves ≤ x IDBKeyRange.upperBound(x)Claves < x IDBKeyRange.upperBound(x, true) Claves ≥ y IDBKeyRange.lowerBound(y)Claves > y IDBKeyRange.lowerBound(y, true)Claves ≥ x && ≤ y IDBKeyRange.bound(x, y)Claves > x &&< y IDBKeyRange.bound(x, y, true, true)Claves > x && ≤ y IDBKeyRange.bound(x, y, true, false)Claves ≥ x &&< y IDBKeyRange.bound(x, y, false, true)Clave = z IDBKeyRange.only(z)
Eliminar datos
• Método delete(key) del objectStore elimina el objeto con la clave indicada
• Como siempre, dentro del contexto de una transacción
• var req = db.transaction(“store”, “readwrite”).objectStore(“store”).delete(key);
• req.onsuccess = function(evt) {...}
Modificar datos
• El método put del almacén permite modificar datos
• Como siempre... Dentro de una transacción ;-)
• var store = db.transaction(“store”).objectStore(“store”);• store.put(data).onsuccess = function(evt) {...}