surrealdb / surrealdb.go

SurrealDB SDK for Golang
https://surrealdb.com
Apache License 2.0
237 stars 64 forks source link

Bug: UnmarshalRaw panics when unmarshalling object #139

Open AAA1exa8 opened 4 months ago

AAA1exa8 commented 4 months ago

Describe the bug

When .Query() returns object UnmarshalRaw panics with

goroutine 1 [running]:
github.com/surrealdb/surrealdb%2ego.UnmarshalRaw({0x635ea0?, 0xc00022e1f8?}, {0x630aa0, 0xc000224430})
        ~/go/pkg/mod/github.com/surrealdb/surrealdb.go@v0.2.1/db.go:119 +0x2e5
main.main()
        /paht/to/file/side.go:39 +0x309
exit status 2

Steps to reproduce

package main

import (
    "fmt"

    "github.com/surrealdb/surrealdb.go"
)

type Id struct {
    Id int `json:"id"`
}

func main() {
    db, err := surrealdb.New("ws://localhost:8000/rpc")
    if err != nil {
        fmt.Print(err.Error())
        return
    }
    defer db.Close()
    if _, err = db.Signin(map[string]interface{}{
        "user": "root",
        "pass": "root",
    }); err != nil {
        fmt.Print(err.Error())
        return
    }
    if _, err = db.Use("namespace", "database"); err != nil {
        fmt.Print(err.Error())
        return
    }
    iddb, err := db.Query(`RETURN {
        id: 3
    }`, nil)
    if err != nil {
        fmt.Print(err.Error())
        return
    }
    var id Id
    _, err = surrealdb.UnmarshalRaw(iddb, &id)
    if err != nil {
        fmt.Print(err.Error())
    }
    fmt.Print(id)

}

Expected behaviour

UnmarashalRaw should correctly unmarshall the response

There is workaround by doing

iddb, err := db.Query(`RETURN [{
    id: 3
}]`, nil)
var id []Id
_, err = surrealdb.UnmarshalRaw(iddb, &id)

SurrealDB version

1.5.0 for linux on x86_64

Contact Details

No response

Is there an existing issue for this?

Code of Conduct

AAA1exa8 commented 4 months ago

I've just quickly went through the code of the current commit and it seems the RawQuery type still expects array

type RawQuery[I any] struct {
    Status string `json:"status"`
    Time   string `json:"time"`
    Result []I    `json:"result"`
    Detail string `json:"detail"`
}

this is the code I ran with the current commit of main

package main

import (
    "fmt"

    "github.com/surrealdb/surrealdb.go"
    "github.com/surrealdb/surrealdb.go/pkg/conn/gorilla"
    "github.com/surrealdb/surrealdb.go/pkg/marshal"
)

type Id struct {
    Id int `json:"id"`
}

func main() {
    ws := gorilla.Create()
    conn, err := ws.Connect("ws://localhost:8000/rpc")
    if err != nil {
        fmt.Print(err.Error())
        return
    }
    db, err := surrealdb.New("ws://localhost:8000/rpc", conn)
    if err != nil {
        fmt.Print(err.Error())
        return
    }
    defer db.Close()
    if _, err = db.Signin(&surrealdb.Auth{
        Namespace: "namespace",
        Database:  "database",
        Username:  "root",
        Password:  "root",
    }); err != nil {
        fmt.Print(err.Error())
        return
    }
    iddb, err := db.Query(`RETURN {
        id: 3
    }`, nil)
    if err != nil {
        fmt.Print(err.Error())
        return
    }
    var id []marshal.RawQuery[Id]
    err = marshal.UnmarshalRaw(iddb, &id)
    if err != nil {
        fmt.Print(err.Error())
    }
    fmt.Print(id)

}

it returns error but no longer panics

json: cannot unmarshal object into Go struct field RawQuery[main.Id].result of type []main.Id[{OK 12.487µs [] }]

it got fixed for me when I changed the type of result to I instead of []I

It also wokrs as expected when the query returns array. The type parameter just needs to alos be array

iddb, err := db.Query(`RETURN [{
    id: 3
}]`, nil)
var id []marshal.RawQuery[[]Id]
err = marshal.UnmarshalRaw(iddb, &id)

I can open PR with the fix

ElecTwix commented 4 months ago

I can open PR with the fix

Feel free to Open PR, all contributions are welcome. As far as I remember SmartUnmarshal also uses that maybe it can need a bit of refactoring in there too.

AAA1exa8 commented 4 months ago

its one line change in SmartUnmarshall