libmpm

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

database.c (14676B)


      1 /*********************************** LICENSE **********************************\
      2 *                            Copyright 2017 Morphux                            *
      3 *                                                                              *
      4 *        Licensed under the Apache License, Version 2.0 (the "License");       *
      5 *        you may not use this file except in compliance with the License.      *
      6 *                  You may obtain a copy of the License at                     *
      7 *                                                                              *
      8 *                 http://www.apache.org/licenses/LICENSE-2.0                   *
      9 *                                                                              *
     10 *      Unless required by applicable law or agreed to in writing, software     *
     11 *       distributed under the License is distributed on an "AS IS" BASIS,      *
     12 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
     13 *        See the License for the specific language governing permissions and   *
     14 *                       limitations under the License.                         *
     15 \******************************************************************************/
     16 
     17 #include <database.h>
     18 
     19 SQL_CALLBACK_DEF(callback_files) {
     20     mlist_t     **head = context;
     21     file_t      *ptr;
     22 
     23     ptr = malloc(sizeof(file_t));
     24     assert(ptr != NULL);
     25     /* Init the file structure */
     26     mpm_file_init(ptr);
     27 
     28     /* Iterating over each column */
     29     for (u8_t i = 0; i < col_num; i++)
     30         sql_to_file(ptr, col_name[i], col_txt[i]);
     31 
     32     /* Add the list to the context */
     33     list_add(*(head), ptr, sizeof(file_t));
     34 
     35     free(ptr);
     36     return 0;
     37 }
     38 
     39 SQL_CALLBACK_DEF(callback_package) {
     40     mlist_t             **head = context;
     41     package_t           *ptr;
     42 
     43     ptr = malloc(sizeof(package_t));
     44     assert(ptr != NULL);
     45     /* Init the package structure */
     46     mpm_package_init(ptr);
     47 
     48     /* Iterating over each column */
     49     for (u8_t i = 0; i < col_num; i++)
     50         sql_to_package(ptr, col_name[i], col_txt[i]);
     51 
     52     /* Add the list to the context */
     53     list_add(*(head), ptr, sizeof(package_t));
     54     free(ptr);
     55     return 0;
     56 }
     57 
     58 SQL_CALLBACK_DEF(callback_categ) {
     59     mlist_t     **head = context;
     60     category_t  *ptr;
     61 
     62     ptr = malloc(sizeof(category_t));
     63     assert(ptr != NULL);
     64     /* Init the category structure */
     65     mpm_category_init(ptr);
     66 
     67     /* Iterating over each column */
     68     for (u8_t i = 0; i < col_num; i++)
     69         ptr = sql_to_category(ptr, col_name[i], col_txt[i]);
     70 
     71     /* Add the list to the context */
     72     list_add(*(head), ptr, sizeof(category_t));
     73     free(ptr);
     74     return 0;
     75 }
     76 
     77 
     78 database_t *mpm_database_open(u8_t *ret, const char *fn) {
     79     database_t          *ptr;
     80     u8_t                error = 0;
     81 
     82     *ret = 0;
     83     ptr = malloc(sizeof(database_t));
     84     assert(ptr != NULL);
     85 
     86     /* If the caller gave a filename, try to open with this one */
     87     if (fn != NULL)
     88         error = sqlite3_open(fn, &ptr->sql);
     89     /* Else, open with the default path */
     90     else
     91         error = sqlite3_open(DB_FN, &ptr->sql);
     92 
     93     if (error != 0)
     94         goto error;
     95 
     96     return ptr;
     97 
     98 error:
     99     sqlite3_close(ptr->sql);
    100     free(ptr);
    101     *ret = error;
    102     return NULL;
    103 }
    104 
    105 u8_t mpm_database_close(database_t *ptr) {
    106     u8_t        error = 1;
    107 
    108     if (ptr != NULL)
    109     {
    110         error = sqlite3_close(ptr->sql);
    111         free(ptr);
    112     }
    113     return error;
    114 }
    115 
    116 u8_t mpm_database_exec(database_t *ptr, const char *query, SQL_CALLBACK_PTR(cl),
    117                             void *ct, char **err) {
    118     if (ptr == NULL || query == NULL)
    119     {
    120         set_mpm_error(ERR_BAD_PTR);
    121         return 1;
    122     }
    123 
    124     return sqlite3_exec(ptr->sql, query, cl, ct, err);
    125 }
    126 
    127 
    128 u8_t mpm_get_package_by_id(database_t *ptr, u64_t id, mlist_t **pkg) {
    129     char        *query;
    130     u8_t        ret;
    131 
    132     if (ptr == NULL)
    133     {
    134         set_mpm_error(ERR_BAD_PTR);
    135         return 1;
    136     }
    137 
    138     *pkg = NULL;
    139     /* Contructing the query */
    140     asprintf(&query, QUERY_GET_PACKAGE_BY_ID(id));
    141 
    142     /* Executing the query */
    143     ret = sqlite3_exec(ptr->sql, query, &callback_package, pkg, NULL);
    144 
    145     free(query);
    146     return ret;
    147 }
    148 
    149 u8_t mpm_get_package_by_name(database_t *ptr, const char *name, mlist_t **pkg) {
    150     char        *query;
    151     u8_t        ret;
    152 
    153     if (ptr == NULL)
    154     {
    155         set_mpm_error(ERR_BAD_PTR);
    156         return 1;
    157     }
    158 
    159     *pkg = NULL;
    160     /* Contructing the query */
    161     asprintf(&query, QUERY_GET_PACKAGE_BY_NAME(name));
    162 
    163     /* Executing the query */
    164     ret = sqlite3_exec(ptr->sql, query, &callback_package, pkg, NULL);
    165 
    166     free(query);
    167     return ret;
    168 }
    169 
    170 package_t *sql_to_package(package_t *ptr, char *name, char *val) {
    171     if (ptr == NULL)
    172     {
    173         set_mpm_error(ERR_BAD_PTR);
    174         return ptr;
    175     }
    176 
    177     /* TODO: Get all columns */
    178     if (strcmp(name, PKG_COL_ID) == 0)
    179     {
    180         ptr->id = strtoull(val, (char **)NULL, 10);
    181     }
    182     else if (strcmp(name, PKG_COL_NAME) == 0)
    183     {
    184         /*strcmp(name, PKG_COL_VERSION) == 0 ||*/
    185         /*strcmp(name, PKG_COL_DESC) == 0) {*/
    186         ptr->name = strdup(val);
    187     }
    188     else if (strcmp(name, PKG_COL_STATE) == 0)
    189     {
    190         ptr->state = val[0] - '0';
    191     } /*else {*/
    192     /*m_panic("Unknown column '%s' in get_package\n", name);*/
    193     /*}*/
    194     return ptr;
    195 }
    196 
    197 
    198 u8_t mpm_database_init(database_t *ptr) {
    199     static const char   *query_table[] = {\
    200             /* Package table */
    201         SQL_CREATE_TABLE PKG_TABLE "("                                      \
    202             PKG_COL_ID          SQL_TYPE_INT    SQL_TYPE_PRIMARY_KEY    "," \
    203             PKG_COL_NAME        SQL_TYPE_TEXT   SQL_TYPE_NOT_NULL       "," \
    204             PKG_COL_VERSION     SQL_TYPE_TEXT   SQL_TYPE_NOT_NULL       "," \
    205             PKG_COL_CATEG       SQL_TYPE_TEXT   SQL_TYPE_NOT_NULL       "," \
    206             PKG_COL_DESC        SQL_TYPE_TEXT   SQL_TYPE_NOT_NULL       "," \
    207             PKG_COL_STATE       SQL_TYPE_INT    SQL_TYPE_NOT_NULL       "," \
    208             PKG_COL_DEPS        SQL_TYPE_TEXT                           "," \
    209             PKG_COL_FILES       SQL_TYPE_TEXT   SQL_TYPE_NOT_NULL       "," \
    210             PKG_COL_BINARIES    SQL_TYPE_TEXT                           "," \
    211             PKG_COL_CONFIG      SQL_TYPE_TEXT                           "," \
    212             PKG_COL_DOCS        SQL_TYPE_TEXT                               \
    213         ");",                                                               \
    214             /* Files table */
    215         SQL_CREATE_TABLE FILE_TABLE "("                                     \
    216             FILE_COL_ID         SQL_TYPE_INT    SQL_TYPE_PRIMARY_KEY    "," \
    217             FILE_COL_PATH       SQL_TYPE_TEXT   SQL_TYPE_NOT_NULL       "," \
    218             FILE_COL_TYPE       SQL_TYPE_INT    SQL_TYPE_NOT_NULL       "," \
    219             FILE_COL_PARENT     SQL_TYPE_INT    SQL_TYPE_NOT_NULL       "," \
    220             FILE_COL_PARENT_NAME SQL_TYPE_TEXT  SQL_TYPE_NOT_NULL       "," \
    221             FILE_COL_HASH       SQL_TYPE_TEXT   SQL_TYPE_NOT_NULL           \
    222         ");",                                                               \
    223             /* Category table */
    224         SQL_CREATE_TABLE CAT_TABLE "("                                      \
    225             CAT_COL_ID          SQL_TYPE_INT    SQL_TYPE_PRIMARY_KEY    "," \
    226             CAT_COL_NAME        SQL_TYPE_TEXT   SQL_TYPE_NOT_NULL       "," \
    227             CAT_COL_PARENT      SQL_TYPE_INT    SQL_TYPE_NOT_NULL       "," \
    228             CAT_COL_PARENT_NAME SQL_TYPE_TEXT   SQL_TYPE_NOT_NULL           \
    229          ");"
    230     };
    231     char        *err = NULL;
    232     u8_t        ret = 0;
    233 
    234     if (ptr == NULL)
    235     {
    236         set_mpm_error(ERR_BAD_PTR);
    237         return 1;
    238     }
    239 
    240     for (u8_t i = 0; i < sizeof(query_table) / sizeof(query_table[0]); i++)
    241     {
    242         ret = mpm_database_exec(ptr, query_table[i], NULL, NULL, &err);
    243         if (ret != 0 || err != NULL)
    244             goto error;
    245     }
    246     return 0;
    247 
    248 error:
    249     m_error("An error happened in the database init: %s\n", err);
    250     sqlite3_free(err);
    251     return ret;
    252 }
    253 
    254 
    255 u8_t mpm_database_add_pkg(database_t *ptr, package_t *pkg) {
    256     char        *query, *err;
    257     char        *deps, *files, *binaries, *config, *docs;
    258     u8_t        ret;
    259 
    260     if (pkg == NULL || ptr == NULL)
    261     {
    262         set_mpm_error(ERR_BAD_PTR);
    263         return 1;
    264     }
    265 
    266     deps = NULL;
    267     files = NULL;
    268     binaries = NULL;
    269     config = NULL;
    270     docs = NULL;
    271     /* Construct the query */
    272     asprintf(&query, SQL_INSERT_TABLE PKG_TABLE \
    273             " (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) " \
    274             "VALUES (\"%s\", \"%s\", \"%s\", \"%s\", %d, \"%s\", \"%s\", \"%s\", \"%s\", \"%s\");",
    275             PKG_COL_NAME, PKG_COL_VERSION, PKG_COL_CATEG, PKG_COL_DESC,
    276             PKG_COL_STATE, PKG_COL_DEPS, PKG_COL_FILES, PKG_COL_BINARIES,
    277             PKG_COL_CONFIG, PKG_COL_DOCS,
    278             pkg->name, pkg->version, pkg->categ->name, pkg->desc, 
    279             pkg->state, deps, files, binaries, config, docs);
    280 
    281     /* Execute the query */
    282     ret = mpm_database_exec(ptr, query, NULL, NULL, &err);
    283     free(query);
    284 
    285     sqlite3_free(err);
    286     return ret;
    287 }
    288 
    289 u8_t mpm_get_file_by_id(database_t *ptr, u64_t id, mlist_t **files) {
    290     char        *query;
    291     u8_t        ret;
    292 
    293     if (ptr == NULL)
    294     {
    295         set_mpm_error(ERR_BAD_PTR);
    296         return 1;
    297     }
    298 
    299     *files = NULL;
    300     /* Construct the query */
    301     asprintf(&query, QUERY_GET_FILES_BY_ID(id));
    302 
    303     /* Execute the query */
    304     ret = sqlite3_exec(ptr->sql, query, &callback_files, files, NULL);
    305     free(query);
    306 
    307     return ret;
    308 }
    309 
    310 u8_t mpm_get_file_by_path(database_t *ptr, const char *path, mlist_t **files) {
    311     char    *query;
    312     u8_t    ret;
    313 
    314     if (ptr == NULL || path == NULL)
    315     {
    316         set_mpm_error(ERR_BAD_PTR);
    317         return 1;
    318     }
    319 
    320     *files = NULL;
    321     /* Construct the query */
    322     asprintf(&query, QUERY_GET_FILES_BY_PATH(path));
    323 
    324     /* Execute the query */
    325     ret = sqlite3_exec(ptr->sql, query, &callback_files, files, NULL);
    326     free(query);
    327 
    328     return ret;
    329 }
    330 
    331 u8_t mpm_get_file_by_parent_id(database_t *ptr, u64_t id,
    332                     mlist_t **files) {
    333     char    *query;
    334     u8_t    ret;
    335 
    336     if (ptr == NULL)
    337     {
    338         set_mpm_error(ERR_BAD_PTR);
    339         return 1;
    340     }
    341 
    342     *files = NULL;
    343     /* Construct the query */
    344     asprintf(&query, QUERY_GET_FILES_BY_PARENT_ID(id));
    345 
    346     /* Execute the query */
    347     ret = sqlite3_exec(ptr->sql, query, &callback_files, files, NULL);
    348     free(query);
    349 
    350     return ret;
    351 }
    352 
    353 u8_t mpm_get_file_by_parent_name(database_t *ptr, const char *name, mlist_t **files) {
    354     char    *query;
    355     u8_t    ret;
    356 
    357     if (ptr == NULL || name == NULL)
    358     {
    359         set_mpm_error(ERR_BAD_PTR);
    360         return 1;
    361     }
    362 
    363     *files = NULL;
    364     /* Construct the query */
    365     asprintf(&query, QUERY_GET_FILES_BY_PARENT_NAME(name));
    366 
    367     /* Execute the query */
    368     ret = sqlite3_exec(ptr->sql, query, &callback_files, files, NULL);
    369     free(query);
    370 
    371     return ret;
    372 }
    373 
    374 file_t          *sql_to_file(file_t *ptr, char *name, char *val) {
    375     if (ptr == NULL)
    376     {
    377         set_mpm_error(ERR_BAD_PTR);
    378         return ptr;
    379     }
    380 
    381     if (strcmp(name, FILE_COL_ID) == 0)
    382     {
    383         ptr->id = strtoull(val, (char **)NULL, 10);
    384     }
    385     else if (strcmp(name, FILE_COL_PATH) == 0)
    386     {
    387         ptr->path = strdup(val);
    388     }
    389     else if (strcmp(name, FILE_COL_TYPE) == 0)
    390     {
    391         ptr->type = val[0] - '0';
    392     }
    393     else if (strcmp(name, FILE_COL_PARENT) == 0)
    394     {
    395         ptr->parent = NULL;
    396     }
    397     else if (strcmp(name, FILE_COL_PARENT_NAME) == 0)
    398     {
    399         ptr->parent_name = strdup(val);
    400     }
    401     else if (strcmp(name, FILE_COL_HASH) == 0)
    402     {
    403         ptr->hash = strdup(val);
    404     }
    405     else
    406     {
    407         m_panic("Unknown column '%s' in get_file\n", name);
    408     }
    409     return ptr;
    410 }
    411 
    412 u8_t mpm_database_add_file(database_t *ptr, file_t *file) {
    413     char    *query, *err;
    414     u8_t    ret;
    415 
    416     if (ptr == NULL || file == NULL)
    417     {
    418         set_mpm_error(ERR_BAD_PTR);
    419         return 1;
    420     }
    421 
    422     /* Construct the query */
    423     asprintf(&query, SQL_INSERT_TABLE FILE_TABLE \
    424          " (%s, %s, %s, %s, %s) " \
    425          "VALUES (\"%s\", \"%d\", \"%lld\", \"%s\", \"%s\");",
    426          FILE_COL_PATH, FILE_COL_TYPE, FILE_COL_PARENT, FILE_COL_PARENT_NAME,
    427          FILE_COL_HASH,
    428          file->path, file->type, file->parent->id, file->parent_name,
    429          file->hash);
    430 
    431     /* Execute the query */
    432     ret = mpm_database_exec(ptr, query, NULL, NULL, &err);
    433     free(query);
    434     sqlite3_free(err);
    435 
    436     return ret;
    437 }
    438 
    439 u8_t mpm_database_add_categ(database_t *ptr, category_t *cat) {
    440     char    *query, *err;
    441     u8_t    ret;
    442 
    443     if (ptr == NULL || cat == NULL)
    444     {
    445         set_mpm_error(ERR_BAD_PTR);
    446         return 1;
    447     }
    448 
    449     /* Construct the query */
    450     asprintf(&query, SQL_INSERT_TABLE CAT_TABLE \
    451             "(%s, %s, %s) " \
    452             "VALUES (\"%s\", \"%lld\", \"%s\");",
    453             CAT_COL_NAME, CAT_COL_PARENT, CAT_COL_PARENT_NAME,
    454             cat->name, cat->parent->id, cat->parent->name
    455     );
    456 
    457     /* Execute the query */
    458     ret = mpm_database_exec(ptr, query, NULL, NULL, &err);
    459     free(query);
    460     sqlite3_free(err);
    461 
    462     return ret;
    463 }
    464 
    465 
    466 u8_t mpm_get_categ_by_id(database_t *ptr, u64_t id, mlist_t **cat) {
    467     char    *query;
    468     u8_t    ret;
    469 
    470     if (ptr == NULL)
    471     {
    472         set_mpm_error(ERR_BAD_PTR);
    473         return 1;
    474     }
    475 
    476     *cat = NULL;
    477     /* Construct the query */
    478     asprintf(&query, QUERY_GET_CATEG_BY_ID(id));
    479 
    480     /* Execute the query */
    481     ret = sqlite3_exec(ptr->sql, query, &callback_categ, cat, NULL);
    482     free(query);
    483 
    484     return ret;
    485 }
    486 
    487 
    488 u8_t mpm_get_categ_by_name(database_t *ptr, const char *name, mlist_t **cat) {
    489     char    *query;
    490     u8_t    ret;
    491 
    492     if (ptr == NULL)
    493     {
    494         set_mpm_error(ERR_BAD_PTR);
    495         return 1;
    496     }
    497 
    498     *cat = NULL;
    499     /* Construct the query */
    500     asprintf(&query, QUERY_GET_CATEG_BY_NAME(name));
    501 
    502     /* Execute the query */
    503     ret = sqlite3_exec(ptr->sql, query, &callback_categ, cat, NULL);
    504     free(query);
    505 
    506     return ret;
    507 }
    508 
    509 
    510 category_t *sql_to_category(category_t *ptr, char *name, char *val) {
    511     if (ptr == NULL)
    512     {
    513         set_mpm_error(ERR_BAD_PTR);
    514         return ptr;
    515     }
    516 
    517     if (strcmp(name, CAT_COL_ID) == 0)
    518     {
    519         ptr->id = strtoull(val, (char **)NULL, 10);
    520     }
    521     else if (strcmp(name, CAT_COL_NAME) == 0)
    522     {
    523         ptr->name = strdup(val);
    524     }
    525     else if (strcmp(name, CAT_COL_PARENT) == 0)
    526     {
    527         ptr->parent = NULL; /* TODO */
    528     }
    529     else if (strcmp(name, CAT_COL_PARENT_NAME) == 0)
    530     {
    531         ptr->parent_name = strdup(val);
    532     }
    533     else
    534     {
    535         m_panic("Unknown column '%s' in get_category\n", name);
    536     }
    537     return ptr;
    538 }