use of lucee.commons.lang.ParserString in project Lucee by lucee.
the class SelectParser method parse.
// select <select-statement> from <tables> where <where-statement>
public Selects parse(String sql) throws SQLParserException {
columnIndex = 0;
ParserString raw = new ParserString(sql.trim());
Selects selects = new Selects();
Select select = new Select();
boolean runAgain = false;
do {
// select
if (!raw.forwardIfCurrentAndNoWordNumberAfter("select"))
throw new SQLParserException("missing select");
raw.removeSpace();
// top
if (raw.forwardIfCurrentAndNoWordNumberAfter("top")) {
raw.removeSpace();
ValueNumber number = number(raw);
if (number == null)
throw new SQLParserException("missing top number");
select.setTop(number);
raw.removeSpace();
}
// distinct
if (raw.forwardIfCurrentAndNoWordNumberAfter("distinct")) {
select.setDistinct(true);
raw.removeSpace();
}
// all
if (raw.forwardIfCurrentAndNoWordNumberAfter("all")) {
select.setDistinct(false);
raw.removeSpace();
}
// select expression
selectExpressions(raw, select);
raw.removeSpace();
// from
if (!raw.forwardIfCurrentAndNoWordNumberAfter("from"))
throw new SQLParserException("missing from");
tableList(raw, select);
raw.removeSpace();
// where
if (raw.forwardIfCurrentAndNoWordNumberAfter("where"))
whereExpressions(raw, select);
raw.removeSpace();
// group by
if (raw.forwardIfCurrentAndNoWordNumberAfter("group by")) {
groupByExpressions(raw, select);
raw.removeSpace();
// having
if (raw.forwardIfCurrentAndNoWordNumberAfter("having"))
havingExpressions(raw, select);
raw.removeSpace();
}
selects.addSelect(select);
runAgain = false;
// union
if (raw.forwardIfCurrentAndNoWordNumberAfter("union")) {
select = new Select();
raw.removeSpace();
if (raw.forwardIfCurrentAndNoWordNumberAfter("all")) {
raw.removeSpace();
select.setUnionDistinct(false);
} else if (raw.forwardIfCurrentAndNoWordNumberAfter("distinct")) {
raw.removeSpace();
select.setUnionDistinct(true);
} else
select.setDistinct(true);
raw.removeSpace();
runAgain = true;
}
} while (runAgain);
// order by
if (raw.forwardIfCurrentAndNoWordNumberAfter("order by"))
orderByExpressions(raw, selects);
raw.removeSpace();
if (raw.forwardIfCurrent(';'))
raw.removeSpace();
if (!raw.isAfterLast())
throw new SQLParserException("can not read the full sql statement (stop at:" + raw.getCurrent() + ")");
return selects;
}
use of lucee.commons.lang.ParserString in project Lucee by lucee.
the class SelectParser method digit.
private String digit(ParserString raw) {
String rtn = "";
while (raw.isValidIndex()) {
if (!raw.isCurrentBetween('0', '9'))
break;
rtn += raw.getCurrentLower();
raw.next();
}
return rtn;
}
use of lucee.commons.lang.ParserString in project Lucee by lucee.
the class SelectParser method identifierBracked.
private String identifierBracked(ParserString raw) throws SQLParserException {
int start = raw.getPos();
do {
raw.next();
} while (raw.isValidIndex() && !raw.isCurrent(']'));
String str = raw.substring(start, raw.getPos() - start);
if (!raw.forwardIfCurrent(']'))
throw new SQLParserException("missing ending ] of identifier");
return str;
}
use of lucee.commons.lang.ParserString in project Lucee by lucee.
the class SelectParser method tableList.
private void tableList(ParserString raw, Select select) throws SQLParserException {
Column column = null;
Expression exp = null;
do {
raw.removeSpace();
exp = column(raw);
if (!(exp instanceof Column))
throw new SQLParserException("invalid table definition");
column = (Column) exp;
raw.removeSpace();
if (raw.forwardIfCurrent("as ")) {
String alias = identifier(raw, new RefBooleanImpl(false));
if (alias == null)
throw new SQLParserException("missing alias in select part");
column.setAlias(alias);
} else {
int start = raw.getPos();
RefBoolean hasBracked = new RefBooleanImpl(false);
// TODO having usw
String alias = identifier(raw, hasBracked);
if (!hasBracked.toBooleanValue()) {
if ("where".equalsIgnoreCase(alias))
raw.setPos(start);
else if ("group".equalsIgnoreCase(alias))
raw.setPos(start);
else if ("having".equalsIgnoreCase(alias))
raw.setPos(start);
else if ("union".equalsIgnoreCase(alias))
raw.setPos(start);
else if ("order".equalsIgnoreCase(alias))
raw.setPos(start);
else if ("limit".equalsIgnoreCase(alias))
raw.setPos(start);
else if (alias != null)
column.setAlias(alias);
} else {
if (alias != null)
column.setAlias(alias);
}
}
select.addFromExpression(column);
raw.removeSpace();
} while (raw.forwardIfCurrent(','));
}
use of lucee.commons.lang.ParserString in project Lucee by lucee.
the class SelectParser method number.
private ValueNumber number(ParserString raw) throws SQLParserException {
// check first character is a number literal representation
if (!(raw.isCurrentBetween('0', '9') || raw.isCurrent('.')))
return null;
StringBuffer rtn = new StringBuffer();
// get digit on the left site of the dot
if (raw.isCurrent('.'))
rtn.append('0');
else
rtn.append(digit(raw));
// read dot if exist
if (raw.forwardIfCurrent('.')) {
rtn.append('.');
String rightSite = digit(raw);
if (rightSite.length() > 0 && raw.forwardIfCurrent('e')) {
if (raw.isCurrentBetween('0', '9')) {
rightSite += 'e' + digit(raw);
} else {
raw.previous();
}
}
// read right side of the dot
if (rightSite.length() == 0)
throw new SQLParserException("Number can't end with [.]");
rtn.append(rightSite);
}
raw.removeSpace();
return new ValueNumber(rtn.toString());
}
Aggregations