DBIx-Class
view release on metacpan or search on metacpan
lib/DBIx/Class/Storage/DBI/Sybase/ASE.pm view on Meta::CPAN
package DBIx::Class::Storage::DBI::Sybase::ASE;
use strict;
use warnings;
use base qw/
DBIx::Class::Storage::DBI::Sybase
DBIx::Class::Storage::DBI::AutoCast
DBIx::Class::Storage::DBI::IdentityInsert
/;
use mro 'c3';
use DBIx::Class::Carp;
use Scalar::Util qw/blessed weaken/;
use Sub::Name();
use Data::Dumper::Concise 'Dumper';
use Try::Tiny;
use Context::Preserve 'preserve_context';
use DBIx::Class::_Util 'sigwarn_silencer';
use namespace::clean;
__PACKAGE__->sql_limit_dialect ('GenericSubQ');
__PACKAGE__->sql_quote_char ([qw/[ ]/]);
__PACKAGE__->datetime_parser_type(
'DBIx::Class::Storage::DBI::Sybase::ASE::DateTime::Format'
);
__PACKAGE__->mk_group_accessors('simple' =>
qw/_identity _identity_method _blob_log_on_update _parent_storage
_writer_storage _is_writer_storage
_bulk_storage _is_bulk_storage _began_bulk_work
/
);
my @also_proxy_to_extra_storages = qw/
connect_call_set_auto_cast auto_cast connect_call_blob_setup
connect_call_datetime_setup
disconnect _connect_info _sql_maker _sql_maker_opts disable_sth_caching
auto_savepoint unsafe cursor_class debug debugobj schema
/;
=head1 NAME
DBIx::Class::Storage::DBI::Sybase::ASE - Sybase ASE SQL Server support for
DBIx::Class
=head1 SYNOPSIS
This subclass supports L<DBD::Sybase> for real (non-Microsoft) Sybase databases.
=head1 DESCRIPTION
If your version of Sybase does not support placeholders, then your storage will
be reblessed to L<DBIx::Class::Storage::DBI::Sybase::ASE::NoBindVars>.
You can also enable that driver explicitly, see the documentation for more
details.
With this driver there is unfortunately no way to get the C<last_insert_id>
without doing a C<SELECT MAX(col)>. This is done safely in a transaction
(locking the table.) See L</INSERTS WITH PLACEHOLDERS>.
A recommended L<connect_info|DBIx::Class::Storage::DBI/connect_info> setting:
on_connect_call => [['datetime_setup'], ['blob_setup', log_on_update => 0]]
=head1 METHODS
=cut
sub _rebless {
my $self = shift;
lib/DBIx/Class/Storage/DBI/Sybase/ASE.pm view on Meta::CPAN
TEXT/IMAGE columns will definitely not work.
You are encouraged to recompile DBD::Sybase with the Sybase Open Client libraries
instead.
See perldoc DBIx::Class::Storage::DBI::Sybase::ASE for more details.
To turn off this warning set the DBIC_SYBASE_FREETDS_NOWARN environment
variable.
EOF
if (not $self->_use_typeless_placeholders) {
if ($self->_use_placeholders) {
$self->auto_cast(1);
}
else {
$self->ensure_class_loaded($no_bind_vars);
bless $self, $no_bind_vars;
$self->_rebless;
}
}
}
elsif (not $self->_get_dbh->{syb_dynamic_supported}) {
# not necessarily FreeTDS, but no placeholders nevertheless
$self->ensure_class_loaded($no_bind_vars);
bless $self, $no_bind_vars;
$self->_rebless;
}
# this is highly unlikely, but we check just in case
elsif (not $self->_use_typeless_placeholders) {
$self->auto_cast(1);
}
}
sub _init {
my $self = shift;
$self->next::method(@_);
if ($self->_using_freetds && (my $ver = $self->_using_freetds_version||999) > 0.82) {
carp_once(
"Buggy FreeTDS version $ver detected, statement caching will not work and "
. 'will be disabled.'
);
$self->disable_sth_caching(1);
}
$self->_set_max_connect(256);
# create storage for insert/(update blob) transactions,
# unless this is that storage
return if $self->_parent_storage;
my $writer_storage = (ref $self)->new;
$writer_storage->_is_writer_storage(1); # just info
$writer_storage->connect_info($self->connect_info);
$writer_storage->auto_cast($self->auto_cast);
weaken ($writer_storage->{_parent_storage} = $self);
$self->_writer_storage($writer_storage);
# create a bulk storage unless connect_info is a coderef
return if ref($self->_dbi_connect_info->[0]) eq 'CODE';
my $bulk_storage = (ref $self)->new;
$bulk_storage->_is_bulk_storage(1); # for special ->disconnect acrobatics
$bulk_storage->connect_info($self->connect_info);
# this is why
$bulk_storage->_dbi_connect_info->[0] .= ';bulkLogin=1';
weaken ($bulk_storage->{_parent_storage} = $self);
$self->_bulk_storage($bulk_storage);
}
for my $method (@also_proxy_to_extra_storages) {
no strict 'refs';
no warnings 'redefine';
my $replaced = __PACKAGE__->can($method);
*{$method} = Sub::Name::subname $method => sub {
my $self = shift;
$self->_writer_storage->$replaced(@_) if $self->_writer_storage;
$self->_bulk_storage->$replaced(@_) if $self->_bulk_storage;
return $self->$replaced(@_);
};
}
sub disconnect {
my $self = shift;
# Even though we call $sth->finish for uses off the bulk API, there's still an
# "active statement" warning on disconnect, which we throw away here.
# This is due to the bug described in _insert_bulk.
# Currently a noop because 'prepare' is used instead of 'prepare_cached'.
local $SIG{__WARN__} = sigwarn_silencer(qr/active statement/i)
if $self->_is_bulk_storage;
# so that next transaction gets a dbh
$self->_began_bulk_work(0) if $self->_is_bulk_storage;
$self->next::method;
}
# This is only invoked for FreeTDS drivers by ::Storage::DBI::Sybase::FreeTDS
sub _set_autocommit_stmt {
my ($self, $on) = @_;
return 'SET CHAINED ' . ($on ? 'OFF' : 'ON');
}
# Set up session settings for Sybase databases for the connection.
#
# Make sure we have CHAINED mode turned on if AutoCommit is off in non-FreeTDS
# DBD::Sybase (since we don't know how DBD::Sybase was compiled.) If however
# we're using FreeTDS, CHAINED mode turns on an implicit transaction which we
# only want when AutoCommit is off.
sub _run_connection_actions {
my $self = shift;
if ($self->_is_bulk_storage) {
# this should be cleared on every reconnect
$self->_began_bulk_work(0);
return;
}
$self->_dbh->{syb_chained_txn} = 1
unless $self->_using_freetds;
$self->next::method(@_);
}
( run in 0.786 second using v1.01-cache-2.11-cpan-39bf76dae61 )