changed formatting for arguments/return values in method docs
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSource.pm
index e8b1b96..cfa8bc9 100644 (file)
@@ -5,16 +5,17 @@ use warnings;
 
 use DBIx::Class::ResultSet;
 use Carp::Clan qw/^DBIx::Class/;
-
 use Storable;
-use Scalar::Util qw/weaken/;
 
 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/);
-__PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class result_class/);
+__PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns
+  _columns _primaries _unique_constraints name resultset_attributes
+  schema from _relationships/);
+
+__PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
+  result_class/);
 
 =head1 NAME 
 
@@ -93,7 +94,8 @@ If the column is allowed to contain NULL values, set a true value
 =item is_auto_increment
 
 Set this to a true value if this is a column that is somehow
-automatically filled. This is currently not used by DBIx::Class.
+automatically filled. This is used to determine which columns to empty
+when cloning objects using C<copy>.
 
 =item is_foreign_key
 
@@ -108,11 +110,9 @@ currently not used by DBIx::Class.
 
 =item sequence
 
-If your column is using a sequence to create it's values, set the name
-of the sequence here, to allow the values to be retrieved
-automatically by the L<DBIx::Class::PK::Auto> module. PK::Auto will
-attempt to retrieve the sequence name from the database, if this value
-is left unset.
+Sets the name of the sequence to use to generate values.  If not 
+specified, L<DBIx::Class::PK::Auto> will attempt to retrieve the 
+name of the sequence from the database automatically.
 
 =back
 
@@ -126,18 +126,15 @@ Convenience alias to add_columns
 
 sub add_columns {
   my ($self, @cols) = @_;
-  $self->_ordered_columns( \@cols )
-    if !$self->_ordered_columns;
+  $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
+  
   my @added;
   my $columns = $self->_columns;
   while (my $col = shift @cols) {
-
+    # If next entry is { ... } use that for the column info, if not
+    # use an empty hashref
     my $column_info = ref $cols[0] ? shift(@cols) : {};
-      # If next entry is { ... } use that for the column info, if not
-      # use an empty hashref
-
     push(@added, $col) unless exists $columns->{$col};
-
     $columns->{$col} = $column_info;
   }
   push @{ $self->_ordered_columns }, @added;
@@ -173,22 +170,21 @@ sub column_info {
   $self->throw_exception("No such column $column") 
     unless exists $self->_columns->{$column};
   #warn $self->{_columns_info_loaded}, "\n";
-  if ( ! $self->_columns->{$column}->{data_type} 
-       && ! $self->{_columns_info_loaded} 
-       && $self->schema && $self->storage() ){
-      $self->{_columns_info_loaded}++;
-      my $info;
-############ eval for the case of storage without table 
-      eval{
-          $info = $self->storage->columns_info_for ( $self->from() );
-      };
-      if ( ! $@ ){
-          for my $col ( keys %{$self->_columns} ){
-              for my $i ( keys %{$info->{$col}} ){
-                  $self->_columns()->{$col}->{$i} = $info->{$col}->{$i};
-              }
-          }
+  if ( ! $self->_columns->{$column}{data_type} 
+       and ! $self->{_columns_info_loaded} 
+       and $self->schema and $self->storage )
+  {
+    $self->{_columns_info_loaded}++;
+    my $info;
+    # eval for the case of storage without table 
+    eval { $info = $self->storage->columns_info_for($self->from) };
+    unless ($@) {
+      foreach my $col ( keys %{$self->_columns} ) {
+        foreach my $i ( keys %{$info->{$col}} ) {
+            $self->_columns->{$col}{$i} = $info->{$col}{$i};
+        }
       }
+    }
   }
   return $self->_columns->{$column};
 }
@@ -202,14 +198,20 @@ Returns all column names in the order they were declared to add_columns
 =cut
 
 sub columns {
-  my $self=shift;
-  $self->throw_exception("columns() is a read-only accessor, did you mean add_columns()?") if (@_ > 1);
+  my $self = shift;
+  $self->throw_exception(
+    "columns() is a read-only accessor, did you mean add_columns()?"
+  ) if (@_ > 1);
   return @{$self->{_ordered_columns}||[]};
 }
 
 =head2 set_primary_key
 
-=head3 Arguments: (@cols)
+=over 4
+
+=item Arguments: (@cols)
+
+=back
 
 Defines one or more columns as primary key for this source. Should be
 called after C<add_columns>.
@@ -224,9 +226,9 @@ retrieve automatically created values from the database.
 sub set_primary_key {
   my ($self, @cols) = @_;
   # check if primary key columns are valid columns
-  for (@cols) {
-    $self->throw_exception("No such column $_ on table ".$self->name)
-      unless $self->has_column($_);
+  foreach my $col (@cols) {
+    $self->throw_exception("No such column $col on table " . $self->name)
+      unless $self->has_column($col);
   }
   $self->_primaries(\@cols);
 
@@ -249,17 +251,21 @@ Declare a unique constraint on this source. Call once for each unique
 constraint. Unique constraints are used when you call C<find> on a
 L<DBIx::Class::ResultSet>, only columns in the constraint are searched,
 
-  # For e.g. UNIQUE (column1, column2)
-  __PACKAGE__->add_unique_constraint(constraint_name => [ qw/column1 column2/ ]);
+e.g.,
+
+  # For UNIQUE (column1, column2)
+  __PACKAGE__->add_unique_constraint(
+    constraint_name => [ qw/column1 column2/ ],
+  );
 
 =cut
 
 sub add_unique_constraint {
   my ($self, $name, $cols) = @_;
 
-  for (@$cols) {
-    $self->throw_exception("No such column $_ on table ".$self->name)
-      unless $self->has_column($_);
+  foreach my $col (@$cols) {
+    $self->throw_exception("No such column $col on table " . $self->name)
+      unless $self->has_column($col);
   }
 
   my %unique_constraints = $self->unique_constraints;
@@ -299,13 +305,18 @@ sub storage { shift->schema->storage; }
 
   $source->add_relationship('relname', 'related_source', $cond, $attrs);
 
-The relation name can be arbitrary, but must be unique for each relationship
-attached to this result source. 'related_source' should be the name with
-which the related result source was registered with the current schema
-(for simple schemas this is usally either Some::Namespace::Foo or just Foo)
+The relationship name can be arbitrary, but must be unique for each
+relationship attached to this result source. 'related_source' should
+be the name with which the related result source was registered with
+the current schema. For example:
+
+  $schema->source('Book')->add_relationship('reviews', 'Review', {
+    'foreign.book_id' => 'self.id',
+  });
 
-The condition needs to be an SQL::Abstract-style representation of the join
-between the tables. For example, if you're creating a rel from Author to Book,
+The condition C<$cond> needs to be an SQL::Abstract-style
+representation of the join between the tables. For example, if you're
+creating a rel from Author to Book,
 
   { 'foreign.author_id' => 'self.id' }
 
@@ -327,15 +338,18 @@ the SQL command immediately before C<JOIN>.
 
 =item proxy
 
-An arrayref containing a list of accessors in the foreign class to
-proxy in the main class. If, for example, you do the following: 
-
-  __PACKAGE__->might_have(bar => 'Bar', undef, { proxy => [ qw/margle/] }); 
+An arrayref containing a list of accessors in the foreign class to proxy in
+the main class. If, for example, you do the following:
+  
+  CD->might_have(liner_notes => 'LinerNotes', undef, {
+    proxy => [ qw/notes/ ],
+  });
+  
+Then, assuming LinerNotes has an accessor named notes, you can do:
 
-Then, assuming Bar has an accessor named margle, you can do:
-
-  my $obj = Foo->find(1);
-  $obj->margle(10); # set margle; Bar object is created if it doesn't exist
+  my $cd = CD->find(1);
+  $cd->notes('Notes go here'); # set notes -- LinerNotes object is
+                              # created if it doesn't exist
 
 =item accessor
 
@@ -353,7 +367,8 @@ relationship.
 
 sub add_relationship {
   my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
-  $self->throw_exception("Can't create relationship without join condition") unless $cond;
+  $self->throw_exception("Can't create relationship without join condition")
+    unless $cond;
   $attrs ||= {};
 
   my %rels = %{ $self->_relationships };
@@ -403,7 +418,11 @@ sub relationships {
 
 =head2 relationship_info
 
-=head3 Arguments: ($relname)
+=over 4
+
+=item Arguments: ($relname)
+
+=back
 
 Returns the relationship information for the specified relationship name
 
@@ -416,7 +435,11 @@ sub relationship_info {
 
 =head2 has_relationship
 
-=head3 Arguments: ($rel)
+=over 4
+
+=item Arguments: ($rel)
+
+=back
 
 Returns 1 if the source has a relationship of this name, 0 otherwise.
 
@@ -429,7 +452,11 @@ sub has_relationship {
 
 =head2 resolve_join
 
-=head3 Arguments: ($relation)
+=over 4
+
+=item Arguments: ($relation)
+
+=back
 
 Returns the join structure required for the related result source
 
@@ -464,7 +491,11 @@ sub resolve_join {
 
 =head2 resolve_condition
 
-=head3 Arguments: ($cond, $as, $alias|$object)
+=over 4
+
+=item Arguments: ($cond, $as, $alias|$object)
+
+=back
 
 Resolves the passed condition to a concrete query fragment. If given an alias,
 returns a join condition; if given an object, inverts that object to produce
@@ -479,8 +510,10 @@ sub resolve_condition {
     my %ret;
     while (my ($k, $v) = each %{$cond}) {
       # XXX should probably check these are valid columns
-      $k =~ s/^foreign\.// || $self->throw_exception("Invalid rel cond key ${k}");
-      $v =~ s/^self\.// || $self->throw_exception("Invalid rel cond val ${v}");
+      $k =~ s/^foreign\.// ||
+       $self->throw_exception("Invalid rel cond key ${k}");
+      $v =~ s/^self\.// ||
+       $self->throw_exception("Invalid rel cond val ${v}");
       if (ref $for) { # Object
         #warn "$self $k $for $v";
         $ret{$k} = $for->get_column($v);
@@ -501,7 +534,11 @@ sub resolve_condition {
 
 =head2 resolve_prefetch
 
-=head3 Arguments: (hashref/arrayref/scalar)
+=over 4
+
+=item Arguments: (hashref/arrayref/scalar)
+
+=back
 
 Accepts one or more relationships for the current source and returns an
 array of column names for each of those relationships. Column names are
@@ -574,7 +611,7 @@ sub resolve_prefetch {
     my $rel_info = $self->relationship_info( $pre );
     $self->throw_exception( $self->name . " has no such relationship '$pre'" )
       unless $rel_info;
-    my $as_prefix = ($alias =~ /^.*?\.(.*)$/ ? $1.'.' : '');
+    my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
     my $rel_source = $self->related_source($pre);
 
     if (exists $rel_info->{attrs}{accessor}
@@ -582,7 +619,7 @@ sub resolve_prefetch {
       $self->throw_exception(
         "Can't prefetch has_many ${pre} (join cond too complex)")
         unless ref($rel_info->{cond}) eq 'HASH';
-      my @key = map { (/^foreign\.(.*)$/ ? ($1) : ()); }
+      my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
                     keys %{$rel_info->{cond}};
       $collapse->{"${as_prefix}${pre}"} = \@key;
       my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
@@ -602,7 +639,11 @@ sub resolve_prefetch {
 
 =head2 related_source
 
-=head3 Arguments: ($relname)
+=over 4
+
+=item Arguments: ($relname)
+
+=back
 
 Returns the result source object for the given relationship
 
@@ -616,12 +657,35 @@ sub related_source {
   return $self->schema->source($self->relationship_info($rel)->{source});
 }
 
+=head2 related_class
+
+=over 4
+
+=item Arguments: ($relname)
+
+=back
+
+Returns the class object for the given relationship
+
+=cut
+
+sub related_class {
+  my ($self, $rel) = @_;
+  if( !$self->has_relationship( $rel ) ) {
+    $self->throw_exception("No such relationship '$rel'");
+  }
+  return $self->schema->class($self->relationship_info($rel)->{source});
+}
+
 =head2 resultset
 
-Returns a resultset for the given source, by calling:
+Returns a resultset for the given source. This will initially be created
+on demand by calling
 
   $self->resultset_class->new($self, $self->resultset_attributes)
 
+but is cached from then on unless resultset_class changes.
+
 =head2 resultset_class
 
 Set the class of the resultset, this is useful if you want to create your
@@ -636,13 +700,15 @@ Specify here any attributes you wish to pass to your specialised resultset.
 
 sub resultset {
   my $self = shift;
-  $self->throw_exception('resultset does not take any arguments. If you want another resultset, call it on the schema instead.') if scalar @_;
-  return $self->{_resultset} if ref $self->{_resultset} eq $self->resultset_class;
-  return $self->{_resultset} = do {
-    my $rs = $self->resultset_class->new($self, $self->{resultset_attributes});
-    weaken $rs->result_source;
-    $rs;
-  };
+  $self->throw_exception(
+    'resultset does not take any arguments. If you want another resultset, '.
+    'call it on the schema instead.'
+  ) if scalar @_;
+  return $self->{_resultset}
+    if ref $self->{_resultset} eq $self->resultset_class;
+  return $self->{_resultset} = $self->resultset_class->new(
+    $self, $self->{resultset_attributes}
+  );
 }
 
 =head2 throw_exception