DBIx-Class
view release on metacpan or search on metacpan
lib/DBIx/Class/Storage/DBI/Sybase/ASE.pm view on Meta::CPAN
next if $info->{data_type} && $info->{data_type} =~ /^timestamp\z/i;
$to_insert->{$col} = \'DEFAULT';
}
}
my $blob_cols = $self->_remove_blob_cols($source, $to_insert);
# do we need the horrific SELECT MAX(COL) hack?
my $need_dumb_last_insert_id = (
$self->_perform_autoinc_retrieval
&&
($self->_identity_method||'') ne '@@IDENTITY'
);
my $next = $self->next::can;
# we are already in a transaction, or there are no blobs
# and we don't need the PK - just (try to) do it
if ($self->{transaction_depth}
|| (!$blob_cols && !$need_dumb_last_insert_id)
) {
return $self->_insert (
$next, $source, $to_insert, $blob_cols, $identity_col
);
}
# otherwise use the _writer_storage to do the insert+transaction on another
# connection
my $guard = $self->_writer_storage->txn_scope_guard;
my $updated_cols = $self->_writer_storage->_insert (
$next, $source, $to_insert, $blob_cols, $identity_col
);
$self->_identity($self->_writer_storage->_identity);
$guard->commit;
return $updated_cols;
}
sub _insert {
my ($self, $next, $source, $to_insert, $blob_cols, $identity_col) = @_;
my $updated_cols = $self->$next ($source, $to_insert);
my $final_row = {
($identity_col ?
($identity_col => $self->last_insert_id($source, $identity_col)) : ()),
%$to_insert,
%$updated_cols,
};
$self->_insert_blobs ($source, $blob_cols, $final_row) if $blob_cols;
return $updated_cols;
}
sub update {
my $self = shift;
my ($source, $fields, $where, @rest) = @_;
#
# When *updating* identities, ASE requires SET IDENTITY_UPDATE called
#
if (my $blob_cols = $self->_remove_blob_cols($source, $fields)) {
# If there are any blobs in $where, Sybase will return a descriptive error
# message.
# XXX blobs can still be used with a LIKE query, and this should be handled.
# update+blob update(s) done atomically on separate connection
$self = $self->_writer_storage;
my $guard = $self->txn_scope_guard;
# First update the blob columns to be updated to '' (taken from $fields, where
# it is originally put by _remove_blob_cols .)
my %blobs_to_empty = map { ($_ => delete $fields->{$_}) } keys %$blob_cols;
# We can't only update NULL blobs, because blobs cannot be in the WHERE clause.
$self->next::method($source, \%blobs_to_empty, $where, @rest);
# Now update the blobs before the other columns in case the update of other
# columns makes the search condition invalid.
my $rv = $self->_update_blobs($source, $blob_cols, $where);
if (keys %$fields) {
# Now set the identity update flags for the actual update
local $self->{_autoinc_supplied_for_op} = grep
{ $_->{is_auto_increment} }
values %{ $source->columns_info([ keys %$fields ]) }
;
my $next = $self->next::can;
my $args = \@_;
return preserve_context {
$self->$next(@$args);
} after => sub { $guard->commit };
}
else {
$guard->commit;
return $rv;
}
}
else {
# Set the identity update flags for the actual update
local $self->{_autoinc_supplied_for_op} = grep
{ $_->{is_auto_increment} }
values %{ $source->columns_info([ keys %$fields ]) }
;
return $self->next::method(@_);
}
}
sub _insert_bulk {
my $self = shift;
( run in 1.460 second using v1.01-cache-2.11-cpan-39bf76dae61 )