Skip to content

Conversation

@tbartelmess
Copy link
Contributor

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.

@tanner0101 tanner0101 added the enhancement New feature or request label Mar 12, 2019
Copy link
Member

@tanner0101 tanner0101 left a 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]]>

@tbartelmess
Copy link
Contributor Author

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.

@tanner0101
Copy link
Member

Any updates on this one?

@tbartelmess
Copy link
Contributor Author

@tanner0101 sorry I thought I pushed this a long time ago, I'll get this fixed up tonight.

@tbartelmess tbartelmess force-pushed the prepared-statements branch 2 times, most recently from 14b8f8b to c97a2fd Compare December 17, 2019 01:02
@tbartelmess tbartelmess marked this pull request as ready for review December 17, 2019 02:17
Copy link
Member

@tanner0101 tanner0101 left a 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 {

Copy link
Member

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]]> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spacing here.

let conn = try PostgresConnection.test(on: eventLoop).wait()

defer { try! conn.close().wait() }
let prepared = try conn.prepare(query: "SELECT 1 as one;").wait()
Copy link
Member

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.

Copy link
Contributor Author

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
}

public func deallocate() -> EventLoopFuture<Void> {
return database.query("DEALLOCATE \"\(name)\"").map { _ in }
Copy link
Member

@tanner0101 tanner0101 Mar 19, 2020

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.

Copy link
Contributor Author

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.

@tbartelmess tbartelmess requested a review from tanner0101 March 22, 2020 22:24
@tanner0101 tanner0101 changed the base branch from master to gm April 21, 2020 18:37
Copy link
Member

@tanner0101 tanner0101 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@tanner0101 tanner0101 merged commit a63827f into vapor:gm Apr 21, 2020
@tbartelmess tbartelmess deleted the prepared-statements branch April 21, 2020 19:10
tanner0101 added a commit that referenced this pull request Apr 22, 2020
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants