sub argify (@cols) { map $_->new(%$_, name => '_'.$_->name), @cols; } sub body_cols ($source) { grep $_->name ne 'id', $source->all_cols; } my @pk_col = ($table->col('id')); my @sources = grep defined, $table, $super_view; my @body_cols = map body_cols($_), @sources; CREATE VIEW $view_name => SELECT { (map $_->qualify, @pk_col), @body_cols, } FROM { $super_view ? ($table->join($super_view)->using(@pk_col)) : $table }; my ($now, $next) = grep defined, $super_view, $table; CREATE FUNCTION "${view_name}_insert" => (argify @body_cols) => RETURNS VOID => AS { INSERT INTO { $now } (body_cols $now) => VALUES (argify body_cols $now); if ($next) { INSERT INTO { $next } ($next->all_cols) => VALUES { $root_table->col('id')->sequence->currval, argify body_cols $next }; } }; my $pk_eq = AND( map (expr { $_ == argify $_ }), @pk_col); CREATE FUNCTION "${view_name}_update" => (argify @pk_col, @body_cols) => RETURNS VOID => AS { foreach my $s (@sources) { UPDATE { $s } SET { map ($_ => argify $_), body_cols $s } WHERE { $pk_eq }; } }; CREATE FUNCTION "${view_name}_delete" => (argify @pk_col) => RETURNS VOID => AS { foreach my $s (@sources) { DELETE FROM { $s } WHERE { $pk_eq }; } };