mirror of https://github.com/vitalif/sophia-perl
perl bindings
commit
95cba3e7c7
|
@ -0,0 +1,50 @@
|
||||||
|
use strict;
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use File::Fetch;
|
||||||
|
use Archive::Extract;
|
||||||
|
|
||||||
|
use FindBin;
|
||||||
|
use ExtUtils::MakeMaker;
|
||||||
|
|
||||||
|
my $sophia = $FindBin::Bin ."/Sophia-src";
|
||||||
|
my $sophia_src = "$sophia/db";
|
||||||
|
|
||||||
|
my $rc = eval
|
||||||
|
{
|
||||||
|
require 5.010;
|
||||||
|
Term::ReadKey->import();
|
||||||
|
1;
|
||||||
|
};
|
||||||
|
|
||||||
|
if($rc && !-e "sophia-master")
|
||||||
|
{
|
||||||
|
eval {
|
||||||
|
my $ff = File::Fetch->new(uri => "http://github.com/pmwkaa/sophia/archive/master.zip");
|
||||||
|
|
||||||
|
if(my $file = $ff->fetch())
|
||||||
|
{
|
||||||
|
my $ae = Archive::Extract->new( archive => $file );
|
||||||
|
$ae->extract( to => '.' );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$sophia = $FindBin::Bin ."/sophia-master";
|
||||||
|
$sophia_src = -e "$sophia/db" ? "$sophia/db" : $sophia;
|
||||||
|
|
||||||
|
`make -C $sophia_src libsophia.a`;
|
||||||
|
|
||||||
|
|
||||||
|
WriteMakefile(
|
||||||
|
AUTHOR => 'Alexander Borisov <lex.borisov@gmail.com>',
|
||||||
|
ABSTRACT_FROM => 'Sophia.pm',
|
||||||
|
VERSION_FROM => 'Sophia.pm',
|
||||||
|
NAME => 'Database::Sophia',
|
||||||
|
LICENSE => 'perl',
|
||||||
|
LINKTYPE => 'dynamic',
|
||||||
|
LIBS => ["-L$sophia_src -lsophia -lpthread"],
|
||||||
|
INC => '-I'. $sophia_src
|
||||||
|
);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,404 @@
|
||||||
|
package Database::Sophia;
|
||||||
|
|
||||||
|
use utf8;
|
||||||
|
use strict;
|
||||||
|
use vars qw($AUTOLOAD $VERSION $ABSTRACT @ISA @EXPORT);
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
$VERSION = 0.8;
|
||||||
|
$ABSTRACT = "Sophia is a modern embeddable key-value database designed for a high load environment (XS for Sophia)";
|
||||||
|
|
||||||
|
@ISA = qw(Exporter DynaLoader);
|
||||||
|
@EXPORT = qw(
|
||||||
|
SPDIR SPALLOC SPCMP SPPAGE SPGC SPGCF
|
||||||
|
SPGROW SPMERGE SPMERGEWM SPMERGEFORCE SPVERSION
|
||||||
|
SPO_RDONLY SPO_RDWR SPO_CREAT SPO_SYNC
|
||||||
|
SPGT SPGTE SPLT SPLTE
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
bootstrap Database::Sophia $VERSION;
|
||||||
|
|
||||||
|
use DynaLoader ();
|
||||||
|
use Exporter ();
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Database::Sophia - Sophia is a modern embeddable key-value database designed for a high load environment (XS for Sophia)
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
|
||||||
|
use Database::Sophia;
|
||||||
|
|
||||||
|
my $env = Database::Sophia->sp_env();
|
||||||
|
|
||||||
|
my $err = $env->sp_ctl(SPDIR, SPO_CREAT|SPO_RDWR, "./db");
|
||||||
|
die $env->sp_error() if $err == -1;
|
||||||
|
|
||||||
|
my $db = $env->sp_open();
|
||||||
|
die $env->sp_error() unless $db;
|
||||||
|
|
||||||
|
$err = $db->sp_set("login", "lastmac");
|
||||||
|
print $db->sp_error(), "\n" if $err == -1;
|
||||||
|
|
||||||
|
my $value = $db->sp_get("login", $err);
|
||||||
|
|
||||||
|
if($err == -1) {
|
||||||
|
print $db->sp_error(), "\n";
|
||||||
|
}
|
||||||
|
elsif($err == 0) {
|
||||||
|
print "Key not found", "\n";
|
||||||
|
}
|
||||||
|
elsif($err == 1) {
|
||||||
|
print "Key found", "\n";
|
||||||
|
print "login: ", $value, "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->sp_destroy();
|
||||||
|
$env->sp_destroy();
|
||||||
|
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
It has unique architecture that was created as a result of research and rethinking of primary algorithmic constraints, associated with a getting popular Log-file based data structures, such as LSM-tree.
|
||||||
|
|
||||||
|
See http://sphia.org/
|
||||||
|
|
||||||
|
|
||||||
|
=head1 METHODS
|
||||||
|
|
||||||
|
=head2 sp_env
|
||||||
|
|
||||||
|
create a new environment handle
|
||||||
|
|
||||||
|
my $env = Database::Sophia->sp_env();
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_ctl
|
||||||
|
|
||||||
|
configurate a database
|
||||||
|
|
||||||
|
=head3 SPDIR
|
||||||
|
|
||||||
|
Sets database directory path and it's open flags to use by sp_open().
|
||||||
|
|
||||||
|
$env->sp_ctl(SPDIR, SPO_CREAT|SPO_RDWR, "./db");
|
||||||
|
|
||||||
|
=item Possible flags are:
|
||||||
|
|
||||||
|
SPO_RDWR - open repository in read-write mode (default)
|
||||||
|
|
||||||
|
SPO_RDONLY - open repository in read-only mode
|
||||||
|
|
||||||
|
SPO_CREAT - create repository if it is not exists.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
|
=head3 SPCMP
|
||||||
|
|
||||||
|
Sets database comparator function to use by database for a key order determination.
|
||||||
|
|
||||||
|
my $sub_cmp = sub {
|
||||||
|
my ($key_a, $key_b, $arg) = @_;
|
||||||
|
}
|
||||||
|
|
||||||
|
$env->sp_ctl(SPCMP, $sub_cmp, "arg to callback");
|
||||||
|
|
||||||
|
|
||||||
|
=head3 SPPAGE
|
||||||
|
|
||||||
|
Sets database max key count in a single page. This option can be tweaked for performance.
|
||||||
|
|
||||||
|
$env->sp_ctl(SPPAGE, 1024);
|
||||||
|
|
||||||
|
|
||||||
|
=head3 SPGC
|
||||||
|
|
||||||
|
Sets flag that garbage collector should be turn on.
|
||||||
|
|
||||||
|
$env->sp_ctl(SPGC, 1);
|
||||||
|
|
||||||
|
|
||||||
|
=head3 SPGCF
|
||||||
|
|
||||||
|
Sets database garbage collector factor value, which is used to determine whether it is time to start gc.
|
||||||
|
|
||||||
|
$env->sp_ctl(SPGCF, 0.5);
|
||||||
|
|
||||||
|
|
||||||
|
=head3 SPGROW
|
||||||
|
|
||||||
|
Sets new database files initial new size and resize factor. This values are used while database extend during merge.
|
||||||
|
|
||||||
|
$env->sp_ctl(SPGROW, 16 * 1024 * 1024, 2.0);
|
||||||
|
|
||||||
|
|
||||||
|
=head3 SPMERGE
|
||||||
|
|
||||||
|
Sets flag that merger thread must be created during sp_open().
|
||||||
|
|
||||||
|
$env->sp_ctl(SPMERGE, 1);
|
||||||
|
|
||||||
|
|
||||||
|
=head3 SPMERGEWM
|
||||||
|
|
||||||
|
Sets database merge watermark value.
|
||||||
|
|
||||||
|
$env->sp_ctl(SPMERGEWM, 200000);
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_open
|
||||||
|
|
||||||
|
Open or create a database
|
||||||
|
|
||||||
|
my $db = $env->sp_open();
|
||||||
|
|
||||||
|
On success, return database object; On error, it returns undef.
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_error
|
||||||
|
|
||||||
|
Get a string error description
|
||||||
|
|
||||||
|
$env->sp_error();
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_destroy
|
||||||
|
|
||||||
|
Free any handle
|
||||||
|
|
||||||
|
$ptr->sp_destroy();
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_begin
|
||||||
|
|
||||||
|
Begin a transaction
|
||||||
|
|
||||||
|
$db->sp_begin();
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_commit
|
||||||
|
|
||||||
|
Apply a transaction
|
||||||
|
|
||||||
|
$db->sp_commit();
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_rollback
|
||||||
|
|
||||||
|
Discard a transaction changes
|
||||||
|
|
||||||
|
$db->sp_rollback();
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_set
|
||||||
|
|
||||||
|
Insert or replace a key-value pair
|
||||||
|
|
||||||
|
$db->sp_set("key", "value");
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_get
|
||||||
|
|
||||||
|
Find a key in a database
|
||||||
|
|
||||||
|
my $error;
|
||||||
|
$db->sp_get("key", $error);
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_delete
|
||||||
|
|
||||||
|
Delete key from a database
|
||||||
|
|
||||||
|
$db->sp_delete("key");
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_cursor
|
||||||
|
|
||||||
|
create a database cursor
|
||||||
|
|
||||||
|
my $cur = $db->sp_cursor(SPGT, "key");
|
||||||
|
|
||||||
|
=item Possible order are:
|
||||||
|
|
||||||
|
SPGT - increasing order (skipping the key, if it is equal)
|
||||||
|
|
||||||
|
SPGTE - increasing order (with key)
|
||||||
|
|
||||||
|
SPLT - decreasing order (skippng the key, if is is equal)
|
||||||
|
|
||||||
|
SPLTE - decreasing order
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
After a use, cursor handle should be freed by $cur->sp_destroy() function.
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_fetch
|
||||||
|
|
||||||
|
Iterate a cursor
|
||||||
|
|
||||||
|
$cur->sp_fetch();
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_key
|
||||||
|
|
||||||
|
Get current key
|
||||||
|
|
||||||
|
$cur->sp_key()
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_keysize
|
||||||
|
|
||||||
|
$cur->sp_keysize()
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_value
|
||||||
|
|
||||||
|
$cur->sp_value()
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_valuesize
|
||||||
|
|
||||||
|
$cur->sp_valuesize()
|
||||||
|
|
||||||
|
|
||||||
|
=head1 Example
|
||||||
|
|
||||||
|
=head2 sp_open
|
||||||
|
|
||||||
|
use Database::Sophia;
|
||||||
|
|
||||||
|
my $env = Database::Sophia->sp_env();
|
||||||
|
|
||||||
|
my $err = $env->sp_ctl(SPDIR, SPO_CREAT|SPO_RDWR, "./db");
|
||||||
|
die $env->sp_error() if $err == -1;
|
||||||
|
|
||||||
|
my $db = $env->sp_open();
|
||||||
|
die $env->sp_error() unless $db;
|
||||||
|
|
||||||
|
=head2 sp_error
|
||||||
|
|
||||||
|
my $db = $env->sp_open();
|
||||||
|
die $env->sp_error() unless $db;
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_destroy
|
||||||
|
|
||||||
|
$db->sp_destroy();
|
||||||
|
$cur->sp_destroy();
|
||||||
|
$env->sp_destroy();
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_begin
|
||||||
|
|
||||||
|
my $rc = $db->sp_begin();
|
||||||
|
print $env->sp_error(), "\n" if $rc == -1;
|
||||||
|
|
||||||
|
$rc = $db->sp_set("key", "value");
|
||||||
|
print $env->sp_error(), "\n" if $rc == -1;
|
||||||
|
|
||||||
|
$rc = $db->sp_commit();
|
||||||
|
print $env->sp_error(), "\n" if $rc == -1;
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_commit
|
||||||
|
|
||||||
|
See sp_begin
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_rollback
|
||||||
|
|
||||||
|
my $rc = $db->sp_begin();
|
||||||
|
print $env->sp_error(), "\n" if $rc == -1;
|
||||||
|
|
||||||
|
$rc = $db->sp_set("key", "value");
|
||||||
|
print $env->sp_error(), "\n" if $rc == -1;
|
||||||
|
|
||||||
|
$rc = $db->sp_rollback();
|
||||||
|
print $env->sp_error(), "\n" if $rc == -1;
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_set
|
||||||
|
|
||||||
|
$rc = $db->sp_set("key", "value");
|
||||||
|
print $env->sp_error(), "\n" if $rc == -1;
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_get
|
||||||
|
|
||||||
|
my $error;
|
||||||
|
my $value = $db->sp_get("key", $error);
|
||||||
|
|
||||||
|
if($error == -1) {
|
||||||
|
print $db->sp_error(), "\n";
|
||||||
|
}
|
||||||
|
elsif($error == 0) {
|
||||||
|
print "Key not found", "\n";
|
||||||
|
}
|
||||||
|
elsif($error == 1) {
|
||||||
|
print "Key found", "\n";
|
||||||
|
print "key: ", $value, "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_fetch
|
||||||
|
|
||||||
|
my $cur = $db->sp_cursor(SPGT, "key");
|
||||||
|
|
||||||
|
while($cur->sp_fetch()) {
|
||||||
|
print $cur->sp_key(), ": ", $cur->sp_value();
|
||||||
|
print $cur->sp_keysize(), ": ", $cur->sp_valuesize();
|
||||||
|
}
|
||||||
|
|
||||||
|
$cur->sp_destroy();
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_key
|
||||||
|
|
||||||
|
See sp_fetch
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_keysize
|
||||||
|
|
||||||
|
See sp_fetch
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_value
|
||||||
|
|
||||||
|
See sp_fetch
|
||||||
|
|
||||||
|
|
||||||
|
=head2 sp_valuesize
|
||||||
|
|
||||||
|
See sp_fetch
|
||||||
|
|
||||||
|
|
||||||
|
=head1 DESTROY
|
||||||
|
|
||||||
|
undef $obj;
|
||||||
|
|
||||||
|
Free mem and destroy object.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Alexander Borisov <lex.borisov@gmail.com>
|
||||||
|
|
||||||
|
=head1 COPYRIGHT AND LICENSE
|
||||||
|
|
||||||
|
This software is copyright (c) 2014 by Alexander Borisov.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
|
||||||
|
|
||||||
|
See libsophia license and COPYRIGHT
|
||||||
|
http://sphia.org/
|
||||||
|
|
||||||
|
|
||||||
|
=cut
|
|
@ -0,0 +1,450 @@
|
||||||
|
// (c) Vitaliy Filippov 2015+
|
||||||
|
|
||||||
|
#include "EXTERN.h"
|
||||||
|
#include "perl.h"
|
||||||
|
#include "XSUB.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <sophia.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
}
|
||||||
|
sophia_env_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
}
|
||||||
|
sophia_ctl_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
}
|
||||||
|
sophia_db_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
}
|
||||||
|
sophia_txn_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
}
|
||||||
|
sophia_snapshot_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
}
|
||||||
|
sophia_cursor_t;
|
||||||
|
|
||||||
|
typedef sophia_env_t * Database__Sophia;
|
||||||
|
typedef sophia_ctl_t * Database__Sophia__Ctl;
|
||||||
|
typedef sophia_db_t * Database__Sophia__DB;
|
||||||
|
typedef sophia_txn_t * Database__Sophia__Txn;
|
||||||
|
typedef sophia_snapshot_t * Database__Sophia__Snapshot;
|
||||||
|
typedef sophia_cursor_t * Database__Sophia__Cursor;
|
||||||
|
|
||||||
|
/*static inline int sp_cmp(char *a_key, size_t asz, char *b_key, size_t bsz, void *arg)
|
||||||
|
{
|
||||||
|
dSP;
|
||||||
|
|
||||||
|
ENTER;
|
||||||
|
SAVETMPS;
|
||||||
|
|
||||||
|
sophia_t *ent = (sophia_t *)arg;
|
||||||
|
|
||||||
|
PUSHMARK(sp);
|
||||||
|
XPUSHs( sv_2mortal( newSVpv(a_key, asz) ) );
|
||||||
|
XPUSHs( sv_2mortal( newSVpv(b_key, bsz) ) );
|
||||||
|
if(ent->arg)
|
||||||
|
{
|
||||||
|
XPUSHs(ent->arg);
|
||||||
|
}
|
||||||
|
PUTBACK;
|
||||||
|
|
||||||
|
long res = 0;
|
||||||
|
int count = call_sv((SV *)ent->cmp, G_SCALAR);
|
||||||
|
|
||||||
|
SPAGAIN;
|
||||||
|
if (count > 0)
|
||||||
|
res = POPi;
|
||||||
|
PUTBACK;
|
||||||
|
|
||||||
|
FREETMPS;
|
||||||
|
LEAVE;
|
||||||
|
|
||||||
|
return (int)res;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
MODULE = Database::Sophia PACKAGE = Database::Sophia
|
||||||
|
|
||||||
|
PROTOTYPES: DISABLE
|
||||||
|
|
||||||
|
Database::Sophia
|
||||||
|
env()
|
||||||
|
CODE:
|
||||||
|
sophia_env_t *env = malloc(sizeof(sophia_env_t));
|
||||||
|
|
||||||
|
env->ptr = sp_env();
|
||||||
|
env->cmp = NULL;
|
||||||
|
env->arg = NULL;
|
||||||
|
|
||||||
|
RETVAL = env;
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
SV*
|
||||||
|
open(env)
|
||||||
|
Database::Sophia env;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
RETVAL = newSViv(sp_open(env->ptr));
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
Database::Sophia::Ctl
|
||||||
|
ctl(env)
|
||||||
|
Database::Sophia env;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
sophia_ctl_t *ctl = malloc(sizeof(sophia_ctl_t));
|
||||||
|
ctl->ptr = sp_ctl(env->ptr);
|
||||||
|
RETVAL = ctl;
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
Database::Sophia::Txn
|
||||||
|
begin(env)
|
||||||
|
Database::Sophia env;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
sophia_txn_t *txn = malloc(sizeof(sophia_txn_t));
|
||||||
|
|
||||||
|
txn->ptr = sp_begin(env->ptr);
|
||||||
|
|
||||||
|
RETVAL = txn;
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
MODULE = Database::Sophia PACKAGE = Database::Sophia::Ctl
|
||||||
|
|
||||||
|
PROTOTYPES: DISABLE
|
||||||
|
|
||||||
|
SV*
|
||||||
|
set(ctl, key, value)
|
||||||
|
Database::Sophia::Ctl ctl;
|
||||||
|
SV *key;
|
||||||
|
SV *value;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
STRLEN len_k = 0, len_v = 0;
|
||||||
|
|
||||||
|
char *key_c = SvPV( key, len_k );
|
||||||
|
char *value_c = SvPV( value, len_v );
|
||||||
|
|
||||||
|
RETVAL = newSViv( sp_set(ctl->ptr, (void *)key_c, (void *)value_c ) );
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
SV*
|
||||||
|
get(ctl, key)
|
||||||
|
Database::Sophia::Ctl ctl;
|
||||||
|
SV *key;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
STRLEN len_k = 0;
|
||||||
|
char *key_c = SvPV( key, len_k );
|
||||||
|
void *obj = sp_get(ctl->ptr, (void*)key_c);
|
||||||
|
if (!obj)
|
||||||
|
{
|
||||||
|
RETVAL = &PL_sv_undef;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *t = sp_type(obj);
|
||||||
|
if (!t)
|
||||||
|
{
|
||||||
|
croak("Object of empty type returned from ctl sp_get");
|
||||||
|
}
|
||||||
|
elseif (!strcmp(t, "database"))
|
||||||
|
{
|
||||||
|
sophia_db_t *db = malloc(sizeof(sophia_db_t));
|
||||||
|
db->ptr = obj;
|
||||||
|
sv_setref_pv(RETVAL, "Database::Sophia::DB", (void *)db);
|
||||||
|
}
|
||||||
|
else if (!strcmp(t, "snapshot"))
|
||||||
|
{
|
||||||
|
sophia_snapshot_t *snapshot = malloc(sizeof(sophia_snapshot_t));
|
||||||
|
snapshot->ptr = obj;
|
||||||
|
sv_setref_pv(RETVAL, "Database::Sophia::Snapshot", (void *)snapshot);
|
||||||
|
}
|
||||||
|
else if (!strcmp(t, "object"))
|
||||||
|
{
|
||||||
|
uint32_t l;
|
||||||
|
char *r = (char*)sp_get(obj, "value", &l);
|
||||||
|
RETVAL = newSVpv(r, l);
|
||||||
|
sp_destroy(obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
croak("Unknown object type returned from ctl sp_get: %s", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
Database::Sophia::Cursor
|
||||||
|
cursor(ctl)
|
||||||
|
Database::Sophia::Ctl ctl;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
sophia_cursor_t *cur = malloc(sizeof(sophia_cursor_t));
|
||||||
|
cur->ptr = sp_cursor(ctl->ptr);
|
||||||
|
RETVAL = cur;
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
|
||||||
|
MODULE = Database::Sophia PACKAGE = Database::Sophia::DB
|
||||||
|
|
||||||
|
SV*
|
||||||
|
open(db)
|
||||||
|
Database::Sophia::DB db;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
RETVAL = newSViv(sp_open(db->ptr));
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
SV*
|
||||||
|
get(db, key)
|
||||||
|
Database::Sophia::DB db;
|
||||||
|
SV *key;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
int err;
|
||||||
|
STRLEN len_k = 0;
|
||||||
|
char *key_c = SvPV(key, len_k);
|
||||||
|
void *value;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
RETVAL = &PL_sv_undef;
|
||||||
|
void *obj = sp_object(db->ptr);
|
||||||
|
void *ret;
|
||||||
|
if (obj)
|
||||||
|
{
|
||||||
|
sp_set(obj, "key", key_c, len_k);
|
||||||
|
ret = sp_get(db->ptr, obj);
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
value = sp_get(ret, "value", &size);
|
||||||
|
RETVAL = newSVpv(value, size);
|
||||||
|
sp_destroy(ret);
|
||||||
|
}
|
||||||
|
sp_destroy(obj);
|
||||||
|
}
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
SV*
|
||||||
|
delete(db, key)
|
||||||
|
Database::Sophia::DB db;
|
||||||
|
SV *key;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
int err;
|
||||||
|
STRLEN len_k = 0;
|
||||||
|
char *key_c = SvPV(key, len_k);
|
||||||
|
|
||||||
|
RETVAL = &PL_sv_undef;
|
||||||
|
void *obj = sp_object(db->ptr);
|
||||||
|
void *ret;
|
||||||
|
if (obj)
|
||||||
|
{
|
||||||
|
sp_set(obj, "key", key_c, len_k);
|
||||||
|
err = sp_delete(db->ptr, obj);
|
||||||
|
sp_destroy(obj);
|
||||||
|
}
|
||||||
|
RETVAL = newSViv(err);
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
SV*
|
||||||
|
set(db, key, value)
|
||||||
|
Database::Sophia::DB db;
|
||||||
|
SV *key;
|
||||||
|
SV *value;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
int err;
|
||||||
|
STRLEN len_k = 0;
|
||||||
|
char *key_c = SvPV(key, len_k);
|
||||||
|
STRLEN len_v = 0;
|
||||||
|
char *value_c = SvPV(value, len_v);
|
||||||
|
|
||||||
|
RETVAL = &PL_sv_undef;
|
||||||
|
void *obj = sp_object(db->ptr);
|
||||||
|
void *ret;
|
||||||
|
if (obj)
|
||||||
|
{
|
||||||
|
sp_set(obj, "key", key_c, len_k);
|
||||||
|
sp_set(obj, "value", value_c, len_v);
|
||||||
|
err = sp_set(db->ptr, obj);
|
||||||
|
sp_destroy(obj);
|
||||||
|
}
|
||||||
|
RETVAL = newSViv(err);
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
Database::Sophia::Cursor
|
||||||
|
cursor(db, key, order)
|
||||||
|
Database::Sophia::DB db;
|
||||||
|
SV *key;
|
||||||
|
SV *order;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
void *c;
|
||||||
|
STRLEN len_k = 0;
|
||||||
|
char *key_c = SvPV(key, len_k);
|
||||||
|
STRLEN len_o = 0;
|
||||||
|
char *order_c = SvPV(order, len_v);
|
||||||
|
void *obj = sp_object(db->ptr);
|
||||||
|
|
||||||
|
RETVAL = &PL_sv_undef;
|
||||||
|
if (obj)
|
||||||
|
{
|
||||||
|
sp_set(obj, "key", key_c, len_k);
|
||||||
|
sp_set(obj, "order", order_c, len_o);
|
||||||
|
c = sp_cursor(db->ptr, obj);
|
||||||
|
sp_destroy(obj);
|
||||||
|
if (c)
|
||||||
|
{
|
||||||
|
sophia_cursor_t *cur = malloc(sizeof(sophia_cursor_t));
|
||||||
|
cur->ptr = c;
|
||||||
|
RETVAL = cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
|
||||||
|
MODULE = Database::Sophia PACKAGE = Database::Sophia::Txn
|
||||||
|
|
||||||
|
PROTOTYPES: DISABLE
|
||||||
|
|
||||||
|
SV*
|
||||||
|
commit(txn)
|
||||||
|
Database::Sophia::Txn txn;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
RETVAL = newSViv( sp_commit(txn->ptr) );
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
SV*
|
||||||
|
get(txn, key)
|
||||||
|
Database::Sophia::Txn txn;
|
||||||
|
SV *key;
|
||||||
|
|
||||||
|
SV*
|
||||||
|
delete(txn, key)
|
||||||
|
Database::Sophia::Txn txn;
|
||||||
|
SV *key;
|
||||||
|
|
||||||
|
SV*
|
||||||
|
set(txn, key, value)
|
||||||
|
Database::Sophia::Txn txn;
|
||||||
|
SV *key;
|
||||||
|
SV *value;
|
||||||
|
|
||||||
|
|
||||||
|
MODULE = Database::Sophia PACKAGE = Database::Sophia::Snapshot
|
||||||
|
|
||||||
|
PROTOTYPES: DISABLE
|
||||||
|
|
||||||
|
SV*
|
||||||
|
drop(snapshot)
|
||||||
|
Database::Sophia::Snapshot snapshot;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
RETVAL = newSViv( sp_drop(snapshot->ptr) );
|
||||||
|
// FIXME destroy
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
SV*
|
||||||
|
get(txn, key)
|
||||||
|
Database::Sophia::Snapshot snapshot;
|
||||||
|
SV *key;
|
||||||
|
|
||||||
|
Database::Sophia::Cursor
|
||||||
|
cursor(db, key, order)
|
||||||
|
Database::Sophia::Snapshot snapshot;
|
||||||
|
SV *key;
|
||||||
|
SV *order;
|
||||||
|
|
||||||
|
|
||||||
|
MODULE = Database::Sophia PACKAGE = Database::Sophia::Cursor
|
||||||
|
|
||||||
|
PROTOTYPES: DISABLE
|
||||||
|
|
||||||
|
SV*
|
||||||
|
get(cursor, key)
|
||||||
|
Database::Sophia::Cursor cursor;
|
||||||
|
SV *key;
|
||||||
|
|
||||||
|
SV*
|
||||||
|
cur_key(cursor)
|
||||||
|
Database::Sophia::Cursor cursor;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
void *obj = sp_object(cursor->ptr);
|
||||||
|
uint32_t size;
|
||||||
|
char *value;
|
||||||
|
if (obj)
|
||||||
|
{
|
||||||
|
value = sp_get(obj, "key", &size);
|
||||||
|
RETVAL = newSVpv(value, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RETVAL = &PL_sv_undef;
|
||||||
|
}
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
SV*
|
||||||
|
cur_value(cursor)
|
||||||
|
Database::Sophia::Cursor cursor;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
void *obj = sp_object(cursor->ptr);
|
||||||
|
uint32_t size;
|
||||||
|
char *value;
|
||||||
|
if (obj)
|
||||||
|
{
|
||||||
|
value = sp_get(obj, "value", &size);
|
||||||
|
RETVAL = newSVpv(value, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RETVAL = &PL_sv_undef;
|
||||||
|
}
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
void
|
||||||
|
DESTROY(ptr)
|
||||||
|
Database::Sophia ptr;
|
||||||
|
|
||||||
|
CODE:
|
||||||
|
if(ptr->ptr)
|
||||||
|
sp_destroy(ptr);
|
||||||
|
if(ptr)
|
||||||
|
free(ptr);
|
|
@ -0,0 +1,13 @@
|
||||||
|
TYPEMAP
|
||||||
|
sophia_env_t * T_PTROBJ
|
||||||
|
Database::Sophia T_PTROBJ
|
||||||
|
sophia_ctl_t * T_PTROBJ
|
||||||
|
Database::Sophia::Ctl T_PTROBJ
|
||||||
|
sophia_txn_t * T_PTROBJ
|
||||||
|
Database::Sophia::Txn T_PTROBJ
|
||||||
|
sophia_db_t * T_PTROBJ
|
||||||
|
Database::Sophia::DB T_PTROBJ
|
||||||
|
sophia_snapshot_t * T_PTROBJ
|
||||||
|
Database::Sophia::Snapshot T_PTROBJ
|
||||||
|
sophia_cursor_t * T_PTROBJ
|
||||||
|
Database::Sophia::Cursor T_PTROBJ
|
Loading…
Reference in New Issue