Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updateOrInsert Method #1509

Closed
Im-Fran opened this issue May 11, 2022 · 2 comments · Fixed by #1743
Closed

updateOrInsert Method #1509

Im-Fran opened this issue May 11, 2022 · 2 comments · Fixed by #1743
Assignees

Comments

@Im-Fran
Copy link

Im-Fran commented May 11, 2022

Hi everyone! I'm currently having some questions about this piece of code created by me:

// Here we assume I have the table 'Users' with the column 'name' and 'city'. And this method is inside my internal user manager.

fun saveUser(user: User) {
    transaction {
        val exists = Users.select { Users.name eq user.name } .count() > 0L
        if (exists) {
            Users.update({ Users.name eq user.name }) {
                it[name] = user.name
                it[city] = user.city
            }
        } else {
            Users.insert {
                it[name] = user.name
                it[city] = user.city
            }
        }
    }
}

Right now I would have no issue with repeating the assignation of the variables, but what will happen with, let's say 64 variables? Do I need to create 128 assignations? I think it would be better a updateOrInsert method that replaces my example so I can just do this:

fun saveUser(user: User) {
    transaction {
        Users.updateOrInsert({ Users.name eq user.name }) {
            it[name] = user.name
            it[city] = user.city
        }
    }
}

I couldn't find something similar in the Wiki or the code, so if someone knows a better way to do this or if it's possible to implement it into Exposed it would be cool ^^

@heli-os
Copy link

heli-os commented May 19, 2022

i extracted it with function:

override fun insert(memberDefinition: MemberRepository.MemberDefinition) {
    execInsert {
        insertOrUpdate(it, memberDefinition)
    }
}

override fun update(id: Long, memberDefinition: MemberRepository.MemberDefinition) {
    execUpdate(id = id) {
        insertOrUpdate(it, memberDefinition)
    }
}

private fun MemberEntities.insertOrUpdate(
    it: UpdateBuilder<Number>,
    memberDefinition: MemberRepository.MemberDefinition
) {
    it[email] = memberDefinition.email
    it[password] = memberDefinition.password
    it[displayName] = memberDefinition.displayName
    it[introduce] = memberDefinition.introduce
    it[profileDog] = memberDefinition.profileDog.name
    it[role] = memberDefinition.role.name
    it[status] = memberDefinition.status.name
}

execInsert and execUpdate are custom transaction {} wrapper that i created.

If you want to automate this, i think you can create a class that makes dsl with reflection.

However, I think that exposed is a light-weight DSL/DAO.

I wish this was supported too, but It seems difficult. So I using Spring Framework, and expecting spring-data-exposed to appear and support it 😅

Does anyone else have any good ideas?

@Im-Fran
Copy link
Author

Im-Fran commented May 19, 2022

Your solution seems to be a good one, but yeah, it would be nice if it came with the API :p

@bog-walk bog-walk self-assigned this May 16, 2023
@bog-walk bog-walk linked a pull request May 20, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants