Golang Decode a BSON with special character Keys to a struct - go

I have a Golang struct called Person where all the properties have to be exported:
type Person struct {
Id string
Name string
}
Now I need to encode my MongoDB BSON response to this Person struct. The BSON looks like:
{
"_id": "ajshJSH78N",
"Name": "Athavan Kanapuli"
}
The Golang code to encode the BSON is:
mongoRecord := Person{}
c := response.session.DB("mydb").C("users")
err := c.Find(bson.M{"username": Credentials.Username, "password": Credentials.Password}).One(&mongoRecord)
The Problem:
_id is not getting encoded into Id
If I change the Person property into _Id, then it won't be exported.
How can I solve this problem?

Define your struct with json tag-
type Person struct {
Id string `json:"_id"`
Name string // this field match with json, so mapping not need
}

I tried to put a json tag like ,
type Person struct {
Id string `json:"_id"`
Name string // this field match with json, so mapping not need
}
But still it didn't work. Because the Mongodb returns '_id' which is of type bson.ObjectId . Hence changing the Struct tag to bson:"_id" and the type of the Person struct has been changed from string to bson.ObjectId. The changes done are as follows ,
type Person struct {
Id bson.ObjectId `bson:"_id"`
Name string
UserName string
IsAdmin bool
IsApprover bool
}
And It works!

Related

Go return struct as JSON in HTTP request

I've defined the following struct in Go:
type repoStars struct {
name string
owner string
stars int
}
And I've created an array repoItems := []repoStars{} which has multiple items of the struct above.
This is how repoItems looks like:
I'm trying to return those items as a JSON response:
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(repoItems)
And it seems empty
What am I doing wrong here?
If the struct fields start with a lower case letter it means unexported. All unexported fields won't be serialised by the encoder.
Change it to capital first letter.
type repoStars struct {
Name string
Owner string
Stars int
}

Gorm w/ Postgres has a nested struct as JSON

I am using GORM and I want to store the following struct in Postgres:
// Value GoDoc
type Value struct {
Name string
Place string
Value interface{}
}
// SharedConfig stores tenant-wide shared values
type SharedConfig struct {
gorm.Model
TenantID string
ProgramID *string
Name string
Value Value
}
I want to store SharedConfig in my DB and want the Value column to be stored as JSON, is this possible? I've only seen uses of the json column type as postgres.Jsonb

Merging 2 structures with different types

I have two structures.
EventForm is the structure that is used to parse the POST body of a request.
EventTable is used for creating the MYSQL table structure and finding/creating rows.
I want to merge EventForm with EventTable so that fields like ID cannot be overridden via the POST body. I am not able to convert the type of EventForm to EventTable since you cannot convert a struct to a different type if the fields do not 100% match. So my question is what is the best way to merge these two structs? If it is not plausible to merge these two structs how could I best solve this problem?
package models
import "time"
// EventTable table structure of "events"
type EventTable struct {
EventForm `xorm:"extends"`
ID int `xorm:"autoincr pk 'id'" json:"id"`
Created time.Time `xorm:"not null created" json:"created"`
Updated time.Time `xorm:"not null updated" json:"updated"`
}
// TableName table name of EventTable
func (u *EventTable) TableName() string {
return "events"
}
// EventForm the structure that is received via an API call
type EventForm struct {
Title string `xorm:"not null" json:"title" required:"true"`
Description string `xorm:"not null" json:"description" required:"true"`
Owner string `xorm:"not null" json:"owner" required:"true"`
Lat string `xorm:"not null" json:"lat" required:"true"`
Lng string `xorm:"not null" json:"lng" required:"true"`
}
I am with #mkopriva and don't fully understand what the problem is. Assuming you are receiving EventForm from some API call
evtForm := GetSomeEventForm()
evtTable := &models.EventTable{ EventForm: evtForm, Created: time.Now() }
someORMProbably.Insert(evtTable)

structs with multiple mapping notations

I have these two structs which represent the same entities (one comes from a Json file and the other from a DB)
type DriverJson struct {
ID int `json:"id"`
Name string `json:"name"`
}
type DriverOrm struct {
ID int `orm:"column(id);auto"`
Name string `orm:"column(name);size(255);null"`
}
I want to merge them into one Driver struct, how do I merge the mapping notations (orm:, json:)?
Thank you
As mentioned in the documentation of reflect.StructTag, by convention the value of a tag string is a space-separated key:"value" pairs, so simply:
type DriverJson struct {
ID int `json:"id" orm:"column(id);auto"`
Name string `json:"name" orm:"column(name);size(255);null`
}
For details, see What are the use(s) for tags in Go?

How can I add a new boolean property to a Golang struct and set the default value to true?

I have a user struct that corresponds to an entity. How can I add a new property active and set the default value to true?
Can I also set the value of that property to true for all existing entities by some easy method?
type User struct {
Id int64 `json:"id"`
Name string `json:"name"`
}
Bonus questions: I don't quite understand the syntax in the struct. What do the three columns represent? What do the JSON strings have ``around them?
//You can't change declared type.
type User struct {
Id int64 `json:"id"`
Name string `json:"name"`
}
//Instead you construct a new one embedding existent
type ActiveUser struct {
User
Active bool
}
//you instantiate type literally
user := User{1, "John"}
//and you can provide constructor for your type
func MakeUserActive(u User) ActiveUser {
auser := ActiveUser{u, true}
return auser
}
activeuser := MakeUserActive(user)
You can see it works https://play.golang.org/p/UU7RAn5RVK
You have to set the default value as true at the moment when you are passing the struct type to a variable, but this means you need to extend that struct with a new Active field.
type User struct {
Id int64 `json:"id"`
Name string `json:"name"`
Active bool
}
user := User{1, "John", true}
json:"id" means that you are mapping the json decoded object field to the field id in your struct type. Practically you are deserialize the json string into object fields which later you can map to their specific field inside the struct.

Resources