rule generation
Matt S Trout [Sun, 2 Aug 2009 00:18:33 +0000 (20:18 -0400)]
lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm

index 2c3fafe..d2c33f2 100644 (file)
@@ -8,6 +8,7 @@ use Carp::Clan qw/^DBIx::Class/;
 use aliased 'DBIx::Class::ResultSource::Table';
 use aliased 'DBIx::Class::ResultClass::HashRefInflator';
 use String::TT qw(strip tt);
+use Scalar::Util qw(blessed);
 use namespace::autoclean;
 
 # how this works:
@@ -135,7 +136,8 @@ BEGIN {
   };
 
   *qualify_with = sub ($source, @names) {
-    map join('.', $source->name, $_), @names;
+    my $name = blessed($source) ? $source->name : $source;
+    map join('.', $name, $_), @names;
   };
 
   *body_cols = sub ($source) {
@@ -149,7 +151,7 @@ BEGIN {
       $source->primary_columns;
   };
 
-  *name_of = *names_of = sub (@cols) { map $_->{name}, @cols };
+  *names_of = sub (@cols) { map $_->{name}, @cols };
 
   *function_body = sub ($name, $args, $body_parts) {
     my $arglist = join(
@@ -168,7 +170,6 @@ BEGIN {
       $function$ LANGUAGE plpgsql;
     };
   };
-    
 }
 
 BEGIN {
@@ -178,6 +179,21 @@ BEGIN {
   *arg_hash = sub ($source) {
     map +($_ => \(argify $_)), names_of body_cols $source;
   };
+
+  *rule_body = sub ($on, $to, $oldlist, $newlist) {
+    my $arglist = join(', ',
+      (qualify_with 'OLD', names_of @$oldlist),
+      (qualify_with 'NEW', names_of @$newlist),
+    );
+    $to = $to->name if blessed($to);
+    return strip tt q{
+      CREATE RULE _[% to %]_[% on %]_rule AS
+        ON [% on | upper %] TO [% to %]
+        DO INSTEAD (
+          SELECT _[% to %]_[% on %]([% arglist %])
+        );
+    };
+  };
 }
 
 method root_table () {
@@ -196,6 +212,9 @@ method view_definition () {
   push(@sources, $super_view) if defined($super_view);
   my @body_cols = map body_cols($_), @sources;
   my @pk_cols = pk_cols $self;
+
+  # SELECT statement
+
   my $select = $sqla->select(
     ($super_view
       ? ([   # FROM _tbl _tbl
@@ -210,7 +229,11 @@ method view_definition () {
       : ($table->name)),
     [ (qualify_with $table, names_of @pk_cols), names_of @body_cols ],
   ).';';
+
   my ($now, $next) = grep defined, $super_view, $table;
+
+  # INSERT function
+
   # NOTE: this assumes a single PK col called id with a sequence somewhere
   # but nothing else -should- so fixing this should make everything work
   my $insert_func =
@@ -234,10 +257,14 @@ method view_definition () {
           : ()
         )
       ];
+
   # note - similar to arg_hash but not quite enough to share code sanely
   my $pk_where = { # id = _id AND id2 = _id2 ...
     map +($_ => \"= ${\argify $_}"), names_of @pk_cols
   };
+
+  # UPDATE function
+
   my $update_func =
     function_body
       $self->name.'_update',
@@ -248,12 +275,21 @@ method view_definition () {
           $pk_where,
         ), @sources
       ];
+
+  # DELETE function
+
   my $delete_func =
     function_body
       $self->name.'_delete',
       [ @pk_cols ],
       [ map $sqla->delete($_->name, $pk_where), @sources ];
-  return join("\n\n", $select, $insert_func, $update_func, $delete_func);
+
+  my @rules = (
+    (rule_body insert => $self, [], \@body_cols),
+    (rule_body update => $self, \@pk_cols, \@body_cols),
+    (rule_body delete => $self, \@pk_cols, []),
+  );
+  return join("\n\n", $select, $insert_func, $update_func, $delete_func, @rules);
 }
 
 1;