Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed some ObjectId related issues and #1 issue #11

Merged
merged 4 commits into from
Nov 11, 2017
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
9 changes: 8 additions & 1 deletion Sources/Convenience.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,16 @@ extension MongoDBStORM {
self.error = StORMError.error("No id specified.")
throw error
}

let (collection, client) = try setupCollection()
let query = BSON()
query.append(key: "_id", string: idval as! String)
let id = "\(idval)"
if BSON.OID.isValidObjectId(id) {
let oid = BSON.OID(id)
query.append(oid: oid)
} else {
query.append(key: "_id", string: id)
}
let status = collection.remove(selector: query)
if "\(status)" != "success" {
LogFile.critical("MongoDB Delete error \(status)")
Expand Down
32 changes: 9 additions & 23 deletions Sources/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,19 @@
import Foundation
import PerfectMongoDB


extension BSON.OID
{
static func isValidObjectId(_ string: String) -> Bool {

#if os(Linux)
let lengthCondition = string.characters.count == 24
#else
let lengthCondition = string.count == 24
#endif
guard lengthCondition else {
return false
}

let allowed: [Character] = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]

#if os(Linux)
let collection = string.characters
#else
let collection = string
#endif

for character in collection {
guard allowed.contains(character) else {
return false
}
if let expression = try? NSRegularExpression(pattern: "[0-9a-f]{24}", options: []) {
#if os(Linux)
let range = NSMakeRange(0, string.characters.count)
#else
let range = NSMakeRange(0, string.count)
#endif
return expression.numberOfMatches(in: string, options: [], range: range) == 1
}

return true
return false
}
}
30 changes: 30 additions & 0 deletions Sources/MongoDBStORM.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,36 @@ open class MongoDBStORM: StORM, StORMProtocol {
}
}

/// Returns a [(String,Any)] object representation of the current object.
/// If any object property begins with an underscore, or with "internal_" it is omitted from the response.
override open func asData(_ offset: Int = 0) -> [(String, Any)] {
var c = [(String, Any)]()
var count = 0
let mirror = Mirror(reflecting: self)
for case let (label?, value) in mirror.children {
if count >= offset && !label.hasPrefix("internal_") && !label.hasPrefix("_") {
c.append((label, modifyValue(value, forKey: label)))
}
count += 1
}
return c
}

/// Returns a [String:Any] object representation of the current object.
/// If any object property begins with an underscore, or with "internal_" it is omitted from the response.
override open func asDataDict(_ offset: Int = 0) -> [String: Any] {
var c = [String: Any]()
var count = 0
let mirror = Mirror(reflecting: self)
for case let (label?, value) in mirror.children {
if count >= offset && !label.hasPrefix("internal_") && !label.hasPrefix("_") {
c[label] = modifyValue(value, forKey: label)
}
count += 1
}
return c
}

/// Generic "to" function
/// Defined as "open" as it is meant to be overridden by the child class.
///
Expand Down
108 changes: 90 additions & 18 deletions Tests/MongoDBStORMTests/MongoDBStORMTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ class User: MongoDBStORM {
var firstname : String = ""
var lastname : String = ""
var email : String = ""

var pseudonyms : [String] = [String]()
var data : [String: String] = [String: String]()

override init() {
super.init()
_collection = "users"
Expand All @@ -24,6 +26,8 @@ class User: MongoDBStORM {
firstname = this.data["firstname"] as? String ?? ""
lastname = this.data["lastname"] as? String ?? ""
email = this.data["email"] as? String ?? ""
pseudonyms = this.data["pseudonyms"] as? [String] ?? [String]()
data = this.data["data"] as? [String: String] ?? [String: String]()
}

func rows() -> [User] {
Expand Down Expand Up @@ -204,22 +208,34 @@ class MongoDBStORMTests: XCTestCase {
DELETE
============================================================================================= */
func testDelete() {
let obj = User()
let rand = Randoms.randomAlphaNumericString(length: 12)
do {
obj.id = rand
obj.firstname = "Mister"
obj.lastname = "PotatoHead"
obj.email = "[email protected]"
try obj.save()
} catch {
XCTFail("\(error)")
}
do {
try obj.delete()
} catch {
XCTFail("\(error)")
}

let ids = [BSON.OID.newObjectId(), Randoms.randomAlphaNumericString(length: 12)]

for id in ids {
let obj = User()
do {
obj.id = id
obj.firstname = "Mister"
obj.lastname = "PotatoHead"
obj.email = "[email protected]"
try obj.save()
} catch {
XCTFail("\(error)")
}
do {
try obj.delete()
} catch {
XCTFail("\(error)")
}

let fetchedObject = User()
do {
try fetchedObject.get(id)
XCTAssertTrue(fetchedObject.results.cursorData.totalRecords == 0, "\(id) still exists")
} catch {
XCTFail("\(error)")
}
}
}


Expand Down Expand Up @@ -301,7 +317,61 @@ class MongoDBStORMTests: XCTestCase {
}


func testArrayData() {
let obj = User()

let pseudonyms = ["Santa", "SantaClaus", "SC", "Potato", "Not Potato", "What else?"]
let id = obj.newObjectId()

obj.id = id
obj.pseudonyms = pseudonyms
do {
try obj.save()
} catch {
XCTFail("Save error: \(obj.error.string())")
}

let fetched = User()
fetched.id = id
do {
try fetched.get()
} catch {
XCTFail("Find error: \(obj.error.string())")
}

XCTAssertTrue(fetched.pseudonyms == pseudonyms, "Fetched data is not equal to saved")
}

func testDictionaryData()
{
let obj = User()

let data = [
"Foo": "Bar",
"True": "False",
"Yellow": "Potato"
]
let id = obj.newObjectId()

obj.id = id
obj.data = data
do {
try obj.save()
} catch {
XCTFail("Save error: \(obj.error.string())")
}

let fetched = User()
fetched.id = id
do {
try fetched.get()
} catch {
XCTFail("Find error: \(obj.error.string())")
}

XCTAssertTrue(fetched.data == data, "Fetched data is not equal to saved")
}

static var allTests : [(String, (MongoDBStORMTests) -> () throws -> Void)] {
return [
("testSaveNew", testSaveNew),
Expand All @@ -314,7 +384,9 @@ class MongoDBStORMTests: XCTestCase {
("testFind", testFindZero),
("testFind", testFind),
("testFindAll", testFindAll),
("testObjectIdValidation", testObjectIdValidation)
("testObjectIdValidation", testObjectIdValidation),
("testArrayData", testArrayData),
("testDictionaryData", testDictionaryData)
]
}

Expand Down