• Stars
    star
    325
  • Rank 129,350 (Top 3 %)
  • Language
    Swift
  • License
    MIT License
  • Created about 6 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

๐Ÿ˜ Non-blocking, event-driven Swift client for PostgreSQL.

PostgresNIO

SSWG Incubating Badge Documentation Team Chat MIT License Continuous Integration Swift 5.6

๐Ÿ˜ Non-blocking, event-driven Swift client for PostgreSQL built on SwiftNIO.

Features:

  • A PostgresConnection which allows you to connect to, authorize with, query, and retrieve results from a PostgreSQL server
  • An async/await interface that supports backpressure
  • Automatic conversions between Swift primitive types and the Postgres wire format
  • Integrated with the Swift server ecosystem, including use of SwiftLog.
  • Designed to run efficiently on all supported platforms (tested extensively on Linux and Darwin systems)
  • Support for Network.framework when available (e.g. on Apple platforms)
  • Supports running on Unix Domain Sockets

PostgresNIO does not provide a ConnectionPool as of today, but this is a feature high on our list. If you need a ConnectionPool today, please have a look at Vapor's PostgresKit.

API Docs

Check out the PostgresNIO API docs for a detailed look at all of the classes, structs, protocols, and more.

Getting started

Adding the dependency

Add PostgresNIO as dependency to your Package.swift:

  dependencies: [
    .package(url: "https://github.com/vapor/postgres-nio.git", from: "1.14.0"),
    ...
  ]

Add PostgresNIO to the target you want to use it in:

  targets: [
    .target(name: "MyFancyTarget", dependencies: [
      .product(name: "PostgresNIO", package: "postgres-nio"),
    ])
  ]

Creating a connection

To create a connection, first create a connection configuration object:

import PostgresNIO

let config = PostgresConnection.Configuration(
  host: "localhost",
  port: 5432,
  username: "my_username",
  password: "my_password",
  database: "my_database",
  tls: .disable
)

A connection must be created on a SwiftNIO EventLoop. In most server use cases, an EventLoopGroup is created at app startup and closed during app shutdown.

import NIOPosix

let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)

// Much later
try await eventLoopGroup.shutdownGracefully()

A Logger is also required.

import Logging

let logger = Logger(label: "postgres-logger")

Now we can put it together:

import PostgresNIO
import NIOPosix
import Logging

let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let logger = Logger(label: "postgres-logger")

let config = PostgresConnection.Configuration(
  host: "localhost",
  port: 5432,
  username: "my_username",
  password: "my_password",
  database: "my_database",
  tls: .disable
)

let connection = try await PostgresConnection.connect(
  on: eventLoopGroup.next(),
  configuration: config,
  id: 1,
  logger: logger
)

// Close your connection once done
try await connection.close()

// Shutdown the EventLoopGroup, once all connections are closed.
try await eventLoopGroup.shutdownGracefully()

Querying

Once a connection is established, queries can be sent to the server. This is very straightforward:

let rows = try await connection.query("SELECT id, username, birthday FROM users", logger: logger)

The query will return a PostgresRowSequence, which is an AsyncSequence of PostgresRows. The rows can be iterated one-by-one:

for try await row in rows {
  // do something with the row
}

Decoding from PostgresRow

However, in most cases it is much easier to request a row's fields as a set of Swift types:

for try await (id, username, birthday) in rows.decode((Int, String, Date).self) {
  // do something with the datatypes.
}

A type must implement the PostgresDecodable protocol in order to be decoded from a row. PostgresNIO provides default implementations for most of Swift's builtin types, as well as some types provided by Foundation:

  • Bool
  • Bytes, Data, ByteBuffer
  • Date
  • UInt8, Int16, Int32, Int64, Int
  • Float, Double
  • String
  • UUID

Querying with parameters

Sending parameterized queries to the database is also supported (in the coolest way possible):

let id = 1
let username = "fancyuser"
let birthday = Date()
try await connection.query("""
  INSERT INTO users (id, username, birthday) VALUES (\(id), \(username), \(birthday))
  """, 
  logger: logger
)

While this looks at first glance like a classic case of SQL injection ๐Ÿ˜ฑ, PostgresNIO's API ensures that this usage is safe. The first parameter of the query(_:logger:) method is not a plain String, but a PostgresQuery, which implements Swift's ExpressibleByStringInterpolation protocol. PostgresNIO uses the literal parts of the provided string as the SQL query and replaces each interpolated value with a parameter binding. Only values which implement the PostgresEncodable protocol may be interpolated in this way. As with PostgresDecodable, PostgresNIO provides default implementations for most common types.

Some queries do not receive any rows from the server (most often INSERT, UPDATE, and DELETE queries with no RETURNING clause, not to mention most DDL queries). To support this, the query(_:logger:) method is marked @discardableResult, so that the compiler does not issue a warning if the return value is not used.

Security

Please see SECURITY.md for details on the security process.

More Repositories

1

vapor

๐Ÿ’ง A server-side Swift HTTP web framework.
Swift
24,188
star
2

fluent

Vapor ORM (queries, models, and relations) for NoSQL and SQL databases
Swift
1,308
star
3

redis

Vapor provider for RediStack
Swift
458
star
4

console-kit

๐Ÿ’ป APIs for creating interactive CLI tools.
Swift
456
star
5

leaf

๐Ÿƒ An expressive, performant, and extensible templating language built for Swift.
Swift
432
star
6

jwt

Vapor JWT provider
Swift
317
star
7

docs

๐Ÿ“– Documentation markdown for all Vapor packages.
Swift
316
star
8

toolbox

Simplifies common command line tasks when using Vapor
Swift
283
star
9

websocket-kit

WebSocket client library built on SwiftNIO
Swift
272
star
10

sql-kit

*๏ธโƒฃ Build SQL queries in Swift. Extensible, protocol-based design that supports DQL, DML, and DDL.
Swift
239
star
11

http

๐Ÿš€ Non-blocking, event-driven HTTP built on Swift NIO.
Swift
238
star
12

mysql-kit

๐Ÿฌ Pure Swift MySQL client built on non-blocking, event-driven sockets.
Swift
222
star
13

fluent-kit

Swift ORM (queries, models, and relations) for NoSQL and SQL databases
Swift
206
star
14

postgres-kit

๐Ÿ˜ Non-blocking, event-driven Swift client for PostgreSQL.
Swift
187
star
15

jwt-kit

๐Ÿ”‘ JSON Web Token (JWT) signing and verification (HMAC, ECDSA, EdDSA, RSA, PSS) with support for JWS and JWK
Swift
180
star
16

queues

A queue system for Vapor.
Swift
163
star
17

fluent-postgres-driver

๐Ÿ˜ PostgreSQL driver for Fluent.
Swift
145
star
18

api-template

๐Ÿ’ง A starting point for Vapor APIs.
Swift
135
star
19

open-crypto

๐Ÿ”‘ Hashing (BCrypt, SHA2, HMAC), encryption (AES), public-key (RSA), and random data generation.
Swift
134
star
20

multipart-kit

๐Ÿž Parses and serializes multipart-encoded data with Codable support.
Swift
132
star
21

routing-kit

๐Ÿš High-performance trie-node router.
Swift
122
star
22

apns

Helpful extensions and abstractions for using APNSwift
Swift
115
star
23

mysql-nio

๐Ÿฌ Non-blocking, event-driven Swift client for MySQL.
Swift
88
star
24

service

๐Ÿ“ฆ Dependency injection / inversion of control framework.
Swift
85
star
25

core

๐ŸŒŽ Utility package containing tools for byte manipulation, Codable, OS APIs, and debugging.
Swift
80
star
26

fluent-mysql-driver

๐Ÿ–‹๐Ÿฌ Swift ORM (queries, models, relations, etc) built on MySQL.
Swift
76
star
27

async-kit

Sugary extensions for the SwiftNIO library
Swift
71
star
28

template

Used by Vapor Toolboxโ€™s new project command
Swift
70
star
29

fluent-sqlite-driver

Fluent driver for SQLite
Swift
67
star
30

sqlite-kit

Non-blocking SQLite client library with SQL builder built on SwiftNIO
Swift
58
star
31

sqlite-nio

Non-blocking wrapper for libsqlite3-dev using SwiftNIO
C
58
star
32

validation

โœ… Extensible data validation library (name, email, etc)
Swift
56
star
33

auth

๐Ÿ‘ค Authentication and Authorization framework for Fluent.
Swift
53
star
34

leaf-kit

๐Ÿƒ An expressive, performant, and extensible templating language built for Swift.
Swift
47
star
35

template-kit

๐Ÿ“„ Easy-to-use foundation for building powerful templating languages in Swift.
Swift
45
star
36

website

Vapor's website running on Swift
Swift
45
star
37

docs-cn

๐Ÿ‡จ๐Ÿ‡ณ Chinese translation of Vapor's documentation markdown.
HTML
43
star
38

web-template

A starting point for web applications
Swift
41
star
39

url-encoded-form

๐Ÿ“ Parse and serialize url-encoded form data with Codable support.
Swift
41
star
40

database-kit

๐Ÿ—„ Core services for creating database integrations.
Swift
40
star
41

auth-template

A starting point for Vapor applications using the auth provider.
Swift
35
star
42

university

Web application, iOS app, and API providing access to tutorials for the Vapor web framework.
Swift
24
star
43

fluent-mongo-driver

MongoDB support for Fluent built on MongoKittten.
Swift
24
star
44

queues-redis-driver

A Redis implementation for https://github.com/vapor/queues
Swift
22
star
45

design

Contains the reference designs and build pipeline to generate all design files for Vapor's sites
Swift
22
star
46

email

A common API for Vapor to integrate with different email providers
Swift
20
star
47

codable-kit

Conveniences for working with Swift's Codable protocols.
Swift
19
star
48

kafka

Swift Apacha Kafka (real-time data pipelines and streaming apps)
Swift
19
star
49

apt

Manage Vapor's Swift APT repository
Shell
17
star
50

blog

The Vapor Blog
Swift
16
star
51

penny-bot

The code that runs Penny ๐Ÿค–
Swift
15
star
52

template-bare

A barebones template ready for use
Swift
12
star
53

docker

Swift
12
star
54

api-docs

Scripts and assets for Vapor's API documentation site at https://api.vapor.codes
Swift
11
star
55

redis-kit

Helpful extensions and abstractions for using RediStack
Swift
8
star
56

swift-getting-started-web-server

The source code for the Getting Started Guide on Vapor on swift.org
Swift
7
star
57

homebrew-tap

Homebrew Taps
Ruby
7
star
58

template-fluent-postgres

A template ready for use configured with Fluent and PostgreSQL
Swift
6
star
59

release-bot

Webhook-based GitHub bot that automatically tags new releases and posts to Discord when you merge PRs
Swift
6
star
60

ci

Support files and configurations for Vapor's CI
Swift
5
star
61

bot-github

A github bot to do things like interact with CI for the Vapor organization
Swift
5
star
62

template-fluent-postgres-leaf

A template ready for use configured with Leaf, Fluent and PostgreSQL
Swift
4
star
63

swiftly-action

Simple one-step access to the Swiftly toolchain manager from GitHub Actions workflows
3
star
64

swift-codecov-action

A GitHub Action which performs Codecov.io uploads with additional support for Swift projects
Swift
3
star
65

template-fluent-mysql

A template ready for use configured with Fluent and MySQL
Swift
2
star
66

docs-de

Deutsche รœbersetzung der Vapor-Dokumentation
HTML
1
star