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