Remove all expansion $XX tags (isolated commit, easily revertable)
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Parser / DBI / PostgreSQL.pm
CommitLineData
80ae061a 1package SQL::Translator::Parser::DBI::PostgreSQL;
2
3# -------------------------------------------------------------------
478f608d 4# Copyright (C) 2002-2009 SQLFairy Authors
80ae061a 5#
6# This program is free software; you can redistribute it and/or
7# modify it under the terms of the GNU General Public License as
8# published by the Free Software Foundation; version 2.
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18# 02111-1307 USA
19# -------------------------------------------------------------------
20
21=head1 NAME
22
23SQL::Translator::Parser::DBI::PostgreSQL - parser for DBD::Pg
24
25=head1 SYNOPSIS
26
27See SQL::Translator::Parser::DBI.
28
29=head1 DESCRIPTION
30
d2522b19 31Uses DBI to query PostgreSQL system tables to determine schema structure.
80ae061a 32
33=cut
34
35use strict;
36use DBI;
80ae061a 37use Data::Dumper;
38use SQL::Translator::Schema::Constants;
39
da06ac74 40use vars qw[ $DEBUG $VERSION @EXPORT_OK ];
41$VERSION = '1.99';
80ae061a 42$DEBUG = 0 unless defined $DEBUG;
43
44# -------------------------------------------------------------------
45sub parse {
46 my ( $tr, $dbh ) = @_;
47
638e82c2 48 my $schema = $tr->schema;
80ae061a 49
d2522b19 50 my $column_select = $dbh->prepare(
51 "SELECT a.attname, t.typname, a.attnum,a.atttypmod as length,
52 a.attnotnull, a.atthasdef, d.adsrc
53 FROM pg_type t,pg_attribute a
54 LEFT JOIN pg_attrdef d ON (d.adrelid = a.attrelid AND a.attnum = d.adnum)
55 WHERE a.attrelid=? AND attnum>0
56 AND a.atttypid=t.oid
57 ORDER BY a.attnum"
58 );
59
60 my $index_select = $dbh->prepare(
61 "SELECT oid, c.relname, i.indkey, i.indnatts, i.indisunique,
62 i.indisprimary, pg_get_indexdef(oid) AS create_string
63 FROM pg_class c,pg_index i
64 WHERE c.relnamespace=2200 AND c.relkind='i'
65 AND c.oid=i.indexrelid AND i.indrelid=?"
66 );
67
68 my $table_select = $dbh->prepare(
69 "SELECT oid,relname FROM pg_class WHERE relnamespace IN
70 (SELECT oid FROM pg_namespace WHERE nspname='public')
71 AND relkind='r';"
72 );
73 $table_select->execute();
74
75 while ( my $tablehash = $table_select->fetchrow_hashref ) {
76
77 my $table_name = $$tablehash{'relname'};
78 my $table_oid = $$tablehash{'oid'};
79
80 my $table = $schema->add_table(
81 name => $table_name,
82 #what is type? type => $table_info->{TABLE_TYPE},
638e82c2 83 ) || die $schema->error;
80ae061a 84
d2522b19 85 $column_select->execute($table_oid);
86
87 while (my $columnhash = $column_select->fetchrow_hashref ) {
638e82c2 88
31f10179 89 #data_type seems to not be populated; perhaps there needs to
90 #be a mapping of query output to reserved constants in sqlt?
91
92 my $col = $table->add_field(
d2522b19 93 name => $$columnhash{'attname'},
94 default_value => $$columnhash{'adsrc'},
7ed7402c 95 data_type => $$columnhash{'typname'},
d2522b19 96 order => $$columnhash{'attnum'},
d2522b19 97 ) || die $table->error;
31f10179 98
99 $col->{size} = [$$columnhash{'length'}] if $$columnhash{'length'}>0;
7ed7402c 100 $col->{is_nullable} = $$columnhash{'attnotnull'} ? 0 : 1;
d2522b19 101 }
638e82c2 102
d2522b19 103 $index_select->execute($table_oid);
104
105 my @column_names = $table->field_names();
106 while (my $indexhash = $index_select->fetchrow_hashref ) {
107 #don't deal with function indexes at the moment
108 next if ($$indexhash{'indkey'} eq ''
109 or !defined($$indexhash{'indkey'}) );
110
111 my $type;
31f10179 112 if ($$indexhash{'indisprimary'}) {
113 $type = UNIQUE; #PRIMARY_KEY;
114
115 #tell sqlt that this is the primary key:
116 my $col_name=$column_names[($$indexhash{'indkey'} - 1)];
117 $table->get_field($col_name)->{is_primary_key}=1;
118
119 } elsif ($$indexhash{'indisunique'}) {
d2522b19 120 $type = UNIQUE;
121 } else {
122 $type = NORMAL;
123 }
638e82c2 124
d2522b19 125 my @column_ids = split /\s+/, $$indexhash{'indkey'};
126 my @columns;
127 foreach my $col (@column_ids) {
128 push @columns, $column_names[($col - 1)];
638e82c2 129 }
d2522b19 130
131 $table->add_index(
132 name => $$indexhash{'relname'},
133 type => $type,
31f10179 134 fields => \@columns,
d2522b19 135 ) || die $table->error;
638e82c2 136 }
80ae061a 137 }
138
139 return 1;
140}
141
1421;
143
144# -------------------------------------------------------------------
13b0b70f 145# Time is a waste of money.
146# Oscar Wilde
80ae061a 147# -------------------------------------------------------------------
148
149=pod
150
151=head1 AUTHOR
152
d2522b19 153Scott Cain E<lt>cain@cshl.eduE<gt>, previous author:
13b0b70f 154Paul Harrington E<lt>harringp@deshaw.comE<gt>.
80ae061a 155
156=head1 SEE ALSO
157
13b0b70f 158SQL::Translator, DBD::Pg.
80ae061a 159
160=cut