view release on metacpan or search on metacpan
# Create new document
$foo->save({ x => 42, y => { a => 1, b => 2, } });
$foo->save({ x => 1, y => { a => 1, b => 10, } });
$foo->name('new_name'); # rename the collection
# Create hash index.
$foo->ensure_hash_index([qw/x y/]);
# Simple query
my $cursor = $db->('new_name')->by_example({ b => 2 });
while( my $doc = $cursor->next ){
# do something
}
# AQL
my $cursor2 = $db->query(
'FOR u IN users FILTER u.age > @age SORT u.name ASC RETURN u'
)->bind( { age => 19 } )->execute();
my $docs = $cursor2->all;
DESCRIPTION
This module is an ArangoDB's REST API client for Perl.
ArangoDB is a universal open-source database with a flexible data model
for documents, graphs, and key-values.
More information: <http://www.arangodb.org/>
SUPPORT API VERSION
lib/ArangoDB.pm view on Meta::CPAN
# Create new document
$foo->save({ x => 42, y => { a => 1, b => 2, } });
$foo->save({ x => 1, y => { a => 1, b => 10, } });
$foo->name('new_name'); # rename the collection
# Create hash index.
$foo->ensure_hash_index([qw/x y/]);
# Simple query
my $cursor = $db->('new_name')->by_example({ b => 2 });
while( my $doc = $cursor->next ){
# do something
}
# AQL
my $cursor2 = $db->query(
'FOR u IN users FILTER u.age > @age SORT u.name ASC RETURN u'
)->bind( { age => 19 } )->execute();
my $docs = $cursor2->all;
=head1 DESCRIPTION
This module is an ArangoDB's REST API client for Perl.
ArangoDB is a universal open-source database with a flexible data model for documents, graphs, and key-values.
More information: L<http://www.arangodb.org/>
=head1 SUPPORT API VERSION
lib/ArangoDB/Collection.pm view on Meta::CPAN
=pod
=head1 METHODS FOR SIMPLE QUERY HANDLING
=head2 all([$options])
Send 'all' simple query. Returns instance of L<ArangoDB::Cursor>.
This will return all documents of in the collection.
my $cursor = $collection->all({ limit => 100 });
$options is query option(HASH reference).The attributes of $options are:
=over 4
=item limit
The maximal amount of documents to return. (optional)
=item skip
lib/ArangoDB/Collection.pm view on Meta::CPAN
}
=pod
=head2 by_example($example[,$options])
Send 'by_example' simple query. Returns instance of L<ArangoDB::Cursor>.
This will find all documents matching a given example.
my $cursor = $collection->by_example({ age => 20 });
=over 4
=item $example
The exmaple.
=item $options
Query option(HASH reference).The attributes of $options are:
lib/ArangoDB/Collection.pm view on Meta::CPAN
=pod
=head2 range($attr,$lower,$upper[,$options])
Send 'range' simple query. Returns instance of L<ArangoDB::Cursor>.
It looks for documents in the collection with attribute between two values.
Note: You must declare a skip-list index on the attribute in order to be able to use a range query.
my $cursor = $collection->range('age', 20, 29, { closed => 1 } );
=over 4
=item $attr
The attribute path to check.
=item $lower
The lower bound.
lib/ArangoDB/Collection.pm view on Meta::CPAN
=pod
=head2 near($latitude,$longitude[,$options])
Send 'near' simple query. Returns instance of L<ArangoDB::Cursor>.
The default will find at most 100 documents near a given coordinate.
The returned list is sorted according to the distance, with the nearest document coming first.
$cursor = $collection->near(0,0, { limit => 20 } );
=over 4
=item $latitude
The latitude of the coordinate.
=item $longitude
The longitude of the coordinate.
lib/ArangoDB/Collection.pm view on Meta::CPAN
=pod
=head2 within($latitude,$longitude,$radius[,$options])
Send 'within' simple query. Returns instance of L<ArangoDB::Cursor>.
This will find all documents with in a given radius around the coordinate (latitude, longitude).
The returned list is sorted by distance.
$cursor = $collection->within(0,0, 10 * 1000, { distance => 'distance' } );
=over 4
=item $latitude
The latitude of the coordinate.
=item $longitude
The longitude of the coordinate.
lib/ArangoDB/Constants.pm view on Meta::CPAN
# Update policies
use constant {
POLICY_LAST => 'last',
PILICY_ERROR => 'error',
};
# API
use constant {
API_DOCUMENT => '/_api/document',
API_COLLECTION => '/_api/collection',
API_CURSOR => '/_api/cursor',
API_EDGE => '/_api/edge',
API_EDGES => '/_api/edges',
API_KEY => '/_api/key/',
API_KEYS => '/_api/keys/',
API_EXAMPLE => '/_api/simple/by-example',
API_QUERY => '/_api/query',
API_EXPLAIN => '/_api/explain',
API_INDEX => '/_api/index',
API_IMPORT => '/_api/import',
API_SIMPLE_ALL => '/_api/simple/all',
lib/ArangoDB/Cursor.pm view on Meta::CPAN
return [ map { !ref($_) ? $_ : _clone($_) } @$orig ];
}
elsif ( $reftype eq 'HASH' ) {
return { map { !ref($_) ? $_ : _clone($_) } %$orig };
}
};
}
}
sub new {
my ( $class, $conn, $cursor ) = @_;
my $len = 0;
if ( defined $cursor->{result} && ref( $cursor->{result} ) eq 'ARRAY' ) {
$len = scalar @{ $cursor->{result} };
}
my $self = bless {
connection => $conn,
id => $cursor->{id},
length => $len,
count => $cursor->{count},
has_more => $cursor->{hasMore},
position => 0,
result => $cursor->{result} || [],
}, $class;
if ( $self->{id} ) {
$self->{_api_path} = API_CURSOR . '/' . $self->{id};
}
weaken( $self->{connection} );
return $self;
}
sub next {
my $self = shift;
lib/ArangoDB/Cursor.pm view on Meta::CPAN
my $self = shift;
return unless $self->{has_more};
eval {
my $res = $self->{connection}->http_put( $self->{_api_path}, {} );
$self->{has_more} = $res->{hasMore};
$self->{length} = scalar( @{ $res->{result} } );
$self->{result} = $res->{result};
$self->{position} = 0;
};
if ($@) {
$self->_server_error_handler( $@, 'Failed to get next batch cursor(%d)' );
}
return 1;
}
sub delete {
my $self = shift;
eval { $self->{connection}->http_delete( $self->{_api_path} ) };
if ($@) {
$self->_server_error_handler( $@, 'Failed to delete cursor(%d)' );
}
}
sub _server_error_handler {
my ( $self, $error, $message ) = @_;
my $msg = sprintf( $message, $self->id );
if ( ref($error) && $error->isa('ArangoDB::ServerException') ) {
$msg .= ':' . ( $error->detail->{errorMessage} || q{} );
}
croak $msg;
lib/ArangoDB/Cursor.pm view on Meta::CPAN
=pod
=head1 NAME
ArangoDB::Cursor - An ArangoDB Query Cursor hanlder
=head1 SYNOPSIS
my $cursor = $db->query('FOR u IN users RETURN u')->execute();
my @docs;
while( my $doc = $cursor->next ){
push @docs, $doc;
}
=head1 DESCRIPTION
Instance of ArandoDB Query Cursor.
=head1 METHODS
=head2 new()
Constructor.
=head2 next()
Returns next document(Instance of L<ArangoDB::Document>).
=head2 all()
Rreturns all documents in the cursor.(ARRAY reference).
The cursor on the server will be deleted implicitly.
=head2 delete()
Delete a cursor.
The cursor will automatically be destroyed on the server when the client has retrieved all documents from it.
The client can also explicitly destroy the cursor at any earlier time using this method.
=head1 AUTHOR
Hideaki Ohno E<lt>hide.o.j55 {at} gmail.comE<gt>
=cut
lib/ArangoDB/Statement.pm view on Meta::CPAN
=head1 SYNOPSIS
use ArangoDB;
my $db = ArangoDB->new(
host => 'localhost',
port => 8529,
);
my $sth = $db->query('FOR u IN users FILTER u.active == true RETURN u');
my $cursor = $sth->execute({
do_count => 1,
batch_size => 10,
});
while( my $doc = $cursor->next() ){
# do something
}
# Use bind variable
my $documents = $db->query(
'FOR u IN users FILTER u.age >= @age SORT u.name ASC RETURN u'
)->bind( age => 18 )->execute()->all;
=head1 DESCRIPTION
lib/ArangoDB/Statement.pm view on Meta::CPAN
Instance of ArangoDB::Connection.
=item $query
AQL statement.
=back
=head2 execute($options)
Execute AQL query and returns cursor(instance of L<ArangoDB::Cursor>).
$options is query options.The attributes of $options are:
=over 4
=item batch_size
Maximum number of result documents to be transferred from the server to the client in one roundtrip (optional).
=item do_count
t/05_query.t view on Meta::CPAN
}
my $expects = [ { name => 'Baz', age => 11 }, { name => 'Bar', age => 20 }, { name => 'John Doe', age => 42 }, ];
is_deeply \@docs, $expects;
my $docs2
= $db->query('FOR u IN users FILTER u.age > @age SORT u.age ASC RETURN u')->bind( age => 10 )->execute->all;
is_deeply [ map { $_->content } @$docs2 ], $expects;
};
subtest 'delete cursor' => sub {
my $db = ArangoDB->new($config);
my $sth = $db->query('FOR u IN users FILTER u.age > @age SORT u.name ASC RETURN u');
$sth->bind( age => 10 );
my $cur = $sth->execute( { batch_size => 2, } );
$cur->delete;
like exception {
while ( my $doc = $cur->next() ) {
}
}, qr/^Failed to get next batch cursor/;
like exception {
$cur->delete;
}, qr/^Failed to delete cursor/;
like exception {
my $guard = mock_guard(
'ArangoDB::Connection' => {
http_delete => sub {die}
}
);
$cur->delete;
}, qr/^Failed to delete cursor/;
};
subtest 'parse query' => sub {
my $db = ArangoDB->new($config);
my $binds = $db->query('FOR u IN users SORT u.name ASC RETURN u')->parse();
is scalar @$binds, 0;
$binds = $db->query('FOR u IN users FILTER u.age > @age SORT u.name ASC RETURN u')->parse();
is_deeply $binds, [qw/age/];
t/05_query.t view on Meta::CPAN
}, qr/^Failed to parse query/;
};
subtest 'explain query' => sub {
my $db = ArangoDB->new($config);
my $plan = $db->query('FOR u IN users SORT u.name ASC RETURN u')->explain();
ok $plan && ref($plan) eq 'ARRAY';
like exception { $db->query('FOR u IN users SORT u.name ASC RETURN ')->explain(); }, qr/^Failed to explain query/;
};
subtest 'cursor' => sub {
my $db = ArangoDB->new($config);
my $conn = $db->{connection};
my $cur = ArangoDB::Cursor->new( $conn, {} );
isa_ok $cur, 'ArangoDB::Cursor';
$cur = ArangoDB::Cursor->new( $conn, { result => {} } );
ok $cur;
$cur = ArangoDB::Cursor->new(
$conn,