[libpostgresql-jdbc-java] 62/93: Added feature to disable column name sanitiser with a new property. Added test cases for existing default behaviour along with tests for behaviour when sanitiser is disabled. Can be configured via Driver or DataSource configuration property.
Emmanuel Bourg
ebourg-guest at moszumanska.debian.org
Mon Jan 9 10:18:52 UTC 2017
This is an automated email from the git hooks/post-receive script.
ebourg-guest pushed a commit to annotated tag REL9_3_1102
in repository libpostgresql-jdbc-java.
commit ced665ef19de63d71beca256bbe48b233221c97e
Author: Jeremy Whiting <jwhiting at redhat.com>
Date: Wed Jan 22 19:06:31 2014 +0000
Added feature to disable column name sanitiser with a new property. Added test cases for existing default behaviour along with tests for behaviour when sanitiser is disabled. Can be configured via Driver or DataSource configuration property.
---
org/postgresql/Driver.java.in | 4 +-
org/postgresql/core/BaseConnection.java | 5 +
org/postgresql/ds/common/BaseDataSource.java | 24 +++-
org/postgresql/jdbc2/AbstractJdbc2Connection.java | 13 ++
org/postgresql/jdbc2/AbstractJdbc2ResultSet.java | 19 ++-
org/postgresql/test/TestUtil.java | 24 ++++
.../test/jdbc2/ColumnSanitiserDisabledTest.java | 133 +++++++++++++++++++++
.../test/jdbc2/ColumnSanitiserEnabledTest.java | 126 +++++++++++++++++++
org/postgresql/test/jdbc2/Jdbc2TestSuite.java | 2 +
.../optional/CaseOptimiserDataSourceTest.java | 116 ++++++++++++++++++
.../test/jdbc2/optional/OptionalTestSuite.java | 1 +
11 files changed, 462 insertions(+), 5 deletions(-)
diff --git a/org/postgresql/Driver.java.in b/org/postgresql/Driver.java.in
index d2f0907..4849266 100644
--- a/org/postgresql/Driver.java.in
+++ b/org/postgresql/Driver.java.in
@@ -482,7 +482,9 @@ public class Driver implements java.sql.Driver
{ "kerberosServerName", Boolean.FALSE,
"The Kerberos service name to use when authenticating with GSSAPI. This is equivalent to libpq's PGKRBSRVNAME environment variable." },
{ "jaasApplicationName", Boolean.FALSE,
- "Specifies the name of the JAAS system or application login configuration." }
+ "Specifies the name of the JAAS system or application login configuration." },
+ { "disableColumnSanitiser", Boolean.FALSE,
+ "Enable optimization that disables column name sanitiser." }
};
/**
diff --git a/org/postgresql/core/BaseConnection.java b/org/postgresql/core/BaseConnection.java
index 6373d53..fb27867 100644
--- a/org/postgresql/core/BaseConnection.java
+++ b/org/postgresql/core/BaseConnection.java
@@ -154,4 +154,9 @@ public interface BaseConnection extends PGConnection, Connection
* @return True for binary transfer, false for text transfer.
*/
public boolean binaryTransferSend(int oid);
+
+ /**
+ * Return whether to disable column name sanitization.
+ */
+ public boolean isColumnSanitiserDisabled();
}
diff --git a/org/postgresql/ds/common/BaseDataSource.java b/org/postgresql/ds/common/BaseDataSource.java
index 514620c..3ab97dc 100644
--- a/org/postgresql/ds/common/BaseDataSource.java
+++ b/org/postgresql/ds/common/BaseDataSource.java
@@ -65,7 +65,8 @@ public abstract class BaseDataSource implements Referenceable
private int protocolVersion = 0;
private String applicationName;
private String stringType=null;
- private boolean logLevelSet = false;
+ private boolean logLevelSet = false;
+ private boolean disableColumnSanitiser = false;
/**
* Gets a connection to the PostgreSQL database. The database is identified by the
@@ -499,6 +500,22 @@ public abstract class BaseDataSource implements Referenceable
{
this.stringType = stringType;
}
+
+ /**
+ * Returns the state of column sanitiser optimisation.
+ * @return boolean is optimisation enabled
+ */
+ public boolean isColumnSanitiserDisabled() {
+ return disableColumnSanitiser;
+ }
+
+ /**
+ * Set the state of column sanitiser optimisation.
+ * @param boolean new optimisation state
+ */
+ public void setDisableColumnSanitiser(boolean disableColumnSanitiser) {
+ this.disableColumnSanitiser = disableColumnSanitiser;
+ }
/**
* Generates a DriverManager URL from the other properties supplied.
@@ -555,6 +572,7 @@ public abstract class BaseDataSource implements Referenceable
if (binaryTransferDisable != null) {
sb.append("&binaryTransferDisable=").append(binaryTransferDisable);
}
+ sb.append("&disableColumnSanitiser=").append(disableColumnSanitiser);
return sb.toString();
}
@@ -583,6 +601,7 @@ public abstract class BaseDataSource implements Referenceable
applicationName = p.getProperty("ApplicationName");
stringType = p.getProperty("stringtype");
binaryTransfer = Boolean.parseBoolean(p.getProperty("binaryTransfer"));
+ disableColumnSanitiser = Boolean.parseBoolean(p.getProperty("disableColumnSanitiser"));
}
/**
@@ -653,6 +672,7 @@ public abstract class BaseDataSource implements Referenceable
{
ref.add(new StringRefAddr("ApplicationName", applicationName));
}
+ ref.add(new StringRefAddr("disableColumnSanitiser", Boolean.toString(disableColumnSanitiser)));
return ref;
}
@@ -682,6 +702,7 @@ public abstract class BaseDataSource implements Referenceable
out.writeObject(binaryTransferEnable);
out.writeObject(binaryTransferDisable);
out.writeBoolean(logLevelSet);
+ out.writeBoolean(disableColumnSanitiser);
}
protected void readBaseObject(ObjectInputStream in) throws IOException, ClassNotFoundException
@@ -709,6 +730,7 @@ public abstract class BaseDataSource implements Referenceable
binaryTransferEnable = (String)in.readObject();
binaryTransferDisable = (String)in.readObject();
logLevelSet = in.readBoolean();
+ disableColumnSanitiser = in.readBoolean();
}
public void initializeFrom(BaseDataSource source) throws IOException, ClassNotFoundException {
diff --git a/org/postgresql/jdbc2/AbstractJdbc2Connection.java b/org/postgresql/jdbc2/AbstractJdbc2Connection.java
index 48a5260..c84de44 100644
--- a/org/postgresql/jdbc2/AbstractJdbc2Connection.java
+++ b/org/postgresql/jdbc2/AbstractJdbc2Connection.java
@@ -58,6 +58,8 @@ public abstract class AbstractJdbc2Connection implements BaseConnection
private final Query rollbackQuery;
private TypeInfo _typeCache;
+
+ private boolean disableColumnSanitiser = false;
// Default statement prepare threshold.
protected int prepareThreshold;
@@ -260,6 +262,8 @@ public abstract class AbstractJdbc2Connection implements BaseConnection
openStackTrace = new Throwable("Connection was created at this point:");
enableDriverManagerLogging();
}
+ this.disableColumnSanitiser = Boolean.valueOf(info.getProperty(""
+ + "disableColumnSanitiser", Boolean.FALSE.toString()));
}
private Set<Integer> getOidSet(String oidList) throws PSQLException {
@@ -1246,4 +1250,13 @@ public abstract class AbstractJdbc2Connection implements BaseConnection
{
return protoConnection.getBackendPID();
}
+
+ public boolean isColumnSanitiserDisabled() {
+ return this.disableColumnSanitiser;
+ }
+
+ public void setDisableColumnSanitiser(boolean disableColumnSanitiser)
+ {
+ this.disableColumnSanitiser = disableColumnSanitiser;
+ }
}
diff --git a/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java b/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
index b847694..503345a 100644
--- a/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
+++ b/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
@@ -25,6 +25,7 @@ import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.Calendar;
import java.util.Locale;
+
import org.postgresql.core.*;
import org.postgresql.largeobject.*;
import org.postgresql.util.ByteConverter;
@@ -2731,15 +2732,20 @@ public abstract class AbstractJdbc2ResultSet implements BaseResultSet, org.postg
private int findColumnIndex(String columnName)
{
- if (columnNameIndexMap == null)
+ if (columnNameIndexMap == null)
{
columnNameIndexMap = new HashMap(fields.length * 2);
// The JDBC spec says when you have duplicate columns names,
// the first one should be returned. So load the map in
// reverse order so the first ones will overwrite later ones.
+ boolean isSanitiserDisabled = connection.isColumnSanitiserDisabled();
for (int i = fields.length - 1; i >= 0; i--)
{
- columnNameIndexMap.put(fields[i].getColumnLabel().toLowerCase(Locale.US), new Integer(i + 1));
+ if (isSanitiserDisabled){
+ columnNameIndexMap.put(fields[i].getColumnLabel(), new Integer(i + 1));
+ } else {
+ columnNameIndexMap.put(fields[i].getColumnLabel().toLowerCase(Locale.US), new Integer(i + 1));
+ }
}
}
@@ -2748,6 +2754,13 @@ public abstract class AbstractJdbc2ResultSet implements BaseResultSet, org.postg
{
return index.intValue();
}
+
+ index = (Integer)columnNameIndexMap.get(columnName.toUpperCase(Locale.US));
+ if (index != null)
+ {
+ columnNameIndexMap.put(columnName, index);
+ return index.intValue();
+ }
index = (Integer)columnNameIndexMap.get(columnName.toLowerCase(Locale.US));
if (index != null)
@@ -2755,7 +2768,7 @@ public abstract class AbstractJdbc2ResultSet implements BaseResultSet, org.postg
columnNameIndexMap.put(columnName, index);
return index.intValue();
}
-
+
return 0;
}
diff --git a/org/postgresql/test/TestUtil.java b/org/postgresql/test/TestUtil.java
index 4c42aee..ab91549 100644
--- a/org/postgresql/test/TestUtil.java
+++ b/org/postgresql/test/TestUtil.java
@@ -531,4 +531,28 @@ public class TestUtil
System.out.println();
}
}
+
+ /*
+ * Find the column for the given label. Only SQLExceptions
+ * for system or set-up problems are thrown.
+ * The PSQLState.UNDEFINED_COLUMN type exception is
+ * consumed to allow cleanup. Relying on the caller
+ * to detect if the column lookup was successful.
+ */
+ public static int findColumn(PreparedStatement query, String label) throws SQLException
+ {
+ int returnValue = 0;
+ ResultSet rs = query.executeQuery();
+ if (rs.next())
+ {
+ try
+ {
+ returnValue = rs.findColumn(label);
+ }
+ catch (SQLException sqle)
+ {} //consume exception to allow cleanup of resource.
+ }
+ rs.close();
+ return returnValue;
+ }
}
diff --git a/org/postgresql/test/jdbc2/ColumnSanitiserDisabledTest.java b/org/postgresql/test/jdbc2/ColumnSanitiserDisabledTest.java
new file mode 100644
index 0000000..d3d9199
--- /dev/null
+++ b/org/postgresql/test/jdbc2/ColumnSanitiserDisabledTest.java
@@ -0,0 +1,133 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (c) 2004-2014, PostgreSQL Global Development Group
+ *
+ *
+ *-------------------------------------------------------------------------
+ */
+package org.postgresql.test.jdbc2;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.postgresql.core.BaseConnection;
+import org.postgresql.test.TestUtil;
+
+/*
+ * This test suite will check the behaviour of the findColumnIndex
+ * method. This is testing the behaviour when sanitiser is disabled.
+ */
+public class ColumnSanitiserDisabledTest extends TestCase
+{
+ private Connection conn;
+
+ public ColumnSanitiserDisabledTest(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws Exception
+ {
+ Properties props = new Properties();
+ props.setProperty("disableColumnSanitiser", Boolean.TRUE.toString());
+ conn = TestUtil.openDB(props);
+ assertTrue(conn instanceof BaseConnection);
+ BaseConnection bc = (BaseConnection)conn;
+ assertTrue(
+ "Expected state [TRUE] of base connection configuration failed test."
+ , bc.isColumnSanitiserDisabled());
+ /* Quoted columns will be stored with case preserved. Driver will
+ * receive column names as defined in db server. */
+ TestUtil.createTable(conn, "allmixedup",
+ "id int primary key, \"DESCRIPTION\" varchar(40), \"fOo\" varchar(3)");
+ Statement data = conn.createStatement();
+ data.execute(TestUtil.insertSQL("allmixedup",
+ "1,'mixed case test', 'bar'"));
+ data.close();
+ }
+
+ protected void tearDown() throws Exception
+ {
+ TestUtil.dropTable(conn, "allmixedup");
+ TestUtil.closeDB(conn);
+ System.setProperty("disableColumnSanitiser", "false");
+ }
+
+ /*
+ * Test cases checking different combinations of columns origination from
+ * database against application supplied column names.
+ */
+
+ public void testTableColumnLowerNowFindFindLowerCaseColumn()
+ throws SQLException
+ {
+ findColumn("id", true);
+ }
+
+ public void testTableColumnLowerNowFindFindUpperCaseColumn()
+ throws SQLException
+ {
+ findColumn("ID", true);
+ }
+
+ public void testTableColumnLowerNowFindFindMixedCaseColumn()
+ throws SQLException
+ {
+ findColumn("Id", false);
+ }
+
+ public void testTableColumnUpperNowFindFindLowerCaseColumn()
+ throws SQLException
+ {
+ findColumn("description", true);
+ }
+
+ public void testTableColumnUpperNowFindFindUpperCaseColumn()
+ throws SQLException
+ {
+ findColumn("DESCRIPTION", true);
+ }
+
+ public void testTableColumnUpperNowFindFindMixedCaseColumn()
+ throws SQLException
+ {
+ findColumn("Description", false);
+ }
+
+ public void testTableColumnMixedNowFindLowerCaseColumn()
+ throws SQLException
+ {
+ findColumn("foo", false);
+ }
+
+ public void testTableColumnMixedNowFindFindUpperCaseColumn()
+ throws SQLException
+ {
+ findColumn("FOO", false);
+ }
+
+ public void testTableColumnMixedNowFindFindMixedCaseColumn()
+ throws SQLException
+ {
+ findColumn("fOo", true);
+ }
+
+ private void findColumn(String label, boolean failOnNotFound)
+ throws SQLException
+ {
+ PreparedStatement query = conn
+ .prepareStatement("select * from allmixedup");
+ if (0 == TestUtil.findColumn(query, label) && failOnNotFound)
+ {
+ fail(String
+ .format("Expected to find the column with the label [%1$s].",
+ label));
+ }
+ query.close();
+ }
+}
diff --git a/org/postgresql/test/jdbc2/ColumnSanitiserEnabledTest.java b/org/postgresql/test/jdbc2/ColumnSanitiserEnabledTest.java
new file mode 100644
index 0000000..3dd356b
--- /dev/null
+++ b/org/postgresql/test/jdbc2/ColumnSanitiserEnabledTest.java
@@ -0,0 +1,126 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (c) 2004-2014, PostgreSQL Global Development Group
+ *
+ *
+ *-------------------------------------------------------------------------
+ */
+package org.postgresql.test.jdbc2;
+
+import org.postgresql.core.BaseConnection;
+import org.postgresql.test.TestUtil;
+
+import junit.framework.TestCase;
+
+import java.sql.*;
+import java.util.Properties;
+
+/*
+ * This test suite will check the behaviour of the findColumnIndex
+ * method. The tests will check the behaviour of the method when
+ * the sanitiser is enabled. Default behaviour of the driver.
+ */
+public class ColumnSanitiserEnabledTest extends TestCase
+{
+ private Connection conn;
+
+ public ColumnSanitiserEnabledTest(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws Exception
+ {
+ Properties props = new Properties();
+ props.setProperty("disableColumnSanitiser", Boolean.FALSE.toString());
+ conn = TestUtil.openDB(props);
+ assertTrue(conn instanceof BaseConnection);
+ BaseConnection bc = (BaseConnection)conn;
+ assertFalse("Expected state [FALSE] of base connection configuration failed test.", bc.isColumnSanitiserDisabled());
+ TestUtil.createTable( conn,"allmixedup",
+ "id int primary key, \"DESCRIPTION\" varchar(40), \"fOo\" varchar(3)");
+ Statement data = conn.createStatement();
+ data.execute(TestUtil.insertSQL("allmixedup",
+ "1,'mixed case test', 'bar'"));
+ data.close();
+ }
+
+ protected void tearDown() throws Exception
+ {
+ TestUtil.dropTable(conn, "allmixedup");
+ TestUtil.closeDB(conn);
+ }
+
+ /*
+ * Test cases checking different combinations of columns origination from
+ * database against application supplied column names.
+ */
+
+ public void testTableColumnLowerNowFindFindLowerCaseColumn()
+ throws SQLException
+ {
+ findColumn("id", true);
+ }
+
+ public void testTableColumnLowerNowFindFindUpperCaseColumn()
+ throws SQLException
+ {
+ findColumn("ID", true);
+ }
+
+ public void testTableColumnLowerNowFindFindMixedCaseColumn()
+ throws SQLException
+ {
+ findColumn("Id", true);
+ }
+
+ public void testTableColumnUpperNowFindFindLowerCaseColumn()
+ throws SQLException
+ {
+ findColumn("description", true);
+ }
+
+ public void testTableColumnUpperNowFindFindUpperCaseColumn()
+ throws SQLException
+ {
+ findColumn("DESCRIPTION", true);
+ }
+
+ public void testTableColumnUpperNowFindFindMixedCaseColumn()
+ throws SQLException
+ {
+ findColumn("Description", true);
+ }
+
+ public void testTableColumnMixedNowFindLowerCaseColumn()
+ throws SQLException
+ {
+ findColumn("foo", true);
+ }
+
+ public void testTableColumnMixedNowFindFindUpperCaseColumn()
+ throws SQLException
+ {
+ findColumn("FOO", true);
+ }
+
+ public void testTableColumnMixedNowFindFindMixedCaseColumn()
+ throws SQLException
+ {
+ findColumn("fOo", true);
+ }
+
+ private void findColumn(String label, boolean failOnNotFound)
+ throws SQLException
+ {
+ PreparedStatement query = conn
+ .prepareStatement("select * from allmixedup");
+ if (0 == TestUtil.findColumn(query, label) && failOnNotFound)
+ {
+ fail(String
+ .format("Expected to find the column with the label [%1$s].",
+ label));
+ }
+ query.close();
+ }
+}
diff --git a/org/postgresql/test/jdbc2/Jdbc2TestSuite.java b/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
index 699aaab..732e498 100644
--- a/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
+++ b/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
@@ -42,6 +42,8 @@ public class Jdbc2TestSuite extends TestSuite
suite.addTestSuite(DatabaseMetaDataPropertiesTest.class);
suite.addTestSuite(SearchPathLookupTest.class);
suite.addTestSuite(EncodingTest.class);
+ suite.addTestSuite(ColumnSanitiserDisabledTest.class);
+ suite.addTestSuite(ColumnSanitiserEnabledTest.class);
// Connectivity/Protocols
diff --git a/org/postgresql/test/jdbc2/optional/CaseOptimiserDataSourceTest.java b/org/postgresql/test/jdbc2/optional/CaseOptimiserDataSourceTest.java
new file mode 100644
index 0000000..a76a633
--- /dev/null
+++ b/org/postgresql/test/jdbc2/optional/CaseOptimiserDataSourceTest.java
@@ -0,0 +1,116 @@
+/*-------------------------------------------------------------------------
+ *
+ * Copyright (c) 2004-2014, PostgreSQL Global Development Group
+ *
+ *
+ *-------------------------------------------------------------------------
+ */
+package org.postgresql.test.jdbc2.optional;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import junit.framework.TestCase;
+
+import org.postgresql.core.BaseConnection;
+import org.postgresql.ds.common.BaseDataSource;
+import org.postgresql.jdbc2.optional.SimpleDataSource;
+import org.postgresql.test.TestUtil;
+/*
+ * DataSource test to ensure the BaseConnection is configured with column
+ * sanitiser disabled.
+ */
+public class CaseOptimiserDataSourceTest extends TestCase
+{
+ private BaseDataSource bds;
+ protected Connection conn;
+
+ protected void initializeDataSource()
+ {
+ if (bds == null)
+ {
+ bds = new SimpleDataSource();
+ setupDataSource(bds);
+ bds.setDisableColumnSanitiser(true);
+ }
+ }
+
+ public void setUp() throws SQLException
+ {
+ Connection conn = getDataSourceConnection();
+ assertTrue(conn instanceof BaseConnection);
+ BaseConnection bc = (BaseConnection)conn;
+ assertTrue(
+ "Expected state [TRUE] of base connection configuration failed test."
+ , bc.isColumnSanitiserDisabled());
+ Statement insert = conn.createStatement();
+ TestUtil.createTable( conn, "allmixedup",
+ "id int primary key, \"DESCRIPTION\" varchar(40), \"fOo\" varchar(3)");
+ insert.execute(TestUtil.insertSQL("allmixedup",
+ "1,'mixed case test', 'bar'"));
+ insert.close();
+ conn.close();
+ }
+
+ @Override
+ public void tearDown() throws SQLException
+ {
+ Connection conn = getDataSourceConnection();
+ Statement drop = conn.createStatement();
+ drop.execute("drop table allmixedup");
+ drop.close();
+ conn.close();
+ bds.setDisableColumnSanitiser(false);
+ }
+
+ /*
+ * Test to ensure a datasource can be configured with the column sanitiser
+ * optimisation. This test checks for a side effect of the sanitiser being
+ * disabled. The column is not expected to be found.
+ */
+ public void testDataSourceDisabledSanitiserPropertySucceeds()
+ throws SQLException
+ {
+ String label = "FOO";
+ PreparedStatement query = getDataSourceConnection().prepareStatement(
+ "select * from allmixedup");
+ if (0 < TestUtil.findColumn(query, label))
+ {
+ fail(String.format(
+ "Did not expect to find the column with the label [%1$s].",
+ label));
+ }
+ query.close();
+ }
+
+ /**
+ * Gets a connection from the current BaseDataSource
+ */
+ protected Connection getDataSourceConnection() throws SQLException
+ {
+ if (bds == null)
+ {
+ initializeDataSource();
+ }
+ return bds.getConnection();
+ }
+
+ public static void setupDataSource(BaseDataSource bds)
+ {
+ bds.setServerName(TestUtil.getServer());
+ bds.setPortNumber(TestUtil.getPort());
+ bds.setDatabaseName(TestUtil.getDatabase());
+ bds.setUser(TestUtil.getUser());
+ bds.setPassword(TestUtil.getPassword());
+ bds.setPrepareThreshold(TestUtil.getPrepareThreshold());
+ bds.setLogLevel(TestUtil.getLogLevel());
+ bds.setProtocolVersion(TestUtil.getProtocolVersion());
+ }
+
+ public CaseOptimiserDataSourceTest(String name)
+ {
+ super(name);
+ }
+}
diff --git a/org/postgresql/test/jdbc2/optional/OptionalTestSuite.java b/org/postgresql/test/jdbc2/optional/OptionalTestSuite.java
index f4a7cc3..88e6af9 100644
--- a/org/postgresql/test/jdbc2/optional/OptionalTestSuite.java
+++ b/org/postgresql/test/jdbc2/optional/OptionalTestSuite.java
@@ -29,6 +29,7 @@ public class OptionalTestSuite extends TestSuite
suite.addTestSuite(SimpleDataSourceTest.class);
suite.addTestSuite(ConnectionPoolTest.class);
suite.addTestSuite(PoolingDataSourceTest.class);
+ suite.addTestSuite(CaseOptimiserDataSourceTest.class);
return suite;
}
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libpostgresql-jdbc-java.git
More information about the pkg-java-commits
mailing list