use strict;
use warnings;
-use base qw/DBIx::Class::Storage::DBI::NoBindVars/;
+use Class::C3;
+use base qw/DBIx::Class::Storage::DBI/;
-my $noquote = {
- int => qr/^ \-? \d+ $/x,
- integer => qr/^ \-? \d+ $/x,
+use Carp::Clan qw/^DBIx::Class/;
- # TODO maybe need to add float/real/etc
-};
+sub _rebless {
+ my $self = shift;
-sub should_quote_data_type {
+ if (ref($self) eq 'DBIx::Class::Storage::DBI::Sybase') {
+ my $dbtype = eval {
+ @{$self->dbh->selectrow_arrayref(qq{sp_server_info \@attribute_id=1})}[2]
+ } || '';
+
+ my $exception = $@;
+ $dbtype =~ s/\W/_/gi;
+ my $subclass = "DBIx::Class::Storage::DBI::Sybase::${dbtype}";
+
+ if (!$exception && $dbtype && $self->load_optional_class($subclass)) {
+ bless $self, $subclass;
+ $self->_rebless;
+ } else {
+ # real Sybase
+ if (not $self->dbh->{syb_dynamic_supported}) {
+ bless $self, 'DBIx::Class::Storage:DBI::Sybase::NoBindVars';
+ $self->_rebless;
+ }
+ $self->connect_call_datetime_setup;
+ }
+ }
+}
+
+sub _populate_dbh {
my $self = shift;
- my ($type, $value) = @_;
+ $self->next::method(@_);
+ $self->connect_call_datetime_setup;
+ 1;
+}
+
+{
+ my $old_dbd_warned = 0;
+
+=head2 connect_call_datetime_setup
+
+Used as:
+
+ on_connect_call => 'datetime_setup'
+
+In L<DBIx::Class::Storage::DBI/connect_info> to set:
+
+ $dbh->syb_date_fmt('ISO_strict'); # output fmt: 2004-08-21T14:36:48.080Z
+ $dbh->do('set dateformat mdy'); # input fmt: 08/13/1979 18:08:55.080
+
+On connection for use with L<DBIx::Class::InflateColumn::DateTime>, using
+L<DateTime::Format::Sybase>, which you will need to install.
+
+This works for both C<DATETIME> and C<SMALLDATETIME> columns, although
+C<SMALLDATETIME> columns only have minute precision.
+
+=cut
+
+ sub connect_call_datetime_setup {
+ my $self = shift;
+ my $dbh = $self->_dbh;
+
+ if ($dbh->can('syb_date_fmt')) {
+ $dbh->syb_date_fmt('ISO_strict');
+ } elsif (not $old_dbd_warned) {
+ carp "Your DBD::Sybase is too old to support ".
+ "DBIx::Class::InflateColumn::DateTime, please upgrade!";
+ $old_dbd_warned = 1;
+ }
+
+ $dbh->do('set dateformat mdy');
+
+ 1;
+ }
+}
+
+sub _dbh_last_insert_id {
+ my ($self, $dbh, $source, $col) = @_;
- return $self->next::method(@_) if not defined $value;
+ # sorry, there's no other way!
+ my $sth = $dbh->prepare_cached("select max($col) from ".$source->from);
+ return ($dbh->selectrow_array($sth))[0];
+}
+
+sub count {
+ my $self = shift;
+ my ($source, $attrs) = @_;
- if (my $re = $noquote->{$type}) {
- return 0 if $value =~ $re;
+ if (not exists $attrs->{rows}) {
+ return $self->next::method(@_);
}
- return $self->next::method(@_);
+ my $offset = $attrs->{offset} || 0;
+ my $total = $attrs->{rows} + $offset;
+
+ my $new_attrs = $self->_copy_attributes_for_count($source, $attrs);
+
+ my $first_pk = ($source->primary_columns)[0];
+
+ $new_attrs->{select} = $first_pk ? "me.$first_pk" : 1;
+
+ my $tmp_rs = $source->resultset_class->new($source, $new_attrs);
+
+ $self->dbh->{syb_rowcount} = $total;
+
+ my $count = 0;
+ $count++ while $tmp_rs->cursor->next;
+
+ $self->dbh->{syb_rowcount} = 0;
+
+ return $count - $offset;
}
+sub datetime_parser_type { "DateTime::Format::Sybase" }
+
1;
=head1 NAME
=head1 SYNOPSIS
-This subclass supports L<DBD::Sybase> for real Sybase databases. If
-you are using an MSSQL database via L<DBD::Sybase>, see
-L<DBIx::Class::Storage::DBI::Sybase::MSSQL>.
+This subclass supports L<DBD::Sybase> for real Sybase databases. If you are
+using an MSSQL database via L<DBD::Sybase>, your storage will be reblessed to
+L<DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server>.
+
+=head1 DESCRIPTION
+
+If your version of Sybase does not support placeholders, then your storage
+will be reblessed to L<DBIx::Class::Storage::DBI::Sybase::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)>.
+
+But your queries will be cached.
+
+=head1 DATES
+
+See L</connect_call_datetime_setup> to setup date formats
+for L<DBIx::Class::InflateColumn::DateTime>.
=head1 AUTHORS
-Brandon L Black <blblack@gmail.com>
+See L<DBIx::Class/CONTRIBUTORS>.
=head1 LICENSE
You may distribute this code under the same terms as Perl itself.
=cut
+# vim:sts=2 sw=2: