/[Frey]/trunk/lib/Frey/Class/Schematize.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/lib/Frey/Class/Schematize.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1093 - (hide annotations)
Sun Jun 28 17:42:51 2009 UTC (14 years, 11 months ago) by dpavlin
File size: 2650 byte(s)
added Schematize which create SQL schema for Moose class
1 dpavlin 1093 package Frey::Class::Schematize;
2     use Moose;
3    
4     extends 'Frey::Class::Loader';
5     extends 'Frey::PPI';
6     with 'Frey::Web';
7     #with 'Frey::Storage';
8    
9     has class => (
10     is => 'rw',
11     isa => 'Str',
12     required => 1,
13     default => 'App::RoomReservation::Reservation',
14     );
15    
16     sub create_table_as_markup {
17     my ($self) = @_;
18     qq|<pre>| . $self->create_table . qq|</pre>|;
19     }
20    
21     use DBI;
22    
23     sub create_table {
24     my ($self) = @_;
25    
26     my ( $meta, $is_role, $instance ) = $self->class_meta( $self->class );
27    
28     my $columns;
29     map {
30     $columns->{ $_->name } = attribute($_);
31     } $meta->get_all_attributes;
32    
33     my @order = $self->attribute_order;
34    
35     return
36     header($meta)
37     . join(",\n\t",
38     "\tid SERIAL",
39     map { $columns->{$_} } @order
40     )
41     . footer()
42     ;
43    
44     }
45    
46     sub class_to_table {
47     my $class = shift;
48     $class =~ s{App::[^:]+::}{};
49     my $table = lc $class;
50     $table =~ s/::/_/g;
51     return $table;
52     }
53    
54     sub header {
55     my $meta = shift;
56    
57     my $name = class_to_table($meta->name);
58    
59     return "CREATE TABLE $name (\n";
60     }
61    
62     sub footer { "\n);\n" }
63    
64     sub attribute {
65     my $attribute = shift;
66     my @constraints;
67    
68     push @constraints, type_of($attribute);
69     push @constraints, 'NOT NULL' if $attribute->is_required;
70     push @constraints, default_of($attribute);
71     push @constraints, foreign_key_of($attribute);
72    
73     return join ' ', $attribute->name, @constraints;
74     }
75    
76     sub type_of {
77     my $attribute = shift;
78    
79     return if !$attribute->has_type_constraint;
80     my $tc = $attribute->type_constraint;
81    
82     my @type_mapping = (
83     [Int => 'INTEGER'],
84     [Num => 'REAL'],
85     [Str => 'TEXT'],
86     [Bool => 'BOOLEAN'],
87     );
88    
89     for (@type_mapping) {
90     my ($moose_type, $sql_type) = @$_;
91     return $sql_type
92     if $tc->is_a_type_of($moose_type);
93     }
94    
95     return;
96     }
97    
98     sub default_of {
99     my $attribute = shift;
100    
101     return unless $attribute->has_default;
102    
103     my $default;
104     if ( $attribute->is_default_a_coderef ) {
105     $default = eval { $attribute->default->(); };
106     if ( $@ ) {
107     warn "can't eval default: $@";
108     return;
109     }
110     my $type = type_of($attribute);
111     if ( $type eq 'BOOLEAN' ) {
112     return ('DEFAULT', $default ? 'TRUE' : 'FALSE');
113     }
114     } else {
115     $default = $attribute->default;
116     }
117    
118     if ($default =~ /^\d+$/ ) {
119     return ('DEFAULT', $default);
120     }
121    
122     return ('DEFAULT', DBD::_::db->quote($default));
123     }
124    
125     sub foreign_key_of {
126     my $attribute = shift;
127    
128     return if !$attribute->has_type_constraint;
129     my $tc = $attribute->type_constraint;
130    
131     return if !$tc->isa('Moose::Meta::TypeConstraint::Class');
132     my $table = class_to_table($tc->class);
133    
134     return ('REFERENCES', $table, '(id)');
135     }
136    
137     =head1 SEE ALSO
138    
139     Based on code from L<http://github.com/sartak/mmop/raw/master/2-schema-generator.pl>
140    
141     L<http://blog.sartak.org/2009/06/mooses-mop-schematize.html>
142    
143     =cut
144    
145     1;

  ViewVC Help
Powered by ViewVC 1.1.26