Institute a central "load this first in testing" package
[dbsrgits/DBIx-Class.git] / t / storage / quote_names.t
1 BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) }
2
3 use strict;
4 use warnings;
5 use Test::More;
6 use Data::Dumper::Concise;
7 use Try::Tiny;
8
9 use DBICTest;
10
11 my %expected = (
12   'DBIx::Class::Storage::DBI'                    =>
13       # no default quote_char
14     {                             name_sep => '.' },
15
16   'DBIx::Class::Storage::DBI::MSSQL'             =>
17     { quote_char => [ '[', ']' ], name_sep => '.' },
18
19   'DBIx::Class::Storage::DBI::DB2'               =>
20     { quote_char => '"',          name_sep => '.' },
21
22   'DBIx::Class::Storage::DBI::Informix'          =>
23     { quote_char => '"',          name_sep => '.' },
24
25   'DBIx::Class::Storage::DBI::InterBase'         =>
26     { quote_char => '"',          name_sep => '.' },
27
28   'DBIx::Class::Storage::DBI::mysql'             =>
29     { quote_char => '`',          name_sep => '.' },
30
31   'DBIx::Class::Storage::DBI::Pg'             =>
32     { quote_char => '"',          name_sep => '.' },
33
34   'DBIx::Class::Storage::DBI::ODBC::ACCESS'      =>
35     { quote_char => [ '[', ']' ], name_sep => '.' },
36
37 # Not testing this one, it's a pain.
38 #  'DBIx::Class::Storage::DBI::ODBC::DB2_400_SQL' =>
39 #    { quote_char => '"',          name_sep => qr/must be connected/ },
40
41   'DBIx::Class::Storage::DBI::Oracle::Generic'   =>
42     { quote_char => '"',          name_sep => '.' },
43
44   'DBIx::Class::Storage::DBI::SQLAnywhere'       =>
45     { quote_char => '"',          name_sep => '.' },
46
47   'DBIx::Class::Storage::DBI::SQLite'            =>
48     { quote_char => '"',          name_sep => '.' },
49
50   'DBIx::Class::Storage::DBI::Sybase::ASE'       =>
51     { quote_char => [ '[', ']' ], name_sep => '.' },
52 );
53
54 for my $class (keys %expected) { SKIP: {
55   eval "require ${class}"
56     or skip "Skipping test of quotes for $class due to missing dependencies", 1;
57
58   my $mapping = $expected{$class};
59   my ($quote_char, $name_sep) = @$mapping{qw/quote_char name_sep/};
60   my $instance = $class->new;
61
62   my $quote_char_text = dumper($quote_char);
63
64   if (exists $mapping->{quote_char}) {
65     is_deeply $instance->sql_quote_char, $quote_char,
66       "sql_quote_char for $class is $quote_char_text";
67   }
68
69   is $instance->sql_name_sep, $name_sep,
70     "sql_name_sep for $class is '$name_sep'";
71 }}
72
73 # Try quote_names with available DBs.
74
75 # Env var to base class mapping, these are the DBs I actually have.
76 # the SQLITE is a fake memory dsn
77 local $ENV{DBICTEST_SQLITE_DSN} = 'dbi:SQLite::memory:';
78 my %dbs = (
79   SQLITE           => 'DBIx::Class::Storage::DBI::SQLite',
80   ORA              => 'DBIx::Class::Storage::DBI::Oracle::Generic',
81   PG               => 'DBIx::Class::Storage::DBI::Pg',
82   MYSQL            => 'DBIx::Class::Storage::DBI::mysql',
83   DB2              => 'DBIx::Class::Storage::DBI::DB2',
84   SYBASE           => 'DBIx::Class::Storage::DBI::Sybase::ASE',
85   SQLANYWHERE      => 'DBIx::Class::Storage::DBI::SQLAnywhere',
86   SQLANYWHERE_ODBC => 'DBIx::Class::Storage::DBI::SQLAnywhere',
87   FIREBIRD         => 'DBIx::Class::Storage::DBI::InterBase',
88   FIREBIRD_ODBC    => 'DBIx::Class::Storage::DBI::InterBase',
89   INFORMIX         => 'DBIx::Class::Storage::DBI::Informix',
90   MSSQL_ODBC       => 'DBIx::Class::Storage::DBI::MSSQL',
91 );
92
93 # lie that we already locked stuff - the tests below do not touch anything
94 # unless we are under travis, where the OOM killers reign and things are rough
95 $ENV{DBICTEST_LOCK_HOLDER} = -1
96   unless DBICTest::RunMode->is_ci;
97
98 # Make sure oracle is tried last - some clients (e.g. 10.2) have symbol
99 # clashes with libssl, and will segfault everything coming after them
100 for my $db (sort {
101     $a eq 'ORA' ? 1
102   : $b eq 'ORA' ? -1
103   : $a cmp $b
104 } keys %dbs) {
105   my ($dsn, $user, $pass) = map $ENV{"DBICTEST_${db}_$_"}, qw/DSN USER PASS/;
106
107   next unless $dsn;
108
109   my $schema;
110
111   my $sql_maker = try {
112     $schema = DBICTest::Schema->connect($dsn, $user, $pass, {
113       quote_names => 1
114     });
115     $schema->storage->ensure_connected;
116     $schema->storage->sql_maker;
117   } || next;
118
119   my ($exp_quote_char, $exp_name_sep) =
120     @{$expected{$dbs{$db}}}{qw/quote_char name_sep/};
121
122   my ($quote_char_text, $name_sep_text) = map { dumper($_) }
123     ($exp_quote_char, $exp_name_sep);
124
125   is_deeply $sql_maker->quote_char,
126     $exp_quote_char,
127     "$db quote_char with quote_names => 1 is $quote_char_text";
128
129
130   is $sql_maker->name_sep,
131     $exp_name_sep,
132     "$db name_sep with quote_names => 1 is $name_sep_text";
133
134   # if something was produced - it better be quoted
135   if (
136     # the SQLT producer has no idea what quotes are :/
137     ! grep { $db eq $_ } qw( SYBASE DB2 )
138       and
139     my $ddl = try { $schema->deployment_statements }
140   ) {
141     my $quoted_artist = $sql_maker->_quote('artist');
142
143     like ($ddl, qr/^CREATE\s+TABLE\s+\Q$quoted_artist/msi, "$db DDL contains expected quoted table name");
144   }
145 }
146
147 done_testing;
148
149 sub dumper {
150   my $val = shift;
151
152   my $dd = DumperObject;
153   $dd->Indent(0);
154   return $dd->Values([ $val ])->Dump;
155 }
156
157 1;