|
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;
|