[Groonga-commit] groonga/groonga at 9c835e1 [master] Split table related commands

Back to archive index

Kouhei Sutou null+****@clear*****
Thu Jan 21 18:11:19 JST 2016


Kouhei Sutou	2016-01-21 18:11:19 +0900 (Thu, 21 Jan 2016)

  New Revision: 9c835e12e26aa2325fe1669b33169fc0972326de
  https://github.com/groonga/groonga/commit/9c835e12e26aa2325fe1669b33169fc0972326de

  Message:
    Split table related commands

  Added files:
    lib/proc/proc_table.c
  Modified files:
    lib/grn_proc.h
    lib/proc.c
    lib/proc/sources.am

  Modified: lib/grn_proc.h (+13 -1)
===================================================================
--- lib/grn_proc.h    2016-01-21 14:24:38 +0900 (ed14930)
+++ lib/grn_proc.h    2016-01-21 18:11:19 +0900 (9603414)
@@ -29,10 +29,22 @@ void grn_proc_init_from_env(void);
 GRN_VAR const char *grn_document_root;
 void grn_db_init_builtin_query(grn_ctx *ctx);
 
-void grn_proc_init_schema(grn_ctx *ctx);
 void grn_proc_init_config_get(grn_ctx *ctx);
 void grn_proc_init_config_set(grn_ctx *ctx);
 void grn_proc_init_config_delete(grn_ctx *ctx);
+void grn_proc_init_schema(grn_ctx *ctx);
+void grn_proc_init_table_create(grn_ctx *ctx);
+void grn_proc_init_table_list(grn_ctx *ctx);
+void grn_proc_init_table_remove(grn_ctx *ctx);
+void grn_proc_init_table_rename(grn_ctx *ctx);
+
+void grn_proc_output_object_name(grn_ctx *ctx, grn_obj *obj);
+void grn_proc_output_object_id_name(grn_ctx *ctx, grn_id id);
+
+void grn_proc_table_set_token_filters(grn_ctx *ctx,
+                                      grn_obj *table,
+                                      grn_obj *token_filter_names);
+
 
 #ifdef __cplusplus
 }

  Modified: lib/proc.c (+14 -450)
===================================================================
--- lib/proc.c    2016-01-21 14:24:38 +0900 (f00a1fd)
+++ lib/proc.c    2016-01-21 18:11:19 +0900 (653c88c)
@@ -1448,42 +1448,6 @@ proc_status(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
 }
 
 static grn_obj_flags
-grn_parse_table_create_flags(grn_ctx *ctx, const char *nptr, const char *end)
-{
-  grn_obj_flags flags = 0;
-  while (nptr < end) {
-    if (*nptr == '|' || *nptr == ' ') {
-      nptr += 1;
-      continue;
-    }
-    if (!memcmp(nptr, "TABLE_HASH_KEY", 14)) {
-      flags |= GRN_OBJ_TABLE_HASH_KEY;
-      nptr += 14;
-    } else if (!memcmp(nptr, "TABLE_PAT_KEY", 13)) {
-      flags |= GRN_OBJ_TABLE_PAT_KEY;
-      nptr += 13;
-    } else if (!memcmp(nptr, "TABLE_DAT_KEY", 13)) {
-      flags |= GRN_OBJ_TABLE_DAT_KEY;
-      nptr += 13;
-    } else if (!memcmp(nptr, "TABLE_NO_KEY", 12)) {
-      flags |= GRN_OBJ_TABLE_NO_KEY;
-      nptr += 12;
-    } else if (!memcmp(nptr, "KEY_NORMALIZE", 13)) {
-      flags |= GRN_OBJ_KEY_NORMALIZE;
-      nptr += 13;
-    } else if (!memcmp(nptr, "KEY_WITH_SIS", 12)) {
-      flags |= GRN_OBJ_KEY_WITH_SIS;
-      nptr += 12;
-    } else {
-      ERR(GRN_INVALID_ARGUMENT, "invalid flags option: %.*s",
-          (int)(end - nptr), nptr);
-      return 0;
-    }
-  }
-  return flags;
-}
-
-static grn_obj_flags
 grn_parse_column_create_flags(grn_ctx *ctx, const char *nptr, const char *end)
 {
   grn_obj_flags flags = 0;
@@ -1528,239 +1492,6 @@ grn_parse_column_create_flags(grn_ctx *ctx, const char *nptr, const char *end)
   return flags;
 }
 
-static grn_bool
-proc_table_create_set_token_filters_put(grn_ctx *ctx,
-                                        grn_obj *token_filters,
-                                        const char *token_filter_name,
-                                        int token_filter_name_length)
-{
-  grn_obj *token_filter;
-
-  token_filter = grn_ctx_get(ctx,
-                             token_filter_name,
-                             token_filter_name_length);
-  if (token_filter) {
-    GRN_PTR_PUT(ctx, token_filters, token_filter);
-    return GRN_TRUE;
-  } else {
-    ERR(GRN_INVALID_ARGUMENT,
-        "[table][create][token-filter] nonexistent token filter: <%.*s>",
-        token_filter_name_length, token_filter_name);
-    return GRN_FALSE;
-  }
-}
-
-static grn_bool
-proc_table_create_set_token_filters_fill(grn_ctx *ctx,
-                                         grn_obj *token_filters,
-                                         grn_obj *token_filter_names)
-{
-  const char *start, *current, *end;
-  const char *name_start, *name_end;
-  const char *last_name_end;
-
-  start = GRN_TEXT_VALUE(token_filter_names);
-  end = start + GRN_TEXT_LEN(token_filter_names);
-  current = start;
-  name_start = NULL;
-  name_end = NULL;
-  last_name_end = start;
-  while (current < end) {
-    switch (current[0]) {
-    case ' ' :
-      if (name_start && !name_end) {
-        name_end = current;
-      }
-      break;
-    case ',' :
-      if (!name_start) {
-        goto break_loop;
-      }
-      if (!name_end) {
-        name_end = current;
-      }
-      proc_table_create_set_token_filters_put(ctx,
-                                              token_filters,
-                                              name_start,
-                                              name_end - name_start);
-      last_name_end = name_end + 1;
-      name_start = NULL;
-      name_end = NULL;
-      break;
-    default :
-      if (!name_start) {
-        name_start = current;
-      }
-      break;
-    }
-    current++;
-  }
-
-break_loop:
-  if (!name_start) {
-    ERR(GRN_INVALID_ARGUMENT,
-        "[table][create][token-filter] empty token filter name: "
-        "<%.*s|%.*s|%.*s>",
-        (int)(last_name_end - start), start,
-        (int)(current - last_name_end), last_name_end,
-        (int)(end - current), current);
-    return GRN_FALSE;
-  }
-
-  if (!name_end) {
-    name_end = current;
-  }
-  proc_table_create_set_token_filters_put(ctx,
-                                          token_filters,
-                                          name_start,
-                                          name_end - name_start);
-
-  return GRN_TRUE;
-}
-
-static void
-proc_table_create_set_token_filters(grn_ctx *ctx,
-                                    grn_obj *table,
-                                    grn_obj *token_filter_names)
-{
-  grn_obj token_filters;
-
-  if (GRN_TEXT_LEN(token_filter_names) == 0) {
-    return;
-  }
-
-  GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, 0);
-  if (proc_table_create_set_token_filters_fill(ctx,
-                                               &token_filters,
-                                               token_filter_names)) {
-    grn_obj_set_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters);
-  }
-  grn_obj_unlink(ctx, &token_filters);
-}
-
-static grn_obj *
-proc_table_create(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
-  grn_obj *table;
-  const char *rest;
-  grn_obj_flags flags = grn_atoi(GRN_TEXT_VALUE(VAR(1)),
-                                 GRN_BULK_CURR(VAR(1)), &rest);
-  if (GRN_TEXT_VALUE(VAR(1)) == rest) {
-    flags = grn_parse_table_create_flags(ctx, GRN_TEXT_VALUE(VAR(1)),
-                                         GRN_BULK_CURR(VAR(1)));
-    if (ctx->rc) { goto exit; }
-  }
-  if (GRN_TEXT_LEN(VAR(0))) {
-    grn_obj *key_type = NULL, *value_type = NULL;
-    if (GRN_TEXT_LEN(VAR(2)) > 0) {
-      key_type = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(2)),
-                             GRN_TEXT_LEN(VAR(2)));
-      if (!key_type) {
-        ERR(GRN_INVALID_ARGUMENT,
-            "[table][create] key type doesn't exist: <%.*s> (%.*s)",
-            (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)),
-            (int)GRN_TEXT_LEN(VAR(2)), GRN_TEXT_VALUE(VAR(2)));
-        return NULL;
-      }
-    }
-    if (GRN_TEXT_LEN(VAR(3)) > 0) {
-      value_type = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(3)),
-                               GRN_TEXT_LEN(VAR(3)));
-      if (!value_type) {
-        ERR(GRN_INVALID_ARGUMENT,
-            "[table][create] value type doesn't exist: <%.*s> (%.*s)",
-            (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)),
-            (int)GRN_TEXT_LEN(VAR(3)), GRN_TEXT_VALUE(VAR(3)));
-        return NULL;
-      }
-    }
-    flags |= GRN_OBJ_PERSISTENT;
-    table = grn_table_create(ctx,
-                             GRN_TEXT_VALUE(VAR(0)),
-                             GRN_TEXT_LEN(VAR(0)),
-                             NULL, flags,
-                             key_type,
-                             value_type);
-    if (table) {
-      grn_obj *normalizer_name;
-      grn_obj_set_info(ctx, table,
-                       GRN_INFO_DEFAULT_TOKENIZER,
-                       grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(4)),
-                                   GRN_TEXT_LEN(VAR(4))));
-      normalizer_name = VAR(5);
-      if (GRN_TEXT_LEN(normalizer_name) > 0) {
-        grn_obj_set_info(ctx, table,
-                         GRN_INFO_NORMALIZER,
-                         grn_ctx_get(ctx,
-                                     GRN_TEXT_VALUE(normalizer_name),
-                                     GRN_TEXT_LEN(normalizer_name)));
-      }
-      proc_table_create_set_token_filters(ctx, table, VAR(6));
-      grn_obj_unlink(ctx, table);
-    }
-  } else {
-    ERR(GRN_INVALID_ARGUMENT,
-        "[table][create] should not create anonymous table");
-  }
-exit :
-  GRN_OUTPUT_BOOL(!ctx->rc);
-  return NULL;
-}
-
-static grn_obj *
-proc_table_remove(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
-  grn_obj *table;
-  table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)),
-                           GRN_TEXT_LEN(VAR(0)));
-  if (table) {
-    grn_obj_remove(ctx,table);
-  } else {
-    ERR(GRN_INVALID_ARGUMENT, "table not found.");
-  }
-  GRN_OUTPUT_BOOL(!ctx->rc);
-  return NULL;
-}
-
-static grn_obj *
-proc_table_rename(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
-  grn_rc rc = GRN_SUCCESS;
-  grn_obj *table = NULL;
-  if (GRN_TEXT_LEN(VAR(0)) == 0) {
-    rc = GRN_INVALID_ARGUMENT;
-    ERR(rc, "[table][rename] table name isn't specified");
-    goto exit;
-  }
-  table = grn_ctx_get(ctx, GRN_TEXT_VALUE(VAR(0)), GRN_TEXT_LEN(VAR(0)));
-  if (!table) {
-    rc = GRN_INVALID_ARGUMENT;
-    ERR(rc,
-        "[table][rename] table isn't found: <%.*s>",
-        (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
-    goto exit;
-  }
-  if (GRN_TEXT_LEN(VAR(1)) == 0) {
-    rc = GRN_INVALID_ARGUMENT;
-    ERR(rc,
-        "[table][rename] new table name isn't specified: <%.*s>",
-        (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)));
-    goto exit;
-  }
-  rc = grn_table_rename(ctx, table,
-                        GRN_TEXT_VALUE(VAR(1)), GRN_TEXT_LEN(VAR(1)));
-  if (rc != GRN_SUCCESS && ctx->rc == GRN_SUCCESS) {
-    ERR(rc,
-        "[table][rename] failed to rename: <%.*s> -> <%.*s>",
-        (int)GRN_TEXT_LEN(VAR(0)), GRN_TEXT_VALUE(VAR(0)),
-        (int)GRN_TEXT_LEN(VAR(1)), GRN_TEXT_VALUE(VAR(1)));
-  }
-exit :
-  GRN_OUTPUT_BOOL(!rc);
-  if (table) { grn_obj_unlink(ctx, table); }
-  return NULL;
-}
-
 static grn_rc
 proc_column_create_resolve_source_name(grn_ctx *ctx,
                                        grn_obj *table,
@@ -2039,8 +1770,8 @@ output_column_name(grn_ctx *ctx, grn_obj *column)
   GRN_OBJ_FIN(ctx, &bulk);
 }
 
-static void
-output_object_name(grn_ctx *ctx, grn_obj *obj)
+void
+grn_proc_output_object_name(grn_ctx *ctx, grn_obj *obj)
 {
   grn_obj bulk;
   int name_len;
@@ -2058,8 +1789,8 @@ output_object_name(grn_ctx *ctx, grn_obj *obj)
   GRN_OBJ_FIN(ctx, &bulk);
 }
 
-static void
-output_object_id_name(grn_ctx *ctx, grn_id id)
+void
+grn_proc_output_object_id_name(grn_ctx *ctx, grn_id id)
 {
   grn_obj *obj = NULL;
 
@@ -2067,7 +1798,7 @@ output_object_id_name(grn_ctx *ctx, grn_id id)
     obj = grn_ctx_at(ctx, id);
   }
 
-  output_object_name(ctx, obj);
+  grn_proc_output_object_name(ctx, obj);
 }
 
 static int
@@ -2102,15 +1833,15 @@ output_column_info(grn_ctx *ctx, grn_obj *column)
   GRN_OUTPUT_CSTR(type);
   grn_dump_column_create_flags(ctx, column->header.flags, &o);
   GRN_OUTPUT_OBJ(&o, NULL);
-  output_object_id_name(ctx, column->header.domain);
-  output_object_id_name(ctx, grn_obj_get_range(ctx, column));
+  grn_proc_output_object_id_name(ctx, column->header.domain);
+  grn_proc_output_object_id_name(ctx, grn_obj_get_range(ctx, column));
   {
     grn_db_obj *obj = (grn_db_obj *)column;
     grn_id *s = obj->source;
     int i = 0, n = obj->source_size / sizeof(grn_id);
     GRN_OUTPUT_ARRAY_OPEN("SOURCES", n);
     for (i = 0; i < n; i++, s++) {
-      output_object_id_name(ctx, *s);
+      grn_proc_output_object_id_name(ctx, *s);
     }
     GRN_OUTPUT_ARRAY_CLOSE();
 
@@ -2200,7 +1931,7 @@ proc_column_list(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_da
         GRN_OUTPUT_OBJ(&buf, NULL);
         name_len = grn_obj_name(ctx, table, name_buf, GRN_TABLE_MAX_KEY_SIZE);
         GRN_OUTPUT_STR(name_buf, name_len);
-        output_object_id_name(ctx, table->header.domain);
+        grn_proc_output_object_id_name(ctx, table->header.domain);
         GRN_OUTPUT_ARRAY_OPEN("SOURCES", 0);
         GRN_OUTPUT_ARRAY_CLOSE();
         GRN_OUTPUT_ARRAY_CLOSE();
@@ -2228,162 +1959,6 @@ proc_column_list(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_da
   return NULL;
 }
 
-static int
-output_table_info(grn_ctx *ctx, grn_obj *table)
-{
-  grn_id id;
-  grn_obj o;
-  const char *path;
-  grn_obj *default_tokenizer;
-  grn_obj *normalizer;
-
-  id = grn_obj_id(ctx, table);
-  path = grn_obj_path(ctx, table);
-  GRN_TEXT_INIT(&o, 0);
-  GRN_OUTPUT_ARRAY_OPEN("TABLE", 8);
-  GRN_OUTPUT_INT64(id);
-  output_object_id_name(ctx, id);
-  GRN_OUTPUT_CSTR(path);
-  GRN_BULK_REWIND(&o);
-  grn_dump_table_create_flags(ctx, table->header.flags, &o);
-  GRN_OUTPUT_OBJ(&o, NULL);
-  output_object_id_name(ctx, table->header.domain);
-  output_object_id_name(ctx, grn_obj_get_range(ctx, table));
-  default_tokenizer = grn_obj_get_info(ctx, table, GRN_INFO_DEFAULT_TOKENIZER,
-                                       NULL);
-  output_object_name(ctx, default_tokenizer);
-  normalizer = grn_obj_get_info(ctx, table, GRN_INFO_NORMALIZER, NULL);
-  output_object_name(ctx, normalizer);
-  grn_obj_unlink(ctx, normalizer);
-  GRN_OUTPUT_ARRAY_CLOSE();
-  GRN_OBJ_FIN(ctx, &o);
-  return 1;
-}
-
-static grn_obj *
-proc_table_list(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
-{
-  grn_obj *db;
-  grn_obj tables;
-  int n_top_level_elements;
-  int n_elements_for_header = 1;
-  int n_tables;
-  int i;
-
-  db = grn_ctx_db(ctx);
-  if (!db) {
-    ERR(GRN_INVALID_ARGUMENT, "[table_list] DB isn't opened");
-    return NULL;
-  }
-
-  {
-    grn_table_cursor *cursor;
-    grn_id id;
-    grn_obj *prefix;
-    const void *min = NULL;
-    unsigned int min_size = 0;
-    int flags = 0;
-
-    prefix = VAR(0);
-    if (GRN_TEXT_LEN(prefix) > 0) {
-      min = GRN_TEXT_VALUE(prefix);
-      min_size = GRN_TEXT_LEN(prefix);
-      flags |= GRN_CURSOR_PREFIX;
-    }
-    cursor = grn_table_cursor_open(ctx, db,
-                                   min, min_size,
-                                   NULL, 0,
-                                   0, -1, flags);
-    if (!cursor) {
-      return NULL;
-    }
-
-    GRN_PTR_INIT(&tables, GRN_OBJ_VECTOR, GRN_ID_NIL);
-    while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
-      grn_obj *object;
-      const char *name;
-      void *key;
-      int i, key_size;
-      grn_bool have_period = GRN_FALSE;
-
-      key_size = grn_table_cursor_get_key(ctx, cursor, &key);
-      name = key;
-      for (i = 0; i < key_size; i++) {
-        if (name[i] == '.') {
-          have_period = GRN_TRUE;
-          break;
-        }
-      }
-      if (have_period) {
-        continue;
-      }
-
-      object = grn_ctx_at(ctx, id);
-      if (object) {
-        if (grn_obj_is_table(ctx, object)) {
-          GRN_PTR_PUT(ctx, &tables, object);
-        } else {
-          grn_obj_unlink(ctx, object);
-        }
-      } else {
-        if (ctx->rc != GRN_SUCCESS) {
-          ERRCLR(ctx);
-        }
-      }
-    }
-    grn_table_cursor_close(ctx, cursor);
-  }
-  n_tables = GRN_BULK_VSIZE(&tables) / sizeof(grn_obj *);
-  n_top_level_elements = n_elements_for_header + n_tables;
-  GRN_OUTPUT_ARRAY_OPEN("TABLE_LIST", n_top_level_elements);
-
-  GRN_OUTPUT_ARRAY_OPEN("HEADER", 8);
-  GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
-  GRN_OUTPUT_CSTR("id");
-  GRN_OUTPUT_CSTR("UInt32");
-  GRN_OUTPUT_ARRAY_CLOSE();
-  GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
-  GRN_OUTPUT_CSTR("name");
-  GRN_OUTPUT_CSTR("ShortText");
-  GRN_OUTPUT_ARRAY_CLOSE();
-  GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
-  GRN_OUTPUT_CSTR("path");
-  GRN_OUTPUT_CSTR("ShortText");
-  GRN_OUTPUT_ARRAY_CLOSE();
-  GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
-  GRN_OUTPUT_CSTR("flags");
-  GRN_OUTPUT_CSTR("ShortText");
-  GRN_OUTPUT_ARRAY_CLOSE();
-  GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
-  GRN_OUTPUT_CSTR("domain");
-  GRN_OUTPUT_CSTR("ShortText");
-  GRN_OUTPUT_ARRAY_CLOSE();
-  GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
-  GRN_OUTPUT_CSTR("range");
-  GRN_OUTPUT_CSTR("ShortText");
-  GRN_OUTPUT_ARRAY_CLOSE();
-  GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
-  GRN_OUTPUT_CSTR("default_tokenizer");
-  GRN_OUTPUT_CSTR("ShortText");
-  GRN_OUTPUT_ARRAY_CLOSE();
-  GRN_OUTPUT_ARRAY_OPEN("PROPERTY", 2);
-  GRN_OUTPUT_CSTR("normalizer");
-  GRN_OUTPUT_CSTR("ShortText");
-  GRN_OUTPUT_ARRAY_CLOSE();
-  GRN_OUTPUT_ARRAY_CLOSE();
-
-  for (i = 0; i < n_tables; i++) {
-    grn_obj *table = GRN_PTR_VALUE_AT(&tables, i);
-    output_table_info(ctx, table);
-    grn_obj_unlink(ctx, table);
-  }
-  GRN_OBJ_FIN(ctx, &tables);
-
-  GRN_OUTPUT_ARRAY_CLOSE();
-
-  return NULL;
-}
-
 static grn_obj *
 proc_missing(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
 {
@@ -4089,7 +3664,7 @@ create_lexicon_for_tokenize(grn_ctx *ctx,
                      GRN_INFO_NORMALIZER, normalizer);
     grn_obj_unlink(ctx, normalizer);
   }
-  proc_table_create_set_token_filters(ctx, lexicon, token_filter_names);
+  grn_proc_table_set_token_filters(ctx, lexicon, token_filter_names);
 
   return lexicon;
 }
@@ -7306,27 +6881,16 @@ grn_db_init_builtin_query(grn_ctx *ctx)
 
   DEF_COMMAND("status", proc_status, 0, vars);
 
-  DEF_VAR(vars[0], "prefix");
-  DEF_COMMAND("table_list", proc_table_list, 1, vars);
+  grn_proc_init_table_list(ctx);
 
   DEF_VAR(vars[0], "table");
   DEF_COMMAND("column_list", proc_column_list, 1, vars);
 
-  DEF_VAR(vars[0], "name");
-  DEF_VAR(vars[1], "flags");
-  DEF_VAR(vars[2], "key_type");
-  DEF_VAR(vars[3], "value_type");
-  DEF_VAR(vars[4], "default_tokenizer");
-  DEF_VAR(vars[5], "normalizer");
-  DEF_VAR(vars[6], "token_filters");
-  DEF_COMMAND("table_create", proc_table_create, 7, vars);
+  grn_proc_init_table_create(ctx);
 
-  DEF_VAR(vars[0], "name");
-  DEF_COMMAND("table_remove", proc_table_remove, 1, vars);
+  grn_proc_init_table_remove(ctx);
 
-  DEF_VAR(vars[0], "name");
-  DEF_VAR(vars[1], "new_name");
-  DEF_COMMAND("table_rename", proc_table_rename, 2, vars);
+  grn_proc_init_table_rename(ctx);
 
   DEF_VAR(vars[0], "table");
   DEF_VAR(vars[1], "name");

  Added: lib/proc/proc_table.c (+575 -0) 100644
===================================================================
--- /dev/null
+++ lib/proc/proc_table.c    2016-01-21 18:11:19 +0900 (090314a)
@@ -0,0 +1,575 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+  Copyright(C) 2009-2016 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_proc.h"
+
+#include "grn_ctx.h"
+#include "grn_str.h"
+
+#include <groonga/plugin.h>
+
+static grn_obj_flags
+command_table_create_parse_flags(grn_ctx *ctx,
+                                 const char *nptr,
+                                 const char *end)
+{
+  grn_obj_flags flags = 0;
+  while (nptr < end) {
+    if (*nptr == '|' || *nptr == ' ') {
+      nptr += 1;
+      continue;
+    }
+    if (!memcmp(nptr, "TABLE_HASH_KEY", 14)) {
+      flags |= GRN_OBJ_TABLE_HASH_KEY;
+      nptr += 14;
+    } else if (!memcmp(nptr, "TABLE_PAT_KEY", 13)) {
+      flags |= GRN_OBJ_TABLE_PAT_KEY;
+      nptr += 13;
+    } else if (!memcmp(nptr, "TABLE_DAT_KEY", 13)) {
+      flags |= GRN_OBJ_TABLE_DAT_KEY;
+      nptr += 13;
+    } else if (!memcmp(nptr, "TABLE_NO_KEY", 12)) {
+      flags |= GRN_OBJ_TABLE_NO_KEY;
+      nptr += 12;
+    } else if (!memcmp(nptr, "KEY_NORMALIZE", 13)) {
+      flags |= GRN_OBJ_KEY_NORMALIZE;
+      nptr += 13;
+    } else if (!memcmp(nptr, "KEY_WITH_SIS", 12)) {
+      flags |= GRN_OBJ_KEY_WITH_SIS;
+      nptr += 12;
+    } else {
+      GRN_PLUGIN_ERROR(ctx,
+                       GRN_INVALID_ARGUMENT,
+                       "[table][create][flags] unknown flag: <%.*s>",
+                       (int)(end - nptr), nptr);
+      return 0;
+    }
+  }
+  return flags;
+}
+
+static grn_bool
+grn_proc_table_set_token_filters_put(grn_ctx *ctx,
+                                     grn_obj *token_filters,
+                                     const char *token_filter_name,
+                                     int token_filter_name_length)
+{
+  grn_obj *token_filter;
+
+  token_filter = grn_ctx_get(ctx,
+                             token_filter_name,
+                             token_filter_name_length);
+  if (token_filter) {
+    GRN_PTR_PUT(ctx, token_filters, token_filter);
+    return GRN_TRUE;
+  } else {
+    GRN_PLUGIN_ERROR(ctx,
+                     GRN_INVALID_ARGUMENT,
+                     "[table][create][token-filter] "
+                     "nonexistent token filter: <%.*s>",
+                     token_filter_name_length, token_filter_name);
+    return GRN_FALSE;
+  }
+}
+
+static grn_bool
+grn_proc_table_set_token_filters_fill(grn_ctx *ctx,
+                                      grn_obj *token_filters,
+                                      grn_obj *token_filter_names)
+{
+  const char *start, *current, *end;
+  const char *name_start, *name_end;
+  const char *last_name_end;
+
+  start = GRN_TEXT_VALUE(token_filter_names);
+  end = start + GRN_TEXT_LEN(token_filter_names);
+  current = start;
+  name_start = NULL;
+  name_end = NULL;
+  last_name_end = start;
+  while (current < end) {
+    switch (current[0]) {
+    case ' ' :
+      if (name_start && !name_end) {
+        name_end = current;
+      }
+      break;
+    case ',' :
+      if (!name_start) {
+        goto break_loop;
+      }
+      if (!name_end) {
+        name_end = current;
+      }
+      grn_proc_table_set_token_filters_put(ctx,
+                                           token_filters,
+                                           name_start,
+                                           name_end - name_start);
+      last_name_end = name_end + 1;
+      name_start = NULL;
+      name_end = NULL;
+      break;
+    default :
+      if (!name_start) {
+        name_start = current;
+      }
+      break;
+    }
+    current++;
+  }
+
+break_loop:
+  if (!name_start) {
+    GRN_PLUGIN_ERROR(ctx,
+                     GRN_INVALID_ARGUMENT,
+                     "[table][create][token-filter] empty token filter name: "
+                     "<%.*s|%.*s|%.*s>",
+                     (int)(last_name_end - start), start,
+                     (int)(current - last_name_end), last_name_end,
+                     (int)(end - current), current);
+    return GRN_FALSE;
+  }
+
+  if (!name_end) {
+    name_end = current;
+  }
+  grn_proc_table_set_token_filters_put(ctx,
+                                       token_filters,
+                                       name_start,
+                                       name_end - name_start);
+
+  return GRN_TRUE;
+}
+
+void
+grn_proc_table_set_token_filters(grn_ctx *ctx,
+                                 grn_obj *table,
+                                 grn_obj *token_filter_names)
+{
+  grn_obj token_filters;
+
+  if (GRN_TEXT_LEN(token_filter_names) == 0) {
+    return;
+  }
+
+  GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, 0);
+  if (grn_proc_table_set_token_filters_fill(ctx,
+                                            &token_filters,
+                                            token_filter_names)) {
+    grn_obj_set_info(ctx, table, GRN_INFO_TOKEN_FILTERS, &token_filters);
+  }
+  grn_obj_unlink(ctx, &token_filters);
+}
+
+static grn_obj *
+command_table_create(grn_ctx *ctx,
+                     int nargs,
+                     grn_obj **args,
+                     grn_user_data *user_data)
+{
+  grn_obj *name;
+  grn_obj *flags_raw;
+  grn_obj *key_type_name;
+  grn_obj *value_type_name;
+  grn_obj *default_tokenizer;
+  grn_obj *normalizer;
+  grn_obj *token_filters;
+  grn_obj *table;
+  const char *rest;
+  grn_obj_flags flags;
+
+  name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+  flags_raw = grn_plugin_proc_get_var(ctx, user_data, "flags", -1);
+  key_type_name = grn_plugin_proc_get_var(ctx, user_data, "key_type", -1);
+  value_type_name = grn_plugin_proc_get_var(ctx, user_data, "value_type", -1);
+  default_tokenizer =
+    grn_plugin_proc_get_var(ctx, user_data, "default_tokenizer", -1);
+  normalizer =
+    grn_plugin_proc_get_var(ctx, user_data, "normalizer", -1);
+  token_filters =
+    grn_plugin_proc_get_var(ctx, user_data, "token_filters", -1);
+
+  flags = grn_atoi(GRN_TEXT_VALUE(flags_raw),
+                   GRN_BULK_CURR(flags_raw),
+                   &rest);
+  if (GRN_TEXT_VALUE(flags_raw) == rest) {
+    flags = command_table_create_parse_flags(ctx,
+                                             GRN_TEXT_VALUE(flags_raw),
+                                             GRN_BULK_CURR(flags_raw));
+    if (ctx->rc) { goto exit; }
+  }
+  if (GRN_TEXT_LEN(name)) {
+    grn_obj *key_type = NULL;
+    grn_obj *value_type = NULL;
+    if (GRN_TEXT_LEN(key_type_name) > 0) {
+      key_type = grn_ctx_get(ctx,
+                             GRN_TEXT_VALUE(key_type_name),
+                             GRN_TEXT_LEN(key_type_name));
+      if (!key_type) {
+        GRN_PLUGIN_ERROR(ctx,
+                         GRN_INVALID_ARGUMENT,
+                         "[table][create] "
+                         "key type doesn't exist: <%.*s> (%.*s)",
+                         (int)GRN_TEXT_LEN(name),
+                         GRN_TEXT_VALUE(name),
+                         (int)GRN_TEXT_LEN(key_type_name),
+                         GRN_TEXT_VALUE(key_type_name));
+        return NULL;
+      }
+    }
+    if (GRN_TEXT_LEN(value_type_name) > 0) {
+      value_type = grn_ctx_get(ctx,
+                               GRN_TEXT_VALUE(value_type_name),
+                               GRN_TEXT_LEN(value_type_name));
+      if (!value_type) {
+        GRN_PLUGIN_ERROR(ctx,
+                         GRN_INVALID_ARGUMENT,
+                         "[table][create] "
+                         "value type doesn't exist: <%.*s> (%.*s)",
+                         (int)GRN_TEXT_LEN(name),
+                         GRN_TEXT_VALUE(name),
+                         (int)GRN_TEXT_LEN(value_type_name),
+                         GRN_TEXT_VALUE(value_type_name));
+        return NULL;
+      }
+    }
+    flags |= GRN_OBJ_PERSISTENT;
+    table = grn_table_create(ctx,
+                             GRN_TEXT_VALUE(name),
+                             GRN_TEXT_LEN(name),
+                             NULL, flags,
+                             key_type,
+                             value_type);
+    if (table) {
+      grn_obj_set_info(ctx, table,
+                       GRN_INFO_DEFAULT_TOKENIZER,
+                       grn_ctx_get(ctx,
+                                   GRN_TEXT_VALUE(default_tokenizer),
+                                   GRN_TEXT_LEN(default_tokenizer)));
+      if (GRN_TEXT_LEN(normalizer) > 0) {
+        grn_obj_set_info(ctx, table,
+                         GRN_INFO_NORMALIZER,
+                         grn_ctx_get(ctx,
+                                     GRN_TEXT_VALUE(normalizer),
+                                     GRN_TEXT_LEN(normalizer)));
+      }
+      grn_proc_table_set_token_filters(ctx, table, token_filters);
+      grn_obj_unlink(ctx, table);
+    }
+  } else {
+    GRN_PLUGIN_ERROR(ctx,
+                     GRN_INVALID_ARGUMENT,
+                     "[table][create] should not create anonymous table");
+  }
+exit :
+  grn_ctx_output_bool(ctx, !ctx->rc);
+  return NULL;
+}
+
+void
+grn_proc_init_table_create(grn_ctx *ctx)
+{
+  grn_expr_var vars[7];
+
+  grn_plugin_expr_var_init(ctx, &(vars[0]), "name", -1);
+  grn_plugin_expr_var_init(ctx, &(vars[1]), "flags", -1);
+  grn_plugin_expr_var_init(ctx, &(vars[2]), "key_type", -1);
+  grn_plugin_expr_var_init(ctx, &(vars[3]), "value_type", -1);
+  grn_plugin_expr_var_init(ctx, &(vars[4]), "default_tokenizer", -1);
+  grn_plugin_expr_var_init(ctx, &(vars[5]), "normalizer", -1);
+  grn_plugin_expr_var_init(ctx, &(vars[6]), "token_filters", -1);
+  grn_plugin_command_create(ctx,
+                            "table_create", -1,
+                            command_table_create,
+                            7,
+                            vars);
+}
+
+static int
+output_table_info(grn_ctx *ctx, grn_obj *table)
+{
+  grn_id id;
+  grn_obj o;
+  const char *path;
+  grn_obj *default_tokenizer;
+  grn_obj *normalizer;
+
+  id = grn_obj_id(ctx, table);
+  path = grn_obj_path(ctx, table);
+  GRN_TEXT_INIT(&o, 0);
+  grn_ctx_output_array_open(ctx, "TABLE", 8);
+  grn_ctx_output_int64(ctx, id);
+  grn_proc_output_object_id_name(ctx, id);
+  grn_ctx_output_cstr(ctx, path);
+  GRN_BULK_REWIND(&o);
+  grn_dump_table_create_flags(ctx, table->header.flags, &o);
+  grn_ctx_output_obj(ctx, &o, NULL);
+  grn_proc_output_object_id_name(ctx, table->header.domain);
+  grn_proc_output_object_id_name(ctx, grn_obj_get_range(ctx, table));
+  default_tokenizer = grn_obj_get_info(ctx, table, GRN_INFO_DEFAULT_TOKENIZER,
+                                       NULL);
+  grn_proc_output_object_name(ctx, default_tokenizer);
+  normalizer = grn_obj_get_info(ctx, table, GRN_INFO_NORMALIZER, NULL);
+  grn_proc_output_object_name(ctx, normalizer);
+  grn_obj_unlink(ctx, normalizer);
+  grn_ctx_output_array_close(ctx);
+  GRN_OBJ_FIN(ctx, &o);
+  return 1;
+}
+
+static grn_obj *
+command_table_list(grn_ctx *ctx, int nargs, grn_obj **args,
+                   grn_user_data *user_data)
+{
+  grn_obj *db;
+  grn_obj tables;
+  int n_top_level_elements;
+  int n_elements_for_header = 1;
+  int n_tables;
+  int i;
+
+  db = grn_ctx_db(ctx);
+
+  {
+    grn_table_cursor *cursor;
+    grn_id id;
+    grn_obj *prefix;
+    const void *min = NULL;
+    unsigned int min_size = 0;
+    int flags = 0;
+
+    prefix = grn_plugin_proc_get_var(ctx, user_data, "prefix", -1);
+    if (GRN_TEXT_LEN(prefix) > 0) {
+      min = GRN_TEXT_VALUE(prefix);
+      min_size = GRN_TEXT_LEN(prefix);
+      flags |= GRN_CURSOR_PREFIX;
+    }
+    cursor = grn_table_cursor_open(ctx, db,
+                                   min, min_size,
+                                   NULL, 0,
+                                   0, -1, flags);
+    if (!cursor) {
+      return NULL;
+    }
+
+    GRN_PTR_INIT(&tables, GRN_OBJ_VECTOR, GRN_ID_NIL);
+    while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+      grn_obj *object;
+      const char *name;
+      void *key;
+      int i, key_size;
+      grn_bool have_period = GRN_FALSE;
+
+      key_size = grn_table_cursor_get_key(ctx, cursor, &key);
+      name = key;
+      for (i = 0; i < key_size; i++) {
+        if (name[i] == '.') {
+          have_period = GRN_TRUE;
+          break;
+        }
+      }
+      if (have_period) {
+        continue;
+      }
+
+      object = grn_ctx_at(ctx, id);
+      if (object) {
+        if (grn_obj_is_table(ctx, object)) {
+          GRN_PTR_PUT(ctx, &tables, object);
+        } else {
+          grn_obj_unlink(ctx, object);
+        }
+      } else {
+        if (ctx->rc != GRN_SUCCESS) {
+          ERRCLR(ctx);
+        }
+      }
+    }
+    grn_table_cursor_close(ctx, cursor);
+  }
+  n_tables = GRN_BULK_VSIZE(&tables) / sizeof(grn_obj *);
+  n_top_level_elements = n_elements_for_header + n_tables;
+  grn_ctx_output_array_open(ctx, "TABLE_LIST", n_top_level_elements);
+
+  grn_ctx_output_array_open(ctx, "HEADER", 8);
+  grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+  grn_ctx_output_cstr(ctx, "id");
+  grn_ctx_output_cstr(ctx, "UInt32");
+  grn_ctx_output_array_close(ctx);
+  grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+  grn_ctx_output_cstr(ctx, "name");
+  grn_ctx_output_cstr(ctx, "ShortText");
+  grn_ctx_output_array_close(ctx);
+  grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+  grn_ctx_output_cstr(ctx, "path");
+  grn_ctx_output_cstr(ctx, "ShortText");
+  grn_ctx_output_array_close(ctx);
+  grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+  grn_ctx_output_cstr(ctx, "flags");
+  grn_ctx_output_cstr(ctx, "ShortText");
+  grn_ctx_output_array_close(ctx);
+  grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+  grn_ctx_output_cstr(ctx, "domain");
+  grn_ctx_output_cstr(ctx, "ShortText");
+  grn_ctx_output_array_close(ctx);
+  grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+  grn_ctx_output_cstr(ctx, "range");
+  grn_ctx_output_cstr(ctx, "ShortText");
+  grn_ctx_output_array_close(ctx);
+  grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+  grn_ctx_output_cstr(ctx, "default_tokenizer");
+  grn_ctx_output_cstr(ctx, "ShortText");
+  grn_ctx_output_array_close(ctx);
+  grn_ctx_output_array_open(ctx, "PROPERTY", 2);
+  grn_ctx_output_cstr(ctx, "normalizer");
+  grn_ctx_output_cstr(ctx, "ShortText");
+  grn_ctx_output_array_close(ctx);
+  grn_ctx_output_array_close(ctx);
+
+  for (i = 0; i < n_tables; i++) {
+    grn_obj *table = GRN_PTR_VALUE_AT(&tables, i);
+    output_table_info(ctx, table);
+    grn_obj_unlink(ctx, table);
+  }
+  GRN_OBJ_FIN(ctx, &tables);
+
+  grn_ctx_output_array_close(ctx);
+
+  return NULL;
+}
+
+void
+grn_proc_init_table_list(grn_ctx *ctx)
+{
+  grn_expr_var vars[1];
+
+  grn_plugin_expr_var_init(ctx, &(vars[0]), "prefix", -1);
+  grn_plugin_command_create(ctx,
+                            "table_list", -1,
+                            command_table_list,
+                            1,
+                            vars);
+}
+
+static grn_obj *
+command_table_remove(grn_ctx *ctx,
+                     int nargs,
+                     grn_obj **args,
+                     grn_user_data *user_data)
+{
+  grn_obj *name;
+  grn_obj *table;
+
+  name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+  table = grn_ctx_get(ctx,
+                      GRN_TEXT_VALUE(name),
+                      GRN_TEXT_LEN(name));
+  if (table) {
+    grn_obj_remove(ctx,table);
+  } else {
+    GRN_PLUGIN_ERROR(ctx,
+                     GRN_INVALID_ARGUMENT,
+                     "[table][remove] table isn't found: <%.*s>",
+                     (int)GRN_TEXT_LEN(name),
+                     GRN_TEXT_VALUE(name));
+  }
+  grn_ctx_output_bool(ctx, !ctx->rc);
+  return NULL;
+}
+
+void
+grn_proc_init_table_remove(grn_ctx *ctx)
+{
+  grn_expr_var vars[1];
+
+  grn_plugin_expr_var_init(ctx, &(vars[0]), "name", -1);
+  grn_plugin_command_create(ctx,
+                            "table_remove", -1,
+                            command_table_remove,
+                            1,
+                            vars);
+}
+
+static grn_obj *
+command_table_rename(grn_ctx *ctx,
+                     int nargs,
+                     grn_obj **args,
+                     grn_user_data *user_data)
+{
+  grn_rc rc = GRN_SUCCESS;
+  grn_obj *name;
+  grn_obj *new_name;
+  grn_obj *table = NULL;
+
+  name = grn_plugin_proc_get_var(ctx, user_data, "name", -1);
+  new_name = grn_plugin_proc_get_var(ctx, user_data, "new_name", -1);
+  if (GRN_TEXT_LEN(name) == 0) {
+    rc = GRN_INVALID_ARGUMENT;
+    GRN_PLUGIN_ERROR(ctx, rc, "[table][rename] table name isn't specified");
+    goto exit;
+  }
+  table = grn_ctx_get(ctx, GRN_TEXT_VALUE(name), GRN_TEXT_LEN(name));
+  if (!table) {
+    rc = GRN_INVALID_ARGUMENT;
+    GRN_PLUGIN_ERROR(ctx,
+                     rc,
+                     "[table][rename] table isn't found: <%.*s>",
+                     (int)GRN_TEXT_LEN(name),
+                     GRN_TEXT_VALUE(name));
+    goto exit;
+  }
+  if (GRN_TEXT_LEN(new_name) == 0) {
+    rc = GRN_INVALID_ARGUMENT;
+    GRN_PLUGIN_ERROR(ctx,
+                     rc,
+                     "[table][rename] new table name isn't specified: <%.*s>",
+                     (int)GRN_TEXT_LEN(name),
+                     GRN_TEXT_VALUE(name));
+    goto exit;
+  }
+  rc = grn_table_rename(ctx, table,
+                        GRN_TEXT_VALUE(new_name),
+                        GRN_TEXT_LEN(new_name));
+  if (rc != GRN_SUCCESS && ctx->rc == GRN_SUCCESS) {
+    GRN_PLUGIN_ERROR(ctx,
+                     rc,
+                     "[table][rename] failed to rename: <%.*s> -> <%.*s>",
+                     (int)GRN_TEXT_LEN(name),
+                     GRN_TEXT_VALUE(name),
+                     (int)GRN_TEXT_LEN(new_name),
+                     GRN_TEXT_VALUE(new_name));
+  }
+exit :
+  grn_ctx_output_bool(ctx, !rc);
+  if (table) { grn_obj_unlink(ctx, table); }
+  return NULL;
+}
+
+void
+grn_proc_init_table_rename(grn_ctx *ctx)
+{
+  grn_expr_var vars[2];
+
+  grn_plugin_expr_var_init(ctx, &(vars[0]), "name", -1);
+  grn_plugin_expr_var_init(ctx, &(vars[1]), "new_name", -1);
+  grn_plugin_command_create(ctx,
+                            "table_rename", -1,
+                            command_table_rename,
+                            1,
+                            vars);
+}

  Modified: lib/proc/sources.am (+2 -1)
===================================================================
--- lib/proc/sources.am    2016-01-21 14:24:38 +0900 (4c224a1)
+++ lib/proc/sources.am    2016-01-21 18:11:19 +0900 (a9818ba)
@@ -1,3 +1,4 @@
 libgrnproc_la_SOURCES =				\
 	proc_config.c				\
-	proc_schema.c
+	proc_schema.c				\
+	proc_table.c
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index