/usr/local/CPAN/DBD-Amazon/SQL/Amazon/ReqFactory.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::ReqFactory;
use SQL::Amazon::Request::Request;
use SQL::Amazon::Parser;
use SQL::Amazon::Parser qw(:pred_node_codes);
use strict;
our $VERSION = '0.10';
use constant HAS_KEYS => 1;
use constant HAS_MATCHES => 2;
my %is_search_function = qw(
AMZN_MATCH_ANY 1
AMZN_MATCH_ALL 1
AMZN_MATCH_TEXT 1
AMZN_POWER_SEARCH 1
);
my %can_search = qw(
CustomerContent SQL::Amazon::Request::CustomerContentSearch
Item SQL::Amazon::Request::ItemSearch
List SQL::Amazon::Request::ListSearch
SellerListing SQL::Amazon::Request::SellerListingSearch
);
my %can_lookup = qw(
BrowseNode SQL::Amazon::Request::BrowseNodeLookup
CustomerContent SQL::Amazon::Request::CustomerContentLookup
Item SQL::Amazon::Request::ItemLookup
List SQL::Amazon::Request::ListLookup
Seller SQL::Amazon::Request::SellerLookup
SellerListing SQL::Amazon::Request::SellerListingLookup
Transaction SQL::Amazon::Request::TransactionLookup
);
my %can_add = qw(
Cart SQL::Amazon::Request::CartAdd
);
my %can_clear = qw(
Cart SQL::Amazon::Request::CartClear
);
my %can_create = qw(
Cart SQL::Amazon::Request::CartCreate
);
my %can_get = qw(
Cart SQL::Amazon::Request::CartGet
);
my %can_modify = qw(
Cart SQL::Amazon::Request::CartModify
);
our $errstr;
sub errstr { return $errstr; }
sub create_request {
my ($class, $reqclass, $table, $predicate, $parser) = @_;
my $command = $parser->{struct}{command};
$errstr = $command . " unsupported on $table.",
return (undef, undef)
unless (
(($command eq 'CREATE') && $can_create{$reqclass}) ||
(($command eq 'DELETE') && $can_clear{$reqclass}) ||
(($command eq 'INSERT') && $can_add{$reqclass}) ||
(($command eq 'UPDATE') && $can_modify{$reqclass}) ||
(($command eq 'SELECT') &&
($can_search{$reqclass} ||
$can_lookup{$reqclass} ||
$can_get{$reqclass}))
);
$errstr = 'Only SELECT operation supported in this release.',
return (undef, undef)
unless ($command eq 'SELECT');
my $flags = classify_request_type($predicate, 0);
$errstr = "$table does not support MATCHES predicate.",
return (undef, undef)
if (($flags & HAS_MATCHES) && (!$can_search{$reqclass}));
my $reqobj;
$reqclass = (($flags & HAS_MATCHES) || (! ($flags & HAS_KEYS))) ?
$can_search{$reqclass} : $can_lookup{$reqclass};
($predicate, $reqobj) = ${reqclass}->new($predicate, $table, $parser);
$errstr = ${reqclass}->errstr,
return (undef, undef)
unless ($predicate || $reqobj);
return ($predicate, $reqobj);
}
sub classify_request_type {
my ($expr, $flags) = @_;
my $conjoins = $expr->[0];
foreach (@$conjoins) {
$flags |= HAS_KEYS,
next
if (($_->[SQL_TREE_OP] eq '=') &&
($_->[SQL_TREE_ARG1]{type} eq 'column') &&
($_->[SQL_TREE_ARG1]{value}=~
/^([A-Z_]\w*\.)?(ASIN|UPC|SKU|EAN)$/i) &&
(! $_->[SQL_TREE_NEG]));
next unless ($_->[SQL_TREE_OP] eq 'USER_DEFINED');
my $name;
$name = (ref $_ ne 'HASH') ?
$_->[SQL_TREE_ARG1]->name :
$_->[SQL_TREE_ARG1]{name};
$flags |= HAS_MATCHES,
next
if $is_search_function{$name};
my $value = (ref $_ ne 'HASH') ?
$_->[SQL_TREE_ARG1]->args :
$_->[SQL_TREE_ARG1]{value};
$flags |= HAS_KEYS
if (($name eq 'AMZN_IN_ANY') &&
($value->[0]{value}=~
/^([A-Z_]\w*\.)?(ASIN|UPC|SKU|EAN)$/i) &&
(! $_->[SQL_TREE_NEG])
);
}
return $flags;
}
sub cleanup_requests {
my ($class, $requests) = @_;
my @sorted_reqs = ();
my @remaining = ();
foreach (@$requests) {
push(@sorted_reqs, $_)
if ($_->[0] eq 'Item');
}
foreach (@$requests) {
push @remaining, $_
unless (($_->[0] eq 'Item') ||
(scalar @sorted_reqs));
}
push @sorted_reqs, @remaining
if scalar @remaining;
return \@sorted_reqs;
}
1;