Skip to content

Commit e2da7f7

Browse files
authored
SWIFT-632 Drop Swift 4.2 support (#330)
1 parent 19a3d0a commit e2da7f7

File tree

12 files changed

+103
-98
lines changed

12 files changed

+103
-98
lines changed

.evergreen/config.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -379,14 +379,15 @@ axes:
379379
- id: swift-version
380380
display_name: "Swift"
381381
values:
382-
- id: "4.2"
383-
display_name: "Swift 4.2"
384-
variables:
385-
SWIFT_VERSION: "4.2.4"
386382
- id: "5.0"
387383
display_name: "Swift 5.0"
388384
variables:
389-
SWIFT_VERSION: "5.0"
385+
SWIFT_VERSION: "5.0.3"
386+
# TODO SWIFT-634: uncomment this
387+
# - id: "5.1"
388+
# display_name: "Swift 5.1"
389+
# variables:
390+
# SWIFT_VERSION: "5.1"
390391

391392
- id: ssl
392393
display_name: SSL

.evergreen/run-atlas-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ set -o errexit # Exit the script with error if any of the commands fail
33

44
# variables
55
PROJECT_DIRECTORY=${PROJECT_DIRECTORY:-$PWD}
6-
SWIFT_VERSION=${SWIFT_VERSION:-4.2}
6+
SWIFT_VERSION=${SWIFT_VERSION:-5.0}
77
INSTALL_DIR="${PROJECT_DIRECTORY}/opt"
88
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
99
EXTRA_FLAGS="-Xlinker -rpath -Xlinker ${INSTALL_DIR}/lib"

.evergreen/run-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set -o errexit # Exit the script with error if any of the commands fail
55
# variables
66
PROJECT_DIRECTORY=${PROJECT_DIRECTORY:-$PWD}
77
MONGODB_URI=${MONGODB_URI:-"NO_URI_PROVIDED"}
8-
SWIFT_VERSION=${SWIFT_VERSION:-4.2}
8+
SWIFT_VERSION=${SWIFT_VERSION:-5.0}
99
INSTALL_DIR="${PROJECT_DIRECTORY}/opt"
1010
TOPOLOGY=${TOPOLOGY:-single}
1111
OS=$(uname -s | tr '[:upper:]' '[:lower:]')

.travis.yml

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,33 +19,19 @@ jobs:
1919
- make linuxmain SOURCERY=${PWD}/sourcery/bin/sourcery
2020
- git diff --exit-code Tests/LinuxMain.swift
2121

22-
- stage: tests
23-
os: osx
24-
osx_image: xcode10.1
25-
env: SWIFT_VERSION=4.2.4
26-
27-
- stage: tests
28-
os: osx
29-
osx_image: xcode10.2
30-
env: SWIFT_VERSION=4.2.4
31-
3222
- stage: tests
3323
os: osx
3424
osx_image: xcode10.2
3525
env: SWIFT_VERSION=5.0
3626

37-
- stage: tests
38-
os: linux
39-
env: SWIFT_VERSION=4.2.4
40-
4127
- stage: tests
4228
os: linux
4329
env: SWIFT_VERSION=5.0
4430

4531
- stage: post-tests
4632
name: code coverage
4733
os: osx
48-
osx_image: xcode10.1
34+
osx_image: xcode10.2
4935
script: make coverage
5036
after_success: bash <(curl -s https://codecov.io/bash)
5137

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:4.2
1+
// swift-tools-version:5.0
22
import PackageDescription
33
let package = Package(
44
name: "MongoSwift",

README.md

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@ The official [MongoDB](https://www.mongodb.com/) driver for Swift.
88
- [Documentation](#documentation)
99
- [Bugs/Feature Requests](#bugs--feature-requests)
1010
- [Installation](#installation)
11-
- [macOS and Linux](#macos-and-linux)
12-
- [Step 1: Install the MongoDB C Driver](#step-1-install-the-mongodb-c-driver)
13-
- [Step 2: Install MongoSwift](#step-2-install-mongoswift)
14-
- [iOS, tvOS, and watchOS](#ios-tvos-and-watchos)
11+
- [Step 1: Install the MongoDB C Driver](#step-1-install-the-mongodb-c-driver)
12+
- [Step 2: Install MongoSwift](#step-2-install-mongoswift)
1513
- [Example Usage](#example-usage)
1614
- [Connect to MongoDB and Create a Collection](#connect-to-mongodb-and-create-a-collection)
1715
- [Create and Insert a Document](#create-and-insert-a-document)
@@ -35,13 +33,11 @@ Bug reports in JIRA for all driver projects (i.e. NODE, PYTHON, CSHARP, JAVA) an
3533
Core Server (i.e. SERVER) project are **public**.
3634

3735
## Installation
38-
`MongoSwift` works with Swift 4.2+.
36+
`MongoSwift` works with Swift 5.0+ on MacOS and Linux.
3937

40-
### macOS and Linux
38+
Installation is supported via [Swift Package Manager](https://swift.org/package-manager/).
4139

42-
Installation on macOS and Linux is supported via [Swift Package Manager](https://swift.org/package-manager/).
43-
44-
#### Step 1: Install the MongoDB C Driver
40+
### Step 1: Install the MongoDB C Driver
4541
The driver wraps the MongoDB C driver, and using it requires having the C driver's two components, `libbson` and `libmongoc`, installed on your system. **The minimum required version of the C Driver is 1.15.1**.
4642

4743
*On a Mac*, you can install both components at once using [Homebrew](https://brew.sh/):
@@ -51,13 +47,13 @@ The driver wraps the MongoDB C driver, and using it requires having the C driver
5147

5248
See example installation from source on Ubuntu in [Docker](https://github.com/mongodb/mongo-swift-driver/tree/master/Examples/Docker).
5349

54-
#### Step 2: Install MongoSwift
50+
### Step 2: Install MongoSwift
5551
*Please follow the instructions in the previous section on installing the MongoDB C Driver before proceeding.*
5652

5753
Add MongoSwift to your dependencies in `Package.swift`:
5854

5955
```swift
60-
// swift-tools-version:4.2
56+
// swift-tools-version:5.0
6157
import PackageDescription
6258

6359
let package = Package(
@@ -73,27 +69,6 @@ let package = Package(
7369

7470
Then run `swift build` to download, compile, and link all your dependencies.
7571

76-
## iOS, tvOS, and watchOS
77-
Installation is supported via [CocoaPods](https://cocoapods.org/).
78-
79-
The pod includes as a dependency an embedded version of the MongoDB C Driver, meant for use on these OSes.
80-
81-
**Note**: the embedded driver currently does not support SSL. See [#141](https://github.com/mongodb/mongo-swift-driver/issues/141) and [CDRIVER-2850](https://jira.mongodb.org/browse/CDRIVER-2850) for more information.
82-
83-
Add `MongoSwift` to your Podfile as follows:
84-
85-
86-
```ruby
87-
platform :ios, '11.0'
88-
use_frameworks!
89-
90-
target 'MyApp' do
91-
pod 'MongoSwift', '~> VERSION.STRING.HERE'
92-
end
93-
```
94-
95-
Then run `pod install` to install your project's dependencies.
96-
9772
## Example Usage
9873

9974
Note: You should call `cleanupMongoSwift()` exactly once at the end of your application to release all memory and other resources allocated by `libmongoc`.
@@ -164,8 +139,8 @@ Note that `Document` conforms to `Collection`, so useful methods from
164139
all available. However, runtime guarantees are not yet met for many of these
165140
methods.
166141

167-
### Usage With Kitura and Vapor
168-
The `Examples/` directory contains sample projects that use the driver with [Kitura](https://github.com/mongodb/mongo-swift-driver/tree/master/Examples/Kitura) and [Vapor](https://github.com/mongodb/mongo-swift-driver/tree/master/Examples/Vapor).
142+
### Usage With Kitura, Vapor, and Perfect
143+
The `Examples/` directory contains sample projects that use the driver with [Kitura](https://github.com/mongodb/mongo-swift-driver/tree/master/Examples/Kitura), [Vapor](https://github.com/mongodb/mongo-swift-driver/tree/master/Examples/Vapor), and [Perfect](https://github.com/mongodb/mongo-swift-driver/tree/master/Examples/Perfect).
169144

170145
## Development Instructions
171146

Sources/MongoSwift/BSON/BSONEncoder.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ private class MutableDictionary: BSONValue {
769769

770770
subscript(key: String) -> BSONValue? {
771771
get {
772-
guard let index = keys.index(of: key) else {
772+
guard let index = keys.firstIndex(of: key) else {
773773
return nil
774774
}
775775
return values[index]
@@ -779,7 +779,7 @@ private class MutableDictionary: BSONValue {
779779
keys.append(key)
780780
values.append(newValue)
781781
} else {
782-
guard let index = keys.index(of: key) else {
782+
guard let index = keys.firstIndex(of: key) else {
783783
return
784784
}
785785
values.remove(at: index)

Sources/MongoSwift/BSON/BSONValue.swift

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ public struct Binary: BSONValue, Equatable, Codable, Hashable {
302302
public init(from uuid: UUID) throws {
303303
let uuidt = uuid.uuid
304304

305-
let uuidData = Data(bytes: [
305+
let uuidData = Data([
306306
uuidt.0, uuidt.1, uuidt.2, uuidt.3,
307307
uuidt.4, uuidt.5, uuidt.6, uuidt.7,
308308
uuidt.8, uuidt.9, uuidt.10, uuidt.11,
@@ -509,11 +509,11 @@ public struct Decimal128: BSONNumber, Equatable, Codable, CustomStringConvertibl
509509

510510
public var description: String {
511511
var str = Data(count: Int(BSON_DECIMAL128_STRING))
512-
return str.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<Int8>) in
513-
withUnsafePointer(to: self.decimal128) { ptr in
514-
bson_decimal128_to_string(ptr, bytes)
512+
return str.withUnsafeMutableCStringPointer { strPtr in
513+
withUnsafePointer(to: self.decimal128) { decPtr in
514+
bson_decimal128_to_string(decPtr, strPtr)
515515
}
516-
return String(cString: bytes)
516+
return String(cString: strPtr)
517517
}
518518
}
519519

@@ -887,11 +887,11 @@ public struct ObjectId: BSONValue, Equatable, CustomStringConvertible, Codable {
887887
/// This `ObjectId`'s data represented as a `String`.
888888
public var hex: String {
889889
var str = Data(count: 25)
890-
return str.withUnsafeMutableBytes { (rawBuffer: UnsafeMutablePointer<Int8>) in
890+
return str.withUnsafeMutableCStringPointer { strPtr in
891891
withUnsafePointer(to: self.oid) { oidPtr in
892-
bson_oid_to_string(oidPtr, rawBuffer)
892+
bson_oid_to_string(oidPtr, strPtr)
893893
}
894-
return String(cString: rawBuffer)
894+
return String(cString: strPtr)
895895
}
896896
}
897897

@@ -1374,3 +1374,20 @@ internal func getDecodingError<T: BSONValue>(type: T.Type, decoder: Decoder) ->
13741374
// Non-BSONDecoders are currently unsupported
13751375
return bsonDecodingUnsupportedError(type: T.self, at: decoder.codingPath)
13761376
}
1377+
1378+
extension Data {
1379+
/// Gets access to the start of the data buffer in the form of an UnsafeMutablePointer<CChar>. Useful for calling C
1380+
/// API methods that expect a location for a string. **You must only call this method on Data instances with
1381+
/// count > 0 so that the base address will exist.**
1382+
/// Based on https://mjtsai.com/blog/2019/03/27/swift-5-released/
1383+
fileprivate mutating func withUnsafeMutableCStringPointer<T>(body: (UnsafeMutablePointer<CChar>) throws -> T)
1384+
rethrows -> T {
1385+
return try self.withUnsafeMutableBytes { (rawPtr: UnsafeMutableRawBufferPointer) in
1386+
let bufferPtr = rawPtr.bindMemory(to: CChar.self)
1387+
// baseAddress is non-nil as long as Data's count > 0.
1388+
// swiftlint:disable:next force_unwrapping
1389+
let bytesPtr = bufferPtr.baseAddress!
1390+
return try body(bytesPtr)
1391+
}
1392+
}
1393+
}

Sources/MongoSwift/BSON/Document.swift

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ extension Document {
335335
* - A `UserError.invalidArgumentError` if the data passed in is invalid JSON.
336336
*/
337337
public init(fromJSON: Data) throws {
338-
self._storage = DocumentStorage(stealing: try fromJSON.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) in
338+
self._storage = DocumentStorage(stealing: try fromJSON.withUnsafeBytePointer { bytes in
339339
var error = bson_error_t()
340340
guard let bson = bson_new_from_json(bytes, fromJSON.count, &error) else {
341341
if error.domain == BSON_ERROR_JSON {
@@ -356,11 +356,20 @@ extension Document {
356356
// see https://www.objc.io/blog/2018/02/13/string-to-data-and-back/
357357
try self.init(fromJSON: json.data(using: .utf8)!) // swiftlint:disable:this force_unwrapping
358358
}
359-
360-
/// Constructs a `Document` from raw BSON `Data`.
361-
public init(fromBSON: Data) {
362-
self._storage = DocumentStorage(stealing: fromBSON.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) in
363-
bson_new_from_data(bytes, fromBSON.count)
359+
/**
360+
* Constructs a `Document` from raw BSON `Data`.
361+
* - Throws:
362+
* - A `UserError.invalidArgumentError` if `bson` is too short or too long to be valid BSON.
363+
* - A `UserError.invalidArgumentError` if the first four bytes of `bson` do not contain `bson.count`.
364+
* - A `UserError.invalidArgumentError` if the final byte of `bson` is not a null byte.
365+
* - SeeAlso: http://bsonspec.org/
366+
*/
367+
public init(fromBSON bson: Data) throws {
368+
self._storage = DocumentStorage(stealing: try bson.withUnsafeBytePointer { bytes in
369+
guard let data = bson_new_from_data(bytes, bson.count) else {
370+
throw UserError.invalidArgumentError(message: "Invalid BSON data")
371+
}
372+
return data
364373
})
365374
}
366375

@@ -547,3 +556,17 @@ extension Document: Hashable {
547556
hasher.combine(self.rawBSON)
548557
}
549558
}
559+
560+
extension Data {
561+
/// Gets access to the start of the data buffer in the form of an UnsafePointer<UInt8>?. Useful for calling C API
562+
/// methods that expect the location of an uint8_t. The pointer provided to `body` will be null if the `Data` has
563+
/// count == 0.
564+
/// Based on https://mjtsai.com/blog/2019/03/27/swift-5-released/
565+
fileprivate func withUnsafeBytePointer<T>(body: (UnsafePointer<UInt8>?) throws -> T) rethrows -> T {
566+
return try self.withUnsafeBytes { (rawPtr: UnsafeRawBufferPointer) in
567+
let bufferPtr = rawPtr.bindMemory(to: UInt8.self)
568+
let bytesPtr = bufferPtr.baseAddress
569+
return try body(bytesPtr)
570+
}
571+
}
572+
}

Tests/LinuxMain.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ extension DocumentTests {
121121
("testDateDecodingStrategies", testDateDecodingStrategies),
122122
("testDataCodingStrategies", testDataCodingStrategies),
123123
("testIntegerRetrieval", testIntegerRetrieval),
124+
("testInvalidBSON", testInvalidBSON),
124125
]
125126
}
126127

0 commit comments

Comments
 (0)