static ret_t dbslayer_step (cherokee_handler_dbslayer_t *hdl, cherokee_buffer_t *buffer) { int re; MYSQL_RES *result; cherokee_dwriter_set_buffer (&hdl->writer, buffer); /* Open the result list */ cherokee_dwriter_list_open (&hdl->writer); /* Iterate through the results */ do { result = mysql_store_result (hdl->conn); if (result == NULL) { /* ERROR: * - Statement didn't return a result set. Eg: Insert * - Reading of the result set failed */ if (mysql_errno (hdl->conn)) { handle_error (hdl); } else { render_empty_result (hdl); } } else { render_result (hdl, result); mysql_free_result (result); } re = mysql_next_result (hdl->conn); if (re > 0) { handle_error (hdl); } } while (re == 0); /* Close results list */ cherokee_dwriter_list_close (&hdl->writer); return ret_eof_have_data; }
static ret_t render_result (cherokee_handler_dbslayer_t *hdl, MYSQL_RES *result) { cuint_t i; cuint_t num_fields; MYSQL_ROW row; MYSQL_FIELD *fields; char *tmp; #define TYPE2S(n) \ case MYSQL_TYPE_ ## n: \ cherokee_dwriter_cstring (&hdl->writer, \ "MYSQL_TYPE_"#n); \ break #define BLOB_TYPE2S(n) \ case MYSQL_TYPE_ ## n: \ if (fields[i].charsetnr == 63) \ cherokee_dwriter_cstring (&hdl->writer, \ "MYSQL_TYPE_TEXT"); \ else \ cherokee_dwriter_cstring (&hdl->writer, \ "MYSQL_TYPE_"#n); \ break #define CHECK_NULL \ if (row[i] == NULL) { \ cherokee_dwriter_null (&hdl->writer); \ continue; \ } cherokee_dwriter_dict_open (&hdl->writer); cherokee_dwriter_cstring (&hdl->writer, "RESULT"); cherokee_dwriter_dict_open (&hdl->writer); num_fields = mysql_num_fields (result); fields = mysql_fetch_fields (result); /* Types * Blobs: http://www.mysql.org/doc/refman/5.1/en/c-api-datatypes.html */ cherokee_dwriter_cstring (&hdl->writer, "TYPES"); cherokee_dwriter_list_open (&hdl->writer); for(i = 0; i < num_fields; i++) { switch(fields[i].type) { TYPE2S(TINY); TYPE2S(SHORT); TYPE2S(LONG); TYPE2S(INT24); TYPE2S(DECIMAL); TYPE2S(NEWDECIMAL); TYPE2S(DOUBLE); TYPE2S(FLOAT); TYPE2S(LONGLONG); TYPE2S(BIT); TYPE2S(TIMESTAMP); TYPE2S(DATE); TYPE2S(TIME); TYPE2S(DATETIME); TYPE2S(YEAR); TYPE2S(STRING); TYPE2S(VAR_STRING); TYPE2S(NEWDATE); TYPE2S(VARCHAR); TYPE2S(SET); TYPE2S(ENUM); TYPE2S(GEOMETRY); TYPE2S(NULL); BLOB_TYPE2S(BLOB); BLOB_TYPE2S(TINY_BLOB); BLOB_TYPE2S(MEDIUM_BLOB); BLOB_TYPE2S(LONG_BLOB); default: cherokee_dwriter_cstring (&hdl->writer, "MYSQL_TYPE_UNKNOWN"); } } cherokee_dwriter_list_close (&hdl->writer); /* Headers */ cherokee_dwriter_cstring (&hdl->writer, "HEADER"); cherokee_dwriter_list_open (&hdl->writer); for(i = 0; i < num_fields; i++) { tmp = fields[i].name; cherokee_dwriter_string (&hdl->writer, tmp, strlen(tmp)); } cherokee_dwriter_list_close (&hdl->writer); /* Data */ cherokee_dwriter_cstring (&hdl->writer, "ROWS"); cherokee_dwriter_list_open (&hdl->writer); while (true) { row = mysql_fetch_row (result); if (! row) break; cherokee_dwriter_list_open (&hdl->writer); for(i = 0; i < num_fields; i++) { switch(fields[i].type) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: case MYSQL_TYPE_INT24: case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_DOUBLE: case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_LONGLONG: CHECK_NULL; cherokee_dwriter_number (&hdl->writer, row[i], strlen(row[i])); break; case MYSQL_TYPE_BIT: case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATE: case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_YEAR: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_VARCHAR: CHECK_NULL; cherokee_dwriter_string (&hdl->writer, row[i], strlen(row[i])); break; case MYSQL_TYPE_BLOB: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: if ((row[i] == NULL) || (fields[i].charsetnr != 63)) { cherokee_dwriter_null (&hdl->writer); continue; } cherokee_dwriter_string (&hdl->writer, row[i], strlen(row[i])); break; case MYSQL_TYPE_SET: case MYSQL_TYPE_ENUM: case MYSQL_TYPE_GEOMETRY: case MYSQL_TYPE_NULL: cherokee_dwriter_null (&hdl->writer); break; default: SHOULDNT_HAPPEN; } } cherokee_dwriter_list_close (&hdl->writer); } cherokee_dwriter_list_close (&hdl->writer); cherokee_dwriter_dict_close (&hdl->writer); cherokee_dwriter_dict_close (&hdl->writer); return ret_ok; }
ret_t cherokee_handler_admin_read_post (cherokee_handler_admin_t *hdl) { int re; ret_t ret; char *tmp; cherokee_buffer_t post = CHEROKEE_BUF_INIT; cherokee_buffer_t line = CHEROKEE_BUF_INIT; cherokee_connection_t *conn = HANDLER_CONN(hdl); /* Check for the post info */ if (! conn->post.has_info) { conn->error_code = http_bad_request; return ret_error; } /* Process line per line */ ret = cherokee_post_read (&conn->post, &conn->socket, &post); switch (ret) { case ret_ok: case ret_eagain: break; default: conn->error_code = http_bad_request; return ret_error; } /* Parse */ TRACE (ENTRIES, "Post contains: '%s'\n", post.buf); cherokee_dwriter_list_open (&hdl->dwriter); for (tmp = post.buf;;) { char *end1 = strchr (tmp, CHR_LF); char *end2 = strchr (tmp, CHR_CR); char *end = cherokee_min_str (end1, end2); if (end == NULL) break; if (end - tmp < 2) break; /* Copy current line and go to the next one */ cherokee_buffer_add (&line, tmp, end - tmp); while ((*end == CHR_CR) || (*end == CHR_LF)) end++; tmp = end; /* Process current line */ ret = process_request_line (hdl, &line); if (ret == ret_error) { conn->error_code = http_bad_request; ret = ret_error; goto exit2; } /* Clean up for the next iteration */ cherokee_buffer_clean (&line); } cherokee_dwriter_list_close (&hdl->dwriter); /* There might be more POST to read */ re = cherokee_post_read_finished (&conn->post); ret = re ? ret_ok : ret_eagain; exit2: cherokee_buffer_mrproper (&post); cherokee_buffer_mrproper (&line); return ret; }