You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lens.apache.org by pr...@apache.org on 2016/10/18 15:00:54 UTC
lens git commit: LENS-897: support for prepared query on lens client
jdbc
Repository: lens
Updated Branches:
refs/heads/master 34f15c6e2 -> 70855ea8c
LENS-897: support for prepared query on lens client jdbc
Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/70855ea8
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/70855ea8
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/70855ea8
Branch: refs/heads/master
Commit: 70855ea8c31fb9aa18deefabf9b2691368fd583d
Parents: 34f15c6
Author: piyush <pi...@gmail.com>
Authored: Tue Oct 18 20:29:36 2016 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Tue Oct 18 20:29:36 2016 +0530
----------------------------------------------------------------------
.../lens/client/jdbc/LensJdbcConnection.java | 2 +-
.../apache/lens/client/jdbc/LensJdbcDriver.java | 2 +-
.../client/jdbc/LensJdbcPreparedStatement.java | 421 +++++++++++++++++++
.../jdbc/LensJdbcPreparedStatementTest.java | 51 +++
4 files changed, 474 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lens/blob/70855ea8/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcConnection.java
----------------------------------------------------------------------
diff --git a/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcConnection.java b/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcConnection.java
index 9ad31ee..a3e7bfb 100644
--- a/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcConnection.java
+++ b/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcConnection.java
@@ -65,7 +65,7 @@ public class LensJdbcConnection implements Connection {
*/
@Override
public PreparedStatement prepareStatement(String s) throws SQLException {
- throw new SQLException("Operation not supported!!!");
+ return new LensJdbcPreparedStatement(this, s);
}
/*
http://git-wip-us.apache.org/repos/asf/lens/blob/70855ea8/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcDriver.java
----------------------------------------------------------------------
diff --git a/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcDriver.java b/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcDriver.java
index 056a0b2..53c7b49 100644
--- a/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcDriver.java
+++ b/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcDriver.java
@@ -50,7 +50,7 @@ public class LensJdbcDriver implements Driver {
*/
@Override
public Connection connect(String s, Properties properties) throws SQLException {
- return null;
+ return new LensJdbcConnection(s, properties);
}
/*
http://git-wip-us.apache.org/repos/asf/lens/blob/70855ea8/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcPreparedStatement.java
----------------------------------------------------------------------
diff --git a/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcPreparedStatement.java b/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcPreparedStatement.java
new file mode 100644
index 0000000..943c59c
--- /dev/null
+++ b/lens-client/src/main/java/org/apache/lens/client/jdbc/LensJdbcPreparedStatement.java
@@ -0,0 +1,421 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.client.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.sql.Date;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+
+public class LensJdbcPreparedStatement extends LensJdbcStatement implements PreparedStatement {
+ private final List<String> sqlTokens;
+ private List<String> parameters;
+ private static final char ESCAPE_CHAR = '\\';
+
+ private static final String NULL = "\"NULL\"";
+
+ private static final ImmutableMap<Character, Character> OPEN_TO_CLOSE_QUOTES =
+ new ImmutableMap.Builder<Character, Character>()
+ .put('\'', '\'')
+ .put('"', '"')
+ .put('`', '`')
+ .build();
+
+ /**
+ * Instantiates a new lens jdbc statement.
+ *
+ * @param connection the connection
+ */
+ public LensJdbcPreparedStatement(LensJdbcConnection connection, String parametrisedSql) {
+ super(connection);
+ this.sqlTokens = tokenize(parametrisedSql);
+ this.parameters = Arrays.asList(new String[sqlTokens.size() - 1]);
+ }
+
+ @Override
+ public ResultSet executeQuery() throws SQLException {
+ final String finalSql = compile();
+ return super.executeQuery(finalSql);
+ }
+
+ @Override
+ public int executeUpdate() throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ parameters.set(parameterIndex - 1, NULL);
+ }
+
+ @Override
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ parameters.set(parameterIndex - 1, String.valueOf(x));
+ }
+
+ @Override
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ parameters.set(parameterIndex - 1, String.valueOf(x));
+ }
+
+ @Override
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ parameters.set(parameterIndex - 1, String.valueOf(x));
+
+ }
+
+ @Override
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ parameters.set(parameterIndex - 1, String.valueOf(x));
+
+ }
+
+ @Override
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ parameters.set(parameterIndex - 1, String.valueOf(x));
+
+ }
+
+ @Override
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ parameters.set(parameterIndex - 1, String.valueOf(x));
+ }
+
+ @Override
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ parameters.set(parameterIndex - 1, String.valueOf(x));
+
+ }
+
+ @Override
+ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+ parameters.set(parameterIndex - 1, String.valueOf(x));
+
+ }
+
+ @Override
+ public void setString(int parameterIndex, String x) throws SQLException {
+ parameters.set(parameterIndex - 1, wrapString(x));
+
+ }
+
+ @Override
+ public void setBytes(int parameterIndex, byte[] x) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+
+ @Override
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ SimpleDateFormat formatter = new SimpleDateFormat("YYYY-MM-dd");
+ parameters.set(parameterIndex - 1, formatter.format(x));
+ }
+
+ @Override
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ SimpleDateFormat formatter = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss.SSS");
+ parameters.set(parameterIndex - 1, formatter.format(x));
+ }
+
+ @Override
+ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+ SimpleDateFormat formatter = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss.SSS");
+ parameters.set(parameterIndex - 1, formatter.format(x));
+ }
+
+ @Override
+ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clearParameters() throws SQLException {
+ parameters = Arrays.asList(new String[sqlTokens.size() - 1]);
+ }
+
+ @Override
+ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean execute() throws SQLException {
+ final String finalSql = compile();
+ return super.execute(finalSql);
+ }
+
+ @Override
+ public void addBatch() throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ResultSetMetaData getMetaData() throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ parameters.set(parameterIndex - 1, NULL);
+ }
+
+ @Override
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setNString(int parameterIndex, String value) throws SQLException {
+ parameters.set(parameterIndex - 1, wrapString(value));
+ }
+
+ @Override
+ public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ @Override
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ throw new UnsupportedOperationException();
+
+ }
+
+
+ // split the sql string by parameter place holder ('?')
+ public static List<String> tokenize(String sql) {
+ Preconditions.checkNotNull(sql);
+
+
+ // if closeQuote is not null we are inside string and have to ignore all ?
+ // and it will have value of closing quotes.
+ Character closeQuote = null;
+
+ //last index till we have processed the string
+ int lastIndex = 0;
+
+ ArrayList tokens = new ArrayList<String>();
+ for (int index = 0; index < sql.length(); index++) {
+
+ char sqlChar = sql.charAt(index);
+ if (ESCAPE_CHAR == sqlChar) {
+ index++;
+ continue;
+ }
+
+
+ if (closeQuote == null && OPEN_TO_CLOSE_QUOTES.containsKey(sqlChar)) {
+ closeQuote = OPEN_TO_CLOSE_QUOTES.get(sqlChar);
+
+ } else if (closeQuote != null) {
+ if (closeQuote.equals(sqlChar)) {
+ closeQuote = null;
+ }
+
+ } else if (sqlChar == '?') {
+ tokens.add(sql.substring(lastIndex, index));
+ lastIndex = index + 1;
+ }
+ }
+ tokens.add(sql.substring(lastIndex, sql.length()));
+
+ return tokens;
+ }
+
+ public String compile() {
+ StringBuffer buf = new StringBuffer();
+ buf.append(sqlTokens.get(0));
+ for (int i = 0; i < parameters.size(); i++) {
+ buf.append(parameters.get(i));
+ buf.append(sqlTokens.get(i + 1));
+ }
+ return buf.toString();
+ }
+
+ private static String wrapString(String x) {
+ return "'" + x + "'";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lens/blob/70855ea8/lens-client/src/test/java/org/apache/lens/jdbc/LensJdbcPreparedStatementTest.java
----------------------------------------------------------------------
diff --git a/lens-client/src/test/java/org/apache/lens/jdbc/LensJdbcPreparedStatementTest.java b/lens-client/src/test/java/org/apache/lens/jdbc/LensJdbcPreparedStatementTest.java
new file mode 100644
index 0000000..310bb7e
--- /dev/null
+++ b/lens-client/src/test/java/org/apache/lens/jdbc/LensJdbcPreparedStatementTest.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.jdbc;
+
+import static org.apache.lens.client.jdbc.LensJdbcPreparedStatement.tokenize;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class LensJdbcPreparedStatementTest {
+
+ @Test
+ public void testTokenize() {
+ List<String> out = tokenize("select * from tab limit ?");
+ Assert.assertArrayEquals(new String[]{"select * from tab limit ", ""}, out.toArray());
+
+ out = tokenize("select * from tab where a = ? and b=c");
+ Assert.assertArrayEquals(new String[]{"select * from tab where a = ", " and b=c"}, out.toArray());
+
+ out = tokenize("select \"? something \" from tab");
+ Assert.assertArrayEquals(new String[]{"select \"? something \" from tab"}, out.toArray());
+
+ out = tokenize("select \'?\' from tab where a=?");
+ Assert.assertArrayEquals(new String[]{"select \'?\' from tab where a=", ""}, out.toArray());
+
+ out = tokenize("select \'indian\\\'s\' from tab where a=b");
+ Assert.assertArrayEquals(new String[]{"select 'indian\\'s' from tab where a=b"}, out.toArray());
+
+
+ }
+
+}