Commit | Line | Data |
86ee0658 |
1 | package 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 | |
7 | SQL::Translator::Parser::DBI::Sybase - parser for DBD::Sybase |
8 | |
9 | =head1 SYNOPSIS |
10 | |
11 | See SQL::Translator::Parser::DBI. |
12 | |
13 | =head1 DESCRIPTION |
14 | |
15 | Uses DBI Catalog Methods. |
16 | |
17 | =cut |
18 | |
19 | use strict; |
20 | use DBI; |
21 | use SQL::Translator::Schema; |
22 | use Data::Dumper; |
23 | |
24 | use 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 | |
28 | no strict 'refs'; |
29 | |
30 | # ------------------------------------------------------------------- |
31 | sub 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{ |
73 | SELECT 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' |
78 | ORDER 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 |
98 | name |
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 |
107 | sysobjects")}; |
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 | |
249 | 1; |
250 | |
251 | =pod |
252 | |
253 | =head1 AUTHOR |
254 | |
255 | Paul Harrington E<lt>harringp@deshaw.comE<gt>, |
256 | |
257 | =head1 SEE ALSO |
258 | |
259 | DBI, DBD::Sybase, SQL::Translator::Schema. |
260 | |
261 | =cut |
262 | |