Class-DBI
view release on metacpan or search on metacpan
- Bug with setting driver defaults [Jay Strauss + Schwern]
- Bug where selecting a column that was only in 'All' group also
attempted to fetch any TEMP columns. [Dominic Mitchell]
Removal of Functionality
- Undocumented ordered_search method has been removed in favour of
order_by option to search.
- Undocumented make_filter method removed in favour of add_constructor
- add_constructor no longer does (undocumented) %s substitutions
- (undocumented) single_value_select() method no longer takes raw
SQL fragments.
0.92 Sat Apr 12 2003
New Functionality
- classes named after reserved SQL words can now supply a
table_alias either directly, or as a second argument to table().
Deprecations
- hasa() now calls has_a() with a warning. It will disappear
completely in a forthcoming release.
Makefile.PL view on Meta::CPAN
0.95 - Breaking the encapsulation of an object (e.g. assuming that
the value for the 'title' column will be stored internally in
$object->{'title'} will stop working in a forthcoming release.
Relying on this behaviour is a Bad Thing, and you should fix it
now! (This also applies to before_create triggers, where
previously it was the supported approach.)
0.93 - Undocumented ordered_search() method no longer exists
- Undocumented make_filter() method no longer exists
- Undocumented option for add_constructor to do %s subitutions removed
- single_value_select() no longer takes raw SQL fragments
0.91 - on_setting() trigger point replaced by new individual column
triggers (see documentation on constraints)
- runtime database errors now throw exceptions
- all errors standardised so on_failed_create no longer needed
- objects now overload in string or boolean context
0.90 - hasa is now deprecated in favour of has_a. Therefore
has_many no longer creates reciprocal hasa relationship.
similarly be:
Music::CD->set_sql(new_music => qq{
SELECT __ESSENTIAL__
FROM __TABLE__
WHERE year > ?
});
For such 'SELECT' queries Ima::DBI's set_sql() method is extended to
create a helper shortcut method, named by prefixing the name of the SQL
fragment with 'search_'. Thus, the above call to set_sql() will
automatically set up the method Music::CD->search_new_music(), which
will execute this search and return the relevant objects or Iterator.
(If there are placeholders in the query, you must pass the relevant
arguments when calling your search method.)
This does the equivalent of:
sub search_new_music {
my ($class, @args) = @_;
my $sth = $class->sql_new_music;
This can also take placeholders and/or do column interpolation if
required:
__PACKAGE__->set_sql(count_above => q{
SELECT COUNT(*) FROM __TABLE__ WHERE %s > ?
});
# .. then ..
my $count = $class->sql_count_above('year')->select_val(2001);
sql_single
Internally Class::DBI defines a very simple SQL fragment called
'single':
"SELECT %s FROM __TABLE__".
This is used to implement the above Class->count_all():
$class->sql_single("COUNT(*)")->select_val;
This interpolates the COUNT(*) into the %s of the SQL, and then executes
the query, returning a single value.
lib/Class/DBI.pm view on Meta::CPAN
my $search = Class::DBI::Search::Basic->new($class, @args);
$search->type($type);
$search->run_search;
}
#----------------------------------------------------------------------
# CONSTRUCTORS
#----------------------------------------------------------------------
sub add_constructor {
my ($class, $method, $fragment) = @_;
return $class->_croak("constructors needs a name") unless $method;
no strict 'refs';
my $meth = "$class\::$method";
return $class->_carp("$method already exists in $class")
if *$meth{CODE};
*$meth = sub {
my $self = shift;
$self->sth_to_objects($self->sql_Retrieve($fragment), \@_);
};
}
sub sth_to_objects {
my ($class, $sth, $args) = @_;
$class->_croak("sth_to_objects needs a statement handle") unless $sth;
unless (UNIVERSAL::isa($sth => "DBI::st")) {
my $meth = "sql_$sth";
$sth = $class->$meth();
}
lib/Class/DBI.pm view on Meta::CPAN
similarly be:
Music::CD->set_sql(new_music => qq{
SELECT __ESSENTIAL__
FROM __TABLE__
WHERE year > ?
});
For such 'SELECT' queries L<Ima::DBI>'s set_sql() method is extended to
create a helper shortcut method, named by prefixing the name of the
SQL fragment with 'search_'. Thus, the above call to set_sql() will
automatically set up the method Music::CD->search_new_music(), which
will execute this search and return the relevant objects or Iterator.
(If there are placeholders in the query, you must pass the relevant
arguments when calling your search method.)
This does the equivalent of:
sub search_new_music {
my ($class, @args) = @_;
my $sth = $class->sql_new_music;
lib/Class/DBI.pm view on Meta::CPAN
This can also take placeholders and/or do column interpolation if required:
__PACKAGE__->set_sql(count_above => q{
SELECT COUNT(*) FROM __TABLE__ WHERE %s > ?
});
# .. then ..
my $count = $class->sql_count_above('year')->select_val(2001);
=head3 sql_single
Internally Class::DBI defines a very simple SQL fragment called 'single':
"SELECT %s FROM __TABLE__".
This is used to implement the above Class->count_all():
$class->sql_single("COUNT(*)")->select_val;
This interpolates the COUNT(*) into the %s of the SQL, and then executes
the query, returning a single value.
lib/Class/DBI/Search/Basic.pm view on Meta::CPAN
=head2 run_search
my @results = $searcher->run_search;
my $iterator = $searcher->run_search;
Actually run the search.
=head1 SUBCLASSING
=head2 sql / bind / fragment
The actual mechanics of generating the SQL and executing it split up
into a variety of methods for you to override.
run_search() is implemented as:
return $cdbi->sth_to_objects($self->sql, $self->bind);
Where sql() is
$cdbi->sql_Retrieve($self->fragment);
There are also a variety of private methods underneath this that could
be overriden in a pinch, but if you need to do this I'd rather you let
me know so that I can make them public, or at least so that I don't
remove them from under your feet.
=cut
use strict;
lib/Class/DBI/Search/Basic.pm view on Meta::CPAN
sub _qual {
my $self = shift;
$self->{_qual} ||= $self->_qual_bind->[0];
}
sub bind {
my $self = shift;
$self->{_bind} ||= $self->_qual_bind->[1];
}
sub fragment {
my $self = shift;
my $frag = join " AND ", @{ $self->_qual };
if (my $order = $self->opt('order_by')) {
$frag .= " ORDER BY $order";
}
return $frag;
}
sub sql {
my $self = shift;
return $self->class->sql_Retrieve($self->fragment);
}
sub run_search {
my $self = shift;
my $cdbi = $self->class;
return $cdbi->sth_to_objects($self->sql, $self->bind);
}
1;
t/10-mysql.t view on Meta::CPAN
is @all, 3, "3 films";
ok $all[2]->title gt $all[1]->title && $all[1]->title gt $all[0]->title,
"sorted by title";
}
{
package Class::DBI::Search::Test::Limited;
use base 'Class::DBI::Search::Basic';
sub fragment {
my $self = shift;
my $frag = $self->SUPER::fragment;
if (defined(my $limit = $self->opt('limit'))) {
$frag .= " LIMIT $limit";
}
return $frag;
}
package main;
MyFilm->add_searcher(search => "Class::DBI::Search::Test::Limited");
my @common = map MyFilm->insert({ title => "Common Title" }), 1 .. 3;
{
my @ltd = MyFilm->search(
title => "Common Title",
( run in 1.202 second using v1.01-cache-2.11-cpan-364913b4093 )