diff options
author | Kentoku SHIBA <kentokushiba@gmail.com> | 2015-02-17 13:34:27 +0900 |
---|---|---|
committer | Kentoku SHIBA <kentokushiba@gmail.com> | 2015-02-17 13:34:27 +0900 |
commit | f5dabd7acaaaf21019a59a641e090a7dfdaefae5 (patch) | |
tree | 1e8bc0ad46144127cbabe23cac945244b3cfbefc /storage/mroonga/vendor/groonga/src | |
parent | 162446a6219ca77e35b4b05c71a9c3dd650d719a (diff) | |
download | mariadb-git-f5dabd7acaaaf21019a59a641e090a7dfdaefae5.tar.gz |
Update Mroonga to the latest version on 2015-02-17T13:34:27+0900
Diffstat (limited to 'storage/mroonga/vendor/groonga/src')
14 files changed, 840 insertions, 243 deletions
diff --git a/storage/mroonga/vendor/groonga/src/CMakeLists.txt b/storage/mroonga/vendor/groonga/src/CMakeLists.txt index 4d02109dae5..258d1866c2b 100644 --- a/storage/mroonga/vendor/groonga/src/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/src/CMakeLists.txt @@ -25,9 +25,7 @@ set_source_files_properties(${GROONGA_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") target_link_libraries(groonga libgroonga) -if(NOT MRN_GROONGA_BUNDLED) - install(TARGETS groonga DESTINATION ${BIN_DIR}) -endif() +install(TARGETS groonga DESTINATION ${BIN_DIR}) if(NOT WIN32) read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/grnslap_sources.am GRNSLAP_SOURCES) @@ -36,9 +34,7 @@ if(NOT WIN32) PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") target_link_libraries(grnslap libgroonga) - if(NOT MRN_GROONGA_BUNDLED) - install(TARGETS grnslap DESTINATION ${BIN_DIR}) - endif() + install(TARGETS grnslap DESTINATION ${BIN_DIR}) endif() read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/groonga_benchmark_sources.am @@ -48,7 +44,5 @@ set_source_files_properties(${GROONGA_BENCHMARK_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") target_link_libraries(groonga-benchmark libgroonga) -if(NOT MRN_GROONGA_BUNDLED) - install(TARGETS groonga-benchmark DESTINATION ${BIN_DIR}) -endif() +install(TARGETS groonga-benchmark DESTINATION ${BIN_DIR}) diff --git a/storage/mroonga/vendor/groonga/src/Makefile.am b/storage/mroonga/vendor/groonga/src/Makefile.am index b125db54c3d..a4d57e85c44 100644 --- a/storage/mroonga/vendor/groonga/src/Makefile.am +++ b/storage/mroonga/vendor/groonga/src/Makefile.am @@ -6,6 +6,10 @@ NONEXISTENT_CXX_SOURCE = nonexistent.cpp bin_PROGRAMS = groonga groonga-benchmark noinst_PROGRAMS = grnslap +if WITH_MRUBY +bin_PROGRAMS += grndb +noinst_PROGRAMS += groonga-mruby +endif EXTRA_DIST = \ CMakeLists.txt @@ -22,9 +26,8 @@ AM_LDFLAGS = -no-undefined DEFAULT_INCLUDES = \ -I$(top_builddir) \ - -I$(srcdir) \ - -I$(top_srcdir) \ -I$(top_srcdir)/include \ + -I$(top_srcdir)/lib \ $(GROONGA_INCLUDEDIR) include groonga_sources.am @@ -46,3 +49,15 @@ nodist_EXTRA_groonga_benchmark_SOURCES = $(NONEXISTENT_CXX_SOURCE) groonga_benchmark_LDADD = \ $(top_builddir)/lib/libgroonga.la \ $(MESSAGE_PACK_LIBS) + +include grndb_sources.am +nodist_EXTRA_grndb_SOURCES = $(NONEXISTENT_CXX_SOURCE) +grndb_LDADD = \ + $(top_builddir)/lib/libgroonga.la \ + $(MESSAGE_PACK_LIBS) + +include groonga_mruby_sources.am +nodist_EXTRA_groonga_mruby_SOURCES = $(NONEXISTENT_CXX_SOURCE) +groonga_mruby_LDADD = \ + $(top_builddir)/lib/libgroonga.la \ + $(MESSAGE_PACK_LIBS) diff --git a/storage/mroonga/vendor/groonga/src/grndb.c b/storage/mroonga/vendor/groonga/src/grndb.c new file mode 100644 index 00000000000..d493338f57e --- /dev/null +++ b/storage/mroonga/vendor/groonga/src/grndb.c @@ -0,0 +1,137 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2014 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifdef WIN32 +# define GROONGA_MAIN +#endif /* WIN32 */ + +#include <grn_mrb.h> +#include <grn_ctx_impl.h> + +#include <mruby/variable.h> +#include <mruby/array.h> + +static int +run_command(grn_ctx *ctx, int argc, char **argv) +{ + int exit_code = EXIT_SUCCESS; + grn_mrb_data *data = &(ctx->impl->mrb); + mrb_state *mrb = data->state; + mrb_value mrb_command_line_module; + mrb_value mrb_grndb_class; + + mrb_command_line_module = mrb_const_get(mrb, + mrb_obj_value(data->module), + mrb_intern_cstr(mrb, "CommandLine")); + if (mrb->exc) { + goto exit; + } + + mrb_grndb_class = mrb_const_get(mrb, + mrb_command_line_module, + mrb_intern_cstr(mrb, "Grndb")); + if (mrb->exc) { + goto exit; + } + + { + int i; + mrb_value mrb_argv; + mrb_value mrb_grndb; + mrb_value mrb_result; + + mrb_argv = mrb_ary_new_capa(mrb, argc); + for (i = 0; i < argc; i++) { + mrb_ary_push(mrb, mrb_argv, mrb_str_new_cstr(mrb, argv[i])); + } + mrb_grndb = mrb_funcall(mrb, mrb_grndb_class, "new", 1, mrb_argv); + if (mrb->exc) { + goto exit; + } + + mrb_result = mrb_funcall(mrb, mrb_grndb, "run", 0); + if (mrb->exc) { + goto exit; + } + + if (!mrb_bool(mrb_result)) { + exit_code = EXIT_FAILURE; + } + } + +exit : + if (mrb->exc) { + mrb_print_error(mrb); + exit_code = EXIT_FAILURE; + } + + return exit_code; +} + +static int +run(grn_ctx *ctx, int argc, char **argv) +{ + int exit_code = EXIT_SUCCESS; + const char *grndb_rb = "command_line/grndb.rb"; + grn_mrb_data *data = &(ctx->impl->mrb); + mrb_state *mrb = data->state; + + mrb_gv_set(mrb, mrb_intern_lit(mrb, "$0"), mrb_str_new_cstr(mrb, argv[0])); + + grn_mrb_load(ctx, grndb_rb); + if (ctx->rc != GRN_SUCCESS) { + fprintf(stderr, "Failed to load Ruby script: <%s>: %s", + grndb_rb, ctx->errbuf); + goto exit; + } + + { + int arena_index; + + arena_index = mrb_gc_arena_save(mrb); + exit_code = run_command(ctx, argc, argv); + mrb_gc_arena_restore(mrb, arena_index); + } + +exit : + if (ctx->rc != GRN_SUCCESS) { + exit_code = EXIT_FAILURE; + } + return exit_code; +} + +int +main(int argc, char **argv) +{ + int exit_code = EXIT_SUCCESS; + + if (grn_init() != GRN_SUCCESS) { + return EXIT_FAILURE; + } + + { + grn_ctx ctx; + grn_ctx_init(&ctx, 0); + exit_code = run(&ctx, argc, argv); + grn_ctx_fin(&ctx); + } + + grn_fin(); + + return exit_code; +} diff --git a/storage/mroonga/vendor/groonga/src/grndb_sources.am b/storage/mroonga/vendor/groonga/src/grndb_sources.am new file mode 100644 index 00000000000..ce2e2bb3466 --- /dev/null +++ b/storage/mroonga/vendor/groonga/src/grndb_sources.am @@ -0,0 +1,2 @@ +grndb_SOURCES = \ + grndb.c diff --git a/storage/mroonga/vendor/groonga/src/grnslap.c b/storage/mroonga/vendor/groonga/src/grnslap.c index 5400fbb23e0..be2f181f3e7 100644 --- a/storage/mroonga/vendor/groonga/src/grnslap.c +++ b/storage/mroonga/vendor/groonga/src/grnslap.c @@ -16,8 +16,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "lib/com.h" -#include "lib/ctx_impl.h" +#include <grn_com.h> +#include <grn_ctx_impl.h> #include <string.h> #include <stdio.h> #ifdef HAVE_SYS_WAIT_H @@ -196,7 +196,7 @@ msg_handler(grn_ctx *ctx, grn_obj *msg) grn_msg_close(ctx, msg); } -static void * CALLBACK +static grn_thread_func_result CALLBACK receiver(void *arg) { grn_ctx ctx_, *ctx = &ctx_; @@ -213,7 +213,7 @@ receiver(void *arg) */ } grn_ctx_fin(ctx); - return NULL; + return GRN_THREAD_FUNC_RETURN_VALUE; } static int diff --git a/storage/mroonga/vendor/groonga/src/groonga.c b/storage/mroonga/vendor/groonga/src/groonga.c index 9d1009d72da..b03e70e0258 100644 --- a/storage/mroonga/vendor/groonga/src/groonga.c +++ b/storage/mroonga/vendor/groonga/src/groonga.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2009-2014 Brazil + Copyright(C) 2009-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,20 +16,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifdef WIN32 -# define GROONGA_MAIN -#endif /* WIN32 */ -#include "lib/groonga_in.h" - -#include "lib/com.h" -#include "lib/ctx_impl.h" -#include "lib/proc.h" -#include "lib/db.h" -#include "lib/util.h" #include <string.h> #include <stdio.h> #include <ctype.h> #include <fcntl.h> + +#ifdef WIN32 +# define GROONGA_MAIN +#endif /* WIN32 */ +#include <grn.h> + +#include <grn_com.h> +#include <grn_ctx_impl.h> +#include <grn_proc.h> +#include <grn_db.h> +#include <grn_util.h> + #ifdef HAVE_SYS_WAIT_H # include <sys/wait.h> #endif /* HAVE_SYS_WAIT_H */ @@ -48,7 +50,14 @@ # include <sys/sysctl.h> #endif /* HAVE_SYS_SYSCTL_H */ +#ifdef HAVE_IO_H +# include <io.h> +#endif /* HAVE_IO_H */ + #ifdef HAVE__STRNICMP +# ifdef strncasecmp +# undef strncasecmp +# endif /* strcasecmp */ # define strncasecmp(s1,s2,n) _strnicmp(s1,s2,n) #endif /* HAVE__STRNICMP */ @@ -210,6 +219,7 @@ read_next_line(grn_ctx *ctx, grn_obj *buf) rc = line_editor_fgets(ctx, buf); #else fprintf(stderr, "> "); + fflush(stderr); rc = grn_text_fgets(ctx, buf, stdin); #endif } else { @@ -271,31 +281,73 @@ output_envelope(grn_ctx *ctx, grn_rc rc, grn_obj *head, grn_obj *body, grn_obj * } static void -s_output(grn_ctx *ctx, int flags, void *arg) +s_output_raw(grn_ctx *ctx, int flags, FILE *stream) +{ + char *chunk = NULL; + unsigned int chunk_size = 0; + int recv_flags; + + grn_ctx_recv(ctx, &chunk, &chunk_size, &recv_flags); + if (chunk_size > 0) { + fwrite(chunk, 1, chunk_size, stream); + } + + if (flags & GRN_CTX_TAIL) { + grn_obj *command; + + fflush(stream); + + command = GRN_CTX_USER_DATA(ctx)->ptr; + GRN_BULK_REWIND(command); + } +} + +static void +s_output_typed(grn_ctx *ctx, int flags, FILE *stream) { if (ctx && ctx->impl && (flags & GRN_CTX_TAIL)) { - grn_obj *buf = ctx->impl->outbuf; + char *chunk = NULL; + unsigned int chunk_size = 0; + int recv_flags; + grn_obj body; grn_obj *command; - if (GRN_TEXT_LEN(buf) || ctx->rc) { - FILE * stream = (FILE *) arg; + + GRN_TEXT_INIT(&body, 0); + grn_ctx_recv(ctx, &chunk, &chunk_size, &recv_flags); + GRN_TEXT_SET(ctx, &body, chunk, chunk_size); + + if (GRN_TEXT_LEN(&body) || ctx->rc) { grn_obj head, foot; GRN_TEXT_INIT(&head, 0); GRN_TEXT_INIT(&foot, 0); - output_envelope(ctx, ctx->rc, &head, buf, &foot); + output_envelope(ctx, ctx->rc, &head, &body, &foot); fwrite(GRN_TEXT_VALUE(&head), 1, GRN_TEXT_LEN(&head), stream); - fwrite(GRN_TEXT_VALUE(buf), 1, GRN_TEXT_LEN(buf), stream); + fwrite(GRN_TEXT_VALUE(&body), 1, GRN_TEXT_LEN(&body), stream); fwrite(GRN_TEXT_VALUE(&foot), 1, GRN_TEXT_LEN(&foot), stream); fputc('\n', stream); fflush(stream); - GRN_BULK_REWIND(buf); GRN_OBJ_FIN(ctx, &head); GRN_OBJ_FIN(ctx, &foot); } + GRN_OBJ_FIN(ctx, &body); + command = GRN_CTX_USER_DATA(ctx)->ptr; GRN_BULK_REWIND(command); } } +static void +s_output(grn_ctx *ctx, int flags, void *arg) +{ + FILE *stream = (FILE *)arg; + + if (grn_ctx_get_output_type(ctx) == GRN_CONTENT_NONE) { + s_output_raw(ctx, flags, stream); + } else { + s_output_typed(ctx, flags, stream); + } +} + static int do_alone(int argc, char **argv) { @@ -584,7 +636,7 @@ run_server(grn_ctx *ctx, grn_obj *db, grn_com_event *ev, struct hostent *he; if (!(he = gethostbyname(hostname))) { send_ready_notify(); - SERR("gethostbyname"); + SOERR("gethostbyname"); } else { ev->opaque = db; grn_edges_init(ctx, dispatcher); @@ -643,94 +695,255 @@ start_service(grn_ctx *ctx, const char *db_path, typedef struct { grn_msg *msg; + grn_bool in_body; + grn_bool is_chunked; } ht_context; static void -h_output(grn_ctx *ctx, int flags, void *arg) +h_output_set_header(grn_ctx *ctx, grn_obj *header, + grn_rc rc, long long int content_length) { - grn_rc expr_rc = ctx->rc; - ht_context *hc = (ht_context *)arg; - grn_sock fd = hc->msg->u.fd; - grn_obj header, head, foot, *outbuf = ctx->impl->outbuf; - if (!(flags & GRN_CTX_TAIL)) { return; } - GRN_TEXT_INIT(&header, 0); - GRN_TEXT_INIT(&head, 0); - GRN_TEXT_INIT(&foot, 0); - output_envelope(ctx, expr_rc, &head, outbuf, &foot); - switch (expr_rc) { + switch (rc) { case GRN_SUCCESS : - GRN_TEXT_SETS(ctx, &header, "HTTP/1.1 200 OK\r\n"); + GRN_TEXT_SETS(ctx, header, "HTTP/1.1 200 OK\r\n"); break; case GRN_INVALID_ARGUMENT : case GRN_SYNTAX_ERROR : - GRN_TEXT_SETS(ctx, &header, "HTTP/1.1 400 Bad Request\r\n"); + GRN_TEXT_SETS(ctx, header, "HTTP/1.1 400 Bad Request\r\n"); break; case GRN_NO_SUCH_FILE_OR_DIRECTORY : - GRN_TEXT_SETS(ctx, &header, "HTTP/1.1 404 Not Found\r\n"); + GRN_TEXT_SETS(ctx, header, "HTTP/1.1 404 Not Found\r\n"); break; default : - GRN_TEXT_SETS(ctx, &header, "HTTP/1.1 500 Internal Server Error\r\n"); + GRN_TEXT_SETS(ctx, header, "HTTP/1.1 500 Internal Server Error\r\n"); break; } - GRN_TEXT_PUTS(ctx, &header, "Connection: close\r\n"); - GRN_TEXT_PUTS(ctx, &header, "Content-Type: "); - GRN_TEXT_PUTS(ctx, &header, grn_ctx_get_mime_type(ctx)); - GRN_TEXT_PUTS(ctx, &header, "\r\nContent-Length: "); - grn_text_lltoa(ctx, &header, - GRN_TEXT_LEN(&head) + GRN_TEXT_LEN(outbuf) + GRN_TEXT_LEN(&foot)); - GRN_TEXT_PUTS(ctx, &header, "\r\n\r\n"); - { - ssize_t ret, len; + GRN_TEXT_PUTS(ctx, header, "Content-Type: "); + GRN_TEXT_PUTS(ctx, header, grn_ctx_get_mime_type(ctx)); + GRN_TEXT_PUTS(ctx, header, "\r\n"); + if (content_length >= 0) { + GRN_TEXT_PUTS(ctx, header, "Connection: close\r\n"); + GRN_TEXT_PUTS(ctx, header, "Content-Length: "); + grn_text_lltoa(ctx, header, content_length); + GRN_TEXT_PUTS(ctx, header, "\r\n"); + } else { + GRN_TEXT_PUTS(ctx, header, "Transfer-Encoding: chunked\r\n"); + } + GRN_TEXT_PUTS(ctx, header, "\r\n"); +} + +static void +h_output_send(grn_ctx *ctx, grn_sock fd, + grn_obj *header, grn_obj *head, grn_obj *body, grn_obj *foot) +{ + ssize_t ret; + ssize_t len = 0; #ifdef WIN32 - WSABUF wsabufs[4]; - wsabufs[0].buf = GRN_TEXT_VALUE(&header); - wsabufs[0].len = GRN_TEXT_LEN(&header); - wsabufs[1].buf = GRN_TEXT_VALUE(&head); - wsabufs[1].len = GRN_TEXT_LEN(&head); - wsabufs[2].buf = GRN_TEXT_VALUE(outbuf); - wsabufs[2].len = GRN_TEXT_LEN(outbuf); - wsabufs[3].buf = GRN_TEXT_VALUE(&foot); - wsabufs[3].len = GRN_TEXT_LEN(&foot); - if (WSASend(fd, wsabufs, 4, &ret, 0, NULL, NULL) == SOCKET_ERROR) { - SERR("WSASend"); + int n_buffers = 0; + WSABUF wsabufs[4]; + if (header) { + wsabufs[n_buffers].buf = GRN_TEXT_VALUE(header); + wsabufs[n_buffers].len = GRN_TEXT_LEN(header); + len += GRN_TEXT_LEN(header); + n_buffers++; + } + if (head) { + wsabufs[n_buffers].buf = GRN_TEXT_VALUE(head); + wsabufs[n_buffers].len = GRN_TEXT_LEN(head); + len += GRN_TEXT_LEN(head); + n_buffers++; + } + if (body) { + wsabufs[n_buffers].buf = GRN_TEXT_VALUE(body); + wsabufs[n_buffers].len = GRN_TEXT_LEN(body); + len += GRN_TEXT_LEN(body); + n_buffers++; + } + if (foot) { + wsabufs[n_buffers].buf = GRN_TEXT_VALUE(foot); + wsabufs[n_buffers].len = GRN_TEXT_LEN(foot); + len += GRN_TEXT_LEN(foot); + n_buffers++; + } + { + DWORD sent; + if (WSASend(fd, wsabufs, n_buffers, &sent, 0, NULL, NULL) == SOCKET_ERROR) { + SOERR("WSASend"); } + ret = sent; + } #else /* WIN32 */ - struct iovec msg_iov[4]; - struct msghdr msg; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = msg_iov; - msg.msg_iovlen = 4; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - msg_iov[0].iov_base = GRN_TEXT_VALUE(&header); - msg_iov[0].iov_len = GRN_TEXT_LEN(&header); - msg_iov[1].iov_base = GRN_TEXT_VALUE(&head); - msg_iov[1].iov_len = GRN_TEXT_LEN(&head); - msg_iov[2].iov_base = GRN_TEXT_VALUE(outbuf); - msg_iov[2].iov_len = GRN_TEXT_LEN(outbuf); - msg_iov[3].iov_base = GRN_TEXT_VALUE(&foot); - msg_iov[3].iov_len = GRN_TEXT_LEN(&foot); - if ((ret = sendmsg(fd, &msg, MSG_NOSIGNAL)) == -1) { - SERR("sendmsg"); - } + struct iovec msg_iov[4]; + struct msghdr msg; + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = msg_iov; + msg.msg_iovlen = 0; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + if (header) { + msg_iov[msg.msg_iovlen].iov_base = GRN_TEXT_VALUE(header); + msg_iov[msg.msg_iovlen].iov_len = GRN_TEXT_LEN(header); + len += GRN_TEXT_LEN(header); + msg.msg_iovlen++; + } + if (head) { + msg_iov[msg.msg_iovlen].iov_base = GRN_TEXT_VALUE(head); + msg_iov[msg.msg_iovlen].iov_len = GRN_TEXT_LEN(head); + len += GRN_TEXT_LEN(head); + msg.msg_iovlen++; + } + if (body) { + msg_iov[msg.msg_iovlen].iov_base = GRN_TEXT_VALUE(body); + msg_iov[msg.msg_iovlen].iov_len = GRN_TEXT_LEN(body); + len += GRN_TEXT_LEN(body); + msg.msg_iovlen++; + } + if (foot) { + msg_iov[msg.msg_iovlen].iov_base = GRN_TEXT_VALUE(foot); + msg_iov[msg.msg_iovlen].iov_len = GRN_TEXT_LEN(foot); + len += GRN_TEXT_LEN(foot); + msg.msg_iovlen++; + } + if ((ret = sendmsg(fd, &msg, MSG_NOSIGNAL)) == -1) { + SOERR("sendmsg"); + } #endif /* WIN32 */ - len = GRN_TEXT_LEN(&header) + GRN_TEXT_LEN(&head) + - GRN_TEXT_LEN(outbuf) + GRN_TEXT_LEN(&foot); - if (ret != len) { - GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, - "couldn't send all data (%" GRN_FMT_LLD "/%" GRN_FMT_LLD ")", - (long long int)ret, (long long int)len); + if (ret != len) { + GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, + "couldn't send all data (%" GRN_FMT_LLD "/%" GRN_FMT_LLD ")", + (long long int)ret, (long long int)len); + } +} + +static void +h_output_raw(grn_ctx *ctx, int flags, ht_context *hc) +{ + grn_rc expr_rc = ctx->rc; + grn_sock fd = hc->msg->u.fd; + grn_obj header_; + grn_obj head_; + grn_obj body_; + grn_obj foot_; + grn_obj *header = NULL; + grn_obj *head = NULL; + grn_obj *body = NULL; + grn_obj *foot = NULL; + char *chunk = NULL; + unsigned int chunk_size = 0; + int recv_flags; + grn_bool is_last_message = (flags & GRN_CTX_TAIL); + + GRN_TEXT_INIT(&header_, 0); + GRN_TEXT_INIT(&head_, 0); + GRN_TEXT_INIT(&body_, GRN_OBJ_DO_SHALLOW_COPY); + GRN_TEXT_INIT(&foot_, 0); + + grn_ctx_recv(ctx, &chunk, &chunk_size, &recv_flags); + GRN_TEXT_SET(ctx, &body_, chunk, chunk_size); + + if (!hc->in_body) { + if (is_last_message) { + h_output_set_header(ctx, &header_, expr_rc, GRN_TEXT_LEN(&body_)); + hc->is_chunked = GRN_FALSE; + } else { + h_output_set_header(ctx, &header_, expr_rc, -1); + hc->is_chunked = GRN_TRUE; + } + header = &header_; + hc->in_body = GRN_TRUE; + } + + if (GRN_TEXT_LEN(&body_) > 0) { + if (hc->is_chunked) { + grn_text_printf(ctx, &head_, + "%x\r\n", (unsigned int)GRN_TEXT_LEN(&body_)); + head = &head_; + GRN_TEXT_PUTS(ctx, &foot_, "\r\n"); + foot = &foot_; } + body = &body_; + } + + if (is_last_message) { + if (hc->is_chunked) { + GRN_TEXT_PUTS(ctx, &foot_, "0\r\n"); + GRN_TEXT_PUTS(ctx, &foot_, "Connection: close\r\n"); + GRN_TEXT_PUTS(ctx, &foot_, "\r\n"); + foot = &foot_; + } + } + + h_output_send(ctx, fd, header, head, body, foot); + + GRN_OBJ_FIN(ctx, &foot_); + GRN_OBJ_FIN(ctx, &body_); + GRN_OBJ_FIN(ctx, &head_); + GRN_OBJ_FIN(ctx, &header_); +} + +static void +h_output_typed(grn_ctx *ctx, int flags, ht_context *hc) +{ + grn_rc expr_rc = ctx->rc; + grn_sock fd = hc->msg->u.fd; + grn_obj header, head, body, foot; + char *chunk = NULL; + unsigned int chunk_size = 0; + int recv_flags; + grn_bool should_return_body; + + if (!(flags & GRN_CTX_TAIL)) { return; } + + switch (hc->msg->header.qtype) { + case 'G' : + case 'P' : + should_return_body = GRN_TRUE; + break; + default : + should_return_body = GRN_FALSE; + break; + } + + GRN_TEXT_INIT(&header, 0); + GRN_TEXT_INIT(&head, 0); + GRN_TEXT_INIT(&body, 0); + GRN_TEXT_INIT(&foot, 0); + + grn_ctx_recv(ctx, &chunk, &chunk_size, &recv_flags); + GRN_TEXT_SET(ctx, &body, chunk, chunk_size); + + output_envelope(ctx, expr_rc, &head, &body, &foot); + h_output_set_header(ctx, &header, expr_rc, + GRN_TEXT_LEN(&head) + + GRN_TEXT_LEN(&body) + + GRN_TEXT_LEN(&foot)); + if (should_return_body) { + h_output_send(ctx, fd, &header, &head, &body, &foot); + } else { + h_output_send(ctx, fd, &header, NULL, NULL, NULL); } - GRN_BULK_REWIND(outbuf); GRN_OBJ_FIN(ctx, &foot); + GRN_OBJ_FIN(ctx, &body); GRN_OBJ_FIN(ctx, &head); GRN_OBJ_FIN(ctx, &header); } static void +h_output(grn_ctx *ctx, int flags, void *arg) +{ + ht_context *hc = (ht_context *)arg; + + if (grn_ctx_get_output_type(ctx) == GRN_CONTENT_NONE) { + h_output_raw(ctx, flags, hc); + } else { + h_output_typed(ctx, flags, hc); + } +} + +static void do_htreq_get(grn_ctx *ctx, grn_msg *msg) { char *path = NULL; @@ -923,10 +1136,6 @@ do_htreq_post_parse_header(grn_ctx *ctx, return GRN_FALSE; } - if (!header->have_100_continue && current == end) { - return GRN_FALSE; - } - if (current == end) { header->body_start = NULL; } else { @@ -961,6 +1170,8 @@ do_htreq_post(grn_ctx *ctx, grn_msg *msg) if (ctx->rc != GRN_SUCCESS) { ht_context context; context.msg = msg; + context.in_body = GRN_FALSE; + context.is_chunked = GRN_FALSE; h_output(ctx, GRN_CTX_TAIL, &context); return; } @@ -971,7 +1182,7 @@ do_htreq_post(grn_ctx *ctx, grn_msg *msg) int send_flags = MSG_NOSIGNAL; send_size = send(fd, continue_message, strlen(continue_message), send_flags); if (send_size == -1) { - SERR("send"); + SOERR("send"); return; } } @@ -999,7 +1210,7 @@ do_htreq_post(grn_ctx *ctx, grn_msg *msg) break; } if (recv_length == -1) { - SERR("recv"); + SOERR("recv"); break; } buffer_start = buffer; @@ -1052,15 +1263,13 @@ do_htreq(grn_ctx *ctx, grn_msg *msg) grn_com_header *header = &msg->header; switch (header->qtype) { case 'G' : /* GET */ + case 'H' : /* HEAD */ do_htreq_get(ctx, msg); break; case 'P' : /* POST */ do_htreq_post(ctx, msg); break; } - /* TODO: support "Connection: keep-alive" */ - ctx->stat = GRN_CTX_QUIT; - /* TODO: support a command in multi requests. e.g.: load command */ grn_ctx_set_next_expr(ctx, NULL); /* if (ctx->rc != GRN_OPERATION_WOULD_BLOCK) {...} */ grn_msg_close(ctx, (grn_obj *)msg); @@ -1653,7 +1862,7 @@ check_rlimit_nofile(grn_ctx *ctx) #endif /* WIN32 */ } -static void * CALLBACK +static grn_thread_func_result CALLBACK h_worker(void *arg) { ht_context hc; @@ -1676,6 +1885,8 @@ h_worker(void *arg) nfthreads--; MUTEX_UNLOCK(q_mutex); hc.msg = (grn_msg *)msg; + hc.in_body = GRN_FALSE; + hc.is_chunked = GRN_FALSE; do_htreq(ctx, (grn_msg *)msg); MUTEX_LOCK(q_mutex); } while (nfthreads < max_nfthreads && grn_gctx.stat != GRN_CTX_QUIT); @@ -1684,7 +1895,7 @@ exit : MUTEX_UNLOCK(q_mutex); GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread end (%d/%d)", nfthreads, nthreads); grn_ctx_fin(ctx); - return NULL; + return GRN_THREAD_FUNC_RETURN_VALUE; } static void @@ -1729,7 +1940,7 @@ h_server(char *path) return exit_code; } -static void * CALLBACK +static grn_thread_func_result CALLBACK g_worker(void *arg) { GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread start (%d/%d)", nfthreads, nthreads + 1); @@ -1790,7 +2001,7 @@ exit : nthreads--; MUTEX_UNLOCK(q_mutex); GRN_LOG(&grn_gctx, GRN_LOG_NOTICE, "thread end (%d/%d)", nfthreads, nthreads); - return NULL; + return GRN_THREAD_FUNC_RETURN_VALUE; } static void @@ -1891,18 +2102,18 @@ g_server(char *path) } enum { - mode_alone = 0, - mode_client, - mode_daemon, - mode_server, - mode_usage, - mode_version, - mode_config, - mode_error + ACTION_USAGE = 1, + ACTION_VERSION, + ACTION_SHOW_CONFIG, + ACTION_ERROR }; -#define MODE_MASK 0x007f -#define MODE_NEW_DB 0x0100 +#define ACTION_MASK (0x0f) +#define FLAG_MODE_ALONE (1 << 4) +#define FLAG_MODE_CLIENT (1 << 5) +#define FLAG_MODE_DAEMON (1 << 6) +#define FLAG_MODE_SERVER (1 << 7) +#define FLAG_NEW_DB (1 << 8) static uint32_t get_core_number(void) @@ -2123,7 +2334,6 @@ static const int default_http_port = DEFAULT_HTTP_PORT; static const int default_gqtp_port = DEFAULT_GQTP_PORT; static grn_encoding default_encoding = GRN_ENC_DEFAULT; static uint32_t default_max_num_threads = DEFAULT_MAX_NFTHREADS; -static const int default_mode = mode_alone; static const int default_log_level = GRN_LOG_DEFAULT_LEVEL; static const char * const default_protocol = "gqtp"; static const char *default_hostname = "localhost"; @@ -2277,8 +2487,8 @@ show_version(void) #ifdef GRN_WITH_ZLIB printf(",zlib"); #endif -#ifdef GRN_WITH_LZO - printf(",lzo"); +#ifdef GRN_WITH_LZ4 + printf(",lz4"); #endif #ifdef USE_KQUEUE printf(",kqueue"); @@ -2397,26 +2607,27 @@ main(int argc, char **argv) *working_directory_arg = NULL; const char *config_path = NULL; int exit_code = EXIT_SUCCESS; - int i, mode = mode_alone; + int i; + int flags = 0; uint32_t cache_limit = 0; static grn_str_getopt_opt opts[] = { {'p', "port", NULL, 0, GETOPT_OP_NONE}, {'e', "encoding", NULL, 0, GETOPT_OP_NONE}, {'t', "max-threads", NULL, 0, GETOPT_OP_NONE}, - {'h', "help", NULL, mode_usage, GETOPT_OP_UPDATE}, - {'c', NULL, NULL, mode_client, GETOPT_OP_UPDATE}, - {'d', NULL, NULL, mode_daemon, GETOPT_OP_UPDATE}, - {'s', NULL, NULL, mode_server, GETOPT_OP_UPDATE}, + {'h', "help", NULL, ACTION_USAGE, GETOPT_OP_UPDATE}, + {'c', NULL, NULL, FLAG_MODE_CLIENT, GETOPT_OP_ON}, + {'d', NULL, NULL, FLAG_MODE_DAEMON, GETOPT_OP_ON}, + {'s', NULL, NULL, FLAG_MODE_SERVER, GETOPT_OP_ON}, {'l', "log-level", NULL, 0, GETOPT_OP_NONE}, {'i', "server-id", NULL, 0, GETOPT_OP_NONE}, - {'n', NULL, NULL, MODE_NEW_DB, GETOPT_OP_ON}, + {'n', NULL, NULL, FLAG_NEW_DB, GETOPT_OP_ON}, {'\0', "protocol", NULL, 0, GETOPT_OP_NONE}, - {'\0', "version", NULL, mode_version, GETOPT_OP_UPDATE}, + {'\0', "version", NULL, ACTION_VERSION, GETOPT_OP_UPDATE}, {'\0', "log-path", NULL, 0, GETOPT_OP_NONE}, {'\0', "query-log-path", NULL, 0, GETOPT_OP_NONE}, {'\0', "pid-path", NULL, 0, GETOPT_OP_NONE}, {'\0', "config-path", NULL, 0, GETOPT_OP_NONE}, - {'\0', "show-config", NULL, mode_config, GETOPT_OP_UPDATE}, + {'\0', "show-config", NULL, ACTION_SHOW_CONFIG, GETOPT_OP_UPDATE}, {'\0', "cache-limit", NULL, 0, GETOPT_OP_NONE}, {'\0', "file", NULL, 0, GETOPT_OP_NONE}, {'\0', "document-root", NULL, 0, GETOPT_OP_NONE}, @@ -2453,14 +2664,14 @@ main(int argc, char **argv) init_default_settings(); /* only for parsing --config-path. */ - i = grn_str_getopt(argc, argv, opts, &mode); + i = grn_str_getopt(argc, argv, opts, &flags); if (i < 0) { show_usage(stderr); return EXIT_FAILURE; } if (config_path) { - const config_file_status status = config_file_load(config_path, opts, &mode); + const config_file_status status = config_file_load(config_path, opts, &flags); if (status == CONFIG_FILE_FOPEN_ERROR) { fprintf(stderr, "%s: can't open config file: %s (%s)\n", argv[0], config_path, strerror(errno)); @@ -2473,7 +2684,7 @@ main(int argc, char **argv) } } else if (*default_config_path) { const config_file_status status = - config_file_load(default_config_path, opts, &mode); + config_file_load(default_config_path, opts, &flags); if (status != CONFIG_FILE_SUCCESS && status != CONFIG_FILE_FOPEN_ERROR) { fprintf(stderr, "%s: failed to parse config file: %s (%s)\n", argv[0], default_config_path, @@ -2491,22 +2702,21 @@ main(int argc, char **argv) } /* ignore mode option in config file */ - mode = (mode == mode_error) ? default_mode : - ((mode & ~MODE_MASK) | default_mode); + flags = (flags == ACTION_ERROR) ? 0 : (flags & ~ACTION_MASK); - i = grn_str_getopt(argc, argv, opts, &mode); - if (i < 0) { mode = mode_error; } - switch (mode & MODE_MASK) { - case mode_version : + i = grn_str_getopt(argc, argv, opts, &flags); + if (i < 0) { flags = ACTION_ERROR; } + switch (flags & ACTION_MASK) { + case ACTION_VERSION : show_version(); return EXIT_SUCCESS; - case mode_usage : + case ACTION_USAGE : show_usage(output); return EXIT_SUCCESS; - case mode_config : - show_config(output, opts, mode & ~MODE_MASK); + case ACTION_SHOW_CONFIG : + show_config(output, opts, flags & ~ACTION_MASK); return EXIT_SUCCESS; - case mode_error : + case ACTION_ERROR : show_usage(stderr); return EXIT_FAILURE; } @@ -2787,23 +2997,14 @@ main(int argc, char **argv) grn_cache_set_max_n_entries(&grn_gctx, cache, cache_limit); } - newdb = (mode & MODE_NEW_DB); - switch (mode & MODE_MASK) { - case mode_alone : - exit_code = do_alone(argc - i, argv + i); - break; - case mode_client : + newdb = (flags & FLAG_NEW_DB); + is_daemon_mode = (flags & FLAG_MODE_DAEMON); + if (flags & FLAG_MODE_CLIENT) { exit_code = do_client(argc - i, argv + i); - break; - case mode_daemon : - is_daemon_mode = GRN_TRUE; - /* fallthru */ - case mode_server : + } else if (is_daemon_mode || (flags & FLAG_MODE_SERVER)) { exit_code = do_server(argc > i ? argv[i] : NULL); - break; - default: - exit_code = EXIT_FAILURE; - break; + } else { + exit_code = do_alone(argc - i, argv + i); } #ifdef GRN_WITH_LIBEDIT diff --git a/storage/mroonga/vendor/groonga/src/groonga_benchmark.c b/storage/mroonga/vendor/groonga/src/groonga_benchmark.c index 61575174950..e7e426e748f 100644 --- a/storage/mroonga/vendor/groonga/src/groonga_benchmark.c +++ b/storage/mroonga/vendor/groonga/src/groonga_benchmark.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2010-2012 Brazil + Copyright(C) 2010-2014 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -17,7 +17,7 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include <config.h> #endif /* HAVE_CONFIG_H */ #include <stdio.h> @@ -37,9 +37,9 @@ #include <netinet/in.h> #endif /* HAVE_NETINET_IN_H */ -#include "lib/str.h" -#include "lib/com.h" -#include "lib/db.h" +#include <grn_str.h> +#include <grn_com.h> +#include <grn_db.h> #ifdef WIN32 #include <windows.h> @@ -598,7 +598,7 @@ command_send_http(grn_ctx *ctx, const char *command, int type, int task_id) fprintf(stderr, "failed to connect to groonga at %s:%d via HTTP: ", grntest_serverhost, grntest_serverport); #ifdef WIN32 - fprintf(stderr, "%d\n", GetLastError()); + fprintf(stderr, "%lu\n", GetLastError()); #else fprintf(stderr, "%s\n", strerror(errno)); #endif @@ -1149,7 +1149,7 @@ typedef struct _grntest_worker { } grntest_worker; #ifdef WIN32 -static int +static unsigned int __stdcall worker(void *val) { @@ -1252,7 +1252,6 @@ get_sysinfo(const char *path, char *result, int olen) char tmpbuf[256]; #ifdef WIN32 - int cinfo[4]; ULARGE_INTEGER dinfo; char cpustring[64]; SYSTEM_INFO sinfo; @@ -1279,12 +1278,15 @@ get_sysinfo(const char *path, char *result, int olen) memset(cpustring, 0, 64); #ifndef __GNUC__ - __cpuid(cinfo, 0x80000002); - memcpy(cpustring, cinfo, 16); - __cpuid(cinfo, 0x80000003); - memcpy(cpustring+16, cinfo, 16); - __cpuid(cinfo, 0x80000004); - memcpy(cpustring+32, cinfo, 16); + { + int cinfo[4]; + __cpuid(cinfo, 0x80000002); + memcpy(cpustring, cinfo, 16); + __cpuid(cinfo, 0x80000003); + memcpy(cpustring+16, cinfo, 16); + __cpuid(cinfo, 0x80000004); + memcpy(cpustring+32, cinfo, 16); + } #endif if (grntest_outtype == OUT_TSV) { @@ -1313,9 +1315,9 @@ get_sysinfo(const char *path, char *result, int olen) GetSystemInfo(&sinfo); if (grntest_outtype == OUT_TSV) { - sprintf(tmpbuf, "CORE\t%d\n", sinfo.dwNumberOfProcessors); + sprintf(tmpbuf, "CORE\t%lu\n", sinfo.dwNumberOfProcessors); } else { - sprintf(tmpbuf, " \"CORE\": %d,\n", sinfo.dwNumberOfProcessors); + sprintf(tmpbuf, " \"CORE\": %lu,\n", sinfo.dwNumberOfProcessors); } strcat(result, tmpbuf); @@ -1338,9 +1340,10 @@ get_sysinfo(const char *path, char *result, int olen) osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osinfo); if (grntest_outtype == OUT_TSV) { - sprintf(tmpbuf, "Windows %d.%d\n", osinfo.dwMajorVersion, osinfo.dwMinorVersion); + sprintf(tmpbuf, "Windows %ld.%ld\n", + osinfo.dwMajorVersion, osinfo.dwMinorVersion); } else { - sprintf(tmpbuf, " \"OS\": \"Windows %d.%d\",\n", osinfo.dwMajorVersion, + sprintf(tmpbuf, " \"OS\": \"Windows %lu.%lu\",\n", osinfo.dwMajorVersion, osinfo.dwMinorVersion); } strcat(result, tmpbuf); @@ -1561,7 +1564,7 @@ start_server(const char *dbpath, int r) 0, NULL, NULL, &si, &grntest_pi); if (ret == 0) { - fprintf(stderr, "Cannot start groonga server: <%s>: error=%d\n", + fprintf(stderr, "Cannot start groonga server: <%s>: error=%lu\n", groonga_path, GetLastError()); exit(1); } diff --git a/storage/mroonga/vendor/groonga/src/groonga_mruby.c b/storage/mroonga/vendor/groonga/src/groonga_mruby.c new file mode 100644 index 00000000000..9978a002f18 --- /dev/null +++ b/storage/mroonga/vendor/groonga/src/groonga_mruby.c @@ -0,0 +1,84 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2014 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include <grn_mrb.h> + +#include <stdio.h> +#include <stdlib.h> + +static int +run(grn_ctx *ctx, const char *db_path, const char *ruby_script_path) +{ + grn_obj *db; + + db = grn_db_open(ctx, db_path); + if (!db) { + if (ctx->rc == GRN_NO_SUCH_FILE_OR_DIRECTORY) { + db = grn_db_create(ctx, db_path, NULL); + if (!db) { + fprintf(stderr, "Failed to create database: <%s>: %s", + db_path, ctx->errbuf); + return EXIT_FAILURE; + } + } else { + fprintf(stderr, "Failed to open database: <%s>: %s", + db_path, ctx->errbuf); + return EXIT_FAILURE; + } + } + + grn_mrb_load(ctx, ruby_script_path); + if (ctx->rc != GRN_SUCCESS) { + fprintf(stderr, "Failed to load Ruby script: <%s>: %s", + ruby_script_path, ctx->errbuf); + } + + grn_obj_close(ctx, db); + + if (ctx->rc == GRN_SUCCESS) { + return EXIT_SUCCESS; + } else { + return EXIT_FAILURE; + } +} + +int +main(int argc, char **argv) +{ + int exit_code = EXIT_SUCCESS; + + if (argc != 3) { + fprintf(stderr, "Usage: %s DB_PATH RUBY_SCRIPT_PATH\n", argv[0]); + return EXIT_FAILURE; + } + + if (grn_init() != GRN_SUCCESS) { + return EXIT_FAILURE; + } + + { + grn_ctx ctx; + grn_ctx_init(&ctx, 0); + exit_code = run(&ctx, argv[1], argv[2]); + grn_ctx_fin(&ctx); + } + + grn_fin(); + + return exit_code; +} diff --git a/storage/mroonga/vendor/groonga/src/groonga_mruby_sources.am b/storage/mroonga/vendor/groonga/src/groonga_mruby_sources.am new file mode 100644 index 00000000000..c9006755c97 --- /dev/null +++ b/storage/mroonga/vendor/groonga/src/groonga_mruby_sources.am @@ -0,0 +1,2 @@ +groonga_mruby_SOURCES = \ + groonga_mruby.c diff --git a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c index 26be6be7d0a..115de1338a4 100644 --- a/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c +++ b/storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2012-2014 Brazil + Copyright(C) 2012-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,9 +16,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> +#ifndef WIN32 +# define NGX_GRN_SUPPORT_STOP_BY_COMMAND +#endif #include <ngx_config.h> #include <ngx_core.h> @@ -26,6 +26,13 @@ #include <groonga.h> +#include <sys/stat.h> + +#ifdef NGX_GRN_SUPPORT_STOP_BY_COMMAND +# include <sys/types.h> +# include <unistd.h> +#endif + #define GRN_NO_FLAGS 0 typedef struct { @@ -56,9 +63,19 @@ typedef struct { typedef struct { grn_bool initialized; grn_ctx context; - grn_obj head; - grn_obj body; - grn_obj foot; + struct { + grn_bool processed; + grn_bool header_sent; + ngx_http_request_t *r; + ngx_int_t rc; + ngx_chain_t *free_chain; + ngx_chain_t *busy_chain; + } raw; + struct { + grn_obj head; + grn_obj body; + grn_obj foot; + } typed; } ngx_http_groonga_handler_data_t; typedef struct { @@ -126,18 +143,54 @@ ngx_http_groonga_logger_log(grn_ctx *ctx, grn_log_level level, const char level_marks[] = " EACewnid-"; u_char buffer[NGX_MAX_ERROR_STR]; u_char *last; - + size_t prefix_size; + size_t message_size; + size_t location_size; + size_t postfix_size; + size_t log_message_size; + +#define LOG_PREFIX_FORMAT "%s|%c|%s " + prefix_size = + strlen(timestamp) + + 1 /* | */ + + 1 /* %c */ + + 1 /* | */ + + strlen(title) + + 1 /* a space */; + message_size = strlen(message); if (location && *location) { - last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR, - "%s|%c|%s %s %s\n", - timestamp, *(level_marks + level), title, message, - location); + location_size = 1 /* a space */ + strlen(location); } else { + location_size = 0; + } + postfix_size = 1 /* \n */; + log_message_size = prefix_size + message_size + location_size + postfix_size; + + if (log_message_size > NGX_MAX_ERROR_STR) { last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR, - "%s|%c|%s %s\n", - timestamp, *(level_marks + level), title, message); + LOG_PREFIX_FORMAT, + timestamp, *(level_marks + level), title); + ngx_write_fd(logger_data->file->fd, buffer, last - buffer); + ngx_write_fd(logger_data->file->fd, (void *)message, message_size); + if (location_size > 0) { + ngx_write_fd(logger_data->file->fd, " ", 1); + ngx_write_fd(logger_data->file->fd, (void *)location, location_size); + } + ngx_write_fd(logger_data->file->fd, "\n", 1); + } else { + if (location && *location) { + last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR, + LOG_PREFIX_FORMAT " %s %s\n", + timestamp, *(level_marks + level), title, message, + location); + } else { + last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR, + LOG_PREFIX_FORMAT " %s\n", + timestamp, *(level_marks + level), title, message); + } + ngx_write_fd(logger_data->file->fd, buffer, last - buffer); } - ngx_write_fd(logger_data->file->fd, buffer, last - buffer); +#undef LOG_PREFIX_FORMAT } static void @@ -336,6 +389,7 @@ ngx_http_groonga_grn_obj_to_ngx_buf(ngx_pool_t *pool, grn_obj *object) buffer->pos = (u_char *)GRN_TEXT_VALUE(object); buffer->last = (u_char *)GRN_TEXT_VALUE(object) + GRN_TEXT_LEN(object); buffer->memory = 1; /* this buffer is in memory */ + buffer->in_file = 0; return buffer; } @@ -351,20 +405,109 @@ ngx_http_groonga_handler_cleanup(void *user_data) } context = &(data->context); - GRN_OBJ_FIN(context, &(data->head)); - GRN_OBJ_FIN(context, &(data->body)); - GRN_OBJ_FIN(context, &(data->foot)); + GRN_OBJ_FIN(context, &(data->typed.head)); + GRN_OBJ_FIN(context, &(data->typed.body)); + GRN_OBJ_FIN(context, &(data->typed.foot)); grn_logger_set(context, NULL); grn_query_logger_set(context, NULL); grn_ctx_fin(context); } static void -ngx_http_groonga_context_receive_handler(grn_ctx *context, - int flags, - void *callback_data) +ngx_http_groonga_handler_set_content_type(ngx_http_request_t *r, + const char *content_type) +{ + r->headers_out.content_type.len = strlen(content_type); + r->headers_out.content_type.data = (u_char *)content_type; + r->headers_out.content_type_len = r->headers_out.content_type.len; +} + +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); + } +} + +static void +ngx_http_groonga_context_receive_handler_typed(grn_ctx *context, + int flags, + ngx_http_groonga_handler_data_t *data) { - ngx_http_groonga_handler_data_t *data = callback_data; char *result = NULL; unsigned int result_size = 0; int recv_flags; @@ -375,6 +518,7 @@ ngx_http_groonga_context_receive_handler(grn_ctx *context, 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; @@ -394,28 +538,43 @@ ngx_http_groonga_context_receive_handler(grn_ctx *context, context->stat |= GRN_CTX_QUIT; } else { context->rc = GRN_OPERATION_NOT_PERMITTED; - GRN_TEXT_PUTS(context, &(data->body), "false"); + GRN_TEXT_PUTS(context, &(data->typed.body), "false"); context->stat &= ~GRN_CTX_QUIT; } } +#endif if (result_size > 0 || - GRN_TEXT_LEN(&(data->body)) > 0 || + GRN_TEXT_LEN(&(data->typed.body)) > 0 || context->rc != GRN_SUCCESS) { if (result_size > 0) { - GRN_TEXT_PUT(context, &(data->body), result, result_size); + GRN_TEXT_PUT(context, &(data->typed.body), result, result_size); } grn_output_envelope(context, context->rc, - &(data->head), - &(data->body), - &(data->foot), + &(data->typed.head), + &(data->typed.body), + &(data->typed.foot), NULL, 0); } } +static void +ngx_http_groonga_context_receive_handler(grn_ctx *context, + int flags, + void *callback_data) +{ + ngx_http_groonga_handler_data_t *data = callback_data; + + if (grn_ctx_get_output_type(context) == GRN_CONTENT_NONE) { + ngx_http_groonga_context_receive_handler_raw(context, flags, data); + } else { + ngx_http_groonga_context_receive_handler_typed(context, flags, data); + } +} + static ngx_int_t ngx_http_groonga_extract_command_path(ngx_http_request_t *r, ngx_str_t *command_path) @@ -461,15 +620,6 @@ ngx_http_groonga_extract_command_path(ngx_http_request_t *r, return NGX_OK; } -static void -ngx_http_groonga_handler_set_content_type(ngx_http_request_t *r, - const char *content_type) -{ - r->headers_out.content_type.len = strlen(content_type); - r->headers_out.content_type.data = (u_char *)content_type; - r->headers_out.content_type_len = r->headers_out.content_type.len; -} - static ngx_int_t ngx_http_groonga_handler_create_data(ngx_http_request_t *r, ngx_http_groonga_handler_data_t **data_return) @@ -496,10 +646,20 @@ ngx_http_groonga_handler_create_data(ngx_http_request_t *r, if (rc != NGX_OK) { return rc; } + data->initialized = GRN_TRUE; - GRN_TEXT_INIT(&(data->head), GRN_NO_FLAGS); - GRN_TEXT_INIT(&(data->body), GRN_NO_FLAGS); - GRN_TEXT_INIT(&(data->foot), GRN_NO_FLAGS); + + data->raw.processed = GRN_FALSE; + data->raw.header_sent = GRN_FALSE; + data->raw.r = r; + data->raw.rc = NGX_OK; + data->raw.free_chain = NULL; + data->raw.busy_chain = NULL; + + GRN_TEXT_INIT(&(data->typed.head), GRN_NO_FLAGS); + GRN_TEXT_INIT(&(data->typed.body), GRN_NO_FLAGS); + GRN_TEXT_INIT(&(data->typed.foot), GRN_NO_FLAGS); + grn_ctx_use(context, grn_ctx_db(&(location_conf->context))); rc = ngx_http_groonga_context_check_error(r->connection->log, context); if (rc != NGX_OK) { @@ -553,9 +713,10 @@ ngx_http_groonga_handler_validate_post_command(ngx_http_request_t *r, context = &(data->context); ngx_http_groonga_handler_set_content_type(r, "text/plain"); - GRN_TEXT_PUTS(context, &(data->body), "command for POST must be <load>: <"); - GRN_TEXT_PUT(context, &(data->body), command.data, command.len); - GRN_TEXT_PUTS(context, &(data->body), ">"); + GRN_TEXT_PUTS(context, &(data->typed.body), + "command for POST must be <load>: <"); + GRN_TEXT_PUT(context, &(data->typed.body), command.data, command.len); + GRN_TEXT_PUTS(context, &(data->typed.body), ">"); return NGX_HTTP_BAD_REQUEST; } @@ -665,7 +826,7 @@ ngx_http_groonga_handler_process_body(ngx_http_request_t *r, body = r->request_body->bufs->buf; if (!body) { ngx_http_groonga_handler_set_content_type(r, "text/plain"); - GRN_TEXT_PUTS(context, &(data->body), "must send load data as body"); + GRN_TEXT_PUTS(context, &(data->typed.body), "must send load data as body"); return NGX_HTTP_BAD_REQUEST; } @@ -744,6 +905,10 @@ ngx_http_groonga_handler_send_response(ngx_http_request_t *r, ngx_chain_t head_chain, body_chain, foot_chain; ngx_chain_t *output_chain = NULL; + if (data->raw.processed) { + return data->raw.rc; + } + context = &(data->context); /* set the 'Content-type' header */ @@ -753,17 +918,17 @@ ngx_http_groonga_handler_send_response(ngx_http_request_t *r, } /* allocate buffers for a response body */ - head_buf = ngx_http_groonga_grn_obj_to_ngx_buf(r->pool, &(data->head)); + head_buf = ngx_http_groonga_grn_obj_to_ngx_buf(r->pool, &(data->typed.head)); if (!head_buf) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } - body_buf = ngx_http_groonga_grn_obj_to_ngx_buf(r->pool, &(data->body)); + body_buf = ngx_http_groonga_grn_obj_to_ngx_buf(r->pool, &(data->typed.body)); if (!body_buf) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } - foot_buf = ngx_http_groonga_grn_obj_to_ngx_buf(r->pool, &(data->foot)); + foot_buf = ngx_http_groonga_grn_obj_to_ngx_buf(r->pool, &(data->typed.foot)); if (!foot_buf) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -778,9 +943,9 @@ ngx_http_groonga_handler_send_response(ngx_http_request_t *r, /* set the status line */ r->headers_out.status = NGX_HTTP_OK; - r->headers_out.content_length_n = GRN_TEXT_LEN(&(data->head)) + - GRN_TEXT_LEN(&(data->body)) + - GRN_TEXT_LEN(&(data->foot)); + r->headers_out.content_length_n = GRN_TEXT_LEN(&(data->typed.head)) + + GRN_TEXT_LEN(&(data->typed.body)) + + GRN_TEXT_LEN(&(data->typed.foot)); if (r->headers_out.content_length_n == 0) { r->header_only = 1; } @@ -1072,7 +1237,7 @@ ngx_http_groonga_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) GRN_CACHE_DEFAULT_MAX_N_ENTRIES); #ifdef NGX_HTTP_GROONGA_LOG_PATH - { + if (!conf->log_file) { ngx_str_t default_log_path; default_log_path.data = (u_char *)NGX_HTTP_GROONGA_LOG_PATH; default_log_path.len = strlen(NGX_HTTP_GROONGA_LOG_PATH); @@ -1085,8 +1250,6 @@ ngx_http_groonga_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) return NGX_CONF_ERROR; } } -#else - conf->log_file = NULL; #endif ngx_conf_merge_str_value(conf->query_log_path, prev->query_log_path, diff --git a/storage/mroonga/vendor/groonga/src/suggest/CMakeLists.txt b/storage/mroonga/vendor/groonga/src/suggest/CMakeLists.txt index 0773026a618..c0c7a9c9964 100644 --- a/storage/mroonga/vendor/groonga/src/suggest/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/src/suggest/CMakeLists.txt @@ -25,11 +25,9 @@ set_source_files_properties(${GROONGA_SUGGEST_CREATE_DATASET_SOURCES} PROPERTIES COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") target_link_libraries(groonga-suggest-create-dataset libgroonga) -if(NOT MRN_GROONGA_BUNDLED) - install( - TARGETS groonga-suggest-create-dataset - DESTINATION ${BIN_DIR}) -endif() +install( + TARGETS groonga-suggest-create-dataset + DESTINATION ${BIN_DIR}) if(GRN_WITH_LIBEVENT AND GRN_WITH_ZEROMQ AND GRN_WITH_MESSAGE_PACK) set(GRN_WITH_SUGGEST_LEARNER TRUE) @@ -82,9 +80,7 @@ if(GRN_WITH_SUGGEST_LEARNER) ${ZEROMQ_LIBRARIES} ${MESSAGE_PACK_LIBRARIES}) - if(NOT MRN_GROONGA_BUNDLED) - install( - TARGETS groonga-suggest-learner groonga-suggest-httpd - DESTINATION ${BIN_DIR}) - endif() + install( + TARGETS groonga-suggest-learner groonga-suggest-httpd + DESTINATION ${BIN_DIR}) endif() diff --git a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_create_dataset.c b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_create_dataset.c index 35f2cd09fc0..d566d24b96a 100644 --- a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_create_dataset.c +++ b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_create_dataset.c @@ -21,7 +21,7 @@ #include <groonga.h> /* For grn_str_getopt() */ -#include <str.h> +#include <grn_str.h> typedef enum { MODE_NONE, diff --git a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_httpd.c b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_httpd.c index 6d94be87a8a..98ae0958908 100644 --- a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_httpd.c +++ b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_httpd.c @@ -16,7 +16,7 @@ */ /* groonga origin headers */ -#include <str.h> +#include <grn_str.h> #include <stdio.h> #include <signal.h> diff --git a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_learner.c b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_learner.c index 060d238565a..18b91d438e2 100644 --- a/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_learner.c +++ b/storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_learner.c @@ -16,7 +16,7 @@ */ /* for grn_str_getopt() */ -#include <str.h> +#include <grn_str.h> #include "zmq_compatible.h" #include <stdio.h> |