removing largely unnecessary dep on MooseX::Method::Signatures
[dbsrgits/DBIx-Class-ResultSet-WithMetaData.git] / lib / DBIx / Class / ResultSet / WithMetaData.pm
CommitLineData
b8e6d226 1package DBIx::Class::ResultSet::WithMetaData;
2
3use strict;
4use warnings;
5
6use Data::Alias;
7use Moose;
79b18b81 8use Method::Signatures::Simple;
b8e6d226 9extends 'DBIx::Class::ResultSet';
10
11has '_row_info' => (
683ececb 12 is => 'rw',
13 isa => 'HashRef'
b8e6d226 14);
15
16has 'was_row' => (
683ececb 17 is => 'rw',
18 isa => 'Int'
b8e6d226 19);
20
b51d39c8 21has 'id_cols' => (
683ececb 22 is => 'rw',
23 isa => 'ArrayRef',
b51d39c8 24);
683ececb 25
26=head1 VERSION
27
28Version 0.999001
29
30=cut
31
32our $VERSION = '0.999001';
33
34=head1 NAME
35
36DBIx::Class::ResultSet::WithMetaData
37
38=head1 SYNOPSIS
39
40 package MyApp::Schema::ResultSet::ObjectType;
41
42 use Moose;
43 use MooseX::Method::Signatures;
44 extends 'DBIx::Class::ResultSet::WithMetaData;
45
46 method with_substr () {
47 foreach my $row ($self->all) {
48 my $substr = substr($row->name, 0, 3);
49 $self->add_row_info(row => $row, info => { substr => $substr });
50 }
51 return $self;
52 }
53
54 ...
55
56
57 # then somewhere else
58
59 my $object_type_arrayref = $object_type_rs->limit(count => 3)->with_substr->display();
60
61 # [{
62 # 'artistid' => '1',
63 # 'name' => 'Caterwauler McCrae',
64 # 'substr' => 'Cat'
65 # },
66 # {
67 # 'artistid' => '2',
68 # 'name' => 'Random Boy Band',
69 # 'substr' => 'Ran'
70 # },
71 # {
72 # 'artistid' => '3',
73 # 'name' => 'We Are Goth',
74 # 'substr' => 'We '
75 # }]
76
77=head1 DESCRIPTION
78
79Attach metadata to rows by chaining ResultSet methods together. When the ResultSet is
80flattened to an ArrayRef the attached metadata is merged with the row hashes to give
81a combined 'hash-plus-other-stuff' representation.
82
83=head1 METHODS
84
85=cut
b51d39c8 86
b8e6d226 87sub new {
683ececb 88 my $self = shift;
b51d39c8 89
683ececb 90 my $new = $self->next::method(@_);
91 foreach my $key (qw/_row_info was_row id_cols/) {
92 alias $new->{$key} = $new->{attrs}{$key};
93 }
b8e6d226 94
683ececb 95 unless ($new->_row_info) {
96 $new->_row_info({});
97 }
b8e6d226 98
683ececb 99 unless ($new->id_cols && scalar(@{$new->id_cols})) {
100 $new->id_cols([sort $new->result_source->primary_columns]);
101 }
b8e6d226 102
683ececb 103 return $new;
b8e6d226 104}
105
683ececb 106=head2 display
107
108=over 4
109
110=item Arguments: none
111
112=item Return Value: ArrayRef
113
114=back
115
116 $arrayref_of_row_hashrefs = $rs->display();
117
118This method uses L<DBIx::Class::ResultClass::HashRefInflator> to convert all
119rows in the ResultSet to HashRefs. These are then merged with any metadata
120that had been attached to the rows using L</add_row_info>.
121
122=cut
123
b8e6d226 124method display () {
125 my $rs = $self->search({});
126 $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
127 my @rows;
683ececb 128 foreach my $row ($rs->all) {
129 if (my $info = $self->row_info_for(id => $self->_mk_id(row => $row))) {
130 $row = { %{$row}, %{$info} };
131 }
132 push(@rows, $row);
133 }
b8e6d226 134
135 return ($self->was_row) ? $rows[0] : \@rows;
136}
137
683ececb 138=head2 add_row_info
139
140=over 4
141
142=item Arguments: row => DBIx::Class::Row object, info => HashRef to attach to the row
143
144=item Return Value: ResultSet
145
146=back
147
148 $rs = $rs->add_row_info(row => $row, info => { dates => [qw/mon weds fri/] } );
149
150This method allows you to attach a HashRef of metadata to a row which will be merged
151with that row when the ResultSet is flattened to a datastructure with L</display>.
152
153=cut
154
79b18b81 155method add_row_info (%opts) {
156 my ($row, $id, $info) = map { $opts{$_} } qw/row id info/;
683ececb 157 if ($row) {
158 $id = $self->_mk_id(row => { $row->get_columns });
159 }
160 unless ($self->find($id)) {
161 die 'invalid id passed to add_row_info';
162 }
163
164 if (my $existing = $self->_row_info->{$id}) {
165 $info = { %{$existing}, %{$info} };
166 }
167
168 $self->_row_info->{$id} = $info;
b8e6d226 169}
170
79b18b81 171method row_info_for (%opts) {
172 my $id = $opts{id};
683ececb 173 return $self->_row_info->{$id};
b8e6d226 174}
175
683ececb 176=head2 order_by (EXPERIMENTAL)
177
178=over 4
179
180=item Arguments: col => $column_name
181
182=item Return Value: ResultSet
183
184=back
185
186 $ordered_rs = $rs->order_by(col => 'name');
187
188Convenience method. Essentually a shortcut for $rs->search({}, { order_by => $col }).
189
190=cut
191
79b18b81 192method order_by (%opts) {
193 my $col = $opts{col};
683ececb 194 $col = "me.$col" unless ($col =~ m/\./);
195 return $self->search({}, { order_by => $col });
b8e6d226 196}
197
683ececb 198=head2 limit (EXPERIMENTAL)
199
200=over 4
201
202=item Arguments: count => Int
203
204=item Return Value: ResultSet
205
206=back
207
208 $limitted_rs = $rs->limit(count => 3);
209
210Convenience method. Essentually a shortcut for $rs->search({}, { rows => $count }).
211
212=cut
213
79b18b81 214method limit (%opts) {
215 my $count = $opts{count};
683ececb 216 return $self->search({}, { rows => $count });
b8e6d226 217}
218
79b18b81 219method _mk_id (%opts) {
220 my $row = $opts{row};
683ececb 221 return join('-', map { $row->{$_} } @{$self->id_cols});
b51d39c8 222}
b8e6d226 223
024c1044 224=head1 AUTHOR
225
226 Luke Saunders <luke.saunders@gmail.com>
227
228=head1 THANKS
229
230As usual, thanks to Matt S Trout for the sanity check.
231
232=head1 LICENSE
233
234 This library is free software under the same license as perl itself
235
236=cut
237
b8e6d226 2381;