Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ jobs:
POSTGRES_HOST_AUTH_METHOD: ${{ matrix.postgres-auth }}
POSTGRES_INITDB_ARGS: --auth-host=${{ matrix.postgres-auth }}
steps:
- name: Install curl
run: apt-get update -y -q && apt-get install -y curl
- name: Check out package
uses: actions/checkout@v5
- name: Run local tests
Expand Down Expand Up @@ -133,7 +135,7 @@ jobs:
run: |
brew upgrade || true
export PATH="$(brew --prefix)/opt/postgresql@13/bin:$PATH" PGDATA=/tmp/vapor-postgres-test
(brew unlink postgresql@14 || true) && brew install "postgresql@13" && brew link --force "postgresql@13"
brew install "postgresql@17" && brew link --force "postgresql@17"
initdb --locale=C --auth-host "scram-sha-256" -U "${POSTGRES_USER}" --pwfile=<(echo "${POSTGRES_PASSWORD}")
pg_ctl start --wait
timeout-minutes: 15
Expand Down
9 changes: 5 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.9
// swift-tools-version:5.10
import PackageDescription

let package = Package(
Expand All @@ -13,9 +13,9 @@ let package = Package(
.library(name: "PostgresKit", targets: ["PostgresKit"]),
],
dependencies: [
.package(url: "https://github.com/vapor/postgres-nio.git", from: "1.21.1"),
.package(url: "https://github.com/vapor/sql-kit.git", from: "3.29.3"),
.package(url: "https://github.com/vapor/async-kit.git", from: "1.19.0"),
.package(url: "https://github.com/vapor/postgres-nio.git", from: "1.27.0"),
.package(url: "https://github.com/vapor/sql-kit.git", from: "3.33.1"),
.package(url: "https://github.com/vapor/async-kit.git", from: "1.21.0"),
],
targets: [
.target(
Expand All @@ -40,6 +40,7 @@ let package = Package(

var swiftSettings: [SwiftSetting] { [
.enableUpcomingFeature("ExistentialAny"),
.enableUpcomingFeature("MemberImportVisibility"),
.enableUpcomingFeature("ConciseMagicFile"),
.enableUpcomingFeature("ForwardTrailingClosures"),
.enableUpcomingFeature("DisableOutwardActorInference"),
Expand Down
66 changes: 32 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/vapor/postgres-kit/assets/1130717/02ca33b1-d788-4846-8280-7cd89f09c397">
<source media="(prefers-color-scheme: light)" srcset="https://github.com/vapor/postgres-kit/assets/1130717/91de055b-0e4f-42f3-8257-946ac40d731c">
<img src="https://github.com/vapor/postgres-kit/assets/1130717/91de055b-0e4f-42f3-8257-946ac40d731c" height="96" alt="PostgresKit">
</picture>
<img src="https://design.vapor.codes/images/vapor-postgreskit.svg" height="96" alt="PostgresKit">
<br>
<br>
<a href="https://docs.vapor.codes/4.0/"><img src="https://design.vapor.codes/images/readthedocs.svg" alt="Documentation"></a>
<a href="https://discord.gg/vapor"><img src="https://design.vapor.codes/images/discordchat.svg" alt="Team Chat"></a>
<a href="LICENSE"><img src="https://design.vapor.codes/images/mitlicense.svg" alt="MIT License"></a>
<a href="https://github.com/vapor/postgres-kit/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/vapor/postgres-kit/test.yml?event=push&style=plastic&logo=github&label=tests&logoColor=%23ccc" alt="Continuous Integration"></a>
<a href="https://codecov.io/github/vapor/postgres-kit"><img src="https://img.shields.io/codecov/c/github/vapor/postgres-kit?style=plastic&logo=codecov&label=codecov"></a>
<a href="https://swift.org"><img src="https://design.vapor.codes/images/swift59up.svg" alt="Swift 5.9+"></a>
<a href="https://swift.org"><img src="https://design.vapor.codes/images/swift510up.svg" alt="Swift 5.10+"></a>
</p>

<br>

🐘 Non-blocking, event-driven Swift client for PostgreSQL.
PostgresKit is an [SQLKit] driver for PostgreSQL clients.

## Overview

PostgresKit supports building and serializing Postgres-dialect SQL queries using [SQLKit]'s API. PostgresKit uses [PostgresNIO] to connect and communicate with the database server asynchronously. [AsyncKit] is used to provide connection pooling.

> Important: It is strongly recommended that users who leverage PostgresKit directly (e.g. absent the Fluent ORM layer) take advantage of PostgresNIO's [PostgresClient] API for connection management rather than relying upon the legacy AsyncKit API.

### Usage

Use the SPM string to easily include the dependendency in your `Package.swift` file.
Reference this package in your `Package.swift` to include it in your project.

```swift
.package(url: "https://github.com/vapor/postgres-kit.git", from: "2.0.0")
Expand All @@ -33,42 +35,30 @@ PostgresKit supports the following platforms:
- Ubuntu 20.04+
- macOS 10.15+

## Overview

PostgresKit is an [SQLKit] driver for PostgreSQL clients. It supports building and serializing Postgres-dialect SQL queries. PostgresKit uses [PostgresNIO] to connect and communicate with the database server asynchronously. [AsyncKit](https://github.com/vapor/async-kit) is used to provide connection pooling.

> [!IMPORTANT]
> It is strongly recommended that users who leverage PostgresKit directly (e.g. absent the Fluent ORM layer) take advantage of PostgresNIO's [PostgresClient] API for connection management rather than relying upon the legacy AsyncKit API.

[SQLKit]: https://github.com/vapor/sql-kit
[PostgresNIO]: https://github.com/vapor/postgres-nio
[AsyncKit]: https://github.com/vapor/async-kit
[PostgresClient]: https://api.vapor.codes/postgresnio/documentation/postgresnio/postgresclient

### Configuration

Database connection options and credentials are specified using a `PostgresConfiguration` struct.
Database connection options and credentials are specified using a ``SQLPostgresConfiguration`` struct.

```swift
import PostgresKit

let configuration = PostgresConfiguration(
let configuration = SQLPostgresConfiguration(
hostname: "localhost",
username: "vapor_username",
password: "vapor_password",
database: "vapor_database"
)
```

URL string based configuration is also supported.
URL-based configuration is also supported.

```swift
guard let configuration = PostgresConfiguration(url: "postgres://...") else {
guard let configuration = SQLPostgresConfiguration(url: "postgres://...") else {
...
}
```

To connect via unix-domain sockets, use `unixDomainSocketPath` instead of `hostname` and `port`.
To connect via unix-domain sockets, use ``SQLPostgresConfiguration/init(unixDomainSocketPath:username:password:database:)`` instead of ``SQLPostgresConfiguration/init(hostname:port:username:password:database:tls:)``.

```swift
let configuration = PostgresConfiguration(
Expand All @@ -81,22 +71,22 @@ let configuration = PostgresConfiguration(

### Connection Pool

Once you have a `PostgresConfiguration`, you can use it to create a connection source and pool.
Once you have a ``SQLPostgresConfiguration``, you can use it to create a connection source and pool.

```swift
let eventLoopGroup: EventLoopGroup = ...
defer { try! eventLoopGroup.syncShutdown() }

let eventLoopGroup: EventLoopGroup = NIOSingletons.posixEventLoopGroup
let pools = EventLoopGroupConnectionPool(
source: PostgresConnectionSource(configuration: configuration),
on: eventLoopGroup
)
defer { pools.shutdown() }

// When you're done:
try await pools.shutdownAsync()
```

First create a `PostgresConnectionSource` using the configuration struct. This type is responsible for creating new connections to your database server as needed.
First create a ``PostgresConnectionSource`` using the configuration struct. This type is responsible for creating new connections to your database server as needed.

Next, use the connection source to create an `EventLoopGroupConnectionPool`. You will also need to pass an `EventLoopGroup`. For more information on creating an `EventLoopGroup`, visit SwiftNIO's [documentation](https://apple.github.io/swift-nio/docs/current/NIO/index.html). Make sure to shutdown the connection pool before it deinitializes.
Next, use the connection source to create an `EventLoopGroupConnectionPool`. You will also need to pass an `EventLoopGroup`. For more information on creating an `EventLoopGroup`, visit [SwiftNIO's documentation]. Make sure to shutdown the connection pool before it deinitializes.

`EventLoopGroupConnectionPool` is a collection of pools for each event loop. When using `EventLoopGroupConnectionPool` directly, random event loops will be chosen as needed.

Expand Down Expand Up @@ -126,7 +116,7 @@ let postgres = pool.database(logger: ...) // PostgresDatabase
let rows = try postgres.simpleQuery("SELECT version();").wait()
```

Visit [PostgresNIO's docs](https://github.com/vapor/postgres-nio) for more information on using `PostgresDatabase`.
Visit [PostgresNIO's docs] for more information on using `PostgresDatabase`.

### SQLDatabase

Expand All @@ -137,4 +127,12 @@ let sql = postgres.sql() // SQLDatabase
let planets = try sql.select().column("*").from("planets").all().wait()
```

Visit [SQLKit's docs](https://github.com/vapor/sql-kit) for more information on using `SQLDatabase`.
Visit [SQLKit's docs] for more information on using `SQLDatabase`.

[SQLKit]: https://github.com/vapor/sql-kit
[SQLKit's docs]: https://api.vapor.codes/sqlkit/documentation/sqlkit
[PostgresNIO]: https://github.com/vapor/postgres-nio
[PostgresNIO's docs]: https://api.vapor.codes/postgresnio/documentation/postgresnio
[AsyncKit]: https://github.com/vapor/async-kit
[PostgresClient]: https://api.vapor.codes/postgresnio/documentation/postgresnio/postgresclient
[SwiftNIO's documentation]: https://swiftpackageindex.com/apple/swift-nio/documentation/nio
128 changes: 113 additions & 15 deletions Sources/PostgresKit/Docs.docc/PostgresKit.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,127 @@
@TitleHeading(Package)
}

PostgresKit is a library providing an SQLKit driver for PostgresNIO.
PostgresKit is an [SQLKit] driver for PostgreSQL clients.

## Overview

This package provides the "foundational" level of support for using [Fluent] with PostgreSQL by implementing the requirements of an [SQLKit] driver. It is responsible for:
PostgresKit supports building and serializing Postgres-dialect SQL queries using [SQLKit]'s API. PostgresKit uses [PostgresNIO] to connect and communicate with the database server asynchronously. [AsyncKit] is used to provide connection pooling.

- Managing the underlying PostgreSQL library ([PostgresNIO]),
- Providing a two-way bridge between PostgresNIO and SQLKit's generic data and metadata formats, and
- Presenting an interface for establishing, managing, and interacting with database connections via [AsyncKit].
> Important: It is strongly recommended that users who leverage PostgresKit directly (e.g. absent the Fluent ORM layer) take advantage of PostgresNIO's [PostgresClient] API for connection management rather than relying upon the legacy AsyncKit API.

> Important: It is strongly recommended that users who leverage PostgresKit directly (e.g. absent the Fluent ORM layer) take advantage of PostgresNIO's [PostgresClient] API for connection management rather than relying upon the legacy AsyncKit-based support.
### Usage

> Tip: A FluentKit driver for PostgreSQL is provided by the [FluentPostgresDriver] package.
Reference this package in your `Package.swift` to include it in your project.

## Version Support
```swift
.package(url: "https://github.com/vapor/postgres-kit.git", from: "2.0.0")
```

This package uses [PostgresNIO] for all underlying database interactions. It is compatible with all versions of PostgreSQL and all platforms supported by that package.
### Supported Platforms

> Caution: There is one exception to the above at the time of this writing: This package requires Swift 5.8 or newer, whereas PostgresNIO continues to support Swift 5.6.
PostgresKit supports the following platforms:

[SQLKit]: https://swiftpackageindex.com/vapor/sql-kit
[PostgresNIO]: https://swiftpackageindex.com/vapor/postgres-nio
[Fluent]: https://swiftpackageindex.com/vapor/fluent-kit
[FluentPostgresDriver]: https://swiftpackageindex.com/vapor/fluent-postgres-driver
[AsyncKit]: https://swiftpackageindex.com/vapor/async-kit
- Ubuntu 20.04+
- macOS 10.15+

### Configuration

Database connection options and credentials are specified using a ``SQLPostgresConfiguration`` struct.

```swift
import PostgresKit

let configuration = SQLPostgresConfiguration(
hostname: "localhost",
username: "vapor_username",
password: "vapor_password",
database: "vapor_database"
)
```

URL-based configuration is also supported.

```swift
guard let configuration = SQLPostgresConfiguration(url: "postgres://...") else {
...
}
```

To connect via unix-domain sockets, use ``SQLPostgresConfiguration/init(unixDomainSocketPath:username:password:database:)`` instead of ``SQLPostgresConfiguration/init(hostname:port:username:password:database:tls:)``.

```swift
let configuration = PostgresConfiguration(
unixDomainSocketPath: "/path/to/socket",
username: "vapor_username",
password: "vapor_password",
database: "vapor_database"
)
```

### Connection Pool

Once you have a ``SQLPostgresConfiguration``, you can use it to create a connection source and pool.

```swift
let eventLoopGroup: EventLoopGroup = NIOSingletons.posixEventLoopGroup
let pools = EventLoopGroupConnectionPool(
source: PostgresConnectionSource(configuration: configuration),
on: eventLoopGroup
)

// When you're done:
try await pools.shutdownAsync()
```

First create a ``PostgresConnectionSource`` using the configuration struct. This type is responsible for creating new connections to your database server as needed.

Next, use the connection source to create an `EventLoopGroupConnectionPool`. You will also need to pass an `EventLoopGroup`. For more information on creating an `EventLoopGroup`, visit [SwiftNIO's documentation]. Make sure to shutdown the connection pool before it deinitializes.

`EventLoopGroupConnectionPool` is a collection of pools for each event loop. When using `EventLoopGroupConnectionPool` directly, random event loops will be chosen as needed.

```swift
pools.withConnection { conn
print(conn) // PostgresConnection on randomly chosen event loop
}
```

To get a pool for a specific event loop, use `pool(for:)`. This returns an `EventLoopConnectionPool`.

```swift
let eventLoop: EventLoop = ...
let pool = pools.pool(for: eventLoop)

pool.withConnection { conn
print(conn) // PostgresConnection on eventLoop
}
```

### PostgresDatabase

Both `EventLoopGroupConnectionPool` and `EventLoopConnectionPool` can be used to create instances of `PostgresDatabase`.

```swift
let postgres = pool.database(logger: ...) // PostgresDatabase
let rows = try postgres.simpleQuery("SELECT version();").wait()
```

Visit [PostgresNIO's docs] for more information on using `PostgresDatabase`.

### SQLDatabase

A `PostgresDatabase` can be used to create an instance of `SQLDatabase`.

```swift
let sql = postgres.sql() // SQLDatabase
let planets = try sql.select().column("*").from("planets").all().wait()
```

Visit [SQLKit's docs] for more information on using `SQLDatabase`.

[SQLKit]: https://github.com/vapor/sql-kit
[SQLKit's docs]: https://api.vapor.codes/sqlkit/documentation/sqlkit
[PostgresNIO]: https://github.com/vapor/postgres-nio
[PostgresNIO's docs]: https://api.vapor.codes/postgresnio/documentation/postgresnio
[AsyncKit]: https://github.com/vapor/async-kit
[PostgresClient]: https://api.vapor.codes/postgresnio/documentation/postgresnio/postgresclient
[SwiftNIO's documentation]: https://swiftpackageindex.com/apple/swift-nio/documentation/nio
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Sources/PostgresKit/Docs.docc/theme-settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"logo-shape": { "dark": "#000", "light": "#fff" },
"fill": { "dark": "#000", "light": "#fff" }
},
"icons": { "technology": "/postgreskit/images/vapor-postgreskit-logo.svg" }
"icons": { "technology": "/postgreskit/images/PostgresKit/vapor-postgreskit-logo.svg" }
},
"features": {
"quickNavigation": { "enable": true },
Expand Down
Loading