-
-
Notifications
You must be signed in to change notification settings - Fork 90
Prepared Statement API #15
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
Conversation
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.
Really nice work on this 👍
One nice addition to this could be a closure-based method that automatically frees the prepared query when done.
let res = db.prepare("SELECT ? as foo") { query in
let a = query.execute("a")
let b = query.execute("b")
let c = query.execute("c")
return .whenAllSucceed([a, b, c], on: db.eventLoop)
}
print(res) // ELFuture<[[PostgresRow]]>|
Hi @tanner0101, Yeah I still thinking about nicer ways to deal with the lifecycle of a prepared statement. However I am probably not getting back to this before early next week. |
|
Any updates on this one? |
|
@tanner0101 sorry I thought I pushed this a long time ago, I'll get this fixed up tonight. |
14b8f8b to
c97a2fd
Compare
tanner0101
left a comment
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.
Thanks for the updates! Sorry this one slipped through my feed. Just some minor nits then this is good to go 👍
| import Foundation | ||
|
|
||
| extension PostgresDatabase { | ||
|
|
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.
Extra line.
| } | ||
| } | ||
|
|
||
| public func prepare(query: String, handler: @escaping (PreparedQuery)->EventLoopFuture<[[PostgresRow]]>)->EventLoopFuture<[[PostgresRow]]> { |
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.
Spacing here.
Sources/PostgresNIO/Connection/PostgresDatabase+PreparedQuery.swift
Outdated
Show resolved
Hide resolved
Sources/PostgresNIO/Connection/PostgresDatabase+PreparedQuery.swift
Outdated
Show resolved
Hide resolved
Sources/PostgresNIO/Connection/PostgresDatabase+PreparedQuery.swift
Outdated
Show resolved
Hide resolved
| let conn = try PostgresConnection.test(on: eventLoop).wait() | ||
|
|
||
| defer { try! conn.close().wait() } | ||
| let prepared = try conn.prepare(query: "SELECT 1 as one;").wait() |
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 this missing a deallocate for the prepared query? Maybe we should add an assertion to make sure it gets deallocated.
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.
A query doesn't need to get deallocated, because the session is closed by the end of this test.
Maybe deallocate is a bad name here because in most cases it refers to memory.
# Conflicts: # Sources/PostgresNIO/Connection/PostgresDatabase+PreparedQuery.swift # Tests/NIOPostgresTests/NIOPostgresTests.swift
# Conflicts: # Tests/NIOPostgresTests/NIOPostgresTests.swift
f42e377 to
14d2ca2
Compare
| } | ||
|
|
||
| public func deallocate() -> EventLoopFuture<Void> { | ||
| return database.query("DEALLOCATE \"\(name)\"").map { _ in } |
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 think this should be done using the special close message instead of a separate query. This can be added similar to other PostgresMessage+... types.
From: https://www.postgresql.org/docs/9.3/protocol-flow.html
The Close message closes an existing prepared statement or portal and releases resources. It is not an error to issue Close against a nonexistent statement or portal name. The response is normally CloseComplete, but could be ErrorResponse if some difficulty is encountered while releasing resources. Note that closing a prepared statement implicitly closes any open portals that were constructed from that statement.
From: https://www.postgresql.org/docs/9.3/protocol-message-formats.html
Close (F)
Byte1('C')
Identifies the message as a Close command.
Int32
Length of message contents in bytes, including self.
Byte1
'S' to close a prepared statement; or 'P' to close a portal.
String
The name of the prepared statement or portal to close (an empty string selects the unnamed prepared statement or portal).
CloseComplete (B)
Byte1('3')
Identifies the message as a Close-complete indicator.
Int32(4)
Length of message contents in bytes, including self.
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.
Yeah, good point, fixed in the last commit.
tanner0101
left a comment
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.
Thanks!
* update docs * update versions * add explicit check for binary for array encoding, #92 * Prepared Statement API (#15) * Added an API for prepared queries # Conflicts: # Sources/PostgresNIO/Connection/PostgresDatabase+PreparedQuery.swift # Tests/NIOPostgresTests/NIOPostgresTests.swift * Updated testPreparedQuery to close the connection # Conflicts: # Tests/NIOPostgresTests/NIOPostgresTests.swift * Added a DEALLOCATE api * Added a closure based API * Implemented log(to:) * Made prepared query a strcut * Spacing fixes * Implement 'Close' command for prepared statements * copy data row column slice (#96) * copy data row column slice * fix double read Co-authored-by: Thomas Bartelmess <tbartelmess@marketcircle.com>
This is still a work in progress, there should be more code-sharing between the "normal" query and prepared queries.
It also still lacks an API to deallocate queries, and a more comprehensive test suite.