diff --git a/src/main/java/ru/yandex/metrika/clickhouse/CHConnection.java b/src/main/java/ru/yandex/metrika/clickhouse/CHConnection.java index 6fcd399ca6407a8d98895e84dd458c2998f5beb8..a1f78cc58e123255277730dd54bbfe851fb76efe 100644 --- a/src/main/java/ru/yandex/metrika/clickhouse/CHConnection.java +++ b/src/main/java/ru/yandex/metrika/clickhouse/CHConnection.java @@ -4,6 +4,7 @@ import org.apache.http.impl.client.CloseableHttpClient; import ru.yandex.metrika.clickhouse.config.ClickHouseSource; import ru.yandex.metrika.clickhouse.copypaste.HttpConnectionProperties; import ru.yandex.metrika.clickhouse.util.CHHttpClientBuilder; +import ru.yandex.metrika.clickhouse.util.LogProxy; import java.io.IOException; import java.sql.*; @@ -37,7 +38,7 @@ public class CHConnection implements Connection { ClickHouseSource source = new ClickHouseSource(host, portNum, "default"); - return new CHStatement(httpclient, source, properties); + return LogProxy.wrap(Statement.class, new CHStatement(httpclient, source, properties)); } @Override diff --git a/src/main/java/ru/yandex/metrika/clickhouse/CHDatabaseMetadata.java b/src/main/java/ru/yandex/metrika/clickhouse/CHDatabaseMetadata.java index d78c29687afb8e7403bb3b36bb04c90b6b42ea11..7a0eb49a81982dbd98be3d2d5721d0552f6af823 100644 --- a/src/main/java/ru/yandex/metrika/clickhouse/CHDatabaseMetadata.java +++ b/src/main/java/ru/yandex/metrika/clickhouse/CHDatabaseMetadata.java @@ -800,7 +800,8 @@ public class CHDatabaseMetadata implements DatabaseMetaData { row.add(tableNamePattern); row.add(descTable.getString(1)); String type = descTable.getString(2); - row.add(Integer.toString(CHResultSet.toSqlType(type))); + int sqlType = CHResultSet.toSqlType(type); + row.add(Integer.toString(sqlType)); row.add(type); // column size ? @@ -808,7 +809,7 @@ public class CHDatabaseMetadata implements DatabaseMetaData { row.add("0"); // decimal digits - if (type.contains("Int")) { + if (sqlType == Types.INTEGER || sqlType == Types.BIGINT && type.contains("Int")) { String bits = type.substring(type.indexOf("Int") + "Int".length()); row.add(bits); //bullshit } else { diff --git a/src/main/java/ru/yandex/metrika/clickhouse/CHStatement.java b/src/main/java/ru/yandex/metrika/clickhouse/CHStatement.java index 4f8a1cb315f926aa64558fa96852e998d1a5461b..07f5cf6943930dc5bcaf18da7c17fcc1a6c36284 100644 --- a/src/main/java/ru/yandex/metrika/clickhouse/CHStatement.java +++ b/src/main/java/ru/yandex/metrika/clickhouse/CHStatement.java @@ -72,9 +72,19 @@ public class CHStatement implements Statement { return 1; } + @Override + public boolean execute(String sql) throws SQLException { + executeQuery(sql); + return true; + } + + + @Override public void close() throws SQLException { - currentResult.close(); + if (currentResult != null) { + currentResult.close(); + } } @Override @@ -132,14 +142,9 @@ public class CHStatement implements Statement { } - @Override - public boolean execute(String sql) throws SQLException { - return false; - } - @Override public ResultSet getResultSet() throws SQLException { - return null; + return currentResult; } @Override diff --git a/src/main/java/ru/yandex/metrika/clickhouse/copypaste/ByteFragment.java b/src/main/java/ru/yandex/metrika/clickhouse/copypaste/ByteFragment.java index bb911f401eb66207de6c0193cd4b2a46a1c75d49..0736c89cf14bcd20d5826d443f22424cea1e092e 100644 --- a/src/main/java/ru/yandex/metrika/clickhouse/copypaste/ByteFragment.java +++ b/src/main/java/ru/yandex/metrika/clickhouse/copypaste/ByteFragment.java @@ -5,7 +5,6 @@ import ru.yandex.metrika.clickhouse.util.CopypasteUtils; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; -import java.util.Arrays; /** * @author orantius @@ -45,11 +44,20 @@ public class ByteFragment { @Override public String toString() { - return "ByteFragment{" + - "buf=" + Arrays.toString(buf) + - ", start=" + start + + StringBuilder b = new StringBuilder(); + b.append("ByteFragment{["); + for (byte b1 : buf) { + if (b1 == '\t') { + b.append("<TAB>"); + } else { + b.append((char) b1); + } + } + b.append(']'); + b.append(", start=" + start + ", len=" + len + - '}'; + '}'); + return b.toString(); } public ByteFragment[] split(byte sep) { diff --git a/src/main/java/ru/yandex/metrika/clickhouse/copypaste/CHResultSet.java b/src/main/java/ru/yandex/metrika/clickhouse/copypaste/CHResultSet.java index d930212fd98810f8ecb938ada9bc37515fd55b83..888602a8a576a42416e9e78abce9234c81a933c9 100644 --- a/src/main/java/ru/yandex/metrika/clickhouse/copypaste/CHResultSet.java +++ b/src/main/java/ru/yandex/metrika/clickhouse/copypaste/CHResultSet.java @@ -301,17 +301,21 @@ public class CHResultSet extends AbstractResultSet { @Override public Object getObject(int columnIndex) throws SQLException { - int type = toSqlType(types[columnIndex - 1]); - switch (type) { - case Types.BIGINT: return getLong(columnIndex); - case Types.INTEGER: return getInt(columnIndex); - case Types.VARCHAR: return getString(columnIndex); - case Types.FLOAT: return getFloat(columnIndex); - case Types.DATE: return getDate(columnIndex); - case Types.TIMESTAMP: return getTime(columnIndex); - case Types.BLOB: return getString(columnIndex); + try { + int type = toSqlType(types[columnIndex - 1]); + switch (type) { + case Types.BIGINT: return getLong(columnIndex); + case Types.INTEGER: return getInt(columnIndex); + case Types.VARCHAR: return getString(columnIndex); + case Types.FLOAT: return getFloat(columnIndex); + case Types.DATE: return getDate(columnIndex); + case Types.TIMESTAMP: return getTime(columnIndex); + case Types.BLOB: return getString(columnIndex); + } + return getString(columnIndex); + } catch (Exception e) { + throw new RuntimeException("Parse exception: " + values[columnIndex - 1].toString(), e); } - return getString(columnIndex); } ///////////////////////////////////////////////////////// diff --git a/src/main/java/ru/yandex/metrika/clickhouse/util/LogProxy.java b/src/main/java/ru/yandex/metrika/clickhouse/util/LogProxy.java new file mode 100644 index 0000000000000000000000000000000000000000..69cba1c6663b1fc4643f64fc0a9dca395dbd73fd --- /dev/null +++ b/src/main/java/ru/yandex/metrika/clickhouse/util/LogProxy.java @@ -0,0 +1,47 @@ +package ru.yandex.metrika.clickhouse.util; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Arrays; + +/** + * Created by jkee on 21.03.15. + */ +public class LogProxy<T> implements InvocationHandler { + + private static final Logger log = Logger.of(LogProxy.class); + + private final T object; + private final Class<T> clazz; + + public static <T> T wrap(Class<T> interfaceClass, T object) { + LogProxy<T> proxy = new LogProxy<T>(interfaceClass, object); + return proxy.getProxy(); + } + + private LogProxy(Class<T> interfaceClass, T object) { + if (!interfaceClass.isInterface()) { + throw new IllegalStateException("Class " + interfaceClass.getName() + " is not an interface"); + } + clazz = interfaceClass; + this.object = object; + } + + public T getProxy() { + //noinspection unchecked + return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[]{clazz}, this); + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + log.info("Call class: " + clazz.getName() + " Method: " + method.getName() + + " Args: " + Arrays.toString(args)); + try { + return method.invoke(object, args); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + } +}