| 1 | export const ALMACEN_PASATIEMPO = "PASATIEMPO" |
| 2 | export const PAS_ID = "PAS_ID" |
| 3 | export const INDICE_NOMBRE = "INDICE_NOMBRE" |
| 4 | export const PAS_NOMBRE = "PAS_NOMBRE" |
| 5 | const BD_NOMBRE = "sincronizacion" |
| 6 | const BD_VERSION = 1 |
| 7 | |
| 8 | /** @type { Promise<IDBDatabase> } */ |
| 9 | export const Bd = new Promise((resolve, reject) => { |
| 10 | |
| 11 | /* Se solicita abrir la base de datos, indicando nombre y |
| 12 | * número de versión. */ |
| 13 | const solicitud = indexedDB.open(BD_NOMBRE, BD_VERSION) |
| 14 | |
| 15 | // Si se presenta un error, rechaza la promesa. |
| 16 | solicitud.onerror = () => reject(solicitud.error) |
| 17 | |
| 18 | // Si se abre con éxito, devuelve una conexión a la base de datos. |
| 19 | solicitud.onsuccess = () => resolve(solicitud.result) |
| 20 | |
| 21 | // Si es necesario, se inicia una transacción para cambio de versión. |
| 22 | solicitud.onupgradeneeded = () => { |
| 23 | |
| 24 | const bd = solicitud.result |
| 25 | |
| 26 | // Como hay cambio de versión, borra el almacén si es que existe. |
| 27 | if (bd.objectStoreNames.contains(ALMACEN_PASATIEMPO)) { |
| 28 | bd.deleteObjectStore(ALMACEN_PASATIEMPO) |
| 29 | } |
| 30 | |
| 31 | // Crea el almacén "PASATIEMPO" con el campo llave "PAS_ID". |
| 32 | const almacenPasatiempo = |
| 33 | bd.createObjectStore(ALMACEN_PASATIEMPO, { keyPath: PAS_ID }) |
| 34 | |
| 35 | // Crea un índice ordenado por el campo "PAS_NOMBRE" que no acepta duplicados. |
| 36 | almacenPasatiempo.createIndex(INDICE_NOMBRE, "PAS_NOMBRE") |
| 37 | } |
| 38 | |
| 39 | }) |
| 1 | import { bdEjecuta } from "../../lib/js/bdEjecuta.js" |
| 2 | import { creaIdCliente } from "../../lib/js/creaIdCliente.js" |
| 3 | import { ALMACEN_PASATIEMPO, Bd } from "./Bd.js" |
| 4 | import { validaNombre } from "../modelo/validaNombre.js" |
| 5 | import { exportaAHtml } from "../../lib/js/exportaAHtml.js" |
| 6 | |
| 7 | /** |
| 8 | * @param {import("../modelo/PASATIEMPO.js").PASATIEMPO} modelo |
| 9 | */ |
| 10 | export async function pasatiempoAgrega(modelo) { |
| 11 | validaNombre(modelo.PAS_NOMBRE) |
| 12 | modelo.PAS_MODIFICACION = Date.now() |
| 13 | modelo.PAS_ELIMINADO = 0 |
| 14 | // Genera id único en internet. |
| 15 | modelo.PAS_ID = creaIdCliente(Date.now().toString()) |
| 16 | return bdEjecuta(Bd, [ALMACEN_PASATIEMPO], transaccion => { |
| 17 | const almacenPasatiempo = transaccion.objectStore(ALMACEN_PASATIEMPO) |
| 18 | almacenPasatiempo.add(modelo) |
| 19 | }) |
| 20 | } |
| 21 | |
| 22 | exportaAHtml(pasatiempoAgrega) |
| 1 | import { bdConsulta } from "../../lib/js/bdConsulta.js" |
| 2 | import { exportaAHtml } from "../../lib/js/exportaAHtml.js" |
| 3 | import { validaPasatiempo } from "../modelo/validaPasatiempo.js" |
| 4 | import { ALMACEN_PASATIEMPO, Bd } from "./Bd.js" |
| 5 | |
| 6 | /** |
| 7 | * @param {string} id |
| 8 | */ |
| 9 | export async function pasatiempoBusca(id) { |
| 10 | |
| 11 | return bdConsulta(Bd, [ALMACEN_PASATIEMPO], |
| 12 | /** |
| 13 | * @param {(resultado: import("../modelo/PASATIEMPO.js").PASATIEMPO|undefined) |
| 14 | * => any} resolve |
| 15 | */ |
| 16 | (transaccion, resolve) => { |
| 17 | |
| 18 | /* Pide el primer objeto de ALMACEN_PASATIEMPO que tenga como llave |
| 19 | * primaria el valor del parámetro id. */ |
| 20 | const consulta = transaccion.objectStore(ALMACEN_PASATIEMPO).get(id) |
| 21 | |
| 22 | // onsuccess se invoca solo una vez, devolviendo el objeto solicitado. |
| 23 | consulta.onsuccess = () => { |
| 24 | /* Se recupera el objeto solicitado usando |
| 25 | * consulta.result |
| 26 | * Si el objeto no se encuentra se recupera undefined. */ |
| 27 | const objeto = consulta.result |
| 28 | if (objeto !== undefined) { |
| 29 | const modelo = validaPasatiempo(objeto) |
| 30 | if (modelo.PAS_ELIMINADO === 0) { |
| 31 | resolve(modelo) |
| 32 | return |
| 33 | } |
| 34 | } |
| 35 | resolve(undefined) |
| 36 | |
| 37 | } |
| 38 | |
| 39 | }) |
| 40 | |
| 41 | } |
| 42 | |
| 43 | exportaAHtml(pasatiempoBusca) |
| 1 | import { bdConsulta } from "../../lib/js/bdConsulta.js" |
| 2 | import { exportaAHtml } from "../../lib/js/exportaAHtml.js" |
| 3 | import { validaPasatiempo } from "../modelo/validaPasatiempo.js" |
| 4 | import { ALMACEN_PASATIEMPO, Bd, INDICE_NOMBRE } from "./Bd.js" |
| 5 | |
| 6 | export async function pasatiempoConsultaNoEliminados() { |
| 7 | |
| 8 | return bdConsulta(Bd, [ALMACEN_PASATIEMPO], |
| 9 | /** |
| 10 | * @param {(resultado: import("../modelo/PASATIEMPO.js").PASATIEMPO[])=>void |
| 11 | * } resolve |
| 12 | */ |
| 13 | (transaccion, resolve) => { |
| 14 | |
| 15 | const resultado = [] |
| 16 | |
| 17 | const almacenPasatiempo = transaccion.objectStore(ALMACEN_PASATIEMPO) |
| 18 | |
| 19 | // Usa el índice INDICE_NOMBRE para recuperar los datos ordenados. |
| 20 | const indiceNombre = almacenPasatiempo.index(INDICE_NOMBRE) |
| 21 | |
| 22 | // Pide un cursor para recorrer cada objeto que devuelve la consulta. |
| 23 | const consulta = indiceNombre.openCursor() |
| 24 | |
| 25 | /* onsuccess se invoca por cada uno de los objetos de la consulta y una vez |
| 26 | * cuando se acaban dichos objetos. */ |
| 27 | consulta.onsuccess = () => { |
| 28 | /* El cursor correspondiente al objeto se recupera usando |
| 29 | * consulta.result */ |
| 30 | const cursor = consulta.result |
| 31 | if (cursor === null) { |
| 32 | /* Si el cursor vale null, ya no hay más objetos que procesar; por lo |
| 33 | * mismo, se devuelve el resultado con los pasatiempos recuperados, usando |
| 34 | * resolve(resultado). */ |
| 35 | resolve(resultado) |
| 36 | } else { |
| 37 | /* Si el cursor no vale null y hay más objetos, el siguiente se obtiene con |
| 38 | * cursor.value */ |
| 39 | const modelo = validaPasatiempo(cursor.value) |
| 40 | if (modelo.PAS_ELIMINADO === 0) { |
| 41 | resultado.push(modelo) |
| 42 | } |
| 43 | /* Busca el siguiente objeto de la consulta, que se recupera la siguiente |
| 44 | * vez que se invoque la función onsuccess. */ |
| 45 | cursor.continue() |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | }) |
| 50 | |
| 51 | } |
| 52 | |
| 53 | exportaAHtml(pasatiempoConsultaNoEliminados) |
| 1 | import { bdConsulta } from "../../lib/js/bdConsulta.js" |
| 2 | import { validaPasatiempo } from "../modelo/validaPasatiempo.js" |
| 3 | import { ALMACEN_PASATIEMPO, Bd } from "./Bd.js" |
| 4 | |
| 5 | /** |
| 6 | * Lista todos los objetos, incluyendo los que tienen borrado lógico. |
| 7 | */ |
| 8 | export async function pasatiempoConsultaTodos() { |
| 9 | |
| 10 | return bdConsulta(Bd, [ALMACEN_PASATIEMPO], |
| 11 | /** |
| 12 | * @param {(resultado: import("../modelo/PASATIEMPO.js").PASATIEMPO[])=>void |
| 13 | * } resolve |
| 14 | */ |
| 15 | (transaccion, resolve) => { |
| 16 | |
| 17 | const resultado = [] |
| 18 | |
| 19 | // Pide un cursor para recorrer cada objeto que devuelve la consulta. |
| 20 | const consulta = transaccion.objectStore(ALMACEN_PASATIEMPO).openCursor() |
| 21 | |
| 22 | /* onsuccess se invoca por cada uno de los objetos de la consulta y una vez |
| 23 | * cuando se acaban dichos objetos. */ |
| 24 | consulta.onsuccess = () => { |
| 25 | /* El cursor correspondiente al objeto se recupera usando |
| 26 | * consulta.result */ |
| 27 | const cursor = consulta.result |
| 28 | if (cursor === null) { |
| 29 | /* Si el cursor vale null, ya no hay más objetos que procesar; por lo |
| 30 | * mismo, se devuelve el resultado con los pasatiempos recuperados, usando |
| 31 | * resolve(resultado). */ |
| 32 | resolve(resultado) |
| 33 | } else { |
| 34 | /* Si el cursor no vale null y hay más objetos, el siguiente se obtiene con |
| 35 | * cursor.value*/ |
| 36 | resultado.push(validaPasatiempo(cursor.value)) |
| 37 | /* Busca el siguiente objeto de la consulta, que se recupera la siguiente |
| 38 | * vez que se invoque la función onsuccess. */ |
| 39 | cursor.continue() |
| 40 | } |
| 41 | } |
| 42 | |
| 43 | }) |
| 44 | |
| 45 | } |
| 1 | import { bdEjecuta } from "../../lib/js/bdEjecuta.js" |
| 2 | import { exportaAHtml } from "../../lib/js/exportaAHtml.js" |
| 3 | import { ALMACEN_PASATIEMPO, Bd } from "./Bd.js" |
| 4 | import { pasatiempoBusca } from "./pasatiempoBusca.js" |
| 5 | |
| 6 | /** |
| 7 | * @param { string } id |
| 8 | */ |
| 9 | export async function pasatiempoElimina(id) { |
| 10 | const modelo = await pasatiempoBusca(id) |
| 11 | if (modelo !== undefined) { |
| 12 | modelo.PAS_MODIFICACION = Date.now() |
| 13 | modelo.PAS_ELIMINADO = 1 |
| 14 | return bdEjecuta(Bd, [ALMACEN_PASATIEMPO], transaccion => { |
| 15 | const almacenPasatiempo = transaccion.objectStore(ALMACEN_PASATIEMPO) |
| 16 | almacenPasatiempo.put(modelo) |
| 17 | }) |
| 18 | } |
| 19 | } |
| 20 | |
| 21 | exportaAHtml(pasatiempoElimina) |
| 1 | import { bdEjecuta } from "../../lib/js/bdEjecuta.js" |
| 2 | import { exportaAHtml } from "../../lib/js/exportaAHtml.js" |
| 3 | import { validaId } from "../modelo/validaId.js" |
| 4 | import { validaNombre } from "../modelo/validaNombre.js" |
| 5 | import { ALMACEN_PASATIEMPO, Bd } from "./Bd.js" |
| 6 | import { pasatiempoBusca } from "./pasatiempoBusca.js" |
| 7 | |
| 8 | /** |
| 9 | * @param { import("../modelo/PASATIEMPO.js").PASATIEMPO } modelo |
| 10 | */ |
| 11 | export async function pasatiempoModifica(modelo) { |
| 12 | validaNombre(modelo.PAS_NOMBRE) |
| 13 | if (modelo.PAS_ID === undefined) |
| 14 | throw new Error(`Falta PAS_ID de ${modelo.PAS_NOMBRE}.`) |
| 15 | validaId(modelo.PAS_ID) |
| 16 | const anterior = await pasatiempoBusca(modelo.PAS_ID) |
| 17 | if (anterior !== undefined) { |
| 18 | modelo.PAS_MODIFICACION = Date.now() |
| 19 | modelo.PAS_ELIMINADO = 0 |
| 20 | return bdEjecuta(Bd, [ALMACEN_PASATIEMPO], transaccion => { |
| 21 | const almacenPasatiempo = transaccion.objectStore(ALMACEN_PASATIEMPO) |
| 22 | almacenPasatiempo.put(modelo) |
| 23 | }) |
| 24 | } |
| 25 | } |
| 26 | |
| 27 | exportaAHtml(pasatiempoModifica) |
| 1 | import { bdEjecuta } from "../../lib/js/bdEjecuta.js" |
| 2 | import { ALMACEN_PASATIEMPO, Bd } from "./Bd.js" |
| 3 | |
| 4 | /** |
| 5 | * Borra el contenido del almacén PASATIEMPO y guarda nuevospasatiempos. |
| 6 | * @param {import("../modelo/PASATIEMPO.js").PASATIEMPO[]} nuevospasatiempos |
| 7 | */ |
| 8 | export async function pasatiemposReemplaza(nuevospasatiempos) { |
| 9 | return bdEjecuta(Bd, [ALMACEN_PASATIEMPO], transaccion => { |
| 10 | const almacenPasatiempo = transaccion.objectStore(ALMACEN_PASATIEMPO) |
| 11 | almacenPasatiempo.clear() |
| 12 | for (const objeto of nuevospasatiempos) { |
| 13 | almacenPasatiempo.add(objeto) |
| 14 | } |
| 15 | }) |
| 16 | } |