You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ag...@apache.org on 2018/01/09 01:02:18 UTC

[geode] branch feature/GEODE-4237 created (now dbb2850)

This is an automated email from the ASF dual-hosted git repository.

agingade pushed a change to branch feature/GEODE-4237
in repository https://gitbox.apache.org/repos/asf/geode.git.


      at dbb2850  GEODE-4237: The JdbcLoader creates PdxInstance using region mapping (column to field).

This branch includes the following new commits:

     new dbb2850  GEODE-4237: The JdbcLoader creates PdxInstance using region mapping (column to field).

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@geode.apache.org" <co...@geode.apache.org>'].

[geode] 01/01: GEODE-4237: The JdbcLoader creates PdxInstance using region mapping (column to field).

Posted by ag...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

agingade pushed a commit to branch feature/GEODE-4237
in repository https://gitbox.apache.org/repos/asf/geode.git

commit dbb285069f0f0c76ecbea3cf776bd7f466b3415f
Author: Anil <ag...@pivotal.io>
AuthorDate: Mon Jan 8 16:59:46 2018 -0800

    GEODE-4237: The JdbcLoader creates PdxInstance using region mapping (column to field).
---
 .../connectors/jdbc/internal/RegionMapping.java    |  36 +++++++
 .../geode/connectors/jdbc/internal/SqlHandler.java |  11 +-
 .../jdbc/internal/RegionMappingTest.java           | 118 ++++++++++++++++++++-
 .../connectors/jdbc/internal/SqlHandlerTest.java   |  35 +++++-
 4 files changed, 189 insertions(+), 11 deletions(-)

diff --git a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/RegionMapping.java b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/RegionMapping.java
index 394fe48..d87c4d5 100644
--- a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/RegionMapping.java
+++ b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/RegionMapping.java
@@ -16,6 +16,7 @@ package org.apache.geode.connectors.jdbc.internal;
 
 import java.io.Serializable;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.geode.annotations.Experimental;
@@ -28,6 +29,7 @@ public class RegionMapping implements Serializable {
   private final String connectionConfigName;
   private final Boolean primaryKeyInValue;
   private final Map<String, String> fieldToColumnMap;
+  private final Map<String, String> columnToFieldMap;
 
   public RegionMapping(String regionName, String pdxClassName, String tableName,
       String connectionConfigName, Boolean primaryKeyInValue,
@@ -39,6 +41,24 @@ public class RegionMapping implements Serializable {
     this.primaryKeyInValue = primaryKeyInValue;
     this.fieldToColumnMap =
         fieldToColumnMap == null ? null : Collections.unmodifiableMap(fieldToColumnMap);
+    this.columnToFieldMap = createReverseMap(fieldToColumnMap);
+  }
+
+  private static Map<String, String> createReverseMap(Map<String, String> fieldToColumnMap) {
+    if (fieldToColumnMap == null) {
+      return null;
+    }
+    Map<String, String> reverseMap = new HashMap<>();
+    for (Map.Entry<String, String> entry : fieldToColumnMap.entrySet()) {
+      String reverseMapKey = entry.getValue().toLowerCase();
+      String reverseMapValue = entry.getKey();
+      if (reverseMap.containsKey(reverseMapKey)) {
+        throw new IllegalArgumentException(
+            "The field " + reverseMapValue + " can not be mapped to more than one column.");
+      }
+      reverseMap.put(reverseMapKey, reverseMapValue);
+    }
+    return Collections.unmodifiableMap(reverseMap);
   }
 
   public String getConnectionConfigName() {
@@ -76,10 +96,26 @@ public class RegionMapping implements Serializable {
     return columnName != null ? columnName : fieldName;
   }
 
+  public String getFieldNameForColumn(String columnName) {
+    String canonicalColumnName = columnName.toLowerCase();
+    String fieldName = null;
+    if (this.columnToFieldMap != null) {
+      fieldName = columnToFieldMap.get(canonicalColumnName);
+    }
+    return fieldName != null ? fieldName : canonicalColumnName;
+  }
+
   public Map<String, String> getFieldToColumnMap() {
     return fieldToColumnMap;
   }
 
+  /**
+   * For unit tests
+   */
+  Map<String, String> getColumnToFieldMap() {
+    return this.columnToFieldMap;
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) {
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 65f9240..25a3694 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
@@ -121,9 +121,8 @@ public class SqlHandler {
     return factory;
   }
 
-  private PdxInstance executeReadStatement(PreparedStatement statement,
-      List<ColumnValue> columnList, PdxInstanceFactory factory, RegionMapping regionMapping,
-      String keyColumnName) {
+  PdxInstance executeReadStatement(PreparedStatement statement, List<ColumnValue> columnList,
+      PdxInstanceFactory factory, RegionMapping regionMapping, String keyColumnName) {
     PdxInstance pdxInstance = null;
     try {
       setValuesInStatement(statement, columnList);
@@ -134,7 +133,7 @@ public class SqlHandler {
           for (int i = 1; i <= ColumnsNumber; i++) {
             Object columnValue = resultSet.getObject(i);
             String columnName = metaData.getColumnName(i);
-            String fieldName = mapColumnNameToFieldName(columnName);
+            String fieldName = mapColumnNameToFieldName(columnName, regionMapping);
             if (regionMapping.isPrimaryKeyInValue()
                 || !keyColumnName.equalsIgnoreCase(columnName)) {
               factory.writeField(fieldName, columnValue, Object.class);
@@ -162,8 +161,8 @@ public class SqlHandler {
     }
   }
 
-  private String mapColumnNameToFieldName(String columnName) {
-    return columnName.toLowerCase();
+  private String mapColumnNameToFieldName(String columnName, RegionMapping regionMapping) {
+    return regionMapping.getFieldNameForColumn(columnName);
   }
 
   public <K, V> void write(Region<K, V> region, Operation operation, K key, PdxInstance value) {
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 99433e9..992d0c4 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
@@ -20,14 +20,19 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
+import org.junit.rules.ExpectedException;
 
 import org.apache.geode.test.junit.categories.UnitTest;
 
 @Category(UnitTest.class)
 public class RegionMappingTest {
 
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
   private String name;
   private String fieldName1;
   private String columnName1;
@@ -48,15 +53,20 @@ public class RegionMappingTest {
 
     fieldMap = new HashMap<>();
 
-    mapping = new RegionMapping(null, null, null, null, false, null);
   }
 
   @Test
   public void initiatedWithNullValues() {
+    mapping = new RegionMapping(null, null, null, null, false, null);
     assertThat(mapping.getTableName()).isNull();
     assertThat(mapping.getRegionName()).isNull();
     assertThat(mapping.getConnectionConfigName()).isNull();
     assertThat(mapping.getPdxClassName()).isNull();
+    assertThat(mapping.getFieldToColumnMap()).isNull();
+    assertThat(mapping.getColumnToFieldMap()).isNull();
+    assertThat(mapping.getRegionToTableName()).isNull();
+    assertThat(mapping.getColumnNameForField("fieldName")).isEqualTo("fieldName");
+    assertThat(mapping.getFieldNameForColumn("columnName")).isEqualTo("columnname");
   }
 
   @Test
@@ -64,6 +74,16 @@ public class RegionMappingTest {
     mapping = new RegionMapping(null, null, name, null, false, null);
 
     assertThat(mapping.getTableName()).isEqualTo(name);
+    assertThat(mapping.getRegionToTableName()).isEqualTo(name);
+  }
+
+  @Test
+  public void hasCorrectTableNameWhenRegionNameIsSet() {
+    mapping = new RegionMapping("regionName", null, "tableName", null, false, null);
+
+    assertThat(mapping.getRegionName()).isEqualTo("regionName");
+    assertThat(mapping.getTableName()).isEqualTo("tableName");
+    assertThat(mapping.getRegionToTableName()).isEqualTo("tableName");
   }
 
   @Test
@@ -71,6 +91,7 @@ public class RegionMappingTest {
     mapping = new RegionMapping(name, null, null, null, false, null);
 
     assertThat(mapping.getRegionName()).isEqualTo(name);
+    assertThat(mapping.getRegionToTableName()).isEqualTo(name);
   }
 
   @Test
@@ -104,6 +125,15 @@ public class RegionMappingTest {
   }
 
   @Test
+  public void returnsColumnNameIfFieldNotMapped() {
+    fieldMap.put("otherField", "column");
+
+    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+
+    assertThat(mapping.getFieldNameForColumn("columnName")).isEqualTo("columnname");
+  }
+
+  @Test
   public void returnsMappedColumnNameForField() {
     fieldMap.put(fieldName1, columnName1);
 
@@ -113,6 +143,15 @@ public class RegionMappingTest {
   }
 
   @Test
+  public void returnsMappedFieldNameForColumn() {
+    fieldMap.put(fieldName1, columnName1);
+
+    mapping = new RegionMapping(null, null, null, null, true, fieldMap);
+
+    assertThat(mapping.getFieldNameForColumn(columnName1)).isEqualTo(fieldName1);
+  }
+
+  @Test
   public void returnsAllMappings() {
     fieldMap.put(fieldName1, columnName1);
     fieldMap.put(fieldName2, columnName2);
@@ -123,5 +162,82 @@ public class RegionMappingTest {
     assertThat(mapping.getFieldToColumnMap()).containsOnlyKeys(fieldName1, fieldName2);
     assertThat(mapping.getFieldToColumnMap()).containsEntry(fieldName1, columnName1)
         .containsEntry(fieldName2, columnName2);
+    assertThat(mapping.getColumnToFieldMap().size()).isEqualTo(2);
+    assertThat(mapping.getColumnToFieldMap()).containsOnlyKeys(columnName1.toLowerCase(),
+        columnName2.toLowerCase());
+    assertThat(mapping.getColumnToFieldMap()).containsEntry(columnName1.toLowerCase(), fieldName1)
+        .containsEntry(columnName2.toLowerCase(), fieldName2);
+  }
+
+  @Test
+  public void regionMappingFailsForInvalidFieldToColumnMapping() {
+    fieldMap.put(fieldName1, columnName1);
+    fieldMap.put(fieldName2, columnName1);
+    expectedException.expect(IllegalArgumentException.class);
+    new RegionMapping(null, null, null, null, true, fieldMap);
   }
+
+  @Test
+  public void verifyTwoNonDefaultInstancesAreEqual() {
+    fieldMap.put(fieldName1, columnName1);
+    fieldMap.put(fieldName2, columnName2);
+    RegionMapping rm1 = new RegionMapping("regionName", "pdxClassName", "tableName",
+        "connectionName", true, fieldMap);
+    RegionMapping rm2 = new RegionMapping("regionName", "pdxClassName", "tableName",
+        "connectionName", true, fieldMap);
+    assertThat(rm1).isEqualTo(rm2);
+  }
+
+  @Test
+  public void verifyTwoDefaultInstancesAreEqual() {
+    RegionMapping rm1 = new RegionMapping("regionName", null, null, "connectionName", false, null);
+    RegionMapping rm2 = new RegionMapping("regionName", null, null, "connectionName", false, null);
+    assertThat(rm1).isEqualTo(rm2);
+  }
+
+  @Test
+  public void verifyTwoSimiliarInstancesAreNotEqual() {
+    fieldMap.put(fieldName1, columnName1);
+    fieldMap.put(fieldName2, columnName2);
+    RegionMapping rm1 = new RegionMapping("regionName", "pdxClassName", "tableName",
+        "connectionName", true, fieldMap);
+    RegionMapping rm2 =
+        new RegionMapping("regionName", "pdxClassName", "tableName", "connectionName", true, null);
+    assertThat(rm1).isNotEqualTo(rm2);
+  }
+
+
+  @Test
+  public void verifyTwoInstancesThatAreEqualHaveSameHashCode() {
+    fieldMap.put(fieldName1, columnName1);
+    fieldMap.put(fieldName2, columnName2);
+    RegionMapping rm1 = new RegionMapping("regionName", "pdxClassName", "tableName",
+        "connectionName", true, fieldMap);
+    RegionMapping rm2 = new RegionMapping("regionName", "pdxClassName", "tableName",
+        "connectionName", true, fieldMap);
+    assertThat(rm1.hashCode()).isEqualTo(rm2.hashCode());
+  }
+
+  @Test
+  public void verifyThatMappingIsEqualToItself() {
+    mapping = new RegionMapping(null, null, null, null, false, null);
+    boolean result = mapping.equals(mapping);
+    assertThat(mapping.hashCode()).isEqualTo(mapping.hashCode());
+    assertThat(result).isTrue();
+  }
+
+  @Test
+  public void verifyThatNullIsNotEqual() {
+    mapping = new RegionMapping(null, null, null, null, false, null);
+    boolean result = mapping.equals(null);
+    assertThat(result).isFalse();
+  }
+
+  @Test
+  public void verifyOtherClassIsNotEqual() {
+    mapping = new RegionMapping(null, null, null, null, false, null);
+    boolean result = mapping.equals("not equal");
+    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 e915a4e..afe8988 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
@@ -33,6 +33,7 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -171,11 +172,13 @@ public class SqlHandlerTest {
     PdxInstanceFactory factory = mock(PdxInstanceFactory.class);
     when(cache.createPdxInstanceFactory(anyString(), anyBoolean())).thenReturn(factory);
 
-    String filedName1 = COLUMN_NAME_1.toLowerCase();
-    String filedName2 = COLUMN_NAME_2.toLowerCase();
+    String fieldName1 = COLUMN_NAME_1.toLowerCase();
+    String fieldName2 = COLUMN_NAME_2.toLowerCase();
+    when(regionMapping.getFieldNameForColumn(COLUMN_NAME_1)).thenReturn(fieldName1);
+    when(regionMapping.getFieldNameForColumn(COLUMN_NAME_2)).thenReturn(fieldName2);
     handler.read(region, new Object());
-    verify(factory).writeField(filedName1, COLUMN_VALUE_1, Object.class);
-    verify(factory).writeField(filedName2, COLUMN_VALUE_2, Object.class);
+    verify(factory).writeField(fieldName1, COLUMN_VALUE_1, Object.class);
+    verify(factory).writeField(fieldName2, COLUMN_VALUE_2, Object.class);
     verify(factory).create();
   }
 
@@ -191,6 +194,7 @@ public class SqlHandlerTest {
     when(cache.createPdxInstanceFactory(anyString(), anyBoolean())).thenReturn(factory);
 
     String fieldName2 = COLUMN_NAME_2.toLowerCase();
+    when(regionMapping.getFieldNameForColumn(COLUMN_NAME_2)).thenReturn(fieldName2);
     handler.read(region, new Object());
     verify(factory).writeField(fieldName2, COLUMN_VALUE_2, Object.class);
     verify(factory, times(1)).writeField(any(), any(), any());
@@ -420,6 +424,28 @@ public class SqlHandlerTest {
     assertThat(columnValueList.get(0).getColumnName()).isEqualTo(KEY_COLUMN);
   }
 
+  @Test
+  public void usesMappedPdxFieldNameWhenReading() throws Exception {
+    ResultSet result = mock(ResultSet.class);
+    setupResultSet(result);
+    when(result.next()).thenReturn(true).thenReturn(false);
+    when(statement.executeQuery()).thenReturn(result);
+
+    PdxInstanceFactory factory = mock(PdxInstanceFactory.class);
+    when(cache.createPdxInstanceFactory(anyString(), anyBoolean())).thenReturn(factory);
+
+    List<ColumnValue> columnList = new ArrayList<>();
+
+    String fieldName1 = "pdxFieldName1";
+    String fieldName2 = "pdxFieldName2";
+    when(regionMapping.getFieldNameForColumn(COLUMN_NAME_1)).thenReturn(fieldName1);
+    when(regionMapping.getFieldNameForColumn(COLUMN_NAME_2)).thenReturn(fieldName2);
+    handler.executeReadStatement(statement, columnList, factory, regionMapping, "keyColumn");
+    verify(factory).writeField(fieldName1, COLUMN_VALUE_1, Object.class);
+    verify(factory).writeField(fieldName2, COLUMN_VALUE_2, Object.class);
+    verify(factory).create();
+  }
+
   private ResultSet getPrimaryKeysMetaData() throws SQLException {
     DatabaseMetaData metadata = mock(DatabaseMetaData.class);
     ResultSet resultSet = mock(ResultSet.class);
@@ -443,4 +469,5 @@ public class SqlHandlerTest {
         .isInstanceOf(IllegalStateException.class).hasMessage("Could not connect to fake:url");
   }
 
+
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@geode.apache.org" <co...@geode.apache.org>.