-
-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add SQLRow decoding support * change spelling to model:, add update builder helper * row coder updates * fix tests
- Loading branch information
1 parent
f0e0029
commit d09b552
Showing
5 changed files
with
231 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,15 @@ | ||
public protocol SQLRow { | ||
var allColumns: [String] { get } | ||
func contains(column: String) -> Bool | ||
func decodeNil(column: String) throws -> Bool | ||
func decode<D>(column: String, as type: D.Type) throws -> D | ||
where D: Decodable | ||
} | ||
|
||
extension SQLRow { | ||
public func decode<D>(model type: D.Type, prefix: String? = nil) throws -> D | ||
where D: Decodable | ||
{ | ||
try SQLRowDecoder().decode(D.self, from: self, prefix: prefix) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
struct SQLRowDecoder { | ||
func decode<T>(_ type: T.Type, from row: SQLRow, prefix: String? = nil) throws -> T | ||
where T: Decodable | ||
{ | ||
return try T.init(from: _Decoder(prefix: prefix, row: row)) | ||
} | ||
|
||
enum _Error: Error { | ||
case nesting | ||
case unkeyedContainer | ||
case singleValueContainer | ||
} | ||
|
||
struct _Decoder: Decoder { | ||
let prefix: String? | ||
let row: SQLRow | ||
var codingPath: [CodingKey] = [] | ||
var userInfo: [CodingUserInfoKey : Any] { | ||
[:] | ||
} | ||
|
||
func container<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key> | ||
where Key: CodingKey | ||
{ | ||
.init(_KeyedDecoder(prefix: self.prefix, row: self.row, codingPath: self.codingPath)) | ||
} | ||
|
||
func unkeyedContainer() throws -> UnkeyedDecodingContainer { | ||
throw _Error.unkeyedContainer | ||
} | ||
|
||
func singleValueContainer() throws -> SingleValueDecodingContainer { | ||
throw _Error.singleValueContainer | ||
} | ||
} | ||
|
||
struct _KeyedDecoder<Key>: KeyedDecodingContainerProtocol | ||
where Key: CodingKey | ||
{ | ||
let prefix: String? | ||
let row: SQLRow | ||
var codingPath: [CodingKey] = [] | ||
var allKeys: [Key] { | ||
self.row.allColumns.compactMap { | ||
Key.init(stringValue: $0) | ||
} | ||
} | ||
|
||
func column(for key: Key) -> String { | ||
if let prefix = self.prefix { | ||
return prefix + key.stringValue | ||
} else { | ||
return key.stringValue | ||
} | ||
} | ||
|
||
func contains(_ key: Key) -> Bool { | ||
self.row.contains(column: self.column(for: key)) | ||
} | ||
|
||
func decodeNil(forKey key: Key) throws -> Bool { | ||
try self.row.decodeNil(column: self.column(for: key)) | ||
} | ||
|
||
func decode<T>(_ type: T.Type, forKey key: Key) throws -> T | ||
where T : Decodable | ||
{ | ||
try self.row.decode(column: self.column(for: key), as: T.self) | ||
} | ||
|
||
func nestedContainer<NestedKey>( | ||
keyedBy type: NestedKey.Type, | ||
forKey key: Key | ||
) throws -> KeyedDecodingContainer<NestedKey> | ||
where NestedKey : CodingKey | ||
{ | ||
throw _Error.nesting | ||
} | ||
|
||
func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer { | ||
throw _Error.nesting | ||
} | ||
|
||
func superDecoder() throws -> Decoder { | ||
_Decoder(prefix: self.prefix, row: self.row, codingPath: self.codingPath) | ||
} | ||
|
||
func superDecoder(forKey key: Key) throws -> Decoder { | ||
throw _Error.nesting | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters