/** * Carga el glosario del taller. * * npm run db:glosario * * Veintiocho términos con sus acepciones numeradas y las formas con las que * aparecen de verdad en el texto. Es lo que hace posible el marcado: sin las * variantes, «sinalefas» en plural no se reconocería y nadie echaría en falta * el globo que no salió. * * Idempotente por slug: reimportar una definición corregida actualiza. Las * acepciones se rehacen enteras —se borran y se vuelven a poner— porque su * número es su identidad y renumerar a mano dejaría huecos. */ import fs from 'node:fs'; import pg from 'pg'; const SEMILLA = JSON.parse(fs.readFileSync('scripts/db/semilla-glosario.json', 'utf8')); const slugificar = (t) => t .toLowerCase() .normalize('NFD') .replace(/[̀-ͯ]/g, '') .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, ''); const c = new pg.Client({ connectionString: process.env.DATABASE_URL, query_timeout: 60_000 }); await c.connect(); await c.query('BEGIN'); const contado = { termino: 0, acepcion: 0, variante: 0 }; const avisos = []; try { const vistos = new Set(); for (const t of SEMILLA.terminos) { const slug = slugificar(t.termino); if (vistos.has(slug)) { avisos.push(`«${t.termino}» sale dos veces en la semilla`); continue; } vistos.add(slug); const { rows } = await c.query( `INSERT INTO termino (id, slug, termino) VALUES ($1,$2,$3) ON CONFLICT (slug) DO UPDATE SET termino = EXCLUDED.termino RETURNING id`, [crypto.randomUUID(), slug, t.termino] ); const terminoId = rows[0].id; contado.termino++; await c.query('DELETE FROM acepcion WHERE termino_id = $1', [terminoId]); for (const [i, a] of t.acepciones.entries()) { await c.query( `INSERT INTO acepcion (id, termino_id, numero, categoria, definicion, ampliacion, ejemplo) VALUES ($1,$2,$3,$4,$5,$6,$7)`, [ crypto.randomUUID(), terminoId, i + 1, a.categoria, a.definicion, a.ampliacion ?? null, a.ejemplo ?? null ] ); contado.acepcion++; } /* * El propio término también es una forma buscable, así no hay que * repetirlo en la lista de variantes de los veintiocho. */ await c.query('DELETE FROM termino_variante WHERE termino_id = $1', [terminoId]); for (const forma of new Set([t.termino, ...(t.variantes ?? [])])) { await c.query( 'INSERT INTO termino_variante (termino_id, forma) VALUES ($1,$2) ON CONFLICT DO NOTHING', [terminoId, forma.toLowerCase()] ); contado.variante++; } } await c.query('COMMIT'); } catch (fallo) { await c.query('ROLLBACK').catch(() => {}); console.error('Falló, no se ha escrito nada:'); console.error(' ' + fallo.message); await c.end(); process.exit(1); } await c.end(); for (const [que, n] of Object.entries(contado)) console.log(` ${que.padEnd(10)} ${n}`); for (const aviso of avisos) console.log(` aviso: ${aviso}`); console.log(''); console.log('Glosario cargado.');