183 lines
3.8 KiB
C
183 lines
3.8 KiB
C
|
|
#include <fx/io/directory.h>
|
||
|
|
#include <fx/io/path.h>
|
||
|
|
#include <ropkg/package-db.h>
|
||
|
|
#include <ropkg/status.h>
|
||
|
|
#include <sqlite3.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
|
||
|
|
struct ropkg_package_db {
|
||
|
|
sqlite3 *db_connection;
|
||
|
|
};
|
||
|
|
|
||
|
|
static fx_result init_database_schema(sqlite3 *db)
|
||
|
|
{
|
||
|
|
const char *sql = NULL;
|
||
|
|
sqlite3_stmt *stmt = NULL;
|
||
|
|
int err = 0;
|
||
|
|
|
||
|
|
sql = "CREATE TABLE repo ("
|
||
|
|
"name TEXT PRIMARY KEY,"
|
||
|
|
"description TEXT,"
|
||
|
|
"protocol TEXT NOT NULL,"
|
||
|
|
"channel TEXT NOT NULL);";
|
||
|
|
err = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||
|
|
if (err != SQLITE_OK) {
|
||
|
|
return fx_error_with_string(
|
||
|
|
ROPKG_ERROR_VENDOR,
|
||
|
|
ROPKG_ERR_DB_OP_FAILED,
|
||
|
|
sqlite3_errmsg(db));
|
||
|
|
}
|
||
|
|
|
||
|
|
err = sqlite3_step(stmt);
|
||
|
|
if (err != SQLITE_DONE) {
|
||
|
|
return fx_error_with_string(
|
||
|
|
ROPKG_ERROR_VENDOR,
|
||
|
|
ROPKG_ERR_DB_OP_FAILED,
|
||
|
|
sqlite3_errmsg(db));
|
||
|
|
}
|
||
|
|
|
||
|
|
sqlite3_finalize(stmt);
|
||
|
|
|
||
|
|
sql = "CREATE TABLE repo_component ("
|
||
|
|
"repo_name TEXT NOT NULL,"
|
||
|
|
"channel_name TEXT NOT NULL,"
|
||
|
|
"PRIMARY KEY (repo_name, channel_name));";
|
||
|
|
err = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||
|
|
if (err != SQLITE_OK) {
|
||
|
|
return fx_error_with_string(
|
||
|
|
ROPKG_ERROR_VENDOR,
|
||
|
|
ROPKG_ERR_DB_OP_FAILED,
|
||
|
|
sqlite3_errmsg(db));
|
||
|
|
}
|
||
|
|
|
||
|
|
err = sqlite3_step(stmt);
|
||
|
|
if (err != SQLITE_DONE) {
|
||
|
|
return fx_error_with_string(
|
||
|
|
ROPKG_ERROR_VENDOR,
|
||
|
|
ROPKG_ERR_DB_OP_FAILED,
|
||
|
|
sqlite3_errmsg(db));
|
||
|
|
}
|
||
|
|
|
||
|
|
sqlite3_finalize(stmt);
|
||
|
|
|
||
|
|
sql = "CREATE TABLE package ("
|
||
|
|
"name TEXT NOT NULL,"
|
||
|
|
"arch TEXT NOT NULL,"
|
||
|
|
"version TEXT NOT NULL,"
|
||
|
|
"description TEXT,"
|
||
|
|
"priority TEXT,"
|
||
|
|
"category TEXT,"
|
||
|
|
"maintainer TEXT NOT NULL,"
|
||
|
|
"provides TEXT,"
|
||
|
|
"dependencies TEXT,"
|
||
|
|
"recommends TEXT,"
|
||
|
|
"suggests TEXT,"
|
||
|
|
"conflicts TEXT,"
|
||
|
|
"enhances TEXT,"
|
||
|
|
"repo_name TEXT NOT NULL,"
|
||
|
|
"channel_name TEXT NOT NULL,"
|
||
|
|
"PRIMARY KEY(name, arch, version, repo_name, channel_name));";
|
||
|
|
err = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||
|
|
if (err != SQLITE_OK) {
|
||
|
|
return fx_error_with_string(
|
||
|
|
ROPKG_ERROR_VENDOR,
|
||
|
|
ROPKG_ERR_DB_OP_FAILED,
|
||
|
|
sqlite3_errmsg(db));
|
||
|
|
}
|
||
|
|
|
||
|
|
err = sqlite3_step(stmt);
|
||
|
|
if (err != SQLITE_DONE) {
|
||
|
|
return fx_error_with_string(
|
||
|
|
ROPKG_ERROR_VENDOR,
|
||
|
|
ROPKG_ERR_DB_OP_FAILED,
|
||
|
|
sqlite3_errmsg(db));
|
||
|
|
}
|
||
|
|
|
||
|
|
sqlite3_finalize(stmt);
|
||
|
|
|
||
|
|
return FX_RESULT_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
static fx_result create_database(
|
||
|
|
fx_directory *dir,
|
||
|
|
const char *path,
|
||
|
|
sqlite3 **out)
|
||
|
|
{
|
||
|
|
fx_path *abs_path = fx_path_join_list(
|
||
|
|
2,
|
||
|
|
&FX_VALUE_OBJECT(fx_directory_get_path(dir)),
|
||
|
|
&FX_CSTR(path));
|
||
|
|
if (!abs_path) {
|
||
|
|
return FX_RESULT_ERR(NO_MEMORY);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (fx_path_exists(abs_path)) {
|
||
|
|
if (fx_path_is_directory(abs_path)) {
|
||
|
|
fx_path_unref(abs_path);
|
||
|
|
return FX_RESULT_ERR(IS_DIRECTORY);
|
||
|
|
}
|
||
|
|
|
||
|
|
fx_path_unlink(abs_path);
|
||
|
|
}
|
||
|
|
|
||
|
|
sqlite3 *db = NULL;
|
||
|
|
int err = sqlite3_open_v2(
|
||
|
|
fx_path_get_cstr(abs_path),
|
||
|
|
&db,
|
||
|
|
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
|
||
|
|
NULL);
|
||
|
|
fx_path_unref(abs_path);
|
||
|
|
|
||
|
|
if (err != SQLITE_OK) {
|
||
|
|
if (db) {
|
||
|
|
sqlite3_close(db);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* TODO check err */
|
||
|
|
return FX_RESULT_ERR(IO_FAILURE);
|
||
|
|
}
|
||
|
|
|
||
|
|
fx_result result = init_database_schema(db);
|
||
|
|
if (fx_result_is_error(result)) {
|
||
|
|
sqlite3_close(db);
|
||
|
|
return fx_result_propagate(result);
|
||
|
|
}
|
||
|
|
|
||
|
|
*out = db;
|
||
|
|
return FX_RESULT_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
fx_result ropkg_package_db_init(
|
||
|
|
fx_directory *dir,
|
||
|
|
const char *path,
|
||
|
|
struct ropkg_package_db **out)
|
||
|
|
{
|
||
|
|
struct ropkg_package_db *db = malloc(sizeof *db);
|
||
|
|
if (!db) {
|
||
|
|
return FX_RESULT_ERR(NO_MEMORY);
|
||
|
|
}
|
||
|
|
|
||
|
|
memset(db, 0x0, sizeof *db);
|
||
|
|
|
||
|
|
fx_result result = create_database(dir, path, &db->db_connection);
|
||
|
|
if (fx_result_is_error(result)) {
|
||
|
|
free(db);
|
||
|
|
return fx_result_propagate(result);
|
||
|
|
}
|
||
|
|
|
||
|
|
*out = db;
|
||
|
|
return FX_RESULT_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
fx_result ropkg_package_db_open(
|
||
|
|
fx_directory *dir,
|
||
|
|
const char *path,
|
||
|
|
struct ropkg_package_db **out)
|
||
|
|
{
|
||
|
|
return FX_RESULT_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
void ropkg_package_db_close(struct ropkg_package_db *db)
|
||
|
|
{
|
||
|
|
}
|