use v6.d.PREVIEW; use DBI::Async; class Ultramarine::Model::DBMigration { has $.dbh is required; has Callable @.migrations = (); method get-meta() { return $.dbh.query(q:to/END/).hash; SELECT * FROM meta ORDER BY version DESC LIMIT 1 END CATCH { when X::DBDish::DBError { return Nil } } } method !update-meta(*%new-values) { my @columns = %new-values.keys; my @values = %new-values{|@columns}; my $query = qq:to/END/; INSERT INTO meta({@columns.join(',')}) VALUES ({@columns.map({'?'}).join(',')}) END say $query; $.dbh.query($query,@values).finish; } method !create-meta() { $.dbh.query(q:to/END/).finish; 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); } } }