Revision history for DBIx::Class
+ * Misc
+ - Replace $row with $result in all docs to be consistent and to
+ clarify various return values
+
0.08250 2013-04-29 22:00 (UTC)
* New Features / Changes
- Rewrite from scratch the result constructor codepath - many bugfixes
Emulates the I<undocumnted> behavior of Class::DBI where the object can be accessed as a hash of columns. This is often used as a performance hack.
- my $column = $row->{column};
+ my $column = $result->{column};
=head2 Differences from Class::DBI
reference with C<filter_from_storage> and C<filter_to_storage> set to either
a method name or a code reference. In either case the filter is invoked as:
- $row_obj->$filter_specification ($value_to_filter)
+ $result->$filter_specification ($value_to_filter)
with C<$filter_specification> being chosen depending on whether the
C<$value_to_filter> is being retrieved from or written to permanent
numbers => [1, 2, 3]
});
- $row->update(
+ $result->update(
{
numbers => [1, 2, 3]
},
Use L<DBIx::Class::Row/discard_changes>.
- $row->discard_changes
+ $result->discard_changes
Discarding changes and refreshing from storage are two sides fo the same coin. When you
want to discard your local changes, just re-fetch the row from storage. When you want
the Row.
# will return the scalar reference:
- $row->somecolumn()
+ $result->somecolumn()
# issue a select using the PK to re-fetch the row data:
- $row->discard_changes();
+ $result->discard_changes();
# Now returns the correct new value:
- $row->somecolumn()
+ $result->somecolumn()
To update and refresh at once, chain your calls:
- $row->update({ 'somecolumn' => { -ident => 'othercolumn' } })->discard_changes;
+ $result->update({ 'somecolumn' => { -ident => 'othercolumn' } })->discard_changes;
=item .. store JSON/YAML in a column and have it deflate/inflate automatically?
With either of these methods the resulting use of the accesssor would be
- my $row;
+ my $result;
- # assume that somewhere in here $row will get assigned to a MyTable row
+ # assume that somewhere in here $result will get assigned to a MyTable row
- $row->non_column_data('some string'); # would set the non_column_data accessor
+ $result->non_column_data('some string'); # would set the non_column_data accessor
# some other stuff happens here
- $row->update(); # would not inline the non_column_data accessor into the update
+ $result->update(); # would not inline the non_column_data accessor into the update
=item How do I use DBIx::Class objects in my TT templates?
For example, the following would not work (assuming C<People> does not have
a declared PK):
- my $row = $schema->resultset('People')
+ my $result = $schema->resultset('People')
->search({ last_name => 'Dantes' })
->next;
- $row->update({ children => 2 }); # <-- exception thrown because $row isn't
+ $result->update({ children => 2 }); # <-- exception thrown because $result isn't
# necessarily unique
So instead the following should be done:
Note that the '+as' does not produce an SQL 'AS' keyword in the
output, see the L<DBIx::Class::Manual::FAQ> for an explanation.
-This type of column restriction has a downside, the resulting $row
+This type of column restriction has a downside, the returned $result
object will have no 'track_name' accessor:
- while(my $row = $search_rs->next) {
- print $row->track_name; ## ERROR
+ while(my $result = $search_rs->next) {
+ print $result->track_name; ## ERROR
}
Instead C<get_column> must be used:
- while(my $row = $search_rs->next) {
- print $row->get_column('track_name'); ## WORKS
+ while(my $result = $search_rs->next) {
+ print $result->get_column('track_name'); ## WORKS
}
=head2 Incomplete related objects
Now you can access the result using the relationship accessor:
- while(my $row = $search_rs->next) {
- print $row->tracks->name; ## WORKS
+ while(my $result = $search_rs->next) {
+ print $result->tracks->name; ## WORKS
}
However, this will produce broken objects. If the tracks id column is
'4', '1990', '1979'
Note that in order to be able to use
-L<< $row->create_related|DBIx::Class::Relationship::Base/create_related >>,
+L<< $result->create_related|DBIx::Class::Relationship::Base/create_related >>,
the coderef must not only return as its second such a "simple" condition
hashref which does not depend on joins being available, but the hashref must
contain only plain values/deflatable objects, such that the result can be
=back
# These pairs do the same thing
- $row = $cd->related_resultset('artist')->single; # has_one relationship
- $row = $cd->artist;
+ $result = $cd->related_resultset('artist')->single; # has_one relationship
+ $result = $cd->artist;
$rs = $cd->related_resultset('tracks'); # has_many relationship
$rs = $cd->tracks;
=item From a Result object:
- $row->result_source;
+ $result->result_source;
=item From a ResultSet object:
=head2 new
- my $row = My::Class->new(\%attrs);
+ my $result = My::Class->new(\%attrs);
- my $row = $schema->resultset('MySource')->new(\%colsandvalues);
+ my $result = $schema->resultset('MySource')->new(\%colsandvalues);
=over
# Each pair does the same thing
# (un-inflated, regular column)
- my $val = $row->get_column('first_name');
- my $val = $row->first_name;
+ my $val = $result->get_column('first_name');
+ my $val = $result->first_name;
- $row->set_column('first_name' => $val);
- $row->first_name($val);
+ $result->set_column('first_name' => $val);
+ $result->first_name($val);
# (inflated column via DBIx::Class::InflateColumn::DateTime)
- my $val = $row->get_inflated_column('last_modified');
- my $val = $row->last_modified;
+ my $val = $result->get_inflated_column('last_modified');
+ my $val = $result->last_modified;
- $row->set_inflated_column('last_modified' => $val);
- $row->last_modified($val);
+ $result->set_inflated_column('last_modified' => $val);
+ $result->last_modified($val);
=over
=head2 insert
- $row->insert;
+ $result->insert;
=over
=head2 in_storage
- $row->in_storage; # Get value
- $row->in_storage(1); # Set value
+ $result->in_storage; # Get value
+ $result->in_storage(1); # Set value
=over
=head2 update
- $row->update(\%columns?)
+ $result->update(\%columns?)
=over
=back
Throws an exception if the result object is not yet in the database,
-according to L</in_storage>.
+according to L</in_storage>. Returns the object itself.
This method issues an SQL UPDATE query to commit any changes to the
object to the database if required (see L</get_dirty_columns>).
If the values passed or any of the column values set on the object
contain scalar references, e.g.:
- $row->last_modified(\'NOW()')->update();
+ $result->last_modified(\'NOW()')->update();
# OR
- $row->update({ last_modified => \'NOW()' });
+ $result->update({ last_modified => \'NOW()' });
The update will pass the values verbatim into SQL. (See
L<SQL::Abstract> docs). The values in your Result object will NOT change
with the actual values from the database, call L</discard_changes>
after the update.
- $row->update()->discard_changes();
+ $result->update()->discard_changes();
To determine before calling this method, which column values have
changed and will be updated, call L</get_dirty_columns>.
=head2 delete
- $row->delete
+ $result->delete
=over
=head2 get_column
- my $val = $row->get_column($col);
+ my $val = $result->get_column($col);
=over
Note that if you used the C<columns> or the C<select/as>
L<search attributes|DBIx::Class::ResultSet/ATTRIBUTES> on the resultset from
-which C<$row> was derived, and B<did not include> C<$columnname> in the list,
+which C<$result> was derived, and B<did not include> C<$columnname> in the list,
this method will return C<undef> even if the database contains some value.
To retrieve all loaded column values as a hash, use L</get_columns>.
=head2 has_column_loaded
- if ( $row->has_column_loaded($col) ) {
+ if ( $result->has_column_loaded($col) ) {
print "$col has been loaded from db";
}
=head2 get_columns
- my %data = $row->get_columns;
+ my %data = $result->get_columns;
=over
=head2 get_dirty_columns
- my %data = $row->get_dirty_columns;
+ my %data = $result->get_dirty_columns;
=over
=head2 make_column_dirty
- $row->make_column_dirty($col)
+ $result->make_column_dirty($col)
=over
=head2 set_column
- $row->set_column($col => $val);
+ $result->set_column($col => $val);
=over
=head2 set_columns
- $row->set_columns({ $col => $val, ... });
+ $result->set_columns({ $col => $val, ... });
=over
=head2 set_inflated_columns
- $row->set_inflated_columns({ $col => $val, $relname => $obj, ... });
+ $result->set_inflated_columns({ $col => $val, $relname => $obj, ... });
=over
=head2 store_column
- $row->store_column($col => $val);
+ $result->store_column($col => $val);
=over
=head2 update_or_insert
- $row->update_or_insert
+ $result->update_or_insert
=over
=head2 is_changed
- my @changed_col_names = $row->is_changed();
- if ($row->is_changed()) { ... }
+ my @changed_col_names = $result->is_changed();
+ if ($result->is_changed()) { ... }
=over
=head2 is_column_changed
- if ($row->is_column_changed('col')) { ... }
+ if ($result->is_column_changed('col')) { ... }
=over
=head2 result_source
- my $resultsource = $row->result_source;
+ my $resultsource = $result->result_source;
=over
=head2 get_from_storage
- my $copy = $row->get_from_storage($attrs)
+ my $copy = $result->get_from_storage($attrs)
=over
=head2 discard_changes
- $row->discard_changes
+ $result->discard_changes
=over
=head2 id
- my @pk = $row->id;
+ my @pk = $result->id;
=over
my $txn_guard = $storage->txn_scope_guard;
- $row->col1("val1");
- $row->update;
+ $result->col1("val1");
+ $result->update;
$txn_guard->commit;
Due to the fact that replicants can lag behind a master, you must take care to
make sure you use one of the methods to force read queries to a master should
you need realtime data integrity. For example, if you insert a row, and then
-immediately re-read it from the database (say, by doing $row->discard_changes)
+immediately re-read it from the database (say, by doing $result->discard_changes)
or you insert a row and then immediately build a query that expects that row
to be an item, you should force the master to handle reads. Otherwise, due to
the lag, there is no certainty your data will be in the expected state.
Otherwise, you can force a single query to use the master with the 'force_pool'
attribute:
- my $row = $resultset->search(undef, {force_pool=>'master'})->find($pk);
+ my $result = $resultset->search(undef, {force_pool=>'master'})->find($pk);
This attribute will safely be ignore by non replicated storages, so you can use
the same code for both types of systems.
$schema->txn_do(sub {
my $rs = $schema->resultset('Book');
- while (my $row = $rs->next) {
+ while (my $result = $rs->next) {
$schema->resultset('MetaData')->create({
- book_id => $row->id,
+ book_id => $result->id,
...
});
}