Merge 'trunk' into 'sybase'
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Sybase.pm
CommitLineData
3885cff6 1package DBIx::Class::Storage::DBI::Sybase;
2
3use strict;
4use warnings;
5
a0348159 6use Class::C3;
c5ce7cd6 7use base qw/DBIx::Class::Storage::DBI/;
3885cff6 8
6b1f5ef7 9use Carp::Clan qw/^DBIx::Class/;
10
47d9646a 11sub _rebless {
b50a5275 12 my $self = shift;
c5ce7cd6 13
14 if (ref($self) eq 'DBIx::Class::Storage::DBI::Sybase') {
15 my $dbtype = eval {
16 @{$self->dbh->selectrow_arrayref(qq{sp_server_info \@attribute_id=1})}[2]
17 } || '';
18
19 my $exception = $@;
20 $dbtype =~ s/\W/_/gi;
21 my $subclass = "DBIx::Class::Storage::DBI::Sybase::${dbtype}";
22
23 if (!$exception && $dbtype && $self->load_optional_class($subclass)) {
24 bless $self, $subclass;
25 $self->_rebless;
683f73ec 26 } else {
27 # real Sybase
28 if (not $self->dbh->{syb_dynamic_supported}) {
29 bless $self, 'DBIx::Class::Storage:DBI::Sybase::NoBindVars';
30 $self->_rebless;
31 }
9539eeb1 32 $self->connect_call_datetime_setup;
63d46bb3 33 $self->connect_call_blob_setup;
47d9646a 34 }
c5ce7cd6 35 }
b50a5275 36}
37
683f73ec 38sub _populate_dbh {
39 my $self = shift;
40 $self->next::method(@_);
9539eeb1 41 $self->connect_call_datetime_setup;
63d46bb3 42 $self->connect_call_blob_setup;
683f73ec 43 1;
44}
45
63d46bb3 46=head2 connect_call_blob_setup
47
48Used as:
49
50 on_connect_call => 'blob_setup'
51
52Does C<< $dbh->{syb_binary_images} = 1; >> to return C<IMAGE> data as raw binary
53instead of as a hex string.
54
6636ad53 55Recommended.
56
63d46bb3 57=cut
58
59sub connect_call_blob_setup {
60 my $self = shift;
61 my $dbh = $self->_dbh;
62 $dbh->{syb_binary_images} = 1;
63}
64
9539eeb1 65=head2 connect_call_datetime_setup
66
67Used as:
68
69 on_connect_call => 'datetime_setup'
70
71In L<DBIx::Class::Storage::DBI/connect_info> to set:
72
3abafb11 73 $dbh->syb_date_fmt('ISO_strict'); # output fmt: 2004-08-21T14:36:48.080Z
74 $dbh->do('set dateformat mdy'); # input fmt: 08/13/1979 18:08:55.080
9539eeb1 75
76On connection for use with L<DBIx::Class::InflateColumn::DateTime>, using
3abafb11 77L<DateTime::Format::Sybase>, which you will need to install.
78
79This works for both C<DATETIME> and C<SMALLDATETIME> columns, although
80C<SMALLDATETIME> columns only have minute precision.
9539eeb1 81
82=cut
83
9041a97a 84{
85 my $old_dbd_warned = 0;
86
9539eeb1 87 sub connect_call_datetime_setup {
6b1f5ef7 88 my $self = shift;
6b1f5ef7 89 my $dbh = $self->_dbh;
90
91 if ($dbh->can('syb_date_fmt')) {
92 $dbh->syb_date_fmt('ISO_strict');
93 } elsif (not $old_dbd_warned) {
94 carp "Your DBD::Sybase is too old to support ".
95 "DBIx::Class::InflateColumn::DateTime, please upgrade!";
96 $old_dbd_warned = 1;
97 }
98
99 $dbh->do('set dateformat mdy');
c5ce7cd6 100
6b1f5ef7 101 1;
c5ce7cd6 102 }
6b1f5ef7 103}
104
6636ad53 105sub datetime_parser_type { "DateTime::Format::Sybase" }
106
6b1f5ef7 107sub _dbh_last_insert_id {
108 my ($self, $dbh, $source, $col) = @_;
c5ce7cd6 109
110 # sorry, there's no other way!
111 my $sth = $dbh->prepare_cached("select max($col) from ".$source->from);
112 return ($dbh->selectrow_array($sth))[0];
a964a928 113}
114
6636ad53 115=head2 count
116
117Counts for limited queries are emulated by executing select queries and
118returning the number of successful executions minus the offset.
119
120This is necessary due to the limitations of Sybase.
121
122=cut
123
b7505130 124sub count {
aa56ff9a 125 my $self = shift;
126 my ($source, $attrs) = @_;
b7505130 127
6537ddaa 128 if (not exists $attrs->{rows}) {
129 return $self->next::method(@_);
130 }
b7505130 131
6537ddaa 132 my $offset = $attrs->{offset} || 0;
133 my $total = $attrs->{rows} + $offset;
b7505130 134
8cebbed0 135 my $new_attrs = $self->_copy_attributes_for_count($source, $attrs);
136
137 my $first_pk = ($source->primary_columns)[0];
138
139 $new_attrs->{select} = $first_pk ? "me.$first_pk" : 1;
a0348159 140
6537ddaa 141 my $tmp_rs = $source->resultset_class->new($source, $new_attrs);
b7505130 142
6537ddaa 143 $self->dbh->{syb_rowcount} = $total;
b7505130 144
6537ddaa 145 my $count = 0;
146 $count++ while $tmp_rs->cursor->next;
b7505130 147
6537ddaa 148 $self->dbh->{syb_rowcount} = 0;
b7505130 149
6537ddaa 150 return $count - $offset;
b7505130 151}
152
3885cff6 1531;
154
155=head1 NAME
156
157DBIx::Class::Storage::DBI::Sybase - Storage::DBI subclass for Sybase
158
159=head1 SYNOPSIS
160
7e8cecc1 161This subclass supports L<DBD::Sybase> for real Sybase databases. If you are
162using an MSSQL database via L<DBD::Sybase>, your storage will be reblessed to
163L<DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server>.
3885cff6 164
7e8cecc1 165=head1 DESCRIPTION
d4483998 166
7e8cecc1 167If your version of Sybase does not support placeholders, then your storage
168will be reblessed to L<DBIx::Class::Storage::DBI::Sybase::NoBindVars>. You can
169also enable that driver explicitly, see the documentation for more details.
c5ce7cd6 170
7e8cecc1 171With this driver there is unfortunately no way to get the C<last_insert_id>
172without doing a C<select max(col)>.
c5ce7cd6 173
174But your queries will be cached.
175
6636ad53 176A recommended L<DBIx::Class::Storage::DBI/connect_info> setting:
177
178 on_connect_call => [qw/datetime_setup blob_setup/]
179
c5ce7cd6 180=head1 DATES
181
3abafb11 182See L</connect_call_datetime_setup> to setup date formats
183for L<DBIx::Class::InflateColumn::DateTime>.
c5ce7cd6 184
6636ad53 185=head1 IMAGE AND TEXT COLUMNS
63d46bb3 186
187See L</connect_call_blob_setup> for a L<DBIx::Class::Storage::DBI/connect_info>
188setting you need to work with C<IMAGE> columns.
189
6636ad53 190Due to limitations in L<DBD::Sybase> and this driver, it is only possible to
9041a97a 191select one C<TEXT> or C<IMAGE> column at a time.
6636ad53 192
3885cff6 193=head1 AUTHORS
194
7e8cecc1 195See L<DBIx::Class/CONTRIBUTORS>.
c5ce7cd6 196
3885cff6 197=head1 LICENSE
198
199You may distribute this code under the same terms as Perl itself.
200
201=cut
c5ce7cd6 202# vim:sts=2 sw=2: