This PR adds a new PreparedStatement protocol to represent prepared statements and an execute function on PostgresConnection to prepare and execute statements.
To implement the features the PR also introduces a PreparedStatementStateMachine that keeps track of the state of a prepared statement at the connection level. This ensures that, for each connection, each statement is prepared once at time of first use and then subsequent uses are going to skip the preparation step and just execute it.
Example usage
First define the struct to represent the prepared statement:
struct ExamplePreparedStatement: PreparedStatement {
static var sql = "SELECT pid, datname FROM pg_stat_activity WHERE state = $1"
typealias Row = (Int, String)
var state: String
func makeBindings() -> PostgresBindings {
var bindings = PostgresBindings()
bindings.append(.init(string: self.state))
return bindings
}
func decodeRow(_ row: PostgresNIO.PostgresRow) throws -> Row {
try row.decode(Row.self)
}
}
then, assuming you already have a PostgresConnection you can execute it:
let preparedStatement = ExamplePreparedStatement(state: "active")
let results = try await connection.execute(preparedStatement, logger: logger)
for (pid, database) in results {
print("PID: \(pid), database: \(database)")
}
Implementation of async/await API for prepared statements (See also https://github.com/vapor/postgres-nio/issues/385).
This PR adds a new
PreparedStatement
protocol to represent prepared statements and anexecute
function onPostgresConnection
to prepare and execute statements.To implement the features the PR also introduces a
PreparedStatementStateMachine
that keeps track of the state of a prepared statement at the connection level. This ensures that, for each connection, each statement is prepared once at time of first use and then subsequent uses are going to skip the preparation step and just execute it.Example usage
First define the struct to represent the prepared statement:
then, assuming you already have a
PostgresConnection
you can execute it: