use DBIx::Class::ResultSetColumn;
use Scalar::Util qw/blessed weaken reftype/;
use DBIx::Class::_Util qw(
- fail_on_internal_wantarray is_plain_value is_literal_value
+ fail_on_internal_wantarray fail_on_internal_call UNRESOLVABLE_CONDITION
);
use Try::Tiny;
use Data::Compare (); # no imports!!! guard against insane architecture
sub new {
my $class = shift;
- return $class->new_result(@_) if ref $class;
+
+ if (ref $class) {
+ DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and fail_on_internal_call;
+ return $class->new_result(@_);
+ }
my ($source, $attrs) = @_;
$source = $source->resolve
my $rs = $self->search_rs( @_ );
if (wantarray) {
- DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_WANTARRAY and my $sog = fail_on_internal_wantarray($rs);
+ DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_WANTARRAY and my $sog = fail_on_internal_wantarray;
return $rs->all;
}
elsif (defined wantarray) {
return unless @$data;
if(defined wantarray) {
- my @created = map { $self->create($_) } @$data;
+ my @created = map { $self->new_result($_)->insert } @$data;
return wantarray ? @created : \@created;
}
else {
foreach my $rel (@rels) {
next unless ref $data->[$index]->{$rel} eq "HASH";
- my $result = $self->related_resultset($rel)->create($data->[$index]->{$rel});
+ my $result = $self->related_resultset($rel)->new_result($data->[$index]->{$rel})->insert;
my (undef, $reverse_relinfo) = %{$rsrc->reverse_relationship_info($rel)};
my $related = $result->result_source->_resolve_condition(
$reverse_relinfo->{cond},
$self->throw_exception( "new_result takes only one argument - a hashref of values" )
if @_ > 2;
- $self->throw_exception( "new_result expects a hashref" )
+ $self->throw_exception( "Result object instantiation requires a hashref as argument" )
unless (ref $values eq 'HASH');
my ($merged_cond, $cols_from_relations) = $self->_merge_with_rscond($values);
sub _merge_with_rscond {
my ($self, $data) = @_;
- my (%new_data, @cols_from_relations);
+ my ($implied_data, @cols_from_relations);
my $alias = $self->{attrs}{alias};
if (! defined $self->{cond}) {
# just massage $data below
}
- elsif ($self->{cond} eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) {
- %new_data = %{ $self->{attrs}{related_objects} || {} }; # nothing might have been inserted yet
- @cols_from_relations = keys %new_data;
- }
- elsif (ref $self->{cond} ne 'HASH') {
- $self->throw_exception(
- "Can't abstract implicit construct, resultset condition not a hash"
- );
+ elsif ($self->{cond} eq UNRESOLVABLE_CONDITION) {
+ $implied_data = $self->{attrs}{related_objects}; # nothing might have been inserted yet
+ @cols_from_relations = keys %{ $implied_data || {} };
}
else {
- if ($self->{cond}) {
- my $implied = $self->_remove_alias(
- $self->result_source->schema->storage->_collapse_cond($self->{cond}),
- $alias,
- );
-
- for my $c (keys %$implied) {
- my $v = $implied->{$c};
- if ( ! length ref $v or is_plain_value($v) ) {
- $new_data{$c} = $v;
- }
- elsif (
- ref $v eq 'HASH' and keys %$v == 1 and exists $v->{'='} and is_literal_value($v->{'='})
- ) {
- $new_data{$c} = $v->{'='};
- }
- }
- }
+ my $eqs = $self->result_source->schema->storage->_extract_fixed_condition_columns($self->{cond}, 'consider_nulls');
+ $implied_data = { map {
+ ( ($eqs->{$_}||'') eq UNRESOLVABLE_CONDITION ) ? () : ( $_ => $eqs->{$_} )
+ } keys %$eqs };
}
- # precedence must be given to passed values over values inherited from
- # the cond, so the order here is important.
- %new_data = (
- %new_data,
- %{ $self->_remove_alias($data, $alias) },
+ return (
+ { map
+ { %{ $self->_remove_alias($_, $alias) } }
+ # precedence must be given to passed values over values inherited from
+ # the cond, so the order here is important.
+ ( $implied_data||(), $data)
+ },
+ \@cols_from_relations
);
-
- return (\%new_data, \@cols_from_relations);
}
# _has_resolved_attr
=cut
sub create {
- my ($self, $col_data) = @_;
- $self->throw_exception( "create needs a hashref" )
- unless ref $col_data eq 'HASH';
- return $self->new_result($col_data)->insert;
+ #my ($self, $col_data) = @_;
+ DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and fail_on_internal_call;
+ return shift->new_result(shift)->insert;
}
=head2 find_or_create
if (keys %$hash and my $row = $self->find($hash, $attrs) ) {
return $row;
}
- return $self->create($hash);
+ return $self->new_result($hash)->insert;
}
=head2 update_or_create
return $row;
}
- return $self->create($cond);
+ return $self->new_result($cond)->insert;
}
=head2 update_or_new