Skip to content

Conversation

zamderax
Copy link

@zamderax zamderax commented Oct 15, 2025

  • Adds practical DocC examples for PostgresPreparedStatement and demonstrates usage with .query and .withTransaction.
  • Added more PostgresCodable docs with minimal SQL schemas for each code snippet so readers know exactly what tables/columns are expected.
  • Fixes an integration test to use tuple decoding for multi‑column rows:
  • Sources/PostgresNIO/Docs.docc/prepared-statement.md: New end‑to‑end examples
    • Define InsertUser and LoadUser prepared statements
    • Mix prepared statements with regular .query calls
    • Use inside withTransaction for atomic sequences
  • Added a new Sources/PostgresNIO/Docs.docc/postgres-codable.md: Add inline SQL schema hints for the examples
    • Shows examples of User codable, Company (JSONB), location (POINT), and enum/raw‑value examples
  • Tests/IntegrationTests/PostgresCodableTests.swift: Decode multi‑column rows via tuple and then construct the model (avoids unsupported direct struct decoding)

- Added a new section on manual query construction using `PostgresBindings` in the README.md.
- Introduced a new `PostgresCodable` documentation file detailing how to encode and decode custom Swift types.
- Enhanced the `PostgresQuery` documentation with examples of string interpolation and dynamic query building.
- Updated `.gitignore` to include `.derivedData`.
- Added integration tests for JSONB encoding and decoding functionality in `PostgresClientTests.swift`.
- Updated `decode` methods in `PostgresRandomAccessRow` to be public for better accessibility.
- Modified documentation examples to utilize `makeRandomAccess()` for decoding rows, ensuring consistency and clarity.
- Added new examples demonstrating the use of Codable structs with JSONB in the documentation.
- Introduced integration tests for JSONB encoding/decoding functionality, validating the round-trip of nested Codable structs.
…ansaction; tests: decode multi-column rows via tuple in PostgresCodable test
Copy link
Member

@gwynne gwynne left a comment

Choose a reason for hiding this comment

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

Several initial nits. I haven't bothered including notes on every single line where double-backticks were missing or - Note:-style callouts were used instead of > Note:, it'd take me a lot longer to do that in the PR interface than it'd take anyone to just fix it in Xcode or such.

/// - Throws: The error of the decoding implementation. See also `PSQLDecodable` protocol for this.
/// - Returns: The decoded value of Type T.
func decode<T: PostgresDecodable, JSONDecoder: PostgresJSONDecoder>(
public func decode<T: PostgresDecodable, JSONDecoder: PostgresJSONDecoder>(
Copy link
Member

Choose a reason for hiding this comment

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

Why?

/// - Throws: The error of the decoding implementation. See also `PSQLDecodable` protocol for this.
/// - Returns: The decoded value of Type T.
func decode<T: PostgresDecodable, JSONDecoder: PostgresJSONDecoder>(
public func decode<T: PostgresDecodable, JSONDecoder: PostgresJSONDecoder>(
Copy link
Member

Choose a reason for hiding this comment

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

Why?

/// }
/// ```
///
/// - Note: `PostgresNonThrowingEncodable` is a variant that doesn't throw, allowing usage without `try`.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// - Note: `PostgresNonThrowingEncodable` is a variant that doesn't throw, allowing usage without `try`.
/// > Note: ``PostgresNonThrowingEncodable`` is a variant that doesn't throw, allowing usage without `try`.

/// A type that can decode itself from a postgres wire binary representation.
///
/// If you want to conform a type to PostgresDecodable you must implement the decode method.
/// Conform your custom types to `PostgresDecodable` to enable them to be decoded from query results.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// Conform your custom types to `PostgresDecodable` to enable them to be decoded from query results.
/// Conform your custom types to ``PostgresDecodable`` to enable them to be decoded from query results.

///
/// ## Conforming Built-in Types
///
/// Many standard Swift types already conform to `PostgresDecodable`:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// Many standard Swift types already conform to `PostgresDecodable`:
/// Many standard Swift types already conform to ``PostgresDecodable``:

/// // Returns nil if the database value is NULL
/// ```
///
/// - Note: The `_DecodableType` associated type is an implementation detail for Optional handling.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// - Note: The `_DecodableType` associated type is an implementation detail for Optional handling.
/// > Note: The `_DecodableType` associated type is an implementation detail for `Optional` handling.

Comment on lines 187 to 188
/// - Note: String interpolation is the recommended approach for simple queries as it automatically handles parameter counting and binding.
/// - Warning: Always use parameter binding for user input. Never concatenate user input directly into SQL strings.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// - Note: String interpolation is the recommended approach for simple queries as it automatically handles parameter counting and binding.
/// - Warning: Always use parameter binding for user input. Never concatenate user input directly into SQL strings.
/// > Note: String interpolation is the recommended approach for simple queries as it automatically handles parameter counting and binding.
///
/// > Warning: Always use parameter binding for user input. Never concatenate user input directly into SQL strings.

Comment on lines 189 to 190
/// - SeeAlso: `PostgresBindings` for more details on manual binding construction.
/// - SeeAlso: `PostgresClient` for connection pool management and query execution.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// - SeeAlso: `PostgresBindings` for more details on manual binding construction.
/// - SeeAlso: `PostgresClient` for connection pool management and query execution.
/// - SeeAlso: ``PostgresBindings`` for more details on manual binding construction.
/// - SeeAlso: ``PostgresClient`` for connection pool management and query execution.

.gitignore Outdated
Package.resolved
.swiftpm
Tests/LinuxMain.swift
.derivedData
Copy link
Member

Choose a reason for hiding this comment

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

Why?

Copy link
Author

Choose a reason for hiding this comment

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

This was an accident as I was unable to use DocC to break a cache. I will remove it.

Comment on lines 83 to 91
var tlsConfiguration = TLSConfiguration.makeClientConfiguration()
tlsConfiguration.certificateVerification = .none
var clientConfig = PostgresClient.Configuration(
host: env("POSTGRES_HOSTNAME") ?? "localhost",
port: env("POSTGRES_PORT").flatMap({ Int($0) }) ?? 5432,
username: env("POSTGRES_USER") ?? "test_username",
password: env("POSTGRES_PASSWORD") ?? "test_password",
database: env("POSTGRES_DB") ?? "test_database",
tls: .prefer(tlsConfiguration)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
var tlsConfiguration = TLSConfiguration.makeClientConfiguration()
tlsConfiguration.certificateVerification = .none
var clientConfig = PostgresClient.Configuration(
host: env("POSTGRES_HOSTNAME") ?? "localhost",
port: env("POSTGRES_PORT").flatMap({ Int($0) }) ?? 5432,
username: env("POSTGRES_USER") ?? "test_username",
password: env("POSTGRES_PASSWORD") ?? "test_password",
database: env("POSTGRES_DB") ?? "test_database",
tls: .prefer(tlsConfiguration)
var clientConfig = PostgresClient.Configuration(
host: env("POSTGRES_HOSTNAME") ?? "localhost",
port: env("POSTGRES_PORT").flatMap({ Int($0) }) ?? 5432,
username: env("POSTGRES_USER") ?? "test_username",
password: env("POSTGRES_PASSWORD") ?? "test_password",
database: env("POSTGRES_DB") ?? "test_database",
tls: .disable

Don't encourage people to disable certificate verification. Match the existing test configuration by disabling TLS.

@zamderax
Copy link
Author

Great I made a bunch of commits to address these.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants