File Coverage

blib/lib/Teng/Schema/Declare.pm
Criterion Covered Total %
statement 96 97 98.9
branch 17 18 94.4
condition 2 3 66.6
subroutine 22 22 100.0
pod 5 5 100.0
total 142 145 97.9


line stmt bran cond sub pod time code
1             use strict;
2 69     69   318715 use warnings;
  69         155  
  69         1716  
3 69     69   311 use parent qw(Exporter);
  69         115  
  69         1900  
4 69     69   989 use Teng::Schema;
  69         639  
  69         324  
5 69     69   4600 use Teng::Schema::Table;
  69         131  
  69         1406  
6 69     69   23136  
  69         213  
  69         21990  
7             our @EXPORT = qw(
8             schema
9             name
10             table
11             pk
12             columns
13             row_class
14             base_row_class
15             inflate
16             deflate
17             default_row_class_prefix
18             );
19             our $CURRENT_SCHEMA_CLASS;
20              
21             my ($code, $schema_class) = @_;
22             local $CURRENT_SCHEMA_CLASS = $schema_class;
23 5     5 1 10157 $code->();
24 5         11 _current_schema();
25 5         15 }
26 5         91  
27             my $current = _current_schema();
28             $current->{__base_row_class} = $_[0];
29             }
30 1     1 1 6  
31 1         7 _current_schema()->{__default_row_class_prefix} = $_[0];
32             }
33              
34             my $table_name = shift;
35 2     2 1 7  
36             my $prefix = defined(_current_schema()->{__default_row_class_prefix}) ? _current_schema()->{__default_row_class_prefix} : do {
37             (my $caller = caller(1)) =~ s/::Schema$//;
38             join '::', $caller, 'Row';
39 242     242 1 320 };
40             join '::', $prefix, Teng::Schema::camelize($table_name);
41 242 100       383 }
42 240         1222  
43 240         689 my $class = __PACKAGE__;
44             my $schema_class;
45 242         607  
46             if ( $CURRENT_SCHEMA_CLASS ) {
47             $schema_class = $CURRENT_SCHEMA_CLASS;
48             } else {
49 495     495   998 my $i = 1;
50 495         1270 while ( $schema_class = caller($i++) ) {
51             if ( ! $schema_class->isa( $class ) ) {
52 495 100       833 last;
53 3         4 }
54             }
55 492         560 }
56 492         1228  
57 735 100       2978 if (! $schema_class) {
58 492         789 Carp::confess( "PANIC: cannot find a package name that is not ISA $class" );
59             }
60              
61             no warnings 'once';
62             if (! $schema_class->isa( 'Teng::Schema' ) ) {
63 495 50       824 no strict 'refs';
64 0         0 push @{ "$schema_class\::ISA" }, 'Teng::Schema';
65             my $schema = $schema_class->new();
66             $schema_class->set_default_instance( $schema );
67 69     69   482 }
  69         134  
  69         3833  
68 495 100       1223  
69 69     69   531 $schema_class->instance();
  69         182  
  69         10434  
70 72         128 }
  72         826  
71 72         497  
72 72         430 sub pk(@);
73             sub columns(@);
74             sub name ($);
75 495         1091 sub row_class ($);
76             sub inflate_rule ($@);
77             my $code = shift;
78             my $current = _current_schema();
79              
80             my (
81             $table_name,
82             @table_pk,
83             @table_columns,
84 243     243 1 40640 @inflate,
85 243         528 @deflate,
86             $row_class,
87             );
88 243         511 no warnings 'redefine';
89            
90             my $dest_class = caller();
91             no strict 'refs';
92             no warnings 'once';
93             local *{"$dest_class\::name"} = sub ($) {
94             $table_name = shift;
95 69     69   460 $row_class ||= row_namespace($table_name);
  69         153  
  69         2974  
96             };
97 243         363 local *{"$dest_class\::pk"} = sub (@) { @table_pk = @_ };
98 69     69   371 local *{"$dest_class\::columns"} = sub (@) { @table_columns = @_ };
  69         146  
  69         2141  
99 69     69   401 local *{"$dest_class\::row_class"} = sub (@) { $row_class = shift };
  69         136  
  69         26838  
100 243         735 local *{"$dest_class\::inflate"} = sub ($&) {
101 243     243   710 my ($rule, $code) = @_;
102 243   66     719 if (ref $rule ne 'Regexp') {
103 243         905 $rule = qr/^\Q$rule\E$/;
104 243     238   624 }
  243         561  
  238         1061  
105 243     242   530 push @inflate, ($rule, $code);
  243         563  
  242         1296  
106 243     3   524 };
  243         559  
  3         10  
107 243         562 local *{"$dest_class\::deflate"} = sub ($&) {
108 17     17   90 my ($rule, $code) = @_;
109 17 100       37 if (ref $rule ne 'Regexp') {
110 13         165 $rule = qr/^\Q$rule\E$/;
111             }
112 17         60 push @deflate, ($rule, $code);
113 243         637 };
114 243         502  
115 17     17   122 $code->();
116 17 100       46  
117 13         105 my @col_names;
118             my %sql_types;
119 17         41 while ( @table_columns ) {
120 243         603 my $col_name = shift @table_columns;
121             if (ref $col_name) {
122 243         678 my $sql_type = $col_name->{type};
123             $col_name = $col_name->{name};
124 243         333 $sql_types{$col_name} = $sql_type;
125             }
126 243         537 push @col_names, $col_name;
127 725         899 }
128 725 100       1125  
129 168         244 $current->add_table(
130 168         224 Teng::Schema::Table->new(
131 168         314 columns => \@col_names,
132             name => $table_name,
133 725         1336 primary_keys => \@table_pk,
134             sql_types => \%sql_types,
135             inflators => \@inflate,
136             deflators => \@deflate,
137             row_class => $row_class,
138             ($current->{__base_row_class} ? (base_row_class => $current->{__base_row_class}) : ()),
139             )
140             );
141             }
142              
143             1;
144              
145 243 100       1103  
146             =head1 NAME
147              
148             Teng::Schema::Declare - DSL For Declaring Teng Schema
149              
150             =head1 NORMAL USE
151              
152             package MyDB::Schema;
153             use strict;
154             use warnings;
155             use Teng::Schema::Declare;
156              
157             table {
158             name "your_table_name";
159             pk "primary_key";
160             columns qw( col1 col2 col3 );
161             inflate 'col1' => sub {
162             my ($col_value) = @_;
163             return MyDB::Class->new(name => $col_value);
164             };
165             deflate 'col1' => sub {
166             my ($col_value) = @_;
167             return ref $col_value ? $col_value->name : $col_value;
168             };
169             row_class 'MyDB::Row'; # optional
170             };
171              
172             =head1 INLINE DECLARATION
173              
174             use Teng::Schema::Declare;
175             my $schema = schema {
176             table {
177             name "your_table_name";
178             columns qw( col1 col2 col3 );
179             };
180             } "MyDB::Schema";
181              
182             =head1 METHODS
183              
184             =over 4
185              
186             =item C<schema>
187              
188             schema data creation wrapper.
189              
190             =item C<table>
191              
192             set table name
193              
194             =item C<pk>
195              
196             set primary key
197              
198             =item C<columns>
199              
200             set columns
201              
202             =item C<inflate_rule>
203              
204             set inflate rule
205              
206             =item C<row_namespace>
207              
208             create Row class namespace
209              
210             =item C<base_row_class>
211              
212             Specify the default base row class with Teng::Schema::Declare.
213              
214             Default value is L<Teng::Row>.
215              
216             This option is useful when you adds features for My::DB::Row class.
217              
218             =item C<default_row_class_prefix>
219              
220             Specify the default prefix of row class.
221              
222             C<row_class> of each table definition has priority over C<default_row_class_prefix>.
223              
224             e.g.:
225              
226             use Teng::Schema::Declare;
227             my $schema = schema {
228             default_row_class_prefix 'My::Entity';
229             table {
230             name 'user';
231             column qw(name);
232             };
233             };
234             $schema->get_row_class('user'); # => My::Entity::User
235              
236             Default value is determined by the schema class.
237              
238             e.g.:
239              
240             package My::DB::Schema;
241             use Teng::Schema::Declare;
242             table {
243             name 'user';
244             column qw(name);
245             };
246              
247             __PACKAGE__->instance->get_row_class('user'); # => My::DB::Row::User
248             1;
249              
250             =back
251              
252             =cut
253