PostgresNIO Documentation

repository·main·Indexed 19 days ago

https://github.com/vapor/postgres-nio

A non-blocking, event-driven Swift client for PostgreSQL built on SwiftNIO. It provides an async/await interface for connection pooling via PostgresClient, direct connection management via PostgresConnection, and automatic type conversion using PostgresEncodable and PostgresDecodable protocols. Features include safe parameterized queries via string interpolation, JSON support through PostgresJSONEncoder/Decoder, and integration with PostgreSQL's Listen & Notify API.

Tokens
3.8K
Snippets
10
Records
24
Agent score
65%

What's inside PostgresNIO

  1. Overview of PostgresNIO

    main
    PostgresNIO is a non-blocking, event-driven Swift client for PostgreSQL built on SwiftNIO. It provides the ability to connect to, authorize with, query, and retrieve results from a PostgreSQL server. It is designed to run efficiently on both Linux and Apple platforms, with support for Network.framework as the underlying transport on Apple platforms.
  2. Decode entire rows as tuples for maximum performance

    main

    For the best performance when consuming PostgresRow results, avoid individual column lookups entirely. Instead, decode the entire row into a Swift tuple in a single operation. This bypasses the need for any cell lookup mechanism and is the most efficient way to process query results.

    connection.query("SELECT id, name, email, age FROM users").whenComplete { result in
        if case .success(let result) = result {
            for row in result.rows {
                // Decode the whole row into a tuple at once
                let (id, name, email, age) = try row.decode((UUID, String, String, Int).self)
                // do further processing
            }
        }
    }
  3. Core protocols for PostgreSQL data translation

    main

    The following types and protocols form the foundation of data translation in PostgresNIO:

    • PostgresCodable: The primary protocol for types that can be both encoded to and decoded from PostgreSQL.
    • PostgresDataType: Represents the specific PostgreSQL data type being used.
    • PostgresFormat: Defines the format used for data representation.
    • PostgresNumeric: Specifically handles numeric data translations.
  4. Understand the deprecation policy of PostgresNIO

    main

    PostgresNIO follows Semantic Versioning (SemVer) 2.0.0. Many existing APIs are being deprecated in favor of modern Swift patterns, specifically those embracing structured concurrency.

    Important: All APIs listed as deprecated will be removed in the next major version release. It is recommended to migrate away from these APIs as soon as possible to ensure future compatibility.

  5. Decoding PostgreSQL data into Swift types

    main

    To read data from PostgreSQL into Swift, use the decoding protocols:

    • PostgresDecodable: The standard decoding protocol.
    • PostgresArrayDecodable: For decoding PostgreSQL arrays into Swift arrays.
    • PostgresRangeDecodable and PostgresRangeArrayDecodable: For decoding PostgreSQL ranges and arrays of ranges.
    • PostgresDecodingContext: Provides metadata and configuration during the decoding process.
  6. How PostgreSQL Listen & Notify works

    main

    PostgreSQL provides a simple Publish/Subscribe (Pub/Sub) messaging system using NOTIFY, LISTEN, and UNLISTEN commands.

    • Channels: The core concept is a named channel. Clients can both publish to and subscribe to these channels.
    • Persistence: Channels are not persisted. If a notification is published to a channel that currently has no active subscribers, the notification is discarded and cannot be retrieved later.
    • Lifecycle: In PostgresNIO, listening is scoped to the lifetime of the provided closure in listen(on:consume:).
  7. How to choose between PostgresClient and PostgresConnection

    main

    PostgresNIO provides two primary ways to interact with the database depending on your management needs:

    1. PostgresClient: Recommended for most developers. It manages a pool of connections for rapid reuse and hides the complexities of connection management. It implements the Service protocol from Swift Service Lifecycle, making it easy to integrate into Swift server applications. Use this if you want to focus on SQL queries without manually managing connection lifecycles.

    2. PostgresConnection: Use this if you need direct control over a single connection. It allows you to run queries, prepared statements, and utilize PostgreSQL's Listen & Notify API directly. Use this if you need to manage the connection lifecycle yourself.

  8. How safe parameterized queries work with string interpolation

    main

    PostgresNIO provides a safe way to use Swift string interpolation in queries. The query(_:logger:) method accepts a PostgresQuery (via ExpressibleByStringInterpolation), which automatically converts interpolated values into safe parameter bindings rather than raw string concatenation. This prevents SQL injection. Only types implementing PostgresEncodable can be interpolated.

    let id = 1
    let username = "fancyuser"
    let birthday = Date()
    
    try await client.query("""
      INSERT INTO users (id, username, birthday) VALUES (\(id), \(username), \(birthday))
      ""
    ) 
  9. Encoding Swift types to PostgreSQL

    main

    To send Swift data to PostgreSQL, use the encoding protocols. Depending on your requirements for error handling and dynamic typing, you can use:

    • PostgresEncodable: The standard encoding protocol.
    • PostgresNonThrowingEncodable: For encoding that is guaranteed not to throw errors.
    • PostgresDynamicTypeEncodable and PostgresThrowingDynamicTypeEncodable: For types where the PostgreSQL type is determined dynamically during encoding.
    • PostgresArrayEncodable: For encoding Swift arrays to PostgreSQL arrays.
    • PostgresRangeEncodable and PostgresRangeArrayEncodable: For encoding Swift ranges and arrays of ranges.
    • PostgresEncodingContext: Provides metadata and configuration during the encoding process.