Skip to content

Commit

Permalink
Added Array Support to driver as well as Unit Tests for new functiona…
Browse files Browse the repository at this point in the history
…lity

Signed-off-by: Andrey Kuzin <akuzin@amazon.com>
  • Loading branch information
akuzin1 committed May 23, 2023
1 parent 5e8d914 commit e15de5e
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 14 deletions.
118 changes: 118 additions & 0 deletions src/main/java/org/opensearch/jdbc/ArrayImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/


package org.opensearch.jdbc;

import java.sql.JDBCType;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.ResultSet;
import java.sql.Struct;
import java.sql.Array;
import java.util.Arrays;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;


/**
* This class implements the {@link java.sql.Struct} interface.
* <p>
* {@code StructImpl} provides a simple implementation of a struct data type.
* </p>
*/
public class ArrayImpl implements Array {
private ArrayList<Object> arrayData;
private JDBCType baseTypeName;

public ArrayImpl(ArrayList<Object> arrayData, JDBCType baseTypeName) {
this.arrayData = arrayData;
this.baseTypeName = baseTypeName;
}

@Override
public String getBaseTypeName() throws SQLException {
return this.baseTypeName.toString();
}

@Override
public int getBaseType() throws SQLException {
throw new SQLFeatureNotSupportedException("getBaseType() is not supported");
}

@Override
public Object getArray() throws SQLException {
return arrayData.toArray();
}

@Override
public Object getArray(Map<String, Class<?>> map) throws SQLException {
throw new SQLFeatureNotSupportedException("getArray(map) is not supported");
}

@Override
public Object getArray(long index, int count) throws SQLException {
if (index < 1 || index > arrayData.size() || index + count - 1 > arrayData.size() || count < 0) {
throw new SQLException("Invalid index or count");
}
int fromIndex = (int) index - 1;
int toIndex = fromIndex + count;
return arrayData.subList(fromIndex, toIndex).toArray();
}

@Override
public Object getArray(long index, int count, Map<String, Class<?>> map) throws SQLException {
throw new SQLFeatureNotSupportedException("getArray(index, count, map) is not supported");
}

@Override
public ResultSet getResultSet() throws SQLException {
throw new SQLFeatureNotSupportedException("getResultSet() is not supported");
}

@Override
public ResultSet getResultSet(Map<String, Class<?>> map) throws SQLException {
throw new SQLFeatureNotSupportedException("getResultSet(map) is not supported");
}

@Override
public ResultSet getResultSet(long index, int count) throws SQLException {
throw new SQLFeatureNotSupportedException("getResultSet(index, count) is not supported");
}

@Override
public ResultSet getResultSet(long index, int count, Map<String, Class<?>> map) throws SQLException {
throw new SQLFeatureNotSupportedException("getResultSet(index, count, map) is not supported");
}

@Override
public void free() throws SQLException {
arrayData = null;
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof Array)) {
return false;
}
if (obj == this) {
return true;
}
Array other = (Array) obj;
try {
Object[] myArray = (Object[]) this.getArray();
Object[] otherArray = (Object[]) this.getArray();

if (!(this.getBaseTypeName().equals(other.getBaseTypeName())) || myArray.length != otherArray.length) {
return false;
}
return Arrays.equals(myArray, otherArray);
}
catch (SQLException e) {
return false;
}
}
}
28 changes: 24 additions & 4 deletions src/main/java/org/opensearch/jdbc/ResultSetImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.JDBCType;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -579,10 +580,24 @@ protected <T> T getObjectX(int columnIndex, Class<T> javaClass) throws SQLExcept

protected <T> T getObjectX(int columnIndex, Class<T> javaClass, Map<String, Object> conversionParams) throws SQLException {
final Object value = getColumn(columnIndex);
final TypeConverter tc = TypeConverters.getInstance(getColumnMetaData(columnIndex).getOpenSearchType().getJdbcType());
// Change made to identify if value is of type array since it isn't an official supported field type

JDBCType trueJdbcType = getColumnMetaData(columnIndex).getOpenSearchType().getJdbcType();

if (javaClass == Array.class) {
trueJdbcType = JDBCType.ARRAY;
if (conversionParams == null) {
conversionParams = new HashMap<String, Object>();
}
conversionParams.put("baseType", getColumnMetaData(columnIndex).getOpenSearchType().getJdbcType());
}

final TypeConverter tc = TypeConverters.getInstance(trueJdbcType);

if (null == tc) {
throw new SQLException("Conversion from " + getColumnMetaData(columnIndex).getOpenSearchType() + " not supported.");
}

return tc.convert(value, javaClass, conversionParams);
}

Expand Down Expand Up @@ -1007,8 +1022,10 @@ public Clob getClob(int columnIndex) throws SQLException {

@Override
public Array getArray(int columnIndex) throws SQLException {
throw new SQLFeatureNotSupportedException("Array is not supported");
}
log.debug(() -> logEntry("getObject (%s, %s)", columnIndex, Array.class));
Array value = getObjectX(columnIndex, Array.class);
log.debug(() -> logExit("getObject", value));
return value; }

@Override
public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
Expand Down Expand Up @@ -1050,7 +1067,10 @@ public Clob getClob(String columnLabel) throws SQLException {

@Override
public Array getArray(String columnLabel) throws SQLException {
throw new SQLFeatureNotSupportedException("Array is not supported");
log.debug(() -> logEntry("getObject (%s, %s)", columnLabel, Array.class));
Array value = getObjectX(getColumnIndex(columnLabel), Array.class);
log.debug(() -> logExit("getObject", value));
return value;
}

@Override
Expand Down
44 changes: 44 additions & 0 deletions src/main/java/org/opensearch/jdbc/types/ArrayType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
package org.opensearch.jdbc.types;

import java.sql.Array;
import java.sql.JDBCType;
import java.util.Map;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.LinkedHashMap;
import java.util.Collections;


import org.opensearch.jdbc.ArrayImpl;

public class ArrayType implements TypeHelper<Array> {

public static final ArrayType INSTANCE = new ArrayType();

private ArrayType() {

}

@Override
public String getTypeName() {
return "Array";
}

@Override
public Array fromValue(Object value, Map<String, Object> conversionParams) {
if (value == null || !(value instanceof ArrayList)) {
return null;
}

JDBCType baseType = conversionParams != null ? (JDBCType) conversionParams.get("baseType") : JDBCType.OTHER;

return new ArrayImpl((ArrayList) value, baseType);

}
}

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package org.opensearch.jdbc.types;

import java.sql.Array;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Struct;
Expand Down Expand Up @@ -38,6 +39,7 @@ public abstract class BaseTypeConverter implements TypeConverter {

typeHandlerMap.put(Struct.class, StructType.INSTANCE);

typeHandlerMap.put(Array.class, ArrayType.INSTANCE);
}

@Override
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/org/opensearch/jdbc/types/OpenSearchType.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

package org.opensearch.jdbc.types;

import java.sql.Array;
import java.sql.Date;
import java.sql.JDBCType;
import java.sql.Struct;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.HashMap;
Expand Down Expand Up @@ -61,15 +63,17 @@ public enum OpenSearchType {
STRING(JDBCType.VARCHAR, String.class, Integer.MAX_VALUE, 0, false),
IP(JDBCType.VARCHAR, String.class, 15, 0, false),
NESTED(JDBCType.STRUCT, null, 0, 0, false),
OBJECT(JDBCType.STRUCT, null, 0, 0, false),
OBJECT(JDBCType.STRUCT, Struct.class, 0, 0, false),
DATE(JDBCType.DATE, Date.class, 10, 10, false),
TIME(JDBCType.TIME, Time.class, 8, 8, false),
DATETIME(JDBCType.TIMESTAMP, Timestamp.class, 29, 29, false),
TIMESTAMP(JDBCType.TIMESTAMP, Timestamp.class, 29, 29, false),
BINARY(JDBCType.VARBINARY, String.class, Integer.MAX_VALUE, 0, false),
NULL(JDBCType.NULL, null, 0, 0, false),
UNDEFINED(JDBCType.NULL, null, 0, 0, false),
UNSUPPORTED(JDBCType.OTHER, null, 0, 0, false);
UNSUPPORTED(JDBCType.OTHER, null, 0, 0, false),
ARRAY(JDBCType.ARRAY, Array.class, 0, 0, false);


private static final Map<JDBCType, OpenSearchType> jdbcTypeToOpenSearchTypeMap;

Expand All @@ -91,6 +95,8 @@ public enum OpenSearchType {
jdbcTypeToOpenSearchTypeMap.put(JDBCType.DATE, DATE);
jdbcTypeToOpenSearchTypeMap.put(JDBCType.VARBINARY, BINARY);
jdbcTypeToOpenSearchTypeMap.put(JDBCType.STRUCT, OBJECT);
jdbcTypeToOpenSearchTypeMap.put(JDBCType.ARRAY, ARRAY);

}

/**
Expand Down
23 changes: 22 additions & 1 deletion src/main/java/org/opensearch/jdbc/types/TypeConverters.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package org.opensearch.jdbc.types;

import java.sql.Array;
import java.sql.Date;
import java.sql.JDBCType;
import java.sql.SQLException;
Expand Down Expand Up @@ -58,8 +59,9 @@ public class TypeConverters {

tcMap.put(JDBCType.NULL, new NullTypeConverter());

// Adding Struct Support
tcMap.put(JDBCType.STRUCT, new StructTypeConverter());

tcMap.put(JDBCType.ARRAY, new ArrayTypeConverter());
}

public static TypeConverter getInstance(JDBCType jdbcType) {
Expand All @@ -85,6 +87,25 @@ public Set<Class> getSupportedJavaClasses() {
}
}

public static class ArrayTypeConverter extends BaseTypeConverter {

private static final Set<Class> supportedJavaClasses = Collections.singleton(Array.class);

ArrayTypeConverter() {

}

@Override
public Class getDefaultJavaClass() {
return Array.class;
}

@Override
public Set<Class> getSupportedJavaClasses() {
return supportedJavaClasses;
}
}

public static class TimestampTypeConverter extends BaseTypeConverter {

private static final Set<Class> supportedJavaClasses = Collections.unmodifiableSet(
Expand Down
Loading

0 comments on commit e15de5e

Please sign in to comment.