static void ngx_http_groonga_context_receive_handler_typed(grn_ctx *context, int flags, ngx_http_groonga_handler_data_t *data) { char *result = NULL; unsigned int result_size = 0; int recv_flags; if (!(flags & GRN_CTX_TAIL)) { return; } grn_ctx_recv(context, &result, &result_size, &recv_flags); #ifdef NGX_GRN_SUPPORT_STOP_BY_COMMAND if (recv_flags == GRN_CTX_QUIT) { ngx_int_t ngx_rc; ngx_int_t ngx_pid; if (ngx_process == NGX_PROCESS_SINGLE) { ngx_pid = getpid(); } else { ngx_pid = getppid(); } ngx_rc = ngx_os_signal_process((ngx_cycle_t *)ngx_cycle, "quit", ngx_pid); if (ngx_rc == NGX_OK) { context->stat &= ~GRN_CTX_QUIT; grn_ctx_recv(context, &result, &result_size, &recv_flags); context->stat |= GRN_CTX_QUIT; } else { context->rc = GRN_OPERATION_NOT_PERMITTED; GRN_TEXT_PUTS(context, &(data->typed.body), "false"); context->stat &= ~GRN_CTX_QUIT; } } #endif if (result_size > 0 || GRN_TEXT_LEN(&(data->typed.body)) > 0 || context->rc != GRN_SUCCESS) { if (result_size > 0) { GRN_TEXT_PUT(context, &(data->typed.body), result, result_size); } grn_output_envelope(context, context->rc, &(data->typed.head), &(data->typed.body), &(data->typed.foot), NULL, 0); } }
static int suggest_result(struct evbuffer *res_buf, const char *types, const char *query, const char *target_name, int threshold, int limit, grn_obj *cmd_buf, grn_ctx *ctx) { if (target_name && types && query) { GRN_BULK_REWIND(cmd_buf); GRN_TEXT_PUTS(ctx, cmd_buf, "/d/suggest?table=item_"); grn_text_urlenc(ctx, cmd_buf, target_name, strlen(target_name)); GRN_TEXT_PUTS(ctx, cmd_buf, "&column=kana&types="); grn_text_urlenc(ctx, cmd_buf, types, strlen(types)); GRN_TEXT_PUTS(ctx, cmd_buf, "&query="); grn_text_urlenc(ctx, cmd_buf, query, strlen(query)); GRN_TEXT_PUTS(ctx, cmd_buf, "&threshold="); grn_text_itoa(ctx, cmd_buf, threshold); GRN_TEXT_PUTS(ctx, cmd_buf, "&limit="); grn_text_itoa(ctx, cmd_buf, limit); { char *res; int flags; unsigned int res_len; grn_ctx_send(ctx, GRN_TEXT_VALUE(cmd_buf), GRN_TEXT_LEN(cmd_buf), 0); grn_ctx_recv(ctx, &res, &res_len, &flags); evbuffer_add(res_buf, res, res_len); return res_len; } } else { evbuffer_add(res_buf, "{}", 2); return 2; } }
const gchar * grn_test_send_command(grn_ctx *context, const gchar *command) { unsigned int send_id, receive_id; GString *result; const gchar **lines; result = g_string_new(NULL); lines = cut_take_string_array(g_strsplit(command, "\n", 0)); for (; *lines; lines++) { gchar *command_result; unsigned int command_result_length; int flags = 0; send_id = grn_ctx_send(context, *lines, strlen(*lines), 0); receive_id = grn_ctx_recv(context, &command_result, &command_result_length, &flags); cut_assert_equal_uint(send_id, receive_id); g_string_append_len(result, command_result, command_result_length); grn_test_assert_context(context, cut_message("<%s>:<%s>", command, result->str)); } return cut_take_strdup(g_string_free(result, FALSE)); }
static void run_command(grn_ctx *context, const gchar *command) { gchar *response; unsigned int response_length; int flags; grn_ctx_send(context, command, strlen(command), 0); grn_ctx_recv(context, &response, &response_length, &flags); }
MRN_API char *mroonga_command(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error) { CommandInfo *info = (CommandInfo *)initid->ptr; grn_ctx *ctx = &(info->ctx); char *command; unsigned int command_length; int flags = 0; if (!args->args[0]) { *is_null = 1; return NULL; } *is_null = 0; command = args->args[0]; command_length = args->lengths[0]; grn_ctx_send(ctx, command, command_length, 0); if (ctx->rc) { my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0)); goto error; } info->result.length(0); do { char *buffer; unsigned int buffer_length; grn_ctx_recv(ctx, &buffer, &buffer_length, &flags); if (ctx->rc) { my_message(ER_ERROR_ON_READ, ctx->errbuf, MYF(0)); goto error; } if (buffer_length > 0) { if (info->result.reserve(buffer_length)) { my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM); goto error; } info->result.q_append(buffer, buffer_length); } } while (flags & GRN_CTX_MORE); *length = info->result.length(); return (char *)(info->result.ptr()); error: *error = 1; return NULL; }
/* * call-seq: * context.receive -> [ID, String] * * groongaサーバからクエリ実行結果文字列を受信する。 */ static VALUE rb_grn_context_receive (VALUE self) { grn_ctx *context; char *string; unsigned string_size; int flags = 0; unsigned int query_id; context = SELF(self); query_id = grn_ctx_recv(context, &string, &string_size, &flags); rb_grn_context_check(context, self); return rb_ary_new3(2, UINT2NUM(query_id), rb_str_new(string, string_size)); }
static void load_from_learner(msgpack_object *o, grn_ctx *ctx, grn_obj *cmd_buf) { if (o->type == MSGPACK_OBJECT_MAP && o->via.map.size) { msgpack_object_kv *kv; kv = &(o->via.map.ptr[0]); if (kv->key.type == MSGPACK_OBJECT_RAW && kv->key.via.raw.size == 6 && !memcmp(kv->key.via.raw.ptr, CONST_STR_LEN("target"))) { if (kv->val.type == MSGPACK_OBJECT_RAW) { int i; GRN_BULK_REWIND(cmd_buf); GRN_TEXT_PUTS(ctx, cmd_buf, "load --table "); GRN_TEXT_PUT(ctx, cmd_buf, kv->val.via.raw.ptr, kv->val.via.raw.size); grn_ctx_send(ctx, GRN_TEXT_VALUE(cmd_buf), GRN_TEXT_LEN(cmd_buf), GRN_CTX_MORE); grn_ctx_send(ctx, CONST_STR_LEN("["), GRN_CTX_MORE); if (kv->val.via.raw.size > 5) { if (!memcmp(kv->val.via.raw.ptr, CONST_STR_LEN("item_")) || !memcmp(kv->val.via.raw.ptr, CONST_STR_LEN("pair_"))) { char delim = '{'; GRN_BULK_REWIND(cmd_buf); for (i = 1; i < o->via.map.size; i++) { GRN_TEXT_PUTC(ctx, cmd_buf, delim); kv = &(o->via.map.ptr[i]); msgpack2json(&(kv->key), ctx, cmd_buf); GRN_TEXT_PUTC(ctx, cmd_buf, ':'); msgpack2json(&(kv->val), ctx, cmd_buf); delim = ','; } GRN_TEXT_PUTC(ctx, cmd_buf, '}'); /* printf("msg: %.*s\n", GRN_TEXT_LEN(cmd_buf), GRN_TEXT_VALUE(cmd_buf)); */ grn_ctx_send(ctx, GRN_TEXT_VALUE(cmd_buf), GRN_TEXT_LEN(cmd_buf), GRN_CTX_MORE); } } grn_ctx_send(ctx, CONST_STR_LEN("]"), 0); { char *res; int flags; unsigned int res_len; grn_ctx_recv(ctx, &res, &res_len, &flags); } } } } }
static void output(grn_ctx *ctx) { int flags = 0; char *str; unsigned int str_len; do { grn_ctx_recv(ctx, &str, &str_len, &flags); if (str_len > 0 || ctx->rc) { if (ctx->rc) { printf("ERROR (%d): %s\n", ctx->rc, ctx->errbuf); } if (str_len > 0) { printf("%.*s\n", str_len, str); } } } while (flags & GRN_CTX_MORE); }
void grn_test_assert_send_command_error_helper (grn_ctx *context, grn_rc expected_rc, const gchar *expected_message, const gchar *command, const gchar *expected_rc_expression, const gchar *expected_message_expression, const gchar *command_expression) { const gchar **lines; lines = cut_take_string_array(g_strsplit(command, "\n", 0)); for (; *lines; lines++) { grn_ctx_send(context, *lines, strlen(*lines), 0); if (context->rc) { break; } } if (context->rc == expected_rc && cut_equal_string(expected_message, context->errbuf)) { gchar *command_result; unsigned int command_result_length; int flags = 0; cut_test_pass(); grn_ctx_recv(context, &command_result, &command_result_length, &flags); } else { cut_set_expected(cut_take_printf("<%s>(%s)", expected_message, grn_rc_to_string(expected_rc))); cut_set_actual(cut_take_printf("<%s>(%s)", context->errbuf, grn_rc_to_string(context->rc))); cut_test_fail(cut_take_printf("<send(\"%s\")>\n" "%s:%d: %s():", command_expression, context->errfile, context->errline, context->errfunc)); } }
static void ngx_http_groonga_context_receive_handler_raw(grn_ctx *context, int flags, ngx_http_groonga_handler_data_t *data) { char *chunk = NULL; unsigned int chunk_size = 0; int recv_flags; ngx_http_request_t *r; ngx_log_t *log; grn_bool is_last_chunk; grn_ctx_recv(context, &chunk, &chunk_size, &recv_flags); data->raw.processed = GRN_TRUE; if (data->raw.rc != NGX_OK) { return; } r = data->raw.r; log = r->connection->log; is_last_chunk = (flags & GRN_CTX_TAIL); if (!data->raw.header_sent) { ngx_http_groonga_handler_set_content_type(r, grn_ctx_get_mime_type(context)); r->headers_out.status = NGX_HTTP_OK; if (is_last_chunk) { r->headers_out.content_length_n = chunk_size; if (chunk_size == 0) { r->header_only = 1; } } else { r->headers_out.content_length_n = -1; } data->raw.rc = ngx_http_send_header(r); data->raw.header_sent = GRN_TRUE; if (data->raw.rc != NGX_OK) { return; } } if (chunk_size > 0 || is_last_chunk) { ngx_chain_t *chain; chain = ngx_chain_get_free_buf(r->pool, &(data->raw.free_chain)); if (!chain) { ngx_log_error(NGX_LOG_ERR, log, 0, "http_groonga: failed to allocate memory for chunked body"); data->raw.rc = NGX_ERROR; return; } if (chunk_size == 0) { chain->buf->pos = NULL; chain->buf->last = NULL; chain->buf->memory = 0; } else { chain->buf->pos = (u_char *)chunk; chain->buf->last = (u_char *)chunk + chunk_size; chain->buf->memory = 1; } chain->buf->tag = (ngx_buf_tag_t)&ngx_http_groonga_module; chain->buf->flush = 1; chain->buf->temporary = 0; chain->buf->in_file = 0; if (is_last_chunk) { chain->buf->last_buf = 1; } else { chain->buf->last_buf = 0; } chain->next = NULL; data->raw.rc = ngx_http_output_filter(r, chain); ngx_chain_update_chains(r->pool, &(data->raw.free_chain), &(data->raw.busy_chain), &chain, (ngx_buf_tag_t)&ngx_http_groonga_module); } }