From: SVN by r. <sv...@ca...> - 2008-01-13 10:54:06
|
Author: roy Date: 2008-01-13 11:42:47 +0100 (Sun, 13 Jan 2008) New Revision: 217 Modified: src/main/java/nl/improved/sqlclient/util/ResultBuilder.java Log: large speed improvement when displaying large result Modified: src/main/java/nl/improved/sqlclient/util/ResultBuilder.java =================================================================== --- src/main/java/nl/improved/sqlclient/util/ResultBuilder.java 2008-01-13 10:41:19 UTC (rev 216) +++ src/main/java/nl/improved/sqlclient/util/ResultBuilder.java 2008-01-13 10:42:47 UTC (rev 217) @@ -1,10 +1,10 @@ package nl.improved.sqlclient.util; +import java.awt.event.ActionEvent; import java.util.*; public class ResultBuilder { public enum Alignment {LEFT, RIGHT}; - private int columnCount = 0, rowCount = 0; private Map<Integer, Integer> columnSizes = new HashMap<Integer, Integer>(); private List<String> header; @@ -12,16 +12,8 @@ private boolean horizontalSeperatorEnabled = true; private char horizontalSeperator = '-', verticalSeparator ='|'; + private RowList rows = new RowList(); - private Set cellValues = new TreeSet<Cell>(new Comparator<Cell>() { - public int compare(Cell c1, Cell c2) { - if (c1.getRow() != c2.getRow()) { - return c1.getRow() - c2.getRow(); - } - return c1.getColumn() - c2.getColumn(); - } - }); - public void setHorizontalSeparatorEnabled(boolean enabled) { this.horizontalSeperatorEnabled = enabled; } @@ -64,41 +56,21 @@ } public void set(int column,int row, CharSequence s, Alignment alignment) { - columnCount = Math.max(columnCount, column); - rowCount = Math.max(rowCount, row); - Cell c = new Cell(column, row, s, alignment); - if (cellValues.contains(c)) { - cellValues.remove(c); - } - cellValues.add(c); - Integer maxValue = columnSizes.get(new Integer(column)); - if (maxValue == null || maxValue.intValue() < c.getLength()+1) { // +1 because one space at end of column - columnSizes.put(new Integer(column), c.getLength()+1); - } + rows.setValue(column, row, s, alignment); } - private Cell getCell(int col, int row) { - Iterator<Cell> iCellValues = cellValues.iterator(); - while (iCellValues.hasNext()) { - Cell c = iCellValues.next(); - if (c.getRow() == row && c.getColumn() == col) { - return c; - } - } - return null; - } - @Override public String toString() { int rowLength = 2; //add |<row>\n - for (int col = 0; col <= columnCount; col++) { + for (int col = 0; col <= rows.columnCount; col++) { Integer colSize = columnSizes.get(col); if (colSize != null) { rowLength += colSize.intValue() + 1; // add | } } - StringBuilder result = new StringBuilder((rowLength * (rowCount + 2 + (header == null ? 0 : 1))) + (footer == null ? 0 : footer.length()+1)); + int probableLength = (rowLength * (rows.rowCount + 2 + (header == null ? 0 : 1))) + (footer == null ? 0 : footer.length()+1) + 500; + StringBuilder result = new StringBuilder(probableLength); if (header != null) { if (horizontalSeperatorEnabled) { for (int i = 0; i < rowLength-1; i++) { @@ -126,21 +98,27 @@ } } result.append('\n'); - for (int row = 0; row <= rowCount; row++) { - result.append(verticalSeparator); - for (int col = 0; col <= columnCount; col++) { - Cell c = getCell(col, row); - int colStart = result.length(); - int spaceUsed = 0; - if (c != null) { - result.append(c.getValue()); - spaceUsed = c.getLength(); - } - Integer colSize = columnSizes.get(col); + Iterator<Cell> cells = rows.iterator(); + int prevRow = 0; + result.append(verticalSeparator); + while (cells.hasNext()) { + Cell cell = cells.next(); + if (cell != null && cell.row != prevRow) { + result.append('\n'); + result.append('|'); + prevRow = cell.row; + } + int colStart = result.length(); + int spaceUsed = 0; + if (cell != null) { + result.append(cell.getValue()); + spaceUsed = cell.getLength(); + + Integer colSize = columnSizes.get(cell.col); if (colSize != null) { int colSizeInt = colSize.intValue(); for (int i = spaceUsed; i < colSizeInt; i++) { - if (c == null || c.getAlignment() == Alignment.LEFT) { + if (cell == null || cell.getAlignment() == Alignment.LEFT) { result.append(' '); } else { result.insert(colStart, ' '); @@ -149,8 +127,8 @@ result.append(verticalSeparator); } } - result.append('\n'); } + result.append('\n'); if (horizontalSeperatorEnabled) { for (int i = 0; i < rowLength-1; i++) { result.append(horizontalSeperator); @@ -165,7 +143,6 @@ } private static class Cell { - private int row, col; private CharSequence buffer; private Alignment alignment; @@ -210,12 +187,122 @@ } } + private class RowList { + private int columnCount = 0, rowCount = 0; + + private Row firstRow = null; + private Row lastRow = null; + + public RowList() { + } + + public void setValue(int col, int row, CharSequence value, Alignment align) { + // TODO remove first row(s) when rowsize larger then maxsize + columnCount = Math.max(columnCount, col); + rowCount = Math.max(rowCount, row); + Row newRow; + if (firstRow == null) { + firstRow = new Row(row); + lastRow = firstRow; + newRow = firstRow; + } else if (lastRow.rowNum == row) { + newRow = lastRow; + } else if (lastRow.rowNum < row) { + lastRow.nextRow = new Row(row); + newRow = lastRow.nextRow; + lastRow = newRow; + } else { + throw new IllegalStateException("Please add rows in order!"); + } + + Cell c = new Cell(col, row, value, align); + if (newRow.cells.contains(c)) { + newRow.cells.remove(c); + } + newRow.cells.add(c); + Integer maxValue = columnSizes.get(new Integer(col)); + if (maxValue == null || maxValue.intValue() < c.getLength()+1) { // +1 because one space at end of column + columnSizes.put(new Integer(col), c.getLength()+1); + } + } + + public Iterator<Cell> iterator() { + Iterator<Cell> i = new Iterator<Cell>() { + Row curRow = firstRow; + int colNr = 0; + @Override + public boolean hasNext() { + return (colNr <= columnCount) || curRow.nextRow != null; + } + + @Override + public Cell next() { + if (colNr > columnCount) { + colNr = 0; + curRow = curRow.nextRow; + } + return curRow.getCell(colNr++); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Not supported."); + } + }; + return i; + } + + private class Row { + public Row nextRow; + public int rowNum; + public List<Cell> cells; + + public Row(int rowNum) { + this.rowNum = rowNum; + cells = new ArrayList<Cell>(); + } + + Cell getCell(int col) { + Cell c; + if (cells.size() > col) { + c = cells.get(col); + if (c.col == col) { + return c; + } + } + Iterator<Cell> iCells = cells.iterator(); + while (iCells.hasNext()) { + c = iCells.next(); + if (c.col == col) { + return c; + } + } + return null; + } + } + } + public static void main(String[] args) throws Exception { ResultBuilder builder = new ResultBuilder(); - builder.set(0,0, "cell 0,0"); - builder.set(1,0, "cell 1,0 and even more stuff"); - builder.set(0,1, "cell 0,1 and some other stuff"); - builder.set(1,1, "cell 1,1"); + builder.set(0, 0, "faaaaaa"); + builder.set(1, 0, "fbbbbbb"); + builder.set(2, 0, "fcccccc"); + builder.set(3, 0, "fdddddd"); + builder.set(4, 0, "feeeeee"); + for (int row = 1; row < 2000; row++) { + builder.set(0, row, "aaaaaaa"); + builder.set(1, row, "bbbbbbb"); + builder.set(2, row, "ccccccc"); + builder.set(3, row, "ddddddd"); + builder.set(4, row, "eeeeeee"); + } + builder.set(0, 2000, "laaaaaa"); + builder.set(1, 2000, "lbbbbbb"); + builder.set(2, 2000, "lcccccc"); + builder.set(3, 2000, "ldddddd"); + builder.set(4, 2000, "leeeeee"); + long start = System.currentTimeMillis(); System.out.println(builder.toString()); + System.out.println("TIME: "+ (System.currentTimeMillis() - start)); } } |
From: SVN by r. <sv...@ca...> - 2008-01-14 10:57:50
|
Author: roy Date: 2008-01-14 11:46:32 +0100 (Mon, 14 Jan 2008) New Revision: 220 Modified: src/main/java/nl/improved/sqlclient/util/ResultBuilder.java Log: fix presentation of result Modified: src/main/java/nl/improved/sqlclient/util/ResultBuilder.java =================================================================== --- src/main/java/nl/improved/sqlclient/util/ResultBuilder.java 2008-01-14 07:04:24 UTC (rev 219) +++ src/main/java/nl/improved/sqlclient/util/ResultBuilder.java 2008-01-14 10:46:32 UTC (rev 220) @@ -105,7 +105,7 @@ Cell cell = cells.next(); if (cell != null && cell.row != prevRow) { result.append('\n'); - result.append('|'); + result.append(verticalSeparator); prevRow = cell.row; } int colStart = result.length(); |
From: SVN by r. <sv...@ca...> - 2008-01-14 14:49:47
|
Author: roy Date: 2008-01-14 15:21:08 +0100 (Mon, 14 Jan 2008) New Revision: 222 Modified: src/main/java/nl/improved/sqlclient/util/ResultBuilder.java Log: fix 'no result' output Modified: src/main/java/nl/improved/sqlclient/util/ResultBuilder.java =================================================================== --- src/main/java/nl/improved/sqlclient/util/ResultBuilder.java 2008-01-14 10:57:59 UTC (rev 221) +++ src/main/java/nl/improved/sqlclient/util/ResultBuilder.java 2008-01-14 14:21:08 UTC (rev 222) @@ -232,7 +232,7 @@ int colNr = 0; @Override public boolean hasNext() { - return (colNr <= columnCount) || curRow.nextRow != null; + return curRow != null && ((colNr <= columnCount) || curRow.nextRow != null); } @Override |
From: SVN by r. <sv...@ca...> - 2009-02-27 08:10:59
|
Author: roy Date: 2009-02-27 09:10:51 +0100 (Fri, 27 Feb 2009) New Revision: 380 Added: src/main/java/nl/improved/sqlclient/util/SQLParser.java src/main/java/nl/improved/sqlclient/util/SQLPart.java Log: new sql parsing api Added: src/main/java/nl/improved/sqlclient/util/SQLParser.java =================================================================== --- src/main/java/nl/improved/sqlclient/util/SQLParser.java 2009-02-20 21:59:19 UTC (rev 379) +++ src/main/java/nl/improved/sqlclient/util/SQLParser.java 2009-02-27 08:10:51 UTC (rev 380) @@ -0,0 +1,396 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package nl.improved.sqlclient.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import nl.improved.sqlclient.Point; +import nl.improved.sqlclient.SQLCommand; +import nl.improved.sqlclient.TabCompletionInfo; + +/** + * + * @author roy + */ +public class SQLParser { + final static char[] breakCharacters = new char[]{' ', '\t', '.', ',', '(',')'}; + /** + * A regular expression statement for name chars. + */ + private static final String NAMING_CHAR = "(_|-|[0-9]|[A-Z])"; + /** + * A table name regular expression statement. + */ + private static final String TABLE = "[A-Z]+"+NAMING_CHAR+"*"; + /** + * A column name regular expression statement. + */ + private static final String COLUMN = "(\\*|[A-Z]+"+NAMING_CHAR+"*)"; + /** + * A variable (table name + columnname) regular expression statement. + */ + private static final String VAR = "(|"+TABLE+"\\.)"+COLUMN; + /** + * SQL Comparators. + */ + private static final String COMPARATOR = "(=|<>|<|>|LIKE)"; + /** + * A sql variable description. + */ + private static final String VALUE = "('.*'|[0-9]+|"+VAR+")"; + + public static TabCompletionInfo getTabCompletionInfo(SQLCommand command, Point commandPoint) { + List<? extends CharSequence> lines = command.getLines(); + return getTabCompletionInfo(lines, commandPoint); + } + public static TabCompletionInfo getTabCompletionInfo(List<? extends CharSequence> lines, Point commandPoint) { + StringBuffer buf = new StringBuffer(); + int position = 0; + for (int y = 0; y < lines.size(); y++) { + CharSequence seq = lines.get(y); + if (y < commandPoint.y) { + position+=seq.length(); + } + if (y == commandPoint.y) { + position+=commandPoint.x; + } + buf.append(seq); + } + return getTabCompletionInfo(buf, position); + } + + public static TabCompletionInfo getTabCompletionInfo(CharSequence sql, int position) { + + List<SQLPart> parts = parse(sql); + System.err.println("PARTS: "+ parts); + int charsLeft = position; + for (SQLPart part : parts) { + if (charsLeft <= part.getPart().length()) { + switch (part.getSQLType()) { + case SELECT : + return getSelectTabCompletionInfo(part, parts, charsLeft); + case FROM : + return getFromTabCompletionInfo(part, parts, charsLeft); + case WHERE : + return getWhereTabCompletionInfo(part, parts, charsLeft); + case GROUPBY : + return getGroupByTabCompletionInfo(part, parts, charsLeft); + case ORDERBY : + return getOrderByTabCompletionInfo(part, parts, charsLeft); + case DELETE : + return getDeleteTabCompletionInfo(part, parts, charsLeft); + case UPDATE : + return getUpdateTabCompletionInfo(part, parts, charsLeft); + case SET : + return getSetTabCompletionInfo(part, parts, charsLeft); + } + } else { + charsLeft -=part.getPart().length(); + } + } + return new TabCompletionInfo(TabCompletionInfo.MatchType.SQL_KEYWORD + , Arrays.asList(new String[]{"SELECT", "INSERT INTO", "UPDATE", "DELETE FROM", "ALTER TABLE"}) + , sql); + } + + + static List<SQLPart> parse(CharSequence sqlSequence) { + List<SQLPart> returnValue = new ArrayList<SQLPart>(); + if (sqlSequence.length() == 0) { + return returnValue; + } + SQLPart.SQLType sqlType; + int start = 0; + int end = sqlSequence.length(); + String sql = sqlSequence.toString().toUpperCase(); + //System.out.println("SQL: "+ sql); + //System.out.println("MATCHES: "+ sql.matches("SELECT.*")); + if (sql.matches("[\\s]*SELECT.*")) { + sqlType = SQLPart.SQLType.SELECT; + if (sql.matches("[\\s]*SELECT.*FROM.*")) { + end = sql.indexOf("FROM"); + } else { + end = sqlSequence.length(); + } + } else if (sql.matches("[\\s]*FROM.*")) { + sqlType = SQLPart.SQLType.FROM; + if (sql.matches("[\\s]*FROM.*WHERE.*")) { + end = sql.indexOf("WHERE"); + } + } else if (sql.matches("[\\s]*WHERE.*")) { + sqlType = SQLPart.SQLType.WHERE; + if (sql.matches("[\\s]*WHERE.*ORDER BY.*")) { + end = sql.indexOf(" ORDER BY"); + } else if (sql.matches("[\\s]*WHERE.*GROUP BY.*")) { + end = sql.indexOf("GROUP BY"); + } + } else if (sql.matches("[\\s]*ORDER BY.*")) { + sqlType = SQLPart.SQLType.ORDERBY; + if (sql.matches("[\\s]*ORDER BY.*GROUP BY.*")) { + end = sql.indexOf("GROUP BY"); + } + } else if (sql.matches("[\\s]*GROUP BY.*")) { + sqlType = SQLPart.SQLType.GROUPBY; + } else if (sql.matches("[\\s]*DELETE.*")) { + sqlType = SQLPart.SQLType.DELETE; + if (sql.matches("[\\s]*DELETE FROM.*")) { + end = sql.indexOf("FROM"); + } else { + end = sqlSequence.length(); + } + } else if (sql.matches("[\\s]*UPDATE.*")) { + sqlType = SQLPart.SQLType.UPDATE; + if (sql.matches("[\\s]*UPDATE.*SET.*")) { + end = sql.indexOf("SET"); + } else { + end = sqlSequence.length(); + } + } else if (sql.matches("[\\s]*SET.*")) { + sqlType = SQLPart.SQLType.SET; + if (sql.matches("[\\s]*WHERE.*")) { + end = sql.indexOf("WHERE"); + } else { + end = sqlSequence.length(); + } + } else { + sqlType = SQLPart.SQLType.OTHER; + } + returnValue.add(new SQLPart(sqlType, sqlSequence.subSequence(start, end))); + returnValue.addAll(parse(sqlSequence.subSequence(end, sqlSequence.length()))); + return returnValue; + } + + private static TabCompletionInfo getDeleteTabCompletionInfo(SQLPart part, List<SQLPart> parts, int charsLeft) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + private static TabCompletionInfo getFromTabCompletionInfo(SQLPart part, List<SQLPart> parts, int charsLeft) { + String stringPart = part.getPart().toString(); + String subPart = stringPart.substring(stringPart.toUpperCase().indexOf("FROM") +"FROM".length(), charsLeft); + String end; + if (subPart.indexOf(',') > 0) { + end = subPart.substring(subPart.lastIndexOf(',')+1); + } else { + end = subPart; + } + String WHERE = "W|WH|WHE|WHER|WHERE"; + String GROUP_BY = "G|GR|GRO|GROU|GROUP|GROUP |GROUP B|GROUP BY"; + String ORDER_BY = "O|OR|ORD|ORDE|ORDER|ORDER |ORDER B|ORDER BY"; + if (subPart.trim().length() > 0 && (end.endsWith(" ") || subPart.matches(".*"+TABLE+"[\\s]+("+WHERE+"|"+GROUP_BY+"|"+ORDER_BY+")")) && + !subPart.trim().endsWith(",")) { + if (subPart.lastIndexOf(" ") >0) { + end = end.substring(end.lastIndexOf(' ')+1); + } + return new TabCompletionInfo(TabCompletionInfo.MatchType.SQL_KEYWORD, Arrays.asList(new String[]{"WHERE", "GROUP BY", "ORDER BY", ","}), end.trim()); + } + return new TabCompletionInfo(TabCompletionInfo.MatchType.TABLE_NAMES, Arrays.asList(new String[]{}), end.trim()); + } + + private static TabCompletionInfo getGroupByTabCompletionInfo(SQLPart part, List<SQLPart> parts, int charsLeft) { + String stringPart = part.getPart().toString(); + String subPart = stringPart.substring(stringPart.toUpperCase().indexOf("GROUP BY")+"GROUP BY".length(), charsLeft); + List<String> possibleMatches = new ArrayList<String>(); + for (SQLPart pPart : parts) { + if (pPart.getSQLType() == SQLPart.SQLType.SELECT) { + String pSubPart = pPart.getPart().toString().substring("SELECT".length()).trim(); + int lastIndex = 0; + int newIndex; + while ( (newIndex = pSubPart.indexOf(',', lastIndex)) > 0) { + String colName = pSubPart.substring(lastIndex, newIndex).trim(); + if (colName.indexOf(' ') >=0) { + colName = colName.substring(colName.lastIndexOf(' ')); + } + if (!possibleMatches.contains(colName)) { + possibleMatches.add(colName); + } + lastIndex = newIndex+1; + } + String colName = pSubPart.substring(lastIndex).trim(); + if (colName.indexOf(' ') >=0) { // alias + colName = colName.substring(colName.lastIndexOf(' ')); + } + if (!possibleMatches.contains(colName) && colName.length() > 0) { + possibleMatches.add(colName); + } + } + } + if (subPart.trim().length() == 0 || subPart.trim().endsWith(",")) { + return new TabCompletionInfo(TabCompletionInfo.MatchType.OTHER, possibleMatches); + } + String end; + if (subPart.indexOf(',') > 0) { + end = subPart.substring(subPart.lastIndexOf(',')).trim(); + } else { + end = subPart.trim(); + } + return new TabCompletionInfo(TabCompletionInfo.MatchType.OTHER, possibleMatches, end); + } + + private static TabCompletionInfo getOrderByTabCompletionInfo(SQLPart part, List<SQLPart> parts, int charsLeft) { + String stringPart = part.getPart().toString(); + String subPart = stringPart.substring(stringPart.toUpperCase().indexOf("ORDER BY")+"ORDER BY".length(), charsLeft); + List<String> possibleMatches = new ArrayList<String>(); + for (SQLPart pPart : parts) { + } + if (subPart.trim().length() == 0 || subPart.trim().endsWith(",")) { + return new TabCompletionInfo(TabCompletionInfo.MatchType.OTHER, possibleMatches); + } + String end; + if (subPart.indexOf(',') > 0) { + end = subPart.substring(subPart.lastIndexOf(',')).trim(); + } else { + end = subPart.trim(); + } + return new TabCompletionInfo(TabCompletionInfo.MatchType.OTHER, possibleMatches, end); + } + + private static TabCompletionInfo getSelectTabCompletionInfo(SQLPart part, List<SQLPart> parts, int position) { + // if it looks like: + // SELECT x + // return "FROM" + String startOfCommand = part.getPart().toString(); + String upCommand = startOfCommand.toUpperCase(); + if (upCommand.substring(upCommand.indexOf("SELECT") + "SELECT".length()) + .matches("[\\s]+"+VAR+"(|[\\s]*,[\\s]*"+VAR+"[\\s]*)[\\s]+(|F|FR|FRO|FROM)")) { + String end = startOfCommand.substring(startOfCommand.lastIndexOf(' ')+1); + return new TabCompletionInfo(TabCompletionInfo.MatchType.SQL_KEYWORD + , Arrays.asList(new String[]{"FROM"}), end); + } + // if it looks like: + // SELECT + // or + // SELECT A, + // return matching columnnames when table names are provided in from clause + // other wise return table names + // TODO check for WHERE Clause + String lastKeyword = "SELECT"; + String sub = startOfCommand.substring(upCommand.indexOf(lastKeyword)+lastKeyword.length()).trim(); + String tableName; + if (sub.indexOf(',') > 0) { + tableName = sub.substring(sub.lastIndexOf(',')+1).trim(); + } else { + tableName = sub; + } + if (tableName.indexOf('.') > 0) { + return new TabCompletionInfo(TabCompletionInfo.MatchType.COLUMN_NAMES + , Arrays.asList(new String[]{tableName.substring(0,tableName.indexOf('.'))}) + , tableName.substring(tableName.indexOf('.')+1)); + } + return new TabCompletionInfo(TabCompletionInfo.MatchType.TABLE_NAMES + , Arrays.asList(new String[0]), tableName); + } + + private static TabCompletionInfo getSetTabCompletionInfo(SQLPart part, List<SQLPart> parts, int charsLeft) { + String startOfCommand = part.getPart().toString().substring(0, charsLeft); + String tmpCommand = startOfCommand.substring(startOfCommand.toUpperCase().indexOf("SET")+"SET".length()+1); + if (tmpCommand.indexOf(',') >0) { + tmpCommand = tmpCommand.substring(tmpCommand.lastIndexOf(',')+1); + } + if (tmpCommand.endsWith(" ")) { + if (tmpCommand.matches(".*"+COMPARATOR+"[\\s]*")) { + return new TabCompletionInfo(TabCompletionInfo.MatchType.COLUMN_NAMES + , getTableNames(parts)); + } + if (tmpCommand.matches(".*"+COMPARATOR+"[\\s]*"+VAR+"[\\s]*")) { + return new TabCompletionInfo(TabCompletionInfo.MatchType.SQL_KEYWORD + , Arrays.asList(new String[]{",", "WHERE"})); + } + if (tmpCommand.trim().length() > 0) { + return new TabCompletionInfo(TabCompletionInfo.MatchType.SQL_KEYWORD + , Arrays.asList(new String[]{"=", "<>", "LIKE", "<", ">"})); + } + } + if (tmpCommand.trim().length() == 0) { + return new TabCompletionInfo(TabCompletionInfo.MatchType.COLUMN_NAMES + , getTableNames(parts)); + } + String end; + if (tmpCommand.indexOf(' ') > 0) { + end = tmpCommand.substring(tmpCommand.lastIndexOf(' ')+1).trim(); + } else { + end = tmpCommand.trim(); + } + if (tmpCommand.trim().length() > 0) { + return new TabCompletionInfo(TabCompletionInfo.MatchType.SQL_KEYWORD + , Arrays.asList(new String[]{"=", "<>", "LIKE", "<", ">"}), end); + } + return new TabCompletionInfo(TabCompletionInfo.MatchType.SQL_KEYWORD + , Arrays.asList(new String[]{",", "WHERE"})); // TODO END + } + + private static List<String> getTableNames(List<SQLPart> parts) { + SQLPart fromSqlPart = null; + for (SQLPart tmpPart : parts) { + if (tmpPart.getSQLType() == SQLPart.SQLType.FROM || tmpPart.getSQLType() == SQLPart.SQLType.UPDATE) { + fromSqlPart = tmpPart; + } + } + return fromSqlPart.getTableNames(); + } + + private static TabCompletionInfo getUpdateTabCompletionInfo(SQLPart part, List<SQLPart> parts, int charsLeft) { + String startOfCommand = part.getPart().toString().substring(0, charsLeft); + String tmpCommand = startOfCommand.substring(startOfCommand.toUpperCase().indexOf("UPDATE")+"UPDATE".length()+1); + if (tmpCommand.trim().length() > 0 && tmpCommand.lastIndexOf(' ') > 0) { + String end = tmpCommand.substring(tmpCommand.lastIndexOf(' ') +1); + return new TabCompletionInfo(TabCompletionInfo.MatchType.SQL_KEYWORD + , Arrays.asList(new String[]{"SET"}), end); + } + return new TabCompletionInfo(TabCompletionInfo.MatchType.TABLE_NAMES + , new ArrayList(), tmpCommand.trim()); + } + + private static TabCompletionInfo getWhereTabCompletionInfo(SQLPart part, List<SQLPart> parts, int charsLeft) { + // find out if it looks like + // 'SELECT x FROM A,B WHERE' + // or + // 'SELECT x FROM A,B WHERE A.x='x' AND/OR ' + String startOfCommand = part.getPart().toString().substring(0, charsLeft); + String tmpCommand = startOfCommand.substring(startOfCommand.toUpperCase().indexOf("WHERE")+"WHERE".length()+1); + String upperCommandString = tmpCommand.toUpperCase(); + //String VAR = "(|"+TABLE+"\\.)(|"+COLUMN+")"; + //String VALUE = "('.*'|[0-9]+|"+VAR+")"; + // VALUE COMPERATOR VALUE + // VALUE IN (.*) + String regExp = "(|"+VALUE+"(|[\\s]*"+COMPARATOR+"[\\s]*(|"+VALUE+"(|([\\s]+(AND|OR)[\\s]+(|"+VALUE+"(|[\\s]*"+COMPARATOR+"[\\s]*(|"+VALUE+"))))*))|[\\s]*IN[\\s]*(.*)[\\s]*))"; + if (upperCommandString.matches(regExp) || upperCommandString.endsWith(".")) { + System.err.println("****** MATCHES: "+ upperCommandString); + int lastIndex = tmpCommand.lastIndexOf(' '); + lastIndex = Math.max(lastIndex, tmpCommand.lastIndexOf('\t')); + lastIndex = Math.max(lastIndex, tmpCommand.lastIndexOf('=')); + lastIndex = Math.max(lastIndex, tmpCommand.lastIndexOf('>')); + lastIndex = Math.max(lastIndex, tmpCommand.lastIndexOf('>')); + int lastBreakIndex = lastIndex; + lastIndex = Math.max(lastIndex, tmpCommand.lastIndexOf('.')); + String end = tmpCommand.substring(lastIndex+1); + if (lastBreakIndex < 0) { + lastBreakIndex = 0; + } + List tableNames = (lastIndex > lastBreakIndex) && lastBreakIndex >=0 ? + Arrays.asList(new String[]{tmpCommand.substring(lastBreakIndex,lastIndex).trim()}) : + getTableNames(parts); + return new TabCompletionInfo(TabCompletionInfo.MatchType.COLUMN_NAMES + , tableNames, end); + } + System.err.println("****** NOT MATCHES: "+ upperCommandString+"\n"+ regExp); + //else System.out.println("'"+upperCommandString +"'\n not matches\n"+regExp); + String end; + if (upperCommandString.matches(".*[\\s]+")) { + end = ""; + } else { + int lastIndex = tmpCommand.lastIndexOf(' '); + lastIndex = Math.max(lastIndex, tmpCommand.lastIndexOf('\t')); + lastIndex = Math.max(lastIndex, tmpCommand.lastIndexOf('=')); + lastIndex = Math.max(lastIndex, tmpCommand.lastIndexOf('>')); + lastIndex = Math.max(lastIndex, tmpCommand.lastIndexOf('>')); + end = tmpCommand.substring(lastIndex+1); + } + return new TabCompletionInfo(TabCompletionInfo.MatchType.SQL_KEYWORD + , Arrays.asList(new String[]{"AND", "OR", "IN", "GROUP BY", "ORDER BY"}), end); + } + +} Added: src/main/java/nl/improved/sqlclient/util/SQLPart.java =================================================================== --- src/main/java/nl/improved/sqlclient/util/SQLPart.java 2009-02-20 21:59:19 UTC (rev 379) +++ src/main/java/nl/improved/sqlclient/util/SQLPart.java 2009-02-27 08:10:51 UTC (rev 380) @@ -0,0 +1,84 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package nl.improved.sqlclient.util; + +import java.util.ArrayList; +import java.util.List; +import nl.improved.sqlclient.TabCompletionInfo; + +/** + * + * @author roy + */ +public class SQLPart { + + enum SQLType {SELECT, INSERT, UPDATE, DELETE, WHERE, VALUES, FROM, GROUPBY, ORDERBY, OTHER, SET} + + private SQLType sqlType; + private CharSequence part; + + public SQLPart(SQLType sqlType, CharSequence part) { + this.sqlType = sqlType; + this.part = part; + } + + public SQLType getSQLType() { + return sqlType; + } + + public CharSequence getPart() { + return part; + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof SQLPart)) { + return false; + } + SQLPart other = (SQLPart) obj; + return other.part.equals(part) && other.sqlType == sqlType; + } + + @Override + public String toString() { + return sqlType+": "+ part.toString(); + } + + public List<String> getTableNames() { + if (sqlType == SQLType.FROM || sqlType == SQLType.UPDATE) { + List<String> returnValue = new ArrayList<String>(); + String stringPart = getPart().toString(); + String sub; + if (sqlType == SQLType.FROM) { + sub = stringPart.substring(stringPart.toUpperCase().indexOf("FROM")+"FROM".length()); + } else { + sub = stringPart.substring(stringPart.toUpperCase().indexOf("UPDATE")+"UPDATE".length()); + } + int lastIndex = 0; + int newIndex; + while ( (newIndex = sub.indexOf(',', lastIndex)) > 0) { + String tableName = sub.substring(lastIndex, newIndex).trim(); + if (tableName.indexOf(" ") > 0) { + tableName = tableName.substring(0, tableName.indexOf(" ")).trim(); + } + System.err.println("********ADDTN: "+ tableName); + returnValue.add(tableName); + lastIndex = newIndex+1; + } + String tmp = sub.substring(lastIndex).trim(); + if (tmp.length() > 0) { + if (tmp.indexOf(" ") > 0) { + tmp = tmp.substring(0, tmp.indexOf(" ")).trim(); + } + System.err.println("********ADD: "+ tmp); + returnValue.add(tmp); + } + return returnValue; + } + throw new IllegalStateException("Table names are only available for FROM,UPDATE ("+ sqlType+")"); + } + +} \ No newline at end of file |
From: SVN by r. <sv...@ca...> - 2009-02-28 13:42:01
|
Author: roy Date: 2009-02-28 14:31:11 +0100 (Sat, 28 Feb 2009) New Revision: 384 Modified: src/main/java/nl/improved/sqlclient/util/SQLParser.java Log: more tabcompletion fixes Modified: src/main/java/nl/improved/sqlclient/util/SQLParser.java =================================================================== --- src/main/java/nl/improved/sqlclient/util/SQLParser.java 2009-02-28 13:29:07 UTC (rev 383) +++ src/main/java/nl/improved/sqlclient/util/SQLParser.java 2009-02-28 13:31:11 UTC (rev 384) @@ -216,7 +216,7 @@ } if (!possibleMatches.contains(colName)) { possibleMatches.add(colName); - if (colName.indexOf('(') < 0) { + if (colName.indexOf("max") < 0 && colName.indexOf("min") < 0 && colName.indexOf("count") < 0) { if (bestMatch.length() > 0) { bestMatch.append(','); } @@ -231,7 +231,7 @@ } if (!possibleMatches.contains(colName) && colName.length() > 0) { possibleMatches.add(colName); - if (colName.indexOf('(') < 0) { + if (colName.indexOf("max") < 0 && colName.indexOf("min") < 0 && colName.indexOf("count") < 0) { if (bestMatch.length() > 0) { bestMatch.append(','); } |
From: SVN by r. <sv...@ca...> - 2009-02-28 13:43:11
|
Author: roy Date: 2009-02-28 14:36:27 +0100 (Sat, 28 Feb 2009) New Revision: 385 Modified: src/main/java/nl/improved/sqlclient/util/SQLParser.java Log: fix set tc Modified: src/main/java/nl/improved/sqlclient/util/SQLParser.java =================================================================== --- src/main/java/nl/improved/sqlclient/util/SQLParser.java 2009-02-28 13:31:11 UTC (rev 384) +++ src/main/java/nl/improved/sqlclient/util/SQLParser.java 2009-02-28 13:36:27 UTC (rev 385) @@ -329,7 +329,7 @@ } if (tmpCommand.trim().length() > 0) { return new TabCompletionInfo(TabCompletionInfo.MatchType.SQL_KEYWORD - , Arrays.asList(new String[]{"=", "<>", "LIKE", "<", ">"})); + , Arrays.asList(new String[]{"="})); } } if (tmpCommand.trim().length() == 0) { |
From: SVN by r. <sv...@ca...> - 2009-03-31 19:39:47
|
Author: roy Date: 2009-03-31 21:39:40 +0200 (Tue, 31 Mar 2009) New Revision: 399 Added: src/main/java/nl/improved/sqlclient/util/Function.java Log: very initial stuff for fuction support Added: src/main/java/nl/improved/sqlclient/util/Function.java =================================================================== --- src/main/java/nl/improved/sqlclient/util/Function.java 2009-03-31 19:38:19 UTC (rev 398) +++ src/main/java/nl/improved/sqlclient/util/Function.java 2009-03-31 19:39:40 UTC (rev 399) @@ -0,0 +1,62 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package nl.improved.sqlclient.util; + +/** + * + * @author roy + */ +public class Function { + private FunctionArg[] types; + private String name; + + public Function(String name, int... types) { + this.name = name; + this.types = new FunctionArg[types.length]; + for (int i = 0; i < types.length; i++) { + this.types[i] = new FunctionArg(types[i]); + } + } + + public Function(String name, FunctionArg... types) { + this.name = name; + this.types = types; + } + + + public int getArgumentCount() { + return types == null ? 0 : types.length; + } + + public FunctionArg getArgumentType(int arg) { + return types[arg]; + } + + public boolean matches(CharSequence s) { + return s.length() > 0 && name.startsWith(s.toString()); + } + + public class FunctionArg { + private int type; + private String help; + public FunctionArg(int type) { + this.type = type; + + } + public FunctionArg(int type, String help) { + this.type = type; + this.help = help; + } + + public int getType() { + return type; + } + + public String getHelp() { + return help; + } + } +} |
From: SVN by r. <sv...@ca...> - 2010-07-19 14:20:11
|
Author: roy Date: 2010-07-19 15:17:56 +0200 (Mon, 19 Jul 2010) New Revision: 477 Modified: src/main/java/nl/improved/sqlclient/util/SQLParser.java src/main/java/nl/improved/sqlclient/util/SQLPart.java Log: fix column completion when statement ends with <tablename>; Modified: src/main/java/nl/improved/sqlclient/util/SQLParser.java =================================================================== --- src/main/java/nl/improved/sqlclient/util/SQLParser.java 2010-05-08 10:32:22 UTC (rev 476) +++ src/main/java/nl/improved/sqlclient/util/SQLParser.java 2010-07-19 13:17:56 UTC (rev 477) @@ -98,6 +98,8 @@ return getInsertTabCompletionInfo(part, parts, charsLeft); case VALUES : return getValuesTabCompletionInfo(part, parts, charsLeft); + case END : + return new TabCompletionInfo(TabCompletionInfo.MatchType.OTHER, null); } } else { charsLeft -=part.getPart().length(); @@ -109,13 +111,17 @@ } - static List<SQLPart> parse(CharSequence sqlSequence) { + static List<SQLPart> parse(CharSequence sqlPart) { List<SQLPart> returnValue = new ArrayList<SQLPart>(); - if (sqlSequence.length() == 0) { + if (sqlPart.length() == 0) { return returnValue; } SQLPart.SQLType sqlType; int start = 0; + CharSequence sqlSequence = sqlPart; + if (sqlPart.charAt(sqlPart.length()-1) ==';') { + sqlSequence = sqlPart.subSequence(0, sqlPart.length()-1); + } int end = sqlSequence.length(); String sql = sqlSequence.toString().toUpperCase(); //System.out.println("SQL: "+ sql); Modified: src/main/java/nl/improved/sqlclient/util/SQLPart.java =================================================================== --- src/main/java/nl/improved/sqlclient/util/SQLPart.java 2010-05-08 10:32:22 UTC (rev 476) +++ src/main/java/nl/improved/sqlclient/util/SQLPart.java 2010-07-19 13:17:56 UTC (rev 477) @@ -16,7 +16,7 @@ */ public class SQLPart { - enum SQLType {SELECT, INSERT, UPDATE, DELETE, WHERE, VALUES, FROM, GROUPBY, ORDERBY, OTHER, SET} + enum SQLType {SELECT, INSERT, UPDATE, DELETE, WHERE, VALUES, FROM, GROUPBY, ORDERBY, OTHER, SET, END} private SQLType sqlType; private CharSequence part; |