]> git.ipfire.org Git - pakfire.git/commitdiff
libpakfire: Add lmdb database environment
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 19 Jan 2021 19:59:57 +0000 (19:59 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 19 Jan 2021 19:59:57 +0000 (19:59 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/libpakfire/db.c [new file with mode: 0644]
src/libpakfire/include/pakfire/db.h [new file with mode: 0644]
src/libpakfire/pakfire.c

index 64b998fbf0ddec7a49491f8b8b4c8ad77404d5dc..a48d9a10d77f9d16653e6e5af30e6a50234954db 100644 (file)
@@ -269,6 +269,7 @@ lib_LTLIBRARIES += \
 libpakfire_la_SOURCES = \
        src/libpakfire/arch.c \
        src/libpakfire/archive.c \
+       src/libpakfire/db.c \
        src/libpakfire/errno.c \
        src/libpakfire/execute.c \
        src/libpakfire/file.c \
@@ -294,6 +295,7 @@ pkginclude_HEADERS += \
        src/libpakfire/include/pakfire/arch.h \
        src/libpakfire/include/pakfire/archive.h \
        src/libpakfire/include/pakfire/constants.h \
+       src/libpakfire/include/pakfire/db.h \
        src/libpakfire/include/pakfire/errno.h \
        src/libpakfire/include/pakfire/execute.h \
        src/libpakfire/include/pakfire/file.h \
diff --git a/src/libpakfire/db.c b/src/libpakfire/db.c
new file mode 100644 (file)
index 0000000..865ef64
--- /dev/null
@@ -0,0 +1,130 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2021 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 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           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <lmdb.h>
+
+#include <pakfire/db.h>
+#include <pakfire/pakfire.h>
+#include <pakfire/logging.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+struct pakfire_db {
+       Pakfire pakfire;
+       int nrefs;
+};
+
+/*
+       This function initialises the database environment, but stores it in the main pakfire
+       object so that we do not have to create a circle-reference between pakfire and the
+       database object.
+*/
+int pakfire_db_env_init(Pakfire pakfire, MDB_env** env) {
+       DEBUG(pakfire, "Initialising database environment\n");
+
+       // Allocate database environment
+       int r = mdb_env_create(env);
+       if (r) {
+               ERROR(pakfire, "Could not allocate database environment\n");
+               return r;
+       }
+
+       const char* root = pakfire_get_path(pakfire);
+       char* path = pakfire_path_join(root, "var/lib/pakfire/database.db");
+
+       // Ensure the directory exists
+       pakfire_mkdir(pakfire, path, 0);
+
+       // Open the database environment
+       r = mdb_env_open(*env, path, 0, 0660);
+       if (r) {
+               switch (r) {
+                       case MDB_VERSION_MISMATCH:
+                               ERROR(pakfire, "The database is of an incompatible version\n");
+                               errno = EINVAL;
+                               break;
+
+                       case MDB_INVALID:
+                               errno = EINVAL;
+                               break;
+
+                       default:
+                               ERROR(pakfire, "Could not open database %s: %s\n", path, strerror(errno));
+                               errno = r;
+               }
+
+               // Reset r to non-zero
+               r = 1;
+               goto ERROR;
+       }
+
+ERROR:
+       free(path);
+
+       return r;
+}
+
+void pakfire_db_env_free(Pakfire pakfire, MDB_env* env) {
+       DEBUG(pakfire, "Freeing database environment\n");
+
+       if (env)
+               mdb_env_close(env);
+}
+
+int pakfire_db_open(struct pakfire_db** db, Pakfire pakfire) {
+       struct pakfire_db* o = pakfire_calloc(1, sizeof(*o));
+       if (!o)
+               return -ENOMEM;
+
+       DEBUG(pakfire, "Allocated database at %p\n", o);
+
+       o->pakfire = pakfire_ref(pakfire);
+       o->nrefs = 1;
+
+       *db = o;
+
+       return 0;
+}
+
+struct pakfire_db* pakfire_db_ref(struct pakfire_db* db) {
+       db->nrefs++;
+
+       return db;
+}
+
+static void pakfire_db_free(struct pakfire_db* db) {
+       DEBUG(db->pakfire, "Releasing database at %p\n", db);
+
+       pakfire_unref(db->pakfire);
+
+       pakfire_free(db);
+}
+
+struct pakfire_db* pakfire_db_unref(struct pakfire_db* db) {
+       if (--db->nrefs > 0)
+               return db;
+
+       pakfire_db_free(db);
+
+       return NULL;
+}
diff --git a/src/libpakfire/include/pakfire/db.h b/src/libpakfire/include/pakfire/db.h
new file mode 100644 (file)
index 0000000..79f505d
--- /dev/null
@@ -0,0 +1,42 @@
+/*#############################################################################
+#                                                                             #
+# Pakfire - The IPFire package management system                              #
+# Copyright (C) 2021 Pakfire development team                                 #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 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           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#ifndef PAKFIRE_DB_H
+#define PAKFIRE_DB_H
+
+#ifdef PAKFIRE_PRIVATE
+
+#include <lmdb.h>
+
+#include <pakfire/types.h>
+
+struct pakfire_db;
+
+int pakfire_db_env_init(Pakfire pakfire, MDB_env** env);
+void pakfire_db_env_free(Pakfire pakfire, MDB_env* env);
+
+int pakfire_db_open(struct pakfire_db** db, Pakfire pakfire);
+
+struct pakfire_db* pakfire_db_ref(struct pakfire_db* db);
+struct pakfire_db* pakfire_db_unref(struct pakfire_db* db);
+
+#endif
+
+#endif /* PAKFIRE_DB_H */
index a05dbecb333793716f4a81c0b280eb7b4ca20d62..d1583721852c9affde05eb05b9bdf175ab3b9ce4 100644 (file)
@@ -29,6 +29,8 @@
 #include <syslog.h>
 #include <unistd.h>
 
+#include <lmdb.h>
+
 #include <solv/evr.h>
 #include <solv/pool.h>
 #include <solv/poolarch.h>
@@ -36,6 +38,7 @@
 
 #include <pakfire/arch.h>
 #include <pakfire/constants.h>
+#include <pakfire/db.h>
 #include <pakfire/logging.h>
 #include <pakfire/package.h>
 #include <pakfire/packagelist.h>
@@ -50,6 +53,9 @@ struct _Pakfire {
        char* cache_path;
        char* arch;
 
+       // Database Environment
+       MDB_env* mdb_env;
+
        // Pool stuff
        Pool* pool;
        int pool_ready;
@@ -81,6 +87,32 @@ static int log_priority(const char* priority) {
        return 0;
 }
 
+// A utility function is already called pakfire_free
+static void _pakfire_free(Pakfire pakfire) {
+       DEBUG(pakfire, "Releasing Pakfire at %p\n", pakfire);
+
+       pakfire_repo_free_all(pakfire);
+
+       if (pakfire->mdb_env)
+               pakfire_db_env_free(pakfire, pakfire->mdb_env);
+
+       if (pakfire->pool)
+               pool_free(pakfire->pool);
+
+       queue_free(&pakfire->installonly);
+
+       if (pakfire->arch)
+               pakfire_free(pakfire->arch);
+
+       if (pakfire->path)
+               pakfire_free(pakfire->path);
+
+       if (pakfire->cache_path)
+               pakfire_free(pakfire->cache_path);
+
+       pakfire_free(pakfire);
+}
+
 PAKFIRE_EXPORT int pakfire_create(Pakfire* pakfire, const char* path, const char* arch) {
        // Default to the native architecture
        if (!arch)
@@ -123,6 +155,14 @@ PAKFIRE_EXPORT int pakfire_create(Pakfire* pakfire, const char* path, const char
        DEBUG(p, "  arch = %s\n", pakfire_get_arch(p));
        DEBUG(p, "  path = %s\n", pakfire_get_path(p));
 
+       // Initialise the database environment
+       int r = pakfire_db_env_init(p, &p->mdb_env);
+       if (r) {
+               _pakfire_free(p);
+
+               return r;
+       }
+
        // Initialize the pool
        p->pool = pool_create();
        pool_setdisttype(p->pool, DISTTYPE_RPM);
@@ -149,23 +189,10 @@ PAKFIRE_EXPORT Pakfire pakfire_ref(Pakfire pakfire) {
 }
 
 PAKFIRE_EXPORT Pakfire pakfire_unref(Pakfire pakfire) {
-       if (!pakfire)
-               return NULL;
-
        if (--pakfire->nrefs > 0)
                return pakfire;
 
-       DEBUG(pakfire, "Releasing Pakfire at %p\n", pakfire);
-
-       pakfire_repo_free_all(pakfire);
-       pool_free(pakfire->pool);
-       queue_free(&pakfire->installonly);
-
-       pakfire_free(pakfire->path);
-       pakfire_free(pakfire->cache_path);
-       pakfire_free(pakfire->arch);
-
-       pakfire_free(pakfire);
+       _pakfire_free(pakfire);
 
        return NULL;
 }