http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/2691117a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/abstractimpl/AbstractBlurStatement.java ---------------------------------------------------------------------- diff --git a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/abstractimpl/AbstractBlurStatement.java b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/abstractimpl/AbstractBlurStatement.java new file mode 100644 index 0000000..eaf98ac --- /dev/null +++ b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/abstractimpl/AbstractBlurStatement.java @@ -0,0 +1,212 @@ +package org.apache.blur.jdbc.abstractimpl; + +/** + * 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. + */ +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.Statement; + +import org.apache.blur.jdbc.util.NotImplemented; + + +public class AbstractBlurStatement implements Statement { + + private Statement throwExceptionDelegate; + + public AbstractBlurStatement() { + throwExceptionDelegate = (Statement) Proxy.newProxyInstance(Statement.class.getClassLoader(), new Class[] { Statement.class }, new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + throw new NotImplemented(method.getName()); + } + }); + } + + public void addBatch(String sql) throws SQLException { + throwExceptionDelegate.addBatch(sql); + } + + public void cancel() throws SQLException { + throwExceptionDelegate.cancel(); + } + + public void clearBatch() throws SQLException { + throwExceptionDelegate.clearBatch(); + } + + public void clearWarnings() throws SQLException { + throwExceptionDelegate.clearWarnings(); + } + + public void close() throws SQLException { + throwExceptionDelegate.close(); + } + + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + return throwExceptionDelegate.execute(sql, autoGeneratedKeys); + } + + public boolean execute(String sql, int[] columnIndexes) throws SQLException { + return throwExceptionDelegate.execute(sql, columnIndexes); + } + + public boolean execute(String sql, String[] columnNames) throws SQLException { + return throwExceptionDelegate.execute(sql, columnNames); + } + + public boolean execute(String sql) throws SQLException { + return throwExceptionDelegate.execute(sql); + } + + public int[] executeBatch() throws SQLException { + return throwExceptionDelegate.executeBatch(); + } + + public ResultSet executeQuery(String sql) throws SQLException { + return throwExceptionDelegate.executeQuery(sql); + } + + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + return throwExceptionDelegate.executeUpdate(sql, autoGeneratedKeys); + } + + public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { + return throwExceptionDelegate.executeUpdate(sql, columnIndexes); + } + + public int executeUpdate(String sql, String[] columnNames) throws SQLException { + return throwExceptionDelegate.executeUpdate(sql, columnNames); + } + + public int executeUpdate(String sql) throws SQLException { + return throwExceptionDelegate.executeUpdate(sql); + } + + public Connection getConnection() throws SQLException { + return throwExceptionDelegate.getConnection(); + } + + public int getFetchDirection() throws SQLException { + return throwExceptionDelegate.getFetchDirection(); + } + + public int getFetchSize() throws SQLException { + return throwExceptionDelegate.getFetchSize(); + } + + public ResultSet getGeneratedKeys() throws SQLException { + return throwExceptionDelegate.getGeneratedKeys(); + } + + public int getMaxFieldSize() throws SQLException { + return throwExceptionDelegate.getMaxFieldSize(); + } + + public int getMaxRows() throws SQLException { + return throwExceptionDelegate.getMaxRows(); + } + + public boolean getMoreResults() throws SQLException { + return throwExceptionDelegate.getMoreResults(); + } + + public boolean getMoreResults(int current) throws SQLException { + return throwExceptionDelegate.getMoreResults(current); + } + + public int getQueryTimeout() throws SQLException { + return throwExceptionDelegate.getQueryTimeout(); + } + + public ResultSet getResultSet() throws SQLException { + return throwExceptionDelegate.getResultSet(); + } + + public int getResultSetConcurrency() throws SQLException { + return throwExceptionDelegate.getResultSetConcurrency(); + } + + public int getResultSetHoldability() throws SQLException { + return throwExceptionDelegate.getResultSetHoldability(); + } + + public int getResultSetType() throws SQLException { + return throwExceptionDelegate.getResultSetType(); + } + + public int getUpdateCount() throws SQLException { + return throwExceptionDelegate.getUpdateCount(); + } + + public SQLWarning getWarnings() throws SQLException { + return throwExceptionDelegate.getWarnings(); + } + + public boolean isClosed() throws SQLException { + return throwExceptionDelegate.isClosed(); + } + + public boolean isPoolable() throws SQLException { + return throwExceptionDelegate.isPoolable(); + } + + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return throwExceptionDelegate.isWrapperFor(iface); + } + + public void setCursorName(String name) throws SQLException { + throwExceptionDelegate.setCursorName(name); + } + + public void setEscapeProcessing(boolean enable) throws SQLException { + throwExceptionDelegate.setEscapeProcessing(enable); + } + + public void setFetchDirection(int direction) throws SQLException { + throwExceptionDelegate.setFetchDirection(direction); + } + + public void setFetchSize(int rows) throws SQLException { + throwExceptionDelegate.setFetchSize(rows); + } + + public void setMaxFieldSize(int max) throws SQLException { + throwExceptionDelegate.setMaxFieldSize(max); + } + + public void setMaxRows(int max) throws SQLException { + throwExceptionDelegate.setMaxRows(max); + } + + public void setPoolable(boolean poolable) throws SQLException { + throwExceptionDelegate.setPoolable(poolable); + } + + public void setQueryTimeout(int seconds) throws SQLException { + throwExceptionDelegate.setQueryTimeout(seconds); + } + + public <T> T unwrap(Class<T> iface) throws SQLException { + return throwExceptionDelegate.unwrap(iface); + } + +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/2691117a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/parser/Parser.java ---------------------------------------------------------------------- diff --git a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/parser/Parser.java b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/parser/Parser.java new file mode 100644 index 0000000..c8b7287 --- /dev/null +++ b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/parser/Parser.java @@ -0,0 +1,205 @@ +package org.apache.blur.jdbc.parser; + +/** + * 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. + */ +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Parser { + + private static final String SELECT = "select"; + private static final String WHERE = "where"; + private static final String NATURAL = "natural"; + private static final String FROM = "from"; + private static final String JOIN = "join"; + private static final String SEP = new String(new char[] { 1 }); + + public static void main(String[] args) { + // System.out.println(new + // Parser().parse("select * from table where query('person.pn:(nice cool)')")); + // System.out.println(new + // Parser().parse("select * from table natural join table2 where person.pn = 'coandol''s' and jon='asdndandanda' And person.pf ='niorce' or nice = 'be'")); + // System.out.println(new + // Parser().parse("select * from table where person.pn = 'coandol''s' and jon='asdndandanda' And person.pf ='niorce' or nice = 'be'")); + System.out.println(new Parser().parse("SELECT * FROM TEST_TABLE T WHERE 1 = 0")); + System.out.println(new Parser().parse("select * from table t where 1 = 0")); + // System.out.println(new + // Parser().parse("select id,locationid,score,cf1.* from table where query('+person.pn:(nice cool) AND cool.a:nice')")); + } + + private String where; + private String tableName; + private List<String> columnNames; + private String joinTable; + + public Parser parse(String query) { + columnNames = getColumnNames(query); + tableName = getTableName(query); + where = getWhere(query); + joinTable = getJoin(query); + return this; + } + + public String getJoinTable() { + return joinTable; + } + + private String getJoin(String query) { + String table = null; + StringTokenizer tokenizer = new StringTokenizer(query); + while (tokenizer.hasMoreTokens()) { + if (NATURAL.equals(tokenizer.nextToken().toLowerCase())) { + if (JOIN.equals(tokenizer.nextToken().toLowerCase())) { + table = tokenizer.nextToken(); + } else { + throw new RuntimeException(); + } + } + } + return table; + } + + private String getWhere(String query) { + StringBuilder result = new StringBuilder(); + StringTokenizer tokenizer = new StringTokenizer(query); + while (tokenizer.hasMoreTokens()) { + if (WHERE.equals(tokenizer.nextToken().toLowerCase())) { + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + result.append(token).append(' '); + } + } + } + return getQuery(result.toString().trim()); + } + + private String getQuery(String query) { + Pattern p = Pattern.compile("([qQ][uU][eE][rR][yY]\\s*\\(\\s*')(.*)('\\s*\\).*)"); + Matcher matcher = p.matcher(query); + if (matcher.find()) { + if (matcher.groupCount() != 3) {// first one is the whole string + throw new RuntimeException("malformed query [" + query + "]"); + } + return matcher.group(2);// 2nd group is the lucene query + } else { + return changeQueryToLucene(query); + } + } + + private String changeQueryToLucene(String query) { + query = fixAndsOrs(query); + query = query.replaceAll("\\s*=\\s*", ":"); + query = query.replace("''", SEP); + query = query.replaceAll("'", ""); + query = query.replace(SEP, "'"); + return query; + } + + private String fixAndsOrs(String query) { + query = fixToUpperToken(query, "AND"); + query = fixToUpperToken(query, "OR"); + return query; + } + + private String fixToUpperToken(String query, String token) { + String queryUpper = query.toUpperCase(); + int start = 0; + int index = queryUpper.indexOf(token, start); + while (index != -1) { + if (!query.substring(index, index + token.length()).equals(token)) { + String everythingInStringToCurrentPosition = query.substring(0, index); + if (!isHitInParameter(everythingInStringToCurrentPosition)) { + query = query.substring(0, index) + token + query.substring(index + token.length()); + return fixToUpperToken(query, token); + } + } + start = index + 1; + index = queryUpper.indexOf(token, start); + } + return query; + } + + private boolean isHitInParameter(String everythingInStringToCurrentPosition) { + char[] charArray = everythingInStringToCurrentPosition.toCharArray(); + int count = 0; + for (int i = 0; i < charArray.length; i++) { + if (charArray[i] == '\'') { + count++; + } + } + return count % 2 != 0; + } + + private String getTableName(String query) { + StringTokenizer tokenizer = new StringTokenizer(query); + while (tokenizer.hasMoreTokens()) { + if (FROM.equals(tokenizer.nextToken().toLowerCase())) { + if (tokenizer.hasMoreTokens()) { + return tokenizer.nextToken(); + } + } + } + throw new IllegalArgumentException("Table not found"); + } + + private List<String> getColumnNames(String query) { + StringTokenizer tokenizer = new StringTokenizer(query); + List<String> columnNames = new ArrayList<String>(); + while (tokenizer.hasMoreTokens()) { + if (SELECT.equals(tokenizer.nextToken().toLowerCase())) { + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken().toLowerCase(); + if (FROM.equals(token)) { + return columnNames; + } + processColumnToken(columnNames, token); + } + } + } + return null; + } + + private void processColumnToken(List<String> columnNames, String token) { + StringTokenizer tokenizer = new StringTokenizer(token, ","); + while (tokenizer.hasMoreTokens()) { + columnNames.add(tokenizer.nextToken()); + } + } + + public String getTableName() { + return tableName; + } + + public List<String> getColumnNames() { + return columnNames; + } + + public String getWhere() { + if (where == null || where.trim().isEmpty()) { + return "*"; + } + return where; + } + + @Override + public String toString() { + return "Parser [columnNames=" + columnNames + ", tableName=" + tableName + ", where=" + where + ", joinTable=" + joinTable + "]"; + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/2691117a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/EmptyResultSet.java ---------------------------------------------------------------------- diff --git a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/EmptyResultSet.java b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/EmptyResultSet.java new file mode 100644 index 0000000..1483a6b --- /dev/null +++ b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/EmptyResultSet.java @@ -0,0 +1,42 @@ +package org.apache.blur.jdbc.util; + +/** + * 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. + */ +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +import org.apache.blur.jdbc.abstractimpl.AbstractBlurResultSet; + + +public class EmptyResultSet extends AbstractBlurResultSet { + + @Override + public void close() throws SQLException { + + } + + @Override + public boolean next() throws SQLException { + return false; + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + return new EmptyResultSetMetaData(); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/2691117a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/EmptyResultSetMetaData.java ---------------------------------------------------------------------- diff --git a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/EmptyResultSetMetaData.java b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/EmptyResultSetMetaData.java new file mode 100644 index 0000000..0a0c7ab --- /dev/null +++ b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/EmptyResultSetMetaData.java @@ -0,0 +1,32 @@ +package org.apache.blur.jdbc.util; + +/** + * 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. + */ +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +import org.apache.blur.jdbc.abstractimpl.AbstractBlurResultSetMetaData; + + +public class EmptyResultSetMetaData extends AbstractBlurResultSetMetaData implements ResultSetMetaData { + + @Override + public int getColumnCount() throws SQLException { + return 0; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/2691117a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/NotImplemented.java ---------------------------------------------------------------------- diff --git a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/NotImplemented.java b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/NotImplemented.java new file mode 100644 index 0000000..cec34ab --- /dev/null +++ b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/NotImplemented.java @@ -0,0 +1,37 @@ +package org.apache.blur.jdbc.util; + +/** + * 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. + */ +public class NotImplemented extends RuntimeException { + + public static final String BLUR_JDBC_DEBUG = "blur.jdbc.debug"; + private static final long serialVersionUID = 4736975316647139778L; + public static final boolean debug = Boolean.getBoolean(BLUR_JDBC_DEBUG); + + public NotImplemented() { + this(null); + } + + public NotImplemented(String name) { + if (debug) { + if (name != null) { + System.err.println("Method [" + name + "]"); + } + new Throwable().printStackTrace(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/2691117a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/SimpleStringResultSet.java ---------------------------------------------------------------------- diff --git a/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/SimpleStringResultSet.java b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/SimpleStringResultSet.java new file mode 100644 index 0000000..eff7797 --- /dev/null +++ b/src/contrib/blur-jdbc/src/main/java/org/apache/blur/jdbc/util/SimpleStringResultSet.java @@ -0,0 +1,101 @@ +package org.apache.blur.jdbc.util; + +/** + * 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. + */ +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Types; +import java.util.List; +import java.util.Map; + +import org.apache.blur.jdbc.abstractimpl.AbstractBlurResultSet; +import org.apache.blur.jdbc.abstractimpl.AbstractBlurResultSetMetaData; + + +public class SimpleStringResultSet extends AbstractBlurResultSet { + + private List<String> columnNames; + private List<Map<String, String>> data; + private int position = -1; + private String lastValue; + + public SimpleStringResultSet(List<String> columnNames, List<Map<String, String>> data) { + this.columnNames = columnNames; + this.data = data; + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + return new SimpleStringResultSetMetaData(columnNames); + } + + @Override + public boolean next() throws SQLException { + if (position + 1 >= data.size()) { + return false; + } + position++; + return true; + } + + @Override + public String getString(int columnIndex) throws SQLException { + String name = columnNames.get(columnIndex - 1); + Map<String, String> row = data.get(position); + return lastValue = row.get(name); + } + + @Override + public boolean wasNull() throws SQLException { + return lastValue == null ? true : false; + } + + @Override + public void close() throws SQLException { + + } + + public static class SimpleStringResultSetMetaData extends AbstractBlurResultSetMetaData { + + private List<String> columnNames; + + public SimpleStringResultSetMetaData(List<String> columnNames) { + this.columnNames = columnNames; + } + + @Override + public int getColumnCount() throws SQLException { + return columnNames.size(); + } + + @Override + public String getColumnName(int column) throws SQLException { + return columnNames.get(column - 1); + } + + @Override + public int getColumnType(int column) throws SQLException { + return Types.VARCHAR; + } + + @Override + public String getColumnTypeName(int column) throws SQLException { + return "string"; + } + + } +}
