sophia-perl/Sophia.xs

505 lines
8.1 KiB
Plaintext
Executable File

// (c) Vitaliy Filippov 2015+
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <stdarg.h>
#include "sophia.h"
typedef struct
{
void *ptr;
void *cmp;
void *arg;
}
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
void
DESTROY(ptr)
Database::Sophia ptr;
CODE:
if(ptr)
free(ptr);
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");
}
else if (!strcmp(t, "database"))
{
sophia_db_t *db = malloc(sizeof(sophia_db_t));
db->ptr = obj;
RETVAL = sv_newmortal();
sv_setref_pv(RETVAL, "Database::Sophia::DB", (void *)db);
SvREFCNT_inc(RETVAL);
}
else if (!strcmp(t, "snapshot"))
{
sophia_snapshot_t *snapshot = malloc(sizeof(sophia_snapshot_t));
snapshot->ptr = obj;
RETVAL = sv_newmortal();
sv_setref_pv(RETVAL, "Database::Sophia::Snapshot", (void *)snapshot);
SvREFCNT_inc(RETVAL);
}
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
void
DESTROY(ptr)
Database::Sophia::Ctl ptr;
CODE:
if(ptr)
free(ptr);
MODULE = Database::Sophia PACKAGE = Database::Sophia::DB
Database::Sophia::Ctl
ctl(db)
Database::Sophia::DB db;
CODE:
sophia_ctl_t *ctl = malloc(sizeof(sophia_ctl_t));
ctl->ptr = sp_ctl(db->ptr);
RETVAL = ctl;
OUTPUT:
RETVAL
SV*
open(db)
Database::Sophia::DB db;
CODE:
RETVAL = newSViv(sp_open(db->ptr));
OUTPUT:
RETVAL
SV*
get(db, key, txn_or_snapshot = &PL_sv_undef)
Database::Sophia::DB db;
SV *key;
SV *txn_or_snapshot;
CODE:
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(SvOK(txn_or_snapshot) ? (INT2PTR(sophia_txn_t*, (SvIV((SV*)SvRV(txn_or_snapshot)))))->ptr : db->ptr, obj);
if (ret)
{
value = sp_get(ret, "value", &size);
RETVAL = newSVpv(value, size);
sp_destroy(ret);
}
sp_destroy(obj);
}
OUTPUT:
RETVAL
SV*
delete(db, key, txn = &PL_sv_undef)
Database::Sophia::DB db;
SV *key;
SV *txn;
CODE:
int err = -1;
STRLEN len_k = 0;
char *key_c = SvPV(key, len_k);
RETVAL = &PL_sv_undef;
void *obj = sp_object(db->ptr);
if (obj)
{
sp_set(obj, "key", key_c, len_k);
err = sp_delete(SvOK(txn) ? (INT2PTR(sophia_txn_t*, (SvIV((SV*)SvRV(txn)))))->ptr : db->ptr, obj);
sp_destroy(obj);
}
RETVAL = newSViv(err);
OUTPUT:
RETVAL
SV*
set(db, key, value, txn = &PL_sv_undef)
Database::Sophia::DB db;
SV *key;
SV *value;
SV *txn;
CODE:
int err = -1;
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);
if (obj)
{
sp_set(obj, "key", key_c, len_k);
sp_set(obj, "value", value_c, len_v);
err = sp_set(SvOK(txn) ? (INT2PTR(sophia_txn_t*, (SvIV((SV*)SvRV(txn)))))->ptr : db->ptr, obj);
sp_destroy(obj);
}
RETVAL = newSViv(err);
OUTPUT:
RETVAL
Database::Sophia::Cursor
cursor(db, key, order, snapshot = &PL_sv_undef)
Database::Sophia::DB db;
SV *key;
SV *order;
SV *snapshot;
CODE:
void *c;
STRLEN len_k = 0;
char *key_c = SvPV(key, len_k);
STRLEN len_o = 0;
char *order_c = SvPV(order, len_o);
void *obj = sp_object(db->ptr);
RETVAL = (void*)&PL_sv_undef;
if (obj)
{
sp_set(obj, "key", key_c, len_k);
sp_set(obj, "order", order_c, len_o);
c = sp_cursor(SvOK(snapshot) ? (INT2PTR(sophia_snapshot_t*, (SvIV((SV*)SvRV(snapshot)))))->ptr : db->ptr, obj);
sp_destroy(obj);
if (c)
{
sophia_cursor_t *cur = malloc(sizeof(sophia_cursor_t));
cur->ptr = c;
RETVAL = cur;
}
}
OUTPUT:
RETVAL
void
DESTROY(ptr)
Database::Sophia::DB ptr;
CODE:
if(ptr->ptr)
sp_destroy(ptr->ptr);
if(ptr)
free(ptr);
MODULE = Database::Sophia PACKAGE = Database::Sophia::Txn
PROTOTYPES: DISABLE
SV*
commit(txn)
Database::Sophia::Txn txn;
CODE:
RETVAL = newSViv( sp_commit(txn->ptr) );
// FIXME destroy
OUTPUT:
RETVAL
void
DESTROY(ptr)
Database::Sophia::Txn ptr;
CODE:
if(ptr->ptr)
sp_destroy(ptr->ptr);
if(ptr)
free(ptr);
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
void
DESTROY(ptr)
Database::Sophia::Snapshot ptr;
CODE:
if(ptr->ptr)
sp_destroy(ptr->ptr);
if(ptr)
free(ptr);
MODULE = Database::Sophia PACKAGE = Database::Sophia::Cursor
PROTOTYPES: DISABLE
SV*
next_key(cursor)
Database::Sophia::Cursor cursor;
CODE:
void *obj = sp_get(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_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::Snapshot ptr;
CODE:
if(ptr->ptr)
sp_destroy(ptr->ptr);
if(ptr)
free(ptr);