line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Aniki::Result::Collection::Joined; |
2
|
2
|
|
|
2
|
|
3048
|
use 5.014002; |
|
2
|
|
|
|
|
8
|
|
3
|
|
|
|
|
|
|
|
4
|
2
|
|
|
2
|
|
10
|
use namespace::autoclean; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
13
|
|
5
|
2
|
|
|
2
|
|
127
|
use Mouse v2.4.5; |
|
2
|
|
|
|
|
22
|
|
|
2
|
|
|
|
|
14
|
|
6
|
|
|
|
|
|
|
extends qw/Aniki::Result::Collection/; |
7
|
|
|
|
|
|
|
|
8
|
2
|
|
|
2
|
|
954
|
use Carp qw/croak/; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
145
|
|
9
|
2
|
|
|
2
|
|
803
|
use Aniki::Row::Joined; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
73
|
|
10
|
2
|
|
|
2
|
|
16
|
use List::MoreUtils qw/none/; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
23
|
|
11
|
2
|
|
|
2
|
|
1326
|
use List::UtilsBy qw/uniq_by/; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
93
|
|
12
|
2
|
|
|
2
|
|
13
|
use Scalar::Util qw/refaddr/; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
1789
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
has '+table_name' => ( |
15
|
|
|
|
|
|
|
required => 0, |
16
|
|
|
|
|
|
|
lazy => 1, |
17
|
|
|
|
|
|
|
default => sub { join ',', @{ $_[0]->table_names } } |
18
|
|
|
|
|
|
|
); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
has '+row_class' => ( |
21
|
|
|
|
|
|
|
lazy => 1, |
22
|
|
|
|
|
|
|
default => sub { croak 'Cannot get row class of '.__PACKAGE__.'. Use row_classes instead of row_class.' }, |
23
|
|
|
|
|
|
|
); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
has table_names => ( |
26
|
|
|
|
|
|
|
is => 'ro', |
27
|
|
|
|
|
|
|
required => 1, |
28
|
|
|
|
|
|
|
); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
has _compact_row_datas => ( |
31
|
|
|
|
|
|
|
is => 'ro', |
32
|
|
|
|
|
|
|
lazy => 1, |
33
|
|
|
|
|
|
|
builder => '_compress', |
34
|
|
|
|
|
|
|
); |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
has _subresult_cache => ( |
37
|
|
|
|
|
|
|
is => 'ro', |
38
|
|
|
|
|
|
|
default => sub { |
39
|
|
|
|
|
|
|
my $self = shift; |
40
|
|
|
|
|
|
|
return +{ |
41
|
|
|
|
|
|
|
map { $_ => undef } @{ $self->table_names }, |
42
|
|
|
|
|
|
|
}; |
43
|
|
|
|
|
|
|
}, |
44
|
|
|
|
|
|
|
); |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub row_classes { |
47
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
48
|
0
|
|
|
|
|
0
|
return map { $self->handler->guess_row_class($_) } @{ $self->table_names }; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
sub rows { |
52
|
11
|
|
|
11
|
1
|
36
|
my $self = shift; |
53
|
11
|
100
|
|
|
|
47
|
if (@_ == 1) { |
54
|
8
|
|
|
|
|
27
|
my $table_name = shift; |
55
|
8
|
|
|
|
|
29
|
return $self->subresult($table_name)->rows(); |
56
|
|
|
|
|
|
|
} |
57
|
3
|
|
|
|
|
31
|
return $self->SUPER::rows(); |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
sub subresult { |
61
|
8
|
|
|
8
|
0
|
30
|
my ($self, $table_name) = @_; |
62
|
8
|
100
|
|
|
|
60
|
return $self->_subresult_cache->{$table_name} if $self->_subresult_cache->{$table_name}; |
63
|
|
|
|
|
|
|
|
64
|
6
|
|
|
|
|
35
|
my $result_class = $self->handler->guess_result_class($table_name); |
65
|
|
|
|
|
|
|
return $self->_subresult_cache->{$table_name} = $result_class->new( |
66
|
|
|
|
|
|
|
table_name => $table_name, |
67
|
|
|
|
|
|
|
handler => $self->handler, |
68
|
30
|
|
|
30
|
|
311
|
row_datas => [uniq_by { refaddr $_ } map { $_->{$table_name} } @{ $self->_compact_row_datas() }], |
|
30
|
|
|
|
|
103
|
|
|
6
|
|
|
|
|
51
|
|
69
|
|
|
|
|
|
|
!$self->suppress_row_objects ? ( |
70
|
6
|
50
|
|
30
|
|
30
|
inflated_rows => [uniq_by { refaddr $_ } map { $_->$table_name } @{ $self->inflated_rows() }], |
|
30
|
|
|
|
|
294
|
|
|
30
|
|
|
|
|
190
|
|
|
6
|
|
|
|
|
81
|
|
71
|
|
|
|
|
|
|
) : (), |
72
|
|
|
|
|
|
|
suppress_row_objects => $self->suppress_row_objects, |
73
|
|
|
|
|
|
|
); |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
sub _uniq_key { |
77
|
30
|
|
|
30
|
|
84
|
my ($row_data, $pk) = @_; |
78
|
30
|
100
|
|
30
|
|
198
|
return if none { defined $row_data->{$_} } @$pk; |
|
30
|
|
|
|
|
323
|
|
79
|
27
|
|
|
|
|
209
|
return join '|', map { quotemeta $row_data->{$_} } @$pk; |
|
27
|
|
|
|
|
159
|
|
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub _compress { |
83
|
3
|
|
|
3
|
|
11
|
my $self = shift; |
84
|
3
|
|
|
|
|
21
|
my $handler = $self->handler; |
85
|
|
|
|
|
|
|
|
86
|
3
|
|
|
|
|
10
|
my @table_names = @{ $self->table_names }; |
|
3
|
|
|
|
|
19
|
|
87
|
|
|
|
|
|
|
my %pk = map { |
88
|
3
|
|
|
|
|
14
|
$_ => [map { $_->name } $handler->schema->get_table($_)->primary_key->fields] |
|
6
|
|
|
|
|
37
|
|
|
6
|
|
|
|
|
56
|
|
89
|
|
|
|
|
|
|
} @table_names; |
90
|
|
|
|
|
|
|
|
91
|
3
|
|
|
|
|
13
|
my @rows; |
92
|
|
|
|
|
|
|
my %cache; |
93
|
3
|
|
|
|
|
10
|
for my $row (@{ $self->row_datas }) { |
|
3
|
|
|
|
|
25
|
|
94
|
15
|
|
|
|
|
40
|
my %rows; |
95
|
|
|
|
|
|
|
|
96
|
15
|
|
|
|
|
47
|
for my $table_name (@table_names) { |
97
|
30
|
|
|
|
|
83
|
my $row_data = $row->{$table_name}; |
98
|
30
|
|
|
|
|
94
|
my $uniq_key = _uniq_key($row_data, $pk{$table_name}); |
99
|
30
|
100
|
66
|
|
|
255
|
$rows{$table_name} = defined $uniq_key ? ($cache{$table_name}{$uniq_key} //= $row_data) : $row_data; |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
15
|
|
|
|
|
69
|
push @rows => \%rows; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
3
|
|
|
|
|
34
|
return \@rows; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub _inflate { |
109
|
3
|
|
|
3
|
|
11
|
my $self = shift; |
110
|
3
|
|
|
|
|
14
|
my $handler = $self->handler; |
111
|
|
|
|
|
|
|
|
112
|
3
|
|
|
|
|
11
|
my @table_names = @{ $self->table_names }; |
|
3
|
|
|
|
|
22
|
|
113
|
3
|
|
|
|
|
13
|
my %row_class = map { $_ => $handler->guess_row_class($_) } @table_names; |
|
6
|
|
|
|
|
71
|
|
114
|
|
|
|
|
|
|
|
115
|
3
|
|
|
|
|
15
|
my @rows; |
116
|
|
|
|
|
|
|
my %cache; |
117
|
3
|
|
|
|
|
9
|
for my $row (@{ $self->_compact_row_datas }) { |
|
3
|
|
|
|
|
20
|
|
118
|
15
|
|
|
|
|
39
|
my %rows; |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# inflate to row class |
121
|
15
|
|
|
|
|
45
|
for my $table_name (@table_names) { |
122
|
30
|
|
|
|
|
80
|
my $row_data = $row->{$table_name}; |
123
|
30
|
|
66
|
|
|
480
|
$rows{$table_name} = $cache{$table_name}{refaddr $row_data} //= $row_class{$table_name}->new( |
124
|
|
|
|
|
|
|
table_name => $table_name, |
125
|
|
|
|
|
|
|
handler => $handler, |
126
|
|
|
|
|
|
|
row_data => $row_data, |
127
|
|
|
|
|
|
|
); |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
15
|
|
|
|
|
83
|
push @rows => Aniki::Row::Joined->new(values %rows); |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
3
|
|
|
|
|
32
|
return \@rows; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable(); |
137
|
|
|
|
|
|
|
__END__ |