package ArangoDB::AbstractDocument;
use strict;
use warnings;
use utf8;
use 5.008001;
use Scalar::Util qw(weaken);
use overload
q{""} => sub { shift->document_handle },
fallback => 1;
sub new {
my ( $class, $conn, $doc ) = @_;
die "Invalid argument for $class : undef" unless defined $doc;
my $self = bless { connection => $conn, }, $class;
weaken( $self->{connection} );
my $id = CORE::delete $doc->{_id};
my $rev = CORE::delete $doc->{_rev};
$self->{is_persistent} = defined $id && defined $rev;
if ( $self->{is_persistent} ) {
( $self->{_collection_id}, $self->{_id} ) = split '/', $id;
$self->{_document_handle} = $id;
$self->{_rev} = $rev;
}
map { $self->{$_} = CORE::delete $doc->{$_} } grep {/^_/} keys %$doc;
$self->{document} = $doc;
return $self;
}
sub id {
$_[0]->{_id};
}
sub revision {
$_[0]->{_rev};
}
sub collection_id {
$_[0]->{_collection_id};
}
sub document_handle {
$_[0]->{_document_handle};
}
sub content {
return $_[0]->{document};
}
sub get {
my ( $self, $attr_name ) = @_;
return $self->{document}{$attr_name};
}
sub set {
my ( $self, $attr_name, $value ) = @_;
$self->{document}{$attr_name} = $value;
return $self;
}
sub fetch {
my ( $self, $no_etag ) = @_;
my @header;
if ( !$no_etag ) {
push @header, 'If-None-Match' => $self->{_rev};
}
my $res = eval { $self->{connection}->http_get( $self->_api_path, \@header ) };
if ($@) {
$self->_server_error_handler( $@, 'fetch' );
}
if ( !defined $res || ref($res) eq 'HASH' ) {
$self->{_rev} = delete $res->{_rev};
$self->{document} = { map { $_ => $res->{$_} } grep { $_ !~ /^_/ } keys %$res };
}
return $self;
}
sub save {
my ( $self, $with_rev_check ) = @_;
eval {
my $rev
= $with_rev_check
? '?rev=' . $self->{_rev}
: q{};
$self->{connection}->http_put( $self->_api_path . $rev, $self->content );
};
if ($@) {
$self->_server_error_handler( $@, 'update' );
}
$self->fetch(1);
return $self;
}
sub delete {
my $self = shift;
eval { $self->{connection}->http_delete( $self->_api_path ) };
if ($@) {
$self->_server_error_handler( $@, 'delete' );
}
return $self;
}
sub _api_path {
die 'Abstract method';
}
sub _server_error_handler {
die 'Abstract method';
}
1;
__END__