[Groonga-commit] groonga/grngo at 6dd0cef [master] Add error handling to grn_table_get_key_info().

Back to archive index

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����������������������������...
Télécharger 



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