Skip to content

Commit

Permalink
feat: Add basic support for bindings/go using CGO (#3204)
Browse files Browse the repository at this point in the history
Demo for bindings/go using CGO
  • Loading branch information
jiaoew1991 authored Sep 28, 2023
1 parent 359771a commit e7b4fbd
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 0 deletions.
30 changes: 30 additions & 0 deletions bindings/go/build_dynamic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//go:build dynamic
// +build dynamic

/*
* 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 opendal

/*
#cgo pkg-config: opendal_c
*/
import "C"

const LibopendalLinkInfo = "dynamically linked to libopendal_c"
11 changes: 11 additions & 0 deletions bindings/go/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module opendal.apache.org/go

go 1.20

require github.com/stretchr/testify v1.8.4

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
9 changes: 9 additions & 0 deletions bindings/go/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
83 changes: 83 additions & 0 deletions bindings/go/opendal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* 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 opendal

/*
#include "opendal.h"
*/
import "C"
import (
"errors"
"fmt"
"unsafe"
)

var (
errInvalidScheme = errors.New("invalid scheme")
errValueEmpty = errors.New("value is empty")
)

type Options map[string]string

type Operator struct {
inner *C.opendal_operator_ptr
}

func NewOperator(scheme string, opt Options) (*Operator, error) {
fmt.Println("libopendal_c info: ", LibopendalLinkInfo)
if len(scheme) == 0 {
return nil, errInvalidScheme
}
opts := C.opendal_operator_options_new()
defer C.opendal_operator_options_free(opts)
for k, v := range opt {
C.opendal_operator_options_set(opts, C.CString(k), C.CString(v))
}
op := C.opendal_operator_new(C.CString(scheme), opts)
return &Operator{
inner: op,
}, nil
}

func (o *Operator) Write(key string, value []byte) error {
if len(value) == 0 {
return errValueEmpty
}
bytes := C.opendal_bytes{data: (*C.uchar)(unsafe.Pointer(&value[0])), len: C.ulong(len(value))}
ret := C.opendal_operator_blocking_write(o.inner, C.CString(key), bytes)
if ret != 0 {
return errors.New(fmt.Sprintf("write failed, error code: %d", ret))
}
return nil
}

func (o *Operator) Read(key string) ([]byte, error) {
result := C.opendal_operator_blocking_read(o.inner, C.CString(key))
ret := int(result.code)
if ret != 0 {
return nil, errors.New(fmt.Sprintf("write failed, error code: %d", ret))
}
return C.GoBytes(unsafe.Pointer(result.data.data), C.int(result.data.len)), nil
}

func (o *Operator) Close() error {
C.opendal_operator_free(o.inner)
return nil
}
39 changes: 39 additions & 0 deletions bindings/go/opendal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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 opendal

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestOperations(t *testing.T) {
opts := make(Options)
opts["root"] = "/myroot"
operator, err := NewOperator("memory", opts)
assert.NoError(t, err)
defer operator.Close()
err = operator.Write("test", []byte("Hello World"))
assert.NoError(t, err)
value, err := operator.Read("test")
assert.NoError(t, err)
assert.Equal(t, "Hello World", string(value))
}

0 comments on commit e7b4fbd

Please sign in to comment.