/*-
* Copyright (c) 2011-2025 Baptiste Daroussin <bapt@FreeBSD.org>
* Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
* Copyright (c) 2023 Serenity Cyber Security, LLC
* Author: Gleb Popov <arrowd@FreeBSD.org>
*
*/
#ifndef _PKGDB_H
#define _PKGDB_H
#include "pkg.h"
#include <sqlite3.h>
#include "pkg/vec.h"
typedef vec_t(struct pkg_repo *) repos_t;
struct pkgdb {
sqlite3 *sqlite;
bool prstmt_initialized;
repos_t repos;
};
struct pkgdb_sqlite_it {
sqlite3 *sqlite;
sqlite3_stmt *stmt;
short flags;
short finished;
short pkg_type;
};
struct pkg_repo_it;
struct pkgdb_it {
struct pkgdb *db;
vec_t(struct pkg_repo_it *) remote;
size_t remote_pos;
struct pkgdb_sqlite_it *local;
};
#define PKGDB_IT_FLAG_CYCLED (0x1)
#define PKGDB_IT_FLAG_ONCE (0x1 << 1)
#define PKGDB_IT_FLAG_AUTO (0x1 << 2)
/**
* Transaction/savepoint handling.
* @param savepoint -- if NULL or an empty string, use BEGIN, ROLLBACK, COMMIT
* otherwise use SAVEPOINT, ROLLBACK TO, RELEASE.
* @return an error code.
*/
int pkgdb_transaction_begin_sqlite(sqlite3 *sqlite, const char *savepoint);
int pkgdb_transaction_commit_sqlite(sqlite3 *sqlite, const char *savepoint);
int pkgdb_transaction_rollback_sqlite(sqlite3 *sqlite, const char *savepoint);
struct pkgdb_it *pkgdb_it_new_sqlite(struct pkgdb *db, sqlite3_stmt *s,
int type, short flags);
struct pkgdb_it *pkgdb_it_new_repo(struct pkgdb *db);
void pkgdb_it_repo_attach(struct pkgdb_it *it, struct pkg_repo_it *rit);
/**
* Load missing flags for a specific package from pkgdb
*/
int pkgdb_ensure_loaded(struct pkgdb *db, struct pkg *pkg, unsigned flags);
int pkgdb_ensure_loaded_sqlite(sqlite3 *sqlite, struct pkg *pkg, unsigned flags);
void pkgshell_open(const char **r);
/**
* Register a conflicts list in a repo
* @param origin the origin of a package
* @param conflicts a list of conflicts origins
* @param conflicts_num number of conflicts for this package
* @param sqlite database
* @return error code
*/
int pkgdb_repo_register_conflicts(const char *origin, char **conflicts,
int conflicts_num, sqlite3 *sqlite);
/**
* Get query for the specified match type
* @param pattern
* @param match
* @return
*/
const char * pkgdb_get_pattern_query(const char *pattern, match_t match);
/**
* Find provides for a specified require in repos
* @param db
* @param provide
* @param repo
* @return
*/
struct pkgdb_it *pkgdb_repo_shlib_require(struct pkgdb *db,
const char *provide, c_charv_t *repos);
/**
* Find requires for a specified provide in repos
* @param db
* @param require
* @param repo
* @return
*/
struct pkgdb_it *pkgdb_repo_shlib_provide(struct pkgdb *db,
const char *require, c_charv_t *repos);
struct pkgdb_it *pkgdb_repo_provide(struct pkgdb *db, const char *require, c_charv_t *repo);
struct pkgdb_it *pkgdb_repo_require(struct pkgdb *db, const char *provide, c_charv_t *repo);
struct pkgdb_it *pkgdb_repo_which(struct pkgdb *db, const char *path, bool glob, c_charv_t *repos);
/**
* Unregister a package from the database
* @return An error code.
*/
int pkgdb_unregister_pkg(struct pkgdb *pkg, int64_t id);
/**
* Optimize db for using of solver
*/
int pkgdb_begin_solver(struct pkgdb *db);
/**
* Restore normal db operations
* @param db
* @return
*/
int pkgdb_end_solver(struct pkgdb *db);
/**
* Check access mode for the specified file
* @param mode
* @param dbdir
* @param dbname
* @return
*/
int pkgdb_check_access(unsigned mode, const char *dbname);
/*
* SQLite utility functions
*/
void pkgdb_regex(sqlite3_context *ctx, int argc, sqlite3_value **argv);
void pkgdb_regex_delete(void *p);
void pkgdb_now(sqlite3_context *ctx, int argc, __unused sqlite3_value **argv);
int pkgdb_sqlcmd_init(sqlite3 *db, const char **err, const void *noused);
int pkgdb_update_config_file_content(struct pkg *pkg, sqlite3 *s);
void pkgdb_syscall_overload(void);
void pkgdb_nfs_corruption(sqlite3 *s);
bool pkgdb_file_exists(struct pkgdb *db, const char *path);
struct sqlite3_stmt *prepare_sql(sqlite3 *s, const char *sql);
void pkgdb_debug(int level, sqlite3_stmt *stmt);
bool pkgdb_is_provided(struct pkgdb *db, const char *req);
bool pkgdb_is_shlib_provided(struct pkgdb *db, const char *req);
#endif