Note to self: Don't checkout anything from //mirror - Even if you have no need to edit it...
Revision history for DBIx::Class
-0.07005 2007-01-10 18:36:00
- - fixup changes file
- - remove erroneous .orig files - oops
-
-0.07004 2007-01-09 21:52:00
+0.07999_02 2007-01-25 20:11:00
+ - add support for binding BYTEA and similar parameters (w/Pg impl)
+ - add support to Ordered for multiple ordering columns
+ - mark DB.pm and compose_connection as deprecated
+ - switch tests to compose_namespace
+ - ResltClass::HashRefInflator added
+ - Changed row and rs objects to not have direct handle to a source,
+ instead a (schema,source_name) tuple of type ResultSourceHandle
+
+0.07999_01 2006-10-05 21:00:00
+ - add connect_info option "disable_statement_caching"
+ - create insert_bulk using execute_array, populate uses it
+ - added DBIx::Class::Schema::load_namespaces, alternative to
+ load_classes
+ - added source_info method for source-level metadata (kinda like
+ column_info)
+ - Some of ::Storage::DBI's code/docs moved to ::Storage
+ - DBIx::Class::Schema::txn_do code moved to ::Storage
+ - Storage::DBI now uses exceptions instead of ->ping/->{Active} checks
+ - Storage exceptions are thrown via the schema class's throw_exception
+ - DBIx::Class::Schema::throw_exception's behavior can be modified via
+ ->exception_action
+ - columns_info_for is deprecated, and no longer runs automatically.
+ You can make it work like before via
+ __PACKAGE__->column_info_from_storage(1) for now
+ - Replaced DBIx::Class::AccessorGroup and Class::Data::Accessor with
+ Class::Accessor::Grouped. Only user noticible change is to
+ table_class on ResultSourceProxy::Table (i.e. table objects in
+ schemas) and, resultset_class and result_class in ResultSource.
+ These accessors no longer automatically require the classes when
+ set.
+
+0.07004
- fix find_related-based queries to correctly grep the unique key
- - fix InflateColumn to inflate/deflate all refs but scalar refs
0.07003 2006-11-16 11:52:00
- fix for rt.cpan.org #22740 (use $^X instead of hardcoded "perl")
# Skip maint stuff
^maint/
-# Avoid copies to .orig
-\.orig$
+# Dont use Module::Build anymore
+# Build.PL
# i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
# brain damage and presumably various other packaging systems too
-$VERSION = '0.07005';
+$VERSION = '0.07999_02';
sub MODIFY_CODE_ATTRIBUTES {
my ($class,$code,@attrs) = @_;
columns to be of the datetime, timestamp or date datatype.
package Event;
- __PACKAGE__->load_components(qw/Core InflateColumn::DateTime/);
+ __PACKAGE__->load_components(qw/InflateColumn::DateTime/);
__PACKAGE__->add_columns(
starts_when => { data_type => 'datetime' }
);
that this feature is new as of 0.07, so it may not be perfect yet - bug
reports to the list very much welcome).
-For more help with using components, see L<DBIx::Class::Manual::Component/USING>.
+For more help with components, see L<DBIx::Class::Manual::Component>.
=cut
);
# Equivalent SQL:
- # SELECT name name, LENGTH( name )
+ # SELECT name name, LENGTH( name ) name_length
# FROM artist
-Note that the C< as > attribute has absolutely nothing to with the sql
-syntax C< SELECT foo AS bar > (see the documentation in
-L<DBIx::Class::ResultSet/ATTRIBUTES>). If your alias exists as a
-column in your base class (i.e. it was added with C<add_columns>), you
-just access it as normal. Our C<Artist> class has a C<name> column, so
-we just use the C<name> accessor:
+If your alias exists as a column in your base class (i.e. it was added
+with C<add_columns>), you just access it as normal. Our C<Artist>
+class has a C<name> column, so we just use the C<name> accessor:
my $artist = $rs->first();
my $name = $artist->name();
select => [
{ distinct => [ $source->columns ] }
],
- as => [ $source->columns ] # remember 'as' is not the same as SQL AS :-)
+ as => [ $source->columns ]
}
);
# LEFT JOIN cd cds ON ( cds.artist = me.artistid )
# GROUP BY name
-Please see L<DBIx::Class::ResultSet/ATTRIBUTES> documentation if you
-are in any way unsure about the use of the attributes above (C< join
->, C< select >, C< as > and C< group_by >).
-
=head3 Predefined searches
You can write your own L<DBIx::Class::ResultSet> class by inheriting from it
{},
{
select => [ { sum => 'Cost' } ],
- as => [ 'total_cost' ], # remember this 'as' is for DBIx::Class::ResultSet not SQL
+ as => [ 'total_cost' ],
}
);
my $tc = $rs->first->get_column('total_cost');
=head2 Many-to-many relationships
-This is straightforward using L<ManyToMany|DBIx::Class::Relationship/many_to_many>:
+This is straightforward using L<DBIx::Class::Relationship::ManyToMany>:
package My::DB;
# ... set up connection ...
To make an object stringify itself as a single column, use something
like this (replace C<foo> with the column/method of your choice):
- use overload '""' => sub { shift->name}, fallback => 1;
+ use overload '""' => 'foo', fallback => 1;
For more complex stringification, you can use an anonymous subroutine:
# do whatever else you wanted if it was a new row
}
-=head3 Wrapping/overloading a column accessor
-
-Problem: Say you have a table "Camera" and want to associate a description
-with each camera. For most cameras, you'll be able to generate the description from
-the other columns. However, in a few special cases you may want to associate a
-custom description with a camera.
-
-Solution:
-
-In your database schema, define a description field in the "Camera" table that
-can contain text and null values.
-
-In DBIC, we'll overload the column accessor to provide a sane default if no
-custom description is defined. The accessor will either return or generate the
-description, depending on whether the field is null or not.
-
-First, in your "Camera" schema class, define the description field as follows:
-
- __PACKAGE__->add_columns(description => { accessor => '_description' });
-
-Next, we'll define the accessor-wrapper subroutine:
-
- sub description {
- my $self = shift;
-
- # If there is an update to the column, we'll let the original accessor
- # deal with it.
- return $self->_description(@_) if @_;
-
- # Fetch the column value.
- my $description = $self->_description;
-
- # If there's something in the description field, then just return that.
- return $description if defined $description && length $descripton;
-
- # Otherwise, generate a description.
- return $self->generate_description;
- }
-
=cut
L<DBIx::Class::ResultSetColumn>, see it's documentation and the
L<Cookbook|DBIx::Class::Manual::Cookbook> for details.
-=item .. fetch a formatted column?
-
-In your table schema class, create a "private" column accessor with:
-
- __PACKAGE__->add_columns(my_common => { accessor => '_hidden_my_column' });
-
-Then, in the same class, implement a subroutine called "my_column" that
-fetches the real value and does the formatting you want.
-
-See the Cookbook for more details.
-
-=item .. fetch a single (or topmost) row?
-
-Sometimes you many only want a single record back from a search. A quick
-way to get that single row is to first run your search as usual:
-
- ->search->(undef, { order_by => "id DESC" })
-
-Then call L<DBIx::Class::ResultSet/slice> and ask it only to return 1 row:
-
- ->slice(0,1)
-
-These two calls can be combined into a single statement:
-
- ->search->(undef, { order_by => "id DESC" })->slice(0,1)
-
-Why slice instead of L<DBIx::Class::ResultSet/first> or L<DBIx::Class::ResultSet/single>?
-If supported by the database, slice will use LIMIT/OFFSET to hint to the database that we
-really only need one row. This can result in a significant speed improvement.
-
=back
=head2 Inserting and updating data
->update({ somecolumn => \'othercolumn' })
-=item .. store JSON/YAML in a column and have it deflate/inflate automatically?
-
-You can use L<DBIx::Class::InflateColumn> to accomplish YAML/JSON storage transparently.
-
-If you want to use JSON, then in your table schema class, do the following:
-
- use JSON;
-
- __PACKAGE__->add_columns(qw/ ... my_column ../)
- __PACKAGE__->inflate_column('my_column', {
- inflate => sub { jsonToObj(shift) },
- deflate => sub { objToJson(shift) },
- });
-
-For YAML, in your table schema class, do the following:
-
- use YAML;
-
- __PACKAGE__->add_columns(qw/ ... my_column ../)
- __PACKAGE__->inflate_column('my_column', {
- inflate => sub { YAML::Load(shift) },
- deflate => sub { YAML::Dump(shift) },
- });
-
-This technique is an easy way to store supplemental unstructured data in a table. Be
-careful not to overuse this capability, however. If you find yourself depending more
-and more on some data within the inflated column, then it may be time to factor that
-data out.
-
=back
=head2 Misc
L<DBI> version 1.50 and L<DBD::Pg> 1.43 are known to work.
-=head2 ... Can't locate object method "source_name" via package ...
-
-There's likely a syntax error in the table class referred to elsewhere
-in this error message. In particular make sure that the package
-declaration is correct, so for a schema C< MySchema > you need to
-specify a fully qualified namespace: C< package MySchema::MyTable; >
-for example.
-
=cut
position INTEGER NOT NULL
);
-In your Schema or DB class add "Ordered" to the top
+Optionally, add one or more columns to specify groupings, allowing you
+to maintain independent ordered lists within one table:
+
+ CREATE TABLE items (
+ item_id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT NOT NULL,
+ position INTEGER NOT NULL,
+ group_id INTEGER NOT NULL
+ );
+
+Or even
+
+ CREATE TABLE items (
+ item_id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT NOT NULL,
+ position INTEGER NOT NULL,
+ group_id INTEGER NOT NULL,
+ other_group_id INTEGER NOT NULL
+ );
+
+In your Schema or DB class add Ordered to the top
of the component list.
__PACKAGE__->load_components(qw( Ordered ... ));
package My::Item;
__PACKAGE__->position_column('position');
-That's it, now you can change the position of your objects.
+If you are using one grouping column, specify it as follows:
+
+ __PACKAGE__->grouping_column('group_id');
+
+Or if you have multiple grouping columns:
+
+ __PACKAGE__->grouping_column(['group_id', 'other_group_id']);
+
+Thats it, now you can change the position of your objects.
#!/use/bin/perl
use My::Item;
__PACKAGE__->position_column('position');
Sets and retrieves the name of the column that stores the
-positional value of each record. Defaults to "position".
+positional value of each record. Default to "position".
=cut
__PACKAGE__->grouping_column('group_id');
-This method specifies a column to limit all queries in
+This method specified a column to limit all queries in
this module by. This effectively allows you to have multiple
ordered lists within the same table.
my $rs = $item->siblings();
my @siblings = $item->siblings();
-Returns either a resultset or an array of all other objects
+Returns either a result set or an array of all other objects
excluding the one you called it on.
=cut
my $sibling = $item->first_sibling();
Returns the first sibling object, or 0 if the first sibling
-is this sibling.
+is this sibliing.
=cut
my $sibling = $item->last_sibling();
-Returns the last sibling, or 0 if the last sibling is this
+Return the last sibling, or 0 if the last sibling is this
sibling.
=cut
my $sibling = $item->previous_sibling();
-Returns the sibling that resides one position back. Returns undef
-if the current object is the first one.
+Returns the sibling that resides one position back. Undef
+is returned if the current object is the first one.
=cut
my $sibling = $item->next_sibling();
-Returns the sibling that resides one position forward. Returns undef
-if the current object is the last one.
+Returns the sibling that resides one position foward. Undef
+is returned if the current object is the last one.
=cut
$item->move_previous();
-Swaps position with the sibling in the position previous in
-the list. Returns 1 on success, and 0 if the object is
-already the first one.
+Swaps position with the sibling on position previous in the list.
+1 is returned on success, and 0 is returned if the objects is already
+the first one.
=cut
$item->move_next();
-Swaps position with the sibling in the next position in the
-list. Returns 1 on success, and 0 if the object is already
-the last in the list.
+Swaps position with the sibling in the next position. 1 is returned on
+success, and 0 is returned if the object is already the last in the list.
=cut
$item->move_first();
-Moves the object to the first position in the list. Returns 1
-on success, and 0 if the object is already the first.
+Moves the object to the first position. 1 is returned on
+success, and 0 is returned if the object is already the first.
=cut
$item->move_last();
-Moves the object to the last position in the list. Returns 1
-on success, and 0 if the object is already the last one.
+Moves the object to the very last position. 1 is returned on
+success, and 0 is returned if the object is already the last one.
=cut
$item->move_to( $position );
-Moves the object to the specified position. Returns 1 on
-success, and 0 if the object is already at the specified
-position.
+Moves the object to the specified position. 1 is returned on
+success, and 0 is returned if the object is already at the
+specified position.
=cut
=head2 _grouping_clause
-This method returns a name=>value pair for limiting a search
-by the collection column. If the collection column is not
+This method returns one or more name=>value pairs for limiting a search
+by the grouping column(s). If the grouping column is not
defined then this will return an empty list.
=cut
If a position is not specified for an insert than a position
will be chosen based on COUNT(*)+1. But, it first selects the
-count, and then inserts the record. The space of time between select
+count then inserts the record. The space of time between select
and insert introduces a race condition. To fix this we need the
ability to lock tables in DBIC. I've added an entry in the TODO
about this.
My::DBIC::Schema::Role->many_to_many( actors => 'actor_roles', 'actor' );
-To add a role for your actor, and fill in the year of the role in the
-actor_roles table:
-
- $actor->add_to_roles($role, { year => 1995 });
-
Many_to_many is not strictly a relationship in its own right. Instead, it is
a bridge between two resultsets which provide the same kind of convenience
accessors as true relationships provide. Although the accessor will return a
});
would return all CDs and include a 'name' column to the information
-passed to object inflation. Note that the 'artist' is the name of the
-column (or relationship) accessor, and 'name' is the name of the column
-accessor in the related table.
+passed to object inflation
=head2 select
=back
-Indicates column names for object inflation. That is, c< as >
-indicates the name that the column can be accessed as via the
-C<get_column> method (or via the object accessor, B<if one already
-exists>). It has nothing to do with the SQL code C< SELECT foo AS bar
->.
-
-The C< as > attribute is used in conjunction with C<select>,
-usually when C<select> contains one or more function or stored
+Indicates column names for object inflation. This is used in conjunction with
+C<select>, usually when C<select> contains one or more function or stored
procedure names:
$rs = $schema->resultset('Employee')->search(undef, {
$source->resultset_attributes({ order_by => [ 'id' ] });
-Specify here any attributes you wish to pass to your specialised
-resultset. For a full list of these, please see
-L<DBIx::Class::ResultSet/ATTRIBUTES>.
+Specify here any attributes you wish to pass to your specialised resultset.
=cut
=head2 update
- $obj->update \%columns?;
+ $obj->update;
Must be run on an object that is already in the database; issues an SQL
UPDATE query to commit any changes to the object to the database if
required.
-Also takes an options hashref of C<< column_name => value> pairs >> to update
-first. But be aware that this hashref might be edited in place, so dont rely on
-it being the same after a call to C<update>.
-
=cut
sub update {
my ($self, $type, $dir, $version, $pversion) = @_;
my $filename = ref($self);
- $filename =~ s/::/-/g;
+ $filename =~ s/::/-/;
$filename = File::Spec->catfile($dir, "$filename-$version-$type.sql");
$filename =~ s/$version/$pversion-$version/ if($pversion);
local $TODO = 'fixing collapse in -current';
is_deeply( $prefetch_result, $nonpre_result,
'Compare 2 level prefetch result to non-prefetch result' );
-}
\ No newline at end of file
+}
+