@@ -28,8 +28,9 @@ import Foundation
2828public struct SQLiteCloudConfig : Sendable {
2929 public let hostname : String
3030 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 ?
3334 public let family : Family
3435 public let passwordHashed : Bool
3536 public let nonlinearizable : Bool
@@ -49,6 +50,52 @@ public struct SQLiteCloudConfig: Sendable {
4950 public let clientCertificate : String ?
5051 public let clientCertificateKey : String ?
5152
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+
5299 public init ( hostname: String ,
53100 username: String ,
54101 password: String ,
@@ -71,10 +118,59 @@ public struct SQLiteCloudConfig: Sendable {
71118 rootCertificate: String ? = nil ,
72119 clientCertificate: String ? = nil ,
73120 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 ) {
74169 self . hostname = hostname
75170 self . port = port
76171 self . username = username
77172 self . password = password
173+ self . apiKey = apiKey
78174 self . family = family
79175 self . passwordHashed = passwordHashed
80176 self . nonlinearizable = nonlinearizable
@@ -94,7 +190,7 @@ public struct SQLiteCloudConfig: Sendable {
94190 self . clientCertificate = clientCertificate
95191 self . clientCertificateKey = clientCertificateKey
96192 }
97-
193+
98194 public init ? ( connectionString: String ) {
99195 guard let url = URL ( string: connectionString) else { return nil }
100196
@@ -103,22 +199,38 @@ public struct SQLiteCloudConfig: Sendable {
103199
104200 /// sqlitecloud://user:pass@host.com:port/dbname?timeout=10&key2=value2&key3=value3.
105201 public init ? ( connectionURL: URL ) {
106- guard let username = connectionURL. user else { return nil }
107- guard let password = connectionURL. password else { return nil }
108202 guard let hostname = connectionURL. host else { return nil }
109- let port = connectionURL. port. map { Port . custom ( portNumber: $0) } ?? . default
110-
203+
111204 let urlComponents = URLComponents ( string: connectionURL. absoluteString)
112205 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+
114228 // external
115229 self . hostname = hostname
116230 self . port = port
117231 self . isReadonlyConnection = UrlParser . parse ( items: queryItems, name: " readonly " )
118232
119233 // in config
120- self . username = username
121- self . password = password
122234 self . dbname = urlComponents? . path. replacingOccurrences ( of: " / " , with: " " )
123235 self . family = Family ( rawValue: UrlParser . parse ( items: queryItems, name: " family " ) ) ?? . ipv4
124236 self . passwordHashed = UrlParser . parse ( items: queryItems, name: " passwordHashed " )
@@ -143,7 +255,11 @@ public struct SQLiteCloudConfig: Sendable {
143255
144256extension SQLiteCloudConfig {
145257 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+ }
147263 }
148264}
149265
0 commit comments