Skip to content

Commit

Permalink
Switch to DBIx::Introspector for SQL generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthur Axel 'fREW' Schmidt committed Jan 12, 2014
1 parent e1706aa commit 7f0c96e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 42 deletions.
1 change: 1 addition & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Revision history for {{$dist->name}}

{{$NEXT}}
- Pick SQL for random row selection in a cleaner way
- Stop using Class::MOP::load_class (RT#91035)

2.019001 2013-11-23 10:19:28 America/Chicago
Expand Down
3 changes: 3 additions & 0 deletions cpanfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ requires 'String::CamelCase' => 0;
requires 'namespace::clean' => 0.23;
requires 'List::Util' => 0;
requires 'DBIx::Class::Candy' => 0.001003;
requires 'DBIx::Introspector';
requires 'Module::Runtime';
requires 'Try::Tiny';

on test => sub {
requires 'Test::More' => 0.94;
Expand Down
60 changes: 18 additions & 42 deletions lib/DBIx/Class/Helper/ResultSet/Random.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,34 @@ package DBIx::Class::Helper::ResultSet::Random;

use strict;
use warnings;
use Module::Runtime 'use_module';
use Try::Tiny;

# ABSTRACT: Get random rows from a ResultSet

# VERSION

# this is ghetto
my %rand_order_by = (
'DBIx::Class::Storage::DBI::SQLite' => 'RANDOM()',
'DBIx::Class::Storage::DBI::mysql' => 'RAND()',
'DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server' => 'NEWID()',
'DBIx::Class::Storage::DBI::MSSQL' => 'NEWID()',
'DBIx::Class::Storage::DBI::Pg' => 'RANDOM()',
'DBIx::Class::Storage::DBI::Oracle' => 'dbms_random.value',
'DBIx::Class::Storage::DBI::Sybase::MSSQL' => 'NEWID()',
'DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server::NoBindVars' =>
'NEWID()',
'DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server' => 'NEWID()',
'DBIx::Class::Storage::DBI::Sybase::ASE::NoBindVars' => 'RAND()',
'DBIx::Class::Storage::DBI::Sybase::ASE' => 'RAND()',
'DBIx::Class::Storage::DBI::Sybase' => 'RAND()',
'DBIx::Class::Storage::DBI::SQLAnywhere' => 'RAND()',
'DBIx::Class::Storage::DBI::Oracle::WhereJoins' => 'dbms_random.value',
'DBIx::Class::Storage::DBI::Oracle::Generic' => 'dbms_random.value',
'DBIx::Class::Storage::DBI::ODBC::SQL_Anywhere' => 'RAND()',
'DBIx::Class::Storage::DBI::ODBC::Firebird' => 'RAND()',
'DBIx::Class::Storage::DBI::ODBC::ACCESS' => 'RND()',
'DBIx::Class::Storage::DBI::mysql::backup' => 'RAND()',
'DBIx::Class::Storage::DBI::InterBase' => 'RAND()',
'DBIx::Class::Storage::DBI::Firebird::Common' => 'RAND()',
'DBIx::Class::Storage::DBI::Firebird' => 'RAND()',
'DBIx::Class::Storage::DBI::DB2' => 'RAND()',
'DBIx::Class::Storage::DBI::ADO::MS_Jet' => 'RND()',
'DBIx::Class::Storage::DBI::ADO::Microsoft_SQL_Server' => 'NEWID()',
'DBIx::Class::Storage::DBI::ACCESS' => 'RND()',
);

{
#sort keys descending to handle more specific storage classes first
#(right now it does not make a difference though)
my @keys_rand_order_by = sort { $b cmp $a } keys %rand_order_by;
sub _introspector {
my $d = use_module('DBIx::Introspector')
->new(drivers => '2013-12.01');

$d->decorate_driver_unconnected(ACCESS => rand_sql => sub { 'RND()' });
$d->decorate_driver_unconnected(Oracle => rand_sql => sub { 'dbms_random.value' });
$d->decorate_driver_unconnected(Pg => rand_sql => sub { 'RANDOM()' });
$d->decorate_driver_unconnected(MSSQL => rand_sql => sub { 'NEWID()' });
$d->decorate_driver_unconnected(SQLite => rand_sql => sub { 'RANDOM()' });

$d
}

my $d;
sub _rand_order_by {
my $self = shift;
$self->result_source->storage->_determine_driver;
my $storage = $self->result_source->storage;
$storage->ensure_connected;

for my $dbms (@keys_rand_order_by) {
return $rand_order_by{$dbms} if $storage->isa($dbms);
}

return 'RAND()';
}
$d ||= $self->_introspector;
return try { $d->get($storage->dbh, undef, 'rand_sql') } catch { 'RAND()' };
}

sub rand {
Expand Down

0 comments on commit 7f0c96e

Please sign in to comment.