/usr/local/CPAN/DBD-Amazon/SQL/Amazon/Statement.pm
#
# Copyright (c) 2005, Presicient Corp., USA
#
# Permission is granted to use this software according to the terms of the
# Artistic License, as specified in the Perl README file,
# with the exception that commercial redistribution, either
# electronic or via physical media, as either a standalone package,
# or incorporated into a third party product, requires prior
# written approval of the author.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Presicient Corp. reserves the right to provide support for this software
# to individual sites under a separate (possibly fee-based)
# agreement.
#
# History:
#
# 2005-Jan-27 D. Arnold
# Coded.
#
package SQL::Amazon::Statement;
use SQL::Statement;
use base qw(SQL::Statement);
use DBI;
use SQL::Amazon::Tables::Table;
use SQL::Amazon::Parser qw(:pred_node_codes);
use strict;
our $VERSION = '0.10';
our $engine;
use constant SQL_S2POPS_STR => 0;
use constant SQL_S2POPS_NUM => 1;
our %s2pops = (
'LIKE', ['LIKE', 'LIKE'],
'CLIKE', ['CLIKE', 'CLIKE'],
'RLIKE', ['RLIKE', 'RLIKE'],
'<', ['lt', '<'],
'>', ['gt', '>'],
'>=', ['ge', '>='],
'<=', ['le', '<='],
'=', ['eq', '=='],
'<>', ['ne', '!='],
);
our %reqlookup = (
'ItemLookup', 'SQL::Amazon::Request::ItemLookup',
'ItemSearch', 'SQL::Amazon::Request::ItemSearch',
);
*is_number = *DBI::looks_like_number;
sub new {
my $class = shift;
my ($sql, $parser, $amzn_engine, $flags) = @_;
$engine = ($amzn_engine &&
ref $amzn_engine &&
(ref $amzn_engine eq 'SQL::Amazon::StorageEngine')) ?
$amzn_engine :
SQL::Amazon::StorageEngine->new()
unless $engine;
my $obj = $class->SUPER::new($sql, $parser, $flags);
return undef
unless $obj;
return $obj;
}
sub open_tables {
my ($obj, $handle, $createMode, $lockMode) = @_;
delete $obj->{amzn_req_ids};
my $reqary = $obj->{amzn_requests};
return $obj->SUPER::open_tables($handle, $createMode, $lockMode)
unless ($reqary && (scalar @$reqary));
my @requests = ();
foreach (@$reqary) {
my $request = $_->populate_request(
$handle->{Database}{USER},
$handle->{Database}{amzn_locale},
$obj,
$handle->{amzn_max_pages},
$handle->{amzn_resp_group}
);
next unless $request;
my $dup = undef;
foreach (@requests) {
$dup = 1,
last
if $request->equals($_);
}
push @requests, $request
unless $dup;
}
my $reqtime = 0;
my $reqids;
($obj->{errstr}, $reqids, $reqtime) =
$engine->send_requests(\@requests);
return $obj->do_err($obj->{errstr})
unless defined($reqtime);
$handle->seterr(0, $obj->{errstr}),
delete $obj->{errstr}
if defined($obj->{errstr});
$obj->{amzn_req_ids} = $reqids;
return $obj->SUPER::open_tables($handle, $createMode, $lockMode);
}
sub process_predicate {
my($obj, $pred, $eval, $rowhash) = @_;
my $predary = $obj->{amzn_predicate};
foreach my $conjoin (@$predary) {
next unless ($conjoin && $conjoin->[0] && scalar @{$conjoin->[0]});
my $match = 1;
foreach (@{$conjoin->[0]}) {
$match = 0,
last
unless ($obj->process_AND_predicate($_, $eval, $rowhash) &&
(!$_->[SQL_TREE_NEG]));
}
return 1
if $match;
}
return 0;
}
sub process_AND_predicate {
my($obj, $pred, $eval, $rowhash) = @_;
my $neg = $pred->[SQL_TREE_NEG];
my $op = $pred->[SQL_TREE_OP];
my $val1 = defined($pred->[SQL_TREE_ARG1]) ?
$obj->get_row_value( $pred->[SQL_TREE_ARG1], $eval, $rowhash ) :
undef;
return $val1
if ($op eq 'USER_DEFINED');
my $val2 = defined($pred->[SQL_TREE_ARG2]) ?
$obj->get_row_value( $pred->[SQL_TREE_ARG2], $eval, $rowhash ) :
undef;
return $neg
if (($op ne 'IS') && (!defined($val1) || !defined($val2)));
return defined($val1) ? $neg : !$neg
if ($op eq 'IS');
$op = ( is_number($val1) and is_number($val2) ) ?
$s2pops{$op}->[SQL_S2POPS_NUM] :
$s2pops{$op}->[SQL_S2POPS_STR];
if (ref $eval !~ /TempTable/) {
my($table) = $eval->table($obj->tables(0)->name());
if ($op eq '=' and !$neg and $table->can('fetch_one_row')){
my $key_col = $table->fetch_one_row(1,1);
$obj->{fetched_from_key} = 1,
$obj->{fetched_value} = $table->fetch_one_row(0, $val2),
return 1
if ($pred->[SQL_TREE_ARG1]->{value} =~ /^$key_col$/i);
}
}
return $obj->is_matched($val1, $op, $val2) ? !$neg : $neg;
}
sub open_table ($$$$$) {
my($obj, $handle, $tname, $createMode, $lockMode) = @_;
return $engine->get_result_set($tname, $obj->{amzn_req_ids}, $createMode);
}
1;