1 /* 2 * Copyright (C) 2019, HuntLabs 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 module hunt.database.driver.postgresql.PostgreSQLConnectOptions; 19 20 import hunt.database.driver.postgresql.SslMode; 21 // import hunt.database.driver.postgresql.impl.PgConnectionUriParser; 22 // import io.vertx.codegen.annotations.DataObject; 23 // import io.vertx.core.buffer.Buffer; 24 // import io.vertx.core.json.JsonObject; 25 // import io.vertx.core.net.*; 26 import hunt.database.base.SqlConnectOptions; 27 28 import hunt.collection.Collections; 29 import hunt.collection.HashMap; 30 import hunt.collection.Map; 31 import hunt.collection.Set; 32 import hunt.net.OpenSSLEngineOptions; 33 import hunt.net.ProxyOptions; 34 import hunt.net.util.HttpURI; 35 import hunt.Exceptions; 36 37 import core.time; 38 import std.concurrency : initOnce; 39 import std.string; 40 41 42 /** 43 * @author <a href="mailto:julien@julienviet.com">Julien Viet</a> 44 * @author Billy Yuan <billy112487983@gmail.com> 45 */ 46 class PgConnectOptions : SqlConnectOptions { 47 48 /** 49 * Provide a {@link PgConnectOptions} configured from a connection URI. 50 * 51 * @param connectionUri the connection URI to configure from 52 * @return a {@link PgConnectOptions} parsed from the connection URI 53 * @throws IllegalArgumentException when the {@code connectionUri} is in an invalid format 54 */ 55 static PgConnectOptions fromUri(string connectionUri) { 56 return new PgConnectOptions(new HttpURI(connectionUri)); 57 } 58 59 /** 60 * Provide a {@link PgConnectOptions} configured with environment variables, if the environment variable 61 * is not set, then a default value will take precedence over this. 62 */ 63 // static PgConnectOptions fromEnv() { 64 // PgConnectOptions pgConnectOptions = new PgConnectOptions(); 65 66 // if (getenv("PGHOSTADDR") is null) { 67 // if (getenv("PGHOST") !is null) { 68 // pgConnectOptions.setHost(getenv("PGHOST")); 69 // } 70 // } else { 71 // pgConnectOptions.setHost(getenv("PGHOSTADDR")); 72 // } 73 74 // if (getenv("PGPORT") !is null) { 75 // try { 76 // pgConnectOptions.setPort(parseInt(getenv("PGPORT"))); 77 // } catch (NumberFormatException e) { 78 // // port will be set to default 79 // } 80 // } 81 82 // if (getenv("PGDATABASE") !is null) { 83 // pgConnectOptions.setDatabase(getenv("PGDATABASE")); 84 // } 85 // if (getenv("PGUSER") !is null) { 86 // pgConnectOptions.setUser(getenv("PGUSER")); 87 // } 88 // if (getenv("PGPASSWORD") !is null) { 89 // pgConnectOptions.setPassword(getenv("PGPASSWORD")); 90 // } 91 // if (getenv("PGSSLMODE") !is null) { 92 // pgConnectOptions.setSslMode(SslMode.of(getenv("PGSSLMODE"))); 93 // } 94 // return pgConnectOptions; 95 // } 96 97 enum string DEFAULT_HOST = "localhost"; 98 static int DEFAULT_PORT = 5432; 99 enum string DEFAULT_DATABASE = "db"; 100 enum string DEFAULT_USER = "user"; 101 enum string DEFAULT_PASSWORD = "pass"; 102 enum int DEFAULT_PIPELINING_LIMIT = 256; 103 enum SslMode DEFAULT_SSLMODE = SslMode.DISABLE; 104 enum string[string] DEFAULT_PROPERTIES = [ 105 "application_name" : "hunt-pg-client", 106 "client_encoding" : "utf8", 107 "DateStyle" : "ISO", 108 "intervalStyle" : "postgres", 109 "extra_float_digits" : "2"]; 110 111 private int pipeliningLimit; 112 private SslMode sslMode; 113 114 this() { 115 super(); 116 } 117 118 this(HttpURI uri) { 119 super(uri); 120 } 121 122 this(PgConnectOptions other) { 123 super(other); 124 pipeliningLimit = other.pipeliningLimit; 125 sslMode = other.sslMode; 126 } 127 128 override 129 PgConnectOptions setHost(string host) { 130 return cast(PgConnectOptions) super.setHost(host); 131 } 132 133 override 134 PgConnectOptions setPort(int port) { 135 return cast(PgConnectOptions) super.setPort(port); 136 } 137 138 override 139 PgConnectOptions setUser(string user) { 140 return cast(PgConnectOptions) super.setUser(user); 141 } 142 143 override 144 PgConnectOptions setPassword(string password) { 145 return cast(PgConnectOptions) super.setPassword(password); 146 } 147 148 override 149 PgConnectOptions setDatabase(string database) { 150 return cast(PgConnectOptions) super.setDatabase(database); 151 } 152 153 int getPipeliningLimit() { 154 return pipeliningLimit; 155 } 156 157 PgConnectOptions setPipeliningLimit(int pipeliningLimit) { 158 if (pipeliningLimit < 1) { 159 throw new IllegalArgumentException(); 160 } 161 this.pipeliningLimit = pipeliningLimit; 162 return this; 163 } 164 165 override PgConnectOptions setCachePreparedStatements(bool cachePreparedStatements) { 166 return cast(PgConnectOptions) super.setCachePreparedStatements(cachePreparedStatements); 167 } 168 169 override 170 PgConnectOptions setPreparedStatementCacheMaxSize(int preparedStatementCacheMaxSize) { 171 return cast(PgConnectOptions) super.setPreparedStatementCacheMaxSize(preparedStatementCacheMaxSize); 172 } 173 174 override 175 PgConnectOptions setPreparedStatementCacheSqlLimit(int preparedStatementCacheSqlLimit) { 176 return cast(PgConnectOptions) super.setPreparedStatementCacheSqlLimit(preparedStatementCacheSqlLimit); 177 } 178 179 override 180 PgConnectOptions setProperties(Map!(string, string) properties) { 181 return cast(PgConnectOptions) super.setProperties(properties); 182 } 183 184 override 185 PgConnectOptions addProperty(string key, string value) { 186 return cast(PgConnectOptions) super.addProperty(key, value); 187 } 188 189 /** 190 * @return the value of current sslmode 191 */ 192 SslMode getSslMode() { 193 return sslMode; 194 } 195 196 /** 197 * Set {@link SslMode} for the client, this option can be used to provide different levels of secure protection. 198 * 199 * @param sslmode the value of sslmode 200 * @return a reference to this, so the API can be used fluently 201 */ 202 PgConnectOptions setSslMode(SslMode sslmode) { 203 this.sslMode = sslmode; 204 return this; 205 } 206 207 override 208 PgConnectOptions setSendBufferSize(int sendBufferSize) { 209 return cast(PgConnectOptions) super.setSendBufferSize(sendBufferSize); 210 } 211 212 override 213 PgConnectOptions setReceiveBufferSize(int receiveBufferSize) { 214 return cast(PgConnectOptions) super.setReceiveBufferSize(receiveBufferSize); 215 } 216 217 override 218 PgConnectOptions setDecoderBufferSize(int size) { 219 return cast(PgConnectOptions) super.setDecoderBufferSize(size); 220 } 221 222 override 223 PgConnectOptions setEncoderBufferSize(int size) { 224 return cast(PgConnectOptions) super.setEncoderBufferSize(size); 225 } 226 227 override 228 PgConnectOptions setReuseAddress(bool reuseAddress) { 229 return cast(PgConnectOptions) super.setReuseAddress(reuseAddress); 230 } 231 232 override 233 PgConnectOptions setTrafficClass(int trafficClass) { 234 return cast(PgConnectOptions) super.setTrafficClass(trafficClass); 235 } 236 237 override 238 PgConnectOptions setTcpNoDelay(bool tcpNoDelay) { 239 return cast(PgConnectOptions) super.setTcpNoDelay(tcpNoDelay); 240 } 241 242 override 243 PgConnectOptions setTcpKeepAlive(bool tcpKeepAlive) { 244 return cast(PgConnectOptions) super.setTcpKeepAlive(tcpKeepAlive); 245 } 246 247 override 248 PgConnectOptions setSoLinger(int soLinger) { 249 return cast(PgConnectOptions) super.setSoLinger(soLinger); 250 } 251 252 // override 253 // PgConnectOptions setUsePooledBuffers(bool usePooledBuffers) { 254 // return cast(PgConnectOptions) super.setUsePooledBuffers(usePooledBuffers); 255 // } 256 257 override 258 PgConnectOptions setIdleTimeout(Duration idleTimeout) { 259 return cast(PgConnectOptions) super.setIdleTimeout(idleTimeout); 260 } 261 262 // override 263 // PgConnectOptions setIdleTimeoutUnit(TimeUnit idleTimeoutUnit) { 264 // return cast(PgConnectOptions) super.setIdleTimeoutUnit(idleTimeoutUnit); 265 // } 266 267 override 268 PgConnectOptions setSsl(bool ssl) { 269 if (ssl) { 270 setSslMode(SslMode.VERIFY_CA); 271 } else { 272 setSslMode(SslMode.DISABLE); 273 } 274 return this; 275 } 276 277 // override 278 // PgConnectOptions setKeyCertOptions(KeyCertOptions options) { 279 // return cast(PgConnectOptions) super.setKeyCertOptions(options); 280 // } 281 282 // override 283 // PgConnectOptions setKeyStoreOptions(JksOptions options) { 284 // return cast(PgConnectOptions) super.setKeyStoreOptions(options); 285 // } 286 287 // override 288 // PgConnectOptions setPfxKeyCertOptions(PfxOptions options) { 289 // return cast(PgConnectOptions) super.setPfxKeyCertOptions(options); 290 // } 291 292 // override 293 // PgConnectOptions setPemKeyCertOptions(PemKeyCertOptions options) { 294 // return cast(PgConnectOptions) super.setPemKeyCertOptions(options); 295 // } 296 297 // override 298 // PgConnectOptions setTrustOptions(TrustOptions options) { 299 // return cast(PgConnectOptions) super.setTrustOptions(options); 300 // } 301 302 // override 303 // PgConnectOptions setTrustStoreOptions(JksOptions options) { 304 // return cast(PgConnectOptions) super.setTrustStoreOptions(options); 305 // } 306 307 // override 308 // PgConnectOptions setPemTrustOptions(PemTrustOptions options) { 309 // return cast(PgConnectOptions) super.setPemTrustOptions(options); 310 // } 311 312 // override 313 // PgConnectOptions setPfxTrustOptions(PfxOptions options) { 314 // return cast(PgConnectOptions) super.setPfxTrustOptions(options); 315 // } 316 317 // override 318 // PgConnectOptions addEnabledCipherSuite(string suite) { 319 // return cast(PgConnectOptions) super.addEnabledCipherSuite(suite); 320 // } 321 322 // override 323 // PgConnectOptions addEnabledSecureTransportProtocol(string protocol) { 324 // return cast(PgConnectOptions) super.addEnabledSecureTransportProtocol(protocol); 325 // } 326 327 // override 328 // PgConnectOptions addCrlPath(string crlPath) { 329 // return cast(PgConnectOptions) super.addCrlPath(crlPath); 330 // } 331 332 // override 333 // PgConnectOptions addCrlValue(Buffer crlValue) { 334 // return cast(PgConnectOptions) super.addCrlValue(crlValue); 335 // } 336 337 // override 338 // PgConnectOptions setTrustAll(bool trustAll) { 339 // return cast(PgConnectOptions) super.setTrustAll(trustAll); 340 // } 341 342 override 343 PgConnectOptions setConnectTimeout(Duration connectTimeout) { 344 return cast(PgConnectOptions) super.setConnectTimeout(connectTimeout); 345 } 346 347 override 348 PgConnectOptions setMetricsName(string metricsName) { 349 return cast(PgConnectOptions) super.setMetricsName(metricsName); 350 } 351 352 override 353 PgConnectOptions setReconnectAttempts(int attempts) { 354 return cast(PgConnectOptions) super.setReconnectAttempts(attempts); 355 } 356 357 override 358 PgConnectOptions setHostnameVerificationAlgorithm(string hostnameVerificationAlgorithm) { 359 return cast(PgConnectOptions) super.setHostnameVerificationAlgorithm(hostnameVerificationAlgorithm); 360 } 361 362 override 363 PgConnectOptions setLogActivity(bool logEnabled) { 364 return cast(PgConnectOptions) super.setLogActivity(logEnabled); 365 } 366 367 override 368 PgConnectOptions setReconnectInterval(Duration interval) { 369 return cast(PgConnectOptions) super.setReconnectInterval(interval); 370 } 371 372 override 373 PgConnectOptions setProxyOptions(ProxyOptions proxyOptions) { 374 return cast(PgConnectOptions) super.setProxyOptions(proxyOptions); 375 } 376 377 override 378 PgConnectOptions setLocalAddress(string localAddress) { 379 return cast(PgConnectOptions) super.setLocalAddress(localAddress); 380 } 381 382 override 383 PgConnectOptions setUseAlpn(bool useAlpn) { 384 return cast(PgConnectOptions) super.setUseAlpn(useAlpn); 385 } 386 387 // override 388 // PgConnectOptions setSslEngineOptions(SSLEngineOptions sslEngineOptions) { 389 // return cast(PgConnectOptions) super.setSslEngineOptions(sslEngineOptions); 390 // } 391 392 // override 393 // PgConnectOptions setJdkSslEngineOptions(JdkSSLEngineOptions sslEngineOptions) { 394 // return cast(PgConnectOptions) super.setJdkSslEngineOptions(sslEngineOptions); 395 // } 396 397 override 398 PgConnectOptions setOpenSslEngineOptions(OpenSSLEngineOptions sslEngineOptions) { 399 return cast(PgConnectOptions) super.setOpenSslEngineOptions(sslEngineOptions); 400 } 401 402 override 403 PgConnectOptions setReusePort(bool reusePort) { 404 return cast(PgConnectOptions) super.setReusePort(reusePort); 405 } 406 407 override 408 PgConnectOptions setTcpFastOpen(bool tcpFastOpen) { 409 return cast(PgConnectOptions) super.setTcpFastOpen(tcpFastOpen); 410 } 411 412 override 413 PgConnectOptions setTcpCork(bool tcpCork) { 414 return cast(PgConnectOptions) super.setTcpCork(tcpCork); 415 } 416 417 override 418 PgConnectOptions setTcpQuickAck(bool tcpQuickAck) { 419 return cast(PgConnectOptions) super.setTcpQuickAck(tcpQuickAck); 420 } 421 422 // override 423 // PgConnectOptions setEnabledSecureTransportProtocols(Set!(string) enabledSecureTransportProtocols) { 424 // return cast(PgConnectOptions) super.setEnabledSecureTransportProtocols(enabledSecureTransportProtocols); 425 // } 426 427 override 428 PgConnectOptions setSslHandshakeTimeout(Duration sslHandshakeTimeout) { 429 return cast(PgConnectOptions) super.setSslHandshakeTimeout(sslHandshakeTimeout); 430 } 431 432 // override 433 // PgConnectOptions setSslHandshakeTimeoutUnit(TimeUnit sslHandshakeTimeoutUnit) { 434 // return cast(PgConnectOptions) super.setSslHandshakeTimeoutUnit(sslHandshakeTimeoutUnit); 435 // } 436 437 /** 438 * Initialize with the default options. 439 */ 440 override protected void initialize() { 441 this.setHost(DEFAULT_HOST); 442 this.setPort(DEFAULT_PORT); 443 this.setUser(DEFAULT_USER); 444 this.setPassword(DEFAULT_PASSWORD); 445 this.setDatabase(DEFAULT_DATABASE); 446 pipeliningLimit = DEFAULT_PIPELINING_LIMIT; 447 sslMode = DEFAULT_SSLMODE; 448 this.setProperties(new HashMap!(string, string)(DEFAULT_PROPERTIES)); 449 } 450 451 // override 452 // JsonObject toJson() { 453 // JsonObject json = super.toJson(); 454 // PgConnectOptionsConverter.toJson(this, json); 455 // return json; 456 // } 457 458 override 459 bool opEquals(Object o) { 460 if (this is o) return true; 461 if (!super.opEquals(o)) return false; 462 463 PgConnectOptions that = cast(PgConnectOptions) o; 464 if(that is null) return false; 465 466 if (pipeliningLimit != that.pipeliningLimit) return false; 467 if (sslMode != that.sslMode) return false; 468 469 return true; 470 } 471 472 override 473 size_t toHash() @trusted nothrow { 474 size_t result = super.toHash(); 475 result = 31 * result + pipeliningLimit; 476 result = 31 * result + sslMode.hashOf(); 477 return result; 478 } 479 480 bool isUsingDomainSocket() { 481 return this.getHost().startsWith("/"); 482 } 483 }