]> git.ipfire.org Git - pakfire.git/commitdiff
packages: Store groups as array
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 31 Aug 2023 03:20:46 +0000 (03:20 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 31 Aug 2023 03:20:46 +0000 (03:20 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/package.c
src/_pakfire/util.c
src/libpakfire/archive.c
src/libpakfire/db.c
src/libpakfire/package.c

index fa7e9b3d04fdeda1ebe40c564e55de5db4401da9..26022538a4825741c0d71dd7b1e7b800bc5a75dc 100644 (file)
@@ -258,9 +258,19 @@ static void Package_set_url(PackageObject* self, PyObject* value) {
 }
 
 static PyObject* Package_get_groups(PackageObject* self) {
-       const char* s = pakfire_package_get_string(self->package, PAKFIRE_PKG_GROUPS);
+       char** groups = pakfire_package_get_strings(self->package, PAKFIRE_PKG_GROUPS);
 
-       return PyUnicode_FromString(s);
+       PyObject* ret = PyUnicodeList_FromStringArray(groups);
+
+       // Cleanup
+       if (groups) {
+               for (char** group = groups; *group; group++)
+                       free(*group);
+
+               free(groups);
+       }
+
+       return ret;
 }
 
 static int Package_set_groups(PackageObject* self, PyObject* value) {
@@ -360,17 +370,11 @@ static PyObject* Package_get_size(PackageObject* self) {
 }
 
 static PyObject* Package_get_build_arches(PackageObject* self) {
-       PyObject* ret = NULL;
-
        // Fetch all supported arches
        char** build_arches = pakfire_package_get_strings(self->package, PAKFIRE_PKG_BUILD_ARCHES);
-       if (!build_arches) {
-               ret = PyList_New(0);
-               goto END;
-       }
 
        // Make a new list
-       ret = PyUnicodeList_FromStringArray(build_arches);
+       PyObject* ret = PyUnicodeList_FromStringArray(build_arches);
 
        // Cleanup
        for (char** build_arch = build_arches; *build_arch; build_arch++) {
@@ -378,7 +382,6 @@ static PyObject* Package_get_build_arches(PackageObject* self) {
        }
        free(build_arches);
 
-END:
        return ret;
 }
 
index 34123ef482ddfa577982bcd6264581ec6203e80f..4642f83290b9ee2543072b0a2c587e414b52e673 100644 (file)
@@ -38,15 +38,11 @@ PyObject* PyUnicodeList_FromStringArray(char** l) {
        PyObject* s = NULL;
        int r;
 
-       // Check inputs
-       if (!l)
-               return NULL;
-
        list = PyList_New(0);
        if (!list)
                goto ERROR;
 
-       for (; *l; l++) {
+       for (; l && *l; l++) {
                s = PyUnicode_FromString(*l);
                if (!s)
                        goto ERROR;
@@ -58,6 +54,7 @@ PyObject* PyUnicodeList_FromStringArray(char** l) {
        }
 
        return list;
+
 ERROR:
        if (list)
                Py_DECREF(list);
index 4f7eab53ac6dbe8cb5dd0700f4890cae612f6623..2152fd0d2c5c37e95d37e03971ea7e3f6d483fcc 100644 (file)
@@ -1047,11 +1047,23 @@ static int pakfire_archive_make_package_from_json(struct pakfire_archive* archiv
        }
 
        // Groups
-       const char* groups = pakfire_archive_metadata_get(archive, "groups", NULL);
-       if (groups) {
-               r = pakfire_package_set_string(pkg, PAKFIRE_PKG_GROUPS, groups);
-               if (r)
-                       goto ERROR;
+       struct json_object* groups = pakfire_archive_metadata_get_object(archive, "groups", NULL);
+       if (groups && json_object_is_type(groups, json_type_array)) {
+               const size_t length = json_object_array_length(groups);
+
+               for (unsigned int i = 0; i < length; i++) {
+                       struct json_object* item = json_object_array_get_idx(groups, i);
+                       if (!item)
+                               continue;
+
+                       const char* group = json_object_get_string(item);
+                       if (!group)
+                               continue;
+
+                       r = pakfire_package_add_string(pkg, PAKFIRE_PKG_GROUPS, group);
+                       if (r)
+                               goto ERROR;
+               }
        }
 
        // Distribution
@@ -1142,7 +1154,7 @@ static int pakfire_archive_make_package_from_json(struct pakfire_archive* archiv
 
        // Build arches
        struct json_object* build_arches = pakfire_archive_metadata_get_object(archive, "build", "arches");
-       if (build_arches) {
+       if (build_arches && json_object_is_type(build_arches, json_type_array)) {
                const size_t length = json_object_array_length(build_arches);
 
                for (unsigned int i = 0; i < length; i++) {
index 8e5d441a8b3d329029110e2ffb1d176d8d714291..7b9be9c1fb44984b55612636735024c5abb4cd6f 100644 (file)
@@ -1267,6 +1267,9 @@ int pakfire_db_add_package(struct pakfire_db* db,
        sqlite3_stmt* stmt = NULL;
        int r;
 
+       char** groups = NULL;
+       char* __groups = NULL;
+
        // Begin a new transaction
        r = pakfire_db_begin_transaction(db);
        if (r)
@@ -1359,10 +1362,16 @@ int pakfire_db_add_package(struct pakfire_db* db,
        }
 
        // Bind groups
-       const char* groups = pakfire_package_get_string(pkg, PAKFIRE_PKG_GROUPS);
-
+       groups = pakfire_package_get_strings(pkg, PAKFIRE_PKG_GROUPS);
        if (groups) {
-               r = sqlite3_bind_text(stmt, 4, groups, -1, NULL);
+               // Join everything together as SQLite doesn't support arrays
+               __groups = pakfire_string_join(groups, " ");
+               if (!__groups) {
+                       r = 1;
+                       goto ERROR;
+               }
+
+               r = sqlite3_bind_text(stmt, 4, __groups, -1, NULL);
                if (r) {
                        ERROR(db->pakfire, "Could not bind groups: %s\n", sqlite3_errmsg(db->handle));
                        goto ERROR;
@@ -1594,6 +1603,10 @@ int pakfire_db_add_package(struct pakfire_db* db,
                goto ERROR;
 
 ERROR:
+       if (groups)
+               pakfire_strings_free(groups);
+       if (__groups)
+               free(groups);
        if (stmt)
                sqlite3_finalize(stmt);
 
index 6f4b3e786064ba0cd82c23d722300a4cf7ce47d3..9394a7c50b8cda7374b86d748727235aab2effac 100644 (file)
@@ -587,6 +587,10 @@ PAKFIRE_EXPORT char** pakfire_package_get_strings(
        Solvable* s = get_solvable(pkg);
 
        switch (key) {
+               case PAKFIRE_PKG_GROUPS:
+                       id = SOLVABLE_GROUP;
+                       break;
+
                case PAKFIRE_PKG_BUILD_ARCHES:
                        id = SOLVABLE_BUILDFLAVOR;
                        break;
@@ -745,10 +749,6 @@ PAKFIRE_EXPORT const char* pakfire_package_get_string(
                        ret = solvable_lookup_str(s, SOLVABLE_URL);
                        break;
 
-               case PAKFIRE_PKG_GROUPS:
-                       ret = solvable_lookup_str(s, SOLVABLE_GROUP);
-                       break;
-
                case PAKFIRE_PKG_VENDOR:
                        ret = solvable_lookup_str(s, SOLVABLE_VENDOR);
                        break;
@@ -909,10 +909,6 @@ PAKFIRE_EXPORT int pakfire_package_set_string(
                        id = SOLVABLE_URL;
                        break;
 
-               case PAKFIRE_PKG_GROUPS:
-                       id = SOLVABLE_GROUP;
-                       break;
-
                case PAKFIRE_PKG_VENDOR:
                        id = SOLVABLE_VENDOR;
                        break;
@@ -986,6 +982,7 @@ PAKFIRE_EXPORT int pakfire_package_set_string(
 
                // Compat which splits a string and stores it as an array
                case PAKFIRE_PKG_BUILD_ARCHES:
+               case PAKFIRE_PKG_GROUPS:
                        return pakfire_package_set_strings_from_string(pkg, key, value);
 
                default:
@@ -1021,9 +1018,12 @@ PAKFIRE_EXPORT int pakfire_package_add_string(struct pakfire_package* pkg,
        Solvable* s = get_solvable(pkg);
 
        switch (key) {
+               case PAKFIRE_PKG_GROUPS:
+                       key_id = SOLVABLE_GROUP;
+                       break;
+
                case PAKFIRE_PKG_BUILD_ARCHES:
                        key_id = SOLVABLE_BUILDFLAVOR;
-                       value_id = pool_str2id(pool, value, 1);
                        break;
 
                default:
@@ -1031,6 +1031,9 @@ PAKFIRE_EXPORT int pakfire_package_add_string(struct pakfire_package* pkg,
                        return 1;
        }
 
+       // Convert value
+       value_id = pool_str2id(pool, value, 1);
+
        // Append the string to the ID array
        solvable_add_idarray(s, key_id, value_id);
 
@@ -1472,15 +1475,22 @@ static void pakfire_package_dump_add_line(char** str, const char* key, const cha
                asprintf(str, "%s%-15s: %s\n", *str, key ? key : "", val);
 }
 
-static void pakfire_package_dump_add_lines(char** str, const char* key, const char* val) {
+static void pakfire_package_dump_add_lines(char** str, const char* key, char** lines) {
+       for (; *lines; lines++) {
+               pakfire_package_dump_add_line(str, key, *lines);
+
+               // Reset the key after the first line
+               key = NULL;
+       }
+}
+
+static void pakfire_package_dump_add_long_line(char** str, const char* key, const char* val) {
        char** lines = pakfire_string_split(val, '\n');
        if (!lines)
                return;
 
-       while (*lines) {
-               pakfire_package_dump_add_line(str, key, *lines);
-               lines++;
-       }
+       pakfire_package_dump_add_lines(str, key, lines);
+       pakfire_strings_free(lines);
 }
 
 static void pakfire_package_dump_add_line_date(char** str, const char* key, time_t date) {
@@ -1578,12 +1588,14 @@ PAKFIRE_EXPORT char* pakfire_package_dump(struct pakfire_package* pkg, int flags
        // Description
        const char* description = pakfire_package_get_string(pkg, PAKFIRE_PKG_DESCRIPTION);
        if (description)
-               pakfire_package_dump_add_lines(&string, _("Description"), description);
+               pakfire_package_dump_add_long_line(&string, _("Description"), description);
 
        // Groups
-       const char* groups = pakfire_package_get_string(pkg, PAKFIRE_PKG_GROUPS);
-       if (groups)
+       char** groups = pakfire_package_get_strings(pkg, PAKFIRE_PKG_GROUPS);
+       if (groups) {
                pakfire_package_dump_add_lines(&string, _("Groups"), groups);
+               pakfire_strings_free(groups);
+       }
 
        // URL
        const char* url = pakfire_package_get_string(pkg, PAKFIRE_PKG_URL);
@@ -1629,9 +1641,7 @@ PAKFIRE_EXPORT char* pakfire_package_dump(struct pakfire_package* pkg, int flags
                // Build Arches
                char** build_arches = pakfire_package_get_strings(pkg, PAKFIRE_PKG_BUILD_ARCHES);
                if (build_arches) {
-                       for (char** build_arch = build_arches; *build_arch; build_arch++)
-                               pakfire_package_dump_add_line(&string, _("Build Arch"), *build_arch);
-
+                       pakfire_package_dump_add_lines(&string, _("Build Arch"), build_arches);
                        pakfire_strings_free(build_arches);
                }
 
@@ -2362,9 +2372,13 @@ struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) {
        }
 
        // Groups
-       const char* groups = pakfire_package_get_string(pkg, PAKFIRE_PKG_GROUPS);
+       char** groups = pakfire_package_get_strings(pkg, PAKFIRE_PKG_GROUPS);
        if (groups) {
-               r = pakfire_json_add_string(pkg->pakfire, md, "groups", groups);
+               r = pakfire_json_add_string_array(pkg->pakfire, md, "groups", groups);
+
+               // Cleanup
+               pakfire_strings_free(groups);
+
                if (r)
                        goto ERROR;
        }