This is an automated email from the ASF dual-hosted git repository.
dschneider pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new 56c3593 GEODE-6156: add --id option to create jdbc-mapping (#2969)
56c3593 is described below
commit 56c35934241500e5afc30a347c969f6abe43920c
Author: Darrel Schneider <[email protected]>
AuthorDate: Tue Dec 11 13:27:42 2018 -0800
GEODE-6156: add --id option to create jdbc-mapping (#2969)
---
.../TableMetaDataManagerIntegrationTest.java | 50 ++++++--
.../jdbc/internal/TestConfigService.java | 2 +-
.../cli/CreateMappingCommandDUnitTest.java | 6 +-
.../cli/DescribeMappingCommandDUnitTest.java | 6 +-
.../internal/cli/ListMappingCommandDUnitTest.java | 2 +-
.../geode/connectors/jdbc/internal/SqlHandler.java | 4 +-
.../jdbc/internal/TableMetaDataManager.java | 40 +++++-
.../jdbc/internal/cli/CreateMappingCommand.java | 9 +-
.../jdbc/internal/cli/DescribeMappingCommand.java | 2 +
.../jdbc/internal/configuration/RegionMapping.java | 28 ++++-
.../connectors/jdbc/internal/xml/ElementType.java | 1 +
.../xml/JdbcConnectorServiceXmlParser.java | 1 +
.../geode.apache.org/schema/jdbc/jdbc-1.0.xsd | 1 +
.../sanctioned-geode-connectors-serializables.txt | 2 +-
.../jdbc/internal/RegionMappingTest.java | 73 +++++++----
.../connectors/jdbc/internal/SqlHandlerTest.java | 4 +-
.../jdbc/internal/TableMetaDataManagerTest.java | 139 +++++++++++++++++----
.../internal/cli/CreateMappingCommandTest.java | 22 ++--
.../internal/cli/CreateMappingFunctionTest.java | 2 +-
.../internal/cli/DescribeMappingCommandTest.java | 11 +-
.../jdbc/internal/cli/ListMappingCommandTest.java | 4 +-
.../jdbc/internal/xml/ElementTypeTest.java | 3 +
22 files changed, 313 insertions(+), 99 deletions(-)
diff --git
a/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerIntegrationTest.java
b/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerIntegrationTest.java
index 2136f4a..399229c 100644
---
a/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerIntegrationTest.java
+++
b/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerIntegrationTest.java
@@ -42,7 +42,6 @@ public abstract class TableMetaDataManagerIntegrationTest {
public void setup() throws Exception {
connection = getConnection();
statement = connection.createStatement();
- createTable();
manager = new TableMetaDataManager();
}
@@ -71,12 +70,20 @@ public abstract class TableMetaDataManagerIntegrationTest {
statement.execute("CREATE TABLE " + REGION_TABLE_NAME + " (" + quote +
"id" + quote
+ " VARCHAR(10) primary key not null," + quote + "name" + quote + "
VARCHAR(10)," + quote
+ "age" + quote + " int)");
+ }
+ protected void createTableWithNoPrimaryKey() throws SQLException {
+ DatabaseMetaData metaData = connection.getMetaData();
+ String quote = metaData.getIdentifierQuoteString();
+ statement.execute("CREATE TABLE " + REGION_TABLE_NAME + " (" + quote +
"nonprimaryid" + quote
+ + " VARCHAR(10)," + quote + "name" + quote + " VARCHAR(10)," + quote
+ + "age" + quote + " int)");
}
@Test
- public void validateKeyColumnName() {
- TableMetaDataView metaData = manager.getTableMetaDataView(connection,
REGION_TABLE_NAME);
+ public void validateKeyColumnName() throws SQLException {
+ createTable();
+ TableMetaDataView metaData = manager.getTableMetaDataView(connection,
REGION_TABLE_NAME, null);
String keyColumnName = metaData.getKeyColumnName();
@@ -84,8 +91,31 @@ public abstract class TableMetaDataManagerIntegrationTest {
}
@Test
- public void validateColumnDataTypeForName() {
- TableMetaDataView metaData = manager.getTableMetaDataView(connection,
REGION_TABLE_NAME);
+ public void validateKeyColumnNameOnNonPrimaryKey() throws SQLException {
+ createTableWithNoPrimaryKey();
+ TableMetaDataView metaData =
+ manager.getTableMetaDataView(connection, REGION_TABLE_NAME,
"nonprimaryid");
+
+ String keyColumnName = metaData.getKeyColumnName();
+
+ assertThat(keyColumnName).isEqualTo("nonprimaryid");
+ }
+
+ @Test
+ public void validateKeyColumnNameOnNonPrimaryKeyWithInExactMatch() throws
SQLException {
+ createTableWithNoPrimaryKey();
+ TableMetaDataView metaData =
+ manager.getTableMetaDataView(connection, REGION_TABLE_NAME,
"NonPrimaryId");
+
+ String keyColumnName = metaData.getKeyColumnName();
+
+ assertThat(keyColumnName).isEqualTo("NonPrimaryId");
+ }
+
+ @Test
+ public void validateColumnDataTypeForName() throws SQLException {
+ createTable();
+ TableMetaDataView metaData = manager.getTableMetaDataView(connection,
REGION_TABLE_NAME, null);
int nameDataType = metaData.getColumnDataType("name");
@@ -93,8 +123,9 @@ public abstract class TableMetaDataManagerIntegrationTest {
}
@Test
- public void validateColumnDataTypeForId() {
- TableMetaDataView metaData = manager.getTableMetaDataView(connection,
REGION_TABLE_NAME);
+ public void validateColumnDataTypeForId() throws SQLException {
+ createTable();
+ TableMetaDataView metaData = manager.getTableMetaDataView(connection,
REGION_TABLE_NAME, null);
int nameDataType = metaData.getColumnDataType("id");
@@ -102,8 +133,9 @@ public abstract class TableMetaDataManagerIntegrationTest {
}
@Test
- public void validateColumnDataTypeForAge() {
- TableMetaDataView metaData = manager.getTableMetaDataView(connection,
REGION_TABLE_NAME);
+ public void validateColumnDataTypeForAge() throws SQLException {
+ createTable();
+ TableMetaDataView metaData = manager.getTableMetaDataView(connection,
REGION_TABLE_NAME, null);
int nameDataType = metaData.getColumnDataType("age");
diff --git
a/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
b/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
index 2f561f9..2441ae8 100644
---
a/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
+++
b/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
@@ -52,6 +52,6 @@ public class TestConfigService {
private static RegionMapping createRegionMapping(String pdxClassName) {
return new RegionMapping(REGION_NAME, pdxClassName, REGION_TABLE_NAME,
- CONNECTION_CONFIG_NAME);
+ CONNECTION_CONFIG_NAME, null);
}
}
diff --git
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
index 2bd74ef..21b48e2 100644
---
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
+++
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
@@ -16,6 +16,7 @@ package org.apache.geode.connectors.jdbc.internal.cli;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__DATA_SOURCE_NAME;
+import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__ID_NAME;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__PDX_NAME;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__REGION_NAME;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__SYNCHRONOUS_NAME;
@@ -183,6 +184,7 @@ public class CreateMappingCommandDUnitTest {
csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection");
csb.addOption(CREATE_MAPPING__TABLE_NAME, "myTable");
csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass");
+ csb.addOption(CREATE_MAPPING__ID_NAME, "myId");
gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess();
@@ -191,6 +193,7 @@ public class CreateMappingCommandDUnitTest {
assertThat(mapping.getDataSourceName()).isEqualTo("connection");
assertThat(mapping.getTableName()).isEqualTo("myTable");
assertThat(mapping.getPdxName()).isEqualTo("myPdxClass");
+ assertThat(mapping.getIds()).isEqualTo("myId");
validateRegionAlteredOnServer(regionName, false);
validateAsyncEventQueueCreatedOnServer(regionName, false);
});
@@ -200,6 +203,7 @@ public class CreateMappingCommandDUnitTest {
assertThat(regionMapping.getDataSourceName()).isEqualTo("connection");
assertThat(regionMapping.getTableName()).isEqualTo("myTable");
assertThat(regionMapping.getPdxName()).isEqualTo("myPdxClass");
+ assertThat(regionMapping.getIds()).isEqualTo("myId");
validateRegionAlteredInClusterConfig(regionName, false);
validateAsyncEventQueueCreatedInClusterConfig(regionName, false);
});
@@ -342,7 +346,7 @@ public class CreateMappingCommandDUnitTest {
// NOTE: --table is optional so it should not be in the output but it is.
See GEODE-3468.
gfsh.executeAndAssertThat(csb.toString()).statusIsError()
.containsOutput(
- "You should specify option (--table, --pdx-name, --synchronous)
for this command");
+ "You should specify option (--table, --pdx-name, --synchronous,
--id) for this command");
}
@Test
diff --git
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java
index d21227e..8490e42 100644
---
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java
+++
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java
@@ -16,6 +16,7 @@ package org.apache.geode.connectors.jdbc.internal.cli;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__DATA_SOURCE_NAME;
+import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__ID_NAME;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__PDX_NAME;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__REGION_NAME;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__TABLE_NAME;
@@ -85,6 +86,7 @@ public class DescribeMappingCommandDUnitTest implements
Serializable {
csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection");
csb.addOption(CREATE_MAPPING__TABLE_NAME, "testTable");
csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass");
+ csb.addOption(CREATE_MAPPING__ID_NAME, "myId");
gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess();
@@ -99,6 +101,7 @@ public class DescribeMappingCommandDUnitTest implements
Serializable {
commandResultAssert.containsKeyValuePair(CREATE_MAPPING__DATA_SOURCE_NAME,
"connection");
commandResultAssert.containsKeyValuePair(CREATE_MAPPING__TABLE_NAME,
"testTable");
commandResultAssert.containsKeyValuePair(CREATE_MAPPING__PDX_NAME,
"myPdxClass");
+ commandResultAssert.containsKeyValuePair(CREATE_MAPPING__ID_NAME, "myId");
}
@Test
@@ -139,13 +142,14 @@ public class DescribeMappingCommandDUnitTest implements
Serializable {
commandResultAssert.containsKeyValuePair(CREATE_MAPPING__DATA_SOURCE_NAME,
"connection");
commandResultAssert.containsKeyValuePair(CREATE_MAPPING__TABLE_NAME,
"testTable");
commandResultAssert.containsKeyValuePair(CREATE_MAPPING__PDX_NAME,
"myPdxClass");
+ commandResultAssert.containsKeyValuePair(CREATE_MAPPING__ID_NAME, "myId");
}
private void createRegionMapping() throws RegionMappingExistsException {
InternalCache cache = ClusterStartupRule.getCache();
JdbcConnectorService service =
cache.getService(JdbcConnectorService.class);
service.createRegionMapping(new RegionMapping(REGION_NAME, "myPdxClass",
- "testTable", "connection"));
+ "testTable", "connection", "myId"));
assertThat(service.getMappingForRegion(REGION_NAME)).isNotNull();
}
}
diff --git
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java
index 00cc454..6cfd1bc 100644
---
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java
+++
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java
@@ -116,7 +116,7 @@ public class ListMappingCommandDUnitTest implements
Serializable {
for (int i = 1; i <= N; i++) {
String name = regionName + "-" + i;
service.createRegionMapping(
- new RegionMapping(name, "x.y.MyPdxClass", "table", "connection"));
+ new RegionMapping(name, "x.y.MyPdxClass", "table", "connection",
null));
assertThat(service.getMappingForRegion(name)).isNotNull();
}
}
diff --git
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java
index 5d46e73..9335d03 100644
---
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java
+++
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java
@@ -76,7 +76,7 @@ public class SqlHandler {
PdxInstance result;
try (Connection connection =
getConnection(regionMapping.getDataSourceName())) {
TableMetaDataView tableMetaData =
this.tableMetaDataManager.getTableMetaDataView(connection,
- regionMapping.getRegionToTableName());
+ regionMapping.getRegionToTableName(), regionMapping.getIds());
EntryColumnData entryColumnData =
getEntryColumnData(tableMetaData, regionMapping, key, null,
Operation.GET);
try (PreparedStatement statement =
@@ -163,7 +163,7 @@ public class SqlHandler {
try (Connection connection =
getConnection(regionMapping.getDataSourceName())) {
TableMetaDataView tableMetaData =
this.tableMetaDataManager.getTableMetaDataView(connection,
- regionMapping.getRegionToTableName());
+ regionMapping.getRegionToTableName(), regionMapping.getIds());
EntryColumnData entryColumnData =
getEntryColumnData(tableMetaData, regionMapping, key, value,
operation);
int updateCount = 0;
diff --git
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManager.java
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManager.java
index f743caa..a454d3e 100644
---
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManager.java
+++
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManager.java
@@ -34,18 +34,20 @@ public class TableMetaDataManager {
private final ConcurrentMap<String, TableMetaDataView> tableToMetaDataMap =
new ConcurrentHashMap<>();
- public TableMetaDataView getTableMetaDataView(Connection connection, String
tableName) {
+ public TableMetaDataView getTableMetaDataView(Connection connection, String
tableName,
+ String ids) {
return tableToMetaDataMap.computeIfAbsent(tableName,
- k -> computeTableMetaDataView(connection, k));
+ k -> computeTableMetaDataView(connection, k, ids));
}
- private TableMetaDataView computeTableMetaDataView(Connection connection,
String tableName) {
+ private TableMetaDataView computeTableMetaDataView(Connection connection,
String tableName,
+ String ids) {
TableMetaData result;
try {
DatabaseMetaData metaData = connection.getMetaData();
try (ResultSet tables = metaData.getTables(null, null, "%", null)) {
String realTableName = getTableNameFromMetaData(tableName, tables);
- String key = getPrimaryKeyColumnNameFromMetaData(realTableName,
metaData);
+ String key = getPrimaryKeyColumnNameFromMetaData(realTableName,
metaData, ids);
String quoteString = metaData.getIdentifierQuoteString();
if (quoteString == null) {
quoteString = "";
@@ -83,8 +85,16 @@ public class TableMetaDataManager {
return result;
}
- private String getPrimaryKeyColumnNameFromMetaData(String tableName,
DatabaseMetaData metaData)
+ private String getPrimaryKeyColumnNameFromMetaData(String tableName,
DatabaseMetaData metaData,
+ String ids)
throws SQLException {
+ if (ids != null && !ids.isEmpty()) {
+ if (!doesColumnExistInTable(tableName, metaData, ids)) {
+ throw new JdbcConnectorException(
+ "The table " + tableName + " does not have a column named " + ids);
+ }
+ return ids;
+ }
try (ResultSet primaryKeys = metaData.getPrimaryKeys(null, null,
tableName)) {
if (!primaryKeys.next()) {
throw new JdbcConnectorException(
@@ -109,4 +119,24 @@ public class TableMetaDataManager {
}
}
}
+
+ private boolean doesColumnExistInTable(String tableName, DatabaseMetaData
metaData,
+ String columnName) throws SQLException {
+ int caseInsensitiveMatches = 0;
+ try (ResultSet columnData = metaData.getColumns(null, null, tableName,
"%")) {
+ while (columnData.next()) {
+ String realColumnName = columnData.getString("COLUMN_NAME");
+ if (columnName.equals(realColumnName)) {
+ return true;
+ } else if (columnName.equalsIgnoreCase(realColumnName)) {
+ caseInsensitiveMatches++;
+ }
+ }
+ }
+ if (caseInsensitiveMatches > 1) {
+ throw new JdbcConnectorException(
+ "The table " + tableName + " has more than one column that matches "
+ columnName);
+ }
+ return caseInsensitiveMatches != 0;
+ }
}
diff --git
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
index 5515f42..6bcefc5 100644
---
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
+++
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
@@ -63,6 +63,9 @@ public class CreateMappingCommand extends SingleGfshCommand {
static final String CREATE_MAPPING__SYNCHRONOUS_NAME = "synchronous";
static final String CREATE_MAPPING__SYNCHRONOUS_NAME__HELP =
"By default, writes will be asynchronous. If true, writes will be
synchronous.";
+ static final String CREATE_MAPPING__ID_NAME = "id";
+ static final String CREATE_MAPPING__ID_NAME__HELP =
+ "The table column name to use as the region key for this JDBC mapping.";
public static String createAsyncEventQueueName(String regionPath) {
if (regionPath.startsWith("/")) {
@@ -86,14 +89,16 @@ public class CreateMappingCommand extends SingleGfshCommand
{
help = CREATE_MAPPING__PDX_NAME__HELP) String pdxName,
@CliOption(key = CREATE_MAPPING__SYNCHRONOUS_NAME,
help = CREATE_MAPPING__SYNCHRONOUS_NAME__HELP,
- specifiedDefaultValue = "true", unspecifiedDefaultValue = "false")
boolean synchronous) {
+ specifiedDefaultValue = "true", unspecifiedDefaultValue = "false")
boolean synchronous,
+ @CliOption(key = CREATE_MAPPING__ID_NAME,
+ help = CREATE_MAPPING__ID_NAME__HELP) String id) {
if (regionName.startsWith("/")) {
regionName = regionName.substring(1);
}
// input
Set<DistributedMember> targetMembers = getMembers(null, null);
- RegionMapping mapping = new RegionMapping(regionName, pdxName, table,
dataSourceName);
+ RegionMapping mapping = new RegionMapping(regionName, pdxName, table,
dataSourceName, id);
try {
ConfigurationPersistenceService configurationPersistenceService =
diff --git
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java
index cb589c8..038c31c 100644
---
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java
+++
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java
@@ -15,6 +15,7 @@
package org.apache.geode.connectors.jdbc.internal.cli;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__DATA_SOURCE_NAME;
+import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__ID_NAME;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__PDX_NAME;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__REGION_NAME;
import static
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__TABLE_NAME;
@@ -89,6 +90,7 @@ public class DescribeMappingCommand extends GfshCommand {
sectionModel.addData(CREATE_MAPPING__DATA_SOURCE_NAME,
mapping.getDataSourceName());
sectionModel.addData(CREATE_MAPPING__TABLE_NAME, mapping.getTableName());
sectionModel.addData(CREATE_MAPPING__PDX_NAME, mapping.getPdxName());
+ sectionModel.addData(CREATE_MAPPING__ID_NAME, mapping.getIds());
}
@CliAvailabilityIndicator({DESCRIBE_MAPPING})
diff --git
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping.java
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping.java
index 7dfebeb..28bbacb 100644
---
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping.java
+++
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping.java
@@ -48,6 +48,7 @@ import org.apache.geode.pdx.internal.TypeRegistry;
* <attribute name="data-source"
type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="table"
type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="pdx-name"
type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="ids"
type="{http://www.w3.org/2001/XMLSchema}string" />
* </restriction>
* </complexContent>
* </complexType>
@@ -69,6 +70,8 @@ public class RegionMapping implements CacheElement {
protected String tableName;
@XmlAttribute(name = "pdx-name")
protected String pdxName;
+ @XmlAttribute(name = "ids")
+ protected String ids;
@XmlTransient
protected String regionName;
@@ -78,11 +81,12 @@ public class RegionMapping implements CacheElement {
public RegionMapping() {}
public RegionMapping(String regionName, String pdxName, String tableName,
- String dataSourceName) {
+ String dataSourceName, String ids) {
this.regionName = regionName;
this.pdxName = pdxName;
this.tableName = tableName;
this.dataSourceName = dataSourceName;
+ this.ids = ids;
}
public void setDataSourceName(String dataSourceName) {
@@ -101,6 +105,10 @@ public class RegionMapping implements CacheElement {
this.pdxName = pdxName;
}
+ public void setIds(String ids) {
+ this.ids = ids;
+ }
+
public String getDataSourceName() {
return dataSourceName;
}
@@ -113,6 +121,10 @@ public class RegionMapping implements CacheElement {
return pdxName;
}
+ public String getIds() {
+ return ids;
+ }
+
public String getTableName() {
return tableName;
}
@@ -230,6 +242,9 @@ public class RegionMapping implements CacheElement {
: that.dataSourceName != null) {
return false;
}
+ if (ids != null ? !ids.equals(that.ids) : that.ids != null) {
+ return false;
+ }
return true;
}
@@ -239,14 +254,19 @@ public class RegionMapping implements CacheElement {
result = 31 * result + pdxName.hashCode();
result = 31 * result + (tableName != null ? tableName.hashCode() : 0);
result = 31 * result + (dataSourceName != null ? dataSourceName.hashCode()
: 0);
+ result = 31 * result + (ids != null ? ids.hashCode() : 0);
return result;
}
@Override
public String toString() {
- return "RegionMapping{" + "regionName='" + regionName + '\'' + ",
pdxName='"
- + pdxName + '\'' + ", tableName='" + tableName + '\'' + ",
dataSourceName='"
- + dataSourceName + '\'' + '}';
+ return "RegionMapping{"
+ + "regionName='" + regionName + '\''
+ + ", pdxName='" + pdxName + '\''
+ + ", tableName='" + tableName + '\''
+ + ", dataSourceName='" + dataSourceName + '\''
+ + ", ids='" + ids + '\''
+ + '}';
}
@Override
diff --git
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java
index 7379d61..46eca88 100644
---
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java
+++
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java
@@ -37,6 +37,7 @@ public enum ElementType {
attributes.getValue(JdbcConnectorServiceXmlParser.DATA_SOURCE));
mapping.setTableName(attributes.getValue(JdbcConnectorServiceXmlParser.TABLE));
mapping.setPdxName(attributes.getValue(JdbcConnectorServiceXmlParser.PDX_NAME));
+ mapping.setIds(attributes.getValue(JdbcConnectorServiceXmlParser.IDS));
stack.push(mapping);
}
diff --git
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlParser.java
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlParser.java
index c2e7d36..abef62c 100644
---
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlParser.java
+++
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlParser.java
@@ -24,6 +24,7 @@ public class JdbcConnectorServiceXmlParser extends
AbstractXmlParser {
static final String DATA_SOURCE = "data-source";
static final String TABLE = "table";
static final String PDX_NAME = "pdx-name";
+ static final String IDS = "ids";
@Override
public String getNamespaceUri() {
diff --git
a/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd
b/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd
index 7082812..b225a4d 100644
---
a/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd
+++
b/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd
@@ -43,6 +43,7 @@ XML schema for JDBC Connector Service in Geode.
<xsd:attribute type="xsd:string" name="data-source"
use="required"/>
<xsd:attribute type="xsd:string" name="table" use="optional"/>
<xsd:attribute type="xsd:string" name="pdx-name"
use="required"/>
+ <xsd:attribute type="xsd:string" name="ids" use="optional"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>
diff --git
a/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt
b/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt
index 8c6a4af..de159fb 100755
---
a/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt
+++
b/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt
@@ -5,4 +5,4 @@
org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunction,false
org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunction,false
org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingFunction,false
org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunction,false
-org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping,false,dataSourceName:java/lang/String,pdxName:java/lang/String,regionName:java/lang/String,tableName:java/lang/String
+org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping,false,dataSourceName:java/lang/String,ids:java/lang/String,pdxName:java/lang/String,regionName:java/lang/String,tableName:java/lang/String
diff --git
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java
index f84b9c0..4eee89f 100644
---
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java
+++
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java
@@ -57,20 +57,21 @@ public class RegionMappingTest {
@Test
public void initiatedWithNullValues() {
- mapping = new RegionMapping(null, "pdxClassName", null, null);
+ mapping = new RegionMapping(null, "pdxClassName", null, null, null);
assertThat(mapping.getTableName()).isNull();
assertThat(mapping.getRegionName()).isNull();
assertThat(mapping.getDataSourceName()).isNull();
assertThat(mapping.getPdxName()).isEqualTo("pdxClassName");
assertThat(mapping.getRegionToTableName()).isNull();
+ assertThat(mapping.getIds()).isNull();
assertThat(mapping.getColumnNameForField("fieldName",
mock(TableMetaDataView.class)))
.isEqualTo("fieldName");
}
@Test
public void hasCorrectTableName() {
- mapping = new RegionMapping(null, null, name, null);
+ mapping = new RegionMapping(null, null, name, null, null);
assertThat(mapping.getTableName()).isEqualTo(name);
assertThat(mapping.getRegionToTableName()).isEqualTo(name);
@@ -78,7 +79,7 @@ public class RegionMappingTest {
@Test
public void hasCorrectTableNameWhenRegionNameIsSet() {
- mapping = new RegionMapping("regionName", null, "tableName", null);
+ mapping = new RegionMapping("regionName", null, "tableName", null, null);
assertThat(mapping.getRegionName()).isEqualTo("regionName");
assertThat(mapping.getTableName()).isEqualTo("tableName");
@@ -87,7 +88,7 @@ public class RegionMappingTest {
@Test
public void hasCorrectRegionName() {
- mapping = new RegionMapping(name, null, null, null);
+ mapping = new RegionMapping(name, null, null, null, null);
assertThat(mapping.getRegionName()).isEqualTo(name);
assertThat(mapping.getRegionToTableName()).isEqualTo(name);
@@ -95,21 +96,29 @@ public class RegionMappingTest {
@Test
public void hasCorrectConfigName() {
- mapping = new RegionMapping(null, null, null, name);
+ mapping = new RegionMapping(null, null, null, name, null);
assertThat(mapping.getDataSourceName()).isEqualTo(name);
}
@Test
public void hasCorrectPdxClassName() {
- mapping = new RegionMapping(null, name, null, null);
+ mapping = new RegionMapping(null, name, null, null, null);
assertThat(mapping.getPdxName()).isEqualTo(name);
}
@Test
+ public void hasCorrectIds() {
+ String ids = "ids";
+ mapping = new RegionMapping(null, null, null, null, ids);
+
+ assertThat(mapping.getIds()).isEqualTo(ids);
+ }
+
+ @Test
public void returnsColumnNameIfFieldNotMapped() {
- mapping = new RegionMapping(null, "pdxClassName", null, null);
+ mapping = new RegionMapping(null, "pdxClassName", null, null, null);
String columnName = mapping.getColumnNameForField(fieldName1,
mock(TableMetaDataView.class));
@@ -119,7 +128,7 @@ public class RegionMappingTest {
@Test
public void
returnsColumnNameFromTableMetaDataIfFieldNotMappedAndMetaDataMatchesWithCaseDiffering()
{
String metaDataColumnName = fieldName1.toUpperCase();
- mapping = new RegionMapping(null, "pdxClassName", null, null);
+ mapping = new RegionMapping(null, "pdxClassName", null, null, null);
TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
when(tableMetaDataView.getColumnNames()).thenReturn(Collections.singleton(metaDataColumnName));
@@ -130,7 +139,7 @@ public class RegionMappingTest {
@Test
public void
returnsColumnNameFromTableMetaDataIfFieldNotMappedAndMetaDataMatchesExactly() {
String metaDataColumnName = fieldName1;
- mapping = new RegionMapping(null, "pdxClassName", null, null);
+ mapping = new RegionMapping(null, "pdxClassName", null, null, null);
TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
when(tableMetaDataView.getColumnNames()).thenReturn(Collections.singleton(metaDataColumnName));
@@ -140,7 +149,7 @@ public class RegionMappingTest {
@Test
public void returnsColumnNameIfFieldNotMappedAndNotInMetaData() {
- mapping = new RegionMapping(null, "pdxClassName", null, null);
+ mapping = new RegionMapping(null, "pdxClassName", null, null, null);
TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
when(tableMetaDataView.getColumnNames()).thenReturn(Collections.singleton("does
not match"));
@@ -149,7 +158,7 @@ public class RegionMappingTest {
@Test
public void getColumnNameForFieldThrowsIfTwoColumnsMatchField() {
- mapping = new RegionMapping(null, "pdxClassName", null, null);
+ mapping = new RegionMapping(null, "pdxClassName", null, null, null);
TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
HashSet<String> columnNames =
@@ -165,7 +174,7 @@ public class RegionMappingTest {
@Test
public void throwsIfColumnNotMappedAndPdxClassNameDoesNotExist() {
- mapping = new RegionMapping(null, "pdxClassName", null, null);
+ mapping = new RegionMapping(null, "pdxClassName", null, null, null);
TypeRegistry typeRegistry = mock(TypeRegistry.class);
when(typeRegistry.getPdxTypesForClassName("pdxClassName")).thenReturn(Collections.emptySet());
expectedException.expect(JdbcConnectorException.class);
@@ -178,7 +187,7 @@ public class RegionMappingTest {
public void
throwsIfColumnNotMappedAndPdxClassNameDoesExistButHasNoMatchingFields() {
String pdxClassName = "pdxClassName";
String columnName = "columnName";
- mapping = new RegionMapping(null, pdxClassName, null, null);
+ mapping = new RegionMapping(null, pdxClassName, null, null, null);
TypeRegistry typeRegistry = mock(TypeRegistry.class);
HashSet<PdxType> pdxTypes = new
HashSet<>(Arrays.asList(mock(PdxType.class)));
when(typeRegistry.getPdxTypesForClassName(pdxClassName)).thenReturn(pdxTypes);
@@ -193,7 +202,7 @@ public class RegionMappingTest {
public void
throwsIfColumnNotMappedAndPdxClassNameDoesExistButHasMoreThanOneMatchingFields()
{
String pdxClassName = "pdxClassName";
String columnName = "columnName";
- mapping = new RegionMapping(null, pdxClassName, null, null);
+ mapping = new RegionMapping(null, pdxClassName, null, null, null);
TypeRegistry typeRegistry = mock(TypeRegistry.class);
PdxType pdxType = mock(PdxType.class);
when(pdxType.getFieldNames())
@@ -211,7 +220,7 @@ public class RegionMappingTest {
public void
returnsIfColumnNotMappedAndPdxClassNameDoesExistAndHasOneFieldThatInexactlyMatches()
{
String pdxClassName = "pdxClassName";
String columnName = "columnName";
- mapping = new RegionMapping(null, pdxClassName, null, null);
+ mapping = new RegionMapping(null, pdxClassName, null, null, null);
TypeRegistry typeRegistry = mock(TypeRegistry.class);
PdxType pdxType = mock(PdxType.class);
when(pdxType.getFieldNames())
@@ -227,7 +236,7 @@ public class RegionMappingTest {
public void
returnsIfColumnNotMappedAndPdxClassNameDoesExistAndHasOneFieldThatExactlyMatches()
{
String pdxClassName = "pdxClassName";
String columnName = "columnName";
- mapping = new RegionMapping(null, pdxClassName, null, null);
+ mapping = new RegionMapping(null, pdxClassName, null, null, null);
TypeRegistry typeRegistry = mock(TypeRegistry.class);
PdxType pdxType = mock(PdxType.class);
when(pdxType.getPdxField(columnName)).thenReturn(mock(PdxField.class));
@@ -240,9 +249,9 @@ public class RegionMappingTest {
@Test
public void verifyTwoDefaultInstancesAreEqual() {
RegionMapping rm1 =
- new RegionMapping("regionName", "pdxClassName", null,
"connectionName");
+ new RegionMapping("regionName", "pdxClassName", null,
"dataSourceName", null);
RegionMapping rm2 =
- new RegionMapping("regionName", "pdxClassName", null,
"connectionName");
+ new RegionMapping("regionName", "pdxClassName", null,
"dataSourceName", null);
assertThat(rm1).isEqualTo(rm2);
}
@@ -250,17 +259,17 @@ public class RegionMappingTest {
@Test
public void verifyTwoInstancesThatAreEqualHaveSameHashCode() {
RegionMapping rm1 = new RegionMapping("regionName",
- "pdxClassName", "tableName", "connectionName");
+ "pdxClassName", "tableName", "dataSourceName", "ids");
RegionMapping rm2 = new RegionMapping("regionName",
- "pdxClassName", "tableName", "connectionName");
+ "pdxClassName", "tableName", "dataSourceName", "ids");
assertThat(rm1.hashCode()).isEqualTo(rm2.hashCode());
}
@Test
public void verifyThatMappingIsEqualToItself() {
- mapping = new RegionMapping(null, "pdxClassName", null, null);
+ mapping = new RegionMapping(null, "pdxClassName", null, null, null);
boolean result = mapping.equals(mapping);
assertThat(mapping.hashCode()).isEqualTo(mapping.hashCode());
assertThat(result).isTrue();
@@ -268,14 +277,14 @@ public class RegionMappingTest {
@Test
public void verifyThatNullIsNotEqual() {
- mapping = new RegionMapping(null, null, null, null);
+ mapping = new RegionMapping(null, null, null, null, null);
boolean result = mapping.equals(null);
assertThat(result).isFalse();
}
@Test
public void verifyOtherClassIsNotEqual() {
- mapping = new RegionMapping(null, null, null, null);
+ mapping = new RegionMapping(null, null, null, null, null);
boolean result = mapping.equals("not equal");
assertThat(result).isFalse();
}
@@ -283,9 +292,9 @@ public class RegionMappingTest {
@Test
public void verifyMappingWithDifferentRegionNamesAreNotEqual() {
RegionMapping rm1 =
- new RegionMapping(null, null, null, null);
+ new RegionMapping(null, null, null, null, null);
RegionMapping rm2 =
- new RegionMapping("name", null, null, null);
+ new RegionMapping("name", null, null, null, null);
boolean result = rm1.equals(rm2);
assertThat(result).isFalse();
}
@@ -293,9 +302,19 @@ public class RegionMappingTest {
@Test
public void verifyMappingWithDifferentPdxClassNameAreNotEqual() {
RegionMapping rm1 =
- new RegionMapping(null, "pdxClassName", null, null);
+ new RegionMapping(null, "pdxClassName", null, null, null);
+ RegionMapping rm2 =
+ new RegionMapping(null, "pdxClass", null, null, null);
+ boolean result = rm1.equals(rm2);
+ assertThat(result).isFalse();
+ }
+
+ @Test
+ public void verifyMappingWithDifferentIdsAreNotEqual() {
+ RegionMapping rm1 =
+ new RegionMapping(null, "pdxClassName", null, null, "ids1");
RegionMapping rm2 =
- new RegionMapping(null, "pdxClass", null, null);
+ new RegionMapping(null, "pdxClassName", null, null, "ids2");
boolean result = rm1.equals(rm2);
assertThat(result).isFalse();
}
diff --git
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java
index 4600886..d93743f 100644
---
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java
+++
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java
@@ -91,7 +91,8 @@ public class SqlHandlerTest {
tableMetaDataView = mock(TableMetaDataView.class);
when(tableMetaDataView.getTableName()).thenReturn(TABLE_NAME);
when(tableMetaDataView.getKeyColumnName()).thenReturn(KEY_COLUMN);
- when(tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
+ final String IDS = "ids";
+ when(tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
IDS))
.thenReturn(tableMetaDataView);
connectorService = mock(JdbcConnectorService.class);
dataSourceFactory = mock(DataSourceFactory.class);
@@ -105,6 +106,7 @@ public class SqlHandlerTest {
when(regionMapping.getDataSourceName()).thenReturn(DATA_SOURCE_NAME);
when(regionMapping.getRegionName()).thenReturn(REGION_NAME);
when(regionMapping.getTableName()).thenReturn(TABLE_NAME);
+ when(regionMapping.getIds()).thenReturn(IDS);
when(regionMapping.getRegionToTableName()).thenReturn(TABLE_NAME);
when(connectorService.getMappingForRegion(REGION_NAME)).thenReturn(regionMapping);
diff --git
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerTest.java
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerTest.java
index 9390263..91e8a73 100644
---
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerTest.java
+++
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerTest.java
@@ -68,17 +68,88 @@ public class TableMetaDataManagerTest {
setupPrimaryKeysMetaData();
when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
- TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, "");
assertThat(data.getKeyColumnName()).isEqualTo(KEY_COLUMN);
verify(connection).getMetaData();
}
@Test
+ public void givenNoColumnsAndNonNullIdsThenExpectException() throws
Exception {
+ when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
+ when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME);
+ when(columnResultSet.next()).thenReturn(false);
+
+ assertThatThrownBy(
+ () -> tableMetaDataManager.getTableMetaDataView(connection,
TABLE_NAME, "nonExistentId"))
+ .isInstanceOf(JdbcConnectorException.class)
+ .hasMessageContaining("The table testTable does not have a column
named nonExistentId");
+ }
+
+ @Test
+ public void givenOneColumnAndNonNullIdsThatDoesNotMatchThenExpectException()
throws Exception {
+ when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
+ when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME);
+ when(columnResultSet.next()).thenReturn(true).thenReturn(false);
+
when(columnResultSet.getString("COLUMN_NAME")).thenReturn("existingColumn");
+
+ assertThatThrownBy(
+ () -> tableMetaDataManager.getTableMetaDataView(connection,
TABLE_NAME, "nonExistentId"))
+ .isInstanceOf(JdbcConnectorException.class)
+ .hasMessageContaining("The table testTable does not have a column
named nonExistentId");
+ }
+
+ @Test
+ public void
givenTwoColumnsAndNonNullIdsThatDoesNotExactlyMatchThenExpectException()
+ throws Exception {
+ when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
+ when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME);
+
when(columnResultSet.next()).thenReturn(true).thenReturn(true).thenReturn(false);
+ when(columnResultSet.getString("COLUMN_NAME")).thenReturn("nonexistentid")
+ .thenReturn("NONEXISTENTID");
+
+ assertThatThrownBy(
+ () -> tableMetaDataManager.getTableMetaDataView(connection,
TABLE_NAME, "nonExistentId"))
+ .isInstanceOf(JdbcConnectorException.class).hasMessageContaining(
+ "The table testTable has more than one column that matches
nonExistentId");
+ }
+
+ @Test
+ public void
givenThreeColumnsAndNonNullIdsThatDoesExactlyMatchThenKeyColumnNameIsReturned()
+ throws Exception {
+ when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
+ when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME);
+
when(columnResultSet.next()).thenReturn(true).thenReturn(true).thenReturn(true)
+ .thenReturn(false);
+
when(columnResultSet.getString("COLUMN_NAME")).thenReturn("existentid").thenReturn("EXISTENTID")
+ .thenReturn("ExistentId");
+
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
"ExistentId");
+
+ assertThat(data.getKeyColumnName()).isEqualTo("ExistentId");
+ }
+
+ @Test
+ public void
givenColumnAndNonNullIdsThatDoesInexactlyMatchThenKeyColumnNameIsReturned()
+ throws Exception {
+ when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
+ when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME);
+ when(columnResultSet.next()).thenReturn(true).thenReturn(false);
+ when(columnResultSet.getString("COLUMN_NAME")).thenReturn("existentid");
+
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
"ExistentId");
+
+ assertThat(data.getKeyColumnName()).isEqualTo("ExistentId");
+ }
+
+ @Test
public void returnsDefaultQuoteString() throws Exception {
setupPrimaryKeysMetaData();
when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
- TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
null);
assertThat(data.getIdentifierQuoteString()).isEqualTo("");
verify(connection).getMetaData();
@@ -91,7 +162,8 @@ public class TableMetaDataManagerTest {
String expectedQuoteString = "123";
when(databaseMetaData.getIdentifierQuoteString()).thenReturn(expectedQuoteString);
- TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
null);
assertThat(data.getIdentifierQuoteString()).isEqualTo(expectedQuoteString);
verify(connection).getMetaData();
@@ -102,8 +174,8 @@ public class TableMetaDataManagerTest {
setupPrimaryKeysMetaData();
when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
- tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
- tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, null);
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, null);
verify(connection).getMetaData();
}
@@ -112,8 +184,9 @@ public class TableMetaDataManagerTest {
SQLException cause = new SQLException("sql message");
when(connection.getMetaData()).thenThrow(cause);
- assertThatThrownBy(() ->
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
- .isInstanceOf(JdbcConnectorException.class).hasMessageContaining("sql
message");
+ assertThatThrownBy(
+ () -> tableMetaDataManager.getTableMetaDataView(connection,
TABLE_NAME, null))
+
.isInstanceOf(JdbcConnectorException.class).hasMessageContaining("sql message");
}
@Test
@@ -121,9 +194,10 @@ public class TableMetaDataManagerTest {
when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
when(tablesResultSet.getString("TABLE_NAME")).thenReturn("otherTable");
- assertThatThrownBy(() ->
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
- .isInstanceOf(JdbcConnectorException.class)
- .hasMessage("no table was found that matches testTable");
+ assertThatThrownBy(
+ () -> tableMetaDataManager.getTableMetaDataView(connection,
TABLE_NAME, null))
+ .isInstanceOf(JdbcConnectorException.class)
+ .hasMessage("no table was found that matches testTable");
}
@Test
@@ -131,9 +205,10 @@ public class TableMetaDataManagerTest {
setupPrimaryKeysMetaData();
when(primaryKeysResultSet.next()).thenReturn(true);
- assertThatThrownBy(() ->
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
- .isInstanceOf(JdbcConnectorException.class)
- .hasMessage("The table " + TABLE_NAME + " has more than one primary
key column.");
+ assertThatThrownBy(
+ () -> tableMetaDataManager.getTableMetaDataView(connection,
TABLE_NAME, null))
+ .isInstanceOf(JdbcConnectorException.class)
+ .hasMessage("The table " + TABLE_NAME + " has more than one
primary key column.");
}
@Test
@@ -144,7 +219,8 @@ public class TableMetaDataManagerTest {
when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME.toUpperCase())
.thenReturn(TABLE_NAME);
- TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
null);
assertThat(data.getTableName()).isEqualTo(TABLE_NAME);
}
@@ -158,7 +234,8 @@ public class TableMetaDataManagerTest {
when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME.toUpperCase());
- TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
null);
assertThat(data.getTableName()).isEqualTo(TABLE_NAME.toUpperCase());
}
@@ -172,9 +249,10 @@ public class TableMetaDataManagerTest {
when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME.toLowerCase())
.thenReturn(TABLE_NAME.toUpperCase());
- assertThatThrownBy(() ->
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
- .isInstanceOf(JdbcConnectorException.class)
- .hasMessage("Duplicate tables that match region name");
+ assertThatThrownBy(
+ () -> tableMetaDataManager.getTableMetaDataView(connection,
TABLE_NAME, null))
+ .isInstanceOf(JdbcConnectorException.class)
+ .hasMessage("Duplicate tables that match region name");
}
@Test
@@ -182,9 +260,10 @@ public class TableMetaDataManagerTest {
setupPrimaryKeysMetaData();
when(primaryKeysResultSet.next()).thenReturn(false);
- assertThatThrownBy(() ->
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
- .isInstanceOf(JdbcConnectorException.class)
- .hasMessage("The table " + TABLE_NAME + " does not have a primary key
column.");
+ assertThatThrownBy(
+ () -> tableMetaDataManager.getTableMetaDataView(connection,
TABLE_NAME, null))
+ .isInstanceOf(JdbcConnectorException.class)
+ .hasMessage("The table " + TABLE_NAME + " does not have a primary
key column.");
}
@Test
@@ -192,7 +271,8 @@ public class TableMetaDataManagerTest {
setupPrimaryKeysMetaData();
when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
- TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
null);
int dataType = data.getColumnDataType("unknownColumn");
assertThat(dataType).isEqualTo(0);
@@ -211,7 +291,8 @@ public class TableMetaDataManagerTest {
when(columnResultSet.getInt("DATA_TYPE")).thenReturn(columnDataType1)
.thenReturn(columnDataType2);
- TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
null);
int dataType1 = data.getColumnDataType(columnName1);
int dataType2 = data.getColumnDataType(columnName2);
@@ -235,7 +316,8 @@ public class TableMetaDataManagerTest {
.thenReturn(columnDataType2);
Set<String> expectedColumnNames = new HashSet<>(Arrays.asList(columnName1,
columnName2));
- TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
null);
Set<String> columnNames = data.getColumnNames();
assertThat(columnNames).isEqualTo(expectedColumnNames);
@@ -247,7 +329,8 @@ public class TableMetaDataManagerTest {
setupPrimaryKeysMetaData();
when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
- TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
null);
verify(primaryKeysResultSet).close();
}
@@ -258,7 +341,8 @@ public class TableMetaDataManagerTest {
setupPrimaryKeysMetaData();
when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
- TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
null);
verify(columnResultSet).close();
}
@@ -268,7 +352,8 @@ public class TableMetaDataManagerTest {
setupPrimaryKeysMetaData();
when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
- TableMetaDataView data =
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+ TableMetaDataView data =
+ tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME,
null);
assertThat(data.getTableName()).isEqualTo(TABLE_NAME);
}
diff --git
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java
index 02211fa..671442d 100644
---
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java
+++
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java
@@ -120,9 +120,10 @@ public class CreateMappingCommandTest {
public void createsMappingReturnsStatusOKWhenFunctionResultSuccess() {
setupRequiredPreconditions();
results.add(successFunctionResult);
+ String ids = "ids";
ResultModel result = createRegionMappingCommand.createMapping(regionName,
dataSourceName,
- tableName, pdxClass, false);
+ tableName, pdxClass, false, ids);
assertThat(result.getStatus()).isSameAs(Result.Status.OK);
Object[] results = (Object[]) result.getConfigObject();
@@ -133,6 +134,7 @@ public class CreateMappingCommandTest {
assertThat(regionMapping.getDataSourceName()).isEqualTo(dataSourceName);
assertThat(regionMapping.getTableName()).isEqualTo(tableName);
assertThat(regionMapping.getPdxName()).isEqualTo(pdxClass);
+ assertThat(regionMapping.getIds()).isEqualTo(ids);
assertThat(synchronous).isFalse();
}
@@ -142,7 +144,7 @@ public class CreateMappingCommandTest {
results.add(successFunctionResult);
ResultModel result = createRegionMappingCommand.createMapping("/" +
regionName, dataSourceName,
- tableName, pdxClass, false);
+ tableName, pdxClass, false, null);
assertThat(result.getStatus()).isSameAs(Result.Status.OK);
Object[] results = (Object[]) result.getConfigObject();
@@ -157,7 +159,7 @@ public class CreateMappingCommandTest {
results.clear();
ResultModel result = createRegionMappingCommand.createMapping(regionName,
dataSourceName,
- tableName, pdxClass, false);
+ tableName, pdxClass, false, null);
assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
}
@@ -168,7 +170,7 @@ public class CreateMappingCommandTest {
doReturn(null).when(createRegionMappingCommand).getConfigurationPersistenceService();
ResultModel result = createRegionMappingCommand.createMapping(regionName,
dataSourceName,
- tableName, pdxClass, false);
+ tableName, pdxClass, false, null);
assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
assertThat(result.toString()).contains("Cluster Configuration must be
enabled.");
@@ -185,7 +187,7 @@ public class CreateMappingCommandTest {
when(cacheConfig.getRegions()).thenReturn(Collections.emptyList());
ResultModel result = createRegionMappingCommand.createMapping(regionName,
dataSourceName,
- tableName, pdxClass, false);
+ tableName, pdxClass, false, null);
assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
assertThat(result.toString())
@@ -214,7 +216,7 @@ public class CreateMappingCommandTest {
when(matchingRegion.getCustomRegionElements()).thenReturn(customList);
ResultModel result = createRegionMappingCommand.createMapping(regionName,
dataSourceName,
- tableName, pdxClass, false);
+ tableName, pdxClass, false, null);
assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
assertThat(result.toString()).contains("A JDBC mapping for " + regionName
+ " already exists.");
@@ -238,7 +240,7 @@ public class CreateMappingCommandTest {
when(matchingRegion.getRegionAttributes()).thenReturn(loaderAttribute);
ResultModel result = createRegionMappingCommand.createMapping(regionName,
dataSourceName,
- tableName, pdxClass, false);
+ tableName, pdxClass, false, null);
assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
assertThat(result.toString()).contains("The existing region " + regionName
@@ -263,7 +265,7 @@ public class CreateMappingCommandTest {
when(matchingRegion.getRegionAttributes()).thenReturn(writerAttribute);
ResultModel result = createRegionMappingCommand.createMapping(regionName,
dataSourceName,
- tableName, pdxClass, true);
+ tableName, pdxClass, true, null);
assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
assertThat(result.toString()).contains("The existing region " + regionName
@@ -292,7 +294,7 @@ public class CreateMappingCommandTest {
when(cacheConfig.getAsyncEventQueues()).thenReturn(asyncEventQueues);
ResultModel result = createRegionMappingCommand.createMapping(regionName,
dataSourceName,
- tableName, pdxClass, true);
+ tableName, pdxClass, true, null);
assertThat(result.getStatus()).isSameAs(Result.Status.OK);
}
@@ -320,7 +322,7 @@ public class CreateMappingCommandTest {
when(cacheConfig.getAsyncEventQueues()).thenReturn(asyncEventQueues);
ResultModel result = createRegionMappingCommand.createMapping(regionName,
dataSourceName,
- tableName, pdxClass, false);
+ tableName, pdxClass, false, null);
assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
assertThat(result.toString())
diff --git
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java
index 955b57f..f28a2fa 100644
---
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java
+++
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java
@@ -76,7 +76,7 @@ public class CreateMappingFunctionTest {
distributedMember = mock(DistributedMember.class);
service = mock(JdbcConnectorService.class);
- regionMapping = new RegionMapping(REGION_NAME, null, null, null);
+ regionMapping = new RegionMapping(REGION_NAME, null, null, null, null);
when(context.getResultSender()).thenReturn(resultSender);
when(context.getCache()).thenReturn(cache);
diff --git
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
index d317982..674b1ae 100644
---
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
+++
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
@@ -69,16 +69,19 @@ public class DescribeMappingCommandTest {
null);
RegionMapping mapping =
- new RegionMapping("region", "class1", "table1", "name1");
+ new RegionMapping("region", "class1", "table1", "name1", "myId");
ResultCollector rc = mock(ResultCollector.class);
doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
when(rc.getResult()).thenReturn(
Collections.singletonList(new CliFunctionResult("server-1", mapping,
"success")));
- gfsh.executeAndAssertThat(command,
COMMAND).statusIsSuccess().containsOutput("region", "region")
- .containsOutput("data-source", "name1").containsOutput("table",
"table1")
- .containsOutput("pdx-name", "class1");
+ gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
+ .containsOutput("region", "region")
+ .containsOutput("data-source", "name1")
+ .containsOutput("table", "table1")
+ .containsOutput("pdx-name", "class1")
+ .containsOutput("id", "myId");
}
@Test
diff --git
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
index 1ae457e..6a2c719 100644
---
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
+++
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
@@ -62,9 +62,9 @@ public class ListMappingCommandTest {
null);
RegionMapping mapping1 =
- new RegionMapping("region1", "class1", "table1", "name1");
+ new RegionMapping("region1", "class1", "table1", "name1", null);
RegionMapping mapping2 =
- new RegionMapping("region2", "class2", "table2", "name2");
+ new RegionMapping("region2", "class2", "table2", "name2", null);
ResultCollector rc = mock(ResultCollector.class);
doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
diff --git
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java
index 295a27b..9b15900 100644
---
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java
+++
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java
@@ -17,6 +17,7 @@ package org.apache.geode.connectors.jdbc.internal.xml;
import static
org.apache.geode.connectors.jdbc.internal.xml.ElementType.JDBC_MAPPING;
import static
org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.DATA_SOURCE;
+import static
org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.IDS;
import static
org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PDX_NAME;
import static
org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.TABLE;
import static org.assertj.core.api.Assertions.assertThat;
@@ -73,6 +74,7 @@ public class ElementTypeTest {
when(attributes.getValue(DATA_SOURCE)).thenReturn("connectionName");
when(attributes.getValue(TABLE)).thenReturn("table");
when(attributes.getValue(PDX_NAME)).thenReturn("pdxClass");
+ when(attributes.getValue(IDS)).thenReturn("ids");
when(regionCreation.getFullPath()).thenReturn("/region");
stack.push(regionCreation);
@@ -83,6 +85,7 @@ public class ElementTypeTest {
assertThat(regionMapping.getDataSourceName()).isEqualTo("connectionName");
assertThat(regionMapping.getTableName()).isEqualTo("table");
assertThat(regionMapping.getPdxName()).isEqualTo("pdxClass");
+ assertThat(regionMapping.getIds()).isEqualTo("ids");
}
@Test