geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aging...@apache.org
Subject [geode] 01/01: GEODE-4237: The JdbcLoader creates PdxInstance using region mapping (column to field).
Date Tue, 09 Jan 2018 01:02:19 GMT
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 <agingade@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" <commits@geode.apache.org>.

Mime
View raw message