Skip to content

Commit d30b5b9

Browse files
committed
WIP - any database adapter
1 parent 217b069 commit d30b5b9

2 files changed

Lines changed: 71 additions & 2 deletions

File tree

Sources/Compiler/Gen/SwiftLanguage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public struct SwiftLanguage: Language {
224224
writer.write(line: "struct Adapters: Otter.Adapters ")
225225
writer.braces {
226226
for adapter in adapters {
227-
writer.write(line: "let ", adapter, ": any DatabaseValueAdapter")
227+
writer.write(line: "let ", adapter, ": AnyDatabaseValueAdapter")
228228
}
229229
}
230230
}

Sources/Otter/DatabaseValueAdapter.swift

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Foundation
2424
///
2525
/// Encoding to `ANY` is NOT handled by default. Decoding is. So if
2626
/// a value needs to support `ANY` `encodeToAny` needs to be implemented.
27-
public protocol DatabaseValueAdapter: Sendable {
27+
public protocol DatabaseValueAdapter<Value>: Sendable {
2828
associatedtype Value
2929

3030
/// Initialize from the `TEXT` affinity
@@ -95,6 +95,75 @@ public extension DatabaseValueAdapter {
9595
}
9696
}
9797

98+
public struct AnyDatabaseValueAdapter<Value>: DatabaseValueAdapter {
99+
@usableFromInline let _decodeString: @Sendable (String) throws(OtterError) -> Value
100+
@usableFromInline let _decodeInt: @Sendable (Int) throws(OtterError) -> Value
101+
@usableFromInline let _decodeDouble: @Sendable (Double) throws(OtterError) -> Value
102+
@usableFromInline let _decodeData: @Sendable (Data) throws(OtterError) -> Value
103+
@usableFromInline let _decodeSQLAny: @Sendable (SQLAny) throws(OtterError) -> Value
104+
@usableFromInline let _encodeToString: @Sendable (Value) throws(OtterError) -> String
105+
@usableFromInline let _encodeToInt: @Sendable (Value) throws(OtterError) -> Int
106+
@usableFromInline let _encodeToDouble: @Sendable (Value) throws(OtterError) -> Double
107+
@usableFromInline let _encodeToData: @Sendable (Value) throws(OtterError) -> Data
108+
@usableFromInline let _encodeToAny: @Sendable (Value) throws(OtterError) -> SQLAny
109+
110+
public init(_ adapter: any DatabaseValueAdapter<Value>) {
111+
// Note: We define the entire closure type `(value) throws(OtterError) -> ...` due to
112+
// what seems to be a limitation in typed throws. Without it, it throws an error
113+
// for an invalid conversion.
114+
self._decodeString = { (value: String) throws(OtterError) -> Value in try adapter.decode(from: value) }
115+
self._decodeInt = { (value: Int) throws(OtterError) -> Value in try adapter.decode(from: value) }
116+
self._decodeDouble = { (value: Double) throws(OtterError) -> Value in try adapter.decode(from: value) }
117+
self._decodeData = { (value: Data) throws(OtterError) -> Value in try adapter.decode(from: value) }
118+
self._decodeSQLAny = { (value: SQLAny) throws(OtterError) -> Value in try adapter.decode(from: value) }
119+
self._encodeToString = { (value: Value) throws(OtterError) -> String in try adapter.encodeToString(value: value) }
120+
self._encodeToInt = { (value: Value) throws(OtterError) -> Int in try adapter.encodeToInt(value: value) }
121+
self._encodeToDouble = { (value: Value) throws(OtterError) -> Double in try adapter.encodeToDouble(value: value) }
122+
self._encodeToData = { (value: Value) throws(OtterError) -> Data in try adapter.encodeToData(value: value) }
123+
self._encodeToAny = { (value: Value) throws(OtterError) -> SQLAny in try adapter.encodeToAny(value: value) }
124+
}
125+
126+
@inlinable public func decode(from primitive: String) throws(OtterError) -> Value {
127+
try _decodeString(primitive)
128+
}
129+
130+
@inlinable public func decode(from primitive: Int) throws(OtterError) -> Value {
131+
try _decodeInt(primitive)
132+
}
133+
134+
@inlinable public func decode(from primitive: Double) throws(OtterError) -> Value {
135+
try _decodeDouble(primitive)
136+
}
137+
138+
@inlinable public func decode(from primitive: Data) throws(OtterError) -> Value {
139+
try _decodeData(primitive)
140+
}
141+
142+
@inlinable public func decode(from primitive: SQLAny) throws(OtterError) -> Value {
143+
try _decodeSQLAny(primitive)
144+
}
145+
146+
@inlinable public func encodeToString(value: Value) throws(OtterError) -> String {
147+
try _encodeToString(value)
148+
}
149+
150+
@inlinable public func encodeToInt(value: Value) throws(OtterError) -> Int {
151+
try _encodeToInt(value)
152+
}
153+
154+
@inlinable public func encodeToDouble(value: Value) throws(OtterError) -> Double {
155+
try _encodeToDouble(value)
156+
}
157+
158+
@inlinable public func encodeToData(value: Value) throws(OtterError) -> Data {
159+
try _encodeToData(value)
160+
}
161+
162+
@inlinable public func encodeToAny(value: Value) throws(OtterError) -> SQLAny {
163+
try _encodeToAny(value)
164+
}
165+
}
166+
98167
// MARK: - Swift Standard Libray
99168

100169
public struct BoolDatabaseValueAdapter: DatabaseValueAdapter {

0 commit comments

Comments
 (0)