Skip to content

Commit

Permalink
Support Swift 5 (#128)
Browse files Browse the repository at this point in the history
* Swift 5 language changes
* Update Swift-Kuery-ORM to 0.5.0
* Update to Kitura-WebSocket-NIO instead of branch
* Update to Swift 5.0.1
  • Loading branch information
Andrew-Lees11 authored and djones6 committed May 1, 2019
1 parent 3081cf8 commit ee7f640
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 81 deletions.
2 changes: 1 addition & 1 deletion .swift-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.2.3
5.0.1
41 changes: 30 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ branches:
matrix:
include:
- os: linux
# Trusty build retained to provide 14.04 coverage (as paid support is still available)
dist: trusty
sudo: required
env: SWIFT_SNAPSHOT=4.0.3
Expand All @@ -24,24 +25,30 @@ matrix:
dist: xenial
sudo: required
services: docker
env: DOCKER_IMAGE=swift:4.2.3
# Temporarily disabled: appid-serversdk-swift does not yet compile on Swift 5
# https://github.com/ibm-cloud-security/appid-serversdk-swift/issues/83
# - os: linux
# dist: xenial
# sudo: required
# services: docker
# env: DOCKER_IMAGE=swift:4.2.3 SWIFT_SNAPSHOT=$SWIFT_DEVELOPMENT_SNAPSHOT
env: DOCKER_IMAGE=swift:4.2.4 SWIFT_SNAPSHOT=4.2.4
- os: linux
dist: xenial
sudo: required
services: docker
env: DOCKER_IMAGE=swift:4.2.3 KITURA_NIO=1
# Note: Ubuntu 16.04
env: DOCKER_IMAGE=swift:5.0.1-xenial
- os: linux
dist: xenial
sudo: required
services: docker
env: DOCKER_IMAGE=ubuntu:18.04 KITURA_NIO=1
# Note: Kitura-WebSocket-NIO requires zlib
env: DOCKER_IMAGE=swift:5.0.1-xenial KITURA_NIO=1 DOCKER_PACKAGES="libz-dev"
- os: linux
dist: xenial
sudo: required
services: docker
# Note: Ubuntu 18.04
env: DOCKER_IMAGE=swift:5.0.1 SWIFT_SNAPSHOT=$SWIFT_DEVELOPMENT_SNAPSHOT
- os: linux
dist: xenial
sudo: required
services: docker
env: DOCKER_IMAGE=swift:5.0.1 SWIFT_SNAPSHOT=$SWIFT_DEVELOPMENT_SNAPSHOT KITURA_NIO=1 DOCKER_PACKAGES="libz-dev"
- os: osx
osx_image: xcode9.2
sudo: required
Expand All @@ -53,10 +60,22 @@ matrix:
- os: osx
osx_image: xcode10.1
sudo: required
env: SWIFT_SNAPSHOT=4.2.1
- os: osx
osx_image: xcode10.1
osx_image: xcode10.2
sudo: required
- os: osx
osx_image: xcode10.2
sudo: required
env: KITURA_NIO=1
- os: osx
osx_image: xcode10.2
sudo: required
env: SWIFT_SNAPSHOT=$SWIFT_DEVELOPMENT_SNAPSHOT
- os: osx
osx_image: xcode10.2
sudo: required
env: SWIFT_SNAPSHOT=$SWIFT_DEVELOPMENT_SNAPSHOT KITURA_NIO=1

before_install:
- git clone https://github.com/IBM-Swift/Package-Builder.git
Expand Down
14 changes: 7 additions & 7 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// swift-tools-version:4.0
// swift-tools-version:5.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

/**
* Copyright IBM Corporation 2016, 2017
* Copyright IBM Corporation 2016, 2017, 2019
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,9 +21,9 @@ import PackageDescription
import Foundation

var dependencies: [Package.Dependency] = [
.package(url: "https://github.com/IBM-Swift/Kitura.git", from: "2.5.0"),
.package(url: "https://github.com/IBM-Swift/Kitura.git", from: "2.6.0"),
.package(url: "https://github.com/IBM-Swift/HeliumLogger.git", from: "1.7.1"),
.package(url: "https://github.com/IBM-Swift/CloudEnvironment.git", from: "8.0.0"),
.package(url: "https://github.com/IBM-Swift/CloudEnvironment.git", from: "9.0.0"),
.package(url: "https://github.com/RuntimeTools/SwiftMetrics.git", from: "2.5.0"),
.package(url: "https://github.com/IBM-Swift/Health.git", from: "1.0.0"),
.package(url: "https://github.com/IBM-Swift/Kitura-OpenAPI.git", from: "1.1.0"),
Expand All @@ -34,7 +34,7 @@ var dependencies: [Package.Dependency] = [
.package(url: "https://github.com/IBM-Swift/Kitura-CredentialsGoogle.git", from: "2.2.0"),
.package(url: "https://github.com/IBM-Swift/Kitura-CredentialsFacebook.git", from: "2.2.0"),
.package(url: "https://github.com/IBM-Swift/Swift-JWT", from: "3.0.0"),
.package(url: "https://github.com/IBM-Swift/Swift-Kuery-ORM.git", .upToNextMinor(from: "0.3.1")),
.package(url: "https://github.com/IBM-Swift/Swift-Kuery-ORM.git", .upToNextMinor(from: "0.5.0")),
]
var targetDependencies: [Target.Dependency] = [ "Kitura", "CloudEnvironment","SwiftMetrics","Health", "KituraOpenAPI", "KituraMarkdown", "KituraStencil", "CredentialsHTTP", "KituraSession", "CredentialsGoogle", "CredentialsFacebook", "SwiftJWT", "SwiftKueryORM",
]
Expand All @@ -49,9 +49,9 @@ dependencies.append(.package(url: "https://github.com/ibm-cloud-security/appid-s
targetDependencies.append("IBMCloudAppID")
#endif

// Temporarily use alternate branch of Kitura-WebSocket while building in NIO mode
// Use alternate implementation of Kitura-WebSocket while building in NIO mode
if ProcessInfo.processInfo.environment["KITURA_NIO"] != nil {
dependencies.append(.package(url: "https://github.com/IBM-Swift/Kitura-WebSocket.git", .exact("0.1.0-nio")))
dependencies.append(.package(url: "https://github.com/IBM-Swift/Kitura-WebSocket-NIO.git", from: "2.0.0"))
} else {
dependencies.append(.package(url: "https://github.com/IBM-Swift/Kitura-WebSocket.git", from: "2.0.0"))
}
Expand Down
68 changes: 68 additions & 0 deletions [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// swift-tools-version:4.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

/**
* Copyright IBM Corporation 2016, 2017, 2019
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/

import PackageDescription
import Foundation

var dependencies: [Package.Dependency] = [
.package(url: "https://github.com/IBM-Swift/Kitura.git", .upToNextMinor(from: "2.6.0")),
.package(url: "https://github.com/IBM-Swift/HeliumLogger.git", from: "1.7.1"),
.package(url: "https://github.com/IBM-Swift/CloudEnvironment.git", from: "9.0.0"),
.package(url: "https://github.com/RuntimeTools/SwiftMetrics.git", from: "2.5.0"),
.package(url: "https://github.com/IBM-Swift/Health.git", from: "1.0.0"),
.package(url: "https://github.com/IBM-Swift/Kitura-OpenAPI.git", from: "1.1.0"),
.package(url: "https://github.com/IBM-Swift/Kitura-StencilTemplateEngine.git", from: "1.9.0"),
.package(url: "https://github.com/IBM-Swift/Kitura-Markdown.git", from: "1.0.0"),
.package(url: "https://github.com/IBM-Swift/Kitura-CredentialsHTTP.git", from: "2.1.0"),
.package(url: "https://github.com/IBM-Swift/Kitura-Session.git", from: "3.3.0"),
.package(url: "https://github.com/IBM-Swift/Kitura-CredentialsGoogle.git", from: "2.2.0"),
.package(url: "https://github.com/IBM-Swift/Kitura-CredentialsFacebook.git", from: "2.2.0"),
.package(url: "https://github.com/IBM-Swift/Swift-JWT", from: "3.0.0"),
.package(url: "https://github.com/IBM-Swift/Swift-Kuery-ORM.git", .upToNextMinor(from: "0.5.0")),
]
var targetDependencies: [Target.Dependency] = [ "Kitura", "CloudEnvironment","SwiftMetrics","Health", "KituraOpenAPI", "KituraMarkdown", "KituraStencil", "CredentialsHTTP", "KituraSession", "CredentialsGoogle", "CredentialsFacebook", "SwiftJWT", "SwiftKueryORM",
]

// Uncomment to use PostgreSQL
// dependencies.append(.package(url: "https://github.com/IBM-Swift/Swift-Kuery-PostgreSQL.git", from: "1.2.0"))
// targetDependencies.append("SwiftKueryPostgreSQL")

// IBMCloudAppID requires OpenSSL that is not included on Mac by default.
#if os(Linux)
dependencies.append(.package(url: "https://github.com/ibm-cloud-security/appid-serversdk-swift", .branch("development")))
targetDependencies.append("IBMCloudAppID")
#endif

// Use alternate implementation of Kitura-WebSocket while building in NIO mode
if ProcessInfo.processInfo.environment["KITURA_NIO"] != nil {
dependencies.append(.package(url: "https://github.com/IBM-Swift/Kitura-WebSocket-NIO.git", from: "1.0.0"))
} else {
dependencies.append(.package(url: "https://github.com/IBM-Swift/Kitura-WebSocket.git", from: "2.0.0"))
}

let package = Package(
name: "Kitura-Sample",
dependencies: dependencies,
targets: [
.target(name: "Kitura-Sample", dependencies: [ .target(name: "Application"), .target(name: "ChatService"), "Kitura" , "HeliumLogger"]),
.target(name: "Application", dependencies: targetDependencies),
.target(name: "ChatService", dependencies: ["Kitura-WebSocket"]),
.testTarget(name: "KituraSampleRouterTests" , dependencies: [.target(name: "Application"), "Kitura","HeliumLogger" ])
]
)
111 changes: 77 additions & 34 deletions Sources/Application/DummyDatabase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,23 @@ import SwiftKuery
// This class is a dummy SwiftKuery plugin that allows the saving and retrieval of "Grade" objects in local storage.
// This allows the Database example to run prior to connecting to a real database.
class DummyConnection: Connection {
var grades = [Grade]()
let queryBuilder: QueryBuilder

init(withDeleteRequiresUsing: Bool = false, withUpdateRequiresFrom: Bool = false, createAutoIncrement: ((String, Bool) -> String)? = nil) {
self.queryBuilder = QueryBuilder(withDeleteRequiresUsing: withDeleteRequiresUsing, withUpdateRequiresFrom: withUpdateRequiresFrom, createAutoIncrement: createAutoIncrement)
func execute(preparedStatement: PreparedStatement, parameters: [String : Any?], onCompletion: @escaping ((QueryResult) -> ())) {
onCompletion(.successNoData)
}

func connect(onCompletion: (QueryError?) -> ()) {}

public var isConnected: Bool { return true }

func closeConnection() {}
var grades = [Grade]()

func execute(query: Query, onCompletion: @escaping ((QueryResult) -> ())) {
do {
let queryComponents = (try query.build(queryBuilder: queryBuilder)).components(separatedBy: " ")
switch queryComponents[0] {
case "SELECT":
if queryComponents[1] == "*" {
return onCompletion(.resultSet(ResultSet(DummyResultFetcher(grades: grades))))
if grades.isEmpty {
return onCompletion(.successNoData)
} else {
return onCompletion(QueryResult.resultSet(ResultSet(DummyResultFetcher(grades: grades), connection: self)))
}
}
case "DELETE":
grades = []
Expand All @@ -64,7 +61,7 @@ class DummyConnection: Connection {
case "SELECT":
if let course = parameters[0] as? String {
let matchingGrades = grades.filter { $0.course == course }
return onCompletion(.resultSet(ResultSet(DummyResultFetcher(grades: matchingGrades))))
return onCompletion(.resultSet(ResultSet(DummyResultFetcher(grades: matchingGrades), connection: self)))
}
default:
return onCompletion(QueryResult.successNoData)
Expand Down Expand Up @@ -94,35 +91,45 @@ class DummyConnection: Connection {
return (try? query.build(queryBuilder: queryBuilder)) ?? ""
}

private func returnResult(_ onCompletion: @escaping ((QueryResult) -> ())) {
return onCompletion(.successNoData)
func execute(preparedStatement: PreparedStatement, parameters: [Any?], onCompletion: @escaping ((QueryResult) -> ())) {
onCompletion(.successNoData)
}

func startTransaction(onCompletion: @escaping ((QueryResult) -> ())) {}
func execute(preparedStatement: PreparedStatement, onCompletion: @escaping ((QueryResult) -> ())) {
onCompletion(.successNoData)
}

func commit(onCompletion: @escaping ((QueryResult) -> ())) {}
init(withDeleteRequiresUsing: Bool = false, withUpdateRequiresFrom: Bool = false) {
self.queryBuilder = QueryBuilder(columnBuilder: DummySQLColumnBuilder())
}

func rollback(onCompletion: @escaping ((QueryResult) -> ())) {}
var queryBuilder: QueryBuilder

func create(savepoint: String, onCompletion: @escaping ((QueryResult) -> ())) {}
func connect(onCompletion: @escaping (QueryResult) -> ()) {}

func rollback(to savepoint: String, onCompletion: @escaping ((QueryResult) -> ())) {}
func connectSync() -> QueryResult { return QueryResult.successNoData }
func closeConnection() {}

func release(savepoint: String, onCompletion: @escaping ((QueryResult) -> ())) {}
var isConnected: Bool = true

func prepareStatement(_ query: Query, onCompletion: @escaping ((QueryResult) -> ())) {}

func prepareStatement(_ raw: String, onCompletion: @escaping ((QueryResult) -> ())) {}

struct TestPreparedStatement: PreparedStatement {}
func release(preparedStatement: PreparedStatement, onCompletion: @escaping ((QueryResult) -> ())) {}

func startTransaction(onCompletion: @escaping ((QueryResult) -> ())) { }

func prepareStatement(_ query: Query) throws -> PreparedStatement { return TestPreparedStatement() }
func commit(onCompletion: @escaping ((QueryResult) -> ())) {}

func prepareStatement(_ raw: String) throws -> PreparedStatement { return TestPreparedStatement() }
func rollback(onCompletion: @escaping ((QueryResult) -> ())) {}

func execute(preparedStatement: PreparedStatement, onCompletion: @escaping ((QueryResult) -> ())) {}
func create(savepoint: String, onCompletion: @escaping ((QueryResult) -> ())) {}

func execute(preparedStatement: PreparedStatement, parameters: [Any?], onCompletion: @escaping ((QueryResult) -> ())) {}
func rollback(to savepoint: String, onCompletion: @escaping ((QueryResult) -> ())) {}

func execute(preparedStatement: PreparedStatement, parameters: [String:Any?], onCompletion: @escaping ((QueryResult) -> ())) {}
func release(savepoint: String, onCompletion: @escaping ((QueryResult) -> ())) {}

func release(preparedStatement: PreparedStatement, onCompletion: @escaping ((QueryResult) -> ())) {}
}

class DummyResultFetcher: ResultFetcher {
Expand All @@ -138,19 +145,55 @@ class DummyResultFetcher: ResultFetcher {
}
}

func fetchNext() -> [Any?]? {
func fetchNext(callback: @escaping (([Any?]?, Error?)) -> ()) {
if fetched < numberOfRows {
fetched += 1
return rows[fetched - 1]
callback((rows[fetched - 1], nil))
}
return nil
callback((nil, nil))
}

func fetchNext(callback: ([Any?]?) ->()) {
callback(fetchNext())
func fetchTitles(callback: @escaping (([String]?, Error?)) -> ()) {
callback((titles, nil))
}

func fetchTitles() -> [String] {
return titles
func done() {}
}

class DummySQLColumnBuilder: ColumnCreator {
func buildColumn(for column: Column, using queryBuilder: QueryBuilder) -> String? {
guard let type = column.type else {
return nil
}

var result = column.name
let identifierQuoteCharacter = queryBuilder.substitutions[QueryBuilder.QuerySubstitutionNames.identifierQuoteCharacter.rawValue]
if !result.hasPrefix(identifierQuoteCharacter) {
result = identifierQuoteCharacter + result + identifierQuoteCharacter + " "
}

var typeString = type.create(queryBuilder: queryBuilder)
if let length = column.length {
typeString += "(\(length))"
}

if column.isPrimaryKey {
result += " PRIMARY KEY"
}
if column.isNotNullable {
result += " NOT NULL"
}
if column.isUnique {
result += " UNIQUE"
}
if let checkExpression = column.checkExpression {
result += checkExpression.contains(column.name) ? " CHECK (" + checkExpression.replacingOccurrences(of: column.name, with: "\"\(column.name)\"") + ")" : " CHECK (" + checkExpression + ")"
}
if let collate = column.collate {
result += " COLLATE \"" + collate + "\""
}
return result
}


}
Loading

0 comments on commit ee7f640

Please sign in to comment.