From a914ad1aa6b13277931ebcc351fcacbc53f3a4d0 Mon Sep 17 00:00:00 2001 From: "kyle.cao" Date: Thu, 19 Aug 2021 11:35:31 +0800 Subject: [PATCH] support cypher parameter fix compatibility small fix tmp add slice2Nlist fix support map fix limit int --- go.mod | 2 + go.sum | 17 +++--- main.go | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 161 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index ac7fec6..705cc57 100644 --- a/go.mod +++ b/go.mod @@ -8,3 +8,5 @@ require ( github.com/vesoft-inc/nebula-go/v2 v2.0.0-20210701060243-a0577f67f375 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect ) + +replace github.com/vesoft-inc/nebula-go/v2 => /home/kyle.cao/workspace/fork/nebula-go diff --git a/go.sum b/go.sum index c6d4b27..4a30d69 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,11 @@ github.com/jedib0t/go-pretty/v6 v6.0.5 h1:oOo0/jSb3NEYKT6l1hhFXoX2UZnkanMuCE2DVT github.com/jedib0t/go-pretty/v6 v6.0.5/go.mod h1:MTr6FgcfNdnN5wPVBzJ6mhJeDyiF0yBvS2TMXEV/XSU= github.com/jievince/liner v1.2.3 h1:hpMEqBKkIg/RHzHCHZqbs19MDq8bT8b5o85D3o/Yggk= github.com/jievince/liner v1.2.3/go.mod h1:6szfFB+ea00sIHdOn/4gDFoD6sa2UaUHR28Ca8QGj9U= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -15,14 +20,14 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/vesoft-inc/nebula-go/v2 v2.0.0-20210701060243-a0577f67f375 h1:7us19i0qiJffpnKeWMQTPxAjaYItR8xTVohSa3JZVqk= -github.com/vesoft-inc/nebula-go/v2 v2.0.0-20210701060243-a0577f67f375/go.mod h1:B7nR6+nOSo0umq/HkCmUfyRtYrJVOsNiPS9u4djDbSc= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 0e657af..063c163 100644 --- a/main.go +++ b/main.go @@ -7,12 +7,14 @@ package main import ( + "encoding/json" "flag" "fmt" "log" "os" "path" "path/filepath" + "regexp" "strconv" "strings" "time" @@ -20,7 +22,8 @@ import ( "github.com/vesoft-inc/nebula-console/box" "github.com/vesoft-inc/nebula-console/cli" "github.com/vesoft-inc/nebula-console/printer" - nebula "github.com/vesoft-inc/nebula-go/v2" + nebulago "github.com/vesoft-inc/nebula-go/v2" + nebula "github.com/vesoft-inc/nebula-go/v2/nebula" ) // Console side commands @@ -32,8 +35,14 @@ const ( ExportCsv = 3 ExportDot = 4 Repeat = 5 + Param = 6 + Params = 7 ) +type ParameterMap map[string]interface{} + +var parameterMap ParameterMap + var dataSetPrinter = printer.NewDataSetPrinter() var planDescPrinter = printer.NewPlanDescPrinter() @@ -104,7 +113,7 @@ func isConsoleCmd(cmd string) (isLocal bool, localCmd int, args []string) { return } - plain := strings.TrimSpace(strings.ToLower(cmd)) + plain := strings.TrimSpace(cmd) if len(plain) < 1 || plain[0] != ':' { return } @@ -115,9 +124,11 @@ func isConsoleCmd(cmd string) (isLocal bool, localCmd int, args []string) { } words := strings.Fields(plain[1:]) localCmdName := words[0] - switch localCmdName { + switch strings.ToLower(localCmdName) { case "exit", "quit": - localCmd = Quit + { + localCmd = Quit + } case "sleep": { localCmd = Sleep @@ -143,6 +154,16 @@ func isConsoleCmd(cmd string) (isLocal bool, localCmd int, args []string) { localCmd = ExportDot args = []string{words[1]} } + case "param": + { + localCmd = Param + args = []string{plain} + } + case "params": + { + localCmd = Params + args = []string{plain} + } } return } @@ -175,12 +196,41 @@ func executeConsoleCmd(c cli.Cli, cmd int, args []string) { printConsoleResp("Error: invald integer, repeats should be greater than 1") } g_repeats = i + case Param: + reg := regexp.MustCompile(`^\s*:param\s+(.+?)\s*=>\s*(.+?)\s*$`) + if reg == nil { + fmt.Println("regexp err") + return + } + if len(args) != 1 { + return + } + res := reg.FindAllStringSubmatch(args[0], -1) + if len(res) != 1 || len(res[0]) != 3 { + return + } + + tmp := make(ParameterMap) + param := "{\"" + res[0][1] + "\"" + ":" + res[0][2] + "}" + err := json.Unmarshal([]byte(param), &tmp) + if err != nil { + printConsoleResp("Error: parameter parsing failed") + return + } + for k, v := range tmp { + parameterMap[k] = v + } + + case Params: + for k := range parameterMap { + fmt.Println(k, " => ", parameterMap[k]) + } default: printConsoleResp("Error: this local command not exists!") } } -func printResultSet(res *nebula.ResultSet, startTime time.Time) (duration time.Duration) { +func printResultSet(res *nebulago.ResultSet, startTime time.Time) (duration time.Duration) { if !res.IsSucceed() && !res.IsPartialSucceed() { fmt.Printf("[ERROR (%d)]: %s", res.GetErrorCode(), res.GetErrorMsg()) fmt.Println() @@ -252,7 +302,18 @@ func loop(c cli.Cli) error { var t2 int32 = 0 for i := 0; i < g_repeats; i++ { start := time.Now() - res, err := session.Execute(line) + // convert interface{} to nebula.Value + params := make(map[string]*nebula.Value) + for k, v := range parameterMap { + value, err := Base2Value(v) + if err != nil { + printConsoleResp(err.Error()) + return err + } + params[k] = value + } + + res, err := session.ExecuteWithParameter(line, params) if err != nil { return err } @@ -318,12 +379,87 @@ func validateFlags() { } } -var pool *nebula.ConnectionPool +// construct Slice to nebula.NList +func Slice2Nlist(list []interface{}) (*nebula.NList, error) { + sv := []*nebula.Value{} + var ret nebula.NList + for _, item := range list { + nv, er := Base2Value(item) + if er != nil { + return nil, er + } + sv = append(sv, nv) + } + ret.Values = sv + return &ret, nil +} + +// construct map to nebula.NMap +func Map2Nmap(m map[string]interface{}) (*nebula.NMap, error) { + var ret nebula.NMap + kvs := map[string]*nebula.Value{} + for k, v := range m { + nv, err := Base2Value(v) + if err != nil { + return nil, err + } + kvs[k] = nv + } + ret.Kvs = kvs + return &ret, nil +} + +// construct go-type to nebula.Value +func Base2Value(any interface{}) (value *nebula.Value, err error) { + value = nebula.NewValue() + if v, ok := any.(bool); ok { + value.BVal = &v + } else if v, ok := any.(int); ok { + ival := int64(v) + value.IVal = &ival + } else if v, ok := any.(float64); ok { + if v == float64(int64(v)) { + iv := int64(v) + value.IVal = &iv + } else { + value.FVal = &v + } + } else if v, ok := any.(float32); ok { + if v == float32(int64(v)) { + iv := int64(v) + value.IVal = &iv + } else { + fval := float64(v) + value.FVal = &fval + } + } else if v, ok := any.(string); ok { + value.SVal = []byte(v) + } else if v, ok := any.([]interface{}); ok { + nv, er := Slice2Nlist([]interface{}(v)) + if er != nil { + err = er + } + value.LVal = nv + } else if v, ok := any.(map[string]interface{}); ok { + nv, er := Map2Nmap(map[string]interface{}(v)) + if er != nil { + err = er + } + value.MVal = nv + } else { + // unsupport other Value type, use this function carefully + err = fmt.Errorf("Do not support convert %T to nebula.Value", any) + } + return +} + +var pool *nebulago.ConnectionPool -var session *nebula.Session +var session *nebulago.Session func main() { flag.Parse() + parameterMap = make(ParameterMap) if flag.NFlag() == 1 && *version { fmt.Printf("nebula-console version Git: %s, Build Time: %s\n", gitCommit, buildDate) @@ -344,16 +480,16 @@ func main() { historyHome = filepath.Dir(ex) // Set to executable folder } - hostAddress := nebula.HostAddress{Host: *address, Port: *port} - hostList := []nebula.HostAddress{hostAddress} - poolConfig := nebula.PoolConfig{ + hostAddress := nebulago.HostAddress{Host: *address, Port: *port} + hostList := []nebulago.HostAddress{hostAddress} + poolConfig := nebulago.PoolConfig{ TimeOut: time.Duration(*timeout) * time.Millisecond, IdleTime: 0 * time.Millisecond, MaxConnPoolSize: 2, MinConnPoolSize: 0, } var err error - pool, err = nebula.NewConnectionPool(hostList, poolConfig, nebula.DefaultLogger{}) + pool, err = nebulago.NewConnectionPool(hostList, poolConfig, nebulago.DefaultLogger{}) if err != nil { log.Panicf(fmt.Sprintf("Fail to initialize the connection pool, host: %s, port: %d, %s", *address, *port, err.Error())) }