diff --git a/config/ydb.checkstyle.xml b/config/ydb.checkstyle.xml new file mode 100644 index 0000000..ab26539 --- /dev/null +++ b/config/ydb.checkstyle.xml @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/ydb.suppressions.xml b/config/ydb.suppressions.xml new file mode 100644 index 0000000..fe45ca6 --- /dev/null +++ b/config/ydb.suppressions.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/jdbc/pom.xml b/jdbc/pom.xml index f76fbfe..9c508fa 100644 --- a/jdbc/pom.xml +++ b/jdbc/pom.xml @@ -53,6 +53,10 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + org.apache.maven.plugins maven-source-plugin diff --git a/jdbc/src/main/java/tech/ydb/jdbc/YdbConnection.java b/jdbc/src/main/java/tech/ydb/jdbc/YdbConnection.java index 4e6b901..7f2d8a9 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/YdbConnection.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/YdbConnection.java @@ -5,9 +5,9 @@ import javax.annotation.Nullable; -import tech.ydb.jdbc.query.YdbQuery; import tech.ydb.jdbc.context.YdbContext; import tech.ydb.jdbc.context.YdbExecutor; +import tech.ydb.jdbc.query.YdbQuery; import tech.ydb.table.query.DataQueryResult; import tech.ydb.table.query.ExplainDataQueryResult; import tech.ydb.table.query.Params; @@ -53,7 +53,8 @@ public interface YdbConnection extends Connection { * @return list of result set * @throws SQLException if query cannot be executed */ - DataQueryResult executeDataQuery(YdbQuery query, YdbExecutor executor, ExecuteDataQuerySettings settings, Params params) throws SQLException; + DataQueryResult executeDataQuery(YdbQuery query, YdbExecutor executor, ExecuteDataQuerySettings settings, + Params params) throws SQLException; /** * Explicitly execute query as a scan query diff --git a/jdbc/src/main/java/tech/ydb/jdbc/YdbDriverInfo.java b/jdbc/src/main/java/tech/ydb/jdbc/YdbDriverInfo.java index 62901e5..744f90b 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/YdbDriverInfo.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/YdbDriverInfo.java @@ -11,4 +11,6 @@ public final class YdbDriverInfo { public static final String DRIVER_FULL_NAME = DRIVER_NAME + " " + DRIVER_VERSION; public static final int JDBC_MAJOR_VERSION = 4; public static final int JDBC_MINOR_VERSION = 2; + + private YdbDriverInfo() { } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/common/FixedResultSetFactory.java b/jdbc/src/main/java/tech/ydb/jdbc/common/FixedResultSetFactory.java index 4bccb52..ab228eb 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/common/FixedResultSetFactory.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/common/FixedResultSetFactory.java @@ -127,7 +127,7 @@ private class FixedResultSet implements ResultSetReader { private final List> rows; private int rowIndex = 0; - public FixedResultSet(List> rows) { + FixedResultSet(List> rows) { this.rows = rows; } @@ -190,7 +190,7 @@ private static class Column { private final String name; private final Type type; - public Column(String name, Type type) { + Column(String name, Type type) { this.name = name; this.type = type; } @@ -237,7 +237,7 @@ private static class FixedValueReader implements ValueReader { private final PrimitiveValue value; private final Type type; - public FixedValueReader(PrimitiveValue value, Type type) { + FixedValueReader(PrimitiveValue value, Type type) { this.value = value; this.type = type; } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/common/JdbcDriverVersion.java b/jdbc/src/main/java/tech/ydb/jdbc/common/JdbcDriverVersion.java index c86b851..f3d9c60 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/common/JdbcDriverVersion.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/common/JdbcDriverVersion.java @@ -32,12 +32,12 @@ public String getFullVersion() { } public static JdbcDriverVersion getInstance() { - return Holder.instance; + return Holder.INSTANCE; } private static class Holder { - private final static String PROPERTIES_PATH = "/ydb_jdbc.properties"; - private final static JdbcDriverVersion instance; + private static final String PROPERTIES_PATH = "/ydb_jdbc.properties"; + private static final JdbcDriverVersion INSTANCE; static { int major = -1; @@ -60,7 +60,7 @@ private static class Holder { } catch (RuntimeException e) { } } - instance = new JdbcDriverVersion(version, major, minor); + INSTANCE = new JdbcDriverVersion(version, major, minor); } } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/common/MappingGetters.java b/jdbc/src/main/java/tech/ydb/jdbc/common/MappingGetters.java index 2040c17..7b4fd7c 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/common/MappingGetters.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/common/MappingGetters.java @@ -16,10 +16,6 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; -import javax.annotation.Nullable; - -import com.google.common.base.Preconditions; - import tech.ydb.jdbc.impl.YdbTypesImpl; import tech.ydb.table.result.PrimitiveReader; import tech.ydb.table.result.ValueReader; @@ -30,159 +26,205 @@ import static tech.ydb.jdbc.YdbConst.UNABLE_TO_CAST; import static tech.ydb.jdbc.YdbConst.UNABLE_TO_CONVERT; +import static tech.ydb.table.values.PrimitiveType.Bool; +import static tech.ydb.table.values.PrimitiveType.Bytes; +import static tech.ydb.table.values.PrimitiveType.Date; +import static tech.ydb.table.values.PrimitiveType.Datetime; +import static tech.ydb.table.values.PrimitiveType.Double; +import static tech.ydb.table.values.PrimitiveType.Float; import static tech.ydb.table.values.PrimitiveType.Int16; import static tech.ydb.table.values.PrimitiveType.Int32; +import static tech.ydb.table.values.PrimitiveType.Int64; +import static tech.ydb.table.values.PrimitiveType.Int8; +import static tech.ydb.table.values.PrimitiveType.Interval; +import static tech.ydb.table.values.PrimitiveType.Json; +import static tech.ydb.table.values.PrimitiveType.JsonDocument; +import static tech.ydb.table.values.PrimitiveType.Text; +import static tech.ydb.table.values.PrimitiveType.Timestamp; +import static tech.ydb.table.values.PrimitiveType.TzDate; +import static tech.ydb.table.values.PrimitiveType.TzDatetime; +import static tech.ydb.table.values.PrimitiveType.TzTimestamp; +import static tech.ydb.table.values.PrimitiveType.Uint16; import static tech.ydb.table.values.PrimitiveType.Uint32; +import static tech.ydb.table.values.PrimitiveType.Uint64; +import static tech.ydb.table.values.PrimitiveType.Uint8; +import static tech.ydb.table.values.PrimitiveType.Uuid; +import static tech.ydb.table.values.PrimitiveType.Yson; +import static tech.ydb.table.values.Type.Kind.PRIMITIVE; public class MappingGetters { + private MappingGetters() { } static Getters buildGetters(Type type) { Type.Kind kind = type.getKind(); - @Nullable PrimitiveType id = type.getKind() == Type.Kind.PRIMITIVE ? ((PrimitiveType) type) : null; - return new Getters( - valueToString(kind, id), - valueToBoolean(kind, id), - valueToByte(kind, id), - valueToShort(kind, id), - valueToInt(kind, id), - valueToLong(kind, id), - valueToFloat(kind, id), - valueToDouble(kind, id), - valueToBytes(kind, id), - valueToObject(kind, id), - valueToDateMillis(kind, id), - valueToNString(kind, id), - valueToURL(kind, id), - valueToBigDecimal(kind, id), - valueToReader(kind, id)); - } - - private static ValueToString valueToString(Type.Kind kind, @Nullable PrimitiveType id) { - Class javaType = String.class; - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bytes: - return value -> new String(value.getBytes()); - case Text: - return PrimitiveReader::getText; - case Json: - return PrimitiveReader::getJson; - case JsonDocument: - return PrimitiveReader::getJsonDocument; - case Yson: - return value -> new String(value.getYson()); - case Uuid: - return value -> String.valueOf(value.getUuid()); - case Bool: - return value -> String.valueOf(value.getBool()); - case Int8: - return value -> String.valueOf(value.getInt8()); - case Uint8: - return value -> String.valueOf(value.getUint8()); - case Int16: - return value -> String.valueOf(value.getInt16()); - case Uint16: - return value -> String.valueOf(value.getUint16()); - case Int32: - return value -> String.valueOf(value.getInt32()); - case Uint32: - return value -> String.valueOf(value.getUint32()); - case Int64: - return value -> String.valueOf(value.getInt64()); - case Uint64: - return value -> String.valueOf(value.getUint64()); - case Float: - return value -> String.valueOf(value.getFloat()); - case Double: - return value -> String.valueOf(value.getDouble()); - case Date: - return value -> String.valueOf(value.getDate()); - case Datetime: - return value -> String.valueOf(value.getDatetime()); - case Timestamp: - return value -> String.valueOf(value.getTimestamp()); - case Interval: - return value -> String.valueOf(value.getInterval()); - case TzDate: - return value -> String.valueOf(value.getTzDate()); - case TzDatetime: - return value -> String.valueOf(value.getTzDatetime()); - case TzTimestamp: - return value -> String.valueOf(value.getTzTimestamp()); - default: - // DyNumber - return value -> { - throw dataTypeNotSupported(id, javaType); - }; - } - } else if (kind == Type.Kind.DECIMAL) { - return value -> String.valueOf(value.getDecimal()); - } else { - return value -> String.valueOf(value.getValue()); - } - } - - private static ValueToBoolean valueToBoolean(Type.Kind kind, @Nullable PrimitiveType id) { - Class javaType = boolean.class; - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bool: - return PrimitiveReader::getBool; - case Int8: - return value -> value.getInt8() != 0; - case Uint8: - return value -> value.getUint8() != 0; - case Int16: - return value -> value.getInt16() != 0; - case Uint16: - return value -> value.getUint16() != 0; - case Int32: - return value -> value.getInt32() != 0; - case Uint32: - return value -> value.getUint32() != 0; - case Int64: - return value -> value.getInt64() != 0; - case Uint64: - return value -> value.getUint64() != 0; - case Bytes: - return value -> { - byte[] stringValue = value.getBytes(); - if (stringValue.length == 0) { + String clazz = kind.toString(); + switch (kind) { + case PRIMITIVE: + PrimitiveType id = (PrimitiveType) type; + return new Getters( + valueToString(id), + valueToBoolean(id), + valueToByte(id), + valueToShort(id), + valueToInt(id), + valueToLong(id), + valueToFloat(id), + valueToDouble(id), + valueToBytes(id), + valueToObject(id), + valueToDateMillis(id), + valueToNString(id), + valueToURL(id), + valueToBigDecimal(id), + valueToReader(id) + ); + case DECIMAL: + return new Getters( + value -> String.valueOf(value.getDecimal()), + castToBooleanNotSupported(clazz), + castToByteNotSupported(clazz), + castToShortNotSupported(clazz), + value -> value.getDecimal().toBigInteger().intValue(), + value -> value.getDecimal().toBigInteger().longValue(), + value -> value.getDecimal().toBigDecimal().floatValue(), + value -> value.getDecimal().toBigDecimal().doubleValue(), + castToBytesNotSupported(clazz), + PrimitiveReader::getDecimal, + castToDateMillisNotSupported(clazz), + castToNStringNotSupported(clazz), + castToUrlNotSupported(clazz), + value -> value.getDecimal().toBigDecimal(), + castToReaderNotSupported(clazz) + ); + default: + return new Getters( + value -> String.valueOf(value.getValue()), + castToBooleanNotSupported(clazz), + castToByteNotSupported(clazz), + castToShortNotSupported(clazz), + castToIntNotSupported(clazz), + castToLongNotSupported(clazz), + castToFloatNotSupported(clazz), + castToDoubleNotSupported(clazz), + castToBytesNotSupported(clazz), + ValueReader::getValue, + castToDateMillisNotSupported(clazz), + castToNStringNotSupported(clazz), + castToUrlNotSupported(clazz), + castToBigDecimalNotSupported(clazz), + castToReaderNotSupported(clazz) + ); + } + } + + private static ValueToString valueToString(PrimitiveType id) { + switch (id) { + case Bytes: + return value -> new String(value.getBytes()); + case Text: + return PrimitiveReader::getText; + case Json: + return PrimitiveReader::getJson; + case JsonDocument: + return PrimitiveReader::getJsonDocument; + case Yson: + return value -> new String(value.getYson()); + case Uuid: + return value -> String.valueOf(value.getUuid()); + case Bool: + return value -> String.valueOf(value.getBool()); + case Int8: + return value -> String.valueOf(value.getInt8()); + case Uint8: + return value -> String.valueOf(value.getUint8()); + case Int16: + return value -> String.valueOf(value.getInt16()); + case Uint16: + return value -> String.valueOf(value.getUint16()); + case Int32: + return value -> String.valueOf(value.getInt32()); + case Uint32: + return value -> String.valueOf(value.getUint32()); + case Int64: + return value -> String.valueOf(value.getInt64()); + case Uint64: + return value -> String.valueOf(value.getUint64()); + case Float: + return value -> String.valueOf(value.getFloat()); + case Double: + return value -> String.valueOf(value.getDouble()); + case Date: + return value -> String.valueOf(value.getDate()); + case Datetime: + return value -> String.valueOf(value.getDatetime()); + case Timestamp: + return value -> String.valueOf(value.getTimestamp()); + case Interval: + return value -> String.valueOf(value.getInterval()); + case TzDate: + return value -> String.valueOf(value.getTzDate()); + case TzDatetime: + return value -> String.valueOf(value.getTzDatetime()); + case TzTimestamp: + return value -> String.valueOf(value.getTzTimestamp()); + default: + // DyNumber + return value -> { + throw dataTypeNotSupported(id, String.class); + }; + } + } + + private static ValueToBoolean valueToBoolean(PrimitiveType id) { + switch (id) { + case Bool: + return PrimitiveReader::getBool; + case Int8: + return value -> value.getInt8() != 0; + case Uint8: + return value -> value.getUint8() != 0; + case Int16: + return value -> value.getInt16() != 0; + case Uint16: + return value -> value.getUint16() != 0; + case Int32: + return value -> value.getInt32() != 0; + case Uint32: + return value -> value.getUint32() != 0; + case Int64: + return value -> value.getInt64() != 0; + case Uint64: + return value -> value.getUint64() != 0; + case Bytes: + return value -> { + byte[] stringValue = value.getBytes(); + if (stringValue.length == 0) { + return false; + } else if (stringValue.length == 1) { + if (stringValue[0] == '0') { return false; - } else if (stringValue.length == 1) { - if (stringValue[0] == '0') { - return false; - } else if (stringValue[0] == '1') { - return true; - } + } else if (stringValue[0] == '1') { + return true; } - throw cannotConvert(id, javaType, new String(stringValue)); - }; - case Text: - return value -> { - String utfValue = value.getText(); - if (utfValue.isEmpty()) { + } + throw cannotConvert(id, boolean.class, new String(stringValue)); + }; + case Text: + return value -> { + String utfValue = value.getText(); + if (utfValue.isEmpty()) { + return false; + } else if (utfValue.length() == 1) { + if (utfValue.charAt(0) == '0') { return false; - } else if (utfValue.length() == 1) { - if (utfValue.charAt(0) == '0') { - return false; - } else if (utfValue.charAt(0) == '1') { - return true; - } + } else if (utfValue.charAt(0) == '1') { + return true; } - throw cannotConvert(id, javaType, utfValue); - }; - default: - return value -> { - throw dataTypeNotSupported(id, javaType); - }; - } - } else { - return value -> { - throw dataTypeNotSupported(kind, javaType); - }; + } + throw cannotConvert(id, boolean.class, utfValue); + }; + default: + return castToBooleanNotSupported(id.name()); } } @@ -191,48 +233,39 @@ private static byte checkByteValue(PrimitiveType id, int value) throws SQLExcept if ((ch & 0x7F) != ch) { throw cannotConvert(id, byte.class, value); } - return (byte)value; + return (byte) value; } private static byte checkByteValue(PrimitiveType id, long value) throws SQLException { long ch = value >= 0 ? value : ~value; - if ((ch & 0x7Fl) != ch) { + if ((ch & 0x7FL) != ch) { throw cannotConvert(id, byte.class, value); } - return (byte)value; - } - - private static ValueToByte valueToByte(Type.Kind kind, PrimitiveType id) { - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bool: - return value -> checkByteValue(id, value.getBool() ? 1 : 0); - case Int8: - return PrimitiveReader::getInt8; - case Int16: - return value -> checkByteValue(id, value.getInt16()); - case Int32: - return value -> checkByteValue(id, value.getInt32()); - case Int64: - return value -> checkByteValue(id, value.getInt64()); - case Uint8: - return value -> checkByteValue(id, value.getUint8()); - case Uint16: - return value -> checkByteValue(id, value.getUint16()); - case Uint32: - return value -> checkByteValue(id, value.getUint32()); - case Uint64: - return value -> checkByteValue(id, value.getUint64()); - default: - return value -> { - throw dataTypeNotSupported(id, byte.class); - }; - } - } else { - return value -> { - throw dataTypeNotSupported(kind, byte.class); - }; + return (byte) value; + } + + private static ValueToByte valueToByte(PrimitiveType id) { + switch (id) { + case Bool: + return value -> checkByteValue(id, value.getBool() ? 1 : 0); + case Int8: + return PrimitiveReader::getInt8; + case Int16: + return value -> checkByteValue(id, value.getInt16()); + case Int32: + return value -> checkByteValue(id, value.getInt32()); + case Int64: + return value -> checkByteValue(id, value.getInt64()); + case Uint8: + return value -> checkByteValue(id, value.getUint8()); + case Uint16: + return value -> checkByteValue(id, value.getUint16()); + case Uint32: + return value -> checkByteValue(id, value.getUint32()); + case Uint64: + return value -> checkByteValue(id, value.getUint64()); + default: + return castToByteNotSupported(id.name()); } } @@ -241,545 +274,405 @@ private static short checkShortValue(PrimitiveType id, int value) throws SQLExce if ((ch & 0x7FFF) != ch) { throw cannotConvert(id, short.class, value); } - return (short)value; + return (short) value; } private static short checkShortValue(PrimitiveType id, long value) throws SQLException { long ch = value >= 0 ? value : ~value; - if ((ch & 0x7FFFl) != ch) { + if ((ch & 0x7FFFL) != ch) { throw cannotConvert(id, short.class, value); } - return (short)value; - } - - private static ValueToShort valueToShort(Type.Kind kind, PrimitiveType id) { - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bool: - return value -> checkShortValue(id, value.getBool() ? 1 : 0); - case Int8: - return PrimitiveReader::getInt8; - case Int16: - return PrimitiveReader::getInt16; - case Int32: - return value -> checkShortValue(id, value.getInt32()); - case Int64: - return value -> checkShortValue(id, value.getInt64()); - case Uint8: - return value -> checkShortValue(id, value.getUint8()); - case Uint16: - return value -> checkShortValue(id, value.getUint16()); - case Uint32: - return value -> checkShortValue(id, value.getUint32()); - case Uint64: - return value -> checkShortValue(id, value.getUint64()); - default: - return value -> { - throw dataTypeNotSupported(id, short.class); - }; - } - } else { - return value -> { - throw dataTypeNotSupported(kind, short.class); - }; + return (short) value; + } + + private static ValueToShort valueToShort(PrimitiveType id) { + switch (id) { + case Bool: + return value -> checkShortValue(id, value.getBool() ? 1 : 0); + case Int8: + return PrimitiveReader::getInt8; + case Int16: + return PrimitiveReader::getInt16; + case Int32: + return value -> checkShortValue(id, value.getInt32()); + case Int64: + return value -> checkShortValue(id, value.getInt64()); + case Uint8: + return value -> checkShortValue(id, value.getUint8()); + case Uint16: + return value -> checkShortValue(id, value.getUint16()); + case Uint32: + return value -> checkShortValue(id, value.getUint32()); + case Uint64: + return value -> checkShortValue(id, value.getUint64()); + default: + return castToShortNotSupported(id.name()); } } private static int checkIntValue(PrimitiveType id, long value) throws SQLException { long ch = value >= 0 ? value : ~value; - if ((ch & 0x7FFFFFFFl) != ch) { + if ((ch & 0x7FFFFFFFL) != ch) { throw cannotConvert(id, int.class, value); } - return (int)value; - } - - private static ValueToInt valueToInt(Type.Kind kind, PrimitiveType id) { - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bool: - return value -> value.getBool() ? 1 : 0; - case Int8: - return PrimitiveReader::getInt8; - case Int16: - return PrimitiveReader::getInt16; - case Int32: - return PrimitiveReader::getInt32; - case Int64: - return value -> checkIntValue(id, value.getInt64()); - case Uint8: - return PrimitiveReader::getUint8; - case Uint16: - return PrimitiveReader::getUint16; - case Uint32: - return value -> checkIntValue(id, value.getUint32()); - case Uint64: - return value -> checkIntValue(id, value.getUint64()); - default: - return value -> { - throw dataTypeNotSupported(id, int.class); - }; - } - } else if (kind == Type.Kind.DECIMAL) { - return value -> value.getDecimal().toBigInteger().intValue(); // TODO: Improve performance - } else { - return value -> { - throw dataTypeNotSupported(kind, int.class); - }; - } - } - - private static ValueToLong valueToLong(Type.Kind kind, @Nullable PrimitiveType id) { - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bool: - return value -> value.getBool() ? 1 : 0; - case Int8: - return PrimitiveReader::getInt8; - case Uint8: - return PrimitiveReader::getUint8; - case Int16: - return PrimitiveReader::getInt16; - case Uint16: - return PrimitiveReader::getUint16; - case Int32: - return PrimitiveReader::getInt32; - case Uint32: - return PrimitiveReader::getUint32; - case Int64: - return PrimitiveReader::getInt64; - case Uint64: - return PrimitiveReader::getUint64; - case Date: - case Datetime: - case TzDate: - case TzDatetime: - case Timestamp: - case TzTimestamp: - ValueToDateMillis delegate = valueToDateMillis(kind, id); - return delegate::fromValue; - case Interval: - return value -> TimeUnit.NANOSECONDS.toMicros(value.getInterval().toNanos()); - default: - return value -> { - throw dataTypeNotSupported(id, long.class); - }; - } - } else if (kind == Type.Kind.DECIMAL) { - return value -> value.getDecimal().toBigInteger().longValue(); // TODO: Improve performance - } else { - return value -> { - throw dataTypeNotSupported(kind, long.class); - }; - } - } - - private static ValueToFloat valueToFloat(Type.Kind kind, @Nullable PrimitiveType id) { - Class javaType = float.class; - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bool: - return value -> value.getBool() ? 1 : 0; - case Int8: - return PrimitiveReader::getInt8; - case Int16: - return PrimitiveReader::getInt16; - case Int32: - return PrimitiveReader::getInt32; - case Int64: - return PrimitiveReader::getInt64; - case Uint8: - return PrimitiveReader::getUint8; - case Uint16: - return PrimitiveReader::getUint16; - case Uint32: - return PrimitiveReader::getUint32; - case Uint64: - return PrimitiveReader::getUint64; - case Float: - return PrimitiveReader::getFloat; - case Double: - return value -> (float) value.getDouble(); - default: - return value -> { - throw dataTypeNotSupported(id, javaType); - }; - } - } else if (kind == Type.Kind.DECIMAL) { - return value -> value.getDecimal().toBigDecimal().floatValue(); - } else { - return value -> { - throw dataTypeNotSupported(kind, javaType); - }; - } - } - - private static ValueToDouble valueToDouble(Type.Kind kind, @Nullable PrimitiveType id) { - Class javaType = double.class; - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bool: - return value -> value.getBool() ? 1 : 0; - case Int8: - return PrimitiveReader::getInt8; - case Uint8: - return PrimitiveReader::getUint8; - case Int16: - return PrimitiveReader::getInt16; - case Uint16: - return PrimitiveReader::getUint16; - case Int32: - return PrimitiveReader::getInt32; - case Uint32: - return PrimitiveReader::getUint32; - case Int64: - return PrimitiveReader::getInt64; - case Uint64: - return PrimitiveReader::getUint64; - case Float: - return PrimitiveReader::getFloat; - case Double: - return PrimitiveReader::getDouble; - default: - return value -> { - throw dataTypeNotSupported(id, javaType); - }; - } - } else if (kind == Type.Kind.DECIMAL) { - return value -> value.getDecimal().toBigDecimal().doubleValue(); - } else { - return value -> { - throw dataTypeNotSupported(kind, javaType); - }; - } - } - - private static ValueToBytes valueToBytes(Type.Kind kind, @Nullable PrimitiveType id) { - Class javaType = byte[].class; - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bytes: - return PrimitiveReader::getBytes; - case Text: - // TODO: pretty ineffective conversion (bytes -> string -> bytes) - return value -> value.getText().getBytes(); - case Json: - return value -> value.getJson().getBytes(); - case JsonDocument: - return value -> value.getJsonDocument().getBytes(); - case Yson: - return PrimitiveReader::getYson; - case Uuid: - return value -> value.getUuid().toString().getBytes(); - default: - return value -> { - throw dataTypeNotSupported(id, javaType); - }; - } - } else { - return value -> { - throw dataTypeNotSupported(kind, javaType); - }; - } - } - - private static ValueToDateMillis valueToDateMillis(Type.Kind kind, @Nullable PrimitiveType id) { - Class javaType = long.class; - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Int64: - return PrimitiveReader::getInt64; - case Uint64: - return PrimitiveReader::getUint64; - case Date: - return value -> TimeUnit.DAYS.toMillis(value.getDate().toEpochDay()); - case Datetime: - return value -> TimeUnit.SECONDS.toMillis(value.getDatetime().toEpochSecond(ZoneOffset.UTC)); - case TzDate: - return value -> TimeUnit.SECONDS.toMillis(value.getTzDate().toEpochSecond()); - case TzDatetime: - return value -> TimeUnit.SECONDS.toMillis(value.getTzDatetime().toEpochSecond()); - case Timestamp: - return value -> value.getTimestamp().toEpochMilli(); - case TzTimestamp: - return value -> TimeUnit.SECONDS.toMillis(value.getTzTimestamp().toEpochSecond()); - default: - return value -> { - throw dataTypeNotSupported(id, javaType); - }; - } - } else { - return value -> { - throw dataTypeNotSupported(kind, javaType); - }; - } - } - - private static ValueToNString valueToNString(Type.Kind kind, @Nullable PrimitiveType id) { - Class javaType = String.class; - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bytes: - return value -> new String(value.getBytes()); - case Text: - return PrimitiveReader::getText; - case Json: - return PrimitiveReader::getJson; - case JsonDocument: - return PrimitiveReader::getJsonDocument; - case Yson: - return value -> new String(value.getYson()); - case Uuid: - return value -> String.valueOf(value.getUuid()); - default: - return value -> { - throw dataTypeNotSupported(id, javaType); - }; - } - } else { - return value -> { - throw dataTypeNotSupported(kind, javaType); - }; - } - } - - private static ValueToURL valueToURL(Type.Kind kind, @Nullable PrimitiveType id) { - Class javaType = URL.class; - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bytes: - return value -> new String(value.getBytes()); - case Text: - return PrimitiveReader::getText; - default: - return value -> { - throw dataTypeNotSupported(id, javaType); - }; - } - } else { - return value -> { - throw dataTypeNotSupported(kind, javaType); - }; - } - } - - private static ValueToBigDecimal valueToBigDecimal(Type.Kind kind, @Nullable PrimitiveType id) { - Class javaType = BigDecimal.class; - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bool: - return value -> BigDecimal.valueOf(value.getBool() ? 1 : 0); - case Int8: - return value -> BigDecimal.valueOf(value.getInt8()); - case Uint8: - return value -> BigDecimal.valueOf(value.getUint8()); - case Int16: - return value -> BigDecimal.valueOf(value.getInt16()); - case Uint16: - return value -> BigDecimal.valueOf(value.getUint16()); - case Int32: - return value -> BigDecimal.valueOf(value.getInt32()); - case Uint32: - return value -> BigDecimal.valueOf(value.getUint32()); - case Int64: - return value -> BigDecimal.valueOf(value.getInt64()); - case Uint64: - return value -> BigDecimal.valueOf(value.getUint64()); - case Float: - return value -> BigDecimal.valueOf(value.getFloat()); - case Double: - return value -> BigDecimal.valueOf(value.getDouble()); - default: - return value -> { - throw dataTypeNotSupported(id, javaType); - }; - } - } else if (kind == Type.Kind.DECIMAL) { - return value -> value.getDecimal().toBigDecimal(); - } else { - return value -> { - throw dataTypeNotSupported(kind, javaType); - }; - } - } - - private static ValueToReader valueToReader(Type.Kind kind, @Nullable PrimitiveType id) { - Class javaType = Reader.class; - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bytes: - return value -> new InputStreamReader(new ByteArrayInputStream(value.getBytes())); - case Text: - return value -> new StringReader(value.getText()); - case Json: - return value -> new StringReader(value.getJson()); - case JsonDocument: - return value -> new StringReader(value.getJsonDocument()); - case Yson: - return value -> new InputStreamReader(new ByteArrayInputStream(value.getYson())); - case Uuid: - return value -> new StringReader(value.getUuid().toString()); - default: - return value -> { - throw dataTypeNotSupported(id, javaType); - }; - } - } else { - return value -> { - throw dataTypeNotSupported(kind, javaType); - }; + return (int) value; + } + + private static ValueToInt valueToInt(PrimitiveType id) { + switch (id) { + case Bool: + return value -> value.getBool() ? 1 : 0; + case Int8: + return PrimitiveReader::getInt8; + case Int16: + return PrimitiveReader::getInt16; + case Int32: + return PrimitiveReader::getInt32; + case Int64: + return value -> checkIntValue(id, value.getInt64()); + case Uint8: + return PrimitiveReader::getUint8; + case Uint16: + return PrimitiveReader::getUint16; + case Uint32: + return value -> checkIntValue(id, value.getUint32()); + case Uint64: + return value -> checkIntValue(id, value.getUint64()); + default: + return castToIntNotSupported(id.name()); + } + } + + private static ValueToLong valueToLong(PrimitiveType id) { + switch (id) { + case Bool: + return value -> value.getBool() ? 1 : 0; + case Int8: + return PrimitiveReader::getInt8; + case Uint8: + return PrimitiveReader::getUint8; + case Int16: + return PrimitiveReader::getInt16; + case Uint16: + return PrimitiveReader::getUint16; + case Int32: + return PrimitiveReader::getInt32; + case Uint32: + return PrimitiveReader::getUint32; + case Int64: + return PrimitiveReader::getInt64; + case Uint64: + return PrimitiveReader::getUint64; + case Date: + case Datetime: + case TzDate: + case TzDatetime: + case Timestamp: + case TzTimestamp: + ValueToDateMillis delegate = valueToDateMillis(id); + return delegate::fromValue; + case Interval: + return value -> TimeUnit.NANOSECONDS.toMicros(value.getInterval().toNanos()); + default: + return castToLongNotSupported(id.name()); + } + } + + private static ValueToFloat valueToFloat(PrimitiveType id) { + switch (id) { + case Bool: + return value -> value.getBool() ? 1 : 0; + case Int8: + return PrimitiveReader::getInt8; + case Int16: + return PrimitiveReader::getInt16; + case Int32: + return PrimitiveReader::getInt32; + case Int64: + return PrimitiveReader::getInt64; + case Uint8: + return PrimitiveReader::getUint8; + case Uint16: + return PrimitiveReader::getUint16; + case Uint32: + return PrimitiveReader::getUint32; + case Uint64: + return PrimitiveReader::getUint64; + case Float: + return PrimitiveReader::getFloat; + case Double: + return value -> (float) value.getDouble(); + default: + return castToFloatNotSupported(id.name()); + } + } + + private static ValueToDouble valueToDouble(PrimitiveType id) { + switch (id) { + case Bool: + return value -> value.getBool() ? 1 : 0; + case Int8: + return PrimitiveReader::getInt8; + case Uint8: + return PrimitiveReader::getUint8; + case Int16: + return PrimitiveReader::getInt16; + case Uint16: + return PrimitiveReader::getUint16; + case Int32: + return PrimitiveReader::getInt32; + case Uint32: + return PrimitiveReader::getUint32; + case Int64: + return PrimitiveReader::getInt64; + case Uint64: + return PrimitiveReader::getUint64; + case Float: + return PrimitiveReader::getFloat; + case Double: + return PrimitiveReader::getDouble; + default: + return castToDoubleNotSupported(id.name()); + } + } + + private static ValueToBytes valueToBytes(PrimitiveType id) { + switch (id) { + case Bytes: + return PrimitiveReader::getBytes; + case Text: + // TODO: pretty ineffective conversion (bytes -> string -> bytes) + return value -> value.getText().getBytes(); + case Json: + return value -> value.getJson().getBytes(); + case JsonDocument: + return value -> value.getJsonDocument().getBytes(); + case Yson: + return PrimitiveReader::getYson; + case Uuid: + return value -> value.getUuid().toString().getBytes(); + default: + return castToBytesNotSupported(id.name()); + } + } + + private static ValueToDateMillis valueToDateMillis(PrimitiveType id) { + switch (id) { + case Int64: + return PrimitiveReader::getInt64; + case Uint64: + return PrimitiveReader::getUint64; + case Date: + return value -> TimeUnit.DAYS.toMillis(value.getDate().toEpochDay()); + case Datetime: + return value -> TimeUnit.SECONDS.toMillis(value.getDatetime().toEpochSecond(ZoneOffset.UTC)); + case TzDate: + return value -> TimeUnit.SECONDS.toMillis(value.getTzDate().toEpochSecond()); + case TzDatetime: + return value -> TimeUnit.SECONDS.toMillis(value.getTzDatetime().toEpochSecond()); + case Timestamp: + return value -> value.getTimestamp().toEpochMilli(); + case TzTimestamp: + return value -> TimeUnit.SECONDS.toMillis(value.getTzTimestamp().toEpochSecond()); + default: + return castToDateMillisNotSupported(id.name()); + } + } + + private static ValueToNString valueToNString(PrimitiveType id) { + switch (id) { + case Bytes: + return value -> new String(value.getBytes()); + case Text: + return PrimitiveReader::getText; + case Json: + return PrimitiveReader::getJson; + case JsonDocument: + return PrimitiveReader::getJsonDocument; + case Yson: + return value -> new String(value.getYson()); + case Uuid: + return value -> String.valueOf(value.getUuid()); + default: + return castToNStringNotSupported(id.name()); + } + } + + private static ValueToURL valueToURL(PrimitiveType id) { + switch (id) { + case Bytes: + return value -> new String(value.getBytes()); + case Text: + return PrimitiveReader::getText; + default: + return castToUrlNotSupported(id.name()); + } + } + + private static ValueToBigDecimal valueToBigDecimal(PrimitiveType id) { + switch (id) { + case Bool: + return value -> BigDecimal.valueOf(value.getBool() ? 1 : 0); + case Int8: + return value -> BigDecimal.valueOf(value.getInt8()); + case Uint8: + return value -> BigDecimal.valueOf(value.getUint8()); + case Int16: + return value -> BigDecimal.valueOf(value.getInt16()); + case Uint16: + return value -> BigDecimal.valueOf(value.getUint16()); + case Int32: + return value -> BigDecimal.valueOf(value.getInt32()); + case Uint32: + return value -> BigDecimal.valueOf(value.getUint32()); + case Int64: + return value -> BigDecimal.valueOf(value.getInt64()); + case Uint64: + return value -> BigDecimal.valueOf(value.getUint64()); + case Float: + return value -> BigDecimal.valueOf(value.getFloat()); + case Double: + return value -> BigDecimal.valueOf(value.getDouble()); + default: + return castToBigDecimalNotSupported(id.name()); + } + } + + private static ValueToReader valueToReader(PrimitiveType id) { + switch (id) { + case Bytes: + return value -> new InputStreamReader(new ByteArrayInputStream(value.getBytes())); + case Text: + return value -> new StringReader(value.getText()); + case Json: + return value -> new StringReader(value.getJson()); + case JsonDocument: + return value -> new StringReader(value.getJsonDocument()); + case Yson: + return value -> new InputStreamReader(new ByteArrayInputStream(value.getYson())); + case Uuid: + return value -> new StringReader(value.getUuid().toString()); + default: + return castToReaderNotSupported(id.name()); } } + private static SqlType buildPrimitiveType(int sqlType, PrimitiveType id) { + switch (id) { + case Text: + case Json: + case JsonDocument: + case Uuid: + return new SqlType(sqlType, String.class); + case Bytes: + case Yson: + return new SqlType(sqlType, byte[].class); + case Bool: + return new SqlType(sqlType, Boolean.class); + case Int8: + return new SqlType(sqlType, Byte.class); + case Uint8: + case Int32: + case Uint16: + return new SqlType(sqlType, Integer.class); + case Int16: + return new SqlType(sqlType, Short.class); + case Uint32: + case Int64: + case Uint64: + return new SqlType(sqlType, Long.class); + case Float: + return new SqlType(sqlType, Float.class); + case Double: + return new SqlType(sqlType, Double.class); + case Date: + return new SqlType(sqlType, LocalDate.class); + case Datetime: + return new SqlType(sqlType, LocalDateTime.class); + case Timestamp: + return new SqlType(sqlType, Instant.class); + case Interval: + return new SqlType(sqlType, Duration.class); + case TzDate: + case TzDatetime: + case TzTimestamp: + return new SqlType(sqlType, ZonedDateTime.class); + default: + return new SqlType(sqlType, Value.class); + } + } static SqlType buildDataType(Type type) { - Type.Kind kind = type.getKind(); // All types must be the same as for #valueToObject int sqlType = YdbTypesImpl.getInstance().toSqlType(type); - if (kind == Type.Kind.PRIMITIVE) { - PrimitiveType id = (PrimitiveType) type; - final Class javaType; - switch (id) { - case Text: - case Json: - case JsonDocument: - case Uuid: - javaType = String.class; - break; - case Bytes: - case Yson: - javaType = byte[].class; - break; - case Bool: - javaType = Boolean.class; - break; - case Int8: - javaType = Byte.class; - break; - case Uint8: - case Int32: - case Uint16: - javaType = Integer.class; - break; - case Int16: - javaType = Short.class; - break; - case Uint32: - case Int64: - case Uint64: - javaType = Long.class; - break; - case Float: - javaType = Float.class; - break; - case Double: - javaType = Double.class; - break; - case Date: - javaType = LocalDate.class; - break; - case Datetime: - javaType = LocalDateTime.class; - break; - case Timestamp: - javaType = Instant.class; - break; - case Interval: - javaType = Duration.class; - break; - case TzDate: - case TzDatetime: - case TzTimestamp: - javaType = ZonedDateTime.class; - break; - default: - javaType = Value.class; - } - return new SqlType(sqlType, javaType); - } else if (kind == Type.Kind.DECIMAL) { - return new SqlType(sqlType, DecimalValue.class); - } else { - return new SqlType(sqlType, Value.class); - } - } - - private static ValueToObject valueToObject(Type.Kind kind, @Nullable PrimitiveType id) { - Class javaType = Object.class; - if (kind == Type.Kind.PRIMITIVE) { - Preconditions.checkState(id != null, "Primitive type must not be null when kind is %s", kind); - switch (id) { - case Bytes: - return PrimitiveReader::getBytes; - case Text: - return PrimitiveReader::getText; - case Json: - return PrimitiveReader::getJson; - case JsonDocument: - return PrimitiveReader::getJsonDocument; - case Yson: - return PrimitiveReader::getYson; - case Uuid: - return PrimitiveReader::getUuid; - case Bool: - return PrimitiveReader::getBool; - case Int8: - return PrimitiveReader::getInt8; - case Uint8: - return PrimitiveReader::getUint8; - case Int16: - return PrimitiveReader::getInt16; - case Uint16: - return PrimitiveReader::getUint16; - case Int32: - return PrimitiveReader::getInt32; - case Uint32: - return PrimitiveReader::getUint32; - case Int64: - return PrimitiveReader::getInt64; - case Uint64: - return PrimitiveReader::getUint64; - case Float: - return PrimitiveReader::getFloat; - case Double: - return PrimitiveReader::getDouble; - case Date: - return PrimitiveReader::getDate; - case Datetime: - return PrimitiveReader::getDatetime; - case Timestamp: - return PrimitiveReader::getTimestamp; - case Interval: - return PrimitiveReader::getInterval; - case TzDate: - return PrimitiveReader::getTzDate; - case TzDatetime: - return PrimitiveReader::getTzDatetime; - case TzTimestamp: - return PrimitiveReader::getTzTimestamp; - default: - // DyNumber - return value -> { - throw dataTypeNotSupported(id, javaType); - }; - } - } else if (kind == Type.Kind.DECIMAL) { - return PrimitiveReader::getDecimal; - } else { - return ValueReader::getValue; + switch (type.getKind()) { + case PRIMITIVE: + return buildPrimitiveType(sqlType, (PrimitiveType) type); + case DECIMAL: + return new SqlType(sqlType, DecimalValue.class); + default: + return new SqlType(sqlType, Value.class); } } + private static ValueToObject valueToObject(PrimitiveType id) { + switch (id) { + case Bytes: + return PrimitiveReader::getBytes; + case Text: + return PrimitiveReader::getText; + case Json: + return PrimitiveReader::getJson; + case JsonDocument: + return PrimitiveReader::getJsonDocument; + case Yson: + return PrimitiveReader::getYson; + case Uuid: + return PrimitiveReader::getUuid; + case Bool: + return PrimitiveReader::getBool; + case Int8: + return PrimitiveReader::getInt8; + case Uint8: + return PrimitiveReader::getUint8; + case Int16: + return PrimitiveReader::getInt16; + case Uint16: + return PrimitiveReader::getUint16; + case Int32: + return PrimitiveReader::getInt32; + case Uint32: + return PrimitiveReader::getUint32; + case Int64: + return PrimitiveReader::getInt64; + case Uint64: + return PrimitiveReader::getUint64; + case Float: + return PrimitiveReader::getFloat; + case Double: + return PrimitiveReader::getDouble; + case Date: + return PrimitiveReader::getDate; + case Datetime: + return PrimitiveReader::getDatetime; + case Timestamp: + return PrimitiveReader::getTimestamp; + case Interval: + return PrimitiveReader::getInterval; + case TzDate: + return PrimitiveReader::getTzDate; + case TzDatetime: + return PrimitiveReader::getTzDatetime; + case TzTimestamp: + return PrimitiveReader::getTzTimestamp; + default: + // DyNumber + return value -> { + throw dataTypeNotSupported(id, Object.class); + }; + } + } private static SQLException cannotConvert(PrimitiveType type, Class javaType, Object value) { return new SQLException(String.format(UNABLE_TO_CONVERT, type, value, javaType)); @@ -789,27 +682,102 @@ private static SQLException dataTypeNotSupported(PrimitiveType type, Class ja return new SQLException(String.format(UNABLE_TO_CAST, type, javaType)); } - private static SQLException dataTypeNotSupported(Type.Kind kind, Class javaType) { - return new SQLException(String.format(UNABLE_TO_CAST, kind, javaType)); + private static ValueToBoolean castToBooleanNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, boolean.class)); + }; } - public static class Getters { - public final ValueToString toString; - public final ValueToBoolean toBoolean; - public final ValueToByte toByte; - public final ValueToShort toShort; - public final ValueToInt toInt; - public final ValueToLong toLong; - public final ValueToFloat toFloat; - public final ValueToDouble toDouble; - public final ValueToBytes toBytes; - public final ValueToObject toObject; - public final ValueToDateMillis toDateMillis; - public final ValueToNString toNString; - public final ValueToURL toURL; - public final ValueToBigDecimal toBigDecimal; - public final ValueToReader toReader; + private static ValueToByte castToByteNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, byte.class)); + }; + } + + private static ValueToShort castToShortNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, short.class)); + }; + } + + private static ValueToInt castToIntNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, int.class)); + }; + } + + private static ValueToLong castToLongNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, long.class)); + }; + } + private static ValueToFloat castToFloatNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, float.class)); + }; + } + + private static ValueToDouble castToDoubleNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, double.class)); + }; + } + + private static ValueToBytes castToBytesNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, byte[].class)); + }; + } + + private static ValueToDateMillis castToDateMillisNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, long.class)); + }; + } + + private static ValueToNString castToNStringNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, String.class)); + }; + } + + private static ValueToURL castToUrlNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, URL.class)); + }; + } + + private static ValueToBigDecimal castToBigDecimalNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, BigDecimal.class)); + }; + } + + private static ValueToReader castToReaderNotSupported(String type) { + return value -> { + throw new SQLException(String.format(UNABLE_TO_CAST, type, Reader.class)); + }; + } + + public static class Getters { + private final ValueToString toString; + private final ValueToBoolean toBoolean; + private final ValueToByte toByte; + private final ValueToShort toShort; + private final ValueToInt toInt; + private final ValueToLong toLong; + private final ValueToFloat toFloat; + private final ValueToDouble toDouble; + private final ValueToBytes toBytes; + private final ValueToObject toObject; + private final ValueToDateMillis toDateMillis; + private final ValueToNString toNString; + private final ValueToURL toURL; + private final ValueToBigDecimal toBigDecimal; + private final ValueToReader toReader; + + @SuppressWarnings("ParameterNumber") Getters(ValueToString toString, ValueToBoolean toBoolean, ValueToByte toByte, @@ -841,65 +809,125 @@ public static class Getters { this.toBigDecimal = toBigDecimal; this.toReader = toReader; } + + public String readString(ValueReader reader) throws SQLException { + return toString.fromValue(reader); + } + + public boolean readBoolean(ValueReader reader) throws SQLException { + return toBoolean.fromValue(reader); + } + + public byte readByte(ValueReader reader) throws SQLException { + return toByte.fromValue(reader); + } + + public short readShort(ValueReader reader) throws SQLException { + return toShort.fromValue(reader); + } + + public int readInt(ValueReader reader) throws SQLException { + return toInt.fromValue(reader); + } + + public long readLong(ValueReader reader) throws SQLException { + return toLong.fromValue(reader); + } + + public float readFloat(ValueReader reader) throws SQLException { + return toFloat.fromValue(reader); + } + + public double readDouble(ValueReader reader) throws SQLException { + return toDouble.fromValue(reader); + } + + public byte[] readBytes(ValueReader reader) throws SQLException { + return toBytes.fromValue(reader); + } + + public Object readObject(ValueReader reader) throws SQLException { + return toObject.fromValue(reader); + } + + public long readDateMillis(ValueReader reader) throws SQLException { + return toDateMillis.fromValue(reader); + } + + public String readNString(ValueReader reader) throws SQLException { + return toNString.fromValue(reader); + } + + public String readURL(ValueReader reader) throws SQLException { + return toURL.fromValue(reader); + } + + public BigDecimal readBigDecimal(ValueReader reader) throws SQLException { + return toBigDecimal.fromValue(reader); + } + + public Reader readReader(ValueReader reader) throws SQLException { + return toReader.fromValue(reader); + } } - public interface ValueToString { + private interface ValueToString { String fromValue(ValueReader reader) throws SQLException; } - public interface ValueToBoolean { + private interface ValueToBoolean { boolean fromValue(ValueReader reader) throws SQLException; } - public interface ValueToByte { + private interface ValueToByte { byte fromValue(ValueReader reader) throws SQLException; } - public interface ValueToShort { + private interface ValueToShort { short fromValue(ValueReader reader) throws SQLException; } - public interface ValueToInt { + private interface ValueToInt { int fromValue(ValueReader reader) throws SQLException; } - public interface ValueToLong { + private interface ValueToLong { long fromValue(ValueReader reader) throws SQLException; } - public interface ValueToFloat { + private interface ValueToFloat { float fromValue(ValueReader reader) throws SQLException; } - public interface ValueToDouble { + private interface ValueToDouble { double fromValue(ValueReader reader) throws SQLException; } - public interface ValueToBytes { + private interface ValueToBytes { byte[] fromValue(ValueReader reader) throws SQLException; } - public interface ValueToObject { + private interface ValueToObject { Object fromValue(ValueReader reader) throws SQLException; } - public interface ValueToDateMillis { + private interface ValueToDateMillis { long fromValue(ValueReader reader) throws SQLException; } - public interface ValueToNString { + private interface ValueToNString { String fromValue(ValueReader reader) throws SQLException; } - public interface ValueToURL { + private interface ValueToURL { String fromValue(ValueReader reader) throws SQLException; } - public interface ValueToBigDecimal { + private interface ValueToBigDecimal { BigDecimal fromValue(ValueReader reader) throws SQLException; } - public interface ValueToReader { + private interface ValueToReader { Reader fromValue(ValueReader reader) throws SQLException; } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/common/MappingSetters.java b/jdbc/src/main/java/tech/ydb/jdbc/common/MappingSetters.java index 3a3b152..090f223 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/common/MappingSetters.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/common/MappingSetters.java @@ -37,6 +37,7 @@ import static tech.ydb.jdbc.YdbConst.UNABLE_TO_CAST; public class MappingSetters { + private MappingSetters() { } static Setters buildSetters(Type type) { return buildToValueImpl(type); diff --git a/jdbc/src/main/java/tech/ydb/jdbc/common/TypeDescription.java b/jdbc/src/main/java/tech/ydb/jdbc/common/TypeDescription.java index 5a2f050..15abd19 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/common/TypeDescription.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/common/TypeDescription.java @@ -11,6 +11,15 @@ import tech.ydb.table.values.Type; public class TypeDescription { + private static final Map TYPES = new ConcurrentHashMap<>(); + + static { + ofInternal(DecimalType.of(DecimalType.MAX_PRECISION)); // max + ofInternal(DecimalType.of(22, 9)); // default for database + for (PrimitiveType type : PrimitiveType.values()) { + ofInternal(type); // All primitive values + } + } private final Type type; private final boolean optional; @@ -58,16 +67,6 @@ public Type ydbType() { return type; } - private static final Map TYPES = new ConcurrentHashMap<>(); - - static { - ofInternal(DecimalType.of(DecimalType.MAX_PRECISION)); // max - ofInternal(DecimalType.of(22, 9)); // default for database - for (PrimitiveType type : PrimitiveType.values()) { - ofInternal(type); // All primitive values - } - } - private static void ofInternal(Type type) { of(type); of(type.makeOptional()); // Register both normal and optional types diff --git a/jdbc/src/main/java/tech/ydb/jdbc/common/YdbFunctions.java b/jdbc/src/main/java/tech/ydb/jdbc/common/YdbFunctions.java index de7be2d..ebfe99c 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/common/YdbFunctions.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/common/YdbFunctions.java @@ -8,6 +8,34 @@ import java.util.stream.Stream; public final class YdbFunctions { + public static final String STRING_FUNCTIONS = Stream.of( + Udf.Hyperscans.functions(), + Udf.Pires.functions(), + Udf.Re2s.functions(), + Udf.Strings.functions(), + Udf.Unicodes.functions(), + Udf.Urls.functions(), + Udf.Ips.functions(), + Udf.Digests.functions(), + Udf.Ysons.functions(), + Builtin.Strings.functions() + ).flatMap(Collection::stream).collect(Collectors.joining(",")); + + public static final String NUMERIC_FUNCTIONS = Stream.of( + Udf.Maths.functions(), + Builtin.Numerics.functions() + ).flatMap(Collection::stream).collect(Collectors.joining(",")); + + public static final String SYSTEM_FUNCTIONS = Stream.of( + Builtin.Systems.functions() + ).flatMap(Collection::stream).collect(Collectors.joining(",")); + + public static final String DATETIME_FUNCTIONS = Stream.of( + Udf.DateTimes.functions(), + Builtin.Dates.functions() + ).flatMap(Collection::stream).collect(Collectors.joining(",")); + + private YdbFunctions() { } public static final class Builtin { public static final class Strings { @@ -311,9 +339,6 @@ public static List functions() { } } - private Builtin() { - } - private static final List ALL_FUNCTIONS = Collections.unmodifiableList(Stream.of( Strings.functions(), Systems.functions(), @@ -322,6 +347,8 @@ private Builtin() { .flatMap(Collection::stream) .collect(Collectors.toList())); + private Builtin() { } + public static List allFunctions() { return ALL_FUNCTIONS; } @@ -341,8 +368,7 @@ public static final class Hyperscans { Arrays.asList(GREP, MATCH, BACKTRACKING_GREP, BACKTRACKING_MATCH, MULTI_GREP, MULTI_MATCH, CAPTURE, REPLACE)); - private Hyperscans() { - } + private Hyperscans() { } public static List functions() { return FUNCTIONS; @@ -359,8 +385,7 @@ public static final class Pires { private static final List FUNCTIONS = Collections.unmodifiableList( Arrays.asList(GREP, MATCH, MULTI_GREP, MULTI_MATCH, CAPTURE, REPLACE)); - private Pires() { - } + private Pires() { } public static List functions() { return FUNCTIONS; @@ -378,8 +403,7 @@ public static final class Re2s { private static final List FUNCTIONS = Collections.unmodifiableList( Arrays.asList(GREP, MATCH, CAPTURE, FIND_AND_CONSUME, REPLACE, COUNT, OPTIONS)); - private Re2s() { - } + private Re2s() { } public static List functions() { return FUNCTIONS; @@ -458,8 +482,7 @@ public static final class Strings { LEVENSTEIN_DISTANCE, LEFT_PAD, RIGHT_PAD, HEX, S_HEX, BIN, S_BIN, HEX_TEXT, BIN_TEXT, HUMAN_READABLE_DURATION, HUMAN_READABLE_QUANTITY, HUMAN_READABLE_BYTES, PREC, REVERSE)); - private Strings() { - } + private Strings() { } public static List functions() { return FUNCTIONS; @@ -499,8 +522,7 @@ public static final class Unicodes { FROM_CODE_POINT_LIST, REVERSE, TO_LOWER, TO_UPPER, TO_TITLE, SPLIT_TO_LIST, JOIN_FROM_LIST)); - private Unicodes() { - } + private Unicodes() { } public static List functions() { return FUNCTIONS; @@ -564,19 +586,18 @@ public static final class DateTimes { public static final String PARSE_X509 = "DateTime::ParseX509"; private static final List FUNCTIONS = Collections.unmodifiableList( Arrays.asList(SPLIT, MAKE_DATE, MAKE_DATETIME, MAKE_TIMESTAMP, MAKE_TZ_DATE, MAKE_TZ_DATETIME, - MAKE_TZ_TIMESTAMP, GET_YEAR, GET_DAY_OF_YEAR, GET_MONTH, GET_MONTH_NAME, GET_WEEK_OF_YEAR - , GET_DAY_OF_MONTH, GET_DAY_OF_WEEK, GET_DAY_OF_WEEK_NAME, GET_HOUR, GET_MINUTE, + MAKE_TZ_TIMESTAMP, GET_YEAR, GET_DAY_OF_YEAR, GET_MONTH, GET_MONTH_NAME, GET_WEEK_OF_YEAR, + GET_DAY_OF_MONTH, GET_DAY_OF_WEEK, GET_DAY_OF_WEEK_NAME, GET_HOUR, GET_MINUTE, GET_SECOND, GET_MILLISECOND_OF_SECOND, GET_MICROSECOND_OF_SECOND, GET_TIMEZONE_ID, - GET_TIMEZONE_NAME, UPDATE, FROM_SECONDS, FROM_MILLISECONDS, FROM_MICROSECONDS, TO_SECONDS - , TO_MILLISECONDS, TO_MICROSECONDS, TO_DAYS, TO_HOURS, TO_MINUTES, INTERVAL_FROM_DAYS, + GET_TIMEZONE_NAME, UPDATE, FROM_SECONDS, FROM_MILLISECONDS, FROM_MICROSECONDS, TO_SECONDS, + TO_MILLISECONDS, TO_MICROSECONDS, TO_DAYS, TO_HOURS, TO_MINUTES, INTERVAL_FROM_DAYS, INTERVAL_FROM_HOURS, INTERVAL_FROM_MINUTES, INTERVAL_FROM_SECONDS, INTERVAL_FROM_MILLISECONDS, INTERVAL_FROM_MICROSECONDS, START_OF_YEAR, START_OF_QUARTER, START_OF_MONTH, START_OF_WEEK, START_OF_DAY, START_OF, TIME_OF_DAY, SHIFT_YEARS, SHIFT_QUARTERS, SHIFT_MONTHS, FORMAT, PARSE, PARSE_RFC822, PARSE_ISO8601, PARSE_HTTP, PARSE_X509)); - private DateTimes() { - } + private DateTimes() { } public static List functions() { return FUNCTIONS; @@ -625,8 +646,7 @@ public static final class Urls { FORCE_HOST_NAME_TO_PUNYCODE, PUNYCODE_TO_HOST_NAME, FORCE_PUNYCODE_TO_HOST_NAME, CAN_BE_PUNYCODE_HOST_NAME, IS_ALLOWED_BY_ROBOTS_TXT)); - private Urls() { - } + private Urls() { } public static List functions() { return FUNCTIONS; @@ -645,8 +665,7 @@ public static final class Ips { Arrays.asList(FROM_STRING, TO_STRING, IS_IPV4, IS_IPV6, IS_EMBEDDED_IPV4, CONVERT_TO_IPV6, GET_SUBNET)); - private Ips() { - } + private Ips() { } public static List functions() { return FUNCTIONS; @@ -724,8 +743,7 @@ public static final class Ysons { Y_PATH_STRING, Y_PATH_DICT, Y_PATH_LIST, ATTRIBUTES, SERIALIZE, SERIALIZE_TEXT, SERIALIZE_PRETTY, SERIALIZE_JSON, OPTIONS)); - private Ysons() { - } + private Ysons() { } public static List functions() { return FUNCTIONS; @@ -763,8 +781,7 @@ public static final class Digests { FARM_HASH_FINGERPRINT32, FARM_HASH_FINGERPRINT64, FARM_HASH_FINGERPRINT128, SUPER_FAST_HASH, SHA1, SHA256, INT_HASH64, XXH3, XXH3_128)); - private Digests() { - } + private Digests() { } public static List functions() { return FUNCTIONS; @@ -818,8 +835,7 @@ public static final class Maths { TGAMMA, TRUNC, LOG, LOG2, LOG10, ATAN2, FMOD, HYPOT, POW, REMAINDER, FUZZY_EQUALS, MOD, REM)); - private Maths() { - } + private Maths() { } public static List functions() { return FUNCTIONS; @@ -843,17 +859,13 @@ public static final class Histograms { GET_SUM_BELOW_BOUND, GET_SUM_IN_RANGE, CALC_UPPER_BOUND, CALC_LOWER_BOUND, CALC_UPPER_BOUND_SAFE, CALC_LOWER_BOUND_SAFE)); - private Histograms() { - } + private Histograms() { } public static List functions() { return FUNCTIONS; } } - private Udf() { - } - private static final List ALL_FUNCTIONS = Collections.unmodifiableList(Stream.of( Hyperscans.functions(), Pires.functions(), @@ -870,35 +882,10 @@ private Udf() { .flatMap(Collection::stream) .collect(Collectors.toList())); + private Udf() { } + public static List allFunctions() { return ALL_FUNCTIONS; } } - - public static final String STRING_FUNCTIONS = Stream.of( - Udf.Hyperscans.functions(), - Udf.Pires.functions(), - Udf.Re2s.functions(), - Udf.Strings.functions(), - Udf.Unicodes.functions(), - Udf.Urls.functions(), - Udf.Ips.functions(), - Udf.Digests.functions(), - Udf.Ysons.functions(), - Builtin.Strings.functions() - ).flatMap(Collection::stream).collect(Collectors.joining(",")); - - public static final String NUMERIC_FUNCTIONS = Stream.of( - Udf.Maths.functions(), - Builtin.Numerics.functions() - ).flatMap(Collection::stream).collect(Collectors.joining(",")); - - public static final String SYSTEM_FUNCTIONS = Stream.of( - Builtin.Systems.functions() - ).flatMap(Collection::stream).collect(Collectors.joining(",")); - - public static final String DATETIME_FUNCTIONS = Stream.of( - Udf.DateTimes.functions(), - Builtin.Dates.functions() - ).flatMap(Collection::stream).collect(Collectors.joining(",")); } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbContext.java b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbContext.java index 3b28f16..de65531 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbContext.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbContext.java @@ -179,9 +179,10 @@ public static YdbContext createContext(YdbConfig config) throws SQLException { GrpcTransportBuilder builder = GrpcTransport.forConnectionString(config.getConnectionString()); connProps.applyToGrpcTransport(builder); - // Use custom single thread scheduler because JDBC driver doesn't need to execute retries except for DISCOERY + // Use custom single thread scheduler + // because JDBC driver doesn't need to execute retries except for DISCOVERY builder.withSchedulerFactory(() -> { - final String namePrefix = "ydb-jdbc-scheduler[" + config.hashCode() +"]-thread-"; + final String namePrefix = "ydb-jdbc-scheduler[" + config.hashCode() + "]-thread-"; final AtomicInteger threadNumber = new AtomicInteger(1); return Executors.newScheduledThreadPool(1, (Runnable r) -> { Thread t = new Thread(r, namePrefix + threadNumber.getAndIncrement()); diff --git a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java index 3d27988..5df41ca 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java @@ -73,7 +73,7 @@ public void execute(String msg, Supplier> runnableSupp simpleExecute(msg, runnableSupplier); logger.log(Level.FINEST, "[{0}] OK ", sw.stop()); } catch (SQLException | RuntimeException ex) { - logger.log(Level.FINE, "[{0}] {1} ", new Object[] { sw.stop(), ex.getMessage() }); + logger.log(Level.FINE, "[{0}] {1} ", new Object[] {sw.stop(), ex.getMessage()}); throw ex; } } @@ -91,7 +91,7 @@ public T call(String msg, Supplier>> callSupplie logger.log(Level.FINEST, "[{0}] OK ", sw.stop()); return value; } catch (SQLException | RuntimeException ex) { - logger.log(Level.FINE, "[{0}] {1} ", new Object[] { sw.stop(), ex.getMessage() }); + logger.log(Level.FINE, "[{0}] {1} ", new Object[] {sw.stop(), ex.getMessage()}); throw ex; } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java index aa8a05c..ced7fa7 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java @@ -10,6 +10,8 @@ * @author Aleksandr Gorshenin */ public class ExceptionFactory { + private ExceptionFactory() { } + static String getSQLState(StatusCode status) { // TODO: Add SQLSTATE message with order with https://en.wikipedia.org/wiki/SQLSTATE return null; diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java index f8a310f..4a760d9 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java @@ -38,7 +38,7 @@ public abstract class BaseYdbStatement implements YdbStatement { // TODO: YDB doesn't return the count of affected rows, so we use little hach to return always 1 private static final YdbResult HAS_UPDATED = new YdbResult(1); - private static FixedResultSetFactory EXPLAIN_RS_FACTORY = FixedResultSetFactory.newBuilder() + private static final FixedResultSetFactory EXPLAIN_RS_FACTORY = FixedResultSetFactory.newBuilder() .addTextColumn(YdbConst.EXPLAIN_COLUMN_AST) .addTextColumn(YdbConst.EXPLAIN_COLUMN_PLAN) .build(); diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/MetaDataTables.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/MetaDataTables.java index b706022..24496c4 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/MetaDataTables.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/MetaDataTables.java @@ -12,7 +12,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getProcedures(java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory PROCEDURES = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory PROCEDURES = FixedResultSetFactory.newBuilder() .addTextColumn("PROCEDURE_CAT") .addTextColumn("PROCEDURE_SCHEM") .addTextColumn("PROCEDURE_NAME") @@ -27,7 +27,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getProcedureColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory PROCEDURE_COLUMNS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory PROCEDURE_COLUMNS = FixedResultSetFactory.newBuilder() .addTextColumn("PROCEDURE_CAT") .addTextColumn("PROCEDURE_SCHEM") .addTextColumn("PROCEDURE_NAME") @@ -53,7 +53,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getTables(java.lang.String, java.lang.String, java.lang.String, java.lang.String[]) */ - public final static FixedResultSetFactory TABLES = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory TABLES = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_CAT") .addTextColumn("TABLE_SCHEM") .addTextColumn("TABLE_NAME") @@ -69,21 +69,21 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getCatalogs() */ - public final static FixedResultSetFactory CATALOGS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory CATALOGS = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_CAT") .build(); /** * @see DatabaseMetaData#getTableTypes() */ - public final static FixedResultSetFactory TABLE_TYPES = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory TABLE_TYPES = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_TYPE") .build(); /** * @see DatabaseMetaData#getColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory COLUMNS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory COLUMNS = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_CAT") .addTextColumn("TABLE_SCHEM") .addTextColumn("TABLE_NAME") @@ -113,7 +113,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getColumnPrivileges(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory COLUMN_PRIVILEGES = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory COLUMN_PRIVILEGES = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_CAT") .addTextColumn("TABLE_SCHEM") .addTextColumn("TABLE_NAME") @@ -127,7 +127,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getTablePrivileges(java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory TABLE_PRIVILEGES = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory TABLE_PRIVILEGES = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_CAT") .addTextColumn("TABLE_SCHEM") .addTextColumn("TABLE_NAME") @@ -140,7 +140,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getBestRowIdentifier(java.lang.String, java.lang.String, java.lang.String, int, boolean) */ - public final static FixedResultSetFactory BEST_ROW_IDENTIFIERS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory BEST_ROW_IDENTIFIERS = FixedResultSetFactory.newBuilder() .addShortColumn("SCOPE") .addTextColumn("COLUMN_NAME") .addIntColumn("DATA_TYPE") @@ -154,7 +154,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getVersionColumns(java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory VERSION_COLUMNS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory VERSION_COLUMNS = FixedResultSetFactory.newBuilder() .addShortColumn("SCOPE") .addTextColumn("COLUMN_NAME") .addIntColumn("DATA_TYPE") @@ -168,7 +168,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getPrimaryKeys(java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory PRIMARY_KEYS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory PRIMARY_KEYS = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_CAT") .addTextColumn("TABLE_SCHEM") .addTextColumn("TABLE_NAME") @@ -180,7 +180,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getImportedKeys(java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory IMPORTED_KEYS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory IMPORTED_KEYS = FixedResultSetFactory.newBuilder() .addTextColumn("PKTABLE_CAT") .addTextColumn("PKTABLE_SCHEM") .addTextColumn("PKTABLE_NAME") @@ -200,7 +200,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getExportedKeys(java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory EXPORTED_KEYS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory EXPORTED_KEYS = FixedResultSetFactory.newBuilder() .addTextColumn("PKTABLE_CAT") .addTextColumn("PKTABLE_SCHEM") .addTextColumn("PKTABLE_NAME") @@ -221,7 +221,7 @@ public class MetaDataTables { * @see DatabaseMetaData#getCrossReference(java.lang.String, java.lang.String, java.lang.String, java.lang.String, * java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory CROSS_REFERENCES = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory CROSS_REFERENCES = FixedResultSetFactory.newBuilder() .addTextColumn("PKTABLE_CAT") .addTextColumn("PKTABLE_SCHEM") .addTextColumn("PKTABLE_NAME") @@ -241,7 +241,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getTypeInfo() */ - public final static FixedResultSetFactory TYPE_INFOS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory TYPE_INFOS = FixedResultSetFactory.newBuilder() .addTextColumn("TYPE_NAME") .addIntColumn("DATA_TYPE") .addIntColumn("PRECISION") @@ -265,7 +265,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getIndexInfo(java.lang.String, java.lang.String, java.lang.String, boolean, boolean) */ - public final static FixedResultSetFactory INDEX_INFOS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory INDEX_INFOS = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_CAT") .addTextColumn("TABLE_SCHEM") .addTextColumn("TABLE_NAME") @@ -284,7 +284,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getUDTs(java.lang.String, java.lang.String, java.lang.String, int[]) */ - public final static FixedResultSetFactory UDTS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory UDTS = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_CAT") .addTextColumn("TABLE_SCHEM") .addTextColumn("TABLE_NAME") @@ -297,7 +297,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getSuperTypes(java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory SUPER_TYPES = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory SUPER_TYPES = FixedResultSetFactory.newBuilder() .addTextColumn("TYPE_CAT") .addTextColumn("TYPE_SCHEM") .addTextColumn("TYPE_NAME") @@ -309,7 +309,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getSuperTables(java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory SUPER_TABLES = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory SUPER_TABLES = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_CAT") .addTextColumn("TABLE_SCHEM") .addTextColumn("TABLE_NAME") @@ -319,7 +319,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getAttributes(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory ATTRIBUTES = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory ATTRIBUTES = FixedResultSetFactory.newBuilder() .addTextColumn("TYPE_CAT") .addTextColumn("TYPE_SCHEM") .addTextColumn("TYPE_NAME") @@ -346,7 +346,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getSchemas(java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory SCHEMAS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory SCHEMAS = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_SCHEM") .addTextColumn("TABLE_CATALOG") .build(); @@ -354,7 +354,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getClientInfoProperties() */ - public final static FixedResultSetFactory CLIENT_INFO_PROPERTIES = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory CLIENT_INFO_PROPERTIES = FixedResultSetFactory.newBuilder() .addTextColumn("NAME") .addIntColumn("MAX_LEN") .addTextColumn("DEFAULT_VALUE") @@ -364,7 +364,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getFunctions(java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory FUNCTIONS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory FUNCTIONS = FixedResultSetFactory.newBuilder() .addTextColumn("FUNCTION_CAT") .addTextColumn("FUNCTION_SCHEM") .addTextColumn("FUNCTION_NAME") @@ -376,7 +376,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getFunctionColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory FUNCTION_COLUMNS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory FUNCTION_COLUMNS = FixedResultSetFactory.newBuilder() .addTextColumn("FUNCTION_CAT") .addTextColumn("FUNCTION_SCHEM") .addTextColumn("FUNCTION_NAME") @@ -399,7 +399,7 @@ public class MetaDataTables { /** * @see DatabaseMetaData#getPseudoColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ - public final static FixedResultSetFactory PSEUDO_COLUMNS = FixedResultSetFactory.newBuilder() + public static final FixedResultSetFactory PSEUDO_COLUMNS = FixedResultSetFactory.newBuilder() .addTextColumn("TABLE_CAT") .addTextColumn("TABLE_SCHEM") .addTextColumn("TABLE_NAME") @@ -413,4 +413,6 @@ public class MetaDataTables { .addIntColumn("CHAR_OCTET_LENGTH") .addTextColumn("IS_NULLABLE") .build(); + + private MetaDataTables() { } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java index 0bcefff..64dea63 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java @@ -21,12 +21,9 @@ import java.util.Properties; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; -import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; -import com.google.common.base.Suppliers; - import tech.ydb.jdbc.YdbConnection; import tech.ydb.jdbc.YdbConst; import tech.ydb.jdbc.YdbDatabaseMetaData; @@ -61,15 +58,14 @@ public class YdbConnectionImpl implements YdbConnection { private final YdbContext ctx; private final YdbExecutor executor; - private final Supplier metaDataSupplier; private final FakeTxMode scanQueryTxMode; private final FakeTxMode schemeQueryTxMode; + private final YdbDatabaseMetaData metaData = new YdbDatabaseMetaDataImpl(this); private volatile YdbTxState state; public YdbConnectionImpl(YdbContext context) throws SQLException { this.ctx = context; - this.metaDataSupplier = Suppliers.memoize(() -> new YdbDatabaseMetaDataImpl(this))::get; this.executor = new YdbExecutor(LOGGER); YdbOperationProperties props = ctx.getOperationProperties(); @@ -106,7 +102,7 @@ private void updateState(YdbTxState newState) { return; } - LOGGER.log(Level.FINE, "update tx state: {0} -> {1}", new Object[] { state, newState }); + LOGGER.log(Level.FINE, "update tx state: {0} -> {1}", new Object[] {state, newState}); this.state = newState; } @@ -193,7 +189,7 @@ public boolean isClosed() { @Override public YdbDatabaseMetaData getMetaData() { - return metaDataSupplier.get(); + return metaData; } @Override @@ -342,7 +338,8 @@ public YdbStatement createStatement(int resultSetType, int resultSetConcurrency) } @Override - public YdbPreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + public YdbPreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) + throws SQLException { return prepareStatement(sql, resultSetType, resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT); } @@ -401,7 +398,8 @@ public YdbPreparedStatement prepareStatement(String sql, int autoGeneratedKeys) ResultSet.HOLD_CURSORS_OVER_COMMIT); } - private YdbPreparedStatement prepareStatement(String sql, int resultSetType, YdbPrepareMode mode) throws SQLException { + private YdbPreparedStatement prepareStatement(String sql, int resultSetType, YdbPrepareMode mode) + throws SQLException { ensureOpened(); executor.clearWarnings(); diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java index d445955..9b981ce 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java @@ -50,11 +50,11 @@ public class YdbDatabaseMetaDataImpl implements YdbDatabaseMetaData { static final String TABLE = "TABLE"; static final String SYSTEM_TABLE = "SYSTEM TABLE"; - private final YdbConnectionImpl connection; + private final YdbConnection connection; private final YdbTypes types; private final YdbExecutor executor; - public YdbDatabaseMetaDataImpl(YdbConnectionImpl connection) { + public YdbDatabaseMetaDataImpl(YdbConnection connection) { this.connection = Objects.requireNonNull(connection); this.types = connection.getYdbTypes(); this.executor = new YdbExecutor(LOGGER); @@ -720,7 +720,7 @@ private class TableRecord implements Comparable { private final boolean isSystem; private final String name; - public TableRecord(String name) { + TableRecord(String name) { this.name = name; this.isSystem = name.startsWith(".sys/") || name.startsWith(".sys_health/") @@ -881,14 +881,14 @@ public ResultSet getBestRowIdentifier(String catalog, String schema, String tabl int decimalDigits = type.getKind() == Type.Kind.DECIMAL ? YdbConst.SQL_DECIMAL_DEFAULT_PRECISION : 0; rs.newRow() - .withShortValue("SCOPE", (short)scope) + .withShortValue("SCOPE", (short) scope) .withTextValue("COLUMN_NAME", key) .withIntValue("DATA_TYPE", types.toSqlType(type)) .withTextValue("TYPE_NAME", type.toString()) .withIntValue("COLUMN_SIZE", 0) .withIntValue("BUFFER_LENGTH", 0) .withShortValue("DECIMAL_DIGITS", (short) decimalDigits) - .withShortValue("PSEUDO_COLUMN", (short)bestRowNotPseudo) + .withShortValue("PSEUDO_COLUMN", (short) bestRowNotPseudo) .build(); } @@ -969,14 +969,14 @@ public ResultSet getTypeInfo() { .withIntValue("PRECISION", types.getSqlPrecision(type)) .withTextValue("LITERAL_PREFIX", literal) .withTextValue("LITERAL_SUFFIX", literal) - .withShortValue("NULLABLE", (short)typeNullable) + .withShortValue("NULLABLE", (short) typeNullable) .withBoolValue("CASE_SENSITIVE", true) .withShortValue("SEARCHABLE", getSearchable(type)) .withBoolValue("UNSIGNED_ATTRIBUTE", getUnsigned(type)) .withBoolValue("FIXED_PREC_SCALE", type.getKind() == Type.Kind.DECIMAL) .withBoolValue("AUTO_INCREMENT", false) // no auto-increments - .withShortValue("MINIMUM_SCALE", (short)scale) - .withShortValue("MAXIMUM_SCALE", (short)scale) + .withShortValue("MINIMUM_SCALE", (short) scale) + .withShortValue("MAXIMUM_SCALE", (short) scale) .withIntValue("SQL_DATA_TYPE", 0) .withIntValue("SQL_DATETIME_SUB", 0) .withIntValue("NUM_PREC_RADIX", 10) @@ -1029,6 +1029,8 @@ private String getLiteral(Type type) { case JsonDocument: case Yson: return "'"; + default: + return null; } } return null; @@ -1357,7 +1359,8 @@ private TableDescription describeTable(String table) throws SQLException { // ignore scheme errors like path not found if (result.getStatus().getCode() == StatusCode.SCHEME_ERROR) { LOGGER.log(Level.WARNING, "Cannot describe table {0} -> {1}", - new Object[]{ table, result.getStatus() }); + new Object[]{table, result.getStatus()} + ); return Result.success(null); } return result; diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbParameterMetaDataImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbParameterMetaDataImpl.java index 5fd57b2..39ec07d 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbParameterMetaDataImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbParameterMetaDataImpl.java @@ -6,11 +6,9 @@ import java.sql.SQLException; import java.sql.Types; +import tech.ydb.jdbc.YdbConst; import tech.ydb.jdbc.YdbParameterMetaData; import tech.ydb.jdbc.common.TypeDescription; - -import static tech.ydb.jdbc.YdbConst.CANNOT_UNWRAP_TO; - import tech.ydb.jdbc.query.JdbcParams; public class YdbParameterMetaDataImpl implements YdbParameterMetaData { @@ -91,7 +89,7 @@ public T unwrap(Class iface) throws SQLException { if (iface.isAssignableFrom(getClass())) { return iface.cast(this); } - throw new SQLException(CANNOT_UNWRAP_TO + iface); + throw new SQLException(YdbConst.CANNOT_UNWRAP_TO + iface); } @Override diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbPreparedStatementImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbPreparedStatementImpl.java index 806ac0e..3a08960 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbPreparedStatementImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbPreparedStatementImpl.java @@ -33,11 +33,11 @@ import tech.ydb.jdbc.YdbResultSet; import tech.ydb.jdbc.YdbTypes; import tech.ydb.jdbc.common.MappingSetters; +import tech.ydb.jdbc.query.JdbcParams; import tech.ydb.jdbc.query.YdbQuery; import tech.ydb.table.query.Params; import tech.ydb.table.values.Type; import tech.ydb.table.values.VoidType; -import tech.ydb.jdbc.query.JdbcParams; public class YdbPreparedStatementImpl extends BaseYdbStatement implements YdbPreparedStatement { private static final Logger LOGGER = Logger.getLogger(YdbPreparedStatementImpl.class.getName()); diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbResultSetImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbResultSetImpl.java index a8f9cfb..d62e8c9 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbResultSetImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbResultSetImpl.java @@ -76,49 +76,49 @@ public String getString(int columnIndex) throws SQLException { if (state.nullValue) { return null; // getString supports all types, it's safe to check nullability here } - return state.description.getters().toString.fromValue(state.value); + return state.description.getters().readString(state.value); } @Override public boolean getBoolean(int columnIndex) throws SQLException { initValueReader(columnIndex); - return state.description.getters().toBoolean.fromValue(state.value); + return state.description.getters().readBoolean(state.value); } @Override public byte getByte(int columnIndex) throws SQLException { initValueReader(columnIndex); - return state.description.getters().toByte.fromValue(state.value); + return state.description.getters().readByte(state.value); } @Override public short getShort(int columnIndex) throws SQLException { initValueReader(columnIndex); - return state.description.getters().toShort.fromValue(state.value); + return state.description.getters().readShort(state.value); } @Override public int getInt(int columnIndex) throws SQLException { initValueReader(columnIndex); - return state.description.getters().toInt.fromValue(state.value); + return state.description.getters().readInt(state.value); } @Override public long getLong(int columnIndex) throws SQLException { initValueReader(columnIndex); - return state.description.getters().toLong.fromValue(state.value); + return state.description.getters().readLong(state.value); } @Override public float getFloat(int columnIndex) throws SQLException { initValueReader(columnIndex); - return state.description.getters().toFloat.fromValue(state.value); + return state.description.getters().readFloat(state.value); } @Override public double getDouble(int columnIndex) throws SQLException { initValueReader(columnIndex); - return state.description.getters().toDouble.fromValue(state.value); + return state.description.getters().readDouble(state.value); } @Deprecated @@ -135,7 +135,7 @@ public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException @Override public byte[] getBytes(int columnIndex) throws SQLException { initValueReader(columnIndex); - byte[] copy = state.description.getters().toBytes.fromValue(state.value); + byte[] copy = state.description.getters().readBytes(state.value); if (state.nullValue) { // TODO: do not parse empty value when optional and no value present return null; } @@ -271,7 +271,7 @@ public Object getObject(int columnIndex) throws SQLException { if (state.nullValue) { return null; // getObject supports all types, it's safe to check nullability here } - return state.description.getters().toObject.fromValue(state.value); + return state.description.getters().readObject(state.value); } @Override @@ -287,7 +287,7 @@ public int findColumn(String columnLabel) throws SQLException { @Override public Reader getCharacterStream(int columnIndex) throws SQLException { initValueReader(columnIndex); - Reader copy = state.description.getters().toReader.fromValue(state.value); + Reader copy = state.description.getters().readReader(state.value); if (state.nullValue) { return null; } @@ -302,7 +302,7 @@ public Reader getCharacterStream(String columnLabel) throws SQLException { @Override public BigDecimal getBigDecimal(int columnIndex) throws SQLException { initValueReader(columnIndex); - BigDecimal copy = state.description.getters().toBigDecimal.fromValue(state.value); + BigDecimal copy = state.description.getters().readBigDecimal(state.value); if (state.nullValue) { return null; } @@ -466,7 +466,7 @@ public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLExcept @Override public URL getURL(int columnIndex) throws SQLException { initValueReader(columnIndex); - String copy = state.description.getters().toURL.fromValue(state.value); + String copy = state.description.getters().readURL(state.value); if (state.nullValue) { return null; } @@ -495,7 +495,7 @@ public boolean isClosed() { @Override public String getNString(int columnIndex) throws SQLException { initValueReader(columnIndex); - String copy = state.description.getters().toNString.fromValue(state.value); + String copy = state.description.getters().readNString(state.value); if (state.nullValue) { return null; } @@ -548,7 +548,7 @@ public ResultSetReader getYdbResultSetReader() { private T getDateImpl(int columnIndex, LongFunction fromMillis) throws SQLException { initValueReader(columnIndex); - long longValue = state.description.getters().toDateMillis.fromValue(state.value); + long longValue = state.description.getters().readDateMillis(state.value); if (state.nullValue) { return null; } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java index 4b73728..87818f6 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java @@ -48,8 +48,8 @@ private YdbTypesImpl() { typeByTypeName.put(DEFAULT_DECIMAL_TYPE.toString(), DEFAULT_DECIMAL_TYPE); // Add deprecated type names - typeByTypeName.put("String" , PrimitiveType.Bytes); - typeByTypeName.put("Utf8" , PrimitiveType.Text); + typeByTypeName.put("String", PrimitiveType.Bytes); + typeByTypeName.put("Utf8", PrimitiveType.Text); typeBySqlType = new IntObjectHashMap<>(16); diff --git a/jdbc/src/main/java/tech/ydb/jdbc/query/JdbcQueryLexer.java b/jdbc/src/main/java/tech/ydb/jdbc/query/JdbcQueryLexer.java index 096b775..fa3e46e 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/query/JdbcQueryLexer.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/query/JdbcQueryLexer.java @@ -1,16 +1,18 @@ package tech.ydb.jdbc.query; -import tech.ydb.jdbc.settings.YdbQueryProperties; - import java.sql.SQLException; +import tech.ydb.jdbc.settings.YdbQueryProperties; + /** * * @author Aleksandr Gorshenin */ public class JdbcQueryLexer { + private JdbcQueryLexer() { } + /** * Parses JDBC query to replace all ? to YQL parameters. * @@ -144,6 +146,7 @@ private static int parseSingleQuotes(final char[] query, int offset) { return query.length; } + @SuppressWarnings("EmptyBlock") private static int parseDoubleQuotes(final char[] query, int offset) { while (++offset < query.length && query[offset] != '"') { // do nothing diff --git a/jdbc/src/main/java/tech/ydb/jdbc/query/YdbExpression.java b/jdbc/src/main/java/tech/ydb/jdbc/query/YdbExpression.java index 96c54ea..4b3e270 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/query/YdbExpression.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/query/YdbExpression.java @@ -5,9 +5,9 @@ * @author Aleksandr Gorshenin */ public class YdbExpression { - static YdbExpression SELECT = new YdbExpression(false, true); - static YdbExpression DDL = new YdbExpression(true, false); - static YdbExpression OTHER_DML = new YdbExpression(false, false); + static final YdbExpression SELECT = new YdbExpression(false, true); + static final YdbExpression DDL = new YdbExpression(true, false); + static final YdbExpression OTHER_DML = new YdbExpression(false, false); private final boolean isDDL; // CREATE, DROP and ALTER private final boolean isSelect; diff --git a/jdbc/src/main/java/tech/ydb/jdbc/query/params/BatchedParams.java b/jdbc/src/main/java/tech/ydb/jdbc/query/params/BatchedParams.java index 2338697..2432ee4 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/query/params/BatchedParams.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/query/params/BatchedParams.java @@ -15,6 +15,7 @@ import tech.ydb.jdbc.YdbConst; import tech.ydb.jdbc.common.TypeDescription; +import tech.ydb.jdbc.query.JdbcParams; import tech.ydb.table.query.Params; import tech.ydb.table.values.ListType; import tech.ydb.table.values.ListValue; @@ -22,7 +23,6 @@ import tech.ydb.table.values.StructValue; import tech.ydb.table.values.Type; import tech.ydb.table.values.Value; -import tech.ydb.jdbc.query.JdbcParams; /** * @@ -199,7 +199,7 @@ public static BatchedParams tryCreateBatched(Map types) { return null; } - StructType itemType = (StructType)innerType; + StructType itemType = (StructType) innerType; return new BatchedParams(listName, itemType); } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/query/params/InMemoryParams.java b/jdbc/src/main/java/tech/ydb/jdbc/query/params/InMemoryParams.java index d8babfa..2793082 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/query/params/InMemoryParams.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/query/params/InMemoryParams.java @@ -10,10 +10,10 @@ import tech.ydb.jdbc.YdbConst; import tech.ydb.jdbc.common.TypeDescription; +import tech.ydb.jdbc.query.JdbcParams; import tech.ydb.table.query.Params; import tech.ydb.table.values.Type; import tech.ydb.table.values.Value; -import tech.ydb.jdbc.query.JdbcParams; /** @@ -97,7 +97,7 @@ public void setParam(int index, Object obj, Type type) throws SQLException { @Override public void setParam(String name, Object obj, Type type) throws SQLException { if (obj instanceof Value) { - paramValues.put(name, (Value)obj); + paramValues.put(name, (Value) obj); return; } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/query/params/PreparedParams.java b/jdbc/src/main/java/tech/ydb/jdbc/query/params/PreparedParams.java index 597be96..e5b3c7b 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/query/params/PreparedParams.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/query/params/PreparedParams.java @@ -14,10 +14,10 @@ import tech.ydb.jdbc.YdbConst; import tech.ydb.jdbc.common.TypeDescription; +import tech.ydb.jdbc.query.JdbcParams; import tech.ydb.table.query.Params; import tech.ydb.table.values.Type; import tech.ydb.table.values.Value; -import tech.ydb.jdbc.query.JdbcParams; /** * diff --git a/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbLookup.java b/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbLookup.java index c2496cf..1caf494 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbLookup.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbLookup.java @@ -21,6 +21,8 @@ public class YdbLookup { private static final String HOME_REF = "~"; private static final String FILE_HOME_REF = FILE_REF + HOME_REF; + private YdbLookup() { } + public static String stringFileReference(String ref) { Optional urlOpt = resolvePath(ref); if (urlOpt.isPresent()) { diff --git a/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbOperationProperties.java b/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbOperationProperties.java index 5ba29b0..5c201b5 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbOperationProperties.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbOperationProperties.java @@ -34,13 +34,15 @@ public class YdbOperationProperties { static final YdbProperty SCAN_QUERY_TX_MODE = YdbProperty.enums( "scanQueryTxMode", FakeTxMode.class, - "Mode of execution scan query inside transaction. Possible values - ERROR(by default), FAKE_TX and SHADOW_COMMIT", + "Mode of execution scan query inside transaction. Possible values - " + + "ERROR(by default), FAKE_TX and SHADOW_COMMIT", FakeTxMode.ERROR ); static final YdbProperty SCHEME_QUERY_TX_MODE = YdbProperty.enums("schemeQueryTxMode", FakeTxMode.class, - "Mode of execution scheme query inside transaction. Possible values - ERROR(by default), FAKE_TX and SHADOW_COMMIT", + "Mode of execution scheme query inside transaction. Possible values - " + + "ERROR(by default), FAKE_TX and SHADOW_COMMIT", FakeTxMode.ERROR ); diff --git a/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbProperty.java b/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbProperty.java index e2966d4..8c772e3 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbProperty.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbProperty.java @@ -55,7 +55,7 @@ public YdbValue readValue(Properties props) throws SQLException { T typed = clazz.cast(value); return new YdbValue<>(true, typed.toString(), typed); } else { - throw new SQLException("Invalid object property " + name +", must be " + clazz + + throw new SQLException("Invalid object property " + name + ", must be " + clazz + ", got " + value.getClass()); } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbQueryProperties.java b/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbQueryProperties.java index 791c700..3db2dbf 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbQueryProperties.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbQueryProperties.java @@ -55,7 +55,8 @@ public YdbQueryProperties(YdbConfig config) throws SQLException { this.isDetectQueryType = !disableSqlOperationsDetect; this.isDetectJdbcParameters = !disableSqlOperationsDetect && !disableJdbcParametersParse; - this.isDeclareJdbcParameters = !disableSqlOperationsDetect && !disableJdbcParametersParse && !disableJdbcParametersDeclare; + this.isDeclareJdbcParameters = !disableSqlOperationsDetect && !disableJdbcParametersParse + && !disableJdbcParametersDeclare; this.forcedType = FORCE_QUERY_MODE.readValue(props).getValue(); } diff --git a/jdbc/src/test/java/tech/ydb/jdbc/settings/YdbDriverProperitesTest.java b/jdbc/src/test/java/tech/ydb/jdbc/settings/YdbDriverProperitesTest.java index c542015..8446805 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/settings/YdbDriverProperitesTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/settings/YdbDriverProperitesTest.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.sql.DriverPropertyInfo; @@ -130,12 +131,19 @@ public void getPropertyInfoDefault() throws SQLException { Assertions.assertEquals("grpc://ydb-demo.testhost.org:2135/test/db", config.getConnectionString()); } + private static String urlEncode(String value) { + try { + return URLEncoder.encode(value, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException ex) { + return value; + } + } + @Test public void getPropertyInfoAllFromUrl() throws SQLException { - String url = "jdbc:ydb:ydb-demo.testhost.org:2135/test/db?" + - Stream.of(customizedPropertyInfo()) - .map(e -> e.name + "=" + URLEncoder.encode(e.value, StandardCharsets.UTF_8)) - .collect(Collectors.joining("&")); + Stream params = Stream.of(customizedPropertyInfo()) + .map(e -> e.name + "=" + urlEncode(e.value)); + String url = "jdbc:ydb:ydb-demo.testhost.org:2135/test/db?" + params.collect(Collectors.joining("&")); DriverPropertyInfo[] propertyInfo = driver.getPropertyInfo(url, null); diff --git a/jdbc/src/test/resources/logging.properties b/jdbc/src/test/resources/logging.properties index 5d4c392..e001d08 100644 --- a/jdbc/src/test/resources/logging.properties +++ b/jdbc/src/test/resources/logging.properties @@ -4,4 +4,4 @@ java.util.logging.ConsoleHandler.level = ALL java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter java.util.logging.SimpleFormatter.format= [%1$tF %1$tT] %3$s [%4$s] %5$s %n -tech.ydb.jdbc.level=ALL \ No newline at end of file +tech.ydb.jdbc.level=ALL diff --git a/pom.xml b/pom.xml index 6214849..9973bc2 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.2.3 + 3.2.5 org.apache.maven.plugins @@ -146,7 +146,27 @@ org.apache.maven.plugins maven-shade-plugin - 3.5.1 + 3.5.2 + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.3.1 + + config/ydb.checkstyle.xml + config/ydb.suppressions.xml + true + + + + test + + check + + +