1 package DBIx::Class::Storage::DBI::Sybase;
7 DBIx::Class::Storage::DBI::Sybase::Base
8 DBIx::Class::Storage::DBI
11 use Carp::Clan qw/^DBIx::Class/;
15 DBIx::Class::Storage::DBI::Sybase - Storage::DBI subclass for Sybase
19 This subclass supports L<DBD::Sybase> for real Sybase databases. If you are
20 using an MSSQL database via L<DBD::Sybase>, your storage will be reblessed to
21 L<DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server>.
25 If your version of Sybase does not support placeholders, then your storage
26 will be reblessed to L<DBIx::Class::Storage::DBI::Sybase::NoBindVars>. You can
27 also enable that driver explicitly, see the documentation for more details.
29 With this driver there is unfortunately no way to get the C<last_insert_id>
30 without doing a C<select max(col)>.
32 But your queries will be cached.
34 A recommended L<DBIx::Class::Storage::DBI/connect_info> settings:
36 on_connect_call => [['datetime_setup'], [blob_setup => log_on_update => 0]]
42 __PACKAGE__->mk_group_accessors('simple' =>
43 qw/_blob_log_on_update/
49 if (ref($self) eq 'DBIx::Class::Storage::DBI::Sybase') {
51 @{$self->dbh->selectrow_arrayref(qq{sp_server_info \@attribute_id=1})}[2]
56 my $subclass = "DBIx::Class::Storage::DBI::Sybase::${dbtype}";
58 if (!$exception && $dbtype && $self->load_optional_class($subclass)) {
59 bless $self, $subclass;
63 if (not $self->dbh->{syb_dynamic_supported}) {
64 $self->ensure_class_loaded('DBIx::Class::Storage::DBI::Sybase::NoBindVars');
65 bless $self, 'DBIx::Class::Storage::DBI::Sybase::NoBindVars';
68 $self->_set_maxConnect;
76 my $dsn = $self->_dbi_connect_info->[0];
78 return if ref($dsn) eq 'CODE';
80 if ($dsn !~ /maxConnect=/) {
81 $self->_dbi_connect_info->[0] = "$dsn;maxConnect=256";
82 my $connected = defined $self->_dbh;
84 $self->ensure_connected if $connected;
88 =head2 connect_call_blob_setup
92 on_connect_call => [ [ blob_setup => log_on_update => 0 ] ]
94 Does C<< $dbh->{syb_binary_images} = 1; >> to return C<IMAGE> data as raw binary
95 instead of as a hex string.
99 Also sets the C<log_on_update> value for blob write operations. The default is
100 C<1>, but C<0> is better if your database is configured for it.
103 L<DBD::Sybase/Handling_IMAGE/TEXT_data_with_syb_ct_get_data()/syb_ct_send_data()>.
107 sub connect_call_blob_setup {
110 my $dbh = $self->_dbh;
111 $dbh->{syb_binary_images} = 1;
113 $self->_blob_log_on_update($args{log_on_update})
114 if exists $args{log_on_update};
119 shift =~ /(?:text|image|lob|bytea|binary)/i;
123 my ($self, $source, $to_insert) = splice @_, 0, 3;
125 my $blob_cols = $self->_remove_blob_cols($source, $to_insert);
127 my $updated_cols = $self->next::method($source, $to_insert, @_);
129 $self->_update_blobs($source, $blob_cols, $to_insert) if %$blob_cols;
131 return $updated_cols;
135 # my ($self, $source) = splice @_, 0, 2;
138 # my $blob_cols = $self->_remove_blob_cols($source, $fields);
144 # @res = $self->next::method($source, @_);
146 # $res[0] = $self->next::method($source, @_);
150 # $self->_update_blobs($source, $blob_cols, $fields) if %$blob_cols;
152 # return wantarray ? @res : $res[0];
155 sub _remove_blob_cols {
156 my ($self, $source, $fields) = @_;
160 for my $col (keys %$fields) {
161 if ($self->_is_lob_type($source->column_info($col)->{data_type})) {
162 $blob_cols{$col} = delete $fields->{$col};
163 $fields->{$col} = \"''";
171 my ($self, $source, $blob_cols, $inserted) = @_;
172 my $dbh = $self->dbh;
174 my $table = $source->from;
176 my %inserted = %$inserted;
177 my (@primary_cols) = $source->primary_columns;
179 croak "Cannot update TEXT/IMAGE column(s) without a primary key"
180 unless @primary_cols;
182 if ((grep { defined $inserted{$_} } @primary_cols) != @primary_cols) {
183 if (@primary_cols == 1) {
184 my $col = $primary_cols[0];
185 $inserted{$col} = $self->last_insert_id($source, $col);
187 croak "Cannot update TEXT/IMAGE column(s) without primary key values";
191 for my $col (keys %$blob_cols) {
192 my $blob = $blob_cols->{$col};
195 if (not $self->isa('DBIx::Class::Storage::DBI::NoBindVars')) {
196 my $search_cond = join ',' => map "$_ = ?", @primary_cols;
199 "select $col from $table where $search_cond"
201 $sth->execute(map $inserted{$_}, @primary_cols);
203 my $search_cond = join ',' => map "$_ = $inserted{$_}", @primary_cols;
205 $sth = $dbh->prepare(
206 "select $col from $table where $search_cond"
212 while ($sth->fetch) {
213 $sth->func('CS_GET', 1, 'ct_data_info') or die $sth->errstr;
215 $sth->func('ct_prepare_send') or die $sth->errstr;
217 my $log_on_update = $self->_blob_log_on_update;
218 $log_on_update = 1 if not defined $log_on_update;
220 $sth->func('CS_SET', 1, {
221 total_txtlen => length($blob),
222 log_on_update => $log_on_update
223 }, 'ct_data_info') or die $sth->errstr;
225 $sth->func($blob, length($blob), 'ct_send_data') or die $sth->errstr;
227 $sth->func('ct_finish_send') or die $sth->errstr;
231 croak $exception if $exception;
235 =head2 connect_call_datetime_setup
239 on_connect_call => 'datetime_setup'
241 In L<DBIx::Class::Storage::DBI/connect_info> to set:
243 $dbh->syb_date_fmt('ISO_strict'); # output fmt: 2004-08-21T14:36:48.080Z
244 $dbh->do('set dateformat mdy'); # input fmt: 08/13/1979 18:08:55.080
246 On connection for use with L<DBIx::Class::InflateColumn::DateTime>, using
247 L<DateTime::Format::Sybase>, which you will need to install.
249 This works for both C<DATETIME> and C<SMALLDATETIME> columns, although
250 C<SMALLDATETIME> columns only have minute precision.
255 my $old_dbd_warned = 0;
257 sub connect_call_datetime_setup {
259 my $dbh = $self->_dbh;
261 if ($dbh->can('syb_date_fmt')) {
262 $dbh->syb_date_fmt('ISO_strict');
263 } elsif (not $old_dbd_warned) {
264 carp "Your DBD::Sybase is too old to support ".
265 "DBIx::Class::InflateColumn::DateTime, please upgrade!";
269 $dbh->do('set dateformat mdy');
275 sub datetime_parser_type { "DateTime::Format::Sybase" }
277 sub _dbh_last_insert_id {
278 my ($self, $dbh, $source, $col) = @_;
280 # sorry, there's no other way!
281 my $sth = $dbh->prepare_cached("select max($col) from ".$source->from);
282 return ($dbh->selectrow_array($sth))[0];
287 =head1 MAXIMUM CONNECTIONS
289 L<DBD::Sybase> makes separate connections to the server for active statements in
290 the background. By default the number of such connections is limited to 25, on
291 both the client side and the server side.
293 This is a bit too low, so on connection the clientside setting is set to C<256>
294 (see L<DBD::Sybase/maxConnect>.) You can override it to whatever setting you
298 L<http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.ase_15.0.sag1/html/sag1/sag1272.htm>
299 for information on changing the setting on the server side.
303 See L</connect_call_datetime_setup> to setup date formats
304 for L<DBIx::Class::InflateColumn::DateTime>.
306 =head1 IMAGE AND TEXT COLUMNS
308 See L</connect_call_blob_setup> for a L<DBIx::Class::Storage::DBI/connect_info>
309 setting you need to work with C<IMAGE> columns.
311 Due to limitations in L<DBD::Sybase> and this driver, it is only possible to
312 select one C<TEXT> or C<IMAGE> column at a time.
316 See L<DBIx::Class/CONTRIBUTORS>.
320 You may distribute this code under the same terms as Perl itself.