The SQL console
SQLite, compiled to WebAssembly, running in this tab over the Portugal section's JSON files. The tables are built when the page loads, from a spec that names the file and field behind every column. Pick a worked query or write your own; nothing leaves your browser.
Worked queries
The tables, and the file behind each
This is tables.json, the loader spec, rendered. The build ran the same
spec through Python's sqlite3 and executed every worked query against it; a query that failed or came
back empty would have failed the build. Arrays and objects are stored as JSON text and unpacked with
json_each; booleans as 1 and 0.
| Table | From | Columns |
|---|---|---|
nodes | graph.json → nodes | id, type, label, pack, source, role, role_class, org, day, time, kind, publisher, published, date, url, page, no_longer_listed |
edges | graph.json → edges | id, verb, source, target, pack |
verbs | ontology.json → edges | verb, inverse, domain, range, pt_verb, pt_inverse, reads, origin |
types | ontology.json → node_types | id, pt, colour, definition |
people | people.json → people | id, name, role, org, page, linkedin |
orgs | orgs.json → orgs | id, name, people, placeholder |
sessions | sessions.json → sessions | id, title, day, time, kind, stage |
stages | sessions.json → stages | id, label, pt, also_called |
sources | sources.json → sources | id, snapshot, page, publisher, url, frozen, bytes, sha256, retrieved, state |
coverage | coverage.json → items | id, publisher, kind, published, title, url, source, bytes, sha256, what_it_says |
stories | stories.json → stories | slug, kicker, title, standfirst, published, byline, stands_on |
changes | changes.json → changes | from_snapshot, to_snapshot, count_from, count_to, added, removed, changed, reason_known |
person_topics | topics.json → person_topics | person, topic, source |
person_tags | topics.json → person_tags | person, tag, type, matched, source |
lexicon | lexicon.json → entries | id, type, label, pt, pattern |
Where SQL is the right language, and where it stops
Counting, grouping, joining two named tables, unpacking a column: SQL does these better than any graph language and the first eight worked queries are that. Walking a path is where it strains — one join per hop, the length fixed in the query, nothing known about inverses — and the recursive traversal near the end of the list is the honest picture of what a two-hop neighbourhood costs to ask for. The graph console asks the same two questions in SPARQL, for comparison.
For an agent
After tool:ready (detail.name = 'nsdb-sql'): window.__tools.sql.run(sql) → {columns, rows, ms} or throws with the SQLite message; .tables() lists tables with row counts; .examples() returns the worked queries with their build-time row counts; .timings() the load measurements; .select(id) puts a worked query in the editor. The page reads #q=<urlencoded sql> and ?example=<id>. Every call is read-only; there is no write path by design.