package com.aggrepoint.dao;
import java.util.Stack;
public class CountHelper {
static final int STATE_SELECT_START = 0;
static final int STATE_SELECT = 1;
static final int STATE_FROM = 2;
static final int STATE_ORDER = 3;
static final int STATE_QUOTE = 10;
static final int STATE_PARENTESIS = 11;
static final char[] SELECT = "SELECT ".toCharArray();
static final char[] FROM = "FROM ".toCharArray();
static final char[] ORDER_BY = "ORDER BY ".toCharArray();
static final char[] DOUBLE_QUOTE = "''".toCharArray();
private String select;
private String from;
private String order;
private int match(char[] chars, int st, char[] match) {
for (int i = 0; i < match.length; i++) {
if (chars.length <= st + i)
return -1;
if (chars[st + i] != match[i])
return -1;
if (match[i] == ' ')
while (chars.length <= st + i + 1 && chars[st + i + 1] == ' ')
st++;
}
return st + match.length - 1;
}
public CountHelper(String sql) {
Stack<Integer> state = new Stack<Integer>();
state.push(STATE_SELECT_START);
sql = sql.trim();
char[] chars = sql.toUpperCase().toCharArray();
int selectSt, selectEd, fromSt, fromEd, orderSt;
selectSt = selectEd = fromSt = fromEd = orderSt = -1;
for (int i = 0; i < chars.length; i++) {
int posi;
switch (state.peek()) {
case STATE_SELECT_START:
posi = match(chars, 0, SELECT);
if (posi > 0)
i = posi;
else
i--;
state.pop();
state.push(STATE_SELECT);
selectSt = i + 1;
break;
case STATE_SELECT:
switch (chars[i]) {
case '(':
state.push(STATE_PARENTESIS);
break;
case '\'':
state.push(STATE_QUOTE);
break;
case 'F':
if (i == 0 || i > 0 && chars[i - 1] == ' ') {
posi = match(chars, i, FROM);
if (posi > 0) {
selectEd = i - 1;
state.pop();
state.push(STATE_FROM);
i = posi;
fromSt = i + 1;
}
}
break;
}
break;
case STATE_FROM:
switch (chars[i]) {
case '(':
state.push(STATE_PARENTESIS);
break;
case '\'':
state.push(STATE_QUOTE);
break;
case 'O':
posi = match(chars, i, ORDER_BY);
if (posi > 0) {
fromEd = i - 1;
state.pop();
state.push(STATE_ORDER);
i = posi;
orderSt = i + 1;
}
break;
}
break;
case STATE_QUOTE:
switch (chars[i]) {
case '\'':
posi = match(chars, i, DOUBLE_QUOTE);
if (posi > 0)
i = posi;
else
state.pop();
break;
}
break;
case STATE_PARENTESIS:
switch (chars[i]) {
case '(':
state.push(STATE_PARENTESIS);
break;
case '\'':
state.push(STATE_QUOTE);
break;
case ')':
state.pop();
break;
}
break;
}
if (state.peek() == STATE_ORDER)
break;
}
if (state.peek() == STATE_FROM)
fromEd = chars.length;
if (fromEd == -1)
return;
if (selectEd == -1) // hql可能没有select
select = "";
else
select = sql.substring(selectSt, selectEd);
from = sql.substring(fromSt, fromEd);
if (orderSt > 0)
order = sql.substring(orderSt);
}
public String getSelect() {
return select;
}
public String getFrom() {
return from;
}
public String getOrder() {
return order;
}
}