Kitura / Swift-Kuery

SQL database abstraction layer
Apache License 2.0
426 stars 41 forks source link

Support efficient multi row inserts/updates #60

Open na-gupta opened 7 years ago

na-gupta commented 7 years ago

Could we add Connection APIs to take multiple parameter sets as follows:

func execute(query: Query, parametersArray: [[Any?]], onCompletion: @escaping ((QueryResult) -> ()))

func execute(query: Query, parametersArray: [[String: Any?]], onCompletion: @escaping ((QueryResult) -> ()))

func execute(_ raw: String, parametersArray: [[Any?]], onCompletion: @escaping ((QueryResult) -> ()))

func execute(_ raw: String, parametersArray: [[String: Any?]], onCompletion: @escaping ((QueryResult) -> ()))

This will let us do more efficient prepared statement inserts/updates/deletes where we prepare the statement once, and execute it multiple times using different bindings.

Perhaps we only support this for inserts/updates/deletes and not for selects?

We could support selects as well, but that will need changes to QueryResult and ResultSet to be able to return multiple results, and may be more messy than it's worth.

irar2 commented 7 years ago

We can return an array of QueryResult for these functions, i.e. for example:

func execute(_ raw: String, parametersArray: [[String: Any?]], onCompletion: @escaping (([QueryResult]) -> ()))
irar2 commented 7 years ago

Since we work asynchronously, there is a problem with running one query after another without waiting for the results of the previous query being read completely. We probably need a somewhat complicated loop with callback to avoid this situation. Which makes me wonder if we should support this. There is no problem with inserting multiple rows in one query, we have a couple of APIs for that. And update is multirow by its nature. @na-gupta What do you think?

na-gupta commented 7 years ago

@irar2 I think the primary real-life use-case for this is for multi row inserts. Like you noted, we currently have that, but not with prepared statements for users who need to use that to counter SQL injection. I agree doing it for selects can get complicated, and also may not be useful to anyone.

Perhaps it's best to put this on the backlog till someone actually requests it?