dump out views and stored procedures
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Parser / DBI / Sybase.pm
CommitLineData
86ee0658 1package SQL::Translator::Parser::DBI::Sybase;
2
e36f4eac 3# $Id: Sybase.pm,v 1.2 2003-10-03 20:56:40 kycl4rk Exp $
86ee0658 4
5=head1 NAME
6
7SQL::Translator::Parser::DBI::Sybase - parser for DBD::Sybase
8
9=head1 SYNOPSIS
10
11See SQL::Translator::Parser::DBI.
12
13=head1 DESCRIPTION
14
15Uses DBI Catalog Methods.
16
17=cut
18
19use strict;
20use DBI;
21use SQL::Translator::Schema;
22use Data::Dumper;
23
24use vars qw[ $DEBUG $VERSION @EXPORT_OK ];
e36f4eac 25$VERSION = sprintf "%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/;
86ee0658 26$DEBUG = 0 unless defined $DEBUG;
27
28no strict 'refs';
29
30# -------------------------------------------------------------------
31sub parse {
32 my ( $tr, $dbh ) = @_;
33
34 if ($dbh->{FetchHashKeyName} ne 'NAME_uc') {
35 warn "setting dbh attribute {FetchHashKeyName} to NAME_uc";
36 $dbh->{FetchHashKeyName} = 'NAME_uc';
37 }
38
39 if ($dbh->{ChopBlanks} != 1) {
40 warn "setting dbh attribute {ChopBlanks} to 1";
41 $dbh->{ChopBlanks} = 1;
42 }
43
44 my $schema = $tr->schema;
45
46 my ($sth, @tables, $columns);
47 my $stuff;
48
49 ### Columns
50
51 # it is much quicker to slurp back everything all at once rather
52 # than make repeated calls
53
54 $sth = $dbh->column_info();
55
56
57 foreach my $c (@{$sth->fetchall_arrayref({})}) {
58 $columns
59 ->{$c->{TABLE_CAT}}
60 ->{$c->{TABLE_SCHEM}}
61 ->{$c->{TABLE_NAME}}
62 ->{columns}
63 ->{$c->{COLUMN_NAME}}= $c;
64 }
65
66 ### Tables and views
67
68 # Get a list of the tables and views.
69 $sth = $dbh->table_info();
70 @tables = @{$sth->fetchall_arrayref({})};
71
72 my $h = $dbh->selectall_arrayref(q{
73SELECT o.name, colid,colid2,c.text
74 FROM syscomments c
75 JOIN sysobjects o
76 ON c.id = o.id
77 WHERE o.type ='V'
78ORDER BY o.name,
79 c.colid,
80 c.colid2
81}
82);
83
84 # View text
85 # I had always thought there was something 'hard' about
e36f4eac 86 # reconstructing text from syscomments ..
86ee0658 87 # this seems to work fine and is certainly not complicated!
88
89 foreach (@{$h}) {
90 $stuff->{view}->{$_->[0]}->{text} .= $_->[3];
91 }
92
93 #### objects with indexes.
94 map {
95 $stuff->{indexes}->{$_->[0]}++
96 if defined;
97 } @{$dbh->selectall_arrayref("SELECT DISTINCT object_name(id) AS
98name
99 FROM sysindexes
100 WHERE indid > 0")};
101
102
103 ## slurp objects
104 map {
105 $stuff->{$_->[1]}->{$_->[0]} = $_;
106 } @{$dbh->selectall_arrayref("SELECT name,type, id FROM
107sysobjects")};
108
109
110 ### Procedures
111 ### Defaults
112 ### Rules
113 ### Bind Defaults
114 ### Bind Rules
115
116 ### Triggers
117
118 ### References
119 ### Keys
120
121 ### Types
122
123 $stuff->{type_info_all} = $dbh->type_info_all;
124
125 ### Tables
126 # According to the DBI docs, these can be
127
128 # "TABLE"
129 # "VIEW"
130 # "SYSTEM TABLE"
131 # "GLOBAL TEMPORARY",
132 # "LOCAL TEMPORARY"
133 # "ALIAS"
134 # "SYNONYM"
135
136 foreach my $table_info (@tables) {
137 next
138 unless (defined($table_info->{TABLE_TYPE}));
139
140 if ($table_info->{TABLE_TYPE} =~ /TABLE/) {
141 my $table = $schema->add_table(
142 name =>
143$table_info->{TABLE_NAME},
144 type =>
145$table_info->{TABLE_TYPE},
146 ) || die $schema->error;
147
148 # find the associated columns
149
150 my $cols =
151 $columns->{$table_info->{TABLE_QUALIFIER}}
152 ->{$table_info->{TABLE_OWNER}}
153 ->{$table_info->{TABLE_NAME}}
154 ->{columns};
155
156 foreach my $c (values %{$cols}) {
157 my $f = $table->add_field(name =>
158$c->{COLUMN_NAME},
159 data_type =>
160$c->{TYPE_NAME},
161 order =>
162$c->{ORDINAL_POSITION},
163 size =>
164$c->{COLUMN_SIZE},
165 ) || die $table->error;
166 $f->is_nullable(1)
167 if ($c->{NULLABLE} == 1);
168 }
169
170 # add in primary key
171 my $h = $dbh->selectall_hashref("sp_pkeys
172$table_info->{TABLE_NAME}", 'COLUMN_NAME');
173 if (scalar keys %{$h} > 1) {
174 my @c = map {
175 $_->{COLUMN_NAME}
176 } sort {
177 $a->{KEY_SEQ} <=> $b->{KEY_SEQ}
178 } values %{$h};
179
180 $table->primary_key(@c)
181 if (scalar @c);
182 }
183
184 # add in any indexes ... how do we tell if the index has
185 # already been created as part of a primary key or other
186 # constraint?
187
188 if (defined($stuff->{indexes}->{$table_info->{TABLE_NAME}}))
189{
190 my $h = $dbh->selectall_hashref("sp_helpindex
191$table_info->{TABLE_NAME}", 'INDEX_NAME');
192 foreach (values %{$h}) {
193 my $fields = $_->{'INDEX_KEYS'};
194 $fields =~ s/\s*//g;
195 my $i = $table->add_index(
196 name =>
197$_->{INDEX_NAME},
198 fields => $fields,
199 );
200 if ($_->{'INDEX_DESCRIPTION'} =~ /unique/i) {
201 $i->type('unique');
202
203 # we could make this a primary key if there
204 # isn't already one defined and if there
205 # aren't any nullable columns in thisindex.
206
207 if (!defined($table->primary_key())) {
208 $table->primary_key($fields)
209 unless grep {
210 $table->get_field($_)->is_nullable()
211 } split(/,\s*/, $fields);
212 }
213 }
214 }
215 }
216 } elsif ($table_info->{TABLE_TYPE} eq 'VIEW') {
217 my $view = $schema->add_view(
218 name =>
219$table_info->{TABLE_NAME},
220 );
221
222 my $cols =
223 $columns->{$table_info->{TABLE_QUALIFIER}}
224 ->{$table_info->{TABLE_OWNER}}
225 ->{$table_info->{TABLE_NAME}}
226 ->{columns};
227
228 $view->fields(map {
229 $_->{COLUMN_NAME}
230 } sort {
231 $a->{ORDINAL_POSITION} <=> $b->{ORDINAL_POSITION}
232 } values %{$cols}
233 );
234
235
236$view->sql($stuff->{view}->{$table_info->{TABLE_NAME}}->{text})
237 if
238(defined($stuff->{view}->{$table_info->{TABLE_NAME}}->{text}));
239 }
240 }
241 ### Permissions
242 ### Groups
243 ### Users
244 ### Aliases
245 ### Logins
246 return 1;
247}
248
2491;
250
251=pod
252
253=head1 AUTHOR
254
255Paul Harrington E<lt>harringp@deshaw.comE<gt>,
256
257=head1 SEE ALSO
258
259DBI, DBD::Sybase, SQL::Translator::Schema.
260
261=cut
262