Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CBOR implementation and HTTP connection engine #153

Merged
merged 29 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
lint
  • Loading branch information
remade committed Sep 13, 2024
commit a10518de25a179332038b87fdb4b588324721879
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ func main() {
- Run `go mod tidy` to download the `surrealdb.go` dependency
- Run `go run main.go` to run the example.

## Data Models

## Contributing

You can run the Makefile commands to run and build the project
Expand Down
9 changes: 4 additions & 5 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ func New(connectionURL string) (*DB, error) {
}
var conn connection.Connection
if scheme == "http" || scheme == "https" {
conn = connection.NewHttp(newParams)
conn = connection.NewHTTPConnection(newParams)
} else if scheme == "ws" || scheme == "wss" {
conn = connection.NewWebSocket(newParams)
conn = connection.NewWebSocketConnection(newParams)
} else {
return nil, fmt.Errorf("invalid connection url")
}
Expand All @@ -48,7 +48,7 @@ func New(connectionURL string) (*DB, error) {
}
newLiveConnParams := newParams
newLiveConnParams.BaseURL = fmt.Sprintf("%s://%s", liveScheme, u.Host)
liveconn := connection.NewWebSocket(newParams)
liveconn := connection.NewWebSocketConnection(newParams)
err = liveconn.Connect()
if err != nil {
return nil, err
Expand Down Expand Up @@ -156,7 +156,7 @@ func (db *DB) Kill(liveQueryID string) (interface{}, error) {

// LiveNotifications returns a channel for live query.
func (db *DB) LiveNotifications(liveQueryID string) (chan connection.Notification, error) {
return db.liveHandler.LiveNotifications(liveQueryID) //check if implemented
return db.liveHandler.LiveNotifications(liveQueryID)
}

// --------------------------------------------------
Expand Down Expand Up @@ -184,7 +184,6 @@ func (db *DB) send(method string, params ...interface{}) (interface{}, error) {
// resp is a helper method for parsing the response from a query.
func (db *DB) resp(_ string, _ []interface{}, res interface{}) (interface{}, error) {
if res == nil {
//return nil, pkg.ErrNoRow
return nil, constants.ErrNoRow
}
return res, nil
Expand Down
12 changes: 9 additions & 3 deletions db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,19 @@ func TestSurrealDBSuite(t *testing.T) {
// Without options
buff := bytes.NewBufferString("")
logData := createLogger(t, buff)
SurrealDBSuite.connImplementations["ws"] = connection.NewWebSocket(connection.NewConnectionParams{}).Logger(logData)
SurrealDBSuite.connImplementations["ws"] = connection.
NewWebSocketConnection(connection.NewConnectionParams{}).
Logger(logData)
SurrealDBSuite.logBuffer = buff

// With options
buffOpt := bytes.NewBufferString("")
logDataOpt := createLogger(t, buff)
SurrealDBSuite.connImplementations["ws_opt"] = connection.NewWebSocket(connection.NewConnectionParams{}).SetTimeOut(time.Minute).SetCompression(true).Logger(logDataOpt)
SurrealDBSuite.connImplementations["ws_opt"] = connection.
NewWebSocketConnection(connection.NewConnectionParams{}).
SetTimeOut(time.Minute).
SetCompression(true).
Logger(logDataOpt)
SurrealDBSuite.logBuffer = buffOpt

RunWsMap(t, SurrealDBSuite)
Expand Down Expand Up @@ -777,7 +783,7 @@ func (s *SurrealDBTestSuite) TestConcurrentOperations() {
}

func (s *SurrealDBTestSuite) TestConnectionBreak() {
ws := connection.NewWebSocket(connection.NewConnectionParams{})
ws := connection.NewWebSocketConnection(connection.NewConnectionParams{})
var url string
if currentURL == "" {
url = defaultURL
Expand Down
2 changes: 1 addition & 1 deletion internal/benchmark/benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type testUser struct {
}

func SetupMockDB() (*surrealdb.DB, error) {
return surrealdb.New("", "")
return surrealdb.New("")
}

func BenchmarkCreate(b *testing.B) {
Expand Down
4 changes: 2 additions & 2 deletions internal/mock/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
type ws struct {
}

func (w *ws) Connect(url string) (connection.Connection, error) {
return w, nil
func (w *ws) Connect(url string) error {
return nil
}

func (w *ws) Send(method string, params []interface{}) (interface{}, error) {
Expand Down
35 changes: 19 additions & 16 deletions pkg/connection/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import (
"time"
)

type Http struct {
type HTTPConnection struct {
BaseConnection

httpClient *http.Client
variables sync.Map
}

func NewHttp(p NewConnectionParams) *Http {
con := Http{
func NewHTTPConnection(p NewConnectionParams) *HTTPConnection {
con := HTTPConnection{
BaseConnection: BaseConnection{
marshaler: p.Marshaler,
unmarshaler: p.Unmarshaler,
Expand All @@ -36,7 +36,7 @@ func NewHttp(p NewConnectionParams) *Http {
return &con
}

func (h *Http) Connect() error {
func (h *HTTPConnection) Connect() error {
if h.baseURL == "" {
return fmt.Errorf("base url not set")
}
Expand All @@ -49,7 +49,7 @@ func (h *Http) Connect() error {
return fmt.Errorf("unmarshaler is not set")
}

httpReq, err := http.NewRequest(http.MethodGet, h.baseURL+"/health", nil)
httpReq, err := http.NewRequest(http.MethodGet, h.baseURL+"/health", http.NoBody)
if err != nil {
return err
}
Expand All @@ -61,21 +61,21 @@ func (h *Http) Connect() error {
return nil
}

func (h *Http) Close() error {
func (h *HTTPConnection) Close() error {
return nil
}

func (h *Http) SetTimeout(timeout time.Duration) *Http {
func (h *HTTPConnection) SetTimeout(timeout time.Duration) *HTTPConnection {
h.httpClient.Timeout = timeout
return h
}

func (h *Http) SetHttpClient(client *http.Client) *Http {
func (h *HTTPConnection) SetHTTPClient(client *http.Client) *HTTPConnection {
h.httpClient = client
return h
}

func (h *Http) Send(method string, params []interface{}) (interface{}, error) {
func (h *HTTPConnection) Send(method string, params []interface{}) (interface{}, error) {
if h.baseURL == "" {
return nil, fmt.Errorf("connection host not set")
}
Expand All @@ -92,6 +92,9 @@ func (h *Http) Send(method string, params []interface{}) (interface{}, error) {
}

req, err := http.NewRequest(http.MethodPost, h.baseURL+"/rpc", bytes.NewBuffer(reqBody))
if err != nil {
return nil, err
}
req.Header.Set("Accept", "application/cbor")
req.Header.Set("Content-Type", "application/cbor")

Expand All @@ -118,24 +121,24 @@ func (h *Http) Send(method string, params []interface{}) (interface{}, error) {

var rpcResponse RPCResponse
err = h.unmarshaler.Unmarshal(resp, &rpcResponse)
if err != nil {
return nil, err
}

// Manage auth tokens
switch method {
case "signin", "signup":
h.variables.Store("token", rpcResponse.Result)
break
case "authenticate":
h.variables.Store("token", params[0])
break
case "invalidate":
h.variables.Delete("token")
break
}

return rpcResponse.Result, nil
}

func (h *Http) MakeRequest(req *http.Request) ([]byte, error) {
func (h *HTTPConnection) MakeRequest(req *http.Request) ([]byte, error) {
resp, err := h.httpClient.Do(req)
if err != nil {
log.Fatalf("Error making HTTP request: %v", err)
Expand All @@ -149,19 +152,19 @@ func (h *Http) MakeRequest(req *http.Request) ([]byte, error) {
return io.ReadAll(resp.Body)
}

func (h *Http) Use(namespace string, database string) error {
func (h *HTTPConnection) Use(namespace string, database string) error {
h.variables.Store("namespace", namespace)
h.variables.Store("database", database)

return nil
}

func (h *Http) Let(key string, value interface{}) error {
func (h *HTTPConnection) Let(key string, value interface{}) error {
h.variables.Store(key, value)
return nil
}

func (h *Http) Unset(key string) error {
func (h *HTTPConnection) Unset(key string) error {
h.variables.Delete(key)
return nil
}
15 changes: 7 additions & 8 deletions pkg/connection/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"github.com/stretchr/testify/assert"
"github.com/surrealdb/surrealdb.go/pkg/model"
"io/ioutil"
"io"
"net/http"
"testing"
"time"
Expand Down Expand Up @@ -33,7 +33,7 @@ func TestEngine_MakeRequest(t *testing.T) {
return &http.Response{
StatusCode: 400,
// Send response to be tested
Body: ioutil.NopCloser(bytes.NewBufferString(`OK`)),
Body: io.NopCloser(bytes.NewBufferString(`OK`)),
// Must be set to non-nil value or it panics
Header: make(http.Header),
}
Expand All @@ -44,28 +44,27 @@ func TestEngine_MakeRequest(t *testing.T) {
Marshaler: model.CborMarshaler{},
Unmarshaler: model.CborUnmashaler{},
}
httpEngine := NewHttp(p)
httpEngine.SetHttpClient(httpClient)
httpEngine := NewHTTPConnection(p)
httpEngine.SetHTTPClient(httpClient)

req, _ := http.NewRequest(http.MethodGet, "http://test.surreal/rpc", nil)
req, _ := http.NewRequest(http.MethodGet, "http://test.surreal/rpc", http.NoBody)
resp, err := httpEngine.MakeRequest(req)
assert.Error(t, err, "should return error for status code 400")

fmt.Println(resp)
}

func TestEngine_HttpMakeRequest(t *testing.T) {

p := NewConnectionParams{
BaseURL: "http://localhost:8000",
Marshaler: model.CborMarshaler{},
Unmarshaler: model.CborUnmashaler{},
}
con := NewHttp(p)
con := NewHTTPConnection(p)
err := con.Use("test", "test")
assert.Nil(t, err, "no error returned when setting namespace and database")

err = con.Connect() //implement a is ready
err = con.Connect() // implement a "is ready"
assert.Nil(t, err, "no error returned when initializing engine connection")

token, err := con.Send("signin", []interface{}{model.Auth{Username: "pass", Password: "pass"}})
Expand Down
Loading