use namespace::clean;
__PACKAGE__->sql_limit_dialect ('RowNum');
+__PACKAGE__->sql_quote_char ('"');
=head1 NAME
use mro 'c3';
__PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::Oracle');
+__PACKAGE__->datetime_parser_type('DateTime::Format::Oracle');
+
+sub _determine_supports_insert_returning {
+ my $self = shift;
+
+# TODO find out which version supports the RETURNING syntax
+# 8i has it and earlier docs are a 404 on oracle.com
+
+ return 1
+ if $self->_server_info->{normalized_dbms_version} >= 8.001;
+
+ return 0;
+}
+
+__PACKAGE__->_use_insert_returning_bound (1);
sub deployment_statements {
my $self = shift;;
# disable default bindtype
local $sql_maker->{bindtype} = 'normal';
-
# look up the correct sequence automatically
my ( $schema, $table ) = $source_name =~ /( (?:${ql})? \w+ (?:${qr})? ) \. ( (?:${ql})? \w+ (?:${qr})? )/x;
+
+ # if no explicit schema was requested - use the default schema (which in the case of Oracle is the db user)
+ $schema ||= uc( ($self->_dbi_connect_info||[])->[1] || '');
+
my ($sql, @bind) = $sql_maker->select (
'ALL_TRIGGERS',
[qw/TRIGGER_BODY TABLE_OWNER TRIGGER_NAME/],
}
sub _dbh_execute {
- my $self = shift;
- my ($dbh, $op, $extra_bind, $ident, $bind_attributes, @args) = @_;
+ my ($self, $dbh, $sql, @args) = @_;
my (@res, $tried);
- my $wantarray = wantarray();
+ my $want = wantarray;
my $next = $self->next::can;
do {
try {
- my $exec = sub { $self->$next($dbh, $op, $extra_bind, $ident, $bind_attributes, @args) };
+ my $exec = sub { $self->$next($dbh, $sql, @args) };
- if (!defined $wantarray) {
+ if (!defined $want) {
$exec->();
}
- elsif (! $wantarray) {
+ elsif (! $want) {
$res[0] = $exec->();
}
else {
if (! $tried and $_ =~ /ORA-01003/) {
# ORA-01003: no statement parsed (someone changed the table somehow,
# invalidating your cursor.)
- my ($sql, $bind) = $self->_prep_for_execute($op, $extra_bind, $ident, \@args);
delete $dbh->{CachedKids}{$sql};
}
else {
};
} while (! $tried++);
- return $wantarray ? @res : $res[0];
+ return wantarray ? @res : $res[0];
+}
+
+sub _dbh_execute_array {
+ #my ($self, $sth, $tuple_status, @extra) = @_;
+
+ # DBD::Oracle warns loudly on partial execute_array failures
+ local $_[1]->{PrintWarn} = 0;
+
+ shift->next::method(@_);
}
=head2 get_autoinc_seq
This sets the proper DateTime::Format module for use with
L<DBIx::Class::InflateColumn::DateTime>.
-=cut
-
-sub datetime_parser_type { return "DateTime::Format::Oracle"; }
-
=head2 connect_call_datetime_setup
Used as:
);
}
-=head2 source_bind_attributes
-
-Handle LOB types in Oracle. Under a certain size (4k?), you can get away
-with the driver assuming your input is the deprecated LONG type if you
-encode it as a hex string. That ain't gonna fly at larger values, where
-you'll discover you have to do what this does.
-
-This method had to be overridden because we need to set ora_field to the
-actual column, and that isn't passed to the call (provided by Storage) to
-bind_attribute_by_data_type.
-
-According to L<DBD::Oracle>, the ora_field isn't always necessary, but
-adding it doesn't hurt, and will save your bacon if you're modifying a
-table with more than one LOB column.
-
-=cut
-
-sub source_bind_attributes
-{
- require DBD::Oracle;
- my $self = shift;
- my($source) = @_;
-
- my %bind_attributes;
-
- foreach my $column ($source->columns) {
- my $data_type = $source->column_info($column)->{data_type}
- or next;
+### Note originally by Ron "Quinn" Straight <quinnfazigu@gmail.org>
+### http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/DBIx-Class.git;a=commitdiff;h=5db2758de644d53e07cd3e05f0e9037bf40116fc
+#
+# Handle LOB types in Oracle. Under a certain size (4k?), you can get away
+# with the driver assuming your input is the deprecated LONG type if you
+# encode it as a hex string. That ain't gonna fly at larger values, where
+# you'll discover you have to do what this does.
+#
+# This method had to be overridden because we need to set ora_field to the
+# actual column, and that isn't passed to the call (provided by Storage) to
+# bind_attribute_by_data_type.
+#
+# According to L<DBD::Oracle>, the ora_field isn't always necessary, but
+# adding it doesn't hurt, and will save your bacon if you're modifying a
+# table with more than one LOB column.
+#
+sub _dbi_attrs_for_bind {
+ my ($self, $ident, $bind) = @_;
+ my $attrs = $self->next::method($ident, $bind);
+
+ for my $i (0 .. $#$attrs) {
+ if (keys %{$attrs->[$i]||{}} and my $col = $bind->[$i][0]{dbic_colname}) {
+ $attrs->[$i]{ora_field} = $col;
+ }
+ }
- my %column_bind_attrs = $self->bind_attribute_by_data_type($data_type);
+ $attrs;
+}
- if ($data_type =~ /^[BC]LOB$/i) {
- if ($DBD::Oracle::VERSION eq '1.23') {
- $self->throw_exception(
-"BLOB/CLOB support in DBD::Oracle == 1.23 is broken, use an earlier or later ".
-"version.\n\nSee: https://rt.cpan.org/Public/Bug/Display.html?id=46016\n"
- );
- }
+my $dbd_loaded;
+sub bind_attribute_by_data_type {
+ my ($self, $dt) = @_;
+
+ $dbd_loaded ||= do {
+ require DBD::Oracle;
+ if ($DBD::Oracle::VERSION eq '1.23') {
+ $self->throw_exception(
+ "BLOB/CLOB support in DBD::Oracle == 1.23 is broken, use an earlier or later ".
+ "version.\n\nSee: https://rt.cpan.org/Public/Bug/Display.html?id=46016\n"
+ );
+ }
+ 1;
+ };
- $column_bind_attrs{'ora_type'} = uc($data_type) eq 'CLOB'
+ if ($self->_is_lob_type($dt)) {
+ return {
+ ora_type => $self->_is_text_lob_type($dt)
? DBD::Oracle::ORA_CLOB()
: DBD::Oracle::ORA_BLOB()
- ;
- $column_bind_attrs{'ora_field'} = $column;
- }
-
- $bind_attributes{$column} = \%column_bind_attrs;
+ };
}
-
- return \%bind_attributes;
}
sub _svp_begin {
my $alias = $self->next::method(@_);
- return $self->sql_maker->_shorten_identifier($alias, [$relname]);
+ # we need to shorten here in addition to the shortening in SQLA itself,
+ # since the final relnames are a crucial for the join optimizer
+ return $self->sql_maker->_shorten_identifier($alias);
}
=head2 with_deferred_fk_checks