Skip to content

Commit

Permalink
implement model func
Browse files Browse the repository at this point in the history
  • Loading branch information
tanner0101 committed Jul 9, 2019
1 parent 1bde239 commit 435a3ac
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 38 deletions.
51 changes: 14 additions & 37 deletions Sources/SQLKit/Builders/SQLInsertBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,44 +31,20 @@ public final class SQLInsertBuilder: SQLQueryBuilder {
/// - parameters:
/// - value: `Encodable` value to insert.
/// - returns: Self for chaining.
public func value<E>(_ value: E) throws -> Self
public func model<E>(_ model: E) throws -> Self
where E: Encodable
{
return values([value])
}

/// Adds zero or more encodable values to be inserted. The columns will be determined by the
/// first value inserted. All subsequent values must have equal column count.
///
/// conn.insert(into: Planet.self)
/// .values([earth, mars]).run()
///
/// - parameters:
/// - values: Array of `Encodable` values to insert.
/// - returns: Self for chaining.
public func values<E>(_ values: [E]) -> Self
where E: Encodable
{
fatalError()
// values.forEach { model in
// let row = SQLQueryEncoder(Database.Query.Insert.Expression.self).encode(model)
// if insert.columns.isEmpty {
// insert.columns += row.map { .column(name: .identifier($0.key), table: nil) }
// } else {
// assert(
// insert.columns.count == row.count,
// "Column count (\(insert.columns.count)) did not equal value count (\(row.count)): \(model)."
// )
// }
// insert.values.append(row.map { row in
// if row.value.isNull {
// return .literal(.default)
// } else {
// return row.value
// }
// })
// }
// return self
let row = try SQLQueryEncoder().encode(model)
if self.insert.columns.isEmpty {
self.insert.columns += row.keys.map { SQLColumn($0, table: nil) }
} else {
assert(
self.insert.columns.count == row.count,
"Column count (\(self.insert.columns.count)) did not equal value count (\(row.count)): \(model)."
)
}
self.insert.values.append(.init(row.values))
return self
}

public func columns(_ columns: String...) -> Self {
Expand All @@ -82,7 +58,8 @@ public final class SQLInsertBuilder: SQLQueryBuilder {
}

public func values(_ values: Encodable...) -> Self {
self.insert.values.append(values.map(SQLBind.init))
let row: [SQLExpression] = values.map(SQLBind.init)
self.insert.values.append(row)
return self
}

Expand Down
1 change: 0 additions & 1 deletion Sources/SQLKit/Query/SQLList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ public struct SQLList: SQLExpression {
}

public func serialize(to serializer: inout SQLSerializer) {

var first = true
for el in self.expressions {
if !first {
Expand Down
75 changes: 75 additions & 0 deletions Sources/SQLKit/SQLQueryEncoder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
public struct SQLQueryEncoder {
public init() { }

public func encode<E>(_ encodable: E) throws -> [String: SQLExpression]
where E: Encodable
{
let encoder = _Encoder()
try encodable.encode(to: encoder)
return encoder.row
}
}

private final class _Encoder: Encoder {
var codingPath: [CodingKey] {
return []
}

var userInfo: [CodingUserInfoKey : Any] {
return [:]
}

var row: [String: SQLExpression]

init() {
self.row = [:]
}

func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key : CodingKey {
return KeyedEncodingContainer(_KeyedEncoder(self))
}

struct _KeyedEncoder<Key>: KeyedEncodingContainerProtocol
where Key: CodingKey
{
var codingPath: [CodingKey] {
return []
}
let encoder: _Encoder
init(_ encoder: _Encoder) {
self.encoder = encoder
}

mutating func encodeNil(forKey key: Key) throws {
self.encoder.row[key.stringValue] = SQLLiteral.null
}

mutating func encode<T>(_ value: T, forKey key: Key) throws where T : Encodable {
self.encoder.row[key.stringValue] = SQLBind(value)
}

mutating func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey {
fatalError()
}

mutating func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer {
fatalError()
}

mutating func superEncoder() -> Encoder {
return self.encoder
}

mutating func superEncoder(forKey key: Key) -> Encoder {
return self.encoder
}
}

func unkeyedContainer() -> UnkeyedEncodingContainer {
fatalError()
}

func singleValueContainer() -> SingleValueEncodingContainer {
fatalError()
}
}

0 comments on commit 435a3ac

Please sign in to comment.