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;
}
Esempio n. 3
0
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;
}