From 17a073838daefc218f4cb40f66cc27803b2d5ac4 Mon Sep 17 00:00:00 2001 From: ngn Date: Tue, 2 Jul 2024 06:04:29 +0300 Subject: [PATCH] new: implement and fix few more database functions --- include/database.h | 14 +++--- include/package.h | 3 ++ src/ctx/pakcage.c | 7 +-- src/database/database.c | 3 +- src/database/package.c | 103 +++++++++++++++++++++++++++++++++++----- src/package/data.c | 6 +-- src/package/depend.c | 30 ++++++++++++ src/package/package.c | 7 ++- 8 files changed, 144 insertions(+), 29 deletions(-) diff --git a/include/database.h b/include/database.h index 766d2d4..fea28b2 100644 --- a/include/database.h +++ b/include/database.h @@ -5,6 +5,8 @@ typedef enum lm_query_index { QUERY_CREATE_TABLE = 0, QUERY_INSERT_PACKAGE = 1, + QUERY_SELECT_PACKAGE = 2, + QUERY_DELETE_PACKAGE = 3, } lm_query_index_t; extern char *queries[]; @@ -21,16 +23,16 @@ typedef bool (*lm_database_keeps_eachfunc_t)(lm_pkg_t *pkg, char *path, void *da lm_database_t *lm_database_new(char *path); void lm_database_free(lm_database_t *db); +bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg, char *name); bool lm_database_add(lm_database_t *db, lm_pkg_t *pkg); bool lm_database_del(lm_database_t *db, lm_pkg_t *pkg); -bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg); -bool lm_database_files_del(lm_database_t *db, lm_pkg_t *pkg); +bool lm_database_files_foreach(lm_database_t *db, lm_pkg_t *pkg, lm_database_files_eachfunc_t func); bool lm_database_files_add(lm_database_t *db, lm_pkg_t *pkg, char *path, char *hash); bool lm_database_files_get(lm_database_t *db, lm_pkg_t *pkg, char *path, char *hash); -bool lm_database_files_foreach(lm_database_t *db, lm_pkg_t *pkg, lm_database_files_eachfunc_t func); +bool lm_database_files_del(lm_database_t *db, lm_pkg_t *pkg); -bool lm_database_keeps_del(lm_database_t *db, lm_pkg_t *pkg); -bool lm_database_keeps_add(lm_database_t *db, lm_pkg_t *pkg, char *path); -bool lm_database_keeps_contains(lm_database_t *db, lm_pkg_t *pkg, char *path); bool lm_database_keeps_foreach(lm_database_t *db, lm_pkg_t *pkg, lm_database_keeps_eachfunc_t func); +bool lm_database_keeps_contains(lm_database_t *db, lm_pkg_t *pkg, char *path); +bool lm_database_keeps_add(lm_database_t *db, lm_pkg_t *pkg, char *path); +bool lm_database_keeps_del(lm_database_t *db, lm_pkg_t *pkg); diff --git a/include/package.h b/include/package.h index f296b22..bf2cb5a 100644 --- a/include/package.h +++ b/include/package.h @@ -10,6 +10,7 @@ lm_pkg_t *lm_package_new(); void lm_package_free(lm_pkg_t *pkg); bool lm_package_verify(lm_pkg_t *pkg); +void lm_package_init(lm_pkg_t *pkg); bool lm_package_data_load(lm_pkg_t *pkg, char *file); void lm_package_data_free(lm_pkg_t *pkg); @@ -18,6 +19,8 @@ bool lm_package_depend_add(lm_pkg_t *pkg, char *depend); size_t lm_package_depend_count(lm_pkg_t *pkg); size_t lm_package_depend_strlen(lm_pkg_t *pkg); bool lm_package_depend_tostr(lm_pkg_t *pkg, char *buffer); +bool lm_package_depend_fromstr(lm_pkg_t *pkg, char *buffer); +void lm_package_depend_free(lm_pkg_t *pkg); size_t lm_package_keep_count(lm_pkg_t *pkg); bool lm_package_keep_add(lm_pkg_t *pkg, char *path); diff --git a/src/ctx/pakcage.c b/src/ctx/pakcage.c index 2ffeabf..85ebfae 100644 --- a/src/ctx/pakcage.c +++ b/src/ctx/pakcage.c @@ -46,13 +46,14 @@ bool lm_ctx_package_verify(lm_ctx_t *ctx, char *name, char *version) { bool lm_ctx_package_is_installed(lm_ctx_t *ctx, char *name, char *version) { lm_database_t *db = lm_ctx_database_new(ctx); + lm_pkg_t pkg; + if(NULL == db) return false; - bool ret = false; - ret = lm_database_package_find(db, name, version); - + bool ret = lm_database_find(db, NULL, name, version); lm_database_free(db); + return ret; } diff --git a/src/database/database.c b/src/database/database.c index 081112c..ad81838 100644 --- a/src/database/database.c +++ b/src/database/database.c @@ -15,8 +15,9 @@ char *queries[] = { " version TEXT NOT NULL," \ " size INT NOT NULL," \ " depends TEXT NOT NULL);", - "INSERT INTO packages VALUES (?, ?, ?, ?, ?)", + "SELECT * FROM packages WHERE name = '?'", + "DELETE from packages WHERE name = '?'", }; lm_database_t *lm_database_new(char *path){ diff --git a/src/database/package.c b/src/database/package.c index 8129a41..c35d06d 100644 --- a/src/database/package.c +++ b/src/database/package.c @@ -8,34 +8,34 @@ #include #include -bool lm_database_package_add(lm_database_t *db, lm_pkg_t *pkg){ +bool lm_database_add(lm_database_t *db, lm_pkg_t *pkg){ if(NULL == db || NULL == pkg){ lm_error_set(LM_ERR_ArgNULL); return false; } char depends[lm_package_depend_strlen(pkg)]; - sqlite3_stmt *insert = NULL; + sqlite3_stmt *st = NULL; bool ret = false; - if(sqlite3_prepare(db->sql, queries[QUERY_INSERT_PACKAGE], strlen(queries[QUERY_INSERT_PACKAGE]), &insert, NULL) != SQLITE_OK){ + if(sqlite3_prepare(db->sql, queries[QUERY_INSERT_PACKAGE], strlen(queries[QUERY_INSERT_PACKAGE]), &st, NULL) != SQLITE_OK){ pdebug(__func__, "(%s) failed to prepare statement: %s", db->path, sqlite3_errmsg(db->sql)); lm_error_set(LM_ERR_DbSqlPrepareFail); goto end; } - sqlite3_bind_text(insert, 1, pkg->name, strlen(pkg->name), SQLITE_STATIC); - sqlite3_bind_text(insert, 2, pkg->desc, strlen(pkg->desc), SQLITE_STATIC); - sqlite3_bind_text(insert, 3, pkg->version, strlen(pkg->version), SQLITE_STATIC); - sqlite3_bind_int64(insert, 4, pkg->size); + sqlite3_bind_text(st, 1, pkg->name, strlen(pkg->name), SQLITE_STATIC); + sqlite3_bind_text(st, 2, pkg->desc, strlen(pkg->desc), SQLITE_STATIC); + sqlite3_bind_text(st, 3, pkg->version, strlen(pkg->version), SQLITE_STATIC); + sqlite3_bind_int64(st, 4, pkg->size); if(!lm_package_depend_tostr(pkg, depends)){ pdebug(__func__, "(%s) failed to convert depends to string: %s", db->path, lm_strerror()); goto end; } - sqlite3_bind_text(insert, 5, depends, strlen(depends), SQLITE_STATIC); + sqlite3_bind_text(st, 5, depends, strlen(depends), SQLITE_STATIC); - if(sqlite3_step(insert) != SQLITE_OK){ + if(sqlite3_step(st) != SQLITE_DONE){ pdebug(__func__, "(%s) failed to execute insert statement: %s", db->path, sqlite3_errmsg(db->sql)); lm_error_set(LM_ERR_DbSqlInsertFail); goto end; @@ -43,11 +43,88 @@ bool lm_database_package_add(lm_database_t *db, lm_pkg_t *pkg){ ret = true; end: - if(NULL != insert) - sqlite3_finalize(insert); + if(NULL != st) + sqlite3_finalize(st); return ret; } -bool lm_database_package_find(lm_database_t *db, lm_pkg_t *pkg){ - return true; +bool lm_database_find(lm_database_t *db, lm_pkg_t *pkg, char *name){ + if(NULL == db || NULL == name){ + lm_error_set(LM_ERR_ArgNULL); + return false; + } + + sqlite3_stmt *st; + bool ret = false; + + if(sqlite3_prepare(db->sql, queries[QUERY_SELECT_PACKAGE], strlen(queries[QUERY_SELECT_PACKAGE]), &st, NULL) != SQLITE_OK){ + pdebug(__func__, "(%s) failed to prepare statement: %s", db->path, sqlite3_errmsg(db->sql)); + lm_error_set(LM_ERR_DbSqlPrepareFail); + goto end; + } + + sqlite3_bind_text(st, 1, name, strlen(name), SQLITE_STATIC); + + if(sqlite3_step(st) != SQLITE_ROW){ + pdebug(__func__, "(%s) got no rows for %s", db->path, name); + lm_error_set(LM_ERR_DbSqlNotFound); + goto end; + } + + if(NULL == pkg){ + ret = true; + goto end; + } + + // package pointer should already be free'd + // we are initing it just in case the caller didn't + lm_package_init(pkg); + + pkg->name = strdup((char*)sqlite3_column_text(st, 0)); + pkg->desc = strdup((char*)sqlite3_column_text(st, 1)); + pkg->version = strdup((char*)sqlite3_column_text(st, 2)); + pkg->size = sqlite3_column_int64(st, 3); + + char *depends = (char*)sqlite3_column_text(st, 3); + if(!lm_package_depend_fromstr(pkg, depends)){ + pdebug(__func__, "(%s) failed to load depends for %s (%s): %s", db->path, name, lm_strerror()); + // error is set by the function + goto end; + } + + ret = true; +end: + if(NULL != st) + sqlite3_finalize(st); + return ret; +} + +bool lm_database_del(lm_database_t *db, lm_pkg_t *pkg){ + if(NULL == db || NULL == pkg){ + lm_error_set(LM_ERR_ArgNULL); + return false; + } + + sqlite3_stmt *st; + bool ret = false; + + if(sqlite3_prepare(db->sql, queries[QUERY_DELETE_PACKAGE], strlen(queries[QUERY_DELETE_PACKAGE]), &st, NULL) != SQLITE_OK){ + pdebug(__func__, "(%s) failed to prepare statement: %s", db->path, sqlite3_errmsg(db->sql)); + lm_error_set(LM_ERR_DbSqlPrepareFail); + goto end; + } + + sqlite3_bind_text(st, 1, pkg->name, strlen(pkg->name), SQLITE_STATIC); + + if(sqlite3_step(st) != SQLITE_DONE){ + pdebug(__func__, "(%s) failed to execute delete statement: %s", db->path, sqlite3_errmsg(db->sql)); + lm_error_set(LM_ERR_DbSqlInsertFail); + goto end; + } + + ret = true; +end: + if(NULL != st) + sqlite3_finalize(st); + return ret; } diff --git a/src/package/data.c b/src/package/data.c index c2b3efd..0cfeb54 100644 --- a/src/package/data.c +++ b/src/package/data.c @@ -55,9 +55,5 @@ void lm_package_data_free(lm_pkg_t *pkg){ free(pkg->desc); free(pkg->name); free(pkg->version); - - if(NULL != pkg->depends){ - for(int i = 0; pkg->depends[i] != NULL; i++) - free(pkg->depends[i]); - } + lm_package_depend_free(pkg); } diff --git a/src/package/depend.c b/src/package/depend.c index 688d888..b2b987e 100644 --- a/src/package/depend.c +++ b/src/package/depend.c @@ -43,6 +43,17 @@ bool lm_package_depend_add(lm_pkg_t *pkg, char *depend){ return true; } +void lm_package_depend_free(lm_pkg_t *pkg){ + if(NULL == pkg) + return; + + for(int i = 0; pkg->depends[i] != NULL; i++) + free(pkg->depends[i]); + free(pkg->depends); + + pkg->depends = NULL; +} + size_t lm_package_depend_strlen(lm_pkg_t *pkg){ size_t len = 1; @@ -76,3 +87,22 @@ bool lm_package_depend_tostr(lm_pkg_t *pkg, char *buffer){ return true; } + +bool lm_package_depend_fromstr(lm_pkg_t *pkg, char *buffer){ + if(NULL == pkg){ + lm_error_set(LM_ERR_ArgNULL); + return false; + } + + lm_package_depend_free(pkg); + + if(NULL == buffer) + return true; + + char *save = NULL, *dep = NULL; + while((dep = strtok_r(buffer, ",", &save)) != NULL) + if(!lm_package_depend_add(pkg, dep)) + return false; + + return true; +} diff --git a/src/package/package.c b/src/package/package.c index 6b89375..e08cc6c 100644 --- a/src/package/package.c +++ b/src/package/package.c @@ -8,10 +8,15 @@ lm_pkg_t *lm_package_new(){ lm_pkg_t *pkg = malloc(sizeof(lm_pkg_t)); - bzero(pkg, sizeof(lm_pkg_t)); + lm_package_init(pkg); return pkg; } +void lm_package_init(lm_pkg_t *pkg){ + bzero(pkg, sizeof(lm_pkg_t)); +} + void lm_package_free(lm_pkg_t *pkg){ lm_package_data_free(pkg); + bzero(pkg, sizeof(lm_pkg_t)); }