diff options
| -rw-r--r-- | src/main.c | 88 |
1 files changed, 84 insertions, 4 deletions
@@ -371,6 +371,85 @@ static void ftag_help(int, char **) printf(" ftag root %s\n", FTAG_ROOT); } +static void ftag_query_usage(void) +{ + fprintf(stderr, "usage: ftag query [-a DATE] [-b DATE] [-t TAG]...\n"); +} + +static int print_all_callback(void *_print_header, int count, char **cols, char **col_names) +{ + int *print_header = _print_header; + if (*print_header) { + for (int i = 0; i < count; i++) { + printf("%s\t", col_names[i]); + } + printf("\n"); + *print_header = 0; + } + for (int i = 0; i < count; i++) { + printf("%s\t", cols[i]); + } + printf("\n"); + return 0; +} + +static void ftag_query(int argc, char **argv) +{ + if (argc == 0) { + ftag_query_usage(); + exit(EXIT_FAILURE); + } + char *after_date; + char *before_date; + char **tags; + int tag_count = 0; + while (argc > 0) { + if (strcmp(argv[0], "-a") == 0) { + assert(argc >= 2); + after_date = argv[1]; + } + else if (strcmp(argv[0], "-b") == 0) { + assert(argc >= 2); + before_date = argv[1]; + } + else if (strcmp(argv[0], "-t") == 0) { + assert(argc >= 2); + tag_count++; + tags = realloc(tags, tag_count*sizeof(*tags)); + tags[tag_count-1] = argv[1]; + } + else { + fprintf(stderr, "ftag query: bad option \"%s\"\n", argv[0]); + ftag_query_usage(); + exit(EXIT_FAILURE); + } + argc -= 2; + argv += 2; + } + char sql[4096]; + char sql_join[2048]; + sqlite3 *db; + int rc; + rc = sqlite3_open(DATABASE_PATH, &db); + sqlite3_check(rc, db); + for (int join_idx = 0; join_idx < tag_count; join_idx++) { + int tag_id = get_id_by_col(db, "tags", "name", tags[join_idx]); + memset(sql_join, 0, sizeof(sql_join)); + snprintf(sql_join, sizeof(sql_join)-1, + "\t(SELECT id,canonical_name,full_name\n" + " FROM (files JOIN file_tags ON id = file)\n" + " WHERE tag = %d)\n", tag_id); + strcat(sql, sql_join); + } + memset(sql, 0, sizeof(sql)); + snprintf(sql, sizeof(sql)-1, "SELECT id,canonical_name,full_name FROM (\n%s);\n", sql_join); + printf("%s: debug: SQL query is:\n%s", __func__, sql); + int print_header = 1; + rc = sqlite3_exec(db, sql, print_all_callback, &print_header, NULL); + sqlite3_check(rc, db); + sqlite3_close(db); +} + /* Check that the tag we are trying to create does not exist yet. If this * callback is ever called, then it already exist, this is a fatal error. */ static int ftag_tag_check(void *, int, char **cols, char **) @@ -464,10 +543,11 @@ int main(int argc, char *argv[]) } const struct ftag_command toplevel_commands[] = { - {.name = "init", .func = ftag_init}, - {.name = "file", .func = ftag_file}, - {.name = "help", .func = ftag_help}, - {.name = "tag", .func = ftag_tag} + {.name = "init", .func = ftag_init}, + {.name = "file", .func = ftag_file}, + {.name = "help", .func = ftag_help}, + {.name = "query", .func = ftag_query}, + {.name = "tag", .func = ftag_tag} }; const int toplevel_command_count = sizeof(toplevel_commands) / sizeof(struct ftag_command); parse_args(argc-1, argv+1, toplevel_commands, toplevel_command_count); |
