aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSoikk2022-08-13 18:49:30 +0200
committerSoikk2022-08-13 18:49:30 +0200
commit4b721332d570f53719894af922c22b7cba146b18 (patch)
tree9c5b8f75345310cd7f2479fca0ebaf20c7ca47dc /src
parent32dd785f881cf3ba6c1c6806cd3af3cbf56437c4 (diff)
downloadsoikk-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')
-rw-r--r--src/database.c142
-rw-r--r--src/main.c46
-rw-r--r--src/parser.c445
-rw-r--r--src/repl.c13
-rw-r--r--src/storage.c32
5 files changed, 590 insertions, 88 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, &lt, 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);
diff --git a/src/main.c b/src/main.c
index b24dcb8..23e1fee 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4,16 +4,17 @@
int main(){
+
inputBuffer *in = newInputBuffer();
- database *db = newDatabase("miDB");
+ /*database *test = newDatabase("miDB");
- addFileTag(db, "vaca.png", "naturalezas");
- addFileTags(db, "terry-davis.jpg", 3, "holyC", "programmer", "very cool");
- addFileTag(db, "vaca.png", "lovely");
- addFileTags(db, "vaca.png", 3, "nature", "animal", "very cool");
- addFileTag(db, "terry-davis.jpg", "based");
+ addFileTag(test, "vaca.png", "naturalezas");
+ addFileTags(test, "terry-davis.jpg", 3, "holyC", "programmer", "very cool");
+ addFileTag(test, "vaca.png", "lovely");
+ addFileTags(test, "vaca.png", 3, "nature", "animal", "very cool");
+ addFileTag(test, "terry-davis.jpg", "based");
- storeDatabase(db, "db.db");
+ storeDatabase(test, "db.db");
printDatabase(db);
@@ -26,29 +27,18 @@ int main(){
for(uint64_t j = 0; j < i; ++j){
printf("\t%s\n", db->ltags->table[l[j]]);
- }
-
-
-
- while(0){
+ }*/
- prompt();
+ database *db = NULL;
+ while(1){
+ prompt(db);
getInput(in);
-
- /*
- insertTag(r, in->buffer);
- printf("Tags of row '%s': %s\n", r->path, r->tags);
- printf("Number of tags: %u. Length of tags: %u\n", r->numTags, r->lenTags);
- */
-
- /*switch(handleInput(in)){
- case META_COMMAND_SUCCESS:
- printf("we done it nigger\n");
- break;
- case META_COMMAND_FAIL:
- printf("uh-oh nigga i dunno what '%s' is!\n", in->buffer);
- break;
- }*/
+ argList *args = splitInput(in);
+ int status = handleInput(args, &db);
+ if(status == EXIT_CODE){
+ printf("Exiting db\n");
+ break;
+ }
}
return 0;
diff --git a/src/parser.c b/src/parser.c
index f26a0cb..0401f43 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1,20 +1,439 @@
#include "db.h"
-int handleMetaCommand(inputBuffer *in){
- if(sameStr(in->buffer, ".exit")){
- freeInputBuffer(in);
- printf("EXIT M'NIGGA\n");
- exit(EXIT_SUCCESS);
- }else{
- return META_COMMAND_FAIL;
+char *keywords[NKEYWORDS] = {"EXIT", "DEBUG",
+ "CREATE", "DELETE", "OPEN", "SAVE", "CLOSE",
+ "ADDF", "ADDT", "DELETEF", "DELETET",
+ "TAG", "REMOVE",
+ "SHOW", "SHOWT", "SHOWF"};
+
+argList *newArgList(void){
+ argList *args = malloc(sizeof(argList));
+ args->argc = 0;
+ args->argv = NULL;
+ return args;
+}
+
+argList *splitInput(inputBuffer *in){
+ if(in->inputSize == 0){
+ return NULL;
+ }
+ argList *args = newArgList();
+ uint64_t len = args->argc = 0;
+
+ // Remove leading spaces
+ while(isspace(in->buffer[len])){
+ ++len;
+ }
+ // Count words (alone or quoted)
+ while(in->buffer[len] != '\0'){
+ while(isspace(in->buffer[len])){
+ ++len;
+ }
+ if(in->buffer[len] == '"'){
+ do{
+ ++len;
+ }while(in->buffer[len] != '"');
+ ++args->argc;
+ }else if(in->buffer[len] == '\''){
+ do{
+ ++len;
+ }while(in->buffer[len] != '\'');
+ ++args->argc;
+ }else{
+ while(in->buffer[len] != '\0' && !isspace(in->buffer[len])){
+ ++len;
+ }
+ ++args->argc;
+ }
+ ++len;
+ }
+ uint64_t *wstarts = malloc(args->argc*sizeof(uint64_t)), *wlens = malloc(args->argc*sizeof(uint64_t));
+ len = args->argc = 0;
+ while(in->buffer[len] != '\0'){
+ while(isspace(in->buffer[len])){
+ ++len;
+ }
+ if(in->buffer[len] == '"'){
+ wstarts[args->argc] = len+1;
+ do{
+ ++len;
+ }while(in->buffer[len] != '"');
+ wlens[args->argc] = len - wstarts[args->argc];
+ ++args->argc;
+ }else if(in->buffer[len] == '\''){
+ wstarts[args->argc] = len+1;
+ do{
+ ++len;
+ }while(in->buffer[len] != '\'');
+ wlens[args->argc] = len -wstarts[args->argc];
+ ++args->argc;
+ }else{
+ wstarts[args->argc] = len;
+ while(in->buffer[len] != '\0' && !isspace(in->buffer[len])){
+ ++len;
+ }
+ wlens[args->argc] = len - wstarts[args->argc];
+ ++args->argc;
+ }
+ ++len;
+ }
+
+ args->argv = malloc(args->argc*sizeof(char*));
+ for(uint64_t i = 0; i < args->argc; ++i){
+ args->argv[i] = calloc(wlens[i]+1, sizeof(char));
+ memcpy(args->argv[i], &in->buffer[wstarts[i]], wlens[i]);
+ }
+ return args;
+}
+
+static int commandExit(argList *args, database **db){
+ // TODO: cleanup functions
+ return EXIT_CODE;
+}
+
+static int commandDebug(argList *args, database **db){
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to debug\n");
+ return -1;
+ }
+ debugDatabase(*db);
+ return 0;
+}
+
+static int commandCreate(argList *args, database **db){
+ if(args->argc < 2){
+ fprintf(stderr, "Error, not enough arguments for command '%s'\n", args->argv[0]);
+ return -1;
+ }
+ for(int i = 1; i < args->argc; ++i){
+ int status = storeDatabase(newDatabase(args->argv[i]), args->argv[i]);
+ if(status != 0){
+ fprintf(stderr, "Error creating and storing database '%s'\n", args->argv[i]);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int commandDelete(argList *args, database **db){
+ if(args->argc < 2){
+ fprintf(stderr, "Error, not enough arguments for command '%s'\n", args->argv[0]);
+ return -1;
+ }
+ for(int i = 1; i < args->argc; ++i){
+ database *t = loadDatabase(args->argv[i]);
+ int status = deleteDatabase(&t);
+ if(status != 0){
+ fprintf(stderr, "Error deleting database '%s'\n", args->argv[i]);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int commandOpen(argList *args, database **db){
+ if(args->argc < 2){
+ fprintf(stderr, "Error: not enough arguments for command '%s'\n", args->argv[0]);
+ return -1;
+ }else if(args->argc > 2){
+ fprintf(stderr, "Error: too many arguments for command 'OPEN'. Only opening first one ('%s')\n", args->argv[1]);
+ }
+ if(*db != NULL){
+ fprintf(stderr, "Error: database '%s' already opened. Close it before proceeding with \"CLOSE '%s'\"\n", (*db)->name, (*db)->name);
+ return -1;
}
+ *db = loadDatabase(args->argv[1]);
+ if(*db == NULL){
+ fprintf(stderr, "Error loading database '%s'\n", args->argv[1]);
+ return -1;
+ }
+ return 0;
}
-int handleInput(inputBuffer *in){
- if(in->buffer[0] == '.'){
- return handleMetaCommand(in);
- }else{
- printf("normal command\n");
+static int commandSave(argList *args, database **db){
+ if(args->argc > 1){
+ fprintf(stderr, "Error: too many arguments for function 'SAVE'. Only saving loaded database ('%s')\n", (*db)->name);
+ }
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to save\n");
+ return -1;
+ }
+ int status = storeDatabase(*db, (*db)->name);
+ if(status != 0){
+ fprintf(stderr, "Error storing database '%s'\n", (*db)->name);
+ return -1;
+ }
+ return 0;
+}
+
+static int commandClose(argList *args, database **db){
+ if(args->argc > 1){
+ fprintf(stderr, "Error: too many arguments for function 'CLOSE'. Only closing loaded database ('%s')\n", (*db)->name);
+ }
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to close\n");
+ return -1;
+ }
+ int status = storeDatabase(*db, (*db)->name);
+ if(status != 0){
+ fprintf(stderr, "Error storing database '%s' before closing it\n", (*db)->name);
+ return -1;
+ }
+ freeDatabase(db);
+ return 0;
+}
+
+static int commandAddf(argList *args, database **db){
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to add files to\n");
+ return -1;
+ }
+ char **files = malloc((args->argc-1)*sizeof(char*));
+ uint64_t fi = 0;
+ for(uint64_t i = 1; i < args->argc; ++i){
+ files[fi++] = args->argv[i];
+ }
+ if(fi == 0){
+ fprintf(stderr, "Error: no files given to add to database\n");
+ return -1;
+ }
+ for(uint64_t i = 0; i < fi; ++i){
+ addFile(*db, files[i]);
+ }
+ return 0;
+}
+
+static int commandAddt(argList *args, database **db){
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to add tags to\n");
+ return -1;
+ }
+ char **tags = malloc((args->argc-1)*sizeof(char*));
+ uint64_t ti = 0;
+ for(uint64_t i = 1; i < args->argc; ++i){
+ tags[ti++] = args->argv[i];
+ }
+ if(ti == 0){
+ fprintf(stderr, "Error: no tags given to add to database\n");
+ return -1;
+ }
+ for(uint64_t i = 0; i < ti; ++i){
+ addTag(*db, tags[i]);
+ }
+ return 0;
+}
+
+static int commandDeletef(argList *args, database **db){
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to delete files from\n");
+ return -1;
+ }
+ char **files = malloc((args->argc-1)*sizeof(char*));
+ uint64_t fi = 0;
+ for(uint64_t i = 1; i < args->argc; ++i){
+ files[fi++] = args->argv[i];
+ }
+ if(fi == 0){
+ fprintf(stderr, "Error: no files given to remove from database\n");
+ return -1;
}
-} \ No newline at end of file
+ for(uint64_t i = 0; i < fi; ++i){
+ removeFile(*db, files[i]);
+ }
+ return 0;
+}
+
+static int commandDeletet(argList *args, database **db){
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to remove tags from\n");
+ return -1;
+ }
+ char **tags = malloc((args->argc-1)*sizeof(char*));
+ uint64_t ti = 0;
+ for(uint64_t i = 1; i < args->argc; ++i){
+ tags[ti++] = args->argv[i];
+ }
+ if(ti == 0){
+ fprintf(stderr, "Error: no tags given to remove from database\n");
+ return -1;
+ }
+ for(uint64_t i = 0; i < ti; ++i){
+ removeTag(*db, tags[i]);
+ }
+ return 0;
+}
+
+static int commandTag(argList *args, database **db){
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to add files and tags to\n");
+ return -1;
+ }
+ char **files = malloc((args->argc-1)*sizeof(char*));
+ uint64_t i, fi = 0, ti = 0;
+ bool with = false;
+ for(i = 1; i < args->argc; ++i){
+ uint32_t l1, l2;
+ if(sameStr(normalizeStr(args->argv[i], &l1), normalizeStr("WITH", &l2))){
+ with = true;
+ ++i;
+ break;
+ }
+ files[fi++] = args->argv[i];
+ }
+ if(fi == 0){
+ fprintf(stderr, "Error: no files given to tag\n");
+ return -1;
+ }
+ if(with == false){
+ fprintf(stderr, "Error: missing 'WITH' keyword on 'TAG' command\n");
+ return -1;
+ }
+ char **tags = malloc((args->argc-i)*sizeof(char*));
+ for(; i < args->argc; ++i){
+ tags[ti++] = args->argv[i];
+ }
+ if(ti == 0){
+ fprintf(stderr, "Error: no tags given to tag files\n");
+ return -1;
+ }
+
+ for(uint64_t f = 0; f < fi; ++f){
+ for(uint64_t t = 0; t < ti; ++t){
+ int status = addFileTag(*db, files[f], tags[t]);
+ if(status != 0){
+ fprintf(stderr, "Error: couldnt add tag '%s' to file '%s'\n", tags[t], files[f]);
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+static int commandRemove(argList *args, database **db){
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to remove files and tags from\n");
+ return -1;
+ }
+ char **tags = malloc((args->argc-1)*sizeof(char*));
+ uint64_t i, ti = 0, fi = 0;
+ bool from = false;
+ for(i = 1; i < args->argc; ++i){
+ uint32_t l1, l2;
+ if(sameStr(normalizeStr(args->argv[i], &l1), normalizeStr("FROM", &l2))){
+ from = true;
+ ++i;
+ break;
+ }
+ tags[ti++] = args->argv[i];
+ }
+ if(ti == 0){
+ fprintf(stderr, "Error: no tags given to remove\n");
+ return -1;
+ }
+ if(from == false){
+ fprintf(stderr, "Error: missing 'FROM' keyword on 'REMOVE' command\n");
+ return -1;
+ }
+ char **files = malloc((args->argc-i)*sizeof(char*));
+ for(; i < args->argc; ++i){
+ files[fi++] = args->argv[i];
+ }
+ if(fi == 0){
+ fprintf(stderr, "Error: no files given to remove\n");
+ return -1;
+ }
+
+ for(uint64_t f = 0; f < fi; ++f){
+ for(uint64_t t = 0; t < ti; ++t){
+ int status = removeFileTag(*db, files[f], tags[t]);
+ if(status != 0){
+ fprintf(stderr, "Error: couldnt remove tag '%s' from file '%s'\n", tags[t], files[f]);
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+static int commandShow(argList *args, database **db){
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to show\n");
+ return -1;
+ }
+ printDatabase(*db);
+ return 0;
+}
+
+static int commandShowt(argList *args, database **db){
+ // We only show the files of one tag
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to show tags of file\n");
+ return -1;
+ }
+ if(args->argc > 2){
+ fprintf(stderr, "Error: too many arguments for 'SHOWT', current support for only one file. Only showing tags of first file ('%s')\n", args->argv[1]);
+ }
+
+ uint64_t rl, *r;
+ int status = searchFile(*db, args->argv[1], 0, &r, &rl);
+ if(status == -1){
+ fprintf(stderr, "Error searching for file '%s'\n", args->argv[1]);
+ return -1;
+ }
+ printf("Tags of file '%s' (%"PRIu64"):\n", args->argv[1], rl);
+ for(uint64_t i = 0; i < rl; ++i){
+ printf("\t- %s\n", (*db)->ltags->table[r[i]]);
+ }
+ printf("\n");
+}
+
+static int commandShowf(argList *args, database **db){
+ // We only show the tags of one file
+ if(*db == NULL){
+ fprintf(stderr, "Error: no database to show files of tag\n");
+ return -1;
+ }
+ if(args->argc > 2){
+ fprintf(stderr, "Error: too many arguments for 'SHOWF', current support for only one tag. Only showing files of first tag ('%s')\n", args->argv[1]);
+ }
+
+ uint64_t rl, *r;
+ int status = searchTag(*db, args->argv[1], 0, &r, &rl);
+ if(status == -1){
+ fprintf(stderr, "Error searching for tag '%s'\n", args->argv[1]);
+ return -1;
+ }
+ printf("Files of tag '%s' (%"PRIu64"):\n", args->argv[1], rl);
+ for(uint64_t i = 0; i < rl; ++i){
+ printf("\t- %s\n", (*db)->lfiles->table[r[i]]);
+ }
+ printf("\n");
+}
+
+ int (*commands[])(argList*, database**) = {
+ commandExit, commandDebug,
+ commandCreate, commandDelete, commandOpen, commandSave, commandClose,
+ commandAddf, commandAddt, commandDeletef, commandDeletet,
+ commandTag, commandRemove,
+ commandShow, commandShowt, commandShowf
+ };
+
+int handleInput(argList *args, database **db){
+ if(args == NULL){
+ return 0;
+ }
+ int command = -1;
+ for(int i = 0; i < NKEYWORDS; ++i){
+ uint32_t l1, l2;
+ if(sameStr(normalizeStr(args->argv[0], &l1), normalizeStr(keywords[i], &l2))){
+ command = i;
+ break;
+ }
+ }
+ if(command == -1){
+ fprintf(stderr, "Error: command '%s' not found\n", args->argv[0]);
+ return -1;
+ }
+ return commands[command](args, db);
+}
diff --git a/src/repl.c b/src/repl.c
index c63ad44..ed829d1 100644
--- a/src/repl.c
+++ b/src/repl.c
@@ -5,7 +5,6 @@ inputBuffer *newInputBuffer(void){
inputBuffer *in = malloc(sizeof(inputBuffer));
in->buffer = NULL;
in->inputSize = 0;
-
return in;
}
@@ -18,13 +17,17 @@ void getInput(inputBuffer *in){
size_t n;
ssize_t r = getline(&(in->buffer), &n, stdin);
if(r <= 0){
- printf("Error\n");
+ fprintf(stderr, "Error\n");
exit(r);
}
in->inputSize = r-1;
in->buffer[in->inputSize] = 0;
}
-void prompt(void){
- printf("db > ");
-} \ No newline at end of file
+void prompt(database *db){
+ if(db == NULL){
+ printf("db > ");
+ }else{
+ printf("%s > ", db->name);
+ }
+}
diff --git a/src/storage.c b/src/storage.c
index 9afede7..bc5ab6b 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -10,6 +10,13 @@ ltable *newLtable(uint64_t size){
return lt;
}
+int deleteLtable(ltable **lt){
+ free((*lt)->table);
+ free(*lt);
+ *lt = NULL;
+ return 0;
+}
+
int insertLtable(ltable *lt, char *str){
uint32_t ls;
str = normalizeStrLimit(str, &ls, MAXPATH-1);
@@ -105,6 +112,13 @@ ctable *newCtable(uint64_t size){
return ct;
}
+int deleteCtable(ctable **ct){
+ free((*ct)->table);
+ free(*ct);
+ *ct = NULL;
+ return 0;
+}
+
int insertCtable(ctable *ct, uint64_t n){
uint64_t *nct = malloc((ct->size+1)*sizeof(uint64_t));
for(uint64_t i = 0; i < ct->size; ++i){
@@ -184,6 +198,13 @@ mtable *newMtable(uint64_t size){
return mt;
}
+int deleteMtable(mtable **mt){
+ free((*mt)->table);
+ free(*mt);
+ *mt = NULL;
+ return 0;
+}
+
int insertMtable(mtable *mt, relation r){
relation *nmt = malloc((mt->size+1)*sizeof(relation));
for(uint64_t i = 0; i < mt->size; ++i){
@@ -301,6 +322,17 @@ node *newNode(uint64_t h, uint64_t i){
return n;
}
+int deleteTree(tree *root){
+ if(*root == NULL){
+ return -1;
+ }
+ deleteTree(&(*root)->left);
+ deleteTree(&(*root)->right);
+ free(*root);
+ *root = NULL;
+ return 0;
+}
+
static node *rotateNodeRight(node *r){
node *nr = r->left;
node *nc = nr->right;