Arango-Tango
view release on metacpan or search on metacpan
0.019 2023-02-24
- Collection.pm
- added: 'cursor' do obtain a generic database cursor
- modified document_paths to use AQL
0.018 2023-02-24
- Collection.pm
- added: 'delete_document' do delete a document
0.017 2023-02-24
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/Tango/API.pm view on Meta::CPAN
'create_document' => {
rest => [ post => '{{database}}_api/document/{collection}']
},
'replace_document' => {
rest => [ put => '{{database}}_api/document/{collection}/{key}' ],
},
'list_collections' => {
rest => [ get => '{{database}}_api/collection'],
schema => { excludeSystem => { type => 'boolean' } }
},
'cursor_next' => {
rest => [ put => '{{database}}_api/cursor/{id}']
},
'cursor_delete' => {
rest => [ delete => '{{database}}_api/cursor/{id}']
},
'accessible_databases' => {
rest => [ get => '_api/database/user']
},
'all_keys' => {
rest => [ put => '{{database}}_api/simple/all-keys' ],
schema => { type => { type => 'string' }, collection => { type => 'string' } },
},
'create_cursor' => {
rest => [ post => '{{database}}_api/cursor' ],
schema => {
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/Tango/Collection.pm view on Meta::CPAN
my ($self, $documents, %options) = @_;
$options{type} ||= "list";
return $self->{arango}->_api( bulk_import_list => {
database => $self->{database},
collection => $self->{name},
_body => $documents,
_url_parameters => \%options
})
}
sub document_paths { ## FIXME: try to get larger cursors whenever possible
my ($self) = @_;
my $paths = [];
my $query = qq!FOR doc IN $self->{name} RETURN CONCAT("/_db/", CURRENT_DATABASE(), "/_api/document/", doc._id)!;
my $cursor = $self->cursor($query);
while(my $row = $cursor->next) {
push @$paths, @$row;
}
return $paths;
}
sub create_document {
my ($self, $body) = @_;
die "Arango::Tango | Refusing to store undefined body" unless defined($body);
return $self->{arango}->_api( create_document => { database => $self->{database}, collection => $self->{name}, _body => $body})
}
lib/Arango/Tango/Collection.pm view on Meta::CPAN
sub clear_access_level {
my ($self, $username) = @_;
return $self->{arango}->clear_access_level( $username , $self->{database}, $self->{name} );
}
sub set_access_level {
my ($self, $username, $grant) = @_;
return $self->{arango}->set_access_level($username, $grant, $self->{database}, $self->{name});
}
sub cursor {
my ($self, $aql, %opts) = @_;
return Arango::Tango::Cursor->_new(arango => $self->{arango}, database => $self->{database}, query => $aql, %opts);
}
1;
__END__
=pod
lib/Arango/Tango/Collection.pm view on Meta::CPAN
$db->clear_access_level($user, 'none')
Clears the collection access level for a specific user.
=head2 C<bulk_import>
$collection->bulk_import([{_key => "something"}, {_key => "something else"}])
Imports a group of documents in a single call.
=head2 C<cursor>
my $cursor = $collection->cursor( $aql_query, %opt );
Performs AQL queries, returning a cursor. An optional hash of
options can be supplied. Supported hashes corresponds to the different attributes
available in the ArangoDB 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-2023 by Alberto Simões.
lib/Arango/Tango/Cursor.pm view on Meta::CPAN
$Arango::Tango::Cursor::VERSION = '0.019';
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) = @_;
if (exists($self->{id})) {
$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/Tango/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-2023 by Alberto Simões.
lib/Arango/Tango/Database.pm view on Meta::CPAN
sub _new {
my ($class, %opts) = @_;
return bless {%opts} => $class;
}
sub delete {
my $self = shift;
return $self->{arango}->delete_database($self->{name});
}
sub cursor {
my ($self, $aql, %opts) = @_;
return Arango::Tango::Cursor->_new(arango => $self->{arango}, database => $self->{name}, query => $aql, %opts);
}
sub collection {
my ($self, $name) = @_;
lib/Arango/Tango/Database.pm view on Meta::CPAN
Creates a new index of type ttl for the given collection. The
mandatory args are C<type> (must be C<ttl>), C<name> (string,
human name for the index), C<fields> (array ref with the
names of the document fields to be used as expiration timestamps)
and C<expireAfter> (integer, seconds).
Returns an object containing the id of the created index and the
confirmation of the provided arguments (C<type>, C<name>, C<fields>
and C<expireAfter>). If an error occurs the error field will be
true, otherwise false.
=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 corresponds to the different attributes
available in the ArangoDB REST API (L<https://docs.arangodb.com/3.4/HTTP/AqlQueryCursor/AccessingCursors.html>).
=head2 C<delete>
$db->delete;
Deletes the supplied database.
=head2 C<delete_collection>
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::Tango::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::Tango::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::Tango::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.270 second using v1.01-cache-2.11-cpan-4d50c553e7e )