Kouhei Sutou
null+****@clear*****
Mon Jan 5 00:40:31 JST 2015
Kouhei Sutou 2015-01-05 00:40:31 +0900 (Mon, 05 Jan 2015) New Revision: cfa6fa4b7108298af319c2fa67eada42070ee9c7 https://github.com/groonga/groonga/commit/cfa6fa4b7108298af319c2fa67eada42070ee9c7 Message: Add experimental new command API Added files: include/groonga/command.h lib/command.c Modified files: include/groonga/Makefile.am include/groonga/groonga.h lib/db.c lib/expr.c lib/grn_db.h lib/sources.am Modified: include/groonga/Makefile.am (+1 -0) =================================================================== --- include/groonga/Makefile.am 2015-01-04 23:55:01 +0900 (c0a0018) +++ include/groonga/Makefile.am 2015-01-05 00:40:31 +0900 (ffdb083) @@ -1,5 +1,6 @@ groonga_includedir = $(pkgincludedir)/groonga groonga_include_HEADERS = \ + command.h \ expr.h \ groonga.h \ ii.h \ Added: include/groonga/command.h (+79 -0) 100644 =================================================================== --- /dev/null +++ include/groonga/command.h 2015-01-05 00:40:31 +0900 (101956a) @@ -0,0 +1,79 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 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 +*/ +#ifndef GROONGA_COMMAND_H +#define GROONGA_COMMAND_H + +#include <groonga/plugin.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _grn_command_input grn_command_input; + +GRN_PLUGIN_EXPORT grn_command_input *grn_command_input_open(grn_ctx *ctx, + grn_obj *command); +GRN_PLUGIN_EXPORT grn_rc grn_command_input_close(grn_ctx *ctx, + grn_command_input *input); + +GRN_PLUGIN_EXPORT grn_obj *grn_command_input_add(grn_ctx *ctx, + grn_command_input *input, + const char *name, + int name_size, + grn_bool *added); +GRN_PLUGIN_EXPORT grn_obj *grn_command_input_get(grn_ctx *ctx, + grn_command_input *input, + const char *name, + int name_size); +GRN_PLUGIN_EXPORT grn_obj *grn_command_input_at(grn_ctx *ctx, + grn_command_input *input, + unsigned int offset); + +typedef void grn_command_run_func(grn_ctx *ctx, + grn_obj *command, + grn_command_input *input, + void *user_data); + +/* + grn_command_register() registers a command to the database which is + associated with `ctx'. `command_name' and `command_name_size' + specify the command name. Alphabetic letters ('A'-'Z' and 'a'-'z'), + digits ('0'-'9') and an underscore ('_') are capable characters. + + `run' is called for running the command. + + grn_command_register() returns GRN_SUCCESS on success, an error + code on failure. + */ +GRN_PLUGIN_EXPORT grn_rc grn_command_register(grn_ctx *ctx, + const char *command_name, + int command_name_size, + grn_command_run_func *run, + grn_expr_var *vars, + unsigned int n_vars, + void *user_data); + +GRN_PLUGIN_EXPORT grn_rc grn_command_run(grn_ctx *ctx, + grn_obj *command, + grn_command_input *input); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* GROONGA_COMMAND_H */ Modified: include/groonga/groonga.h (+1 -0) =================================================================== --- include/groonga/groonga.h 2015-01-04 23:55:01 +0900 (523cd86) +++ include/groonga/groonga.h 2015-01-05 00:40:31 +0900 (cdab232) @@ -119,6 +119,7 @@ typedef enum { GRN_UNSUPPORTED_COMMAND_VERSION = -71, GRN_NORMALIZER_ERROR = -72, GRN_TOKEN_FILTER_ERROR = -73, + GRN_COMMAND_ERROR = -74, } grn_rc; GRN_API grn_rc grn_init(void); Added: lib/command.c (+194 -0) 100644 =================================================================== --- /dev/null +++ lib/command.c 2015-01-05 00:40:31 +0900 (b0f7522) @@ -0,0 +1,194 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 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 <string.h> + +#include "grn.h" +#include "grn_db.h" +#include "grn_ctx_impl.h" + +struct _grn_command_input { + grn_obj *command; + grn_hash *arguments; +}; + +grn_command_input * +grn_command_input_open(grn_ctx *ctx, grn_obj *command) +{ + grn_command_input *input = NULL; + + GRN_API_ENTER; + input = GRN_MALLOC(sizeof(grn_command_input)); + if (!input) { + ERR(GRN_NO_MEMORY_AVAILABLE, + "[command-input] failed to allocate grn_command_input"); + goto exit; + } + + input->command = command; + /* TODO: Allocate by self. */ + { + uint32_t n; + input->arguments = grn_expr_get_vars(ctx, input->command, &n); + } + +exit : + GRN_API_RETURN(input); +} + +grn_rc +grn_command_input_close(grn_ctx *ctx, grn_command_input *input) +{ + GRN_API_ENTER; + + /* TODO: Free input->arguments by self. */ + grn_expr_clear_vars(ctx, input->command); + GRN_FREE(input); + + GRN_API_RETURN(ctx->rc); +} + +grn_obj * +grn_command_input_add(grn_ctx *ctx, + grn_command_input *input, + const char *name, + int name_size, + grn_bool *added) +{ + grn_obj *argument = NULL; + /* TODO: Use grn_bool */ + int internal_added = GRN_FALSE; + + GRN_API_ENTER; + + if (name_size == -1) { + name_size = strlen(name); + } + if (input->arguments) { + grn_hash_add(ctx, input->arguments, name, name_size, (void **)&argument, + &internal_added); + if (internal_added) { + GRN_TEXT_INIT(argument, 0); + } + } + if (added) { + *added = internal_added; + } + + GRN_API_RETURN(argument); +} + +grn_obj * +grn_command_input_get(grn_ctx *ctx, + grn_command_input *input, + const char *name, + int name_size) +{ + grn_obj *argument = NULL; + + GRN_API_ENTER; + + if (name_size == -1) { + name_size = strlen(name); + } + if (input->arguments) { + grn_hash_get(ctx, input->arguments, name, name_size, (void **)&argument); + } + + GRN_API_RETURN(argument); +} + +grn_obj * +grn_command_input_at(grn_ctx *ctx, + grn_command_input *input, + unsigned int offset) +{ + grn_obj *argument = NULL; + + GRN_API_ENTER; + if (input->arguments) { + uint32_t size; + argument = (grn_obj *)grn_hash_get_value_(ctx, input->arguments, + offset + 1, &size); + } + GRN_API_RETURN(argument); +} + +grn_rc +grn_command_register(grn_ctx *ctx, + const char *command_name, + int command_name_size, + grn_command_run_func *run, + grn_expr_var *vars, + unsigned int n_vars, + void *user_data) +{ + GRN_API_ENTER; + + if (command_name_size == -1) { + command_name_size = strlen(command_name); + } + + { + grn_obj *command_object; + command_object = grn_proc_create(ctx, + command_name, + command_name_size, + GRN_PROC_COMMAND, + NULL, NULL, NULL, n_vars, vars); + if (!command_object) { + GRN_PLUGIN_ERROR(ctx, GRN_COMMAND_ERROR, + "[command][%.*s] failed to grn_proc_create()", + command_name_size, command_name); + GRN_API_RETURN(ctx->rc); + } + + { + grn_proc *command = (grn_proc *)command_object; + command->callbacks.command.run = run; + command->user_data = user_data; + } + } + + GRN_API_RETURN(GRN_SUCCESS); +} + +grn_rc +grn_command_run(grn_ctx *ctx, + grn_obj *command, + grn_command_input *input) +{ + grn_proc *proc; + + GRN_API_ENTER; + + proc = (grn_proc *)command; + if (proc->callbacks.command.run) { + proc->callbacks.command.run(ctx, command, input, proc->user_data); + } else { + /* TODO: REMOVE ME. For backward compatibility. */ + uint32_t stack_curr = ctx->impl->stack_curr; + grn_proc_call(ctx, command, 0, command); + if (ctx->impl->stack_curr > stack_curr) { + grn_ctx_pop(ctx); + } + } + + GRN_API_RETURN(ctx->rc); +} + Modified: lib/db.c (+1 -0) =================================================================== --- lib/db.c 2015-01-04 23:55:01 +0900 (1be1494) +++ lib/db.c 2015-01-05 00:40:31 +0900 (28b8cbf) @@ -617,6 +617,7 @@ grn_proc_create(grn_ctx *ctx, const char *name, int name_size, grn_proc_type typ res->funcs[PROC_NEXT] = next; res->funcs[PROC_FIN] = fin; res->selector = NULL; + memset(&(res->callbacks), 0, sizeof(res->callbacks)); GRN_TEXT_INIT(&res->name_buf, 0); res->vars = NULL; res->nvars = 0; Modified: lib/expr.c (+10 -1) =================================================================== --- lib/expr.c 2015-01-04 23:55:01 +0900 (c14818e) +++ lib/expr.c 2015-01-05 00:40:31 +0900 (b4e0f1e) @@ -2955,7 +2955,16 @@ grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs) uint32_t stack_curr = ctx->impl->stack_curr; GRN_API_ENTER; if (expr->header.type == GRN_PROC) { - grn_proc_call(ctx, expr, nargs, expr); + grn_proc *proc = (grn_proc *)expr; + if (proc->type == GRN_PROC_COMMAND) { + grn_command_input *input; + input = grn_command_input_open(ctx, expr); + grn_command_run(ctx, expr, input); + grn_command_input_close(ctx, input); + GRN_API_RETURN(NULL); + } else { + grn_proc_call(ctx, expr, nargs, expr); + } } else { grn_expr *e = (grn_expr *)expr; register grn_obj **s_ = ctx->impl->stack, *s0 = NULL, *s1 = NULL, **sp, *vp = e->values; Modified: lib/grn_db.h (+4 -0) =================================================================== --- lib/grn_db.h 2015-01-04 23:55:01 +0900 (252ec92) +++ lib/grn_db.h 2015-01-05 00:40:31 +0900 (67b9c23) @@ -21,6 +21,7 @@ #include "grn_ctx.h" #include "grn_store.h" +#include <groonga/command.h> #include <groonga/token_filter.h> #ifdef __cplusplus @@ -181,6 +182,9 @@ struct _grn_proc { union { struct { + grn_command_run_func *run; + } command; + struct { grn_token_filter_init_func *init; grn_token_filter_filter_func *filter; grn_token_filter_fin_func *fin; Modified: lib/sources.am (+1 -0) =================================================================== --- lib/sources.am 2015-01-04 23:55:01 +0900 (0be9ded) +++ lib/sources.am 2015-01-05 00:40:31 +0900 (4fa37c9) @@ -1,6 +1,7 @@ libgroonga_la_SOURCES = \ com.c \ grn_com.h \ + command.c \ ctx.c \ grn_ctx.h \ grn_ctx_impl.h \ -------------- next part -------------- HTML����������������������������...Download