LCOV - code coverage report
Current view: top level - libpkg - pkgdb_query.c (source / functions) Hit Total Coverage
Test: plop Lines: 173 283 61.1 %
Date: 2024-12-30 07:09:03 Functions: 15 22 68.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 86 210 41.0 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2011-2022 Baptiste Daroussin <bapt@FreeBSD.org>
       3                 :            :  * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
       4                 :            :  * Copyright (c) 2011 Will Andrews <will@FreeBSD.org>
       5                 :            :  * Copyright (c) 2011 Philippe Pepiot <phil@philpep.org>
       6                 :            :  * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
       7                 :            :  * Copyright (c) 2012-2013 Matthew Seaman <matthew@FreeBSD.org>
       8                 :            :  * Copyright (c) 2012 Bryan Drewery <bryan@shatow.net>
       9                 :            :  * Copyright (c) 2013 Gerald Pfeifer <gerald@pfeifer.com>
      10                 :            :  * Copyright (c) 2013-2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
      11                 :            :  * Copyright (c) 2023 Serenity Cyber Security, LLC
      12                 :            :  *                    Author: Gleb Popov <arrowd@FreeBSD.org>
      13                 :            :  * All rights reserved.
      14                 :            :  *
      15                 :            :  * Redistribution and use in source and binary forms, with or without
      16                 :            :  * modification, are permitted provided that the following conditions
      17                 :            :  * are met:
      18                 :            :  * 1. Redistributions of source code must retain the above copyright
      19                 :            :  *    notice, this list of conditions and the following disclaimer
      20                 :            :  *    in this position and unchanged.
      21                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      22                 :            :  *    notice, this list of conditions and the following disclaimer in the
      23                 :            :  *    documentation and/or other materials provided with the distribution.
      24                 :            :  *
      25                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      26                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      27                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      28                 :            :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      29                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      30                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      31                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      32                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      33                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      34                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      35                 :            :  */
      36                 :            : 
      37                 :            : #include "pkgvec.h"
      38                 :            : #ifdef HAVE_CONFIG_H
      39                 :            : #include "pkg_config.h"
      40                 :            : #endif
      41                 :            : 
      42                 :            : #include <assert.h>
      43                 :            : #include <errno.h>
      44                 :            : #include <regex.h>
      45                 :            : #include <grp.h>
      46                 :            : #ifdef HAVE_LIBUTIL_H
      47                 :            : #include <libutil.h>
      48                 :            : #endif
      49                 :            : #include <stdlib.h>
      50                 :            : #include <stdio.h>
      51                 :            : #include <stdbool.h>
      52                 :            : #include <string.h>
      53                 :            : #include <unistd.h>
      54                 :            : #include <signal.h>
      55                 :            : 
      56                 :            : #include <sqlite3.h>
      57                 :            : 
      58                 :            : #include "pkg.h"
      59                 :            : #include "private/event.h"
      60                 :            : #include "private/pkg.h"
      61                 :            : #include "private/pkgdb.h"
      62                 :            : #include "private/utils.h"
      63                 :            : 
      64                 :            : const char *
      65                 :       1669 : pkgdb_get_pattern_query(const char *pattern, match_t match)
      66                 :            : {
      67                 :       1669 :         char            *checkorigin = NULL;
      68                 :       1669 :         char            *checkflavor = NULL;
      69                 :       1669 :         const char      *comp = NULL;
      70                 :            : 
      71         [ +  + ]:       1669 :         if (pattern != NULL) {
      72                 :       1131 :                 checkorigin = strchr(pattern, '/');
      73         [ +  + ]:       1131 :                 if (checkorigin != NULL)
      74                 :          1 :                         checkflavor = strchr(checkorigin, '@');
      75                 :       1131 :         }
      76                 :            : 
      77   [ +  +  -  +  :       1669 :         switch (match) {
                   +  + ]
      78                 :            :         case MATCH_ALL:
      79                 :        538 :                 comp = "";
      80                 :        538 :                 break;
      81                 :            :         case MATCH_INTERNAL:
      82                 :        982 :                 comp = " WHERE p.name = ?1";
      83                 :        982 :                 break;
      84                 :            :         case MATCH_EXACT:
      85         [ -  + ]:        126 :                 if (pkgdb_case_sensitive()) {
      86         [ #  # ]:          0 :                         if (checkorigin == NULL)
      87                 :          0 :                                 comp = " WHERE (p.name = ?1 OR p.name || '-' || version = ?1)";
      88         [ #  # ]:          0 :                         else if (checkflavor == NULL)
      89                 :          0 :                                 comp = " WHERE (origin = ?1 OR categories.name || substr(origin, instr(origin, '/')) = ?1)";
      90                 :            :                         else
      91                 :          0 :                                 comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor = ?1)";
      92                 :          0 :                 } else {
      93         [ +  + ]:        126 :                         if (checkorigin == NULL)
      94                 :        125 :                                 comp = " WHERE (p.name = ?1 COLLATE NOCASE OR "
      95                 :            :                                 "p.name || '-' || version = ?1 COLLATE NOCASE)";
      96         [ +  - ]:          1 :                         else if (checkflavor == NULL)
      97                 :          1 :                                 comp = " WHERE (origin = ?1 COLLATE NOCASE OR categories.name || substr(origin, instr(origin, '/'))  = ?1 COLLATE NOCASE)";
      98                 :            :                         else
      99                 :          0 :                                 comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor = ?1 COLLATE NOCASE)";
     100                 :            :                 }
     101                 :        126 :                 break;
     102                 :            :         case MATCH_GLOB:
     103         [ -  + ]:         18 :                 if (pkgdb_case_sensitive()) {
     104         [ #  # ]:          0 :                         if (checkorigin == NULL)
     105                 :          0 :                                 comp = " WHERE (p.name GLOB ?1 "
     106                 :            :                                         "OR p.name || '-' || version GLOB ?1)";
     107         [ #  # ]:          0 :                         else if (checkflavor == NULL)
     108                 :          0 :                                 comp = " WHERE (origin GLOB ?1 OR categories.name || substr(origin, instr(origin, '/')) GLOB ?1)";
     109                 :            :                         else
     110                 :          0 :                                 comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor GLOB ?1)";
     111                 :          0 :                 } else  {
     112         [ -  + ]:         18 :                         if (checkorigin == NULL)
     113                 :         18 :                                 comp = " WHERE (lower(p.name) GLOB lower(?1)  "
     114                 :            :                                         "OR lower(p.name || '-' || version) GLOB lower(?1) )";
     115         [ #  # ]:          0 :                         else if (checkflavor == NULL)
     116                 :          0 :                                 comp = " WHERE (lower(origin) GLOB lower(?1) OR lower(categories.name || substr(origin, instr(origin, '/'))) GLOB lower(?1))";
     117                 :            :                         else
     118                 :          0 :                                 comp = "WHERE (lower(categories.name || substr(origin, instr(origin, '/')) || '@' || flavor) GLOB lower(?1))";
     119                 :            :                 }
     120                 :         18 :                 break;
     121                 :            :         case MATCH_REGEX:
     122         [ -  + ]:          5 :                 if (checkorigin == NULL)
     123                 :          5 :                         comp = " WHERE (p.name REGEXP ?1 "
     124                 :            :                             "OR p.name || '-' || version REGEXP ?1)";
     125         [ #  # ]:          0 :                 else if (checkflavor == NULL)
     126                 :          0 :                         comp = " WHERE (origin REGEXP ?1 OR categories.name || substr(origin, instr(origin, '/')) REGEXP ?1)";
     127                 :            :                 else
     128                 :          0 :                         comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor REGEXP ?1)";
     129                 :          5 :                 break;
     130                 :            :         }
     131                 :            : 
     132                 :       1669 :         return (comp);
     133                 :            : }
     134                 :            : 
     135                 :            : struct pkgdb_it *
     136                 :       1082 : pkgdb_query_cond(struct pkgdb *db, const char *cond, const char *pattern, match_t match)
     137                 :            : {
     138                 :            :         char             sql[BUFSIZ];
     139                 :            :         sqlite3_stmt    *stmt;
     140                 :       1082 :         const char      *comp = NULL;
     141                 :            : 
     142         [ +  - ]:       1082 :         assert(db != NULL);
     143                 :            : 
     144   [ +  +  +  -  :       1082 :         if (match != MATCH_ALL && (pattern == NULL || pattern[0] == '\0'))
                   -  + ]
     145                 :          0 :                 return (NULL);
     146                 :            : 
     147                 :       1082 :         comp = pkgdb_get_pattern_query(pattern, match);
     148                 :            : 
     149         [ +  + ]:       1082 :         if (cond) {
     150                 :        494 :                 sqlite3_snprintf(sizeof(sql), sql,
     151                 :            :                                 "WITH flavors AS "
     152                 :            :                                 "  (SELECT package_id, value.annotation AS flavor FROM pkg_annotation "
     153                 :            :                                 "   LEFT JOIN annotation tag ON pkg_annotation.tag_id = tag.annotation_id "
     154                 :            :                                 "   LEFT JOIN annotation value ON pkg_annotation.value_id = value.annotation_id "
     155                 :            :                                 "   WHERE tag.annotation = 'flavor') "
     156                 :            :                                 "SELECT DISTINCT(p.id), origin, p.name, p.name as uniqueid, "
     157                 :            :                                 "   version, comment, desc, "
     158                 :            :                                 "   message, arch, maintainer, www, "
     159                 :            :                                 "   prefix, flatsize, licenselogic, automatic, "
     160                 :            :                                 "   locked, time, manifestdigest, vital "
     161                 :            :                                 "   FROM packages AS p "
     162                 :            :                                 "   LEFT JOIN pkg_categories ON p.id = pkg_categories.package_id "
     163                 :            :                                 "   LEFT JOIN categories ON categories.id = pkg_categories.category_id "
     164                 :            :                                 "   LEFT JOIN flavors ON flavors.package_id = p.id "
     165                 :            :                                 "    %s %s (%s) ORDER BY p.name;",
     166                 :        247 :                                         comp, pattern == NULL ? "WHERE" : "AND", cond + 7);
     167         [ +  + ]:       1082 :         } else if (match == MATCH_INTERNAL) {
     168                 :       1398 :                 sqlite3_snprintf(sizeof(sql), sql,
     169                 :            :                                 "SELECT DISTINCT(p.id), origin, p.name, p.name as uniqueid, "
     170                 :            :                                         "version, comment, desc, "
     171                 :            :                                         "message, arch, maintainer, www, "
     172                 :            :                                         "prefix, flatsize, licenselogic, automatic, "
     173                 :            :                                         "locked, time, manifestdigest, vital "
     174                 :            :                                 "FROM packages AS p "
     175                 :            :                                 "%s"
     176                 :        699 :                                 " ORDER BY p.name", comp);
     177                 :        699 :         } else {
     178                 :        272 :                 sqlite3_snprintf(sizeof(sql), sql,
     179                 :            :                                 "WITH flavors AS "
     180                 :            :                                 "  (SELECT package_id, value.annotation AS flavor FROM pkg_annotation "
     181                 :            :                                 "   LEFT JOIN annotation tag ON pkg_annotation.tag_id = tag.annotation_id "
     182                 :            :                                 "   LEFT JOIN annotation value ON pkg_annotation.value_id = value.annotation_id "
     183                 :            :                                 "   WHERE tag.annotation = 'flavor') "
     184                 :            :                                 "SELECT DISTINCT(p.id), origin, p.name, p.name as uniqueid, "
     185                 :            :                                         "version, comment, desc, "
     186                 :            :                                         "message, arch, maintainer, www, "
     187                 :            :                                         "prefix, flatsize, licenselogic, automatic, "
     188                 :            :                                         "locked, time, manifestdigest, vital "
     189                 :            :                                 "FROM packages AS p "
     190                 :            :                                 "LEFT JOIN pkg_categories ON p.id = pkg_categories.package_id "
     191                 :            :                                 "LEFT JOIN categories ON categories.id = pkg_categories.category_id "
     192                 :            :                                 "LEFT JOIN flavors ON flavors.package_id = p.id "
     193                 :            :                                 "%s"
     194                 :        136 :                                 " ORDER BY p.name", comp);
     195                 :            :         }
     196                 :            : 
     197         [ -  + ]:       1082 :         if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
     198                 :          0 :                 ERROR_SQLITE(db->sqlite, sql);
     199                 :          0 :                 return (NULL);
     200                 :            :         }
     201                 :            : 
     202         [ +  + ]:       1082 :         if (match != MATCH_ALL)
     203                 :        786 :                 sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_TRANSIENT);
     204                 :       1082 :         pkgdb_debug(4, stmt);
     205                 :            : 
     206                 :       1082 :         return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
     207                 :       1082 : }
     208                 :            : 
     209                 :            : struct pkgdb_it *
     210                 :        819 : pkgdb_query(struct pkgdb *db, const char *pattern, match_t match)
     211                 :            : {
     212                 :        819 :         return pkgdb_query_cond(db, NULL, pattern, match);
     213                 :            : }
     214                 :            : 
     215                 :            : bool
     216                 :        226 : pkgdb_file_exists(struct pkgdb *db, const char *path)
     217                 :            : {
     218                 :            :         sqlite3_stmt    *stmt;
     219                 :            :         char    sql[BUFSIZ];
     220                 :        226 :         bool    ret = false;
     221                 :            : 
     222         [ +  - ]:        226 :         assert(db != NULL);
     223                 :            : 
     224         [ +  - ]:        226 :         if (path == NULL)
     225                 :          0 :                 return (false);
     226                 :            : 
     227                 :        226 :         sqlite3_snprintf(sizeof(sql), sql,
     228                 :            :             "select path from files where path = ?1;");
     229                 :            : 
     230         [ +  - ]:        226 :         if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
     231                 :          0 :                 ERROR_SQLITE(db->sqlite, sql);
     232                 :          0 :         }
     233                 :            : 
     234                 :        226 :         sqlite3_bind_text(stmt, 1, path, -1, SQLITE_TRANSIENT);
     235                 :        226 :         pkgdb_debug(4, stmt);
     236                 :            : 
     237         [ +  + ]:        226 :         if (sqlite3_step(stmt) != SQLITE_DONE) {
     238                 :         16 :                 ret = true;
     239                 :         16 :         }
     240                 :            : 
     241                 :        226 :         sqlite3_finalize(stmt);
     242                 :        226 :         return (ret);
     243                 :        226 : }
     244                 :            : 
     245                 :            : struct pkgdb_it *
     246                 :          5 : pkgdb_query_which(struct pkgdb *db, const char *path, bool glob)
     247                 :            : {
     248                 :            :         sqlite3_stmt    *stmt;
     249                 :            :         char    sql[BUFSIZ];
     250                 :            : 
     251         [ +  - ]:          5 :         assert(db != NULL);
     252                 :            : 
     253         [ +  - ]:          5 :         if (path == NULL)
     254                 :          0 :                 return (NULL);
     255                 :            : 
     256                 :         10 :         sqlite3_snprintf(sizeof(sql), sql,
     257                 :            :                         "SELECT p.id, p.origin, p.name, p.name as uniqueid, "
     258                 :            :                         "p.version, p.comment, p.desc, "
     259                 :            :                         "p.message, p.arch, p.maintainer, p.www, "
     260                 :            :                         "p.prefix, p.flatsize, p.time "
     261                 :            :                         "FROM packages AS p "
     262                 :            :                         "LEFT JOIN files AS f ON p.id = f.package_id "
     263                 :          5 :                         "WHERE f.path %s ?1 GROUP BY p.id;", glob ? "GLOB" : "=");
     264                 :            : 
     265         [ -  + ]:          5 :         if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
     266                 :          0 :                 ERROR_SQLITE(db->sqlite, sql);
     267                 :          0 :                 return (NULL);
     268                 :            :         }
     269                 :            : 
     270                 :          5 :         sqlite3_bind_text(stmt, 1, path, -1, SQLITE_TRANSIENT);
     271                 :          5 :         pkgdb_debug(4, stmt);
     272                 :            : 
     273                 :          5 :         return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
     274                 :          5 : }
     275                 :            : 
     276                 :            : struct pkgdb_it *
     277                 :          0 : pkgdb_query_shlib_require(struct pkgdb *db, const char *shlib)
     278                 :            : {
     279                 :            :         sqlite3_stmt    *stmt;
     280                 :          0 :         const char       sql[] = ""
     281                 :            :                 "SELECT p.id, p.origin, p.name, p.name as uniqueid, "
     282                 :            :                         "p.version, p.comment, p.desc, "
     283                 :            :                         "p.message, p.arch, p.maintainer, p.www, "
     284                 :            :                         "p.prefix, p.flatsize, p.time "
     285                 :            :                         "FROM packages AS p, pkg_shlibs_required AS ps, shlibs AS s "
     286                 :            :                         "WHERE p.id = ps.package_id "
     287                 :            :                                 "AND ps.shlib_id = s.id "
     288                 :            :                                 "AND s.name = ?1;";
     289                 :            : 
     290         [ #  # ]:          0 :         assert(db != NULL);
     291                 :            : 
     292         [ #  # ]:          0 :         if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
     293                 :          0 :                 ERROR_SQLITE(db->sqlite, sql);
     294                 :          0 :                 return (NULL);
     295                 :            :         }
     296                 :            : 
     297                 :          0 :         sqlite3_bind_text(stmt, 1, shlib, -1, SQLITE_TRANSIENT);
     298                 :          0 :         pkgdb_debug(4, stmt);
     299                 :            : 
     300                 :          0 :         return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
     301                 :          0 : }
     302                 :            : 
     303                 :            : struct pkgdb_it *
     304                 :          7 : pkgdb_query_shlib_provide(struct pkgdb *db, const char *shlib)
     305                 :            : {
     306                 :            :         sqlite3_stmt    *stmt;
     307                 :          7 :         const char       sql[] = ""
     308                 :            :                 "SELECT p.id, p.origin, p.name, p.name as uniqueid, "
     309                 :            :                         "p.version, p.comment, p.desc, "
     310                 :            :                         "p.message, p.arch, p.maintainer, p.www, "
     311                 :            :                         "p.prefix, p.flatsize, p.manifestdigest, p.time "
     312                 :            :                         "FROM packages AS p, pkg_shlibs_provided AS ps, shlibs AS s "
     313                 :            :                         "WHERE p.id = ps.package_id "
     314                 :            :                                 "AND ps.shlib_id = s.id "
     315                 :            :                                 "AND s.name = ?1;";
     316                 :            : 
     317         [ +  - ]:          7 :         assert(db != NULL);
     318                 :            : 
     319         [ -  + ]:          7 :         if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
     320                 :          0 :                 ERROR_SQLITE(db->sqlite, sql);
     321                 :          0 :                 return (NULL);
     322                 :            :         }
     323                 :            : 
     324                 :          7 :         sqlite3_bind_text(stmt, 1, shlib, -1, SQLITE_TRANSIENT);
     325                 :          7 :         pkgdb_debug(4, stmt);
     326                 :            : 
     327                 :          7 :         return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
     328                 :          7 : }
     329                 :            : 
     330                 :            : struct pkgdb_it *
     331                 :          2 : pkgdb_query_require(struct pkgdb *db, const char *req)
     332                 :            : {
     333                 :            :         sqlite3_stmt    *stmt;
     334                 :          2 :         const char       sql[] = ""
     335                 :            :                 "SELECT p.id, p.origin, p.name, p.name as uniqueid, "
     336                 :            :                         "p.version, p.comment, p.desc, "
     337                 :            :                         "p.message, p.arch, p.maintainer, p.www, "
     338                 :            :                         "p.prefix, p.flatsize, p.time "
     339                 :            :                         "FROM packages AS p, pkg_requires AS ps, requires AS s "
     340                 :            :                         "WHERE p.id = ps.package_id "
     341                 :            :                                 "AND ps.require_id = s.id "
     342                 :            :                                 "AND s.require = ?1;";
     343                 :            : 
     344         [ +  - ]:          2 :         assert(db != NULL);
     345                 :            : 
     346         [ -  + ]:          2 :         if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
     347                 :          0 :                 ERROR_SQLITE(db->sqlite, sql);
     348                 :          0 :                 return (NULL);
     349                 :            :         }
     350                 :            : 
     351                 :          2 :         sqlite3_bind_text(stmt, 1, req, -1, SQLITE_TRANSIENT);
     352                 :          2 :         pkgdb_debug(4, stmt);
     353                 :            : 
     354                 :          2 :         return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
     355                 :          2 : }
     356                 :            : 
     357                 :            : struct pkgdb_it *
     358                 :          9 : pkgdb_query_provide(struct pkgdb *db, const char *req)
     359                 :            : {
     360                 :            :         sqlite3_stmt    *stmt;
     361                 :          9 :         const char       sql[] = ""
     362                 :            :                 "SELECT p.id, p.origin, p.name, p.name as uniqueid, "
     363                 :            :                         "p.version, p.comment, p.desc, "
     364                 :            :                         "p.message, p.arch, p.maintainer, p.www, "
     365                 :            :                         "p.prefix, p.flatsize, p.time "
     366                 :            :                         "FROM packages AS p, pkg_provides AS ps, provides AS s "
     367                 :            :                         "WHERE p.id = ps.package_id "
     368                 :            :                                 "AND ps.provide_id = s.id "
     369                 :            :                                 "AND s.provide = ?1;";
     370                 :            : 
     371         [ +  - ]:          9 :         assert(db != NULL);
     372                 :            : 
     373         [ -  + ]:          9 :         if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) {
     374                 :          0 :                 ERROR_SQLITE(db->sqlite, sql);
     375                 :          0 :                 return (NULL);
     376                 :            :         }
     377                 :            : 
     378                 :          9 :         sqlite3_bind_text(stmt, 1, req, -1, SQLITE_TRANSIENT);
     379                 :          9 :         pkgdb_debug(4, stmt);
     380                 :            : 
     381                 :          9 :         return (pkgdb_it_new_sqlite(db, stmt, PKG_INSTALLED, PKGDB_IT_FLAG_ONCE));
     382                 :          9 : }
     383                 :            : 
     384                 :            : static bool
     385                 :        372 : consider_this_repo(c_charv_t *repos, const char *name)
     386                 :            : {
     387                 :            :         /* All repositories */
     388         [ +  + ]:        372 :         if (repos == NULL)
     389                 :        332 :                 return (true);
     390                 :            : 
     391         [ +  + ]:         40 :         if (repos->len == 0)
     392                 :         23 :                 return (true);
     393                 :            : 
     394                 :         17 :         return (c_charv_contains(repos, name, true));
     395                 :        372 : }
     396                 :            : 
     397                 :            : struct pkgdb_it *
     398                 :          0 : pkgdb_repo_query_cond(struct pkgdb *db, const char *cond, const char *pattern, match_t match,
     399                 :            :     const char *repo)
     400                 :            : {
     401                 :            :         c_charv_t r;
     402                 :            :         struct pkgdb_it *ret;
     403                 :            : 
     404                 :          0 :         pkgvec_init(&r);
     405                 :            : 
     406         [ #  # ]:          0 :         if (repo != NULL)
     407   [ #  #  #  #  :          0 :                 pkgvec_push(&r, repo);
                   #  # ]
     408                 :            : 
     409                 :          0 :         ret = pkgdb_repo_query_cond2(db, cond, pattern, match, &r);
     410                 :          0 :         pkgvec_free(&r);
     411                 :            : 
     412                 :          0 :         return (ret);
     413                 :            : }
     414                 :            : 
     415                 :            : struct pkgdb_it *
     416                 :        297 : pkgdb_repo_query_cond2(struct pkgdb *db, const char *cond, const char *pattern, match_t match,
     417                 :            :     c_charv_t *repos)
     418                 :            : {
     419                 :            :         struct pkgdb_it *it;
     420                 :            :         struct pkg_repo_it *rit;
     421                 :            : 
     422                 :        297 :         it = pkgdb_it_new_repo(db);
     423         [ +  - ]:        297 :         if (it == NULL)
     424                 :          0 :                 return (NULL);
     425                 :            : 
     426   [ +  +  +  +  :        647 :         tll_foreach(db->repos, cur) {
                   +  + ]
     427         [ -  + ]:        350 :                 if (consider_this_repo(repos, cur->item->name)) {
     428   [ +  +  +  - ]:        350 :                         if (pattern != NULL && *pattern == '@')
     429                 :          0 :                                 rit = cur->item->ops->groupquery(cur->item, pattern + 1, match);
     430                 :            :                         else
     431                 :        350 :                                 rit = cur->item->ops->query(cur->item, cond, pattern, match);
     432         [ -  + ]:        350 :                         if (rit != NULL)
     433                 :        350 :                                 pkgdb_it_repo_attach(it, rit);
     434                 :        350 :                 }
     435                 :        350 :         }
     436                 :            : 
     437                 :        297 :         return (it);
     438                 :        297 : }
     439                 :            : 
     440                 :          0 : struct pkgdb_it *pkgdb_repo_query(struct pkgdb *db, const char *pattern,
     441                 :            :         match_t match, const char *repo)
     442                 :            : {
     443                 :          0 :         return pkgdb_repo_query_cond(db, NULL, pattern, match, repo);
     444                 :            : }
     445                 :            : 
     446                 :        285 : struct pkgdb_it *pkgdb_repo_query2(struct pkgdb *db, const char *pattern,
     447                 :            :         match_t match, c_charv_t *repos)
     448                 :            : {
     449                 :        285 :         return pkgdb_repo_query_cond2(db, NULL, pattern, match, repos);
     450                 :            : }
     451                 :            : 
     452                 :            : struct pkgdb_it *
     453                 :          0 : pkgdb_repo_shlib_require(struct pkgdb *db, const char *require, c_charv_t *repos)
     454                 :            : {
     455                 :            :         struct pkgdb_it *it;
     456                 :            :         struct pkg_repo_it *rit;
     457                 :            : 
     458                 :          0 :         it = pkgdb_it_new_repo(db);
     459         [ #  # ]:          0 :         if (it == NULL)
     460                 :          0 :                 return (NULL);
     461                 :            : 
     462   [ #  #  #  #  :          0 :         tll_foreach(db->repos, cur) {
                   #  # ]
     463         [ #  # ]:          0 :                 if (consider_this_repo(repos, cur->item->name)) {
     464         [ #  # ]:          0 :                         if (cur->item->ops->shlib_required != NULL) {
     465                 :          0 :                                 rit = cur->item->ops->shlib_required(cur->item, require);
     466         [ #  # ]:          0 :                                 if (rit != NULL)
     467                 :          0 :                                         pkgdb_it_repo_attach(it, rit);
     468                 :          0 :                         }
     469                 :          0 :                 }
     470                 :          0 :         }
     471                 :            : 
     472                 :          0 :         return (it);
     473                 :          0 : }
     474                 :            : 
     475                 :            : struct pkgdb_it *
     476                 :          7 : pkgdb_repo_shlib_provide(struct pkgdb *db, const char *require, c_charv_t *repos)
     477                 :            : {
     478                 :            :         struct pkgdb_it *it;
     479                 :            :         struct pkg_repo_it *rit;
     480                 :            : 
     481                 :          7 :         it = pkgdb_it_new_repo(db);
     482         [ +  - ]:          7 :         if (it == NULL)
     483                 :          0 :                 return (NULL);
     484                 :            : 
     485   [ +  +  +  +  :         12 :         tll_foreach(db->repos, cur) {
                   -  + ]
     486         [ -  + ]:          5 :                 if (consider_this_repo(repos, cur->item->name)) {
     487         [ -  + ]:          5 :                         if (cur->item->ops->shlib_required != NULL) {
     488                 :          5 :                                 rit = cur->item->ops->shlib_provided(cur->item, require);
     489         [ -  + ]:          5 :                                 if (rit != NULL)
     490                 :          5 :                                         pkgdb_it_repo_attach(it, rit);
     491                 :          5 :                         }
     492                 :          5 :                 }
     493                 :          5 :         }
     494                 :            : 
     495                 :          7 :         return (it);
     496                 :          7 : }
     497                 :            : 
     498                 :            : struct pkgdb_it *
     499                 :          0 : pkgdb_repo_require(struct pkgdb *db, const char *require, c_charv_t *repo)
     500                 :            : {
     501                 :            :         struct pkgdb_it *it;
     502                 :            :         struct pkg_repo_it *rit;
     503                 :            : 
     504                 :          0 :         it = pkgdb_it_new_repo(db);
     505         [ #  # ]:          0 :         if (it == NULL)
     506                 :          0 :                 return (NULL);
     507                 :            : 
     508   [ #  #  #  #  :          0 :         tll_foreach(db->repos, cur) {
                   #  # ]
     509         [ #  # ]:          0 :                 if (consider_this_repo(repo, cur->item->name)) {
     510         [ #  # ]:          0 :                         if (cur->item->ops->required != NULL) {
     511                 :          0 :                                 rit = cur->item->ops->required(cur->item, require);
     512         [ #  # ]:          0 :                                 if (rit != NULL)
     513                 :          0 :                                         pkgdb_it_repo_attach(it, rit);
     514                 :          0 :                         }
     515                 :          0 :                 }
     516                 :          0 :         }
     517                 :            : 
     518                 :          0 :         return (it);
     519                 :          0 : }
     520                 :            : 
     521                 :            : struct pkgdb_it *
     522                 :          8 : pkgdb_repo_provide(struct pkgdb *db, const char *require, c_charv_t *repo)
     523                 :            : {
     524                 :            :         struct pkgdb_it *it;
     525                 :            :         struct pkg_repo_it *rit;
     526                 :            : 
     527                 :          8 :         it = pkgdb_it_new_repo(db);
     528         [ +  - ]:          8 :         if (it == NULL)
     529                 :          0 :                 return (NULL);
     530                 :            : 
     531   [ +  -  +  +  :         16 :         tll_foreach(db->repos, cur) {
                   -  + ]
     532         [ -  + ]:          8 :                 if (consider_this_repo(repo, cur->item->name)) {
     533         [ -  + ]:          8 :                         if (cur->item->ops->required != NULL) {
     534                 :          8 :                                 rit = cur->item->ops->provided(cur->item, require);
     535         [ -  + ]:          8 :                                 if (rit != NULL)
     536                 :          8 :                                         pkgdb_it_repo_attach(it, rit);
     537                 :          8 :                         }
     538                 :          8 :                 }
     539                 :          8 :         }
     540                 :            : 
     541                 :          8 :         return (it);
     542                 :          8 : }
     543                 :            : 
     544                 :            : struct pkgdb_it *
     545                 :          1 : pkgdb_repo_search(struct pkgdb *db, const char *pattern, match_t match,
     546                 :            :     pkgdb_field field, pkgdb_field sort, const char *repo)
     547                 :            : {
     548                 :            :         c_charv_t r;
     549                 :            :         struct pkgdb_it *ret;
     550                 :            : 
     551                 :          1 :         pkgvec_init(&r);
     552         [ +  - ]:          1 :         if (repo != NULL)
     553   [ #  #  #  #  :          0 :                 pkgvec_push(&r, repo);
                   #  # ]
     554                 :            : 
     555                 :          1 :         ret = pkgdb_repo_search2(db, pattern, match, field, sort, &r);
     556                 :          1 :         pkgvec_free(&r);
     557                 :            : 
     558                 :          1 :         return (ret);
     559                 :            : }
     560                 :            : 
     561                 :            : struct pkgdb_it *
     562                 :          9 : pkgdb_repo_search2(struct pkgdb *db, const char *pattern, match_t match,
     563                 :            :     pkgdb_field field, pkgdb_field sort, c_charv_t *repos)
     564                 :            : {
     565                 :            :         struct pkgdb_it *it;
     566                 :            :         struct pkg_repo_it *rit;
     567                 :            : 
     568                 :          9 :         it = pkgdb_it_new_repo(db);
     569         [ +  - ]:          9 :         if (it == NULL)
     570                 :          0 :                 return (NULL);
     571                 :            : 
     572   [ +  -  +  +  :         18 :         tll_foreach(db->repos, cur) {
                   -  + ]
     573         [ -  + ]:          9 :                 if (consider_this_repo(repos, cur->item->name)) {
     574         [ -  + ]:          9 :                         if (cur->item->ops->search != NULL) {
     575                 :         18 :                                 rit = cur->item->ops->search(cur->item, pattern, match,
     576                 :          9 :                                         field, sort);
     577         [ -  + ]:          9 :                                 if (rit != NULL)
     578                 :          9 :                                         pkgdb_it_repo_attach(it, rit);
     579                 :          9 :                         }
     580         [ -  + ]:          9 :                         if (cur->item->ops->groupsearch != NULL) {
     581                 :          9 :                                 rit = cur->item->ops->groupsearch(cur->item, pattern, match, field);
     582         [ +  - ]:          9 :                                 if (rit != NULL)
     583                 :          0 :                                         pkgdb_it_repo_attach(it, rit);
     584                 :          9 :                         }
     585                 :          9 :                 }
     586                 :          9 :         }
     587                 :            : 
     588                 :          9 :         return (it);
     589                 :          9 : }
     590                 :            : 
     591                 :            : struct pkgdb_it *
     592                 :          0 : pkgdb_all_search(struct pkgdb *db, const char *pattern, match_t match,
     593                 :            :     pkgdb_field field, pkgdb_field sort, const char *repo)
     594                 :            : {
     595                 :            :         c_charv_t r;
     596                 :            :         struct pkgdb_it *ret;
     597                 :            : 
     598                 :          0 :         pkgvec_init(&r);
     599                 :            : 
     600         [ #  # ]:          0 :         if (repo != NULL)
     601   [ #  #  #  #  :          0 :                 pkgvec_push(&r, repo);
                   #  # ]
     602                 :            : 
     603                 :          0 :         ret = pkgdb_all_search2(db, pattern, match, field, sort, &r);
     604                 :            : 
     605                 :          0 :         pkgvec_free(&r);
     606                 :            : 
     607                 :          0 :         return (ret);
     608                 :            : }
     609                 :            : 
     610                 :            : struct pkgdb_it *
     611                 :          0 : pkgdb_all_search2(struct pkgdb *db, const char *pattern, match_t match,
     612                 :            :     pkgdb_field field, pkgdb_field sort, c_charv_t *repos)
     613                 :            : {
     614                 :            :         struct pkgdb_it *it;
     615                 :            :         struct pkg_repo_it *rit;
     616                 :            : 
     617                 :            : 
     618                 :          0 :         it = pkgdb_query(db, pattern, match);
     619                 :            : 
     620   [ #  #  #  #  :          0 :         tll_foreach(db->repos, cur) {
                   #  # ]
     621         [ #  # ]:          0 :                 if (consider_this_repo(repos, cur->item->name)) {
     622         [ #  # ]:          0 :                         if (cur->item->ops->search != NULL) {
     623                 :          0 :                                 rit = cur->item->ops->search(cur->item, pattern, match,
     624                 :          0 :                                         field, sort);
     625         [ #  # ]:          0 :                                 if (rit != NULL)
     626                 :          0 :                                         pkgdb_it_repo_attach(it, rit);
     627                 :          0 :                         }
     628                 :          0 :                 }
     629                 :          0 :         }
     630                 :            : 
     631                 :          0 :         return (it);
     632                 :            : }

Generated by: LCOV version 1.15