Every val now gets its own SQLite database, and a powerful database UI. This makes it even easier for your vals to persist data and then more transparent to see what data exists, update it manually if you need to, and run queries against the val-specific database.
This also unlocks new ways to collaborate: when you fork one of your own projects, you can choose to fork the database too, so that the new forked val contains a copy of the old database.
Code example
Using the std/sqlite val to access the val database:
import sqlite from "https://esm.town/v/std/sqlite/main.ts";
await sqlite.execute('CREATE TABLE IF NOT EXISTS "docs" (contents TEXT)');
await sqlite.execute('INSERT INTO docs (contents) VALUES ("Hello, world!")');
Demo
…
Every val now gets its own SQLite database, and a powerful database UI. This makes it even easier for your vals to persist data and then more transparent to see what data exists, update it manually if you need to, and run queries against the val-specific database.
This also unlocks new ways to collaborate: when you fork one of your own projects, you can choose to fork the database too, so that the new forked val contains a copy of the old database.
Code example
Using the std/sqlite val to access the val database:
import sqlite from "https://esm.town/v/std/sqlite/main.ts";
await sqlite.execute('CREATE TABLE IF NOT EXISTS "docs" (contents TEXT)');
await sqlite.execute('INSERT INTO docs (contents) VALUES ("Hello, world!")');
Demo
With the built-in SQLite browser you can:
- Add and rename columns
- Delete rows
- Get the schema of any table
- Run queries
- Export tables as CSV
- Dump the database as SQL
History
In 2023 we launched SQLite for every Val Town user, powered by our friends at Turso. Vals could use the database with zero configuration and total control. A lot of the most interesting vals are built on this - my Bluesky ThinkUp Tribute val uses SQLite to store people’s social media bios, and devstats uses the database to track statistics about our repository.
But because databases were scoped to users and organizations, they contained intermixed data: it’s impossible to tell a priori which data came from which val. Scoped databases fix that problem, eliminating conflicts between different vals and making it easy to just browse val-specific data.
Security
We’ve designed scoped databases to be more secure, too: vals can only access their own scoped database, and can’t reach across to access data from other vals. This makes it a lot safer to work on SQLite databases too, because your schema changes can’t affect any other vals.
Under the hood, we’ve added project-scoped API tokens to make this work: each val automatically gets a temporary API token as the VAL_TOWN_API_KEY environment variable. That API token has always belonged to a user, but now it belongs to a val as well, which gives it specific val superpowers.
Existing databases will stick around
We’re supporting both val-scoped and user-scoped databases for the long term: there are uses to both, and there’s no reason to force everyone into a gnarly upgrade path. But val scoped databases are definitely recommended for new projects: they make a lot of things easier, and come with a powerful UI.
Thanks Turso for the continued collaboration!
We’ve provisioned thousands of databases and this will add even more - but it’s possible because Turso runs SQLite in the cloud. This feature really relies on some tricks from Turso too, like forking databases by seeding from point-in-time backups.