diff --git a/observable/src/components/nafrev2-db.js b/observable/src/components/nafrev2-db.js deleted file mode 100644 index 9b58f16..0000000 --- a/observable/src/components/nafrev2-db.js +++ /dev/null @@ -1,55 +0,0 @@ -import * as duckdb from "npm:@duckdb/duckdb-wasm"; - -const R2_BASE = "https://pub-6526c18d68154746a16baf2f76a38544.r2.dev/nafrev2"; -const NAFREV2_FILES = [ - "sections", - "divisions", - "groupes", - "classes", - "sous_classes", -]; - -const _parquetCache = new Map(); - -async function fetchBuffer(url) { - if (!_parquetCache.has(url)) { - const resp = await fetch(url); - if (!resp.ok) throw new Error(`Failed to fetch ${url}: ${resp.status}`); - _parquetCache.set(url, new Uint8Array(await resp.arrayBuffer())); - } - return _parquetCache.get(url); -} - -let _dbPromise = null; - -export async function initNafrev2DB(invalidation = null) { - if (_dbPromise) return _dbPromise; - _dbPromise = (async () => { - const bundles = duckdb.getJsDelivrBundles(); - const bundle = await duckdb.selectBundle(bundles); - const workerUrl = URL.createObjectURL( - new Blob([`importScripts("${bundle.mainWorker}");`], { - type: "text/javascript", - }), - ); - const worker = new Worker(workerUrl); - const db = new duckdb.AsyncDuckDB(new duckdb.VoidLogger(), worker); - await db.instantiate(bundle.mainModule, bundle.pthreadWorker); - for (const f of NAFREV2_FILES) { - await db.registerFileBuffer( - `${f}.parquet`, - await fetchBuffer(`${R2_BASE}/raw__${f}.parquet`), - ); - } - const conn = await db.connect(); - return { db, conn }; - })(); - if (invalidation) { - invalidation.then(async () => { - const cached = _dbPromise; - _dbPromise = null; - if (cached) (await cached).db.terminate(); - }); - } - return _dbPromise; -} diff --git a/observable/src/data/nafrev2.json.js b/observable/src/data/nafrev2.json.js new file mode 100644 index 0000000..9d6f6d0 --- /dev/null +++ b/observable/src/data/nafrev2.json.js @@ -0,0 +1,30 @@ +import { runDuckDBLoader, parquetPath } from "./db.js"; + +const sections = parquetPath("nafrev2", "sections.parquet"); +const divisions = parquetPath("nafrev2", "divisions.parquet"); +const groupes = parquetPath("nafrev2", "groupes.parquet"); +const classes = parquetPath("nafrev2", "classes.parquet"); +const sousClasses = parquetPath("nafrev2", "sous_classes.parquet"); + +await runDuckDBLoader( + "nafrev2", + `SELECT ns.section_id, ns.section, + nd.division_id, nd.division, + ng.groupe_id, ng.groupe, + nc.classe_id, nc.classe, + nsc.sous_classe_id, nsc.sous_classe + FROM read_parquet(${JSON.stringify(sousClasses)}) nsc + JOIN read_parquet(${JSON.stringify( + classes, + )}) nc ON nsc.classe_id = nc.classe_id + JOIN read_parquet(${JSON.stringify( + groupes, + )}) ng ON nsc.groupe_id = ng.groupe_id + JOIN read_parquet(${JSON.stringify( + divisions, + )}) nd ON nsc.division_id = nd.division_id + JOIN read_parquet(${JSON.stringify( + sections, + )}) ns ON nsc.section_id = ns.section_id + ORDER BY nsc.sous_classe_id`, +); diff --git a/observable/src/nafrev2.md b/observable/src/nafrev2.md index 3af9a95..821354a 100644 --- a/observable/src/nafrev2.md +++ b/observable/src/nafrev2.md @@ -4,39 +4,11 @@ title: NAF Rév. 2 — Nomenclature d'activités ```js import * as Inputs from "npm:@observablehq/inputs"; -import * as d3 from "npm:d3"; import { showPopup } from "./components/popup.js"; -import { initNafrev2DB } from "./components/nafrev2-db.js"; ``` ```js -const { db, conn } = await initNafrev2DB(invalidation); - -const _hierarchyResult = await conn.query(` - SELECT ns.section_id, ns.section, - nd.division_id, nd.division, - ng.groupe_id, ng.groupe, - nc.classe_id, nc.classe, - nsc.sous_classe_id, nsc.sous_classe - FROM read_parquet('sous_classes.parquet') nsc - JOIN read_parquet('classes.parquet') nc ON nsc.classe_id = nc.classe_id - JOIN read_parquet('groupes.parquet') ng ON nsc.groupe_id = ng.groupe_id - JOIN read_parquet('divisions.parquet') nd ON nsc.division_id = nd.division_id - JOIN read_parquet('sections.parquet') ns ON nsc.section_id = ns.section_id - ORDER BY nsc.sous_classe_id -`); -const hierarchy = _hierarchyResult.toArray().map((r) => ({ - section_id: r.section_id, - section: r.section, - division_id: r.division_id, - division: r.division, - groupe_id: r.groupe_id, - groupe: r.groupe, - classe_id: r.classe_id, - classe: r.classe, - sous_classe_id: r.sous_classe_id, - sous_classe: r.sous_classe, -})); +const hierarchy = await FileAttachment("data/nafrev2.json").json(); ``` ```js @@ -252,6 +224,7 @@ window.wdaShowApePopup = (event, cell) => { { label: "Classe", id: ds.classeId, value: ds.classe }, { label: "Code APE", id: ds.apeId, value: ds.ape }, ], + href: `sirene?ape=${encodeURIComponent(ds.apeId)}`, }); }; ```