use v6.d.PREVIEW; use DBIish; class Ultramarine::Model::DBMigration { has $.dbh is required; has Callable @.migrations = (); method get-meta() { my $sth = $.dbh.prepare(q:to/END/); SELECT * FROM meta ORDER BY version DESC LIMIT 1 END $sth.execute; return $sth.row(:hash); CATCH { when X::DBDish::DBError { return Nil } } LEAVE { .finish with $sth } } method !update-meta(*%new-values) { my @columns = %new-values.keys; my @values = %new-values{|@columns}; $.dbh.do(qq:to/END/,@values); INSERT INTO meta({@columns.join(',')}) VALUES ({@columns.map({'?'}).join(',')}) END } method !create-meta() { $.dbh.do(q:to/END/); CREATE TABLE meta ( version INTEGER NOT NULL, done_at TEXT DEFAULT (datetime('now')) ) END self!update-meta(:0version); return %(:0version); } method ensure-schema() { my %meta = self.get-meta() // self!create-meta(); my $version = %meta; while (@.migrations[$version]) -> $migration { $migration.($.dbh); ++$version; self!update-meta(:$version); } } }