use strict;
use warnings;
package Thrift::API::HiveClient;
{
  $Thrift::API::HiveClient::VERSION = '0.002';
}
# ABSTRACT: A Hadoop Hive client using the Thrift API
use Moo;
use Carp;
use Thrift;
use Thrift::Socket;
use Thrift::BufferedTransport;
use Thrift::BinaryProtocol;
use Thrift::API::HiveClient::Service::ThriftHive;

has host => ( is => 'ro' );

has port => ( is => 'ro' );

# These exist to make testing with various other
# Thrift Implementation classes easier, eventually.
has _socket => ( is => 'rwp' );
has _transport => ( is => 'rwp' );
has _protocol => ( is => 'rwp' );
has _client => ( is => 'rwp' );

# setters implied by the 'rwp' mode on the attrs above.
# having to write these these annoys me. Time to write a MooX module...
sub _set_socket { $_[0]->{_socket} = $_[1] }
sub _set_transport { $_[0]->{_transport} = $_[1] }
sub _set_protocol { $_[0]->{_protocol} = $_[1] }
sub _set_client { $_[0]->{_client} = $_[1] }

# after constructon is complete, initialize any attributes that
# weren't set in the constructor.
sub BUILD {
  my ($self) = @_;

  $self->_set_socket(
     Thrift::Socket->new( $self->host, $self->port )
  ) unless $self->_socket;

  $self->_set_transport(
    Thrift::BufferedTransport->new( $self->_socket )
  ) unless $self->_transport;

  $self->_set_protocol(
    Thrift::BinaryProtocol->new( $self->_transport )
  ) unless $self->_protocol;

  $self->_set_client(
    Thrift::API::HiveClient::Service::ThriftHiveClient->new( $self->_protocol )
  ) unless $self->_client;
}


sub connect {
  my ($self) = @_;
  $self->_transport->open;
}

# when the user calls a method on an object of this class, see if that method exists
# on the ThriftHiveClient object. If so, create a sub that calls that method on the
# client object. If not, die horribly.
sub AUTOLOAD {
    my ($self) = @_;
    (my $meth = our $AUTOLOAD) =~ s/.*:://;
    return if $meth eq 'DESTROY';
    no strict 'refs';
    if ( $self->_client->can($meth) ) {
      *$AUTOLOAD = sub { shift->_client->$meth( @_ ) };
      goto &$AUTOLOAD;
    }
    croak "No such method exists: $AUTOLOAD";
}

1 && q{this is a terrible kludge}; # truth


=pod

=head1 NAME

Thrift::API::HiveClient - A Hadoop Hive client using the Thrift API

=head1 VERSION

version 0.002

=head1 DESCRIPTION

B<THIS CODE IS ALPHA-QUALITY, EXPERIMENTAL, AND LIKELY FLAMMABLE>

That said, I decided it would be nice to make it easy to connect to a Hadoop Hive server via
its Thrift interface and that's what this module provides. It tries to keep the gory details
from you and make things as simple as possible. The majority of the code in this dist was
generated by the thrift compiler, but is hidden behind the friendly facade of the module
whose documentation you are reading now. Enjoy, and please feel free to send bug reports
and/or patches!

=head1 ATTRIBUTES

=head2 host

The host on which the hiveserver process is running. Should be a
valid hostname or IP address. I<required>, I<immutable>

=head2 port

The TCP port on which the hiveserver process is listening. Should be
a valid port number. I<required>, I<immutable>

=head1 METHODS

=head2 new( ... )

Standard object constructor. Arguments are the attributes described above. For example:

  my $cli = Thrift::API::HiveClient->new( host => 'localhost', port => 10000 );

=head2 connect( )

Connect to the configured hiveserver.

=head1 THRIFT API METHODS

These are the methods exposed by the Thrift API. The HiveClient object simply acts
as a proxy for all the methods available on the (underlying) ThriftHiveClient object.

However, for your convenience, all these methods are documented here, as well as I can.

=head2 execute( $hql )

The given HQL statement is sent to the hiveserver and executed. The results can be
retrieved by using the fetch* methods.

  $cli->execute('select * from foo');

=head2 fetchAll( )

All results from a previous call to execute() are returned as an array

  my $res = $cli->fetchAll();

=head2 getClusterStatus( )

Returns an object (blessed hash) showing some of the status of the Hadoop cluster.

=head2 get_fields( $db_name, $tbl_name );

Returns an array of FieldSchema objects with info about the fields in the given
table in the given database.

  my $tbl_schema = $cli->get_fields( 'default', 'foo' );

=head1 EXTENDS

=over 4

=item * L<Moo::Object>

=back

=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan

=head1 SUPPORT

=head2 Bugs / Feature Requests

Please report any bugs or feature requests by email to C<bug-thrift-api-hiveclient at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Thrift-API-HiveClient>. You will be automatically notified of any
progress on the request by the system.

=head2 Source Code

The code is open to the world, and available for you to hack on. Please feel free to browse it and play
with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
from your repository :)

L<https://github.com/Hercynium/Thrift-API-HiveClient>

  git clone git://github.com/Hercynium/Thrift-API-HiveClient.git

=head1 AUTHOR

Stephen R. Scaffidi <sscaffidi@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2012 by Stephen R. Scaffidi.

This is free software, licensed under:

  The Apache License, Version 2.0, January 2004

=cut


__END__

