line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Fey::Meta::Class::Table; |
2
|
|
|
|
|
|
|
|
3
|
10
|
|
|
10
|
|
50
|
use strict; |
|
10
|
|
|
|
|
26
|
|
|
10
|
|
|
|
|
334
|
|
4
|
10
|
|
|
10
|
|
50
|
use warnings; |
|
10
|
|
|
|
|
15
|
|
|
10
|
|
|
|
|
273
|
|
5
|
10
|
|
|
10
|
|
44
|
use namespace::autoclean; |
|
10
|
|
|
|
|
15
|
|
|
10
|
|
|
|
|
62
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.47'; |
8
|
|
|
|
|
|
|
|
9
|
10
|
|
|
10
|
|
755
|
use Fey::Exceptions qw( param_error ); |
|
10
|
|
|
|
|
15
|
|
|
10
|
|
|
|
|
772
|
|
10
|
10
|
|
|
10
|
|
4615
|
use Fey::Hash::ColumnsKey; |
|
10
|
|
|
|
|
22
|
|
|
10
|
|
|
|
|
313
|
|
11
|
10
|
|
|
10
|
|
4088
|
use Fey::Object::Policy; |
|
10
|
|
|
|
|
43
|
|
|
10
|
|
|
|
|
442
|
|
12
|
10
|
|
|
10
|
|
6411
|
use Fey::Meta::Attribute::FromInflator; |
|
10
|
|
|
|
|
196
|
|
|
10
|
|
|
|
|
657
|
|
13
|
10
|
|
|
10
|
|
7131
|
use Fey::Meta::Attribute::FromColumn; |
|
10
|
|
|
|
|
39
|
|
|
10
|
|
|
|
|
537
|
|
14
|
10
|
|
|
10
|
|
6530
|
use Fey::Meta::Attribute::FromSelect; |
|
10
|
|
|
|
|
42
|
|
|
10
|
|
|
|
|
963
|
|
15
|
10
|
|
|
10
|
|
3603
|
use Fey::Meta::Class::Schema; |
|
10
|
|
|
|
|
37
|
|
|
10
|
|
|
|
|
506
|
|
16
|
10
|
|
|
10
|
|
6803
|
use Fey::Meta::HasOne::ViaFK; |
|
10
|
|
|
|
|
44
|
|
|
10
|
|
|
|
|
489
|
|
17
|
10
|
|
|
10
|
|
941101
|
use Fey::Meta::HasOne::ViaSelect; |
|
10
|
|
|
|
|
47
|
|
|
10
|
|
|
|
|
1143
|
|
18
|
10
|
|
|
10
|
|
6325
|
use Fey::Meta::HasMany::ViaFK; |
|
10
|
|
|
|
|
43
|
|
|
10
|
|
|
|
|
460
|
|
19
|
10
|
|
|
10
|
|
6094
|
use Fey::Meta::HasMany::ViaSelect; |
|
10
|
|
|
|
|
46
|
|
|
10
|
|
|
|
|
457
|
|
20
|
10
|
|
|
10
|
|
6461
|
use Fey::Meta::Method::Constructor; |
|
10
|
|
|
|
|
38
|
|
|
10
|
|
|
|
|
557
|
|
21
|
10
|
|
|
10
|
|
6161
|
use Fey::Meta::Method::FromSelect; |
|
10
|
|
|
|
|
40
|
|
|
10
|
|
|
|
|
576
|
|
22
|
|
|
|
|
|
|
use Fey::ORM::Types |
23
|
10
|
|
|
10
|
|
94
|
qw( Bool ClassName CodeRef DoesHasMany DoesHasOne HashRef Object ); |
|
10
|
|
|
|
|
20
|
|
|
10
|
|
|
|
|
114
|
|
24
|
10
|
|
|
10
|
|
86016
|
use List::AllUtils qw( all ); |
|
10
|
|
|
|
|
26
|
|
|
10
|
|
|
|
|
794
|
|
25
|
10
|
|
|
10
|
|
73
|
use Try::Tiny (); |
|
10
|
|
|
|
|
25
|
|
|
10
|
|
|
|
|
254
|
|
26
|
|
|
|
|
|
|
|
27
|
10
|
|
|
10
|
|
54
|
use Moose; |
|
10
|
|
|
|
|
19
|
|
|
10
|
|
|
|
|
94
|
|
28
|
10
|
|
|
10
|
|
47109
|
use MooseX::ClassAttribute; |
|
10
|
|
|
|
|
21
|
|
|
10
|
|
|
|
|
107
|
|
29
|
10
|
|
|
10
|
|
45847
|
use MooseX::SemiAffordanceAccessor; |
|
10
|
|
|
|
|
27
|
|
|
10
|
|
|
|
|
96
|
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
extends 'Moose::Meta::Class'; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
class_has '_ClassToTableMap' => ( |
34
|
|
|
|
|
|
|
traits => ['Hash'], |
35
|
|
|
|
|
|
|
is => 'ro', |
36
|
|
|
|
|
|
|
isa => HashRef ['Fey::Table'], |
37
|
|
|
|
|
|
|
default => sub { {} }, |
38
|
|
|
|
|
|
|
lazy => 1, |
39
|
|
|
|
|
|
|
handles => { |
40
|
|
|
|
|
|
|
TableForClass => 'get', |
41
|
|
|
|
|
|
|
_SetTableForClass => 'set', |
42
|
|
|
|
|
|
|
_ClassHasTable => 'exists', |
43
|
|
|
|
|
|
|
}, |
44
|
|
|
|
|
|
|
); |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
has '_object_cache_is_enabled' => ( |
47
|
|
|
|
|
|
|
is => 'rw', |
48
|
|
|
|
|
|
|
isa => Bool, |
49
|
|
|
|
|
|
|
lazy => 1, |
50
|
|
|
|
|
|
|
default => 0, |
51
|
|
|
|
|
|
|
); |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
has '_object_cache' => ( |
54
|
|
|
|
|
|
|
is => 'ro', |
55
|
|
|
|
|
|
|
isa => HashRef [Object], |
56
|
|
|
|
|
|
|
lazy => 1, |
57
|
|
|
|
|
|
|
default => sub { {} }, |
58
|
|
|
|
|
|
|
clearer => '_clear_object_cache', |
59
|
|
|
|
|
|
|
); |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
has 'table' => ( |
62
|
|
|
|
|
|
|
is => 'rw', |
63
|
|
|
|
|
|
|
isa => 'Fey::Table', |
64
|
|
|
|
|
|
|
writer => '_set_table', |
65
|
|
|
|
|
|
|
predicate => '_has_table', |
66
|
|
|
|
|
|
|
); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
has 'inflators' => ( |
69
|
|
|
|
|
|
|
traits => ['Hash'], |
70
|
|
|
|
|
|
|
is => 'ro', |
71
|
|
|
|
|
|
|
isa => HashRef [CodeRef], |
72
|
|
|
|
|
|
|
default => sub { {} }, |
73
|
|
|
|
|
|
|
lazy => 1, |
74
|
|
|
|
|
|
|
handles => { |
75
|
|
|
|
|
|
|
_add_inflator => 'set', |
76
|
|
|
|
|
|
|
has_inflator => 'exists', |
77
|
|
|
|
|
|
|
}, |
78
|
|
|
|
|
|
|
); |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
has 'deflators' => ( |
81
|
|
|
|
|
|
|
traits => ['Hash'], |
82
|
|
|
|
|
|
|
is => 'ro', |
83
|
|
|
|
|
|
|
isa => HashRef [CodeRef], |
84
|
|
|
|
|
|
|
default => sub { {} }, |
85
|
|
|
|
|
|
|
lazy => 1, |
86
|
|
|
|
|
|
|
handles => { |
87
|
|
|
|
|
|
|
deflator_for => 'get', |
88
|
|
|
|
|
|
|
_add_deflator => 'set', |
89
|
|
|
|
|
|
|
has_deflator => 'exists', |
90
|
|
|
|
|
|
|
}, |
91
|
|
|
|
|
|
|
); |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
has 'schema_class' => ( |
94
|
|
|
|
|
|
|
is => 'ro', |
95
|
|
|
|
|
|
|
isa => ClassName, |
96
|
|
|
|
|
|
|
lazy => 1, |
97
|
|
|
|
|
|
|
default => sub { |
98
|
|
|
|
|
|
|
Fey::Meta::Class::Schema->ClassForSchema( $_[0]->table()->schema() ); |
99
|
|
|
|
|
|
|
}, |
100
|
|
|
|
|
|
|
); |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
has 'policy' => ( |
103
|
|
|
|
|
|
|
is => 'rw', |
104
|
|
|
|
|
|
|
isa => 'Fey::Object::Policy', |
105
|
|
|
|
|
|
|
default => sub { Fey::Object::Policy->new() }, |
106
|
|
|
|
|
|
|
); |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
has '_has_ones' => ( |
109
|
|
|
|
|
|
|
traits => ['Hash'], |
110
|
|
|
|
|
|
|
is => 'ro', |
111
|
|
|
|
|
|
|
isa => HashRef [DoesHasOne], |
112
|
|
|
|
|
|
|
default => sub { {} }, |
113
|
|
|
|
|
|
|
lazy => 1, |
114
|
|
|
|
|
|
|
handles => { |
115
|
|
|
|
|
|
|
_has_one => 'get', |
116
|
|
|
|
|
|
|
_add_has_one => 'set', |
117
|
|
|
|
|
|
|
_has_has_one => 'exists', |
118
|
|
|
|
|
|
|
has_ones => 'values', |
119
|
|
|
|
|
|
|
_remove_has_one => 'delete', |
120
|
|
|
|
|
|
|
}, |
121
|
|
|
|
|
|
|
); |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
has '_has_manies' => ( |
124
|
|
|
|
|
|
|
traits => ['Hash'], |
125
|
|
|
|
|
|
|
is => 'ro', |
126
|
|
|
|
|
|
|
isa => HashRef [DoesHasMany], |
127
|
|
|
|
|
|
|
default => sub { {} }, |
128
|
|
|
|
|
|
|
lazy => 1, |
129
|
|
|
|
|
|
|
handles => { |
130
|
|
|
|
|
|
|
_has_many => 'get', |
131
|
|
|
|
|
|
|
_add_has_many => 'set', |
132
|
|
|
|
|
|
|
_has_has_many => 'exists', |
133
|
|
|
|
|
|
|
has_manies => 'values', |
134
|
|
|
|
|
|
|
_remove_has_many => 'delete', |
135
|
|
|
|
|
|
|
}, |
136
|
|
|
|
|
|
|
); |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
has '_select_sql_cache' => ( |
139
|
|
|
|
|
|
|
is => 'ro', |
140
|
|
|
|
|
|
|
isa => 'Fey::Hash::ColumnsKey', |
141
|
|
|
|
|
|
|
lazy => 1, |
142
|
|
|
|
|
|
|
default => sub { Fey::Hash::ColumnsKey->new() }, |
143
|
|
|
|
|
|
|
); |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
has '_sql_string_cache' => ( |
146
|
|
|
|
|
|
|
is => 'ro', |
147
|
|
|
|
|
|
|
isa => HashRef [HashRef], |
148
|
|
|
|
|
|
|
lazy => 1, |
149
|
|
|
|
|
|
|
default => sub { |
150
|
|
|
|
|
|
|
{ {} } |
151
|
|
|
|
|
|
|
}, |
152
|
|
|
|
|
|
|
); |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
has '_select_by_pk_sql' => ( |
155
|
|
|
|
|
|
|
is => 'ro', |
156
|
|
|
|
|
|
|
isa => 'Fey::SQL::Select', |
157
|
|
|
|
|
|
|
lazy => 1, |
158
|
|
|
|
|
|
|
default => sub { return $_[0]->name()->_MakeSelectByPKSQL() }, |
159
|
|
|
|
|
|
|
); |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
has '_count_sql' => ( |
162
|
|
|
|
|
|
|
is => 'ro', |
163
|
|
|
|
|
|
|
isa => 'Fey::SQL::Select', |
164
|
|
|
|
|
|
|
lazy => 1, |
165
|
|
|
|
|
|
|
builder => '_build_count_sql', |
166
|
|
|
|
|
|
|
); |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub ClassForTable { |
169
|
27
|
|
|
27
|
1
|
905
|
my $class = shift; |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
return @_ == 1 |
172
|
|
|
|
|
|
|
? $class->_ClassForTable(@_) |
173
|
27
|
100
|
|
|
|
258
|
: map { $class->_ClassForTable($_) } @_; |
|
2
|
|
|
|
|
84
|
|
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
sub _ClassForTable { |
177
|
28
|
|
|
28
|
|
50
|
my $class = shift; |
178
|
28
|
|
|
|
|
47
|
my $table = shift; |
179
|
|
|
|
|
|
|
|
180
|
28
|
|
|
|
|
1022
|
my $map = $class->_ClassToTableMap(); |
181
|
|
|
|
|
|
|
|
182
|
28
|
|
|
|
|
54
|
for my $class_name ( keys %{$map} ) { |
|
28
|
|
|
|
|
114
|
|
183
|
27
|
|
|
|
|
187
|
my $potential_table = $map->{$class_name}; |
184
|
|
|
|
|
|
|
|
185
|
27
|
100
|
100
|
|
|
629
|
return $class_name |
186
|
|
|
|
|
|
|
if $potential_table->name() eq $table->name() |
187
|
|
|
|
|
|
|
&& $potential_table->schema()->name() eq $table->schema()->name(); |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
24
|
|
|
|
|
254
|
return; |
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
## no critic (Subroutines::ProhibitUnusedPrivateSubroutines) |
194
|
|
|
|
|
|
|
sub _search_cache { |
195
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
196
|
0
|
|
|
|
|
0
|
my $p = shift; |
197
|
|
|
|
|
|
|
|
198
|
0
|
|
|
|
|
0
|
my $cache = $self->_object_cache(); |
199
|
|
|
|
|
|
|
|
200
|
0
|
|
|
|
|
0
|
for my $key ( @{ $self->table()->candidate_keys() } ) { |
|
0
|
|
|
|
|
0
|
|
201
|
0
|
|
|
|
|
0
|
my @names = map { $_->name() } @{$key}; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
202
|
0
|
0
|
|
0
|
|
0
|
next unless all { defined $p->{$_} } @names; |
|
0
|
|
|
|
|
0
|
|
203
|
|
|
|
|
|
|
|
204
|
0
|
|
|
|
|
0
|
my $cache_key = join "\0", map { ( $_, $p->{$_} ) } sort @names; |
|
0
|
|
|
|
|
0
|
|
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
return $cache->{$cache_key} |
207
|
0
|
0
|
|
|
|
0
|
if exists $cache->{$cache_key}; |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
sub _write_to_cache { |
212
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
213
|
0
|
|
|
|
|
0
|
my $object = shift; |
214
|
|
|
|
|
|
|
|
215
|
0
|
|
|
|
|
0
|
my $cache = $self->_object_cache(); |
216
|
|
|
|
|
|
|
|
217
|
0
|
|
|
|
|
0
|
for my $key ( @{ $self->table()->candidate_keys() } ) { |
|
0
|
|
|
|
|
0
|
|
218
|
0
|
|
|
|
|
0
|
my @names = map { $_->name() } @{$key}; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
219
|
|
|
|
|
|
|
|
220
|
0
|
|
|
|
|
0
|
my @pieces = map { ( $_, $object->$_() ) } sort @names; |
|
0
|
|
|
|
|
0
|
|
221
|
|
|
|
|
|
|
|
222
|
0
|
0
|
|
0
|
|
0
|
next unless all {defined} @pieces; |
|
0
|
|
|
|
|
0
|
|
223
|
|
|
|
|
|
|
|
224
|
0
|
|
|
|
|
0
|
my $cache_key = join "\0", @pieces; |
225
|
|
|
|
|
|
|
|
226
|
0
|
|
|
|
|
0
|
$cache->{$cache_key} = $object; |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
sub _associate_table { |
231
|
26
|
|
|
26
|
|
54
|
my $self = shift; |
232
|
26
|
|
|
|
|
43
|
my $table = shift; |
233
|
26
|
|
|
|
|
43
|
my $context = shift; |
234
|
|
|
|
|
|
|
|
235
|
26
|
|
|
|
|
143
|
my $caller = $self->name(); |
236
|
|
|
|
|
|
|
|
237
|
26
|
100
|
|
|
|
1040
|
param_error 'Cannot call has_table() more than once per class' |
238
|
|
|
|
|
|
|
if $self->_has_table(); |
239
|
|
|
|
|
|
|
|
240
|
25
|
100
|
|
|
|
143
|
param_error 'Cannot associate the same table with multiple classes' |
241
|
|
|
|
|
|
|
if $self->ClassForTable($table); |
242
|
|
|
|
|
|
|
|
243
|
24
|
100
|
|
|
|
760
|
param_error 'A table object passed to has_table() must have a schema' |
244
|
|
|
|
|
|
|
unless $table->has_schema(); |
245
|
|
|
|
|
|
|
|
246
|
23
|
|
|
|
|
716
|
my $class = Fey::Meta::Class::Schema->ClassForSchema( $table->schema() ); |
247
|
|
|
|
|
|
|
|
248
|
23
|
50
|
66
|
|
|
696
|
param_error 'You must load your schema class before calling has_table()' |
|
|
|
66
|
|
|
|
|
249
|
|
|
|
|
|
|
unless $class |
250
|
|
|
|
|
|
|
&& $class->can('meta') |
251
|
|
|
|
|
|
|
&& $class->meta()->_has_schema(); |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
param_error |
254
|
|
|
|
|
|
|
'A table object passed to has_table() must have at least one key' |
255
|
22
|
100
|
|
|
|
45
|
unless @{ $table->primary_key() }; |
|
22
|
|
|
|
|
578
|
|
256
|
|
|
|
|
|
|
|
257
|
21
|
|
|
|
|
9648
|
$self->_SetTableForClass( $self->name() => $table ); |
258
|
|
|
|
|
|
|
|
259
|
21
|
|
|
|
|
855
|
$self->_set_table($table); |
260
|
|
|
|
|
|
|
|
261
|
21
|
|
|
|
|
105
|
$self->_make_column_attributes($context); |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
## use critic; |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
sub _make_column_attributes { |
266
|
21
|
|
|
21
|
|
38
|
my $self = shift; |
267
|
21
|
|
|
|
|
43
|
my $context = shift; |
268
|
|
|
|
|
|
|
|
269
|
21
|
|
|
|
|
711
|
my $table = $self->table(); |
270
|
|
|
|
|
|
|
|
271
|
21
|
|
|
|
|
124
|
for my $column ( $table->columns() ) { |
272
|
78
|
|
|
|
|
6258
|
my $name = $column->name(); |
273
|
|
|
|
|
|
|
|
274
|
78
|
100
|
|
|
|
850
|
next if $self->has_method($name); |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
my %attr_p = ( |
277
|
|
|
|
|
|
|
metaclass => 'Fey::Meta::Attribute::FromColumn', |
278
|
|
|
|
|
|
|
is => 'rw', |
279
|
|
|
|
|
|
|
isa => $self->_type_for_column($column), |
280
|
|
|
|
|
|
|
lazy => 1, |
281
|
0
|
|
|
0
|
|
0
|
default => sub { $_[0]->_get_column_value($name) }, |
282
|
77
|
|
|
|
|
3181
|
column => $column, |
283
|
|
|
|
|
|
|
writer => q{_set_} . $name, |
284
|
|
|
|
|
|
|
clearer => q{_clear_} . $name, |
285
|
|
|
|
|
|
|
predicate => q{has_} . $name, |
286
|
|
|
|
|
|
|
definition_context => $context, |
287
|
|
|
|
|
|
|
); |
288
|
|
|
|
|
|
|
|
289
|
77
|
|
|
|
|
559
|
$self->add_attribute( $name, %attr_p ); |
290
|
|
|
|
|
|
|
|
291
|
77
|
50
|
|
|
|
896083
|
if ( my $transform = $self->policy()->transform_for_column($column) ) |
292
|
|
|
|
|
|
|
{ |
293
|
0
|
|
|
|
|
0
|
$self->_add_transform( $name, {}, %{$transform} ); |
|
0
|
|
|
|
|
0
|
|
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
} |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
# XXX - can this be overridden or customized? should it account for |
299
|
|
|
|
|
|
|
# per-column/policy-level transforms? |
300
|
|
|
|
|
|
|
{ |
301
|
|
|
|
|
|
|
my %FeyToMoose = ( |
302
|
|
|
|
|
|
|
text => 'Str', |
303
|
|
|
|
|
|
|
blob => 'Str', |
304
|
|
|
|
|
|
|
integer => 'Int', |
305
|
|
|
|
|
|
|
float => 'Num', |
306
|
|
|
|
|
|
|
datetime => 'Str', |
307
|
|
|
|
|
|
|
date => 'Str', |
308
|
|
|
|
|
|
|
time => 'Str', |
309
|
|
|
|
|
|
|
boolean => 'Bool', |
310
|
|
|
|
|
|
|
other => 'Value', |
311
|
|
|
|
|
|
|
); |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
sub _type_for_column { |
314
|
77
|
|
|
77
|
|
158
|
my $self = shift; |
315
|
77
|
|
|
|
|
118
|
my $column = shift; |
316
|
|
|
|
|
|
|
|
317
|
77
|
|
|
|
|
2484
|
my $type = $FeyToMoose{ $column->generic_type() }; |
318
|
|
|
|
|
|
|
|
319
|
77
|
100
|
|
|
|
14829
|
$type .= q{ | Undef} |
320
|
|
|
|
|
|
|
if $column->is_nullable(); |
321
|
|
|
|
|
|
|
|
322
|
77
|
|
|
|
|
1866
|
return $type; |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
sub _add_transform { |
327
|
7
|
|
|
7
|
|
10
|
my $self = shift; |
328
|
7
|
|
|
|
|
11
|
my $name = shift; |
329
|
7
|
|
|
|
|
10
|
my $context = shift; |
330
|
7
|
|
|
|
|
17
|
my %p = @_; |
331
|
|
|
|
|
|
|
|
332
|
7
|
|
|
|
|
34
|
my $attr = $self->get_attribute($name); |
333
|
|
|
|
|
|
|
|
334
|
7
|
100
|
|
|
|
66
|
param_error "The column $name does not exist as an attribute" |
335
|
|
|
|
|
|
|
unless $attr; |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
$self->_add_inflator_to_attribute( |
338
|
|
|
|
|
|
|
$name, |
339
|
|
|
|
|
|
|
$context, |
340
|
|
|
|
|
|
|
$attr, |
341
|
|
|
|
|
|
|
$p{inflate}, |
342
|
|
|
|
|
|
|
$p{handles} |
343
|
6
|
100
|
|
|
|
35
|
) if $p{inflate}; |
344
|
|
|
|
|
|
|
|
345
|
5
|
50
|
|
|
|
18
|
if ( $p{deflate} ) { |
346
|
5
|
100
|
|
|
|
188
|
param_error |
347
|
|
|
|
|
|
|
"Cannot provide more than one deflator for a column ($name)" |
348
|
|
|
|
|
|
|
if $self->has_deflator($name); |
349
|
|
|
|
|
|
|
|
350
|
4
|
|
|
|
|
139
|
$self->_add_deflator( $name => $p{deflate} ); |
351
|
|
|
|
|
|
|
} |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
## no critic (Subroutines::ProhibitManyArgs) |
355
|
|
|
|
|
|
|
sub _add_inflator_to_attribute { |
356
|
5
|
|
|
5
|
|
8
|
my $self = shift; |
357
|
5
|
|
|
|
|
8
|
my $name = shift; |
358
|
5
|
|
|
|
|
8
|
my $context = shift; |
359
|
5
|
|
|
|
|
7
|
my $attr = shift; |
360
|
5
|
|
|
|
|
9
|
my $inflator = shift; |
361
|
5
|
|
|
|
|
8
|
my $handles = shift; |
362
|
|
|
|
|
|
|
|
363
|
5
|
100
|
|
|
|
49
|
param_error "Cannot provide more than one inflator for a column ($name)" |
364
|
|
|
|
|
|
|
if $attr->isa('Fey::Meta::Attribute::FromInflator'); |
365
|
|
|
|
|
|
|
|
366
|
4
|
|
|
|
|
25
|
$self->remove_attribute($name); |
367
|
|
|
|
|
|
|
|
368
|
4
|
|
|
|
|
1297
|
my $raw_name = $name . q{_raw}; |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
# XXX - should the private writer invoke the deflator? |
371
|
4
|
|
|
|
|
26
|
my $raw_attr = $attr->clone( |
372
|
|
|
|
|
|
|
name => $raw_name, |
373
|
|
|
|
|
|
|
reader => $raw_name, |
374
|
|
|
|
|
|
|
definition_context => $context, |
375
|
|
|
|
|
|
|
); |
376
|
|
|
|
|
|
|
|
377
|
4
|
|
|
|
|
10123
|
$self->add_attribute($raw_attr); |
378
|
|
|
|
|
|
|
|
379
|
4
|
|
|
|
|
37065
|
my $inflated_predicate = q{_has_inflated_} . $name; |
380
|
4
|
|
|
|
|
11
|
my $inflated_clear = q{_clear_inflated_} . $name; |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
my $default = sub { |
383
|
4
|
|
|
4
|
|
918
|
my $self = shift; |
384
|
|
|
|
|
|
|
|
385
|
4
|
|
|
|
|
53
|
return $self->$inflator( $self->$raw_name() ); |
386
|
4
|
|
|
|
|
25
|
}; |
387
|
|
|
|
|
|
|
|
388
|
4
|
100
|
|
|
|
17
|
my %handles = $handles ? ( handles => $handles ) : (); |
389
|
|
|
|
|
|
|
|
390
|
4
|
|
|
|
|
23
|
$self->add_attribute( |
391
|
|
|
|
|
|
|
$name, |
392
|
|
|
|
|
|
|
metaclass => 'Fey::Meta::Attribute::FromInflator', |
393
|
|
|
|
|
|
|
is => 'ro', |
394
|
|
|
|
|
|
|
lazy => 1, |
395
|
|
|
|
|
|
|
default => $default, |
396
|
|
|
|
|
|
|
predicate => $inflated_predicate, |
397
|
|
|
|
|
|
|
clearer => $inflated_clear, |
398
|
|
|
|
|
|
|
init_arg => undef, |
399
|
|
|
|
|
|
|
raw_attribute => $raw_attr, |
400
|
|
|
|
|
|
|
inflator => $inflator, |
401
|
|
|
|
|
|
|
definition_context => $context, |
402
|
|
|
|
|
|
|
%handles, |
403
|
|
|
|
|
|
|
); |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
my $clear_inflated = sub { |
406
|
2
|
|
|
2
|
|
932
|
my $self = shift; |
407
|
|
|
|
|
|
|
|
408
|
2
|
|
|
|
|
38
|
$self->$inflated_clear(); |
409
|
4
|
|
|
|
|
20356
|
}; |
410
|
|
|
|
|
|
|
|
411
|
4
|
|
|
|
|
39
|
$self->add_after_method_modifier( $raw_attr->clearer(), $clear_inflated ); |
412
|
4
|
|
|
|
|
821
|
$self->add_after_method_modifier( $raw_attr->writer(), $clear_inflated ); |
413
|
|
|
|
|
|
|
|
414
|
4
|
|
|
|
|
634
|
$self->_add_inflator( $name => $inflator ); |
415
|
|
|
|
|
|
|
} |
416
|
|
|
|
|
|
|
## use critic |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
sub add_has_one { |
419
|
12
|
|
|
12
|
1
|
28
|
my $self = shift; |
420
|
12
|
|
|
|
|
42
|
my %p = @_; |
421
|
|
|
|
|
|
|
|
422
|
12
|
50
|
|
|
|
497
|
param_error 'You must call has_table() before calling has_one().' |
423
|
|
|
|
|
|
|
unless $self->_has_table(); |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
param_error |
426
|
|
|
|
|
|
|
'You cannot pass both a select and fk parameter when creating a has-one relationship' |
427
|
12
|
50
|
66
|
|
|
67
|
if $p{select} && $p{fk}; |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
my $class |
430
|
|
|
|
|
|
|
= $p{select} |
431
|
12
|
100
|
|
|
|
49
|
? 'Fey::Meta::HasOne::ViaSelect' |
432
|
|
|
|
|
|
|
: 'Fey::Meta::HasOne::ViaFK'; |
433
|
|
|
|
|
|
|
|
434
|
12
|
|
|
|
|
52
|
$p{foreign_table} = delete $p{table}; |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
$p{is_cached} = delete $p{cache} |
437
|
12
|
100
|
|
|
|
56
|
if exists $p{cache}; |
438
|
|
|
|
|
|
|
$p{allows_undef} = delete $p{undef} |
439
|
12
|
100
|
|
|
|
45
|
if exists $p{undef}; |
440
|
|
|
|
|
|
|
|
441
|
12
|
|
|
|
|
435
|
my $has_one = $class->new( |
442
|
|
|
|
|
|
|
table => $self->table(), |
443
|
|
|
|
|
|
|
namer => $self->policy()->has_one_namer(), |
444
|
|
|
|
|
|
|
%p, |
445
|
|
|
|
|
|
|
); |
446
|
|
|
|
|
|
|
|
447
|
11
|
|
|
|
|
68
|
$has_one->attach_to_class($self); |
448
|
|
|
|
|
|
|
|
449
|
9
|
|
|
|
|
62159
|
$self->_add_has_one( $has_one->name() => $has_one ); |
450
|
|
|
|
|
|
|
} |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
sub remove_has_one { |
453
|
8
|
|
|
8
|
1
|
10840
|
my $self = shift; |
454
|
8
|
|
|
|
|
15
|
my $name = shift; |
455
|
|
|
|
|
|
|
|
456
|
8
|
50
|
|
|
|
370
|
return unless $self->_has_has_one($name); |
457
|
|
|
|
|
|
|
|
458
|
8
|
|
|
|
|
308
|
my $has_one = $self->_has_one($name); |
459
|
|
|
|
|
|
|
|
460
|
8
|
|
|
|
|
47
|
$has_one->detach_from_class(); |
461
|
|
|
|
|
|
|
|
462
|
8
|
|
|
|
|
267
|
$self->_remove_has_one( $has_one->name() ); |
463
|
|
|
|
|
|
|
} |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
sub add_has_many { |
466
|
10
|
|
|
10
|
1
|
19
|
my $self = shift; |
467
|
10
|
|
|
|
|
37
|
my %p = @_; |
468
|
|
|
|
|
|
|
|
469
|
10
|
50
|
|
|
|
534
|
param_error 'You must call has_table() before calling has_many().' |
470
|
|
|
|
|
|
|
unless $self->_has_table(); |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
param_error |
473
|
|
|
|
|
|
|
'You cannot pass both a select and fk parameter when creating a has-many relationship' |
474
|
10
|
50
|
66
|
|
|
64
|
if $p{select} && $p{fk}; |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
my $class |
477
|
|
|
|
|
|
|
= $p{select} |
478
|
10
|
100
|
|
|
|
48
|
? 'Fey::Meta::HasMany::ViaSelect' |
479
|
|
|
|
|
|
|
: 'Fey::Meta::HasMany::ViaFK'; |
480
|
|
|
|
|
|
|
|
481
|
10
|
|
|
|
|
37
|
$p{foreign_table} = delete $p{table}; |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
$p{is_cached} = delete $p{cache} |
484
|
10
|
100
|
|
|
|
50
|
if exists $p{cache}; |
485
|
|
|
|
|
|
|
|
486
|
10
|
|
|
|
|
418
|
my $has_many = $class->new( |
487
|
|
|
|
|
|
|
table => $self->table(), |
488
|
|
|
|
|
|
|
namer => $self->policy()->has_many_namer(), |
489
|
|
|
|
|
|
|
%p, |
490
|
|
|
|
|
|
|
); |
491
|
|
|
|
|
|
|
|
492
|
9
|
|
|
|
|
80
|
$has_many->attach_to_class($self); |
493
|
|
|
|
|
|
|
|
494
|
7
|
|
|
|
|
924
|
$self->_add_has_many( $has_many->name() => $has_many ); |
495
|
|
|
|
|
|
|
} |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
sub remove_has_many { |
498
|
5
|
|
|
5
|
1
|
13325
|
my $self = shift; |
499
|
5
|
|
|
|
|
12
|
my $name = shift; |
500
|
|
|
|
|
|
|
|
501
|
5
|
100
|
|
|
|
303
|
return unless $self->_has_has_many($name); |
502
|
|
|
|
|
|
|
|
503
|
4
|
|
|
|
|
204
|
my $has_many = $self->_has_many($name); |
504
|
|
|
|
|
|
|
|
505
|
4
|
|
|
|
|
25
|
$has_many->detach_from_class(); |
506
|
|
|
|
|
|
|
|
507
|
4
|
|
|
|
|
210
|
$self->_remove_has_many( $has_many->name() ); |
508
|
|
|
|
|
|
|
} |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
sub _build_count_sql { |
511
|
0
|
|
|
0
|
|
|
my $self = shift; |
512
|
|
|
|
|
|
|
|
513
|
0
|
|
|
|
|
|
my $table = $self->table(); |
514
|
|
|
|
|
|
|
|
515
|
0
|
|
|
|
|
|
my $select = $self->schema_class()->SQLFactoryClass()->new_select(); |
516
|
|
|
|
|
|
|
|
517
|
0
|
|
|
|
|
|
$select->select( Fey::Literal::Function->new( 'COUNT', '*' ) ) |
518
|
|
|
|
|
|
|
->from($table); |
519
|
|
|
|
|
|
|
|
520
|
0
|
|
|
|
|
|
return $select; |
521
|
|
|
|
|
|
|
} |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
sub add_query_method { |
524
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
525
|
|
|
|
|
|
|
|
526
|
0
|
|
|
|
|
|
my $method = Fey::Meta::Method::FromSelect->new( |
527
|
|
|
|
|
|
|
package_name => $self->name(), |
528
|
|
|
|
|
|
|
@_, |
529
|
|
|
|
|
|
|
); |
530
|
|
|
|
|
|
|
|
531
|
0
|
|
|
|
|
|
$self->add_method( $method->name() => $method ); |
532
|
|
|
|
|
|
|
|
533
|
0
|
|
|
|
|
|
return; |
534
|
|
|
|
|
|
|
} |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
sub make_immutable { |
537
|
|
|
|
|
|
|
shift->SUPER::make_immutable( |
538
|
0
|
|
|
0
|
1
|
|
@_, |
539
|
|
|
|
|
|
|
constructor_class => 'Fey::Meta::Method::Constructor', |
540
|
|
|
|
|
|
|
); |
541
|
|
|
|
|
|
|
} |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
if ( $Moose::VERSION >= 1.9900 ) { |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
# XXX - can we refactor Moose/CMOP core to make overriding (and copying) |
546
|
|
|
|
|
|
|
# all of this unnecessary? |
547
|
|
|
|
|
|
|
override _inline_new_object => sub { |
548
|
|
|
|
|
|
|
my $self = shift; |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
#<<< |
551
|
|
|
|
|
|
|
return ( |
552
|
|
|
|
|
|
|
'my $class = shift;', |
553
|
|
|
|
|
|
|
'$class = Scalar::Util::blessed($class) || $class;', |
554
|
|
|
|
|
|
|
$self->_inline_fallback_constructor('$class'), |
555
|
|
|
|
|
|
|
$self->_inline_params( '$params', '$class' ), |
556
|
|
|
|
|
|
|
$self->_inline_search_cache(), |
557
|
|
|
|
|
|
|
'my $instance;', |
558
|
|
|
|
|
|
|
'$class->_ClearConstructorError();', |
559
|
|
|
|
|
|
|
'my @args = @_;', |
560
|
|
|
|
|
|
|
'Try::Tiny::try {', |
561
|
|
|
|
|
|
|
'@_ = @args;', |
562
|
|
|
|
|
|
|
$self->_inline_generate_instance( '$instance', '$class' ), |
563
|
|
|
|
|
|
|
$self->_inline_slot_initializers, |
564
|
|
|
|
|
|
|
$self->_inline_preserve_weak_metaclasses, |
565
|
|
|
|
|
|
|
$self->_inline_extra_init, |
566
|
|
|
|
|
|
|
'}', |
567
|
|
|
|
|
|
|
'Try::Tiny::catch {', |
568
|
|
|
|
|
|
|
'die $_ unless Scalar::Util::blessed($_) && $_->isa(q{Fey::Exception::NoSuchRow});', |
569
|
|
|
|
|
|
|
'$class->_SetConstructorError($_);', |
570
|
|
|
|
|
|
|
'undef $instance;', |
571
|
|
|
|
|
|
|
'};', |
572
|
|
|
|
|
|
|
'return unless $instance;', |
573
|
|
|
|
|
|
|
$self->_inline_write_to_cache(), |
574
|
|
|
|
|
|
|
'return $instance', |
575
|
|
|
|
|
|
|
); |
576
|
|
|
|
|
|
|
#>>> |
577
|
|
|
|
|
|
|
}; |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
# The default version of this sticks a "my" in front of the declaration, |
580
|
|
|
|
|
|
|
# but we want to declare the $instance var earlier. |
581
|
|
|
|
|
|
|
override _inline_generate_instance => sub { |
582
|
|
|
|
|
|
|
my $self = shift; |
583
|
|
|
|
|
|
|
my ( $inst, $class ) = @_; |
584
|
|
|
|
|
|
|
return ( |
585
|
|
|
|
|
|
|
$inst . ' = ' . $self->_inline_create_instance($class) . ';', |
586
|
|
|
|
|
|
|
); |
587
|
|
|
|
|
|
|
}; |
588
|
|
|
|
|
|
|
} |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
sub _inline_search_cache { |
591
|
0
|
|
|
0
|
|
|
my $self = shift; |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
#<<< |
594
|
|
|
|
|
|
|
return |
595
|
0
|
|
|
|
|
|
( 'if ( $metaclass->_object_cache_is_enabled() ) {', |
596
|
|
|
|
|
|
|
'my $cached = $metaclass->_search_cache($params);', |
597
|
|
|
|
|
|
|
'return $cached if $cached;', |
598
|
|
|
|
|
|
|
'}' |
599
|
|
|
|
|
|
|
); |
600
|
|
|
|
|
|
|
#>>> |
601
|
|
|
|
|
|
|
} |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
sub _inline_write_to_cache { |
604
|
0
|
|
|
0
|
|
|
my $self = shift; |
605
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
return |
607
|
0
|
|
|
|
|
|
'$metaclass->_write_to_cache($instance) if $metaclass->_object_cache_is_enabled();'; |
608
|
|
|
|
|
|
|
} |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
__PACKAGE__->meta()->make_immutable(); |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
1; |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
# ABSTRACT: A metaclass for table classes |
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
__END__ |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
=pod |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
=head1 NAME |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
Fey::Meta::Class::Table - A metaclass for table classes |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
=head1 VERSION |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
version 0.47 |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
=head1 SYNOPSIS |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
package MyApp::User; |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
use Fey::ORM::Table; |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
print __PACKAGE__->meta()->ClassForTable($table); |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
=head1 DESCRIPTION |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
This is the metaclass for table classes. When you use |
639
|
|
|
|
|
|
|
L<Fey::ORM::Table> in your class, it uses this class to do all the |
640
|
|
|
|
|
|
|
heavy lifting. |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
=head1 METHODS |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
This class provides the following methods: |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
=head2 Fey::Meta::Class::Table->ClassForTable( $table1, $table2 ) |
647
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
Given one or more L<Fey::Table> objects, this method returns the name |
649
|
|
|
|
|
|
|
of the class which "has" that table, if any. |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
=head2 Fey::Meta::Class::Table->TableForClass($class) |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
Given a class, this method returns the L<Fey::Table> object associated |
654
|
|
|
|
|
|
|
with that class, if any. |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
=head2 $meta->table() |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
Returns the L<Fey::Table> for the metaclass's class. |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
=head2 $meta->add_has_one(%options) |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
Creates a new L<Fey::Meta::HasOne::ViaFK> or |
663
|
|
|
|
|
|
|
L<Fey::Meta::HasOne::ViaSelect> object and adds it to the |
664
|
|
|
|
|
|
|
metaclass. Internally, this will call C<attach_to_class()> on the |
665
|
|
|
|
|
|
|
C<HasOne> meta-object. |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
=head2 $meta->has_ones() |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
Returns a list of the C<HasOne> objects added to this metaclass. |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
=head2 $meta->remove_has_one($name) |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
Removes the named C<HasOne> meta-object. Internally, this will call |
674
|
|
|
|
|
|
|
C<detach_from_class()> on the C<HasOne> meta-object. |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
=head2 $meta->add_has_many(%options) |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
Creates a new L<Fey::Meta::HasMany::ViaFK> or |
679
|
|
|
|
|
|
|
L<Fey::Meta::HasMany::ViaSelect> object and adds it to the |
680
|
|
|
|
|
|
|
metaclass. Internally, this will call C<attach_to_class()> on the |
681
|
|
|
|
|
|
|
C<HasMany> meta-object. |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
=head2 $meta->has_manies() |
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
Returns a list of the C<HasMany> objects added to this metaclass. |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
=head2 $meta->remove_has_many($name) |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
Removes the named C<HasMany> meta-object. Internally, this will call |
690
|
|
|
|
|
|
|
C<detach_from_class()> on the C<HasMany> meta-object. |
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
=head2 $meta->has_inflator($name) |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
Returns a boolean indicating whether or not there is an inflator |
695
|
|
|
|
|
|
|
defined for the named column. |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
=head2 $meta->has_deflator($name) |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
Returns a boolean indicating whether or not there is an inflator |
700
|
|
|
|
|
|
|
defined for the named column. |
701
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
=head2 $meta->add_query_method(%options) |
703
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
Adds a new L<Fey::Meta::Method::FromSelect> method to the class. The |
705
|
|
|
|
|
|
|
C<%options> passed to this method will be passed to the |
706
|
|
|
|
|
|
|
L<Fey::Meta::Method::FromSelect> constructor. |
707
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
=head2 $meta->make_immutable() |
709
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
This class overrides C<< Moose::Meta::Class->make_immutable() >> in |
711
|
|
|
|
|
|
|
order to do its own optimizations for immutability. |
712
|
|
|
|
|
|
|
|
713
|
|
|
|
|
|
|
=head1 AUTHOR |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
Dave Rolsky <autarch@urth.org> |
716
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
This software is copyright (c) 2011 - 2015 by Dave Rolsky. |
720
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
722
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
=cut |