line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mandel::Model; |
2
|
27
|
|
|
27
|
|
230
|
use Mojo::Base -base; |
|
27
|
|
|
|
|
63
|
|
|
27
|
|
|
|
|
327
|
|
3
|
27
|
|
|
27
|
|
7948
|
use Mojo::Loader 'load_class'; |
|
27
|
|
|
|
|
232347
|
|
|
27
|
|
|
|
|
1524
|
|
4
|
27
|
|
|
27
|
|
195
|
use Mojo::Util; |
|
27
|
|
|
|
|
56
|
|
|
27
|
|
|
|
|
1013
|
|
5
|
26
|
|
|
26
|
|
11187
|
use Mandel::Model::Field; |
|
26
|
|
|
|
|
72
|
|
|
26
|
|
|
|
|
240
|
|
6
|
26
|
|
|
26
|
|
919
|
use Carp 'confess'; |
|
26
|
|
|
|
|
188
|
|
|
26
|
|
|
|
|
15738
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
my $ANON = 1; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
has collection_name => sub { |
11
|
|
|
|
|
|
|
my $self = shift; |
12
|
|
|
|
|
|
|
my $name = $self->name; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
return $name =~ /s$/ ? $name : $name . 's' if $name; |
15
|
|
|
|
|
|
|
confess "collection_name or name required in constructor"; |
16
|
|
|
|
|
|
|
}; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
has collection_class => 'Mandel::Collection'; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
has document_class => sub { |
21
|
|
|
|
|
|
|
my $self = shift; |
22
|
|
|
|
|
|
|
my $name = ucfirst $self->name || 'AnonDoc'; |
23
|
|
|
|
|
|
|
my $class = "Mandel::Document::__ANON_${ANON}__::$name"; # this might change |
24
|
|
|
|
|
|
|
|
25
|
5
|
|
|
5
|
|
41
|
eval <<" PACKAGE" or confess $@; |
|
5
|
|
|
5
|
|
14
|
|
|
5
|
|
|
1
|
|
27
|
|
|
5
|
|
|
4
|
|
39
|
|
|
5
|
|
|
|
|
12
|
|
|
5
|
|
|
|
|
21
|
|
|
1
|
|
|
|
|
30
|
|
|
4
|
|
|
|
|
105
|
|
26
|
|
|
|
|
|
|
package $class; |
27
|
|
|
|
|
|
|
use Mojo::Base "Mandel::Document"; |
28
|
|
|
|
|
|
|
sub model { \$self } |
29
|
|
|
|
|
|
|
\$INC{"Mandel/Document/__ANON__$ANON.pm"} = "GENERATED"; |
30
|
|
|
|
|
|
|
PACKAGE |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
$ANON++; |
33
|
|
|
|
|
|
|
$class; |
34
|
|
|
|
|
|
|
}; |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
has name => ''; |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
sub field { |
39
|
17
|
|
|
17
|
1
|
58
|
my ($self, $name, $meta) = @_; |
40
|
|
|
|
|
|
|
|
41
|
17
|
100
|
|
|
|
47
|
if ($meta) { |
42
|
12
|
|
|
|
|
39
|
return $self->_add_field($name => $meta); # $name might be an array-ref |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
5
|
50
|
|
|
|
8
|
for (@{$self->{fields} || []}) { |
|
5
|
|
|
|
|
18
|
|
46
|
15
|
100
|
|
|
|
28
|
return $_ if $name eq $_->name; |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
|
49
|
0
|
|
|
|
|
0
|
return; |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub _add_field { |
53
|
12
|
|
|
12
|
|
27
|
my ($self, $fields, $meta) = @_; |
54
|
12
|
|
|
|
|
47
|
my $class = $self->document_class; |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# Compile fieldibutes |
57
|
12
|
100
|
|
|
|
110
|
for my $name (@{ref $fields eq 'ARRAY' ? $fields : [$fields]}) { |
|
12
|
|
|
|
|
61
|
|
58
|
13
|
|
|
|
|
39
|
local $meta->{name} = $name; |
59
|
13
|
|
|
|
|
108
|
my $field = Mandel::Model::Field->new($meta); |
60
|
13
|
|
|
|
|
168
|
my $builder = $field->builder; |
61
|
13
|
|
|
|
|
29
|
my $code = ""; |
62
|
|
|
|
|
|
|
|
63
|
13
|
|
|
|
|
44
|
$code .= "package $class;\nsub $name {\n my \$raw = \$_[0]->data;\n"; |
64
|
|
|
|
|
|
|
|
65
|
13
|
100
|
|
|
|
38
|
if ($builder) { |
66
|
2
|
|
|
|
|
9
|
$code |
67
|
|
|
|
|
|
|
.= "return exists \$raw->{'$name'} ? (\$raw->{'$name'}) : (\$raw->{'$name'} = \$_[0]->\$builder) if \@_ == 1;\n"; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
else { |
70
|
11
|
|
|
|
|
68
|
$code .= "return \$raw->{'$name'} if \@_ == 1;\n"; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
13
|
|
|
|
|
31
|
$code .= "local \$_ = \$_[1];\n"; |
74
|
13
|
100
|
|
|
|
85
|
$code .= $self->_field_type($meta->{isa}) if $meta->{isa}; |
75
|
13
|
|
|
|
|
43
|
$code .= "\$_[0]->{dirty}{$name} = 1;"; |
76
|
13
|
|
|
|
|
30
|
$code .= "\$raw->{'$name'} = \$_;\n"; |
77
|
13
|
|
|
|
|
24
|
$code .= "return \$_[0];\n}"; |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# We compile custom attribute code for speed |
80
|
26
|
|
|
26
|
|
209
|
no strict 'refs'; |
|
26
|
|
|
|
|
68
|
|
|
26
|
|
|
|
|
6533
|
|
81
|
13
|
50
|
|
|
|
37
|
warn "-- Attribute $name in $class\n$code\n\n" if $ENV{MOJO_BASE_DEBUG}; |
82
|
13
|
50
|
|
7
|
0
|
2238
|
Carp::croak "Mandel::Document error: $@ ($code)" unless eval "$code;1"; |
|
9
|
100
|
|
2
|
|
75
|
|
|
9
|
100
|
|
1
|
|
92
|
|
|
8
|
100
|
|
1
|
|
4645
|
|
|
4
|
100
|
|
1
|
|
52
|
|
|
4
|
50
|
|
|
|
13
|
|
|
4
|
50
|
|
|
|
11
|
|
|
5
|
50
|
|
|
|
36
|
|
|
3
|
50
|
|
|
|
50
|
|
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
1055
|
|
|
2
|
|
|
|
|
57
|
|
|
2
|
|
|
|
|
11
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
8
|
|
|
2
|
|
|
|
|
8
|
|
|
2
|
|
|
|
|
45
|
|
|
1
|
|
|
|
|
5
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
1
|
|
|
|
|
593
|
|
|
1
|
|
|
|
|
28
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
|
84
|
13
|
|
|
|
|
51
|
push @{$self->{fields}}, $field; |
|
13
|
|
|
|
|
65
|
|
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
12
|
|
|
|
|
51
|
$self; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
sub fields { |
91
|
4
|
100
|
|
4
|
1
|
67
|
@{$_[0]->{fields} || []}; |
|
4
|
|
|
|
|
50
|
|
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub _field_type { |
95
|
7
|
|
|
7
|
|
48
|
my ($self, $type) = @_; |
96
|
7
|
|
|
|
|
13
|
my $code = ""; |
97
|
|
|
|
|
|
|
|
98
|
26
|
|
|
26
|
|
15429
|
use Types::Standard 'Num'; |
|
26
|
|
|
|
|
1943731
|
|
|
26
|
|
|
|
|
278
|
|
99
|
|
|
|
|
|
|
|
100
|
7
|
100
|
100
|
|
|
26
|
if ($type->has_coercion and $type->coercion->can_be_inlined) { |
101
|
2
|
|
|
|
|
154
|
$code .= '$_ = ' . $type->coercion->inline_coercion('$_') . ";\n"; |
102
|
|
|
|
|
|
|
} |
103
|
6
|
100
|
|
|
|
413
|
if ($type->can_be_inlined) { |
104
|
6
|
|
|
|
|
151
|
$code .= $type->inline_assert('$_') . "\n"; |
105
|
|
|
|
|
|
|
} |
106
|
7
|
100
|
|
|
|
488
|
if ($type->is_a_type_of(Num)) { |
107
|
4
|
|
|
|
|
363
|
$code .= "\$_ += 0;\n"; |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
7
|
|
|
|
|
4423
|
return $code; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub relationship { |
114
|
6
|
|
|
4
|
1
|
2796
|
my $self = shift; |
115
|
|
|
|
|
|
|
|
116
|
7
|
50
|
|
|
|
45
|
if (@_ == 1) { |
117
|
2
|
|
|
|
|
11
|
return $self->{relationship}{$_[0]}; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
6
|
|
|
|
|
26
|
my ($type, $field, $other, %args) = @_; |
121
|
6
|
|
|
|
|
41
|
my $class = 'Mandel::Relationship::' . Mojo::Util::camelize($type); |
122
|
6
|
|
|
|
|
122
|
my $e = load_class $class; |
123
|
|
|
|
|
|
|
|
124
|
5
|
100
|
|
|
|
72
|
confess $e if ref $e; |
125
|
|
|
|
|
|
|
|
126
|
5
|
|
|
|
|
23
|
$self->{relationship}{$field} |
127
|
|
|
|
|
|
|
= $class->new(accessor => $field, document_class => $self->document_class, related_class => $other, %args); |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
sub new_collection { |
131
|
4
|
|
|
5
|
1
|
18
|
my ($self, $connection, %args) = @_; |
132
|
|
|
|
|
|
|
|
133
|
4
|
|
100
|
|
|
13
|
$self->collection_class->new( |
134
|
|
|
|
|
|
|
{connection => $connection || confess('$model->new_collection($connection)'), model => $self, %args}); |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
1; |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=encoding utf8 |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head1 NAME |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
Mandel::Model - An object modelling a document |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=head1 DESCRIPTION |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
This class is used to descrieb the structure of L |
148
|
|
|
|
|
|
|
in mongodb. |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=head2 collection_name |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
The name of the collection in the database. Default is the plural form of L. |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=head2 collection_class |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
The class name of the collection class. This default to L. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=head2 document_class |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
The class name of the document this description is attached to. Default to |
163
|
|
|
|
|
|
|
an autogenerated class name. |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
=head2 name |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
The name of this model. Same as given to L and |
168
|
|
|
|
|
|
|
L. |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=head1 METHODS |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head2 field |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
$field_obj = $self->field('name'); |
175
|
|
|
|
|
|
|
$self = $self->field(name => \%meta); |
176
|
|
|
|
|
|
|
$self = $self->field(['name1', 'name2'], \%meta); |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
Used to define new field(s) or retrieve a defined L |
179
|
|
|
|
|
|
|
object. |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=head2 fields |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
@fields = $self->fields; |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
Get list of L objects in the order they were added to |
186
|
|
|
|
|
|
|
thie model. |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=head2 relationship |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
$rel_obj = $self->relationship($type => $accessor => 'Other::Document::Class', %args); |
191
|
|
|
|
|
|
|
$rel_obj = $self->relationship($accessor); |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
This method is used to describe a relationship between two documents. |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
See L, L or |
196
|
|
|
|
|
|
|
L. |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
C<$accessor> will be used as l, |
199
|
|
|
|
|
|
|
"Other::Document::Class" will be used as L |
200
|
|
|
|
|
|
|
and C will be used as |
201
|
|
|
|
|
|
|
L. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
C<%args> is passed on the the L constructor. |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=head2 new_collection |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
$self->new_collection($connection); |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
Returns a new instance of L. |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=head1 SEE ALSO |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
L, L, L |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
=head1 AUTHOR |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
Jan Henning Thorsen - C |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=cut |