1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 2016 - 2018 */
6 /* Copyright (c) The Exim Maintainers 2020 */
7 /* See the file NOTICE for conditions of use and distribution. */
11 #ifdef EXPERIMENTAL_LMDB
15 typedef struct lmdbstrct
22 /*************************************************
24 *************************************************/
27 lmdb_open(const uschar
* filename
, uschar
** errmsg
)
29 MDB_env
* db_env
= NULL
;
32 const uschar
* errstr
;
34 lmdb_p
= store_get(sizeof(Lmdbstrct
), FALSE
);
37 if ((ret
= mdb_env_create(&db_env
)))
39 errstr
= US
"create environment";
43 if ((ret
= mdb_env_open(db_env
, CS filename
, MDB_NOSUBDIR
|MDB_RDONLY
, 0660)))
45 errstr
= string_sprintf("open environment with %s", filename
);
49 if ((ret
= mdb_txn_begin(db_env
, NULL
, MDB_RDONLY
, &lmdb_p
->txn
)))
51 errstr
= US
"start transaction";
55 if ((ret
= mdb_open(lmdb_p
->txn
, NULL
, 0, &lmdb_p
->db_dbi
)))
57 errstr
= US
"open database";
65 if (lmdb_p
->txn
) mdb_txn_abort(lmdb_p
->txn
);
66 if (db_env
) mdb_env_close(db_env
);
67 *errmsg
= string_sprintf("LMDB: Unable to %s: %s", errstr
, mdb_strerror(ret
));
73 /*************************************************
75 *************************************************/
78 lmdb_find(void * handle
, const uschar
* filename
,
79 const uschar
* keystring
, int length
, uschar
** result
, uschar
** errmsg
,
80 uint
* do_cache
, const uschar
* opts
)
84 Lmdbstrct
* lmdb_p
= handle
;
86 dbkey
.mv_data
= CS keystring
;
87 dbkey
.mv_size
= length
;
89 DEBUG(D_lookup
) debug_printf_indent("LMDB: lookup key: %s\n", CS keystring
);
91 if ((ret
= mdb_get(lmdb_p
->txn
, lmdb_p
->db_dbi
, &dbkey
, &data
)) == 0)
93 *result
= string_copyn(US data
.mv_data
, data
.mv_size
);
94 DEBUG(D_lookup
) debug_printf_indent("LMDB: lookup result: %s\n", *result
);
97 else if (ret
== MDB_NOTFOUND
)
99 *errmsg
= US
"LMDB: lookup, no data found";
100 DEBUG(D_lookup
) debug_printf_indent("%s\n", *errmsg
);
105 *errmsg
= string_sprintf("LMDB: lookup error: %s", mdb_strerror(ret
));
106 DEBUG(D_lookup
) debug_printf_indent("%s\n", *errmsg
);
112 /*************************************************
113 * Close entry point *
114 *************************************************/
117 lmdb_close(void * handle
)
119 Lmdbstrct
* lmdb_p
= handle
;
120 MDB_env
* db_env
= mdb_txn_env(lmdb_p
->txn
);
121 mdb_txn_abort(lmdb_p
->txn
);
122 mdb_env_close(db_env
);
126 /*************************************************
127 * Version reporting entry point *
128 *************************************************/
130 #include "../version.h"
133 lmdb_version_report(FILE * f
)
135 fprintf(f
, "Library version: LMDB: Compile: %d.%d.%d\n",
136 MDB_VERSION_MAJOR
, MDB_VERSION_MINOR
, MDB_VERSION_PATCH
);
138 fprintf(f
, " Exim version %s\n", EXIM_VERSION_STR
);
142 static lookup_info lmdb_lookup_info
= {
143 .name
= US
"lmdb", /* lookup name */
144 .type
= lookup_absfile
, /* query-style lookup */
145 .open
= lmdb_open
, /* open function */
146 .check
= NULL
, /* no check function */
147 .find
= lmdb_find
, /* find function */
148 .close
= lmdb_close
, /* close function */
149 .tidy
= NULL
, /* tidy function */
150 .quote
= NULL
, /* quoting function */
151 .version_report
= lmdb_version_report
/* version reporting */
155 # define lmdb_lookup_module_info _lookup_module_info
156 #endif /* DYNLOOKUP */
158 static lookup_info
*_lookup_list
[] = { &lmdb_lookup_info
};
159 lookup_module_info lmdb_lookup_module_info
= { LOOKUP_MODULE_INFO_MAGIC
, _lookup_list
, 1 };
161 #endif /* EXPERIMENTAL_LMDB */