Skip to content
This repository has been archived by the owner on Mar 30, 2024. It is now read-only.

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
natebird authored Apr 5, 2017
2 parents a06b2d3 + fda088e commit 8ef2aaa
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 133 deletions.
18 changes: 8 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@ matrix:
- os: linux
dist: trusty
sudo: required
services:
- postgresql
addons:
postgresql: "9.5"
postgresql: 9.5
- os: osx
osx_image: xcode8
osx_image: xcode8.3
install:
- "[ $TRAVIS_OS_NAME = osx ] && pg_ctl -D /usr/local/var/postgres start && sleep 3 || true"
- "[ $TRAVIS_OS_NAME = osx ] && createuser -s postgres || true"
- psql -U postgres -c 'CREATE DATABASE test;'

- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then rm -rf /usr/local/var/postgres && initdb /usr/local/var/postgres -E utf8; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then pg_ctl -D /usr/local/var/postgres start && sleep 3 || true; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo -u travis createuser -s -p 5432 postgres; fi
- psql -U postgres -c 'create database test;'
script:
- eval "$(curl -sL swift.vapor.sh/ci)"
- eval "$(curl -sL swift.vapor.sh/codecov)"
- eval "$(curl -sL https://swift.vapor.sh/ci-3.1)"
- eval "$(curl -sL https://swift.vapor.sh/codecov)"
11 changes: 8 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ import PackageDescription
let package = Package(
name: "PostgreSQL",
dependencies: [
.Package(url: "https://github.com/vapor/cpostgresql.git", majorVersion: 1),
.Package(url: "https://github.com/vapor/node.git", majorVersion: 1),
.Package(url: "https://github.com/vapor/core.git", majorVersion: 1),
// Module map for `libpq`
.Package(url: "https://github.com/vapor/cpostgresql.git", Version(2,0,0, prereleaseIdentifiers: ["alpha"])),

// Data structure for converting between multiple representations
.Package(url: "https://github.com/vapor/node.git", Version(2,0,0, prereleaseIdentifiers: ["beta"])),

// Core extensions, type-aliases, and functions that facilitate common tasks
.Package(url: "https://github.com/vapor/core.git", Version(2,0,0, prereleaseIdentifiers: ["beta"])),
]
)
25 changes: 11 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# PostgreSQL for Swift

[![Swift](http://img.shields.io/badge/swift-3.0-brightgreen.svg)](https://swift.org)
[![Build Status](https://travis-ci.org/vapor/postgresql.svg?branch=master)](https://travis-ci.org/vapor/postgresql)

A Swift wrapper for PostgreSQL.

- [x] Thread-Safe
- [x] Prepared Statements
- [x] Tested

This wrapper uses the latest PostgreSQL fetch API to enable performant prepared statements and output bindings.

The Swift wrappers around the PostgreSQL's C structs and pointers automatically manage closing connections and deallocating memeory. Additionally, the PostgreSQL library API is used to perform thread safe, performant queries to the database.
This wrapper uses the latest PostgreSQL fetch API to enable performant prepared statements and output bindings. Data is sent to and received from the PostgreSQL server in its native data type without converting to and from strings.

The Swift wrappers around the PostgreSQL's C structs and pointers automatically manage closing connections and deallocating memory. Additionally, the PostgreSQL library API is used to perform thread safe, performant queries to the database.

## Examples
## 📖 Examples

### Connecting to the Database

Expand Down Expand Up @@ -62,7 +64,7 @@ let result = try postgreSQL.execute("SELECT LAST_INSERTED_ID() as id", [], conne

No need to worry about closing the connection.

## Building
## 🚀 Building

### macOS

Expand All @@ -72,9 +74,6 @@ Install PostgreSQL
brew install postgresql
brew link postgresql
brew services start postgresql

// to stop
brew services stop postgresql
```

### Linux
Expand All @@ -87,14 +86,12 @@ sudo apt-get install postgresql postgresql-contrib libpq-dev
psql -h dbhost -U username dbname
```

`swift build` should work normally.
Use `vapor build` or `swift build`.

## Fluent

This wrapper was created to power [Fluent](https://github.com/qutheory/fluent), an ORM for Swift.

## 👥 Authors

Made by [Prince Ugwuh](https://twitter.com/Prince2k3) a member of Qutheory community.
This wrapper was created to power [Fluent](https://github.com/qutheory/fluent), an [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping) for Swift.

## 👥 Contributors

Maintained by [Steven Roebert](https://github.com/sroebert), [Nate Bird](https://twitter.com/natesbird), [Prince Ugwuh](https://twitter.com/Prince2k3), and other members of the Vapor community.
46 changes: 20 additions & 26 deletions Sources/PostgreSQL/Connection.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
#if os(Linux)
import CPostgreSQLLinux
#else
import CPostgreSQLMac
#endif


import CPostgreSQL

public final class Connection: ConnInfoInitializable {
public typealias ConnectionPointer = OpaquePointer
Expand All @@ -20,7 +14,7 @@ public final class Connection: ConnInfoInitializable {

public init(conninfo: ConnInfo) throws {
let string: String

switch conninfo {
case .raw(let info):
string = info
Expand All @@ -29,41 +23,41 @@ public final class Connection: ConnInfoInitializable {
case .basic(let host, let port, let database, let user, let password):
string = "host='\(host)' port='\(port)' dbname='\(database)' user='\(user)' password='\(password)' client_encoding='UTF8'"
}

self.connection = PQconnectdb(string)
if !self.connected {
throw DatabaseError.cannotEstablishConnection(error)
}
}

@discardableResult
public func execute(_ query: String, _ values: [Node]? = []) throws -> [[String: Node]] {
guard !query.isEmpty else {
throw DatabaseError.noQuery
}

let values = values ?? []

var types: [Oid] = []
types.reserveCapacity(values.count)

var paramValues: [[Int8]?] = []
paramValues.reserveCapacity(values.count)

var lengths: [Int32] = []
lengths.reserveCapacity(values.count)

var formats: [Int32] = []
formats.reserveCapacity(values.count)

for value in values {
let (bytes, oid, format) = value.postgresBindingData
paramValues.append(bytes)
types.append(oid?.rawValue ?? 0)
lengths.append(Int32(bytes?.count ?? 0))
formats.append(format.rawValue)
}

let res: Result.Pointer = PQexecParams(
connection, query,
Int32(values.count),
Expand All @@ -74,11 +68,11 @@ public final class Connection: ConnInfoInitializable {
formats,
DataFormat.binary.rawValue
)

defer {
PQclear(res)
}

switch Database.Status(result: res) {
case .nonFatalError, .fatalError, .unknown:
throw DatabaseError.invalidSQL(message: String(cString: PQresultErrorMessage(res)))
Expand Down Expand Up @@ -110,28 +104,28 @@ public final class Connection: ConnInfoInitializable {
guard let s = PQerrorMessage(connection) else {
return ""
}
return String(cString: s)
return String(cString: s)
}

deinit {
try? close()
}

// MARK: - Load Configuration

private func getConfiguration() throws -> Configuration {
if let configuration = self.configuration {
return configuration
}

let hasIntegerDatetimes = getBooleanParameterStatus(key: "integer_datetimes", default: true)

let configuration = Configuration(hasIntegerDatetimes: hasIntegerDatetimes)
self.configuration = configuration

return configuration
}

private func getBooleanParameterStatus(key: String, `default` defaultValue: Bool = false) -> Bool {
guard let value = PQparameterStatus(connection, "integer_datetimes") else {
return defaultValue
Expand Down
6 changes: 1 addition & 5 deletions Sources/PostgreSQL/ConnectionInfo.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
#if os(Linux)
import CPostgreSQLLinux
#else
import CPostgreSQLMac
#endif
import CPostgreSQL

public enum ConnInfo {
case raw(String)
Expand Down
6 changes: 1 addition & 5 deletions Sources/PostgreSQL/Database.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
#if os(Linux)
import CPostgreSQLLinux
#else
import CPostgreSQLMac
#endif
import CPostgreSQL

public enum DatabaseError: Error {
case cannotEstablishConnection(String)
Expand Down
12 changes: 10 additions & 2 deletions Sources/PostgreSQL/Node+Binding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ protocol Bindable {

extension Node: Bindable {
var postgresBindingData: ([Int8]?, OID?, DataFormat) {
switch self {
switch wrapped {
case .null:
// PQexecParams converts nil pointer to NULL.
// see: https://www.postgresql.org/docs/9.1/static/libpq-exec.html
Expand Down Expand Up @@ -38,9 +38,14 @@ extension Node: Bindable {
case .object(_):
print("Unsupported Node type for PostgreSQL binding, everything except for .object is supported.")
return (nil, nil, .string)

default:
return (nil, nil, .string)
}
}

}

extension StructuredData {
var postgresArrayElementString: String {
switch self {
case .null:
Expand Down Expand Up @@ -69,6 +74,9 @@ extension Node: Bindable {
case .object(_):
print("Unsupported Node array type for PostgreSQL binding, everything except for .object is supported.")
return "NULL"

default:
return ""
}
}
}
Expand Down
6 changes: 1 addition & 5 deletions Sources/PostgreSQL/Node+Oid.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
#if os(Linux)
import CPostgreSQLLinux
#else
import CPostgreSQLMac
#endif
import CPostgreSQL
import Foundation

/// Oid values can be found in the following file:
Expand Down
6 changes: 1 addition & 5 deletions Sources/PostgreSQL/Result.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
#if os(Linux)
import CPostgreSQLLinux
#else
import CPostgreSQLMac
#endif
import CPostgreSQL

class Result {
typealias Pointer = OpaquePointer
Expand Down
8 changes: 1 addition & 7 deletions Sources/PostgreSQL/Status.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@

#if os(Linux)
import CPostgreSQLLinux
#else
import CPostgreSQLMac
#endif

import CPostgreSQL

extension Database {
public enum Status {
Expand Down
Loading

0 comments on commit 8ef2aaa

Please sign in to comment.