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