Saving Sql result sets in a nested structure and skipping if empty

I am trying to save a SQL query dataset in a structure and display in JSON. I almost did it. Now the problem is that the result set of nested structures is empty, and I would not want to display it.

The same problem is indicated here , but using the pointer ends in a panic when the scan may be due to what I'm using&user.Profile.Firstname

2015/11/01 16:42:16 Panic recovery → runtime error: invalid memory address or reversal of a pointer to zero

If I delete the pointer, then everything will be fine, only an empty field will remain. I am confused how to achieve this.

package main

import (
    "database/sql"
    "github.com/gin-gonic/gin"
    _ "github.com/go-sql-driver/mysql"
    "log"
)

type User struct {
    Id       int64
    Username string
    Email    string
    Profile  Profile `json:",omitempty"`
}

type Profile struct {
    Id        int64  `json:",omitempty"`
    UserId    int64  `json:",omitempty"`
    Firstname *string `json:",omitempty"`
    Lastname  *string `json:",omitempty"`
}

var DB *sql.DB

func checkErr(err error, msg string) {
    if err != nil {
        log.Fatal(msg, err)
    }
}

func main() {
    DB, _ = sql.Open("mysql", "username:secrect@/database")
    defer DB.Close()

    r := gin.Default()
    v1 := r.Group("api/v1/")
    {
        v1.GET("users", GetUsers)
    }
    r.Run(":8080")
}


func GetUsers(c *gin.Context) {
    stmt, err := DB.Query("Select users.id, username , email , firstname , lastname from users left join profiles on users.id = profiles.user_id ")
    if err != nil {
        panic(err.Error())
    }
    defer stmt.Close()

    users := []User{}

    for stmt.Next() {
        var user User
        err := stmt.Scan(&user.Id, &user.Username, &user.Email, &user.Profile.Firstname, &user.Profile.Lastname)
        if err != nil {
            panic(err.Error())
        }

        users = append(users, user)
    }

    c.JSON(200, &users)
}

Output:

{
  "Id": 1,
  "Username": "test1",
  "Email": "test1@example.com",
  "Profile": {
    "Firstname": "John",
    "Lastname": "Doe"
  }
},
{
  "Id": 2,
  "Username": "test2",
  "Email": "test2@example.com",
  "Profile": {
  }
},
+7
source share
1

, gin encoding/json , Profile, , , User:

type User struct {
    ....
    Profile *Profile `json:",omitempty"`
}

:

"omitempty" , , , false, 0, nil, nil , , .

, .

, db. Profile, , User, :

var user User
var profile Profile
_ = stmt.Scan(&user.Id, &user.Username, &user.Email, &profile.Firstname, &profile.Lastname)
if profile != Profile{} {
    user.Profile = &profile
}

, , , .

+3

Source: https://habr.com/ru/post/1614035/


All Articles