diff --git a/CMakeLists.txt b/CMakeLists.txt index 605ab76..7fad325 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ OPTION (ENABLE_TCL "Build the Tcl bindings?" OFF) OPTION (USE_VENDORDIRS "Install the bindings in vendor directories?" OFF) +OPTION (ENABLE_RPMDB_LMDB "Build with rpm db as lmdb?" OFF) OPTION (ENABLE_RPMDB "Build with rpm database support?" OFF) OPTION (ENABLE_RPMPKG "Build with rpm package support?" OFF) OPTION (ENABLE_PUBKEY "Build with pubkey support?" OFF) @@ -83,6 +84,17 @@ INCLUDE (${CMAKE_SOURCE_DIR}/VERSION.cmake) SET (have_system x) +IF (PHOTON) +MESSAGE(STATUS "Building for Photon") +ADD_DEFINITIONS (-DPHOTON) +SET (RPM5 ON) +SET (ENABLE_RPMDB ON) +SET (ENABLE_RPMMD ON) +SET (ENABLE_RPMDB_LMDB ON) +SET (ENABLE_COMPLEX_DEPS ON) +SET (have_system ${have_system}x) +ENDIF (PHOTON) + IF (FEDORA) MESSAGE(STATUS "Building for Fedora") ADD_DEFINITIONS (-DFEDORA) @@ -220,17 +232,25 @@ IF (ENABLE_RPMDB) ENDIF (RPMMISC_LIBRARY) ENDIF (RPM5) - # check if rpm contains a bundled berkeley db - CHECK_INCLUDE_FILE(rpm/db.h HAVE_RPM_DB_H) - IF (NOT HAVE_RPM_DB_H) - FIND_LIBRARY (DB_LIBRARY NAMES db) + IF (NOT ENABLE_RPMDB_LMDB) + # check if rpm contains a bundled berkeley db + CHECK_INCLUDE_FILE(rpm/db.h HAVE_RPM_DB_H) + IF (NOT HAVE_RPM_DB_H) + FIND_LIBRARY (DB_LIBRARY NAMES db) + IF (DB_LIBRARY) + SET (RPMDB_LIBRARY ${DB_LIBRARY} ${RPMDB_LIBRARY}) + ENDIF (DB_LIBRARY) + IF (DB_INCLUDE_DIR) + INCLUDE_DIRECTORIES (${DB_INCLUDE_DIR}) + ENDIF (DB_INCLUDE_DIR) + ENDIF (NOT HAVE_RPM_DB_H) + ELSE (NOT ENABLE_RPMDB_LMDB) + FIND_LIBRARY (DB_LIBRARY NAMES lmdb) IF (DB_LIBRARY) SET (RPMDB_LIBRARY ${DB_LIBRARY} ${RPMDB_LIBRARY}) ENDIF (DB_LIBRARY) - IF (DB_INCLUDE_DIR) - INCLUDE_DIRECTORIES (${DB_INCLUDE_DIR}) - ENDIF (DB_INCLUDE_DIR) - ENDIF (NOT HAVE_RPM_DB_H) + ENDIF (NOT ENABLE_RPMDB_LMDB) + INCLUDE (CheckLibraryExists) CHECK_LIBRARY_EXISTS(rpmio pgpDigGetParams "" HAVE_PGPDIGGETPARAMS) ENDIF (ENABLE_RPMDB) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 703796c..d56184f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,5 +1,5 @@ -IF (SUSE OR FEDORA OR DEBIAN OR MANDRIVA OR MAGEIA) +IF (PHOTON OR SUSE OR FEDORA OR DEBIAN OR MANDRIVA OR MAGEIA) ADD_SUBDIRECTORY (solv) -ENDIF (SUSE OR FEDORA OR DEBIAN OR MANDRIVA OR MAGEIA) +ENDIF (PHOTON OR SUSE OR FEDORA OR DEBIAN OR MANDRIVA OR MAGEIA) diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt index b8917a2..5d75c3f 100644 --- a/ext/CMakeLists.txt +++ b/ext/CMakeLists.txt @@ -11,6 +11,13 @@ IF (ENABLE_RPMDB OR ENABLE_RPMPKG) pool_fileconflicts.h repo_rpmdb.h) ENDIF (ENABLE_RPMDB OR ENABLE_RPMPKG) +IF (ENABLE_RPMDB_LMDB) + SET (libsolvext_SRCS ${libsolvext_SRCS} + db_lmdb.c) + SET (libsolvext_HEADERS ${libsolvext_HEADERS} + db_lmdb.h) +ENDIF (ENABLE_RPMDB_LMDB) + IF (ENABLE_PUBKEY) SET (libsolvext_SRCS ${libsolvext_SRCS} repo_pubkey.c) diff --git a/ext/db_lmdb.c b/ext/db_lmdb.c new file mode 100644 index 0000000..c3941b0 --- /dev/null +++ b/ext/db_lmdb.c @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2007-2012, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +/* + * db_lmdb + * + * bridge for db to lmdb calls + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "db_lmdb.h" +#include "util.h" + +int db_env_open(struct _DB_ENV_ *dbenv, const char *dbpath, u_int32_t flags, int naccess) +{ + int err = 0; + + err = mdb_env_open(dbenv->env, dbpath, 0, naccess); + bail_on_error(err); + +error: + return err; +} + +int db_env_close(struct _DB_ENV_ *dbenv, u_int32_t flags) +{ + int err = 0; + + if(dbenv && dbenv->env) + mdb_env_close(dbenv->env); + + return err; +} + +int db_env_get_open_flags(struct _DB_ENV_ *dbenv, u_int32_t *flags) +{ + *flags = 0; + return 0; +} + +int db_env_create (DB_ENV **dbenvp, u_int32_t flags) +{ + DB_ENV *dbenv = NULL; + MDB_env *mdbenv = NULL; + int err = 0; + + dbenv = solv_malloc(sizeof(DB_ENV)); + if(!dbenv) + err = ENOMEM; + bail_on_error(err); + + err = mdb_env_create(&mdbenv); + bail_on_error(err); + + err = mdb_env_set_maxreaders(mdbenv, 16); + bail_on_error(err); + + err = mdb_env_set_maxdbs(mdbenv, 32); + bail_on_error(err); + + err = mdb_env_set_mapsize(mdbenv, 50*1024*1024); + bail_on_error(err); + + dbenv->env = mdbenv; + dbenv->open = db_env_open; + dbenv->close = db_env_close; + dbenv->get_open_flags = db_env_get_open_flags; + + *dbenvp = dbenv; +cleanup: + return err; + +error: + if(mdbenv) + mdb_env_close(mdbenv); + solv_free(dbenv); + goto cleanup; +} + +//db +int db_close(struct _DB_ *db, u_int32_t flags) +{ + return 0; +} + +int dbc_close(struct _DBC_ *dbc) +{ +/* + if(dbc->txn) + { + if(dbc->txn->txn) + mdb_txn_abort(dbc->txn->txn); + dbc->txn->txn = NULL; + solv_free(dbc->txn); + } + dbc->txn = NULL; +*/ + return 0; +} + +int dbc_c_close(struct _DBC_ *dbc) +{ + if(dbc->cursor) + mdb_cursor_close(dbc->cursor); + dbc->cursor = NULL; + return 0; +} + +int dbc_c_get(struct _DBC_ *dbc, struct _DBT_ *key, struct _DBT_ *value, u_int32_t flags) +{ + int err = 0; + u_int32_t flagsin = flags == DB_SET ? MDB_SET : MDB_NEXT; + MDB_val mkey, mval; + + if(flagsin == MDB_SET) + { + mkey.mv_size = key->size; + mkey.mv_data = key->data; + } + + err = mdb_cursor_get(dbc->cursor, &mkey, &mval, flagsin); + bail_on_error(err); + + if(flagsin == MDB_NEXT) + { + key->size = mkey.mv_size; + key->data = mkey.mv_data; + } + value->size = mval.mv_size; + value->data = mval.mv_data; + +cleanup: + return err; +error: + goto cleanup; +} + +int db_cursor(struct _DB_ *db, struct _DB_TXN_ *txn, + struct _DBC_ **dbcp, u_int32_t flags) +{ + int err = 0; + DBC *dbc = NULL; + + DB_TXN *txncurrent = txn ? txn : db->txn; + + if(!txncurrent || !txncurrent->txn) + err = EINVAL; + bail_on_error(err); + + dbc = solv_malloc(sizeof(DBC)); + if(!dbc) + err = ENOMEM; + bail_on_error(err); + + err = mdb_cursor_open(txncurrent->txn, db->db, &dbc->cursor); + bail_on_error(err); + + dbc->close = dbc_close; + dbc->c_close = dbc_c_close; + dbc->c_get = dbc_c_get; + + *dbcp = dbc; +cleanup: + return err; +error: + solv_free(dbc); + goto cleanup; +} + +int db_get(struct _DB_ *db, struct _DB_TXN_ *txn, + struct _DBT_ *key, struct _DBT_ *value, u_int32_t flags) +{ + return 0; +} + +int db_open(struct _DB_ *db, struct _DB_TXN_ *txn, + const char *file, const char *database, + DBTYPE dbtype, u_int32_t flags, int mode) +{ + int err = 0; + DB_TXN *txnp = NULL; + MDB_dbi dbi = -1; + DB_TXN *txncurrent = txn; + + if(!txn) + { + u_int32_t txnflags = flags & DB_RDONLY ? MDB_RDONLY : 0; + txnp = solv_malloc(sizeof(DB_TXN)); + if(!txnp) + err = ENOMEM; + bail_on_error(err); + + err = mdb_txn_begin(db->env, NULL, txnflags, &txnp->txn); + bail_on_error(err); + + txncurrent = txnp; + } + + err = mdb_dbi_open(txncurrent->txn, file, 0, &dbi); + bail_on_error(err); + + db->txn = txnp; + db->db = dbi; + +cleanup: + return err; +error: + solv_free(txnp); + goto cleanup; +} + +int db_get_byteswapped(struct _DB_ *db, int *byteswapped) +{ + *byteswapped = 0; + return 0; +} + +int db_create (DB **db, DB_ENV *dbenv, u_int32_t flags) +{ + int err = 0; + DB *dbp = NULL; + + dbp = solv_malloc(sizeof(DB)); + if(!dbp) + err = ENOMEM; + bail_on_error(err); + + + dbp->env = dbenv->env; + dbp->close = db_close; + dbp->cursor = db_cursor; + dbp->get = db_get; + dbp->get_byteswapped = db_get_byteswapped; + dbp->open = db_open; + *db = dbp; + +cleanup: + return err; +error: + solv_free(dbp); + goto cleanup; +} diff --git a/ext/db_lmdb.h b/ext/db_lmdb.h new file mode 100644 index 0000000..4eb197d --- /dev/null +++ b/ext/db_lmdb.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2007-2008, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +#ifndef RPM_LMDB_H +#define RPM_LMDB_H + +#include + +typedef enum +{ + DB_UNKNOWN=5 +} DBTYPE; + +typedef struct _DB_ENV_ +{ + MDB_env *env; + int (*get_open_flags) (struct _DB_ENV_ *, u_int32_t *); + int (*open) (struct _DB_ENV_ *, const char *, u_int32_t, int); + int (*close) (struct _DB_ENV_ *, u_int32_t); +}DB_ENV; + +typedef struct _DB_TXN_ +{ + MDB_txn *txn; +}DB_TXN; + +typedef struct _DBT_ +{ + void *data; + u_int32_t size; +}DBT; + +typedef struct _DBC_ +{ + MDB_cursor *cursor; + int (*close) (struct _DBC_ *); + int (*c_close) (struct _DBC_ *); + int (*c_get) (struct _DBC_ *, struct _DBT_ *, struct _DBT_ *, u_int32_t); +}DBC; + +typedef struct _DB_ +{ + DB_TXN *txn; + MDB_dbi db; + MDB_env *env; + int (*close) (struct _DB_ *, u_int32_t); + int (*cursor)(struct _DB_ *, struct _DB_TXN_ *, struct _DBC_ **, u_int32_t); + int (*get) (struct _DB_ *, struct _DB_TXN_ *, struct _DBT_ *, struct _DBT_ *, u_int32_t); + int (*get_byteswapped) (struct _DB_ *, int *); + int (*open) (struct _DB_ *, + struct _DB_TXN_ *, + const char *, + const char *, + DBTYPE, + u_int32_t, + int); +}DB; + +//definitions from db.h +#define DB_CREATE 0x00000001 +#define DB_INIT_CDB 0x00000080 +#define DB_INIT_MPOOL 0x00000400 +#define DB_PRIVATE 0x00010000 +#define DB_RDONLY 0x00000400 + +#define DB_NEXT 16 +#define DB_SET 26 + +int db_env_create (DB_ENV **, u_int32_t); +int db_create (DB **, DB_ENV *, u_int32_t); + +#define bail_on_error(nerror) \ + do { \ + if (nerror) \ + { \ + goto error; \ + } \ + } while(0) +#endif//RPM_LMDB_H diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c index fe05bec..9f4ad31 100644 --- a/ext/repo_rpmdb.c +++ b/ext/repo_rpmdb.c @@ -25,6 +25,7 @@ #include #ifdef ENABLE_RPMDB +#define ENABLE_RPMDB_LMDB #include #include @@ -37,7 +38,11 @@ # if defined(SUSE) || defined(HAVE_RPM_DB_H) # include # else -# include +# ifdef ENABLE_RPMDB_LMDB +# include "db_lmdb.h" +# else +# include +# endif # endif #endif @@ -1515,7 +1520,7 @@ count_headers(struct rpmdbstate *state) DBT dbkey; DBT dbdata; - snprintf(dbpath, PATH_MAX, "%s%s/Name", state->rootdir ? state->rootdir : "", state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm"); + snprintf(dbpath, PATH_MAX, "%s%s/data.mdb", state->rootdir ? state->rootdir : "", state->is_ostree ? "/usr/share/rpm" : "/var/lib/rpm"); if (stat(dbpath, &statbuf)) return 0; memset(&dbkey, 0, sizeof(dbkey)); @@ -1841,7 +1846,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags) } /* XXX: should get ro lock of Packages database! */ - snprintf(dbpath, PATH_MAX, "%s%s/Packages", state.rootdir ? state.rootdir : "", state.is_ostree ? "/usr/share/rpm" : "/var/lib/rpm"); + snprintf(dbpath, PATH_MAX, "%s%s/data.mdb", state.rootdir ? state.rootdir : "", state.is_ostree ? "/usr/share/rpm" : "/var/lib/rpm"); if (stat(dbpath, &packagesstat)) { pool_error(pool, -1, "%s: %s", dbpath, strerror(errno));