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 | } |