--- /dev/null
+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 };
+ }
+ };
+
+