Data-Toolkit
view release on metacpan or search on metacpan
lib/Data/Toolkit/Connector/DBI.pm view on Meta::CPAN
=cut
sub add {
my $self = shift;
my $source = shift;
my $map = shift;
croak "Data::Toolkit::Connector::DBI->add called before addspec has been defined" if !$self->{add_sth};
croak "Data::Toolkit::Connector::DBI->add first parameter should be a Data::Toolkit::Entry"
if ($source and !$source->isa('Data::Toolkit::Entry'));
croak "Data::Toolkit::Connector::DBI->add second parameter should be a Data::Toolkit::Map"
if ($map and !$map->isa('Data::Toolkit::Map'));
carp "Data::Toolkit::Connector::DBI->add $self $source" if $debug;
# Apply the map if we have one
$source = $source->map($map) if $map;
# The args to be passed to the SQL UPDATE statement
my @args;
# The array of names that came from the addspec
my @arglist = @{$self->{add_arglist}};
# Check that we have an entry to get params from
print "ARGLIST for add: ", (join '/', @arglist), "\n" if $debug;
if ($arglist[0] and !$source) {
croak "Data::Toolkit::Connector::DBI->add requires an entry when the addspec includes parameters";
}
# Extract the args from the entry
my $arg;
foreach $arg (@arglist) {
my $value = $source->get($arg);
croak "add spec calls for a '$arg' attribute but the entry does not have one" if !$value;
# We only use the first value from the list.
# This is permitted to be undef or the null string.
$value = $value->[0];
push @args, $value;
}
# Start the operation and return the statement handle having stashed a copy internally
return $self->{add_result} = $self->{add_sth}->execute( @args );
}
########################################
=head2 updatespec
Supply or fetch spec for update
$spec = $dbiConn->updatespec();
$spec = $dbiConn->updatespec( "UPDATE people set name = %myname% WHERE joinkey = %mykey%" );
Parameters are indicated thus: %name% - this will result in a '?'-style placeholder in
the SQL statement and the named attribute will be extracted from the supplied entry
by the update() method.
=cut
sub updatespec {
my $self = shift;
my $updatespec = shift;
carp "Data::Toolkit::Connector::DBI->updatespec $self $updatespec " if $debug;
croak "Data::Toolkit::Connector::DBI->updatespec called before server connection opened" if !$self->{server};
# No arg supplied - just return existing setting
return $self->{updatespec} if (!$updatespec);
# We have a new updatespec so stash it for future reference
$self->{updatespec} = $updatespec;
# We need to parse the spec to find the list of args that it calls for.
# Start by clearing the arglist and update string
my $update = '';
my @arglist;
$self->{update_arglist} = \@arglist;
# Parameter names are between pairs of % characters
# Where we want a literal '%' it is represented by '%%'
# so if the update string has at least two '%' left then there is work to be done
while ($updatespec =~ /%.*%/) {
my ($left,$name,$right) = ($updatespec =~ /^([^%]*)%([a-zA-Z0-9_]*)%(.*)$/);
# Everything before the first % gets added to the update string
$update .= $left;
if ($name) {
# Add the name to the list of attributes needed when the update is performed
push @arglist, $name;
# Put the placeholder in the actual update string
$update .= '?';
}
else {
# We got '%%' so add a literal '%' to the update string
$update .= '%';
}
# The remainder of the updatespec goes round again
$updatespec = $right;
}
# Anything left in the updatespec gets appended to the update string
$update .= $updatespec;
# Stash the resulting string and associated list of attributes
$self->{update_statement} = $update;
# Prepare the statement and stash the statement handle
$self->{update_sth} = $self->{server}->prepare( $update );
croak "Failed to prepare update '$update'" if !$self->{update_sth};
carp "Data::Toolkit::Connector::DBI->updatespec setting '$update', (" . (join ',',@arglist) . ")" if $debug;
# Return the spec string that we were given
return $self->{updatespec};
}
########################################
=head2 update
Update a row in the database using data from a source entry and an optional map.
If a map is supplied, it is used to transform data from the source entry before
it is applied to the database operation.
Returns the result of the DBI execute operation.
$msg = $dbConn->update($sourceEntry);
$msg = $dbConn->update($sourceEntry, $updateMap);
A suitable update operation must have been defined using the updatespec() method
before update() is called:
$spec = $dbiConn->updatespec( "UPDATE people set name = %myname% WHERE key = %mykey%" );
$msg = $dbiConn->update( $entry );
NOTE that only the first value of a given attribute is used, as relational databases expect
a single value for each column in a given row.
Note also that multiple rows could be affected by a single call to this method, depending
on how the updatespec has been defined.
=cut
sub update {
my $self = shift;
my $source = shift;
my $map = shift;
croak "Data::Toolkit::Connector::DBI->update called before updatespec has been defined" if !$self->{update_sth};
croak "Data::Toolkit::Connector::DBI->update first parameter should be a Data::Toolkit::Entry"
if ($source and !$source->isa('Data::Toolkit::Entry'));
croak "Data::Toolkit::Connector::DBI->update second parameter should be a Data::Toolkit::Map"
if ($map and !$map->isa('Data::Toolkit::Map'));
carp "Data::Toolkit::Connector::DBI->update $self $source" if $debug;
# Apply the map if we have one
$source = $source->map($map) if $map;
# The args to be passed to the SQL UPDATE statement
my @args;
# The array of names that came from the updatespec
my @arglist = @{$self->{update_arglist}};
# Check that we have an entry to get params from
print "ARGLIST for update: ", (join ',', @arglist), "\n" if $debug;
if ($arglist[0] and !$source) {
croak "Data::Toolkit::Connector::DBI->update requires an entry when the updatespec includes parameters";
}
# Extract the args from the entry
my $arg;
foreach $arg (@arglist) {
my $value = $source->get($arg);
croak "update spec calls for a '$arg' attribute but the entry does not have one" if !$value;
# We only use the first value from the list.
# This is permitted to be the null string.
# It should not be undef, as that would need an 'IS NULL' clause in SQL.
$value = $value->[0];
push @args, $value;
}
# Start the search and return the statement handle having stashed a copy internally
return $self->{update_result} = $self->{update_sth}->execute( @args );
}
########################################
=head2 deletespec
Supply or fetch spec for delete
$spec = $dbiConn->deletespec();
$spec = $dbiConn->deletespec( "DELETE from people WHERE joinkey = %mykey%" );
Parameters are indicated thus: %name% - this will result in a '?'-style placeholder in
the SQL statement and the named attribute will be extracted from the supplied entry
by the delete() method.
=cut
sub deletespec {
my $self = shift;
my $deletespec = shift;
( run in 2.726 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )