1 package DBIx::Class::ResultSet::WithMetaData;
8 use Method::Signatures::Simple;
9 extends 'DBIx::Class::ResultSet';
26 has '_hash_modifiers' => (
31 has '_key_modifiers' => (
42 our $VERSION = '1.000001';
46 DBIx::Class::ResultSet::WithMetaData
50 package MyApp::Schema::ResultSet::ObjectType;
53 use MooseX::Method::Signatures;
54 extends 'DBIx::Class::ResultSet::WithMetaData;
56 method with_substr () {
57 return $self->_with_meta_key(
59 return substr(shift->{name}, 0, 3);
69 my $object_type_arrayref = $object_type_rs->with_substr->display();
73 # 'name' => 'Caterwauler McCrae',
78 # 'name' => 'Random Boy Band',
83 # 'name' => 'We Are Goth',
89 Attach metadata to rows by chaining ResultSet methods together. When the ResultSet is
90 flattened to an ArrayRef the attached metadata is merged with the row hashes to give
91 a combined 'hash-plus-other-stuff' representation.
100 my $new = $self->next::method(@_);
101 foreach my $key (qw/_row_info was_row id_cols _key_modifiers _hash_modifiers/) {
102 alias $new->{$key} = $new->{attrs}{$key};
105 unless ($new->_row_info) {
109 unless ($new->_key_modifiers) {
110 $new->_key_modifiers([]);
112 unless ($new->_hash_modifiers) {
113 $new->_hash_modifiers([]);
116 unless ($new->id_cols && scalar(@{$new->id_cols})) {
117 $new->id_cols([sort $new->result_source->primary_columns]);
127 =item Arguments: none
129 =item Return Value: ArrayRef
133 $arrayref_of_row_hashrefs = $rs->display();
135 This method uses L<DBIx::Class::ResultClass::HashRefInflator> to convert all
136 rows in the ResultSet to HashRefs. These are then merged with any metadata
137 that had been attached to the rows using L</add_row_info>.
142 my $rs = $self->search({});
143 $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
145 foreach my $row ($rs->all) {
146 # THIS BLOCK IS DEPRECATED
147 if (my $info = $self->row_info_for(id => $self->_mk_id(row => $row))) {
148 $row = { %{$row}, %{$info} };
151 foreach my $modifier (@{$rs->_hash_modifiers}) {
152 my $row_hash = $modifier->($row);
153 if (ref $row_hash ne 'HASH') {
154 die 'modifier subref (added via build_metadata) did not return hashref';
157 # simple merge for now, potentially needs to be more complex
158 $row->{$_} = $row_hash->{$_} for keys %{$row_hash};
161 foreach my $params (@{$rs->_key_modifiers}) {
162 my $modifier = $params->{modifier};
163 my $key = $params->{key};
165 if (my $val = $modifier->($row)) {
172 return ($self->was_row) ? $rows[0] : \@rows;
175 =head2 _with_meta_key
179 =item Arguments: key_name => subref($row_hash)
181 =item Return Value: ResultSet
185 $self->_with_meta_key( substr => sub ($row) {
186 return substr(shift->{name}, 0, 3);
189 This method allows you populate a certain key for each row hash at L</display> time.
193 method _with_meta_key ($key, $modifier) {
194 my $rs = $self->search({});
196 die 'build_metadata called without key';
199 unless ($modifier && (ref $modifier eq 'CODE')) {
200 die 'build_metadata called without modifier param';
203 push( @{$rs->_key_modifiers}, { key => $key, modifier => $modifier });
207 =head2 _with_meta_hash
211 =item Arguments: subref($row_hash)
213 =item Return Value: ResultSet
217 $self->_with_meta_hash( sub ($row) {
219 my $return_hash = { substr => substr($row->{name}, 0, 3), substr2 => substr($row->{name}, 0, 4) };
223 Use this method when you want to populate multiple keys of the hash at the same time. If you just want to
224 populate one key, use L</_with_meta_key>.
228 method _with_meta_hash ($modifier) {
229 my $rs = $self->search({});
230 unless ($modifier && (ref $modifier eq 'CODE')) {
231 die 'build_metadata called without modifier param';
234 push( @{$rs->_hash_modifiers}, $modifier );
238 =head2 add_row_info (DEPRECATED)
242 =item Arguments: row => DBIx::Class::Row object, info => HashRef to attach to the row
244 =item Return Value: ResultSet
248 $rs = $rs->add_row_info(row => $row, info => { dates => [qw/mon weds fri/] } );
250 DEPRECATED - this method is quite slow as it requires that you iterate through
251 the resultset each time you want to add metadata. Replaced by L</build_metadata>.
255 method add_row_info (%opts) {
256 my ($row, $id, $info) = map { $opts{$_} } qw/row id info/;
258 warn 'DEPRECATED - add_row_info is deprecated in favour of build_metadata';
260 $id = $self->_mk_id(row => { $row->get_columns });
263 unless ($row || $self->find($id)) {
264 die 'invalid id passed to add_row_info';
267 if (my $existing = $self->_row_info->{$id}) {
268 $info = { %{$existing}, %{$info} };
271 $self->_row_info->{$id} = $info;
275 method row_info_for (%opts) {
277 return $self->_row_info->{$id};
281 method _mk_id (%opts) {
282 my $row = $opts{row};
283 return join('-', map { $row->{$_} } @{$self->id_cols});
288 Luke Saunders <luke.saunders@gmail.com>
292 As usual, thanks to Matt S Trout for the sanity check.
296 This library is free software under the same license as perl itself