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 #############################################################################*/
22 #include <linux/limits.h>
28 #include <pakfire/archive.h>
29 #include <pakfire/db.h>
30 #include <pakfire/file.h>
31 #include <pakfire/logging.h>
32 #include <pakfire/package.h>
33 #include <pakfire/pakfire.h>
34 #include <pakfire/private.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
55 static void logging_callback(void* data
, int r
, const char* msg
) {
56 Pakfire pakfire
= (Pakfire
)data
;
58 ERROR(pakfire
, "Database Error: %s: %s\n",
59 sqlite3_errstr(r
), msg
);
62 static int pakfire_db_execute(struct pakfire_db
* db
, const char* stmt
) {
65 DEBUG(db
->pakfire
, "Executing database query: %s\n", stmt
);
68 r
= sqlite3_exec(db
->handle
, stmt
, NULL
, NULL
, NULL
);
69 } while (r
== SQLITE_BUSY
);
73 ERROR(db
->pakfire
, "Database query failed: %s\n", sqlite3_errmsg(db
->handle
));
79 static int pakfire_db_begin_transaction(struct pakfire_db
* db
) {
80 return pakfire_db_execute(db
, "BEGIN TRANSACTION");
83 static int pakfire_db_commit(struct pakfire_db
* db
) {
84 return pakfire_db_execute(db
, "COMMIT");
87 static int pakfire_db_rollback(struct pakfire_db
* db
) {
88 return pakfire_db_execute(db
, "ROLLBACK");
92 This function performs any fast optimization and tries to truncate the WAL log file
93 to keep the database as compact as possible on disk.
95 static void pakfire_db_optimize(struct pakfire_db
* db
) {
96 pakfire_db_execute(db
, "PRAGMA optimize");
97 pakfire_db_execute(db
, "PRAGMA wal_checkpoint = TRUNCATE");
100 static void pakfire_db_free(struct pakfire_db
* db
) {
102 // Optimize the database before it is being closed
103 pakfire_db_optimize(db
);
105 // Close database handle
106 int r
= sqlite3_close(db
->handle
);
107 if (r
!= SQLITE_OK
) {
108 ERROR(db
->pakfire
, "Could not close database handle: %s\n",
109 sqlite3_errmsg(db
->handle
));
113 pakfire_unref(db
->pakfire
);
118 static sqlite3_value
* pakfire_db_get(struct pakfire_db
* db
, const char* key
) {
119 sqlite3_stmt
* stmt
= NULL
;
120 sqlite3_value
* val
= NULL
;
123 const char* sql
= "SELECT val FROM settings WHERE key = ?";
125 // Prepare the statement
126 r
= sqlite3_prepare_v2(db
->handle
, sql
, strlen(sql
), &stmt
, NULL
);
127 if (r
!= SQLITE_OK
) {
128 //ERROR(db->pakfire, "Could not prepare SQL statement: %s: %s\n",
129 // sql, sqlite3_errmsg(db->handle));
134 r
= sqlite3_bind_text(stmt
, 1, key
, strlen(key
), NULL
);
135 if (r
!= SQLITE_OK
) {
136 ERROR(db
->pakfire
, "Could not bind key: %s\n", sqlite3_errmsg(db
->handle
));
140 // Execute the statement
142 r
= sqlite3_step(stmt
);
143 } while (r
== SQLITE_BUSY
);
145 // We should have read a row
150 val
= sqlite3_column_value(stmt
, 0);
152 ERROR(db
->pakfire
, "Could not read value\n");
156 // Copy value onto the heap
157 val
= sqlite3_value_dup(val
);
161 sqlite3_finalize(stmt
);
166 static int pakfire_db_set_int(struct pakfire_db
* db
, const char* key
, int val
) {
167 sqlite3_stmt
* stmt
= NULL
;
170 const char* sql
= "INSERT INTO settings(key, val) VALUES(?, ?) \
171 ON CONFLICT (key) DO UPDATE SET val = excluded.val";
174 r
= sqlite3_prepare_v2(db
->handle
, sql
, strlen(sql
), &stmt
, NULL
);
175 if (r
!= SQLITE_OK
) {
176 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s: %s\n",
177 sql
, sqlite3_errmsg(db
->handle
));
182 r
= sqlite3_bind_text(stmt
, 1, key
, strlen(key
), NULL
);
183 if (r
!= SQLITE_OK
) {
184 ERROR(db
->pakfire
, "Could not bind key: %s\n", sqlite3_errmsg(db
->handle
));
189 r
= sqlite3_bind_int64(stmt
, 2, val
);
190 if (r
!= SQLITE_OK
) {
191 ERROR(db
->pakfire
, "Could not bind val: %s\n", sqlite3_errmsg(db
->handle
));
195 // Execute the statement
197 r
= sqlite3_step(stmt
);
198 } while (r
== SQLITE_BUSY
);
201 r
= (r
== SQLITE_OK
);
205 sqlite3_finalize(stmt
);
210 static int pakfire_db_get_schema(struct pakfire_db
* db
) {
211 sqlite3_value
* value
= pakfire_db_get(db
, "schema");
215 int schema
= sqlite3_value_int64(value
);
216 sqlite3_value_free(value
);
218 DEBUG(db
->pakfire
, "Database has schema version %d\n", schema
);
223 static int pakfire_db_create_schema(struct pakfire_db
* db
) {
226 // Create settings table
227 r
= pakfire_db_execute(db
, "CREATE TABLE IF NOT EXISTS settings(key TEXT, val TEXT)");
231 // settings: Add a unique index on key
232 r
= pakfire_db_execute(db
, "CREATE UNIQUE INDEX IF NOT EXISTS settings_key ON settings(key)");
236 // Create packages table
237 r
= pakfire_db_execute(db
,
238 "CREATE TABLE IF NOT EXISTS packages("
239 "id INTEGER PRIMARY KEY, "
246 "inst_size INTEGER, "
254 "build_time INTEGER, "
255 "installed INTEGER, "
262 // packages: Create index to find package by name
263 r
= pakfire_db_execute(db
, "CREATE INDEX IF NOT EXISTS packages_name ON packages(name)");
267 // packages: Create unique index over UUID
268 r
= pakfire_db_execute(db
, "CREATE UNIQUE INDEX IF NOT EXISTS packages_uuid ON packages(uuid)");
272 // Create dependencies table
273 r
= pakfire_db_execute(db
,
274 "CREATE TABLE IF NOT EXISTS dependencies("
278 "FOREIGN KEY (pkg) REFERENCES packages(id) ON DELETE CASCADE"
283 // dependencies: Add index over packages
284 r
= pakfire_db_execute(db
, "CREATE INDEX IF NOT EXISTS dependencies_pkg_index ON dependencies(pkg)");
288 // Create files table
289 r
= pakfire_db_execute(db
,
290 "CREATE TABLE IF NOT EXISTS files("
291 "id INTEGER PRIMARY KEY, "
304 "capabilities TEXT, "
305 "FOREIGN KEY (pkg) REFERENCES packages(id) ON DELETE CASCADE"
310 // files: Add index over packages
311 r
= pakfire_db_execute(db
, "CREATE INDEX IF NOT EXISTS files_pkg_index ON files(pkg)");
315 // Create scriptlets table
316 r
= pakfire_db_execute(db
,
317 "CREATE TABLE IF NOT EXISTS scriptlets("
318 "id INTEGER PRIMARY KEY, "
322 "FOREIGN KEY (pkg) REFERENCES packages(id) ON DELETE CASCADE"
327 // scriptlets: Add index over packages
328 r
= pakfire_db_execute(db
, "CREATE INDEX IF NOT EXISTS scriptlets_pkg_index ON scriptlets(pkg)");
335 static int pakfire_db_migrate_to_schema_8(struct pakfire_db
* db
) {
336 // packages: Drop build_id column
339 // TODO sqlite doesn't support adding foreign keys to existing tables and so we would
340 // need to recreate the whole table and rename it afterwards. Annoying.
345 static int pakfire_db_migrate_schema(struct pakfire_db
* db
) {
348 while (db
->schema
< CURRENT_SCHEMA
) {
349 // Begin a new transaction
350 r
= pakfire_db_begin_transaction(db
);
354 switch (db
->schema
) {
357 r
= pakfire_db_create_schema(db
);
361 db
->schema
= CURRENT_SCHEMA
;
365 r
= pakfire_db_migrate_to_schema_8(db
);
373 ERROR(db
->pakfire
, "Cannot migrate database from schema %d\n", db
->schema
);
377 // Update the schema version
378 r
= pakfire_db_set_int(db
, "schema", CURRENT_SCHEMA
);
383 r
= pakfire_db_commit(db
);
391 pakfire_db_rollback(db
);
396 static int pakfire_db_setup(struct pakfire_db
* db
) {
400 sqlite3_config(SQLITE_CONFIG_LOG
, logging_callback
, db
->pakfire
);
402 // Enable foreign keys
403 pakfire_db_execute(db
, "PRAGMA foreign_keys = ON");
405 // Make LIKE case-sensitive
406 pakfire_db_execute(db
, "PRAGMA case_sensitive_like = ON");
408 // Fetch the current schema
409 db
->schema
= pakfire_db_get_schema(db
);
411 // Check if the schema is recent enough
412 if (db
->schema
> 0 && db
->schema
< SCHEMA_MIN_SUP
) {
413 ERROR(db
->pakfire
, "Database schema %d is not supported by this version of Pakfire\n",
418 // Done when not in read-write mode
419 if (db
->mode
!= PAKFIRE_DB_READWRITE
)
422 // Disable secure delete
423 pakfire_db_execute(db
, "PRAGMA secure_delete = OFF");
425 // Set database journal to WAL
426 r
= pakfire_db_execute(db
, "PRAGMA journal_mode = WAL");
427 if (r
!= SQLITE_OK
) {
428 ERROR(db
->pakfire
, "Could not set journal mode to WAL: %s\n",
429 sqlite3_errmsg(db
->handle
));
433 // Disable autocheckpoint
434 r
= sqlite3_wal_autocheckpoint(db
->handle
, 0);
435 if (r
!= SQLITE_OK
) {
436 ERROR(db
->pakfire
, "Could not disable autocheckpoint: %s\n",
437 sqlite3_errmsg(db
->handle
));
441 // Create or migrate schema
442 r
= pakfire_db_migrate_schema(db
);
449 PAKFIRE_EXPORT
int pakfire_db_open(struct pakfire_db
** db
, Pakfire pakfire
, int flags
) {
452 struct pakfire_db
* o
= calloc(1, sizeof(*o
));
456 o
->pakfire
= pakfire_ref(pakfire
);
459 int sqlite3_flags
= 0;
461 // Store mode & forward it to sqlite3
462 if (flags
& PAKFIRE_DB_READWRITE
) {
463 o
->mode
= PAKFIRE_DB_READWRITE
;
464 sqlite3_flags
|= SQLITE_OPEN_READWRITE
| SQLITE_OPEN_CREATE
;
466 o
->mode
= PAKFIRE_DB_READONLY
;
467 sqlite3_flags
|= SQLITE_OPEN_READONLY
;
471 r
= pakfire_make_path(o
->pakfire
, o
->path
, DATABASE_PATH
);
475 // Try to open the sqlite3 database file
476 r
= sqlite3_open_v2(o
->path
, &o
->handle
, sqlite3_flags
, NULL
);
477 if (r
!= SQLITE_OK
) {
478 ERROR(pakfire
, "Could not open database %s: %s\n",
479 o
->path
, sqlite3_errmsg(o
->handle
));
485 // Setup the database
486 r
= pakfire_db_setup(o
);
500 PAKFIRE_EXPORT
struct pakfire_db
* pakfire_db_ref(struct pakfire_db
* db
) {
506 PAKFIRE_EXPORT
struct pakfire_db
* pakfire_db_unref(struct pakfire_db
* db
) {
515 static unsigned long pakfire_db_integrity_check(struct pakfire_db
* db
) {
516 sqlite3_stmt
* stmt
= NULL
;
519 r
= sqlite3_prepare_v2(db
->handle
, "PRAGMA integrity_check", -1, &stmt
, NULL
);
521 ERROR(db
->pakfire
, "Could not prepare integrity check: %s\n",
522 sqlite3_errmsg(db
->handle
));
527 unsigned long errors
= 0;
531 r
= sqlite3_step(stmt
);
532 } while (r
== SQLITE_BUSY
);
534 if (r
== SQLITE_ROW
) {
535 const char* error
= (const char*)sqlite3_column_text(stmt
, 0);
537 // If the message is "ok", the database has passed the check
538 if (strcmp(error
, "ok") == 0)
541 // Increment error counter
545 ERROR(db
->pakfire
, "%s\n", error
);
547 // Break on anything else
552 sqlite3_finalize(stmt
);
555 ERROR(db
->pakfire
, "Database integrity check failed\n");
557 INFO(db
->pakfire
, "Database integrity check passed\n");
562 static unsigned long pakfire_db_foreign_key_check(struct pakfire_db
* db
) {
563 sqlite3_stmt
* stmt
= NULL
;
566 r
= sqlite3_prepare_v2(db
->handle
, "PRAGMA foreign_key_check", -1, &stmt
, NULL
);
568 ERROR(db
->pakfire
, "Could not prepare foreign key check: %s\n",
569 sqlite3_errmsg(db
->handle
));
574 unsigned long errors
= 0;
578 r
= sqlite3_step(stmt
);
579 } while (r
== SQLITE_BUSY
);
581 if (r
== SQLITE_ROW
) {
582 const unsigned char* table
= sqlite3_column_text(stmt
, 0);
583 unsigned long rowid
= sqlite3_column_int64(stmt
, 1);
584 const unsigned char* foreign_table
= sqlite3_column_text(stmt
, 2);
585 unsigned long foreign_rowid
= sqlite3_column_int64(stmt
, 3);
587 // Increment error counter
591 ERROR(db
->pakfire
, "Foreign key violation found in %s, row %lu: "
592 "%lu does not exist in table %s\n", table
, rowid
, foreign_rowid
, foreign_table
);
594 // Break on anything else
599 sqlite3_finalize(stmt
);
602 ERROR(db
->pakfire
, "Foreign key check failed\n");
604 INFO(db
->pakfire
, "Foreign key check passed\n");
610 This function performs an integrity check of the database
612 PAKFIRE_EXPORT
int pakfire_db_check(struct pakfire_db
* db
) {
615 // Perform integrity check
616 r
= pakfire_db_integrity_check(db
);
620 // Perform foreign key check
621 r
= pakfire_db_foreign_key_check(db
);
628 // Returns the number of packages installed
629 PAKFIRE_EXPORT ssize_t
pakfire_db_packages(struct pakfire_db
* db
) {
630 sqlite3_stmt
* stmt
= NULL
;
631 ssize_t packages
= -1;
633 int r
= sqlite3_prepare_v2(db
->handle
, "SELECT COUNT(*) FROM packages", -1, &stmt
, NULL
);
635 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s\n",
636 sqlite3_errmsg(db
->handle
));
642 r
= sqlite3_step(stmt
);
643 } while (r
== SQLITE_BUSY
);
645 if (r
== SQLITE_ROW
) {
646 packages
= sqlite3_column_int64(stmt
, 0);
649 sqlite3_finalize(stmt
);
654 static int pakfire_db_add_dependencies(struct pakfire_db
* db
, unsigned long id
, PakfirePackage pkg
) {
655 sqlite3_stmt
* stmt
= NULL
;
658 const char* sql
= "INSERT INTO dependencies(pkg, type, dependency) VALUES(?, ?, ?)";
660 // Prepare the statement
661 r
= sqlite3_prepare_v2(db
->handle
, sql
, -1, &stmt
, NULL
);
663 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s: %s\n",
664 sql
, sqlite3_errmsg(db
->handle
));
668 const struct __relation
{
670 char** (*func
)(PakfirePackage
);
672 { "provides", pakfire_package_get_provides
},
673 { "prerequires", pakfire_package_get_prerequires
},
674 { "requires", pakfire_package_get_requires
},
675 { "conflicts", pakfire_package_get_conflicts
},
676 { "obsoletes", pakfire_package_get_obsoletes
},
677 { "recommends", pakfire_package_get_recommends
},
678 { "suggests", pakfire_package_get_suggests
},
679 { "supplements", pakfire_package_get_supplements
},
680 { "enhances", pakfire_package_get_enhances
},
684 for (const struct __relation
* relation
= relations
; relation
->type
; relation
++) {
685 char** list
= relation
->func(pkg
);
689 for (char** dep
= list
; *dep
; dep
++) {
691 r
= sqlite3_bind_int64(stmt
, 1, id
);
693 ERROR(db
->pakfire
, "Could not bind id: %s\n",
694 sqlite3_errmsg(db
->handle
));
699 r
= sqlite3_bind_text(stmt
, 2, relation
->type
, -1, NULL
);
701 ERROR(db
->pakfire
, "Could not bind type: %s\n",
702 sqlite3_errmsg(db
->handle
));
707 r
= sqlite3_bind_text(stmt
, 3, *dep
, -1, NULL
);
709 ERROR(db
->pakfire
, "Could not bind dependency: %s\n",
710 sqlite3_errmsg(db
->handle
));
716 r
= sqlite3_step(stmt
);
717 } while (r
== SQLITE_BUSY
);
721 // Reset bound values
733 sqlite3_finalize(stmt
);
738 static int pakfire_db_add_files(struct pakfire_db
* db
, unsigned long id
, PakfireArchive archive
) {
739 sqlite3_stmt
* stmt
= NULL
;
742 // Get the filelist from the archive
743 PakfireFilelist filelist
= pakfire_archive_get_filelist(archive
);
745 ERROR(db
->pakfire
, "Could not fetch filelist from archive\n");
749 // Nothing to do if the list is empty
750 if (pakfire_filelist_is_empty(filelist
)) {
755 const char* sql
= "INSERT INTO files(pkg, path, size, type, config, datafile, mode, "
756 "user, 'group', hash1, ctime, mtime, capabilities) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
758 // Prepare the statement
759 r
= sqlite3_prepare_v2(db
->handle
, sql
, -1, &stmt
, NULL
);
761 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s: %s\n",
762 sql
, sqlite3_errmsg(db
->handle
));
766 for (unsigned int i
= 0; i
< pakfire_filelist_size(filelist
); i
++) {
767 PakfireFile file
= pakfire_filelist_get(filelist
, i
);
770 r
= sqlite3_bind_int64(stmt
, 1, id
);
772 ERROR(db
->pakfire
, "Could not bind id: %s\n", sqlite3_errmsg(db
->handle
));
773 pakfire_file_unref(file
);
778 const char* path
= pakfire_file_get_path(file
);
780 r
= sqlite3_bind_text(stmt
, 2, path
, -1, NULL
);
782 ERROR(db
->pakfire
, "Could not bind path: %s\n", sqlite3_errmsg(db
->handle
));
783 pakfire_file_unref(file
);
788 size_t size
= pakfire_file_get_size(file
);
790 r
= sqlite3_bind_int64(stmt
, 3, size
);
792 ERROR(db
->pakfire
, "Could not bind size: %s\n", sqlite3_errmsg(db
->handle
));
793 pakfire_file_unref(file
);
797 // Bind type - XXX this is char which isn't very helpful
798 //char type = pakfire_file_get_type(file);
800 r
= sqlite3_bind_null(stmt
, 4);
802 ERROR(db
->pakfire
, "Could not bind type: %s\n", sqlite3_errmsg(db
->handle
));
803 pakfire_file_unref(file
);
807 // Bind config - XXX TODO
808 r
= sqlite3_bind_null(stmt
, 5);
810 ERROR(db
->pakfire
, "Could not bind config: %s\n", sqlite3_errmsg(db
->handle
));
811 pakfire_file_unref(file
);
815 // Bind datafile - XXX TODO
816 r
= sqlite3_bind_null(stmt
, 6);
818 ERROR(db
->pakfire
, "Could not bind datafile: %s\n", sqlite3_errmsg(db
->handle
));
819 pakfire_file_unref(file
);
824 mode_t mode
= pakfire_file_get_mode(file
);
826 r
= sqlite3_bind_int64(stmt
, 7, mode
);
828 ERROR(db
->pakfire
, "Could not bind mode: %s\n", sqlite3_errmsg(db
->handle
));
829 pakfire_file_unref(file
);
834 const char* user
= pakfire_file_get_user(file
);
836 r
= sqlite3_bind_text(stmt
, 8, user
, -1, NULL
);
838 ERROR(db
->pakfire
, "Could not bind user: %s\n", sqlite3_errmsg(db
->handle
));
839 pakfire_file_unref(file
);
844 const char* group
= pakfire_file_get_group(file
);
846 r
= sqlite3_bind_text(stmt
, 9, group
, -1, NULL
);
848 ERROR(db
->pakfire
, "Could not bind group: %s\n", sqlite3_errmsg(db
->handle
));
849 pakfire_file_unref(file
);
854 const char* chksum
= pakfire_file_get_chksum(file
);
856 r
= sqlite3_bind_text(stmt
, 10, chksum
, -1, NULL
);
858 ERROR(db
->pakfire
, "Could not bind hash1: %s\n", sqlite3_errmsg(db
->handle
));
859 pakfire_file_unref(file
);
864 time_t ctime
= pakfire_file_get_ctime(file
);
866 r
= sqlite3_bind_int64(stmt
, 11, ctime
);
868 ERROR(db
->pakfire
, "Could not bind ctime: %s\n", sqlite3_errmsg(db
->handle
));
869 pakfire_file_unref(file
);
874 time_t mtime
= pakfire_file_get_mtime(file
);
876 r
= sqlite3_bind_int64(stmt
, 12, mtime
);
878 ERROR(db
->pakfire
, "Could not bind mtime: %s\n", sqlite3_errmsg(db
->handle
));
879 pakfire_file_unref(file
);
883 // Bind capabilities - XXX TODO
884 r
= sqlite3_bind_null(stmt
, 13);
886 ERROR(db
->pakfire
, "Could not bind capabilities: %s\n", sqlite3_errmsg(db
->handle
));
887 pakfire_file_unref(file
);
893 r
= sqlite3_step(stmt
);
894 } while (r
== SQLITE_BUSY
);
896 // Move on to next file
897 pakfire_file_unref(file
);
900 if (r
!= SQLITE_DONE
) {
901 ERROR(db
->pakfire
, "Could not add file to database: %s\n",
902 sqlite3_errmsg(db
->handle
));
906 // Reset bound values
915 sqlite3_finalize(stmt
);
917 pakfire_filelist_unref(filelist
);
922 static int pakfire_db_add_scriptlets(struct pakfire_db
* db
, unsigned long id
, PakfireArchive archive
) {
923 sqlite3_stmt
* stmt
= NULL
;
927 const char* sql
= "INSERT INTO scriptlets(pkg, type, scriptlet) VALUES(?, ?, ?)";
929 // Prepare the statement
930 r
= sqlite3_prepare_v2(db
->handle
, sql
, -1, &stmt
, NULL
);
932 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s: %s\n",
933 sql
, sqlite3_errmsg(db
->handle
));
937 for (const char** type
= pakfire_scriptlet_types
; *type
; type
++) {
938 // Fetch the scriptlet
939 struct pakfire_scriptlet
* scriptlet
= pakfire_archive_get_scriptlet(archive
, *type
);
944 r
= sqlite3_bind_int64(stmt
, 1, id
);
946 ERROR(db
->pakfire
, "Could not bind id: %s\n", sqlite3_errmsg(db
->handle
));
947 pakfire_scriptlet_unref(scriptlet
);
952 r
= sqlite3_bind_text(stmt
, 2, *type
, -1, NULL
);
954 ERROR(db
->pakfire
, "Could not bind type: %s\n", sqlite3_errmsg(db
->handle
));
955 pakfire_scriptlet_unref(scriptlet
);
959 const char* data
= pakfire_scriptlet_get_data(scriptlet
, &size
);
962 r
= sqlite3_bind_text(stmt
, 3, data
, size
, NULL
);
964 ERROR(db
->pakfire
, "Could not bind scriptlet: %s\n", sqlite3_errmsg(db
->handle
));
965 pakfire_scriptlet_unref(scriptlet
);
971 r
= sqlite3_step(stmt
);
972 } while (r
== SQLITE_BUSY
);
975 if (r
!= SQLITE_DONE
) {
976 ERROR(db
->pakfire
, "Could not add scriptlet to database: %s\n",
977 sqlite3_errmsg(db
->handle
));
978 pakfire_scriptlet_unref(scriptlet
);
982 pakfire_scriptlet_unref(scriptlet
);
984 // Reset bound values
993 sqlite3_finalize(stmt
);
998 PAKFIRE_EXPORT
int pakfire_db_add_package(struct pakfire_db
* db
,
999 PakfirePackage pkg
, PakfireArchive archive
) {
1000 sqlite3_stmt
* stmt
= NULL
;
1003 // Begin a new transaction
1004 r
= pakfire_db_begin_transaction(db
);
1008 const char* sql
= "INSERT INTO packages(name, evr, arch, groups, filename, size, "
1009 "inst_size, hash1, license, summary, description, uuid, vendor, build_host, "
1010 "build_time, installed, repository, reason) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, "
1011 "?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, ?, ?)";
1013 // Prepare the statement
1014 r
= sqlite3_prepare_v2(db
->handle
, sql
, strlen(sql
), &stmt
, NULL
);
1015 if (r
!= SQLITE_OK
) {
1016 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s: %s\n",
1017 sql
, sqlite3_errmsg(db
->handle
));
1022 const char* name
= pakfire_package_get_name(pkg
);
1024 r
= sqlite3_bind_text(stmt
, 1, name
, -1, NULL
);
1026 ERROR(db
->pakfire
, "Could not bind name: %s\n", sqlite3_errmsg(db
->handle
));
1031 const char* evr
= pakfire_package_get_evr(pkg
);
1033 r
= sqlite3_bind_text(stmt
, 2, evr
, -1, NULL
);
1035 ERROR(db
->pakfire
, "Could not bind evr: %s\n", sqlite3_errmsg(db
->handle
));
1040 const char* arch
= pakfire_package_get_arch(pkg
);
1042 r
= sqlite3_bind_text(stmt
, 3, arch
, -1, NULL
);
1044 ERROR(db
->pakfire
, "Could not bind arch: %s\n", sqlite3_errmsg(db
->handle
));
1049 char* groups
= pakfire_package_get_groups(pkg
);
1051 r
= sqlite3_bind_text(stmt
, 4, groups
, -1, NULL
);
1053 ERROR(db
->pakfire
, "Could not bind groups: %s\n", sqlite3_errmsg(db
->handle
));
1062 r
= sqlite3_bind_null(stmt
, 4);
1068 const char* filename
= pakfire_package_get_filename(pkg
);
1070 r
= sqlite3_bind_text(stmt
, 5, filename
, -1, NULL
);
1072 ERROR(db
->pakfire
, "Could not bind filename: %s\n", sqlite3_errmsg(db
->handle
));
1077 unsigned long long size
= pakfire_package_get_downloadsize(pkg
);
1079 r
= sqlite3_bind_int64(stmt
, 6, size
);
1081 ERROR(db
->pakfire
, "Could not bind size: %s\n", sqlite3_errmsg(db
->handle
));
1085 // Bind installed size
1086 unsigned long long inst_size
= pakfire_package_get_installsize(pkg
);
1088 r
= sqlite3_bind_int64(stmt
, 7, inst_size
);
1090 ERROR(db
->pakfire
, "Could not bind inst_size: %s\n", sqlite3_errmsg(db
->handle
));
1095 const char* hash1
= pakfire_package_get_checksum(pkg
);
1097 r
= sqlite3_bind_text(stmt
, 8, hash1
, -1, NULL
);
1099 ERROR(db
->pakfire
, "Could not bind hash1: %s\n", sqlite3_errmsg(db
->handle
));
1104 const char* license
= pakfire_package_get_license(pkg
);
1106 r
= sqlite3_bind_text(stmt
, 9, license
, -1, NULL
);
1108 ERROR(db
->pakfire
, "Could not bind license: %s\n", sqlite3_errmsg(db
->handle
));
1113 const char* summary
= pakfire_package_get_summary(pkg
);
1115 r
= sqlite3_bind_text(stmt
, 10, summary
, -1, NULL
);
1117 ERROR(db
->pakfire
, "Could not bind summary: %s\n", sqlite3_errmsg(db
->handle
));
1122 const char* description
= pakfire_package_get_description(pkg
);
1124 r
= sqlite3_bind_text(stmt
, 11, description
, -1, NULL
);
1126 ERROR(db
->pakfire
, "Could not bind description: %s\n", sqlite3_errmsg(db
->handle
));
1131 const char* uuid
= pakfire_package_get_uuid(pkg
);
1133 r
= sqlite3_bind_text(stmt
, 12, uuid
, -1, NULL
);
1135 ERROR(db
->pakfire
, "Could not bind uuid: %s\n", sqlite3_errmsg(db
->handle
));
1140 const char* vendor
= pakfire_package_get_vendor(pkg
);
1142 r
= sqlite3_bind_text(stmt
, 13, vendor
, -1, NULL
);
1144 ERROR(db
->pakfire
, "Could not bind vendor: %s\n", sqlite3_errmsg(db
->handle
));
1149 const char* build_host
= pakfire_package_get_build_host(pkg
);
1151 r
= sqlite3_bind_text(stmt
, 14, build_host
, -1, NULL
);
1153 ERROR(db
->pakfire
, "Could not bind build_host: %s\n", sqlite3_errmsg(db
->handle
));
1158 time_t build_time
= pakfire_package_get_build_time(pkg
);
1160 r
= sqlite3_bind_int64(stmt
, 15, build_time
);
1162 ERROR(db
->pakfire
, "Could not bind build_time: %s\n", sqlite3_errmsg(db
->handle
));
1166 // Bind repository name
1167 PakfireRepo repo
= pakfire_package_get_repo(pkg
);
1169 const char* repo_name
= pakfire_repo_get_name(repo
);
1170 pakfire_repo_unref(repo
);
1172 r
= sqlite3_bind_text(stmt
, 16, repo_name
, -1, NULL
);
1178 r
= sqlite3_bind_null(stmt
, 16);
1183 // XXX TODO Bind reason
1184 r
= sqlite3_bind_null(stmt
, 17);
1190 r
= sqlite3_step(stmt
);
1191 } while (r
== SQLITE_BUSY
);
1193 if (r
!= SQLITE_DONE
) {
1194 ERROR(db
->pakfire
, "Could not add package to database: %s\n",
1195 sqlite3_errmsg(db
->handle
));
1200 unsigned long packages_id
= sqlite3_last_insert_rowid(db
->handle
);
1203 r
= sqlite3_finalize(stmt
);
1208 r
= pakfire_db_add_dependencies(db
, packages_id
, pkg
);
1213 r
= pakfire_db_add_files(db
, packages_id
, archive
);
1218 r
= pakfire_db_add_scriptlets(db
, packages_id
, archive
);
1222 // All done, commit!
1223 r
= pakfire_db_commit(db
);
1231 sqlite3_finalize(stmt
);
1233 pakfire_db_rollback(db
);
1238 PAKFIRE_EXPORT
int pakfire_db_remove_package(struct pakfire_db
* db
, PakfirePackage pkg
) {
1239 sqlite3_stmt
* stmt
= NULL
;
1242 // Fetch the package's UUID
1243 const char* uuid
= pakfire_package_get_uuid(pkg
);
1245 ERROR(db
->pakfire
, "Package has no UUID\n");
1249 r
= sqlite3_prepare_v2(db
->handle
,
1250 "DELETE FROM packages WHERE uuid = ?", -1, &stmt
, NULL
);
1252 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s\n",
1253 sqlite3_errmsg(db
->handle
));
1258 r
= sqlite3_bind_text(stmt
, 1, uuid
, -1, NULL
);
1260 ERROR(db
->pakfire
, "Could not bind uuid: %s\n", sqlite3_errmsg(db
->handle
));
1266 r
= sqlite3_step(stmt
);
1267 } while (r
== SQLITE_BUSY
);
1269 // Check if we have been successful
1270 if (r
!= SQLITE_DONE
) {
1271 ERROR(db
->pakfire
, "Could not delete package %s\n", uuid
);
1280 sqlite3_finalize(stmt
);
1285 struct pakfire_scriptlet
* pakfire_db_get_scriptlet(struct pakfire_db
* db
,
1286 PakfirePackage pkg
, const char* type
) {
1287 struct pakfire_scriptlet
* scriptlet
= NULL
;
1288 sqlite3_stmt
* stmt
= NULL
;
1291 // Fetch the package's UUID
1292 const char* uuid
= pakfire_package_get_uuid(pkg
);
1294 ERROR(db
->pakfire
, "Package has no UUID\n");
1298 const char* sql
= "SELECT scriptlet.scriptlet FROM packages \
1299 JOIN scriptlets ON packages.id = scriptlets.pkg \
1300 WHERE packages.uuid = ? AND scriptlets.type = ?";
1302 r
= sqlite3_prepare_v2(db
->handle
, sql
, strlen(sql
), &stmt
, NULL
);
1304 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s %s\n",
1305 sql
, sqlite3_errmsg(db
->handle
));
1310 r
= sqlite3_bind_text(stmt
, 1, uuid
, -1, NULL
);
1312 ERROR(db
->pakfire
, "Could not bind uuid: %s\n", sqlite3_errmsg(db
->handle
));
1316 r
= sqlite3_bind_text(stmt
, 2, type
, -1, NULL
);
1318 ERROR(db
->pakfire
, "Could not bind type: %s\n", sqlite3_errmsg(db
->handle
));
1322 DEBUG(db
->pakfire
, "Searching for scriptlet for package %s of type %s\n", uuid
, type
);
1326 r
= sqlite3_step(stmt
);
1327 } while (r
== SQLITE_BUSY
);
1329 // We have some payload
1330 if (r
== SQLITE_ROW
) {
1331 const void* data
= sqlite3_column_blob(stmt
, 1);
1332 ssize_t size
= sqlite3_column_bytes(stmt
, 1);
1334 // Create a scriptlet object
1335 r
= pakfire_scriptlet_create(&scriptlet
, db
->pakfire
, type
, data
, size
);
1342 sqlite3_finalize(stmt
);
1347 static int pakfire_db_load_package(struct pakfire_db
* db
, PakfireRepo repo
, sqlite3_stmt
* stmt
) {
1348 PakfirePackage pkg
= NULL
;
1352 const char* name
= (const char*)sqlite3_column_text(stmt
, 0);
1354 ERROR(db
->pakfire
, "Could not read name: %s\n", sqlite3_errmsg(db
->handle
));
1359 const char* evr
= (const char*)sqlite3_column_text(stmt
, 1);
1361 ERROR(db
->pakfire
, "Could not read evr: %s\n", sqlite3_errmsg(db
->handle
));
1366 const char* arch
= (const char*)sqlite3_column_text(stmt
, 2);
1368 ERROR(db
->pakfire
, "Could not read arch: %s\n", sqlite3_errmsg(db
->handle
));
1373 pkg
= pakfire_package_create(db
->pakfire
, repo
, name
, evr
, arch
);
1375 ERROR(db
->pakfire
, "Could not create package\n");
1380 const char* groups
= (const char*)sqlite3_column_text(stmt
, 3);
1382 pakfire_package_set_groups(pkg
, groups
);
1386 const char* filename
= (const char*)sqlite3_column_text(stmt
, 4);
1388 pakfire_package_set_filename(pkg
, filename
);
1392 size_t size
= sqlite3_column_int64(stmt
, 5);
1394 pakfire_package_set_downloadsize(pkg
, size
);
1398 size
= sqlite3_column_int64(stmt
, 6);
1400 pakfire_package_set_installsize(pkg
, size
);
1404 const char* hash1
= (const char*)sqlite3_column_text(stmt
, 7);
1406 pakfire_package_set_checksum(pkg
, hash1
);
1410 const char* license
= (const char*)sqlite3_column_text(stmt
, 8);
1412 pakfire_package_set_license(pkg
, license
);
1416 const char* summary
= (const char*)sqlite3_column_text(stmt
, 9);
1418 pakfire_package_set_summary(pkg
, summary
);
1422 const char* description
= (const char*)sqlite3_column_text(stmt
, 10);
1424 pakfire_package_set_description(pkg
, description
);
1428 const char* uuid
= (const char*)sqlite3_column_text(stmt
, 11);
1430 pakfire_package_set_uuid(pkg
, uuid
);
1434 const char* vendor
= (const char*)sqlite3_column_text(stmt
, 12);
1436 pakfire_package_set_vendor(pkg
, vendor
);
1440 const char* build_host
= (const char*)sqlite3_column_text(stmt
, 13);
1442 pakfire_package_set_build_host(pkg
, build_host
);
1446 time_t build_time
= sqlite3_column_int64(stmt
, 14);
1448 pakfire_package_set_build_time(pkg
, build_time
);
1452 time_t install_time
= sqlite3_column_int64(stmt
, 15);
1454 pakfire_package_set_install_time(pkg
, install_time
);
1458 const char* files
= (const char*)sqlite3_column_text(stmt
, 16);
1460 r
= pakfire_package_set_filelist_from_string(pkg
, files
);
1467 const struct dependency
{
1469 void (*func
)(PakfirePackage pkg
, const char* dep
);
1470 } dependencies
[] = {
1471 { 17, pakfire_package_add_provides
},
1472 { 18, pakfire_package_add_prerequires
},
1473 { 10, pakfire_package_add_requires
},
1474 { 20, pakfire_package_add_conflicts
},
1475 { 21, pakfire_package_add_obsoletes
},
1476 { 22, pakfire_package_add_recommends
},
1477 { 23, pakfire_package_add_suggests
},
1478 { 24, pakfire_package_add_supplements
},
1479 { 25, pakfire_package_add_enhances
},
1483 for (const struct dependency
* deps
= dependencies
; deps
->field
; deps
++) {
1484 const char* relations
= (const char*)sqlite3_column_text(stmt
, deps
->field
);
1486 pakfire_parse_deps(db
->pakfire
, pkg
, deps
->func
, relations
);
1495 pakfire_package_unref(pkg
);
1500 int pakfire_db_load(struct pakfire_db
* db
, PakfireRepo repo
) {
1501 sqlite3_stmt
* stmt
= NULL
;
1504 DEBUG(db
->pakfire
, "Loading package database...\n");
1506 // Drop contents of the repository
1507 pakfire_repo_clear(repo
);
1509 // Save starting time
1510 clock_t t_start
= clock();
1515 "name, evr, arch, groups, filename, size, inst_size, hash1, license, summary, "
1516 "description, uuid, vendor, build_host, build_time, "
1517 "strftime('%s', installed) AS installed, "
1519 "SELECT group_concat(path, '\n') FROM files WHERE files.pkg = packages.id"
1522 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1523 "WHERE d.pkg = packages.id AND d.type = 'provides'"
1526 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1527 "WHERE d.pkg = packages.id AND d.type = 'prerequires'"
1528 ") AS prerequires, "
1530 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1531 "WHERE d.pkg = packages.id AND d.type = 'requires'"
1534 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1535 "WHERE d.pkg = packages.id AND d.type = 'conflicts'"
1538 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1539 "WHERE d.pkg = packages.id AND d.type = 'obsoletes'"
1542 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1543 "WHERE d.pkg = packages.id AND d.type = 'recommends'"
1546 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1547 "WHERE d.pkg = packages.id AND d.type = 'suggests'"
1550 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1551 "WHERE d.pkg = packages.id AND d.type = 'supplements'"
1552 ") AS supplements, "
1554 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1555 "WHERE d.pkg = packages.id AND d.type = 'enhances'"
1561 // Prepare the statement
1562 r
= sqlite3_prepare_v2(db
->handle
, sql
, strlen(sql
), &stmt
, NULL
);
1564 ERROR(db
->pakfire
, "Could not prepare SQL statement: %s %s\n",
1565 sql
, sqlite3_errmsg(db
->handle
));
1571 r
= sqlite3_step(stmt
);
1574 // Retry if the database was busy
1580 r
= pakfire_db_load_package(db
, repo
, stmt
);
1585 // All rows have been processed
1589 // Go to error in any other cases
1596 // Save time when we finished
1599 DEBUG(db
->pakfire
, "Loading package database completed in %.4fms\n",
1600 (double)(t_end
- t_start
) * 1000 / CLOCKS_PER_SEC
);
1602 // Internalize repository
1603 pakfire_repo_internalize(repo
);
1610 ERROR(db
->pakfire
, "Failed reading package database: %d\n", r
);
1611 pakfire_repo_clear(repo
);
1615 sqlite3_finalize(stmt
);