Commit | Line | Data |
c00bb9f8 |
1 | package SQL::Translator::Producer::Turnkey; |
2 | |
3 | # ------------------------------------------------------------------- |
e12e1ffc |
4 | # $Id: Turnkey.pm,v 1.1.2.7 2003-10-13 22:05:44 allenday Exp $ |
c00bb9f8 |
5 | # ------------------------------------------------------------------- |
6 | # Copyright (C) 2003 Allen Day <allenday@ucla.edu>, |
7 | # Ying Zhang <zyolive@yahoo.com> |
8 | # |
9 | # This program is free software; you can redistribute it and/or |
10 | # modify it under the terms of the GNU General Public License as |
11 | # published by the Free Software Foundation; version 2. |
12 | # |
13 | # This program is distributed in the hope that it will be useful, but |
14 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | # General Public License for more details. |
17 | # |
18 | # You should have received a copy of the GNU General Public License |
19 | # along with this program; if not, write to the Free Software |
20 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
21 | # 02111-1307 USA |
22 | # ------------------------------------------------------------------- |
23 | |
24 | use strict; |
25 | use vars qw[ $VERSION $DEBUG ]; |
e12e1ffc |
26 | $VERSION = sprintf "%d.%02d", q$Revision: 1.1.2.7 $ =~ /(\d+)\.(\d+)/; |
c00bb9f8 |
27 | $DEBUG = 1 unless defined $DEBUG; |
28 | |
29 | use SQL::Translator::Schema::Constants; |
30 | use SQL::Translator::Utils qw(header_comment); |
31 | use Data::Dumper; |
32 | use Template; |
33 | |
34 | my %CDBI_auto_pkgs = ( |
35 | MySQL => 'mysql', |
36 | PostgreSQL => 'Pg', |
37 | Oracle => 'Oracle', |
38 | ); |
39 | |
40 | # ------------------------------------------------------------------- |
41 | sub produce { |
42 | my $t = shift; |
43 | my $create = undef; |
44 | local $DEBUG = $t->debug; |
45 | my $no_comments = $t->no_comments; |
46 | my $schema = $t->schema; |
47 | my $args = $t->producer_args; |
48 | my $db_user = $args->{'db_user'} || ''; |
49 | my $db_pass = $args->{'db_pass'} || ''; |
50 | my $main_pkg_name = $args->{'main_pkg_name'} || |
51 | $t->format_package_name('DBI'); |
52 | my $header = header_comment(__PACKAGE__, "# "); |
53 | my $parser_type = ( split /::/, $t->parser_type )[-1]; |
54 | my $from = $CDBI_auto_pkgs{ $parser_type } || ''; |
55 | my $dsn = $args->{'dsn'} || sprintf( 'dbi:%s:_', |
56 | $CDBI_auto_pkgs{ $parser_type } |
57 | ? $CDBI_auto_pkgs{ $parser_type } : $parser_type |
58 | ); |
59 | my $sep = '# ' . '-' x 67; |
60 | |
61 | # |
62 | # Identify "link tables" (have only PK and FK fields). |
63 | # |
64 | my %linkable; |
65 | my %linktable; |
66 | foreach my $table ( $schema->get_tables ) { |
67 | my $is_link = 1; |
68 | foreach my $field ( $table->get_fields ) { |
69 | unless ( $field->is_primary_key or $field->is_foreign_key ) { |
70 | $is_link = 0; |
71 | last; |
72 | } |
73 | } |
74 | |
75 | next unless $is_link; |
76 | |
77 | foreach my $left ( $table->get_fields ) { |
78 | next unless $left->is_foreign_key; |
79 | my $lfk = $left->foreign_key_reference or next; |
80 | my $lr_table = $schema->get_table( $lfk->reference_table ) |
81 | or next; |
82 | my $lr_field_name = ($lfk->reference_fields)[0]; |
83 | my $lr_field = $lr_table->get_field($lr_field_name); |
84 | next unless $lr_field->is_primary_key; |
85 | |
86 | foreach my $right ( $table->get_fields ) { |
87 | next if $left->name eq $right->name; |
88 | |
89 | my $rfk = $right->foreign_key_reference or next; |
90 | my $rr_table = $schema->get_table( $rfk->reference_table ) |
91 | or next; |
92 | my $rr_field_name = ($rfk->reference_fields)[0]; |
93 | my $rr_field = $rr_table->get_field($rr_field_name); |
94 | next unless $rr_field->is_primary_key; |
95 | |
96 | $linkable{ $lr_table->name }{ $rr_table->name } = $table; |
97 | $linkable{ $rr_table->name }{ $lr_table->name } = $table; |
98 | $linktable{ $table->name } = $table; |
99 | } |
100 | } |
101 | } |
102 | |
103 | # |
104 | # Iterate over all tables |
105 | # |
106 | my ( %packages, $order ); |
107 | for my $table ( $schema->get_tables ) { |
108 | my $table_name = $table->name or next; |
109 | |
110 | my $table_pkg_name = $t->format_package_name($table_name); |
111 | $packages{ $table_pkg_name } = { |
112 | order => ++$order, |
113 | pkg_name => $table_pkg_name, |
114 | base => $main_pkg_name, |
115 | table => $table_name, |
116 | }; |
117 | |
118 | # |
119 | # Primary key may have a differenct accessor method name |
120 | # |
121 | if ( my $constraint = $table->primary_key ) { |
122 | my $field = ($constraint->fields)[0]; |
123 | $packages{ $table_pkg_name }{'columns_primary'} = $field; |
124 | |
125 | if ( my $pk_xform = $t->format_pk_name ) { |
126 | my $pk_name = $pk_xform->( $table_pkg_name, $field ); |
127 | |
128 | $packages{ $table_pkg_name }{'pk_accessor'} = |
129 | "#\n# Primary key accessor\n#\n". |
130 | "sub $pk_name {\n shift->$field\n}\n\n"; |
131 | |
132 | } |
133 | } |
134 | |
135 | my $is_data = 0; |
136 | foreach my $field ( $table->get_fields ) { |
137 | if ( !$field->is_foreign_key and !$field->is_primary_key ) { |
138 | push @{ $packages{ $table_pkg_name }{'columns_essential'} }, $field->name; |
139 | $is_data++; |
140 | } elsif ( !$field->is_primary_key ) { |
141 | push @{ $packages{ $table_pkg_name }{'columns_others'} }, $field->name; |
142 | } |
143 | } |
144 | |
145 | my %linked; |
146 | if ( $is_data ) { |
147 | foreach my $link ( keys %{ $linkable{ $table_name } } ) { |
148 | my $linkmethodname; |
149 | |
150 | if ( my $fk_xform = $t->format_fk_name ) { |
151 | # ADD CALLBACK FOR PLURALIZATION MANGLING HERE |
152 | $linkmethodname = $fk_xform->($linkable{$table_name}{$link}->name, |
153 | ($schema->get_table($link)->primary_key->fields)[0]).'s'; |
154 | } else { |
155 | # ADD CALLBACK FOR PLURALIZATION MANGLING HERE |
156 | $linkmethodname = $linkable{$table_name}{$link}->name.'_'. |
157 | ($schema->get_table($link)->primary_key->fields)[0].'s'; |
158 | } |
159 | |
160 | my @rk_fields = (); |
161 | my @lk_fields = (); |
162 | foreach my $field ($linkable{$table_name}{$link}->get_fields) { |
163 | next unless $field->is_foreign_key; |
164 | |
165 | next unless( |
166 | $field->foreign_key_reference->reference_table eq $table_name |
167 | || |
168 | $field->foreign_key_reference->reference_table eq $link |
169 | ); |
170 | push @lk_fields, ($field->foreign_key_reference->reference_fields)[0] |
171 | if $field->foreign_key_reference->reference_table eq $link; |
172 | push @rk_fields, $field->name |
173 | if $field->foreign_key_reference->reference_table eq $table_name; |
174 | } |
175 | |
176 | #if one possible traversal via link table |
177 | if (scalar(@rk_fields) == 1 and scalar(@lk_fields) == 1) { |
178 | foreach my $rk_field (@rk_fields) { |
179 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link } }, |
180 | push @{ $packages{ $table_pkg_name }{'has_many'}{$link}{'link_one_one'} }, |
181 | "sub ".$linkmethodname." { my \$self = shift; ". |
182 | "return map \$_->". |
183 | ($schema->get_table($link)->primary_key->fields)[0]. |
184 | ", \$self->".$linkable{$table_name}{$link}->name. |
185 | "_".$rk_field." }\n\n"; |
186 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link }{'one_one'} }, |
187 | # {link_method_name => $linkmethodname, primary_key_field => ($schema->get_table($link)->primary_key->fields)[0], |
188 | # table_name => $linkable{$table_name}{$link}->name, rk_field => $rk_field}; |
e12e1ffc |
189 | |
190 | if(!$linktable{$table_name} and !$linktable{$link}){ $linkable{$table_name}{$link} ||= 1; } |
191 | |
c00bb9f8 |
192 | } |
193 | #else there is more than one way to traverse it. ack! |
194 | #let's treat these types of link tables as a many-to-one (easier) |
195 | # |
196 | #NOTE: we need to rethink the link method name, as the cardinality |
197 | #has shifted on us. |
198 | } elsif (scalar(@rk_fields) == 1) { |
199 | foreach my $rk_field (@rk_fields) { |
200 | # ADD CALLBACK FOR PLURALIZATION MANGLING HERE |
201 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link } }, |
202 | push @{ $packages{ $table_pkg_name }{'has_many'}{ $link }{'link_many_one'} }, |
203 | "sub " . $linkable{$table_name}{$link}->name . |
204 | "s { my \$self = shift; return \$self->" . |
205 | $linkable{$table_name}{$link}->name . "_" . |
206 | $rk_field . "(\@_) }\n\n"; |
207 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link }{'many_one'} }, |
208 | # { |
209 | # table_name => $linkable{$table_name}{$link}->name, rk_field => $rk_field |
210 | # }; |
e12e1ffc |
211 | |
212 | if(!$linktable{$table_name} and !$linktable{$link}){ $linkable{$table_name}{$link} ||= 1; } |
213 | |
c00bb9f8 |
214 | } |
215 | } elsif (scalar(@lk_fields) == 1) { |
216 | #these will be taken care of on the other end... |
217 | } else { |
218 | #many many many. need multiple iterations here, data structure revision |
219 | #to handle N FK sources. This code has not been tested and likely doesn't |
220 | #work here |
221 | foreach my $rk_field (@rk_fields) { |
222 | # ADD CALLBACK FOR PLURALIZATION MANGLING HERE |
223 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link } }, |
224 | push @{ $packages{ $table_pkg_name }{'has_many'}{ $link }{'link_many_many'} }, |
225 | "sub " . $linkable{$table_name}{$link}->name . "_" . $rk_field . |
226 | "s { my \$self = shift; return \$self->" . |
227 | $linkable{$table_name}{$link}->name . "_" . |
228 | $rk_field . "(\@_) }\n\n"; |
229 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link }{'many_many'} }, |
230 | # { |
231 | # table_name => $linkable{$table_name}{$link}->name, rk_field => $rk_field |
232 | # }; |
e12e1ffc |
233 | |
234 | if(!$linktable{$table_name} and !$linktable{$link}){ $linkable{$table_name}{$link} ||= 1; } |
235 | |
c00bb9f8 |
236 | } |
237 | } |
238 | } |
239 | } |
240 | |
241 | |
242 | # |
243 | # Use foreign keys to set up "has_a/has_many" relationships. |
244 | # |
245 | foreach my $field ( $table->get_fields ) { |
246 | if ( $field->is_foreign_key ) { |
247 | my $table_name = $table->name; |
248 | my $field_name = $field->name; |
249 | my $fk_method = $t->format_fk_name($table_name, $field_name); |
250 | my $fk = $field->foreign_key_reference; |
251 | my $ref_table = $fk->reference_table; |
252 | my $ref_pkg = $t->format_package_name($ref_table); |
253 | my $ref_field = ($fk->reference_fields)[0]; |
254 | |
255 | push @{ $packages{ $table_pkg_name }{'has_a'} }, |
256 | "$table_pkg_name->has_a(\n". |
257 | " $field_name => '$ref_pkg'\n);\n\n". |
258 | "sub $fk_method {\n". |
259 | " return shift->$field_name\n}\n\n" |
260 | ; |
261 | |
e12e1ffc |
262 | if(!$linktable{$ref_table} and !$linktable{$table_name}){ $linkable{$ref_table}{$table_name} ||= 1; } |
c00bb9f8 |
263 | |
264 | # |
265 | # If this table "has a" to the other, then it follows |
266 | # that the other table "has many" of this one, right? |
267 | # |
268 | # No... there is the possibility of 1-1 cardinality |
269 | |
270 | #if there weren't M-M relationships via the has_many |
271 | #being set up here, create nice pluralized method alias |
272 | #rather for user as alt. to ugly tablename_fieldname name |
273 | if(! $packages{ $ref_pkg }{ 'has_many' }{ $table_name } ){ |
274 | # ADD CALLBACK FOR PLURALIZATION MANGLING HERE |
275 | #push @{ $packages{ $ref_pkg }{'has_many'}{ $table_name } }, |
276 | # "sub $table_name\s {\n return shift->$table_name\_$field_name\n}\n\n"; |
277 | push @{ $packages{ $ref_pkg }{'has_many'}{ $table_name }{'fk_pluralized'} }, |
278 | { table_name => $table_name, field_name => $field_name }; |
279 | |
e12e1ffc |
280 | if(!$linktable{$ref_table} and !$linktable{$table_name}){ $linkable{$ref_table}{$table_name} ||= 1; } |
281 | |
c00bb9f8 |
282 | #else ugly |
283 | } else { |
284 | } |
285 | |
286 | #push @{ $packages{ $ref_pkg }{'has_many'}{ $table_name } }, |
287 | # "$ref_pkg->has_many(\n '${table_name}_${field_name}', ". |
288 | # "'$table_pkg_name' => '$field_name'\n);\n\n"; |
289 | push @{ $packages{ $ref_pkg }{'has_many'}{ $table_name }{pluralized} }, |
290 | { ref_pkg => $ref_pkg, table_pkg_name => $table_pkg_name, table_name => $table_name, field_name => $field_name }; |
e12e1ffc |
291 | |
292 | if(!$linktable{$ref_table} and !$linktable{$table_name}){ $linkable{$ref_table}{$table_name} ||= 1; } |
c00bb9f8 |
293 | } |
294 | } |
295 | } |
296 | |
297 | my %metadata; |
298 | $metadata{"packages"} = \%packages; |
299 | $metadata{"linkable"} = \%linkable; |
300 | return(translateForm($t, \%metadata)); |
301 | } |
302 | |
303 | ########################################### |
304 | # Here documents for the tt2 templates # |
305 | ########################################### |
306 | |
307 | my $turnkey_atom_tt2 = <<'EOF'; |
308 | [% ###### DOCUMENT START ###### %] |
309 | |
310 | [% FOREACH package = linkable %] |
311 | |
312 | ############################################## |
313 | |
74611019 |
314 | package Turnkey::Atom::[% package.key FILTER ucfirst %]; |
c00bb9f8 |
315 | |
316 | [% pname = package.key FILTER ucfirst%] |
74611019 |
317 | [% pkey = "Turnkey::Model::${pname}" %] |
c00bb9f8 |
318 | |
74611019 |
319 | use base qw(Turnkey::Atom); |
c00bb9f8 |
320 | use Data::Dumper; |
321 | |
322 | sub can_render { |
323 | return 1; |
324 | } |
325 | |
326 | sub render { |
327 | my $self = shift; |
328 | my $dbobject = shift; |
329 | # Assumption here that if it's not rendering on it's own dbobject |
330 | # then it's a list. This will be updated when AtomLists are implemented -boconnor |
74611019 |
331 | if(ref($dbobject) eq 'Turnkey::Model::[% package.key FILTER ucfirst %]') { |
136556a6 |
332 | $self->focus("yes"); |
c00bb9f8 |
333 | return(_render_record($dbobject)); |
334 | } |
335 | else { return(_render_list($dbobject)); } |
336 | } |
337 | |
338 | sub _render_record { |
339 | my $dbobject = shift; |
340 | my @output = (); |
341 | my $row = {}; |
342 | my $field_hash = {}; |
343 | [% FOREACH field = packages.$pkey.columns_essential %] |
344 | $field_hash->{[% field %]} = $dbobject->[% field %](); |
345 | [% END %] |
74611019 |
346 | [% FOREACH field = packages.$pkey.columns_others %] |
347 | $field_hash->{[% field %]} = $dbobject->[% field %](); |
348 | [% END %] |
c00bb9f8 |
349 | $row->{data} = $field_hash; |
350 | $row->{id} = $dbobject->id(); |
351 | push @output, $row; |
352 | return(\@output); |
353 | } |
354 | |
355 | sub _render_list { |
356 | my $dbobject = shift; |
357 | my @output = (); |
b6d71d87 |
358 | my @objects = defined $dbobject ? $dbobject->[% package.key %]s : (); |
c00bb9f8 |
359 | foreach my $object (@objects) |
360 | { |
361 | my $row = {}; |
362 | my $field_hash = {}; |
363 | [% FOREACH field = packages.$pkey.columns_essential %] |
364 | $field_hash->{[% field %]} = $object->[% field %](); |
74611019 |
365 | [% END %] |
366 | [% FOREACH field = packages.$pkey.columns_others %] |
367 | $field_hash->{[% field %]} = $object->[% field %](); |
c00bb9f8 |
368 | [% END %] |
74611019 |
369 | |
c00bb9f8 |
370 | $row->{data} = $field_hash; |
371 | $row->{id} = $object->id(); |
372 | push @output, $row; |
373 | } |
374 | return(\@output); |
375 | } |
376 | |
377 | sub head { |
378 | return 1; |
379 | } |
380 | |
381 | 1; |
382 | |
383 | [% END %] |
384 | EOF |
385 | |
e12e1ffc |
386 | |
c00bb9f8 |
387 | my $turnkey_dbi_tt2 = <<EOF; |
388 | [% ####### MACRO START ###### %] |
389 | |
390 | [% MACRO printPackage(package) BLOCK %] |
391 | # -------------------------------------------- |
392 | package [% package.pkg_name %]; |
393 | use base '[% package.base %]'; |
394 | use Class::DBI::Pager; |
395 | |
396 | [% package.pkg_name %]->set_up_table('[% package.table %]'); |
397 | [% package.pkg_name %]->columns(Primary => qw/[% printList(package.columns_primary) %]/); |
398 | [% package.pkg_name %]->columns(Essential => qw/[% printList(package.columns_essential) %]/); |
399 | |
400 | [% printPKAccessors(package.columns_primary, package.table) %] |
401 | [% printHasMany(package.has_many, package.table) %] |
402 | [% printHasA(package.has_a, package.pkg_name) %] |
403 | |
404 | [% END %] |
405 | |
406 | [% MACRO printPKAccessors(array, name) BLOCK %] |
407 | # |
408 | # Primary key accessor |
409 | # |
410 | [% FOREACH item = array %] |
411 | sub [% name %] { |
412 | shift->[% item %]; |
413 | } |
414 | [% END %] |
415 | [% END %] |
416 | |
417 | [% MACRO printHasMany(hash, name) BLOCK %] |
418 | # |
419 | # Has Many |
420 | # |
421 | [% FOREACH group = hash %][% FOREACH item = group.value %][% FOREACH arr = item.value %] |
422 | # Key: [% group.key %] |
423 | # Relationship: [% item.key %] |
424 | [% IF item.key == 'fk_pluralized' %] |
425 | sub [% arr.table_name -%]s { |
426 | return shift->[% arr.table_name %]_[% arr.field_name %] |
427 | }; |
428 | [% ELSIF item.key == 'pluralized' %] |
429 | [% arr.ref_pkg %]->has_many('[% arr.table_name %]_[% arr.field_name %]', '[% arr.table_pkg_name %]' => '[% arr.field_name %]'); |
430 | [% ELSIF item.key == 'link_one_one' %] |
431 | [% FOREACH line = item.value %] |
432 | [% line %] |
433 | [% END %] |
434 | [% ELSIF item.key == 'link_many_one' %] |
435 | [% FOREACH line = item.value %] |
436 | [% line %] |
437 | [% END %] |
438 | [% ELSIF item.key == 'link_many_many' %] |
439 | [% FOREACH line = item.value %] |
440 | [% line %] |
441 | [% END %] |
442 | [% END %] |
443 | |
444 | [% END %][% END %][% END %][% END %] |
445 | |
446 | [% MACRO printHasA(hash, pkg_name) BLOCK %] |
447 | # |
448 | # Has A |
449 | # |
450 | [% #name %] |
451 | [% FOREACH item = hash %][% item %] |
452 | [% END %][% END %] |
453 | |
454 | [% MACRO printList(array) BLOCK %][% FOREACH item = array %][% item %] [% END %][% END %] |
455 | |
456 | |
457 | [% ###### DOCUMENT START ###### %] |
458 | |
74611019 |
459 | package Turnkey::Model::DBI; |
c00bb9f8 |
460 | |
461 | # Created by SQL::Translator::Producer::ClassDBI |
462 | # Template used AutoDBI.tt2 |
463 | |
464 | use strict; |
465 | use base qw(Class::DBI::Pg); |
466 | |
74611019 |
467 | Turnkey::Model::DBI->set_db('Main', '[% db_str %]', '[% db_user %]', '[% db_pass %]'); |
c00bb9f8 |
468 | |
fa93031a |
469 | sub search_ilike { shift->_do_search(ILIKE => @_) } |
470 | |
c00bb9f8 |
471 | [% FOREACH package = packages %] |
472 | [% printPackage(package.value) %] |
473 | [% END %] |
e12e1ffc |
474 | EOF |
c00bb9f8 |
475 | |
476 | my $turnkey_xml_tt2 = <<EOF; |
477 | <?xml version="1.0" encoding="UTF-8"?> |
74611019 |
478 | <!DOCTYPE Turnkey SYSTEM "Turnkey.dtd"> |
479 | <Turnkey> |
c00bb9f8 |
480 | |
481 | <!-- The basic layout is fixed --> |
74611019 |
482 | <container bgcolor="#dedbde" cellpadding="0" cellspacing="0" height="90%" orientation="vertical" type="root" width="100%" xlink:label="RootContainer"> |
c00bb9f8 |
483 | <container cellpadding="3" cellspacing="0" orientation="horizontal" type="container" height="100%" width="100%" xlink:label="MiddleContainer"> |
484 | <container align="center" cellpadding="2" cellspacing="0" class="leftbar" orientation="vertical" type="minor" width="0%" xlink:label="MidLeftContainer"/> |
485 | <container cellpadding="0" cellspacing="0" orientation="vertical" width="100%" type="major" xlink:label="MainContainer"/> |
486 | </container> |
487 | </container> |
488 | |
489 | <!-- Atom Classes --> |
490 | [% FOREACH package = linkable %] |
e12e1ffc |
491 | [% class = package.key | replace('Turnkey::Model::',''); class = class FILTER ucfirst; %] |
492 | <atom class="Turnkey::Atom::[% class %]" name="[% class %]" xlink:label="[% class %]Atom"/> |
c00bb9f8 |
493 | [% END %] |
494 | |
495 | <!-- Atom Bindings --> |
496 | <atomatombindings> |
497 | [% FOREACH focus_atom = linkable %] |
498 | [% FOREACH link_atom = focus_atom.value %] |
e12e1ffc |
499 | [% class = focus_atom.key | replace('Turnkey::Model::',''); class = class FILTER ucfirst; %] |
500 | <atomatombinding xlink:from="#[% class %]Atom" xlink:to="#[% link_atom.key FILTER ucfirst %]Atom" xlink:label="[% class %]Atom2[% link_atom.key FILTER ucfirst %]Atom"/> |
c00bb9f8 |
501 | [% END %] |
502 | [% END %] |
503 | </atomatombindings> |
504 | |
505 | <atomcontainerbindings> |
506 | [% FOREACH focus_atom = linkable %] |
74611019 |
507 | <atomcontainerbindingslayout xlink:label="Turnkey::Model::[% focus_atom.key FILTER ucfirst %]"> |
c00bb9f8 |
508 | [% FOREACH link_atom = focus_atom.value %] |
509 | <atomcontainerbinding xlink:from="#MidLeftContainer" xlink:label="MidLeftContainer2[% link_atom.key FILTER ucfirst %]Atom" xlink:to="#[% link_atom.key FILTER ucfirst %]Atom"/> |
510 | [% END %] |
511 | <atomcontainerbinding xlink:from="#MainContainer" xlink:label="MainContainer2[% focus_atom.key FILTER ucfirst %]Atom" xlink:to="#[% focus_atom.key FILTER ucfirst %]Atom"/> |
512 | </atomcontainerbindingslayout> |
513 | [% END %] |
514 | </atomcontainerbindings> |
515 | |
516 | <uribindings> |
74611019 |
517 | <uribinding uri="/" class="Turnkey::Util::Frontpage"/> |
c00bb9f8 |
518 | </uribindings> |
519 | |
520 | <classbindings> |
521 | [% FOREACH focus_atom = linkable %] |
e12e1ffc |
522 | [% class = focus_atom.key | replace('Turnkey::Model::','') ; class = class FILTER ucfirst %] |
523 | <classbinding class="Turnkey::Model::[% class %]" plugin="#[% class %]Atom" rank="0"/> |
c00bb9f8 |
524 | [% END %] |
525 | </classbindings> |
526 | |
74611019 |
527 | </Turnkey> |
c00bb9f8 |
528 | EOF |
529 | |
530 | my $turnkey_template_tt2 = <<'EOF'; |
531 | [% TAGS [- -] %] |
532 | [% MACRO renderpanel(panel,dbobject) BLOCK %] |
533 | <!-- begin panel: [% panel.label %] --> |
534 | <table border="0" width="[% panel.width %]" height="[% panel.height %]" bgcolor="[% panel.bgcolor %]" valign="top" cellpadding="[% panel.cellpadding %]" cellspacing="[% panel.cellspacing %]" align="[% panel.align %]" valign="[% panel.valign %]"> |
535 | <tr> |
536 | [% FOREACH p = panel.containers %] |
537 | [% IF p.can_render(panel) %] |
538 | <td valign="top" class="[% p.class %]" align="[% panel.align %]" height="[% p.height || 1 %]" width="[% p.width %]"> |
539 | [% IF p.type == 'Container' %] |
540 | [% renderpanel(p,dbobject) %] |
541 | [% ELSE %] |
74611019 |
542 | <table cellpadding="2" cellspacing="0" align="left" height="100%" width="100%"> |
c00bb9f8 |
543 | [% IF p.name %] |
74611019 |
544 | <tr bgcolor="#5aa5e2" height="1"> |
545 | <td><font class="font" color="#FFFFFF">[% p.name %][% IF panel.type == 'major' %]: [% dbobject.name %][% END %]</font></td> |
c00bb9f8 |
546 | <td align="right" width="0"><!--<nobr><img src="/images/v.gif"/><img src="/images/^.gif"/>[% IF p.delible == 'yes' %]<img src="/images/x.gif"/>[% END %]</nobr>--></td> |
547 | </tr> |
548 | [% END %] |
74611019 |
549 | <tr><td colspan="2" class="font" bgcolor="#FFFFFF"> |
c00bb9f8 |
550 | <!-- begin atom: [% p.label %] --> |
21b4dd44 |
551 | <table cellpadding="2" cellspacing="0" align="left" height="100%" width="100%"> |
552 | [% renderatom(p,dbobject) %] |
c00bb9f8 |
553 | </table> |
554 | </table> |
555 | [% END %] |
556 | </td> |
557 | [% IF panel.orientation == 'vertical' %] |
558 | </tr><tr> |
559 | [% END %] |
560 | [% END %] |
561 | [% END %] |
562 | </tr> |
563 | </table> |
564 | <!-- end panel: [% panel.label %] --> |
565 | [% END %] |
fa93031a |
566 | [% BLOCK make_linked_dbobject %] |
567 | [% PERL %] |
568 | $stash->set(linked_dbobject => [% class %]->retrieve([% id %])); |
569 | [% END %] |
570 | [% END %] |
b6d71d87 |
571 | [% MACRO obj2link(obj) SWITCH ref(obj) %] |
572 | [% CASE '' %] |
573 | [% obj %] |
574 | [% CASE DEFAULT %] |
575 | <a href="[% obj2url(obj) %]">[% obj %]</a> |
576 | [% END %] |
577 | [% MACRO obj2url(obj) SWITCH obj %] |
578 | [% CASE DEFAULT %] |
579 | /?id=[% obj %];class=[% ref(obj) %] |
580 | [% END %] |
fa93031a |
581 | [% MACRO obj2desc(obj) SWITCH ref(obj) %] |
582 | [% CASE '' %] |
583 | [% obj %] |
584 | [% CASE DEFAULT %] |
585 | [% obj %] |
586 | [% END %] |
c00bb9f8 |
587 | [% MACRO renderatom(atom, dbobject) SWITCH atom.name %] |
588 | [- FOREACH package = linkable -] |
589 | [% CASE '[- package.key FILTER ucfirst -]' %] |
136556a6 |
590 | [% render[- package.key FILTER ucfirst -]Atom(atom, dbobject) %] |
c00bb9f8 |
591 | [- END -] |
592 | [% CASE DEFAULT %] |
136556a6 |
593 | [% renderlist(atom, dbobject) %] |
c00bb9f8 |
594 | [% END %] |
595 | [- FOREACH package = linkable -] |
136556a6 |
596 | [% MACRO render[- package.key FILTER ucfirst -]Atom(atom, dbobject) BLOCK %] |
597 | [% lstArr = atom.render(dbobject) %] |
598 | [% rowcount = 0 %] |
599 | [% IF atom.focus == "yes" %] |
c00bb9f8 |
600 | [% FOREACH record = lstArr %] |
b6d71d87 |
601 | [% field = record.data %] |
c00bb9f8 |
602 | [- pname = package.key FILTER ucfirst -] |
74611019 |
603 | [- pkey = "Turnkey::Model::${pname}" -] |
b6d71d87 |
604 | [% id = record.id %] |
605 | [- first = 1 -] |
c00bb9f8 |
606 | [- FOREACH field = packages.$pkey.columns_essential -] |
b6d71d87 |
607 | [- IF first -] |
d5de365f |
608 | <tr><td><b>[- field -]</b></td><td>[% obj2link(field.[- field -]) %]</td></tr> |
b6d71d87 |
609 | [- first = 0 -] |
610 | [- ELSE -] |
611 | <tr><td><b>[- field -]</b></td><td>[% obj2link(field.[- field -]) %]</td></tr> |
612 | [- END -] |
c00bb9f8 |
613 | [- END -] |
74611019 |
614 | [- FOREACH field = packages.$pkey.columns_others -] |
b6d71d87 |
615 | <tr><td><b>[- field -]</b></td><td>[% obj2link(field.[- field -]) %]</td></tr> |
74611019 |
616 | [- END -] |
136556a6 |
617 | [% IF (rowcount > 1) %] <tr><td colspan="2"><hr></td></tr> [% END %] |
618 | [% rowcount = rowcount + 1 %] |
619 | [% END %] |
620 | [% ELSE %] |
fa93031a |
621 | <tr><td><ul> |
136556a6 |
622 | [% FOREACH record = lstArr %] |
fa93031a |
623 | [% class = ref(atom) | replace('::Atom::', '::Model::') %] |
624 | [% id = record.id %] |
625 | [% PROCESS make_linked_dbobject %] |
626 | <li style="margin-left: -20px; list-style: circle;">[% obj2link(linked_dbobject) %]</li> |
136556a6 |
627 | [% END %] |
fa93031a |
628 | </ul></td></tr> |
c00bb9f8 |
629 | [% END %] |
630 | [% END %] |
631 | [- END -] |
136556a6 |
632 | [% MACRO renderlist(atom, dbobject) BLOCK %] |
633 | [% lstArr = atom.render(dbobject) %] |
c00bb9f8 |
634 | [% FOREACH item = lstArr %] |
635 | <tr>[% item %]</tr> |
636 | [% END %] |
637 | [% END %] |
638 | EOF |
639 | |
640 | sub translateForm |
641 | { |
642 | my $t = shift; |
643 | my $output = shift; |
644 | my $args = $t->producer_args; |
645 | my $tt2 = $args->{'template'}; |
646 | my $tt2Ref; |
647 | if ($tt2 eq 'atom') { $tt2Ref = \$turnkey_atom_tt2; } |
648 | if ($tt2 eq 'dbi') { $tt2Ref = \$turnkey_dbi_tt2; } |
649 | if ($tt2 eq 'xml') { $tt2Ref = \$turnkey_xml_tt2; } |
650 | if ($tt2 eq 'template') { $tt2Ref = \$turnkey_template_tt2; } |
651 | |
652 | my $vars = { |
653 | packages => $output->{packages}, |
654 | linkable => $output->{linkable}, |
655 | linktable => $output->{linktable}, |
656 | db_str => $args->{db_str}, |
657 | db_user => $args->{db_user}, |
658 | db_pass => $args->{db_pass}, |
659 | }; |
660 | my $config = { |
661 | EVAL_PERL => 1, # evaluate Perl code blocks |
662 | }; |
663 | |
664 | # create Template object |
665 | my $template = Template->new($config); |
666 | |
667 | my $result; |
668 | # specify input filename, or file handle, text reference, etc. |
669 | # process input template, substituting variables |
670 | $template->process($tt2Ref, $vars, \$result) || die $template->error(); |
671 | return($result); |
672 | } |
673 | |
674 | 1; |
675 | |
676 | # ------------------------------------------------------------------- |
677 | |
678 | =pod |
679 | |
680 | =head1 NAME |
681 | |
682 | SQL::Translator::Producer::ClassDBI - create Class::DBI classes from schema |
683 | |
684 | =head1 SYNOPSIS |
685 | |
686 | Use this producer as you would any other from SQL::Translator. See |
687 | L<SQL::Translator> for details. |
688 | |
689 | This package utilizes SQL::Translator's formatting methods |
690 | format_package_name(), format_pk_name(), format_fk_name(), and |
691 | format_table_name() as it creates classes, one per table in the schema |
692 | provided. An additional base class is also created for database connectivity |
693 | configuration. See L<Class::DBI> for details on how this works. |
694 | |
695 | =head1 AUTHORS |
696 | |
697 | Allen Day E<lt>allenday@ucla.eduE<gt> |
698 | Ying Zhang E<lt>zyolive@yahoo.comE<gt>, |
699 | Ken Y. Clark E<lt>kclark@cpan.orgE<gt>, |
700 | Brian O'Connor E<lt>brian.oconnor@excite.comE<gt>. |