Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Sources/MongoSwift/BSON/BSON.swift
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public enum BSON {

/// Return this BSON as an `Int` if possible.
/// This will coerce non-integer numeric cases (e.g. `.double`) into an `Int` if such coercion would be lossless.
public func asInt() -> Int? {
public func toInt() -> Int? {
switch self {
case let .int32(value):
return Int(value)
Expand All @@ -239,7 +239,7 @@ public enum BSON {

/// Return this BSON as an `Int32` if possible.
/// This will coerce numeric cases (e.g. `.double`) into an `Int32` if such coercion would be lossless.
public func asInt32() -> Int32? {
public func toInt32() -> Int32? {
switch self {
case let .int32(value):
return value
Expand All @@ -254,7 +254,7 @@ public enum BSON {

/// Return this BSON as an `Int64` if possible.
/// This will coerce numeric cases (e.g. `.double`) into an `Int64` if such coercion would be lossless.
public func asInt64() -> Int64? {
public func toInt64() -> Int64? {
switch self {
case let .int32(value):
return Int64(value)
Expand All @@ -269,12 +269,12 @@ public enum BSON {

/// Return this BSON as a `Double` if possible.
/// This will coerce numeric cases (e.g. `.decimal128`) into a `Double` if such coercion would be lossless.
public func asDouble() -> Double? {
public func toDouble() -> Double? {
switch self {
case let .double(d):
return d
default:
guard let intValue = self.asInt() else {
guard let intValue = self.toInt() else {
return nil
}
return Double(intValue)
Expand All @@ -283,7 +283,7 @@ public enum BSON {

/// Return this BSON as a `Decimal128` if possible.
/// This will coerce numeric cases (e.g. `.double`) into a `Decimal128` if such coercion would be lossless.
public func asDecimal128() -> Decimal128? {
public func toDecimal128() -> Decimal128? {
switch self {
case let .decimal128(d):
return d
Expand Down
2 changes: 1 addition & 1 deletion Sources/MongoSwift/BSON/BSONDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ extension _BSONDecoder {
case .binary:
let binary = try self.unboxCustom(value) { $0.binaryValue }
do {
return try UUID(from: binary)
return try binary.toUUID()
} catch {
throw DecodingError.dataCorrupted(
DecodingError.Context(
Expand Down
6 changes: 3 additions & 3 deletions Sources/MongoSwift/BSON/BSONEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public class BSONEncoder {
)
}

return dict.asDocument()
return dict.toDocument()
}

/**
Expand Down Expand Up @@ -778,7 +778,7 @@ private class MutableDictionary: BSONValue {
fileprivate static var bsonType: BSONType { .document }

// This is unused
fileprivate var bson: BSON { .document(self.asDocument()) }
fileprivate var bson: BSON { .document(self.toDocument()) }

// rather than using a dictionary, do this so we preserve key orders
fileprivate var keys = [String]()
Expand Down Expand Up @@ -806,7 +806,7 @@ private class MutableDictionary: BSONValue {
}

/// Converts self to a `Document` with equivalent key-value pairs.
fileprivate func asDocument() -> Document {
fileprivate func toDocument() -> Document {
var doc = Document()
for i in 0..<self.keys.count {
doc[self.keys[i]] = self.values[i].bson
Expand Down
69 changes: 31 additions & 38 deletions Sources/MongoSwift/BSON/BSONValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ extension Array: BSONValue where Element == BSON {
}

/// Attempts to map this `[BSON]` to a `[T]`, where `T` is a `BSONValue`.
internal func asArrayOf<T: BSONValue>(_: T.Type) -> [T]? {
internal func toArrayOf<T: BSONValue>(_: T.Type) -> [T]? {
var result: [T] = []
for element in self {
guard let bsonValue = element.bsonValue as? T else {
Expand Down Expand Up @@ -321,6 +321,27 @@ public struct BSONBinary: BSONValue, Equatable, Codable, Hashable {
return try self.init(data: dataObj, subtype: UInt8(subtype.rawValue))
})
}

/// Converts this `BSONBinary` instance to a `UUID`.
/// - Throws:
/// - `InvalidArgumentError` if a non-UUID subtype is set on this `BSONBinary`.
public func toUUID() throws -> UUID {
guard [Subtype.uuid.rawValue, Subtype.uuidDeprecated.rawValue].contains(self.subtype) else {
throw InvalidArgumentError(
message: "Expected a UUID binary subtype, got subtype \(self.subtype) instead."
)
}

let data = self.data
let uuid: uuid_t = (
data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15]
)

return UUID(uuid: uuid)
}
}

/// An extension of `Bool` to represent the BSON Boolean type.
Expand Down Expand Up @@ -886,34 +907,6 @@ extension BSONObjectID: Hashable {
}
}

/// Extension to allow a `UUID` to be initialized from a `BSONBinary`.
extension UUID {
/// Initializes a `UUID` instance from a `BSONBinary`.
/// - Throws:
/// - `InvalidArgumentError` if a non-UUID subtype is set on the `BSONBinary`.
public init(from binary: BSONBinary) throws {
guard [
BSONBinary.Subtype.uuid.rawValue,
BSONBinary.Subtype.uuidDeprecated.rawValue
].contains(binary.subtype) else {
throw InvalidArgumentError(
message: "Expected a UUID binary type " +
"(\(BSONBinary.Subtype.uuid)), got \(binary.subtype) instead."
)
}

let data = binary.data
let uuid: uuid_t = (
data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11],
data[12], data[13], data[14], data[15]
)

self.init(uuid: uuid)
}
}

// A mapping of regex option characters to their equivalent `NSRegularExpression` option.
// note that there is a BSON regexp option 'l' that `NSRegularExpression`
// doesn't support. The flag will be dropped if BSON containing it is parsed,
Expand All @@ -926,7 +919,7 @@ private let regexOptsMap: [Character: NSRegularExpression.Options] = [
"x": .allowCommentsAndWhitespace
]

/// An extension of `NSRegularExpression` to allow it to be initialized from a `BSONRegularExpression`.
/// An extension of `NSRegularExpression` to support conversion to and from `BSONRegularExpression`.
extension NSRegularExpression {
/// Convert a string of options flags into an equivalent `NSRegularExpression.Options`
internal static func optionsFromString(_ stringOptions: String) -> NSRegularExpression.Options {
Expand All @@ -945,14 +938,6 @@ extension NSRegularExpression {
for (char, o) in regexOptsMap { if options.contains(o) { optsString += String(char) } }
return String(optsString.sorted())
}

/// Initializes a new `NSRegularExpression` with the pattern and options of the provided `BSONRegularExpression`.
/// Note: `NSRegularExpression` does not support the `l` locale dependence option, so it will
/// be omitted if set on the provided `BSONRegularExpression`.
public convenience init(from regex: BSONRegularExpression) throws {
let opts = NSRegularExpression.optionsFromString(regex.options)
try self.init(pattern: regex.pattern, options: opts)
}
}

/// A struct to represent a BSON regular expression.
Expand Down Expand Up @@ -1016,6 +1001,14 @@ public struct BSONRegularExpression: BSONValue, Equatable, Codable, Hashable {
return self.init(pattern: patternString, options: optionsString)
})
}

/// Converts this `BSONRegularExpression` to an `NSRegularExpression`.
/// Note: `NSRegularExpression` does not support the `l` locale dependence option, so it will be omitted if it was
/// set on this instance.
public func toNSRegularExpression() throws -> NSRegularExpression {
let opts = NSRegularExpression.optionsFromString(self.options)
return try NSRegularExpression(pattern: self.pattern, options: opts)
}
}

/// An extension of String to represent the BSON string type.
Expand Down
14 changes: 7 additions & 7 deletions Sources/MongoSwift/MongoCollection+BulkWrite.swift
Original file line number Diff line number Diff line change
Expand Up @@ -408,22 +408,22 @@ public struct BulkWriteResult: Decodable {
return nil
}

self.deletedCount = try reply.getValue(for: MongocKeys.deletedCount.rawValue)?.asInt() ?? 0
self.insertedCount = try reply.getValue(for: MongocKeys.insertedCount.rawValue)?.asInt() ?? 0
self.deletedCount = try reply.getValue(for: MongocKeys.deletedCount.rawValue)?.toInt() ?? 0
self.insertedCount = try reply.getValue(for: MongocKeys.insertedCount.rawValue)?.toInt() ?? 0
self.insertedIDs = insertedIDs
self.matchedCount = try reply.getValue(for: MongocKeys.matchedCount.rawValue)?.asInt() ?? 0
self.modifiedCount = try reply.getValue(for: MongocKeys.modifiedCount.rawValue)?.asInt() ?? 0
self.upsertedCount = try reply.getValue(for: MongocKeys.upsertedCount.rawValue)?.asInt() ?? 0
self.matchedCount = try reply.getValue(for: MongocKeys.matchedCount.rawValue)?.toInt() ?? 0
self.modifiedCount = try reply.getValue(for: MongocKeys.modifiedCount.rawValue)?.toInt() ?? 0
self.upsertedCount = try reply.getValue(for: MongocKeys.upsertedCount.rawValue)?.toInt() ?? 0

var upsertedIDs = [Int: BSON]()

if let upserted = try reply.getValue(for: MongocKeys.upserted.rawValue)?.arrayValue {
guard let upserted = upserted.asArrayOf(Document.self) else {
guard let upserted = upserted.toArrayOf(Document.self) else {
throw InternalError(message: "\"upserted\" array did not contain only documents")
}

for upsert in upserted {
guard let index = try upsert.getValue(for: "index")?.asInt() else {
guard let index = try upsert.getValue(for: "index")?.toInt() else {
throw InternalError(message: "Could not cast upserted index to `Int`")
}
upsertedIDs[index] = upsert["_id"]
Expand Down
8 changes: 4 additions & 4 deletions Sources/MongoSwift/MongoCollection+FindAndModify.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ internal protocol FindAndModifyOptionsConvertible {
/// Converts `self` to a `FindAndModifyOptions`
///
/// - Throws: `InvalidArgumentError` if any of the options are invalid.
func asFindAndModifyOptions() throws -> FindAndModifyOptions
func toFindAndModifyOptions() throws -> FindAndModifyOptions
}

/// Options to use when executing a `findOneAndDelete` command on a `MongoCollection`.
Expand All @@ -158,7 +158,7 @@ public struct FindOneAndDeleteOptions: FindAndModifyOptionsConvertible, Decodabl
/// An optional `WriteConcern` to use for the command.
public var writeConcern: WriteConcern?

internal func asFindAndModifyOptions() throws -> FindAndModifyOptions {
internal func toFindAndModifyOptions() throws -> FindAndModifyOptions {
try FindAndModifyOptions(
collation: self.collation,
maxTimeMS: self.maxTimeMS,
Expand Down Expand Up @@ -211,7 +211,7 @@ public struct FindOneAndReplaceOptions: FindAndModifyOptionsConvertible, Decodab
/// An optional `WriteConcern` to use for the command.
public var writeConcern: WriteConcern?

internal func asFindAndModifyOptions() throws -> FindAndModifyOptions {
internal func toFindAndModifyOptions() throws -> FindAndModifyOptions {
try FindAndModifyOptions(
bypassDocumentValidation: self.bypassDocumentValidation,
collation: self.collation,
Expand Down Expand Up @@ -275,7 +275,7 @@ public struct FindOneAndUpdateOptions: FindAndModifyOptionsConvertible, Decodabl
/// An optional `WriteConcern` to use for the command.
public var writeConcern: WriteConcern?

internal func asFindAndModifyOptions() throws -> FindAndModifyOptions {
internal func toFindAndModifyOptions() throws -> FindAndModifyOptions {
try FindAndModifyOptions(
arrayFilters: self.arrayFilters,
bypassDocumentValidation: self.bypassDocumentValidation,
Expand Down
16 changes: 8 additions & 8 deletions Sources/MongoSwift/MongoCollection+Write.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ extension MongoCollection {
options: InsertOneOptions? = nil,
session: ClientSession? = nil
) -> EventLoopFuture<InsertOneResult?> {
self.bulkWrite([.insertOne(value)], options: options?.asBulkWriteOptions(), session: session)
self.bulkWrite([.insertOne(value)], options: options?.toBulkWriteOptions(), session: session)
.flatMapThrowing { try InsertOneResult(from: $0) }
.flatMapErrorThrowing { throw convertBulkWriteError($0) }
}
Expand Down Expand Up @@ -93,7 +93,7 @@ extension MongoCollection {
) -> EventLoopFuture<UpdateResult?> {
let modelOptions = ReplaceOneModelOptions(collation: options?.collation, upsert: options?.upsert)
let model = WriteModel.replaceOne(filter: filter, replacement: replacement, options: modelOptions)
return self.bulkWrite([model], options: options?.asBulkWriteOptions(), session: session)
return self.bulkWrite([model], options: options?.toBulkWriteOptions(), session: session)
.flatMapThrowing { try UpdateResult(from: $0) }
.flatMapErrorThrowing { throw convertBulkWriteError($0) }
}
Expand Down Expand Up @@ -131,7 +131,7 @@ extension MongoCollection {
upsert: options?.upsert
)
let model: WriteModel<CollectionType> = .updateOne(filter: filter, update: update, options: modelOptions)
return self.bulkWrite([model], options: options?.asBulkWriteOptions(), session: session)
return self.bulkWrite([model], options: options?.toBulkWriteOptions(), session: session)
.flatMapThrowing { try UpdateResult(from: $0) }
.flatMapErrorThrowing { throw convertBulkWriteError($0) }
}
Expand Down Expand Up @@ -169,7 +169,7 @@ extension MongoCollection {
upsert: options?.upsert
)
let model: WriteModel<CollectionType> = .updateMany(filter: filter, update: update, options: modelOptions)
return self.bulkWrite([model], options: options?.asBulkWriteOptions(), session: session)
return self.bulkWrite([model], options: options?.toBulkWriteOptions(), session: session)
.flatMapThrowing { try UpdateResult(from: $0) }
.flatMapErrorThrowing { throw convertBulkWriteError($0) }
}
Expand Down Expand Up @@ -201,7 +201,7 @@ extension MongoCollection {
) -> EventLoopFuture<DeleteResult?> {
let modelOptions = DeleteModelOptions(collation: options?.collation)
let model: WriteModel<CollectionType> = .deleteOne(filter, options: modelOptions)
return self.bulkWrite([model], options: options?.asBulkWriteOptions(), session: session)
return self.bulkWrite([model], options: options?.toBulkWriteOptions(), session: session)
.flatMapThrowing { try DeleteResult(from: $0) }
.flatMapErrorThrowing { throw convertBulkWriteError($0) }
}
Expand Down Expand Up @@ -233,7 +233,7 @@ extension MongoCollection {
) -> EventLoopFuture<DeleteResult?> {
let modelOptions = DeleteModelOptions(collation: options?.collation)
let model: WriteModel<CollectionType> = .deleteMany(filter, options: modelOptions)
return self.bulkWrite([model], options: options?.asBulkWriteOptions(), session: session)
return self.bulkWrite([model], options: options?.toBulkWriteOptions(), session: session)
.flatMapThrowing { try DeleteResult(from: $0) }
.flatMapErrorThrowing { throw convertBulkWriteError($0) }
}
Expand All @@ -243,12 +243,12 @@ extension MongoCollection {
private protocol BulkWriteOptionsConvertible {
var bypassDocumentValidation: Bool? { get }
var writeConcern: WriteConcern? { get }
func asBulkWriteOptions() -> BulkWriteOptions
func toBulkWriteOptions() -> BulkWriteOptions
}

/// Default implementation of the protocol.
private extension BulkWriteOptionsConvertible {
func asBulkWriteOptions() -> BulkWriteOptions {
func toBulkWriteOptions() -> BulkWriteOptions {
BulkWriteOptions(
bypassDocumentValidation: self.bypassDocumentValidation,
writeConcern: self.writeConcern
Expand Down
6 changes: 3 additions & 3 deletions Sources/MongoSwift/MongoError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ private func parseMongocError(_ error: bson_error_t, reply: Document?) -> MongoE
let code = mongoc_error_code_t(rawValue: error.code)
let message = toErrorString(error)

let errorLabels = reply?["errorLabels"]?.arrayValue?.asArrayOf(String.self)
let errorLabels = reply?["errorLabels"]?.arrayValue?.toArrayOf(String.self)
let codeName = reply?["codeName"]?.stringValue ?? ""

switch (domain, code) {
Expand Down Expand Up @@ -352,7 +352,7 @@ internal func extractMongoError(error bsonError: bson_error_t, reply: Document?
return WriteError(
writeFailure: writeError,
writeConcernFailure: wcError,
errorLabels: serverReply["errorLabels"]?.arrayValue?.asArrayOf(String.self)
errorLabels: serverReply["errorLabels"]?.arrayValue?.toArrayOf(String.self)
)
} catch {
return fallback
Expand Down Expand Up @@ -439,7 +439,7 @@ internal func extractBulkWriteError<T: Codable>(
writeConcernFailure: try extractWriteConcernError(from: reply),
otherError: other,
result: errResult,
errorLabels: reply["errorLabels"]?.arrayValue?.asArrayOf(String.self)
errorLabels: reply["errorLabels"]?.arrayValue?.toArrayOf(String.self)
)
} catch {
return fallback
Expand Down
2 changes: 1 addition & 1 deletion Sources/MongoSwift/Operations/FindAndModifyOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ internal struct FindAndModifyOperation<T: Codable>: Operation {
internal func execute(using connection: Connection, session: ClientSession?) throws -> T? {
// we always need to send *something*, as findAndModify requires one of "remove"
// or "update" to be set.
let opts = try self.options?.asFindAndModifyOptions() ?? FindAndModifyOptions()
let opts = try self.options?.toFindAndModifyOptions() ?? FindAndModifyOptions()
if let session = session { try opts.setSession(session) }
if let update = self.update { try opts.setUpdate(update) }

Expand Down
2 changes: 1 addition & 1 deletion Sources/MongoSwift/Operations/ListDatabasesOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ internal struct ListDatabasesOperation: Operation {
}
}

guard let databases = reply["databases"]?.arrayValue?.asArrayOf(Document.self) else {
guard let databases = reply["databases"]?.arrayValue?.toArrayOf(Document.self) else {
throw InternalError(message: "Invalid server response: \(reply)")
}

Expand Down
Loading