1 /*#############################################################################
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2021 Pakfire development team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
27 #include <pakfire/archive.h>
28 #include <pakfire/db.h>
29 #include <pakfire/file.h>
30 #include <pakfire/logging.h>
31 #include <pakfire/package.h>
32 #include <pakfire/pakfire.h>
33 #include <pakfire/private.h>
34 #include <pakfire/relationlist.h>
35 #include <pakfire/repo.h>
36 #include <pakfire/types.h>
37 #include <pakfire/util.h>
39 #define DATABASE_PATH PAKFIRE_PRIVATE_DIR "/packages.db"
41 #define CURRENT_SCHEMA 8
42 #define SCHEMA_MIN_SUP 7
54 static void logging_callback(void* data
, int r
, const char* msg
) {
55 Pakfire pakfire
= (Pakfire
)data
;
57 ERROR(pakfire
, "Database Error: %s: %s\n",
58 sqlite3_errstr(r
), msg
);
61 static int pakfire_db_execute(struct pakfire_db
* db
, const char* stmt
) {
64 DEBUG(db
->pakfire
, "Executing database query: %s\n", stmt
);
67 r
= sqlite3_exec(db
->handle
, stmt
, NULL
, NULL
, NULL
);
68 } while (r
== SQLITE_BUSY
);
72 ERROR(db
->pakfire
, "Database query failed: %s\n", sqlite3_errmsg(db
->handle
));
78 static int pakfire_db_begin_transaction(struct pakfire_db
* db
) {
79 return pakfire_db_execute(db
, "BEGIN TRANSACTION");
82 static int pakfire_db_commit(struct pakfire_db
* db
) {
83 return pakfire_db_execute(db
, "COMMIT");
86 static int pakfire_db_rollback(struct pakfire_db
* db
) {
87 return pakfire_db_execute(db
, "ROLLBACK");
91 This function performs any fast optimization and tries to truncate the WAL log file
92 to keep the database as compact as possible on disk.
94 static void pakfire_db_optimize(struct pakfire_db
* db
) {
95 pakfire_db_execute(db
, "PRAGMA optimize");
96 pakfire_db_execute(db
, "PRAGMA wal_checkpoint = TRUNCATE");
99 static void pakfire_db_free(struct pakfire_db
* db
) {
100 DEBUG(db
->pakfire
, "Releasing database at %p\n", db
);
103 // Optimize the database before it is being closed
104 pakfire_db_optimize(db
);
106 // Close database handle
107 int r
= sqlite3_close(db
->handle
);
108 if (r
!= SQLITE_OK
) {
109 ERROR(db
->pakfire
, "Could not close database handle: %s\n",
110 sqlite3_errmsg(db
->handle
));
114 pakfire_unref(db
->pakfire
);
119 static sqlite3_value
* pakfire_db_get(struct pakfire_db
* db
, const char* key
) {
120 sqlite3_stmt
* stmt
= NULL
;
121 sqlite3_value
* val
= NULL
;
124 const char* sql
= "SELECT val FROM settings WHERE key = ?";
126 // Prepare the statement
127 r
= sqlite3_prepare_v2(db
->handle
, sql
, strlen(sql
), &stmt
, NULL
);
128 if (r
!= SQLITE_OK
) {
129 //ERROR(db->pakfire, "Could not prepare SQL statement: %s: %s\n",
130 // sql, sqlite3_errmsg(db->handle));
135 r
= sqlite3_bind_text(stmt
, 1, key
, strlen(key
), NULL
);
136 if (r
!= SQLITE_OK
) {
137 ERROR(db
->pakfire
, "Could not bind key: %s\n", sqlite3_errmsg(db
->handle
));
141 // Execute the statement
143 r
= sqlite3_step(stmt
);
144 } while (r
== SQLITE_BUSY
);
146 // We should have read a row
151 val
= sqlite3_column_value(stmt
, 0);
153 ERROR(db
->pakfire
, "Could not read value\n");
157 // Copy value onto the heap
158 val
= sqlite3_value_dup(val
);
162 sqlite3_finalize(stmt
);
167 static int pakfire_db_set_int(struct pakfire_db
* db
, const char* key
, int val
) {
168 sqlite3_stmt
* stmt
= NULL
;
171 const char* sql
= "INSERT INTO settings(key, val) VALUES(?, ?) \
172 ON CONFLICT (key) DO UPDATE SET val = excluded.val";
175 r
= sqlite3_prepare_v2(db
->handle
, sql
, strlen(sql
), &stmt
, NULL
);
176 if (r
!= SQLITE_OK
) {
177 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s: %s\n",
178 sql
, sqlite3_errmsg(db
->handle
));
183 r
= sqlite3_bind_text(stmt
, 1, key
, strlen(key
), NULL
);
184 if (r
!= SQLITE_OK
) {
185 ERROR(db
->pakfire
, "Could not bind key: %s\n", sqlite3_errmsg(db
->handle
));
190 r
= sqlite3_bind_int64(stmt
, 2, val
);
191 if (r
!= SQLITE_OK
) {
192 ERROR(db
->pakfire
, "Could not bind val: %s\n", sqlite3_errmsg(db
->handle
));
196 // Execute the statement
198 r
= sqlite3_step(stmt
);
199 } while (r
== SQLITE_BUSY
);
202 r
= (r
== SQLITE_OK
);
206 sqlite3_finalize(stmt
);
211 static int pakfire_db_get_schema(struct pakfire_db
* db
) {
212 sqlite3_value
* value
= pakfire_db_get(db
, "schema");
216 int schema
= sqlite3_value_int64(value
);
217 sqlite3_value_free(value
);
219 DEBUG(db
->pakfire
, "Database has schema version %d\n", schema
);
224 static int pakfire_db_create_schema(struct pakfire_db
* db
) {
227 // Create settings table
228 r
= pakfire_db_execute(db
, "CREATE TABLE IF NOT EXISTS settings(key TEXT, val TEXT)");
232 // settings: Add a unique index on key
233 r
= pakfire_db_execute(db
, "CREATE UNIQUE INDEX IF NOT EXISTS settings_key ON settings(key)");
237 // Create packages table
238 r
= pakfire_db_execute(db
,
239 "CREATE TABLE IF NOT EXISTS packages("
240 "id INTEGER PRIMARY KEY, "
249 "inst_size INTEGER, "
257 "build_time INTEGER, "
258 "installed INTEGER, "
265 // packages: Create index to find package by name
266 r
= pakfire_db_execute(db
, "CREATE INDEX IF NOT EXISTS packages_name ON packages(name)");
270 // packages: Create unique index over UUID
271 r
= pakfire_db_execute(db
, "CREATE UNIQUE INDEX IF NOT EXISTS packages_uuid ON packages(uuid)");
275 // Create dependencies table
276 r
= pakfire_db_execute(db
,
277 "CREATE TABLE IF NOT EXISTS dependencies("
281 "FOREIGN KEY (pkg) REFERENCES packages(id) ON DELETE CASCADE"
286 // dependencies: Add index over packages
287 r
= pakfire_db_execute(db
, "CREATE INDEX IF NOT EXISTS dependencies_pkg_index ON dependencies(pkg)");
291 // Create files table
292 r
= pakfire_db_execute(db
,
293 "CREATE TABLE IF NOT EXISTS files("
294 "id INTEGER PRIMARY KEY, "
306 "capabilities TEXT, "
307 "FOREIGN KEY (pkg) REFERENCES packages(id) ON DELETE CASCADE"
312 // files: Add index over packages
313 r
= pakfire_db_execute(db
, "CREATE INDEX IF NOT EXISTS files_pkg_index ON files(pkg)");
317 // Create scriptlets table
318 r
= pakfire_db_execute(db
,
319 "CREATE TABLE IF NOT EXISTS scriptlets("
320 "id INTEGER PRIMARY KEY, "
324 "FOREIGN KEY (pkg) REFERENCES packages(id) ON DELETE CASCADE"
329 // scriptlets: Add index over packages
330 r
= pakfire_db_execute(db
, "CREATE INDEX IF NOT EXISTS scriptlets_pkg_index ON scriptlets(pkg)");
337 static int pakfire_db_migrate_to_schema_8(struct pakfire_db
* db
) {
338 // packages: Drop build_id column
341 // TODO sqlite doesn't support adding foreign keys to existing tables and so we would
342 // need to recreate the whole table and rename it afterwards. Annoying.
347 static int pakfire_db_migrate_schema(struct pakfire_db
* db
) {
350 while (db
->schema
< CURRENT_SCHEMA
) {
351 // Begin a new transaction
352 r
= pakfire_db_begin_transaction(db
);
356 switch (db
->schema
) {
359 r
= pakfire_db_create_schema(db
);
363 db
->schema
= CURRENT_SCHEMA
;
367 r
= pakfire_db_migrate_to_schema_8(db
);
375 ERROR(db
->pakfire
, "Cannot migrate database from schema %d\n", db
->schema
);
379 // Update the schema version
380 r
= pakfire_db_set_int(db
, "schema", CURRENT_SCHEMA
);
385 r
= pakfire_db_commit(db
);
393 pakfire_db_rollback(db
);
398 static int pakfire_db_setup(struct pakfire_db
* db
) {
402 sqlite3_config(SQLITE_CONFIG_LOG
, logging_callback
, db
->pakfire
);
404 // Enable foreign keys
405 pakfire_db_execute(db
, "PRAGMA foreign_keys = ON");
407 // Make LIKE case-sensitive
408 pakfire_db_execute(db
, "PRAGMA case_sensitive_like = ON");
410 // Fetch the current schema
411 db
->schema
= pakfire_db_get_schema(db
);
413 // Check if the schema is recent enough
414 if (db
->schema
> 0 && db
->schema
< SCHEMA_MIN_SUP
) {
415 ERROR(db
->pakfire
, "Database schema %d is not supported by this version of Pakfire\n",
420 // Done when not in read-write mode
421 if (db
->mode
!= PAKFIRE_DB_READWRITE
)
424 // Disable secure delete
425 pakfire_db_execute(db
, "PRAGMA secure_delete = OFF");
427 // Set database journal to WAL
428 r
= pakfire_db_execute(db
, "PRAGMA journal_mode = WAL");
429 if (r
!= SQLITE_OK
) {
430 ERROR(db
->pakfire
, "Could not set journal mode to WAL: %s\n",
431 sqlite3_errmsg(db
->handle
));
435 // Disable autocheckpoint
436 r
= sqlite3_wal_autocheckpoint(db
->handle
, 0);
437 if (r
!= SQLITE_OK
) {
438 ERROR(db
->pakfire
, "Could not disable autocheckpoint: %s\n",
439 sqlite3_errmsg(db
->handle
));
443 // Create or migrate schema
444 r
= pakfire_db_migrate_schema(db
);
451 PAKFIRE_EXPORT
int pakfire_db_open(struct pakfire_db
** db
, Pakfire pakfire
, int flags
) {
454 struct pakfire_db
* o
= calloc(1, sizeof(*o
));
458 DEBUG(pakfire
, "Allocated database at %p\n", o
);
460 o
->pakfire
= pakfire_ref(pakfire
);
463 int sqlite3_flags
= 0;
465 // Store mode & forward it to sqlite3
466 if (flags
& PAKFIRE_DB_READWRITE
) {
467 o
->mode
= PAKFIRE_DB_READWRITE
;
468 sqlite3_flags
|= SQLITE_OPEN_READWRITE
| SQLITE_OPEN_CREATE
;
470 o
->mode
= PAKFIRE_DB_READONLY
;
471 sqlite3_flags
|= SQLITE_OPEN_READONLY
;
475 char* path
= pakfire_make_path(o
->pakfire
, DATABASE_PATH
);
479 // Try to open the sqlite3 database file
480 r
= sqlite3_open_v2(path
, &o
->handle
, sqlite3_flags
, NULL
);
481 if (r
!= SQLITE_OK
) {
482 ERROR(pakfire
, "Could not open database %s: %s\n",
483 path
, sqlite3_errmsg(o
->handle
));
489 // Setup the database
490 r
= pakfire_db_setup(o
);
507 PAKFIRE_EXPORT
struct pakfire_db
* pakfire_db_ref(struct pakfire_db
* db
) {
513 PAKFIRE_EXPORT
struct pakfire_db
* pakfire_db_unref(struct pakfire_db
* db
) {
522 static unsigned long pakfire_db_integrity_check(struct pakfire_db
* db
) {
523 sqlite3_stmt
* stmt
= NULL
;
526 r
= sqlite3_prepare_v2(db
->handle
, "PRAGMA integrity_check", -1, &stmt
, NULL
);
528 ERROR(db
->pakfire
, "Could not prepare integrity check: %s\n",
529 sqlite3_errmsg(db
->handle
));
534 unsigned long errors
= 0;
538 r
= sqlite3_step(stmt
);
539 } while (r
== SQLITE_BUSY
);
541 if (r
== SQLITE_ROW
) {
542 const char* error
= (const char*)sqlite3_column_text(stmt
, 0);
544 // If the message is "ok", the database has passed the check
545 if (strcmp(error
, "ok") == 0)
548 // Increment error counter
552 ERROR(db
->pakfire
, "%s\n", error
);
554 // Break on anything else
559 sqlite3_finalize(stmt
);
562 ERROR(db
->pakfire
, "Database integrity check failed\n");
564 INFO(db
->pakfire
, "Database integrity check passed\n");
569 static unsigned long pakfire_db_foreign_key_check(struct pakfire_db
* db
) {
570 sqlite3_stmt
* stmt
= NULL
;
573 r
= sqlite3_prepare_v2(db
->handle
, "PRAGMA foreign_key_check", -1, &stmt
, NULL
);
575 ERROR(db
->pakfire
, "Could not prepare foreign key check: %s\n",
576 sqlite3_errmsg(db
->handle
));
581 unsigned long errors
= 0;
585 r
= sqlite3_step(stmt
);
586 } while (r
== SQLITE_BUSY
);
588 if (r
== SQLITE_ROW
) {
589 const unsigned char* table
= sqlite3_column_text(stmt
, 0);
590 unsigned long rowid
= sqlite3_column_int64(stmt
, 1);
591 const unsigned char* foreign_table
= sqlite3_column_text(stmt
, 2);
592 unsigned long foreign_rowid
= sqlite3_column_int64(stmt
, 3);
594 // Increment error counter
598 ERROR(db
->pakfire
, "Foreign key violation found in %s, row %lu: "
599 "%lu does not exist in table %s\n", table
, rowid
, foreign_rowid
, foreign_table
);
601 // Break on anything else
606 sqlite3_finalize(stmt
);
609 ERROR(db
->pakfire
, "Foreign key check failed\n");
611 INFO(db
->pakfire
, "Foreign key check passed\n");
617 This function performs an integrity check of the database
619 PAKFIRE_EXPORT
int pakfire_db_check(struct pakfire_db
* db
) {
622 // Perform integrity check
623 r
= pakfire_db_integrity_check(db
);
627 // Perform foreign key check
628 r
= pakfire_db_foreign_key_check(db
);
635 // Returns the number of packages installed
636 PAKFIRE_EXPORT ssize_t
pakfire_db_packages(struct pakfire_db
* db
) {
637 sqlite3_stmt
* stmt
= NULL
;
638 ssize_t packages
= -1;
640 int r
= sqlite3_prepare_v2(db
->handle
, "SELECT COUNT(*) FROM packages", -1, &stmt
, NULL
);
642 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s\n",
643 sqlite3_errmsg(db
->handle
));
649 r
= sqlite3_step(stmt
);
650 } while (r
== SQLITE_BUSY
);
652 if (r
== SQLITE_ROW
) {
653 packages
= sqlite3_column_int64(stmt
, 0);
656 sqlite3_finalize(stmt
);
661 static int pakfire_db_add_dependencies(struct pakfire_db
* db
, unsigned long id
, PakfirePackage pkg
) {
662 sqlite3_stmt
* stmt
= NULL
;
665 const char* sql
= "INSERT INTO dependencies(pkg, type, dependency) VALUES(?, ?, ?)";
667 // Prepare the statement
668 r
= sqlite3_prepare_v2(db
->handle
, sql
, -1, &stmt
, NULL
);
670 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s: %s\n",
671 sql
, sqlite3_errmsg(db
->handle
));
675 const struct __relation
{
677 PakfireRelationList (*func
)(PakfirePackage
);
679 { "provides", pakfire_package_get_provides
},
680 { "prerequires", pakfire_package_get_prerequires
},
681 { "requires", pakfire_package_get_requires
},
682 { "conflicts", pakfire_package_get_conflicts
},
683 { "obsoletes", pakfire_package_get_obsoletes
},
684 { "recommends", pakfire_package_get_recommends
},
685 { "suggests", pakfire_package_get_suggests
},
686 { "supplements", pakfire_package_get_supplements
},
687 { "enhances", pakfire_package_get_enhances
},
691 for (const struct __relation
* relation
= relations
; relation
->type
; relation
++) {
692 PakfireRelationList list
= relation
->func(pkg
);
696 for (unsigned int i
= 0; i
< pakfire_relationlist_size(list
); i
++) {
697 PakfireRelation rel
= pakfire_relationlist_get(list
, i
);
701 char* dependency
= pakfire_relation_str(rel
);
703 pakfire_relation_unref(rel
);
709 r
= sqlite3_bind_int64(stmt
, 1, id
);
711 ERROR(db
->pakfire
, "Could not bind id: %s\n",
712 sqlite3_errmsg(db
->handle
));
713 pakfire_relation_unref(rel
);
718 r
= sqlite3_bind_text(stmt
, 2, relation
->type
, -1, NULL
);
720 ERROR(db
->pakfire
, "Could not bind type: %s\n",
721 sqlite3_errmsg(db
->handle
));
722 pakfire_relation_unref(rel
);
727 r
= sqlite3_bind_text(stmt
, 3, dependency
, -1, NULL
);
729 ERROR(db
->pakfire
, "Could not bind dependency: %s\n",
730 sqlite3_errmsg(db
->handle
));
731 pakfire_relation_unref(rel
);
737 r
= sqlite3_step(stmt
);
738 } while (r
== SQLITE_BUSY
);
740 pakfire_relation_unref(rel
);
743 // Reset bound values
747 pakfire_relationlist_unref(list
);
755 sqlite3_finalize(stmt
);
760 static int pakfire_db_add_files(struct pakfire_db
* db
, unsigned long id
, PakfireArchive archive
) {
761 sqlite3_stmt
* stmt
= NULL
;
764 // Get the filelist from the archive
765 PakfireFilelist filelist
= pakfire_archive_get_filelist(archive
);
767 ERROR(db
->pakfire
, "Could not fetch filelist from archive\n");
771 // Nothing to do if the list is empty
772 if (pakfire_filelist_is_empty(filelist
)) {
777 const char* sql
= "INSERT INTO files(pkg, name, size, type, config, datafile, mode, "
778 "user, 'group', hash1, mtime, capabilities) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
780 // Prepare the statement
781 r
= sqlite3_prepare_v2(db
->handle
, sql
, -1, &stmt
, NULL
);
783 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s: %s\n",
784 sql
, sqlite3_errmsg(db
->handle
));
788 for (unsigned int i
= 0; i
< pakfire_filelist_size(filelist
); i
++) {
789 PakfireFile file
= pakfire_filelist_get(filelist
, i
);
792 r
= sqlite3_bind_int64(stmt
, 1, id
);
794 ERROR(db
->pakfire
, "Could not bind id: %s\n", sqlite3_errmsg(db
->handle
));
795 pakfire_file_unref(file
);
800 const char* name
= pakfire_file_get_name(file
);
802 r
= sqlite3_bind_text(stmt
, 2, name
, -1, NULL
);
804 ERROR(db
->pakfire
, "Could not bind name: %s\n", sqlite3_errmsg(db
->handle
));
805 pakfire_file_unref(file
);
810 size_t size
= pakfire_file_get_size(file
);
812 r
= sqlite3_bind_int64(stmt
, 3, size
);
814 ERROR(db
->pakfire
, "Could not bind size: %s\n", sqlite3_errmsg(db
->handle
));
815 pakfire_file_unref(file
);
819 // Bind type - XXX this is char which isn't very helpful
820 //char type = pakfire_file_get_type(file);
822 r
= sqlite3_bind_null(stmt
, 4);
824 ERROR(db
->pakfire
, "Could not bind type: %s\n", sqlite3_errmsg(db
->handle
));
825 pakfire_file_unref(file
);
829 // Bind config - XXX TODO
830 r
= sqlite3_bind_null(stmt
, 5);
832 ERROR(db
->pakfire
, "Could not bind config: %s\n", sqlite3_errmsg(db
->handle
));
833 pakfire_file_unref(file
);
837 // Bind datafile - XXX TODO
838 r
= sqlite3_bind_null(stmt
, 6);
840 ERROR(db
->pakfire
, "Could not bind datafile: %s\n", sqlite3_errmsg(db
->handle
));
841 pakfire_file_unref(file
);
846 mode_t mode
= pakfire_file_get_mode(file
);
848 r
= sqlite3_bind_int64(stmt
, 7, mode
);
850 ERROR(db
->pakfire
, "Could not bind mode: %s\n", sqlite3_errmsg(db
->handle
));
851 pakfire_file_unref(file
);
856 const char* user
= pakfire_file_get_user(file
);
858 r
= sqlite3_bind_text(stmt
, 8, user
, -1, NULL
);
860 ERROR(db
->pakfire
, "Could not bind user: %s\n", sqlite3_errmsg(db
->handle
));
861 pakfire_file_unref(file
);
866 const char* group
= pakfire_file_get_group(file
);
868 r
= sqlite3_bind_text(stmt
, 9, group
, -1, NULL
);
870 ERROR(db
->pakfire
, "Could not bind group: %s\n", sqlite3_errmsg(db
->handle
));
871 pakfire_file_unref(file
);
876 const char* chksum
= pakfire_file_get_chksum(file
);
878 r
= sqlite3_bind_text(stmt
, 10, chksum
, -1, NULL
);
880 ERROR(db
->pakfire
, "Could not bind hash1: %s\n", sqlite3_errmsg(db
->handle
));
881 pakfire_file_unref(file
);
886 time_t mtime
= pakfire_file_get_time(file
);
888 r
= sqlite3_bind_int64(stmt
, 11, mtime
);
890 ERROR(db
->pakfire
, "Could not bind mtime: %s\n", sqlite3_errmsg(db
->handle
));
891 pakfire_file_unref(file
);
895 // Bind capabilities - XXX TODO
896 r
= sqlite3_bind_null(stmt
, 12);
898 ERROR(db
->pakfire
, "Could not bind capabilities: %s\n", sqlite3_errmsg(db
->handle
));
899 pakfire_file_unref(file
);
905 r
= sqlite3_step(stmt
);
906 } while (r
== SQLITE_BUSY
);
908 // Move on to next file
909 pakfire_file_unref(file
);
912 if (r
!= SQLITE_DONE
) {
913 ERROR(db
->pakfire
, "Could not add file to database: %s\n",
914 sqlite3_errmsg(db
->handle
));
918 // Reset bound values
927 sqlite3_finalize(stmt
);
929 pakfire_filelist_unref(filelist
);
934 static int pakfire_db_add_scriptlets(struct pakfire_db
* db
, unsigned long id
, PakfireArchive archive
) {
935 sqlite3_stmt
* stmt
= NULL
;
938 const struct pakfire_scriptlet_type
* scriptlet_type
= PAKFIRE_SCRIPTLET_TYPES
;
939 struct pakfire_scriptlet
* scriptlet
;
941 const char* sql
= "INSERT INTO scriptlets(pkg, type, scriptlet) VALUES(?, ?, ?)";
943 // Prepare the statement
944 r
= sqlite3_prepare_v2(db
->handle
, sql
, -1, &stmt
, NULL
);
946 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s: %s\n",
947 sql
, sqlite3_errmsg(db
->handle
));
951 while (scriptlet_type
->type
) {
952 // Fetch the scriptlet
953 scriptlet
= pakfire_archive_get_scriptlet(archive
, scriptlet_type
->type
);
955 // Go to next one if the archive does not have a scriptlet of the given type
962 r
= sqlite3_bind_int64(stmt
, 1, id
);
964 ERROR(db
->pakfire
, "Could not bind id: %s\n", sqlite3_errmsg(db
->handle
));
969 r
= sqlite3_bind_text(stmt
, 2, scriptlet_type
->handle
, -1, NULL
);
971 ERROR(db
->pakfire
, "Could not bind type: %s\n", sqlite3_errmsg(db
->handle
));
976 r
= sqlite3_bind_text(stmt
, 3, scriptlet
->data
, scriptlet
->size
, NULL
);
978 ERROR(db
->pakfire
, "Could not bind scriptlet: %s\n", sqlite3_errmsg(db
->handle
));
984 r
= sqlite3_step(stmt
);
985 } while (r
== SQLITE_BUSY
);
988 if (r
!= SQLITE_DONE
) {
989 ERROR(db
->pakfire
, "Could not add scriptlet to database: %s\n",
990 sqlite3_errmsg(db
->handle
));
994 // Reset bound values
1005 sqlite3_finalize(stmt
);
1010 PAKFIRE_EXPORT
int pakfire_db_add_package(struct pakfire_db
* db
,
1011 PakfirePackage pkg
, PakfireArchive archive
) {
1012 sqlite3_stmt
* stmt
= NULL
;
1015 // Begin a new transaction
1016 r
= pakfire_db_begin_transaction(db
);
1020 const char* sql
= "INSERT INTO packages(name, epoch, version, release, arch, groups, "
1021 "filename, size, inst_size, hash1, license, summary, description, uuid, vendor, "
1022 "build_host, build_time, installed, repository, reason) VALUES(?, ?, "
1023 "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, ?, ?)";
1025 // Prepare the statement
1026 r
= sqlite3_prepare_v2(db
->handle
, sql
, strlen(sql
), &stmt
, NULL
);
1027 if (r
!= SQLITE_OK
) {
1028 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s: %s\n",
1029 sql
, sqlite3_errmsg(db
->handle
));
1034 const char* name
= pakfire_package_get_name(pkg
);
1036 r
= sqlite3_bind_text(stmt
, 1, name
, -1, NULL
);
1038 ERROR(db
->pakfire
, "Could not bind name: %s\n", sqlite3_errmsg(db
->handle
));
1043 unsigned long epoch
= pakfire_package_get_epoch(pkg
);
1045 r
= sqlite3_bind_int64(stmt
, 2, epoch
);
1047 ERROR(db
->pakfire
, "Could not bind epoch: %s\n", sqlite3_errmsg(db
->handle
));
1052 const char* version
= pakfire_package_get_version(pkg
);
1054 r
= sqlite3_bind_text(stmt
, 3, version
, -1, NULL
);
1056 ERROR(db
->pakfire
, "Could not bind version: %s\n", sqlite3_errmsg(db
->handle
));
1061 const char* release
= pakfire_package_get_release(pkg
);
1063 r
= sqlite3_bind_text(stmt
, 4, release
, -1, NULL
);
1065 ERROR(db
->pakfire
, "Could not bind release: %s\n", sqlite3_errmsg(db
->handle
));
1070 const char* arch
= pakfire_package_get_arch(pkg
);
1072 r
= sqlite3_bind_text(stmt
, 5, arch
, -1, NULL
);
1074 ERROR(db
->pakfire
, "Could not bind arch: %s\n", sqlite3_errmsg(db
->handle
));
1079 const char* groups
= pakfire_package_get_groups(pkg
);
1081 r
= sqlite3_bind_text(stmt
, 6, groups
, -1, NULL
);
1083 ERROR(db
->pakfire
, "Could not bind groups: %s\n", sqlite3_errmsg(db
->handle
));
1088 const char* filename
= pakfire_package_get_filename(pkg
);
1090 r
= sqlite3_bind_text(stmt
, 7, filename
, -1, NULL
);
1092 ERROR(db
->pakfire
, "Could not bind filename: %s\n", sqlite3_errmsg(db
->handle
));
1097 unsigned long long size
= pakfire_package_get_downloadsize(pkg
);
1099 r
= sqlite3_bind_int64(stmt
, 8, size
);
1101 ERROR(db
->pakfire
, "Could not bind size: %s\n", sqlite3_errmsg(db
->handle
));
1105 // Bind installed size
1106 unsigned long long inst_size
= pakfire_package_get_installsize(pkg
);
1108 r
= sqlite3_bind_int64(stmt
, 9, inst_size
);
1110 ERROR(db
->pakfire
, "Could not bind inst_size: %s\n", sqlite3_errmsg(db
->handle
));
1115 const char* hash1
= pakfire_package_get_checksum(pkg
);
1117 r
= sqlite3_bind_text(stmt
, 10, hash1
, -1, NULL
);
1119 ERROR(db
->pakfire
, "Could not bind hash1: %s\n", sqlite3_errmsg(db
->handle
));
1124 const char* license
= pakfire_package_get_license(pkg
);
1126 r
= sqlite3_bind_text(stmt
, 11, license
, -1, NULL
);
1128 ERROR(db
->pakfire
, "Could not bind license: %s\n", sqlite3_errmsg(db
->handle
));
1133 const char* summary
= pakfire_package_get_summary(pkg
);
1135 r
= sqlite3_bind_text(stmt
, 12, summary
, -1, NULL
);
1137 ERROR(db
->pakfire
, "Could not bind summary: %s\n", sqlite3_errmsg(db
->handle
));
1142 const char* description
= pakfire_package_get_description(pkg
);
1144 r
= sqlite3_bind_text(stmt
, 13, description
, -1, NULL
);
1146 ERROR(db
->pakfire
, "Could not bind description: %s\n", sqlite3_errmsg(db
->handle
));
1151 const char* uuid
= pakfire_package_get_uuid(pkg
);
1153 r
= sqlite3_bind_text(stmt
, 14, uuid
, -1, NULL
);
1155 ERROR(db
->pakfire
, "Could not bind uuid: %s\n", sqlite3_errmsg(db
->handle
));
1160 const char* vendor
= pakfire_package_get_vendor(pkg
);
1162 r
= sqlite3_bind_text(stmt
, 15, vendor
, -1, NULL
);
1164 ERROR(db
->pakfire
, "Could not bind vendor: %s\n", sqlite3_errmsg(db
->handle
));
1169 const char* build_host
= pakfire_package_get_build_host(pkg
);
1171 r
= sqlite3_bind_text(stmt
, 16, build_host
, -1, NULL
);
1173 ERROR(db
->pakfire
, "Could not bind build_host: %s\n", sqlite3_errmsg(db
->handle
));
1178 time_t build_time
= pakfire_package_get_build_time(pkg
);
1180 r
= sqlite3_bind_int64(stmt
, 17, build_time
);
1182 ERROR(db
->pakfire
, "Could not bind build_time: %s\n", sqlite3_errmsg(db
->handle
));
1186 // Bind repository name
1187 PakfireRepo repo
= pakfire_package_get_repo(pkg
);
1189 const char* repo_name
= pakfire_repo_get_name(repo
);
1190 pakfire_repo_unref(repo
);
1192 r
= sqlite3_bind_text(stmt
, 18, repo_name
, -1, NULL
);
1198 r
= sqlite3_bind_null(stmt
, 18);
1203 // XXX TODO Bind reason
1204 r
= sqlite3_bind_null(stmt
, 19);
1210 r
= sqlite3_step(stmt
);
1211 } while (r
== SQLITE_BUSY
);
1213 if (r
!= SQLITE_DONE
) {
1214 ERROR(db
->pakfire
, "Could not add package to database: %s\n",
1215 sqlite3_errmsg(db
->handle
));
1220 unsigned long packages_id
= sqlite3_last_insert_rowid(db
->handle
);
1223 r
= sqlite3_finalize(stmt
);
1228 r
= pakfire_db_add_dependencies(db
, packages_id
, pkg
);
1233 r
= pakfire_db_add_files(db
, packages_id
, archive
);
1238 r
= pakfire_db_add_scriptlets(db
, packages_id
, archive
);
1242 // All done, commit!
1243 r
= pakfire_db_commit(db
);
1251 sqlite3_finalize(stmt
);
1253 pakfire_db_rollback(db
);
1258 PAKFIRE_EXPORT
int pakfire_db_remove_package(struct pakfire_db
* db
, PakfirePackage pkg
) {
1259 sqlite3_stmt
* stmt
= NULL
;
1262 // Fetch the package's UUID
1263 const char* uuid
= pakfire_package_get_uuid(pkg
);
1265 ERROR(db
->pakfire
, "Package has no UUID\n");
1269 r
= sqlite3_prepare_v2(db
->handle
,
1270 "DELETE FROM packages WHERE uuid = ?", -1, &stmt
, NULL
);
1272 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s\n",
1273 sqlite3_errmsg(db
->handle
));
1278 r
= sqlite3_bind_text(stmt
, 1, uuid
, -1, NULL
);
1280 ERROR(db
->pakfire
, "Could not bind uuid: %s\n", sqlite3_errmsg(db
->handle
));
1286 r
= sqlite3_step(stmt
);
1287 } while (r
== SQLITE_BUSY
);
1289 // Check if we have been successful
1290 if (r
!= SQLITE_DONE
) {
1291 ERROR(db
->pakfire
, "Could not delete package %s\n", uuid
);
1300 sqlite3_finalize(stmt
);
1305 struct pakfire_scriptlet
* pakfire_db_get_scriptlet(struct pakfire_db
* db
,
1306 PakfirePackage pkg
, pakfire_scriptlet_type type
) {
1307 struct pakfire_scriptlet
* scriptlet
= NULL
;
1308 sqlite3_stmt
* stmt
= NULL
;
1311 // Fetch the package's UUID
1312 const char* uuid
= pakfire_package_get_uuid(pkg
);
1314 ERROR(db
->pakfire
, "Package has no UUID\n");
1318 const char* sql
= "SELECT scriptlet.scriptlet FROM packages \
1319 JOIN scriptlets ON packages.id = scriptlets.pkg \
1320 WHERE packages.uuid = ? AND scriptlets.type = ?";
1322 r
= sqlite3_prepare_v2(db
->handle
, sql
, strlen(sql
), &stmt
, NULL
);
1324 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s %s\n",
1325 sql
, sqlite3_errmsg(db
->handle
));
1330 r
= sqlite3_bind_text(stmt
, 1, uuid
, -1, NULL
);
1332 ERROR(db
->pakfire
, "Could not bind uuid: %s\n", sqlite3_errmsg(db
->handle
));
1337 const char* handle
= pakfire_scriptlet_handle_from_type(type
);
1341 r
= sqlite3_bind_text(stmt
, 2, handle
, -1, NULL
);
1343 ERROR(db
->pakfire
, "Could not bind type: %s\n", sqlite3_errmsg(db
->handle
));
1347 DEBUG(db
->pakfire
, "Searching for scriptlet for package %s of type %s\n", uuid
, handle
);
1351 r
= sqlite3_step(stmt
);
1352 } while (r
== SQLITE_BUSY
);
1354 // We have some payload
1355 if (r
== SQLITE_ROW
) {
1356 const void* data
= sqlite3_column_blob(stmt
, 1);
1357 ssize_t size
= sqlite3_column_bytes(stmt
, 1);
1359 // Create a scriptlet object
1360 scriptlet
= pakfire_scriptlet_create(db
->pakfire
, data
, size
);
1367 sqlite3_finalize(stmt
);
1372 static int pakfire_db_load_package(struct pakfire_db
* db
, PakfireRepo repo
, sqlite3_stmt
* stmt
) {
1373 PakfirePackage pkg
= NULL
;
1378 const char* name
= (const char*)sqlite3_column_text(stmt
, 0);
1380 ERROR(db
->pakfire
, "Could not read name: %s\n", sqlite3_errmsg(db
->handle
));
1384 // Epoch (INTEGER but cast as string)
1385 const char* epoch
= (const char*)sqlite3_column_text(stmt
, 1);
1387 ERROR(db
->pakfire
, "Could not read epoch: %s\n", sqlite3_errmsg(db
->handle
));
1392 const char* version
= (const char*)sqlite3_column_text(stmt
, 2);
1394 ERROR(db
->pakfire
, "Could not read version: %s\n", sqlite3_errmsg(db
->handle
));
1399 const char* release
= (const char*)sqlite3_column_text(stmt
, 3);
1401 ERROR(db
->pakfire
, "Could not read release: %s\n", sqlite3_errmsg(db
->handle
));
1406 const char* arch
= (const char*)sqlite3_column_text(stmt
, 4);
1408 ERROR(db
->pakfire
, "Could not read arch: %s\n", sqlite3_errmsg(db
->handle
));
1412 // Join EVR together
1413 evr
= pakfire_package_join_evr(epoch
, version
, release
);
1415 ERROR(db
->pakfire
, "Could not join evr\n");
1420 pkg
= pakfire_package_create(db
->pakfire
, repo
, name
, evr
, arch
);
1422 ERROR(db
->pakfire
, "Could not create package\n");
1427 const char* groups
= (const char*)sqlite3_column_text(stmt
, 5);
1429 pakfire_package_set_groups(pkg
, groups
);
1433 const char* filename
= (const char*)sqlite3_column_text(stmt
, 6);
1435 pakfire_package_set_filename(pkg
, filename
);
1439 size_t size
= sqlite3_column_int64(stmt
, 7);
1441 pakfire_package_set_downloadsize(pkg
, size
);
1445 size
= sqlite3_column_int64(stmt
, 8);
1447 pakfire_package_set_installsize(pkg
, size
);
1451 const char* hash1
= (const char*)sqlite3_column_text(stmt
, 9);
1453 pakfire_package_set_checksum(pkg
, hash1
);
1457 const char* license
= (const char*)sqlite3_column_text(stmt
, 10);
1459 pakfire_package_set_license(pkg
, license
);
1463 const char* summary
= (const char*)sqlite3_column_text(stmt
, 11);
1465 pakfire_package_set_summary(pkg
, summary
);
1469 const char* description
= (const char*)sqlite3_column_text(stmt
, 12);
1471 pakfire_package_set_description(pkg
, description
);
1475 const char* uuid
= (const char*)sqlite3_column_text(stmt
, 13);
1477 pakfire_package_set_uuid(pkg
, uuid
);
1481 const char* vendor
= (const char*)sqlite3_column_text(stmt
, 14);
1483 pakfire_package_set_vendor(pkg
, vendor
);
1487 const char* build_host
= (const char*)sqlite3_column_text(stmt
, 15);
1489 pakfire_package_set_build_host(pkg
, build_host
);
1493 time_t build_time
= sqlite3_column_int64(stmt
, 16);
1495 pakfire_package_set_build_time(pkg
, build_time
);
1499 time_t install_time
= sqlite3_column_int64(stmt
, 17);
1501 pakfire_package_set_install_time(pkg
, install_time
);
1505 const char* files
= (const char*)sqlite3_column_text(stmt
, 18);
1507 r
= pakfire_package_set_filelist_from_string(pkg
, files
);
1514 const struct dependency
{
1516 void (*func
)(PakfirePackage pkg
, PakfireRelationList list
);
1517 } dependencies
[] = {
1518 { 19, pakfire_package_set_provides
},
1519 { 20, pakfire_package_set_prerequires
},
1520 { 21, pakfire_package_set_requires
},
1521 { 22, pakfire_package_set_conflicts
},
1522 { 23, pakfire_package_set_obsoletes
},
1523 { 24, pakfire_package_set_recommends
},
1524 { 25, pakfire_package_set_suggests
},
1525 { 26, pakfire_package_set_supplements
},
1526 { 27, pakfire_package_set_enhances
},
1530 for (const struct dependency
* deps
= dependencies
; deps
->field
; deps
++) {
1531 const char* relations
= (const char*)sqlite3_column_text(stmt
, deps
->field
);
1533 PakfireRelationList list
;
1535 r
= pakfire_relationlist_create_from_string(&list
, db
->pakfire
, relations
);
1539 deps
->func(pkg
, list
);
1540 pakfire_relationlist_unref(list
);
1552 pakfire_package_unref(pkg
);
1557 int pakfire_db_load(struct pakfire_db
* db
, PakfireRepo repo
) {
1558 sqlite3_stmt
* stmt
= NULL
;
1561 DEBUG(db
->pakfire
, "Loading package database...\n");
1563 // Save starting time
1564 clock_t t_start
= clock();
1569 "name, epoch, version, release, arch, groups, filename, size, inst_size, "
1570 "hash1, license, summary, description, uuid, vendor, build_host, build_time, "
1571 "strftime('%s', installed) AS installed, "
1573 "SELECT group_concat(name, '\n') FROM files WHERE files.pkg = packages.id"
1576 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1577 "WHERE d.pkg = packages.id AND d.type = 'provides'"
1580 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1581 "WHERE d.pkg = packages.id AND d.type = 'prerequires'"
1582 ") AS prerequires, "
1584 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1585 "WHERE d.pkg = packages.id AND d.type = 'requires'"
1588 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1589 "WHERE d.pkg = packages.id AND d.type = 'conflicts'"
1592 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1593 "WHERE d.pkg = packages.id AND d.type = 'obsoletes'"
1596 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1597 "WHERE d.pkg = packages.id AND d.type = 'recommends'"
1600 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1601 "WHERE d.pkg = packages.id AND d.type = 'suggests'"
1604 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1605 "WHERE d.pkg = packages.id AND d.type = 'supplements'"
1606 ") AS supplements, "
1608 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1609 "WHERE d.pkg = packages.id AND d.type = 'enhances'"
1615 // Prepare the statement
1616 r
= sqlite3_prepare_v2(db
->handle
, sql
, strlen(sql
), &stmt
, NULL
);
1618 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s %s\n",
1619 sql
, sqlite3_errmsg(db
->handle
));
1625 r
= sqlite3_step(stmt
);
1628 // Retry if the database was busy
1634 r
= pakfire_db_load_package(db
, repo
, stmt
);
1639 // All rows have been processed
1643 // Go to error in any other cases
1650 // Save time when we finished
1653 DEBUG(db
->pakfire
, "Loading package database completed in %.4fms\n",
1654 (double)(t_end
- t_start
) * 1000 / CLOCKS_PER_SEC
);
1656 // Internalize repository
1657 pakfire_repo_internalize(repo
);
1664 ERROR(db
->pakfire
, "Failed reading package database: %d\n", r
);
1667 sqlite3_finalize(stmt
);