forked from vapor/fluent-mysql-driver
/
MySQLType.swift
82 lines (73 loc) 路 3.35 KB
/
MySQLType.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/// A MySQL type can represent itself statically as a column definition for
/// migrations and convert to / from native MySQL data.
public typealias MySQLType = MySQLColumnDefinitionStaticRepresentable & MySQLDataConvertible
/// A MySQL type that is represented by JSON in the database.
public protocol MySQLJSONType: MySQLType, Codable { }
extension MySQLJSONType {
/// An appropriate `MySQLColumnDefinition` for this type.
public static var mySQLColumnDefinition: MySQLColumnDefinition { return .json() }
/// See `MySQLDataConvertible.convertToMySQLData(format:)`
public func convertToMySQLData() throws -> MySQLData {
return try MySQLData(json: self)
}
/// See `MySQLDataConvertible.convertFromMySQLData()`
public static func convertFromMySQLData(_ mysqlData: MySQLData) throws -> Self {
guard let json = try mysqlData.json(Self.self) else {
throw MySQLError(identifier: "json", reason: "Could not parse JSON from: \(self)", source: .capture())
}
return json
}
}
extension MySQLText: MySQLColumnDefinitionStaticRepresentable {
/// See `MySQLColumnDefinitionStaticRepresentable`
public static var mySQLColumnDefinition: MySQLColumnDefinition {
return .text()
}
}
// MARK: Enum
/// This type-alias makes it easy to declare nested enum types for your `MySQLModel`.
///
/// enum PetType: Int, MySQLEnumType {
/// case cat, dog
/// }
///
/// `MySQLEnumType` can be used easily with any enum that has a `MySQLType` conforming `RawValue`.
///
/// You will need to implement custom `ReflectionDecodable` conformance for enums that have non-standard integer
/// values or enums whose `RawValue` is not an integer.
///
/// enum FavoriteTreat: String, MySQLEnumType {
/// case bone = "b"
/// case tuna = "t"
/// static func reflectDecoded() -> (FavoriteTreat, FavoriteTreat) {
/// return (.bone, .tuna)
/// }
/// }
///
public protocol MySQLEnumType: MySQLType, ReflectionDecodable, Codable, RawRepresentable where Self.RawValue: MySQLDataConvertible { }
/// Provides a default `MySQLColumnDefinitionStaticRepresentable` implementation where the type is also
/// `RawRepresentable` by a `MySQLColumnDefinitionStaticRepresentable` type.
extension MySQLColumnDefinitionStaticRepresentable where Self: RawRepresentable, Self.RawValue: MySQLColumnDefinitionStaticRepresentable
{
public static var mySQLColumnDefinition: MySQLColumnDefinition { return RawValue.mySQLColumnDefinition }
}
/// Provides a default `MySQLDataConvertible` implementation where the type is also
/// `RawRepresentable` by a `MySQLDataConvertible` type.
extension MySQLDataConvertible where Self: RawRepresentable, Self.RawValue: MySQLDataConvertible
{
/// See `MySQLDataConvertible.convertToMySQLData()`
public func convertToMySQLData() throws -> MySQLData {
return try rawValue.convertToMySQLData()
}
/// See `MySQLDataConvertible.convertFromMySQLData(_:)`
public static func convertFromMySQLData(_ data: MySQLData) throws -> Self {
guard let extractedCase = try self.init(rawValue: .convertFromMySQLData(data)) else {
throw MySQLError(
identifier: "rawValue",
reason: "Could not create `\(Self.self)` from: \(data)",
source: .capture()
)
}
return extractedCase
}
}