From: Huck Boles Date: Fri, 23 Dec 2022 21:09:56 +0000 (-0600) Subject: working database X-Git-Url: https://git.huck.website/?a=commitdiff_plain;h=79e9b062fdd2c32dddef991d2fd8103df8a4c901;p=odot.git working database --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..583b95b --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +* +!.gitignore +!LICENSE +!README.md +!Makefile +!*.c +!*.h +!*.o +sqlite3.c diff --git a/Makefile b/Makefile index 0340115..ec5faf1 100644 --- a/Makefile +++ b/Makefile @@ -4,31 +4,36 @@ DESTDIR = $(PREFIX)/bin PROG = odot +CC = gcc CFILE = $(PROG).c database.c HEADER = $(PROG).h sqlite3.h OBJECTS = $(PROG).o database.o task.o sqlite3.o -CFLAGS = -Wall -lpthread +LDFLAGS = -L . +LDLIBS = -lpthread +CFLAGS = -Wall -Wextra -O2 +CPPFLAGS = -I . +ALL_CFLAGS = $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LDLIBS) sql: sqlite3.c - gcc sqlite3.c $(CFLAGS) -c + $(CC) sqlite3.c $(CFLAGS) -c header: $(HEADER) - gcc $(HEADER) $(CFLAGS) -c + $(CC) $(HEADER) $(CFLAGS) -c compile: $(CFILE) - gcc $(CFILE) $(CFLAGS) -c + $(CC) $(CFILE) $(CFLAGS) -c link: $(OBJECTS) - gcc $(OBJECTS) $(CFLAGS) -o $(PROG) + $(CC) $(OBJECTS) $(CFLAGS) -o $(PROG) -build: $(CFILE) $(HEADER) sqlite3.c - gcc $(CFILE) $(HEADER) sqlite3.c $(CFLAGS) -o $(PROG) +build: $(CFILE) $(HEADER) sqlite3.o + $(CC) $(CFILE) sqlite3.o $(CFLAGS) -o $(PROG) -install: $(CFILE) $(HEADER) $(SQLFILE) - gcc $(CFILE) $(HEADER) $(SQLFILE) $(CFLAGS) -o $(DESTDIR)/$(PROG) +install: $(CFILE) $(HEADER) sqlite3.o + $(CC) $(CFILE) sqlite3.o $(CFLAGS) -o $(DESTDIR)/$(PROG) debug: $(CFILE) - gcc $(CFILE) sqlite3.o $(CFLAGS) -g -o $(PROG) + $(CC) $(CFILE) sqlite3.o $(CFLAGS) -ggdb3 -Og -o $(PROG) clean: rm *.gch *.o diff --git a/database.c b/database.c index 3e94c78..76ba218 100644 --- a/database.c +++ b/database.c @@ -1,156 +1,65 @@ #include "odot.h" +extern char *group, + *task; + + sqlite3 *accessdb(char *file){ sqlite3 *db; int err = sqlite3_open(file, &db); - if (err) { - fprintf(stderr, "Could not open database: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - exit(1); - } + if (err) sqlerror(db); return db; } -void buildtables(sqlite3 *db){ - char *cmd = malloc(MAXLINE * sizeof(char)); - char **errmsg = 0; - - sprintf(cmd,"CREATE TABLE IF NOT EXISTS Tasks (Task varchar(1000) NOT NULL PRIMARY KEY, Type varchar(100) NOT NULL, Done int NOT NULL DEFAULT 0);"); - int err = sqlite3_exec(db,cmd,NULL,NULL,errmsg); - if (err) { - fprintf(stderr, "Could not create table: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - exit(1); - } - - free(cmd); - return; -} - - -void addtask(sqlite3 *db, struct task task){ - char *cmd = malloc(MAXLINE * sizeof(char)); - char **errmsg = 0; - - sprintf(cmd,"INSERT INTO Tasks VALUES ( '%s', '%s', 0);",task.task,task.group); - int err = sqlite3_exec(db,cmd,NULL,NULL,errmsg); - if (err) { - fprintf(stderr, "Could not add task: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - exit(1); - } - - free(cmd); +void sqlcmd(sqlite3 *db, char *cmd){ + int err = sqlite3_exec(db,cmd,NULL,NULL,NULL); + if (err) sqlerror(db); return; -} - -void removetask(sqlite3 *db, struct task task){ - char *cmd = malloc(MAXLINE * sizeof(char)); - char **errmsg = 0; - sprintf(cmd,"DELETE FROM Tasks WHERE Task = '%s';",task.task); - int err = sqlite3_exec(db,cmd,NULL,NULL,errmsg); - if (err) { - fprintf(stderr, "Could not remove task: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - exit(1); - } - - free(cmd); - return; } -void donetask(sqlite3 *db, struct task task){ - char *cmd = malloc(MAXLINE * sizeof(char)); - char **errmsg = 0; - - sprintf(cmd,"UPDATE Tasks SET Done = 1 WHERE Task = '%s';",task.task); - int err = sqlite3_exec(db,cmd,NULL,NULL,errmsg); - if (err) { - fprintf(stderr, "Could not modify task in db: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - exit(1); - } - - free(cmd); +void sqlprint(sqlite3 *db, char *cmd){ + int err = sqlite3_exec(db,cmd,printcallback,0,NULL); + if (err) sqlerror(db); return; -} -int printcallback(void *unused,int argc, char **argv, char **name){ - printf("\t[%s] - ", (strcmp(argv[0],"1") == 0) ? "X" : " "); - for (int i = 1; i < argc; i++){ - printf("%s\t",argv[i]); - } - printf("\n"); - return 0; } -void print(sqlite3 *db){ - char *cmd = malloc(MAXLINE * sizeof(char)); - char **errmsg = 0; - - sprintf(cmd,"SELECT Done, Type, Task FROM Tasks WHERE Done = 0 ORDER BY Type;"); - printf("TODO:"); - int err = sqlite3_exec(db,cmd,printcallback,0,errmsg); - if (err) { - fprintf(stderr, "Could not access db: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - exit(1); - } - - free(cmd); +void sqlgroup(sqlite3 *db, char *cmd){ + int err = sqlite3_exec(db,cmd,groupcallback,0,NULL); + if (err) sqlerror(db); return; + } -void printdone(sqlite3 *db){ - char *cmd = malloc(MAXLINE * sizeof(char)); - char **errmsg = 0; - - sprintf(cmd,"SELECT Done, Type, Task FROM Tasks ORDER BY Type;"); - printf("TODO:"); - int err = sqlite3_exec(db,cmd,printcallback,0,errmsg); - if (err) { - fprintf(stderr, "Could not access db: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - exit(1); - } - free(cmd); - return; +void sqlerror(sqlite3 *db) { + fprintf(stderr, "%s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + error(1); } -void printgroup(sqlite3 *db, struct task t){ - char *cmd = malloc(MAXLINE * sizeof(char)); - char **errmsg = 0; - - sprintf(cmd,"SELECT Done, Type, Task FROM Tasks WHERE (Type = '%s' AND Done = 0) OR Task = '%s' ORDER BY Type;",t.group,t.task); - printf("TODO:"); - int err = sqlite3_exec(db,cmd,printcallback,0,errmsg); - if (err) { - fprintf(stderr, "Could not access db: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - exit(1); +int printcallback(void *unused,int argc, char **argv, char **name){ + int i = 1; + + if (argv[2]){ + char *g = malloc(strlen(argv[1])*sizeof(char)); + sprintf(g,"%s",argv[1]); + if (strcmp(g,group) != 0) { + sprintf(group,"%s",argv[1]); + printf("\n\t\033[34m%s\033[0m\n",argv[1]); + } + i = 2; } - free(cmd); - return; + printf("\t\033[32m[\033[0m%s\033[32m]\033[0m - ", (strcmp(argv[0],"1") == 0) ? "\033[31;1mX\033[0m" : " "); + printf("%s\n",argv[i]); + return 0; } -void printgroupdone(sqlite3 *db, struct task t){ - char *cmd = malloc(MAXLINE * sizeof(char)); - char **errmsg = 0; - - sprintf(cmd,"SELECT Done, Type, Task FROM Tasks WHERE Type = '%s' OR Task = '%s' ORDER BY Type;",t.group, t.task); - printf("TODO:"); - int err = sqlite3_exec(db,cmd,printcallback,0,errmsg); - if (err) { - fprintf(stderr, "Could not access db: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - exit(1); - } - - free(cmd); - return; +int groupcallback(void *unused,int argc, char **argv, char **name){ + strcpy(group,argv[0]); + return 0; } diff --git a/odot.c b/odot.c index 67d47eb..37a1397 100644 --- a/odot.c +++ b/odot.c @@ -3,34 +3,26 @@ /* global variables */ int showdone = 0, showall = 0; + char *group, - *task; + *task, + *action; int main(int argc, char *argv[]){ + if (argc == 1) help(); + sqlite3 *db; - db = accessdb("odot.db"); - buildtables(db); + db = accessdb(filepath()); + sqlcmd(db,BUILDTABLE); - /* print all todo tasks if called alone */ - if (argc == 1) { - print(db); - return 0; - } group = malloc(MAXLINE * sizeof(char)); task = malloc(MAXLINE * sizeof(char)); + action = malloc(MAXLINE * sizeof(char)); - char *action = malloc(100*sizeof(char)); - - strcpy(action,argv[1]); parseopt(argc,argv); - struct task t = maketask(task,group); - free(task); - free(group); - - - operate(action,t,db); + operate(db); sqlite3_close(db); return 0; @@ -38,8 +30,11 @@ int main(int argc, char *argv[]){ void parseopt(int n, char **args){ char c; - while ((c = getopt(n,args,"g:ad")) != -1){ + while ((c = getopt(n,args,"g:adh")) != -1){ switch (c) { + case 'h': + help(); + break; case 'a': showall = 1; break; @@ -47,56 +42,114 @@ void parseopt(int n, char **args){ showdone = 1; break; case 'g': - strcpy(group,optarg); + sprintf(group,"%s",optarg); break; case '?': printf("Unknown Option: %c\n", optopt); } } - if (strcmp(group, "") == 0) strcpy(group,"all"); + sprintf(group,"%s",(strcmp(group,"") == 0) ? "" : group); + sprintf(action,"%s",args[optind]); - for (; optind < n; optind++){ - if (optind > 1) { - strcat(task,args[optind]); - strcat(task,(optind != n -1) ? " " : ""); - } + for (int j = optind + 1; j < n; j++){ + strcat(task,args[j]); + strcat(task,(j != n-1) ? " " : ""); } } -struct task maketask(char *task, char *group){ - struct task tmp; +void operate(sqlite3 *db){ + char *cmd = malloc(MAXLINE*sizeof(char)); - tmp.task = malloc(strlen(task)*sizeof(char)); - strcpy(tmp.task,task); - - tmp.group = malloc(strlen(group)*sizeof(char)); - strcpy(tmp.group,group); - - return tmp; -} - -void operate(char *action, struct task t, sqlite3 *db){ if (strcmp(action,"new") == 0){ - addtask(db, t); + sprintf(cmd,"%s%s' ,'%s', 0);",INSERT,task,group); + sqlcmd(db,cmd); } else if (strcmp(action,"done") == 0){ - donetask(db, t); + sprintf(cmd,"%s%s';",DONE,task); + sqlcmd(db,cmd); + sprintf(cmd,"%s%s';", GETGROUP,task); + sqlgroup(db,cmd); + sprintf(cmd,"SELECT Done, Task FROM Tasks WHERE Task = '%s'",task); + printf("\n"); + sqlprint(db,cmd); } else if (strcmp(action,"remove") == 0){ - removetask(db,t); + sprintf(cmd,"%s%s';",DELETE,task); + sqlcmd(db,cmd); } else if (strcmp(action,"show") != 0) { - printf("Unknown subcommand: %s\n",action); + fprintf(stderr,"\033[33;1mUnknown subcommand\033[0m: %s\n",action); } + printf("\n\t\033[35;1mTODO\033[0m: \033[36m%s\033[0m\n\n",group); if (showall == 1) { if (showdone == 1) { - printdone(db); + sqlprint(db,PRINTALL); } else { - print(db); + sqlprint(db,PRINT); } } else { if (showdone == 1) { - printgroupdone(db,t); + sprintf(cmd,"%s%s' ORDER BY Done;",PRINTGROUPALL,group); + sqlprint(db,cmd); + } else if (strcmp(group,"\t") != 0) { + sprintf(cmd,"%s%s';",PRINTGROUP,group); + sqlprint(db,cmd); } else { - printgroup(db,t); + sqlprint(db,PRINT); } } } + +char *filepath(void){ + char *dir = getenv("XDG_DATA_HOME"); + char *db = malloc(MAXLINE * sizeof(char)); + + if (!dir) { + dir = getenv("HOME"); + if (!dir) error(3); + strcat(dir,"/.local/share"); + } + strcat(dir,"/odot"); + + DIR *test = opendir(dir); + + if (test) { + closedir(test); + } else { + int err = mkdir(dir, 0777); + if (err) error(2); + } + + sprintf(db,"%s/odot.db",dir); + + return db; +} + +void error(int err){ + switch (err) { + case 1: + fprintf(stderr,"^^ SQL error ^^\n"); + break; + case 2: + fprintf(stderr,"Could not create odot directory\n\t$XDG_DATA_HOME/odot\n"); + break; + case 3: + fprintf(stderr,"Could not determine $HOME\n"); + break; + } + exit(err); +} + +void help(){ + printf("Usage: odot [subcommand] (task)\n"); + printf("\tSubcommands:\n"); + printf("\tnew\tadd new task to database\n"); + printf("\tdone\tmark task as done in database\n"); + printf("\tshow\tshow tasks in database\n"); + printf("\tremove\tremove task from database\t\n"); + printf("\tOptions:\n"); + printf("\t-a\tshow all groups\n"); + printf("\t-d\talso show completed tasks\n"); + printf("\t-g\tset group for task\n"); + printf("\t-h\tshow this help\n"); + + exit(0); +} diff --git a/odot.h b/odot.h index 2123d26..754a783 100644 --- a/odot.h +++ b/odot.h @@ -4,29 +4,35 @@ #include #include #include +#include +#include #include "sqlite3.h" #define MAXLINE 10000 -struct task { - char *task; - char *group; -}; +#define BUILDTABLE "CREATE TABLE IF NOT EXISTS Tasks (Task varchar(1000) NOT NULL PRIMARY KEY, Type varchar(8), Done int NOT NULL DEFAULT 0);" +#define INSERT "INSERT INTO Tasks VALUES ( '" +#define DELETE "DELETE FROM Tasks WHERE Task = '" +#define DONE "UPDATE Tasks SET Done = 1 WHERE Task = '" +#define GETGROUP "SELECT Type FROM Tasks WHERE Task = '" +#define PRINT "SELECT Done, Type, Task FROM Tasks WHERE Done = 0 ORDER BY Type;" +#define PRINTALL "SELECT Done, Type, Task FROM Tasks ORDER BY Type;" +#define PRINTGROUP "SELECT Done, Task FROM Tasks WHERE Done = 0 AND Type = '" +#define PRINTGROUPALL "SELECT Done, Task FROM Tasks WHERE Type = '" +char *filepath(void); +void error(int); +void help(void); void parseopt(int, char**); -void operate(char *, struct task, sqlite3 *); -struct task maketask(char *, char *); +void operate(sqlite3 *); /* functions for interfacing with database: database.c */ sqlite3 *accessdb(char *); -void buildtables(sqlite3 *); -void addtask(sqlite3 *, struct task); -void removetask(sqlite3 *, struct task); -void donetask(sqlite3 *, struct task); +void sqlcmd(sqlite3 *,char *); +void sqlprint(sqlite3 *,char *); +void sqlgroup(sqlite3 *,char *); +void sqlerror(sqlite3 *); int printcallback(void *,int,char **,char **); -void print(sqlite3 *); -void printdone(sqlite3 *); -void printgroup(sqlite3 *, struct task); -void printgroupdone(sqlite3 *, struct task); +int groupcallback(void *,int,char **,char **); diff --git a/sqlite3.o b/sqlite3.o new file mode 100644 index 0000000..fa25a93 Binary files /dev/null and b/sqlite3.o differ