I have the following method that actually updates the database row against a table. It first checks for an entry if it exists with a certain condition and only if it exists, it updates the corresponding row. So effectively, there are two calls being made to the database. I would like to avoid having two calls sent to the database. So here is the code:
def confirmUserRegistration(hash: String) = async {
val query = UserRegistrationTable.registrationForHash(hash)
val isRowAvailable = await(database.run(query.result.headOption))
if (isRowAvailable.isDefined) {
// do the update
} else {
// do nothing and return
}
}
The UserRegistrationTable.registrationForHash(hash) query looks like this:
object UserRegistrationTable {
val all = TableQuery[UserRegistrationTable]
val registrationForHash = (hash: String) => {
all.filter(_.registrationHash === hash)
}
}
So how can I optimize my service to issue only one call to the database?
EDIT: Updated with the feedback given by the post below:
Here is how my method looks:
def confirmUserRegistration(hash: String) = async {
val query = {
UserRegistrationTable.registrationForHash(hash)
.map(_.hasUserConfirmed)
.update(true)
}
val isUpdated: Int = await(database.run(query))
}
Just use the following update:
val updateOperation: DBIO[Int] = all
.filter(_.registrationHash === hash)
.map(u => (u.field1, u.field2, u.field3))
.update((newValue1, newValue2, newValue3))
Notice that updateResult
above is DBIO
containing Int
- being the number of updated rows.
So you can do:
db.run(updateOperation).map { updatedRows =>
if(updatedRows >= 0) {
// at least one row was affected, return something here
} else {
// nothing got updated, return something here
}
}
In case you wanted to updated whole row you could use your case class but I doubt that is what you want:
val userRegistration: UserRegistrationCaseClass = ...
val updateOperation: DBIO[Int] = all
.filter(_.registrationHash === hash)
.update(newUserRegistration)