'0+' => \&count,
'bool' => sub { 1; },
fallback => 1;
+use Carp::Clan qw/^DBIx::Class/;
use Data::Page;
use Storable;
use Data::Dumper;
{ key => 'artist_title' }
);
-If no C<key> is specified and you explicitly name columns, it searches on all
-unique constraints defined on the source, including the primary key.
-
If the C<key> is specified as C<primary>, it searches only on the primary key.
See also L</find_or_create> and L</update_or_create>. For information on how to
my $self = shift;
my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
- # Parse out a hash from input
+ # Default to the primary key, but allow a specific key
my @cols = exists $attrs->{key}
? $self->result_source->unique_constraint_columns($attrs->{key})
: $self->result_source->primary_columns;
+ $self->throw_exception(
+ "Can't find unless a primary key or unique constraint is defined"
+ ) unless @cols;
- my $hash;
+ # Parse out a hashref from input
+ my $query;
if (ref $_[0] eq 'HASH') {
- $hash = { %{$_[0]} };
+ $query = { %{$_[0]} };
}
elsif (@_ == @cols) {
- $hash = {};
- @{$hash}{@cols} = @_;
- }
- elsif (@_) {
- # For backwards compatibility
- $hash = {@_};
+ $query = {};
+ @{$query}{@cols} = @_;
}
else {
- $self->throw_exception(
- "Arguments to find must be a hashref or match the number of columns in the "
- . (exists $attrs->{key} ? "$attrs->{key} unique constraint" : "primary key")
- );
+ # Compatibility: Allow e.g. find(id => $value)
+ carp "find by key => value deprecated; please use a hashref instead";
+ $query = {@_};
}
- # Check the hash we just parsed against our source's unique constraints
- my @constraint_names = exists $attrs->{key}
- ? ($attrs->{key})
- : $self->result_source->unique_constraint_names;
- $self->throw_exception(
- "Can't find unless a primary key or unique constraint is defined"
- ) unless @constraint_names;
-
- my @unique_queries;
- foreach my $name (@constraint_names) {
- my @unique_cols = $self->result_source->unique_constraint_columns($name);
- my $unique_query = $self->_build_unique_query($hash, \@unique_cols);
-
- # Add the ResultSet's alias
- foreach my $key (grep { ! m/\./ } keys %$unique_query) {
- $unique_query->{"$self->{attrs}{alias}.$key"} = delete $unique_query->{$key};
- }
-
- push @unique_queries, $unique_query if %$unique_query;
+ # Add the ResultSet's alias
+ foreach my $key (grep { ! m/\./ } keys %$query) {
+ $query->{"$self->{attrs}{alias}.$key"} = delete $query->{$key};
}
- # Handle cases where the ResultSet already defines the query
- my $query = @unique_queries ? \@unique_queries : undef;
-
# Run the query
if (keys %$attrs) {
my $rs = $self->search($query, $attrs);
$attrs->{order_by} = [ $attrs->{order_by} ] if
$attrs->{order_by} and !ref($attrs->{order_by});
$attrs->{order_by} ||= [];
+
+ if(my $seladds = delete($attrs->{'+select'})) {
+ my @seladds = (ref($seladds) eq 'ARRAY' ? @$seladds : ($seladds));
+ $attrs->{select} = [
+ @{ $attrs->{select} },
+ map { (m/\./ || ref($_)) ? $_ : "${alias}.$_" } $seladds
+ ];
+ }
+ if(my $asadds = delete($attrs->{'+as'})) {
+ my @asadds = (ref($asadds) eq 'ARRAY' ? @$asadds : ($asadds));
+ $attrs->{as} = [ @{ $attrs->{as} }, @asadds ];
+ }
my $collapse = $attrs->{collapse} || {};
if (my $prefetch = delete $attrs->{prefetch}) {
my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
my $hash = ref $_[0] eq 'HASH' ? shift : {@_};
- my $row = $self->find($hash, $attrs);
- if (defined $row) {
- $row->update($hash);
- return $row;
+ my @constraint_names = exists $attrs->{key}
+ ? ($attrs->{key})
+ : $self->result_source->unique_constraint_names;
+ $self->throw_exception(
+ "update_or_create requires a primary key or unique constraint; none is defined on "
+ . $self->result_source->name
+ ) unless @constraint_names;
+
+ my @unique_queries;
+ foreach my $name (@constraint_names) {
+ my @unique_cols = $self->result_source->unique_constraint_columns($name);
+ my $unique_query = $self->_build_unique_query($hash, \@unique_cols);
+
+ push @unique_queries, $unique_query
+ if keys %$unique_query == @unique_cols;
+ }
+
+ if (@unique_queries) {
+ my $row = $self->single(\@unique_queries);
+ if (defined $row) {
+ $row->update($hash);
+ return $row;
+ }
}
return $self->create($hash);
through directly to SQL, so you can give e.g. C<year DESC> for a
descending order on the column `year'.
+Please note that if you have quoting enabled (see
+L<DBIx::Class::Storage/quote_char>) you will need to do C<\'year DESC' > to
+specify an order. (The scalar ref causes it to be passed as raw sql to the DB,
+so you will need to manually quote things as appropriate.)
+
=head2 columns
=over 4
attribute, the column names returned are storage-dependent. E.g. MySQL would
return a column named C<count(employeeid)> in the above example.
+=head2 +select
+
+=over 4
+
+Indicates additional columns to be selected from storage. Works the same as
+L<select> but adds columns to the selection.
+
+=back
+
+=head2 +as
+
+=over 4
+
+Indicates additional column names for those added via L<+select>.
+
+=back
+
=head2 as
=over 4
Makes the resultset paged and specifies the page to retrieve. Effectively
identical to creating a non-pages resultset and then calling ->page($page)
-on it.
+on it.
+
+If L<rows> attribute is not specified it defualts to 10 rows per page.
=head2 rows
Specifes the maximum number of rows for direct retrieval or the number of
rows per page if the page attribute or method is used.
+=head2 offset
+
+=over 4
+
+=item Value: $offset
+
+=back
+
+Specifies the (zero-based) row number for the first row to be returned, or the
+of the first row of the first page if paging is used.
+
=head2 group_by
=over 4