From: Michael Tremer Date: Wed, 10 Feb 2021 15:06:15 +0000 (+0000) Subject: db: Load filelists X-Git-Tag: 0.9.28~1285^2~772 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d995f7fcf2d0c16ce6c167f34a9ed9e4ee7435ef;p=pakfire.git db: Load filelists To avoid running an extra query for the filelist, we simply have SQLite concatenate the filelist and we split it again after. It would have been nicer to use NUL to concatenate the string, but that is unfortunately difficult in SQLite, so that we use newline and replace it later so that we can only run memcpy() once instead of once per line. Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/db.c b/src/libpakfire/db.c index be782819b..4acde24b0 100644 --- a/src/libpakfire/db.c +++ b/src/libpakfire/db.c @@ -1476,6 +1476,15 @@ static int pakfire_db_load_package(struct pakfire_db* db, PakfireRepo repo, sqli pakfire_package_set_buildtime(pkg, build_time); } + // Files + const char* files = (const char*)sqlite3_column_text(stmt, 17); + if (files) { + DEBUG(db->pakfire, "FILES = %s\n", files); + r = pakfire_package_set_filelist_from_string(pkg, files); + if (r) + goto ERROR; + } + // Success r = 0; @@ -1498,7 +1507,10 @@ int pakfire_db_load(struct pakfire_db* db, PakfireRepo repo) { const char* sql = "SELECT " "name, epoch, version, release, arch, groups, filename, size, inst_size, " - "hash1, license, summary, description, uuid, vendor, build_host, build_time " + "hash1, license, summary, description, uuid, vendor, build_host, build_time, " + "(" + "SELECT group_concat(name, '\n') FROM files WHERE files.pkg = packages.id" + ") AS files " "FROM " "packages" ";"; diff --git a/src/libpakfire/include/pakfire/package.h b/src/libpakfire/include/pakfire/package.h index 56f6c2d96..81bfe31a4 100644 --- a/src/libpakfire/include/pakfire/package.h +++ b/src/libpakfire/include/pakfire/package.h @@ -121,6 +121,7 @@ char* pakfire_package_get_cache_full_path(PakfirePackage pkg); PakfireFilelist pakfire_package_get_filelist(PakfirePackage pkg); int pakfire_package_set_filelist(PakfirePackage pkg, PakfireFilelist filelist); +int pakfire_package_set_filelist_from_string(PakfirePackage pkg, const char* files); enum pakfire_package_keynames { PAKFIRE_PKG, diff --git a/src/libpakfire/package.c b/src/libpakfire/package.c index a88560e32..7a4296548 100644 --- a/src/libpakfire/package.c +++ b/src/libpakfire/package.c @@ -1010,7 +1010,7 @@ PAKFIRE_EXPORT PakfireFilelist pakfire_package_get_filelist(PakfirePackage pkg) return filelist; } -PAKFIRE_EXPORT int pakfire_package_set_filelist(PakfirePackage pkg, PakfireFilelist filelist) { +static int pakfire_package_append_file(PakfirePackage pkg, const char* path) { // Fetch repodata PakfireRepo repo = pakfire_package_get_repo(pkg); Repodata* repodata = pakfire_repo_get_repodata(repo); @@ -1018,24 +1018,71 @@ PAKFIRE_EXPORT int pakfire_package_set_filelist(PakfirePackage pkg, PakfireFilel Id handle = pakfire_package_get_handle(pkg); + char* basename = pakfire_basename(path); + char* dirname = pakfire_dirname(path); + + // Convert directory into ID + Id did = repodata_str2dir(repodata, dirname, 1); + if (!did) + did = repodata_str2dir(repodata, "/", 1); + + // Add data to list + repodata_add_dirstr(repodata, handle, + SOLVABLE_FILELIST, did, basename); + + free(basename); + free(dirname); + + return 0; +} + +PAKFIRE_EXPORT int pakfire_package_set_filelist(PakfirePackage pkg, PakfireFilelist filelist) { + int r; + for (unsigned int i = 0; i < pakfire_filelist_size(filelist); i++) { PakfireFile file = pakfire_filelist_get(filelist, i); - char* basename = pakfire_file_get_basename(file); - char* dirname = pakfire_file_get_dirname(file); + const char* name = pakfire_file_get_name(file); + if (name) { + r = pakfire_package_append_file(pkg, name); + if (r) { + pakfire_file_unref(file); + return r; + } + } + + pakfire_file_unref(file); + + } + + return 0; +} - // Convert directory into ID - Id did = repodata_str2dir(repodata, dirname, 1); - if (!did) - did = repodata_str2dir(repodata, "/", 1); +int pakfire_package_set_filelist_from_string(PakfirePackage pkg, const char* files) { + // Total length of the input string + size_t size = strlen(files); - // Add data to list - repodata_add_dirstr(repodata, handle, - SOLVABLE_FILELIST, did, basename); + // Copy files to the stack to be able to modify it + char* buffer = alloca(size + 1); - pakfire_file_unref(file); - free(basename); - free(dirname); + // Copy the content + memcpy(buffer, files, size); + + // Replace all line breaks with NUL + for (unsigned int i = 0; i < size; i++) { + if (buffer[i] == '\n') + buffer[i] = '\0'; + } + + size_t p = 0; + while (p < size) { + const char* name = &buffer[p]; + + int r = pakfire_package_append_file(pkg, name); + if (r) + return r; + + p += strlen(name) + 1; } return 0;