Applied patch from Ryan to uniqify index names sanely for the mysql producer
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Parser / DBI.pm
CommitLineData
6a9f7bae 1package SQL::Translator::Parser::DBI;
2
3# -------------------------------------------------------------------
9fb7423b 4# $Id: DBI.pm,v 1.10 2006-05-24 18:08:41 duality72 Exp $
6a9f7bae 5# -------------------------------------------------------------------
90075866 6# Copyright (C) 2002-4 SQLFairy Authors
6a9f7bae 7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; version 2.
11#
12# This program is distributed in the hope that it will be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15# General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20# 02111-1307 USA
21# -------------------------------------------------------------------
22
23=head1 NAME
24
25SQL::Translator::Parser::DBI - "parser" for DBI handles
26
27=head1 SYNOPSIS
28
29 use DBI;
30 use SQL::Translator;
31
90e373b0 32 my $dbh = DBI->connect('dsn', 'user', 'pass',
33 {
34 RaiseError => 1,
35 FetchHashKeyName => 'NAME_lc',
36 }
37 );
6a9f7bae 38
39 my $translator = SQL::Translator->new(
40 parser => 'DBI',
41 dbh => $dbh,
42 );
43
44Or:
45
46 use SQL::Translator;
47
90e373b0 48 my $translator = SQL::Translator->new(
49 parser => 'DBI',
50 parser_args => {
51 dsn => 'dbi:mysql:FOO',
52 db_user => 'guest',
53 db_password => 'password',
54 }
6a9f7bae 55 );
56
57=head1 DESCRIPTION
58
59This parser accepts an open database handle (or the arguments to create
05078e2c 60one) and queries the database directly for the information.
6a9f7bae 61
62The following are acceptable arguments:
63
05078e2c 64=over 4
6a9f7bae 65
66=item * dbh
67
90e373b0 68An open DBI database handle. NB: Be sure to create the database with the
69"FetchHashKeyName => 'NAME_lc'" option as all the DBI parsers expect
70lowercased column names.
6a9f7bae 71
72=item * dsn
73
74The DSN to use for connecting to a database.
75
76=item * db_user
77
78The user name to use for connecting to a database.
79
80=item * db_password
81
82The password to use for connecting to a database.
83
84=back
85
05078e2c 86There is no need to specify which type of database you are querying as
87this is determined automatically by inspecting $dbh->{'Driver'}{'Name'}.
88If a parser exists for your database, it will be used automatically;
89if not, the code will fail automatically (and you can write the parser
90and contribute it to the project!).
91
92Currently parsers exist for the following databases:
93
94=over 4
95
96=item * MySQL
97
98=item * SQLite
99
100=item * Sybase
101
102=item * PostgreSQL (still experimental)
103
104=back
105
106Most of these parsers are able to query the database directly for the
107structure rather than parsing a text file. For large schemas, this is
108probably orders of magnitude faster than traditional parsing (which
109uses Parse::RecDescent, an amazing module but really quite slow).
110
111Though no Oracle parser currently exists, it would be fairly easy to
112query an Oracle database directly by using DDL::Oracle to generate a
113DDL for the schema and then using the normal Oracle parser on this.
114Perhaps future versions of SQL::Translator will include the ability to
115query Oracle directly and skip the parsing of a text file, too.
116
6a9f7bae 117=cut
118
119# -------------------------------------------------------------------
120
121use strict;
122use DBI;
123use vars qw($VERSION @EXPORT);
9fb7423b 124$VERSION = sprintf "%d.%02d", q$Revision: 1.10 $ =~ /(\d+)\.(\d+)/;
6a9f7bae 125
126use constant DRIVERS => {
05078e2c 127 mysql => 'MySQL',
461c1a96 128 odbc => 'SQLServer',
aaac0589 129 oracle => 'Oracle',
130 pg => 'PostgreSQL',
05078e2c 131 sqlite => 'SQLite',
132 sybase => 'Sybase',
69dad5b9 133 pg => 'PostgreSQL',
134 db2 => 'DB2',
6a9f7bae 135};
136
137use Exporter;
05078e2c 138
139use SQL::Translator::Utils qw(debug);
140
9d53a6a2 141use SQL::Translator::Parser::DBI::MySQL;
461c1a96 142use SQL::Translator::Parser::DBI::SQLServer;
6a9f7bae 143use SQL::Translator::Parser::DBI::SQLite;
525905b9 144use SQL::Translator::Parser::DBI::Sybase;
05078e2c 145use SQL::Translator::Parser::DBI::PostgreSQL;
69dad5b9 146use SQL::Translator::Parser::DBI::DB2;
aaac0589 147use SQL::Translator::Parser::DBI::Oracle;
6a9f7bae 148
149use base qw(Exporter);
150@EXPORT = qw(parse);
151
152#
153# Passed a SQL::Translator instance and a string containing the data
154#
155sub parse {
156 my ( $tr, $data ) = @_;
157
6a9f7bae 158 my $args = $tr->parser_args;
159 my $dbh = $args->{'dbh'};
160 my $dsn = $args->{'dsn'};
161 my $db_user = $args->{'db_user'};
162 my $db_password = $args->{'db_password'};
163
164 unless ( $dbh ) {
165 die 'No DSN' unless $dsn;
9d53a6a2 166 $dbh = DBI->connect( $dsn, $db_user, $db_password,
167 {
168 FetchHashKeyName => 'NAME_lc',
169 LongReadLen => 3000,
170 LongTruncOk => 1,
171 RaiseError => 1,
172 }
173 );
6a9f7bae 174 }
175
176 die 'No database handle' unless defined $dbh;
177
178 my $db_type = $dbh->{'Driver'}{'Name'} or die 'Cannot determine DBI type';
179 my $driver = DRIVERS->{ lc $db_type } or die "$db_type not supported";
180 my $pkg = "SQL::Translator::Parser::DBI::$driver";
181 my $sub = $pkg.'::parse';
182
05078e2c 183 #
184 # I can't get this to work. I seem to have to have the "use"
185 # statements above.
186 #
187# $tr->load( $pkg );
188
189 eval {
6a9f7bae 190 no strict 'refs';
191 &{ $sub }( $tr, $dbh ) or die "No result from $pkg";
05078e2c 192 };
193
194 $dbh->disconnect if defined $dbh;
195
196 die $@ if $@;
6a9f7bae 197
198 return 1;
199}
200
2011;
202
203# -------------------------------------------------------------------
204=pod
205
206=head1 AUTHOR
207
208Ken Y. Clark E<lt>kclark@cpan.orgE<gt>.
209
210=head1 SEE ALSO
211
05078e2c 212DBI, SQL::Translator.
6a9f7bae 213
214=cut