X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSource.pm;h=18e239642f0f33170424d31ae7211b024e117499;hb=8ae83f0e;hp=0a5d1fc07ef335baa39c99d8d9d3d13458897231;hpb=0ff3368690783358903b3689a1a96ef21271f825;p=dbsrgits%2FDBIx-Class-Historic.git diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index 0a5d1fc..18e2396 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -14,6 +14,7 @@ use Scalar::Util qw( blessed weaken isweak refaddr ); # FIXME - somehow breaks ResultSetManager, do not remove until investigated use DBIx::Class::ResultSet; +use Moo; use namespace::clean; my @hashref_attributes = qw( @@ -23,12 +24,20 @@ my @hashref_attributes = qw( my @arrayref_attributes = qw( _ordered_columns _primaries ); -__PACKAGE__->mk_group_accessors(simple => + +has [ @hashref_attributes, @arrayref_attributes, qw( source_name name column_info_from_storage sqlt_deploy_callback ), +] => ( + is => 'rw', ); +has '+name' => ( default => "!!NAME NOT SET!!" ); +has '+sqlt_deploy_callback' => ( default => 'default_sqlt_deploy_hook' ); + +# We use the CAG accessors for this due to the "load-on-get" logic +# not being cleanly triggerable from within Moo __PACKAGE__->mk_group_accessors(component_class => qw/ resultset_class result_class @@ -60,8 +69,8 @@ DBIx::Class::ResultSource - Result source object __PACKAGE__->table_class('DBIx::Class::ResultSource::View'); __PACKAGE__->table('year2000cds'); - __PACKAGE__->result_source_instance->is_virtual(1); - __PACKAGE__->result_source_instance->view_definition( + __PACKAGE__->result_source->is_virtual(1); + __PACKAGE__->result_source->view_definition( "SELECT cdid, artist, title FROM cd WHERE year ='2000'" ); @@ -121,6 +130,16 @@ Creates a new ResultSource object. Not normally called directly by end users. =cut + +# FIXME +# +# haarg: one more question - is there a straightforward way to inline BUILD/BUILDARGS ? +# ( I have both ) +# not really. it's something we probably should do, but don't currently. + +# Because there are spots that call ->new($rsrc_object) in the wild +sub BUILDARGS { +{ %{ $_[1] || {} } } } + { my $rsrc_registry; @@ -132,19 +151,14 @@ Creates a new ResultSource object. Not normally called directly by end users. } values %{ $rsrc_registry->{ refaddr($_[0]) }{ derivatives } } } - sub new { - my ($class, $attrs) = @_; - $class = ref $class if ref $class; - - my $ancestor = delete $attrs->{__derived_from}; - - my $self = bless { %$attrs }, $class; + sub BUILD { + my $self = shift; DBIx::Class::_ENV_::ASSERT_NO_ERRONEOUS_METAINSTANCE_USE and # a constructor with 'name' as sole arg clearly isn't "inheriting" from anything - ( not ( keys(%$self) == 1 and exists $self->{name} ) ) + ( not ( keys(%{$_[0]}) == 1 and exists $_[0]->{name} ) ) and defined CORE::caller(1) and @@ -161,6 +175,15 @@ Creates a new ResultSource object. Not normally called directly by end users. Carp::confess("Incorrect instantiation of '$self': you almost certainly wanted to call ->clone() instead"); + my $ancestor = delete $_[0]->{__derived_from}; + + # Allow complete transparency to subclasses: ->new( \%random_stuff ) + %$self = ( + %{$_[0]}, + %$self, + ); + + my $own_slot = $rsrc_registry->{ my $own_addr = refaddr $self } = { derivatives => {} }; @@ -194,10 +217,8 @@ Creates a new ResultSource object. Not normally called directly by end users. } + # not a default because we use the CAG accessors, see top of file $self->{resultset_class} ||= 'DBIx::Class::ResultSet'; - $self->{name} ||= "!!NAME NOT SET!!"; - $self->{_columns_info_loaded} ||= 0; - $self->{sqlt_deploy_callback} ||= 'default_sqlt_deploy_hook'; $self->{$_} = { %{ $self->{$_} || {} } } for @hashref_attributes; @@ -445,13 +466,19 @@ sub add_columns { my ($self, @cols) = @_; $self->_ordered_columns(\@cols) unless $self->_ordered_columns; - my @added; + my ( @added, $colinfos ); my $columns = $self->_columns; + while (my $col = shift @cols) { - my $column_info = {}; - if ($col =~ s/^\+//) { - $column_info = $self->column_info($col); - } + my $column_info = + ( + $col =~ s/^\+// + and + ( $colinfos ||= $self->columns_info )->{$col} + ) + || + {} + ; # If next entry is { ... } use that for the column info, if not # use an empty hashref @@ -462,6 +489,7 @@ sub add_columns { push(@added, $col) unless exists $columns->{$col}; $columns->{$col} = $column_info; } + push @{ $self->_ordered_columns }, @added; return $self; } @@ -511,35 +539,10 @@ contents of the hashref. =cut sub column_info { - my ($self, $column) = @_; - $self->throw_exception("No such column $column") - unless exists $self->_columns->{$column}; - - if ( ! $self->_columns->{$column}{data_type} - and ! $self->{_columns_info_loaded} - and $self->column_info_from_storage - and my $stor = dbic_internal_try { $self->schema->storage } ) - { - $self->{_columns_info_loaded}++; - - # try for the case of storage without table - dbic_internal_try { - my $info = $stor->columns_info_for( $self->from ); - my $lc_info = { map - { (lc $_) => $info->{$_} } - ( keys %$info ) - }; - - foreach my $col ( keys %{$self->_columns} ) { - $self->_columns->{$col} = { - %{ $self->_columns->{$col} }, - %{ $info->{$col} || $lc_info->{lc $col} || {} } - }; - } - }; - } + DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and fail_on_internal_call; - return $self->_columns->{$column}; + #my ($self, $column) = @_; + $_[0]->columns_info([ $_[1] ])->{$_[1]}; } =head2 columns @@ -634,6 +637,8 @@ sub columns_info { } } else { + # the shallow copy is crucial - there are exists() checks within + # the wider codebase %ret = %$colinfo; } @@ -1059,11 +1064,11 @@ sub unique_constraint_columns { =back - __PACKAGE__->result_source_instance->sqlt_deploy_callback('mycallbackmethod'); + __PACKAGE__->result_source->sqlt_deploy_callback('mycallbackmethod'); or - __PACKAGE__->result_source_instance->sqlt_deploy_callback(sub { + __PACKAGE__->result_source->sqlt_deploy_callback(sub { my ($source_instance, $sqlt_table) = @_; ... } ); @@ -1857,14 +1862,17 @@ sub _pk_depends_on { # auto-increment my $rel_source = $self->related_source($rel_name); + my $colinfos; + foreach my $p ($self->primary_columns) { - if (exists $keyhash->{$p}) { - unless (defined($rel_data->{$keyhash->{$p}}) - || $rel_source->column_info($keyhash->{$p}) - ->{is_auto_increment}) { - return 0; - } - } + return 0 if ( + exists $keyhash->{$p} + and + ! defined( $rel_data->{$keyhash->{$p}} ) + and + ! ( $colinfos ||= $rel_source->columns_info ) + ->{$keyhash->{$p}}{is_auto_increment} + ) } return 1; @@ -2401,7 +2409,7 @@ sub related_source { else { my $class = $self->relationship_info($rel)->{class}; $self->ensure_class_loaded($class); - $class->result_source_instance; + $class->result_source; } }