use DBIx::Class::ResultSetColumn;
use Scalar::Util qw/blessed weaken/;
use Try::Tiny;
+use Data::Compare (); # no imports!!! guard against insane architecture
# not importing first() as it will clash with our own method
use List::Util ();
sub get_data {
my $self = shift;
my $request = $self->get_request; # Get a request object somehow.
- my $schema = $self->get_schema; # Get the DBIC schema object somehow.
+ my $schema = $self->result_source->schema;
my $cd_rs = $schema->resultset('CD')->search({
title => $request->param('title'),
For a list of attributes that can be passed to C<search>, see
L</ATTRIBUTES>. For more examples of using this function, see
L<Searching|DBIx::Class::Manual::Cookbook/Searching>. For a complete
-documentation for the first argument, see L<SQL::Abstract>.
+documentation for the first argument, see L<SQL::Abstract>
+and its extension L<DBIx::Class::SQLMaker>.
For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
sub _stack_cond {
my ($self, $left, $right) = @_;
+
+ # collapse single element top-level conditions
+ # (single pass only, unlikely to need recursion)
+ for ($left, $right) {
+ if (ref $_ eq 'ARRAY') {
+ if (@$_ == 0) {
+ $_ = undef;
+ }
+ elsif (@$_ == 1) {
+ $_ = $_->[0];
+ }
+ }
+ elsif (ref $_ eq 'HASH') {
+ my ($first, $more) = keys %$_;
+
+ # empty hash
+ if (! defined $first) {
+ $_ = undef;
+ }
+ # one element hash
+ elsif (! defined $more) {
+ if ($first eq '-and' and ref $_->{'-and'} eq 'HASH') {
+ $_ = $_->{'-and'};
+ }
+ elsif ($first eq '-or' and ref $_->{'-or'} eq 'ARRAY') {
+ $_ = $_->{'-or'};
+ }
+ }
+ }
+ }
+
+ # merge hashes with weeding out of duplicates (simple cases only)
+ if (ref $left eq 'HASH' and ref $right eq 'HASH') {
+
+ # shallow copy to destroy
+ $right = { %$right };
+ for (grep { exists $right->{$_} } keys %$left) {
+ # the use of eq_deeply here is justified - the rhs of an
+ # expression can contain a lot of twisted weird stuff
+ delete $right->{$_} if Data::Compare::Compare( $left->{$_}, $right->{$_} );
+ }
+
+ $right = undef unless keys %$right;
+ }
+
+
if (defined $left xor defined $right) {
return defined $left ? $left : $right;
}
- elsif (defined $left) {
- return { -and => [ map
- { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
- ($left, $right)
- ]};
+ elsif (! defined $left) {
+ return undef;
+ }
+ else {
+ return { -and => [ $left, $right ] };
}
-
- return undef;
}
=head2 search_literal
my $rsrc = $self->result_source;
+ my $constraint_name;
+ if (exists $attrs->{key}) {
+ $constraint_name = defined $attrs->{key}
+ ? $attrs->{key}
+ : $self->throw_exception("An undefined 'key' resultset attribute makes no sense")
+ ;
+ }
+
# Parse out the condition from input
my $call_cond;
+
if (ref $_[0] eq 'HASH') {
$call_cond = { %{$_[0]} };
}
else {
- my $constraint = exists $attrs->{key} ? $attrs->{key} : 'primary';
- my @c_cols = $rsrc->unique_constraint_columns($constraint);
+ # if only values are supplied we need to default to 'primary'
+ $constraint_name = 'primary' unless defined $constraint_name;
+
+ my @c_cols = $rsrc->unique_constraint_columns($constraint_name);
$self->throw_exception(
- "No constraint columns, maybe a malformed '$constraint' constraint?"
+ "No constraint columns, maybe a malformed '$constraint_name' constraint?"
) unless @c_cols;
$self->throw_exception (
'find() expects either a column/value hashref, or a list of values '
- . "corresponding to the columns of the specified unique constraint '$constraint'"
+ . "corresponding to the columns of the specified unique constraint '$constraint_name'"
) unless @c_cols == @_;
$call_cond = {};
my $alias = exists $attrs->{alias} ? $attrs->{alias} : $self->{attrs}{alias};
my $final_cond;
- if (exists $attrs->{key}) {
+ if (defined $constraint_name) {
$final_cond = $self->_qualify_cond_columns (
$self->_build_unique_cond (
- $attrs->{key},
+ $constraint_name,
$call_cond,
),
unless ref $values eq 'HASH';
my $guard = $self->result_source->schema->txn_scope_guard;
- $_->update($values) for $self->all;
+ $_->update({%$values}) for $self->all; # shallow copy - update will mangle it
$guard->commit;
return 1;
}
# cruft placed in standalone method
my $data = $self->_normalize_populate_args(@_);
+ return unless @$data;
+
if(defined wantarray) {
my @created;
foreach my $item (@$data) {
my ($self, $arg) = @_;
if (ref $arg eq 'ARRAY') {
- if (ref $arg->[0] eq 'HASH') {
+ if (!@$arg) {
+ return [];
+ }
+ elsif (ref $arg->[0] eq 'HASH') {
return $arg;
}
elsif (ref $arg->[0] eq 'ARRAY') {