X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSource.pm;h=4bb6ff602e3cebb3dd771a615e2326b62bf1dd9d;hb=fac560c2bcc31d5ab5f981abc521a41501cb1e8a;hp=ee55dbc64355842f6cde0e6185dd2ff199f07009;hpb=b2078cd5ce75c6b74ddcec39369dea28390345d9;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index ee55dbc..4bb6ff6 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -4,18 +4,20 @@ use strict; use warnings; use DBIx::Class::ResultSet; +use DBIx::Class::ResultSourceHandle; use Carp::Clan qw/^DBIx::Class/; use Storable; use base qw/DBIx::Class/; -__PACKAGE__->load_components(qw/AccessorGroup/); __PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns _columns _primaries _unique_constraints name resultset_attributes - schema from _relationships/); + schema from _relationships column_info_from_storage source_info/); __PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class - result_class source_name/); + result_class/); + +__PACKAGE__->mk_group_ro_accessors('simple' => qw/source_name/); =head1 NAME @@ -30,12 +32,23 @@ retrieved, most usually a table (see L) =head1 METHODS +=pod + +=head2 new + + $class->new(); + + $class->new({attribute_name => value}); + +Creates a new ResultSource object. Not normally called directly by end users. + =cut sub new { my ($class, $attrs) = @_; $class = ref $class if ref $class; - my $new = bless({ %{$attrs || {}}, _resultset => undef }, $class); + + my $new = bless { %{$attrs || {}} }, $class; $new->{resultset_class} ||= 'DBIx::Class::ResultSet'; $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} }; $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}]; @@ -48,6 +61,17 @@ sub new { =pod +=head2 source_info + +Stores a hashref of per-source metadata. No specific key names +have yet been standardized, the examples below are purely hypothetical +and don't actually accomplish anything on their own: + + __PACKAGE__->source_info({ + "_tablespace" => 'fast_disk_array_3', + "_engine" => 'InnoDB', + }); + =head2 add_columns $table->add_columns(qw/col1 col2 col3/); @@ -83,29 +107,31 @@ whatever your database supports. =item size The length of your column, if it is a column type that can have a size -restriction. This is currently not used by DBIx::Class. +restriction. This is currently only used by L. =item is_nullable Set this to a true value for a columns that is allowed to contain -NULL values. This is currently not used by DBIx::Class. +NULL values. This is currently only used by L. =item is_auto_increment Set this to a true value for a column whose value is somehow automatically set. This is used to determine which columns to empty -when cloning objects using C. +when cloning objects using C. It is also used by +L. =item is_foreign_key Set this to a true value for a column that contains a key from a -foreign table. This is currently not used by DBIx::Class. +foreign table. This is currently only used by +L. =item default_value Set this to the default value which will be inserted into a column by the database. Can contain either a value or a function. This is -currently not used by DBIx::Class. +currently only used by L. =item sequence @@ -114,6 +140,14 @@ generate a new key value. If not specified, L will attempt to retrieve the name of the sequence from the database automatically. +=item extras + +This is used by L and L +to add extra non-generic data to the column. For example: C<< extras +=> { unsigned => 1} >> is used by the MySQL producer to set an integer +column to unsigned. For more details, see +L. + =back =head2 add_column @@ -171,24 +205,38 @@ sub column_info { unless exists $self->_columns->{$column}; #warn $self->{_columns_info_loaded}, "\n"; if ( ! $self->_columns->{$column}{data_type} + and $self->column_info_from_storage and ! $self->{_columns_info_loaded} and $self->schema and $self->storage ) { $self->{_columns_info_loaded}++; - my $info; + my $info = {}; + my $lc_info = {}; # eval for the case of storage without table - eval { $info = $self->storage->columns_info_for($self->from) }; + eval { $info = $self->storage->columns_info_for( $self->from ) }; unless ($@) { + for my $realcol ( keys %{$info} ) { + $lc_info->{lc $realcol} = $info->{$realcol}; + } foreach my $col ( keys %{$self->_columns} ) { - foreach my $i ( keys %{$info->{$col}} ) { - $self->_columns->{$col}{$i} = $info->{$col}{$i}; - } + $self->_columns->{$col} = { + %{ $self->_columns->{$col} }, + %{ $info->{$col} || $lc_info->{lc $col} || {} } + }; } } } return $self->_columns->{$column}; } +=head2 column_info_from_storage + +Enables the on-demand automatic loading of the above column +metadata from storage as neccesary. This is *deprecated*, and +should not be used. It will be removed before 1.0. + + __PACKAGE__->column_info_from_storage(1); + =head2 columns my @column_names = $obj->columns; @@ -232,7 +280,7 @@ sub remove_columns { } foreach (@cols) { - undef $columns->{$_}; + delete $columns->{$_}; }; $self->_ordered_columns(\@remaining); @@ -290,13 +338,24 @@ constraint. constraint_name => [ qw/column1 column2/ ], ); +Alternatively, you can specify only the columns: + + __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]); + +This will result in a unique constraint named C, where +C is replaced with the table name. + Unique constraints are used, for example, when you call L. Only columns in the constraint are searched. =cut sub add_unique_constraint { - my ($self, $name, $cols) = @_; + my $self = shift; + my $cols = pop @_; + my $name = shift; + + $name ||= $self->name_unique_constraint($cols); foreach my $col (@$cols) { $self->throw_exception("No such column $col on table " . $self->name) @@ -308,6 +367,22 @@ sub add_unique_constraint { $self->_unique_constraints(\%unique_constraints); } +=head2 name_unique_constraint + +Return a name for a unique constraint containing the specified columns. These +names consist of the table name and each column name, separated by underscores. + +For example, a constraint on a table named C containing the columns +C and C would result in a constraint name of C<cd_artist_title>. + +=cut + +sub name_unique_constraint { + my ($self, $cols) = @_; + + return join '_', $self->name, @$cols; +} + =head2 unique_constraints Read-only accessor which returns the list of unique constraints on this source. @@ -356,7 +431,10 @@ Returns an expression of the source to be supplied to storage to specify retrieval from this source. In the case of a database, the required FROM clause contents. -=cut +=head2 schema + +Returns the L<DBIx::Class::Schema> object that this result source +belongs too. =head2 storage @@ -451,10 +529,7 @@ sub add_relationship { my $f_source = $self->schema->source($f_source_name); unless ($f_source) { - eval "require $f_source_name;"; - if ($@) { - die $@ unless $@ =~ /Can't locate/; - } + $self->ensure_class_loaded($f_source_name); $f_source = $f_source_name->result_source; #my $s_class = ref($self->schema); #$f_source_name =~ m/^${s_class}::(.*)$/; @@ -868,13 +943,23 @@ but is cached from then on unless resultset_class changes. =head2 resultset_class +` package My::ResultSetClass; + use base 'DBIx::Class::ResultSet'; + ... + + $source->resultset_class('My::ResultSet::Class'); + Set the class of the resultset, this is useful if you want to create your own resultset methods. Create your own class derived from -L<DBIx::Class::ResultSet>, and set it here. +L<DBIx::Class::ResultSet>, and set it here. =head2 resultset_attributes -Specify here any attributes you wish to pass to your specialised resultset. + $source->resultset_attributes({ order_by => [ 'id' ] }); + +Specify here any attributes you wish to pass to your specialised +resultset. For a full list of these, please see +L<DBIx::Class::ResultSet/ATTRIBUTES>. =cut @@ -885,12 +970,6 @@ sub resultset { 'call it on the schema instead.' ) if scalar @_; - # disabled until we can figure out a way to do it without consistency issues - # - #return $self->{_resultset} - # if ref $self->{_resultset} eq $self->resultset_class; - #return $self->{_resultset} = - return $self->resultset_class->new( $self, $self->{resultset_attributes} ); @@ -916,6 +995,20 @@ its class name. # from your schema... $schema->resultset('Books')->find(1); +=head2 handle + +Obtain a new handle to this source. Returns an instance of a +L<DBIx::Class::ResultSourceHandle>. + +=cut + +sub handle { + return new DBIx::Class::ResultSourceHandle({ + schema => $_[0]->schema, + source_moniker => $_[0]->source_name + }); +} + =head2 throw_exception See L<DBIx::Class::Schema/"throw_exception">.