Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Dlang
lmdb-d
Commits
0388dd72
Commit
0388dd72
authored
Nov 09, 2018
by
Carsten Schlote
Browse files
Cleanups
parent
a64060cd
Changes
2
Hide whitespace changes
Inline
Side-by-side
docs/lmdb-d-demo/source/main.d
View file @
0388dd72
...
...
@@ -5,30 +5,43 @@ import core.stdc.string;
import
std
.
bitmanip
;
import
std
.
conv
;
import
std
.
format
;
import
std
.
random
;
import
std
.
stdio
;
import
std
.
string
;
//import lmdb_d;
/** Minimalistic demo code for lmdb
* @param args Commandline args as a dynamic array of strings
*/
void
main
(
const
string
[]
args
)
{
writefln
(
"lmdb binding demo, compiled on %s"
,
__DATE__
);
/* Extract the lmdb version */
int
major
,
minor
,
patch
;
char
*
vstr_c
=
mdb_version
(&
major
,
&
minor
,
&
patch
);
const
string
vstr
=
to
!
string
(
vstr_c
);
writefln
(
"The installed lmdb version is %s"
,
vstr
);
/* Run some demo code on the liblmdb C API bindings */
lmdb_toy1
(
args
);
/* Run some demo code using some more OO binding code (WIP) */
try
{
lmdb_toy2
(
args
);
lmdb_toy3
(
args
);
}
catch
(
Exception
ex
)
{
writeln
(
"Catched exeception :"
,
ex
.
msg
);
writeln
(
"
Something wonderful has happened.\n
Catched exeception :"
,
ex
.
msg
);
}
}
/** Display the lmdb error string in case of error
* @param rc Resultcode to check
* @param msg Message to display in case of error
* @param line Line number or __LINE__ if not given
* @return bool, true if ok, false in case of error
*/
bool
check_rc
(
int
rc
,
string
msg
,
int
line
=
__LINE__
)
{
if
(
rc
!=
0
)
...
...
@@ -39,10 +52,11 @@ bool check_rc(int rc, string msg, int line = __LINE__)
return
true
;
}
/* Import the complete module into scope */
import
lmdb
;
/** Simple test for the low-level C library calls
*
*
@param args Commandline args as a dynamic array of strings
*/
void
lmdb_toy1
(
const
string
[]
args
)
{
...
...
@@ -61,21 +75,21 @@ void lmdb_toy1(const string[] args)
/* Note: Most error checking omitted for simplicity */
rc
=
mdb_env_create
(&
env
);
if
(!
check_rc
(
rc
,
"Can't create MDB env"
))
goto
leave2
;
rc
=
mdb_env_open
(
env
,
".
/testdb
"
,
0
,
std
.
conv
.
octal
!
664
);
if
(!
check_rc
(
rc
,
"Can't open MDB file"
))
goto
leave2
;
if
(!
check_rc
(
rc
,
"Can't create MDB env"
))
goto
free_mdb_env
;
rc
=
mdb_env_open
(
env
,
"."
,
0
,
std
.
conv
.
octal
!
664
);
if
(!
check_rc
(
rc
,
"Can't open MDB file"
))
goto
free_mdb_env
;
rc
=
mdb_txn_begin
(
env
,
null
,
0
,
&
txn
);
if
(!
check_rc
(
rc
,
"Can't start the MDB transaction"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't start the MDB transaction"
))
goto
close_mdb_databases
;
rc
=
mdb_dbi_open
(
txn
,
null
,
0
,
&
dbi
);
if
(!
check_rc
(
rc
,
"Can't open MDB index"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't open MDB index"
))
goto
close_mdb_databases
;
rc
=
mdb_drop
(
txn
,
dbi
,
0
);
if
(!
check_rc
(
rc
,
"Can't drop MDB table"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't drop MDB table"
))
goto
close_mdb_databases
;
rc
=
mdb_dbi_flags
(
txn
,
dbi
,
&
dbi_flags
);
if
(!
check_rc
(
rc
,
"Can't read MDB flags"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't read MDB flags"
))
goto
close_mdb_databases
;
foreach
(
i
;
0
..
5
)
{
...
...
@@ -94,15 +108,15 @@ void lmdb_toy1(const string[] args)
key
.
mv_data
[
0
..
key
.
mv_size
],
data
.
mv_data
,
data
.
mv_data
[
0
..
data
.
mv_size
]);
rc
=
mdb_put
(
txn
,
dbi
,
&
key
,
&
data
,
0
);
if
(!
check_rc
(
rc
,
"Can't put MDB data"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't put MDB data"
))
goto
close_mdb_databases
;
}
rc
=
mdb_txn_commit
(
txn
);
if
(!
check_rc
(
rc
,
"Can't commit MDB transaction"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't commit MDB transaction"
))
goto
close_mdb_databases
;
rc
=
mdb_txn_begin
(
env
,
null
,
MDB_RDONLY
,
&
txn
);
if
(!
check_rc
(
rc
,
"Can't start the MDB transaction"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't start the MDB transaction"
))
goto
close_mdb_databases
;
rc
=
mdb_cursor_open
(
txn
,
dbi
,
&
cursor
);
if
(!
check_rc
(
rc
,
"Can't open MDB index"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't open MDB index"
))
goto
close_mdb_databases
;
while
((
rc
=
mdb_cursor_get
(
cursor
,
&
key
,
&
data
,
MDB_cursor_op
.
MDB_NEXT
))
==
0
)
{
ubyte
[
4
]
tmp
=
key
.
data
!
ubyte
()[
0..4
];
...
...
@@ -111,20 +125,20 @@ void lmdb_toy1(const string[] args)
if
(
verbose
)
writefln
(
"GET: key: %x %s, data: %x %s"
,
key
.
mv_data
,
key
.
mv_data
[
0
..
key
.
mv_size
],
data
.
mv_data
,
data
.
mv_data
[
0
..
data
.
mv_size
]);
mdb_cursor_close
(
cursor
);
}
mdb_cursor_close
(
cursor
);
mdb_txn_abort
(
txn
);
rc
=
mdb_txn_begin
(
env
,
null
,
0
,
&
txn
);
if
(!
check_rc
(
rc
,
"Can't start the MDB transaction"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't start the MDB transaction"
))
goto
close_mdb_databases
;
rc
=
mdb_cursor_open
(
txn
,
dbi
,
&
cursor
);
if
(!
check_rc
(
rc
,
"Can't open MDB index"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't open MDB index"
))
goto
close_mdb_databases
;
foreach
(
i
;
items
)
{
auto
kval
=
nativeToBigEndian
(
i
);
key
.
assign
!(
ubyte
[
4
])(&
kval
,
kval
.
length
);
writefln
(
"DEL: key: %x %s"
,
key
.
mv_data
,
kval
);
rc
=
mdb_del
(
txn
,
dbi
,
&
key
,
null
);
if
(!
check_rc
(
rc
,
"Can't open MDB index"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't open MDB index"
))
goto
close_mdb_databases
;
}
// while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_cursor_op.MDB_FIRST)) == 0)
// {
...
...
@@ -133,16 +147,16 @@ void lmdb_toy1(const string[] args)
// key.mv_data[0 .. key.mv_size], data.mv_data, data.mv_data[0 .. data.mv_size]);
// // rc = mdb_cursor_del(cursor, 0);
// rc = mdb_del(txn, dbi, &key, null);
// if (!check_rc(rc, "Can't delete MDB index")) goto
leave
;
// if (!check_rc(rc, "Can't delete MDB index")) goto
close_mdb_databases
;
// }
mdb_cursor_close
(
cursor
);
if
(!
check_rc
(
rc
,
"Can't del MDB item"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't del MDB item"
))
goto
close_mdb_databases
;
mdb_txn_commit
(
txn
);
rc
=
mdb_txn_begin
(
env
,
null
,
MDB_RDONLY
,
&
txn
);
if
(!
check_rc
(
rc
,
"Can't start the MDB transaction"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't start the MDB transaction"
))
goto
close_mdb_databases
;
rc
=
mdb_cursor_open
(
txn
,
dbi
,
&
cursor
);
if
(!
check_rc
(
rc
,
"Can't open MDB index"
))
goto
leave
;
if
(!
check_rc
(
rc
,
"Can't open MDB index"
))
goto
close_mdb_databases
;
while
((
rc
=
mdb_cursor_get
(
cursor
,
&
key
,
&
data
,
MDB_cursor_op
.
MDB_NEXT
))
==
0
)
{
ubyte
[
4
]
tmp
=
key
.
data
!
ubyte
()[
0..4
];
...
...
@@ -155,10 +169,9 @@ void lmdb_toy1(const string[] args)
}
mdb_txn_abort
(
txn
);
leave
:
close_mdb_databases
:
mdb_dbi_close
(
env
,
dbi
);
leave2
:
free_mdb_env
:
mdb_env_close
(
env
);
}
...
...
@@ -176,7 +189,7 @@ void lmdb_toy2(const string[] args)
/* Note: Most error checking omitted for simplicity */
auto
env
=
MdbEnv
.
create
();
env
.
open
(
".
/testdb
"
,
0
,
std
.
conv
.
octal
!
664
);
env
.
open
(
"."
,
0
,
std
.
conv
.
octal
!
664
);
auto
txn
=
MdbTxn
.
begin
(
env
.
handle
());
auto
dbi
=
MdbDbi
.
open
(
txn
.
handle
());
...
...
@@ -200,7 +213,7 @@ void lmdb_toy2(const string[] args)
MdbCursor
cursor
;
writeln
(
"List of data items in DB. Remember items for deletion"
);
lmdb_
toy2_
iterate_readonly
(
env
,
txn
,
dbi
,
cursor
,
(
MdbVal
x
)
{
items
~=
new
MdbVal
(
x
);
return
true
;
},
verbose
);
lmdb_iterate_readonly
_job
(
env
,
txn
,
dbi
,
cursor
,
(
MdbVal
x
)
{
items
~=
new
MdbVal
(
x
);
return
true
;
},
verbose
);
writefln
(
"Delete %d remembered items"
,
items
.
length
);
txn
=
MdbTxn
.
begin
(
env
.
handle
(),
null
,
0
);
...
...
@@ -215,67 +228,14 @@ void lmdb_toy2(const string[] args)
txn
.
commit
();
writeln
(
"List of all remaining data items in DB."
);
lmdb_
toy2_
iterate_readonly
(
env
,
txn
,
dbi
,
cursor
,
null
,
verbose
);
lmdb_iterate_readonly
_job
(
env
,
txn
,
dbi
,
cursor
,
null
,
verbose
);
dbi
.
close
(
env
);
env
.
close
();
}
/** Iterate through all nodes in RW mode, execute a delegate for each node.
* @param env Reference to MdbEnv class
* @param tcn Reference to MdbTxn class
* @param cursor Reference to MdbCursor class
* @param fkt Delegate with reference to an MdbVal object. Returns bool=false to bereak loop.
*/
void
lmdb_toy2_iterate_readwrite
(
MdbEnv
env
,
MdbTxn
txn
,
MdbDbi
dbi
,
MdbCursor
cursor
,
bool
delegate
(
MdbVal
)
fkt
,
string
opname
=
"PUT"
,
bool
verbose
=
true
)
{
int
itemcount
;
bool
fkt_rc
;
MdbVal
key
=
new
MdbVal
(),
data
=
new
MdbVal
();
txn
=
MdbTxn
.
begin
(
env
.
handle
(),
null
,
0
);
cursor
=
MdbCursor
.
open
(
txn
.
handle
(),
dbi
.
handle
());
while
(
cursor
.
get
(
key
,
data
,
MDB_cursor_op
.
MDB_NEXT
))
{
itemcount
++;
if
(
verbose
)
writefln
(
"%s: key: %s, data: %s"
,
opname
,
key
,
data
);
if
(
fkt
!
is
null
)
fkt_rc
=
fkt
(
key
);
if
(!
fkt_rc
)
break
;
}
if
(!
itemcount
)
writeln
(
"DEL: Database seems to be empty."
);
txn
.
abort
();
}
/** Iterate through all nodes in RO mode, execute a delegate for each node.
* @param env Reference to MdbEnv class
* @param tcn Reference to MdbTxn class
* @param cursor Reference to MdbCursor class
* @param fkt Delegate with reference to an MdbVal object. Returns bool=false to bereak loop.
*/
void
lmdb_toy2_iterate_readonly
(
MdbEnv
env
,
MdbTxn
txn
,
MdbDbi
dbi
,
MdbCursor
cursor
,
bool
delegate
(
MdbVal
)
fkt
,
bool
verbose
=
true
)
{
int
itemcount
;
bool
fkt_rc
;
MdbVal
key
=
new
MdbVal
(),
data
=
new
MdbVal
();
txn
=
MdbTxn
.
begin
(
env
.
handle
(),
null
,
MDB_RDONLY
);
cursor
=
MdbCursor
.
open
(
txn
.
handle
(),
dbi
.
handle
());
while
(
cursor
.
get
(
key
,
data
,
MDB_cursor_op
.
MDB_NEXT
))
{
itemcount
++;
if
(
verbose
)
writefln
(
"GET: key: %s, data: %s"
,
key
,
data
);
if
(
fkt
!
is
null
)
fkt_rc
=
fkt
(
key
);
if
(!
fkt_rc
)
break
;
}
if
(!
itemcount
)
writeln
(
"GET: Database seems to be empty."
);
txn
.
abort
();
}
/* ------------------------------------------------------------------------- */
import
std
.
bitmanip
;
import
std
.
format
;
struct
myDataTable
{
uint
field0
;
...
...
@@ -294,7 +254,7 @@ void lmdb_toy3(const string[] args)
/* Note: Most error checking omitted for simplicity */
auto
env
=
MdbEnv
.
create
();
env
.
open
(
".
/testdb
"
,
0
,
std
.
conv
.
octal
!
664
);
env
.
open
(
"."
,
0
,
std
.
conv
.
octal
!
664
);
auto
txn
=
MdbTxn
.
begin
(
env
.
handle
());
auto
dbi
=
MdbDbi
.
open
(
txn
.
handle
(),
null
,
MDB_INTEGERKEY
);
...
...
@@ -319,7 +279,7 @@ void lmdb_toy3(const string[] args)
MdbCursor
cursor
;
writeln
(
"List of data items in DB. Remember items for deletion"
);
lmdb_
toy2_
iterate_readonly
(
env
,
txn
,
dbi
,
cursor
,
(
MdbVal
x
)
{
items
~=
new
MdbVal
(
x
);
return
true
;
},
verbose
);
lmdb_iterate_readonly
_job
(
env
,
txn
,
dbi
,
cursor
,
(
MdbVal
x
)
{
items
~=
new
MdbVal
(
x
);
return
true
;
},
verbose
);
writefln
(
"Delete %d remembered items"
,
items
.
length
);
txn
=
MdbTxn
.
begin
(
env
.
handle
(),
null
,
0
);
...
...
@@ -334,8 +294,61 @@ void lmdb_toy3(const string[] args)
txn
.
commit
();
writeln
(
"List of all remaining data items in DB."
);
lmdb_
toy2_
iterate_readonly
(
env
,
txn
,
dbi
,
cursor
,
null
,
verbose
);
lmdb_iterate_readonly
_job
(
env
,
txn
,
dbi
,
cursor
,
null
,
verbose
);
dbi
.
close
(
env
);
env
.
close
();
}
\ No newline at end of file
}
/* ------------------------------------------------------------------------- */
/** Iterate through all nodes in RW mode, execute a delegate for each node.
* @param env Reference to MdbEnv class
* @param tcn Reference to MdbTxn class
* @param cursor Reference to MdbCursor class
* @param fkt Delegate with reference to an MdbVal object. Returns bool=false to bereak loop.
*/
void
lmdb_toy2_iterate_readwrite
(
MdbEnv
env
,
MdbTxn
txn
,
MdbDbi
dbi
,
MdbCursor
cursor
,
bool
delegate
(
MdbVal
)
fkt
,
string
opname
=
"PUT"
,
bool
verbose
=
true
)
{
int
itemcount
;
bool
fkt_rc
;
MdbVal
key
=
new
MdbVal
(),
data
=
new
MdbVal
();
txn
=
MdbTxn
.
begin
(
env
.
handle
(),
null
,
0
);
cursor
=
MdbCursor
.
open
(
txn
.
handle
(),
dbi
.
handle
());
while
(
cursor
.
get
(
key
,
data
,
MDB_cursor_op
.
MDB_NEXT
))
{
itemcount
++;
if
(
verbose
)
writefln
(
"%s: key: %s, data: %s"
,
opname
,
key
,
data
);
if
(
fkt
!
is
null
)
fkt_rc
=
fkt
(
key
);
if
(!
fkt_rc
)
break
;
}
if
(!
itemcount
)
writeln
(
"DEL: Database seems to be empty."
);
txn
.
abort
();
}
/** Iterate through all nodes in RO mode, execute a delegate for each node.
* @param env Reference to MdbEnv class
* @param tcn Reference to MdbTxn class
* @param cursor Reference to MdbCursor class
* @param fkt Delegate with reference to an MdbVal object. Returns bool=false to bereak loop.
*/
void
lmdb_iterate_readonly_job
(
MdbEnv
env
,
MdbTxn
txn
,
MdbDbi
dbi
,
MdbCursor
cursor
,
bool
delegate
(
MdbVal
)
fkt
,
bool
verbose
=
true
)
{
int
itemcount
;
bool
fkt_rc
;
MdbVal
key
=
new
MdbVal
(),
data
=
new
MdbVal
();
txn
=
MdbTxn
.
begin
(
env
.
handle
(),
null
,
MDB_RDONLY
);
cursor
=
MdbCursor
.
open
(
txn
.
handle
(),
dbi
.
handle
());
while
(
cursor
.
get
(
key
,
data
,
MDB_cursor_op
.
MDB_NEXT
))
{
itemcount
++;
if
(
verbose
)
writefln
(
"GET: key: %s, data: %s"
,
key
,
data
);
if
(
fkt
!
is
null
)
fkt_rc
=
fkt
(
key
);
if
(!
fkt_rc
)
break
;
}
if
(!
itemcount
)
writeln
(
"GET: Database seems to be empty."
);
txn
.
abort
();
}
source/lmdb.d
View file @
0388dd72
import
core
.
sys
.
posix
.
sys
.
types
;
/** @file lmdb.h
import
core
.
sys
.
posix
.
sys
.
types
;
/** @file lmdb.d
* @brief Lightning memory-mapped database library
*
* @mainpage Lightning Memory-Mapped Database Manager (LMDB)
...
...
@@ -171,7 +170,6 @@ import core.sys.posix.sys.types;
* * A smal OO D class completes the low level structures.
*/
extern
(
C
):
/** Unix permissions for creating files, or dummy definition for Windows */
...
...
@@ -1655,4 +1653,3 @@ int mdb_reader_list(MDB_env* env, MDB_msg_func* func, void* ctx);
*/
int
mdb_reader_check
(
MDB_env
*
env
,
int
*
dead
);
/** @} */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment