diff options
| author | Soikk | 2022-08-13 18:49:30 +0200 |
|---|---|---|
| committer | Soikk | 2022-08-13 18:49:30 +0200 |
| commit | 4b721332d570f53719894af922c22b7cba146b18 (patch) | |
| tree | 9c5b8f75345310cd7f2479fca0ebaf20c7ca47dc /src/database.c | |
| parent | 32dd785f881cf3ba6c1c6806cd3af3cbf56437c4 (diff) | |
| download | soikk-DB-4b721332d570f53719894af922c22b7cba146b18.tar.xz soikk-DB-4b721332d570f53719894af922c22b7cba146b18.tar.zst | |
Added primitive repl, delete functions for database and remove tag from file function.
Diffstat (limited to 'src/database.c')
| -rw-r--r-- | src/database.c | 142 |
1 files changed, 100 insertions, 42 deletions
diff --git a/src/database.c b/src/database.c index 461e02d..40ea86d 100644 --- a/src/database.c +++ b/src/database.c @@ -16,6 +16,34 @@ database *newDatabase(char *name){ return db; } +int freeDatabase(database **db){ + deleteLtable(&(*db)->lfiles); + deleteLtable(&(*db)->ltags); + deleteCtable(&(*db)->cfiles); + deleteCtable(&(*db)->ctags); + deleteTree(&(*db)->hfiles); + deleteTree(&(*db)->htags); + deleteMtable(&(*db)->map); + free((*db)->name); + free(*db); + *db = NULL; + return 0; +} + +int deleteDatabase(database **db){ + if(*db == NULL){ + fprintf(stderr, "Error: can't delete NULL database\n"); + return -1; + } + int r = remove((*db)->name); + if(r != 0){ + fprintf(stderr, "Error deleting database '%s'\n", (*db)->name); + return -1; + } + freeDatabase(db); + return 0; +} + uint64_t addFile(database *db, char *file){ uint32_t l; file = normalizeStrLimit(file, &l, MAXPATH-1); @@ -53,47 +81,6 @@ static void decreaseCount(ctable *ct, uint64_t i){ ct->table[i]--; } -static int addRelation(database *db, relation r){ - if(searchMtable(db->map, r) == UINTMAX_MAX){ - insertMtable(db->map, r); - return 0; - } - return -1; -} - -int addFileTag(database *db, char *file, char *tag){ - uint64_t fi = addFile(db, file), ti = addTag(db, tag); - int r = addRelation(db, (relation){.file = fi, .tag = ti}); - if(r == 0){ - increaseCount(db->cfiles, fi); - increaseCount(db->ctags, ti); - return 0; - } - return -1; -} - -int addFileTags(database *db, char *file, int ntags, ...){ - va_list tags; - va_start(tags, ntags); - for(uint64_t i = 0; i < ntags; ++i){ - char *tag = va_arg(tags, char*); - addFileTag(db, file, tag); - } - va_end(tags); - return 0; -} - -int addTagFiles(database *db, char *tag, int nfiles, ...){ - va_list files; - va_start(files, nfiles); - for(uint64_t i = 0; i < nfiles; ++i){ - char *file = va_arg(files, char*); - addFileTag(db, file, tag); - } - va_end(files); - return 0; -} - static void decreaseHigherIndexNode(node *n, uint64_t i){ if(n == NULL){ return; @@ -167,6 +154,69 @@ int removeTag(database *db, char *tag){ return 0; } +static int addRelation(database *db, relation r){ + if(searchMtable(db->map, r) == UINTMAX_MAX){ + insertMtable(db->map, r); + return 0; + } + return -1; +} + +int addFileTag(database *db, char *file, char *tag){ + uint64_t fi = addFile(db, file), ti = addTag(db, tag); + int r = addRelation(db, (relation){.file = fi, .tag = ti}); + if(r == 0){ + increaseCount(db->cfiles, fi); + increaseCount(db->ctags, ti); + return 0; + } + return -1; +} + +int addFileTags(database *db, char *file, int ntags, ...){ + va_list tags; + va_start(tags, ntags); + for(uint64_t i = 0; i < ntags; ++i){ + char *tag = va_arg(tags, char*); + addFileTag(db, file, tag); + } + va_end(tags); + return 0; +} + +int addTagFiles(database *db, char *tag, int nfiles, ...){ + va_list files; + va_start(files, nfiles); + for(uint64_t i = 0; i < nfiles; ++i){ + char *file = va_arg(files, char*); + addFileTag(db, file, tag); + } + va_end(files); + return 0; +} + +int removeFileTag(database *db, char *file, char *tag){ + uint32_t lf, lt; + file = normalizeStrLimit(file, &lf, MAXPATH-1); + tag = normalizeStrLimit(tag, <, MAXPATH-1); + uint64_t hf = crc64(0, file, lf), ht = crc64(0, tag, lt); + uint64_t fi = searchNode(db->hfiles, hf), ti = searchNode(db->htags, ht); + if(fi == UINTMAX_MAX){ + fprintf(stderr, "Error: no such file '%s'\n", file); + return -1; + } + if(ti == UINTMAX_MAX){ + fprintf(stderr, "Error: no such tag '%s'\n", tag); + return -1; + } + int status = removeMtable(db->map, (relation){.file = fi, .tag = ti}); + if(status == -1){ + fprintf(stderr, "Error: tag '%s' not associated with file '%s'\n", tag, file); + return -1; + } + return 0; +} + int searchFile(database *db, char *file, uint64_t n, uint64_t **r, uint64_t *rl){ uint32_t l; file = normalizeStrLimit(file, &l, MAXPATH-1); @@ -244,6 +294,10 @@ int storeDatabase(database *db, const char *path){ database *loadDatabase(const char* path){ FILE *fp = fopen(path, "rb"); + if(fp == NULL){ + fprintf(stderr, "Error: no such file (%s)\n", path); + return NULL; + } char *header = calloc(2, sizeof(char)); fread(header, sizeof(char), 2, fp); if(!sameStr(header, "DB")){ @@ -277,7 +331,7 @@ void printDatabase(database *db){ printf("\n"); } -void debugAVLtree(node *n){ +static void debugAVLtree(node *n){ if(n != NULL){ printf("\t\t+ %" PRIu64 " -> %" PRIu64 "\n", n->h, n->i); debugAVLtree(n->left); @@ -286,6 +340,10 @@ void debugAVLtree(node *n){ } void debugDatabase(database *db){ + if(db == NULL){ + fprintf(stderr, "Error: database is NULL\n"); + return; + } printf("\n"); printf("Name: %s\n", db->name); printf("\t-lfiles: %d\n", db->lfiles->size); |
