11#include <errno.h>
2+ #include <string.h>
23
34#include "erl_nif.h"
45#include <erl_driver.h>
910
1011#define CHECK (expr , label ) \
1112 if (MDB_SUCCESS != (ret = (expr))) { \
12- ERR_LOG("CHECK(\"%s\") failed \"%s\" at %s:%d in %s()\n", \
13- #expr, mdb_strerror(ret), __FILE__, __LINE__, __func__);\
13+ ERR_LOG("CHECK(\"%s\") failed \"%s(%d) \" at %s:%d in %s()\n", \
14+ #expr, mdb_strerror(ret),ret, __FILE__, __LINE__, __func__);\
1415 err = __strerror_term(env,ret); \
1516 goto label; \
1617 }
@@ -38,7 +39,7 @@ typedef struct lmdb_dbi_s {
3839} lmdb_dbi_t ;
3940
4041static void lmdb_dtor (ErlNifEnv * __attribute__((unused )) env , void * obj ) {
41- INFO_LOG ("destroy...... obj -> %p" , obj );
42+ INFO_LOG ("destroy...... lmdb.env -> %p" , obj );
4243 lmdb_env_t * lmdb = (lmdb_env_t * )obj ;
4344 if (lmdb ) {
4445 if (lmdb -> env ) {
@@ -49,6 +50,7 @@ static void lmdb_dtor(ErlNifEnv* __attribute__((unused)) env, void* obj) {
4950}
5051
5152static void lmdb_dbi_dtor (ErlNifEnv * env , void * obj ) {
53+ INFO_LOG ("destroy...... lmdb.dbi -> %p" , obj );
5254 __UNUSED (env );
5355 lmdb_dbi_t * f = (lmdb_dbi_t * )obj ;
5456 if (f ) {
@@ -180,6 +182,7 @@ static ERL_NIF_TERM elmdb_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
180182 .lmdb_env = handle ,
181183 .dbi = dbi
182184 };
185+ strncpy (family -> name , dbname , strlen (dbname ) + 1 );
183186 ERL_NIF_TERM res = enif_make_resource (env , family );
184187 enif_release_resource (family );
185188 enif_keep_resource (handle );
@@ -192,8 +195,74 @@ static ERL_NIF_TERM elmdb_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
192195 return err ;
193196}
194197
195- static ERL_NIF_TERM hello (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [])
196- {
198+ static ERL_NIF_TERM elmdb_put (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv []) {
199+ lmdb_dbi_t * dbihandle = NULL ;
200+ if (!enif_get_resource (env , argv [0 ], lmdbDbiResType , (void * * )& dbihandle )) {
201+ return enif_make_badarg (env );
202+ }
203+ ErlNifBinary keyTerm ;
204+ ErlNifBinary valTerm ;
205+ if (!enif_inspect_binary (env , argv [1 ], & keyTerm ) ||
206+ !enif_inspect_binary (env , argv [2 ], & valTerm )) {
207+ return enif_make_badarg (env );
208+ }
209+
210+ int ret ;
211+ ERL_NIF_TERM err ;
212+
213+ MDB_txn * txn = NULL ;
214+ CHECK (mdb_txn_begin (dbihandle -> lmdb_env -> env , NULL , 0 , & txn ), err1 );
215+
216+ MDB_val key , val ;
217+ key .mv_size = keyTerm .size ;
218+ key .mv_data = keyTerm .data ;
219+ val .mv_size = valTerm .size ;
220+ val .mv_data = valTerm .data ;
221+
222+ mdb_put (txn , dbihandle -> dbi , & key , & val , MDB_NOOVERWRITE );
223+ CHECK (mdb_txn_commit (txn ), err2 );
224+ return argv [0 ];
225+
226+ err1 :
227+ mdb_txn_abort (txn );
228+ err2 :
229+ return err ;
230+ }
231+
232+ static ERL_NIF_TERM elmdb_get (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv []) {
233+ lmdb_dbi_t * dbihandle = NULL ;
234+ if (!enif_get_resource (env , argv [0 ], lmdbDbiResType , (void * * )& dbihandle )) {
235+ return enif_make_badarg (env );
236+ }
237+
238+ ErlNifBinary keyTerm ;
239+ if (!enif_inspect_binary (env , argv [1 ], & keyTerm )) {
240+ return enif_make_badarg (env );
241+ }
242+
243+ int ret ;
244+ ERL_NIF_TERM err ;
245+
246+ MDB_txn * txn = NULL ;
247+ CHECK (mdb_txn_begin (dbihandle -> lmdb_env -> env , NULL , MDB_RDONLY , & txn ), err1 );
248+
249+ MDB_val key , val ;
250+ key .mv_size = keyTerm .size ;
251+ key .mv_data = keyTerm .data ;
252+ CHECK ( mdb_get (txn , dbihandle -> dbi , & key , & val ), err1 );
253+ mdb_txn_abort (txn );
254+
255+ ERL_NIF_TERM res ;
256+ unsigned char * bin = enif_make_new_binary (env , val .mv_size , & res );
257+ memcpy (bin , val .mv_data , val .mv_size );
258+ return res ;
259+
260+ err1 :
261+ mdb_txn_abort (txn );
262+ return err ;
263+ }
264+
265+ static ERL_NIF_TERM hello (ErlNifEnv * env , int argc , const ERL_NIF_TERM argv []) {
197266 if (enif_is_atom (env , argv [0 ])) {
198267 return enif_make_tuple2 (env ,
199268 enif_make_atom (env , "hello" ),
@@ -208,6 +277,8 @@ static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
208277static ErlNifFunc nif_funcs [] = {
209278 {"init" , 1 , elmdb_init },
210279 {"open" , 2 , elmdb_open },
280+ {"put" , 3 , elmdb_put },
281+ {"get" , 2 , elmdb_get },
211282 {"hello" , 1 , hello }
212283};
213284
0 commit comments