diff options
author | Florian Festi <ffesti@redhat.com> | 2009-12-03 13:50:37 +0100 |
---|---|---|
committer | Florian Festi <ffesti@redhat.com> | 2009-12-07 15:59:13 +0100 |
commit | e2c217b4b76118e6dab9f8dfb3284bb4ddbe2b3e (patch) | |
tree | 0ed878feb0a385b61b2b7582da90dc12735da4d4 | |
parent | 139c031d2c54fe9e692765dae05da89d7ecfa8cc (diff) | |
download | rpm-e2c217b4b76118e6dab9f8dfb3284bb4ddbe2b3e.tar.gz |
Remove support for sqlite based rpm database
Also remove abstraction layer between rpmdb.h and the back end
in lib/backend/
-rw-r--r-- | INSTALL | 6 | ||||
-rw-r--r-- | configure.ac | 33 | ||||
-rw-r--r-- | lib/Makefile.am | 5 | ||||
-rw-r--r-- | lib/backend/db3.c | 83 | ||||
-rw-r--r-- | lib/backend/dbconfig.c | 184 | ||||
-rw-r--r-- | lib/backend/sqlite.c | 1308 | ||||
-rw-r--r-- | lib/rpmdb.c | 126 | ||||
-rw-r--r-- | lib/rpmdb.h | 2 | ||||
-rw-r--r-- | lib/rpmdb_internal.h | 218 |
9 files changed, 193 insertions, 1772 deletions
@@ -63,12 +63,6 @@ Minimal instructions for building BDB are make make install -If you want to use the alternative SQLite backend for RPM database instead -of the default Berkeley DB, it can be enabled with --enable-sqlite3 option -to configure. Note that the SQLite backend is not as tested as BDB. -SQLite >= 3.x is required and is available from - http://www.sqlite.org/ - For embedded Lua scripting support (recommended and enabled by default), you'll need Lua >= 5.1 library + development environment installed. Note that only the library is needed at runtime, RPM never calls external diff --git a/configure.ac b/configure.ac index 4c060af70..895907f1e 100644 --- a/configure.ac +++ b/configure.ac @@ -399,39 +399,6 @@ esac AC_SUBST([WITH_DB_LIB]) -#================= -# Check for sqlite3 library. -AC_ARG_ENABLE(sqlite3, [AS_HELP_STRING([--enable-sqlite3],[enable sqlite3 support])], -[case "$enable_sqlite3" in -yes|no) ;; -*) AC_MSG_ERROR([invalid argument to --enable-sqlite3]) - ;; -esac], -[enable_sqlite3=no]) - -WITH_SQLITE3_INCLUDE= -WITH_SQLITE3_LIB= -WITH_SQLITE3=no -AS_IF([test "$enable_sqlite3" = yes],[ - AC_CHECK_HEADERS([sqlite3.h], - [ AC_CHECK_LIB(sqlite3, sqlite3_open, [ - WITH_SQLITE3_INCLUDE= - WITH_SQLITE3_LIB="-lsqlite3" - WITH_SQLITE3=yes - ],[ - AC_MSG_ERROR([missing libsqlite3]) - ]) - ],[ - AC_MSG_ERROR([missing sqlite3.h]) - ]) -]) - -AC_SUBST(WITH_SQLITE3_INCLUDE) -AC_SUBST(WITH_SQLITE3_LIB) -AM_CONDITIONAL([SQLITE3],[test "$WITH_SQLITE3" = yes]) - -#================= - dnl AmigaOS and IXEmul have a fork() dummy case "$host" in m68k-*-amigaos ) diff --git a/lib/Makefile.am b/lib/Makefile.am index b37866957..244d40b8b 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -5,7 +5,6 @@ include $(top_srcdir)/rpm.am AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -I$(top_builddir)/include/ AM_CPPFLAGS += @WITH_NSS_INCLUDE@ AM_CPPFLAGS += @WITH_POPT_INCLUDE@ -AM_CPPFLAGS += @WITH_SQLITE3_INCLUDE@ AM_CPPFLAGS += -I$(top_srcdir)/misc AM_CPPFLAGS += -DLOCALEDIR="\"$(localedir)\"" AM_CPPFLAGS += -DSYSCONFDIR="\"$(sysconfdir)\"" @@ -35,9 +34,6 @@ librpm_la_SOURCES = \ verify.c rpmlock.c rpmlock.h misc.h \ legacy.c merge.c \ rpmliblua.c rpmliblua.h -if SQLITE3 -librpm_la_SOURCES += backend/sqlite.c -endif librpm_la_LDFLAGS = -version-info 1:0:0 @@ -45,7 +41,6 @@ librpm_la_LIBADD = \ $(top_builddir)/rpmio/librpmio.la \ @WITH_POPT_LIB@ \ @WITH_SELINUX_LIB@ \ - @WITH_SQLITE3_LIB@ \ @WITH_CAP_LIB@ \ @WITH_ACL_LIB@ \ @LIBINTL@ diff --git a/lib/backend/db3.c b/lib/backend/db3.c index bc3b8a49d..9636be2c8 100644 --- a/lib/backend/db3.c +++ b/lib/backend/db3.c @@ -1,4 +1,4 @@ -/** \ingroup db3 +/** \ingroup rpmdb * \file lib/db3.c */ @@ -62,7 +62,7 @@ static int db_fini(dbiIndex dbi, const char * dbhome) return rc; } -static int db3_fsync_disable(int fd) +static int fsync_disable(int fd) { return 0; } @@ -72,7 +72,7 @@ static int db3_fsync_disable(int fd) * dbenv->failchk() callback method for determining is the given pid/tid * is alive. We only care about pid's though. */ -static int db3isalive(DB_ENV *dbenv, pid_t pid, db_threadid_t tid, uint32_t flags) +static int isalive(DB_ENV *dbenv, pid_t pid, db_threadid_t tid, uint32_t flags) { int alive = 0; @@ -136,7 +136,7 @@ static int db_init(dbiIndex dbi, const char * dbhome, DB_ENV ** dbenvp) * thread_count 8 is some kind of "magic minimum" value... */ dbenv->set_thread_count(dbenv, 8); - dbenv->set_isalive(dbenv, db3isalive); + dbenv->set_isalive(dbenv, isalive); #endif #if !(DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3) @@ -169,7 +169,7 @@ static int db_init(dbiIndex dbi, const char * dbhome, DB_ENV ** dbenvp) } if (dbi->dbi_no_fsync) { - xx = db_env_set_func_fsync(db3_fsync_disable); + xx = db_env_set_func_fsync(fsync_disable); xx = cvtdberr(dbi, "db_env_set_func_fsync", xx, _debug); } @@ -204,7 +204,7 @@ errxit: return rc; } -static int db3sync(dbiIndex dbi, unsigned int flags) +int dbiSync(dbiIndex dbi, unsigned int flags) { DB * db = dbi->dbi_db; int rc = 0; @@ -216,12 +216,12 @@ static int db3sync(dbiIndex dbi, unsigned int flags) return rc; } -static int db3cclose(dbiIndex dbi, DBC * dbcursor, +int dbiCclose(dbiIndex dbi, DBC * dbcursor, unsigned int flags) { int rc = -2; - /* XXX db3copen error pathways come through here. */ + /* XXX dbiCopen error pathways come through here. */ if (dbcursor != NULL) { rc = dbcursor->c_close(dbcursor); rc = cvtdberr(dbi, "dbcursor->c_close", rc, _debug); @@ -229,7 +229,7 @@ static int db3cclose(dbiIndex dbi, DBC * dbcursor, return rc; } -static int db3copen(dbiIndex dbi, DB_TXN * txnid, +int dbiCopen(dbiIndex dbi, DB_TXN * txnid, DBC ** dbcp, unsigned int dbiflags) { DB * db = dbi->dbi_db; @@ -252,18 +252,23 @@ static int db3copen(dbiIndex dbi, DB_TXN * txnid, if (dbcp) *dbcp = dbcursor; else - (void) db3cclose(dbi, dbcursor, 0); + (void) dbiCclose(dbi, dbcursor, 0); return rc; } -static int db3cput(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, + +/* Store (key,data) pair in index database. */ +int dbiPut(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, unsigned int flags) { DB * db = dbi->dbi_db; int rc; + assert(key->data != NULL && key->size > 0 && data->data != NULL && data->size > 0); assert(db != NULL); + + (void) rpmswEnter(&dbi->dbi_rpmdb->db_putops, (ssize_t) 0); if (dbcursor == NULL) { rc = db->put(db, dbi->dbi_txnid, key, data, 0); rc = cvtdberr(dbi, "db->put", rc, _debug); @@ -272,16 +277,20 @@ static int db3cput(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, rc = cvtdberr(dbi, "dbcursor->c_put", rc, _debug); } + (void) rpmswExit(&dbi->dbi_rpmdb->db_putops, (ssize_t) data->size); return rc; } -static int db3cdel(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, - unsigned int flags) +int dbiDel(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, + unsigned int flags) { DB * db = dbi->dbi_db; int rc; assert(db != NULL); + assert(key->data != NULL && key->size > 0); + (void) rpmswEnter(&dbi->dbi_rpmdb->db_delops, 0); + if (dbcursor == NULL) { rc = db->del(db, dbi->dbi_txnid, key, flags); rc = cvtdberr(dbi, "db->del", rc, _debug); @@ -300,16 +309,22 @@ static int db3cdel(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, } } + (void) rpmswExit(&dbi->dbi_rpmdb->db_delops, data->size); return rc; } -static int db3cget(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, +/* Retrieve (key,data) pair from index database. */ +int dbiGet(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, unsigned int flags) { + DB * db = dbi->dbi_db; int _printit; int rc; + assert((flags == DB_NEXT) || (key->data != NULL && key->size > 0)); + (void) rpmswEnter(&dbi->dbi_rpmdb->db_getops, 0); + assert(db != NULL); if (dbcursor == NULL) { /* XXX duplicates require cursors. */ @@ -318,19 +333,20 @@ static int db3cget(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, _printit = (rc == DB_NOTFOUND ? 0 : _debug); rc = cvtdberr(dbi, "db->get", rc, _printit); } else { - /* XXX db3 does DB_FIRST on uninitialized cursor */ + /* XXX db4 does DB_FIRST on uninitialized cursor */ rc = dbcursor->c_get(dbcursor, key, data, flags); /* XXX DB_NOTFOUND can be returned */ _printit = (rc == DB_NOTFOUND ? 0 : _debug); rc = cvtdberr(dbi, "dbcursor->c_get", rc, _printit); } + (void) rpmswExit(&dbi->dbi_rpmdb->db_getops, data->size); return rc; } -static int db3ccount(dbiIndex dbi, DBC * dbcursor, - unsigned int * countp, - unsigned int flags) +int dbiCount(dbiIndex dbi, DBC * dbcursor, + unsigned int * countp, + unsigned int flags) { db_recno_t count = 0; int rc = 0; @@ -344,22 +360,24 @@ static int db3ccount(dbiIndex dbi, DBC * dbcursor, return rc; } -static int db3byteswapped(dbiIndex dbi) +int dbiByteSwapped(dbiIndex dbi) { DB * db = dbi->dbi_db; int rc = 0; + if (dbi->dbi_byteswapped != -1) + return dbi->dbi_byteswapped; + if (db != NULL) { int isswapped = 0; rc = db->get_byteswapped(db, &isswapped); if (rc == 0) - rc = isswapped; + dbi->dbi_byteswapped = rc = isswapped; } - return rc; } -static int db3stat(dbiIndex dbi, unsigned int flags) +int dbiStat(dbiIndex dbi, unsigned int flags) { DB * db = dbi->dbi_db; #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3) @@ -384,7 +402,7 @@ static int db3stat(dbiIndex dbi, unsigned int flags) return rc; } -static int db3close(dbiIndex dbi, unsigned int flags) +int dbiClose(dbiIndex dbi, unsigned int flags) { rpmdb rpmdb = dbi->dbi_rpmdb; const char * dbhome = rpmdbHome(rpmdb); @@ -477,14 +495,13 @@ static int db3close(dbiIndex dbi, unsigned int flags) exit: dbi->dbi_db = NULL; - dbi = db3Free(dbi); + dbi = dbiFree(dbi); return rc; } -static int db3open(rpmdb rpmdb, rpmTag rpmtag, dbiIndex * dbip) +int dbiOpenDB(rpmdb rpmdb, rpmTag rpmtag, dbiIndex * dbip) { - extern const struct _dbiVec db3vec; const char *dbhome = rpmdbHome(rpmdb); dbiIndex dbi = NULL; int rc = 0; @@ -502,7 +519,7 @@ static int db3open(rpmdb rpmdb, rpmTag rpmtag, dbiIndex * dbip) /* * Parse db configuration parameters. */ - if ((dbi = db3New(rpmdb, rpmtag)) == NULL) + if ((dbi = dbiNew(rpmdb, rpmtag)) == NULL) return 1; oflags = (dbi->dbi_oeflags | dbi->dbi_oflags); @@ -834,21 +851,11 @@ static int db3open(rpmdb rpmdb, rpmTag rpmtag, dbiIndex * dbip) dbi->dbi_db = db; if (rc == 0 && dbi->dbi_db != NULL && dbip != NULL) { - dbi->dbi_vec = &db3vec; *dbip = dbi; } else { dbi->dbi_verify_on_close = 0; - (void) db3close(dbi, 0); + (void) dbiClose(dbi, 0); } return rc; } - -/** \ingroup db3 - */ -RPM_GNUC_INTERNAL -const struct _dbiVec db3vec = { - DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH, - db3open, db3close, db3sync, db3copen, db3cclose, db3cdel, - db3cget, db3cput, db3ccount, db3byteswapped, db3stat -}; diff --git a/lib/backend/dbconfig.c b/lib/backend/dbconfig.c index 37d87f895..62973b840 100644 --- a/lib/backend/dbconfig.c +++ b/lib/backend/dbconfig.c @@ -14,199 +14,199 @@ #include "lib/rpmdb_internal.h" #include "debug.h" -static struct _dbiIndex db3dbi; +static struct _dbiIndex staticdbi; -/** \ingroup db3 +/** \ingroup dbi */ static const struct poptOption rdbOptions[] = { /* XXX DB_CXX_NO_EXCEPTIONS */ - { "create", 0,POPT_BIT_SET, &db3dbi.dbi_oeflags, DB_CREATE, + { "create", 0,POPT_BIT_SET, &staticdbi.dbi_oeflags, DB_CREATE, NULL, NULL }, - { "thread", 0,POPT_BIT_SET, &db3dbi.dbi_oeflags, DB_THREAD, + { "thread", 0,POPT_BIT_SET, &staticdbi.dbi_oeflags, DB_THREAD, NULL, NULL }, - { "force", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_FORCE, + { "force", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_FORCE, NULL, NULL }, - { "cdb", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_INIT_CDB, + { "cdb", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_INIT_CDB, NULL, NULL }, - { "lock", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_INIT_LOCK, + { "lock", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_INIT_LOCK, NULL, NULL }, - { "log", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_INIT_LOG, + { "log", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_INIT_LOG, NULL, NULL }, - { "mpool", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_INIT_MPOOL, + { "mpool", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_INIT_MPOOL, NULL, NULL }, - { "txn", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_INIT_TXN, + { "txn", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_INIT_TXN, NULL, NULL }, - { "joinenv", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_JOINENV, + { "joinenv", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_JOINENV, NULL, NULL }, - { "recover", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_RECOVER, + { "recover", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_RECOVER, NULL, NULL }, - { "recover_fatal", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_RECOVER_FATAL, + { "recover_fatal", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_RECOVER_FATAL, NULL, NULL }, - { "shared", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_SYSTEM_MEM, + { "shared", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_SYSTEM_MEM, NULL, NULL }, - { "txn_nosync", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_TXN_NOSYNC, + { "txn_nosync", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_TXN_NOSYNC, NULL, NULL }, - { "use_environ_root", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_USE_ENVIRON_ROOT, + { "use_environ_root", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_USE_ENVIRON_ROOT, NULL, NULL }, - { "use_environ", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_USE_ENVIRON, + { "use_environ", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_USE_ENVIRON, NULL, NULL }, - { "lockdown", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_LOCKDOWN, + { "lockdown", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_LOCKDOWN, NULL, NULL }, - { "private", 0,POPT_BIT_SET, &db3dbi.dbi_eflags, DB_PRIVATE, + { "private", 0,POPT_BIT_SET, &staticdbi.dbi_eflags, DB_PRIVATE, NULL, NULL }, - { "txn_sync", 0,POPT_BIT_SET, &db3dbi.dbi_tflags, DB_TXN_SYNC, + { "txn_sync", 0,POPT_BIT_SET, &staticdbi.dbi_tflags, DB_TXN_SYNC, NULL, NULL }, - { "txn_nowait",0,POPT_BIT_SET, &db3dbi.dbi_tflags, DB_TXN_NOWAIT, + { "txn_nowait",0,POPT_BIT_SET, &staticdbi.dbi_tflags, DB_TXN_NOWAIT, NULL, NULL }, - { "excl", 0,POPT_BIT_SET, &db3dbi.dbi_oflags, DB_EXCL, + { "excl", 0,POPT_BIT_SET, &staticdbi.dbi_oflags, DB_EXCL, NULL, NULL }, - { "nommap", 0,POPT_BIT_SET, &db3dbi.dbi_oflags, DB_NOMMAP, + { "nommap", 0,POPT_BIT_SET, &staticdbi.dbi_oflags, DB_NOMMAP, NULL, NULL }, - { "rdonly", 0,POPT_BIT_SET, &db3dbi.dbi_oflags, DB_RDONLY, + { "rdonly", 0,POPT_BIT_SET, &staticdbi.dbi_oflags, DB_RDONLY, NULL, NULL }, - { "truncate", 0,POPT_BIT_SET, &db3dbi.dbi_oflags, DB_TRUNCATE, + { "truncate", 0,POPT_BIT_SET, &staticdbi.dbi_oflags, DB_TRUNCATE, NULL, NULL }, - { "fcntl_locking",0,POPT_BIT_SET, &db3dbi.dbi_oflags, DB_FCNTL_LOCKING, + { "fcntl_locking",0,POPT_BIT_SET, &staticdbi.dbi_oflags, DB_FCNTL_LOCKING, NULL, NULL }, - { "btree", 0,POPT_ARG_VAL, &db3dbi.dbi_type, DB_BTREE, + { "btree", 0,POPT_ARG_VAL, &staticdbi.dbi_type, DB_BTREE, NULL, NULL }, - { "hash", 0,POPT_ARG_VAL, &db3dbi.dbi_type, DB_HASH, + { "hash", 0,POPT_ARG_VAL, &staticdbi.dbi_type, DB_HASH, NULL, NULL }, - { "recno", 0,POPT_ARG_VAL, &db3dbi.dbi_type, DB_RECNO, + { "recno", 0,POPT_ARG_VAL, &staticdbi.dbi_type, DB_RECNO, NULL, NULL }, - { "queue", 0,POPT_ARG_VAL, &db3dbi.dbi_type, DB_QUEUE, + { "queue", 0,POPT_ARG_VAL, &staticdbi.dbi_type, DB_QUEUE, NULL, NULL }, - { "unknown", 0,POPT_ARG_VAL, &db3dbi.dbi_type, DB_UNKNOWN, + { "unknown", 0,POPT_ARG_VAL, &staticdbi.dbi_type, DB_UNKNOWN, NULL, NULL }, - { "file", 0,POPT_ARG_STRING, &db3dbi.dbi_file, 0, + { "file", 0,POPT_ARG_STRING, &staticdbi.dbi_file, 0, NULL, NULL }, - { "subfile", 0,POPT_ARG_STRING, &db3dbi.dbi_subfile, 0, + { "subfile", 0,POPT_ARG_STRING, &staticdbi.dbi_subfile, 0, NULL, NULL }, - { "mode", 0,POPT_ARG_INT, &db3dbi.dbi_mode, 0, + { "mode", 0,POPT_ARG_INT, &staticdbi.dbi_mode, 0, NULL, NULL }, - { "perms", 0,POPT_ARG_INT, &db3dbi.dbi_perms, 0, + { "perms", 0,POPT_ARG_INT, &staticdbi.dbi_perms, 0, NULL, NULL }, - { "shmkey", 0,POPT_ARG_LONG, &db3dbi.dbi_shmkey, 0, + { "shmkey", 0,POPT_ARG_LONG, &staticdbi.dbi_shmkey, 0, NULL, NULL }, - { "tmpdir", 0,POPT_ARG_STRING, &db3dbi.dbi_tmpdir, 0, + { "tmpdir", 0,POPT_ARG_STRING, &staticdbi.dbi_tmpdir, 0, NULL, NULL }, - { "verify", 0,POPT_ARG_NONE, &db3dbi.dbi_verify_on_close, 0, + { "verify", 0,POPT_ARG_NONE, &staticdbi.dbi_verify_on_close, 0, NULL, NULL }, - { "usedbenv", 0,POPT_ARG_NONE, &db3dbi.dbi_use_dbenv, 0, + { "usedbenv", 0,POPT_ARG_NONE, &staticdbi.dbi_use_dbenv, 0, NULL, NULL }, - { "nofsync", 0,POPT_ARG_NONE, &db3dbi.dbi_no_fsync, 0, + { "nofsync", 0,POPT_ARG_NONE, &staticdbi.dbi_no_fsync, 0, NULL, NULL }, - { "nodbsync", 0,POPT_ARG_NONE, &db3dbi.dbi_no_dbsync, 0, + { "nodbsync", 0,POPT_ARG_NONE, &staticdbi.dbi_no_dbsync, 0, NULL, NULL }, - { "lockdbfd", 0,POPT_ARG_NONE, &db3dbi.dbi_lockdbfd, 0, + { "lockdbfd", 0,POPT_ARG_NONE, &staticdbi.dbi_lockdbfd, 0, NULL, NULL }, - { "temporary", 0,POPT_ARG_NONE, &db3dbi.dbi_temporary, 0, + { "temporary", 0,POPT_ARG_NONE, &staticdbi.dbi_temporary, 0, NULL, NULL }, - { "debug", 0,POPT_ARG_NONE, &db3dbi.dbi_debug, 0, + { "debug", 0,POPT_ARG_NONE, &staticdbi.dbi_debug, 0, NULL, NULL }, - { "cachesize", 0,POPT_ARG_INT, &db3dbi.dbi_cachesize, 0, + { "cachesize", 0,POPT_ARG_INT, &staticdbi.dbi_cachesize, 0, NULL, NULL }, - { "errpfx", 0,POPT_ARG_STRING, &db3dbi.dbi_errpfx, 0, + { "errpfx", 0,POPT_ARG_STRING, &staticdbi.dbi_errpfx, 0, NULL, NULL }, - { "region_init", 0,POPT_ARG_VAL, &db3dbi.dbi_region_init, 1, + { "region_init", 0,POPT_ARG_VAL, &staticdbi.dbi_region_init, 1, NULL, NULL }, - { "tas_spins", 0,POPT_ARG_INT, &db3dbi.dbi_tas_spins, 0, + { "tas_spins", 0,POPT_ARG_INT, &staticdbi.dbi_tas_spins, 0, NULL, NULL }, #if defined(DB_VERB_CHKPOINT) - { "chkpoint", 0,POPT_BIT_SET, &db3dbi.dbi_verbose, DB_VERB_CHKPOINT, + { "chkpoint", 0,POPT_BIT_SET, &staticdbi.dbi_verbose, DB_VERB_CHKPOINT, NULL, NULL }, #endif - { "deadlock", 0,POPT_BIT_SET, &db3dbi.dbi_verbose, DB_VERB_DEADLOCK, + { "deadlock", 0,POPT_BIT_SET, &staticdbi.dbi_verbose, DB_VERB_DEADLOCK, NULL, NULL }, - { "recovery", 0,POPT_BIT_SET, &db3dbi.dbi_verbose, DB_VERB_RECOVERY, + { "recovery", 0,POPT_BIT_SET, &staticdbi.dbi_verbose, DB_VERB_RECOVERY, NULL, NULL }, - { "waitsfor", 0,POPT_BIT_SET, &db3dbi.dbi_verbose, DB_VERB_WAITSFOR, + { "waitsfor", 0,POPT_BIT_SET, &staticdbi.dbi_verbose, DB_VERB_WAITSFOR, NULL, NULL }, - { "verbose", 0,POPT_ARG_VAL, &db3dbi.dbi_verbose, -1, + { "verbose", 0,POPT_ARG_VAL, &staticdbi.dbi_verbose, -1, NULL, NULL }, - { "lk_oldest", 0,POPT_ARG_VAL, &db3dbi.dbi_lk_detect, DB_LOCK_OLDEST, + { "lk_oldest", 0,POPT_ARG_VAL, &staticdbi.dbi_lk_detect, DB_LOCK_OLDEST, NULL, NULL }, - { "lk_random", 0,POPT_ARG_VAL, &db3dbi.dbi_lk_detect, DB_LOCK_RANDOM, + { "lk_random", 0,POPT_ARG_VAL, &staticdbi.dbi_lk_detect, DB_LOCK_RANDOM, NULL, NULL }, - { "lk_youngest",0, POPT_ARG_VAL, &db3dbi.dbi_lk_detect, DB_LOCK_YOUNGEST, + { "lk_youngest",0, POPT_ARG_VAL, &staticdbi.dbi_lk_detect, DB_LOCK_YOUNGEST, NULL, NULL }, /* XXX lk_conflicts matrix */ - { "lk_max", 0,POPT_ARG_INT, &db3dbi.dbi_lk_max, 0, + { "lk_max", 0,POPT_ARG_INT, &staticdbi.dbi_lk_max, 0, NULL, NULL }, - { "lg_bsize", 0,POPT_ARG_INT, &db3dbi.dbi_lg_bsize, 0, + { "lg_bsize", 0,POPT_ARG_INT, &staticdbi.dbi_lg_bsize, 0, NULL, NULL }, - { "lg_max", 0,POPT_ARG_INT, &db3dbi.dbi_lg_max, 0, + { "lg_max", 0,POPT_ARG_INT, &staticdbi.dbi_lg_max, 0, NULL, NULL }, /* XXX tx_recover */ - { "tx_max", 0,POPT_ARG_INT, &db3dbi.dbi_tx_max, 0, + { "tx_max", 0,POPT_ARG_INT, &staticdbi.dbi_tx_max, 0, NULL, NULL }, - { "lorder", 0,POPT_ARG_INT, &db3dbi.dbi_lorder, 0, + { "lorder", 0,POPT_ARG_INT, &staticdbi.dbi_lorder, 0, NULL, NULL }, - { "mmapsize", 0,POPT_ARG_INT, &db3dbi.dbi_mmapsize, 0, + { "mmapsize", 0,POPT_ARG_INT, &staticdbi.dbi_mmapsize, 0, NULL, NULL }, - { "mp_mmapsize", 0,POPT_ARG_INT, &db3dbi.dbi_mmapsize, 0, + { "mp_mmapsize", 0,POPT_ARG_INT, &staticdbi.dbi_mmapsize, 0, NULL, NULL }, - { "mp_size", 0,POPT_ARG_INT, &db3dbi.dbi_cachesize, 0, + { "mp_size", 0,POPT_ARG_INT, &staticdbi.dbi_cachesize, 0, NULL, NULL }, - { "pagesize", 0,POPT_ARG_INT, &db3dbi.dbi_pagesize, 0, + { "pagesize", 0,POPT_ARG_INT, &staticdbi.dbi_pagesize, 0, NULL, NULL }, /* XXX bt_minkey */ /* XXX bt_compare */ /* XXX bt_dup_compare */ /* XXX bt_prefix */ - { "bt_dup", 0,POPT_BIT_SET, &db3dbi.dbi_bt_flags, DB_DUP, + { "bt_dup", 0,POPT_BIT_SET, &staticdbi.dbi_bt_flags, DB_DUP, NULL, NULL }, - { "bt_dupsort",0,POPT_BIT_SET, &db3dbi.dbi_bt_flags, DB_DUPSORT, + { "bt_dupsort",0,POPT_BIT_SET, &staticdbi.dbi_bt_flags, DB_DUPSORT, NULL, NULL }, - { "bt_recnum", 0,POPT_BIT_SET, &db3dbi.dbi_bt_flags, DB_RECNUM, + { "bt_recnum", 0,POPT_BIT_SET, &staticdbi.dbi_bt_flags, DB_RECNUM, NULL, NULL }, - { "bt_revsplitoff", 0,POPT_BIT_SET, &db3dbi.dbi_bt_flags, DB_REVSPLITOFF, + { "bt_revsplitoff", 0,POPT_BIT_SET, &staticdbi.dbi_bt_flags, DB_REVSPLITOFF, NULL, NULL }, - { "h_dup", 0,POPT_BIT_SET, &db3dbi.dbi_h_flags, DB_DUP, + { "h_dup", 0,POPT_BIT_SET, &staticdbi.dbi_h_flags, DB_DUP, NULL, NULL }, - { "h_dupsort", 0,POPT_BIT_SET, &db3dbi.dbi_h_flags, DB_DUPSORT, + { "h_dupsort", 0,POPT_BIT_SET, &staticdbi.dbi_h_flags, DB_DUPSORT, NULL, NULL }, - { "h_ffactor", 0,POPT_ARG_INT, &db3dbi.dbi_h_ffactor, 0, + { "h_ffactor", 0,POPT_ARG_INT, &staticdbi.dbi_h_ffactor, 0, NULL, NULL }, - { "h_nelem", 0,POPT_ARG_INT, &db3dbi.dbi_h_nelem, 0, + { "h_nelem", 0,POPT_ARG_INT, &staticdbi.dbi_h_nelem, 0, NULL, NULL }, - { "re_renumber", 0,POPT_BIT_SET, &db3dbi.dbi_re_flags, DB_RENUMBER, + { "re_renumber", 0,POPT_BIT_SET, &staticdbi.dbi_re_flags, DB_RENUMBER, NULL, NULL }, - { "re_snapshot",0,POPT_BIT_SET, &db3dbi.dbi_re_flags, DB_SNAPSHOT, + { "re_snapshot",0,POPT_BIT_SET, &staticdbi.dbi_re_flags, DB_SNAPSHOT, NULL, NULL }, - { "re_delim", 0,POPT_ARG_INT, &db3dbi.dbi_re_delim, 0, + { "re_delim", 0,POPT_ARG_INT, &staticdbi.dbi_re_delim, 0, NULL, NULL }, - { "re_len", 0,POPT_ARG_INT, &db3dbi.dbi_re_len, 0, + { "re_len", 0,POPT_ARG_INT, &staticdbi.dbi_re_len, 0, NULL, NULL }, - { "re_pad", 0,POPT_ARG_INT, &db3dbi.dbi_re_pad, 0, + { "re_pad", 0,POPT_ARG_INT, &staticdbi.dbi_re_pad, 0, NULL, NULL }, - { "re_source", 0,POPT_ARG_STRING, &db3dbi.dbi_re_source, 0, + { "re_source", 0,POPT_ARG_STRING, &staticdbi.dbi_re_source, 0, NULL, NULL }, - { "q_extentsize", 0,POPT_ARG_INT, &db3dbi.dbi_q_extentsize, 0, + { "q_extentsize", 0,POPT_ARG_INT, &staticdbi.dbi_q_extentsize, 0, NULL, NULL }, POPT_TABLEEND }; -dbiIndex db3Free(dbiIndex dbi) +dbiIndex dbiFree(dbiIndex dbi) { if (dbi) { dbi->dbi_file = _free(dbi->dbi_file); @@ -221,10 +221,10 @@ dbiIndex db3Free(dbiIndex dbi) } /** @todo Set a reasonable "last gasp" default db config. */ -static const char * const db3_config_default = +static const char * const dbi_config_default = "db3:hash:mpool:cdb:verbose:mp_mmapsize=8Mb:cachesize=512Kb:pagesize=512:perms=0644"; -dbiIndex db3New(rpmdb rpmdb, rpmTag rpmtag) +dbiIndex dbiNew(rpmdb rpmdb, rpmTag rpmtag) { dbiIndex dbi = xcalloc(1, sizeof(*dbi)); char *dbOpts; @@ -235,7 +235,7 @@ dbiIndex db3New(rpmdb rpmdb, rpmTag rpmtag) dbOpts = _free(dbOpts); dbOpts = rpmExpand("%{_dbi_config}", NULL); if (!(dbOpts && *dbOpts && *dbOpts != '%')) { - dbOpts = rpmExpand(db3_config_default, NULL); + dbOpts = rpmExpand(dbi_config_default, NULL); } } @@ -244,7 +244,7 @@ dbiIndex db3New(rpmdb rpmdb, rpmTag rpmtag) char *o, *oe; char *p, *pe; - memset(&db3dbi, 0, sizeof(db3dbi)); + memset(&staticdbi, 0, sizeof(staticdbi)); /*=========*/ for (o = dbOpts; o && *o; o = oe) { const struct poptOption *opt; @@ -355,8 +355,8 @@ dbiIndex db3New(rpmdb rpmdb, rpmTag rpmtag) dbOpts = _free(dbOpts); - *dbi = db3dbi; /* structure assignment */ - memset(&db3dbi, 0, sizeof(db3dbi)); + *dbi = staticdbi; /* structure assignment */ + memset(&staticdbi, 0, sizeof(staticdbi)); if (!(dbi->dbi_perms & 0600)) dbi->dbi_perms = 0644; @@ -381,7 +381,7 @@ dbiIndex db3New(rpmdb rpmdb, rpmTag rpmtag) dbi->dbi_byteswapped = -1; /* -1 unknown, 0 native order, 1 alien order */ - if (!dbi->dbi_use_dbenv) { /* db3 dbenv is always used now. */ + if (!dbi->dbi_use_dbenv) { /* dbenv is always used now. */ dbi->dbi_use_dbenv = 1; dbi->dbi_eflags |= (DB_INIT_MPOOL|DB_JOINENV); dbi->dbi_mmapsize = 16 * 1024 * 1024; @@ -405,12 +405,12 @@ char * prDbiOpenFlags(int dbflags, int print_dbenv_flags) if (opt->argInfo != POPT_BIT_SET) continue; if (print_dbenv_flags) { - if (!(opt->arg == &db3dbi.dbi_oeflags || - opt->arg == &db3dbi.dbi_eflags)) + if (!(opt->arg == &staticdbi.dbi_oeflags || + opt->arg == &staticdbi.dbi_eflags)) continue; } else { - if (!(opt->arg == &db3dbi.dbi_oeflags || - opt->arg == &db3dbi.dbi_oflags)) + if (!(opt->arg == &staticdbi.dbi_oeflags || + opt->arg == &staticdbi.dbi_oflags)) continue; } if ((dbflags & opt->val) != opt->val) diff --git a/lib/backend/sqlite.c b/lib/backend/sqlite.c deleted file mode 100644 index 5a3b9fab8..000000000 --- a/lib/backend/sqlite.c +++ /dev/null @@ -1,1308 +0,0 @@ - -/* - * sqlite.c - * sqlite interface for rpmdb - * - * Author: Mark Hatle <mhatle@mvista.com> or <fray@kernel.crashing.org> - * Copyright (c) 2004 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * or GNU Library General Public License, at your option, - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * and GNU Library Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include "system.h" - -#include <sqlite3.h> - -#include <rpm/rpmtypes.h> -#include <rpm/rpmlog.h> -#include <rpm/rpmmacro.h> -#include <rpm/rpmfileutil.h> -#include <rpm/rpmstring.h> -#include <rpm/rpmdb.h> - -#include "lib/rpmdb_internal.h" - -#include "debug.h" - - -static int _debug = 0; - -/* Define the things normally in a header... */ -struct _sql_db_s; typedef struct _sql_db_s SQL_DB; -struct _sql_dbcursor_s; typedef struct _sql_dbcursor_s *SCP_t; - -struct _sql_db_s { - sqlite3 * db; /* Database pointer */ - int transaction; /* Do we have a transaction open? */ -}; - -struct _sql_dbcursor_s { - DB *dbp; - - char * cmd; /* SQL command string */ - sqlite3_stmt *pStmt; /* SQL byte code */ - const char * pzErrmsg; /* SQL error msg */ - - /* Table -- result of query */ - char ** av; /* item ptrs */ - int * avlen; /* item sizes */ - int nalloc; - int ac; /* no. of items */ - int rx; /* Which row are we on? 1, 2, 3 ... */ - int nr; /* no. of rows */ - int nc; /* no. of columns */ - - int all; /* sequential iteration cursor */ - DBT ** keys; /* array of package keys */ - int nkeys; - - int count; - - void * lkey; /* Last key returned */ - void * ldata; /* Last data returned */ - - int used; -}; - -union _dbswap { - uint64_t ul; - uint32_t ui[2]; - uint8_t uc[8]; -}; - -#define _DBSWAP(_a) \ - { unsigned char _b, *_c = (_a).uc; \ - _b = _c[7]; _c[7] = _c[0]; _c[0] = _b; \ - _b = _c[6]; _c[6] = _c[1]; _c[1] = _b; \ - _b = _c[5]; _c[5] = _c[2]; _c[2] = _b; \ - _b = _c[4]; _c[4] = _c[3]; _c[3] = _b; \ - } - -static const unsigned int endian = 0x11223344; - -static char * sqlCwd = NULL; -static int sqlInRoot = 0; - -static void enterChroot(dbiIndex dbi) -{ - int xx; - rpmdb db = dbi->dbi_rpmdb; - - if (rstreq(db->db_root, "/") || db->db_chrootDone || sqlInRoot) - /* Nothing to do, was not already in chroot */ - return; - -if (_debug) -fprintf(stderr, "sql:chroot(%s)\n", db->db_root); - - sqlCwd = rpmGetCwd(); - xx = chdir("/"); - xx = chroot(db->db_root); -assert(xx == 0); - sqlInRoot=1; -} - -static void leaveChroot(dbiIndex dbi) -{ - int xx; - rpmdb db = dbi->dbi_rpmdb; - - if (rstreq(db->db_root, "/") || db->db_chrootDone || !sqlInRoot) - /* Nothing to do, not in chroot */ - return; - -if (_debug) -fprintf(stderr, "sql:chroot(.)\n"); - - xx = chroot("."); -assert(xx == 0); - xx = chdir(sqlCwd); - sqlCwd = _free(sqlCwd); - - sqlInRoot=0; -} - -static void dbg_scp(void *ptr) -{ - SCP_t scp = ptr; - -if (_debug) -fprintf(stderr, "\tscp %p [%d:%d] av %p avlen %p nr [%d:%d] nc %d all %d\n", scp, scp->ac, scp->nalloc, scp->av, scp->avlen, scp->rx, scp->nr, scp->nc, scp->all); - -} - -static void dbg_keyval(const char * msg, dbiIndex dbi, DBC * dbcursor, - DBT * key, DBT * data, unsigned int flags) -{ - -if (!_debug) return; - - fprintf(stderr, "%s on %s (%p,%p,%p,0x%x)", msg, dbi->dbi_subfile, dbcursor, key, data, flags); - - /* XXX FIXME: ptr alignment is fubar here. */ - if (key != NULL && key->data != NULL) { - fprintf(stderr, " key 0x%x[%d]", *(unsigned int *)key->data, key->size); - if (dbi->dbi_rpmtag == RPMTAG_NAME) - fprintf(stderr, " \"%s\"", (const char *)key->data); - } - if (data != NULL && data->data != NULL) - fprintf(stderr, " data 0x%x[%d]", *(unsigned int *)data->data, data->size); - - fprintf(stderr, "\n"); - dbg_scp(dbcursor); -} - - -static SCP_t scpResetKeys(SCP_t scp) -{ - int ix; - -if (_debug) -fprintf(stderr, "*** %s(%p)\n", __FUNCTION__, scp); -dbg_scp(scp); - - for ( ix =0 ; ix < scp->nkeys ; ix++ ) { - scp->keys[ix]->data = _free(scp->keys[ix]->data); - scp->keys[ix] = _free(scp->keys[ix]); - } - scp->keys = _free(scp->keys); - scp->nkeys = 0; - - return scp; -} - - -static SCP_t scpResetAv(SCP_t scp) -{ - int xx; - -if (_debug) -fprintf(stderr, "*** %s(%p)\n", __FUNCTION__, scp); -dbg_scp(scp); - - if (scp->av) { - if (scp->nalloc <= 0) { - /* Clean up SCP_t used by sqlite3_get_table(). */ - sqlite3_free_table(scp->av); - scp->av = NULL; - scp->nalloc = 0; - } else { - /* Clean up SCP_t used by sql_step(). */ - for (xx = 0; xx < scp->ac; xx++) - scp->av[xx] = _free(scp->av[xx]); - if (scp->av != NULL) - memset(scp->av, 0, scp->nalloc * sizeof(*scp->av)); - if (scp->avlen != NULL) - memset(scp->avlen, 0, scp->nalloc * sizeof(*scp->avlen)); - scp->av = _free(scp->av); - scp->avlen = _free(scp->avlen); - scp->nalloc = 0; - } - } else - scp->nalloc = 0; - scp->ac = 0; - scp->nr = 0; - scp->nc = 0; - - return scp; -} - - -static SCP_t scpReset(SCP_t scp) -{ - int xx; - -if (_debug) -fprintf(stderr, "*** %s(%p)\n", __FUNCTION__, scp); -dbg_scp(scp); - - if (scp->cmd) { - sqlite3_free(scp->cmd); - scp->cmd = NULL; - } - if (scp->pStmt) { - xx = sqlite3_reset(scp->pStmt); - if (xx) rpmlog(RPMLOG_DEBUG, "reset %d\n", xx); - xx = sqlite3_finalize(scp->pStmt); - if (xx) rpmlog(RPMLOG_DEBUG, "finalize %d\n", xx); - scp->pStmt = NULL; - } - - scp = scpResetAv(scp); - - scp->rx = 0; - return scp; -} - -static SCP_t scpFree(SCP_t scp) -{ - scp = scpReset(scp); - scp = scpResetKeys(scp); - scp->av = _free(scp->av); - scp->avlen = _free(scp->avlen); - -if (_debug) -fprintf(stderr, "*** %s(%p)\n", __FUNCTION__, scp); - scp = _free(scp); - return NULL; -} - -static SCP_t scpNew(DB * dbp) -{ - SCP_t scp = xcalloc(1, sizeof(*scp)); - scp->dbp = dbp; - - scp->used = 0; - - scp->lkey = NULL; - scp->ldata = NULL; - -if (_debug) -fprintf(stderr, "*** %s(%p)\n", __FUNCTION__, scp); - return scp; -} - -static int sql_step(dbiIndex dbi, SCP_t scp) -{ - const char * cname; - const char * vtype; - size_t nb; - int loop; - int need; - int rc; - int i; - - scp->nc = sqlite3_column_count(scp->pStmt); - - if (scp->nr == 0 && scp->av != NULL) - need = 2 * scp->nc; - else - need = scp->nc; - - /* XXX scp->nc = need = scp->nalloc = 0 case forces + 1 here */ - if (!scp->ac && !need && !scp->nalloc) - need++; - - if (scp->ac + need >= scp->nalloc) { - /* XXX +4 is bogus, was +1 */ - scp->nalloc = 2 * scp->nalloc + need + 4; - scp->av = xrealloc(scp->av, scp->nalloc * sizeof(*scp->av)); - scp->avlen = xrealloc(scp->avlen, scp->nalloc * sizeof(*scp->avlen)); - } - - if (scp->nr == 0) { - for (i = 0; i < scp->nc; i++) { - scp->av[scp->ac] = xstrdup(sqlite3_column_name(scp->pStmt, i)); - if (scp->avlen) scp->avlen[scp->ac] = strlen(scp->av[scp->ac]) + 1; - scp->ac++; -assert(scp->ac <= scp->nalloc); - } - } - - loop = 1; - while (loop) { - rc = sqlite3_step(scp->pStmt); - switch (rc) { - case SQLITE_DONE: -if (_debug) -fprintf(stderr, "sqlite3_step: DONE scp %p [%d:%d] av %p avlen %p\n", scp, scp->ac, scp->nalloc, scp->av, scp->avlen); - loop = 0; - break; - case SQLITE_ROW: - if (scp->av != NULL) - for (i = 0; i < scp->nc; i++) { - /* Expand the row array for new elements */ - if (scp->ac + need >= scp->nalloc) { - /* XXX +4 is bogus, was +1 */ - scp->nalloc = 2 * scp->nalloc + need + 4; - scp->av = xrealloc(scp->av, scp->nalloc * sizeof(*scp->av)); - scp->avlen = xrealloc(scp->avlen, scp->nalloc * sizeof(*scp->avlen)); - } - - cname = sqlite3_column_name(scp->pStmt, i); - vtype = sqlite3_column_decltype(scp->pStmt, i); - nb = 0; - - if (rstreq(vtype, "blob")) { - const void * v = sqlite3_column_blob(scp->pStmt, i); - nb = sqlite3_column_bytes(scp->pStmt, i); -if (_debug) -fprintf(stderr, "\t%d %s %s %p[%zd]\n", i, cname, vtype, v, nb); - if (nb > 0) { - void * t = xmalloc(nb); - scp->av[scp->ac] = memcpy(t, v, nb); - scp->avlen[scp->ac] = nb; - scp->ac++; - } - } else - if (rstreq(vtype, "double")) { - double v = sqlite3_column_double(scp->pStmt, i); - nb = sizeof(v); -if (_debug) -fprintf(stderr, "\t%d %s %s %g\n", i, cname, vtype, v); - if (nb > 0) { - scp->av[scp->ac] = memcpy(xmalloc(nb), &v, nb); - scp->avlen[scp->ac] = nb; -assert(dbiByteSwapped(dbi) == 0); /* Byte swap?! */ - scp->ac++; - } - } else - if (rstreq(vtype, "int")) { - int32_t v = sqlite3_column_int(scp->pStmt, i); - nb = sizeof(v); -if (_debug) -fprintf(stderr, "\t%d %s %s %d\n", i, cname, vtype, v); - if (nb > 0) { - scp->av[scp->ac] = memcpy(xmalloc(nb), &v, nb); - scp->avlen[scp->ac] = nb; -if (dbiByteSwapped(dbi) == 1) -{ - union _dbswap dbswap; - memcpy(dbswap.ui, scp->av[scp->ac], sizeof(dbswap.ui)); - dbswap.ui[1] = 0; - _DBSWAP(dbswap); - memcpy(scp->av[scp->ac], dbswap.ui, sizeof(dbswap.ui)); -} - scp->ac++; - } - } else - if (rstreq(vtype, "int64")) { - int64_t v = sqlite3_column_int64(scp->pStmt, i); - nb = sizeof(v); -if (_debug) -fprintf(stderr, "\t%d %s %s %ld\n", i, cname, vtype, (long)v); - if (nb > 0) { - scp->av[scp->ac] = memcpy(xmalloc(nb), &v, nb); - scp->avlen[scp->ac] = nb; -assert(dbiByteSwapped(dbi) == 0); /* Byte swap?! */ - scp->ac++; - } - } else - if (rstreq(vtype, "text")) { - const char * v = (const char *) sqlite3_column_text(scp->pStmt, i); - nb = strlen(v) + 1; -if (_debug) -fprintf(stderr, "\t%d %s %s \"%s\"\n", i, cname, vtype, v); - if (nb > 0) { - scp->av[scp->ac] = memcpy(xmalloc(nb), v, nb); - scp->avlen[scp->ac] = nb; - scp->ac++; - } - } -assert(scp->ac <= scp->nalloc); - } - scp->nr++; - break; - case SQLITE_BUSY: - fprintf(stderr, "sqlite3_step: BUSY %d\n", rc); - break; - case SQLITE_ERROR: { - char *cwd = rpmGetCwd(); - fprintf(stderr, "sqlite3_step: ERROR %d -- %s\n", rc, scp->cmd); - fprintf(stderr, " %s (%d)\n", - sqlite3_errmsg(((SQL_DB*)dbi->dbi_db)->db), sqlite3_errcode(((SQL_DB*)dbi->dbi_db)->db)); - - fprintf(stderr, " cwd '%s'\n", cwd); - free(cwd); - loop = 0; - } - break; - case SQLITE_MISUSE: - fprintf(stderr, "sqlite3_step: MISUSE %d\n", rc); - loop = 0; - break; - default: - fprintf(stderr, "sqlite3_step: rc %d\n", rc); - loop = 0; - break; - } - } - - if (rc == SQLITE_DONE) - rc = SQLITE_OK; - - return rc; -} - -static int sql_bind_key(dbiIndex dbi, SCP_t scp, int pos, DBT * key) -{ - int rc = 0; - - union _dbswap dbswap; - -assert(key->data != NULL); - switch (dbi->dbi_rpmtag) { - case RPMDBI_PACKAGES: - { unsigned int hnum; -assert(key->size == sizeof(int32_t)); - memcpy(&hnum, key->data, sizeof(hnum)); - -if (dbiByteSwapped(dbi) == 1) -{ - memcpy(dbswap.ui, &hnum, sizeof(dbswap.ui)); - dbswap.ui[1] = 0; - _DBSWAP(dbswap); - memcpy(&hnum, dbswap.ui, sizeof(hnum)); -} - rc = sqlite3_bind_int(scp->pStmt, pos, hnum); - } break; - default: - switch (rpmTagGetType(dbi->dbi_rpmtag) & RPM_MASK_TYPE) { - case RPM_NULL_TYPE: - case RPM_BIN_TYPE: - rc = sqlite3_bind_blob(scp->pStmt, pos, key->data, key->size, SQLITE_STATIC); - break; - case RPM_CHAR_TYPE: - case RPM_INT8_TYPE: - { unsigned char i; -assert(key->size == sizeof(unsigned char)); -assert(dbiByteSwapped(dbi) == 0); /* Byte swap?! */ - memcpy(&i, key->data, sizeof(i)); - rc = sqlite3_bind_int(scp->pStmt, pos, i); - } break; - case RPM_INT16_TYPE: - { unsigned short i; -assert(key->size == sizeof(int16_t)); -assert(dbiByteSwapped(dbi) == 0); /* Byte swap?! */ - memcpy(&i, key->data, sizeof(i)); - rc = sqlite3_bind_int(scp->pStmt, pos, i); - } break; - case RPM_INT32_TYPE: - { uint32_t i; -assert(key->size == sizeof(int32_t)); - memcpy(&i, key->data, sizeof(i)); - -if (dbiByteSwapped(dbi) == 1) -{ - memcpy(dbswap.ui, &i, sizeof(dbswap.ui)); - dbswap.ui[1] = 0; - _DBSWAP(dbswap); - memcpy(&i, dbswap.ui, sizeof(i)); -} - rc = sqlite3_bind_int(scp->pStmt, pos, i); - } break; - case RPM_INT64_TYPE: - { uint64_t l; -assert(key->size == sizeof(int64_t)); - memcpy(&l, key->data, sizeof(l)); - -if (dbiByteSwapped(dbi) == 1) -{ - memcpy(&dbswap.ul, &l, sizeof(dbswap.ul)); - _DBSWAP(dbswap); - memcpy(&l, &dbswap.ul, sizeof(dbswap.ul)); -} - rc = sqlite3_bind_int(scp->pStmt, pos, l); - } break; - case RPM_STRING_TYPE: - case RPM_STRING_ARRAY_TYPE: - case RPM_I18NSTRING_TYPE: - rc = sqlite3_bind_text(scp->pStmt, pos, key->data, key->size, SQLITE_STATIC); - break; - default: - rc = 1; - break; - } - } - - return rc; -} - -static int sql_bind_data(dbiIndex dbi, SCP_t scp, int pos, DBT * data) -{ - int rc; - -assert(data->data != NULL); - rc = sqlite3_bind_blob(scp->pStmt, pos, data->data, data->size, SQLITE_STATIC); - - return rc; -} - -/*===================================================================*/ -/* - * Transaction support - */ - -static int sql_startTransaction(dbiIndex dbi) -{ - SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db; - int rc = 0; - - /* XXX: Transaction Support */ - if (!sqldb->transaction) { - char * pzErrmsg; - rc = sqlite3_exec(sqldb->db, "BEGIN TRANSACTION;", NULL, NULL, &pzErrmsg); - -if (_debug) -fprintf(stderr, "Begin %s SQL transaction %s (%d)\n", - dbi->dbi_subfile, pzErrmsg, rc); - - if (rc == 0) - sqldb->transaction = 1; - } - - return rc; -} - -static int sql_endTransaction(dbiIndex dbi) -{ - SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db; - int rc=0; - - /* XXX: Transaction Support */ - if (sqldb->transaction) { - char * pzErrmsg; - rc = sqlite3_exec(sqldb->db, "END TRANSACTION;", NULL, NULL, &pzErrmsg); - -if (_debug) -fprintf(stderr, "End %s SQL transaction %s (%d)\n", - dbi->dbi_subfile, pzErrmsg, rc); - - if (rc == 0) - sqldb->transaction = 0; - } - - return rc; -} - -static int sql_commitTransaction(dbiIndex dbi, int flag) -{ - SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db; - int rc = 0; - - /* XXX: Transactions */ - if ( sqldb->transaction ) { - char * pzErrmsg; - rc = sqlite3_exec(sqldb->db, "COMMIT;", NULL, NULL, &pzErrmsg); - -if (_debug) -fprintf(stderr, "Commit %s SQL transaction(s) %s (%d)\n", - dbi->dbi_subfile, pzErrmsg, rc); - - sqldb->transaction=0; - - /* Start a new transaction if we were in the middle of one */ - if ( flag == 0 ) - rc = sql_startTransaction(dbi); - } - - return rc; -} - -static int sql_busy_handler(void * dbi_void, int time) -{ - dbiIndex dbi = (dbiIndex) dbi_void; - - rpmlog(RPMLOG_WARNING, _("Unable to get lock on db %s, retrying... (%d)\n"), - dbi->dbi_file, time); - - (void) sleep(1); - - return 1; -} - -/*===================================================================*/ - -/** - * Verify the DB is setup.. if not initialize it - * - * Create the table.. create the db_info - */ -static int sql_initDB(dbiIndex dbi) -{ - SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db; - SCP_t scp = scpNew(dbi->dbi_db); - char *cmd = NULL; - int rc = 0; - - /* Check if the table exists... */ - rasprintf(&cmd, - "SELECT name FROM 'sqlite_master' WHERE type='table' and name='%s';", - dbi->dbi_subfile); - rc = sqlite3_get_table(sqldb->db, cmd, - &scp->av, &scp->nr, &scp->nc, (char **)&scp->pzErrmsg); - cmd = _free(cmd); - if (rc) - goto exit; - - if (scp->nr < 1) { - const char * valtype = "blob"; - const char * keytype; - - switch (dbi->dbi_rpmtag) { - case RPMDBI_PACKAGES: - keytype = "int UNIQUE PRIMARY KEY"; - valtype = "blob"; - break; - default: - switch (rpmTagGetType(dbi->dbi_rpmtag) & RPM_MASK_TYPE) { - case RPM_NULL_TYPE: - case RPM_BIN_TYPE: - keytype = "blob UNIQUE"; - break; - case RPM_CHAR_TYPE: - case RPM_INT8_TYPE: - case RPM_INT16_TYPE: - case RPM_INT32_TYPE: - case RPM_INT64_TYPE: - keytype = "int UNIQUE"; - break; - case RPM_STRING_TYPE: - case RPM_STRING_ARRAY_TYPE: - case RPM_I18NSTRING_TYPE: - keytype = "text UNIQUE"; - break; - default: - rc = 1; - goto exit; - break; - } - } -if (_debug) -fprintf(stderr, "\t%s(%d) type(%d) keytype %s\n", rpmTagGetName(dbi->dbi_rpmtag), dbi->dbi_rpmtag, rpmTagGetType(dbi->dbi_rpmtag), keytype); - rasprintf(&cmd, "CREATE %sTABLE '%s' (key %s, value %s)", - dbi->dbi_rpmtag == RPMDBI_DEPENDS ? "TEMPORARY " : " ", - dbi->dbi_subfile, keytype, valtype); - rc = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg); - cmd = _free(cmd); - if (rc) - goto exit; - - rasprintf(&cmd, "CREATE %sTABLE 'db_info' (endian TEXT)", - dbi->dbi_rpmtag == RPMDBI_DEPENDS ? "TEMPORARY " : " "); - rc = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg); - cmd = _free(cmd); - if (rc) - goto exit; - - rasprintf(&cmd, "INSERT INTO 'db_info' values('%d')", ((union _dbswap *)&endian)->uc[0]); - rc = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg); - _free(cmd); - if (rc) - goto exit; - } - - if (dbi->dbi_no_fsync) { - int xx; - rasprintf(&cmd, "PRAGMA synchronous = OFF;"); - xx = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg); - cmd = _free(cmd); - } - -exit: - if (rc) - rpmlog(RPMLOG_WARNING, _("Unable to initDB %s (%d)\n"), - scp->pzErrmsg, rc); - - scp = scpFree(scp); - - return rc; -} - -/** - * Close database cursor. - * @param dbi index database handle - * @param dbcursor database cursor - * @param flags (unused) - * @return 0 on success - */ -static int sql_cclose (dbiIndex dbi, DBC * dbcursor, - unsigned int flags) -{ - SCP_t scp = (SCP_t)dbcursor; - int rc; - -if (_debug) -fprintf(stderr, "==> %s(%p)\n", __FUNCTION__, scp); - - if (scp->lkey) - scp->lkey = _free(scp->lkey); - - if (scp->ldata) - scp->ldata = _free(scp->ldata); - -enterChroot(dbi); - - if (flags == DB_WRITECURSOR) - rc = sql_commitTransaction(dbi, 1); - else - rc = sql_endTransaction(dbi); - - scp = scpFree(scp); - -leaveChroot(dbi); - - return rc; -} - -/** - * Close index database, and destroy database handle. - * @param dbi index database handle - * @param flags (unused) - * @return 0 on success - */ -static int sql_close(dbiIndex dbi, unsigned int flags) -{ - SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db; - int rc = 0; - - if (sqldb) { -enterChroot(dbi); - - /* Commit, don't open a new one */ - rc = sql_commitTransaction(dbi, 1); - - (void) sqlite3_close(sqldb->db); - - rpmlog(RPMLOG_DEBUG, "closed sql db %s\n", - dbi->dbi_subfile); - -leaveChroot(dbi); - } - - dbi = db3Free(dbi); - - return rc; -} - -/** - * Return handle for an index database. - * @param rpmdb rpm database - * @param rpmtag rpm tag - * @param dbip - * @return 0 on success - */ -static int sql_open(rpmdb rpmdb, rpmTag rpmtag, dbiIndex * dbip) -{ - extern const struct _dbiVec sqlitevec; - - char * dbhome; - char * dbfname; - const char * sql_errcode; - dbiIndex dbi; - SQL_DB * sqldb; - int rc = 0; - int xx; - - if (dbip) - *dbip = NULL; - - /* - * Parse db configuration parameters. - */ - if ((dbi = db3New(rpmdb, rpmtag)) == NULL) - return 1; - -enterChroot(dbi); - - /* sqlite uses subfile for table name */ - dbi->dbi_subfile = xstrdup(dbi->dbi_file); - - dbi->dbi_mode=O_RDWR; - - dbhome = rpmGenPath(NULL, rpmdb->db_home, NULL); - - dbfname = rpmGenPath(dbhome, dbi->dbi_file, NULL); - - rpmlog(RPMLOG_DEBUG, "opening sql db %s (%s) mode=0x%x\n", - dbfname, dbi->dbi_subfile, dbi->dbi_mode); - - /* Open the Database */ - sqldb = xcalloc(1,sizeof(*sqldb)); - - sql_errcode = NULL; - xx = sqlite3_open(dbfname, &sqldb->db); - if (xx != SQLITE_OK) - sql_errcode = sqlite3_errmsg(sqldb->db); - - if (sqldb->db) - (void) sqlite3_busy_handler(sqldb->db, &sql_busy_handler, dbi); - - sqldb->transaction = 0; /* Initialize no current transactions */ - - dbi->dbi_db = (DB *)sqldb; - - if (sql_errcode != NULL) { - rpmlog(RPMLOG_ERR, _("Unable to open database: %s\n"), sql_errcode); - rc = EINVAL; - } - - /* initialize table */ - if (rc == 0) - rc = sql_initDB(dbi); - - if (rc == 0 && dbi->dbi_db != NULL && dbip != NULL) { - dbi->dbi_vec = &sqlitevec; - *dbip = dbi; - } else { - (void) sql_close(dbi, 0); - } - - free(dbhome); - dbfname = _free(dbfname); - -leaveChroot(dbi); - - return rc; -} - -/** - * Flush pending operations to disk. - * @param dbi index database handle - * @param flags (unused) - * @return 0 on success - */ -static int sql_sync (dbiIndex dbi, unsigned int flags) -{ - int rc = 0; - -enterChroot(dbi); - rc = sql_commitTransaction(dbi, 0); -leaveChroot(dbi); - - return rc; -} - -/** - * Open database cursor. - * @param dbi index database handle - * @param txnid database transaction handle - * @retval dbcp address of new database cursor - * @param flags DB_WRITECURSOR or 0 - * @return 0 on success - */ -static int sql_copen (dbiIndex dbi, DB_TXN * txnid, - DBC ** dbcp, unsigned int flags) -{ - SCP_t scp = scpNew(dbi->dbi_db); - DBC * dbcursor = (DBC *)scp; - int rc = 0; - -if (_debug) -fprintf(stderr, "==> %s(%s) tag %d type %d scp %p\n", __FUNCTION__, rpmTagGetName(dbi->dbi_rpmtag), dbi->dbi_rpmtag, rpmTagGetType(dbi->dbi_rpmtag), scp); - -enterChroot(dbi); - - /* If we're going to write, start a transaction (lock the DB) */ - if (flags == DB_WRITECURSOR) - rc = sql_startTransaction(dbi); - - if (dbcp) - *dbcp = dbcursor; - else - (void) sql_cclose(dbi, dbcursor, 0); - -leaveChroot(dbi); - - return rc; -} - -/** - * Delete (key,data) pair(s) using db->del or dbcursor->c_del. - * @param dbi index database handle - * @param dbcursor database cursor (NULL will use db->del) - * @param key delete key value/length/flags - * @param data delete data value/length/flags - * @param flags (unused) - * @return 0 on success - */ -static int sql_cdel (dbiIndex dbi, DBC * dbcursor, DBT * key, - DBT * data, unsigned int flags) -{ - SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db; - SCP_t scp = scpNew(dbi->dbi_db); - int rc = 0; - -dbg_keyval(__FUNCTION__, dbi, dbcursor, key, data, flags); -enterChroot(dbi); - - scp->cmd = sqlite3_mprintf("DELETE FROM '%q' WHERE key=? AND value=?;", - dbi->dbi_subfile); - - rc = sqlite3_prepare(sqldb->db, scp->cmd, strlen(scp->cmd), &scp->pStmt, &scp->pzErrmsg); - if (rc) rpmlog(RPMLOG_DEBUG, "cdel(%s) prepare %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc); - rc = sql_bind_key(dbi, scp, 1, key); - if (rc) rpmlog(RPMLOG_DEBUG, "cdel(%s) bind key %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc); - rc = sql_bind_data(dbi, scp, 2, data); - if (rc) rpmlog(RPMLOG_DEBUG, "cdel(%s) bind data %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc); - - rc = sql_step(dbi, scp); - if (rc) rpmlog(RPMLOG_DEBUG, "cdel(%s) sql_step rc %d\n", dbi->dbi_subfile, rc); - - scp = scpFree(scp); - -leaveChroot(dbi); - - return rc; -} - -/** - * Retrieve (key,data) pair using db->get or dbcursor->c_get. - * @param dbi index database handle - * @param dbcursor database cursor (NULL will use db->get) - * @param key retrieve key value/length/flags - * @param data retrieve data value/length/flags - * @param flags (unused) - * @return 0 on success - */ -static int sql_cget (dbiIndex dbi, DBC * dbcursor, DBT * key, - DBT * data, unsigned int flags) -{ - SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db; - SCP_t scp = (SCP_t)dbcursor; - int rc = 0; - int ix; - -dbg_keyval(__FUNCTION__, dbi, dbcursor, key, data, flags); - -enterChroot(dbi); - - /* - * First determine if this is a new scan or existing scan - */ - -if (_debug) -fprintf(stderr, "\tcget(%s) scp %p rc %d flags %d av %p\n", - dbi->dbi_subfile, scp, rc, flags, scp->av); - if ( flags == DB_SET || scp->used == 0 ) { - scp->used = 1; /* Signal this scp as now in use... */ - scp = scpReset(scp); /* Free av and avlen, reset counters.*/ - -/* XXX: Should we also reset the key table here? Can you re-use a cursor? */ - - /* - * If we're scanning everything, load the iterator key table - */ - if ( key->size == 0) { - scp->all = 1; - -/* - * The only condition not dealt with is if there are multiple identical keys. This can lead - * to later iteration confusion. (It may return the same value for the multiple keys.) - */ - -/* Only RPMDBI_PACKAGES is supposed to be iterating, and this is guarenteed to be unique */ -assert(dbi->dbi_rpmtag == RPMDBI_PACKAGES); - - switch (dbi->dbi_rpmtag) { - case RPMDBI_PACKAGES: - scp->cmd = sqlite3_mprintf("SELECT key FROM '%q' ORDER BY key;", - dbi->dbi_subfile); - break; - default: - scp->cmd = sqlite3_mprintf("SELECT key FROM '%q';", - dbi->dbi_subfile); - break; - } - rc = sqlite3_prepare(sqldb->db, scp->cmd, strlen(scp->cmd), &scp->pStmt, &scp->pzErrmsg); - if (rc) rpmlog(RPMLOG_DEBUG, "cget(%s) sequential prepare %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc); - - rc = sql_step(dbi, scp); - if (rc) rpmlog(RPMLOG_DEBUG, "cget(%s) sequential sql_step rc %d\n", dbi->dbi_subfile, rc); - - scp = scpResetKeys(scp); - scp->nkeys = scp->nr; - scp->keys = xcalloc(scp->nkeys, sizeof(*scp->keys)); - for (ix = 0; ix < scp->nkeys; ix++) { - scp->keys[ix] = xmalloc(sizeof(DBT)); - scp->keys[ix]->size = scp->avlen[ix+1]; - scp->keys[ix]->data = xmalloc(scp->keys[ix]->size); - memcpy(scp->keys[ix]->data, scp->av[ix+1], scp->avlen[ix+1]); - } - } else { - /* - * We're only scanning ONE element - */ - scp = scpResetKeys(scp); - scp->nkeys = 1; - scp->keys = xcalloc(scp->nkeys, sizeof(*scp->keys)); - scp->keys[0] = xmalloc(sizeof(DBT)); - scp->keys[0]->size = key->size; - scp->keys[0]->data = xmalloc(scp->keys[0]->size); - memcpy(scp->keys[0]->data, key->data, key->size); - } - - scp = scpReset(scp); /* reset */ - - /* Prepare SQL statement to retrieve the value for the current key */ - scp->cmd = sqlite3_mprintf("SELECT value FROM '%q' WHERE key=?;", dbi->dbi_subfile); - rc = sqlite3_prepare(sqldb->db, scp->cmd, strlen(scp->cmd), &scp->pStmt, &scp->pzErrmsg); - - if (rc) rpmlog(RPMLOG_DEBUG, "cget(%s) prepare %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc); - } - - scp = scpResetAv(scp); /* Free av and avlen, reset counters.*/ - - /* Now continue with a normal retrive based on key */ - if ((scp->rx + 1) > scp->nkeys ) - rc = DB_NOTFOUND; /* At the end of the list */ - - if (rc != 0) - goto exit; - - /* Bind key to prepared statement */ - rc = sql_bind_key(dbi, scp, 1, scp->keys[scp->rx]); - if (rc) rpmlog(RPMLOG_DEBUG, "cget(%s) key bind %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc); - - rc = sql_step(dbi, scp); - if (rc) rpmlog(RPMLOG_DEBUG, "cget(%s) sql_step rc %d\n", dbi->dbi_subfile, rc); - - rc = sqlite3_reset(scp->pStmt); - if (rc) rpmlog(RPMLOG_DEBUG, "reset %d\n", rc); - -/* 1 key should return 0 or 1 row/value */ -assert(scp->nr < 2); - - if (scp->nr == 0 && scp->all == 0) - rc = DB_NOTFOUND; /* No data for that key found! */ - - if (rc != 0) - goto exit; - - /* If we're looking at the whole db, return the key */ - if (scp->all) { - -/* To get this far there has to be _1_ key returned! (protect against dup keys) */ -assert(scp->nr == 1); - - if ( scp->lkey ) { - scp->lkey = _free(scp->lkey); - } - - key->size = scp->keys[scp->rx]->size; - key->data = xmalloc(key->size); - if (! (key->flags & DB_DBT_MALLOC)) - scp->lkey = key->data; - - (void) memcpy(key->data, scp->keys[scp->rx]->data, key->size); - } - - /* Construct and return the data element (element 0 is "value", 1 is _THE_ value)*/ - switch (dbi->dbi_rpmtag) { - default: - if ( scp->ldata ) { - scp->ldata = _free(scp->ldata); - } - - data->size = scp->avlen[1]; - data->data = xmalloc(data->size); - if (! (data->flags & DB_DBT_MALLOC) ) - scp->ldata = data->data; - - (void) memcpy(data->data, scp->av[1], data->size); - } - - scp->rx++; - - /* XXX FIXME: ptr alignment is fubar here. */ -if (_debug) -fprintf(stderr, "\tcget(%s) found key 0x%x (%d)\n", dbi->dbi_subfile, - key->data == NULL ? 0 : *(unsigned int *)key->data, key->size); -if (_debug) -fprintf(stderr, "\tcget(%s) found data 0x%x (%d)\n", dbi->dbi_subfile, - key->data == NULL ? 0 : *(unsigned int *)data->data, data->size); - -exit: - if (rc == DB_NOTFOUND) { -if (_debug) -fprintf(stderr, "\tcget(%s) not found\n", dbi->dbi_subfile); - } - -leaveChroot(dbi); - - return rc; -} - -/** - * Store (key,data) pair using db->put or dbcursor->c_put. - * @param dbi index database handle - * @param dbcursor database cursor (NULL will use db->put) - * @param key store key value/length/flags - * @param data store data value/length/flags - * @param flags (unused) - * @return 0 on success - */ -static int sql_cput (dbiIndex dbi, DBC * dbcursor, DBT * key, - DBT * data, unsigned int flags) -{ - SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db; - SCP_t scp = scpNew(dbi->dbi_db); - int rc = 0; - -dbg_keyval(__FUNCTION__, dbi, dbcursor, key, data, flags); - -enterChroot(dbi); - - switch (dbi->dbi_rpmtag) { - default: - scp->cmd = sqlite3_mprintf("INSERT OR REPLACE INTO '%q' VALUES(?, ?);", - dbi->dbi_subfile); - rc = sqlite3_prepare(sqldb->db, scp->cmd, strlen(scp->cmd), &scp->pStmt, &scp->pzErrmsg); - if (rc) rpmlog(RPMLOG_DEBUG, "cput(%s) prepare %s (%d)\n",dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc); - rc = sql_bind_key(dbi, scp, 1, key); - if (rc) rpmlog(RPMLOG_DEBUG, "cput(%s) key bind %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc); - rc = sql_bind_data(dbi, scp, 2, data); - if (rc) rpmlog(RPMLOG_DEBUG, "cput(%s) data bind %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc); - - rc = sql_step(dbi, scp); - if (rc) rpmlog(RPMLOG_DEBUG, "cput(%s) sql_step rc %d\n", dbi->dbi_subfile, rc); - - break; - } - - scp = scpFree(scp); - -leaveChroot(dbi); - - return rc; -} - -/** - * Is database byte swapped? - * @param dbi index database handle - * @return 0 no - */ -static int sql_byteswapped (dbiIndex dbi) -{ - SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db; - SCP_t scp = scpNew(dbi->dbi_db); - int sql_rc, rc = 0; - union _dbswap db_endian; - -enterChroot(dbi); - - sql_rc = sqlite3_get_table(sqldb->db, "SELECT endian FROM 'db_info';", - &scp->av, &scp->nr, &scp->nc, (char **)&scp->pzErrmsg); - - if (sql_rc == 0 && scp->nr > 0) { -assert(scp->av != NULL); - db_endian.uc[0] = strtol(scp->av[1], NULL, 10); - - if ( db_endian.uc[0] == ((union _dbswap *)&endian)->uc[0] ) - rc = 0; /* Native endian */ - else - rc = 1; /* swapped */ - - } else { - if ( sql_rc ) { - rpmlog(RPMLOG_DEBUG, "db_info failed %s (%d)\n", - scp->pzErrmsg, sql_rc); - } - rpmlog(RPMLOG_WARNING, _("Unable to determine DB endianess.\n")); - } - - scp = scpFree(scp); - -leaveChroot(dbi); - - return rc; -} - -/************************************************** - * - * All of the following are not implemented! - * they are not used by the rest of the system - * - **************************************************/ - -/** - * Retrieve count of (possible) duplicate items using dbcursor->c_count. - * @param dbi index database handle - * @param dbcursor database cursor - * @param countp address of count - * @param flags (unused) - * @return 0 on success - */ -static int sql_ccount (dbiIndex dbi, DBC * dbcursor, - unsigned int * countp, - unsigned int flags) -{ -if (_debug) -fprintf(stderr, "*** %s:\n", __FUNCTION__); - return EINVAL; -} - -/** \ingroup dbi - * Save statistics in database handle. - * @param dbi index database handle - * @param flags retrieve statistics that don't require traversal? - * @return 0 on success - */ -static int sql_stat (dbiIndex dbi, unsigned int flags) -{ - SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db; - SCP_t scp = scpNew(dbi->dbi_db); - int rc = 0; - long nkeys = -1; - -enterChroot(dbi); - - dbi->dbi_stats = _free(dbi->dbi_stats); - - dbi->dbi_stats = xcalloc(1, sizeof(DB_HASH_STAT)); - - scp->cmd = sqlite3_mprintf("SELECT COUNT('key') FROM '%q';", dbi->dbi_subfile); - rc = sqlite3_get_table(sqldb->db, scp->cmd, - &scp->av, &scp->nr, &scp->nc, (char **)&scp->pzErrmsg); - - if ( rc == 0 && scp->nr > 0) { -assert(scp->av != NULL); - nkeys = strtol(scp->av[1], NULL, 10); - - rpmlog(RPMLOG_DEBUG, " stat on %s nkeys %ld\n", - dbi->dbi_subfile, nkeys); - } else { - if ( rc ) { - rpmlog(RPMLOG_DEBUG, "stat failed %s (%d)\n", - scp->pzErrmsg, rc); - } - } - - if (nkeys < 0) - nkeys = 4096; /* Good high value */ - - ((DB_HASH_STAT *)(dbi->dbi_stats))->hash_nkeys = nkeys; - - scp = scpFree(scp); - -leaveChroot(dbi); - - return rc; -} - -/* Major, minor, patch version of DB.. we're not using db.. so set to 0 */ -/* open, close, sync, associate, join */ -/* cursor_open, cursor_close, cursor_dup, cursor_delete, cursor_get, */ -/* cursor_pget?, cursor_put, cursor_count */ -/* db_bytewapped, stat */ -RPM_GNUC_INTERNAL -const struct _dbiVec sqlitevec = { - 0, 0, 0, - sql_open, - sql_close, - sql_sync, - sql_copen, - sql_cclose, - sql_cdel, - sql_cget, - sql_cput, - sql_ccount, - sql_byteswapped, - sql_stat -}; - diff --git a/lib/rpmdb.c b/lib/rpmdb.c index f6028e148..52d2437a4 100644 --- a/lib/rpmdb.c +++ b/lib/rpmdb.c @@ -172,27 +172,6 @@ static void dbiTagsFree(void) dbiTags.max = 0; } -#define DB1vec NULL -#define DB2vec NULL - -#ifdef HAVE_DB_H -extern struct _dbiVec db3vec; -#define DB3vec &db3vec -#else -#define DB3vec NULL -#endif - -#ifdef HAVE_SQLITE3_H -extern struct _dbiVec sqlitevec; -#define SQLITEvec &sqlitevec -#else -#define SQLITEvec NULL -#endif - -static struct _dbiVec * const mydbvecs[] = { - DB1vec, DB1vec, DB2vec, DB3vec, SQLITEvec, NULL -}; - dbiIndex dbiOpen(rpmdb db, rpmTag rpmtag, unsigned int flags) { int dbix; @@ -224,74 +203,27 @@ dbiIndex dbiOpen(rpmdb db, rpmTag rpmtag, unsigned int flags) _dbapi_rebuild = 4; /* _dbapi_wanted = (_rebuildinprogress ? -1 : db->db_api); */ _dbapi_wanted = (_rebuildinprogress ? _dbapi_rebuild : db->db_api); - - switch (_dbapi_wanted) { - default: - _dbapi = _dbapi_wanted; - if (_dbapi < 0 || _dbapi >= 5 || mydbvecs[_dbapi] == NULL) { - rpmlog(RPMLOG_ERR, _("dbiOpen: dbapi %d not available\n"), _dbapi); - return NULL; - } - errno = 0; - dbi = NULL; - rc = (*mydbvecs[_dbapi]->open) (db, rpmtag, &dbi); - if (rc) { - static int _printed[32]; - if (!_printed[dbix & 0x1f]++) - rpmlog(RPMLOG_ERR, - _("cannot open %s index using db%d - %s (%d)\n"), - rpmTagGetName(rpmtag), _dbapi, - (rc > 0 ? strerror(rc) : ""), rc); - _dbapi = -1; - } - break; - case -1: + if (_dbapi == -1) { _dbapi = 5; - while (_dbapi-- > 1) { - if (mydbvecs[_dbapi] == NULL) - continue; - errno = 0; - dbi = NULL; - rc = (*mydbvecs[_dbapi]->open) (db, rpmtag, &dbi); - if (rc == 0 && dbi) - break; - } - if (_dbapi <= 0) { - static int _printed[32]; - if (!_printed[dbix & 0x1f]++) - rpmlog(RPMLOG_ERR, _("cannot open %s index\n"), - rpmTagGetName(rpmtag)); - rc = 1; - goto exit; - } - if (db->db_api == -1 && _dbapi > 0) - db->db_api = _dbapi; - break; } -/* We don't ever _REQUIRE_ conversion... */ -#define SQLITE_HACK -#ifdef SQLITE_HACK_XXX - /* Require conversion. */ - if (rc && _dbapi_wanted >= 0 && _dbapi != _dbapi_wanted && _dbapi_wanted == _dbapi_rebuild) { - rc = (_rebuildinprogress ? 0 : 1); - goto exit; - } - - /* Suggest possible configuration */ - if (_dbapi_wanted >= 0 && _dbapi != _dbapi_wanted) { - rc = 1; - goto exit; + if (_dbapi != 5) { + rpmlog(RPMLOG_ERR, _("dbiOpen: dbapi %d not available\n"), _dbapi); + return NULL; } - - /* Suggest possible configuration */ - if (_dbapi_wanted < 0 && _dbapi != _dbapi_rebuild) { - rc = (_rebuildinprogress ? 0 : 1); - goto exit; + errno = 0; + dbi = NULL; + rc = dbiOpenDB(db, rpmtag, &dbi); + if (rc) { + static int _printed[32]; + if (!_printed[dbix & 0x1f]++) + rpmlog(RPMLOG_ERR, + _("cannot open %s index using db%d - %s (%d)\n"), + rpmTagGetName(rpmtag), _dbapi, + (rc > 0 ? strerror(rc) : ""), rc); + _dbapi = -1; } -#endif -exit: if (dbi != NULL && rc == 0) { db->_dbi[dbix] = dbi; if (rpmtag == RPMDBI_PACKAGES && db->db_bits == NULL) { @@ -306,37 +238,13 @@ exit: } #ifdef HAVE_DB_H else - dbi = db3Free(dbi); + dbi = dbiFree(dbi); #endif /* FIX: db->_dbi may be NULL */ return dbi; } -/* Retrieve (key,data) pair from index database. */ -int dbiGet(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, - unsigned int flags) -{ - int rc; - assert((flags == DB_NEXT) || (key->data != NULL && key->size > 0)); - (void) rpmswEnter(&dbi->dbi_rpmdb->db_getops, 0); - rc = (dbi->dbi_vec->cget) (dbi, dbcursor, key, data, flags); - (void) rpmswExit(&dbi->dbi_rpmdb->db_getops, data->size); - return rc; -} - -/* Store (key,data) pair in index database. */ -int dbiPut(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, - unsigned int flags) -{ - int rc; - assert(key->data != NULL && key->size > 0 && data->data != NULL && data->size > 0); - (void) rpmswEnter(&dbi->dbi_rpmdb->db_putops, (ssize_t) 0); - rc = (dbi->dbi_vec->cput) (dbi, dbcursor, key, data, flags); - (void) rpmswExit(&dbi->dbi_rpmdb->db_putops, (ssize_t) data->size); - return rc; -} - /** * Create and initialize item for index database set. * @param hdrNum header instance in db @@ -2019,7 +1927,7 @@ top: /* * If we got the next key, save the header instance number. * - * For db3 Packages, instance 0 (i.e. mi->mi_setx == 0) is the + * Instance 0 (i.e. mi->mi_setx == 0) is the * largest header instance in the database, and should be * skipped. */ diff --git a/lib/rpmdb.h b/lib/rpmdb.h index 30465eea8..33afa6449 100644 --- a/lib/rpmdb.h +++ b/lib/rpmdb.h @@ -1,7 +1,7 @@ #ifndef H_RPMDB #define H_RPMDB -/** \ingroup rpmdb dbi db1 db3 +/** \ingroup rpmdb dbi * \file lib/rpmdb.h * Access RPM indices using Berkeley DB interface(s). */ diff --git a/lib/rpmdb_internal.h b/lib/rpmdb_internal.h index 7f5a1587c..d986d094f 100644 --- a/lib/rpmdb_internal.h +++ b/lib/rpmdb_internal.h @@ -42,123 +42,7 @@ struct _dbiIndexSet { }; /** \ingroup dbi - * Private methods for accessing an index database. - */ -struct _dbiVec { - int dbv_major; /*!< Berkeley db version major */ - int dbv_minor; /*!< Berkeley db version minor */ - int dbv_patch; /*!< Berkeley db version patch */ - -/** \ingroup dbi - * Return handle for an index database. - * @param rpmdb rpm database - * @param rpmtag rpm tag - * @return 0 on success - */ - int (*open) (rpmdb rpmdb, rpmTag rpmtag, dbiIndex * dbip); - -/** \ingroup dbi - * Close index database, and destroy database handle. - * @param dbi index database handle - * @param flags (unused) - * @return 0 on success - */ - int (*close) (dbiIndex dbi, unsigned int flags); - -/** \ingroup dbi - * Flush pending operations to disk. - * @param dbi index database handle - * @param flags (unused) - * @return 0 on success - */ - int (*sync) (dbiIndex dbi, unsigned int flags); - -/** \ingroup dbi - * Open database cursor. - * @param dbi index database handle - * @param txnid database transaction handle - * @retval dbcp address of new database cursor - * @param dbiflags DB_WRITECURSOR or 0 - * @return 0 on success - */ - int (*copen) (dbiIndex dbi, DB_TXN * txnid, - DBC ** dbcp, unsigned int dbiflags); - -/** \ingroup dbi - * Close database cursor. - * @param dbi index database handle - * @param dbcursor database cursor - * @param flags (unused) - * @return 0 on success - */ - int (*cclose) (dbiIndex dbi, DBC * dbcursor, unsigned int flags); - -/** \ingroup dbi - * Delete (key,data) pair(s) using db->del or dbcursor->c_del. - * @param dbi index database handle - * @param dbcursor database cursor (NULL will use db->del) - * @param key delete key value/length/flags - * @param data delete data value/length/flags - * @param flags (unused) - * @return 0 on success - */ - int (*cdel) (dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, - unsigned int flags); - -/** \ingroup dbi - * Retrieve (key,data) pair using db->get or dbcursor->c_get. - * @param dbi index database handle - * @param dbcursor database cursor (NULL will use db->get) - * @param key retrieve key value/length/flags - * @param data retrieve data value/length/flags - * @param flags (unused) - * @return 0 on success - */ - int (*cget) (dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, - unsigned int flags); - -/** \ingroup dbi - * Store (key,data) pair using db->put or dbcursor->c_put. - * @param dbi index database handle - * @param dbcursor database cursor (NULL will use db->put) - * @param key store key value/length/flags - * @param data store data value/length/flags - * @param flags (unused) - * @return 0 on success - */ - int (*cput) (dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, - unsigned int flags); - -/** \ingroup dbi - * Retrieve count of (possible) duplicate items using dbcursor->c_count. - * @param dbi index database handle - * @param dbcursor database cursor - * @param countp address of count - * @param flags (unused) - * @return 0 on success - */ - int (*ccount) (dbiIndex dbi, DBC * dbcursor, - unsigned int * countp, - unsigned int flags); - -/** \ingroup dbi - * Is database byte swapped? - * @param dbi index database handle - * @return 0 no - */ - int (*byteswapped) (dbiIndex dbi); - -/** \ingroup dbi - * Save statistics in database handle. - * @param dbi index database handle - * @param flags retrieve statistics that don't require traversal? - * @return 0 on success - */ - int (*stat) (dbiIndex dbi, unsigned int flags); -}; - -/** \ingroup dbi - * Describes an index database (implemented on Berkeley db3 functionality). + * Describes an index database (implemented on Berkeley db functionality). */ struct _dbiIndex { char * dbi_file; /*!< file component of path */ @@ -245,9 +129,6 @@ unsigned char * dbi_lk_conflicts; DB * dbi_db; /*!< Berkeley DB * handle */ DB_TXN * dbi_txnid; /*!< Bekerley DB_TXN * transaction id */ void * dbi_stats; /*!< Berkeley db statistics */ - - const struct _dbiVec * dbi_vec; /*!< private methods */ - }; /** \ingroup rpmdb @@ -300,25 +181,25 @@ enum rpmdbFlags { extern "C" { #endif -/** \ingroup db3 +/** \ingroup dbi * Return new configured index database handle instance. * @param rpmdb rpm database * @param rpmtag rpm tag * @return index database handle */ RPM_GNUC_INTERNAL -dbiIndex db3New(rpmdb rpmdb, rpmTag rpmtag); +dbiIndex dbiNew(rpmdb rpmdb, rpmTag rpmtag); -/** \ingroup db3 +/** \ingroup dbi * Destroy index database handle instance. * @param dbi index database handle * @return NULL always */ RPM_GNUC_INTERNAL -dbiIndex db3Free( dbiIndex dbi); +dbiIndex dbiFree( dbiIndex dbi); -/** \ingroup db3 - * Format db3 open flags for debugging print. +/** \ingroup dbi + * Format dbi open flags for debugging print. * @param dbflags db open flags * @param print_dbenv_flags format db env flags instead? * @return formatted flags (malloced) @@ -337,6 +218,18 @@ RPM_GNUC_INTERNAL dbiIndex dbiOpen(rpmdb db, rpmTag rpmtag, unsigned int flags); + +/** \ingroup dbi + * Actually open the database of the index. + * @param db rpm database + * @param rpmtag rpm tag + * @param dbiIndex address of index database handle + * @return 0 on success + */ +RPM_GNUC_INTERNAL +int dbiOpenDB(rpmdb rpmdb, rpmTag rpmtag, dbiIndex * dbip); + + /* FIX: vector annotations */ /** \ingroup dbi * Open a database cursor. @@ -346,12 +239,9 @@ dbiIndex dbiOpen(rpmdb db, rpmTag rpmtag, * @param flags DB_WRITECURSOR if writing, or 0 * @return 0 on success */ -static inline +RPM_GNUC_INTERNAL int dbiCopen(dbiIndex dbi, DB_TXN * txnid, - DBC ** dbcp, unsigned int flags) -{ - return (*dbi->dbi_vec->copen) (dbi, txnid, dbcp, flags); -} + DBC ** dbcp, unsigned int flags); /** \ingroup dbi * Close a database cursor. @@ -360,11 +250,8 @@ int dbiCopen(dbiIndex dbi, DB_TXN * txnid, * @param flags (unused) * @return 0 on success */ -static inline -int dbiCclose(dbiIndex dbi, DBC * dbcursor, unsigned int flags) -{ - return (*dbi->dbi_vec->cclose) (dbi, dbcursor, flags); -} +RPM_GNUC_INTERNAL +int dbiCclose(dbiIndex dbi, DBC * dbcursor, unsigned int flags); /** \ingroup dbi * Delete (key,data) pair(s) from index database. @@ -375,17 +262,9 @@ int dbiCclose(dbiIndex dbi, DBC * dbcursor, unsigned int flags) * @param flags (unused) * @return 0 on success */ -static inline +RPM_GNUC_INTERNAL int dbiDel(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, - unsigned int flags) -{ - int rc; - assert(key->data != NULL && key->size > 0); - (void) rpmswEnter(&dbi->dbi_rpmdb->db_delops, 0); - rc = (dbi->dbi_vec->cdel) (dbi, dbcursor, key, data, flags); - (void) rpmswExit(&dbi->dbi_rpmdb->db_delops, data->size); - return rc; -} + unsigned int flags); /** \ingroup dbi * Retrieve (key,data) pair from index database. @@ -421,74 +300,53 @@ int dbiPut(dbiIndex dbi, DBC * dbcursor, DBT * key, DBT * data, * @param flags (unused) * @return 0 on success */ -static inline int dbiCount(dbiIndex dbi, DBC * dbcursor, unsigned int * countp, - unsigned int flags) -{ - return (*dbi->dbi_vec->ccount) (dbi, dbcursor, countp, flags); -} + unsigned int flags); /** \ingroup dbi - * Verify (and close) index database. + * Close index database. * @param dbi index database handle * @param flags (unused) * @return 0 on success */ -static inline -int dbiVerify(dbiIndex dbi, unsigned int flags) -{ - dbi->dbi_verify_on_close = 1; - return (*dbi->dbi_vec->close) (dbi, flags); -} +int dbiClose(dbiIndex dbi, unsigned int flags); /** \ingroup dbi - * Close index database. + * Flush pending operations to disk. * @param dbi index database handle * @param flags (unused) * @return 0 on success */ -static inline -int dbiClose(dbiIndex dbi, unsigned int flags) -{ - return (*dbi->dbi_vec->close) (dbi, flags); -} +int dbiSync (dbiIndex dbi, unsigned int flags); /** \ingroup dbi - * Flush pending operations to disk. + * Verify (and close) index database. * @param dbi index database handle * @param flags (unused) * @return 0 on success */ static inline -int dbiSync (dbiIndex dbi, unsigned int flags) +int dbiVerify(dbiIndex dbi, unsigned int flags) { - return (*dbi->dbi_vec->sync) (dbi, flags); + dbi->dbi_verify_on_close = 1; + return dbiClose(dbi, flags); } + /** \ingroup dbi * Is database byte swapped? * @param dbi index database handle * @return 0 same order, 1 swapped order */ -static inline -int dbiByteSwapped(dbiIndex dbi) -{ - if (dbi->dbi_byteswapped == -1) - dbi->dbi_byteswapped = (*dbi->dbi_vec->byteswapped) (dbi); - return dbi->dbi_byteswapped; -} +int dbiByteSwapped(dbiIndex dbi); + /** \ingroup dbi * Is database byte swapped? * @param dbi index database handle * @param flags DB_FAST_STAT or 0 * @return 0 on success */ -static inline -int dbiStat(dbiIndex dbi, unsigned int flags) -{ - return (*dbi->dbi_vec->stat) (dbi, flags); -} - +int dbiStat(dbiIndex dbi, unsigned int flags); /** \ingroup dbi * Destroy set of index database items. |