Kouhei Sutou 2018-12-18 16:30:19 +0900 (Tue, 18 Dec 2018) Revision: 5fbeecb9abddf2f878f866b59a8242c82e93ce76 https://github.com/groonga/groonga/commit/5fbeecb9abddf2f878f866b59a8242c82e93ce76 Message: Extract grn_column_copy() Modified files: include/groonga/column.h lib/column.c lib/proc/proc_column.c Modified: include/groonga/column.h (+4 -0) =================================================================== --- include/groonga/column.h 2018-12-18 15:45:07 +0900 (cfdff27f7) +++ include/groonga/column.h 2018-12-18 16:30:19 +0900 (340ed6cc5) @@ -1,5 +1,6 @@ /* Copyright(C) 2009-2017 Brazil + Copyright(C) 2018 Kouhei Sutou <kou****@clear*****> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -33,6 +34,9 @@ GRN_API void *grn_column_cache_ref(grn_ctx *ctx, grn_id id, size_t *value_size); +GRN_API grn_rc +grn_column_copy(grn_ctx *ctx, grn_obj *from, grn_obj *to); + #ifdef __cplusplus } #endif Modified: lib/column.c (+242 -0) =================================================================== --- lib/column.c 2018-12-18 15:45:07 +0900 (4b2d902c3) +++ lib/column.c 2018-12-18 16:30:19 +0900 (8002378db) @@ -1,6 +1,7 @@ /* -*- c-basic-offset: 2 -*- */ /* Copyright(C) 2009-2017 Brazil + Copyright(C) 2018 Kouhei Sutou <kou****@clear*****> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -116,3 +117,244 @@ grn_column_cache_ref(grn_ctx *ctx, GRN_API_RETURN(value); } + +static void +grn_column_copy_same_table(grn_ctx *ctx, + grn_obj *table, + grn_obj *from_column, + grn_obj *to_column) +{ + grn_table_cursor *cursor; + grn_id id; + grn_obj value; + + cursor = grn_table_cursor_open(ctx, table, + NULL, 0, + NULL, 0, + 0, -1, 0); + if (!cursor) { + return; + } + + GRN_VOID_INIT(&value); + while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx, from_column, id, &value); + grn_obj_set_value(ctx, to_column, id, &value, GRN_OBJ_SET); + } + GRN_OBJ_FIN(ctx, &value); + grn_table_cursor_close(ctx, cursor); +} + +static void +grn_column_copy_same_key_type(grn_ctx *ctx, + grn_obj *from_table, + grn_obj *from_column, + grn_obj *to_table, + grn_obj *to_column) +{ + grn_table_cursor *cursor; + grn_id from_id; + grn_obj value; + + cursor = grn_table_cursor_open(ctx, from_table, + NULL, 0, + NULL, 0, + 0, -1, 0); + if (!cursor) { + return; + } + + GRN_VOID_INIT(&value); + while ((from_id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { + 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) { + char from_name[GRN_TABLE_MAX_KEY_SIZE]; + int from_name_size; + char to_name[GRN_TABLE_MAX_KEY_SIZE]; + int to_name_size; + grn_obj key_buffer; + grn_obj inspected_key; + + from_name_size = grn_obj_name(ctx, + from_column, + from_name, + sizeof(from_name)); + to_name_size = grn_obj_name(ctx, + to_column, + to_name, + sizeof(to_name)); + 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_inspect(ctx, &inspected_key, &key_buffer); + ERR(GRN_INVALID_ARGUMENT, + "[column][copy] failed to copy key: <%.*s>: " + "<%.*s> -> <%.*s>", + (int)GRN_TEXT_LEN(&inspected_key), + GRN_TEXT_VALUE(&inspected_key), + from_name_size, from_name, + to_name_size, to_name); + GRN_OBJ_FIN(ctx, &inspected_key); + GRN_OBJ_FIN(ctx, &key_buffer); + break; + } + + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx, from_column, from_id, &value); + grn_obj_set_value(ctx, to_column, to_id, &value, GRN_OBJ_SET); + } + GRN_OBJ_FIN(ctx, &value); + grn_table_cursor_close(ctx, cursor); +} + +static void +grn_column_copy_different(grn_ctx *ctx, + grn_obj *from_table, + grn_obj *from_column, + grn_obj *to_table, + grn_obj *to_column) +{ + grn_table_cursor *cursor; + grn_id from_id; + grn_obj from_key_buffer; + grn_obj to_key_buffer; + grn_obj value; + + cursor = grn_table_cursor_open(ctx, from_table, + NULL, 0, + NULL, 0, + 0, -1, 0); + if (!cursor) { + return; + } + + 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_VOID_INIT(&value); + while ((from_id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { + 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) { + char from_name[GRN_TABLE_MAX_KEY_SIZE]; + int from_name_size; + char to_name[GRN_TABLE_MAX_KEY_SIZE]; + int to_name_size; + grn_obj *to_key_type; + grn_obj inspected_key; + grn_obj inspected_to_key_type; + + from_name_size = grn_obj_name(ctx, + from_column, + from_name, + sizeof(from_name)); + to_name_size = grn_obj_name(ctx, + to_column, + to_name, + sizeof(to_name)); + 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, + "[column][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), + from_name_size, from_name, + to_name_size, 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) { + continue; + } + + GRN_BULK_REWIND(&value); + grn_obj_get_value(ctx, from_column, from_id, &value); + grn_obj_set_value(ctx, to_column, to_id, &value, GRN_OBJ_SET); + } + GRN_OBJ_FIN(ctx, &from_key_buffer); + GRN_OBJ_FIN(ctx, &to_key_buffer); + GRN_OBJ_FIN(ctx, &value); + + grn_table_cursor_close(ctx, cursor); +} + +grn_rc +grn_column_copy(grn_ctx *ctx, grn_obj *from, grn_obj *to) +{ + grn_obj *from_table; + grn_obj *to_table; + + GRN_API_ENTER; + + from_table = grn_ctx_at(ctx, from->header.domain); + to_table = grn_ctx_at(ctx, to->header.domain); + if ((from_table->header.type == GRN_TABLE_NO_KEY || + to_table->header.type == GRN_TABLE_NO_KEY) && + from_table != to_table) { + char from_name[GRN_TABLE_MAX_KEY_SIZE]; + int from_name_size; + char to_name[GRN_TABLE_MAX_KEY_SIZE]; + int to_name_size; + + from_name_size = grn_obj_name(ctx, from, from_name, sizeof(from_name)); + to_name_size = grn_obj_name(ctx, to, to_name, sizeof(to_name)); + ERR(GRN_OPERATION_NOT_SUPPORTED, + "[column][copy] copy from/to TABLE_NO_KEY isn't supported: " + "<%.*s> -> <%.*s>", + from_name_size, from_name, + to_name_size, to_name); + goto exit; + } + + if (from_table == to_table) { + grn_column_copy_same_table(ctx, from_table, from, to); + } else if (from_table->header.domain == to_table->header.domain) { + grn_column_copy_same_key_type(ctx, + from_table, from, + to_table, to); + } else { + grn_column_copy_different(ctx, + from_table, from, + to_table, to); + } + +exit : + GRN_API_RETURN(ctx->rc); +} + Modified: lib/proc/proc_column.c (+2 -199) =================================================================== --- lib/proc/proc_column.c 2018-12-18 15:45:07 +0900 (fa6dacf86) +++ lib/proc/proc_column.c 2018-12-18 16:30:19 +0900 (124d12ce1) @@ -1,6 +1,7 @@ /* -*- c-basic-offset: 2 -*- */ /* Copyright(C) 2009-2016 Brazil + Copyright(C) 2018 Kouhei Sutou <kou****@clear*****> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -751,167 +752,6 @@ command_column_copy_resolve_target(grn_ctx *ctx, return ctx->rc; } -static void -command_column_copy_same_table(grn_ctx *ctx, grn_obj *table, - grn_obj *from_column, grn_obj *to_column) -{ - grn_table_cursor *cursor; - grn_id id; - grn_obj value; - - cursor = grn_table_cursor_open(ctx, table, - NULL, 0, - NULL, 0, - 0, -1, 0); - if (!cursor) { - return; - } - - GRN_VOID_INIT(&value); - while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { - GRN_BULK_REWIND(&value); - grn_obj_get_value(ctx, from_column, id, &value); - grn_obj_set_value(ctx, to_column, id, &value, GRN_OBJ_SET); - } - GRN_OBJ_FIN(ctx, &value); - grn_table_cursor_close(ctx, cursor); -} - -static void -command_column_copy_same_key_type(grn_ctx *ctx, - grn_obj *from_table, - grn_obj *from_column, - grn_obj *to_table, - grn_obj *to_column) -{ - grn_table_cursor *cursor; - grn_id from_id; - grn_obj value; - - cursor = grn_table_cursor_open(ctx, from_table, - NULL, 0, - NULL, 0, - 0, -1, 0); - if (!cursor) { - return; - } - - GRN_VOID_INIT(&value); - while ((from_id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { - 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) { - continue; - } - - GRN_BULK_REWIND(&value); - grn_obj_get_value(ctx, from_column, from_id, &value); - grn_obj_set_value(ctx, to_column, to_id, &value, GRN_OBJ_SET); - } - GRN_OBJ_FIN(ctx, &value); - grn_table_cursor_close(ctx, cursor); -} - -static void -command_column_copy_different(grn_ctx *ctx, - grn_obj *from_table, - grn_obj *from_column, - grn_obj *to_table, - grn_obj *to_column, - grn_obj *from_table_name, - grn_obj *from_column_name, - grn_obj *to_table_name, - grn_obj *to_column_name) -{ - grn_table_cursor *cursor; - grn_id from_id; - grn_obj from_key_buffer; - grn_obj to_key_buffer; - grn_obj value; - - cursor = grn_table_cursor_open(ctx, from_table, - NULL, 0, - NULL, 0, - 0, -1, 0); - if (!cursor) { - return; - } - - 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_VOID_INIT(&value); - while ((from_id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { - 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, - "[column][copy] failed to cast key: <%.*s> -> %.*s: " - "<%.*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_table_name), - GRN_TEXT_VALUE(from_table_name), - (int)GRN_TEXT_LEN(from_column_name), - GRN_TEXT_VALUE(from_column_name), - (int)GRN_TEXT_LEN(to_table_name), - GRN_TEXT_VALUE(to_table_name), - (int)GRN_TEXT_LEN(to_column_name), - GRN_TEXT_VALUE(to_column_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) { - continue; - } - - GRN_BULK_REWIND(&value); - grn_obj_get_value(ctx, from_column, from_id, &value); - grn_obj_set_value(ctx, to_column, to_id, &value, GRN_OBJ_SET); - } - GRN_OBJ_FIN(ctx, &from_key_buffer); - GRN_OBJ_FIN(ctx, &to_key_buffer); - GRN_OBJ_FIN(ctx, &value); - - grn_table_cursor_close(ctx, cursor); -} - static grn_obj * command_column_copy(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) @@ -944,44 +784,7 @@ command_column_copy(grn_ctx *ctx, int nargs, grn_obj **args, goto exit; } - if ((from_table->header.type == GRN_TABLE_NO_KEY || - to_table->header.type == GRN_TABLE_NO_KEY) && - from_table != to_table) { - rc = GRN_OPERATION_NOT_SUPPORTED; - GRN_PLUGIN_ERROR(ctx, - rc, - "[column][copy] copy from/to TABLE_NO_KEY isn't supported: " - "<%.*s%c%.*s> -> <%.*s%c%.*s>", - (int)GRN_TEXT_LEN(from_table_name), - GRN_TEXT_VALUE(from_table_name), - GRN_DB_DELIMITER, - (int)GRN_TEXT_LEN(from_column_name), - GRN_TEXT_VALUE(from_column_name), - (int)GRN_TEXT_LEN(to_table_name), - GRN_TEXT_VALUE(to_table_name), - GRN_DB_DELIMITER, - (int)GRN_TEXT_LEN(to_column_name), - GRN_TEXT_VALUE(to_column_name)); - goto exit; - } - - if (from_table == to_table) { - command_column_copy_same_table(ctx, from_table, from_column, to_column); - } else if (from_table->header.domain == to_table->header.domain) { - command_column_copy_same_key_type(ctx, - from_table, from_column, - to_table, to_column); - } else { - command_column_copy_different(ctx, - from_table, - from_column, - to_table, - to_column, - from_table_name, - from_column_name, - to_table_name, - to_column_name); - } + rc = grn_column_copy(ctx, from_column, to_column); exit : grn_ctx_output_bool(ctx, rc == GRN_SUCCESS); -------------- next part -------------- An HTML attachment was scrubbed... URL: <https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20181218/225219fd/attachment-0001.html>