]> git.ipfire.org Git - pakfire.git/commitdiff
db: Load filelists
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 10 Feb 2021 15:06:15 +0000 (15:06 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 10 Feb 2021 15:06:15 +0000 (15:06 +0000)
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 <michael.tremer@ipfire.org>
src/libpakfire/db.c
src/libpakfire/include/pakfire/package.h
src/libpakfire/package.c

index be782819b8c444ad99fa612ca1280f4d978efed4..4acde24b02a55669181bdc7c9c8c77e035a2ad1f 100644 (file)
@@ -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"
                ";";
index 56f6c2d96370a1e671ffbd3d0cbe10e6e271775a..81bfe31a4b1f38f2a95ef2ce78badd305b08fac1 100644 (file)
@@ -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,
index a88560e326c5cfa027823d5b5639c013b5df51b8..7a42965489deae78652aef1e8a533f398a1fecad 100644 (file)
@@ -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;