@@ -28,8 +28,9 @@ import Foundation
28
28
public struct SQLiteCloudConfig : Sendable {
29
29
public let hostname : String
30
30
public let port : Port
31
- public let username : String
32
- public let password : String
31
+ public let username : String ?
32
+ public let password : String ?
33
+ public let apiKey : String ?
33
34
public let family : Family
34
35
public let passwordHashed : Bool
35
36
public let nonlinearizable : Bool
@@ -49,6 +50,52 @@ public struct SQLiteCloudConfig: Sendable {
49
50
public let clientCertificate : String ?
50
51
public let clientCertificateKey : String ?
51
52
53
+ public init ( hostname: String ,
54
+ apiKey: String ,
55
+ port: Port = . default,
56
+ family: Family = . ipv4,
57
+ passwordHashed: Bool = false ,
58
+ nonlinearizable: Bool = false ,
59
+ timeout: Int = 0 ,
60
+ compression: Bool = false ,
61
+ zerotext: Bool = false ,
62
+ memory: Bool = false ,
63
+ dbCreate: Bool = false ,
64
+ insecure: Bool = false ,
65
+ noblob: Bool = false ,
66
+ isReadonlyConnection: Bool = false ,
67
+ maxData: Int = 0 ,
68
+ maxRows: Int = 0 ,
69
+ maxRowset: Int = 0 ,
70
+ dbname: String ? = nil ,
71
+ rootCertificate: String ? = nil ,
72
+ clientCertificate: String ? = nil ,
73
+ clientCertificateKey: String ? = nil ) {
74
+ self . init ( hostname: hostname,
75
+ username: nil ,
76
+ password: nil ,
77
+ apiKey: apiKey,
78
+ port: port,
79
+ family: family,
80
+ passwordHashed: passwordHashed,
81
+ nonlinearizable: nonlinearizable,
82
+ timeout: timeout,
83
+ compression: compression,
84
+ zerotext: zerotext,
85
+ memory: memory,
86
+ dbCreate: dbCreate,
87
+ insecure: insecure,
88
+ noblob: noblob,
89
+ isReadonlyConnection: isReadonlyConnection,
90
+ maxData: maxData,
91
+ maxRows: maxRows,
92
+ maxRowset: maxRowset,
93
+ dbname: dbname,
94
+ rootCertificate: rootCertificate,
95
+ clientCertificate: clientCertificate,
96
+ clientCertificateKey: clientCertificateKey)
97
+ }
98
+
52
99
public init ( hostname: String ,
53
100
username: String ,
54
101
password: String ,
@@ -71,10 +118,59 @@ public struct SQLiteCloudConfig: Sendable {
71
118
rootCertificate: String ? = nil ,
72
119
clientCertificate: String ? = nil ,
73
120
clientCertificateKey: String ? = nil ) {
121
+ self . init ( hostname: hostname,
122
+ username: username,
123
+ password: password,
124
+ apiKey: nil ,
125
+ port: port,
126
+ family: family,
127
+ passwordHashed: passwordHashed,
128
+ nonlinearizable: nonlinearizable,
129
+ timeout: timeout,
130
+ compression: compression,
131
+ zerotext: zerotext,
132
+ memory: memory,
133
+ dbCreate: dbCreate,
134
+ insecure: insecure,
135
+ noblob: noblob,
136
+ isReadonlyConnection: isReadonlyConnection,
137
+ maxData: maxData,
138
+ maxRows: maxRows,
139
+ maxRowset: maxRowset,
140
+ dbname: dbname,
141
+ rootCertificate: rootCertificate,
142
+ clientCertificate: clientCertificate,
143
+ clientCertificateKey: clientCertificateKey)
144
+ }
145
+
146
+ private init ( hostname: String ,
147
+ username: String ? ,
148
+ password: String ? ,
149
+ apiKey: String ? ,
150
+ port: Port = . default,
151
+ family: Family = . ipv4,
152
+ passwordHashed: Bool = false ,
153
+ nonlinearizable: Bool = false ,
154
+ timeout: Int = 0 ,
155
+ compression: Bool = false ,
156
+ zerotext: Bool = false ,
157
+ memory: Bool = false ,
158
+ dbCreate: Bool = false ,
159
+ insecure: Bool = false ,
160
+ noblob: Bool = false ,
161
+ isReadonlyConnection: Bool = false ,
162
+ maxData: Int = 0 ,
163
+ maxRows: Int = 0 ,
164
+ maxRowset: Int = 0 ,
165
+ dbname: String ? = nil ,
166
+ rootCertificate: String ? = nil ,
167
+ clientCertificate: String ? = nil ,
168
+ clientCertificateKey: String ? = nil ) {
74
169
self . hostname = hostname
75
170
self . port = port
76
171
self . username = username
77
172
self . password = password
173
+ self . apiKey = apiKey
78
174
self . family = family
79
175
self . passwordHashed = passwordHashed
80
176
self . nonlinearizable = nonlinearizable
@@ -94,7 +190,7 @@ public struct SQLiteCloudConfig: Sendable {
94
190
self . clientCertificate = clientCertificate
95
191
self . clientCertificateKey = clientCertificateKey
96
192
}
97
-
193
+
98
194
public init ? ( connectionString: String ) {
99
195
guard let url = URL ( string: connectionString) else { return nil }
100
196
@@ -103,22 +199,38 @@ public struct SQLiteCloudConfig: Sendable {
103
199
104
200
/// sqlitecloud://user:
[email protected] :port/dbname?timeout=10&key2=value2&key3=value3.
105
201
public init ? ( connectionURL: URL ) {
106
- guard let username = connectionURL. user else { return nil }
107
- guard let password = connectionURL. password else { return nil }
108
202
guard let hostname = connectionURL. host else { return nil }
109
- let port = connectionURL. port. map { Port . custom ( portNumber: $0) } ?? . default
110
-
203
+
111
204
let urlComponents = URLComponents ( string: connectionURL. absoluteString)
112
205
let queryItems = urlComponents? . queryItems
113
-
206
+
207
+ // There are 2 kind of possibile credentials types
208
+ // - based on an apikey
209
+ // - based on the username and the password combo
210
+ // We need to search for this credential info in the connection string.
211
+ // First we check for apikey, if fails we fallback on the user/pass combo.
212
+
213
+ if let apiKey = UrlParser . parse ( items: queryItems, name: " apikey " ) {
214
+ self . username = nil
215
+ self . password = nil
216
+ self . apiKey = apiKey
217
+ } else {
218
+ guard let username = connectionURL. user else { return nil }
219
+ guard let password = connectionURL. password else { return nil }
220
+
221
+ self . username = username
222
+ self . password = password
223
+ self . apiKey = nil
224
+ }
225
+
226
+ let port = connectionURL. port. map { Port . custom ( portNumber: $0) } ?? . default
227
+
114
228
// external
115
229
self . hostname = hostname
116
230
self . port = port
117
231
self . isReadonlyConnection = UrlParser . parse ( items: queryItems, name: " readonly " )
118
232
119
233
// in config
120
- self . username = username
121
- self . password = password
122
234
self . dbname = urlComponents? . path. replacingOccurrences ( of: " / " , with: " " )
123
235
self . family = Family ( rawValue: UrlParser . parse ( items: queryItems, name: " family " ) ) ?? . ipv4
124
236
self . passwordHashed = UrlParser . parse ( items: queryItems, name: " passwordHashed " )
@@ -143,7 +255,11 @@ public struct SQLiteCloudConfig: Sendable {
143
255
144
256
extension SQLiteCloudConfig {
145
257
var connectionString : String {
146
- " sqlitecloud:// \( username) :****@ \( hostname) : \( port. number) / \( dbname ?? . empty) "
258
+ if let apiKey {
259
+ " sqlitecloud:// \( hostname) : \( port. number) / \( dbname ?? . empty) ?apikey= \( apiKey) "
260
+ } else {
261
+ " sqlitecloud:// \( username ?? " " ) :****@ \( hostname) : \( port. number) / \( dbname ?? . empty) "
262
+ }
147
263
}
148
264
}
149
265
0 commit comments