From: Matt S Trout Date: Sun, 2 Aug 2009 00:08:30 +0000 (-0400) Subject: generate function bodies X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=05fd24773189f8638cb40e16f2cf3b5ce981189e;p=dbsrgits%2FDBIx-Class-ResultSource-MultipleTableInheritance.git generate function bodies --- diff --git a/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm b/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm index 8f5fe21..2c3fafe 100644 --- a/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm +++ b/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm @@ -7,6 +7,7 @@ use Method::Signatures::Simple; 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 namespace::autoclean; # how this works: @@ -65,6 +66,7 @@ method _attach_additional_sources () { map $schema->source($_), $schema->sources; confess "Couldn't find attached source for parent $parent_name - did you use load_classes? This module is only compatible with load_namespaces" unless $parent; + $self->parent_source($parent); # so our parent is the one in this schema } # create the raw table source @@ -107,7 +109,7 @@ method set_primary_key (@args) { method raw_source_name () { my $base = $self->source_name; - confess "Can't generate raw source name when we don't have a source_name" + confess "Can't generate raw source name for ${\$self->name} when we don't have a source_name" unless $base; return 'Raw::'.$base; } @@ -147,14 +149,43 @@ BEGIN { $source->primary_columns; }; - *names_of = sub (@cols) { map $_->{name}, @cols }; + *name_of = *names_of = sub (@cols) { map $_->{name}, @cols }; - *arglist = sub (@cols) { - map join(' ', @{$_}{qw(name data_type)}), @cols; + *function_body = sub ($name, $args, $body_parts) { + my $arglist = join( + ', ', + map '_'.join(' ', @{$_}{qw(name data_type)}), + @$args + ); + my $body = join("\n", '', map " $_;", @$body_parts); + return strip tt q{ + CREATE OR REPLACE FUNCTION [% name %] + ([% arglist %]) + RETURNS VOID AS $function$ + BEGIN + [%- body %] + END; + $function$ LANGUAGE plpgsql; + }; }; } +BEGIN { + + use signatures; + + *arg_hash = sub ($source) { + map +($_ => \(argify $_)), names_of body_cols $source; + }; +} + +method root_table () { + $self->parent_source + ? $self->parent_source->root_table + : $self->schema->source($self->raw_source_name) +} + method view_definition () { my $schema = $self->schema; confess "Can't generate view without connected schema, sorry" @@ -178,8 +209,51 @@ method view_definition () { ]) : ($table->name)), [ (qualify_with $table, names_of @pk_cols), names_of @body_cols ], - ); - return $select; + ).';'; + my ($now, $next) = grep defined, $super_view, $table; + # 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 = + function_body + $self->name.'_insert', + \@body_cols, + [ + $sqla->insert( # INSERT INTO _tbl (foo, ...) VALUES (_foo, ...) + $now->name, + { arg_hash $now }, + ), + ($next + ? $sqla->insert( # INSERT INTO super_view (id, ...) + # VALUES (currval('_root_tbl_id_seq'), ...) + $next->name, + { + (arg_hash $next), + id => \"currval('${\$self->root_table->name}_id_seq')", + } + ) + : () + ) + ]; + # 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 + }; + my $update_func = + function_body + $self->name.'_update', + [ @pk_cols, @body_cols ], + [ map $sqla->update( + $_->name, # UPDATE foo + { arg_hash $_ }, # SET a = _a + $pk_where, + ), @sources + ]; + 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); } 1;