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