I want to create a function (in the example code called gremlinResultToStruct()
) that takes an arbitrary struct and populates the values from a database query. Please note that the "Properties" key in the GremlinResultStruct are arbitrary too (that is why it is a Properties map[string][]struct
)
GOAL:
I want gremlinResultToStruct()
to populate the given struct based on its keys if they are available in the database results.
WHY:
I have hundreds of structs like Foo and Bar in my codebase and I want to have a single function that populates the struct needed in the code instead of creating semi-duplicate code.
CODE:
My code looks like this, it also contains the question:
// Gremlin Query result struct
type GremlinResult struct {
AtType string `json:"@type"`
AtValue []struct {
AtType string `json:"@type"`
AtValue struct {
ID struct {
AtType string `json:"@type"`
AtValue int `json:"@value"`
} `json:"id"`
Label string `json:"label"`
Properties map[string][]struct { // <== IMPORTANT, CONTAINS A VALUE THAT IS THE EQUIVALENT OF THE KEY IN THE STRUCT (like Something, SomethingElse, EvenMoreSomethingElse or AndMoreSomethingElse)
AtType string `json:"@type"`
AtValue struct {
ID struct {
AtType string `json:"@type"`
AtValue int `json:"@value"`
} `json:"id"`
Label string `json:"label"`
Value string `json:"value"`
} `json:"@value"`
} `json:"@properties"`
} `json:"@value"`
} `json:"@value"`
}
type Foo struct {
Something string
SomethingElse bool
}
type Bar struct {
EvenMoreSomethingElse string
AndMoreSomethingElse int
}
func gremlinResultToStruct(result *GremlinResult, ???){ // What to do at ???
// How to itterate over the ??? key values (like: Something, SomethingElse, EvenMoreSomethingElse or AndMoreSomethingElse)
// How to populate:
// VARIABLE := Something, SomethingElse, EvenMoreSomethingElse or AndMoreSomethingElse
// result.AtValue[0].AtValue.Properties[ VARIABLE ][0].AtValue.Value
}
func main {
// Do stuff to get JSON results. HOW is not relevant for question
dbResults := doDbStuffToPopulateResuts()
// Create the results variable as gremlinResults struct
results := GremlinResult{}
// Unmarshall to this struct
err = json.Unmarshal(dbResults, &results)
// 1. Expected result should be "result-a" (see below)
// Create the Foo struct
foo := Foo{}
// HERE IS MY QUESTION ABOUT (see function above)
gremlinResultToStruct(&results, &foo)
// NOW foo SHOULD HAVE Something and SomethingElse set
fmt.Println(foo.Something, foo.SomethingElse)
// 2. Expected result should be "result-b" (see below)
// Create the Bar struct
bar := Bar{}
// HERE IS MY QUESTION ABOUT (see function above)
gremlinResultToStruct(&results, &bar)
// NOW foo SHOULD HAVE Something and SomethingElse set
fmt.Println(bar.EvenMoreSomethingElse, bar.AndMoreSomethingElse)
}
Example JSON results.
result-A:
{
"@type": "g:List",
"@value": [{
"@type": "g:Vertex",
"@value": {
"id": {
"@type": "g:Int64",
"@value": 200
},
"label": "key",
"properties": {
"SomeThing": [{ // <== IMPORTANT, same as struct field in Foo{}
"@type": "g:VertexProperty",
"@value": {
"id": {
"@type": "g:Int64",
"@value": 201
},
"value": true,
"label": "Write"
}
}],
"SomeThingElse": [{ // <== IMPORTANT, same as struct field in Foo{}
"@type": "g:VertexProperty",
"@value": {
"id": {
"@type": "g:Int64",
"@value": 202
},
"value": true,
"label": "Read"
}
}]
}
}
}]
}
result-B:
{
"@type": "g:List",
"@value": [{
"@type": "g:Vertex",
"@value": {
"id": {
"@type": "g:Int64",
"@value": 200
},
"label": "key",
"properties": {
"EvenMoreSomethingElse": [{ // <== IMPORTANT, same as struct field in Bar{}
"@type": "g:VertexProperty",
"@value": {
"id": {
"@type": "g:Int64",
"@value": 201
},
"value": true,
"label": "Write"
}
}],
"AndEvenMoreSomethingElse": [{ // <== IMPORTANT, same as struct field in Bar{}
"@type": "g:VertexProperty",
"@value": {
"id": {
"@type": "g:Int64",
"@value": 202
},
"value": true,
"label": "Read"
}
}]
}
}
}]
}