Getting an error while inserting a slice into Redis database using redix.v3. What's redis command to insert a slice? SET or HMSET?
My code:
type Domain struct {
ID string `json:"ID,omitempty"`
ParentID string `json:"parentID,omitempty"`
ParentType string `json:"parentType,omitempty"`
Owner string `json:"owner,omitempty"`
PATEnabled string `json:"PATEnabled,omitempty"`
Name string `json:"name,omitempty"`
}
for _, domain := range domains {
if err := client.Do(radix.FlatCmd(nil, "HMSET", domain.ID, domain)); err != nil {
log.Println(err)
}
Error message:
could not marshal value of type Domain
Related
I am using the REST proxy instance of Kafka for producing and consuming messages.Using the API to get new messages but I am not able to convert those messages to a struct model in Go. For example:
// Get records
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf(FETCH_CONSUMER, URL, GROUP, CONSUMER), nil)
if err != nil {
panic(err)
}
req.Header.Add("Accept", CONTENT_TYPE)
respRecords, err := client.Do(req)
if err != nil {
panic(err)
}
defer respRecords.Body.Close()
fmt.Printf("Response %s\n", respRecords.Status)
fmt.Println(respRecords.Body)
recordsBodyResp := bufio.NewScanner(respRecords.Body)
for recordsBodyResp.Scan() {
fmt.Printf("<--Body %s\n", recordsBodyResp.Text())
}
The value returned is in the following format:
[{"topic":"backward","key":null,"value":{"AdoptionID":"abcd123","IPAddress":"8.8.8.8","Port":"80","Status":"requested"},"partition":0,"offset":7}]
Since it's an array of objects, I want to extract the value portion of the key "value" into a struct.
That is where I am stuck.
You can create a struct like:
type AutoGenerated []struct {
Topic string `json:"topic"`
Key interface{} `json:"key"`
Value Value `json:"value"`
Partition int `json:"partition"`
Offset int `json:"offset"`
}
type Value struct {
AdoptionID string `json:"AdoptionID"`
IPAddress string `json:"IPAddress"`
Port string `json:"Port"`
Status string `json:"Status"`
}
And Unmarshal in that struct.
See this sample code:
package main
import (
"fmt"
"encoding/json"
)
func main() {
type Value struct {
AdoptionID string `json:"AdoptionID"`
IPAddress string `json:"IPAddress"`
Port string `json:"Port"`
Status string `json:"Status"`
}
type AutoGenerated []struct {
Topic string `json:"topic"`
Key interface{} `json:"key"`
Value Value `json:"value"`
Partition int `json:"partition"`
Offset int `json:"offset"`
}
byt := []byte(`[{"topic":"backward","key":null,"value":{"AdoptionID":"abcd123","IPAddress":"8.8.8.8","Port":"80","Status":"requested"},"partition":0,"offset":7}]`)
var dat AutoGenerated
if err := json.Unmarshal(byt, &dat); err != nil {
panic(err)
}
fmt.Printf("%#v", dat)
}
I am using Go fiber's body parser to parse the request body. I have the following struct
type SignInCredentials struct {
Email string
Password []byte
}
Where I have a Password as a slice of bytes. When I try to parse the body like so
func SignUp(db *database.Database) fiber.Handler {
return func(c *fiber.Ctx) error {
cred := new(model.SignUpCredentials)
if err := c.BodyParser(cred); err != nil {
return SendParsingError(c)
}
I get a schema error
schema: error converting value for index 0 of \"Password\
because the type of the form data password doesn't match the []byte type. I looked at their examples and I noticed that in the documentation they use a string to store the password. But I am set on storing it as a slice of bytes. How can I do this?
// Field names should start with an uppercase letter
type Person struct {
Name string `json:"name" xml:"name" form:"name"`
Pass string `json:"pass" xml:"pass" form:"pass"`
}
app.Post("/", func(c *fiber.Ctx) error {
p := new(Person)
if err := c.BodyParser(p); err != nil {
return err
}
log.Println(p.Name) // john
log.Println(p.Pass) // doe
// ...
})
It is transmitted as a string, not []byte. You need to parse it as a string first, then you can transform it into the structure you want:
func SignUp(db *database.Database) fiber.Handler {
return func(c *fiber.Ctx) error {
// an anonymous struct to parse the body
body := struct{
Email string
Password string
}{}
if err := c.BodyParser(body); err != nil {
return SendParsingError(c)
}
cred := SignInCredentials{
Email: body.Email,
Password: []byte(body.Password),
}
I'm trying to write an API that will do different things with the data depending on its purpose.
API results - The API should expose certain fields to the user
Validation - Validation should handle different schemas e.g. login form doesn't require Name, but register does
Database - The database should save everything, including password etc. - if I try using the same struct for the API and DB with json:"-" or un-exporting the field the database save also ignores the field
Some sample code is below with a couple of comments in capitals to show where I ideally need to type cast to change the data. As they are different structs, they cannot be type cast, so I get an error. How can I fix this?
Alternatively, what is a better way of doing different things with the data without having lots of similar structs?
// IDValidation for uuids
type IDValidation struct {
ID string `json:"id" validate:"required,uuid"`
}
// RegisterValidation for register form
type RegisterValidation struct {
Name string `json:"name" validate:"required"`
Email string `json:"email" validate:"required,email"`
Password string `json:"password" validate:"required,min=8"`
}
// UserModel to save in DB
type UserModel struct {
ID string `json:"id,omitempty"`
Name string `json:"name"`
Email string `json:"email"`
Password string `json:"password,omitempty"`
Active bool `json:"active,omitempty"`
CreatedAt int64 `json:"created_at,omitempty"`
UpdatedAt int64 `json:"updated_at,omitempty"`
jwt.StandardClaims
}
// UserAPI data to display to user
type UserAPI struct {
ID string `json:"id,omitempty"`
Name string `json:"name"`
Email string `json:"email"`
Active bool `json:"active,omitempty"`
}
// register a user
func register(c echo.Context) error {
u := new(UserModel)
if err := c.Bind(u); err != nil {
return err
}
// NEED TO CAST TO RegisterValidation HERE?
if err := c.Validate(u); err != nil {
return err
}
token, err := u.Register()
if err != nil {
return err
}
return c.JSON(http.StatusOK, lib.JSON{"token": token})
}
// retrieve a user
func retrieve(c echo.Context) error {
u := IDValidation{
ID: c.Param("id"),
}
if err := c.Validate(u); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
}
// NEED TO CAST USER TO UserAPI?
user, err := userModel.GetByID(u.ID)
if err != nil {
return err
}
return c.JSON(200, lib.JSON{"message": "User found", "user": user})
}
Given the following data structure which has been created in the database and there is valid data in the rows in the appropriate tables:-
type Deployment struct {
gorm.Model
Name string `gorm:"unique_index:idx_name"`
RestAPIUser string
RestAPIPass string
Servers []Server
model *Model
}
type Server struct {
gorm.Model
DeploymentID uint
Hostname string `gorm:"unique_index:idx_hostname"`
RestPort string
Version string
}
I'm trying to select all Deployments and have GORM automatically fill the Servers for each Deployment.
Unfortunately, it doesn't do this. I've tried several variations of using the Associations() func but I can't seem to get it to work. I seem to have to do this manually:-
func (m *Model) GetDeployments() ([]Deployment, error) {
deployments := []Deployment{}
err := m.db.Find(&deployments).Error
if err != nil {
return nil, err
}
deploymentsWithServers := []Deployment{}
for _, d := range deployments {
servers := []Server{}
err := m.db.Model(&d).Association("Servers").Find(&servers).Error
if err != nil {
return nil, err
}
d.Servers = servers
deploymentsWithServers = append(deploymentsWithServers, d)
}
return deploymentsWithServers, nil
}
Does anyone have any suggestions how I can get GORM to fill the Servers field automatically? Thanks!
Try
m.db.Preload("Servers").Find(&Deployment{})
I have a BaseEntity struct and one method with *BaseEntity receiver that parses xml from file
type BaseEntity struct {
FilePath string
Collection string
}
func (this *BaseEntity) Parse() *[]byte {
xmlFile, err := ioutil.ReadFile(this.FilePath)
if err != nil {
fmt.Println("Error opening file:", err)
return nil
}
return &xmlFile
}
I also have several structs where BaseEntity is embedded, for eg. Users, Posts, Comments, Tags ... etc
type Users struct {
Data []User `xml:"row"`
BaseEntity
}
type User struct {
WebsiteUrl string `xml:"WebsiteUrl,attr"`
UpVotes string `xml:"UpVotes,attr"`
Id string `xml:"Id,attr"`
Age string `xml:"Age,attr"`
DisplayName string `xml:"DisplayName,attr"`
AboutMe string `xml:"AboutMe,attr"`
Reputation string `xml:"Reputation,attr"`
LastAccessDate string `xml:"LastAccessDate,attr"`
DownVotes string `xml:"DownVotes,attr"`
AccountId string `xml:"AccountId,attr"`
Location string `xml:"Location,attr"`
Views string `xml:"Views,attr"`
CreationDate string `xml:"CreationDate,attr"`
ProfileImageUrl string `xml:"ProfileImageUrl,attr"`
}
func (this *Users) LoadDataToDB() {
file := this.Parse()
xml.Unmarshal(*file, &this)
// Init db
db := database.MgoDb{}
db.Init()
defer db.Close()
for _, row := range this.Data {
err := db.C(this.Collection).Insert(&row)
if err != nil {
fmt.Println(err)
}
}
}
And for each of these structs I need to create a method LoadDataToDB that loads data in db and has some code.
This method can't have *BaseEntity receiver because I can't get this.Data in base struct and I can't get this struct from parameters because it always a different struct.
How to DRY and move this repeating method from every embedded struct to one?