Add modifyValue(_:,forKey:)

This adds and implements `open func modifyValue(_ v: Any?, forKey k: String) -> Any` to the `StORM` class.
The intent of this addition is to allow base classes to optionally change the data sent to the database. For example, I am using it to properly handle `Optional`s and the `Date` class in PostgreSQL as follows:
```swift
override func modifyValue(_ val: Any, forKey k: String) -> Any {
	var v = val
	if let o = val as? OptionalProtocol {
		if o.isSome() {
			v = o.unwrap() // not-nil
		} else {
			return ""  // nil
		}
	}
	// After this point, v is guarenteed to not be optional or nil
	
	if let d = v as? Date {
		return d.timestamptz
	}
	
	return v
}
```
The implementations of `OptionalProtocol` and `timestamptz` are irrelevant for this pr.

The `forKey` parameter is there in case someone wants to switch based on name, not on value.

The name is just a placeholder, so feel free to change it if you think of something better.
This commit is contained in:
thislooksfun 2017-08-10 00:48:39 -05:00 committed by GitHub
parent dde705a0a9
commit 6d27a7b86a
1 changed files with 10 additions and 8 deletions

View File

@ -45,7 +45,9 @@ open class StORM {
} }
return c return c
} }
open func modifyValue(_ v: Any, forKey k: String) -> Any { return v }
/// Returns a [(String,Any)] object representation of the current object. /// 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. /// If any object property begins with an underscore, or with "internal_" it is omitted from the response.
public func asData(_ offset: Int = 0) -> [(String, Any)] { public func asData(_ offset: Int = 0) -> [(String, Any)] {
@ -55,11 +57,11 @@ open class StORM {
for case let (label?, value) in mirror.children { for case let (label?, value) in mirror.children {
if count >= offset && !label.hasPrefix("internal_") && !label.hasPrefix("_") { if count >= offset && !label.hasPrefix("internal_") && !label.hasPrefix("_") {
if value is [String:Any] { if value is [String:Any] {
c.append((label, try! (value as! [String:Any]).jsonEncodedString())) c.append((label, modifyValue(try! (value as! [String:Any]).jsonEncodedString(), forKey: label)))
} else if value is [String] { } else if value is [String] {
c.append((label, (value as! [String]).joined(separator: ","))) c.append((label, modifyValue((value as! [String]).joined(separator: ","), forKey: label)))
} else { } else {
c.append((label, value)) c.append((label, modifyValue(value, forKey: label)))
} }
} }
count += 1 count += 1
@ -76,11 +78,11 @@ open class StORM {
for case let (label?, value) in mirror.children { for case let (label?, value) in mirror.children {
if count >= offset && !label.hasPrefix("internal_") && !label.hasPrefix("_") { if count >= offset && !label.hasPrefix("internal_") && !label.hasPrefix("_") {
if value is [String:Any] { if value is [String:Any] {
c[label] = try! (value as! [String:Any]).jsonEncodedString() c[label] = modifyValue(try! (value as! [String:Any]).jsonEncodedString(), forKey: label)
} else if value is [String] { } else if value is [String] {
c[label] = (value as! [String]).joined(separator: ",") c[label] = modifyValue((value as! [String]).joined(separator: ","), forKey: label)
} else { } else {
c[label] = value c[label] = modifyValue(value, forKey: label)
} }
} }
count += 1 count += 1
@ -93,7 +95,7 @@ open class StORM {
public func firstAsKey() -> (String, Any) { public func firstAsKey() -> (String, Any) {
let mirror = Mirror(reflecting: self) let mirror = Mirror(reflecting: self)
for case let (label?, value) in mirror.children { for case let (label?, value) in mirror.children {
return (label, value) return (label, modifyValue(value, forKey: label))
} }
return ("id", "unknown") return ("id", "unknown")
} }