diff --git a/httpd.c b/httpd.c index 8afb199..586bb93 100644 --- a/httpd.c +++ b/httpd.c @@ -257,28 +257,61 @@ void send_json_response(int sockfd, struct myhttp_header *header, sqlite3 *db) struct coin_status_base *sb; struct coin_status *t = NULL; char tempstr[200]; - char *x = NULL; int full_rank = 0; strcpy(code, "200"); send_header(sockfd, code, "application/json"); - if ((x = strstr(header->url, "rank="))) { - x = x + strlen("rank="); + /* example url sets + * + * /home/path?rank=full + * /home/path?coinid=bitcoin&start=min_5&limit=min_30 + */ + struct uri_base *tokens; + struct uri_entry *te_entry; + tokens = tokenize_uri(header->url); + if (tokens == NULL) { + CM_ERROR("tokenization malfunction\n"); + return; + } + te_entry = tokens->first; + if (strcmp(te_entry->key, "rank") == 0) { LOCK_SHIFT_COLUMN_LOCKER; - if (strcmp(x, "full") == 0) { + if (strcmp(te_entry->value, "full") == 0) { /* /home/path/?rank=full */ sb = fetch_entire_rank(db); full_rank = 1; - } else { - sb = fetch_duration(db, "min_0", x); + } else { /* /home/path/?rank=min_5 ... etc.. */ + sb = fetch_duration(db, "min_0", te_entry->value); } UNLOCK_SHIFT_COLUMN_LOCKER; t = sb->first; + } else if (strcmp(te_entry->key, "coinid") == 0) { /* /home/path/?coinid=bitcoin&range=1 or 2 */ + char *coin_id = te_entry->value; + te_entry = te_entry->next; + + if (strcmp(te_entry->key, "range") == 0) { + char *range = te_entry->value; + + if (strcmp(range, "1") == 0){ + LOCK_SHIFT_COLUMN_LOCKER; + fetch_range_level1(coin_id, db, sockfd); + UNLOCK_SHIFT_COLUMN_LOCKER; + free_uri_base(tokens); + + return; + } + } else { + CM_ERROR("invalid option for '%s' coinid\n", coin_id); + return; + } + } else { + CM_ERROR("tokenization malfunction\n"); + return; } + free_uri_base(tokens); - if (t == NULL) - { + if (t == NULL) { write(sockfd, "{\"error\": \"error occured\"}\n", strlen("{\"error\": \"error occured\"}\n")); return; } diff --git a/sql_api.c b/sql_api.c index 41b5d70..6f3bfad 100644 --- a/sql_api.c +++ b/sql_api.c @@ -163,6 +163,56 @@ struct coin_status_base *fetch_duration(sqlite3 *db, const char *col1, return coin_stat_base; } +/* min_0, min_5, min_10, min_15, min_30, hr_1, hr_4, hr_6, hr_12, hr_24 */ +void fetch_range_level1(const char *coin_id, sqlite3 *db, int sockfd) +{ + char *sql; + sqlite3_stmt *stmt_1; + int rc; + char tempstr[255]; + + LOCK_DB_ACCESS; + + sql = sqlite3_mprintf("SELECT min_0, min_5, min_10, min_15, min_30, hr_1, hr_4, hr_6, hr_12, hr_24 " + "FROM coin_history " + "WHERE coin_key = '%s';", coin_id); + + if (sqlite3_prepare_v2(db, sql, -1, &stmt_1, 0) != SQLITE_OK) + CM_ERROR("%s\n", sqlite3_errmsg(db)); + + rc = sqlite3_step(stmt_1); + if(rc == SQLITE_ROW) { /* new row of data ready */ + sprintf(tempstr, "{ " + "\t\"min_0\": %d, " + "\t\"min_5\": %d, " + "\t\"min_10\": %d, " + "\t\"min_15\": %d, " + "\t\"min_30\": %d, " + "\t\"hr_1\": %d, " + "\t\"hr_4\": %d, " + "\t\"hr_6\": %d, " + "\t\"hr_12\": %d, " + "\t\"hr_24\": %d " + "}", + sqlite3_column_int(stmt_1, 0), + sqlite3_column_int(stmt_1, 1), + sqlite3_column_int(stmt_1, 2), + sqlite3_column_int(stmt_1, 3), + sqlite3_column_int(stmt_1, 4), + sqlite3_column_int(stmt_1, 5), + sqlite3_column_int(stmt_1, 6), + sqlite3_column_int(stmt_1, 7), + sqlite3_column_int(stmt_1, 8), + sqlite3_column_int(stmt_1, 9)); + write(sockfd, tempstr, strlen(tempstr)); + } + + UNLOCK_DB_ACCESS; + + sqlite3_finalize(stmt_1); + sqlite3_free(sql); +} + /** * @brief Return two columns of data as a difference of two times. * diff --git a/sql_api.h b/sql_api.h index 6c3da65..bfe0ff8 100644 --- a/sql_api.h +++ b/sql_api.h @@ -40,5 +40,6 @@ extern struct coin_status_base *fetch_duration(sqlite3 *db, const char *col1, const char *col2); extern void print_coin_status_base(struct coin_status_base *sb); extern void free_coin_status_base(struct coin_status_base *sb); +extern void fetch_range_level1(const char *coin_id, sqlite3 *db, int sockfd); #endif