/PG.swift

A PostgreSQL client library written in pure Swift (without any dependency the C libpq).

Primary LanguageObjective-CMIT LicenseMIT

PG.swift

macOS Linux MIT

A PostgreSQL client library written in pure Swift (without any dependency the C libpq).

Usage

See Swift Package Manager.

import PG

let config = Client.Config(user: "postgres", database: "pg_swift_tests")
let pool = Pool(config)

let id = UUID(uuidString: "A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11")
let query = Query("SELECT * FROM example WHERE id = $1;", id)
pool.exec(query) { result in
	switch result {
	case .success(let result):
		print("name: \(result.rows.first?["name"])")
	case .failure(let error):
		print("failed to excecute query: \(error)")
	}
}

Motivation

While everyone seems to agree that there needs to be a Swift native interface to Postgres, they all use the C library, libpq. This is a reasonable approach but has a few drawbacks. For one, C lacks a universal event driven, non-blocking socket interface, so you are forced to block a thread while you wait for query responses. Swift has both DispatchSources and RunLoops (this project currently uses the former). This avoids creating extra threads, which incure performance and memory overhead. Additionally, the client has to do extra work to convert the data from the conneciton into C structures, then again into Swift types.

The goal of this project is to be usable as is to connect to a PostgreSQL database, but low level enough that it won't get in the way (both in terms of performance and unused code) of higher levels of abstraction.

Status

This project is in it's very earliest stage. You can create a client that connects to a server and excecute queries. Here are some of the bigger features that need to be implemented before the framework is usable:

  • Connect client to server.
  • Handle authentication other than passwordless.
  • Execute queries.
  • Return query results and convert them to usable types.
  • Support for SSL.
  • Support for Linux (using BlueSocket and DispatchSources).
  • Handle connection errors, disconnects and reconnects.
  • Support for LISTEN and NOTIFY.
  • Database pool for concurrent queries to the same server.

Related projects

It's my intention to add other projects that expand upon this projects capabilities but can be ommited if the user doesn't need them.

  • Integration with PromiseKit.
  • String interpolation for queries that expand into query bindings.
  • Swift 4 Encodable support on QueryResult.