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