Fixor borked docs (we already test for this in t/66-postgres-dbi-parser.t)
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Parser / DBI.pm
CommitLineData
6a9f7bae 1package SQL::Translator::Parser::DBI;
2
6a9f7bae 3=head1 NAME
4
5SQL::Translator::Parser::DBI - "parser" for DBI handles
6
7=head1 SYNOPSIS
8
9 use DBI;
10 use SQL::Translator;
11
ea93df61 12 my $dbh = DBI->connect('dsn', 'user', 'pass',
90e373b0 13 {
14 RaiseError => 1,
15 FetchHashKeyName => 'NAME_lc',
16 }
17 );
6a9f7bae 18
19 my $translator = SQL::Translator->new(
20 parser => 'DBI',
6a84bf09 21 parser_args => {
22 dbh => $dbh,
23 },
6a9f7bae 24 );
25
26Or:
27
28 use SQL::Translator;
29
90e373b0 30 my $translator = SQL::Translator->new(
31 parser => 'DBI',
32 parser_args => {
33 dsn => 'dbi:mysql:FOO',
34 db_user => 'guest',
35 db_password => 'password',
36 }
6a9f7bae 37 );
38
39=head1 DESCRIPTION
40
ea93df61 41This parser accepts an open database handle (or the arguments to create
42one) and queries the database directly for the information.
6a9f7bae 43
44The following are acceptable arguments:
45
05078e2c 46=over 4
6a9f7bae 47
48=item * dbh
49
ea93df61 50An open DBI database handle. NB: Be sure to create the database with the
51"FetchHashKeyName => 'NAME_lc'" option as all the DBI parsers expect
90e373b0 52lowercased column names.
6a9f7bae 53
54=item * dsn
55
56The DSN to use for connecting to a database.
57
58=item * db_user
59
60The user name to use for connecting to a database.
61
62=item * db_password
63
64The password to use for connecting to a database.
65
66=back
67
05078e2c 68There is no need to specify which type of database you are querying as
69this is determined automatically by inspecting $dbh->{'Driver'}{'Name'}.
70If a parser exists for your database, it will be used automatically;
71if not, the code will fail automatically (and you can write the parser
ea93df61 72and contribute it to the project!).
05078e2c 73
74Currently parsers exist for the following databases:
75
76=over 4
77
78=item * MySQL
79
80=item * SQLite
81
82=item * Sybase
83
84=item * PostgreSQL (still experimental)
85
86=back
87
88Most of these parsers are able to query the database directly for the
89structure rather than parsing a text file. For large schemas, this is
90probably orders of magnitude faster than traditional parsing (which
91uses Parse::RecDescent, an amazing module but really quite slow).
92
93Though no Oracle parser currently exists, it would be fairly easy to
94query an Oracle database directly by using DDL::Oracle to generate a
95DDL for the schema and then using the normal Oracle parser on this.
96Perhaps future versions of SQL::Translator will include the ability to
97query Oracle directly and skip the parsing of a text file, too.
98
6a9f7bae 99=cut
100
6a9f7bae 101use strict;
f27f9229 102use warnings;
6a9f7bae 103use DBI;
0c04c5a2 104our @EXPORT;
105our $VERSION = '1.59';
6a9f7bae 106
107use constant DRIVERS => {
05078e2c 108 mysql => 'MySQL',
461c1a96 109 odbc => 'SQLServer',
aaac0589 110 oracle => 'Oracle',
111 pg => 'PostgreSQL',
05078e2c 112 sqlite => 'SQLite',
113 sybase => 'Sybase',
69dad5b9 114 pg => 'PostgreSQL',
115 db2 => 'DB2',
6a9f7bae 116};
117
118use Exporter;
05078e2c 119
120use SQL::Translator::Utils qw(debug);
121
6a9f7bae 122use base qw(Exporter);
123@EXPORT = qw(parse);
124
125#
126# Passed a SQL::Translator instance and a string containing the data
127#
128sub parse {
129 my ( $tr, $data ) = @_;
130
6a9f7bae 131 my $args = $tr->parser_args;
132 my $dbh = $args->{'dbh'};
133 my $dsn = $args->{'dsn'};
134 my $db_user = $args->{'db_user'};
135 my $db_password = $args->{'db_password'};
136
c3919fdd 137 my $dbh_is_local;
6a9f7bae 138 unless ( $dbh ) {
139 die 'No DSN' unless $dsn;
ea93df61 140 $dbh = DBI->connect( $dsn, $db_user, $db_password,
9d53a6a2 141 {
142 FetchHashKeyName => 'NAME_lc',
143 LongReadLen => 3000,
144 LongTruncOk => 1,
145 RaiseError => 1,
ea93df61 146 }
9d53a6a2 147 );
c3919fdd 148 $dbh_is_local = 1;
6a9f7bae 149 }
150
151 die 'No database handle' unless defined $dbh;
152
153 my $db_type = $dbh->{'Driver'}{'Name'} or die 'Cannot determine DBI type';
154 my $driver = DRIVERS->{ lc $db_type } or die "$db_type not supported";
155 my $pkg = "SQL::Translator::Parser::DBI::$driver";
156 my $sub = $pkg.'::parse';
157
c5e9acd3 158 SQL::Translator::load( $pkg );
05078e2c 159
c3919fdd 160 my $s = eval {
6a9f7bae 161 no strict 'refs';
162 &{ $sub }( $tr, $dbh ) or die "No result from $pkg";
05078e2c 163 };
c3919fdd 164 my $err = $@;
05078e2c 165
c3919fdd 166 eval { $dbh->disconnect } if (defined $dbh and $dbh_is_local);
05078e2c 167
c3919fdd 168 die $err if $err;
6a9f7bae 169
c3919fdd 170 return $s;
6a9f7bae 171}
172
1731;
174
6a9f7bae 175=pod
176
177=head1 AUTHOR
178
11ad2df9 179Ken Y. Clark E<lt>kclark@cpan.orgE<gt>.
6a9f7bae 180
181=head1 SEE ALSO
182
05078e2c 183DBI, SQL::Translator.
6a9f7bae 184
185=cut