Doc tweaks
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Parser / DBI.pm
1 package SQL::Translator::Parser::DBI;
2
3 # -------------------------------------------------------------------
4 # $Id: DBI.pm,v 1.5 2004-02-09 22:23:40 kycl4rk Exp $
5 # -------------------------------------------------------------------
6 # Copyright (C) 2002-4 SQLFairy Authors
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
25 SQL::Translator::Parser::DBI - "parser" for DBI handles
26
27 =head1 SYNOPSIS
28
29   use DBI;
30   use SQL::Translator;
31
32   my $dbh = DBI->connect(...);
33
34   my $translator  =  SQL::Translator->new(
35       parser      => 'DBI',
36       dbh         => $dbh,
37   );
38
39 Or:
40
41   use SQL::Translator;
42
43   my $translator  =  SQL::Translator->new(
44       parser      => 'DBI',
45       dsn         => 'dbi:mysql:FOO',
46       db_user     => 'guest',
47       db_password => 'password',
48   );
49
50 =head1 DESCRIPTION
51
52 This parser accepts an open database handle (or the arguments to create 
53 one) and queries the database directly for the information.  
54
55 The following are acceptable arguments:
56
57 =over 4
58
59 =item * dbh
60
61 An open DBI database handle.
62
63 =item * dsn
64
65 The DSN to use for connecting to a database.
66
67 =item * db_user
68
69 The user name to use for connecting to a database.
70
71 =item * db_password
72
73 The password to use for connecting to a database.
74
75 =back
76
77 There is no need to specify which type of database you are querying as
78 this is determined automatically by inspecting $dbh->{'Driver'}{'Name'}.
79 If a parser exists for your database, it will be used automatically;
80 if not, the code will fail automatically (and you can write the parser
81 and contribute it to the project!).  
82
83 Currently parsers exist for the following databases:
84
85 =over 4
86
87 =item * MySQL
88
89 =item * SQLite
90
91 =item * Sybase
92
93 =item * PostgreSQL (still experimental)
94
95 =back
96
97 Most of these parsers are able to query the database directly for the
98 structure rather than parsing a text file.  For large schemas, this is
99 probably orders of magnitude faster than traditional parsing (which
100 uses Parse::RecDescent, an amazing module but really quite slow).
101
102 Though no Oracle parser currently exists, it would be fairly easy to
103 query an Oracle database directly by using DDL::Oracle to generate a
104 DDL for the schema and then using the normal Oracle parser on this.
105 Perhaps future versions of SQL::Translator will include the ability to
106 query Oracle directly and skip the parsing of a text file, too.
107
108 =cut
109
110 # -------------------------------------------------------------------
111
112 use strict;
113 use DBI;
114 use vars qw($VERSION @EXPORT);
115 $VERSION = sprintf "%d.%02d", q$Revision: 1.5 $ =~ /(\d+)\.(\d+)/;
116
117 use constant DRIVERS => {
118     mysql            => 'MySQL',
119     sqlite           => 'SQLite',
120     sybase           => 'Sybase',
121     pg               => 'PostgreSQL',
122 };
123
124 use Exporter;
125
126 use SQL::Translator::Utils qw(debug);
127
128 use SQL::Translator::Parser::DBI::MySQL;
129 use SQL::Translator::Parser::DBI::SQLite;
130 use SQL::Translator::Parser::DBI::Sybase;
131 use SQL::Translator::Parser::DBI::PostgreSQL;
132
133 use base qw(Exporter);
134 @EXPORT = qw(parse);
135
136 #
137 # Passed a SQL::Translator instance and a string containing the data
138 #
139 sub parse {
140     my ( $tr, $data ) = @_;
141
142     my $args          = $tr->parser_args;
143     my $dbh           = $args->{'dbh'};
144     my $dsn           = $args->{'dsn'};
145     my $db_user       = $args->{'db_user'};
146     my $db_password   = $args->{'db_password'};
147
148     unless ( $dbh ) {
149         die 'No DSN' unless $dsn;
150         $dbh = DBI->connect( $dsn, $db_user, $db_password, 
151             {
152                 FetchHashKeyName => 'NAME_lc',
153                 LongReadLen      => 3000,
154                 LongTruncOk      => 1,
155                 RaiseError       => 1,
156             } 
157         );
158     }
159
160     die 'No database handle' unless defined $dbh;
161
162     my $db_type = $dbh->{'Driver'}{'Name'} or die 'Cannot determine DBI type';
163     my $driver  = DRIVERS->{ lc $db_type } or die "$db_type not supported";
164     my $pkg     = "SQL::Translator::Parser::DBI::$driver";
165     my $sub     = $pkg.'::parse';
166
167     #
168     # I can't get this to work.  I seem to have to have the "use"
169     # statements above.
170     #
171 #    $tr->load( $pkg );
172
173     eval {
174         no strict 'refs';
175         &{ $sub }( $tr, $dbh ) or die "No result from $pkg";
176     };
177
178     $dbh->disconnect if defined $dbh;
179
180     die $@ if $@;
181
182     return 1;
183 }
184
185 1;
186
187 # -------------------------------------------------------------------
188 =pod
189
190 =head1 AUTHOR
191
192 Ken Y. Clark E<lt>kclark@cpan.orgE<gt>.
193
194 =head1 SEE ALSO
195
196 DBI, SQL::Translator.
197
198 =cut