go-gorm / gorm

The fantastic ORM library for Golang, aims to be developer friendly
https://gorm.io
MIT License
37.02k stars 3.94k forks source link

feat(expression): support case-when expression #7276

Open minhtri1396 opened 1 week ago

minhtri1396 commented 1 week ago

What did this pull request do?

Implement case-when expression to use case-when in SQL query.

User Case Description

We can use this expression to update batches instead of single update.

userIDs := make([]string, len(inputUsers))
userNameCases := make([]*clause.ExprCaseCondition, len(inputUsers))
for idx, user := range inputUsers {
    userIDs[idx] = user.ID
    userNameCases[idx] = &clause.ExprCaseCondition{
        When: "user_id=?",
        Then: "?",
        Vars: []any{
            user.ID,
            user.Name,
        },
    }
}

db.
    Table("users").
    Where("user_id IN (?)", userIDs).
    UpdateColumns(map[string]any{
        "user_name": clause.ExprCase{
            Cases: userNameCases,
            Else: &clause.ExprCaseElse{
            Then: "user_name",
                Vars: nil,
            },
        },
    })

The generated SQL will be:

UPDATE `users`
SET `user_name`=CASE
    WHEN user_id="user-001" THEN "user-name-001"
    WHEN user_id="user-002" THEN "user-name-002"
    ELSE user_name
END
WHERE user_id IN ("user-001","user-002")
jinzhu commented 1 week ago

Could we design the API to look something like this and place it in the datatypes package?

casewhen := datatypes.When("name = ?", "123").Then("hello").
            When("name = ?", "234").Then("hello2").
            Else("hello3")

db.Model(&user).Where("id = ?", 1).Update(map[string]any{"name": casewhen})