DBIx-DataModel
view release on metacpan or search on metacpan
lib/DBIx/DataModel/Source/Table.pm view on Meta::CPAN
# an arrayref which is an array of values or a "bind value with type"
# -- see L<DBIx::Class::ResultSet/"DBIC BIND VALUES">
(does($v, 'ARRAY') && ($sqla->{array_datatypes} ||
$sqla->is_bind_value_with_type($v)))
||
# literal SQL in the form $k => \ ["FUNC(?)", $v]
(ref $v eq 'REF' && does($$v, 'ARRAY'))
){
# do nothing (pass the ref to SQL::Abstract::More)
}
# otherwise it is probably wrong data
else {
carp "unexpected reference $k in record, deleted";
delete $self->{$k};
}
}
}
return keys %subrecords ? \%subrecords : undef;
}
sub _insert_subtrees {
my ($self, $subrecords, %options) = @_;
my $class = ref $self;
my %results;
while (my ($role, $arrayref) = each %$subrecords) {
does $arrayref, 'ARRAY'
or croak "Expected an arrayref for component role $role in $class";
next if not @$arrayref;
# insert via the "insert_into_..." method
my $meth = "insert_into_$role";
$results{$role} = [$self->$meth(@$arrayref, %options)];
# also reinject in memory into source object
$self->{$role} = $arrayref;
}
return \%results;
}
#------------------------------------------------------------
# delete
#------------------------------------------------------------
my $delete_spec = {
-where => {type => HASHREF, optional => 0},
};
sub _parse_delete_args {
my $self = shift;
my @pk_cols = $self->metadm->primary_key;
my $where;
my @cascaded;
if ($self->_is_called_as_class_method) {
# parse arguments
@_ or croak "delete() as class method: not enough arguments";
my $uses_named_args = ! ref $_[0] && $_[0] =~ /^-/;
if ($uses_named_args) {
my %args = validate_with(params => \@_,
spec => $delete_spec,
allow_extra => 0);
$where = $args{-where};
}
else { # uses positional args
if (does $_[0], 'HASH') { # called as: delete({fields})
my $hash = shift;
@{$where}{@pk_cols} = @{$hash}{@pk_cols};
!@_ or croak "delete() : too many arguments";
}
else { # called as: delete(@primary_key)
my ($n_vals, $n_keys) = (scalar(@_), scalar(@pk_cols));
$n_vals == $n_keys
or croak "delete(): got $n_vals cols in primary key, expected $n_keys";
@{$where}{@pk_cols} = @_;
}
my $missing = join ", ", grep {!defined $where->{$_}} @pk_cols;
croak "delete(): missing value for $missing" if $missing;
}
}
else { # called as instance method
# build $where from primary key
@{$where}{@pk_cols} = @{$self}{@pk_cols};
# cascaded delete
COMPONENT_NAME:
foreach my $component_name ($self->metadm->components) {
my $components = $self->{$component_name} or next COMPONENT_NAME;
does($components, 'ARRAY')
or croak "delete() : component $component_name is not an arrayref";
push @cascaded, @$components;
}
}
return ($where, \@cascaded);
}
sub delete {
my $self = shift;
my $schema = $self->schema;
my ($where, $cascaded) = $self->_parse_delete_args(@_);
# perform cascaded deletes for components within $self
$_->delete foreach @$cascaded;
# perform this delete
my ($sql, @bind) = $schema->sql_abstract->delete(
-from => $self->db_from,
-where => $where,
);
$schema->_debug($sql . " / " . CORE::join(", ", @bind) );
my $method = $schema->dbi_prepare_method;
my $sth = $schema->dbh->$method($sql);
$sth->execute(@bind);
}
#------------------------------------------------------------
# update
#------------------------------------------------------------
my $update_spec = {
-set => {type => HASHREF, optional => 0},
-where => {type => HASHREF, optional => 0},
};
sub _parse_update_args { # returns ($schema, $to_set, $where)
my $self = shift;
my ($to_set, $where);
if ($self->_is_called_as_class_method) {
@_
or croak "update() as class method: not enough arguments";
my $uses_named_args = ! ref $_[0] && $_[0] =~ /^-/;
if ($uses_named_args) {
my %args = validate_with(params => \@_,
spec => $update_spec,
allow_extra => 0);
($to_set, $where) = @args{qw/-set -where/};
}
else { # uses positional args: update([@primary_key], {fields_to_update})
does $_[-1], 'HASH'
or croak "update(): expected a hashref as last argument";
$to_set = { %{pop @_} }; # shallow copy
my @pk_cols = $self->metadm->primary_key;
if (@_) {
my ($n_vals, $n_keys) = (scalar(@_), scalar(@pk_cols));
$n_vals == $n_keys
or croak "update(): got $n_vals cols in primary key, expected $n_keys";
@{$where}{@pk_cols} = @_;
}
else {
# extract primary key from hashref
@{$where}{@pk_cols} = delete @{$to_set}{@pk_cols};
}
}
}
else { # called as instance method
my %clone = %$self;
# extract primary key from object
( run in 1.004 second using v1.01-cache-2.11-cpan-39bf76dae61 )