Defined Type

Using a Defined Type that satisfies the genorm.ExprTypeinterface is an even stronger way to prevent SQL mistakes.

In the Configuration file used as an example of usage, both the id and user_id columns of the messages table are of type uuid.UUID. Therefore, the

messageValues, err := genorm.
    Select(orm.Message()).
    Where(genorm.Eq(message.IDExpr, message.UserIDExpr)).
    GetAll(db)

will not result in a compile error.

However, there should be few cases where you want to compare the id of a message with the id of a user.

Define the MessageID and UserID types as follows.

type MessageID uuid.UUID

func (mid *MessageID) Scan(src any) error {
    return (*uuid.UUID)(mid).Scan(src)
}

func (mid MessageID) Value() (driver.Value, error) {
    return uuid.UUID(mid).Value()
}

type UserID uuid.UUID

func (uid *UserID) Scan(src any) error {
    return (*uuid.UUID)(uid).Scan(src)
}

func (uid UserID) Value() (driver.Value, error) {
    return uuid.UUID(uid).Value()
}

Then, set the id and user_id columns in the messages table in the Configuration file to the MessageID and UserID types.

By doing so, message's id and user's id can be treated as different types, and the following code will result in a compile error.

messageValues, err := genorm.
    Select(orm.Message()).
    Where(genorm.Eq(message.IDExpr, message.UserIDExpr)).
    GetAll(db)

results matching ""

    No results matching ""