summaryrefslogtreecommitdiff
path: root/storage/mroonga/vendor/groonga/src
diff options
context:
space:
mode:
Diffstat (limited to 'storage/mroonga/vendor/groonga/src')
-rw-r--r--storage/mroonga/vendor/groonga/src/CMakeLists.txt12
-rw-r--r--storage/mroonga/vendor/groonga/src/Makefile.am19
-rw-r--r--storage/mroonga/vendor/groonga/src/grndb.c137
-rw-r--r--storage/mroonga/vendor/groonga/src/grndb_sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/src/grnslap.c8
-rw-r--r--storage/mroonga/vendor/groonga/src/groonga.c487
-rw-r--r--storage/mroonga/vendor/groonga/src/groonga_benchmark.c41
-rw-r--r--storage/mroonga/vendor/groonga/src/groonga_mruby.c84
-rw-r--r--storage/mroonga/vendor/groonga/src/groonga_mruby_sources.am2
-rw-r--r--storage/mroonga/vendor/groonga/src/httpd/nginx-module/ngx_http_groonga_module.c269
-rw-r--r--storage/mroonga/vendor/groonga/src/suggest/CMakeLists.txt16
-rw-r--r--storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_create_dataset.c2
-rw-r--r--storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_httpd.c2
-rw-r--r--storage/mroonga/vendor/groonga/src/suggest/groonga_suggest_learner.c2
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>