AlignDB-SQL
view release on metacpan or search on metacpan
NAME
AlignDB::SQL - An SQL statement generator.
SYNOPSIS
my $sql = AlignDB::SQL->new();
$sql->select([ 'id', 'name', 'bucket_id', 'note_id' ]);
$sql->from([ 'foo' ]);
$sql->add_where('name', 'fred');
$sql->add_where('bucket_id', { op => '!=', value => 47 });
$sql->add_where('note_id', \'IS NULL');
$sql->limit(1);
my $sth = $dbh->prepare($sql->as_sql);
$sth->execute(@{ $sql->{bind} });
my @values = $sth->selectrow_array();
my $obj = SomeObject->new();
$obj->set_columns(...);
DESCRIPTION
AlignDB::SQL represents an SQL statement.
Most codes come from Data::ObjectDriver::SQL
lib/AlignDB/SQL.pm view on Meta::CPAN
package AlignDB::SQL;
use Moose;
use MooseX::Storage;
use YAML qw(Dump Load DumpFile LoadFile);
with Storage( 'format' => 'YAML' );
our $VERSION = '1.0.2';
has 'select' => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } );
has 'select_map' => ( is => 'rw', isa => 'HashRef', default => sub { {} } );
has 'select_map_reverse' => ( is => 'rw', isa => 'HashRef', default => sub { {} } );
has 'from' => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } );
has 'joins' => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } );
has 'where' => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } );
has 'bind' => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } );
has 'limit' => ( is => 'rw', isa => 'Int' );
has 'offset' => ( is => 'rw', );
has 'group' => ( is => 'rw', );
has 'order' => ( is => 'rw', );
has 'having' => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } );
has 'where_values' => ( is => 'rw', isa => 'HashRef', default => sub { {} } );
has '_sql' => ( is => 'rw', isa => 'Str', default => '' );
has 'indent' => ( is => 'rw', isa => 'Str', default => ' ' x 2 );
has 'replace' => ( is => 'rw', isa => 'HashRef', default => sub { {} } );
sub add_select {
my $self = shift;
my ( $term, $col ) = @_;
$col ||= $term;
push @{ $self->select }, $term;
$self->select_map->{$term} = $col;
$self->select_map_reverse->{$col} = $term;
}
sub add_join {
my $self = shift;
my ( $table, $joins ) = @_;
push @{ $self->joins },
{
table => $table,
joins => ref($joins) eq 'ARRAY' ? $joins : [$joins],
};
}
sub as_header {
my $self = shift;
my @terms;
if ( @{ $self->select } ) {
my %select_map = %{ $self->select_map };
for my $term ( @{ $self->select } ) {
if ( exists $select_map{$term} ) {
my $alias = $select_map{$term};
push @terms, $alias;
}
else {
push @terms, $term;
}
}
}
if ( keys %{ $self->replace } ) {
for my $find ( keys %{ $self->replace } ) {
lib/AlignDB/SQL.pm view on Meta::CPAN
return @terms;
}
sub as_sql {
my $self = shift;
my $indent = $self->indent;
my $sql = '';
if ( @{ $self->select } ) {
my %select_map = %{ $self->select_map };
my @terms;
for my $term ( @{ $self->select } ) {
if ( exists $select_map{$term} ) {
my $alias = $select_map{$term};
# add_select( 'f.foo' => 'foo' ) ===> f.foo
# add_select( 'COUNT(*)' => 'count' ) ===> COUNT(*) count
if ( $alias and $term =~ /(?:^|\.)\Q$alias\E$/ ) {
push @terms, $term;
}
else {
push @terms, "$term $alias";
}
}
else {
push @terms, $term;
}
lib/AlignDB/SQL.pm view on Meta::CPAN
my ( $col, $val ) = @_;
# TODO: should check if the value is same with $val?
exists $self->where_values->{$col};
}
sub add_having {
my $self = shift;
my ( $col, $val ) = @_;
if ( my $orig = $self->select_map_reverse->{$col} ) {
$col = $orig;
}
my ( $term, $bind ) = $self->_mk_term( $col, $val );
push @{ $self->{having} }, "($term)";
push @{ $self->{bind} }, @$bind;
}
#@returns AlignDB::SQL
sub copy {
lib/AlignDB/SQL.pm view on Meta::CPAN
=encoding UTF-8
=head1 NAME
AlignDB::SQL - An SQL statement generator.
=head1 SYNOPSIS
my $sql = AlignDB::SQL->new();
$sql->select([ 'id', 'name', 'bucket_id', 'note_id' ]);
$sql->from([ 'foo' ]);
$sql->add_where('name', 'fred');
$sql->add_where('bucket_id', { op => '!=', value => 47 });
$sql->add_where('note_id', \'IS NULL');
$sql->limit(1);
my $sth = $dbh->prepare($sql->as_sql);
$sth->execute(@{ $sql->{bind} });
my @values = $sth->selectrow_array();
my $obj = SomeObject->new();
$obj->set_columns(...);
=head1 DESCRIPTION
I<AlignDB::SQL> represents an SQL statement.
Most codes come from Data::ObjectDriver::SQL
$stmt = ns();
$stmt->add_where(%terms);
is( strip( $stmt->as_sql_where ),
"WHERE ((foo = ?) AND (foo = ?) AND (foo = ?))" );
$stmt->add_where(%terms);
is( strip( $stmt->as_sql_where ),
"WHERE ((foo = ?) AND (foo = ?) AND (foo = ?)) AND ((foo = ?) AND (foo = ?) AND (foo = ?))"
);
$stmt = ns();
$stmt->add_select( foo => 'foo' );
$stmt->add_select('bar');
$stmt->from( [qw( baz )] );
is( strip( $stmt->as_sql ), "SELECT foo, bar FROM baz" );
$stmt = ns();
$stmt->add_select( 'f.foo' => 'foo' );
$stmt->add_select( 'COUNT(*)' => 'count' );
$stmt->from( [qw( baz )] );
is( strip( $stmt->as_sql ), "SELECT f.foo, COUNT(*) count FROM baz" );
my $map = $stmt->select_map;
is( scalar( keys %$map ), 2 );
is( $map->{'f.foo'}, 'foo' );
is( $map->{'COUNT(*)'}, 'count' );
# HAVING
$stmt = ns();
$stmt->add_select( foo => 'foo' );
$stmt->add_select( 'COUNT(*)' => 'count' );
$stmt->from( [qw(baz)] );
$stmt->add_where( foo => 1 );
$stmt->group( { column => 'baz' } );
$stmt->order( { column => 'foo', desc => 'DESC' } );
$stmt->limit(2);
$stmt->add_having( count => 2 );
is( strip( $stmt->as_sql ),
"SELECT foo, COUNT(*) count FROM baz WHERE (foo = ?) GROUP BY baz HAVING (COUNT(*) = ?) ORDER BY foo DESC LIMIT 2"
);
t/02.replace.t view on Meta::CPAN
$_[0] =~ s/\s+/ /g;
$_[0] =~ s/ $//s;
return $_[0];
}
my $stmt = ns();
ok( $stmt, 'Created SQL object' );
# Replace
$stmt = ns();
$stmt->add_select( foo => 'foo' );
$stmt->add_select( 'COUNT(*)' => 'count' );
$stmt->from( [qw(baz)] );
$stmt->add_where( foo => 1 );
$stmt->group( { column => 'baz' } );
$stmt->order( { column => 'foo', desc => 'DESC' } );
$stmt->limit(2);
$stmt->add_having( count => 2 );
$stmt->replace( { foo => 'foobar', baz => 'barbaz' } );
is strip($stmt->as_sql),
"SELECT foobar, COUNT(*) count FROM barbaz WHERE (foobar = ?) GROUP BY barbaz HAVING (COUNT(*) = ?) ORDER BY foobar DESC LIMIT 2";
# Replace with meta-char
$stmt = ns();
$stmt->add_select( 'foo.bar' => 'foo.bar' );
$stmt->add_select( 'COUNT(*)' => 'count' );
$stmt->from( [qw(baz)] );
$stmt->replace( { 'foo.bar' => 'foo.foobar' } );
is strip($stmt->as_sql), "SELECT foo.foobar, COUNT(*) count FROM baz";
t/04.copy.t view on Meta::CPAN
sub ns {
AlignDB::SQL->new;
}
my $stmt = ns();
ok $stmt, 'Created SQL object';
# Replace
$stmt = ns();
$stmt->add_select( foo => 'foo' );
$stmt->add_select( 'COUNT(*)' => 'count' );
$stmt->from( [qw(baz)] );
$stmt->add_where( foo => 1 );
$stmt->group( { column => 'baz' } );
$stmt->order( { column => 'foo', desc => 'DESC' } );
$stmt->limit(2);
$stmt->add_having( count => 2 );
$stmt->replace( { foo => 'foobar', baz => 'barbaz' } );
my $stmt_copy = $stmt->copy;
is $stmt->as_sql, $stmt_copy->as_sql, "Copy, clone, duplicate or what ever";
t/library/02.freeze.t view on Meta::CPAN
BEGIN {
use_ok('AlignDB::SQL::Library');
}
use AlignDB::SQL;
my $temp_lib = "temp.lib";
my $sql_file = AlignDB::SQL::Library->new( lib => $temp_lib );
my $sql = AlignDB::SQL->new();
$sql->select( [ 'id', 'name' ] );
$sql->add_select('bucket_id');
$sql->add_select('note_id');
$sql->from( ['foo'] );
$sql->add_where( 'name', 'fred' );
$sql->add_where( 'bucket_id', { op => '!=', value => 47 } );
$sql->add_where( 'note_id', \'IS NULL' );
$sql->limit(1);
$sql_file->set( 'foobar_query', $sql );
is( $sql_file->retrieve('foobar_query')->as_sql,
$sql->as_sql, 'Create a new query in the library.' );
t/library/03.thaw.t view on Meta::CPAN
BEGIN {
use_ok('AlignDB::SQL::Library');
}
use AlignDB::SQL;
my $temp_lib = "temp.lib";
my $sql_file = AlignDB::SQL::Library->new( lib => $temp_lib );
my $sql = AlignDB::SQL->new();
$sql->select( [ 'id', 'name' ] );
$sql->add_select('bucket_id');
$sql->add_select('note_id');
$sql->from( ['foo'] );
$sql->add_where( 'name', 'fred' );
$sql->add_where( 'bucket_id', { op => '!=', value => 47 } );
$sql->add_where( 'note_id', \'IS NULL' );
$sql->limit(1);
my $retr_sql = $sql_file->retr('foobar_query');
my $thaw_sql = AlignDB::SQL->thaw($retr_sql);
is( $thaw_sql->as_sql, $sql->as_sql, 'Retrieved query from library.' );
( run in 0.672 second using v1.01-cache-2.11-cpan-49f99fa48dc )