-
-
Notifications
You must be signed in to change notification settings - Fork 2
Automatic Schema Versioning
⚡️ Create, alter, and drop schemas without needing to worry about versioning.
Linked QL comes with the concept of versioning to your database, and along with it, a powerful rollback and rollforward mechanism! Meet Linked QL's Automatic Schema Savepoints and Rollbacks!
Here, you alter your schema and get back a reference to a "savepoint" automatically created for you:
// Alter schema and obtain savepoint
const savepoint = await client.query(
`CREATE TABLE public.users (
id int,
name varchar
)`,
{ desc: 'Create users table' }
);
You are able obtain same savepoint on-demand:
const savepoint = await client.database('public').savepoint();
Inspect savepoint:
// Some details
console.log(savepoint.versionTag()); // 1
console.log(savepoint.commitDesc()); // Create users table
console.log(savepoint.commitDate()); // 2024-07-17T22:40:56.786Z
// Everything...
console.log(savepoint.jsonfy());
Console
{ // Internal parameters... master_savepoint: null, id: '952cc6ae-5b5b-4534-8b03-dc38ee8658ac', database_tag: 'db.1730978107426', // Schema snapshot... name: 'public', '$name': null, tables: [ { name: 'users', columns: [Array], constraints: [], indexes: [], status: 'new' } ], status: null, // Version details... version_tag: 1, version_tags: [ 1 ], version_state: 'commit', commit_date: '2024-07-17T22:40:56.786Z', commit_desc: 'Create users table', commit_ref: null, commit_pid: '72776', rollback_date: null, rollback_desc: null, rollback_ref: null, rollback_pid: null, // Cascades... cascades: [] }
Roll back savepoint:
// Preview the rollback SQL
console.log(savepoint.restorePreview());
// "DROP TABLE public.users CASCADE"
// Execute rollback (drops "users" table)
await savepoint.rollback({
desc: 'Users table unnecessary'
});
Roll forward savepoint:
// Preview the re-commit SQL
console.log(savepoint.restorePreview());
// "CREATE TABLE public.users (...)"
// Execute recommit (recreates "users" table)
await savepoint.recommit({
desc: 'Users table necessary again'
});
Roll all the way back (or forward) to a point in time:
// Rollback to a point
let savepoint;
while((savepoint = await client.database('public').savepoint()) && savepoint.versionTag() > 3) {
await savepoint.rollback({
desc: 'These changes are no more necessary'
});
}
// Rollforward to a point
let savepoint;
while((savepoint = await client.database('public').savepoint({ lookAhead: true })) && savepoint.versionTag() <= 5) {
await savepoint.recommit({
desc: 'These changes are necessary again'
});
}
You essentially get time travel in any direction - and as seamlessly as you move on a movie track!
✨ Meanwhile, your schema histories now live as data (instead of as files), making them queryable, analyzable, and even visualizable, just as regular data! Plus, the DB now essentially becomes the absolute source of truth for both itself and its client applications!
See Linked QL Migration to see how versioning works in during migrations.