[Groonga-commit] groonga/grnxx at c217462 [master] Gnx: implement Column.GetValue() for scalar value types.

Back to archive index

susumu.yata null+****@clear*****
Fri May 1 11:28:14 JST 2015


susumu.yata	2015-05-01 11:28:14 +0900 (Fri, 01 May 2015)

  New Revision: c217462e49fb6fa49f1bbc388ae69e6b325ac53e
  https://github.com/groonga/grnxx/commit/c217462e49fb6fa49f1bbc388ae69e6b325ac53e

  Message:
    Gnx: implement Column.GetValue() for scalar value types.

  Modified files:
    go3/gnx/grn.go
    go3/gnx/grn_cgo.c
    go3/gnx/grn_cgo.h
    go3/gnx/grn_test.go

  Modified: go3/gnx/grn.go (+96 -0)
===================================================================
--- go3/gnx/grn.go    2015-05-01 10:32:07 +0900 (391ec03)
+++ go3/gnx/grn.go    2015-05-01 11:28:14 +0900 (2c85255)
@@ -955,3 +955,99 @@ func (column *GrnColumn) SetValue(id Int, value interface{}) error {
 			reflect.TypeOf(value).Name())
 	}
 }
+
+// getBool() gets a Bool value.
+func (column *GrnColumn) getBool(id Int) (interface{}, error) {
+	var grnValue C.grn_bool
+	if ok := C.grn_cgo_column_get_bool(column.table.db.ctx, column.obj,
+		C.grn_id(id), &grnValue); ok != C.GRN_TRUE {
+		return nil, fmt.Errorf("grn_cgo_column_get_bool() failed")
+	}
+	if grnValue == C.GRN_TRUE {
+		return True, nil
+	} else {
+		return False, nil
+	}
+}
+
+// getInt() gets an Int value.
+func (column *GrnColumn) getInt(id Int) (interface{}, error) {
+	var grnValue C.int64_t
+	if ok := C.grn_cgo_column_get_int(column.table.db.ctx, column.obj,
+		C.grn_id(id), &grnValue); ok != C.GRN_TRUE {
+		return nil, fmt.Errorf("grn_cgo_column_get_int() failed")
+	}
+	return Int(grnValue), nil
+}
+
+// getFloat() gets a Float value.
+func (column *GrnColumn) getFloat(id Int) (interface{}, error) {
+	var grnValue C.double
+	if ok := C.grn_cgo_column_get_float(column.table.db.ctx, column.obj,
+		C.grn_id(id), &grnValue); ok != C.GRN_TRUE {
+		return nil, fmt.Errorf("grn_cgo_column_get_float() failed")
+	}
+	return Float(grnValue), nil
+}
+
+// getGeoPoint() gets a GeoPoint value.
+func (column *GrnColumn) getGeoPoint(id Int) (interface{}, error) {
+	var grnValue C.grn_geo_point
+	if ok := C.grn_cgo_column_get_geo_point(column.table.db.ctx, column.obj,
+		C.grn_id(id), &grnValue); ok != C.GRN_TRUE {
+		return nil, fmt.Errorf("grn_cgo_column_get_geo_point() failed")
+	}
+	return GeoPoint{int32(grnValue.latitude), int32(grnValue.longitude)}, nil
+}
+
+// getText() gets a Text value.
+func (column *GrnColumn) getText(id Int) (interface{}, error) {
+	var grnValue C.grn_cgo_text
+	if ok := C.grn_cgo_column_get_text(column.table.db.ctx, column.obj,
+		C.grn_id(id), &grnValue); ok != C.GRN_TRUE {
+		return nil, fmt.Errorf("grn_cgo_column_get_text() failed")
+	}
+	if grnValue.size == 0 {
+		return make(Text, 0), nil
+	}
+	value := make(Text, int(grnValue.size))
+	grnValue.ptr = (*C.char)(unsafe.Pointer(&value[0]))
+	if ok := C.grn_cgo_column_get_text(column.table.db.ctx, column.obj,
+		C.grn_id(id), &grnValue); ok != C.GRN_TRUE {
+		return nil, fmt.Errorf("grn_cgo_column_get_text() failed")
+	}
+	return value, nil
+}
+
+// GetValue() gets a value.
+// TODO: GetValue() should use allocated spaces for better performance.
+func (column *GrnColumn) GetValue(id Int) (interface{}, error) {
+	if !column.isVector {
+		switch column.valueType {
+		case BoolID:
+			return column.getBool(id)
+		case IntID:
+			return column.getInt(id)
+		case FloatID:
+			return column.getFloat(id)
+		case GeoPointID:
+			return column.getGeoPoint(id)
+		case TextID:
+			return column.getText(id)
+		}
+	} else {
+		switch column.valueType {
+		case BoolID:
+			return nil, fmt.Errorf("not supported yet")
+		case IntID:
+			return nil, fmt.Errorf("not supported yet")
+		case FloatID:
+			return nil, fmt.Errorf("not supported yet")
+		case GeoPointID:
+			return nil, fmt.Errorf("not supported yet")
+		case TextID:
+			return nil, fmt.Errorf("not supported yet")
+		}
+	}
+	return nil, fmt.Errorf("undefined value type: valueType = %d", column.valueType)
+}

  Modified: go3/gnx/grn_cgo.c (+54 -0)
===================================================================
--- go3/gnx/grn_cgo.c    2015-05-01 10:32:07 +0900 (7e3300f)
+++ go3/gnx/grn_cgo.c    2015-05-01 11:28:14 +0900 (ffd26c2)
@@ -322,3 +322,57 @@ grn_bool grn_cgo_column_set_text_vector(grn_ctx *ctx, grn_obj *column,
   GRN_OBJ_FIN(ctx, &obj);
   return rc == GRN_SUCCESS;
 }
+
+grn_bool grn_cgo_column_get_bool(grn_ctx *ctx, grn_obj *column,
+                                 grn_id id, grn_bool *value) {
+  grn_obj value_obj;
+  GRN_BOOL_INIT(&value_obj, 0);
+  grn_obj_get_value(ctx, column, id, &value_obj);
+  *value = GRN_BOOL_VALUE(&value_obj);
+  GRN_OBJ_FIN(ctx, &value_obj);
+  return GRN_TRUE;
+}
+
+grn_bool grn_cgo_column_get_int(grn_ctx *ctx, grn_obj *column,
+                                grn_id id, int64_t *value) {
+  grn_obj value_obj;
+  GRN_INT64_INIT(&value_obj, 0);
+  grn_obj_get_value(ctx, column, id, &value_obj);
+  *value = GRN_INT64_VALUE(&value_obj);
+  GRN_OBJ_FIN(ctx, &value_obj);
+  return GRN_TRUE;
+}
+
+grn_bool grn_cgo_column_get_float(grn_ctx *ctx, grn_obj *column,
+                                  grn_id id, double *value) {
+  grn_obj value_obj;
+  GRN_FLOAT_INIT(&value_obj, 0);
+  grn_obj_get_value(ctx, column, id, &value_obj);
+  *value = GRN_FLOAT_VALUE(&value_obj);
+  GRN_OBJ_FIN(ctx, &value_obj);
+  return GRN_TRUE;
+}
+
+grn_bool grn_cgo_column_get_geo_point(grn_ctx *ctx, grn_obj *column,
+                                      grn_id id, grn_geo_point *value) {
+  grn_obj value_obj;
+  GRN_WGS84_GEO_POINT_INIT(&value_obj, 0);
+  grn_obj_get_value(ctx, column, id, &value_obj);
+  GRN_GEO_POINT_VALUE(&value_obj, value->latitude, value->longitude);
+  GRN_OBJ_FIN(ctx, &value_obj);
+  return GRN_TRUE;
+}
+
+grn_bool grn_cgo_column_get_text(grn_ctx *ctx, grn_obj *column,
+                                 grn_id id, grn_cgo_text *value) {
+  grn_obj value_obj;
+  GRN_TEXT_INIT(&value_obj, 0);
+  grn_obj_get_value(ctx, column, id, &value_obj);
+  size_t size = GRN_TEXT_LEN(&value_obj);
+  if (size <= value->size) {
+    memcpy(value->ptr, GRN_TEXT_VALUE(&value_obj), size);
+  }
+  value->size = size;
+  GRN_OBJ_FIN(ctx, &value_obj);
+  return GRN_TRUE;
+}

  Modified: go3/gnx/grn_cgo.h (+14 -2)
===================================================================
--- go3/gnx/grn_cgo.h    2015-05-01 10:32:07 +0900 (aa07704)
+++ go3/gnx/grn_cgo.h    2015-05-01 11:28:14 +0900 (5ac72f5)
@@ -7,12 +7,12 @@
 #include <groonga.h>
 
 typedef struct {
-  const char *ptr;
+  char *ptr;
   size_t size;
 } grn_cgo_text;
 
 typedef struct {
-  const void *ptr;
+  void *ptr;
   size_t size;
 } grn_cgo_vector;
 
@@ -103,4 +103,16 @@ grn_bool grn_cgo_column_set_text_vector(grn_ctx *ctx, grn_obj *column,
                                         grn_id id,
                                         const grn_cgo_vector *value);
 
+// TODO: Comment.
+grn_bool grn_cgo_column_get_bool(grn_ctx *ctx, grn_obj *column,
+                                 grn_id id, grn_bool *value);
+grn_bool grn_cgo_column_get_int(grn_ctx *ctx, grn_obj *column,
+                                grn_id id, int64_t *value);
+grn_bool grn_cgo_column_get_float(grn_ctx *ctx, grn_obj *column,
+                                  grn_id id, double *value);
+grn_bool grn_cgo_column_get_geo_point(grn_ctx *ctx, grn_obj *column,
+                                      grn_id id, grn_geo_point *value);
+grn_bool grn_cgo_column_get_text(grn_ctx *ctx, grn_obj *column,
+                                 grn_id id, grn_cgo_text *value);
+
 #endif  // GRN_CGO_H

  Modified: go3/gnx/grn_test.go (+36 -0)
===================================================================
--- go3/gnx/grn_test.go    2015-05-01 10:32:07 +0900 (438c68a)
+++ go3/gnx/grn_test.go    2015-05-01 11:28:14 +0900 (360ecd7)
@@ -4,6 +4,7 @@ import (
 	"io/ioutil"
 	"math/rand"
 	"os"
+	"reflect"
 	"strconv"
 	"testing"
 )
@@ -420,3 +421,38 @@ func TestGrnColumnSetValue(t *testing.T) {
 	testGrnColumnSetVectorValue(t, "GeoPoint")
 	testGrnColumnSetVectorValue(t, "Text")
 }
+
+func testGrnColumnGetScalarValue(t *testing.T, valueType string) {
+	dirPath, _, db, table, column := createTempGrnColumn(t, "Table", nil, "Value", valueType, nil)
+	defer removeTempGrnDB(t, dirPath, db)
+
+	for i := 0; i < 100; i++ {
+		_, id, err := table.InsertRow(nil)
+		if err != nil {
+			t.Fatalf("GrnTable.InsertRow() failed: %v", err)
+		}
+		value := generateRandomScalarValue(valueType)
+		if err := column.SetValue(id, value); err != nil {
+			t.Fatalf("GrnColumn.SetValue() failed: %v", err)
+		}
+		if storedValue, err := column.GetValue(id); err != nil {
+			t.Fatalf("GrnColumn.GetValue() failed: %v", err)
+		} else if !reflect.DeepEqual(value, storedValue) {
+			t.Fatalf("GrnColumn.GetValue() failed: value = %v, storedValue = %v", value, storedValue)
+		}
+	}
+}
+
+func TestGrnColumnGetValue(t *testing.T) {
+	testGrnColumnGetScalarValue(t, "Bool")
+	testGrnColumnGetScalarValue(t, "Int")
+	testGrnColumnGetScalarValue(t, "Float")
+	testGrnColumnGetScalarValue(t, "GeoPoint")
+	testGrnColumnGetScalarValue(t, "Text")
+
+//	testGrnColumnGetVectorValue(t, "Bool")
+//	testGrnColumnGetVectorValue(t, "Int")
+//	testGrnColumnGetVectorValue(t, "Float")
+//	testGrnColumnGetVectorValue(t, "GeoPoint")
+//	testGrnColumnGetVectorValue(t, "Text")
+}
-------------- next part --------------
HTML����������������������������...
Download 



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