-
-
Notifications
You must be signed in to change notification settings - Fork 154
Adding insert or update retrieving pgsql #233
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
Adding insert or update retrieving pgsql #233
Conversation
@vincentlauvlwj it seems the test failed because travis was not able to launch the database container (unrelated to the code I've changed)? Do you have an option to re-run the checks on your side @vincentlauvlwj ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for my late response, I made some comment on your code, can your check them?
* @property updateAssignments the updated column assignments while key conflict exists. | ||
* @property returningColumns the columns to returning. | ||
*/ | ||
public data class BulkInsertReturningExpression( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to create a new expression type? We already have BulkInsertExpression
, we can make the change on it. What's your opinion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I recall correctly, the reason why I did a new method is because its return
type is different, and it would make a breakable change. Also, returning has a performance overhead that you might not want to have as default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, we can create a new method, we have to do that in this way because backward compatibility is important. What I mean is they can share the same expression class, we just need to add returningColumns
to BulkInsertExpression
, with a default value emptyList()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll try to make this change when I have time!
* @property updateAssignments the updated column assignments while any key conflict exists. | ||
* @property returningColumns the columns to returning. | ||
*/ | ||
public data class InsertOrUpdateReturningColumnsExpression( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can make change on InsertOrUpdateExpression
.
*/ | ||
public fun <T : BaseTable<*>> Database.bulkInsertReturning( | ||
table: T, block: BulkInsertReturningStatementBuilder<T>.(T) -> Unit | ||
): Pair<Int, CachedRowSet> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it is a good practice to return a CachedRowSet
, as users have to obtain result values by column name, which is unsafe without strong type and static compiler checking.
Is it possible to return a List<TupleN<C1, C2>>
? It will be a great convenience as we can use the function like this:
val results = database.bulkInsertReturning(Employees) {
// ...
returning(
it.id,
it.job
)
}
for ((id, job) in results) {
println(id)
println(job)
}
BTW, if we just return one column returning(it.id)
, the return type can be List<C>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry @vincentlauvlwj I am confused on this one.
Do you have another function that implements this so I can see how you do it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried writing some pseudo code, the implementation might look like:
fun <T : BaseTable<*>, R1 : Any, R2 : Any> Database.bulkInsertReturning(
table: T, returning: Pair<Column<R1>, Column<R2>>, block: BulkInsertStatementBuilder<T>.(T) -> Unit
): List<Pair<R1?, R2?>> {
val expression = ....
val (_, rowSet) = executeUpdateAndRetrieveKeys(expression)
val (r1, r2) = returning
return rowSet.asIterable().map { row ->
Pair(
r1.sqlType.getResult(row, 1),
r2.sqlType.getResult(row, 2)
)
}
}
Then the usage should be:
val listOfIdAndJob = database.bulkInsertReturning(Employees, returning = Pair(Employees.id, Employees.job)) {
item {
....
}
}
for ((id, job) in listOfIdAndJob) {
println(id)
println(job)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But in this way, we need to add some overloaded version of bulkInsertReturning
function. Maybe 3 is enough, they respectively return:
List<R?>
List<Pair<R1?, R2?>>
List<Triple<R1?, R2?, R3?>>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll take a look into this, thank you for the examples.
@vincentlauvlwj I just did these modifications. |
Adding documentation
Ready! |
Merged, will release in next version. |
Hi @vincentlauvlwj !
These functions will allow upserts and bulk upserts to be more efficient in PostgreSQL when the developer wants to upsert and receive the created/existing ID or any other column.
Adding RETURNING support for in all Insert, Bulk Insert, Insert or Update and Bulk Insert or Update operations.
Eg.: