FAQ
I'm working on a driver for OrientDb which operates over http. Since
OrientDb works with a sql-ish query language, commands can be really simple
:

data, err := driver.Command("select * from User")

Which just returns a json array containing all the properties from the User
class:

{
      "result":[
          {
            "@rid":"#12:1",
            "@class": "User",
            "username":"Steve",
            "age": 23
          },
          {...},
          {...}
      ]
}

Which is great, and I can unmarshal this into some struct with all the
fields I expect, but say I do something like this:

data, err := driver.Command("select username from User")

Which gives me something like this:

{
      "result":[
          {
            "username":"Steve",
          },
          {...},
          {...}
      ]
}

Now it's a little harder to marshal the result back into a nice Go struct.
Basically the way I see it, there are two options


    - Let the result struct contain a slice of map[string]interface{} in
    which case the user of the library has to always use the correct keys when
    getting items out of the result. Not the worst thing in the world, but it
    could be a lot prettier. The user in this case also has to do type
    assertions, which results in a lot of code looking like this:
    username := results[0].Properties["username"].(string)

    - Or I could create a struct for every type of response I could possibly
    get back, which would make the code prettier but it would be a lot of work
    and a lot of unnecessary code. I could probably write a code generation
    tool to analyze all queries in the code, and generate structs and
    Marshal/UnmarshalJSON methods for each of these types, but that doesn't
    sound like a lot of fun, does it?

So, can anyone think of a better way to handle this?


Cheers,
Steve

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Gima at Apr 16, 2015 at 5:10 pm
    I remember there being other libraries as well, but for accessing the
    data inside a map in a “structured way”, I could only find this with a
    fast search: https://github.com/jmoiron/jsonq



    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Harry B at Apr 16, 2015 at 5:22 pm
    Is there any difference that I fail to see between first output and second
    output, other than that there are few columns in the second output?
    If so, why can't you Unmarshal (didn't you mean unmarshal?) the result in
    to a struct that always contains all the columns of the table.?
    struct can always have more fields than the JSON being parsed.
    I assume this is something you were planning to do to handle case #1
    anyways.
    On Thursday, April 16, 2015 at 9:52:57 AM UTC-7, Steve Coffey wrote:

    I'm working on a driver for OrientDb which operates over http. Since
    OrientDb works with a sql-ish query language, commands can be really simple
    :

    data, err := driver.Command("select * from User")

    Which just returns a json array containing all the properties from the
    User class:

    {
    "result":[
    {
    "@rid":"#12:1",
    "@class": "User",
    "username":"Steve",
    "age": 23
    },
    {...},
    {...}
    ]
    }

    Which is great, and I can unmarshal this into some struct with all the
    fields I expect, but say I do something like this:

    data, err := driver.Command("select username from User")

    Which gives me something like this:

    {
    "result":[
    {
    "username":"Steve",
    },
    {...},
    {...}
    ]
    }

    Now it's a little harder to marshal the result back into a nice Go struct.
    Basically the way I see it, there are two options


    - Let the result struct contain a slice of map[string]interface{} in
    which case the user of the library has to always use the correct keys when
    getting items out of the result. Not the worst thing in the world, but it
    could be a lot prettier. The user in this case also has to do type
    assertions, which results in a lot of code looking like this:
    username := results[0].Properties["username"].(string)

    - Or I could create a struct for every type of response I could
    possibly get back, which would make the code prettier but it would be a lot
    of work and a lot of unnecessary code. I could probably write a code
    generation tool to analyze all queries in the code, and generate structs
    and Marshal/UnmarshalJSON methods for each of these types, but that doesn't
    sound like a lot of fun, does it?

    So, can anyone think of a better way to handle this?


    Cheers,
    Steve
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Steve Coffey at Apr 16, 2015 at 6:23 pm
    Right, that's probably a better, more complete variation on solution 1.
    Probably the best solution would be to have the api look something like this

    func Command(sql string, result *interface{}) (error)

    Which executes the command and populates a struct with the values of the
    response using that struct's custom UnMarshalJson method. That's probably
    what I'll end up doing.

    And you're right, the major difference is that the first result has more
    columns returned than the second, and it seems like there should be a
    better way to handle ambiguity in the response than just passing back a map.

    On Thursday, April 16, 2015 at 1:22:02 PM UTC-4, Harry B wrote:

    Is there any difference that I fail to see between first output and second
    output, other than that there are few columns in the second output?
    If so, why can't you Unmarshal (didn't you mean unmarshal?) the result in
    to a struct that always contains all the columns of the table.?
    struct can always have more fields than the JSON being parsed.
    I assume this is something you were planning to do to handle case #1
    anyways.
    On Thursday, April 16, 2015 at 9:52:57 AM UTC-7, Steve Coffey wrote:

    I'm working on a driver for OrientDb which operates over http. Since
    OrientDb works with a sql-ish query language, commands can be really simple
    :

    data, err := driver.Command("select * from User")

    Which just returns a json array containing all the properties from the
    User class:

    {
    "result":[
    {
    "@rid":"#12:1",
    "@class": "User",
    "username":"Steve",
    "age": 23
    },
    {...},
    {...}
    ]
    }

    Which is great, and I can unmarshal this into some struct with all the
    fields I expect, but say I do something like this:

    data, err := driver.Command("select username from User")

    Which gives me something like this:

    {
    "result":[
    {
    "username":"Steve",
    },
    {...},
    {...}
    ]
    }

    Now it's a little harder to marshal the result back into a nice Go
    struct. Basically the way I see it, there are two options


    - Let the result struct contain a slice of map[string]interface{} in
    which case the user of the library has to always use the correct keys when
    getting items out of the result. Not the worst thing in the world, but it
    could be a lot prettier. The user in this case also has to do type
    assertions, which results in a lot of code looking like this:
    username := results[0].Properties["username"].(string)

    - Or I could create a struct for every type of response I could
    possibly get back, which would make the code prettier but it would be a lot
    of work and a lot of unnecessary code. I could probably write a code
    generation tool to analyze all queries in the code, and generate structs
    and Marshal/UnmarshalJSON methods for each of these types, but that doesn't
    sound like a lot of fun, does it?

    So, can anyone think of a better way to handle this?


    Cheers,
    Steve
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedApr 16, '15 at 4:53p
activeApr 16, '15 at 6:23p
posts4
users3
websitegolang.org

3 users in discussion

Steve Coffey: 2 posts Harry B: 1 post Gima: 1 post

People

Translate

site design / logo © 2021 Grokbase