Skip to content
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

PreparedStatement use with optional parameters #509

Open
duncangroenewald opened this issue Sep 21, 2024 · 3 comments
Open

PreparedStatement use with optional parameters #509

duncangroenewald opened this issue Sep 21, 2024 · 3 comments
Labels
documentation Issues/PRs related to documentation enhancement New feature or request good first issue Good for newcomers

Comments

@duncangroenewald
Copy link

Some explanation of how to set bindings for optional values in a prepared statement would be helpful. It seems you can't set binding is the property is optional. If so how do you set the property (column) to NULL in a prepared statement if that is even possible.

I could find no example of such a scenario.

Thanks

@duncangroenewald duncangroenewald added the enhancement New feature or request label Sep 21, 2024
@fabianfett fabianfett added the documentation Issues/PRs related to documentation label Oct 4, 2024
@rgcottrell
Copy link
Contributor

I was able to create bindings to optional properties in a PostgresPreparedStatement by creating an extension to PostgresBindings. I was then able to verify that NULL values were inserted into the database.

extension PostgresBindings {
    public mutating func append<Value: PostgresDynamicTypeEncodable>(_ value: Optional<Value>) {
        switch value {
        case .some(let value):
            append(value)
        case .none:
            appendNull()
        }
    }
}

With the extension in place, you can then construct a prepared statement the way you would expect. Here is an example of how that might look:

struct InsertStatement: PostgresPreparedStatement {
    static let sql = "INSERT INTO mytable (id, value) VALUES ($1, $2)"

    var id: UUID
    var value: String?

    func makeBindings() -> PostgresBindings {
        var bindings = PostgresBindings(capacity: 2)
        bindings.append(id)
        bindings.append(value)
        return bindings
    }

    func decodeRow(_ row: PostgresRow) {}
}

A downside of creating the extension in my own code is that it is unavailable to the PostgresNIOMacros package. As a result I have to create the prepared statement by hand, which involves a lot more boilerplate and chance for errors.

@fabianfett
Copy link
Collaborator

cc @lovetodream.

@rgcottrell would you be interested in providing a patch to fix this in PostgresNIO directly?

@fabianfett fabianfett added the good first issue Good for newcomers label Oct 14, 2024
@rgcottrell
Copy link
Contributor

@fabianfett Sure, I can take a look at putting together a patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Issues/PRs related to documentation enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants