1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
use strict;
use warnings;
use Test::More;
BEGIN {
require DBIx::Class::Optional::Dependencies;
plan skip_all => 'Test needs ' . DBIx::Class::Optional::Dependencies->req_missing_for ('id_shortener')
unless DBIx::Class::Optional::Dependencies->req_ok_for ('id_shortener');
}
use Test::Exception;
use Data::Dumper::Concise;
use lib qw(t/lib);
use DBICTest ':DiffSQL';
use DBIx::Class::SQLMaker::Oracle;
#
# Offline test for connect_by
# ( without active database connection)
#
my @handle_tests = (
{
connect_by => { 'parentid' => { '-prior' => \'artistid' } },
stmt => '"parentid" = PRIOR artistid',
bind => [],
msg => 'Simple: "parentid" = PRIOR artistid',
},
{
connect_by => { 'parentid' => { '!=' => { '-prior' => { -ident => 'artistid' } } } },
stmt => '"parentid" != ( PRIOR "artistid" )',
bind => [],
msg => 'Simple: "parentid" != ( PRIOR "artistid" )',
},
# Examples from http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/queries003.htm
# CONNECT BY last_name != 'King' AND PRIOR employee_id = manager_id ...
{
connect_by => [
last_name => { '!=' => 'King' },
manager_id => { '-prior' => { -ident => 'employee_id' } },
],
stmt => '( "last_name" != ? OR "manager_id" = PRIOR "employee_id" )',
bind => ['King'],
msg => 'oracle.com example #1',
},
# CONNECT BY PRIOR employee_id = manager_id and
# PRIOR account_mgr_id = customer_id ...
{
connect_by => {
manager_id => { '-prior' => { -ident => 'employee_id' } },
customer_id => { '>', { '-prior' => \'account_mgr_id' } },
},
stmt => '( "customer_id" > ( PRIOR account_mgr_id ) AND "manager_id" = PRIOR "employee_id" )',
bind => [],
msg => 'oracle.com example #2',
},
# CONNECT BY NOCYCLE PRIOR employee_id = manager_id AND LEVEL <= 4;
# TODO: NOCYCLE parameter doesn't work
);
my $sqla_oracle = DBIx::Class::SQLMaker::Oracle->new( quote_char => '"', name_sep => '.' );
isa_ok($sqla_oracle, 'DBIx::Class::SQLMaker::Oracle');
for my $case (@handle_tests) {
my ( $stmt, @bind );
my $msg = sprintf("Offline: %s",
$case->{msg} || substr($case->{stmt},0,25),
);
lives_ok(
sub {
( $stmt, @bind ) = $sqla_oracle->_recurse_where( $case->{connect_by} );
is_same_sql_bind( $stmt, \@bind, $case->{stmt}, $case->{bind},$msg )
|| diag "Search term:\n" . Dumper $case->{connect_by};
}
,sprintf("lives is ok from '%s'",$msg));
}
is (
$sqla_oracle->_shorten_identifier('short_id'),
'short_id',
'_shorten_identifier for short id without keywords ok'
);
is (
$sqla_oracle->_shorten_identifier('short_id', [qw/ foo /]),
'short_id',
'_shorten_identifier for short id with one keyword ok'
);
is (
$sqla_oracle->_shorten_identifier('short_id', [qw/ foo bar baz /]),
'short_id',
'_shorten_identifier for short id with keywords ok'
);
is (
$sqla_oracle->_shorten_identifier('very_long_identifier_which_exceeds_the_30char_limit'),
'VryLngIdntfrWhchExc_72M8CIDTM7',
'_shorten_identifier without keywords ok',
);
is (
$sqla_oracle->_shorten_identifier('very_long_identifier_which_exceeds_the_30char_limit',[qw/ foo /]),
'Foo_72M8CIDTM7KBAUPXG48B22P4E',
'_shorten_identifier with one keyword ok',
);
is (
$sqla_oracle->_shorten_identifier('very_long_identifier_which_exceeds_the_30char_limit',[qw/ foo bar baz /]),
'FooBarBaz_72M8CIDTM7KBAUPXG48B',
'_shorten_identifier with keywords ok',
);
# test SQL generation for INSERT ... RETURNING
sub UREF { \do { my $x } };
$sqla_oracle->{bindtype} = 'columns';
for my $q ('', '"') {
local $sqla_oracle->{quote_char} = $q;
my ($sql, @bind) = $sqla_oracle->insert(
'artist',
{
'name' => 'Testartist',
},
{
'returning' => 'artistid',
'returning_container' => [],
},
);
is_same_sql_bind(
$sql, \@bind,
"INSERT INTO ${q}artist${q} (${q}name${q}) VALUES (?) RETURNING ${q}artistid${q} INTO ?",
[ [ name => 'Testartist' ], [ artistid => UREF ] ],
'sql_maker generates insert returning for one column'
);
($sql, @bind) = $sqla_oracle->insert(
'artist',
{
'name' => 'Testartist',
},
{
'returning' => \'artistid',
'returning_container' => [],
},
);
is_same_sql_bind(
$sql, \@bind,
"INSERT INTO ${q}artist${q} (${q}name${q}) VALUES (?) RETURNING artistid INTO ?",
[ [ name => 'Testartist' ], [ artistid => UREF ] ],
'sql_maker generates insert returning for one column'
);
($sql, @bind) = $sqla_oracle->insert(
'computed_column_test',
{
'a_timestamp' => '2010-05-26 18:22:00',
},
{
'returning' => [ 'id', 'a_computed_column', 'charfield' ],
'returning_container' => [],
},
);
is_same_sql_bind(
$sql, \@bind,
"INSERT INTO ${q}computed_column_test${q} (${q}a_timestamp${q}) VALUES (?) RETURNING ${q}id${q}, ${q}a_computed_column${q}, ${q}charfield${q} INTO ?, ?, ?",
[ [ a_timestamp => '2010-05-26 18:22:00' ], [ id => UREF ], [ a_computed_column => UREF ], [ charfield => UREF ] ],
'sql_maker generates insert returning for multiple columns'
);
}
done_testing;
|