Make Access inner joins 'INNER JOIN' to avoid JOIN syntax errors
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Optional / Dependencies.pm
CommitLineData
8057ed01 1package DBIx::Class::Optional::Dependencies;
2
3use warnings;
4use strict;
5
9c1700e3 6use Carp ();
fb39747c 7
8# NO EXTERNAL NON-5.8.1 CORE DEPENDENCIES EVER (e.g. C::A::G)
8057ed01 9# This module is to be loaded by Makefile.PM on a pristine system
10
f6b26571 11# POD is generated automatically by calling _gen_pod from the
12# Makefile.PL in $AUTHOR mode
13
2a2a7b23 14my $json_any = {
15 'JSON::Any' => '1.22',
16};
17
2b48ebff 18my $moose_basic = {
68de9438 19 'Moose' => '0.98',
20 'MooseX::Types' => '0.21',
21};
22
23my $replicated = {
24 %$moose_basic,
2b48ebff 25};
26
ebcd0e4f 27my $admin_basic = {
28 %$moose_basic,
2a2a7b23 29 %$json_any,
68de9438 30 'MooseX::Types::Path::Class' => '0.05',
31 'MooseX::Types::JSON' => '0.02',
68de9438 32 'namespace::autoclean' => '0.09',
33};
34
35my $datetime_basic = {
36 'DateTime' => '0.55',
37 'DateTime::Format::Strptime' => '1.2',
ebcd0e4f 38};
39
c7d50a7d 40my $id_shortener = {
41 'Math::BigInt' => '1.89',
42 'Math::Base36' => '0.07',
43};
44
be68095d 45my $rdbms_sqlite = {
46 'DBD::SQLite' => '0',
47};
48my $rdbms_pg = {
49 'DBD::Pg' => '0',
50};
51my $rdbms_mssql_odbc = {
52 'DBD::ODBC' => '0',
53};
54my $rdbms_mssql_sybase = {
55 'DBD::Sybase' => '0',
56};
56dca25f 57my $rdbms_mssql_ado = {
58 'DBD::ADO' => '0',
59};
726c8f65 60my $rdbms_msaccess_odbc = {
61 'DBD::ODBC' => '0',
62};
63my $rdbms_msaccess_ado = {
64 'DBD::ADO' => '0',
65};
be68095d 66my $rdbms_mysql = {
67 'DBD::mysql' => '0',
68};
69my $rdbms_oracle = {
70 'DBD::Oracle' => '0',
71 %$id_shortener,
72};
73my $rdbms_ase = {
74 'DBD::Sybase' => '0',
75};
76my $rdbms_db2 = {
77 'DBD::DB2' => '0',
78};
e02b39b4 79my $rdbms_firebird_odbc = {
80 'DBD::ODBC' => '0',
81};
be68095d 82
8057ed01 83my $reqs = {
84 dist => {
85 #'Module::Install::Pod::Inherit' => '0.01',
86 },
87
88 replicated => {
68de9438 89 req => $replicated,
f6b26571 90 pod => {
91 title => 'Storage::Replicated',
92 desc => 'Modules required for L<DBIx::Class::Storage::DBI::Replicated>',
93 },
8057ed01 94 },
95
68de9438 96 test_replicated => {
97 req => {
98 %$replicated,
99 'Test::Moose' => '0',
100 },
101 },
102
103
8057ed01 104 admin => {
2b48ebff 105 req => {
ebcd0e4f 106 %$admin_basic,
107 },
108 pod => {
109 title => 'DBIx::Class::Admin',
110 desc => 'Modules required for the DBIx::Class administrative library',
111 },
112 },
113
a4a02f15 114 admin_script => {
ebcd0e4f 115 req => {
2b48ebff 116 %$moose_basic,
ebcd0e4f 117 %$admin_basic,
2b48ebff 118 'Getopt::Long::Descriptive' => '0.081',
2b48ebff 119 'Text::CSV' => '1.16',
120 },
e144415f 121 pod => {
122 title => 'dbicadmin',
123 desc => 'Modules required for the CLI DBIx::Class interface dbicadmin',
124 },
8057ed01 125 },
126
127 deploy => {
f6b26571 128 req => {
9e34d554 129 'SQL::Translator' => '0.11006',
f6b26571 130 },
131 pod => {
132 title => 'Storage::DBI::deploy()',
c7d50a7d 133 desc => 'Modules required for L<DBIx::Class::Storage::DBI/deploy> and L<DBIx::Class::Storage::DBI/deployment_statements>',
f6b26571 134 },
8057ed01 135 },
136
c7d50a7d 137 id_shortener => {
138 req => $id_shortener,
139 },
140
0d374214 141 test_component_accessor => {
142 req => {
143 'Class::Unload' => '0.07',
144 },
145 },
146
a109c954 147 test_pod => {
f6b26571 148 req => {
14d17d71 149 'Test::Pod' => '1.41',
a109c954 150 },
151 },
152
153 test_podcoverage => {
154 req => {
f6b26571 155 'Test::Pod::Coverage' => '1.08',
156 'Pod::Coverage' => '0.20',
a109c954 157 },
158 },
159
160 test_notabs => {
161 req => {
d146b340 162 'Test::NoTabs' => '0.9',
a109c954 163 },
164 },
165
166 test_eol => {
167 req => {
d146b340 168 'Test::EOL' => '0.6',
f6b26571 169 },
8057ed01 170 },
171
2a2a7b23 172 test_prettydebug => {
173 req => $json_any,
174 },
175
226d1c35 176 test_leaks => {
f6b26571 177 req => {
f6b26571 178 'Test::Memory::Cycle' => '0',
179 'Devel::Cycle' => '1.10',
a109c954 180 },
181 },
f6b26571 182
68de9438 183 test_dt => {
184 req => $datetime_basic,
185 },
186
187 test_dt_sqlite => {
a109c954 188 req => {
68de9438 189 %$datetime_basic,
f6b26571 190 # t/36datetime.t
191 # t/60core.t
192 'DateTime::Format::SQLite' => '0',
68de9438 193 },
194 },
f6b26571 195
68de9438 196 test_dt_mysql => {
197 req => {
198 %$datetime_basic,
9c92bb1c 199 # t/inflate/datetime_mysql.t
200 # (doesn't need Mysql itself)
68de9438 201 'DateTime::Format::MySQL' => '0',
202 },
203 },
9c92bb1c 204
68de9438 205 test_dt_pg => {
206 req => {
207 %$datetime_basic,
9c92bb1c 208 # t/inflate/datetime_pg.t
209 # (doesn't need PG itself)
ab35aeab 210 'DateTime::Format::Pg' => '0.16004',
f6b26571 211 },
8057ed01 212 },
213
68de9438 214 test_cdbicompat => {
f6b26571 215 req => {
216 'DBIx::ContextualFetch' => '0',
217 'Class::DBI::Plugin::DeepAbstractSearch' => '0',
218 'Class::Trigger' => '0',
219 'Time::Piece::MySQL' => '0',
220 'Clone' => '0',
221 'Date::Simple' => '3.03',
222 },
8057ed01 223 },
224
be68095d 225 # this is just for completeness as SQLite
226 # is a core dep of DBIC for testing
227 rdbms_sqlite => {
228 req => {
229 %$rdbms_sqlite,
230 },
231 pod => {
232 title => 'SQLite support',
233 desc => 'Modules required to connect to SQLite',
234 },
235 },
236
237 rdbms_pg => {
238 req => {
239 %$rdbms_pg,
240 },
241 pod => {
242 title => 'PostgreSQL support',
243 desc => 'Modules required to connect to PostgreSQL',
244 },
245 },
246
247 rdbms_mssql_odbc => {
248 req => {
249 %$rdbms_mssql_odbc,
250 },
251 pod => {
252 title => 'MSSQL support via DBD::ODBC',
253 desc => 'Modules required to connect to MSSQL via DBD::ODBC',
254 },
255 },
256
257 rdbms_mssql_sybase => {
258 req => {
259 %$rdbms_mssql_sybase,
260 },
261 pod => {
262 title => 'MSSQL support via DBD::Sybase',
56dca25f 263 desc => 'Modules required to connect to MSSQL via DBD::Sybase',
264 },
265 },
266
267 rdbms_mssql_ado => {
268 req => {
269 %$rdbms_mssql_ado,
270 },
271 pod => {
272 title => 'MSSQL support via DBD::ADO (Windows only)',
273 desc => 'Modules required to connect to MSSQL via DBD::ADO. This particular DBD is available on Windows only',
be68095d 274 },
275 },
276
726c8f65 277 rdbms_msaccess_odbc => {
278 req => {
279 %$rdbms_msaccess_odbc,
280 },
281 pod => {
282 title => 'MS Access support via DBD::ODBC',
283 desc => 'Modules required to connect to MS Access via DBD::ODBC',
284 },
285 },
286
287 rdbms_msaccess_ado => {
288 req => {
289 %$rdbms_msaccess_ado,
290 },
291 pod => {
292 title => 'MS Access support via DBD::ADO (Windows only)',
293 desc => 'Modules required to connect to MS Access via DBD::ADO. This particular DBD is available on Windows only',
294 },
295 },
296
be68095d 297 rdbms_mysql => {
298 req => {
299 %$rdbms_mysql,
300 },
301 pod => {
302 title => 'MySQL support',
303 desc => 'Modules required to connect to MySQL',
304 },
305 },
306
307 rdbms_oracle => {
308 req => {
309 %$rdbms_oracle,
310 },
311 pod => {
312 title => 'Oracle support',
313 desc => 'Modules required to connect to Oracle',
314 },
315 },
316
317 rdbms_ase => {
318 req => {
319 %$rdbms_ase,
320 },
321 pod => {
322 title => 'Sybase ASE support',
323 desc => 'Modules required to connect to Sybase ASE',
324 },
325 },
326
327 rdbms_db2 => {
328 req => {
329 %$rdbms_db2,
330 },
331 pod => {
332 title => 'DB2 support',
333 desc => 'Modules required to connect to DB2',
334 },
335 },
336
337# the order does matter because the rdbms support group might require
338# a different version that the test group
68de9438 339 test_rdbms_pg => {
f6b26571 340 req => {
341 $ENV{DBICTEST_PG_DSN}
342 ? (
be68095d 343 %$rdbms_pg,
f6b26571 344 'Sys::SigAction' => '0',
345 'DBD::Pg' => '2.009002',
f6b26571 346 ) : ()
347 },
8057ed01 348 },
349
afae8507 350 test_rdbms_mssql_odbc => {
351 req => {
352 $ENV{DBICTEST_MSSQL_ODBC_DSN}
353 ? (
be68095d 354 %$rdbms_mssql_odbc,
afae8507 355 ) : ()
356 },
357 },
358
56dca25f 359 test_rdbms_mssql_ado => {
360 req => {
361 $ENV{DBICTEST_MSSQL_ADO_DSN}
362 ? (
363 %$rdbms_mssql_ado,
364 ) : ()
365 },
366 },
367
afae8507 368 test_rdbms_mssql_sybase => {
369 req => {
370 $ENV{DBICTEST_MSSQL_DSN}
371 ? (
be68095d 372 %$rdbms_mssql_sybase,
afae8507 373 ) : ()
374 },
375 },
376
726c8f65 377 test_rdbms_msaccess_odbc => {
378 req => {
379 $ENV{DBICTEST_MSACCESS_ODBC_DSN}
380 ? (
381 %$rdbms_msaccess_odbc,
382 %$datetime_basic,
383 'Data::GUID' => '0',
384 ) : ()
385 },
386 },
387
388 test_rdbms_msaccess_ado => {
389 req => {
390 $ENV{DBICTEST_MSACCESS_ADO_DSN}
391 ? (
392 %$rdbms_msaccess_ado,
393 %$datetime_basic,
394 'Data::GUID' => 0,
395 ) : ()
396 },
397 },
398
68de9438 399 test_rdbms_mysql => {
f6b26571 400 req => {
401 $ENV{DBICTEST_MYSQL_DSN}
402 ? (
be68095d 403 %$rdbms_mysql,
f6b26571 404 ) : ()
405 },
8057ed01 406 },
407
68de9438 408 test_rdbms_oracle => {
f6b26571 409 req => {
410 $ENV{DBICTEST_ORA_DSN}
411 ? (
be68095d 412 %$rdbms_oracle,
f6b26571 413 'DateTime::Format::Oracle' => '0',
e1b7e9b4 414 'DBD::Oracle' => '1.24',
f6b26571 415 ) : ()
416 },
8057ed01 417 },
418
68de9438 419 test_rdbms_ase => {
f6b26571 420 req => {
421 $ENV{DBICTEST_SYBASE_DSN}
422 ? (
be68095d 423 %$rdbms_ase,
f6b26571 424 ) : ()
425 },
8057ed01 426 },
427
68de9438 428 test_rdbms_db2 => {
f58a165c 429 req => {
430 $ENV{DBICTEST_DB2_DSN}
431 ? (
be68095d 432 %$rdbms_db2,
f58a165c 433 ) : ()
434 },
435 },
436
e02b39b4 437 test_rdbms_firebird_odbc => {
438 req => {
439 $ENV{DBICTEST_FIREBIRD_ODBC_DSN}
440 ? (
441 %$rdbms_firebird_odbc,
442 ) : ()
443 },
444 },
445
42168332 446 test_memcached => {
447 req => {
448 $ENV{DBICTEST_MEMCACHED}
449 ? (
450 'Cache::Memcached' => 0,
451 ) : ()
452 },
453 },
454
8057ed01 455};
456
f6b26571 457
fb39747c 458sub req_list_for {
459 my ($class, $group) = @_;
460
9c1700e3 461 Carp::croak "req_list_for() expects a requirement group name"
fb39747c 462 unless $group;
463
f6b26571 464 my $deps = $reqs->{$group}{req}
9c1700e3 465 or Carp::croak "Requirement group '$group' does not exist";
fb39747c 466
467 return { %$deps };
468}
469
470
471our %req_availability_cache;
472sub req_ok_for {
473 my ($class, $group) = @_;
474
9c1700e3 475 Carp::croak "req_ok_for() expects a requirement group name"
fb39747c 476 unless $group;
477
d8799bab 478 return $class->_check_deps($group)->{status};
fb39747c 479}
480
481sub req_missing_for {
482 my ($class, $group) = @_;
483
9c1700e3 484 Carp::croak "req_missing_for() expects a requirement group name"
fb39747c 485 unless $group;
486
d8799bab 487 return $class->_check_deps($group)->{missing};
fb39747c 488}
489
490sub req_errorlist_for {
491 my ($class, $group) = @_;
492
9c1700e3 493 Carp::croak "req_errorlist_for() expects a requirement group name"
fb39747c 494 unless $group;
495
d8799bab 496 return $class->_check_deps($group)->{errorlist};
fb39747c 497}
498
499sub _check_deps {
500 my ($class, $group) = @_;
501
d8799bab 502 return $req_availability_cache{$group} ||= do {
503
504 my $deps = $class->req_list_for ($group);
505
506 my %errors;
507 for my $mod (keys %$deps) {
508 my $req_line = "require $mod;";
509 if (my $ver = $deps->{$mod}) {
510 $req_line .= "$mod->VERSION($ver);";
511 }
512
513 eval $req_line;
514
515 $errors{$mod} = $@ if $@;
516 }
517
518 my $res;
fb39747c 519
d8799bab 520 if (keys %errors) {
521 my $missing = join (', ', map { $deps->{$_} ? "$_ >= $deps->{$_}" : $_ } (sort keys %errors) );
522 $missing .= " (see $class for details)" if $reqs->{$group}{pod};
70c28808 523 $missing .= "\n";
d8799bab 524 $res = {
525 status => 0,
526 errorlist => \%errors,
527 missing => $missing,
528 };
fb39747c 529 }
530 else {
d8799bab 531 $res = {
532 status => 1,
533 errorlist => {},
534 missing => '',
535 };
fb39747c 536 }
537
d8799bab 538 $res;
539 };
fb39747c 540}
541
e3fc11e1 542sub req_group_list {
543 return { map { $_ => { %{ $reqs->{$_}{req} || {} } } } (keys %$reqs) };
544}
545
546# This is to be called by the author only (automatically in Makefile.PL)
f6b26571 547sub _gen_pod {
ccebe1f1 548 my ($class, $distver) = @_;
31fa1764 549
af4ac504 550 my $modfn = __PACKAGE__ . '.pm';
551 $modfn =~ s/\:\:/\//g;
f6b26571 552
31fa1764 553 my $podfn = __FILE__;
554 $podfn =~ s/\.pm$/\.pod/;
555
ccebe1f1 556 $distver ||=
31fa1764 557 eval { require DBIx::Class; DBIx::Class->VERSION; }
558 ||
ccebe1f1 559 die
31fa1764 560"\n\n---------------------------------------------------------------------\n" .
561'Unable to load core DBIx::Class module to determine current version, '.
562'possibly due to missing dependencies. Author-mode autodocumentation ' .
563"halted\n\n" . $@ .
564"\n\n---------------------------------------------------------------------\n"
31fa1764 565 ;
566
e3fc11e1 567 my $sqltver = $class->req_list_for ('deploy')->{'SQL::Translator'}
568 or die "Hrmm? No sqlt dep?";
7e3dc46f 569
f6b26571 570 my @chunks = (
d8799bab 571 <<'EOC',
af4ac504 572#########################################################################
573##################### A U T O G E N E R A T E D ########################
574#########################################################################
575#
576# The contents of this POD file are auto-generated. Any changes you make
577# will be lost. If you need to change the generated text edit _gen_pod()
578# at the end of $modfn
579#
580EOC
f6b26571 581 '=head1 NAME',
7e3dc46f 582 "$class - Optional module dependency specifications (for module authors)",
e3fc11e1 583 '=head1 SYNOPSIS',
d8799bab 584 <<"EOS",
7e3dc46f 585Somewhere in your build-file (e.g. L<Module::Install>'s Makefile.PL):
586
587 ...
588
589 configure_requires 'DBIx::Class' => '$distver';
590
591 require $class;
592
be68095d 593 my \$deploy_deps = $class->req_list_for('deploy');
7e3dc46f 594
595 for (keys %\$deploy_deps) {
596 requires \$_ => \$deploy_deps->{\$_};
597 }
598
599 ...
600
601Note that there are some caveats regarding C<configure_requires()>, more info
602can be found at L<Module::Install/configure_requires>
603EOS
f6b26571 604 '=head1 DESCRIPTION',
605 <<'EOD',
606Some of the less-frequently used features of L<DBIx::Class> have external
607module dependencies on their own. In order not to burden the average user
608with modules he will never use, these optional dependencies are not included
609in the base Makefile.PL. Instead an exception with a descriptive message is
610thrown when a specific feature is missing one or several modules required for
611its operation. This module is the central holding place for the current list
7e3dc46f 612of such dependencies, for DBIx::Class core authors, and DBIx::Class extension
613authors alike.
f6b26571 614EOD
615 '=head1 CURRENT REQUIREMENT GROUPS',
616 <<'EOD',
617Dependencies are organized in C<groups> and each group can list one or more
618required modules, with an optional minimum version (or 0 for any version).
ecb68746 619The group name can be used in the
f6b26571 620EOD
621 );
622
623 for my $group (sort keys %$reqs) {
624 my $p = $reqs->{$group}{pod}
625 or next;
626
627 my $modlist = $reqs->{$group}{req}
628 or next;
629
630 next unless keys %$modlist;
631
632 push @chunks, (
633 "=head2 $p->{title}",
634 "$p->{desc}",
635 '=over',
636 ( map { "=item * $_" . ($modlist->{$_} ? " >= $modlist->{$_}" : '') } (sort keys %$modlist) ),
637 '=back',
638 "Requirement group: B<$group>",
639 );
640 }
641
642 push @chunks, (
643 '=head1 METHODS',
e3fc11e1 644 '=head2 req_group_list',
645 '=over',
d8799bab 646 '=item Arguments: none',
e3fc11e1 647 '=item Returns: \%list_of_requirement_groups',
648 '=back',
d8799bab 649 <<'EOD',
e3fc11e1 650This method should be used by DBIx::Class packagers, to get a hashref of all
651dependencies keyed by dependency group. Each key (group name) can be supplied
652to one of the group-specific methods below.
653EOD
654
f6b26571 655 '=head2 req_list_for',
656 '=over',
657 '=item Arguments: $group_name',
658 '=item Returns: \%list_of_module_version_pairs',
659 '=back',
d8799bab 660 <<'EOD',
f6b26571 661This method should be used by DBIx::Class extension authors, to determine the
7e3dc46f 662version of modules a specific feature requires in the B<current> version of
e3fc11e1 663DBIx::Class. See the L</SYNOPSIS> for a real-world
7e3dc46f 664example.
f6b26571 665EOD
666
667 '=head2 req_ok_for',
668 '=over',
669 '=item Arguments: $group_name',
670 '=item Returns: 1|0',
671 '=back',
d8799bab 672 <<'EOD',
673Returns true or false depending on whether all modules required by
674C<$group_name> are present on the system and loadable.
675EOD
f6b26571 676
677 '=head2 req_missing_for',
678 '=over',
679 '=item Arguments: $group_name',
680 '=item Returns: $error_message_string',
681 '=back',
d8799bab 682 <<"EOD",
f6b26571 683Returns a single line string suitable for inclusion in larger error messages.
684This method would normally be used by DBIx::Class core-module author, to
685indicate to the user that he needs to install specific modules before he will
686be able to use a specific feature.
687
e3fc11e1 688For example if some of the requirements for C<deploy> are not available,
689the returned string could look like:
f6b26571 690
e3fc11e1 691 SQL::Translator >= $sqltver (see $class for details)
f6b26571 692
693The author is expected to prepend the necessary text to this message before
694returning the actual error seen by the user.
695EOD
696
697 '=head2 req_errorlist_for',
698 '=over',
699 '=item Arguments: $group_name',
700 '=item Returns: \%list_of_loaderrors_per_module',
701 '=back',
702 <<'EOD',
703Returns a hashref containing the actual errors that occured while attempting
704to load each module in the requirement group.
705EOD
fb8ae353 706 '=head1 AUTHOR',
707 'See L<DBIx::Class/CONTRIBUTORS>.',
708 '=head1 LICENSE',
709 'You may distribute this code under the same terms as Perl itself',
f6b26571 710 );
711
9c1700e3 712 open (my $fh, '>', $podfn) or Carp::croak "Unable to write to $podfn: $!";
f6b26571 713 print $fh join ("\n\n", @chunks);
714 close ($fh);
715}
716
8057ed01 7171;