paged resultset, which will fetch only a small number of records at a time:
my $rs = $schema->resultset('Artist')->search(
- {},
+ undef,
{
page => 1, # page to return (defaults to 1)
rows => 10, # number of results per page
The C<page> attribute does not have to be specified in your search:
my $rs = $schema->resultset('Artist')->search(
- {},
+ undef,
{
rows => 10,
}
specify which ones you need:
my $rs = $schema->resultset('Artist')->search(
- {},
+ undef,
{
- cols => [qw/ name /]
+ columns => [qw/ name /]
}
);
to access the returned value:
my $rs = $schema->resultset('Artist')->search(
- {},
+ undef,
{
select => [ 'name', { LENGTH => 'name' } ],
as => [qw/ name name_length /],
=head3 SELECT DISTINCT with multiple columns
my $rs = $schema->resultset('Foo')->search(
- {},
+ undef,
{
select => [
{ distinct => [ $source->columns ] }
=head3 SELECT COUNT(DISTINCT colname)
my $rs = $schema->resultset('Foo')->search(
- {},
+ undef,
{
select => [
{ count => { distinct => 'colname' } }
L<DBIx::Class> supports C<GROUP BY> as follows:
my $rs = $schema->resultset('Artist')->search(
- {},
+ undef,
{
join => [qw/ cds /],
select => [ 'name', { count => 'cds.cdid' } ],
# LEFT JOIN cd cds ON ( cds.artist = me.artistid )
# GROUP BY name
+=head3 Predefined searches
+
+You can write your own DBIx::Class::ResultSet class by inheriting from it
+and define often used searches as methods:
+
+ package My::DBIC::ResultSet::CD;
+ use strict;
+ use warnings;
+ use base 'DBIx::Class::ResultSet';
+
+ sub search_cds_ordered {
+ my ($self) = @_;
+
+ return $self->search(
+ {},
+ { order_by => 'name DESC' },
+ );
+ }
+
+ 1;
+
+To use your resultset, first tell DBIx::Class to create an instance of it
+for you, in your My::DBIC::Schema::CD class:
+
+ __PACKAGE__->resultset_class('My::DBIC::ResultSet::CD');
+
+Then call your new method in your code:
+
+ my $ordered_cds = $schema->resultset('CD')->search_cds_ordered();
+
+
+=head3 Predefined searches without writing a ResultSet class
+
+Alternatively you can automatically generate a DBIx::Class::ResultSet
+class by using the ResultSetManager component and tagging your method
+as ResultSet:
+
+ __PACKAGE__->load_components(qw/ ResultSetManager Core /);
+
+ sub search_cds_ordered : ResultSet {
+ my ($self) = @_;
+ return $self->search(
+ {},
+ { order_by => 'name DESC' },
+ );
+ }
+
+Then call your method in the same way from your code:
+
+ my $ordered_cds = $schema->resultset('CD')->search_cds_ordered();
+
=head2 Using joins and prefetch
You can use the C<join> attribute to allow searching on, or sorting your
deep using the same syntax as a multi-step join:
my $rs = $schema->resultset('Tag')->search(
- {},
+ undef,
{
prefetch => {
cd => 'artist'
=head2 Transactions
As of version 0.04001, there is improved transaction support in
-L<DBIx::Class::Storage::DBI>. Here is an example of the recommended
-way to use it:
+L<DBIx::Class::Storage::DBI> and L<DBIx::Class::Schema>. Here is an
+example of the recommended way to use it:
- my $genus = Genus->find(12);
- eval {
- MyDB->txn_begin;
+ my $genus = $schema->resultset('Genus')->find(12);
+
+ my $coderef1 = sub {
+ my ($schema, $genus, $code) = @_;
$genus->add_to_species({ name => 'troglodyte' });
$genus->wings(2);
$genus->update;
- cromulate($genus); # Can have a nested transation
- MyDB->txn_commit;
+ $schema->txn_do($code, $genus); # Can have a nested transaction
+ return $genus->species;
+ };
+
+ my $coderef2 = sub {
+ my ($genus) = @_;
+ $genus->extinct(1);
+ $genus->update;
};
- if ($@) {
- # Rollback might fail, too
- eval {
- MyDB->txn_rollback
- };
+
+ my $rs;
+ eval {
+ $rs = $schema->txn_do($coderef1, $schema, $genus, $coderef2);
+ };
+
+ if ($@) { # Transaction failed
+ die "the sky is falling!" #
+ if ($@ =~ /Rollback failed/); # Rollback failed
+
+ deal_with_failed_transaction();
}
-Currently, a nested commit will do nothing and a nested rollback will
-die. The code at each level must be sure to call rollback in the case
-of an error, to ensure that the rollback will propagate to the top
-level and be issued. Support for savepoints and for true nested
+Nested transactions will work as expected. That is, only the outermost
+transaction will actually issue a commit to the $dbh, and a rollback
+at any level of any transaction will cause the entire nested
+transaction to fail. Support for savepoints and for true nested
transactions (for databases that support them) will hopefully be added
in the future.
$class->next::method($attrs);
}
+For more information about C<next::method>, look in the L<Class::C3>
+documentation. See also L<DBIx::Class::Manual::Component> for more
+ways to write your own base classes to do this.
+
+People looking for ways to do "triggers" with DBIx::Class are probably
+just looking for this.
+
=head2 Stringification
Employ the standard stringification technique by using the C<overload>
your main database class to make sure it disconnects cleanly:
$SIG{INT} = sub {
- __PACKAGE__->storage->dbh->disconnect;
+ __PACKAGE__->storage->disconnect;
};
=head2 Schema import/export
validate => $validate || 0,
parser_args => {
'DBIx::Schema' => $schema,
- }
+ },
producer_args => {
'prefix' => 'My::Schema',
- }
+ },
);
$translator->parser('DBIx::Class');
print $output;
You could use L<Module::Find> to search for all subclasses in the MyDB::*
-namespace, which is currently left as an excercise for the reader.
+namespace, which is currently left as an exercise for the reader.
=head2 Schema versioning
The JDBC-bridge is one way of getting access to a MSSQL-server from a platform
that Microsoft doesn't deliver native client libraries for. (e.g. Linux)
+=head2 Setting quotes for the generated SQL.
+
+If the database contains columnames with spaces and/or reserved words, the
+SQL-query needs to be quoted. This is done using:
+
+ __PACKAGE__->storage->sql_maker->quote_char([ qw/[ ]/] );
+ __PACKAGE__->storage->sql_maker->name_sep('.');
+
+The first sets the quotesymbols. If the quote i "symmetric" as " or '
+
+ __PACKAGE__->storage->sql_maker->quote_char('"');
+
+is enough. If the left quote differs form the right quote, the first
+notation should be used. name_sep needs to be set to allow the
+SQL generator to put the quotes the correct place.
+
=cut