Skip to content

Commit

Permalink
#20: Refactored ColumnAdapterNotes. (#25)
Browse files Browse the repository at this point in the history
* #20: Refactored `ColumnAdapterNotes`.
  • Loading branch information
redcatbear authored Jan 31, 2020
1 parent 4456ed8 commit 1777376
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 153 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,108 +2,44 @@

import java.util.Objects;

import javax.json.*;

import com.exasol.adapter.AdapterException;
import com.exasol.utils.JsonHelper;

/**
* Serializes and deserializes the column adapter notes specific to the JDBC Adapter.
* Holds the column adapter notes.
*/
public final class ColumnAdapterNotes {
private static final String TYPE_NAME = "typeName";
private static final String JDBC_DATA_TYPE = "jdbcDataType";
private final int jdbcDataType;
private final String typeName;

/**
* Create a new instance of the {@link ColumnAdapterNotes}.
*
* @param jdbcDataType JDBC data type in int format
* @param typeName name of the data type
* @param jdbcDataType JDBC data type number
*/
public ColumnAdapterNotes(final int jdbcDataType, final String typeName) {
public ColumnAdapterNotes(final int jdbcDataType) {
this.jdbcDataType = jdbcDataType;
this.typeName = typeName;
}

/**
* Get JDBC data type.
*
* @return JDBC data type as an int
*
* @return JDBC data type as a number
*/
public int getJdbcDataType() {
return this.jdbcDataType;
}

/**
* Get JDBC type name.
*
* @return JDBC type name as a string
*/
public String getTypeName() {
return this.typeName;
}

/**
* Serialized column adapter notes.
*
* @param notes column adapter notes
* @return serialized column adapter notes
*/
public static String serialize(final ColumnAdapterNotes notes) {
final JsonBuilderFactory factory = JsonHelper.getBuilderFactory();
final JsonObjectBuilder builder = factory.createObjectBuilder().add(JDBC_DATA_TYPE, notes.getJdbcDataType())
.add(TYPE_NAME, notes.getTypeName());
return builder.build().toString();
}

/**
* Deserialize column adapter notes.
*
* @param columnAdapterNotes column adapter notes
* @param columnName column name
* @return deserialized column adapter notes
* @throws AdapterException if column adapter notes are empty or null
*/
public static ColumnAdapterNotes deserialize(final String columnAdapterNotes, final String columnName)
throws AdapterException {
if ((columnAdapterNotes == null) || columnAdapterNotes.isEmpty()) {
throw new AdapterException("The adapternotes field of column " + columnName
+ " is empty or null. Please refresh the virtual schema.");
}
final JsonObject root;
try {
root = JsonHelper.getJsonObject(columnAdapterNotes);
} catch (final Exception exception) {
throw new AdapterException("Can not get the json object for column notes of column " + columnName
+ ". Please refresh the virtual schema. Caused by: " + exception.getMessage(), exception);
}
checkKey(root, JDBC_DATA_TYPE, columnName);
checkKey(root, TYPE_NAME, columnName);
return new ColumnAdapterNotes(root.getInt(JDBC_DATA_TYPE), root.getString(TYPE_NAME));
}

private static void checkKey(final JsonObject root, final String key, final String columnName)
throws AdapterException {
if (!root.containsKey(key)) {
throw new AdapterException("Adapter notes of column " + columnName + " don't have the key " + key
+ ". Please refresh the virtual schema");
}
}

@Override
public boolean equals(final Object other) {
if (this == other)
if (this == other) {
return true;
if (!(other instanceof ColumnAdapterNotes))
}
if (!(other instanceof ColumnAdapterNotes)) {
return false;
}
final ColumnAdapterNotes that = (ColumnAdapterNotes) other;
return this.jdbcDataType == that.jdbcDataType && Objects.equals(this.typeName, that.typeName);
return this.jdbcDataType == that.jdbcDataType;
}

@Override
public int hashCode() {
return Objects.hash(this.jdbcDataType, this.typeName);
return Objects.hash(this.jdbcDataType);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.exasol.adapter.adapternotes;

import javax.json.*;

import com.exasol.adapter.AdapterException;
import com.exasol.utils.JsonHelper;

/**
* Converts column adapter Notes into JSON format and back.
*/
public final class ColumnAdapterNotesJsonConverter {
private static final ColumnAdapterNotesJsonConverter COLUMN_ADAPTER_NOTES_JSON_CONVERTER = new ColumnAdapterNotesJsonConverter();

/**
* Returns instance of {@link ColumnAdapterNotesJsonConverter} singleton class.
*
* @return {@link ColumnAdapterNotesJsonConverter} instance
*/
public static ColumnAdapterNotesJsonConverter getInstance() {
return COLUMN_ADAPTER_NOTES_JSON_CONVERTER;
}

private ColumnAdapterNotesJsonConverter() {
// intentionally left blank
}

/**
* Converts column adapter notes into a JSON format.
*
* @param columnAdapterNotes column adapter notes to be converted
* @return string representation of a JSON Object
*/
public String convertToJson(final ColumnAdapterNotes columnAdapterNotes) {
final JsonBuilderFactory factory = JsonHelper.getBuilderFactory();
final JsonObjectBuilder builder = factory.createObjectBuilder().add("jdbcDataType",
columnAdapterNotes.getJdbcDataType());
return builder.build().toString();
}

/**
* Converts JSON representation of column adapter notes into instance of {@link ColumnAdapterNotes} class.
*
* @param adapterNotes JSON representation of schema adapter notes
* @param columnName name of the column
* @return instance of {@link ColumnAdapterNotes}
* @throws AdapterException if the adapter notes are missing or cannot be parsed
*/
public ColumnAdapterNotes convertFromJsonToColumnAdapterNotes(final String adapterNotes, final String columnName)
throws AdapterException {
if ((adapterNotes == null) || adapterNotes.isEmpty()) {
throw new AdapterException("Adapter notes for column " + columnName + " are empty or NULL. " //
+ "Please refresh the virtual schema.");
}
final JsonObject root;
try {
root = JsonHelper.getJsonObject(adapterNotes);
} catch (final Exception exception) {
throw new AdapterException("Could not parse the column adapter notes of column \"" + columnName + "\"." //
+ "Please refresh the virtual schema.", exception);
}
return new ColumnAdapterNotes(root.getInt("jdbcDataType"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import java.util.Objects;

/**
* Holds the schema adapter notes specific to the JDBC Adapter. Also includes functionality to serialize and
* deserialize.
* Holds the schema adapter notes specific to the JDBC Adapter.
*/
public final class SchemaAdapterNotes {
private final String catalogSeparator;
Expand Down Expand Up @@ -159,22 +158,22 @@ public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
if ((o == null) || (getClass() != o.getClass())) {
return false;
}
final SchemaAdapterNotes that = (SchemaAdapterNotes) o;
return this.storesLowerCaseIdentifiers == that.storesLowerCaseIdentifiers
&& this.storesUpperCaseIdentifiers == that.storesUpperCaseIdentifiers
&& this.storesMixedCaseIdentifiers == that.storesMixedCaseIdentifiers
&& this.supportsMixedCaseIdentifiers == that.supportsMixedCaseIdentifiers
&& this.storesLowerCaseQuotedIdentifiers == that.storesLowerCaseQuotedIdentifiers
&& this.storesUpperCaseQuotedIdentifiers == that.storesUpperCaseQuotedIdentifiers
&& this.storesMixedCaseQuotedIdentifiers == that.storesMixedCaseQuotedIdentifiers
&& this.supportsMixedCaseQuotedIdentifiers == that.supportsMixedCaseQuotedIdentifiers
&& this.areNullsSortedAtEnd == that.areNullsSortedAtEnd
&& this.areNullsSortedAtStart == that.areNullsSortedAtStart
&& this.areNullsSortedHigh == that.areNullsSortedHigh
&& this.areNullsSortedLow == that.areNullsSortedLow
return (this.storesLowerCaseIdentifiers == that.storesLowerCaseIdentifiers)
&& (this.storesUpperCaseIdentifiers == that.storesUpperCaseIdentifiers)
&& (this.storesMixedCaseIdentifiers == that.storesMixedCaseIdentifiers)
&& (this.supportsMixedCaseIdentifiers == that.supportsMixedCaseIdentifiers)
&& (this.storesLowerCaseQuotedIdentifiers == that.storesLowerCaseQuotedIdentifiers)
&& (this.storesUpperCaseQuotedIdentifiers == that.storesUpperCaseQuotedIdentifiers)
&& (this.storesMixedCaseQuotedIdentifiers == that.storesMixedCaseQuotedIdentifiers)
&& (this.supportsMixedCaseQuotedIdentifiers == that.supportsMixedCaseQuotedIdentifiers)
&& (this.areNullsSortedAtEnd == that.areNullsSortedAtEnd)
&& (this.areNullsSortedAtStart == that.areNullsSortedAtStart)
&& (this.areNullsSortedHigh == that.areNullsSortedHigh)
&& (this.areNullsSortedLow == that.areNullsSortedLow)
&& Objects.equals(this.catalogSeparator, that.catalogSeparator)
&& Objects.equals(this.identifierQuoteString, that.identifierQuoteString);
}
Expand Down Expand Up @@ -393,4 +392,4 @@ public SchemaAdapterNotes build() {
return new SchemaAdapterNotes(this);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private SchemaAdapterNotesJsonConverter() {
/**
* Converts schema adapter notes into a JSON format.
*
* @param schemaAdapterNotes instance
* @param schemaAdapterNotes schema adapter notes to be converted
* @return string representation of a JSON Object
*/
public String convertToJson(final SchemaAdapterNotes schemaAdapterNotes) {
Expand All @@ -65,27 +65,25 @@ public String convertToJson(final SchemaAdapterNotes schemaAdapterNotes) {
}

/**
* Converts JSON representation of schema adapter notes into instance of {@link SchemaAdapterNotesJsonConverter}
* class.
* Converts JSON representation of schema adapter notes into instance of {@link SchemaAdapterNotes} class.
*
* @param adapterNotes JSON representation of schema adapter notes
* @param schemaName name of virtual schema
* @return instance of {@link SchemaAdapterNotesJsonConverter}
* @return instance of {@link SchemaAdapterNotes}
* @throws AdapterException if the adapter notes are missing or cannot be parsed
*/
public SchemaAdapterNotes convertFromJsonToSchemaAdapterNotes(final String adapterNotes, final String schemaName)
throws AdapterException {
if ((adapterNotes == null) || adapterNotes.isEmpty()) {
throw new AdapterException("Adapter notes for virtual schema " + schemaName + " are empty or null. " //
+ "Please refresh the virtual schema");
throw new AdapterException("Adapter notes for virtual schema " + schemaName + " are empty or NULL. " //
+ "Please refresh the virtual schema.");
}
final JsonObject root;
try {
root = JsonHelper.getJsonObject(adapterNotes);
} catch (final Exception ex) {
throw new AdapterException(
"Could not parse the json which is expected to be stored in the adapter notes of virtual schema "
+ schemaName + ". Please refresh the virtual schema");
} catch (final Exception exception) {
throw new AdapterException("Could not parse the schema adapter notes of virtual schema \"" + schemaName
+ "\". Please refresh the virtual schema.", exception);
}
checkKey(root, CATALOG_SEPARATOR, schemaName);
checkKey(root, IDENTIFIER_QUOTE_STRING, schemaName);
Expand Down Expand Up @@ -126,4 +124,4 @@ private static void checkKey(final JsonObject root, final String key, final Stri
+ ". Please refresh the virtual schema");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import com.exasol.adapter.AdapterProperties;
import com.exasol.adapter.adapternotes.ColumnAdapterNotes;
import com.exasol.adapter.adapternotes.ColumnAdapterNotesJsonConverter;
import com.exasol.adapter.dialects.IdentifierConverter;
import com.exasol.adapter.metadata.ColumnMetadata;
import com.exasol.adapter.metadata.DataType;
Expand Down Expand Up @@ -91,8 +92,8 @@ private ColumnMetadata mapColumn(final ResultSet remoteColumn) throws SQLExcepti
final JdbcTypeDescription jdbcTypeDescription = readJdbcTypeDescription(remoteColumn);
final String columnName = readColumnName(remoteColumn);
final String originalTypeName = readColumnTypeName(remoteColumn);
final String adapterNotes = ColumnAdapterNotes
.serialize(new ColumnAdapterNotes(jdbcTypeDescription.getJdbcType(), originalTypeName));
final String adapterNotes = ColumnAdapterNotesJsonConverter.getInstance()
.convertToJson(new ColumnAdapterNotes(jdbcTypeDescription.getJdbcType()));
final DataType exasolType = mapJdbcType(jdbcTypeDescription);
return ColumnMetadata.builder() //
.name(columnName) //
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.exasol.adapter.adapternotes;

import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.sql.Types;

import org.json.JSONException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.skyscreamer.jsonassert.JSONAssert;

import com.exasol.adapter.AdapterException;

class ColumnAdapterNotesJsonConverterTest {
private static final String JDBC_DATA_TYPE = "jdbcDataType";
private ColumnAdapterNotesJsonConverter converter;

@BeforeEach
void beforeEach() {
this.converter = ColumnAdapterNotesJsonConverter.getInstance();
}

@Test
void testConvertToJson() throws JSONException {
final int expectedType = Types.DATE;
final ColumnAdapterNotes adapterNotes = new ColumnAdapterNotes(expectedType);
JSONAssert.assertEquals("{\"" + JDBC_DATA_TYPE + "\":" + expectedType + "}",
this.converter.convertToJson(adapterNotes), false);
}

@Test
void testConvertFromJsonToColumnAdapterNotes() throws AdapterException {
final int expectedType = Types.VARCHAR;
final String adapterNotesAsJson = "{\"" + JDBC_DATA_TYPE + "\":" + expectedType + "}";
final ColumnAdapterNotes expectedAdapterNotes = new ColumnAdapterNotes(expectedType);
assertThat(this.converter.convertFromJsonToColumnAdapterNotes(adapterNotesAsJson, "C1"),
equalTo(expectedAdapterNotes));
}

@Test
void testConvertFromJsonToColumnAdapterNotesThrowsExceptionWhenAdapterNotesAreNull() {
assertThrows(AdapterException.class, () -> this.converter.convertFromJsonToColumnAdapterNotes(null, ""));
}

@Test
void testConvertFromJsonToColumnAdapterNotesThrowsExceptionWithEmptyAdapterNotes() {
assertThrows(AdapterException.class, () -> this.converter.convertFromJsonToColumnAdapterNotes("", ""));
}

@Test
void testconvertFromJsonToColumnAdapterNotesThrowsExceptionWithWrongAdapterNotes() {
assertThrows(AdapterException.class, () -> this.converter.convertFromJsonToColumnAdapterNotes("testNotes", ""));
}
}
Loading

0 comments on commit 1777376

Please sign in to comment.