Tie-Google
view release on metacpan - search on metacpan
view release on metacpan or search on metacpan
use Symbol qw(gensym);
use Net::Google;
# Offsets into the array-based object
sub KEY() { 0 } # The user's API key
sub TYPE() { 1 } # The tie type: SCALAR, ARRAY, HASH
sub QUERY() { 2 } # The query terms
sub OPTIONS() { 3 } # Options tied in
sub DATA() { 4 } # Search results
sub GOOGLE() { 5 } # Net::Google instance
# Tie types that we support and have to differentiate between
sub SCALAR() { 0 }
sub ARRAY() { 1 }
sub HASH() { 2 }
$VERSION = 0.03;
$DEFAULT_BATCH_SIZE = 10 unless defined $DEFAULT_BATCH_SIZE;
$DEBUG = 0 unless defined $DEBUG;
# tie constructors
sub TIESCALAR { return shift->new(SCALAR, @_) }
sub TIEARRAY { return shift->new(ARRAY, @_) }
sub TIEHASH { return shift->new(HASH, @_) }
# ----------------------------------------------------------------------
# new($TYPE, $KEY, $query)
#
# Create a new Tie::Google instance. This method should never be
# called by outside facing code, only by the TIEFOO methods.
#
# A Tie::Google instance maintains a few pieces of information:
#
# 0. The API key of the user
#
# 1. The type of tie (SCALAR, ARRAY, HASH)
#
# 2. The query
#
# 3. Options passed in
#
# 4. The results of the query.
#
# 5. The Net::Google instace, created with the API key (item 0)
#
# The interesting things happen here in new. new must be passed a
# type, a key, and a query. If the user is tieing a scalar ("I feel
# lucky"), then we are only interested in the first element returned
# by the search; if the user is tieing an array, then we want all of
# the elements; if the user is tieing a hash, then we want all of the
# elements of a number of searches. My "solution" (heh heh heh) is to
# store all data in a hashref, indexed into the instance as DATA; if
# the user is tieing an array or scalar (Tie::Google treats them
# identically), then we store the results in the key named $KEY, so
# that we can treat all types of ties consistently; otherwise, search
# results are keyed by query.
# ----------------------------------------------------------------------
sub new {
my ($class, $type, $KEY, $query, $options) = @_;
$options = { } unless defined $options && ref($options) eq 'HASH';
my $self = bless [ $KEY, $type, $query, $options, { }, undef, ] => $class;
# Is $KEY actually a file?
# I do this in DBD::google as well; perhaps there I should submit
# a patch to Aaron so that Net::Google can do this directly.
if (-e $KEY) {
my $fh = gensym;
open $fh, $KEY or die "Can't open keyfile $KEY for reading: $!";
chomp($KEY = <$fh>);
close $fh or die "Can't close keyfile $KEY: $!";
$self->[KEY] = $KEY;
}
# Set some reasonable defaults search boundaries, and instantiate
# the Net::Google instance.
$options->{'starts_at'} = 0 unless defined $options->{'starts_at'};
$options->{'max_results'} ||= $DEFAULT_BATCH_SIZE;
$self->[GOOGLE] = Net::Google->new(key => $self->[KEY],
debug => $options->{'debug'} || 0);
# * If called from TIEHASH, then store the results keyed by
# search terms, otherwise keyed by $KEY
#
# * If called from TIESCALAR, we only want the first result.
#
# $self->[OPTIONS] contains starts_at and max_results.
#
if ($type == HASH) {
$self->do_search($query, $query,
$self->[OPTIONS]->{'starts_at'},
$self->[OPTIONS]->{'max_results'});
}
elsif ($type == SCALAR) {
$self->do_search($KEY, $query, 0, 1);
}
else {
$self->do_search($KEY, $query,
$self->[OPTIONS]->{'starts_at'},
$self->[OPTIONS]->{'max_results'});
}
return $self;
}
# ----------------------------------------------------------------------
# do_search($store_as, $query)
#
# This is where all the Net::Google magic has to happen.
#
# do_search will use Net::Google to search for $query, and store the
# results in $self->[DATA]->{$store_as}.
# ----------------------------------------------------------------------
sub do_search {
my ($self, $store_as, $query, $start, $num) = @_;
# Preparation for the search
#
# do_search can conceivably be invoked with one argument,
# in which case we use it both as search term and key into the
view all matches for this distributionview release on metacpan - search on metacpan
( run in 1.541 second using v1.00-cache-2.02-grep-82fe00e-cpan-d29e8ade9f55 )