E. Carpeta « js / bd »

Versión para imprimir.

1. js / bd / Bd.js

1export const ALMACEN_PASATIEMPO = "PASATIEMPO"
2export const PAS_ID = "PAS_ID"
3export const INDICE_NOMBRE = "INDICE_NOMBRE"
4export const PAS_NOMBRE = "PAS_NOMBRE"
5const BD_NOMBRE = "sincronizacion"
6const BD_VERSION = 1
7
8/** @type { Promise<IDBDatabase> } */
9export 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})

2. js / bd / pasatiempoAgrega.js

1import { bdEjecuta } from "../../lib/js/bdEjecuta.js"
2import { creaIdCliente } from "../../lib/js/creaIdCliente.js"
3import { ALMACEN_PASATIEMPO, Bd } from "./Bd.js"
4import { validaNombre } from "../modelo/validaNombre.js"
5import { exportaAHtml } from "../../lib/js/exportaAHtml.js"
6
7/**
8 * @param {import("../modelo/PASATIEMPO.js").PASATIEMPO} modelo
9 */
10export 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
22exportaAHtml(pasatiempoAgrega)

3. js / bd / pasatiempoBusca.js

1import { bdConsulta } from "../../lib/js/bdConsulta.js"
2import { exportaAHtml } from "../../lib/js/exportaAHtml.js"
3import { validaPasatiempo } from "../modelo/validaPasatiempo.js"
4import { ALMACEN_PASATIEMPO, Bd } from "./Bd.js"
5
6/**
7 * @param {string} id
8 */
9export 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
43exportaAHtml(pasatiempoBusca)

4. js / bd / pasatiempoConsultaNoEliminados.js

1import { bdConsulta } from "../../lib/js/bdConsulta.js"
2import { exportaAHtml } from "../../lib/js/exportaAHtml.js"
3import { validaPasatiempo } from "../modelo/validaPasatiempo.js"
4import { ALMACEN_PASATIEMPO, Bd, INDICE_NOMBRE } from "./Bd.js"
5
6export 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
53exportaAHtml(pasatiempoConsultaNoEliminados)

5. js / bd / pasatiempoConsultaTodos.js

1import { bdConsulta } from "../../lib/js/bdConsulta.js"
2import { validaPasatiempo } from "../modelo/validaPasatiempo.js"
3import { ALMACEN_PASATIEMPO, Bd } from "./Bd.js"
4
5/**
6 * Lista todos los objetos, incluyendo los que tienen borrado lógico.
7 */
8export 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}

6. js / bd / pasatiempoElimina.js

1import { bdEjecuta } from "../../lib/js/bdEjecuta.js"
2import { exportaAHtml } from "../../lib/js/exportaAHtml.js"
3import { ALMACEN_PASATIEMPO, Bd } from "./Bd.js"
4import { pasatiempoBusca } from "./pasatiempoBusca.js"
5
6/**
7 * @param { string } id
8 */
9export 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
21exportaAHtml(pasatiempoElimina)

7. js / bd / pasatiempoModifica.js

1import { bdEjecuta } from "../../lib/js/bdEjecuta.js"
2import { exportaAHtml } from "../../lib/js/exportaAHtml.js"
3import { validaId } from "../modelo/validaId.js"
4import { validaNombre } from "../modelo/validaNombre.js"
5import { ALMACEN_PASATIEMPO, Bd } from "./Bd.js"
6import { pasatiempoBusca } from "./pasatiempoBusca.js"
7
8/**
9 * @param { import("../modelo/PASATIEMPO.js").PASATIEMPO } modelo
10 */
11export 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
27exportaAHtml(pasatiempoModifica)

8. js / bd / pasatiemposReemplaza.js

1import { bdEjecuta } from "../../lib/js/bdEjecuta.js"
2import { 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 */
8export 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}