susumu.yata
null+****@clear*****
Fri Jul 10 16:02:42 JST 2015
susumu.yata 2015-07-10 16:02:42 +0900 (Fri, 10 Jul 2015) New Revision: 6dd0cef01d59b469a6b2a13ddecbd2a6ebe7c26e https://github.com/groonga/grngo/commit/6dd0cef01d59b469a6b2a13ddecbd2a6ebe7c26e Message: Add error handling to grn_table_get_key_info(). GitHub: #12 Modified files: grngo.c grngo.go grngo.h Modified: grngo.c (+43 -39) =================================================================== --- grngo.c 2015-07-10 15:28:28 +0900 (ae28d8b) +++ grngo.c 2015-07-10 16:02:42 +0900 (b48f3c1) @@ -2,7 +2,7 @@ #include <string.h> -#define GRNGO_MAX_DATA_TYPE_ID GRN_DB_WGS84_GEO_POINT +#define GRNGO_MAX_BUILTIN_TYPE_ID GRN_DB_WGS84_GEO_POINT grn_rc grngo_find_table(grn_ctx *ctx, const char *name, size_t name_len, grn_obj **table) { @@ -49,46 +49,50 @@ grn_rc grngo_table_get_name(grn_ctx *ctx, grn_obj *table, char **name) { return GRN_SUCCESS; } -// grngo_init_type_info() initializes the members of type_info. -// The initialized type info specifies a valid Void type. -static void grngo_init_type_info(grngo_type_info *type_info) { +static void grngo_table_type_info_init(grngo_table_type_info *type_info) { type_info->data_type = GRN_DB_VOID; - type_info->dimension = 0; type_info->ref_table = NULL; } -grn_bool grngo_table_get_key_info(grn_ctx *ctx, grn_obj *table, - grngo_type_info *key_info) { - grngo_init_type_info(key_info); - while (table) { - switch (table->header.type) { - case GRN_TABLE_HASH_KEY: - case GRN_TABLE_PAT_KEY: - case GRN_TABLE_DAT_KEY: { - if (table->header.domain <= GRNGO_MAX_DATA_TYPE_ID) { - key_info->data_type = table->header.domain; - return GRN_TRUE; - } - table = grn_ctx_at(ctx, table->header.domain); - if (!table) { - return GRN_FALSE; - } - if (!key_info->ref_table) { - key_info->ref_table = table; - } - break; - } - case GRN_TABLE_NO_KEY: { - // GRN_DB_VOID, if the table has no key. - return GRN_TRUE; +grn_rc grngo_table_get_key_info(grn_ctx *ctx, grn_obj *table, + grngo_table_type_info *key_info) { + if (!ctx || !table || !grn_obj_is_table(ctx, table) || !key_info) { + return GRN_INVALID_ARGUMENT; + } + grngo_table_type_info_init(key_info); + switch (table->header.type) { + case GRN_TABLE_HASH_KEY: + case GRN_TABLE_PAT_KEY: + case GRN_TABLE_DAT_KEY: { + if (table->header.domain <= GRNGO_MAX_BUILTIN_TYPE_ID) { + key_info->data_type = table->header.domain; + return GRN_SUCCESS; } - default: { - // The object is not a table. - return GRN_FALSE; + grn_obj *ref_table = grn_ctx_at(ctx, table->header.domain); + if (!ref_table || !grn_obj_is_table(ctx, ref_table)) { + if (ctx->rc != GRN_SUCCESS) { + return ctx->rc; + } + return GRN_UNKNOWN_ERROR; } + key_info->ref_table = ref_table; + return GRN_SUCCESS; + } + case GRN_TABLE_NO_KEY: { + return GRN_SUCCESS; + } + default: { + return GRN_UNKNOWN_ERROR; } } - return GRN_FALSE; +} + +// grngo_init_type_info() initializes the members of type_info. +// The initialized type info specifies a valid Void type. +static void grngo_init_type_info(grngo_type_info *type_info) { + type_info->data_type = GRN_DB_VOID; + type_info->dimension = 0; + type_info->ref_table = NULL; } grn_bool grngo_table_get_value_info(grn_ctx *ctx, grn_obj *table, @@ -103,13 +107,13 @@ grn_bool grngo_table_get_value_info(grn_ctx *ctx, grn_obj *table, case GRN_TABLE_DAT_KEY: case GRN_TABLE_NO_KEY: { grn_id range = grn_obj_get_range(ctx, table); - if (range <= GRNGO_MAX_DATA_TYPE_ID) { + if (range <= GRNGO_MAX_BUILTIN_TYPE_ID) { value_info->data_type = range; return GRN_TRUE; } value_info->ref_table = grn_ctx_at(ctx, range); - grngo_type_info key_info; - if (!grngo_table_get_key_info(ctx, value_info->ref_table, &key_info)) { + grngo_table_type_info key_info; + if (grngo_table_get_key_info(ctx, value_info->ref_table, &key_info) != GRN_SUCCESS) { return GRN_FALSE; } value_info->data_type = key_info.data_type; @@ -145,13 +149,13 @@ grn_bool grngo_column_get_value_info(grn_ctx *ctx, grn_obj *column, } } grn_id range = grn_obj_get_range(ctx, column); - if (range <= GRNGO_MAX_DATA_TYPE_ID) { + if (range <= GRNGO_MAX_BUILTIN_TYPE_ID) { value_info->data_type = range; return GRN_TRUE; } value_info->ref_table = grn_ctx_at(ctx, range); - grngo_type_info key_info; - if (!grngo_table_get_key_info(ctx, value_info->ref_table, &key_info)) { + grngo_table_type_info key_info; + if (grngo_table_get_key_info(ctx, value_info->ref_table, &key_info) != GRN_SUCCESS) { return GRN_FALSE; } value_info->data_type = key_info.data_type; Modified: grngo.go (+10 -7) =================================================================== --- grngo.go 2015-07-10 15:28:28 +0900 (24c33f7) +++ grngo.go 2015-07-10 16:02:42 +0900 (b9bf95d) @@ -720,19 +720,17 @@ func (db *DB) FindTable(name string) (*Table, error) { if rc != C.GRN_SUCCESS { return nil, newGrnError("grngo_find_table()", &rc, db.ctx) } - var keyInfo C.grngo_type_info - if ok := C.grngo_table_get_key_info(db.ctx, obj, &keyInfo); ok != C.GRN_TRUE { - return nil, fmt.Errorf("grngo_table_get_key_info() failed: name = <%s>", - name) + var keyInfo C.grngo_table_type_info + rc = C.grngo_table_get_key_info(db.ctx, obj, &keyInfo) + if rc != C.GRN_SUCCESS { + return nil, newGrnError("grngo_table_get_key_info()", &rc, db.ctx) } // Check the key type. keyType := DataType(keyInfo.data_type) // Find the destination table if the key is table reference. var keyTable *Table if keyInfo.ref_table != nil { - if keyType == Void { - return nil, fmt.Errorf("reference to void: name = <%s>", name) - } + defer C.grn_obj_unlink(db.ctx, keyInfo.ref_table) var cKeyTableName *C.char rc := C.grngo_table_get_name(db.ctx, keyInfo.ref_table, &cKeyTableName) if rc != C.GRN_SUCCESS { @@ -744,6 +742,11 @@ func (db *DB) FindTable(name string) (*Table, error) { if err != nil { return nil, err } + finalTable := keyTable + for finalTable.keyTable != nil { + finalTable = finalTable.keyTable + } + keyType = finalTable.keyType } var valueInfo C.grngo_type_info if ok := C.grngo_table_get_value_info(db.ctx, obj, &valueInfo); ok != C.GRN_TRUE { Modified: grngo.h (+11 -3) =================================================================== --- grngo.h 2015-07-10 15:28:28 +0900 (9dac671) +++ grngo.h 2015-07-10 16:02:42 +0900 (041dbd4) @@ -26,15 +26,23 @@ grn_rc grngo_table_get_name(grn_ctx *ctx, grn_obj *table, char **name); typedef struct { grn_builtin_type data_type; // Data type (GRN_DB_VOID, GRN_DB_BOOL, etc.). + // If the type is table reference, GRN_DB_VOID + // is stored. + grn_obj *ref_table; // The referenced table of table reference. +} grngo_table_type_info; + +typedef struct { + grn_builtin_type data_type; // Data type (GRN_DB_VOID, GRN_DB_BOOL, etc.). // If the type is table reference, the key type // of the referenced table is stored. int dimension; // Vector depth, 0 means the type is scalar. grn_obj *ref_table; // The referenced table of table reference. } grngo_type_info; -// grngo_table_get_key_info() gets information of the table key. -grn_bool grngo_table_get_key_info(grn_ctx *ctx, grn_obj *table, - grngo_type_info *key_info); +// grngo_table_get_key_info gets information of the table key (_key). +grn_rc grngo_table_get_key_info(grn_ctx *ctx, grn_obj *table, + grngo_table_type_info *key_info); + // grngo_table_get_value_info() gets information of the table value. grn_bool grngo_table_get_value_info(grn_ctx *ctx, grn_obj *table, grngo_type_info *value_info); -------------- next part -------------- HTML����������������������������...Download