libmpm

morphux C package management library
Log | Files | Refs | Submodules | README | LICENSE | git clone https://git.ne02ptzero.me/git/libmpm

commit 02aec5a15e25c58819b2785cde9bb4a20f3783d3
parent 41e53fe863420ee11885ae10a673dcfb55b81537
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Tue,  7 Feb 2017 11:40:49 +0100

Merge branch 'unstable'

Diffstat:
Minc/database.h | 9++++++++-
Msrc/category.c | 6+++++-
Msrc/database.c | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/package.c | 7+++++--
Mtests/test_database.c | 34++++++++++++++++++++++++++++++++++
5 files changed, 157 insertions(+), 4 deletions(-)

diff --git a/inc/database.h b/inc/database.h @@ -28,6 +28,7 @@ # define QUERY_GET_PACKAGE_BY_ID(id) "SELECT * FROM " PKG_TABLE " WHERE id = %lld", id # define QUERY_GET_PACKAGE_BY_NAME(name) "SELECT * FROM " PKG_TABLE " WHERE name = \"%s\"", name # define QUERY_GET_FILES_BY_ID(id) "SELECT * FROM " FILE_TABLE " WHERE id = %lld", id +# define QUERY_GET_CATEG_BY_ID(id) "SELECT * FROM" CAT_TABLE " WHERE id = %lld", id # define SQL_CREATE_TABLE "CREATE table " # define SQL_INSERT_TABLE "INSERT INTO " @@ -41,6 +42,10 @@ typedef struct s_database { } database_t; +/* SQL callbacks */ +SQL_CALLBACK_DEF(callback_files); +SQL_CALLBACK_DEF(callback_categ); + database_t *mpm_database_open(u8_t *ret, const char *fn); u8_t mpm_database_close(database_t *ptr); u8_t mpm_database_exec(database_t *ptr, const char *query, @@ -54,8 +59,10 @@ u8_t mpm_database_init(database_t *ptr); u8_t mpm_database_add_pkg(database_t *ptr, package_t *pkg); u8_t mpm_get_file_by_id(database_t *ptr, u64_t id, mlist_t **files); -SQL_CALLBACK_DEF(callback_files); file_t *sql_to_file(file_t *ptr, char *name, char *val); u8_t mpm_database_add_file(database_t *ptr, file_t *file); +category_t *sql_to_category(category_t *ptr, char *name, char *val); +u8_t mpm_get_categ_by_id(database_t *ptr, u64_t id, mlist_t **cat); +u8_t mpm_database_add_categ(database_t *ptr, category_t *cat); #endif /* DATABASE_H */ diff --git a/src/category.c b/src/category.c @@ -26,7 +26,11 @@ int mpm_category_free(void *tmp) { if (ptr) { free(ptr->name); free(ptr->parent_name); - mpm_package_free(ptr->parent); + if (ptr->parent != NULL) { + ptr->parent->categ = NULL; + mpm_package_free(ptr->parent); + free(ptr->parent); + } } return 1; } diff --git a/src/database.c b/src/database.c @@ -417,3 +417,108 @@ u8_t mpm_database_add_file(database_t *ptr, file_t *file) { sqlite3_free(err); return ret; } + +/*! + * \brief Add a category in the database + * \param ptr Opened connection to a database + * \param cat Category to add + */ +u8_t mpm_database_add_categ(database_t *ptr, category_t *cat) { + char *query, *err; + u8_t ret; + + if (ptr == NULL || cat == NULL) + return 1; + + asprintf(&query, SQL_INSERT_TABLE CAT_TABLE \ + "(%s, %s, %s) " \ + "VALUES (\"%s\", \"%lld\", \"%s\");", + CAT_COL_NAME, CAT_COL_PARENT, CAT_COL_PARENT_NAME, + cat->name, cat->parent->id, cat->parent->name + ); + ret = mpm_database_exec(ptr, query, NULL, NULL, &err); + free(query); + assert(ret == 0 && err == NULL); + sqlite3_free(err); + return ret; +} + +/*! + * \brief Get a category by his Id + * \param ptr Opened Database connection + * \param id ID to search for + * \param files Pointer on a list, used to store the results + * \return Error code + * + * This function will search in an already opened database a category with a + * given id. + * A sql QUERY is constructed in this function, with the following content: + * SELECT * FROM categ WHERE id = %d, where %d is the given id + * This function will call list_add to add results to the given list, + * caller should properly free this list. + * + * \note This function will set files to NULL before filling it with the results. + * You should not call this function with an existing files list. + */ +u8_t mpm_get_categ_by_id(database_t *ptr, u64_t id, mlist_t **cat) { + char *query; + u8_t ret; + + if (ptr == NULL) + return 1; + + *cat = NULL; + asprintf(&query, QUERY_GET_CATEG_BY_ID(id)); + ret = sqlite3_exec(ptr->sql, query, &callback_categ, cat, NULL); + free(query); + return ret; +} + +/** + * int name(void *context, int col_num, char **col_txt, char **col_name) + */ +SQL_CALLBACK_DEF(callback_categ) { + mlist_t **head = context; + category_t *ptr; + + ptr = malloc(sizeof(category_t)); + assert(ptr != NULL); + mpm_category_init(ptr); + + for (u8_t i = 0; i < col_num; i++) + ptr = sql_to_category(ptr, col_name[i], col_txt[i]); + + list_add(*(head), ptr, sizeof(category_t)); + free(ptr); + return 0; +} + +/*! + * \brief Fill a category_t structure with a SQL result + * \param ptr Pointer to category_t. Must not be NULL. + * \param name Name of the column + * \param val Value of the column + * + * This function will transform an SQL result, given through an sqlite callback, + * and fill a category_t structure with it. + * All the types conversion needed (string -> *) are done in this function. + * + * \note If a unknown column is passed to this function, a panic will be throwed. + */ +category_t *sql_to_category(category_t *ptr, char *name, char *val) { + if (ptr == NULL) + return ptr; + + if (strcmp(name, CAT_COL_ID) == 0) { + ptr->id = strtoull(val, (char **)NULL, 10); + } else if (strcmp(name, CAT_COL_NAME) == 0) { + ptr->name = strdup(val); + } else if (strcmp(name, CAT_COL_PARENT) == 0) { + ptr->parent = NULL; /* TODO */ + } else if (strcmp(name, CAT_COL_PARENT_NAME) == 0) { + ptr->parent_name = strdup(val); + } else { + m_panic("Unknown column '%s' in get_category\n", name); + } + return ptr; +} diff --git a/src/package.c b/src/package.c @@ -27,8 +27,11 @@ int mpm_package_free(void *tmp) { free(ptr->name); free(ptr->version); free(ptr->desc); - mpm_category_free(ptr->categ); - free(ptr->categ); + if (ptr->categ != NULL) { + ptr->categ->parent = NULL; + mpm_category_free(ptr->categ); + free(ptr->categ); + } /*list_free(ptr->deps, &package_free);*/ /* TODO: Files free */ } diff --git a/tests/test_database.c b/tests/test_database.c @@ -297,6 +297,39 @@ TEST(database_add_file_2) { return TEST_SUCCESS; } +TEST(database_add_category_1) { + category_t *cat = NULL; + package_t *parent; + database_t *ptr = NULL; + u8_t ret = 0; + + ptr = mpm_database_open(&ret, NULL); + TEST_ASSERT((ret == 0), "Can't open the database"); + TEST_ASSERT((ptr != NULL), "Can't open the database"); + + ret = mpm_database_init(ptr); + TEST_ASSERT((ret == 0), "Can't init the database"); + + cat = malloc(sizeof(category_t)); + parent = malloc(sizeof(package_t)); + assert(cat != NULL); + assert(parent != NULL); + + mpm_category_init(cat); + mpm_package_init(parent); + cat->name = strdup("test"); + parent->name = strdup("test_package"); + parent->id = 666; + cat->parent = parent; + parent->categ = cat; + + ret = mpm_database_add_categ(ptr, cat); + TEST_ASSERT((ret == 0), "Cant' add the category"); + mpm_database_close(ptr); + mpm_category_free(cat); + free(cat); + return TEST_SUCCESS; +} TEST(database_get_pkg_by_id_1) { mlist_t *lst; @@ -478,4 +511,5 @@ void register_test_database(void) { reg_test("database", database_get_file_by_id_1); reg_test("database", database_get_file_by_id_2); reg_test("database", database_sql_to_file); + reg_test("database", database_add_category_1); }