surrealdb / surrealdb.go

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

Send and receive generic records as structs #3

Closed TimothyStiles closed 1 year ago

TimothyStiles commented 2 years ago

This PR needs to be cleaned up a smidge but it has generic struct insertion, retrieval, and unmarshaling.

TimothyStiles commented 2 years ago

@tobiemh this pull request adds an Unmarshal function and lets users send and receive/parse arbitrary data structures. This functionality also respects and expands the previous API allowing users to send map[string]interface{}as well as their struct of choice.

For example:


    userMap, err := db.Create("users", map[string]interface{}{
        "username": "john",
        "password": "123",
    })

    if err != nil || userMap == nil {
        panic(err)
    }

    userData, err := db.Create("users", testUser{
        Username: "johnny",
        Password: "123",
    })

Data can be unmarshaled as so:

    userData, err := db.Create("users", testUser{
        Username: "johnny",
        Password: "123",
    })

    var user testUser
    err = surrealdb.Unmarshal(userData, &user)
    if err != nil {
        panic(err)
    }

    fmt.Println(user.Username)

    // Output: johnny

Struct slices can also be unmarshaled:

    userData, err := db.Select("users") // TODO: should let users specify a selector other than '*'

    // unmarshal the data into a user slice
    users := []testUser{}
    err = surrealdb.Unmarshal(userData, &users)
    if err != nil {
        panic(err)
    }

    for _, user := range users {
        if user.Username == "johnnyjohn" {
            fmt.Println(user.Username)
            break
        }
    }
    // Output: johnnyjohn

It also lets users update entries using structs:

    userData, err := db.Create("users", testUser{
        Username: "johnny",
        Password: "123",
    })

    // unmarshal the data into a user struct
    var user testUser
    err = surrealdb.Unmarshal(userData, &user)
    if err != nil {
        panic(err)
    }

    user.Password = "456"

    // Update the user
    userData, err = db.Update("users", user)

    if err != nil {
        panic(err)
    }

    // unmarshal the data into a user struct
    var updatedUser []testUser
    err = surrealdb.Unmarshal(userData, &updatedUser)

    if err != nil {
        panic(err)
    }

    // TODO: check if this updates only the user with the same ID or all users
    fmt.Println(updatedUser[0].Password)

    // Output: 456

I think the functionality here may cover most things in a standard ORM which is exciting. Just need to get arbitrary selectors working for Delete and Select but that's coming in a separate PR!

-Tim

josearomeroj commented 2 years ago

What about a way to add a custom marshaller?

tobiemh commented 1 year ago

Hey @TimothyStiles just wanted to check on the status of this, iron out any bugs if there are any, rebase off of main (there have been some changes), and then get this merged! Let me know your thoughts!

TimothyStiles commented 1 year ago

Hey @TimothyStiles just wanted to check on the status of this, iron out any bugs if there are any, rebase off of main (there have been some changes), and then get this merged! Let me know your thoughts!

Hey @tobiemh check out @garrison-henkle's PR #8. It adds some functionality that does what I was trying to fix. Can we review and merge that one? Already reviewed it a little.

tobiemh commented 1 year ago

Ok @TimothyStiles thanks! Shall we close this?

TimothyStiles commented 1 year ago

@tobiemh Depending on how things are setup there's a slight possibility that closing this PR may muck things up for PR #8.

It's bedtime for me here in California so can't confirm this now but feel free to close this PR when #8 is merged!

TimothyStiles commented 1 year ago

Merged in PR #8. Closing.