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