[Groonga-commit] groonga/groonga at 8de4784 [master] Add table_copy commnad

Back to archive index

Kouhei Sutou null+****@clear*****
Mon Aug 15 15:55:35 JST 2016


Kouhei Sutou	2016-08-15 15:55:35 +0900 (Mon, 15 Aug 2016)

  New Revision: 8de4784cba6fe0794abf9640c20d4c7cc33c1eb0
  https://github.com/groonga/groonga/commit/8de4784cba6fe0794abf9640c20d4c7cc33c1eb0

  Message:
    Add table_copy commnad
    
    TODO:
    
      * Document

  Added files:
    test/command/suite/table_copy/different.expected
    test/command/suite/table_copy/different.test
    test/command/suite/table_copy/no_key.expected
    test/command/suite/table_copy/no_key.test
    test/command/suite/table_copy/same_key_type.expected
    test/command/suite/table_copy/same_key_type.test
    test/command/suite/table_copy/same_table.expected
    test/command/suite/table_copy/same_table.test
  Modified files:
    lib/grn_proc.h
    lib/proc.c
    lib/proc/proc_table.c

  Modified: lib/grn_proc.h (+1 -0)
===================================================================
--- lib/grn_proc.h    2016-08-14 14:49:15 +0900 (a2ca3d0)
+++ lib/grn_proc.h    2016-08-15 15:55:35 +0900 (78058b4)
@@ -62,6 +62,7 @@ void grn_proc_init_schema(grn_ctx *ctx);
 void grn_proc_init_select(grn_ctx *ctx);
 void grn_proc_init_snippet(grn_ctx *ctx);
 void grn_proc_init_snippet_html(grn_ctx *ctx);
+void grn_proc_init_table_copy(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);

  Modified: lib/proc.c (+2 -0)
===================================================================
--- lib/proc.c    2016-08-14 14:49:15 +0900 (aeca678)
+++ lib/proc.c    2016-08-15 15:55:35 +0900 (36cccfa)
@@ -3587,4 +3587,6 @@ grn_db_init_builtin_commands(grn_ctx *ctx)
   grn_proc_init_query_expand(ctx);
 
   grn_proc_init_object_list(ctx);
+
+  grn_proc_init_table_copy(ctx);
 }

  Modified: lib/proc/proc_table.c (+250 -0)
===================================================================
--- lib/proc/proc_table.c    2016-08-14 14:49:15 +0900 (7a6aadf)
+++ lib/proc/proc_table.c    2016-08-15 15:55:35 +0900 (3501555)
@@ -658,3 +658,253 @@ grn_proc_init_table_rename(grn_ctx *ctx)
                             2,
                             vars);
 }
+
+static grn_rc
+command_table_copy_resolve_target(grn_ctx *ctx,
+                                  const char *label,
+                                  grn_obj *name,
+                                  grn_obj **table)
+{
+  if (GRN_TEXT_LEN(name) == 0) {
+    GRN_PLUGIN_ERROR(ctx,
+                     GRN_INVALID_ARGUMENT,
+                     "[table][copy] %s name isn't specified",
+                     label);
+    return ctx->rc;
+  }
+  *table = grn_ctx_get(ctx,
+                       GRN_TEXT_VALUE(name),
+                       GRN_TEXT_LEN(name));
+  if (!*table) {
+    GRN_PLUGIN_ERROR(ctx,
+                     GRN_INVALID_ARGUMENT,
+                     "[table][copy] %s table isn't found: <%.*s>",
+                     label,
+                     (int)GRN_TEXT_LEN(name),
+                     GRN_TEXT_VALUE(name));
+    return ctx->rc;
+  }
+
+  return ctx->rc;
+}
+
+static void
+command_table_copy_same_key_type(grn_ctx *ctx,
+                                 grn_obj *from_table,
+                                 grn_obj *to_table,
+                                 grn_obj *from_name,
+                                 grn_obj *to_name)
+{
+  GRN_TABLE_EACH_BEGIN_FLAGS(ctx, from_table, cursor, from_id,
+                             GRN_CURSOR_BY_KEY | GRN_CURSOR_ASCENDING) {
+    void   *key;
+    int     key_size;
+    grn_id  to_id;
+
+    key_size = grn_table_cursor_get_key(ctx, cursor, &key);
+    to_id    = grn_table_add(ctx, to_table, key, key_size, NULL);
+    if (to_id == GRN_ID_NIL) {
+      grn_obj key_buffer;
+      grn_obj inspected_key;
+      if (from_table->header.domain == GRN_DB_SHORT_TEXT) {
+        GRN_SHORT_TEXT_INIT(&key_buffer, 0);
+      } else {
+        GRN_VALUE_FIX_SIZE_INIT(&key_buffer, 0, from_table->header.domain);
+      }
+      grn_bulk_write(ctx, &key_buffer, key, key_size);
+      GRN_TEXT_INIT(&inspected_key, 0);
+      grn_inspect(ctx, &inspected_key, &key_buffer);
+      GRN_PLUGIN_ERROR(ctx,
+                       GRN_INVALID_ARGUMENT,
+                       "[table][copy] failed to copy key: <%.*s>: "
+                       "<%.*s> -> <%.*s>",
+                       (int)GRN_TEXT_LEN(&inspected_key),
+                       GRN_TEXT_VALUE(&inspected_key),
+                       (int)GRN_TEXT_LEN(from_name),
+                       GRN_TEXT_VALUE(from_name),
+                       (int)GRN_TEXT_LEN(to_name),
+                       GRN_TEXT_VALUE(to_name));
+      GRN_OBJ_FIN(ctx, &inspected_key);
+      GRN_OBJ_FIN(ctx, &key_buffer);
+      break;
+    }
+  } GRN_TABLE_EACH_END(ctx, cursor);
+}
+
+static void
+command_table_copy_different(grn_ctx *ctx,
+                              grn_obj *from_table,
+                              grn_obj *to_table,
+                              grn_obj *from_name,
+                              grn_obj *to_name)
+{
+  grn_obj from_key_buffer;
+  grn_obj to_key_buffer;
+
+  if (from_table->header.domain == GRN_DB_SHORT_TEXT) {
+    GRN_SHORT_TEXT_INIT(&from_key_buffer, 0);
+  } else {
+    GRN_VALUE_FIX_SIZE_INIT(&from_key_buffer, 0, from_table->header.domain);
+  }
+  if (to_table->header.domain == GRN_DB_SHORT_TEXT) {
+    GRN_SHORT_TEXT_INIT(&to_key_buffer, 0);
+  } else {
+    GRN_VALUE_FIX_SIZE_INIT(&to_key_buffer, 0, to_table->header.domain);
+  }
+
+  GRN_TABLE_EACH_BEGIN_FLAGS(ctx, from_table, cursor, from_id,
+                             GRN_CURSOR_BY_KEY | GRN_CURSOR_ASCENDING) {
+    void *key;
+    int key_size;
+    grn_rc cast_rc;
+    grn_id to_id;
+
+    GRN_BULK_REWIND(&from_key_buffer);
+    GRN_BULK_REWIND(&to_key_buffer);
+
+    key_size = grn_table_cursor_get_key(ctx, cursor, &key);
+    grn_bulk_write(ctx, &from_key_buffer, key, key_size);
+    cast_rc = grn_obj_cast(ctx, &from_key_buffer, &to_key_buffer, GRN_FALSE);
+    if (cast_rc != GRN_SUCCESS) {
+      grn_obj *to_key_type;
+      grn_obj inspected_key;
+      grn_obj inspected_to_key_type;
+
+      to_key_type = grn_ctx_at(ctx, to_table->header.domain);
+      GRN_TEXT_INIT(&inspected_key, 0);
+      GRN_TEXT_INIT(&inspected_to_key_type, 0);
+      grn_inspect(ctx, &inspected_key, &from_key_buffer);
+      grn_inspect(ctx, &inspected_to_key_type, to_key_type);
+      ERR(cast_rc,
+          "[table][copy] failed to cast key: <%.*s> -> %.*s: "
+          "<%.*s> -> <%.*s>",
+          (int)GRN_TEXT_LEN(&inspected_key),
+          GRN_TEXT_VALUE(&inspected_key),
+          (int)GRN_TEXT_LEN(&inspected_to_key_type),
+          GRN_TEXT_VALUE(&inspected_to_key_type),
+          (int)GRN_TEXT_LEN(from_name),
+          GRN_TEXT_VALUE(from_name),
+          (int)GRN_TEXT_LEN(to_name),
+          GRN_TEXT_VALUE(to_name));
+      GRN_OBJ_FIN(ctx, &inspected_key);
+      GRN_OBJ_FIN(ctx, &inspected_to_key_type);
+      break;
+    }
+
+    to_id = grn_table_add(ctx, to_table,
+                          GRN_BULK_HEAD(&to_key_buffer),
+                          GRN_BULK_VSIZE(&to_key_buffer),
+                          NULL);
+    if (to_id == GRN_ID_NIL) {
+      grn_obj inspected_from_key;
+      grn_obj inspected_to_key;
+      GRN_TEXT_INIT(&inspected_from_key, 0);
+      GRN_TEXT_INIT(&inspected_to_key, 0);
+      grn_inspect(ctx, &inspected_from_key, &from_key_buffer);
+      grn_inspect(ctx, &inspected_to_key, &to_key_buffer);
+      GRN_PLUGIN_ERROR(ctx,
+                       GRN_INVALID_ARGUMENT,
+                       "[table][copy] failed to copy key: <%.*s> -> <%.*s>: "
+                       "<%.*s> -> <%.*s>",
+                       (int)GRN_TEXT_LEN(&inspected_from_key),
+                       GRN_TEXT_VALUE(&inspected_from_key),
+                       (int)GRN_TEXT_LEN(&inspected_to_key),
+                       GRN_TEXT_VALUE(&inspected_to_key),
+                       (int)GRN_TEXT_LEN(from_name),
+                       GRN_TEXT_VALUE(from_name),
+                       (int)GRN_TEXT_LEN(to_name),
+                       GRN_TEXT_VALUE(to_name));
+      GRN_OBJ_FIN(ctx, &inspected_from_key);
+      GRN_OBJ_FIN(ctx, &inspected_to_key);
+      break;
+    }
+  } GRN_TABLE_EACH_END(ctx, cursor);
+  GRN_OBJ_FIN(ctx, &from_key_buffer);
+  GRN_OBJ_FIN(ctx, &to_key_buffer);
+}
+
+static grn_obj *
+command_table_copy(grn_ctx *ctx,
+                   int nargs,
+                   grn_obj **args,
+                   grn_user_data *user_data)
+{
+  grn_rc rc = GRN_SUCCESS;
+  grn_obj *from_table = NULL;
+  grn_obj *to_table = NULL;
+  grn_obj *from_name;
+  grn_obj *to_name;
+
+  from_name = grn_plugin_proc_get_var(ctx, user_data, "from_name", -1);
+  to_name   = grn_plugin_proc_get_var(ctx, user_data, "to_name", -1);
+
+  rc = command_table_copy_resolve_target(ctx, "from", from_name, &from_table);
+  if (rc != GRN_SUCCESS) {
+    goto exit;
+  }
+  rc = command_table_copy_resolve_target(ctx, "to", to_name, &to_table);
+  if (rc != GRN_SUCCESS) {
+    goto exit;
+  }
+
+  if (from_table->header.type == GRN_TABLE_NO_KEY ||
+      to_table->header.type == GRN_TABLE_NO_KEY) {
+    GRN_PLUGIN_ERROR(ctx,
+                     GRN_OPERATION_NOT_SUPPORTED,
+                     "[table][copy] copy from/to TABLE_NO_KEY isn't supported: "
+                     "<%.*s> -> <%.*s>",
+                     (int)GRN_TEXT_LEN(from_name),
+                     GRN_TEXT_VALUE(from_name),
+                     (int)GRN_TEXT_LEN(to_name),
+                     GRN_TEXT_VALUE(to_name));
+    rc = ctx->rc;
+    goto exit;
+  }
+
+  if (from_table == to_table) {
+    GRN_PLUGIN_ERROR(ctx,
+                     GRN_OPERATION_NOT_SUPPORTED,
+                     "[table][copy] from table and to table is the same: "
+                     "<%.*s>",
+                     (int)GRN_TEXT_LEN(from_name),
+                     GRN_TEXT_VALUE(from_name));
+    rc = ctx->rc;
+    goto exit;
+  }
+
+  if (from_table->header.domain == to_table->header.domain) {
+    command_table_copy_same_key_type(ctx,
+                                     from_table, to_table,
+                                     from_name, to_name);
+  } else {
+    command_table_copy_different(ctx,
+                                 from_table, to_table,
+                                 from_name, to_name);
+  }
+
+exit :
+  grn_ctx_output_bool(ctx, rc == GRN_SUCCESS);
+
+  if (to_table) {
+    grn_obj_unlink(ctx, to_table);
+  }
+  if (from_table) {
+    grn_obj_unlink(ctx, from_table);
+  }
+
+  return NULL;
+}
+
+void
+grn_proc_init_table_copy(grn_ctx *ctx)
+{
+  grn_expr_var vars[2];
+
+  grn_plugin_expr_var_init(ctx, &(vars[0]), "from_name", -1);
+  grn_plugin_expr_var_init(ctx, &(vars[1]), "to_name", -1);
+  grn_plugin_command_create(ctx,
+                            "table_copy", -1,
+                            command_table_copy,
+                            2,
+                            vars);
+}

  Added: test/command/suite/table_copy/different.expected (+29 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/table_copy/different.expected    2016-08-15 15:55:35 +0900 (ce04f58)
@@ -0,0 +1,29 @@
+table_create SmallNumbers TABLE_HASH_KEY UInt8
+[[0,0.0,0.0],true]
+load --table SmallNumbers
+[
+{"_key": 10},
+{"_key": 20},
+{"_key": 30}
+]
+[[0,0.0,0.0],3]
+table_create LargeNumbers TABLE_HASH_KEY UInt64
+[[0,0.0,0.0],true]
+table_copy SmallNumbers LargeNumbers
+[[0,0.0,0.0],true]
+dump --dump_schema no
+load --table SmallNumbers
+[
+["_key"],
+[10],
+[20],
+[30]
+]
+
+load --table LargeNumbers
+[
+["_key"],
+[10],
+[20],
+[30]
+]

  Added: test/command/suite/table_copy/different.test (+14 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/table_copy/different.test    2016-08-15 15:55:35 +0900 (df504d3)
@@ -0,0 +1,14 @@
+table_create SmallNumbers TABLE_HASH_KEY UInt8
+
+load --table SmallNumbers
+[
+{"_key": 10},
+{"_key": 20},
+{"_key": 30}
+]
+
+table_create LargeNumbers TABLE_HASH_KEY UInt64
+
+table_copy SmallNumbers LargeNumbers
+
+dump --dump_schema no

  Added: test/command/suite/table_copy/no_key.expected (+24 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/table_copy/no_key.expected    2016-08-15 15:55:35 +0900 (cde4b70)
@@ -0,0 +1,24 @@
+table_create Logs TABLE_NO_KEY
+[[0,0.0,0.0],true]
+load --table Logs
+[
+{},
+{},
+{}
+]
+[[0,0.0,0.0],3]
+table_create ApplicationLogs TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+table_copy Logs ApplicationLogs
+[
+  [
+    [
+      -58,
+      0.0,
+      0.0
+    ],
+    "[table][copy] copy from/to TABLE_NO_KEY isn't supported: <Logs> -> <ApplicationLogs>"
+  ],
+  false
+]
+#|e| [table][copy] copy from/to TABLE_NO_KEY isn't supported: <Logs> -> <ApplicationLogs>

  Added: test/command/suite/table_copy/no_key.test (+12 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/table_copy/no_key.test    2016-08-15 15:55:35 +0900 (cf52bc3)
@@ -0,0 +1,12 @@
+table_create Logs TABLE_NO_KEY
+
+load --table Logs
+[
+{},
+{},
+{}
+]
+
+table_create ApplicationLogs TABLE_HASH_KEY ShortText
+
+table_copy Logs ApplicationLogs

  Added: test/command/suite/table_copy/same_key_type.expected (+29 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/table_copy/same_key_type.expected    2016-08-15 15:55:35 +0900 (a77a709)
@@ -0,0 +1,29 @@
+table_create Users TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+load --table Users
+[
+{"_key": "alice"},
+{"_key": "bob"},
+{"_key": "charlie"}
+]
+[[0,0.0,0.0],3]
+table_create Friends TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_copy Users Friends
+[[0,0.0,0.0],true]
+dump --dump_schema no
+load --table Users
+[
+["_key"],
+["alice"],
+["bob"],
+["charlie"]
+]
+
+load --table Friends
+[
+["_key"],
+["alice"],
+["bob"],
+["charlie"]
+]

  Added: test/command/suite/table_copy/same_key_type.test (+14 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/table_copy/same_key_type.test    2016-08-15 15:55:35 +0900 (0ecb1b9)
@@ -0,0 +1,14 @@
+table_create Users TABLE_HASH_KEY ShortText
+
+load --table Users
+[
+{"_key": "alice"},
+{"_key": "bob"},
+{"_key": "charlie"}
+]
+
+table_create Friends TABLE_PAT_KEY ShortText
+
+table_copy Users Friends
+
+dump --dump_schema no

  Added: test/command/suite/table_copy/same_table.expected (+22 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/table_copy/same_table.expected    2016-08-15 15:55:35 +0900 (c675f78)
@@ -0,0 +1,22 @@
+table_create Logs TABLE_DAT_KEY UInt64
+[[0,0.0,0.0],true]
+load --table Logs
+[
+{"_key": 0},
+{"_key": 1},
+{"_key": 2}
+]
+[[0,0.0,0.0],3]
+table_copy Logs Logs
+[
+  [
+    [
+      -58,
+      0.0,
+      0.0
+    ],
+    "[table][copy] from table and to table is the same: <Logs>"
+  ],
+  false
+]
+#|e| [table][copy] from table and to table is the same: <Logs>

  Added: test/command/suite/table_copy/same_table.test (+10 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/table_copy/same_table.test    2016-08-15 15:55:35 +0900 (ed2d631)
@@ -0,0 +1,10 @@
+table_create Logs TABLE_DAT_KEY UInt64
+
+load --table Logs
+[
+{"_key": 0},
+{"_key": 1},
+{"_key": 2}
+]
+
+table_copy Logs Logs
-------------- next part --------------
HTML����������������������������...
Download 



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