This is an automated email from the ASF dual-hosted git repository.
jin pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/incubator-hugegraph-toolchain.git
The following commit(s) were added to refs/heads/master by this push:
new 8133144f feature(client): support go client for hugegraph (#514)
8133144f is described below
commit 8133144fdbc3078203622617d82febe1394d2cd9
Author: izliang <[email protected]>
AuthorDate: Mon Dec 11 16:45:48 2023 +0800
feature(client): support go client for hugegraph (#514)
Add Hugegraph-client for golang
Support REST API By This feature
---------
Co-authored-by: imbajin <[email protected]>
---
.github/workflows/client-ci.yml | 2 +-
.github/workflows/client-go-ci.yml | 64 +++
.github/workflows/hubble-ci.yml | 2 +-
.github/workflows/loader-ci.yml | 2 +-
.github/workflows/spark-connector-ci.yml | 2 +-
.github/workflows/stale.yml | 2 +-
.github/workflows/tools-ci.yml | 2 +-
.gitignore | 3 +
.licenserc.yaml | 3 +
hugegraph-client-go/Makefile | 72 ++++
hugegraph-client-go/README.en.md | 96 +++++
hugegraph-client-go/README.md | 94 +++++
hugegraph-client-go/api/api.go | 45 ++
hugegraph-client-go/api/api.response.go | 94 +++++
hugegraph-client-go/api/api.resquest.go | 78 ++++
hugegraph-client-go/api/v1/api.go | 33 ++
hugegraph-client-go/api/v1/edge/edge.go | 19 +
hugegraph-client-go/api/v1/edge/edge_test.go | 26 ++
hugegraph-client-go/api/v1/edgelabel/edgelabel.go | 291 +++++++++++++
.../api/v1/edgelabel/edgelabel_test.go | 187 +++++++++
hugegraph-client-go/api/v1/gremlin/gemlin.go | 239 +++++++++++
hugegraph-client-go/api/v1/gremlin/gemlin_test.go | 52 +++
.../api/v1/propertykey/propertykey.go | 458 +++++++++++++++++++++
.../api/v1/propertykey/propertykey_test.go | 120 ++++++
hugegraph-client-go/api/v1/schema.go | 151 +++++++
hugegraph-client-go/api/v1/schema_test.go | 37 ++
hugegraph-client-go/api/v1/version.go | 95 +++++
hugegraph-client-go/api/v1/version_test.go | 40 ++
hugegraph-client-go/api/v1/vertex/vertex.go | 304 ++++++++++++++
hugegraph-client-go/api/v1/vertex/vertex_test.go | 112 +++++
.../api/v1/vertexlabel/vertexlabel.go | 457 ++++++++++++++++++++
.../api/v1/vertexlabel/vertexlabel_test.go | 168 ++++++++
hugegraph-client-go/go.mod | 4 +
hugegraph-client-go/go.sum | 16 +
hugegraph-client-go/hgtransport/hgtransport.go | 220 ++++++++++
hugegraph-client-go/hgtransport/logger.go | 396 ++++++++++++++++++
hugegraph-client-go/hugegraph.go | 113 +++++
hugegraph-client-go/hugegraph_test.go | 43 ++
hugegraph-client-go/internal/model/model.go | 57 +++
hugegraph-client-go/internal/version/version.go | 21 +
pom.xml | 3 +
41 files changed, 4217 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/client-ci.yml b/.github/workflows/client-ci.yml
index b8c19c70..f9e2dbe7 100644
--- a/.github/workflows/client-ci.yml
+++ b/.github/workflows/client-ci.yml
@@ -1,4 +1,4 @@
-name: "hugegraph-client-ci"
+name: "java-client-ci"
on:
workflow_dispatch:
diff --git a/.github/workflows/client-go-ci.yml
b/.github/workflows/client-go-ci.yml
new file mode 100644
index 00000000..bb97bf73
--- /dev/null
+++ b/.github/workflows/client-go-ci.yml
@@ -0,0 +1,64 @@
+name: "go-client-ci"
+
+on:
+ push:
+ branches:
+ - master
+ - /^release-.*$/
+ paths:
+ - hugegraph-client-go/**
+ - hugegraph-dist/**
+ - .github/workflows/**
+ - pom.xml
+ pull_request:
+ paths:
+ - hugegraph-client-go/**
+ - hugegraph-dist/**
+ - .github/workflows/**
+ - pom.xml
+
+jobs:
+ client-go-ci:
+ runs-on: ubuntu-latest
+ env:
+ TRAVIS_DIR: hugegraph-client/assembly/travis
+ COMMIT_ID: be6ee386b9939dc6bd6fcbdf2274b8acc3a0a314
+ strategy:
+ fail-fast: false
+ matrix:
+ JAVA_VERSION: ['11']
+ steps:
+ - name: Install JDK 11
+ uses: actions/setup-java@v3
+ with:
+ java-version: ${{ matrix.JAVA_VERSION }}
+ distribution: 'zulu'
+
+ - name: Cache Maven packages
+ uses: actions/cache@v3
+ with:
+ path: ~/.m2
+ key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
+ restore-keys: ${{ runner.os }}-m2
+
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 2
+
+ - name: Prepare env and service
+ run: |
+ $TRAVIS_DIR/install-hugegraph-from-source.sh $COMMIT_ID
+
+ - name: Init Go env
+ uses: actions/[email protected]
+ with: { go-version: '1.x' }
+
+ - name: Go test
+ run: |
+ go version
+ sudo swapoff -a
+ sudo sysctl -w vm.swappiness=1
+ sudo sysctl -w fs.file-max=262144
+ sudo sysctl -w vm.max_map_count=262144
+ cd hugegraph-client-go && make test
diff --git a/.github/workflows/hubble-ci.yml b/.github/workflows/hubble-ci.yml
index ce9ec48f..0451f0ce 100644
--- a/.github/workflows/hubble-ci.yml
+++ b/.github/workflows/hubble-ci.yml
@@ -1,4 +1,4 @@
-name: "hugegraph-hubble-ci"
+name: "hubble-ci"
on:
workflow_dispatch:
diff --git a/.github/workflows/loader-ci.yml b/.github/workflows/loader-ci.yml
index 3c676302..267994ed 100644
--- a/.github/workflows/loader-ci.yml
+++ b/.github/workflows/loader-ci.yml
@@ -1,4 +1,4 @@
-name: "hugegraph-loader-ci"
+name: "loader-ci"
on:
workflow_dispatch:
diff --git a/.github/workflows/spark-connector-ci.yml
b/.github/workflows/spark-connector-ci.yml
index c5b312bc..072a7094 100644
--- a/.github/workflows/spark-connector-ci.yml
+++ b/.github/workflows/spark-connector-ci.yml
@@ -1,4 +1,4 @@
-name: "hugegraph-spark-connector-ci"
+name: "spark-connector-ci"
on:
push:
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 3da56372..64b62dc5 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -12,7 +12,7 @@ jobs:
pull-requests: write
steps:
- - uses: actions/stale@v3
+ - uses: actions/stale@v8
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'Due to the lack of activity, the current issue
is marked as stale and will be closed after 20 days, any update will remove the
stale label'
diff --git a/.github/workflows/tools-ci.yml b/.github/workflows/tools-ci.yml
index f00582b2..9c64b9e7 100644
--- a/.github/workflows/tools-ci.yml
+++ b/.github/workflows/tools-ci.yml
@@ -1,4 +1,4 @@
-name: "hugegraph-tools-ci"
+name: "tools-ci"
on:
workflow_dispatch:
push:
diff --git a/.gitignore b/.gitignore
index fe63f8b6..6909ee44 100644
--- a/.gitignore
+++ b/.gitignore
@@ -95,3 +95,6 @@ tree.txt
# system ignore
Thumbs.db
+
+# client-go
+go.env
\ No newline at end of file
diff --git a/.licenserc.yaml b/.licenserc.yaml
index 827be9c8..da6493d7 100644
--- a/.licenserc.yaml
+++ b/.licenserc.yaml
@@ -75,6 +75,9 @@ header: # `header` section is configurations for source codes
license header.
- 'assembly/**'
- '.github/**/*'
- '**/target/*'
+ - 'hugegraph-client-go/go.mod'
+ - 'hugegraph-client-go/go.sum'
+ - 'hugegraph-client-go/Makefile'
-
'hugegraph-client/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker'
# - 'hugegraph-hubble/hubble-fe/**'
comment: on-failure # on what condition license-eye will comment on the pull
request, `on-failure`, `always`, `never`.
diff --git a/hugegraph-client-go/Makefile b/hugegraph-client-go/Makefile
new file mode 100644
index 00000000..0c49457e
--- /dev/null
+++ b/hugegraph-client-go/Makefile
@@ -0,0 +1,72 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# init project path
+HOMEDIR := $(shell pwd)
+OUTDIR := $(HOMEDIR)/output
+
+# Get the go environment required for compilation
+export GOENV = $(HOMEDIR)/go.env
+
+GO := GO111MODULE=on go
+GOPATH := $(shell $(GO) env GOPATH)
+GOMOD := $(GO) mod
+GOBUILD := $(GO) build
+GOTEST := $(GO) test -race -timeout 30s -gcflags="-N -l"
+GOPKGS := $$($(GO) list ./...| grep -vE "vendor")
+
+# test cover files
+COVPROF := $(HOMEDIR)/covprof.out # coverage profile
+COVFUNC := $(HOMEDIR)/covfunc.txt # coverage profile information for each
function
+COVHTML := $(HOMEDIR)/covhtml.html # HTML representation of coverage profile
+
+# make, make all
+all: prepare compile package
+
+set-env:
+ $(GO) env -w GO111MODULE=on
+
+
+#make prepare, download dependencies
+prepare: gomod
+
+gomod: set-env
+ $(GOMOD) download
+
+#make compile
+compile: build
+
+build:
+ $(GOBUILD) -o $(HOMEDIR)/hugegraph-client-go
+# make test, test your code
+test: prepare test-case
+test-case:
+ $(GOTEST) -v -cover $(GOPKGS)
+
+# make package
+package: package-bin
+package-bin:
+ rm -rf $(OUTDIR)
+ mkdir -p $(OUTDIR)
+ mv hugegraph-client-go $(OUTDIR)/
+# make clean
+clean:
+ $(GO) clean
+ rm -rf $(OUTDIR)
+ rm -rf $(GOPATH)/pkg/darwin_amd64
+# avoid filename conflict and speed up build
+.PHONY: all prepare compile test package clean build
diff --git a/hugegraph-client-go/README.en.md b/hugegraph-client-go/README.en.md
new file mode 100644
index 00000000..1b8f37f5
--- /dev/null
+++ b/hugegraph-client-go/README.en.md
@@ -0,0 +1,96 @@
+# go-hugegraph
+
+#### Introduction
+
+HugeGraph client SDK tool based on Go language
+
+#### Software Architecture
+
+Software Architecture Description
+
+#### Installation Tutorial
+
+```Shell
+
+Go get github. com/go huggraph
+
+```
+
+#### Implement API
+
+| API | illustrate |
+|---------|-------------------------|
+| schema | Obtain the model schema |
+| version | Get version information |
+
+#### Instructions for use
+
+##### 1. Initialize the client
+
+```Go
+package main
+
+import "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go"
+import
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/hgtransport"
+
+func main() {
+
+ clinet, err := hugegraph.NewCommonClient(hugegraph.Config{
+ Host: "127.0.0.1",
+ Port: 8080,
+ Graph: "hugegraph",
+ Username: "",
+ Password: "",
+ Logger: &hgtransport.ColorLogger{
+ Output: os.Stdout,
+ EnableRequestBody: true,
+ EnableResponseBody: true,
+ },
+ })
+
+ if err != nil {
+ log.Fatalf("Error creating the client: %s\n", err)
+ }
+}
+```
+
+##### 2. Obtain the hugegraph version
+
+-1. Use the SDK to obtain version information
+
+```Go
+package main
+
+import (
+ "fmt"
+ "log"
+)
+
+func getVersion() {
+
+ client := initClient()
+ res, err := client.Version()
+ if err != nil {
+ log.Fatalf("Error getting the response: %s\n", err)
+ }
+ defer res.Body.Close()
+
+ fmt.Println(res.Versions)
+ fmt.Println(res.Versions.Version)
+}
+```
+
+-2. Result Set Response Body
+
+```Go
+package main
+
+type VersionResponse struct {
+ Versions struct {
+ Version string `json:"version"` // hugegraph version
+ Core string `json:"core"` // hugegraph core version
+ Gremlin string `json:"gremlin"` // hugegraph gremlin version
+ API string `json:"api"` // hugegraph api version
+ } ` json: 'versions'`
+}
+```
diff --git a/hugegraph-client-go/README.md b/hugegraph-client-go/README.md
new file mode 100644
index 00000000..faf0cc06
--- /dev/null
+++ b/hugegraph-client-go/README.md
@@ -0,0 +1,94 @@
+# go-hugegraph
+
+#### 介绍
+
+基于 Go 语言的 HugeGraph Client SDK 工具
+
+#### 软件架构
+
+软件架构说明
+
+#### 安装教程
+
+```shell
+go get github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go
+```
+
+#### 实现 API
+
+| API | 说明 |
+|---------|-------------|
+| schema | 获取模型 schema |
+| version | 获取版本信息 |
+
+#### 使用说明
+
+##### 1.初始化客户端
+
+```go
+package main
+
+import "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go"
+import
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/hgtransport"
+
+func main() {
+
+ clinet, err := hugegraph.NewCommonClient(hugegraph.Config{
+ Host: "127.0.0.1",
+ Port: 8080,
+ Graph: "hugegraph",
+ Username: "",
+ Password: "",
+ Logger: &hgtransport.ColorLogger{
+ Output: os.Stdout,
+ EnableRequestBody: true,
+ EnableResponseBody: true,
+ },
+ })
+
+ if err != nil {
+ log.Fatalf("Error creating the client: %s\n", err)
+ }
+}
+```
+
+##### 2.获取 hugegraph 版本
+
+- 1.使用 SDK 获取版本信息
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+)
+
+func getVersion() {
+
+ client := initClient()
+ res, err := client.Version()
+ if err != nil {
+ log.Fatalf("Error getting the response: %s\n", err)
+ }
+ defer res.Body.Close()
+
+ fmt.Println(res.Versions)
+ fmt.Println(res.Versions.Version)
+}
+```
+
+- 2.返回值的结构
+
+```go
+package main
+
+type VersionResponse struct {
+ Versions struct {
+ Version string `json:"version"` // hugegraph version
+ Core string `json:"core"` // hugegraph core version
+ Gremlin string `json:"gremlin"` // hugegraph gremlin version
+ API string `json:"api"` // hugegraph api version
+ } ` json: 'versions'`
+}
+```
diff --git a/hugegraph-client-go/api/api.go b/hugegraph-client-go/api/api.go
new file mode 100644
index 00000000..ac1ec92d
--- /dev/null
+++ b/hugegraph-client-go/api/api.go
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package api
+
+import (
+ "net/http"
+ "strconv"
+ "time"
+
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/hgtransport"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/internal/version"
+)
+
+// VERSION returns the package version as a string.
+const VERSION = version.Client
+
+// Transport defines the interface for an API client.
+type Transport interface {
+ Perform(*http.Request) (*http.Response, error)
+ GetConfig() hgtransport.Config
+}
+
+// formatDuration converts duration to a string in the format
+// accepted by Hugegraph.
+func formatDuration(d time.Duration) string {
+ if d < time.Millisecond {
+ return strconv.FormatInt(int64(d), 10) + "nanos"
+ }
+ return strconv.FormatInt(int64(d)/int64(time.Millisecond), 10) + "ms"
+}
diff --git a/hugegraph-client-go/api/api.response.go
b/hugegraph-client-go/api/api.response.go
new file mode 100644
index 00000000..b8c80f1e
--- /dev/null
+++ b/hugegraph-client-go/api/api.response.go
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package api
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "strconv"
+ "strings"
+)
+
+// Response represents the API response.
+type Response struct {
+ StatusCode int
+ Header http.Header
+ Body io.ReadCloser
+}
+
+// String returns the response as a string.
+//
+// The intended usage is for testing or debugging only.
+func (r *Response) String() string {
+ var (
+ out = new(bytes.Buffer)
+ b1 = bytes.NewBuffer([]byte{})
+ b2 = bytes.NewBuffer([]byte{})
+ tr io.Reader
+ )
+
+ if r != nil && r.Body != nil {
+ tr = io.TeeReader(r.Body, b1)
+ defer func(Body io.ReadCloser) {
+ err := Body.Close()
+ if err != nil {
+
+ }
+ }(r.Body)
+
+ if _, err := io.Copy(b2, tr); err != nil {
+ out.WriteString(fmt.Sprintf("<error reading response body: %v>",
err))
+ return out.String()
+ }
+ defer func() { r.Body = ioutil.NopCloser(b1) }()
+ }
+
+ if r != nil {
+ out.WriteString(fmt.Sprintf("[%d %s]", r.StatusCode,
http.StatusText(r.StatusCode)))
+ if r.StatusCode > 0 {
+ out.WriteRune(' ')
+ }
+ } else {
+ out.WriteString("[0 <nil>]")
+ }
+
+ if r != nil && r.Body != nil {
+ out.ReadFrom(b2) // errcheck exclude (*bytes.Buffer).ReadFrom
+ }
+
+ return out.String()
+}
+
+// Status returns the response status as a string.
+func (r *Response) Status() string {
+ var b strings.Builder
+ if r != nil {
+ b.WriteString(strconv.Itoa(r.StatusCode))
+ b.WriteString(" ")
+ b.WriteString(http.StatusText(r.StatusCode))
+ }
+ return b.String()
+}
+
+// IsError returns true when the response status indicates failure.
+func (r *Response) IsError() bool {
+ return r.StatusCode > 299
+}
diff --git a/hugegraph-client-go/api/api.resquest.go
b/hugegraph-client-go/api/api.resquest.go
new file mode 100644
index 00000000..9d08acfe
--- /dev/null
+++ b/hugegraph-client-go/api/api.resquest.go
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package api
+
+import (
+ "bytes"
+ "context"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+const (
+ headerContentType = "Content-Type"
+)
+
+var (
+ headerContentTypeJSON = []string{"application/json"}
+)
+
+// Request defines the API request.
+type Request interface {
+ Do(ctx context.Context, transport Transport) (*Response, error)
+}
+
+// newRequest creates an HTTP request.
+func NewRequest(method, path string, params *url.Values, body io.Reader)
(*http.Request, error) {
+
+ u := &url.URL{
+ Path: path,
+ }
+ if params != nil {
+ u.RawQuery = params.Encode()
+ }
+ r := http.Request{
+ Method: method,
+ URL: u,
+ Proto: "HTTP/1.1",
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ Header: make(http.Header),
+ }
+
+ if body != nil {
+ switch b := body.(type) {
+ case *bytes.Buffer:
+ r.Body = ioutil.NopCloser(body)
+ r.ContentLength = int64(b.Len())
+ case *bytes.Reader:
+ r.Body = ioutil.NopCloser(body)
+ r.ContentLength = int64(b.Len())
+ case *strings.Reader:
+ r.Body = ioutil.NopCloser(body)
+ r.ContentLength = int64(b.Len())
+ default:
+ r.Body = ioutil.NopCloser(body)
+ }
+ }
+
+ return &r, nil
+}
diff --git a/hugegraph-client-go/api/v1/api.go
b/hugegraph-client-go/api/v1/api.go
new file mode 100644
index 00000000..09fec0fe
--- /dev/null
+++ b/hugegraph-client-go/api/v1/api.go
@@ -0,0 +1,33 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with this
+* work for additional information regarding copyright ownership. The ASF
+* licenses this file to You under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+ */
+
+package v1
+
+import
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api"
+
+type APIV1 struct {
+ Version Version
+ Schema Schema
+}
+
+// New creates new API
+func New(t api.Transport) *APIV1 {
+ return &APIV1{
+ Version: newVersionFunc(t),
+ Schema: newSchemaFunc(t),
+ }
+}
diff --git a/hugegraph-client-go/api/v1/edge/edge.go
b/hugegraph-client-go/api/v1/edge/edge.go
new file mode 100644
index 00000000..46ac9495
--- /dev/null
+++ b/hugegraph-client-go/api/v1/edge/edge.go
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package edge
+
diff --git a/hugegraph-client-go/api/v1/edge/edge_test.go
b/hugegraph-client-go/api/v1/edge/edge_test.go
new file mode 100644
index 00000000..d2163373
--- /dev/null
+++ b/hugegraph-client-go/api/v1/edge/edge_test.go
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package edge_test
+
+import "testing"
+
+func testEdge(t *testing.T) {
+ // 1.create source vertex
+ // 2.create target vertex
+ // 3.create edge
+}
diff --git a/hugegraph-client-go/api/v1/edgelabel/edgelabel.go
b/hugegraph-client-go/api/v1/edgelabel/edgelabel.go
new file mode 100644
index 00000000..5a2d90a2
--- /dev/null
+++ b/hugegraph-client-go/api/v1/edgelabel/edgelabel.go
@@ -0,0 +1,291 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package edgelabel
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/internal/model"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "strings"
+)
+
+type Edgelabel struct {
+ Create
+ DeleteByName
+ GetAll
+}
+
+func New(t api.Transport) *Edgelabel {
+ return &Edgelabel{
+ // Create
https://hugegraph.apache.org/docs/clients/restful-api/edgelabel/#141-create-an-edgelabel
+ Create: newCreateFunc(t),
+ // DeleteByName
https://hugegraph.apache.org/docs/clients/restful-api/edgelabel/#145-delete-edgelabel-by-name
+ DeleteByName: newDeleteByNameFunc(t),
+ // GetAll
https://hugegraph.apache.org/docs/clients/restful-api/edgelabel/#143-get-all-edgelabels
+ GetAll: newGetAll(t),
+ }
+}
+
+func newCreateFunc(t api.Transport) Create {
+ return func(o ...func(*CreateRequest)) (*CreateResponse, error) {
+ var r = CreateRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newDeleteByNameFunc(t api.Transport) DeleteByName {
+ return func(o ...func(*DeleteByNameRequest)) (*DeleteByNameResponse,
error) {
+ var r = DeleteByNameRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newGetAll(t api.Transport) GetAll {
+ return func(o ...func(*GetAllRequest)) (*GetAllResponse, error) {
+ var r = GetAllRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+
+type Create func(o ...func(*CreateRequest)) (*CreateResponse, error)
+type DeleteByName func(o ...func(*DeleteByNameRequest))
(*DeleteByNameResponse, error)
+type GetAll func(o ...func(*GetAllRequest)) (*GetAllResponse, error)
+
+type CreateRequest struct {
+ Body io.Reader
+ ctx context.Context
+ reqData CreateRequestData
+}
+type CreateRequestData struct {
+ Name string `json:"name"`
+ SourceLabel string `json:"source_label"`
+ TargetLabel string `json:"target_label"`
+ Frequency model.Frequency `json:"frequency"`
+ Properties []string `json:"properties"`
+ SortKeys []string `json:"sort_keys"`
+ NullableKeys []string `json:"nullable_keys"`
+ EnableLabelIndex bool `json:"enable_label_index"`
+}
+type CreateResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data CreateResponseData `json:"-"`
+}
+type CreateResponseData struct {
+ ID int `json:"id"`
+ SortKeys []string `json:"sort_keys"`
+ SourceLabel string `json:"source_label"`
+ Name string `json:"name"`
+ IndexNames []string `json:"index_names"`
+ Properties []string `json:"properties"`
+ TargetLabel string `json:"target_label"`
+ Frequency string `json:"frequency"`
+ NullableKeys []string `json:"nullable_keys"`
+ EnableLabelIndex bool `json:"enable_label_index"`
+ UserData struct {
+ } `json:"user_data"`
+}
+
+type DeleteByNameRequest struct {
+ Body io.Reader
+ ctx context.Context
+ name string
+}
+type DeleteByNameResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data DeleteByNameResponseData `json:"-"`
+}
+type DeleteByNameResponseData struct {
+ TaskID int `json:"task_id"`
+}
+
+type GetAllRequest struct {
+ Body io.Reader
+ ctx context.Context
+}
+type GetAllResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data GetAllResponseData `json:"-"`
+}
+
+type GetAllResponseData struct {
+ Edgelabels []struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ SourceLabel string `json:"source_label"`
+ TargetLabel string `json:"target_label"`
+ Frequency string `json:"frequency"`
+ SortKeys []interface{} `json:"sort_keys"`
+ NullableKeys []interface{} `json:"nullable_keys"`
+ IndexLabels []string `json:"index_labels"`
+ Properties []string `json:"properties"`
+ Status string `json:"status"`
+ TTL int `json:"ttl"`
+ EnableLabelIndex bool `json:"enable_label_index"`
+ UserData struct {
+ CreateTime string `json:"~create_time"`
+ } `json:"user_data"`
+ } `json:"edgelabels"`
+}
+
+func (r Create) WithReqData(reqData CreateRequestData) func(request
*CreateRequest) {
+ return func(r *CreateRequest) {
+ r.reqData = reqData
+ }
+}
+func (p DeleteByName) WithName(name string) func(request *DeleteByNameRequest)
{
+ return func(r *DeleteByNameRequest) {
+ r.name = name
+ }
+}
+
+func (r CreateRequest) Do(ctx context.Context, transport api.Transport)
(*CreateResponse, error) {
+
+ if len(r.reqData.Name) <= 0 {
+ return nil, errors.New("create edgeLabel must set name")
+ }
+ if len(r.reqData.SourceLabel) <= 0 {
+ return nil, errors.New("create edgeLabel must set source_label")
+ }
+ if len(r.reqData.TargetLabel) <= 0 {
+ return nil, errors.New("create edgeLabel must set target_label")
+ }
+ if len(r.reqData.Properties) <= 0 {
+ return nil, errors.New("create edgeLabel must set properties")
+ }
+
+ byteBody, err := json.Marshal(&r.reqData)
+ if err != nil {
+ return nil, err
+ }
+ reader := strings.NewReader(string(byteBody))
+
+ req, err := api.NewRequest("POST",
fmt.Sprintf("/graphs/%s/schema/edgelabels", transport.GetConfig().Graph), nil,
reader)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &CreateResponse{}
+ respData := CreateResponseData{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
+func (r DeleteByNameRequest) Do(ctx context.Context, transport api.Transport)
(*DeleteByNameResponse, error) {
+
+ if len(r.name) <= 0 {
+ return nil, errors.New("delete by name ,please set name")
+ }
+ req, err := api.NewRequest("DELETE",
fmt.Sprintf("/graphs/%s/schema/edgelabels/%s", transport.GetConfig().Graph,
r.name), nil, r.Body)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &DeleteByNameResponse{}
+ respData := DeleteByNameResponseData{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
+func (g GetAllRequest) Do(ctx context.Context, transport api.Transport)
(*GetAllResponse, error) {
+
+ req, err := api.NewRequest("GET",
fmt.Sprintf("/graphs/%s/schema/edgelabels", transport.GetConfig().Graph), nil,
nil)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &GetAllResponse{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ fmt.Println(string(bytes))
+ respData := GetAllResponseData{}
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
diff --git a/hugegraph-client-go/api/v1/edgelabel/edgelabel_test.go
b/hugegraph-client-go/api/v1/edgelabel/edgelabel_test.go
new file mode 100644
index 00000000..6709c17a
--- /dev/null
+++ b/hugegraph-client-go/api/v1/edgelabel/edgelabel_test.go
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package edgelabel_test
+
+import (
+ "fmt"
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1/edgelabel"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1/propertykey"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1/vertexlabel"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/internal/model"
+ "math/rand"
+ "testing"
+ "time"
+)
+
+func TestEdgelabel(t *testing.T) {
+
+ // 1. 创建 Edgelabel
+ client, err := hugegraph.NewDefaultCommonClient()
+ if err != nil {
+ t.Errorf("NewDefaultCommonClient() error = %v", err)
+ }
+
+ rand.Seed(time.Now().UnixNano())
+ randNum := rand.Intn(999999)
+ pkName1 := fmt.Sprintf("tpk1-%d", randNum)
+ pkName2 := fmt.Sprintf("tpk2-%d", randNum)
+
+ vertexLabelName1 := fmt.Sprintf("tvl-1%d", randNum)
+ vertexLabelName2 := fmt.Sprintf("tvl-2%d", randNum)
+ edgeLabelName := fmt.Sprintf("tel-%d", randNum)
+
+ // 创建顶点使用的pk
+ createPk(client, pkName1, t)
+ createPk(client, pkName2, t)
+
+ // 创建source顶点label
+ createVertexLabel(client, vertexLabelName1, t, pkName1, pkName1)
+ // 创建target顶点label
+ createVertexLabel(client, vertexLabelName2, t, pkName1, pkName1)
+ // 创建边的label
+ createEdgeLabel(client, edgeLabelName, t, vertexLabelName1,
vertexLabelName2, []string{}, []string{}, []string{pkName2}, true)
+
+ // 获取边的label
+ allEdgeLabels, err := client.EdgeLabel.GetAll()
+ if err != nil {
+ t.Errorf("client.EdgeLabel.GetAll() error = %v", err)
+ }
+ hasLabel := false
+ for _, edgeLabel := range allEdgeLabels.Data.Edgelabels {
+ if edgeLabel.Name == edgeLabelName {
+ hasLabel = true
+ break
+ }
+ }
+ if !hasLabel {
+ t.Errorf("client.EdgeLabel.GetAll() error = %v", err)
+ }
+
+ // 删除边的label
+ client.EdgeLabel.DeleteByName(
+ client.EdgeLabel.DeleteByName.WithName(edgeLabelName),
+ )
+
+ client.VertexLabel.DeleteByName(
+ client.VertexLabel.DeleteByName.WithName(vertexLabelName1),
+ )
+ client.VertexLabel.DeleteByName(
+ client.VertexLabel.DeleteByName.WithName(vertexLabelName2),
+ )
+
+ //deletePk(client, pkName1, t)
+ //deletePk(client, pkName2, t)
+}
+
+func createPk(client *hugegraph.CommonClient, pkName string, t *testing.T)
*propertykey.CreateResponse {
+ pk1 := propertykey.CreateRequestData{
+ Name: pkName,
+ DataType: model.PropertyDataTypeInt,
+ Cardinality: model.PropertyCardinalitySingle,
+ }
+
+ pk1Resp, err := client.Propertykey.Create(
+ client.Propertykey.Create.WithReqData(pk1),
+ )
+ if err != nil {
+ t.Errorf("Create Propertykey error = %v", err)
+ }
+ if pk1Resp.Data.PropertyKey.Name != pk1.Name {
+ t.Errorf("Create Propertykey error = %v", err)
+ }
+ return pk1Resp
+}
+
+func TestGet(t *testing.T) {
+ client, err := hugegraph.NewDefaultCommonClient()
+ if err != nil {
+ t.Errorf("NewDefaultCommonClient() error = %v", err)
+ }
+ client.EdgeLabel.GetAll()
+}
+
+func createVertexLabel(
+ client *hugegraph.CommonClient,
+ vertexLabelName string,
+ t *testing.T,
+ pkName string,
+ pkNames ...string) *vertexlabel.CreateResponse {
+ createResp, err := client.VertexLabel.Create(
+ client.VertexLabel.Create.WithReqData(
+ vertexlabel.CreateRequestData{
+ Name: vertexLabelName,
+ IDStrategy: model.IDStrategyDefault,
+ Properties: pkNames,
+ PrimaryKeys: []string{
+ pkName,
+ },
+ NullableKeys: []string{},
+ EnableLabelIndex: true,
+ },
+ ),
+ )
+ if err != nil {
+ t.Errorf("Create Vertexlabel error = %v", err)
+ }
+ if createResp.Data.Name != vertexLabelName {
+ t.Errorf("Create Vertexlabel error = %v", err)
+ }
+ return createResp
+}
+
+func createEdgeLabel(
+ client *hugegraph.CommonClient,
+ edgeLabelName string,
+ t *testing.T,
+ sourceLabel string,
+ targetLabel string,
+ sortKeys []string,
+ nullableKeys []string,
+ pkNames []string,
+ enableLabelIndex bool,
+) {
+ // 1. 创建 Edgelabel
+ client.EdgeLabel.Create(
+ client.EdgeLabel.Create.WithReqData(
+ edgelabel.CreateRequestData{
+ Name: edgeLabelName,
+ SourceLabel: sourceLabel,
+ TargetLabel: targetLabel,
+ Frequency: model.FrequencySingle,
+ Properties: pkNames,
+ SortKeys: sortKeys,
+ NullableKeys: nullableKeys,
+ EnableLabelIndex: enableLabelIndex,
+ },
+ ),
+ )
+}
+
+func deletePk(client *hugegraph.CommonClient, name string, t *testing.T) {
+ // propertyKey delete
+ respDelete, err := client.Propertykey.DeleteByName(
+ client.Propertykey.DeleteByName.WithName(name),
+ )
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+ if respDelete.StatusCode > 299 {
+ t.Errorf("delete propertyKey failed")
+ }
+}
diff --git a/hugegraph-client-go/api/v1/gremlin/gemlin.go
b/hugegraph-client-go/api/v1/gremlin/gemlin.go
new file mode 100644
index 00000000..5be0f42b
--- /dev/null
+++ b/hugegraph-client-go/api/v1/gremlin/gemlin.go
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package gremlin
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api"
+ "io"
+ "io/ioutil"
+ "net/http"
+ url2 "net/url"
+ "strings"
+)
+
+type Gremlin struct {
+ Get
+ Post
+}
+
+func New(t api.Transport) *Gremlin {
+ return &Gremlin{
+ Get: newGetFunc(t),
+ Post: newPostFunc(t),
+ }
+}
+
+type Get func(o ...func(*GetRequest)) (*GetResponse, error)
+type Post func(o ...func(*PostRequest)) (*PostResponse, error)
+
+func newGetFunc(t api.Transport) Get {
+ return func(o ...func(*GetRequest)) (*GetResponse, error) {
+ var r = GetRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newPostFunc(t api.Transport) Post {
+ return func(o ...func(*PostRequest)) (*PostResponse, error) {
+ var r = PostRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+
+type GetRequest struct {
+ ctx context.Context
+ gremlin string
+ bindings map[string]string
+ language string
+ aliases map[string]string
+}
+type GetResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+}
+type PostRequest struct {
+ ctx context.Context
+ body io.ReadCloser
+ gremlin string
+ bindings map[string]string
+ language string
+ aliases struct {
+ //Graph string `json:"graph"`
+ //G string `json:"g"`
+ }
+}
+type PostRequestData struct {
+ Gremlin string `json:"gremlin"`
+ Bindings map[string]string `json:"bindings,omitempty"`
+ Language string `json:"language,omitempty"`
+ Aliases struct {
+ //Graph string `json:"graph"`
+ //G string `json:"g"`
+ } `json:"aliases,omitempty"`
+}
+type PostResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data *PostResponseData `json:"data"`
+}
+type PostResponseData struct {
+ RequestID string `json:"requestId,omitempty"`
+ Status struct {
+ Message string `json:"message"`
+ Code int `json:"code"`
+ Attributes struct {
+ } `json:"attributes"`
+ } `json:"status"`
+ Result struct {
+ Data interface{} `json:"data"`
+ Meta interface{} `json:"meta"`
+ } `json:"result,omitempty"`
+ Exception string `json:"exception,omitempty"`
+ Message string `json:"message,omitempty"`
+ Cause string `json:"cause,omitempty"`
+ Trace []string `json:"trace,omitempty"`
+}
+
+func (g Get) WithGremlin(gremlin string) func(request *GetRequest) {
+ return func(r *GetRequest) {
+ r.gremlin = gremlin
+ }
+}
+func (g Post) WithGremlin(gremlin string) func(request *PostRequest) {
+ return func(r *PostRequest) {
+ r.gremlin = gremlin
+ }
+}
+
+func (g GetRequest) Do(ctx context.Context, transport api.Transport)
(*GetResponse, error) {
+
+ url := "/gremlin"
+ params := &url2.Values{}
+ if len(g.gremlin) <= 0 {
+ return nil, errors.New("please set gremlin")
+ } else {
+ params.Add("gremlin", g.gremlin)
+ }
+ if len(g.language) > 0 {
+ params.Add("language", g.language)
+ }
+
+ if g.aliases != nil && len(g.aliases) >= 0 {
+ aliasesJsonStr, err := json.Marshal(g.aliases)
+ if err != nil {
+ return nil, err
+ }
+ params.Add("aliases", string(aliasesJsonStr))
+ }
+
+ if g.bindings != nil && len(g.bindings) >= 0 {
+ bindingsJsonStr, err := json.Marshal(g.bindings)
+ if err != nil {
+ return nil, err
+ }
+ params.Add("bindings", string(bindingsJsonStr))
+ }
+
+ req, err := api.NewRequest("GET", url, params, nil)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ fmt.Println(string(bytes))
+
+ gremlinGetResponse := &GetResponse{}
+ gremlinGetResponse.StatusCode = res.StatusCode
+ return gremlinGetResponse, nil
+}
+func (g PostRequest) Do(ctx context.Context, transport api.Transport)
(*PostResponse, error) {
+
+ if len(g.gremlin) < 1 {
+ return nil, errors.New("PostRequest param error , gremlin is empty")
+ }
+
+ if len(g.language) < 1 {
+ g.language = "gremlin-groovy"
+ }
+
+ gd := &PostRequestData{
+ Gremlin: g.gremlin,
+ Bindings: g.bindings,
+ Language: g.language,
+ Aliases: g.aliases,
+ }
+
+ byteBody, err := json.Marshal(&gd) // 序列化
+
+ if err != nil {
+ return nil, err
+ }
+
+ reader := strings.NewReader(string(byteBody))
+ req, _ := api.NewRequest("POST", "/gremlin", nil, reader)
+
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ gremlinPostResp := &PostResponse{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ respData := &PostResponseData{}
+ err = json.Unmarshal(bytes, respData)
+ if err != nil {
+ return nil, err
+ }
+ gremlinPostResp.StatusCode = res.StatusCode
+ gremlinPostResp.Header = res.Header
+ gremlinPostResp.Body = res.Body
+ gremlinPostResp.Data = respData
+ return gremlinPostResp, nil
+}
diff --git a/hugegraph-client-go/api/v1/gremlin/gemlin_test.go
b/hugegraph-client-go/api/v1/gremlin/gemlin_test.go
new file mode 100644
index 00000000..c8cddd67
--- /dev/null
+++ b/hugegraph-client-go/api/v1/gremlin/gemlin_test.go
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package gremlin_test
+
+import (
+ "fmt"
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go"
+ "log"
+ "testing"
+)
+
+func TestGremlin(t *testing.T) {
+
+ client, err := hugegraph.NewDefaultCommonClient()
+ if err != nil {
+ log.Println(err)
+ }
+ respGet, err := client.Gremlin.Get(
+ client.Gremlin.Get.WithGremlin("hugegraph.traversal().V().limit(3)"),
+ )
+ if err != nil {
+ log.Fatalln(err)
+ }
+ if respGet.StatusCode != 200 {
+ t.Error("client.Gremlin.GremlinGet error ")
+ }
+
+ respPost, err := client.Gremlin.Post(
+ client.Gremlin.Post.WithGremlin("hugegraph.traversal().V().limit(3)"),
+ )
+ if err != nil {
+ log.Fatalln(err)
+ }
+ fmt.Println(respPost.Data.Result.Data)
+
+}
diff --git a/hugegraph-client-go/api/v1/propertykey/propertykey.go
b/hugegraph-client-go/api/v1/propertykey/propertykey.go
new file mode 100644
index 00000000..125d9a08
--- /dev/null
+++ b/hugegraph-client-go/api/v1/propertykey/propertykey.go
@@ -0,0 +1,458 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with this
+* work for additional information regarding copyright ownership. The ASF
+* licenses this file to You under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+ */
+
+package propertykey
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/internal/model"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+type PropertyKey struct {
+ Create
+ DeleteByName
+ GetAll
+ GetByName
+ UpdateUserdata
+}
+
+func New(t api.Transport) *PropertyKey {
+ return &PropertyKey{
+ // Create
https://hugegraph.apache.org/docs/clients/restful-api/propertykey/#121-create-a-propertykey
+ Create: newCreateFunc(t),
+ // DeleteByName
https://hugegraph.apache.org/docs/clients/restful-api/propertykey/#125-delete-propertykey-according-to-name
+ DeleteByName: newDeleteByNameFunc(t),
+ // GetAll
https://hugegraph.apache.org/docs/clients/restful-api/propertykey/#123-get-all-propertykeys
+ GetAll: newGetAllFunc(t),
+ // GetByName
https://hugegraph.apache.org/docs/clients/restful-api/propertykey/#124-get-propertykey-according-to-name
+ GetByName: newGetByNameFunc(t),
+ // UpdateUserdata
https://hugegraph.apache.org/docs/clients/restful-api/propertykey/#122-add-or-remove-userdata-for-an-existing-propertykey
+ UpdateUserdata: newUpdateUserdataFunc(t),
+ }
+}
+
+func newCreateFunc(t api.Transport) Create {
+ return func(o ...func(*CreateRequest)) (*CreateResponse, error) {
+ var r = CreateRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newDeleteByNameFunc(t api.Transport) DeleteByName {
+ return func(o ...func(*DeleteByNameRequest)) (*DeleteByNameResponse,
error) {
+ var r = DeleteByNameRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newGetAllFunc(t api.Transport) GetAll {
+ return func(o ...func(*GetAllRequest)) (*GetAllResponse, error) {
+ var r = GetAllRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newGetByNameFunc(t api.Transport) GetByName {
+ return func(o ...func(*GetByNameRequest)) (*GetByNameResponse, error) {
+ var r = GetByNameRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newUpdateUserdataFunc(t api.Transport) UpdateUserdata {
+ return func(o ...func(*UpdateUserdataRequest)) (*UpdateUserdataResponse,
error) {
+ var r = UpdateUserdataRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+
+type Create func(o ...func(*CreateRequest)) (*CreateResponse, error)
+type DeleteByName func(o ...func(*DeleteByNameRequest))
(*DeleteByNameResponse, error)
+type GetAll func(o ...func(*GetAllRequest)) (*GetAllResponse, error)
+type GetByName func(o ...func(*GetByNameRequest)) (*GetByNameResponse, error)
+type UpdateUserdata func(o ...func(*UpdateUserdataRequest))
(*UpdateUserdataResponse, error)
+
+type CreateRequest struct {
+ Body io.Reader
+ ctx context.Context
+ reqData CreateRequestData
+}
+type CreateRequestData struct {
+ Name string `json:"name"`
+ DataType model.PropertyDataType `json:"data_type"`
+ Cardinality model.PropertyCardinality `json:"cardinality"`
+}
+type CreateResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data CreateResponseData `json:"versions"`
+}
+type CreateResponseData struct {
+ PropertyKey struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ DataType string `json:"data_type"`
+ Cardinality string `json:"cardinality"`
+ AggregateType string `json:"aggregate_type"`
+ WriteType string `json:"write_type"`
+ Properties []interface{} `json:"properties"`
+ Status string `json:"status"`
+ UserData struct {
+ CreateTime string `json:"~create_time"`
+ } `json:"user_data"`
+ } `json:"property_key"`
+ TaskID int `json:"task_id"`
+}
+
+type DeleteByNameRequest struct {
+ Body io.Reader
+ ctx context.Context
+ name string
+}
+type DeleteByNameResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data DeleteByNameResponseData `json:"versions"`
+}
+type DeleteByNameResponseData struct {
+ TaskID int `json:"task_id"`
+}
+
+type GetAllRequest struct {
+ Body io.Reader
+ ctx context.Context
+}
+type GetAllResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data GetAllResponseData `json:"-"`
+}
+type GetAllResponseData struct {
+ Propertykeys []struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ DataType string `json:"data_type"`
+ Cardinality string `json:"cardinality"`
+ Properties []interface{} `json:"properties"`
+ UserData struct {
+ } `json:"user_data"`
+ } `json:"propertykeys"`
+}
+
+type GetByNameRequest struct {
+ Body io.Reader
+ ctx context.Context
+ name string
+}
+type GetByNameResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data GetByNameResponseData `json:"-"`
+}
+type GetByNameResponseData struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ DataType string `json:"data_type"`
+ Cardinality string `json:"cardinality"`
+ AggregateType string `json:"aggregate_type"`
+ WriteType string `json:"write_type"`
+ Properties []interface{} `json:"properties"`
+ Status string `json:"status"`
+ UserData struct {
+ Min int `json:"min"`
+ Max int `json:"max"`
+ CreateTime string `json:"~create_time"`
+ } `json:"user_data"`
+}
+
+type UpdateUserdataRequest struct {
+ Body io.Reader
+ ctx context.Context
+ reqData UpdateUserdataRequestData
+}
+type UpdateUserdataRequestData struct {
+ Action model.Action `json:"-"`
+ Name string `json:"name"`
+ UserData struct {
+ Min int `json:"min"`
+ Max int `json:"max"`
+ } `json:"user_data"`
+}
+type UpdateUserdataResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data UpdateUserdataResponseData `json:"-"`
+}
+type UpdateUserdataResponseData struct {
+ PropertyKey struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ DataType string `json:"data_type"`
+ Cardinality string `json:"cardinality"`
+ AggregateType string `json:"aggregate_type"`
+ WriteType string `json:"write_type"`
+ Properties []interface{} `json:"properties"`
+ Status string `json:"status"`
+ UserData struct {
+ Min int `json:"min"`
+ Max int `json:"max"`
+ CreateTime string `json:"~create_time"`
+ } `json:"user_data"`
+ } `json:"property_key"`
+ TaskID int `json:"task_id"`
+}
+
+func (r CreateRequest) Do(ctx context.Context, transport api.Transport)
(*CreateResponse, error) {
+
+ if len(r.reqData.Name) <= 0 {
+ return nil, errors.New("create property must set name")
+ }
+ if len(r.reqData.DataType) <= 0 {
+ return nil, errors.New("create property must set dataType")
+ }
+ if len(r.reqData.Cardinality) <= 0 {
+ return nil, errors.New("create property must set cardinality")
+ }
+
+ byteBody, err := json.Marshal(&r.reqData)
+ if err != nil {
+ return nil, err
+ }
+ reader := strings.NewReader(string(byteBody))
+
+ req, err := api.NewRequest("POST",
fmt.Sprintf("/graphs/%s/schema/propertykeys", transport.GetConfig().Graph),
nil, reader)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &CreateResponse{}
+ respData := CreateResponseData{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
+func (r DeleteByNameRequest) Do(ctx context.Context, transport api.Transport)
(*DeleteByNameResponse, error) {
+
+ if len(r.name) <= 0 {
+ return nil, errors.New("delete by name ,please set name")
+ }
+ req, err := api.NewRequest("DELETE",
fmt.Sprintf("/graphs/%s/schema/propertykeys/%s", transport.GetConfig().Graph,
r.name), nil, r.Body)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &DeleteByNameResponse{}
+ respData := DeleteByNameResponseData{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
+func (r GetAllRequest) Do(ctx context.Context, transport api.Transport)
(*GetAllResponse, error) {
+
+ req, err := api.NewRequest("GET",
fmt.Sprintf("/graphs/%s/schema/propertykeys", transport.GetConfig().Graph),
nil, r.Body)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &GetAllResponse{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ respData := GetAllResponseData{}
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
+func (r GetByNameRequest) Do(ctx context.Context, transport api.Transport)
(*GetByNameResponse, error) {
+
+ if len(r.name) <= 0 {
+ return nil, errors.New("get_by_name must set name")
+ }
+
+ req, err := api.NewRequest("GET",
fmt.Sprintf("/graphs/%s/schema/propertykeys/%s", transport.GetConfig().Graph,
r.name), nil, r.Body)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &GetByNameResponse{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ respData := GetByNameResponseData{}
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
+func (r UpdateUserdataRequest) Do(ctx context.Context, transport
api.Transport) (*UpdateUserdataResponse, error) {
+
+ params := &url.Values{}
+ if len(r.reqData.Action) <= 0 {
+ return nil, errors.New("property update userdata must set action")
+ } else {
+ params.Add("action", string(r.reqData.Action))
+ }
+ if len(r.reqData.Name) <= 0 {
+ return nil, errors.New("property update userdata must set name")
+ }
+
+ byteBody, err := json.Marshal(&r.reqData)
+ if err != nil {
+ return nil, err
+ }
+ reader := strings.NewReader(string(byteBody))
+
+ req, err := api.NewRequest("PUT",
fmt.Sprintf("/graphs/%s/schema/propertykeys/%s", transport.GetConfig().Graph,
r.reqData.Name), params, reader)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &UpdateUserdataResponse{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ respData := UpdateUserdataResponseData{}
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
+
+func (r Create) WithReqData(reqData CreateRequestData) func(request
*CreateRequest) {
+ return func(r *CreateRequest) {
+ r.reqData = reqData
+ }
+}
+func (p DeleteByName) WithName(name string) func(request *DeleteByNameRequest)
{
+ return func(r *DeleteByNameRequest) {
+ r.name = name
+ }
+}
+func (r GetByName) WithName(name string) func(request *GetByNameRequest) {
+ return func(r *GetByNameRequest) {
+ r.name = name
+ }
+}
+func (r UpdateUserdata) WithReqData(reqData UpdateUserdataRequestData)
func(request *UpdateUserdataRequest) {
+ return func(r *UpdateUserdataRequest) {
+ r.reqData = reqData
+ }
+}
diff --git a/hugegraph-client-go/api/v1/propertykey/propertykey_test.go
b/hugegraph-client-go/api/v1/propertykey/propertykey_test.go
new file mode 100644
index 00000000..14e1e99c
--- /dev/null
+++ b/hugegraph-client-go/api/v1/propertykey/propertykey_test.go
@@ -0,0 +1,120 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with this
+* work for additional information regarding copyright ownership. The ASF
+* licenses this file to You under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+ */
+
+package propertykey_test
+
+import (
+ "fmt"
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1/propertykey"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/internal/model"
+ "log"
+ "math/rand"
+ "testing"
+ "time"
+)
+
+func TestPropertyKey(t *testing.T) {
+
+ client, err := hugegraph.NewDefaultCommonClient()
+ if err != nil {
+ log.Println(err)
+ }
+ rand.Seed(time.Now().UnixNano())
+ name := fmt.Sprintf("testProperty%d", rand.Intn(99999))
+
+ // create propertyKey
+ respCreate, err := client.Propertykey.Create(
+ client.Propertykey.Create.WithReqData(
+ propertykey.CreateRequestData{
+ Name: name,
+ DataType: model.PropertyDataTypeInt,
+ Cardinality: model.PropertyCardinalitySingle,
+ },
+ ),
+ )
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+ if respCreate.Data.PropertyKey.Name != name ||
respCreate.Data.PropertyKey.ID <= 0 {
+ t.Errorf("create propertyKey failed")
+ }
+
+ // propertyKey get all
+ respGetAll, err := client.Propertykey.GetAll()
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+
+ hasCreated := false
+ for _, pk := range respGetAll.Data.Propertykeys {
+ if pk.Name == name {
+ hasCreated = true
+ }
+ }
+ if !hasCreated {
+ t.Errorf("get all propertyKey failed")
+ }
+
+ // propertyKey update user_data
+ respUpdateUserdata, err := client.Propertykey.UpdateUserdata(
+ client.Propertykey.UpdateUserdata.WithReqData(
+ propertykey.UpdateUserdataRequestData{
+ Action: model.ActionAppend,
+ Name: name,
+ UserData: struct {
+ Min int `json:"min"`
+ Max int `json:"max"`
+ }(struct {
+ Min int
+ Max int
+ }{
+ Min: 1,
+ Max: 10,
+ }),
+ },
+ ),
+ )
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+ if respUpdateUserdata.Data.PropertyKey.UserData.Max != 10 {
+ t.Errorf("update userdata propertyKey failed")
+ }
+
+ // propertyKey get by name
+ respGetByName, err := client.Propertykey.GetByName(
+ client.Propertykey.GetByName.WithName(name),
+ )
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+ if respGetByName.Data.Name != name || respGetByName.Data.ID <= 0 ||
respGetByName.Data.UserData.Max != 10 {
+ t.Errorf("getByName propertyKey failed")
+ }
+
+ // propertyKey delete
+ respDelete, err := client.Propertykey.DeleteByName(
+ client.Propertykey.DeleteByName.WithName(name),
+ )
+ if err != nil {
+ t.Errorf(err.Error())
+ }
+ if respDelete.StatusCode > 299 {
+ t.Errorf("delete propertyKey failed")
+ }
+}
diff --git a/hugegraph-client-go/api/v1/schema.go
b/hugegraph-client-go/api/v1/schema.go
new file mode 100644
index 00000000..ebe237ff
--- /dev/null
+++ b/hugegraph-client-go/api/v1/schema.go
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package v1
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/hgtransport"
+ "io"
+ "io/ioutil"
+ "net/http"
+
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api"
+)
+
+// ----- API Definition -------------------------------------------------------
+// View Schema information of HugeGraph
+//
+// See full documentation at
https://hugegraph.apache.org/docs/clients/restful-api/schema/#11-schema
+func newSchemaFunc(t api.Transport) Schema {
+ return func(o ...func(*SchemaRequest)) (*SchemaResponse, error) {
+ var r = SchemaRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+
+type Schema func(o ...func(*SchemaRequest)) (*SchemaResponse, error)
+
+type SchemaRequest struct {
+ Body io.Reader
+ ctx context.Context
+ config hgtransport.Config
+}
+
+type SchemaResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data SchemaResponseData `json:"-"`
+}
+
+type SchemaResponseData struct {
+ Propertykeys []struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ DataType string `json:"data_type"`
+ Cardinality string `json:"cardinality"`
+ AggregateType string `json:"aggregate_type"`
+ WriteType string `json:"write_type"`
+ Properties []interface{} `json:"properties"`
+ Status string `json:"status"`
+ UserData struct {
+ CreateTime string `json:"~create_time"`
+ } `json:"user_data"`
+ } `json:"propertykeys"`
+ Vertexlabels []struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ IDStrategy string `json:"id_strategy"`
+ PrimaryKeys []string `json:"primary_keys"`
+ NullableKeys []interface{} `json:"nullable_keys"`
+ IndexLabels []string `json:"index_labels"`
+ Properties []string `json:"properties"`
+ Status string `json:"status"`
+ TTL int `json:"ttl"`
+ EnableLabelIndex bool `json:"enable_label_index"`
+ UserData struct {
+ CreateTime string `json:"~create_time"`
+ } `json:"user_data"`
+ } `json:"vertexlabels"`
+ Edgelabels []struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ SourceLabel string `json:"source_label"`
+ TargetLabel string `json:"target_label"`
+ Frequency string `json:"frequency"`
+ SortKeys []interface{} `json:"sort_keys"`
+ NullableKeys []interface{} `json:"nullable_keys"`
+ IndexLabels []string `json:"index_labels"`
+ Properties []string `json:"properties"`
+ Status string `json:"status"`
+ TTL int `json:"ttl"`
+ EnableLabelIndex bool `json:"enable_label_index"`
+ UserData struct {
+ CreateTime string `json:"~create_time"`
+ } `json:"user_data"`
+ } `json:"edgelabels"`
+ Indexlabels []struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ BaseType string `json:"base_type"`
+ BaseValue string `json:"base_value"`
+ IndexType string `json:"index_type"`
+ Fields []string `json:"fields"`
+ Status string `json:"status"`
+ UserData struct {
+ CreateTime string `json:"~create_time"`
+ } `json:"user_data"`
+ } `json:"indexlabels"`
+}
+
+func (r SchemaRequest) Do(ctx context.Context, transport api.Transport)
(*SchemaResponse, error) {
+
+ req, err := api.NewRequest("GET", fmt.Sprintf("/graphs/%s/schema",
transport.GetConfig().Graph), nil, r.Body)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ schemaRespData := SchemaResponseData{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bytes, &schemaRespData)
+ if err != nil {
+ return nil, err
+ }
+ schemaResp := &SchemaResponse{}
+ schemaResp.StatusCode = res.StatusCode
+ schemaResp.Header = res.Header
+ schemaResp.Body = res.Body
+ schemaResp.Data = schemaRespData
+ return schemaResp, nil
+}
diff --git a/hugegraph-client-go/api/v1/schema_test.go
b/hugegraph-client-go/api/v1/schema_test.go
new file mode 100644
index 00000000..47daab74
--- /dev/null
+++ b/hugegraph-client-go/api/v1/schema_test.go
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package v1_test
+
+import (
+ "fmt"
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go"
+ "log"
+ "testing"
+)
+
+func TestSchemaRequest_Do(t *testing.T) {
+ client, err := hugegraph.NewDefaultCommonClient()
+ if err != nil {
+ log.Println(err)
+ }
+ schema, err := client.Schema()
+ if err != nil {
+ log.Fatalln(err)
+ }
+ fmt.Println(schema.Data)
+}
diff --git a/hugegraph-client-go/api/v1/version.go
b/hugegraph-client-go/api/v1/version.go
new file mode 100644
index 00000000..e3a55990
--- /dev/null
+++ b/hugegraph-client-go/api/v1/version.go
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package v1
+
+import (
+ "context"
+ "encoding/json"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/hgtransport"
+ "io"
+ "io/ioutil"
+ "net/http"
+
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api"
+)
+
+// ----- API Definition -------------------------------------------------------
+// View version information of HugeGraph
+//
+// See full documentation at
https://hugegraph.apache.org/docs/clients/restful-api/other/#1111-view-version-information-of-hugegraph
+func newVersionFunc(t api.Transport) Version {
+ return func(o ...func(*VersionRequest)) (*VersionResponse, error) {
+ var r = VersionRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+
+type Version func(o ...func(*VersionRequest)) (*VersionResponse, error)
+
+type VersionRequest struct {
+ Body io.Reader
+ ctx context.Context
+ config hgtransport.Config
+}
+
+type VersionResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Versions VersionResponseData `json:"versions"`
+}
+
+type VersionResponseData struct {
+ Version string `json:"version"` // hugegraph version
+ Core string `json:"core"` // hugegraph core version
+ Gremlin string `json:"gremlin"` // hugegraph gremlin version
+ API string `json:"api"` // hugegraph api version
+}
+
+func (r VersionRequest) Do(ctx context.Context, transport api.Transport)
(*VersionResponse, error) {
+
+ req, err := api.NewRequest("GET", "/versions", nil, r.Body)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ versionResp := &VersionResponse{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bytes, versionResp)
+ if err != nil {
+ return nil, err
+ }
+ versionResp.StatusCode = res.StatusCode
+ versionResp.Header = res.Header
+ versionResp.Body = res.Body
+ return versionResp, nil
+}
diff --git a/hugegraph-client-go/api/v1/version_test.go
b/hugegraph-client-go/api/v1/version_test.go
new file mode 100644
index 00000000..62309885
--- /dev/null
+++ b/hugegraph-client-go/api/v1/version_test.go
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package v1_test
+
+import (
+ "testing"
+
+ hugegraph
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go"
+)
+
+func TestVersionRequest_Do(t *testing.T) {
+
+ client, err := hugegraph.NewDefaultCommonClient()
+ if err != nil {
+ t.Errorf("NewDefaultCommonClient() error = %v", err)
+ }
+
+ resp, err := client.Version()
+ if err != nil {
+ t.Errorf(" client.Version() error = %v", err)
+ }
+ if resp.StatusCode != 200 {
+ t.Errorf(" client.Version() code error = %v", resp.StatusCode)
+ }
+}
diff --git a/hugegraph-client-go/api/v1/vertex/vertex.go
b/hugegraph-client-go/api/v1/vertex/vertex.go
new file mode 100644
index 00000000..0e2a3c52
--- /dev/null
+++ b/hugegraph-client-go/api/v1/vertex/vertex.go
@@ -0,0 +1,304 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package vertex
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/internal/model"
+ "io"
+ "io/ioutil"
+ "net/http"
+ url2 "net/url"
+ "strings"
+)
+
+type Vertex struct {
+ Create
+ BatchCreate
+ UpdateProperties
+ BatchUpdateProperties
+ DeleteProperties
+ GetByCond
+ GetByID
+ DeleteByID
+}
+
+func New(t api.Transport) *Vertex {
+ return &Vertex{
+ // Create
https://hugegraph.apache.org/docs/clients/restful-api/vertex/#211-create-a-vertex
+ Create: newCreateFunc(t),
+ // BatchCreate
https://hugegraph.apache.org/docs/clients/restful-api/vertex/#212-create-multiple-vertices
+ BatchCreate: newBatchCreateFunc(t),
+ // UpdateProperties
https://hugegraph.apache.org/docs/clients/restful-api/vertex/#213-update-vertex-properties
+ UpdateProperties: newUpdatePropertiesFunc(t),
+ }
+}
+
+type CreateReq struct {
+ ctx context.Context
+ data model.Vertex[any]
+}
+type CreateResp struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data model.Vertex[any]
+}
+type BatchCreateReq struct {
+ ctx context.Context
+ vertices []model.Vertex[any]
+}
+type BatchCreateResp struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ IDs []string
+}
+type UpdatePropertiesReq struct {
+ ctx context.Context
+ id string
+ action model.Action
+ vertex model.Vertex[any]
+}
+type UpdatePropertiesResp struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data model.Vertex[any]
+}
+
+type Create func(o ...func(*CreateReq)) (*CreateResp, error)
+type BatchCreate func(o ...func(*BatchCreateReq)) (*BatchCreateResp, error)
+type UpdateProperties func(o ...func(*UpdatePropertiesReq))
(*UpdatePropertiesResp, error)
+type BatchUpdateProperties func(o ...func(*CreateReq)) (*CreateResp, error)
+type DeleteProperties func(o ...func(*CreateReq)) (*CreateResp, error)
+type GetByCond func(o ...func(*CreateReq)) (*CreateResp, error)
+type GetByID func(o ...func(*CreateReq)) (*CreateResp, error)
+type DeleteByID func(o ...func(*CreateReq)) (*CreateResp, error)
+
+func newCreateFunc(t api.Transport) Create {
+ return func(o ...func(*CreateReq)) (*CreateResp, error) {
+ var r = CreateReq{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newBatchCreateFunc(t api.Transport) BatchCreate {
+ return func(o ...func(*BatchCreateReq)) (*BatchCreateResp, error) {
+ var r = BatchCreateReq{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newUpdatePropertiesFunc(t api.Transport) UpdateProperties {
+ return func(o ...func(*UpdatePropertiesReq)) (*UpdatePropertiesResp,
error) {
+ var r = UpdatePropertiesReq{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+
+func (c Create) WithContext(ctx context.Context) func(*CreateReq) {
+ return func(req *CreateReq) {
+ req.ctx = ctx
+ }
+}
+func (c BatchCreate) WithContext(ctx context.Context) func(req
*BatchCreateReq) {
+ return func(req *BatchCreateReq) {
+ req.ctx = ctx
+ }
+}
+func (c UpdateProperties) WithContext(ctx context.Context) func(req
*UpdatePropertiesReq) {
+ return func(req *UpdatePropertiesReq) {
+ req.ctx = ctx
+ }
+}
+
+func (c Create) WithVertex(vertex model.Vertex[any]) func(*CreateReq) {
+ return func(req *CreateReq) {
+ req.data = vertex
+ }
+}
+func (c BatchCreate) WithVertices(vertices []model.Vertex[any])
func(*BatchCreateReq) {
+ return func(req *BatchCreateReq) {
+ req.vertices = vertices
+ }
+}
+func (c UpdateProperties) WithVertex(vertex model.Vertex[any])
func(*UpdatePropertiesReq) {
+ return func(req *UpdatePropertiesReq) {
+ req.vertex = vertex
+ }
+}
+func (c UpdateProperties) WithID(ID string) func(*UpdatePropertiesReq) {
+ return func(req *UpdatePropertiesReq) {
+ req.id = ID
+ }
+}
+func (c UpdateProperties) WithAction(action model.Action)
func(*UpdatePropertiesReq) {
+ return func(req *UpdatePropertiesReq) {
+ req.action = action
+ }
+}
+
+func (c CreateReq) Do(ctx context.Context, transport api.Transport)
(*CreateResp, error) {
+ config := transport.GetConfig()
+ url := ""
+ if len(config.GraphSpace) > 0 {
+ url = fmt.Sprintf("/graphspaces/%s/graphs/%s/graph/vertices",
config.GraphSpace, config.Graph)
+ } else {
+ url = fmt.Sprintf("/graphs/%s/graph/vertices", config.Graph)
+ }
+
+ jsonData, err := json.Marshal(c.data)
+ if err != nil {
+ return nil, err
+ }
+ reader := strings.NewReader(string(jsonData))
+
+ req, err := api.NewRequest("POST", url, nil, reader)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ vertexCreateRespData := model.Vertex[any]{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bytes, &vertexCreateRespData)
+ if err != nil {
+ return nil, err
+ }
+ resp := &CreateResp{}
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = vertexCreateRespData
+
+ return resp, nil
+}
+func (c BatchCreateReq) Do(ctx context.Context, transport api.Transport)
(*BatchCreateResp, error) {
+ config := transport.GetConfig()
+ url := ""
+ if len(config.GraphSpace) > 0 {
+ url = fmt.Sprintf("/graphspaces/%s/graphs/%s/graph/vertices/batch",
config.GraphSpace, config.Graph)
+ } else {
+ url = fmt.Sprintf("/graphs/%s/graph/vertices/batch", config.Graph)
+ }
+
+ jsonData, err := json.Marshal(c.vertices)
+ if err != nil {
+ return nil, err
+ }
+ reader := strings.NewReader(string(jsonData))
+
+ req, err := api.NewRequest("POST", url, nil, reader)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ vertexCreateRespData := make([]string, 0)
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bytes, &vertexCreateRespData)
+ if err != nil {
+ return nil, err
+ }
+ resp := &BatchCreateResp{}
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.IDs = vertexCreateRespData
+ return resp, nil
+}
+func (c UpdatePropertiesReq) Do(ctx context.Context, transport api.Transport)
(*UpdatePropertiesResp, error) {
+ config := transport.GetConfig()
+ url := ""
+ if len(config.GraphSpace) > 0 {
+ url = fmt.Sprintf("/graphspaces/%s/graphs/%s/graph/vertices/\"%s\"",
config.GraphSpace, config.Graph, c.id)
+ } else {
+ url = fmt.Sprintf("/graphs/%s/graph/vertices/\"%s\"", config.Graph,
c.id)
+ }
+
+ params := &url2.Values{}
+ params.Add("action", string(c.action))
+
+ jsonData, err := json.Marshal(c.vertex)
+ if err != nil {
+ return nil, err
+ }
+ reader := strings.NewReader(string(jsonData))
+
+ req, err := api.NewRequest("PUT", url, params, reader)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ respData := model.Vertex[any]{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp := &UpdatePropertiesResp{}
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+
+ return resp, nil
+}
diff --git a/hugegraph-client-go/api/v1/vertex/vertex_test.go
b/hugegraph-client-go/api/v1/vertex/vertex_test.go
new file mode 100644
index 00000000..4af7fc4d
--- /dev/null
+++ b/hugegraph-client-go/api/v1/vertex/vertex_test.go
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package vertex_test
+
+import (
+ "testing"
+)
+
+type Person struct {
+ Name string `json:"name,omitempty"`
+ Age uint64 `json:"age,omitempty"`
+ City string `json:"city,omitempty"`
+}
+
+func TestVertex(t *testing.T) {
+
+ // 1.create
+ //client, err := hugegraph.NewDefaultCommonClient()
+ //ctx := context.Background()
+ //if err != nil {
+ // log.Println(err)
+ //}
+ //person := Person{
+ // Name: "tom",
+ // Age: 18,
+ // City: "beijing",
+ //}
+ //
+ //vertex := model.Vertex[any]{
+ // Label: "person",
+ // Properties: person,
+ //}
+ //
+ //// create
+ //respCreate, err := client.Vertex.Create(
+ // client.Vertex.Create.WithContext(ctx),
+ // client.Vertex.Create.WithVertex(vertex),
+ //)
+ //if err != nil {
+ // log.Println(err)
+ //}
+ //vertexID := respCreate.Data.ID
+ //fmt.Println(vertexID)
+ //
+ //// batchCreate
+ //vertices := []model.Vertex[any]{
+ // {
+ // Label: "person",
+ // Properties: Person{
+ // Name: "bob",
+ // Age: 22,
+ // City: "shanghai",
+ // },
+ // },
+ // {
+ // Label: "person",
+ // Properties: Person{
+ // Name: "angle",
+ // Age: 28,
+ // City: "guangzhou",
+ // },
+ // },
+ //}
+ //
+ //respBatchResp, err := client.Vertex.BatchCreate(
+ // client.Vertex.BatchCreate.WithContext(ctx),
+ // client.Vertex.BatchCreate.WithVertices(vertices),
+ //)
+ //if err != nil {
+ // log.Println(err)
+ //}
+ //for i, datum := range respBatchResp.IDs {
+ // fmt.Printf("index:%d\tid:%s\n", i, datum)
+ //}
+ //
+ //// update properties
+ //updatePerson := model.Vertex[any]{
+ // Label: "person",
+ // Properties: Person{
+ // Age: 10,
+ // },
+ //}
+ //respUpdate, err := client.Vertex.UpdateProperties(
+ // client.Vertex.UpdateProperties.WithContext(ctx),
+ // client.Vertex.UpdateProperties.WithVertex(updatePerson),
+ // client.Vertex.UpdateProperties.WithID(vertexID),
+ // client.Vertex.UpdateProperties.WithAction(model.ActionAppend),
+ //)
+ //if respUpdate.Data.ID != vertexID {
+ // t.Errorf("error")
+ //}
+ //fmt.Println(respUpdate.Data.Properties)
+}
+
+func createVertexLabel() {
+
+}
diff --git a/hugegraph-client-go/api/v1/vertexlabel/vertexlabel.go
b/hugegraph-client-go/api/v1/vertexlabel/vertexlabel.go
new file mode 100644
index 00000000..76bc3e0d
--- /dev/null
+++ b/hugegraph-client-go/api/v1/vertexlabel/vertexlabel.go
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package vertexlabel
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/internal/model"
+)
+
+type VertexLabel struct {
+ Create
+ DeleteByName
+ GetAll
+ GetByName
+ UpdateUserdata
+}
+
+func New(t api.Transport) *VertexLabel {
+ return &VertexLabel{
+ // Create
https://hugegraph.apache.org/docs/clients/restful-api/vertexlabel/#131-create-a-vertexlabel
+ Create: newCreateFunc(t),
+ // DeleteByName
https://hugegraph.apache.org/docs/clients/restful-api/vertexlabel/#135-delete-vertexlabel-by-name
+ DeleteByName: newDeleteByNameFunc(t),
+ // GetAll
https://hugegraph.apache.org/docs/clients/restful-api/vertexlabel/#133-get-all-vertexlabels
+ GetAll: newGetAllFunc(t),
+ // GetByName
https://hugegraph.apache.org/docs/clients/restful-api/vertexlabel/#134-get-vertexlabel-by-name
+ GetByName: newGetByNameFunc(t),
+ // UpdateUserdata
https://hugegraph.apache.org/docs/clients/restful-api/propertykey/#122-add-or-remove-userdata-for-an-existing-propertykey
+ UpdateUserdata: newUpdateUserdataFunc(t),
+ }
+}
+
+type Create func(o ...func(*CreateRequest)) (*CreateResponse, error)
+type DeleteByName func(o ...func(*DeleteByNameRequest))
(*DeleteByNameResponse, error)
+type GetAll func(o ...func(*GetAllRequest)) (*GetAllResponse, error)
+type GetByName func(o ...func(*GetByNameRequest)) (*GetByNameResponse, error)
+type UpdateUserdata func(o ...func(*UpdateUserdataRequest))
(*UpdateUserdataResponse, error)
+
+func newCreateFunc(t api.Transport) Create {
+ return func(o ...func(*CreateRequest)) (*CreateResponse, error) {
+ var r = CreateRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newDeleteByNameFunc(t api.Transport) DeleteByName {
+ return func(o ...func(*DeleteByNameRequest)) (*DeleteByNameResponse, error)
{
+ var r = DeleteByNameRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newGetAllFunc(t api.Transport) GetAll {
+ return func(o ...func(*GetAllRequest)) (*GetAllResponse, error) {
+ var r = GetAllRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newGetByNameFunc(t api.Transport) GetByName {
+ return func(o ...func(*GetByNameRequest)) (*GetByNameResponse, error) {
+ var r = GetByNameRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+func newUpdateUserdataFunc(t api.Transport) UpdateUserdata {
+ return func(o ...func(*UpdateUserdataRequest)) (*UpdateUserdataResponse,
error) {
+ var r = UpdateUserdataRequest{}
+ for _, f := range o {
+ f(&r)
+ }
+ return r.Do(r.ctx, t)
+ }
+}
+
+type CreateRequest struct {
+ Body io.Reader
+ ctx context.Context
+ reqData CreateRequestData
+}
+type CreateRequestData struct {
+ Name string `json:"name"`
+ IDStrategy model.IDStrategy `json:"id_strategy"`
+ Properties []string `json:"properties"`
+ PrimaryKeys []string `json:"primary_keys"`
+ NullableKeys []string `json:"nullable_keys"`
+ EnableLabelIndex bool `json:"enable_label_index"`
+}
+type CreateResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data CreateResponseData `json:"-"`
+}
+type CreateResponseData struct {
+ ID int `json:"id"`
+ PrimaryKeys []string `json:"primary_keys"`
+ IDStrategy model.IDStrategy `json:"id_strategy"`
+ Name string `json:"name"`
+ IndexNames []string `json:"index_names"`
+ Properties []string `json:"properties"`
+ NullableKeys []string `json:"nullable_keys"`
+ EnableLabelIndex bool `json:"enable_label_index"`
+ UserData struct {
+ } `json:"user_data"`
+}
+
+type DeleteByNameRequest struct {
+ Body io.Reader
+ ctx context.Context
+ name string
+}
+type DeleteByNameResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ DeleteByNames DeleteByNameResponseData `json:"versions"`
+}
+type DeleteByNameResponseData struct {
+ TaskID int `json:"task_id"`
+}
+
+type GetAllRequest struct {
+ Body io.Reader
+ ctx context.Context
+}
+type GetAllResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data GetAllResponseData `json:"-"`
+}
+type GetAllResponseData struct {
+ Vertexlabels []struct {
+ ID int `json:"id"`
+ PrimaryKeys []string `json:"primary_keys"`
+ IDStrategy string `json:"id_strategy"`
+ Name string `json:"name"`
+ IndexNames []interface{} `json:"index_names"`
+ Properties []string `json:"properties"`
+ NullableKeys []string `json:"nullable_keys"`
+ EnableLabelIndex bool `json:"enable_label_index"`
+ UserData struct {
+ Super string `json:"super"`
+ } `json:"user_data,omitempty"`
+ } `json:"vertexlabels"`
+}
+
+type GetByNameRequest struct {
+ Body io.Reader
+ ctx context.Context
+ name string
+}
+type GetByNameResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data GetByNameResponseData `json:"-"`
+}
+type GetByNameResponseData struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ IDStrategy string `json:"id_strategy"`
+ PrimaryKeys []string `json:"primary_keys"`
+ NullableKeys []interface{} `json:"nullable_keys"`
+ IndexLabels []string `json:"index_labels"`
+ Properties []string `json:"properties"`
+ Status string `json:"status"`
+ TTL int `json:"ttl"`
+ EnableLabelIndex bool `json:"enable_label_index"`
+ UserData struct {
+ CreateTime string `json:"~create_time"`
+ } `json:"user_data"`
+}
+
+type UpdateUserdataRequest struct {
+ Body io.Reader
+ ctx context.Context
+ reqData UpdateUserdataRequestData
+}
+
+
+type UpdateUserdataRequestData struct {
+ Action model.Action `json:"-"`
+ Name string `json:"name"`
+ Properties []string `json:"properties"`
+ NullableKeys []string `json:"nullable_keys"`
+ UserData struct {
+ Super string `json:"super"`
+ } `json:"user_data"`
+}
+type UpdateUserdataResponse struct {
+ StatusCode int `json:"-"`
+ Header http.Header `json:"-"`
+ Body io.ReadCloser `json:"-"`
+ Data UpdateUserdataResponseData `json:"-"`
+}
+type UpdateUserdataResponseData struct {
+ ID int `json:"id"`
+ PrimaryKeys []string `json:"primary_keys"`
+ IDStrategy string `json:"id_strategy"`
+ Name string `json:"name"`
+ IndexNames []interface{} `json:"index_names"`
+ Properties []string `json:"properties"`
+ NullableKeys []string `json:"nullable_keys"`
+ EnableLabelIndex bool `json:"enable_label_index"`
+ UserData struct {
+ Super string `json:"super"`
+ } `json:"user_data"`
+}
+
+func (r CreateRequest) Do(ctx context.Context, transport api.Transport)
(*CreateResponse, error) {
+
+ if len(r.reqData.Name) <= 0 {
+ return nil, errors.New("create property must set name")
+ }
+ if len(r.reqData.IDStrategy) <= 0 {
+ return nil, errors.New("create property must set id_strategy")
+ }
+ if len(r.reqData.Properties) <= 0 {
+ return nil, errors.New("create property must set properties")
+ }
+
+ byteBody, err := json.Marshal(&r.reqData)
+ if err != nil {
+ return nil, err
+ }
+ reader := strings.NewReader(string(byteBody))
+
+ req, err := api.NewRequest("POST",
fmt.Sprintf("/graphs/%s/schema/vertexlabels", transport.GetConfig().Graph),
nil, reader)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &CreateResponse{}
+ respData := CreateResponseData{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
+func (r DeleteByNameRequest) Do(ctx context.Context, transport api.Transport)
(*DeleteByNameResponse, error) {
+
+ if len(r.name) <= 0 {
+ return nil, errors.New("delete by name ,please set name")
+ }
+ req, err := api.NewRequest("DELETE",
fmt.Sprintf("/graphs/%s/schema/vertexlabels/%s", transport.GetConfig().Graph,
r.name), nil, r.Body)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ versionResp := &DeleteByNameResponse{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bytes, versionResp)
+ if err != nil {
+ return nil, err
+ }
+ versionResp.StatusCode = res.StatusCode
+ versionResp.Header = res.Header
+ versionResp.Body = res.Body
+ return versionResp, nil
+}
+func (r GetAllRequest) Do(ctx context.Context, transport api.Transport)
(*GetAllResponse, error) {
+
+ req, err := api.NewRequest("GET",
fmt.Sprintf("/graphs/%s/schema/vertexlabels", transport.GetConfig().Graph),
nil, r.Body)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &GetAllResponse{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ respData := GetAllResponseData{}
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
+func (r GetByNameRequest) Do(ctx context.Context, transport api.Transport)
(*GetByNameResponse, error) {
+
+ if len(r.name) <= 0 {
+ return nil, errors.New("GetByNameRequest must set name")
+ }
+
+ req, err := api.NewRequest("GET",
fmt.Sprintf("/graphs/%s/schema/vertexlabels/%s", transport.GetConfig().Graph,
r.name), nil, r.Body)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &GetByNameResponse{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ respData := GetByNameResponseData{}
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
+func (r UpdateUserdataRequest) Do(ctx context.Context, transport
api.Transport) (*UpdateUserdataResponse, error) {
+ params := &url.Values{}
+ if len(r.reqData.Action) <= 0 {
+ return nil, errors.New("property update userdata must set action")
+ } else {
+ params.Add("action", string(r.reqData.Action))
+ }
+ if len(r.reqData.Name) <= 0 {
+ return nil, errors.New("property update userdata must set name")
+ }
+
+ byteBody, err := json.Marshal(&r.reqData)
+ if err != nil {
+ return nil, err
+ }
+ reader := strings.NewReader(string(byteBody))
+
+ req, err := api.NewRequest("PUT",
fmt.Sprintf("/graphs/%s/schema/vertexlabels/%s", transport.GetConfig().Graph,
r.reqData.Name), params, reader)
+ if err != nil {
+ return nil, err
+ }
+ if ctx != nil {
+ req = req.WithContext(ctx)
+ }
+
+ res, err := transport.Perform(req)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := &UpdateUserdataResponse{}
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return nil, err
+ }
+ respData := UpdateUserdataResponseData{}
+ err = json.Unmarshal(bytes, &respData)
+ if err != nil {
+ return nil, err
+ }
+ resp.StatusCode = res.StatusCode
+ resp.Header = res.Header
+ resp.Body = res.Body
+ resp.Data = respData
+ return resp, nil
+}
+
+func (r Create) WithReqData(reqData CreateRequestData) func(request
*CreateRequest) {
+ return func(r *CreateRequest) {
+ r.reqData = reqData
+ }
+}
+func (p DeleteByName) WithName(name string) func(request *DeleteByNameRequest)
{
+ return func(r *DeleteByNameRequest) {
+ r.name = name
+ }
+}
+func (v GetByName) WithName(name string) func(r *GetByNameRequest) {
+ return func(r *GetByNameRequest) {
+ r.name = name
+ }
+}
+func (r UpdateUserdata) WithReqData(reqData UpdateUserdataRequestData)
func(request *UpdateUserdataRequest) {
+ return func(r *UpdateUserdataRequest) {
+ r.reqData = reqData
+ }
+}
diff --git a/hugegraph-client-go/api/v1/vertexlabel/vertexlabel_test.go
b/hugegraph-client-go/api/v1/vertexlabel/vertexlabel_test.go
new file mode 100644
index 00000000..5289434d
--- /dev/null
+++ b/hugegraph-client-go/api/v1/vertexlabel/vertexlabel_test.go
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package vertexlabel_test
+
+import (
+ "fmt"
+ "github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1/propertykey"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1/vertexlabel"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/internal/model"
+ "math/rand"
+ "testing"
+ "time"
+)
+
+func TestVertexLabel(t *testing.T) {
+ client, err := hugegraph.NewDefaultCommonClient()
+ if err != nil {
+ t.Errorf("NewDefaultCommonClient() error = %v", err)
+ }
+
+ rand.Seed(time.Now().UnixNano())
+ randNum := rand.Intn(999999)
+ pkName := fmt.Sprintf("testPropertyKey%d", randNum)
+ vertexLabelName := fmt.Sprintf("testVertexLabel%d", randNum)
+
+ // create propertykey
+ createPk(client, pkName, t)
+ // create vertexlabel
+ createVertexLabel(client, vertexLabelName, t, pkName, pkName)
+ // get all
+ getAll(client, vertexLabelName, t)
+ // update vertexlabel userdata
+ //updateUserData(client, vertexLabelName, pkName, t)
+ // get by name
+ getByName(client, vertexLabelName, t)
+ // delete vertexlabel
+ deleteByName(client, vertexLabelName, t)
+}
+
+func createPk(client *hugegraph.CommonClient, pkName string, t *testing.T)
*propertykey.CreateResponse {
+ pk1 := propertykey.CreateRequestData{
+ Name: pkName,
+ DataType: model.PropertyDataTypeInt,
+ Cardinality: model.PropertyCardinalitySingle,
+ }
+
+ pk1Resp, err := client.Propertykey.Create(
+ client.Propertykey.Create.WithReqData(pk1),
+ )
+ if err != nil {
+ t.Errorf("Create Propertykey error = %v", err)
+ }
+ if pk1Resp.Data.PropertyKey.Name != pk1.Name {
+ t.Errorf("Create Propertykey error = %v", err)
+ }
+
+ return pk1Resp
+}
+
+func createVertexLabel(
+ client *hugegraph.CommonClient,
+ vertexLabelName string,
+ t *testing.T,
+ pkName string,
+ pkNames ...string) *vertexlabel.CreateResponse {
+ createResp, err := client.VertexLabel.Create(
+ client.VertexLabel.Create.WithReqData(
+ vertexlabel.CreateRequestData{
+ Name: vertexLabelName,
+ IDStrategy: model.IDStrategyDefault,
+ Properties: pkNames,
+ PrimaryKeys: []string{
+ pkName,
+ },
+ NullableKeys: []string{},
+ EnableLabelIndex: true,
+ },
+ ),
+ )
+ if err != nil {
+ t.Errorf("Create Vertexlabel error = %v", err)
+ }
+ if createResp.Data.Name != vertexLabelName {
+ t.Errorf("Create Vertexlabel error = %v", err)
+ }
+ return createResp
+}
+
+func updateUserData(client *hugegraph.CommonClient, vertexLabelName string,
pkName string, t *testing.T) *vertexlabel.UpdateUserdataResponse {
+ respUpdateUserData, err := client.VertexLabel.UpdateUserdata(
+ client.VertexLabel.UpdateUserdata.WithReqData(
+ vertexlabel.UpdateUserdataRequestData{
+ Action: model.ActionAppend,
+ Name: vertexLabelName,
+ Properties: []string{pkName},
+ NullableKeys: []string{pkName},
+ UserData: struct {
+ Super string `json:"super"`
+ }{
+ Super: "animal",
+ },
+ },
+ ),
+ )
+ if err != nil {
+ t.Errorf("updateUserData Vertexlabel error = %v", err)
+ }
+ //if respUpdateUserData.Data.Name != vertexLabelName {
+ // t.Errorf("updateUserData Vertexlabel error = %v", err)
+ //}
+ return respUpdateUserData
+}
+
+func getByName(client *hugegraph.CommonClient, vertexLabelName string, t
*testing.T) {
+ respGetByName, err := client.VertexLabel.GetByName(
+ client.VertexLabel.GetByName.WithName(vertexLabelName),
+ )
+ if err != nil {
+ t.Errorf("getbyname Vertexlabel error = %v", err)
+ }
+ if respGetByName.Data.Name != vertexLabelName {
+ t.Errorf("getbyname Vertexlabel error")
+ }
+}
+
+func getAll(client *hugegraph.CommonClient, vertexLabelName string, t
*testing.T) {
+ respGetAll, err := client.VertexLabel.GetAll()
+ if err != nil {
+ t.Errorf("getAll Vertexlabel error = %v", err)
+ }
+ name := ""
+ for _, s := range respGetAll.Data.Vertexlabels {
+ if s.Name == vertexLabelName {
+ name = s.Name
+ }
+ }
+ if name != vertexLabelName {
+ t.Errorf("getAll Vertexlabel error")
+ }
+}
+
+func deleteByName(client *hugegraph.CommonClient, vertexLabelName string, t
*testing.T) {
+ respDeleteByName, err := client.VertexLabel.DeleteByName(
+ client.VertexLabel.DeleteByName.WithName(vertexLabelName),
+ )
+ if err != nil {
+ t.Errorf("deletebyname Vertexlabel error = %v", err)
+ }
+ if respDeleteByName.StatusCode > 299 {
+ t.Errorf("deletebyname Vertexlabel error")
+ }
+}
diff --git a/hugegraph-client-go/go.mod b/hugegraph-client-go/go.mod
new file mode 100644
index 00000000..d45b4200
--- /dev/null
+++ b/hugegraph-client-go/go.mod
@@ -0,0 +1,4 @@
+module github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go
+
+go 1.19
+
diff --git a/hugegraph-client-go/go.sum b/hugegraph-client-go/go.sum
new file mode 100644
index 00000000..b156c04c
--- /dev/null
+++ b/hugegraph-client-go/go.sum
@@ -0,0 +1,16 @@
+github.com/chzyer/logex v1.1.10/go.mod
h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/logex v1.2.1/go.mod
h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod
h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/readline v1.5.1
h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
+github.com/chzyer/readline v1.5.1/go.mod
h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod
h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/chzyer/test v1.0.0/go.mod
h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
+github.com/google/pprof v0.0.0-20211214055906-6f57359322fd
h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
+github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod
h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
+github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod
h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
+github.com/ianlancetaylor/demangle v0.0.0-20211126204342-3ad08eb09c01
h1:+0qIm4/XbPn2PYkj6QM6CX/FJN5DGvFOaMkSyB1xuh8=
+github.com/ianlancetaylor/demangle v0.0.0-20211126204342-3ad08eb09c01/go.mod
h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
+golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
diff --git a/hugegraph-client-go/hgtransport/hgtransport.go
b/hugegraph-client-go/hgtransport/hgtransport.go
new file mode 100644
index 00000000..8c669c8b
--- /dev/null
+++ b/hugegraph-client-go/hgtransport/hgtransport.go
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package hgtransport
+
+import (
+ "bytes"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "regexp"
+ "runtime"
+ "strings"
+ "time"
+
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/internal/version"
+)
+
+// Version returns the package version as a string.
+const Version = version.Client
+
+var (
+ userAgent string
+ reGoVersion = regexp.MustCompile(`go(\d+\.\d+\..+)`)
+)
+
+func init() {
+ userAgent = initUserAgent()
+}
+
+// Interface defines the interface for HTTP client.
+type Interface interface {
+ Perform(*http.Request) (*http.Response, error)
+ GetConfig() Config
+}
+
+// Config represents the configuration of HTTP client.
+type Config struct {
+ URL *url.URL
+ Username string
+ Password string
+ GraphSpace string
+ Graph string
+ Transport http.RoundTripper
+ Logger Logger
+}
+
+// Client represents the HTTP client.
+type Client struct {
+ url *url.URL
+ username string
+ password string
+ graphspace string
+ graph string
+ transport http.RoundTripper
+ logger Logger
+}
+
+// New creates new HTTP client.
+//
+// http.DefaultTransport will be used if no transport is passed in the
configuration.
+func New(cfg Config) *Client {
+ if cfg.Transport == nil {
+ cfg.Transport = http.DefaultTransport
+ }
+
+ return &Client{
+ url: cfg.URL,
+ username: cfg.Username,
+ password: cfg.Password,
+ graphspace: cfg.GraphSpace,
+ graph: cfg.Graph,
+ transport: cfg.Transport,
+ logger: cfg.Logger,
+ }
+}
+
+func (c *Client) GetConfig() Config {
+ return Config{
+ URL: c.url,
+ Username: c.username,
+ Password: c.password,
+ GraphSpace: c.graphspace,
+ Graph: c.graph,
+ Transport: c.transport,
+ Logger: nil,
+ }
+}
+
+// Perform executes the request and returns a response or error.
+func (c *Client) Perform(req *http.Request) (*http.Response, error) {
+
+ u := c.url
+ c.setURL(u, req)
+ c.setUserAgent(req)
+ c.setHost(req)
+ c.setContentTypeJSON(req)
+
+ if _, ok := req.Header["Authorization"]; !ok {
+ c.setBasicAuth(u, req)
+ }
+
+ var dupReqBody *bytes.Buffer
+ if c.logger != nil && c.logger.RequestBodyEnabled() {
+ if req.Body != nil && req.Body != http.NoBody {
+ dupReqBody = bytes.NewBuffer(make([]byte, 0,
int(req.ContentLength)))
+ dupReqBody.ReadFrom(req.Body)
+ req.Body = ioutil.NopCloser(bytes.NewBuffer(dupReqBody.Bytes()))
+ }
+ }
+ start := time.Now().UTC()
+ res, err := c.transport.RoundTrip(req)
+ dur := time.Since(start)
+
+ if c.logger == nil {
+ return res, err
+ }
+
+ var dupRes http.Response
+ if res != nil {
+ dupRes = *res
+ }
+ if c.logger.RequestBodyEnabled() {
+ if req.Body != nil && req.Body != http.NoBody {
+ req.Body = ioutil.NopCloser(dupReqBody)
+ }
+ }
+ if c.logger.ResponseBodyEnabled() {
+ if res != nil && res.Body != nil && res.Body != http.NoBody {
+ b1, b2, _ := duplicateBody(res.Body)
+ dupRes.Body = b1
+ res.Body = b2
+ }
+ }
+ c.logger.LogRoundTrip(req, &dupRes, err, start, dur) // errcheck exclude
+
+ return res, err
+}
+
+func (c *Client) setURL(u *url.URL, req *http.Request) *http.Request {
+ req.URL.Scheme = u.Scheme
+ req.URL.Host = u.Host
+
+ if u.Path != "" {
+ var b strings.Builder
+ b.Grow(len(u.Path) + len(req.URL.Path))
+ b.WriteString(u.Path)
+ b.WriteString(req.URL.Path)
+ req.URL.Path = b.String()
+ }
+
+ return req
+}
+
+func (c *Client) setBasicAuth(u *url.URL, req *http.Request) *http.Request {
+ if u.User != nil {
+ password, _ := u.User.Password()
+ req.SetBasicAuth(u.User.Username(), password)
+ return req
+ }
+
+ if c.username != "" && c.password != "" {
+ req.SetBasicAuth(c.username, c.password)
+ return req
+ }
+
+ return req
+}
+
+func (c *Client) setUserAgent(req *http.Request) *http.Request {
+ req.Header.Set("User-Agent", userAgent)
+ return req
+}
+
+func (c *Client) setHost(req *http.Request) *http.Request {
+ req.Header.Set("Host", req.URL.Host)
+ return req
+}
+
+func (c *Client) setContentTypeJSON(req *http.Request) *http.Request {
+ req.Header.Set("Content-Type", "application/json;charset=UTF-8")
+ return req
+}
+
+func initUserAgent() string {
+ var b strings.Builder
+
+ b.WriteString("go-hugegraph")
+ b.WriteRune('/')
+ b.WriteString(Version)
+ b.WriteRune(' ')
+ b.WriteRune('(')
+ b.WriteString(runtime.GOOS)
+ b.WriteRune(' ')
+ b.WriteString(runtime.GOARCH)
+ b.WriteString("; ")
+ b.WriteString("Go ")
+ if v := reGoVersion.ReplaceAllString(runtime.Version(), "$1"); v != "" {
+ b.WriteString(v)
+ } else {
+ b.WriteString(runtime.Version())
+ }
+ b.WriteRune(')')
+
+ return b.String()
+}
diff --git a/hugegraph-client-go/hgtransport/logger.go
b/hugegraph-client-go/hgtransport/logger.go
new file mode 100644
index 00000000..306a7766
--- /dev/null
+++ b/hugegraph-client-go/hgtransport/logger.go
@@ -0,0 +1,396 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package hgtransport
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// Logger defines an interface for logging request and response.
+type Logger interface {
+ // LogRoundTrip should not modify the request or response, except for
consuming and closing the body.
+ // Implementations have to check for nil values in request and response.
+ LogRoundTrip(*http.Request, *http.Response, error, time.Time,
time.Duration) error
+ // RequestBodyEnabled makes the client pass a copy of request body to the
logger.
+ RequestBodyEnabled() bool
+ // ResponseBodyEnabled makes the client pass a copy of response body to
the logger.
+ ResponseBodyEnabled() bool
+}
+
+// TextLogger prints the log message in plain text.
+type TextLogger struct {
+ Output io.Writer
+ EnableRequestBody bool
+ EnableResponseBody bool
+}
+
+// ColorLogger prints the log message in a terminal-optimized plain text.
+type ColorLogger struct {
+ Output io.Writer
+ EnableRequestBody bool
+ EnableResponseBody bool
+}
+
+// CurlLogger prints the log message as a runnable curl command.
+type CurlLogger struct {
+ Output io.Writer
+ EnableRequestBody bool
+ EnableResponseBody bool
+}
+
+// JSONLogger prints the log message as JSON.
+type JSONLogger struct {
+ Output io.Writer
+ EnableRequestBody bool
+ EnableResponseBody bool
+}
+
+// LogRoundTrip prints the information about request and response.
+func (l *TextLogger) LogRoundTrip(req *http.Request, res *http.Response, err
error, start time.Time, dur time.Duration) error {
+ fmt.Fprintf(l.Output, "%s %s %s [status:%d request:%s]\n",
+ start.Format(time.RFC3339),
+ req.Method,
+ req.URL.String(),
+ resStatusCode(res),
+ dur.Truncate(time.Millisecond),
+ )
+ if l.RequestBodyEnabled() && req != nil && req.Body != nil && req.Body !=
http.NoBody {
+ var buf bytes.Buffer
+ buf.ReadFrom(req.Body)
+ logBodyAsText(l.Output, &buf, ">")
+ }
+ if l.ResponseBodyEnabled() && res != nil && res.Body != nil && res.Body !=
http.NoBody {
+ defer res.Body.Close()
+ var buf bytes.Buffer
+ buf.ReadFrom(res.Body)
+ logBodyAsText(l.Output, &buf, "<")
+ }
+ if err != nil {
+ fmt.Fprintf(l.Output, "! ERROR: %v\n", err)
+ }
+ return nil
+}
+
+// RequestBodyEnabled returns true when the request body should be logged.
+func (l *TextLogger) RequestBodyEnabled() bool { return l.EnableRequestBody }
+
+// ResponseBodyEnabled returns true when the response body should be logged.
+func (l *TextLogger) ResponseBodyEnabled() bool { return l.EnableResponseBody }
+
+// LogRoundTrip prints the information about request and response.
+func (l *ColorLogger) LogRoundTrip(req *http.Request, res *http.Response, err
error, start time.Time, dur time.Duration) error {
+ query, _ := url.QueryUnescape(req.URL.RawQuery)
+ if query != "" {
+ query = "?" + query
+ }
+
+ var (
+ status string
+ color string
+ )
+
+ status = res.Status
+ switch {
+ case res.StatusCode > 0 && res.StatusCode < 300:
+ color = "\x1b[32m"
+ case res.StatusCode > 299 && res.StatusCode < 500:
+ color = "\x1b[33m"
+ case res.StatusCode > 499:
+ color = "\x1b[31m"
+ default:
+ status = "ERROR"
+ color = "\x1b[31;4m"
+ }
+
+ fmt.Fprintf(l.Output, "%6s \x1b[1;4m%s://%s%s\x1b[0m%s %s%s\x1b[0m
\x1b[2m%s\x1b[0m\n",
+ req.Method,
+ req.URL.Scheme,
+ req.URL.Host,
+ req.URL.Path,
+ query,
+ color,
+ status,
+ dur.Truncate(time.Millisecond),
+ )
+
+ if l.RequestBodyEnabled() && req != nil && req.Body != nil && req.Body !=
http.NoBody {
+ var buf bytes.Buffer
+ buf.ReadFrom(req.Body)
+ fmt.Fprint(l.Output, "\x1b[2m")
+ logBodyAsText(l.Output, &buf, " »")
+ fmt.Fprint(l.Output, "\x1b[0m")
+ }
+
+ if l.ResponseBodyEnabled() && res != nil && res.Body != nil && res.Body !=
http.NoBody {
+ defer res.Body.Close()
+ var buf bytes.Buffer
+ buf.ReadFrom(res.Body)
+ fmt.Fprint(l.Output, "\x1b[2m")
+ logBodyAsText(l.Output, &buf, " «")
+ fmt.Fprint(l.Output, "\x1b[0m")
+ }
+
+ if err != nil {
+ fmt.Fprintf(l.Output, "\x1b[31;1m» ERROR \x1b[31m%v\x1b[0m\n", err)
+ }
+
+ if l.RequestBodyEnabled() || l.ResponseBodyEnabled() {
+ fmt.Fprintf(l.Output, "\x1b[2m%s\x1b[0m\n", strings.Repeat("─", 80))
+ }
+ return nil
+}
+
+// RequestBodyEnabled returns true when the request body should be logged.
+func (l *ColorLogger) RequestBodyEnabled() bool { return l.EnableRequestBody }
+
+// ResponseBodyEnabled returns true when the response body should be logged.
+func (l *ColorLogger) ResponseBodyEnabled() bool { return l.EnableResponseBody
}
+
+// LogRoundTrip prints the information about request and response.
+func (l *CurlLogger) LogRoundTrip(req *http.Request, res *http.Response, err
error, start time.Time, dur time.Duration) error {
+ var b bytes.Buffer
+
+ var query string
+ qvalues := url.Values{}
+ for k, v := range req.URL.Query() {
+ if k == "pretty" {
+ continue
+ }
+ for _, qv := range v {
+ qvalues.Add(k, qv)
+ }
+ }
+ if len(qvalues) > 0 {
+ query = qvalues.Encode()
+ }
+
+ b.WriteString(`curl`)
+ if req.Method == "HEAD" {
+ b.WriteString(" --head")
+ } else {
+ fmt.Fprintf(&b, " -X %s", req.Method)
+ }
+
+ if len(req.Header) > 0 {
+ for k, vv := range req.Header {
+ if k == "Authorization" || k == "User-Agent" {
+ continue
+ }
+ v := strings.Join(vv, ",")
+ b.WriteString(fmt.Sprintf(" -H '%s: %s'", k, v))
+ }
+ }
+
+ b.WriteString(" 'http://localhost:9200")
+ b.WriteString(req.URL.Path)
+ b.WriteString("?pretty")
+ if query != "" {
+ fmt.Fprintf(&b, "&%s", query)
+ }
+ b.WriteString("'")
+
+ if req != nil && req.Body != nil && req.Body != http.NoBody {
+ var buf bytes.Buffer
+ buf.ReadFrom(req.Body)
+
+ b.Grow(buf.Len())
+ b.WriteString(" -d \\\n'")
+ json.Indent(&b, buf.Bytes(), "", " ")
+ b.WriteString("'")
+ }
+
+ b.WriteRune('\n')
+
+ var status string
+ status = res.Status
+
+ fmt.Fprintf(&b, "# => %s [%s] %s\n", start.UTC().Format(time.RFC3339),
status, dur.Truncate(time.Millisecond))
+ if l.ResponseBodyEnabled() && res != nil && res.Body != nil && res.Body !=
http.NoBody {
+ var buf bytes.Buffer
+ buf.ReadFrom(res.Body)
+
+ b.Grow(buf.Len())
+ b.WriteString("# ")
+ json.Indent(&b, buf.Bytes(), "# ", " ")
+ }
+
+ b.WriteString("\n")
+ if l.ResponseBodyEnabled() && res != nil && res.Body != nil && res.Body !=
http.NoBody {
+ b.WriteString("\n")
+ }
+
+ b.WriteTo(l.Output)
+
+ return nil
+}
+
+// RequestBodyEnabled returns true when the request body should be logged.
+func (l *CurlLogger) RequestBodyEnabled() bool { return l.EnableRequestBody }
+
+// ResponseBodyEnabled returns true when the response body should be logged.
+func (l *CurlLogger) ResponseBodyEnabled() bool { return l.EnableResponseBody }
+
+// LogRoundTrip prints the information about request and response.
+func (l *JSONLogger) LogRoundTrip(req *http.Request, res *http.Response, err
error, start time.Time, dur time.Duration) error {
+ // https://github.com/elastic/ecs/blob/master/schemas/http.yml
+ //
+ // TODO(karmi): Research performance optimization of using sync.Pool
+
+ bsize := 200
+ var b = bytes.NewBuffer(make([]byte, 0, bsize))
+ var v = make([]byte, 0, bsize)
+
+ appendTime := func(t time.Time) {
+ v = v[:0]
+ v = t.AppendFormat(v, time.RFC3339)
+ b.Write(v)
+ }
+
+ appendQuote := func(s string) {
+ v = v[:0]
+ v = strconv.AppendQuote(v, s)
+ b.Write(v)
+ }
+
+ appendInt := func(i int64) {
+ v = v[:0]
+ v = strconv.AppendInt(v, i, 10)
+ b.Write(v)
+ }
+
+ port := req.URL.Port()
+
+ b.WriteRune('{')
+ // -- Timestamp
+ b.WriteString(`"@timestamp":"`)
+ appendTime(start.UTC())
+ b.WriteRune('"')
+ // -- Event
+ b.WriteString(`,"event":{`)
+ b.WriteString(`"duration":`)
+ appendInt(dur.Nanoseconds())
+ b.WriteRune('}')
+ // -- URL
+ b.WriteString(`,"url":{`)
+ b.WriteString(`"scheme":`)
+ appendQuote(req.URL.Scheme)
+ b.WriteString(`,"domain":`)
+ appendQuote(req.URL.Hostname())
+ if port != "" {
+ b.WriteString(`,"port":`)
+ b.WriteString(port)
+ }
+ b.WriteString(`,"path":`)
+ appendQuote(req.URL.Path)
+ b.WriteString(`,"query":`)
+ appendQuote(req.URL.RawQuery)
+ b.WriteRune('}') // Close "url"
+ // -- HTTP
+ b.WriteString(`,"http":`)
+ // ---- Request
+ b.WriteString(`{"request":{`)
+ b.WriteString(`"method":`)
+ appendQuote(req.Method)
+ if l.RequestBodyEnabled() && req != nil && req.Body != nil && req.Body !=
http.NoBody {
+ var buf bytes.Buffer
+ buf.ReadFrom(req.Body)
+
+ b.Grow(buf.Len() + 8)
+ b.WriteString(`,"body":`)
+ appendQuote(buf.String())
+ }
+ b.WriteRune('}') // Close "http.request"
+ // ---- Response
+ b.WriteString(`,"response":{`)
+ b.WriteString(`"status_code":`)
+ appendInt(int64(resStatusCode(res)))
+ if l.ResponseBodyEnabled() && res != nil && res.Body != nil && res.Body !=
http.NoBody {
+ defer res.Body.Close()
+ var buf bytes.Buffer
+ buf.ReadFrom(res.Body)
+
+ b.Grow(buf.Len() + 8)
+ b.WriteString(`,"body":`)
+ appendQuote(buf.String())
+ }
+ b.WriteRune('}') // Close "http.response"
+ b.WriteRune('}') // Close "http"
+ // -- Error
+ if err != nil {
+ b.WriteString(`,"error":{"message":`)
+ appendQuote(err.Error())
+ b.WriteRune('}') // Close "error"
+ }
+ b.WriteRune('}')
+ b.WriteRune('\n')
+ b.WriteTo(l.Output)
+
+ return nil
+}
+
+// RequestBodyEnabled returns true when the request body should be logged.
+func (l *JSONLogger) RequestBodyEnabled() bool { return l.EnableRequestBody }
+
+// ResponseBodyEnabled returns true when the response body should be logged.
+func (l *JSONLogger) ResponseBodyEnabled() bool { return l.EnableResponseBody }
+
+func logBodyAsText(dst io.Writer, body io.Reader, prefix string) {
+ scanner := bufio.NewScanner(body)
+ for scanner.Scan() {
+ s := scanner.Text()
+ if s != "" {
+ fmt.Fprintf(dst, "%s %s\n", prefix, s)
+ }
+ }
+}
+
+func duplicateBody(body io.ReadCloser) (io.ReadCloser, io.ReadCloser, error) {
+ var (
+ b1 bytes.Buffer
+ b2 bytes.Buffer
+ tr = io.TeeReader(body, &b2)
+ )
+ _, err := b1.ReadFrom(tr)
+ if err != nil {
+ return ioutil.NopCloser(io.MultiReader(&b1, errorReader{err: err})),
ioutil.NopCloser(io.MultiReader(&b2, errorReader{err: err})), err
+ }
+ defer func() { body.Close() }()
+
+ return ioutil.NopCloser(&b1), ioutil.NopCloser(&b2), nil
+}
+
+func resStatusCode(res *http.Response) int {
+ if res == nil {
+ return -1
+ }
+ return res.StatusCode
+}
+
+type errorReader struct{ err error }
+
+func (r errorReader) Read(p []byte) (int, error) { return 0, r.err }
diff --git a/hugegraph-client-go/hugegraph.go b/hugegraph-client-go/hugegraph.go
new file mode 100644
index 00000000..910f836b
--- /dev/null
+++ b/hugegraph-client-go/hugegraph.go
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package hugegraph
+
+import (
+ "errors"
+ "fmt"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1/edgelabel"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1/gremlin"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1/propertykey"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1/vertex"
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/api/v1/vertexlabel"
+ "net"
+ "net/http"
+ "net/url"
+ "os"
+
+
"github.com/apache/incubator-hugegraph-toolchain/hugegraph-client-go/hgtransport"
+)
+
+// Config 配置类型
+type Config struct {
+ Host string // hugegraph Server host
+ Port int // hugegraph Server api port
+ GraphSpace string // graphSpace is a feature supported
feature. if you not set graphSpace, please set empty string
+ Graph string // this name is configured in the hugegraph
+ Username string // server username .if you not set username
,please set empty string
+ Password string // server password .if you not set password
,please set empty string
+ Transport http.RoundTripper // The HTTP transport object.
+ Logger hgtransport.Logger // The logger object.
+}
+
+type CommonClient struct {
+ Vertex *vertex.Vertex
+ Gremlin *gremlin.Gremlin
+ Propertykey *propertykey.PropertyKey
+ VertexLabel *vertexlabel.VertexLabel
+ EdgeLabel *edgelabel.Edgelabel
+ *v1.APIV1
+ Transport hgtransport.Interface
+ Graph string
+ GraphSpace string
+}
+
+func NewDefaultCommonClient() (*CommonClient, error) {
+ return NewCommonClient(Config{
+ Host: "127.0.0.1",
+ Port: 8080,
+ GraphSpace: "",
+ Graph: "hugegraph",
+ Username: "admin",
+ Password: "pa",
+ Logger: &hgtransport.ColorLogger{
+ Output: os.Stdout,
+ EnableRequestBody: true,
+ EnableResponseBody: true,
+ },
+ })
+}
+
+func NewCommonClient(cfg Config) (*CommonClient, error) {
+
+ if len(cfg.Host) < 3 {
+ return nil, errors.New("cannot create client: host length error")
+ }
+ address := net.ParseIP(cfg.Host)
+ if address == nil {
+ return nil, errors.New("cannot create client: host is format error")
+ }
+ if cfg.Port < 1 || cfg.Port > 65535 {
+ return nil, errors.New("cannot create client: port is error")
+ }
+
+ tp := hgtransport.New(hgtransport.Config{
+ URL: &url.URL{
+ Host: fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
+ Scheme: "http",
+ },
+ Username: cfg.Username,
+ Password: cfg.Password,
+ Graph: cfg.Graph,
+ Transport: cfg.Transport,
+ Logger: cfg.Logger,
+ })
+
+ return &CommonClient{
+ Vertex: vertex.New(tp),
+ Gremlin: gremlin.New(tp),
+ Propertykey: propertykey.New(tp),
+ VertexLabel: vertexlabel.New(tp),
+ EdgeLabel: edgelabel.New(tp),
+ APIV1: v1.New(tp),
+ Transport: tp,
+ Graph: cfg.Graph,
+ GraphSpace: cfg.GraphSpace,
+ }, nil
+}
diff --git a/hugegraph-client-go/hugegraph_test.go
b/hugegraph-client-go/hugegraph_test.go
new file mode 100644
index 00000000..b58a6a17
--- /dev/null
+++ b/hugegraph-client-go/hugegraph_test.go
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package hugegraph
+
+import (
+ "testing"
+)
+
+func TestNewDefaultCommonClient(t *testing.T) {
+ tests := []struct {
+ name string
+ wantErr bool
+ }{
+ {
+ name: "test",
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ _, err := NewDefaultCommonClient()
+ if (err != nil) != tt.wantErr {
+ t.Errorf("NewDefaultCommonClient() error = %v, wantErr %v",
err, tt.wantErr)
+ return
+ }
+ })
+ }
+}
diff --git a/hugegraph-client-go/internal/model/model.go
b/hugegraph-client-go/internal/model/model.go
new file mode 100644
index 00000000..51fdd5dd
--- /dev/null
+++ b/hugegraph-client-go/internal/model/model.go
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package model
+
+const (
+ PropertyDataTypeInt PropertyDataType = "INT" // data_type int
+
+ PropertyCardinalitySingle PropertyCardinality = "SINGLE" // cardinality
single
+
+ ActionAppend Action = "append" // append action
+ ActionEliminate Action = "eliminate" // eliminate(remove) action
+
+ IDStrategyDefault IDStrategy = "DEFAULT" // default id_strategy,The
default strategy is primary key ID.
+
+ FrequencySingle Frequency = "SINGLE" // single frequency
+)
+
+type PropertyDataType string
+type PropertyCardinality string
+type Action string
+type IDStrategy string
+type Frequency string
+
+// Vertex models that support generic types
+type Vertex[T any] struct {
+ ID string `json:"id,omitempty"`
+ Label string `json:"label"`
+ Typ string `json:"type,omitempty"`
+ Properties T `json:"properties"`
+}
+
+// Edge models that support generic types
+type Edge[T any] struct {
+ ID string `json:"id,omitempty"`
+ Label string `json:"label"`
+ Typ string `json:"type,omitempty"`
+ OutV string `json:"outV"`
+ OutVLabel string `json:"outVLabel"`
+ InV string `json:"inV"`
+ InVLabel string `json:"inVLabel"`
+ Properties T `json:"properties"`
+}
diff --git a/hugegraph-client-go/internal/version/version.go
b/hugegraph-client-go/internal/version/version.go
new file mode 100644
index 00000000..05e3e2b7
--- /dev/null
+++ b/hugegraph-client-go/internal/version/version.go
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package version
+
+// Client returns the client version as a string.
+const Client = "1.2.0"
diff --git a/pom.xml b/pom.xml
index ed3aa7c8..daa21e32 100644
--- a/pom.xml
+++ b/pom.xml
@@ -506,6 +506,9 @@
<!-- Maven -->
<exclude>.repository/**</exclude>
<exclude>**/.flattened-pom.xml</exclude>
+ <!-- Go -->
+ <exclude>**/hugegraph-client-go/go.sum</exclude>
+ <exclude>**/hugegraph-client-go/go.mod</exclude>
</excludes>
<consoleOutput>true</consoleOutput>
</configuration>