vapor / postgres-nio

🐘 Non-blocking, event-driven Swift client for PostgreSQL.
https://api.vapor.codes/postgresnio/documentation/postgresnio/
MIT License
317 stars 72 forks source link

async/await prepared statement API #390

Closed mariosangiorgio closed 1 year ago

mariosangiorgio commented 1 year ago

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 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)")
}
fabianfett commented 1 year ago

Fixes #385

codecov-commenter commented 1 year ago

Codecov Report

Merging #390 (da87ce0) into main (5217ba7) will increase coverage by 1.44%. The diff coverage is 83.33%.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #390 +/- ## ========================================== + Coverage 47.53% 48.98% +1.44% ========================================== Files 109 110 +1 Lines 8764 8954 +190 ========================================== + Hits 4166 4386 +220 + Misses 4598 4568 -30 ``` | [Files Changed](https://app.codecov.io/gh/vapor/postgres-nio/pull/390?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vapor) | Coverage Δ | | |---|---|---| | [Sources/PostgresNIO/New/PostgresQuery.swift](https://app.codecov.io/gh/vapor/postgres-nio/pull/390?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vapor#diff-U291cmNlcy9Qb3N0Z3Jlc05JTy9OZXcvUG9zdGdyZXNRdWVyeS5zd2lmdA==) | `81.29% <0.00%> (+2.77%)` | :arrow_up: | | [...es/PostgresNIO/Connection/PostgresConnection.swift](https://app.codecov.io/gh/vapor/postgres-nio/pull/390?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vapor#diff-U291cmNlcy9Qb3N0Z3Jlc05JTy9Db25uZWN0aW9uL1Bvc3RncmVzQ29ubmVjdGlvbi5zd2lmdA==) | `42.35% <52.08%> (+1.23%)` | :arrow_up: | | [... State Machine/PreparedStatementStateMachine.swift](https://app.codecov.io/gh/vapor/postgres-nio/pull/390?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vapor#diff-U291cmNlcy9Qb3N0Z3Jlc05JTy9OZXcvQ29ubmVjdGlvbiBTdGF0ZSBNYWNoaW5lL1ByZXBhcmVkU3RhdGVtZW50U3RhdGVNYWNoaW5lLnN3aWZ0) | `91.83% <91.83%> (ø)` | | | [...urces/PostgresNIO/New/PostgresChannelHandler.swift](https://app.codecov.io/gh/vapor/postgres-nio/pull/390?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vapor#diff-U291cmNlcy9Qb3N0Z3Jlc05JTy9OZXcvUG9zdGdyZXNDaGFubmVsSGFuZGxlci5zd2lmdA==) | `84.45% <98.82%> (+6.23%)` | :arrow_up: | | [Sources/PostgresNIO/New/PSQLTask.swift](https://app.codecov.io/gh/vapor/postgres-nio/pull/390?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vapor#diff-U291cmNlcy9Qb3N0Z3Jlc05JTy9OZXcvUFNRTFRhc2suc3dpZnQ=) | `78.12% <100.00%> (+16.58%)` | :arrow_up: | ... and [6 files with indirect coverage changes](https://app.codecov.io/gh/vapor/postgres-nio/pull/390/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vapor)