Commit c5ac6706 authored by Bernhard Link's avatar Bernhard Link

move package database handling from packages.c to database.c

parent fcbdd616
2007-09-15 Bernhard R. Link <brlink@debian.org>
* move package database handling from packages.c to database.c
2007-09-14 Bernhard R. Link <brlink@debian.org> 2007-09-14 Bernhard R. Link <brlink@debian.org>
* rereference now also refreshes references by tracking data. * rereference now also refreshes references by tracking data.
......
...@@ -16,12 +16,12 @@ AM_CPPFLAGS = -std=gnu99 -Wall $(ARCHIVECPP) $(DBCPPFLAGS) ...@@ -16,12 +16,12 @@ AM_CPPFLAGS = -std=gnu99 -Wall $(ARCHIVECPP) $(DBCPPFLAGS)
reprepro_LDADD = $(ARCHIVELIBS) $(DBLIBS) reprepro_LDADD = $(ARCHIVELIBS) $(DBLIBS)
changestool_LDADD = $(ARCHIVELIBS) changestool_LDADD = $(ARCHIVELIBS)
reprepro_SOURCES = configparser.c database.c freespace.c log.c changes.c incoming.c uploaderslist.c guesscomponent.c files.c md5.c md5sum.c dirs.c chunks.c reference.c packages.c binaries.c sources.c checks.c names.c dpkgversions.c release.c mprintf.c updates.c strlist.c signature.c distribution.c checkindeb.c checkindsc.c checkin.c copyfile.c upgradelist.c target.c aptmethod.c downloadcache.c main.c override.c terms.c ignore.c filterlist.c exports.c tracking.c optionsfile.c readrelease.c donefile.c pull.c contents.c filelist.c $(ARCHIVE_USED) reprepro_SOURCES = configparser.c database.c freespace.c log.c changes.c incoming.c uploaderslist.c guesscomponent.c files.c md5.c md5sum.c dirs.c chunks.c reference.c binaries.c sources.c checks.c names.c dpkgversions.c release.c mprintf.c updates.c strlist.c signature.c distribution.c checkindeb.c checkindsc.c checkin.c copyfile.c upgradelist.c target.c aptmethod.c downloadcache.c main.c override.c terms.c ignore.c filterlist.c exports.c tracking.c optionsfile.c readrelease.c donefile.c pull.c contents.c filelist.c $(ARCHIVE_USED)
EXTRA_reprepro_SOURCE = $(ARCHIVE_UNUSED) EXTRA_reprepro_SOURCE = $(ARCHIVE_UNUSED)
changestool_SOURCES = tool.c chunkedit.c strlist.c md5sum.c md5.c mprintf.c chunks.c signature.c dirs.c names.c copyfile.c $(ARCHIVE_USED) changestool_SOURCES = tool.c chunkedit.c strlist.c md5sum.c md5.c mprintf.c chunks.c signature.c dirs.c names.c copyfile.c $(ARCHIVE_USED)
noinst_HEADERS = configparser.h database_p.h database.h freespace.h log.h changes.h incoming.h guesscomponent.h md5.h md5sum.h dirs.h files.h chunks.h reference.h packages.h binaries.h sources.h checks.h names.h release.h error.h mprintf.h updates.h strlist.h signature.h distribution.h debfile.h checkindeb.h checkindsc.h copyfile.h upgradelist.h target.h aptmethod.h downloadcache.h override.h terms.h ignore.h filterlist.h dpkgversions.h checkin.h exports.h globals.h tracking.h trackingt.h optionsfile.h readrelease.h donefile.h pull.h ar.h filelist.h contents.h chunkedit.h uploaderslist.h noinst_HEADERS = configparser.h database_p.h database.h freespace.h log.h changes.h incoming.h guesscomponent.h md5.h md5sum.h dirs.h files.h chunks.h reference.h binaries.h sources.h checks.h names.h release.h error.h mprintf.h updates.h strlist.h signature.h distribution.h debfile.h checkindeb.h checkindsc.h copyfile.h upgradelist.h target.h aptmethod.h downloadcache.h override.h terms.h ignore.h filterlist.h dpkgversions.h checkin.h exports.h globals.h tracking.h trackingt.h optionsfile.h readrelease.h donefile.h pull.h ar.h filelist.h contents.h chunkedit.h uploaderslist.h
MAINTAINERCLEANFILES = Makefile.in configure install-sh stamp-h.in aclocal.m4 config.h.in mkinstalldirs config.guess config.sub missing MAINTAINERCLEANFILES = Makefile.in configure install-sh stamp-h.in aclocal.m4 config.h.in mkinstalldirs config.guess config.sub missing
......
This diff is collapsed.
...@@ -7,16 +7,42 @@ ...@@ -7,16 +7,42 @@
#ifndef REPREPRO_ERROR_H #ifndef REPREPRO_ERROR_H
#include "error.h" #include "error.h"
#endif #endif
#ifndef REPREPRO_STRLIST_H
#include "strlist.h"
#endif
struct database; struct database;
struct distribution; struct distribution;
struct table;
struct cursor;
retvalue database_create(struct database **, const char *dbdir, struct distribution *, bool fast, bool nopackages, bool allowunused, bool readonly, size_t waitforlock); retvalue database_create(struct database **, const char *dbdir, struct distribution *, bool fast, bool nopackages, bool allowunused, bool readonly, size_t waitforlock, bool verbosedb);
retvalue database_close(struct database *); retvalue database_close(struct database *);
const char *database_directory(struct database *); const char *database_directory(struct database *);
retvalue database_openfiles(struct database *, const char *mirrordir); retvalue database_openfiles(struct database *, const char *mirrordir);
retvalue database_openreferences(struct database *); retvalue database_openreferences(struct database *);
retvalue database_listpackages(struct database *, /*@out@*/struct strlist *);
retvalue database_droppackages(struct database *, const char *);
retvalue database_openpackages(struct database *, const char *identifier, bool readonly, /*@out@*/struct table **);
retvalue table_close(/*@only@*/struct table *);
bool table_isempty(struct table *);
/* retrieve a record from the database, return RET_NOTHING if there is none: */
retvalue table_getrecord(struct table *, const char *, /*@out@*/char **);
retvalue table_adduniqrecord(struct table *, const char *key, const char *data);
retvalue table_replacerecord(struct table *, const char *key, const char *data);
retvalue table_deleterecord(struct table *, const char *key);
retvalue table_checkkey(struct table *, const char *key);
retvalue table_newglobaluniqcursor(struct table *, /*@out@*/struct cursor **);
retvalue table_newduplicatecursor(struct table *, const char *key, /*@out@*/struct cursor **);
bool cursor_nexttemp(struct table *, struct cursor *, /*@out@*/const char **, /*@out@*/const char **);
retvalue cursor_replace(struct table *, struct cursor *, const char *);
retvalue cursor_close(struct table *, /*@only@*/struct cursor *);
#endif #endif
...@@ -14,9 +14,9 @@ struct database { ...@@ -14,9 +14,9 @@ struct database {
char *directory; char *directory;
struct filesdb *files; struct filesdb *files;
struct references *references; struct references *references;
bool locked; bool locked, verbose;
int dircreationdepth; int dircreationdepth;
bool nopackages, readonly; bool nopackages, readonly, packagesdatabaseopen;
int version, compatibilityversion; int version, compatibilityversion;
}; };
......
...@@ -31,8 +31,9 @@ ...@@ -31,8 +31,9 @@
#include "error.h" #include "error.h"
#include "mprintf.h" #include "mprintf.h"
#include "strlist.h" #include "strlist.h"
#include "names.h"
#include "chunks.h" #include "chunks.h"
#include "packages.h" #include "database.h"
#include "exports.h" #include "exports.h"
#include "md5sum.h" #include "md5sum.h"
#include "copyfile.h" #include "copyfile.h"
...@@ -400,7 +401,7 @@ static retvalue callexporthook(const char *confdir,/*@null@*/const char *hook, c ...@@ -400,7 +401,7 @@ static retvalue callexporthook(const char *confdir,/*@null@*/const char *hook, c
} }
} }
retvalue export_target(const char *confdir, const char *relativedir, packagesdb packages, const struct exportmode *exportmode, struct release *release, bool onlyifmissing, bool snapshot) { retvalue export_target(const char *confdir, const char *relativedir, struct table *packages, const struct exportmode *exportmode, struct release *release, bool onlyifmissing, bool snapshot) {
retvalue r; retvalue r;
struct filetorelease *file; struct filetorelease *file;
const char *status; const char *status;
......
...@@ -4,9 +4,6 @@ ...@@ -4,9 +4,6 @@
#ifndef REPREPRO_RELEASE_H #ifndef REPREPRO_RELEASE_H
#include "release.h" #include "release.h"
#endif #endif
#ifndef REPREPRO_PACKAGES_H
#include "packages.h"
#endif
struct exportmode { struct exportmode {
/* "Packages", "Sources" or something like that */ /* "Packages", "Sources" or something like that */
...@@ -25,6 +22,6 @@ struct configiterator; ...@@ -25,6 +22,6 @@ struct configiterator;
retvalue exportmode_set(struct exportmode *mode, const char *confdir, struct configiterator *iter); retvalue exportmode_set(struct exportmode *mode, const char *confdir, struct configiterator *iter);
void exportmode_done(struct exportmode *mode); void exportmode_done(struct exportmode *mode);
retvalue export_target(const char *confdir, const char *relativedir, packagesdb packages, const struct exportmode *exportmode, struct release *release, bool onlymissing, bool snapshot); retvalue export_target(const char *confdir, const char *relativedir, struct table *packages, const struct exportmode *exportmode, struct release *release, bool onlymissing, bool snapshot);
#endif #endif
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
#include "files.h" #include "files.h"
#include "database.h" #include "database.h"
#include "target.h" #include "target.h"
#include "packages.h"
#include "reference.h" #include "reference.h"
#include "binaries.h" #include "binaries.h"
#include "sources.h" #include "sources.h"
...@@ -104,6 +103,7 @@ static size_t waitforlock = 0; ...@@ -104,6 +103,7 @@ static size_t waitforlock = 0;
static enum exportwhen export = EXPORT_NORMAL; static enum exportwhen export = EXPORT_NORMAL;
int verbose = 0; int verbose = 0;
static bool fast = false; static bool fast = false;
static bool verbosedatabase = false;
static enum spacecheckmode spacecheckmode = scm_FULL; static enum spacecheckmode spacecheckmode = scm_FULL;
/* default: 100 MB for database to grow */ /* default: 100 MB for database to grow */
static off_t reserveddbspace = 1024*1024*100 static off_t reserveddbspace = 1024*1024*100
...@@ -114,7 +114,7 @@ static off_t reservedotherspace = 1024*1024; ...@@ -114,7 +114,7 @@ static off_t reservedotherspace = 1024*1024;
* to change something owned by lower owners. */ * to change something owned by lower owners. */
enum config_option_owner config_state, enum config_option_owner config_state,
#define O(x) owner_ ## x = CONFIG_OWNER_DEFAULT #define O(x) owner_ ## x = CONFIG_OWNER_DEFAULT
O(fast), O(mirrordir), O(distdir), O(dbdir), O(listdir), O(confdir), O(logdir), O(overridedir), O(methoddir), O(section), O(priority), O(component), O(architecture), O(packagetype), O(nothingiserror), O(nolistsdownload), O(keepunreferenced), O(keepunneededlists), O(keepdirectories), O(askforpassphrase), O(skipold), O(export), O(waitforlock), O(spacecheckmode), O(reserveddbspace), O(reservedotherspace), O(guessgpgtty); O(fast), O(mirrordir), O(distdir), O(dbdir), O(listdir), O(confdir), O(logdir), O(overridedir), O(methoddir), O(section), O(priority), O(component), O(architecture), O(packagetype), O(nothingiserror), O(nolistsdownload), O(keepunreferenced), O(keepunneededlists), O(keepdirectories), O(askforpassphrase), O(skipold), O(export), O(waitforlock), O(spacecheckmode), O(reserveddbspace), O(reservedotherspace), O(guessgpgtty), O(verbosedatabase);
#undef O #undef O
#define CONFIGSET(variable,value) if(owner_ ## variable <= config_state) { \ #define CONFIGSET(variable,value) if(owner_ ## variable <= config_state) { \
...@@ -563,7 +563,7 @@ static retvalue list_in_target(void *data, struct target *target, ...@@ -563,7 +563,7 @@ static retvalue list_in_target(void *data, struct target *target,
const char *packagename = data; const char *packagename = data;
char *control,*version; char *control,*version;
result = packages_get(target->packages, packagename, &control); result = table_getrecord(target->packages, packagename, &control);
if( RET_IS_OK(result) ) { if( RET_IS_OK(result) ) {
r = (*target->getversion)(target, control, &version); r = (*target->getversion)(target, control, &version);
if( RET_IS_OK(r) ) { if( RET_IS_OK(r) ) {
...@@ -712,17 +712,17 @@ static retvalue printout(UNUSED(void *data),const char *package,const char *chun ...@@ -712,17 +712,17 @@ static retvalue printout(UNUSED(void *data),const char *package,const char *chun
ACTION_u_B(dumpcontents) { ACTION_u_B(dumpcontents) {
retvalue result,r; retvalue result,r;
packagesdb packages; struct table *packages;
assert( argc == 2 ); assert( argc == 2 );
result = packages_initialize(&packages, database, argv[1]); result = database_openpackages(database, argv[1], true, &packages);
if( RET_WAS_ERROR(result) ) if( RET_WAS_ERROR(result) )
return result; return result;
result = packages_foreach(packages,printout,NULL); result = packages_foreach(packages,printout,NULL);
r = packages_done(packages); r = table_close(packages);
RET_ENDUPDATE(result,r); RET_ENDUPDATE(result,r);
return result; return result;
...@@ -1017,7 +1017,7 @@ static retvalue copy(/*@temp@*/void *data, struct target *origtarget, ...@@ -1017,7 +1017,7 @@ static retvalue copy(/*@temp@*/void *data, struct target *origtarget,
d->destination->codename); d->destination->codename);
result = RET_NOTHING; result = RET_NOTHING;
} else } else
result = packages_get(origtarget->packages, d->name, &chunk); result = table_getrecord(origtarget->packages, d->name, &chunk);
if( result == RET_NOTHING && verbose > 2 ) if( result == RET_NOTHING && verbose > 2 )
printf("No instance of '%s' found in '%s'!\n", printf("No instance of '%s' found in '%s'!\n",
d->name, origtarget->identifier); d->name, origtarget->identifier);
...@@ -1812,14 +1812,6 @@ ACTION_C(createsymlinks) { ...@@ -1812,14 +1812,6 @@ ACTION_C(createsymlinks) {
/***********************clearvanished***********************************/ /***********************clearvanished***********************************/
static retvalue docount(void *data,UNUSED(const char *a),UNUSED(const char *b)) {
long int *p = data;
(*p)++;
return RET_OK;
}
ACTION_U_D(clearvanished) { ACTION_U_D(clearvanished) {
retvalue result,r; retvalue result,r;
struct distribution *d; struct distribution *d;
...@@ -1827,7 +1819,7 @@ ACTION_U_D(clearvanished) { ...@@ -1827,7 +1819,7 @@ ACTION_U_D(clearvanished) {
bool *inuse; bool *inuse;
int i; int i;
result = packages_getdatabases(database, &identifiers); result = database_listpackages(database, &identifiers);
if( !RET_IS_OK(result) ) { if( !RET_IS_OK(result) ) {
return result; return result;
} }
...@@ -1860,17 +1852,16 @@ ACTION_U_D(clearvanished) { ...@@ -1860,17 +1852,16 @@ ACTION_U_D(clearvanished) {
if( interrupted() ) if( interrupted() )
return RET_ERROR_INTERRUPTED; return RET_ERROR_INTERRUPTED;
if( delete <= 0 ) { if( delete <= 0 ) {
long int count = 0; struct table *packages;
packagesdb db; r = database_openpackages(database, identifier, true,
r = packages_initialize(&db, database, identifier); &packages);
if( !RET_WAS_ERROR(r) ) if( RET_IS_OK(r) ) {
r = packages_foreach(db, docount, &count); if( !table_isempty(packages) ) {
if( !RET_WAS_ERROR(r) ) fprintf(stderr,
r = packages_done(db); "There are still packages in '%s', not removing (give --delete to do so)!\n", identifier);
if( count > 0 ) { continue;
fprintf(stderr, }
"There are still %ld packages in '%s', not removing (give --delete to do so)!\n", count, identifier); r = table_close(packages);
continue;
} }
} }
if( interrupted() ) if( interrupted() )
...@@ -1882,7 +1873,7 @@ ACTION_U_D(clearvanished) { ...@@ -1882,7 +1873,7 @@ ACTION_U_D(clearvanished) {
/* derference anything left */ /* derference anything left */
references_remove(database, identifier, dereferenced); references_remove(database, identifier, dereferenced);
/* remove the database */ /* remove the database */
packages_drop(database, identifier); database_droppackages(database, identifier);
} }
free(inuse); free(inuse);
strlist_done(&identifiers); strlist_done(&identifiers);
...@@ -2199,7 +2190,7 @@ static retvalue callaction(const struct action *action, int argc, const char *ar ...@@ -2199,7 +2190,7 @@ static retvalue callaction(const struct action *action, int argc, const char *ar
result = database_create(&database, dbdir, alldistributions, result = database_create(&database, dbdir, alldistributions,
fast, ISSET(needs, NEED_NO_PACKAGES), fast, ISSET(needs, NEED_NO_PACKAGES),
ISSET(needs, MAY_UNUSED), ISSET(needs, IS_RO), ISSET(needs, MAY_UNUSED), ISSET(needs, IS_RO),
waitforlock); waitforlock, verbosedatabase || (verbose >= 30) );
if( !RET_IS_OK(result) ) { if( !RET_IS_OK(result) ) {
return result; return result;
} }
...@@ -2286,6 +2277,8 @@ LO_NOKEEPDIRECTORIES, ...@@ -2286,6 +2277,8 @@ LO_NOKEEPDIRECTORIES,
LO_NOFAST, LO_NOFAST,
LO_NOSKIPOLD, LO_NOSKIPOLD,
LO_NOGUESSGPGTTY, LO_NOGUESSGPGTTY,
LO_VERBOSEDB,
LO_NOVERBOSEDB,
LO_EXPORT, LO_EXPORT,
LO_DISTDIR, LO_DISTDIR,
LO_DBDIR, LO_DBDIR,
...@@ -2464,6 +2457,12 @@ static void handle_option(int c,const char *optarg) { ...@@ -2464,6 +2457,12 @@ static void handle_option(int c,const char *optarg) {
case LO_NOFAST: case LO_NOFAST:
CONFIGSET(fast, false); CONFIGSET(fast, false);
break; break;
case LO_VERBOSEDB:
CONFIGSET(verbosedatabase, true);
break;
case LO_NOVERBOSEDB:
CONFIGSET(verbosedatabase, false);
break;
case LO_EXPORT: case LO_EXPORT:
setexport(optarg); setexport(optarg);
break; break;
...@@ -2656,6 +2655,10 @@ int main(int argc,char *argv[]) { ...@@ -2656,6 +2655,10 @@ int main(int argc,char *argv[]) {
{"nonoguessgpgtty", no_argument, &longoption, LO_GUESSGPGTTY}, {"nonoguessgpgtty", no_argument, &longoption, LO_GUESSGPGTTY},
{"fast", no_argument, &longoption, LO_FAST}, {"fast", no_argument, &longoption, LO_FAST},
{"nofast", no_argument, &longoption, LO_NOFAST}, {"nofast", no_argument, &longoption, LO_NOFAST},
{"verbosedb", no_argument, &longoption, LO_VERBOSEDB},
{"noverbosedb", no_argument, &longoption, LO_NOVERBOSEDB},
{"verbosedatabase", no_argument, &longoption, LO_VERBOSEDB},
{"noverbosedatabase", no_argument, &longoption, LO_NOVERBOSEDB},
{"skipold", no_argument, &longoption, LO_SKIPOLD}, {"skipold", no_argument, &longoption, LO_SKIPOLD},
{"noskipold", no_argument, &longoption, LO_NOSKIPOLD}, {"noskipold", no_argument, &longoption, LO_NOSKIPOLD},
{"nonoskipold", no_argument, &longoption, LO_SKIPOLD}, {"nonoskipold", no_argument, &longoption, LO_SKIPOLD},
......
/* This file is part of "reprepro"
* Copyright (C) 2003,2004,2005 Bernhard R. Link
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include <config.h>
#include <assert.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <zlib.h>
#include "error.h"
#include "strlist.h"
#include "names.h"
#include "md5sum.h"
#include "dirs.h"
#include "files.h"
#include "database_p.h"
#include "packages.h"
struct s_packagesdb {
char *identifier;
DB *database;
};
extern int verbose;
// to make sure the problems do not arise there:
int isopen = 0;
/* release the packages-database initialized got be packages_initialize */
retvalue packages_done(packagesdb db) {
int r;
isopen--;
if( isopen < 0 )
fprintf(stderr,"isopen: %d\n",isopen);
r = db->database->close(db->database,0);
free(db->identifier);
free(db);
if( r < 0 )
return RET_DBERR(r);
else
return RET_OK;
}
retvalue packages_init(packagesdb *db,struct database *database,const char *codename,const char *component,const char *architecture,const char *packagetype) {
char * identifier;
retvalue r;
identifier = calc_identifier(codename,component,architecture,packagetype);
if( identifier == NULL )
return RET_ERROR_OOM;
r = packages_initialize(db, database, identifier);
free(identifier);
return r;
}
/* initialize the packages-database for <identifier> */
retvalue packages_initialize(packagesdb *db,struct database *database,const char *identifier) {
packagesdb pkgs;
retvalue r;
assert( !database->nopackages );
if( database->nopackages ) {
fputs("Internal Error: Accessing packages database while that was not prepared!\n", stderr);
return RET_ERROR;
}
pkgs = malloc(sizeof(struct s_packagesdb));
if( pkgs == NULL ) {
return RET_ERROR_OOM;
}
pkgs->identifier = strdup(identifier);
if( pkgs->identifier == NULL ) {
free(pkgs);
return RET_ERROR_OOM;
}
isopen++;
if( isopen > 1 )
fprintf(stderr,"isopen: %d\n",isopen);
// TODO: allow users of this function to specify readonly
r = database_opentable(database, "packages.db", identifier,
DB_BTREE, 0 , NULL, false, &pkgs->database);
if( RET_WAS_ERROR(r) ) {
free(pkgs->identifier);
free(pkgs);
return r;
}
*db = pkgs;
return RET_OK;
}
/* replace a save chunk with another */
retvalue packages_replace(packagesdb db,const char *package,const char *chunk) {
int dbret;
DBT key,data;
SETDBT(key,package);
if ((dbret = db->database->del(db->database, NULL, &key, 0)) == 0) {
if( verbose > 2 )
printf("db: removed old '%s' from '%s'.\n", (const char *)key.data,db->identifier);
} else {
db->database->err(db->database, dbret, "packages.db, while removing old %s:",package);
if( dbret != DB_NOTFOUND )
return RET_DBERR(dbret);
}
SETDBT(key,package);
SETDBT(data,chunk);
if ((dbret = db->database->put(db->database, NULL, &key, &data, DB_NOOVERWRITE)) == 0) {
if( verbose > 2 )
printf("db: '%s' added to '%s'.\n", (const char *)key.data,db->identifier);
return RET_OK;
} else {
db->database->err(db->database, dbret, "packages.db(%s):",db->identifier);
return RET_DBERR(dbret);
}
}
/* save a given chunk in the database */
retvalue packages_add(packagesdb db,const char *package,const char *chunk) {
int dbret;
DBT key,data;
SETDBT(key,package);
SETDBT(data,chunk);
if ((dbret = db->database->put(db->database, NULL, &key, &data, DB_NOOVERWRITE)) == 0) {
if( verbose > 2 )
printf("db: '%s' added to '%s'.\n", (const char *)key.data,db->identifier);
return RET_OK;
} else {
db->database->err(db->database, dbret, "packages.db(%s):",db->identifier);
return RET_DBERR(dbret);
}
}
/* get the saved chunk from the database */
retvalue packages_get(packagesdb db,const char *package,char **chunk) {
int dbret;
DBT key,data;
SETDBT(key,package);
CLEARDBT(data);
if( (dbret = db->database->get(db->database, NULL, &key, &data, 0)) == 0){
char *c;
c = strdup(data.data);
if( c == NULL )
return RET_ERROR_OOM;
else {
*chunk = c;
return RET_OK;
}
} else if( dbret == DB_NOTFOUND ){
return RET_NOTHING;
} else {
db->database->err(db->database, dbret, "packages.db(%s):",db->identifier);
return RET_DBERR(dbret);
}
}
/* remove a given chunk from the database */
retvalue packages_remove(packagesdb db,const char *package) {
int dbret;
DBT key;
SETDBT(key,package);
if ((dbret = db->database->del(db->database, NULL, &key, 0)) == 0) {
if( verbose > 2 )
printf("db: '%s' removed from '%s'.\n", (const char *)key.data,db->identifier);
return RET_OK;
} else {
db->database->err(db->database, dbret, "packages.db:");
return RET_DBERR(dbret);
}
}
/* check for existance of the given version of a package in the arch,
static retvalue package_check(packagesdb db,const char *package) {
int dbret;
DBT key,data;
SETDBT(key,package);
CLEARDBT(data);
if( (dbret = db->database->get(db->database, NULL, &key, &data, 0)) == 0){
return RET_OK;
} else if( dbret == DB_NOTFOUND ){
return RET_NOTHING;
} else {
db->database->err(db->database, dbret, "packages.db(%s):",db->identifier);
return RET_DBERR(dbret);
}
}
*/
/* action to be called by packages_forall */
//typedef retvalue per_package_action(void *data,const char *package,const char *chunk);
/* call action once for each saved chunk: */
retvalue packages_foreach(packagesdb db,per_package_action action,void *privdata) {
DBC *cursor;
DBT key,data;
int dbret;
retvalue ret,r;
cursor = NULL;
if( (dbret = db->database->cursor(db->database,NULL,&cursor,0)) != 0 ) {
db->database->err(db->database, dbret, "packages.db(%s):",db->identifier);
return RET_ERROR;
}
CLEARDBT(key);
CLEARDBT(data);
ret = RET_NOTHING;
while( (dbret=cursor->c_get(cursor,&key,&data,DB_NEXT)) == 0 ) {
r = action(privdata,(const char*)key.data,(const char*)data.data);
RET_UPDATE(ret,r);
if( RET_WAS_ERROR(r) ) {
if( verbose > 0 )
fprintf(stderr,"packages_foreach: Stopping procession of further packages due to previous errors\n");
break;
}
CLEARDBT(key);
CLEARDBT(data);
}
if( dbret != 0 && dbret != DB_NOTFOUND ) {
db->database->err(db->database, dbret, "packages.db(%s):",db->identifier);
return RET_DBERR(dbret);
}
if( (dbret = cursor->c_close(cursor)) != 0 ) {
db->database->err(db->database, dbret, "packages.db(%s):",db->identifier);
return RET_DBERR(dbret);
}
return ret;
}
/* action to be called by packages_processall */
//typedef retvalue per_package_modifier(void *data,const char *package,const char *chunk, char **newchunk);
/* call action once for each saved chunk and replace with a new one, if it returns RET_OK: */
retvalue packages_modifyall(packagesdb db, per_package_modifier *action, const struct distribution *privdata, bool *setifmodified) {
DBC *cursor;
DBT key,data;
int dbret;
retvalue result,r;
cursor = NULL;
if( (dbret = db->database->cursor(db->database,NULL,&cursor,0/*DB_WRITECURSOR*/)) != 0 ) {
db->database->err(db->database, dbret, "packages.db(%s):",db->identifier);
return RET_ERROR;
}
CLEARDBT(key);
CLEARDBT(data);
result = RET_NOTHING;
while( (dbret=cursor->c_get(cursor,&key,&data,DB_NEXT)) == 0 ) {
char *newdata = NULL;
r = action(privdata,(const char*)key.data,(const char*)data.data,&newdata);
RET_UPDATE(result,r);
if( RET_WAS_ERROR(r) ) {
if( verbose > 0 )
fprintf(stderr,"packages_modifyall: Stopping procession of further packages due to privious errors\n");
break;
}
if( RET_IS_OK(r) ) {
SETDBT(data,newdata);
dbret = cursor->c_put(cursor,&key,&data,DB_CURRENT);
free(newdata);
if( dbret != 0 ) {
db->database->err(db->database, dbret, "packages.db(%s):",db->identifier);
return RET_DBERR(dbret);
}
if( setifmodified != NULL )
*setifmodified = true;
}
CLEARDBT(key);
CLEARDBT(data);
}
if( dbret != 0 && dbret != DB_NOTFOUND ) {
db->database->err(db->database, dbret, "packages.db(%s):",db->identifier);
return RET_DBERR(dbret);
}
if( (dbret = cursor->c_close(cursor)) != 0 ) {
db->database->err(db->database, dbret, "packages.db(%s):",db->identifier);
return RET_DBERR(dbret);
}
return result;
}
/* Get a list of all identifiers having a package list */
retvalue packages_getdatabases(struct database *database, struct strlist *identifiers) {
return database_listsubtables(database, "packages.db", identifiers);
}
/* drop a database */
retvalue packages_drop(struct database *database, const char *identifier) {
return database_dropsubtable(database, "packages.db", identifier);
}
#ifndef REPREPRO_PACKAGES_H
#define REPREPRO_PACKAGES_H
#ifndef REPREPRO_ERROR_H
#include "error.h"
#warning "What's hapening here?"
#endif
#ifndef REPREPRO_STRLIST_H
#include "strlist.h"
#warning "What's hapening here?"
#endif
#ifndef REPREPRO_DATABASE_H
#include "database.h"
#endif
#ifndef REPREPRO_NAMES_H
#include "names.h"
#endif
typedef struct s_packagesdb *packagesdb;
/* initialize the packages-database for <identifier> */
retvalue packages_initialize(/*@out@*/packagesdb *pkgs, struct database *,const char *identifier);
/* The same but calculate the identifier */
retvalue packages_init(packagesdb *pkgs, struct database *,const char *codename,const char *component,const char *architecture,const char *packagetype);
/* release the packages-database initialized got be packages_initialize */
retvalue packages_done(/*@only@*/packagesdb db);