remove commented copyright
[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 DBI;
101 use vars qw($VERSION @EXPORT);
102 $VERSION = '1.59';
103
104 use constant DRIVERS => {
105     mysql            => 'MySQL',
106     odbc             => 'SQLServer',
107     oracle           => 'Oracle',
108     pg               => 'PostgreSQL',
109     sqlite           => 'SQLite',
110     sybase           => 'Sybase',
111     pg               => 'PostgreSQL',
112     db2              => 'DB2',
113 };
114
115 use Exporter;
116
117 use SQL::Translator::Utils qw(debug);
118
119 use base qw(Exporter);
120 @EXPORT = qw(parse);
121
122 #
123 # Passed a SQL::Translator instance and a string containing the data
124 #
125 sub parse {
126     my ( $tr, $data ) = @_;
127
128     my $args          = $tr->parser_args;
129     my $dbh           = $args->{'dbh'};
130     my $dsn           = $args->{'dsn'};
131     my $db_user       = $args->{'db_user'};
132     my $db_password   = $args->{'db_password'};
133
134     unless ( $dbh ) {
135         die 'No DSN' unless $dsn;
136         $dbh = DBI->connect( $dsn, $db_user, $db_password,
137             {
138                 FetchHashKeyName => 'NAME_lc',
139                 LongReadLen      => 3000,
140                 LongTruncOk      => 1,
141                 RaiseError       => 1,
142             }
143         );
144     }
145
146     die 'No database handle' unless defined $dbh;
147
148     my $db_type = $dbh->{'Driver'}{'Name'} or die 'Cannot determine DBI type';
149     my $driver  = DRIVERS->{ lc $db_type } or die "$db_type not supported";
150     my $pkg     = "SQL::Translator::Parser::DBI::$driver";
151     my $sub     = $pkg.'::parse';
152
153     SQL::Translator::load( $pkg );
154
155     eval {
156         no strict 'refs';
157         &{ $sub }( $tr, $dbh ) or die "No result from $pkg";
158     };
159
160     $dbh->disconnect if defined $dbh;
161
162     die $@ if $@;
163
164     return 1;
165 }
166
167 1;
168
169 =pod
170
171 =head1 AUTHOR
172
173 Ken Y. Clark E<lt>kclark@cpan.orgE<gt>.
174
175 =head1 SEE ALSO
176
177 DBI, SQL::Translator.
178
179 =cut