1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 2016 - 2017*/
6 /* See the file NOTICE for conditions of use and distribution. */
10 #ifdef EXPERIMENTAL_LMDB
14 typedef struct lmdbstrct
21 /*************************************************
23 *************************************************/
26 lmdb_open(uschar
* filename
, uschar
** errmsg
)
28 MDB_env
* db_env
= NULL
;
31 const uschar
* errstr
;
33 lmdb_p
= store_get(sizeof(Lmdbstrct
));
36 if ((ret
= mdb_env_create(&db_env
)))
38 errstr
= US
"create environment";
42 if ((ret
= mdb_env_open(db_env
, CS filename
, MDB_NOSUBDIR
|MDB_RDONLY
, 0660)))
44 errstr
= string_sprintf("open environment with %s", filename
);
48 if ((ret
= mdb_txn_begin(db_env
, NULL
, MDB_RDONLY
, &lmdb_p
->txn
)))
50 errstr
= US
"start transaction";
54 if ((ret
= mdb_open(lmdb_p
->txn
, NULL
, 0, &lmdb_p
->db_dbi
)))
56 errstr
= US
"open database";
64 if (lmdb_p
->txn
) mdb_txn_abort(lmdb_p
->txn
);
65 if (db_env
) mdb_env_close(db_env
);
66 *errmsg
= string_sprintf("LMDB: Unable to %s: %s", errstr
, mdb_strerror(ret
));
72 /*************************************************
74 *************************************************/
77 lmdb_find(void * handle
, uschar
* filename
,
78 const uschar
* keystring
, int length
, uschar
** result
, uschar
** errmsg
,
83 Lmdbstrct
* lmdb_p
= handle
;
85 dbkey
.mv_data
= CS keystring
;
86 dbkey
.mv_size
= length
;
88 DEBUG(D_lookup
) debug_printf("LMDB: lookup key: %s\n", CS keystring
);
90 if ((ret
= mdb_get(lmdb_p
->txn
, lmdb_p
->db_dbi
, &dbkey
, &data
)) == 0)
92 *result
= string_copyn(US data
.mv_data
, data
.mv_size
);
93 DEBUG(D_lookup
) debug_printf("LMDB: lookup result: %s\n", *result
);
96 else if (ret
== MDB_NOTFOUND
)
98 *errmsg
= US
"LMDB: lookup, no data found";
99 DEBUG(D_lookup
) debug_printf("%s\n", *errmsg
);
104 *errmsg
= string_sprintf("LMDB: lookup error: %s", mdb_strerror(ret
));
105 DEBUG(D_lookup
) debug_printf("%s\n", *errmsg
);
111 /*************************************************
112 * Close entry point *
113 *************************************************/
116 lmdb_close(void * handle
)
118 Lmdbstrct
* lmdb_p
= handle
;
119 MDB_env
* db_env
= mdb_txn_env(lmdb_p
->txn
);
120 mdb_txn_abort(lmdb_p
->txn
);
121 mdb_env_close(db_env
);
125 /*************************************************
126 * Version reporting entry point *
127 *************************************************/
129 #include "../version.h"
132 lmdb_version_report(FILE * f
)
134 fprintf(f
, "Library version: LMDB: Compile: %d.%d.%d\n",
135 MDB_VERSION_MAJOR
, MDB_VERSION_MINOR
, MDB_VERSION_PATCH
);
137 fprintf(f
, " Exim version %s\n", EXIM_VERSION_STR
);
141 static lookup_info lmdb_lookup_info
= {
142 US
"lmdb", /* lookup name */
143 lookup_absfile
, /* query-style lookup */
144 lmdb_open
, /* open function */
145 NULL
, /* no check function */
146 lmdb_find
, /* find function */
147 lmdb_close
, /* close function */
148 NULL
, /* tidy function */
149 NULL
, /* quoting function */
150 lmdb_version_report
/* version reporting */
154 # define lmdb_lookup_module_info _lookup_module_info
155 #endif /* DYNLOOKUP */
157 static lookup_info
*_lookup_list
[] = { &lmdb_lookup_info
};
158 lookup_module_info lmdb_lookup_module_info
= { LOOKUP_MODULE_INFO_MAGIC
, _lookup_list
, 1 };
160 #endif /* EXPERIMENTAL_LMDB */