forked from Telodendria/Cytoplasm
Compare commits
No commits in common. "cf1b78b224c4b5253c4b61055364977bd571c018" and "f32cdb7d899aecc9feef20262afdd14d6ab197b7" have entirely different histories.
cf1b78b224
...
f32cdb7d89
5 changed files with 102 additions and 122 deletions
|
@ -48,17 +48,6 @@
|
||||||
*/
|
*/
|
||||||
typedef struct Db Db;
|
typedef struct Db Db;
|
||||||
|
|
||||||
/**
|
|
||||||
* Some "hints" for the database backend for operations.
|
|
||||||
* Hints are a way for the program to declare what to except of it
|
|
||||||
* (and the program MUST adhere to these hints, but the backend
|
|
||||||
* MAY adhere).
|
|
||||||
*/
|
|
||||||
typedef enum DbHint {
|
|
||||||
DB_HINT_READONLY, /* The database reference is treated as read-only */
|
|
||||||
DB_HINT_WRITE /* The database reference is treated as read/write */
|
|
||||||
} DbHint;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When an object is locked, a reference is returned. This reference
|
* When an object is locked, a reference is returned. This reference
|
||||||
* is owned by the current thread, and the database is inaccessible to
|
* is owned by the current thread, and the database is inaccessible to
|
||||||
|
@ -129,15 +118,6 @@ extern DbRef * DbCreate(Db *, size_t,...);
|
||||||
*/
|
*/
|
||||||
extern DbRef * DbLock(Db *, size_t,...);
|
extern DbRef * DbLock(Db *, size_t,...);
|
||||||
|
|
||||||
/**
|
|
||||||
* Behaves like
|
|
||||||
* .Fn DbLock ,
|
|
||||||
* but with hints on the reference itself, as
|
|
||||||
* .Fn DbLock
|
|
||||||
* itself is read/write.
|
|
||||||
*/
|
|
||||||
extern DbRef * DbLockIntent(Db *, DbHint, size_t,...);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immediately and permanently remove an object from the database.
|
* Immediately and permanently remove an object from the database.
|
||||||
* This function assumes the object is not locked, otherwise undefined
|
* This function assumes the object is not locked, otherwise undefined
|
||||||
|
|
25
src/Db/Db.c
25
src/Db/Db.c
|
@ -327,30 +327,7 @@ DbLock(Db * db, size_t nArgs,...)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = db->lockFunc(db, DB_HINT_WRITE, args);
|
ret = db->lockFunc(db, args);
|
||||||
|
|
||||||
ArrayFree(args);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
DbRef *
|
|
||||||
DbLockIntent(Db * db, DbHint hint, size_t nArgs,...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
Array *args;
|
|
||||||
DbRef *ret;
|
|
||||||
|
|
||||||
va_start(ap, nArgs);
|
|
||||||
args = ArrayFromVarArgs(nArgs, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
if (!args || !db->lockFunc)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = db->lockFunc(db, hint, args);
|
|
||||||
|
|
||||||
ArrayFree(args);
|
ArrayFree(args);
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ DbFileName(FlatDb * db, Array * args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static DbRef *
|
static DbRef *
|
||||||
FlatLock(Db *d, DbHint hint, Array *dir)
|
FlatLock(Db *d, Array *dir)
|
||||||
{
|
{
|
||||||
FlatDb *db = (FlatDb *) d;
|
FlatDb *db = (FlatDb *) d;
|
||||||
FlatDbRef *ref = NULL;
|
FlatDbRef *ref = NULL;
|
||||||
|
@ -146,8 +146,6 @@ FlatLock(Db *d, DbHint hint, Array *dir)
|
||||||
|
|
||||||
ref = Malloc(sizeof(*ref));
|
ref = Malloc(sizeof(*ref));
|
||||||
DbRefInit(d, (DbRef *) ref);
|
DbRefInit(d, (DbRef *) ref);
|
||||||
/* TODO: Hints */
|
|
||||||
ref->base.hint = hint;
|
|
||||||
ref->base.ts = UtilLastModified(path);
|
ref->base.ts = UtilLastModified(path);
|
||||||
ref->base.json = JsonDecode(stream);
|
ref->base.json = JsonDecode(stream);
|
||||||
ref->stream = stream;
|
ref->stream = stream;
|
||||||
|
@ -250,7 +248,7 @@ FlatCreate(Db *d, Array *dir)
|
||||||
|
|
||||||
/* FlatLock() will lock again for us */
|
/* FlatLock() will lock again for us */
|
||||||
pthread_mutex_unlock(&d->lock);
|
pthread_mutex_unlock(&d->lock);
|
||||||
ret = FlatLock(d, DB_HINT_WRITE, dir);
|
ret = FlatLock(d, dir);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ struct Db
|
||||||
|
|
||||||
/* Functions for implementation-specific operations
|
/* Functions for implementation-specific operations
|
||||||
* (opening a ref, closing a db, removing an entry, ...) */
|
* (opening a ref, closing a db, removing an entry, ...) */
|
||||||
DbRef * (*lockFunc)(Db *, DbHint, Array *);
|
DbRef * (*lockFunc)(Db *, Array *);
|
||||||
DbRef * (*create)(Db *, Array *);
|
DbRef * (*create)(Db *, Array *);
|
||||||
Array * (*list)(Db *, Array *);
|
Array * (*list)(Db *, Array *);
|
||||||
bool (*unlock)(Db *, DbRef *);
|
bool (*unlock)(Db *, DbRef *);
|
||||||
|
@ -89,7 +89,8 @@ struct DbRef
|
||||||
DbRef *prev;
|
DbRef *prev;
|
||||||
DbRef *next;
|
DbRef *next;
|
||||||
|
|
||||||
DbHint hint;
|
/* TODO: Functions for implementation-specific operations */
|
||||||
|
|
||||||
/* Implementation-specific constructs */
|
/* Implementation-specific constructs */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
152
src/Db/LMDB.c
152
src/Db/LMDB.c
|
@ -17,7 +17,6 @@ typedef struct LMDB {
|
||||||
Db base; /* The base implementation required to pass */
|
Db base; /* The base implementation required to pass */
|
||||||
|
|
||||||
MDB_env *environ;
|
MDB_env *environ;
|
||||||
MDB_dbi dbi;
|
|
||||||
} LMDB;
|
} LMDB;
|
||||||
typedef struct LMDBRef {
|
typedef struct LMDBRef {
|
||||||
DbRef base;
|
DbRef base;
|
||||||
|
@ -136,13 +135,14 @@ LMDBKeyHead(MDB_val key)
|
||||||
}
|
}
|
||||||
|
|
||||||
static DbRef *
|
static DbRef *
|
||||||
LMDBLock(Db *d, DbHint hint, Array *k)
|
LMDBLock(Db *d, Array *k)
|
||||||
{
|
{
|
||||||
LMDB *db = (LMDB *) d;
|
LMDB *db = (LMDB *) d;
|
||||||
MDB_txn *transaction;
|
MDB_txn *transaction;
|
||||||
LMDBRef *ret = NULL;
|
LMDBRef *ret = NULL;
|
||||||
MDB_val key, json_val;
|
MDB_val key, empty_json;
|
||||||
int code, flags;
|
MDB_dbi dbi;
|
||||||
|
int code;
|
||||||
if (!d || !k)
|
if (!d || !k)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -151,11 +151,8 @@ LMDBLock(Db *d, DbHint hint, Array *k)
|
||||||
pthread_mutex_lock(&d->lock);
|
pthread_mutex_lock(&d->lock);
|
||||||
key = LMDBTranslateKey(k);
|
key = LMDBTranslateKey(k);
|
||||||
|
|
||||||
/* Create a transaction, honoring hints. */
|
/* create a txn */
|
||||||
/* TODO: Do we want to create a "main" transaction that everyone inherits
|
if ((code = mdb_txn_begin(db->environ, NULL, 0, &transaction)) != 0)
|
||||||
* from? */
|
|
||||||
flags = hint == DB_HINT_READONLY ? MDB_RDONLY : 0;
|
|
||||||
if ((code = mdb_txn_begin(db->environ, NULL, flags, &transaction)) != 0)
|
|
||||||
{
|
{
|
||||||
/* Very bad! */
|
/* Very bad! */
|
||||||
Log(LOG_ERR,
|
Log(LOG_ERR,
|
||||||
|
@ -164,13 +161,25 @@ LMDBLock(Db *d, DbHint hint, Array *k)
|
||||||
);
|
);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
/* apparently you need to give it a dbi */
|
||||||
|
if ((code = mdb_dbi_open(transaction, "db", MDB_CREATE, &dbi)) != 0)
|
||||||
|
{
|
||||||
|
Log(LOG_ERR,
|
||||||
|
"%s: could not get transaction dbi: %s",
|
||||||
|
__func__, mdb_strerror(code)
|
||||||
|
);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
json_val.mv_size = 0;
|
empty_json.mv_size = 0;
|
||||||
json_val.mv_data = NULL;
|
empty_json.mv_data = NULL;
|
||||||
code = mdb_get(transaction, db->dbi, &key, &json_val);
|
/* get data from it */
|
||||||
|
code = mdb_get(transaction, dbi, &key, &empty_json);
|
||||||
if (code == MDB_NOTFOUND)
|
if (code == MDB_NOTFOUND)
|
||||||
{
|
{
|
||||||
|
/* No use logging it, as that is just locking behaviour */
|
||||||
mdb_txn_abort(transaction);
|
mdb_txn_abort(transaction);
|
||||||
|
mdb_dbi_close(db->environ, dbi);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
else if (code != 0)
|
else if (code != 0)
|
||||||
|
@ -180,6 +189,7 @@ LMDBLock(Db *d, DbHint hint, Array *k)
|
||||||
__func__, mdb_strerror(code)
|
__func__, mdb_strerror(code)
|
||||||
);
|
);
|
||||||
mdb_txn_abort(transaction);
|
mdb_txn_abort(transaction);
|
||||||
|
mdb_dbi_close(db->environ, dbi);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,20 +205,11 @@ LMDBLock(Db *d, DbHint hint, Array *k)
|
||||||
StringArrayAppend(ret->base.name, ent);
|
StringArrayAppend(ret->base.name, ent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret->base.json = LMDBDecode(json_val);
|
ret->base.json = LMDBDecode(empty_json);
|
||||||
ret->base.hint = hint;
|
|
||||||
ret->transaction = NULL;
|
|
||||||
|
|
||||||
if (hint == DB_HINT_WRITE)
|
|
||||||
{
|
|
||||||
ret->transaction = transaction;
|
ret->transaction = transaction;
|
||||||
}
|
ret->dbi = dbi;
|
||||||
else
|
|
||||||
{
|
|
||||||
mdb_txn_abort(transaction);
|
|
||||||
}
|
|
||||||
end:
|
end:
|
||||||
if (!ret || hint == DB_HINT_READONLY)
|
if (!ret)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&d->lock);
|
pthread_mutex_unlock(&d->lock);
|
||||||
}
|
}
|
||||||
|
@ -221,6 +222,7 @@ LMDBExists(Db *d, Array *k)
|
||||||
MDB_val key, empty;
|
MDB_val key, empty;
|
||||||
LMDB *db = (LMDB *) d;
|
LMDB *db = (LMDB *) d;
|
||||||
MDB_txn *transaction;
|
MDB_txn *transaction;
|
||||||
|
MDB_dbi dbi;
|
||||||
int code;
|
int code;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (!d || !k)
|
if (!d || !k)
|
||||||
|
@ -241,9 +243,21 @@ LMDBExists(Db *d, Array *k)
|
||||||
);
|
);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
/* apparently you need to give it a dbi */
|
||||||
|
if ((code = mdb_dbi_open(transaction, "db", MDB_CREATE, &dbi)) != 0)
|
||||||
|
{
|
||||||
|
Log(LOG_ERR,
|
||||||
|
"%s: could not get transaction dbi: %s",
|
||||||
|
__func__, mdb_strerror(code)
|
||||||
|
);
|
||||||
|
goto end;
|
||||||
|
|
||||||
ret = mdb_get(transaction, db->dbi, &key, &empty) == 0;
|
}
|
||||||
|
|
||||||
|
ret = mdb_get(transaction, dbi, &key, &empty) == 0;
|
||||||
mdb_txn_abort(transaction);
|
mdb_txn_abort(transaction);
|
||||||
|
mdb_dbi_close(db->environ, dbi);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
LMDBKillKey(key);
|
LMDBKillKey(key);
|
||||||
pthread_mutex_unlock(&d->lock);
|
pthread_mutex_unlock(&d->lock);
|
||||||
|
@ -255,6 +269,7 @@ LMDBDelete(Db *d, Array *k)
|
||||||
MDB_val key, empty;
|
MDB_val key, empty;
|
||||||
LMDB *db = (LMDB *) d;
|
LMDB *db = (LMDB *) d;
|
||||||
MDB_txn *transaction;
|
MDB_txn *transaction;
|
||||||
|
MDB_dbi dbi;
|
||||||
int code;
|
int code;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (!d || !k)
|
if (!d || !k)
|
||||||
|
@ -275,9 +290,21 @@ LMDBDelete(Db *d, Array *k)
|
||||||
);
|
);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
/* apparently you need to give it a dbi */
|
||||||
|
if ((code = mdb_dbi_open(transaction, "db", MDB_CREATE, &dbi)) != 0)
|
||||||
|
{
|
||||||
|
Log(LOG_ERR,
|
||||||
|
"%s: could not get transaction dbi: %s",
|
||||||
|
__func__, mdb_strerror(code)
|
||||||
|
);
|
||||||
|
goto end;
|
||||||
|
|
||||||
ret = mdb_del(transaction, db->dbi, &key, &empty) == 0;
|
}
|
||||||
|
|
||||||
|
ret = mdb_del(transaction, dbi, &key, &empty) == 0;
|
||||||
mdb_txn_commit(transaction);
|
mdb_txn_commit(transaction);
|
||||||
|
mdb_dbi_close(db->environ, dbi);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
LMDBKillKey(key);
|
LMDBKillKey(key);
|
||||||
pthread_mutex_unlock(&d->lock);
|
pthread_mutex_unlock(&d->lock);
|
||||||
|
@ -292,7 +319,7 @@ LMDBUnlock(Db *d, DbRef *r)
|
||||||
FILE *fakestream;
|
FILE *fakestream;
|
||||||
Stream *stream;
|
Stream *stream;
|
||||||
MDB_val key, val;
|
MDB_val key, val;
|
||||||
bool ret = true;
|
bool ret;
|
||||||
|
|
||||||
if (!d || !r)
|
if (!d || !r)
|
||||||
{
|
{
|
||||||
|
@ -301,8 +328,6 @@ LMDBUnlock(Db *d, DbRef *r)
|
||||||
|
|
||||||
val.mv_data = NULL;
|
val.mv_data = NULL;
|
||||||
val.mv_size = 0;
|
val.mv_size = 0;
|
||||||
if (ref->transaction && r->hint == DB_HINT_WRITE)
|
|
||||||
{
|
|
||||||
key = LMDBTranslateKey(r->name);
|
key = LMDBTranslateKey(r->name);
|
||||||
|
|
||||||
fakestream = open_memstream((char **) &val.mv_data, &val.mv_size);
|
fakestream = open_memstream((char **) &val.mv_data, &val.mv_size);
|
||||||
|
@ -311,20 +336,20 @@ LMDBUnlock(Db *d, DbRef *r)
|
||||||
StreamFlush(stream);
|
StreamFlush(stream);
|
||||||
StreamClose(stream);
|
StreamClose(stream);
|
||||||
|
|
||||||
ret = mdb_put(ref->transaction, db->dbi, &key, &val, 0) == 0;
|
ret = mdb_put(ref->transaction, ref->dbi, &key, &val, 0) == 0;
|
||||||
|
|
||||||
mdb_txn_commit(ref->transaction);
|
mdb_txn_commit(ref->transaction);
|
||||||
LMDBKillKey(key);
|
mdb_dbi_close(db->environ, ref->dbi);
|
||||||
}
|
|
||||||
StringArrayFree(ref->base.name);
|
StringArrayFree(ref->base.name);
|
||||||
JsonFree(ref->base.json);
|
JsonFree(ref->base.json);
|
||||||
Free(ref);
|
Free(ref);
|
||||||
|
|
||||||
|
LMDBKillKey(key);
|
||||||
if (val.mv_data)
|
if (val.mv_data)
|
||||||
{
|
{
|
||||||
free(val.mv_data);
|
free(val.mv_data);
|
||||||
}
|
}
|
||||||
if (ret && r->hint == DB_HINT_WRITE)
|
if (ret)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&d->lock);
|
pthread_mutex_unlock(&d->lock);
|
||||||
}
|
}
|
||||||
|
@ -337,6 +362,7 @@ LMDBCreate(Db *d, Array *k)
|
||||||
MDB_txn *transaction;
|
MDB_txn *transaction;
|
||||||
LMDBRef *ret = NULL;
|
LMDBRef *ret = NULL;
|
||||||
MDB_val key, empty_json;
|
MDB_val key, empty_json;
|
||||||
|
MDB_dbi dbi;
|
||||||
int code;
|
int code;
|
||||||
if (!d || !k)
|
if (!d || !k)
|
||||||
{
|
{
|
||||||
|
@ -356,25 +382,38 @@ LMDBCreate(Db *d, Array *k)
|
||||||
);
|
);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
/* apparently you need to give it a dbi */
|
||||||
|
if ((code = mdb_dbi_open(transaction, "db", MDB_CREATE, &dbi)) != 0)
|
||||||
|
{
|
||||||
|
Log(LOG_ERR,
|
||||||
|
"%s: could not get transaction dbi: %s",
|
||||||
|
__func__, mdb_strerror(code)
|
||||||
|
);
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
empty_json.mv_size = 2;
|
empty_json.mv_size = 2;
|
||||||
empty_json.mv_data = "{}";
|
empty_json.mv_data = "{}";
|
||||||
/* put data in it */
|
/* put data in it */
|
||||||
code = mdb_put(transaction, db->dbi, &key, &empty_json, MDB_NOOVERWRITE);
|
code = mdb_put(transaction, dbi, &key, &empty_json, MDB_NOOVERWRITE);
|
||||||
if (code == MDB_KEYEXIST)
|
if (code == MDB_KEYEXIST)
|
||||||
{
|
{
|
||||||
|
mdb_dbi_close(db->environ, dbi);
|
||||||
mdb_txn_abort(transaction);
|
mdb_txn_abort(transaction);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
else if (code == MDB_MAP_FULL)
|
else if (code == MDB_MAP_FULL)
|
||||||
{
|
{
|
||||||
Log(LOG_ERR, "%s: db is full", __func__);
|
Log(LOG_ERR, "%s: db is full", __func__);
|
||||||
|
mdb_dbi_close(db->environ, dbi);
|
||||||
mdb_txn_abort(transaction);
|
mdb_txn_abort(transaction);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
else if (code != 0)
|
else if (code != 0)
|
||||||
{
|
{
|
||||||
Log(LOG_ERR, "%s: mdb_put failure: %s", __func__, mdb_strerror(code));
|
Log(LOG_ERR, "%s: mdb_put failure: %s", __func__, mdb_strerror(code));
|
||||||
|
mdb_dbi_close(db->environ, dbi);
|
||||||
mdb_txn_abort(transaction);
|
mdb_txn_abort(transaction);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -391,9 +430,9 @@ LMDBCreate(Db *d, Array *k)
|
||||||
StringArrayAppend(ret->base.name, ent);
|
StringArrayAppend(ret->base.name, ent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret->base.hint = DB_HINT_WRITE;
|
|
||||||
ret->base.json = HashMapCreate();
|
ret->base.json = HashMapCreate();
|
||||||
ret->transaction = transaction;
|
ret->transaction = transaction;
|
||||||
|
ret->dbi = dbi;
|
||||||
end:
|
end:
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
|
@ -415,6 +454,7 @@ LMDBList(Db *d, Array *k)
|
||||||
MDB_cursor *cursor;
|
MDB_cursor *cursor;
|
||||||
MDB_cursor_op op = MDB_SET_RANGE;
|
MDB_cursor_op op = MDB_SET_RANGE;
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
|
MDB_dbi dbi;
|
||||||
int code;
|
int code;
|
||||||
|
|
||||||
if (!d || !k)
|
if (!d || !k)
|
||||||
|
@ -435,13 +475,24 @@ LMDBList(Db *d, Array *k)
|
||||||
);
|
);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if ((code = mdb_cursor_open(txn, db->dbi, &cursor)) != 0)
|
/* apparently you need to give it a dbi */
|
||||||
|
if ((code = mdb_dbi_open(txn, "db", MDB_CREATE, &dbi)) != 0)
|
||||||
|
{
|
||||||
|
Log(LOG_ERR,
|
||||||
|
"%s: could not get transaction dbi: %s",
|
||||||
|
__func__, mdb_strerror(code)
|
||||||
|
);
|
||||||
|
mdb_txn_abort(txn);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if ((code = mdb_cursor_open(txn, dbi, &cursor)) != 0)
|
||||||
{
|
{
|
||||||
Log(LOG_ERR,
|
Log(LOG_ERR,
|
||||||
"%s: could not get cursor: %s",
|
"%s: could not get cursor: %s",
|
||||||
__func__, mdb_strerror(code)
|
__func__, mdb_strerror(code)
|
||||||
);
|
);
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
|
mdb_dbi_close(db->environ, dbi);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,6 +520,7 @@ LMDBList(Db *d, Array *k)
|
||||||
|
|
||||||
mdb_cursor_close(cursor);
|
mdb_cursor_close(cursor);
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
|
mdb_dbi_close(db->environ, dbi);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
LMDBKillKey(key);
|
LMDBKillKey(key);
|
||||||
|
@ -486,7 +538,6 @@ LMDBClose(Db *d)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mdb_dbi_close(db->environ, db->dbi);
|
|
||||||
mdb_env_close(db->environ);
|
mdb_env_close(db->environ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,8 +546,6 @@ DbOpenLMDB(char *dir, size_t size)
|
||||||
{
|
{
|
||||||
/* TODO */
|
/* TODO */
|
||||||
MDB_env *env = NULL;
|
MDB_env *env = NULL;
|
||||||
MDB_txn *txn;
|
|
||||||
MDB_dbi dbi;
|
|
||||||
int code;
|
int code;
|
||||||
LMDB *db;
|
LMDB *db;
|
||||||
if (!dir || !size)
|
if (!dir || !size)
|
||||||
|
@ -534,35 +583,10 @@ DbOpenLMDB(char *dir, size_t size)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialise a DBI */
|
|
||||||
{
|
|
||||||
if ((code = mdb_txn_begin(env, NULL, 0, &txn)) != 0)
|
|
||||||
{
|
|
||||||
Log(LOG_ERR,
|
|
||||||
"%s: could not begin transaction: %s",
|
|
||||||
__func__, mdb_strerror(code)
|
|
||||||
);
|
|
||||||
mdb_env_close(env);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if ((code = mdb_dbi_open(txn, "db", MDB_CREATE, &dbi)) != 0)
|
|
||||||
{
|
|
||||||
Log(LOG_ERR,
|
|
||||||
"%s: could not get transaction dbi: %s",
|
|
||||||
__func__, mdb_strerror(code)
|
|
||||||
);
|
|
||||||
mdb_txn_abort(txn);
|
|
||||||
mdb_env_close(env);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
mdb_txn_commit(txn);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
db = Malloc(sizeof(*db));
|
db = Malloc(sizeof(*db));
|
||||||
DbInit((Db *) db);
|
DbInit((Db *) db);
|
||||||
db->environ = env;
|
db->environ = env;
|
||||||
db->dbi = dbi;
|
|
||||||
|
|
||||||
db->base.lockFunc = LMDBLock;
|
db->base.lockFunc = LMDBLock;
|
||||||
db->base.create = LMDBCreate;
|
db->base.create = LMDBCreate;
|
||||||
|
|
Loading…
Reference in a new issue