Arango-DB

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

0.004  2019-03-30
   - Rewrote REST API calls
   - Validate options with JSON::Schema::Fit

0.003  2019-03-25
   - Added 'collection' method.
   - Reworked tests to delete the testing database if it exists.
     (dangerous, but will keep for now)
   - Testing mechanism for uri parameters under work.
   - Complete support for: _api/version
   - First cursor implementation

0.0002  2019-03-23
   - Require specific version of MIME::Base64 for encode_base64url method. 

0.0001  2019-03-22
   - Basic version. Almost useless. A two hour begining.

lib/Arango/DB/API.pm  view on Meta::CPAN

use Clone 'clone';
use MIME::Base64 3.11 'encode_base64url';
use URI::Encode qw(uri_encode);
use JSON::Schema::Fit 0.02;

my %API = (
    create_document   => { method => 'post',   uri => '{database}_api/document/{collection}' },
    delete_collection => { method => 'delete', uri => '{database}_api/collection/{name}'     },
    delete_database   => { method => 'delete', uri => '_api/database/{name}'                 },
    list_collections  => { method => 'get',    uri => '{database}_api/collection'            },
    cursor_next       => { method => 'put',    uri => '{database}_api/cursor/{id}'           },
    cursor_delete     => { method => 'delete', uri => '{database}_api/cursor/{id}'           },
    list_databases    => { method => 'get',    uri => '_api/database'                        },
    status            => { method => 'get',    uri => '_admin/status'                        },
    time              => { method => 'get',    uri => '_admin/time'                          },
    statistics        => { method => 'get',    uri => '_admin/statistics'                    },
    statistics_description  => { method => 'get', uri => '_admin/statistics-description'     },
    'create_database' => {
        method  => 'post',
        uri     => '_api/database',
        params  => { name => { type => 'string' }},
        builder => sub { 

lib/Arango/DB/API.pm  view on Meta::CPAN

    'all_keys' => {
        method => 'put',
        uri    => '{database}_api/simple/all-keys',
        params => { type => { type => 'string' }, collection => { type => 'string' } },
    },
    'version' => {
        method => 'get',
        uri    => '_api/version',
        params => {  details => { type => 'boolean' } } ,
    },
    'create_cursor' => {
        method => 'post',
        uri    => '{database}_api/cursor',
        params => { 
            query       => { type => 'string'  }, 
            count       => { type => 'boolean' },
            batchSize   => { type => 'integer' },
            cache       => { type => 'boolean' },
            memoryLimit => { type => 'integer' },
            ttl         => { type => 'integer' },
            bindVars => { type => 'object', additionalProperties => 1 },
            options  => { type => 'object', additionalProperties => 0, properties => {
                    failOnWarning               => { type => 'boolean' },

lib/Arango/DB/Cursor.pm  view on Meta::CPAN

$Arango::DB::Cursor::VERSION = '0.006';
use warnings;
use strict;

use Data::Dumper;

sub _new {
  my ($class, %opts) = @_;
  my $self = { arango => $opts{arango}, database => $opts{database} };

  my $ans = $self->{arango}->_api('create_cursor', \%opts);

  return bless { %$ans, %$self, __current => 0 } => $class;
}

sub next {
  my $self = shift;

  if (!$self->{error} && $self->{__current} == 0) {
    $self->{__current}++;
    return $self->{result};
  }

  if ($self->{hasMore}) {
    my $ans = $self->{arango}->_api('cursor_next', { database => $self->{database}, id => $self->{id} });
    if (!$ans->{error}) {
      $self->{hasMore} = $ans->{hasMore};
      return $ans->{result};
    }
  }

  return undef;
}

sub finish {
  my ($self) = @_;
  $self->{arango}->_api('cursor_delete',  { database => $self->{database}, id => $self->{id} });
  delete $self->{$_} for (keys %$self);
}

sub has_more {
  my ($self) = @_;
  return $self->{hasMore};
}

1;

lib/Arango/DB/Cursor.pm  view on Meta::CPAN

Returns the next results. On the first call, returns the results
obtained from the first query request.  Subsequent requests will try
to gather more hits if they exists, and the query id is still alive.

=item C<has_more>

Returns a boolean stating if there are more results to be fetched.

=item C<finish>

Deletes the cursor in the server and destroys all the object details.

=back

=head1 AUTHOR

Alberto Simões <ambs@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2019 by Alberto Simões.

lib/Arango/DB/Database.pm  view on Meta::CPAN

   my ($self, $name) = @_;
   my @match = grep { $_->{name} eq $name } @{$self->list_collections};
   if (scalar(@match)) {
      return Arango::DB::Collection->_new(arango => $self->{arango}, database => $self->{name}, 'name' => $name);
   }
   else {
      die "Arango::DB | Collection not found in database $self->{name}."
   }
}

sub cursor {
    my ($self, $aql, %opts) = @_;
    return Arango::DB::Cursor->_new(arango => $self->{arango}, database => $self->{name}, query => $aql, %opts);
}

sub list_collections {
    my ($self) = @_;
    return $self->{arango}->list_collections($self->{name});
}

sub create_collection {

lib/Arango/DB/Database.pm  view on Meta::CPAN

    my $collection = $database->collection("some_collection");

Opens an existing collection, and returns a reference to a L<Arango::DB::Collection> representing it.

=head2 C<delete_collection>

   $database->delete_collection("col_name");

Deletes a collection.

=head2 C<cursor>

   my $cursor = $database->cursor( $aql_query, %opt );

Performs AQL queries, returning a cursor. An optional hash of
options can be supplied. Supported hashes corresponde to the different attributes
available in the Arango::DB REST API (L<https://docs.arangodb.com/3.4/HTTP/AqlQueryCursor/AccessingCursors.html>).

=head1 AUTHOR

Alberto Simões <ambs@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2019 by Alberto Simões.

t/04-query.t  view on Meta::CPAN

     { name => 'Bamm-Bamm Rubble', gender => 'male' }
];
for my $doc (@$documents) {
    $collection->create_document( $doc );
}

my $list = $collection->document_paths();
is scalar(@$list), 5, "Five documents imported correctly";

my $query = q{FOR p IN collection LIMIT 2 RETURN p};
my $cursor = $db->cursor($query);

isa_ok $cursor, 'Arango::DB::Cursor';
ok exists($cursor->{result}) => 'Results key exists';
is scalar(@{$cursor->{result}}) => 2 => 'Correct number of hits';


$cursor = $db->cursor($query, count => 1);
isa_ok $cursor, 'Arango::DB::Cursor';
ok exists($cursor->{count}) => 'Results count exists';

$cursor = $db->cursor($query, batchSize => 1);
is scalar(@{$cursor->{result}}) => 1 => 'Number of hits is batchSize';

ok $cursor->has_more, "Cursor has more hits";

my $results = $cursor->next;
is scalar(@$results), 1, "First batch right size";
$results = $cursor->next;
is scalar(@$results), 1, "Second batch right size";
$results = $cursor->next;
is $results, undef, "No more results";

## Bind vars
#
$cursor = $db->cursor('FOR p IN @@collection RETURN p', bindVars => { '@collection' => 'collection' });
isa_ok $cursor, 'Arango::DB::Cursor';

## Do t again
$cursor = $db->cursor($query, batchSize => 1);
$cursor->finish;
is $cursor, {}, "Finish removed all data";

$arango->delete_database("tmp_");

done_testing;



( run in 0.282 second using v1.01-cache-2.11-cpan-4d50c553e7e )