Google-Fusion
view release on metacpan or search on metacpan
lib/Google/Fusion.pm view on Meta::CPAN
our $VERSION = '0.10';
=head1 SYNOPSIS
my $fusion = Google::Fusion->new(
client_id => $client_id,
client_secret => $client_secret,
token_store => $token_store,
);
# Get the result for a query
my $result = $fusion->query( $sql );
# Print out the rows returned
foreach( @{ $result->rows } ){
print join( ',', @{ $_ } ) . "\n";
}
=head1 PARAMS/ACCESSORS
One of the following combination of parameters is required:
client_id and client_secret
You will be prompted with a URL, with which you will atain an access_code.
client_id, client_secret, access_code
The OAuth2 client will complete the authorization process for you and get the refresh_token and access_token for you
refresh_token and optionally access_token
The OAuth2 client will get a valid access_token for you if necessary, and refresh it when necessary.
access_token
You will be able to make requests as long as the access_token is valid.
=over 2
=item * client_id <Str>
The client id of your application.
=item * client_secret <Str>
The secret for your application
=item * refresh_token <Str>
Refresh token.
Can be defined here, otherwise it will be aquired during the authorization process
=item * access_token <Str>
A temporary access token aquired during the authorization process
Can be defined here, otherwise it will be aquired during the authorization process
=item * keep_alive <Int>
Use keep_alive for connections - this will make the application /much/ more responsive.
Default: 1
=item * headers <Bool>
Responses passed with headers.
Default: 1
=item * access_code <Str>
The code returned during the OAuth2 authorization process with which access_token and refresh_token are aquired.
=item * auth_client
A Net::OAuth2::Moosey::Client object with which authenticated requests are made. If you are running
in application mode (interactive), then you can accept the default.
If you already have an authenticated client, then initialise with it.
If you have some required parameters (access_token, refresh_token or access_code), but no client
object yet, then just define these parameters, and allow the client to be created for you.
=item * query_cache <Str>
Path to a directory to use as a query cache. This can be used to cache your results for blazing
fast performance, and not actually hitting google for every query when testing, but should not
be enabled in a productive environment otherwise you will have stale content.
=item * token_store <Str>
Path to the token store file to store access/refresh tokens
=back
=cut
subtype 'InsertStatement',
as 'Str',
where { $_ =~ m/^INSERT/ };
has 'client_id' => ( is => 'ro', isa => 'Str', );
has 'client_secret' => ( is => 'ro', isa => 'Str', );
has 'refresh_token' => ( is => 'ro', isa => 'Str', );
has 'access_token' => ( is => 'ro', isa => 'Str', );
has 'access_code' => ( is => 'ro', isa => 'Str', );
has 'query_cache' => ( is => 'ro', isa => 'Str', );
has 'token_store' => ( is => 'ro', isa => 'Str', );
has 'headers' => ( is => 'ro', isa => 'Bool', required => 1, default => 1, );
has 'keep_alive' => ( is => 'ro', isa => 'Bool', required => 1, default => 1, );
has 'auth_client' => ( is => 'ro', required => 1, lazy => 1,
isa => 'Net::OAuth2::Moosey::Client',
builder => '_build_auth_client',
);
has 'insert_buffer' => ( is => 'rw', isa => 'Str', clearer => 'clear_insert_buffer', default => sub{ '' } );
has 'insert_buffer_limit' => ( is => 'ro', isa => 'Int', default => 20_000 );
# Local method to build the auth_client if it wasn't passed
sub _build_auth_client {
my $self = shift;
my %client_params = (
site_url_base => 'https://accounts.google.com/o/oauth2/auth',
access_token_url_base => 'https://accounts.google.com/o/oauth2/token',
authorize_url_base => 'https://accounts.google.com/o/oauth2/auth',
scope => 'https://www.google.com/fusiontables/api/query',
);
foreach( qw/client_id client_secret refresh_token access_code access_token keep_alive token_store/ ){
$client_params{$_} = $self->$_ if defined $self->$_;
}
# $self->logger->debug( "Initialising Client with:\n". Dump( \%client_params ) );
my $client = Net::OAuth2::Moosey::Client->new( %client_params );
return $client;
}
=head1 METHODS
=head2 query
Submit a (Googley) SQL query. Single argument is the SQL.
Return is a L<Google::Fusion::Result> object
Example:
my $result = $fusion->query( 'SELECT * FROM 123456' );
=cut
sub query {
my $self = shift;
my $sql = shift;
# Get a valid access_token before timing the query time
my $auth_time_start = time();
$self->auth_client->access_token_object->valid_access_token();
my $auth_time = time() - $auth_time_start;
my $query_start = time();
my $response = $self->_query_or_cache( $sql );
my $query_time = time() - $query_start;
my $result = Google::Fusion::Result->new(
query => $sql,
response => $response,
query_time => $query_time,
auth_time => $auth_time,
total_time => $query_time + $auth_time,
);
if( not $response->is_success ){
$result->error( sprintf "%s (%u)", $response->message, $response->code );
}else{
# Response was a success
# TODO: RCL 2011-09-08 Parse the actual error message from the response
# TODO: RCL 2011-09-08 Refresh access_key if it was invalid, or move that
# action to the Client?
my $data = $response->decoded_content();
# print $data;
my $csv = Text::CSV->new ( {
binary => 1, # Reliable handling of UTF8 characters
escape_char => '"',
quote_char => '"',
} ) or croak( "Cannot use CSV: ".Text::CSV->error_diag () );
my $io = IO::String->new( $data );
my $parsed_data = $csv->getline_all( $io );
$csv->eof or $csv->error_diag();
( run in 1.609 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )