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