Navigation Menu

Skip to content

Commit

Permalink
Gnx: add db.InsertRow().
Browse files Browse the repository at this point in the history
  • Loading branch information
s-yata committed Apr 6, 2015
1 parent 209a941 commit 26c9921
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 0 deletions.
58 changes: 58 additions & 0 deletions go2/gnx/gnx.cpp
@@ -0,0 +1,58 @@
#include "gnx.h"

#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

gnx_bool gnx_insert_row(grn_ctx *ctx, const char *table_name,
gnx_data_type key_type, const void *key,
gnx_int *row_id) {
grn_obj *table = grn_ctx_get(ctx, table_name, strlen(table_name));
if (!table) {
*row_id = GNX_NA_INT;
return GNX_NA_BOOL;
}
// TODO: type check.
unsigned int key_size = 0;
switch (key_type) {
case GNX_NA: {
key = nullptr;
break;
}
case GNX_INT: {
key_size = sizeof(gnx_int);
break;
}
case GNX_FLOAT: {
key_size = sizeof(gnx_float);
break;
}
// case GNX_GEO_POINT: {
// key_size = sizeof(gnx_geo_point);
// }
case GNX_TEXT: {
gnx_text text = *static_cast<const gnx_text *>(key);
key = text.data;
key_size = text.size;
break;
}
default: {
*row_id = GNX_NA_INT;
return GNX_NA_BOOL;
}
}
int added;
grn_id id = grn_table_add(ctx, table, key, key_size, &added);
if (id == GRN_ID_NIL) {
*row_id = GNX_NA_INT;
return GNX_NA_BOOL;
}
*row_id = id;
return added ? GNX_TRUE : GNX_FALSE;
}

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
39 changes: 39 additions & 0 deletions go2/gnx/gnx.go
@@ -1,9 +1,12 @@
package gnx

/*
#cgo CXXFLAGS: -std=c++11
#cgo LDFLAGS: -lgrnxx -lstdc++
#cgo pkg-config: groonga
#include <groonga.h>
#include <stdlib.h>
#include "gnx.h"
*/
import "C"

Expand Down Expand Up @@ -983,3 +986,39 @@ func (db *DB) LoadCMap(
return db.loadCMap(tableName, columnarRecordsMap)
}
}

func (db *DB) InsertRow(tableName string, key Valuer) (bool, Int, error) {
dbID, err := db.selectGroongaDB(key)
if err != nil {
return false, NAInt(), err
}
groongaDB := db.groongaDBs[dbID]

var inserted C.gnx_bool
var rowID C.gnx_int
cTableName := C.CString(tableName)
defer C.free(unsafe.Pointer(cTableName))
switch value := key.(type) {
case nil:
inserted = C.gnx_insert_row(
groongaDB.ctx, cTableName, C.GNX_NA, nil, &rowID)
case Int:
inserted = C.gnx_insert_row(
groongaDB.ctx, cTableName, C.GNX_INT, unsafe.Pointer(&value), &rowID)
case Float:
inserted = C.gnx_insert_row(
groongaDB.ctx, cTableName, C.GNX_FLOAT, unsafe.Pointer(&value), &rowID)
// case GeoPoint:
case Text:
cValue := C.CString(string(value))
defer C.free(unsafe.Pointer(cValue))
text := C.gnx_text{cValue, C.gnx_int(len(value))}
inserted = C.gnx_insert_row(
groongaDB.ctx, cTableName, C.GNX_TEXT, unsafe.Pointer(&text), &rowID)
}
if inserted == C.GNX_NA_BOOL {
err = fmt.Errorf("gnx_insert_row() failed")
}
rowID = ((rowID - 1) * C.gnx_int(len(db.groongaDBs))) + C.gnx_int(dbID) + 1
return inserted == C.GNX_TRUE, Int(rowID), err
}
43 changes: 43 additions & 0 deletions go2/gnx/gnx.h
@@ -0,0 +1,43 @@
#ifndef GNX_H
#define GNX_H

#include <groonga.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

typedef enum gnx_data_type {
GNX_NA,
GNX_BOOL,
GNX_INT,
GNX_FLOAT,
GNX_GEO_POINT,
GNX_TEXT
} gnx_data_type;

typedef uint8_t gnx_bool;
typedef int64_t gnx_int;
typedef double gnx_float;
//typedef gnx_geo_point struct { int32_t latitude; int32_t longitude; };
typedef struct {
const char *data;
gnx_int size;
} gnx_text;

#define GNX_TRUE ((gnx_bool)3)
#define GNX_FALSE ((gnx_bool)0)

#define GNX_NA_BOOL ((gnx_bool)1)
#define GNX_NA_INT (((gnx_int)1) << 63)

gnx_bool gnx_insert_row(grn_ctx *ctx, const char *table_name,
gnx_data_type key_type, const void *key,
gnx_int *row_id);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

#endif // GNX_H
125 changes: 125 additions & 0 deletions go2/gnxTest.go
Expand Up @@ -238,7 +238,132 @@ func testB() {
}
}

func testC() {
log.Println("testC()")

db, dir, err := gnx.CreateTempDB("", "gnxConsole", 2)
if err != nil {
log.Println(err)
return
}
defer os.RemoveAll(dir)
defer db.Close()

{
for i := 0; i < 2; i++ {
_, err = db.GroongaQuery(i, "table_create Table TABLE_NO_KEY")
if err != nil {
log.Println(err)
return
}
}
keys := []gnx.Valuer{nil, nil, nil}
for i, key := range keys {
inserted, rowID, err := db.InsertRow("Table", key)
if err != nil {
log.Fatalln("err:", err)
}
fmt.Printf("i: %v, key: %v, inserted: %v, rowID: %v\n",
i, key, inserted, rowID)
}
command := "select Table --limit -1 --cache no"
for i := 0; i < 2; i++ {
jsonBytes, err := db.GroongaQuery(i, command)
if err != nil {
log.Println(err)
return
}
fmt.Printf("result[%d]: %s\n", i, string(jsonBytes))
}
}

{
for i := 0; i < 2; i++ {
_, err = db.GroongaQuery(i, "table_create Table2 TABLE_PAT_KEY Int32")
if err != nil {
log.Println(err)
return
}
}
keys := []gnx.Valuer{gnx.Int(10), gnx.Int(20), gnx.Int(30)}
for i, key := range keys {
inserted, rowID, err := db.InsertRow("Table2", key)
if err != nil {
log.Fatalln("err:", err)
}
fmt.Printf("i: %v, key: %v, inserted: %v, rowID: %v\n",
i, key, inserted, rowID)
}
command := "select Table2 --limit -1 --cache no"
for i := 0; i < 2; i++ {
jsonBytes, err := db.GroongaQuery(i, command)
if err != nil {
log.Println(err)
return
}
fmt.Printf("result[%d]: %s\n", i, string(jsonBytes))
}
}

{
for i := 0; i < 2; i++ {
_, err = db.GroongaQuery(i, "table_create Table3 TABLE_PAT_KEY Float")
if err != nil {
log.Println(err)
return
}
}
keys := []gnx.Valuer{gnx.Float(1.25), gnx.Float(2.5), gnx.Float(3.75)}
for i, key := range keys {
inserted, rowID, err := db.InsertRow("Table3", key)
if err != nil {
log.Fatalln("err:", err)
}
fmt.Printf("i: %v, key: %v, inserted: %v, rowID: %v\n",
i, key, inserted, rowID)
}
command := "select Table3 --limit -1 --cache no"
for i := 0; i < 2; i++ {
jsonBytes, err := db.GroongaQuery(i, command)
if err != nil {
log.Println(err)
return
}
fmt.Printf("result[%d]: %s\n", i, string(jsonBytes))
}
}

{
for i := 0; i < 2; i++ {
_, err = db.GroongaQuery(i, "table_create Table4 TABLE_PAT_KEY ShortText")
if err != nil {
log.Println(err)
return
}
}
keys := []gnx.Valuer{gnx.Text("cat"), gnx.Text("dog"), gnx.Text("horse")}
for i, key := range keys {
inserted, rowID, err := db.InsertRow("Table4", key)
if err != nil {
log.Fatalln("err:", err)
}
fmt.Printf("i: %v, key: %v, inserted: %v, rowID: %v\n",
i, key, inserted, rowID)
}
command := "select Table4 --limit -1 --cache no"
for i := 0; i < 2; i++ {
jsonBytes, err := db.GroongaQuery(i, command)
if err != nil {
log.Println(err)
return
}
fmt.Printf("result[%d]: %s\n", i, string(jsonBytes))
}
}
}

func main() {
testA()
testB()
testC()
}

0 comments on commit 26c9921

Please sign in to comment.