gogf / gf

GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang.
https://goframe.org
MIT License
11.44k stars 1.56k forks source link

database/gdb: scan zero value for google.protobuf.Timestamp #3571

Open zcyc opened 4 months ago

zcyc commented 4 months ago

Go version

go version go1.22.3 darwin/amd64

GoFrame version

v2.7.0

Can this bug be reproduced with the latest release?

Option Yes

What did you do?

I run gf-demo-grpc and use PostgresSQL for database. DDL is:

create table "user"
(
    id serial primary key,
    passport  varchar(45) not null unique,
    password  varchar(45) not null,
    nickname  varchar(45) not null,
    create_at timestamp,
    update_at timestamp,
    delete_at timestamp
);

When i request the GetById method, scan the zero value for google.protobuf.Timestamp of pbentity.User

What did you see happen?

{
    "User": {
        "Id": 1,
        "Passport": "正团小斯",
        "Password": "口际严消只但",
        "Nickname": "进影一得华来行",
        "CreateAt": {
            "seconds": "0",
            "nanos": 0
        },
        "UpdateAt": {
            "seconds": "0",
            "nanos": 0
        },
        "DeleteAt": null
    }
}

What did you expect to see?

{
    "User": {
        "Id": 1,
        "Passport": "正团小斯",
        "Password": "口际严消只但",
        "Nickname": "进影一得华来行",
        "CreateAt": {
            "seconds": "1715155546",
            "nanos": 0
        },
        "UpdateAt": {
            "seconds": "1715155546",
            "nanos": 0
        },
        "DeleteAt": null
    }
}
zcyc commented 4 months ago

目前是这样实现的,不知道有没有更优雅的方式

func (s *sUser) GetById(ctx context.Context, uid uint64) (*pbentity.User, error) {
    var (
        user   *entity.User
        userPB *pbentity.User
    )

    // 从数据库中获取用户信息
    err := dao.User.Ctx(ctx).Where(do.User{
        Id: uid,
    }).Scan(&user)
    if user == nil {
        return nil, gerror.NewCodef(gcode.CodeInvalidParameter, g.I18n().T(ctx, "{#user-not-found}"))
    }

    // 转换 pb 对象
    if err := gconv.Struct(user, &userPB); err != nil {
        return nil, gerror.NewCodef(gcode.CodeInternalError, g.I18n().T(ctx, "{#system-busy}"))
    }

    // 处理 pb 时间
    userPB.CreateAt = timestamppb.New(user.CreateAt.Time)
    userPB.UpdateAt = timestamppb.New(user.UpdateAt.Time)

    return userPB, err
}
Issues-translate-bot commented 4 months ago

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


This is currently possible, but I don’t know if there is a more elegant way.


func (s *sUser) GetById(ctx context.Context, uid uint64) (*pbentity.User, error) {
var (
user *entity.User
userPB *pbentity.User
)

// Get user information from the database err := dao.User.Ctx(ctx).Where(do.User{ Id: uid, }).Scan(&user) if user == nil { return nil, gerror.NewCodef(gcode.CodeInvalidParameter, g.I18n().T(ctx, "{#user-not-found}")) }

// Convert pb object if err := gconv.Struct(user, &userPB); err != nil { return nil, gerror.NewCodef(gcode.CodeInternalError, g.I18n().T(ctx, "{#system-busy}")) }

// Process pb time userPB.CreateAt = timestamppb.New(user.CreateAt.Time) userPB.UpdateAt = timestamppb.New(user.UpdateAt.Time)

return userPB, err }

wln32 commented 3 months ago

@zcyc 可以试试给字段实现一个json.Unmarshaler接口