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