]> git.ipfire.org Git - pakfire.git/blob - src/libpakfire/db.c
db: Properly abort when we cannot import a file
[pakfire.git] / src / libpakfire / db.c
1 /*#############################################################################
2 # #
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2021 Pakfire development team #
5 # #
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. #
10 # #
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. #
15 # #
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/>. #
18 # #
19 #############################################################################*/
20
21 #include <errno.h>
22 #include <linux/limits.h>
23 #include <stdlib.h>
24 #include <time.h>
25
26 #include <openssl/sha.h>
27 #include <solv/solver.h>
28 #include <sqlite3.h>
29
30 #include <pakfire/archive.h>
31 #include <pakfire/db.h>
32 #include <pakfire/dependencies.h>
33 #include <pakfire/file.h>
34 #include <pakfire/filelist.h>
35 #include <pakfire/logging.h>
36 #include <pakfire/package.h>
37 #include <pakfire/pakfire.h>
38 #include <pakfire/repo.h>
39 #include <pakfire/string.h>
40 #include <pakfire/util.h>
41
42 #define DATABASE_PATH PAKFIRE_PRIVATE_DIR "/packages.db"
43
44 #define CURRENT_SCHEMA 8
45 #define SCHEMA_MIN_SUP 7
46
47 struct pakfire_db {
48 struct pakfire* pakfire;
49 int nrefs;
50
51 char path[PATH_MAX];
52 int mode;
53
54 sqlite3* handle;
55 int schema;
56 time_t last_modified_at;
57 };
58
59 static void logging_callback(void* data, int r, const char* msg) {
60 struct pakfire* pakfire = (struct pakfire*)data;
61
62 ERROR(pakfire, "Database Error: %s: %s\n",
63 sqlite3_errstr(r), msg);
64 }
65
66 static sqlite3_value* pakfire_db_get(struct pakfire_db* db, const char* key) {
67 sqlite3_stmt* stmt = NULL;
68 sqlite3_value* val = NULL;
69 int r;
70
71 const char* sql = "SELECT val FROM settings WHERE key = ?";
72
73 // Prepare the statement
74 r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
75 if (r != SQLITE_OK) {
76 //ERROR(db->pakfire, "Could not prepare SQL statement: %s: %s\n",
77 // sql, sqlite3_errmsg(db->handle));
78 return NULL;
79 }
80
81 // Bind key
82 r = sqlite3_bind_text(stmt, 1, key, strlen(key), NULL);
83 if (r != SQLITE_OK) {
84 ERROR(db->pakfire, "Could not bind key: %s\n", sqlite3_errmsg(db->handle));
85 goto ERROR;
86 }
87
88 // Execute the statement
89 do {
90 r = sqlite3_step(stmt);
91 } while (r == SQLITE_BUSY);
92
93 // We should have read a row
94 if (r != SQLITE_ROW)
95 goto ERROR;
96
97 // Read value
98 val = sqlite3_column_value(stmt, 0);
99 if (!val) {
100 ERROR(db->pakfire, "Could not read value\n");
101 goto ERROR;
102 }
103
104 // Copy value onto the heap
105 val = sqlite3_value_dup(val);
106
107 ERROR:
108 if (stmt)
109 sqlite3_finalize(stmt);
110
111 return val;
112 }
113
114 static char* pakfire_db_get_string(struct pakfire_db* db, const char* key) {
115 char* s = NULL;
116
117 // Fetch the value from the database
118 sqlite3_value* value = pakfire_db_get(db, key);
119 if (!value)
120 return NULL;
121
122 // Extract the value as string
123 const char* p = (const char*)sqlite3_value_text(value);
124 if (!p)
125 goto ERROR;
126
127 // Copy string to heap
128 s = strdup(p);
129
130 ERROR:
131 if (value)
132 sqlite3_value_free(value);
133
134 return s;
135 }
136
137 static int pakfire_db_set_string(struct pakfire_db* db, const char* key, const char* val) {
138 sqlite3_stmt* stmt = NULL;
139 int r;
140
141 DEBUG(db->pakfire, "Setting %s to '%s'\n", key, val);
142
143 const char* sql = "INSERT INTO settings(key, val) VALUES(?, ?) \
144 ON CONFLICT (key) DO UPDATE SET val = excluded.val";
145
146 // Prepare statement
147 r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
148 if (r != SQLITE_OK) {
149 ERROR(db->pakfire, "Could not prepare SQL statement: %s: %s\n",
150 sql, sqlite3_errmsg(db->handle));
151 return 1;
152 }
153
154 // Bind key
155 r = sqlite3_bind_text(stmt, 1, key, strlen(key), NULL);
156 if (r != SQLITE_OK) {
157 ERROR(db->pakfire, "Could not bind key: %s\n", sqlite3_errmsg(db->handle));
158 goto ERROR;
159 }
160
161 // Bind val
162 r = sqlite3_bind_text(stmt, 2, val, strlen(val), NULL);
163 if (r != SQLITE_OK) {
164 ERROR(db->pakfire, "Could not bind val: %s\n", sqlite3_errmsg(db->handle));
165 goto ERROR;
166 }
167
168 // Execute the statement
169 do {
170 r = sqlite3_step(stmt);
171 } while (r == SQLITE_BUSY);
172
173 // Set return code
174 r = (r == SQLITE_OK);
175
176 ERROR:
177 if (stmt)
178 sqlite3_finalize(stmt);
179
180 return r;
181 }
182
183 static int pakfire_db_set_int(struct pakfire_db* db, const char* key, int val) {
184 sqlite3_stmt* stmt = NULL;
185 int r;
186
187 DEBUG(db->pakfire, "Setting %s to '%d'\n", key, val);
188
189 const char* sql = "INSERT INTO settings(key, val) VALUES(?, ?) \
190 ON CONFLICT (key) DO UPDATE SET val = excluded.val";
191
192 // Prepare statement
193 r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
194 if (r != SQLITE_OK) {
195 ERROR(db->pakfire, "Could not prepare SQL statement: %s: %s\n",
196 sql, sqlite3_errmsg(db->handle));
197 return 1;
198 }
199
200 // Bind key
201 r = sqlite3_bind_text(stmt, 1, key, strlen(key), NULL);
202 if (r != SQLITE_OK) {
203 ERROR(db->pakfire, "Could not bind key: %s\n", sqlite3_errmsg(db->handle));
204 goto ERROR;
205 }
206
207 // Bind val
208 r = sqlite3_bind_int64(stmt, 2, val);
209 if (r != SQLITE_OK) {
210 ERROR(db->pakfire, "Could not bind val: %s\n", sqlite3_errmsg(db->handle));
211 goto ERROR;
212 }
213
214 // Execute the statement
215 do {
216 r = sqlite3_step(stmt);
217 } while (r == SQLITE_BUSY);
218
219 // Set return code
220 r = (r == SQLITE_OK);
221
222 ERROR:
223 if (stmt)
224 sqlite3_finalize(stmt);
225
226 return r;
227 }
228
229 static time_t pakfire_read_modification_time(struct pakfire_db* db) {
230 time_t t = 0;
231
232 // Fetch the value from the database
233 sqlite3_value* value = pakfire_db_get(db, "last_modified_at");
234 if (value) {
235 t = sqlite3_value_int64(value);
236 sqlite3_value_free(value);
237 } else {
238 DEBUG(db->pakfire, "Could not find last modification timestamp\n");
239 }
240
241 return t;
242 }
243
244 static int pakfire_update_modification_time(struct pakfire_db* db) {
245 // Get the current time in UTC
246 time_t t = time(NULL);
247
248 // Store it in the database
249 int r = pakfire_db_set_int(db, "last_modified_at", t);
250 if (r)
251 return r;
252
253 // Update the last modification timestamp
254 db->last_modified_at = t;
255
256 return r;
257 }
258
259 static int pakfire_db_execute(struct pakfire_db* db, const char* stmt) {
260 int r;
261
262 DEBUG(db->pakfire, "Executing database query: %s\n", stmt);
263
264 do {
265 r = sqlite3_exec(db->handle, stmt, NULL, NULL, NULL);
266 } while (r == SQLITE_BUSY);
267
268 // Log any errors
269 if (r) {
270 ERROR(db->pakfire, "Database query failed: %s\n", sqlite3_errmsg(db->handle));
271 }
272
273 return r;
274 }
275
276 static int pakfire_db_begin_transaction(struct pakfire_db* db) {
277 return pakfire_db_execute(db, "BEGIN TRANSACTION");
278 }
279
280 static int pakfire_db_commit(struct pakfire_db* db) {
281 /*
282 If the database was opened in read-write mode, we will store the
283 timestamp of the latest modification to compare whether the database
284 has been changed mid-transaction.
285 */
286 if (db->mode == PAKFIRE_DB_READWRITE) {
287 int r = pakfire_update_modification_time(db);
288 if (r)
289 return r;
290 }
291
292 return pakfire_db_execute(db, "COMMIT");
293 }
294
295 static int pakfire_db_rollback(struct pakfire_db* db) {
296 return pakfire_db_execute(db, "ROLLBACK");
297 }
298
299 /*
300 This function performs any fast optimization and tries to truncate the WAL log file
301 to keep the database as compact as possible on disk.
302 */
303 static void pakfire_db_optimize(struct pakfire_db* db) {
304 pakfire_db_execute(db, "PRAGMA optimize");
305 pakfire_db_execute(db, "PRAGMA wal_checkpoint = TRUNCATE");
306 }
307
308 static void pakfire_db_free(struct pakfire_db* db) {
309 if (db->handle) {
310 // Optimize the database before it is being closed
311 pakfire_db_optimize(db);
312
313 // Close database handle
314 int r = sqlite3_close(db->handle);
315 if (r != SQLITE_OK) {
316 ERROR(db->pakfire, "Could not close database handle: %s\n",
317 sqlite3_errmsg(db->handle));
318 }
319 }
320
321 pakfire_unref(db->pakfire);
322
323 free(db);
324 }
325
326 static int pakfire_db_get_schema(struct pakfire_db* db) {
327 sqlite3_value* value = pakfire_db_get(db, "schema");
328 if (!value)
329 return -1;
330
331 int schema = sqlite3_value_int64(value);
332 sqlite3_value_free(value);
333
334 DEBUG(db->pakfire, "Database has schema version %d\n", schema);
335
336 return schema;
337 }
338
339 static int pakfire_db_create_schema(struct pakfire_db* db) {
340 int r;
341
342 // Create settings table
343 r = pakfire_db_execute(db, "CREATE TABLE IF NOT EXISTS settings(key TEXT, val TEXT)");
344 if (r)
345 return 1;
346
347 // settings: Add a unique index on key
348 r = pakfire_db_execute(db, "CREATE UNIQUE INDEX IF NOT EXISTS settings_key ON settings(key)");
349 if (r)
350 return 1;
351
352 // Create packages table
353 r = pakfire_db_execute(db,
354 "CREATE TABLE IF NOT EXISTS packages("
355 "id INTEGER PRIMARY KEY, "
356 "name TEXT, "
357 "evr TEXT, "
358 "arch TEXT, "
359 "groups TEXT, "
360 "filename TEXT, "
361 "size INTEGER, "
362 "inst_size INTEGER, "
363 "digest TEXT, "
364 "license TEXT, "
365 "summary TEXT, "
366 "description TEXT, "
367 "uuid TEXT, "
368 "vendor TEXT, "
369 "build_host TEXT, "
370 "build_time INTEGER, "
371 "installed INTEGER, "
372 "userinstalled INTEGER, "
373 "repository TEXT, "
374 "source_name TEXT, "
375 "source_evr TEXT, "
376 "source_arch TEXT, "
377 "distribution TEXT"
378 ")");
379 if (r)
380 return 1;
381
382 // packages: Create index to find package by name
383 r = pakfire_db_execute(db, "CREATE INDEX IF NOT EXISTS packages_name ON packages(name)");
384 if (r)
385 return 1;
386
387 // packages: Create unique index over UUID
388 r = pakfire_db_execute(db, "CREATE UNIQUE INDEX IF NOT EXISTS packages_uuid ON packages(uuid)");
389 if (r)
390 return 1;
391
392 // Create dependencies table
393 r = pakfire_db_execute(db,
394 "CREATE TABLE IF NOT EXISTS dependencies("
395 "pkg INTEGER, "
396 "type TEXT, "
397 "dependency TEXT, "
398 "FOREIGN KEY (pkg) REFERENCES packages(id) ON DELETE CASCADE"
399 ")");
400 if (r)
401 return r;
402
403 // dependencies: Add index over packages
404 r = pakfire_db_execute(db, "CREATE INDEX IF NOT EXISTS dependencies_pkg_index ON dependencies(pkg)");
405 if (r)
406 return r;
407
408 // Create files table
409 r = pakfire_db_execute(db,
410 "CREATE TABLE IF NOT EXISTS files("
411 "id INTEGER PRIMARY KEY, "
412 "path TEXT, "
413 "pkg INTEGER, "
414 "size INTEGER, "
415 "config INTEGER, "
416 "datafile INTEGER, "
417 "mode INTEGER, "
418 "user TEXT, "
419 "'group' TEXT, "
420 "ctime INTEGER, "
421 "mtime INTEGER, "
422 "capabilities TEXT, "
423 "digest_sha512 BLOB, "
424 "digest_sha256 BLOB, "
425 "FOREIGN KEY (pkg) REFERENCES packages(id) ON DELETE CASCADE"
426 ")");
427 if (r)
428 return 1;
429
430 // files: Add index over packages
431 r = pakfire_db_execute(db, "CREATE INDEX IF NOT EXISTS files_pkg_index ON files(pkg)");
432 if (r)
433 return 1;
434
435 // files: Add index over path
436 r = pakfire_db_execute(db, "CREATE INDEX IF NOT EXISTS files_path_index ON files(path)");
437 if (r)
438 return 1;
439
440 // Create scriptlets table
441 r = pakfire_db_execute(db,
442 "CREATE TABLE IF NOT EXISTS scriptlets("
443 "id INTEGER PRIMARY KEY, "
444 "pkg INTEGER, "
445 "type TEXT, "
446 "scriptlet TEXT, "
447 "FOREIGN KEY (pkg) REFERENCES packages(id) ON DELETE CASCADE"
448 ")");
449 if (r)
450 return 1;
451
452 // scriptlets: Add index over packages
453 r = pakfire_db_execute(db, "CREATE INDEX IF NOT EXISTS scriptlets_pkg_index ON scriptlets(pkg)");
454 if (r)
455 return 1;
456
457 const char* arch = pakfire_get_arch(db->pakfire);
458
459 // Set architecture
460 r = pakfire_db_set_string(db, "arch", arch);
461 if (r) {
462 ERROR(db->pakfire, "Could not set architecture\n");
463 return r;
464 }
465
466 return 0;
467 }
468
469 static int pakfire_db_migrate_to_schema_8(struct pakfire_db* db) {
470 // packages: Drop build_id column
471
472 // Add foreign keys
473 // TODO sqlite doesn't support adding foreign keys to existing tables and so we would
474 // need to recreate the whole table and rename it afterwards. Annoying.
475
476 return 0;
477 }
478
479 static int pakfire_db_migrate_schema(struct pakfire_db* db) {
480 int r;
481
482 while (db->schema < CURRENT_SCHEMA) {
483 // Begin a new transaction
484 r = pakfire_db_begin_transaction(db);
485 if (r)
486 goto ROLLBACK;
487
488 switch (db->schema) {
489 // No schema exists
490 case -1:
491 r = pakfire_db_create_schema(db);
492 if (r)
493 goto ROLLBACK;
494
495 db->schema = CURRENT_SCHEMA;
496 break;
497
498 case 7:
499 r = pakfire_db_migrate_to_schema_8(db);
500 if (r)
501 goto ROLLBACK;
502
503 db->schema++;
504 break;
505
506 default:
507 ERROR(db->pakfire, "Cannot migrate database from schema %d\n", db->schema);
508 goto ROLLBACK;
509 }
510
511 // Update the schema version
512 r = pakfire_db_set_int(db, "schema", CURRENT_SCHEMA);
513 if (r)
514 goto ROLLBACK;
515
516 // All done, commit!
517 r = pakfire_db_commit(db);
518 if (r)
519 goto ROLLBACK;
520 }
521
522 return 0;
523
524 ROLLBACK:
525 pakfire_db_rollback(db);
526
527 return 1;
528 }
529
530 static int pakfire_db_check_arch(struct pakfire_db* db) {
531 int r = 1;
532
533 // Fetch database architecture
534 char* db_arch = pakfire_db_get_string(db, "arch");
535 if (!db_arch) {
536 ERROR(db->pakfire, "Database is of an unknown architecture\n");
537 goto ERROR;
538 }
539
540 // Fetch the running architecture
541 const char* arch = pakfire_get_arch(db->pakfire);
542 if (!arch)
543 goto ERROR;
544
545 // They should match
546 if (strcmp(db_arch, arch) == 0)
547 r = 0;
548
549 ERROR:
550 if (db_arch)
551 free(db_arch);
552
553 return r;
554 }
555
556 static int pakfire_db_setup(struct pakfire_db* db) {
557 int r;
558
559 // Setup logging
560 sqlite3_config(SQLITE_CONFIG_LOG, logging_callback, db->pakfire);
561
562 // Enable foreign keys
563 pakfire_db_execute(db, "PRAGMA foreign_keys = ON");
564
565 // Make LIKE case-sensitive
566 pakfire_db_execute(db, "PRAGMA case_sensitive_like = ON");
567
568 // Fetch the current schema
569 db->schema = pakfire_db_get_schema(db);
570
571 // Check if the schema is recent enough
572 if (db->schema > 0 && db->schema < SCHEMA_MIN_SUP) {
573 ERROR(db->pakfire, "Database schema %d is not supported by this version of Pakfire\n",
574 db->schema);
575 return 1;
576 }
577
578 // Read modification timestamp
579 db->last_modified_at = pakfire_read_modification_time(db);
580
581 DEBUG(db->pakfire, "The database was last modified at %ld\n", db->last_modified_at);
582
583 // Done when not in read-write mode
584 if (db->mode != PAKFIRE_DB_READWRITE)
585 return 0;
586
587 // Disable secure delete
588 pakfire_db_execute(db, "PRAGMA secure_delete = OFF");
589
590 // Set database journal to WAL
591 r = pakfire_db_execute(db, "PRAGMA journal_mode = WAL");
592 if (r != SQLITE_OK) {
593 ERROR(db->pakfire, "Could not set journal mode to WAL: %s\n",
594 sqlite3_errmsg(db->handle));
595 return 1;
596 }
597
598 // Disable autocheckpoint
599 r = sqlite3_wal_autocheckpoint(db->handle, 0);
600 if (r != SQLITE_OK) {
601 ERROR(db->pakfire, "Could not disable autocheckpoint: %s\n",
602 sqlite3_errmsg(db->handle));
603 return 1;
604 }
605
606 // Create or migrate schema
607 r = pakfire_db_migrate_schema(db);
608 if (r)
609 return r;
610
611 return 0;
612 }
613
614 int pakfire_db_open(struct pakfire_db** db, struct pakfire* pakfire, int flags) {
615 int r = 1;
616
617 struct pakfire_db* o = calloc(1, sizeof(*o));
618 if (!o)
619 return -ENOMEM;
620
621 o->pakfire = pakfire_ref(pakfire);
622 o->nrefs = 1;
623
624 int sqlite3_flags = 0;
625
626 // Store mode & forward it to sqlite3
627 if (flags & PAKFIRE_DB_READWRITE) {
628 o->mode = PAKFIRE_DB_READWRITE;
629 sqlite3_flags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
630 } else {
631 o->mode = PAKFIRE_DB_READONLY;
632 sqlite3_flags |= SQLITE_OPEN_READONLY;
633 }
634
635 // Make the filename
636 r = pakfire_path(o->pakfire, o->path, "%s", DATABASE_PATH);
637 if (r)
638 goto END;
639
640 // Try to open the sqlite3 database file
641 r = sqlite3_open_v2(o->path, &o->handle, sqlite3_flags, NULL);
642 if (r != SQLITE_OK) {
643 ERROR(pakfire, "Could not open database %s: %s\n",
644 o->path, sqlite3_errmsg(o->handle));
645
646 r = 1;
647 goto END;
648 }
649
650 // Setup the database
651 r = pakfire_db_setup(o);
652 if (r)
653 goto END;
654
655 // Check for compatible architecture
656 r = pakfire_db_check_arch(o);
657 if (r)
658 goto END;
659
660 *db = o;
661 r = 0;
662
663 END:
664 if (r)
665 pakfire_db_free(o);
666
667 return r;
668 }
669
670 struct pakfire_db* pakfire_db_ref(struct pakfire_db* db) {
671 db->nrefs++;
672
673 return db;
674 }
675
676 struct pakfire_db* pakfire_db_unref(struct pakfire_db* db) {
677 if (--db->nrefs > 0)
678 return db;
679
680 pakfire_db_free(db);
681
682 return NULL;
683 }
684
685 static unsigned long pakfire_db_integrity_check(struct pakfire_db* db) {
686 sqlite3_stmt* stmt = NULL;
687 int r;
688
689 r = sqlite3_prepare_v2(db->handle, "PRAGMA integrity_check", -1, &stmt, NULL);
690 if (r) {
691 ERROR(db->pakfire, "Could not prepare integrity check: %s\n",
692 sqlite3_errmsg(db->handle));
693 return 1;
694 }
695
696 // Count any errors
697 unsigned long errors = 0;
698
699 while (1) {
700 do {
701 r = sqlite3_step(stmt);
702 } while (r == SQLITE_BUSY);
703
704 if (r == SQLITE_ROW) {
705 const char* error = (const char*)sqlite3_column_text(stmt, 0);
706
707 // If the message is "ok", the database has passed the check
708 if (strcmp(error, "ok") == 0)
709 continue;
710
711 // Increment error counter
712 errors++;
713
714 // Log the message
715 ERROR(db->pakfire, "%s\n", error);
716
717 // Break on anything else
718 } else
719 break;
720 }
721
722 sqlite3_finalize(stmt);
723
724 if (errors)
725 ERROR(db->pakfire, "Database integrity check failed\n");
726 else
727 INFO(db->pakfire, "Database integrity check passed\n");
728
729 return errors;
730 }
731
732 static unsigned long pakfire_db_foreign_key_check(struct pakfire_db* db) {
733 sqlite3_stmt* stmt = NULL;
734 int r;
735
736 r = sqlite3_prepare_v2(db->handle, "PRAGMA foreign_key_check", -1, &stmt, NULL);
737 if (r) {
738 ERROR(db->pakfire, "Could not prepare foreign key check: %s\n",
739 sqlite3_errmsg(db->handle));
740 return 1;
741 }
742
743 // Count any errors
744 unsigned long errors = 0;
745
746 while (1) {
747 do {
748 r = sqlite3_step(stmt);
749 } while (r == SQLITE_BUSY);
750
751 if (r == SQLITE_ROW) {
752 const unsigned char* table = sqlite3_column_text(stmt, 0);
753 unsigned long rowid = sqlite3_column_int64(stmt, 1);
754 const unsigned char* foreign_table = sqlite3_column_text(stmt, 2);
755 unsigned long foreign_rowid = sqlite3_column_int64(stmt, 3);
756
757 // Increment error counter
758 errors++;
759
760 // Log the message
761 ERROR(db->pakfire, "Foreign key violation found in %s, row %lu: "
762 "%lu does not exist in table %s\n", table, rowid, foreign_rowid, foreign_table);
763
764 // Break on anything else
765 } else
766 break;
767 }
768
769 sqlite3_finalize(stmt);
770
771 if (errors)
772 ERROR(db->pakfire, "Foreign key check failed\n");
773 else
774 INFO(db->pakfire, "Foreign key check passed\n");
775
776 return errors;
777 }
778
779 /*
780 This function performs an integrity check of the database
781 */
782 int pakfire_db_check(struct pakfire_db* db) {
783 int r;
784
785 // Perform integrity check
786 r = pakfire_db_integrity_check(db);
787 if (r)
788 return 1;
789
790 // Perform foreign key check
791 r = pakfire_db_foreign_key_check(db);
792 if (r)
793 return 1;
794
795 return 0;
796 }
797
798 // Returns the number of packages installed
799 ssize_t pakfire_db_packages(struct pakfire_db* db) {
800 sqlite3_stmt* stmt = NULL;
801 ssize_t packages = -1;
802
803 int r = sqlite3_prepare_v2(db->handle, "SELECT COUNT(*) FROM packages", -1, &stmt, NULL);
804 if (r) {
805 ERROR(db->pakfire, "Could not prepare SQL statement: %s\n",
806 sqlite3_errmsg(db->handle));
807 return -1;
808 }
809
810 // Execute query
811 do {
812 r = sqlite3_step(stmt);
813 } while (r == SQLITE_BUSY);
814
815 if (r == SQLITE_ROW) {
816 packages = sqlite3_column_int64(stmt, 0);
817 }
818
819 sqlite3_finalize(stmt);
820
821 return packages;
822 }
823
824 static void pakfire_db_add_userinstalled(struct pakfire* pakfire, const char* name) {
825 Pool* pool = pakfire_get_solv_pool(pakfire);
826
827 // Convert name to ID
828 Id id = pool_str2id(pool, name, 1);
829
830 // Append it to pooljobs
831 queue_push2(&pool->pooljobs, SOLVER_USERINSTALLED|SOLVER_SOLVABLE_NAME, id);
832 }
833
834 static const struct pakfire_digest {
835 enum pakfire_digests type;
836 const char* prefix;
837 } pakfire_digests[] = {
838 { PAKFIRE_DIGEST_SHA512, "sha512:" },
839 { PAKFIRE_DIGEST_SHA256, "sha256:" },
840 { 0, NULL },
841 };
842
843 static char* pakfire_db_pack_digest(enum pakfire_digests type, const char* hexdigest) {
844 char* s = NULL;
845 int r;
846
847 for (const struct pakfire_digest* digest = pakfire_digests; digest->type; digest++) {
848 if (digest->type == type) {
849 r = asprintf(&s, "%s%s", digest->prefix, hexdigest);
850 if (r < 0)
851 return NULL;
852
853 return s;
854 }
855 }
856
857 return NULL;
858 }
859
860 static const char* pakfire_db_unpack_digest(const char* hexdigest, enum pakfire_digests* type) {
861 *type = 0;
862
863 // Don't do anything for empty input
864 if (!hexdigest || !*hexdigest)
865 return NULL;
866
867 for (const struct pakfire_digest* digest = pakfire_digests; digest->type; digest++) {
868 if (pakfire_string_startswith(hexdigest, digest->prefix)) {
869 *type = digest->type;
870
871 // Return the beginning of the hexdigest
872 return hexdigest + strlen(digest->prefix);
873 }
874 }
875
876 // No match
877 return NULL;
878 }
879
880 static int pakfire_db_add_dependencies(struct pakfire_db* db, unsigned long id, struct pakfire_package* pkg) {
881 sqlite3_stmt* stmt = NULL;
882 int r = 1;
883
884 const char* sql = "INSERT INTO dependencies(pkg, type, dependency) VALUES(?, ?, ?)";
885
886 // Prepare the statement
887 r = sqlite3_prepare_v2(db->handle, sql, -1, &stmt, NULL);
888 if (r) {
889 ERROR(db->pakfire, "Could not prepare SQL statement: %s: %s\n",
890 sql, sqlite3_errmsg(db->handle));
891 goto END;
892 }
893
894 const struct __relation {
895 const char* type;
896 char** (*func)(struct pakfire_package*);
897 } relations[] = {
898 { "provides", pakfire_package_get_provides },
899 { "prerequires", pakfire_package_get_prerequires },
900 { "requires", pakfire_package_get_requires },
901 { "conflicts", pakfire_package_get_conflicts },
902 { "obsoletes", pakfire_package_get_obsoletes },
903 { "recommends", pakfire_package_get_recommends },
904 { "suggests", pakfire_package_get_suggests },
905 { "supplements", pakfire_package_get_supplements },
906 { "enhances", pakfire_package_get_enhances },
907 { NULL, NULL },
908 };
909
910 for (const struct __relation* relation = relations; relation->type; relation++) {
911 char** list = relation->func(pkg);
912 if (!list)
913 continue;
914
915 for (char** dep = list; *dep; dep++) {
916 // Bind package ID
917 r = sqlite3_bind_int64(stmt, 1, id);
918 if (r) {
919 ERROR(db->pakfire, "Could not bind id: %s\n",
920 sqlite3_errmsg(db->handle));
921 goto END;
922 }
923
924 // Bind type
925 r = sqlite3_bind_text(stmt, 2, relation->type, -1, NULL);
926 if (r) {
927 ERROR(db->pakfire, "Could not bind type: %s\n",
928 sqlite3_errmsg(db->handle));
929 goto END;
930 }
931
932 // Bind dependency
933 r = sqlite3_bind_text(stmt, 3, *dep, -1, NULL);
934 if (r) {
935 ERROR(db->pakfire, "Could not bind dependency: %s\n",
936 sqlite3_errmsg(db->handle));
937 goto END;
938 }
939
940 // Execute query
941 do {
942 r = sqlite3_step(stmt);
943 } while (r == SQLITE_BUSY);
944
945 free(*dep);
946
947 // Reset bound values
948 sqlite3_reset(stmt);
949 }
950
951 free(list);
952 }
953
954 // All okay
955 r = 0;
956
957 END:
958 if (stmt)
959 sqlite3_finalize(stmt);
960
961 return r;
962 }
963
964 static int pakfire_db_add_files(struct pakfire_db* db, unsigned long id, struct pakfire_archive* archive) {
965 sqlite3_stmt* stmt = NULL;
966 int r = 1;
967
968 // Get the filelist from the archive
969 struct pakfire_filelist* filelist = pakfire_archive_get_filelist(archive);
970 if (!filelist) {
971 ERROR(db->pakfire, "Could not fetch filelist from archive\n");
972 return 1;
973 }
974
975 // Nothing to do if the list is empty
976 if (pakfire_filelist_is_empty(filelist)) {
977 r = 0;
978 goto END;
979 }
980
981 const char* sql = "INSERT INTO files(pkg, path, size, config, datafile, mode, "
982 "user, 'group', ctime, mtime, capabilities, digest_sha512, digest_sha256) "
983 "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
984
985 // Prepare the statement
986 r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
987 if (r) {
988 ERROR(db->pakfire, "Could not prepare SQL statement: %s: %s\n",
989 sql, sqlite3_errmsg(db->handle));
990 goto END;
991 }
992
993 for (unsigned int i = 0; i < pakfire_filelist_size(filelist); i++) {
994 struct pakfire_file* file = pakfire_filelist_get(filelist, i);
995
996 // Bind package ID
997 r = sqlite3_bind_int64(stmt, 1, id);
998 if (r) {
999 ERROR(db->pakfire, "Could not bind id: %s\n", sqlite3_errmsg(db->handle));
1000 pakfire_file_unref(file);
1001 goto END;
1002 }
1003
1004 // Bind name
1005 const char* path = pakfire_file_get_path(file);
1006
1007 r = sqlite3_bind_text(stmt, 2, path, -1, NULL);
1008 if (r) {
1009 ERROR(db->pakfire, "Could not bind path: %s\n", sqlite3_errmsg(db->handle));
1010 pakfire_file_unref(file);
1011 goto END;
1012 }
1013
1014 // Bind size
1015 size_t size = pakfire_file_get_size(file);
1016
1017 r = sqlite3_bind_int64(stmt, 3, size);
1018 if (r) {
1019 ERROR(db->pakfire, "Could not bind size: %s\n", sqlite3_errmsg(db->handle));
1020 pakfire_file_unref(file);
1021 goto END;
1022 }
1023
1024 // Bind config - XXX TODO
1025 r = sqlite3_bind_null(stmt, 4);
1026 if (r) {
1027 ERROR(db->pakfire, "Could not bind config: %s\n", sqlite3_errmsg(db->handle));
1028 pakfire_file_unref(file);
1029 goto END;
1030 }
1031
1032 // Bind datafile - XXX TODO
1033 r = sqlite3_bind_null(stmt, 5);
1034 if (r) {
1035 ERROR(db->pakfire, "Could not bind datafile: %s\n", sqlite3_errmsg(db->handle));
1036 pakfire_file_unref(file);
1037 goto END;
1038 }
1039
1040 // Bind mode
1041 mode_t mode = pakfire_file_get_mode(file);
1042
1043 r = sqlite3_bind_int64(stmt, 6, mode);
1044 if (r) {
1045 ERROR(db->pakfire, "Could not bind mode: %s\n", sqlite3_errmsg(db->handle));
1046 pakfire_file_unref(file);
1047 goto END;
1048 }
1049
1050 // Bind user
1051 const char* user = pakfire_file_get_user(file);
1052
1053 r = sqlite3_bind_text(stmt, 7, user, -1, NULL);
1054 if (r) {
1055 ERROR(db->pakfire, "Could not bind user: %s\n", sqlite3_errmsg(db->handle));
1056 pakfire_file_unref(file);
1057 goto END;
1058 }
1059
1060 // Bind group
1061 const char* group = pakfire_file_get_group(file);
1062
1063 r = sqlite3_bind_text(stmt, 8, group, -1, NULL);
1064 if (r) {
1065 ERROR(db->pakfire, "Could not bind group: %s\n", sqlite3_errmsg(db->handle));
1066 pakfire_file_unref(file);
1067 goto END;
1068 }
1069
1070 // Bind ctime
1071 time_t ctime = pakfire_file_get_ctime(file);
1072
1073 r = sqlite3_bind_int64(stmt, 9, ctime);
1074 if (r) {
1075 ERROR(db->pakfire, "Could not bind ctime: %s\n", sqlite3_errmsg(db->handle));
1076 pakfire_file_unref(file);
1077 goto END;
1078 }
1079
1080 // Bind mtime
1081 time_t mtime = pakfire_file_get_mtime(file);
1082
1083 r = sqlite3_bind_int64(stmt, 10, mtime);
1084 if (r) {
1085 ERROR(db->pakfire, "Could not bind mtime: %s\n", sqlite3_errmsg(db->handle));
1086 pakfire_file_unref(file);
1087 goto END;
1088 }
1089
1090 // Bind capabilities - XXX TODO
1091 r = sqlite3_bind_null(stmt, 11);
1092 if (r) {
1093 ERROR(db->pakfire, "Could not bind capabilities: %s\n", sqlite3_errmsg(db->handle));
1094 pakfire_file_unref(file);
1095 goto END;
1096 }
1097
1098 const unsigned char* sha512_digest = NULL;
1099 size_t sha512_length = 0;
1100
1101 // SHA-512 Digest
1102 sha512_digest = pakfire_file_get_digest(file, PAKFIRE_DIGEST_SHA512, &sha512_length);
1103 if (sha512_digest) {
1104 r = sqlite3_bind_blob(stmt, 12, sha512_digest, sha512_length, NULL);
1105 } else {
1106 r = sqlite3_bind_null(stmt, 12);
1107 }
1108 if (r) {
1109 ERROR(db->pakfire, "Could not bind SHA-512 digest: %s\n",
1110 sqlite3_errmsg(db->handle));
1111 pakfire_file_unref(file);
1112 goto END;
1113 }
1114
1115 const unsigned char* sha256_digest = NULL;
1116 size_t sha256_length = 0;
1117
1118 // SHA-256 Digest
1119 sha256_digest = pakfire_file_get_digest(file, PAKFIRE_DIGEST_SHA256, &sha256_length);
1120 if (sha256_digest) {
1121 r = sqlite3_bind_blob(stmt, 13, sha256_digest, sha256_length, NULL);
1122 } else {
1123 r = sqlite3_bind_null(stmt, 13);
1124 }
1125 if (r) {
1126 ERROR(db->pakfire, "Could not bind SHA-256 digest: %s\n",
1127 sqlite3_errmsg(db->handle));
1128 pakfire_file_unref(file);
1129 goto END;
1130 }
1131
1132 // Execute query
1133 do {
1134 r = sqlite3_step(stmt);
1135 } while (r == SQLITE_BUSY);
1136
1137 // Check for errors
1138 if (r != SQLITE_DONE) {
1139 ERROR(db->pakfire, "Could not add file to database: %s\n",
1140 sqlite3_errmsg(db->handle));
1141 pakfire_file_unref(file);
1142 goto END;
1143 }
1144
1145 // Move on to next file
1146 pakfire_file_unref(file);
1147
1148 // Reset bound values
1149 sqlite3_reset(stmt);
1150 }
1151
1152 // All okay
1153 r = 0;
1154
1155 END:
1156 if (stmt)
1157 sqlite3_finalize(stmt);
1158 pakfire_filelist_unref(filelist);
1159
1160 return r;
1161 }
1162
1163 static int pakfire_db_add_scriptlets(struct pakfire_db* db, unsigned long id, struct pakfire_archive* archive) {
1164 sqlite3_stmt* stmt = NULL;
1165 size_t size;
1166 int r = 1;
1167
1168 const char* sql = "INSERT INTO scriptlets(pkg, type, scriptlet) VALUES(?, ?, ?)";
1169
1170 // Prepare the statement
1171 r = sqlite3_prepare_v2(db->handle, sql, -1, &stmt, NULL);
1172 if (r) {
1173 ERROR(db->pakfire, "Could not prepare SQL statement: %s: %s\n",
1174 sql, sqlite3_errmsg(db->handle));
1175 goto END;
1176 }
1177
1178 for (const char** type = pakfire_scriptlet_types; *type; type++) {
1179 // Fetch the scriptlet
1180 struct pakfire_scriptlet* scriptlet = pakfire_archive_get_scriptlet(archive, *type);
1181 if (!scriptlet)
1182 continue;
1183
1184 // Bind package ID
1185 r = sqlite3_bind_int64(stmt, 1, id);
1186 if (r) {
1187 ERROR(db->pakfire, "Could not bind id: %s\n", sqlite3_errmsg(db->handle));
1188 pakfire_scriptlet_unref(scriptlet);
1189 goto END;
1190 }
1191
1192 // Bind handle
1193 r = sqlite3_bind_text(stmt, 2, *type, -1, NULL);
1194 if (r) {
1195 ERROR(db->pakfire, "Could not bind type: %s\n", sqlite3_errmsg(db->handle));
1196 pakfire_scriptlet_unref(scriptlet);
1197 goto END;
1198 }
1199
1200 const char* data = pakfire_scriptlet_get_data(scriptlet, &size);
1201
1202 // Bind scriptlet
1203 r = sqlite3_bind_text(stmt, 3, data, size, NULL);
1204 if (r) {
1205 ERROR(db->pakfire, "Could not bind scriptlet: %s\n", sqlite3_errmsg(db->handle));
1206 pakfire_scriptlet_unref(scriptlet);
1207 goto END;
1208 }
1209
1210 // Execute query
1211 do {
1212 r = sqlite3_step(stmt);
1213 } while (r == SQLITE_BUSY);
1214
1215 // Check for errors
1216 if (r != SQLITE_DONE) {
1217 ERROR(db->pakfire, "Could not add scriptlet to database: %s\n",
1218 sqlite3_errmsg(db->handle));
1219 pakfire_scriptlet_unref(scriptlet);
1220 goto END;
1221 }
1222
1223 pakfire_scriptlet_unref(scriptlet);
1224
1225 // Reset bound values
1226 sqlite3_reset(stmt);
1227 }
1228
1229 // All okay
1230 r = 0;
1231
1232 END:
1233 if (stmt)
1234 sqlite3_finalize(stmt);
1235
1236 return r;
1237 }
1238
1239 int pakfire_db_add_package(struct pakfire_db* db,
1240 struct pakfire_package* pkg, struct pakfire_archive* archive, int userinstalled) {
1241 sqlite3_stmt* stmt = NULL;
1242 char* digest = NULL;
1243 int r;
1244
1245 // Begin a new transaction
1246 r = pakfire_db_begin_transaction(db);
1247 if (r)
1248 goto ERROR;
1249
1250 const char* sql = "INSERT INTO "
1251 "packages("
1252 "name, "
1253 "evr, "
1254 "arch, "
1255 "groups, "
1256 "filename, "
1257 "size, "
1258 "inst_size, "
1259 "digest, "
1260 "license, "
1261 "summary, "
1262 "description, "
1263 "uuid, "
1264 "vendor, "
1265 "build_host, "
1266 "build_time, "
1267 "installed, "
1268 "repository, "
1269 "userinstalled, "
1270 "source_name, "
1271 "source_evr, "
1272 "source_arch, "
1273 "distribution"
1274 ") VALUES("
1275 "?, "
1276 "?, "
1277 "?, "
1278 "?, "
1279 "?, "
1280 "?, "
1281 "?, "
1282 "?, "
1283 "?, "
1284 "?, "
1285 "?, "
1286 "?, "
1287 "?, "
1288 "?, "
1289 "?, "
1290 "CURRENT_TIMESTAMP, "
1291 "?, "
1292 "?, "
1293 "?, "
1294 "?, "
1295 "?, "
1296 "?"
1297 ")";
1298
1299 // Prepare the statement
1300 r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
1301 if (r != SQLITE_OK) {
1302 ERROR(db->pakfire, "Could not prepare SQL statement: %s: %s\n",
1303 sql, sqlite3_errmsg(db->handle));
1304 goto ERROR;
1305 }
1306
1307 // Bind name
1308 const char* name = pakfire_package_get_name(pkg);
1309
1310 r = sqlite3_bind_text(stmt, 1, name, -1, NULL);
1311 if (r) {
1312 ERROR(db->pakfire, "Could not bind name: %s\n", sqlite3_errmsg(db->handle));
1313 goto ERROR;
1314 }
1315
1316 // Bind evr
1317 const char* evr = pakfire_package_get_evr(pkg);
1318
1319 r = sqlite3_bind_text(stmt, 2, evr, -1, NULL);
1320 if (r) {
1321 ERROR(db->pakfire, "Could not bind evr: %s\n", sqlite3_errmsg(db->handle));
1322 goto ERROR;
1323 }
1324
1325 // Bind arch
1326 const char* arch = pakfire_package_get_arch(pkg);
1327
1328 r = sqlite3_bind_text(stmt, 3, arch, -1, NULL);
1329 if (r) {
1330 ERROR(db->pakfire, "Could not bind arch: %s\n", sqlite3_errmsg(db->handle));
1331 goto ERROR;
1332 }
1333
1334 // Bind groups
1335 char* groups = pakfire_package_get_groups(pkg);
1336 if (groups) {
1337 r = sqlite3_bind_text(stmt, 4, groups, -1, NULL);
1338 if (r) {
1339 ERROR(db->pakfire, "Could not bind groups: %s\n", sqlite3_errmsg(db->handle));
1340 free(groups);
1341 goto ERROR;
1342 }
1343
1344 free(groups);
1345
1346 // No groups
1347 } else {
1348 r = sqlite3_bind_null(stmt, 4);
1349 if (r)
1350 goto ERROR;
1351 }
1352
1353 // Bind filename
1354 const char* filename = pakfire_package_get_filename(pkg);
1355
1356 r = sqlite3_bind_text(stmt, 5, filename, -1, NULL);
1357 if (r) {
1358 ERROR(db->pakfire, "Could not bind filename: %s\n", sqlite3_errmsg(db->handle));
1359 goto ERROR;
1360 }
1361
1362 // Bind size
1363 unsigned long long size = pakfire_package_get_downloadsize(pkg);
1364
1365 r = sqlite3_bind_int64(stmt, 6, size);
1366 if (r) {
1367 ERROR(db->pakfire, "Could not bind size: %s\n", sqlite3_errmsg(db->handle));
1368 goto ERROR;
1369 }
1370
1371 // Bind installed size
1372 unsigned long long inst_size = pakfire_package_get_installsize(pkg);
1373
1374 r = sqlite3_bind_int64(stmt, 7, inst_size);
1375 if (r) {
1376 ERROR(db->pakfire, "Could not bind inst_size: %s\n", sqlite3_errmsg(db->handle));
1377 goto ERROR;
1378 }
1379
1380 enum pakfire_digests digest_type = 0;
1381
1382 const char* hexdigest = pakfire_package_get_hexdigest(pkg, &digest_type);
1383 if (hexdigest) {
1384 digest = pakfire_db_pack_digest(digest_type, hexdigest);
1385 if (!digest)
1386 goto ERROR;
1387
1388 r = sqlite3_bind_text(stmt, 8, digest, -1, NULL);
1389 if (r) {
1390 ERROR(db->pakfire, "Could not bind digest: %s\n", sqlite3_errmsg(db->handle));
1391 goto ERROR;
1392 }
1393 }
1394
1395 // Bind license
1396 const char* license = pakfire_package_get_license(pkg);
1397
1398 r = sqlite3_bind_text(stmt, 9, license, -1, NULL);
1399 if (r) {
1400 ERROR(db->pakfire, "Could not bind license: %s\n", sqlite3_errmsg(db->handle));
1401 goto ERROR;
1402 }
1403
1404 // Bind summary
1405 const char* summary = pakfire_package_get_summary(pkg);
1406
1407 r = sqlite3_bind_text(stmt, 10, summary, -1, NULL);
1408 if (r) {
1409 ERROR(db->pakfire, "Could not bind summary: %s\n", sqlite3_errmsg(db->handle));
1410 goto ERROR;
1411 }
1412
1413 // Bind description
1414 const char* description = pakfire_package_get_description(pkg);
1415
1416 r = sqlite3_bind_text(stmt, 11, description, -1, NULL);
1417 if (r) {
1418 ERROR(db->pakfire, "Could not bind description: %s\n", sqlite3_errmsg(db->handle));
1419 goto ERROR;
1420 }
1421
1422 // Bind uuid
1423 const char* uuid = pakfire_package_get_uuid(pkg);
1424
1425 r = sqlite3_bind_text(stmt, 12, uuid, -1, NULL);
1426 if (r) {
1427 ERROR(db->pakfire, "Could not bind uuid: %s\n", sqlite3_errmsg(db->handle));
1428 goto ERROR;
1429 }
1430
1431 // Bind vendor
1432 const char* vendor = pakfire_package_get_vendor(pkg);
1433
1434 r = sqlite3_bind_text(stmt, 13, vendor, -1, NULL);
1435 if (r) {
1436 ERROR(db->pakfire, "Could not bind vendor: %s\n", sqlite3_errmsg(db->handle));
1437 goto ERROR;
1438 }
1439
1440 // Bind build_host
1441 const char* build_host = pakfire_package_get_build_host(pkg);
1442
1443 r = sqlite3_bind_text(stmt, 14, build_host, -1, NULL);
1444 if (r) {
1445 ERROR(db->pakfire, "Could not bind build_host: %s\n", sqlite3_errmsg(db->handle));
1446 goto ERROR;
1447 }
1448
1449 // Bind build_time
1450 time_t build_time = pakfire_package_get_build_time(pkg);
1451
1452 r = sqlite3_bind_int64(stmt, 15, build_time);
1453 if (r) {
1454 ERROR(db->pakfire, "Could not bind build_time: %s\n", sqlite3_errmsg(db->handle));
1455 goto ERROR;
1456 }
1457
1458 // Bind repository name
1459 struct pakfire_repo* repo = pakfire_package_get_repo(pkg);
1460 if (repo) {
1461 const char* repo_name = pakfire_repo_get_name(repo);
1462 pakfire_repo_unref(repo);
1463
1464 r = sqlite3_bind_text(stmt, 16, repo_name, -1, NULL);
1465 if (r)
1466 goto ERROR;
1467
1468 // No repository?
1469 } else {
1470 r = sqlite3_bind_null(stmt, 16);
1471 if (r)
1472 goto ERROR;
1473 }
1474
1475 // installed by the user?
1476 r = sqlite3_bind_int(stmt, 17, userinstalled);
1477 if (r) {
1478 ERROR(db->pakfire, "Could not bind userinstalled: %s\n", sqlite3_errmsg(db->handle));
1479 goto ERROR;
1480 }
1481
1482 // Source package name
1483 const char* source_name = pakfire_package_get_source_name(pkg);
1484 if (source_name) {
1485 r = sqlite3_bind_text(stmt, 18, source_name, -1, NULL);
1486 if (r)
1487 goto ERROR;
1488 } else {
1489 r = sqlite3_bind_null(stmt, 18);
1490 if (r)
1491 goto ERROR;
1492 }
1493
1494 // Source EVR
1495 const char* source_evr = pakfire_package_get_source_evr(pkg);
1496 if (source_evr) {
1497 r = sqlite3_bind_text(stmt, 19, source_evr, -1, NULL);
1498 if (r)
1499 goto ERROR;
1500 } else {
1501 r = sqlite3_bind_null(stmt, 19);
1502 if (r)
1503 goto ERROR;
1504 }
1505
1506 // Source arch
1507 const char* source_arch = pakfire_package_get_source_arch(pkg);
1508 if (source_arch) {
1509 r = sqlite3_bind_text(stmt, 20, source_arch, -1, NULL);
1510 if (r)
1511 goto ERROR;
1512 } else {
1513 r = sqlite3_bind_null(stmt, 20);
1514 if (r)
1515 goto ERROR;
1516 }
1517
1518 // Distribution
1519 const char* distribution = pakfire_package_get_distribution(pkg);
1520 if (distribution) {
1521 r = sqlite3_bind_text(stmt, 21, distribution, -1, NULL);
1522 if (r)
1523 goto ERROR;
1524 } else {
1525 r = sqlite3_bind_null(stmt, 21);
1526 if (r)
1527 goto ERROR;
1528 }
1529
1530 // Run query
1531 do {
1532 r = sqlite3_step(stmt);
1533 } while (r == SQLITE_BUSY);
1534
1535 if (r != SQLITE_DONE) {
1536 ERROR(db->pakfire, "Could not add package to database: %s\n",
1537 sqlite3_errmsg(db->handle));
1538 r = 1;
1539 goto ERROR;
1540 }
1541
1542 // Save package ID
1543 unsigned long packages_id = sqlite3_last_insert_rowid(db->handle);
1544
1545 // Add dependencies
1546 r = pakfire_db_add_dependencies(db, packages_id, pkg);
1547 if (r)
1548 goto ERROR;
1549
1550 // Add files
1551 r = pakfire_db_add_files(db, packages_id, archive);
1552 if (r)
1553 goto ERROR;
1554
1555 // Add scriptlets
1556 r = pakfire_db_add_scriptlets(db, packages_id, archive);
1557 if (r)
1558 goto ERROR;
1559
1560 ERROR:
1561 if (stmt)
1562 sqlite3_finalize(stmt);
1563 if (digest)
1564 free(digest);
1565
1566 // Commit or rollback
1567 if (r)
1568 pakfire_db_rollback(db);
1569 else
1570 r = pakfire_db_commit(db);
1571
1572 return r;
1573 }
1574
1575 int pakfire_db_remove_package(struct pakfire_db* db, struct pakfire_package* pkg) {
1576 sqlite3_stmt* stmt = NULL;
1577 int r = 1;
1578
1579 // Begin a new transaction
1580 r = pakfire_db_begin_transaction(db);
1581 if (r)
1582 goto ERROR;
1583
1584 // Fetch the package's UUID
1585 const char* uuid = pakfire_package_get_uuid(pkg);
1586 if (!uuid) {
1587 ERROR(db->pakfire, "Package has no UUID\n");
1588 r = 1;
1589 goto ERROR;
1590 }
1591
1592 r = sqlite3_prepare_v2(db->handle,
1593 "DELETE FROM packages WHERE uuid = ?", -1, &stmt, NULL);
1594 if (r) {
1595 ERROR(db->pakfire, "Could not prepare SQL statement: %s\n",
1596 sqlite3_errmsg(db->handle));
1597 goto ERROR;
1598 }
1599
1600 // Bind UUID
1601 r = sqlite3_bind_text(stmt, 1, uuid, -1, NULL);
1602 if (r) {
1603 ERROR(db->pakfire, "Could not bind uuid: %s\n", sqlite3_errmsg(db->handle));
1604 goto ERROR;
1605 }
1606
1607 // Execute query
1608 do {
1609 r = sqlite3_step(stmt);
1610 } while (r == SQLITE_BUSY);
1611
1612 // Check if we have been successful
1613 if (r != SQLITE_DONE) {
1614 ERROR(db->pakfire, "Could not delete package %s\n", uuid);
1615 r = 1;
1616 goto ERROR;
1617 }
1618
1619 // All done
1620 r = 0;
1621
1622 ERROR:
1623 if (stmt)
1624 sqlite3_finalize(stmt);
1625
1626 // Commit or rollback
1627 if (r)
1628 pakfire_db_rollback(db);
1629 else
1630 r = pakfire_db_commit(db);
1631
1632 return r;
1633 }
1634
1635 struct pakfire_scriptlet* pakfire_db_get_scriptlet(struct pakfire_db* db,
1636 struct pakfire_package* pkg, const char* type) {
1637 struct pakfire_scriptlet* scriptlet = NULL;
1638 sqlite3_stmt* stmt = NULL;
1639 int r = 1;
1640
1641 // Fetch the package's UUID
1642 const char* uuid = pakfire_package_get_uuid(pkg);
1643 if (!uuid) {
1644 ERROR(db->pakfire, "Package has no UUID\n");
1645 goto ERROR;
1646 }
1647
1648 const char* sql = "SELECT scriptlets.scriptlet FROM packages \
1649 JOIN scriptlets ON packages.id = scriptlets.pkg \
1650 WHERE packages.uuid = ? AND scriptlets.type = ?";
1651
1652 r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
1653 if (r) {
1654 ERROR(db->pakfire, "Could not prepare SQL statement: %s %s\n",
1655 sql, sqlite3_errmsg(db->handle));
1656 goto ERROR;
1657 }
1658
1659 // Bind UUID
1660 r = sqlite3_bind_text(stmt, 1, uuid, -1, NULL);
1661 if (r) {
1662 ERROR(db->pakfire, "Could not bind uuid: %s\n", sqlite3_errmsg(db->handle));
1663 goto ERROR;
1664 }
1665
1666 r = sqlite3_bind_text(stmt, 2, type, -1, NULL);
1667 if (r) {
1668 ERROR(db->pakfire, "Could not bind type: %s\n", sqlite3_errmsg(db->handle));
1669 goto ERROR;
1670 }
1671
1672 DEBUG(db->pakfire, "Searching for scriptlet for package %s of type %s\n", uuid, type);
1673
1674 // Execute query
1675 do {
1676 r = sqlite3_step(stmt);
1677 } while (r == SQLITE_BUSY);
1678
1679 // We have some payload
1680 if (r == SQLITE_ROW) {
1681 const void* data = sqlite3_column_blob(stmt, 1);
1682 ssize_t size = sqlite3_column_bytes(stmt, 1);
1683
1684 // Create a scriptlet object
1685 r = pakfire_scriptlet_create(&scriptlet, db->pakfire, type, data, size);
1686 if (r)
1687 goto ERROR;
1688 }
1689
1690 ERROR:
1691 if (stmt)
1692 sqlite3_finalize(stmt);
1693
1694 return scriptlet;
1695 }
1696
1697 static int pakfire_db_load_package(struct pakfire_db* db, struct pakfire_repo* repo, sqlite3_stmt* stmt) {
1698 struct pakfire_package* pkg = NULL;
1699 int r = 1;
1700
1701 // Name
1702 const char* name = (const char*)sqlite3_column_text(stmt, 0);
1703 if (!name) {
1704 ERROR(db->pakfire, "Could not read name: %s\n", sqlite3_errmsg(db->handle));
1705 goto ERROR;
1706 }
1707
1708 // EVR
1709 const char* evr = (const char*)sqlite3_column_text(stmt, 1);
1710 if (!evr) {
1711 ERROR(db->pakfire, "Could not read evr: %s\n", sqlite3_errmsg(db->handle));
1712 goto ERROR;
1713 }
1714
1715 // Arch
1716 const char* arch = (const char*)sqlite3_column_text(stmt, 2);
1717 if (!arch) {
1718 ERROR(db->pakfire, "Could not read arch: %s\n", sqlite3_errmsg(db->handle));
1719 goto ERROR;
1720 }
1721
1722 // Create package
1723 pkg = pakfire_package_create(db->pakfire, repo, name, evr, arch);
1724 if (!pkg) {
1725 ERROR(db->pakfire, "Could not create package\n");
1726 goto ERROR;
1727 }
1728
1729 // ID
1730 uint64_t id = sqlite3_column_int64(stmt, 3);
1731 if (id)
1732 pakfire_package_set_dbid(pkg, id);
1733
1734 // Groups
1735 const char* groups = (const char*)sqlite3_column_text(stmt, 4);
1736 if (groups) {
1737 pakfire_package_set_groups(pkg, groups);
1738 }
1739
1740 // Filename
1741 const char* filename = (const char*)sqlite3_column_text(stmt, 5);
1742 if (filename) {
1743 pakfire_package_set_filename(pkg, filename);
1744 }
1745
1746 // Size
1747 size_t size = sqlite3_column_int64(stmt, 6);
1748 if (size) {
1749 pakfire_package_set_downloadsize(pkg, size);
1750 }
1751
1752 // Installed size
1753 size = sqlite3_column_int64(stmt, 7);
1754 if (size) {
1755 pakfire_package_set_installsize(pkg, size);
1756 }
1757
1758 // Digest
1759 const char* digest = (const char*)sqlite3_column_text(stmt, 8);
1760 if (digest) {
1761 enum pakfire_digests digest_type = 0;
1762
1763 // Unpack digest
1764 const char* hexdigest = pakfire_db_unpack_digest(digest, &digest_type);
1765 if (hexdigest)
1766 pakfire_package_set_hexdigest(pkg, digest_type, hexdigest);
1767 }
1768
1769 // License
1770 const char* license = (const char*)sqlite3_column_text(stmt, 9);
1771 if (license) {
1772 pakfire_package_set_license(pkg, license);
1773 }
1774
1775 // Summary
1776 const char* summary = (const char*)sqlite3_column_text(stmt, 10);
1777 if (summary) {
1778 pakfire_package_set_summary(pkg, summary);
1779 }
1780
1781 // Description
1782 const char* description = (const char*)sqlite3_column_text(stmt, 11);
1783 if (description) {
1784 pakfire_package_set_description(pkg, description);
1785 }
1786
1787 // UUID
1788 const char* uuid = (const char*)sqlite3_column_text(stmt, 12);
1789 if (uuid) {
1790 pakfire_package_set_uuid(pkg, uuid);
1791 }
1792
1793 // Vendor
1794 const char* vendor = (const char*)sqlite3_column_text(stmt, 13);
1795 if (vendor) {
1796 pakfire_package_set_vendor(pkg, vendor);
1797 }
1798
1799 // Build Host
1800 const char* build_host = (const char*)sqlite3_column_text(stmt, 14);
1801 if (build_host) {
1802 pakfire_package_set_build_host(pkg, build_host);
1803 }
1804
1805 // Build Time
1806 time_t build_time = sqlite3_column_int64(stmt, 15);
1807 if (build_time) {
1808 pakfire_package_set_build_time(pkg, build_time);
1809 }
1810
1811 // Install Time
1812 time_t install_time = sqlite3_column_int64(stmt, 16);
1813 if (install_time) {
1814 pakfire_package_set_install_time(pkg, install_time);
1815 }
1816
1817 // installed by user?
1818 int userinstalled = sqlite3_column_int(stmt, 17);
1819 if (userinstalled)
1820 pakfire_db_add_userinstalled(db->pakfire, name);
1821
1822 // Files
1823 const char* files = (const char*)sqlite3_column_text(stmt, 18);
1824 if (files) {
1825 r = pakfire_package_set_filelist_from_string(pkg, files);
1826 if (r)
1827 goto ERROR;
1828 }
1829
1830 // Dependencies
1831
1832 const struct dependency {
1833 unsigned int field;
1834 void (*func)(struct pakfire_package* pkg, const char* dep);
1835 } dependencies[] = {
1836 { 19, pakfire_package_add_provides },
1837 { 20, pakfire_package_add_prerequires },
1838 { 21, pakfire_package_add_requires },
1839 { 22, pakfire_package_add_conflicts },
1840 { 23, pakfire_package_add_obsoletes },
1841 { 24, pakfire_package_add_recommends },
1842 { 25, pakfire_package_add_suggests },
1843 { 26, pakfire_package_add_supplements },
1844 { 27, pakfire_package_add_enhances },
1845 { 0, NULL },
1846 };
1847
1848 for (const struct dependency* deps = dependencies; deps->field; deps++) {
1849 const char* relations = (const char*)sqlite3_column_text(stmt, deps->field);
1850 if (relations) {
1851 pakfire_str2deps(db->pakfire, pkg, deps->func, relations);
1852 }
1853 }
1854
1855 // Source package
1856 const char* source_name = (const char*)sqlite3_column_text(stmt, 28);
1857 if (source_name)
1858 pakfire_package_set_source_name(pkg, source_name);
1859
1860 // Source EVR
1861 const char* source_evr = (const char*)sqlite3_column_text(stmt, 29);
1862 if (source_evr)
1863 pakfire_package_set_source_evr(pkg, source_evr);
1864
1865 // Source arch
1866 const char* source_arch = (const char*)sqlite3_column_text(stmt, 30);
1867 if (source_arch)
1868 pakfire_package_set_source_arch(pkg, source_arch);
1869
1870 // Distribution
1871 const char* distribution = (const char*)sqlite3_column_text(stmt, 31);
1872 if (distribution)
1873 pakfire_package_set_distribution(pkg, distribution);
1874
1875 // Success
1876 r = 0;
1877
1878 ERROR:
1879 if (pkg)
1880 pakfire_package_unref(pkg);
1881
1882 return r;
1883 }
1884
1885 int pakfire_db_load(struct pakfire_db* db, struct pakfire_repo* repo) {
1886 sqlite3_stmt* stmt = NULL;
1887 int r = 1;
1888
1889 DEBUG(db->pakfire, "Loading package database...\n");
1890
1891 // Drop contents of the repository
1892 pakfire_repo_clear(repo);
1893
1894 // Save starting time
1895 clock_t t_start = clock();
1896 clock_t t_end;
1897
1898 const char* sql =
1899 "SELECT "
1900 "name, "
1901 "evr, "
1902 "arch, "
1903 "id, "
1904 "groups, "
1905 "filename, "
1906 "size, "
1907 "inst_size, "
1908 "digest, "
1909 "license, "
1910 "summary, "
1911 "description, "
1912 "uuid, "
1913 "vendor, "
1914 "build_host, "
1915 "build_time, "
1916 "strftime('%s', installed) AS installed, "
1917 "userinstalled, "
1918 "("
1919 "SELECT group_concat(path, '\n') FROM files WHERE files.pkg = packages.id"
1920 ") AS files, "
1921 "("
1922 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1923 "WHERE d.pkg = packages.id AND d.type = 'provides'"
1924 ") AS provides, "
1925 "("
1926 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1927 "WHERE d.pkg = packages.id AND d.type = 'prerequires'"
1928 ") AS prerequires, "
1929 "("
1930 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1931 "WHERE d.pkg = packages.id AND d.type = 'requires'"
1932 ") AS requires, "
1933 "("
1934 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1935 "WHERE d.pkg = packages.id AND d.type = 'conflicts'"
1936 ") AS conflicts, "
1937 "("
1938 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1939 "WHERE d.pkg = packages.id AND d.type = 'obsoletes'"
1940 ") AS obsoletes, "
1941 "("
1942 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1943 "WHERE d.pkg = packages.id AND d.type = 'recommends'"
1944 ") AS recommends, "
1945 "("
1946 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1947 "WHERE d.pkg = packages.id AND d.type = 'suggests'"
1948 ") AS suggests, "
1949 "("
1950 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1951 "WHERE d.pkg = packages.id AND d.type = 'supplements'"
1952 ") AS supplements, "
1953 "("
1954 "SELECT group_concat(dependency, '\n') FROM dependencies d "
1955 "WHERE d.pkg = packages.id AND d.type = 'enhances'"
1956 ") AS enhances, "
1957 "source_name, "
1958 "source_evr, "
1959 "source_arch, "
1960 "distribution "
1961 "FROM "
1962 "packages"
1963 ";";
1964
1965 // Prepare the statement
1966 r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
1967 if (r) {
1968 ERROR(db->pakfire, "Could not prepare SQL statement: %s %s\n",
1969 sql, sqlite3_errmsg(db->handle));
1970 goto ERROR;
1971 }
1972
1973 for (;;) {
1974 // Execute query
1975 r = sqlite3_step(stmt);
1976
1977 switch (r) {
1978 // Retry if the database was busy
1979 case SQLITE_BUSY:
1980 continue;
1981
1982 // Read a row
1983 case SQLITE_ROW:
1984 r = pakfire_db_load_package(db, repo, stmt);
1985 if (r)
1986 goto ERROR;
1987 break;
1988
1989 // All rows have been processed
1990 case SQLITE_DONE:
1991 goto END;
1992
1993 // Go to error in any other cases
1994 default:
1995 goto ERROR;
1996 }
1997 }
1998
1999 END:
2000 // Save time when we finished
2001 t_end = clock();
2002
2003 DEBUG(db->pakfire, "Loading package database completed in %.4fms\n",
2004 (double)(t_end - t_start) * 1000 / CLOCKS_PER_SEC);
2005
2006 // Mark repository as changed
2007 pakfire_repo_has_changed(repo);
2008
2009 // All done
2010 r = 0;
2011
2012 ERROR:
2013 if (r) {
2014 ERROR(db->pakfire, "Failed reading package database: %d\n", r);
2015 pakfire_repo_clear(repo);
2016 }
2017
2018 if (stmt)
2019 sqlite3_finalize(stmt);
2020
2021 return r;
2022 }
2023
2024 static int pakfire_db_load_file_digest(struct pakfire_db* db, struct pakfire_file* file,
2025 sqlite3_stmt* stmt, const enum pakfire_digests type, const int field) {
2026 // Fetch digest
2027 const unsigned char* digest = sqlite3_column_blob(stmt, field);
2028
2029 // Nothing further to do if field is NULL
2030 if (!digest)
2031 return 0;
2032
2033 // Length of the stored value
2034 const size_t length = sqlite3_column_bytes(stmt, field);
2035
2036 // Check if the digest has the correct length
2037 if (pakfire_digest_length(type) != length) {
2038 const char* path = pakfire_file_get_path(file);
2039
2040 ERROR(db->pakfire, "%s: Digest has an incorrect size of %zu byte(s)\n",
2041 path, length);
2042 return 1;
2043 }
2044
2045 // Store digest
2046 return pakfire_file_set_digest(file, type, digest);
2047 }
2048
2049 static int pakfire_db_load_file(struct pakfire_db* db, struct pakfire_filelist* filelist,
2050 sqlite3_stmt* stmt) {
2051 struct pakfire_file* file = NULL;
2052 int r;
2053
2054 // Create a new file object
2055 r = pakfire_file_create(&file, db->pakfire);
2056 if (r)
2057 goto ERROR;
2058
2059 // Path
2060 const char* path = (const char*)sqlite3_column_text(stmt, 0);
2061
2062 // Abort if no path is set
2063 if (!path) {
2064 ERROR(db->pakfire, "File has no path\n");
2065 r = 1;
2066 goto ERROR;
2067 }
2068
2069 // Set path
2070 r = pakfire_file_set_path(file, path);
2071 if (r) {
2072 ERROR(db->pakfire, "%s: Could not set path '%s': %m\n", path, path);
2073 goto ERROR;
2074 }
2075
2076 // Size
2077 size_t size = sqlite3_column_int64(stmt, 1);
2078 if (size)
2079 pakfire_file_set_size(file, size);
2080
2081 // Mode
2082 mode_t mode = sqlite3_column_int(stmt, 2);
2083 if (mode)
2084 pakfire_file_set_mode(file, mode);
2085
2086 // User
2087 const char* user = (const char*)sqlite3_column_text(stmt, 3);
2088
2089 // Abort if no user is set
2090 if (!user) {
2091 ERROR(db->pakfire, "%s: No user\n", path);
2092 r = 1;
2093 goto ERROR;
2094 }
2095
2096 // Set user
2097 r = pakfire_file_set_user(file, user);
2098 if (r) {
2099 ERROR(db->pakfire, "%s: Could not set user '%s': %m\n", path, user);
2100 goto ERROR;
2101 }
2102
2103 // Group
2104 const char* group = (const char*)sqlite3_column_text(stmt, 4);
2105
2106 // Abort if no group is set
2107 if (!group) {
2108 ERROR(db->pakfire, "%s: No group\n", path);
2109 r = 1;
2110 goto ERROR;
2111 }
2112
2113 // Set group
2114 r = pakfire_file_set_group(file, group);
2115 if (r) {
2116 ERROR(db->pakfire, "%s: Could not set group '%s': %m\n", path, group);
2117 goto ERROR;
2118 }
2119
2120 // ctime
2121 time_t ctime = sqlite3_column_int64(stmt, 5);
2122 if (ctime)
2123 pakfire_file_set_ctime(file, ctime);
2124
2125 // mtime
2126 time_t mtime = sqlite3_column_int64(stmt, 6);
2127 if (mtime)
2128 pakfire_file_set_mtime(file, mtime);
2129
2130 // SHA-512 Digest
2131 r = pakfire_db_load_file_digest(db, file, stmt, PAKFIRE_DIGEST_SHA512, 7);
2132 if (r)
2133 goto ERROR;
2134
2135 // SHA-256 Digest
2136 r = pakfire_db_load_file_digest(db, file, stmt, PAKFIRE_DIGEST_SHA256, 8);
2137 if (r)
2138 goto ERROR;
2139
2140 // Append the file to the filelist
2141 r = pakfire_filelist_append(filelist, file);
2142 if (r)
2143 goto ERROR;
2144
2145 ERROR:
2146 if (file)
2147 pakfire_file_unref(file);
2148
2149 return r;
2150 }
2151
2152 int pakfire_db_filelist(struct pakfire_db* db, struct pakfire_filelist** filelist) {
2153 struct pakfire_filelist* list = NULL;
2154 sqlite3_stmt* stmt = NULL;
2155 int r;
2156
2157 const char* sql =
2158 "SELECT "
2159 "path, "
2160 "size, "
2161 "mode, "
2162 "user, "
2163 "'group', "
2164 "ctime, "
2165 "mtime, "
2166 "digest_sha512, "
2167 "digest_sha256 "
2168 "FROM files "
2169 "ORDER BY path"
2170 ";";
2171
2172 // Prepare the statement
2173 r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
2174 if (r) {
2175 ERROR(db->pakfire, "Could not prepare SQL statement: %s %s\n",
2176 sql, sqlite3_errmsg(db->handle));
2177 goto ERROR;
2178 }
2179
2180 // Create a new filelist
2181 r = pakfire_filelist_create(&list, db->pakfire);
2182 if (r)
2183 goto ERROR;
2184
2185 // Iterate over all rows
2186 for (;;) {
2187 // Execute query
2188 r = sqlite3_step(stmt);
2189
2190 switch (r) {
2191 // Retry if the database was busy
2192 case SQLITE_BUSY:
2193 continue;
2194
2195 // Read a row
2196 case SQLITE_ROW:
2197 r = pakfire_db_load_file(db, list, stmt);
2198 if (r)
2199 goto ERROR;
2200 break;
2201
2202 // All rows have been processed
2203 case SQLITE_DONE:
2204 r = 0;
2205 goto END;
2206
2207 // Go to error in any other cases
2208 default:
2209 goto ERROR;
2210 }
2211 }
2212
2213 END:
2214 // Return the filelist
2215 *filelist = pakfire_filelist_ref(list);
2216
2217 ERROR:
2218 if (r)
2219 ERROR(db->pakfire, "Could not fetch filelist: %m\n");
2220
2221 if (stmt)
2222 sqlite3_finalize(stmt);
2223 if (list)
2224 pakfire_filelist_unref(list);
2225
2226 return r;
2227 }
2228
2229 int pakfire_db_package_filelist(struct pakfire_db* db, struct pakfire_filelist** filelist,
2230 struct pakfire_package* pkg) {
2231 struct pakfire_filelist* fl = NULL;
2232 sqlite3_stmt* stmt = NULL;
2233 int r = 1;
2234
2235 // Fetch the package ID
2236 uint64_t id = pakfire_package_get_dbid(pkg);
2237 if (!id) {
2238 ERROR(db->pakfire, "Package did not have an ID\n");
2239 return 1;
2240 }
2241
2242 // Create a new filelist
2243 r = pakfire_filelist_create(&fl, db->pakfire);
2244 if (r) {
2245 ERROR(db->pakfire, "Could not create filelist: %m\n");
2246 goto ERROR;
2247 }
2248
2249 const char* sql =
2250 "SELECT "
2251 "path, "
2252 "size, "
2253 "mode, "
2254 "user, "
2255 "'group', "
2256 "ctime, "
2257 "mtime, "
2258 "digest_sha512, "
2259 "digest_sha256 "
2260 "FROM files "
2261
2262 // Select all files that belong to this package
2263 "WHERE "
2264 "pkg = ? "
2265
2266 // Filter out any files that are also in a different package (i.e. an update
2267 // that has already been installed and this is the cleanup of the obsolete pkg)
2268 "AND "
2269 "NOT EXISTS ("
2270 "SELECT "
2271 "1 "
2272 "FROM files AS duplicates "
2273 "WHERE "
2274 "files.path = duplicates.path "
2275 "AND "
2276 "files.pkg != duplicates.pkg"
2277 ") "
2278
2279 // Return the longest paths first
2280 "ORDER BY "
2281 "length(path) DESC"
2282 ";";
2283
2284 // Prepare the statement
2285 r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
2286 if (r) {
2287 ERROR(db->pakfire, "Could not prepare SQL statement: %s %s\n",
2288 sql, sqlite3_errmsg(db->handle));
2289 goto ERROR;
2290 }
2291
2292 // Bind package ID
2293 r = sqlite3_bind_int64(stmt, 1, id);
2294 if (r) {
2295 ERROR(db->pakfire, "Could not bind package ID: %s\n", sqlite3_errmsg(db->handle));
2296 goto ERROR;
2297 }
2298
2299 for (;;) {
2300 // Execute query
2301 r = sqlite3_step(stmt);
2302
2303 switch (r) {
2304 // Retry if the database was busy
2305 case SQLITE_BUSY:
2306 continue;
2307
2308 // Read a row
2309 case SQLITE_ROW:
2310 r = pakfire_db_load_file(db, fl, stmt);
2311 if (r)
2312 goto ERROR;
2313 break;
2314
2315 // All rows have been processed
2316 case SQLITE_DONE:
2317 goto END;
2318
2319 // Go to error in any other cases
2320 default:
2321 goto ERROR;
2322 }
2323 }
2324
2325 END:
2326 *filelist = pakfire_filelist_ref(fl);
2327 r = 0;
2328
2329 ERROR:
2330 if (stmt)
2331 sqlite3_finalize(stmt);
2332 if (fl)
2333 pakfire_filelist_unref(fl);
2334
2335 return r;
2336 }