basic argument parsing, sql setups and other preparations
This commit is contained in:
parent
f9659e0430
commit
9399f71406
9 changed files with 392 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
cmake-*-debug
|
||||
*.db
|
6
CMakeLists.txt
Normal file
6
CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.31)
|
||||
project(klist C)
|
||||
|
||||
set(CMAKE_C_STANDARD 90)
|
||||
|
||||
add_subdirectory(src)
|
1
src/CMakeLists.txt
Normal file
1
src/CMakeLists.txt
Normal file
|
@ -0,0 +1 @@
|
|||
add_subdirectory(main)
|
3
src/main/CMakeLists.txt
Normal file
3
src/main/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
add_executable(klist main.c sql.c util.c)
|
||||
target_include_directories(klist PRIVATE include)
|
||||
target_link_libraries(klist sqlite3)
|
30
src/main/include/sql.h
Normal file
30
src/main/include/sql.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
enum KLIST_SQL {
|
||||
INIT,
|
||||
ADD_USER,
|
||||
GET_USER,
|
||||
GET_USERS,
|
||||
MOD_USER_NAME,
|
||||
MOD_USER_LOCAL,
|
||||
MOD_USER_DISCORD,
|
||||
MOD_USER_GOOGLE,
|
||||
ADD_LIST,
|
||||
GET_LIST,
|
||||
GET_LISTS,
|
||||
MOD_LIST_NAME,
|
||||
DEL_LIST,
|
||||
ADD_STAGE,
|
||||
GET_STAGE,
|
||||
GET_STAGES_FOR_LIST,
|
||||
DEL_STAGE,
|
||||
ADD_TASK,
|
||||
GET_TASK,
|
||||
GET_TASKS,
|
||||
MOD_TASK_NAME,
|
||||
MOD_TASK_DESCRIPTION,
|
||||
DEL_TASK,
|
||||
_KLIST_SQL_COUNT
|
||||
};
|
||||
|
||||
char *klist_sql_get(const enum KLIST_SQL);
|
81
src/main/include/util.h
Normal file
81
src/main/include/util.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
#pragma once
|
||||
#include <sqlite3.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* command parsing
|
||||
*/
|
||||
|
||||
enum klist_command {
|
||||
USER,
|
||||
LIST,
|
||||
TASK,
|
||||
};
|
||||
struct klist {
|
||||
sqlite3 *db;
|
||||
sqlite3_stmt **stmts;
|
||||
u_int cmd;
|
||||
void *cmd_ctx;
|
||||
int error;
|
||||
|
||||
};
|
||||
typedef struct klist klist;
|
||||
|
||||
klist *klist_init(char *db);
|
||||
void klist_deinit(klist *list);
|
||||
|
||||
|
||||
enum klist_user_command {
|
||||
USER_GET,
|
||||
USER_DELETE
|
||||
};
|
||||
struct klist_user_context {
|
||||
enum klist_command cmd;
|
||||
};
|
||||
typedef struct klist_user_context klist_user_context;
|
||||
|
||||
klist_user_context *klist_user_context_init(klist *list);
|
||||
void klist_user_context_deinit(klist_user_context *ctx);
|
||||
|
||||
|
||||
enum klist_list_command {
|
||||
LIST_ADD,
|
||||
LIST_EDIT,
|
||||
LIST_GET,
|
||||
LIST_DELETE,
|
||||
};
|
||||
struct klist_list_context {
|
||||
enum klist_user_command cmd;
|
||||
char *name;
|
||||
char **stages;
|
||||
};
|
||||
typedef struct klist_list_context klist_list_context;
|
||||
|
||||
klist_list_context *klist_list_context_init(klist *list);
|
||||
void klist_list_context_deinit(klist_list_context *ctx);
|
||||
|
||||
|
||||
enum klist_task_command {
|
||||
TASK_ADD,
|
||||
TASK_EDIT,
|
||||
TASK_GET,
|
||||
TASK_DELETE,
|
||||
};
|
||||
struct klist_task_context {
|
||||
enum klist_task_command cmd;
|
||||
char *list;
|
||||
char *name;
|
||||
char *stage;
|
||||
};
|
||||
typedef struct klist_task_context klist_task_context;
|
||||
|
||||
klist_task_context *klist_task_context_init(klist *list);
|
||||
void klist_task_context_deinit(klist_task_context *ctx);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* sql preparations
|
||||
*/
|
||||
|
||||
void klist_sql_prepare(klist *, char *db);
|
148
src/main/main.c
Normal file
148
src/main/main.c
Normal file
|
@ -0,0 +1,148 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
void print_help(char **argv);
|
||||
void setup(klist *ctx, int argc, char **argv);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
klist *ctx = klist_init("test.db");
|
||||
|
||||
if (argc == 1) {
|
||||
print_help(argv);
|
||||
ctx->error = 1;
|
||||
}
|
||||
|
||||
if (!ctx->error) {
|
||||
setup(ctx, argc, argv);
|
||||
switch (ctx->cmd) {
|
||||
case USER:
|
||||
switch (((klist_list_context *)ctx->cmd_ctx)->cmd) {
|
||||
case USER_GET:
|
||||
case USER_DELETE:
|
||||
default: ;
|
||||
}
|
||||
case LIST:
|
||||
switch (((klist_user_context *)ctx->cmd_ctx)->cmd) {
|
||||
case LIST_ADD:
|
||||
case LIST_EDIT:
|
||||
case LIST_GET:
|
||||
case LIST_DELETE:
|
||||
default: ;
|
||||
}
|
||||
case TASK:
|
||||
switch (((klist_task_context *)ctx->cmd_ctx)->cmd) {
|
||||
case TASK_ADD:
|
||||
case TASK_EDIT:
|
||||
case TASK_GET:
|
||||
case TASK_DELETE:
|
||||
default: ;
|
||||
}
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
|
||||
const int error = ctx->error;
|
||||
klist_deinit(ctx);
|
||||
return error;
|
||||
}
|
||||
|
||||
void print_help(char **argv) {
|
||||
fprintf(stderr, "Usage: %s <action>\n", argv[0]);
|
||||
}
|
||||
|
||||
void setup(klist *ctx, int argc, char **argv) {
|
||||
if (strcmp(argv[1], "user") == 0)
|
||||
ctx->cmd = USER;
|
||||
else if (strcmp(argv[1], "list") == 0)
|
||||
ctx->cmd = LIST;
|
||||
else if (strcmp(argv[1], "task") == 0)
|
||||
ctx->cmd = TASK;
|
||||
else print_help(argv);
|
||||
|
||||
int opt;
|
||||
switch (ctx->cmd) {
|
||||
case USER:
|
||||
optind = 2;
|
||||
while ((opt = getopt(argc, argv, "dg")) != -1)
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
fprintf(stderr, "Deleting user %u\n", getuid());
|
||||
break;
|
||||
case 'g':
|
||||
fprintf(stderr, "Printing user lists\n");
|
||||
break;
|
||||
default:
|
||||
print_help(argv);
|
||||
}
|
||||
|
||||
break;
|
||||
case LIST:
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Prints all lists.\n");
|
||||
break;
|
||||
}
|
||||
klist_list_context *list_ctx = malloc(sizeof(struct klist_list_context));
|
||||
|
||||
optind = 3;
|
||||
while ((opt = getopt(argc, argv, "aeds:")) != -1)
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
list_ctx->cmd = LIST_ADD;
|
||||
break;
|
||||
case 'e':
|
||||
list_ctx->cmd = LIST_EDIT;
|
||||
break;
|
||||
case 'd':
|
||||
list_ctx->cmd = LIST_DELETE;
|
||||
break;
|
||||
default:
|
||||
print_help(argv);
|
||||
fprintf(stderr, ""
|
||||
"list options:"
|
||||
"-a\tadd a list"
|
||||
"-e\tedit a list"
|
||||
"-d\tdelete a list"
|
||||
"Not providing a parameter prints all lists.");
|
||||
}
|
||||
ctx->cmd_ctx = list_ctx;
|
||||
break;
|
||||
case TASK:
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Prints all lists.\n");
|
||||
break;
|
||||
}
|
||||
klist_list_context *task_ctx = malloc(sizeof(struct klist_task_context));
|
||||
|
||||
optind = 3;
|
||||
while ((opt = getopt(argc, argv, "aeds:")) != -1)
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
task_ctx->cmd = TASK_ADD;
|
||||
break;
|
||||
case 'e':
|
||||
task_ctx->cmd = TASK_EDIT;
|
||||
break;
|
||||
case 'd':
|
||||
task_ctx->cmd = TASK_DELETE;
|
||||
break;
|
||||
default:
|
||||
print_help(argv);
|
||||
fprintf(stderr, ""
|
||||
"task options:"
|
||||
"-a\tadd a task"
|
||||
"-e\tedit a task"
|
||||
"-d\tdelete a task"
|
||||
"Not providing a parameter prints all tasks of a list.");
|
||||
}
|
||||
|
||||
ctx->cmd_ctx = task_ctx;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "How did we land here?! Pls report argv[1] = %s\n", argv[1]);
|
||||
print_help(argv);
|
||||
}
|
||||
}
|
67
src/main/sql.c
Normal file
67
src/main/sql.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include "include/sql.h"
|
||||
|
||||
|
||||
char *klist_sql_get(const enum KLIST_SQL sql) {
|
||||
switch (sql) {
|
||||
case INIT: return
|
||||
"create table if not exists users ("
|
||||
" id integer primary key,"
|
||||
" name text not null,"
|
||||
" local_id integer, -- if the thing is running locally"
|
||||
" discord_id integer, -- if logging in via web via discord"
|
||||
" google_id integer -- if logging in via web via google"
|
||||
");"
|
||||
"create table if not exists user_lists ("
|
||||
" id integer primary key,"
|
||||
" user_id integer not null,"
|
||||
" list_id integer not null"
|
||||
");"
|
||||
"create table if not exists lists ("
|
||||
" id integer primary key,"
|
||||
" name text not null,"
|
||||
" desc text"
|
||||
");"
|
||||
"create table if not exists task_stages ("
|
||||
" id integer primary key,"
|
||||
" name text not null,"
|
||||
" desc text,"
|
||||
" list_id integer not null,"
|
||||
" foreign key (list_id) references lists(id)"
|
||||
");"
|
||||
"-- this currently enables moving tasks _between lists_ (calculated of course)"
|
||||
"create table if not exists tasks ("
|
||||
" id integer primary key,"
|
||||
" name text not null,"
|
||||
" desc text,"
|
||||
" stage integer not null,"
|
||||
" due date,"
|
||||
" due_stage integer, -- more like target stage"
|
||||
" foreign key (stage) references task_stages(id),"
|
||||
" foreign key (due_stage) references task_stages(id)"
|
||||
")";
|
||||
case ADD_USER: return "insert into users values (?1, ?2, ?3, ?4)";
|
||||
case GET_USER: return "select * from users where id = ?1";
|
||||
case GET_USERS: return "select * from users";
|
||||
case MOD_USER_NAME: return "update users set name = ?1 where id = ?2";
|
||||
case MOD_USER_LOCAL: return "update users set local_id = ?1 where id = ?2";;
|
||||
case MOD_USER_DISCORD: return "update users set discord_id = ?1 where id = ?2";
|
||||
case MOD_USER_GOOGLE: return "update users set google_id = ?1 where id = ?2";
|
||||
case ADD_LIST: return "insert into lists values (?1, ?2)";
|
||||
case GET_LIST: return "select * from lists where id = ?1";
|
||||
case GET_LISTS: return "select * from lists";
|
||||
case MOD_LIST_NAME: return "update lists set name = ?1 where id = ?2";
|
||||
case DEL_LIST: return "delete from lists where id = ?1";
|
||||
case ADD_STAGE: return "insert into task_stages values (?1, ?2, ?3)";
|
||||
case GET_STAGE: return "select * from task_stages where id = ?1";
|
||||
case GET_STAGES_FOR_LIST: return "select * from task_stages";
|
||||
case DEL_STAGE: return "delete from task_stages where id = ?1";
|
||||
case ADD_TASK: return "insert into tasks values (?1, ?2, ?3, ?4, ?5, ?6);";
|
||||
case GET_TASK: return "select * from tasks where id = ?1";
|
||||
case GET_TASKS: return "select * from tasks;";
|
||||
case MOD_TASK_NAME: return "update tasks set name = ?1 where id = ?2";
|
||||
case MOD_TASK_DESCRIPTION: return "update tasks set description = ?1 where id = ?2";
|
||||
case DEL_TASK: return "delete from tasks where id = ?1";
|
||||
case _KLIST_SQL_COUNT: return ";";
|
||||
}
|
||||
return "";
|
||||
}
|
54
src/main/util.c
Normal file
54
src/main/util.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "sql.h"
|
||||
|
||||
/*
|
||||
* command parsing
|
||||
*/
|
||||
|
||||
klist *klist_init(char *db) {
|
||||
klist *ctx = malloc(sizeof(klist));
|
||||
ctx->stmts = malloc(sizeof(sqlite3_stmt *) * _KLIST_SQL_COUNT);
|
||||
ctx->cmd_ctx = NULL;
|
||||
ctx->error = 0;
|
||||
|
||||
klist_sql_prepare(ctx, db);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
void klist_deinit(klist *ctx) {
|
||||
sqlite3_close(ctx->db);
|
||||
if (ctx->cmd_ctx) free(ctx->cmd_ctx);
|
||||
free(ctx->stmts);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
klist_user_context *klist_user_context_init(klist *list) {
|
||||
klist_user_context *ctx = malloc(sizeof(klist_user_context));
|
||||
|
||||
return ctx;
|
||||
}
|
||||
void klist_user_context_deinit(klist_user_context *ctx);
|
||||
|
||||
klist_list_context *klist_list_context_init(klist *list);
|
||||
void klist_list_context_deinit(klist_list_context *ctx);
|
||||
|
||||
klist_task_context *klist_task_context_init(klist *list);
|
||||
void klist_task_context_deinit(klist_task_context *ctx);
|
||||
|
||||
/*
|
||||
* sql preparations
|
||||
*/
|
||||
|
||||
void klist_sql_prepare(klist *ctx, char *db) {
|
||||
ctx->stmts = malloc(sizeof(sqlite3_stmt *) * _KLIST_SQL_COUNT);
|
||||
sqlite3_open(db ? db : ":memory:", &ctx->db);
|
||||
|
||||
int i = 0;
|
||||
for (i; i < _KLIST_SQL_COUNT; i++)
|
||||
if (sqlite3_prepare(ctx->db, klist_sql_get(i), 0, &ctx->stmts[i], NULL) != SQLITE_OK)
|
||||
fprintf(stderr, "sqlite3_prepare: %s\n", sqlite3_errmsg(ctx->db));
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue