Skip to content
Permalink
Browse files

Support custom 'options' connection property (#1356)

* feat: support custom 'options' connection property

* add support for custom 'options' connection property
* add parsing of 'options' to TestUtil

this closes #222

* doc: update documentation to mention custom 'options' connection property support

* update README.md and docs/documentation/head/connect.md so that they mention 'options' connection
parameter

* test: add unit test for 'options' connection initialization parameter

* add a unit test to check 'options' connection initialization parameter is passed to the database
To do that, a schema is created. search_path is then set by 'options' to its name, and is checked
after establishing a connection
  • Loading branch information...
leskin-in authored and davecramer committed Dec 6, 2018
1 parent 0999bb7 commit 7be21fc307fa28781d26a6f3752564236e3f9203
@@ -100,7 +100,7 @@ where:
* **host** (Optional) is the server address to connect. This could be a DNS or IP address, or it could be *localhost* or *127.0.0.1* for the local computer. To specify an IPv6 address your must enclose the host parameter with square brackets (jdbc:postgresql://[::1]:5740/accounting). Defaults to `localhost`.
* **port** (Optional) is the port number listening on the host. Defaults to `5432`.
* **database** (Optional) is the database name. Defaults to the same name as the *user name* used in the connection.
* **propertyX** (Optional) is one or more option connection properties. For more information see *Connection properties*.
* **propertyX** (Optional) is one or more option connection properties. For more information see *Connection properties*.

#### Connection Properties
In addition to the standard connection parameters the driver supports a number of additional properties which can be used to specify additional driver behaviour specific to PostgreSQL™. These properties may be specified in either the connection URL or an additional Properties object parameter to DriverManager.getConnection.
@@ -109,6 +109,7 @@ In addition to the standard connection parameters the driver supports a number o
| ----------------------------- | ------- | :-----: | ------------- |
| user | String | null | The database user on whose behalf the connection is being made. |
| password | String | null | The database user's password. |
| options | String | null | Specify 'options' connection initialization parameter. |
| ssl | Boolean | false | Control use of SSL (true value causes SSL to be required) |
| sslfactory | String | null | Provide a SSLSocketFactory class when using SSL. |
| sslfactoryarg (deprecated) | String | null | Argument forwarded to constructor of SSLSocketFactory class. |
@@ -149,7 +150,7 @@ In addition to the standard connection parameters the driver supports a number o
| preferQueryMode | String | extended | Specifies which mode is used to execute queries to database, possible values: extended, extendedForPrepared, extendedCacheEverything, simple |
| reWriteBatchedInserts | Boolean | false | Enable optimization to rewrite and collapse compatible INSERT statements that are batched. |

## Contributing
## Contributing
For information on how to contribute to the project see the [Contributing Guidelines](CONTRIBUTING.md)

----------------------------------------------------
@@ -54,6 +54,9 @@ URL or an additional `Properties` object parameter to `DriverManager.getConnecti
The following examples illustrate the use of both methods to establish a SSL
connection.

If a property is specified both in URL and in `Properties` object, the value from
`Properties` object is ignored.

```java
String url = "jdbc:postgresql://localhost/test";
Properties props = new Properties();
@@ -68,11 +71,20 @@ Connection conn = DriverManager.getConnection(url);

* **user** = String

The database user on whose behalf the connection is being made.
The database user on whose behalf the connection is being made.

* **password** = String

The database user's password.
The database user's password.

* **options** = String

Specify 'options' connection initialization parameter.

The value of this property may contain spaces or other special characters,
and it should be properly encoded if provided in the connection URL. Spaces
are considered to separate command-line arguments, unless escaped with
a backslash (`\`); `\\` represents a literal backslash.

* **ssl** = boolean

@@ -459,4 +471,4 @@ And read pool balances connections between slaves nodes, but allows connections

If a slave fails, all slaves in the list will be tried first. If the case that there are no available slaves
the master will be tried. If all of the servers are marked as "can't connect" in the cache then an attempt
will be made to connect to all of the hosts in the URL in order.
will be made to connect to all of the hosts in the URL in order.
@@ -55,6 +55,12 @@
"Force use of a particular protocol version when connecting, currently only version 3 is supported.",
false, "3"),

/**
* Specify 'options' connection initialization parameter.
* The value of this parameter may contain spaces and other special characters or their URL representation.
*/
OPTIONS("options", null, "Specify 'options' connection initialization parameter."),

/**
* <p>Logger level of the driver. Allowed values: {@code OFF}, {@code DEBUG} or {@code TRACE}.</p>
*
@@ -339,6 +339,12 @@ public QueryExecutor openConnectionImpl(HostSpec[] hostSpecs, String user, Strin
if (currentSchema != null) {
paramList.add(new String[]{"search_path", currentSchema});
}

String options = PGProperty.OPTIONS.get(info);
if (options != null) {
paramList.add(new String[]{"options", options});
}

return paramList;
}

@@ -232,6 +232,21 @@ public void setPortNumber(int portNumber) {
this.portNumber = portNumber;
}

/**
* @return command line options for this connection
*/
public String getOptions() {
return PGProperty.OPTIONS.get(properties);
}

/**
* Set command line options for this connection
* @param options string to set options to
*/
public void setOptions(String options) {
PGProperty.OPTIONS.set(properties, options);
}

/**
* @return login timeout
* @see PGProperty#LOGIN_TIMEOUT
@@ -69,6 +69,11 @@ public static String getURL(String hostport, String database) {
protocolVersion = "&protocolVersion=" + getProtocolVersion();
}

String options = "";
if (getOptions() != null) {
options = "&options=" + getOptions();
}

String binaryTransfer = "";
if (getBinaryTransfer() != null && !getBinaryTransfer().equals("")) {
binaryTransfer = "&binaryTransfer=" + getBinaryTransfer();
@@ -96,6 +101,7 @@ public static String getURL(String hostport, String database) {
+ logLevel
+ logFile
+ protocolVersion
+ options
+ binaryTransfer
+ receiveBufferSize
+ sendBufferSize
@@ -127,6 +133,10 @@ public static int getProtocolVersion() {
return Integer.parseInt(System.getProperty("protocolVersion", "0"));
}

public static String getOptions() {
return System.getProperty("options");
}

/*
* Returns the Test database
*/
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2004, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/

package org.postgresql.test.core;

import org.postgresql.PGProperty;
import org.postgresql.test.TestUtil;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

public class OptionsPropertyTest {
private static final String schemaName = "options_property_test";
private static final String optionsValue = "-c search_path=" + schemaName;

@Before
public void setUp() throws Exception {
Connection con = TestUtil.openDB();
Statement stmt = con.createStatement();
stmt.execute("DROP SCHEMA IF EXISTS " + schemaName + ";");
stmt.execute("CREATE SCHEMA " + schemaName + ";");
stmt.close();
TestUtil.closeDB(con);
}

@Test
public void testOptionsInProperties() throws Exception {
Properties props = new Properties();
props.setProperty(PGProperty.OPTIONS.getName(), optionsValue);

Connection con = TestUtil.openDB(props);
Statement stmt = con.createStatement();
stmt.execute("SHOW search_path");

ResultSet rs = stmt.getResultSet();
if (!rs.next()) {
Assert.fail("'options' connection initialization parameter should be passed to the database.");
}
Assert.assertEquals("'options' connection initialization parameter should be passed to the database.", schemaName, rs.getString(1));

stmt.close();
TestUtil.closeDB(con);
}

@After
public void tearDown() throws Exception {
Connection con = TestUtil.openDB();
Statement stmt = con.createStatement();
stmt.execute("DROP SCHEMA " + schemaName + ";");
stmt.close();
TestUtil.closeDB(con);
}
}
@@ -16,6 +16,7 @@
import org.postgresql.jdbc.PrimitiveArraySupportTest;
import org.postgresql.test.core.JavaVersionTest;
import org.postgresql.test.core.NativeQueryBindLengthTest;
import org.postgresql.test.core.OptionsPropertyTest;
import org.postgresql.test.util.ExpressionPropertiesTest;
import org.postgresql.test.util.LruCacheTest;
import org.postgresql.test.util.ServerVersionParseTest;
@@ -61,6 +62,7 @@
ReaderInputStreamTest.class,
ServerVersionParseTest.class,
ServerVersionTest.class,
OptionsPropertyTest.class,

TypeCacheDLLStressTest.class,

0 comments on commit 7be21fc

Please sign in to comment.
You can’t perform that action at this time.