aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.c88
1 files changed, 84 insertions, 4 deletions
diff --git a/src/main.c b/src/main.c
index f2f0c55..6bdc28e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);