mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
108 lines
2.7 KiB
Java
108 lines
2.7 KiB
Java
package io.ebeaninternal.server.querydefn;
|
|
|
|
import javax.persistence.PersistenceException;
|
|
|
|
/**
|
|
* Parses a Object relational query statement into a OrmQueryDetail and OrmQueryAttributes.
|
|
* <p>
|
|
* The reason they are split into detail and attributes is that the AutoTune feature is used to
|
|
* replace the OrmQueryDetail leaving the attributes unchanged.
|
|
* </p>
|
|
*/
|
|
public class OrmQueryDetailParser {
|
|
|
|
private final OrmQueryDetail detail = new OrmQueryDetail();
|
|
|
|
private final SimpleTextParser parser;
|
|
|
|
public OrmQueryDetailParser(String oql) {
|
|
this.parser = new SimpleTextParser(oql);
|
|
}
|
|
|
|
public OrmQueryDetail parse() throws PersistenceException {
|
|
|
|
if (parser.isEmpty()) return detail;
|
|
|
|
parser.nextWord();
|
|
processInitial();
|
|
return detail;
|
|
}
|
|
|
|
private void processInitial() {
|
|
if (parser.isMatch("select")) {
|
|
readSelect();
|
|
} else if (parser.isMatch("find")) {
|
|
OrmQueryProperties props = readFindFetch();
|
|
detail.setBase(props);
|
|
} else {
|
|
process();
|
|
}
|
|
while (!parser.isFinished()) {
|
|
process();
|
|
}
|
|
}
|
|
|
|
private boolean isFetch() {
|
|
return parser.isMatch("fetch") || parser.isMatch("join");
|
|
}
|
|
|
|
private void process() {
|
|
if (isFetch()) {
|
|
detail.fetch(readFindFetch());
|
|
} else {
|
|
throw new PersistenceException("Query expected 'fetch', 'where','order by' or 'limit' keyword but got ["
|
|
+ parser.getWord() + "] \r " + parser.getOql());
|
|
}
|
|
}
|
|
|
|
private void readSelect() {
|
|
String props = parser.nextWord();
|
|
if (props.startsWith("(")) {
|
|
props = props.substring(1, props.length() - 1);
|
|
OrmQueryProperties base = new OrmQueryProperties(null, props);
|
|
detail.setBase(base);
|
|
parser.nextWord();
|
|
} else {
|
|
process();
|
|
}
|
|
}
|
|
|
|
private OrmQueryProperties readFindFetch() {
|
|
|
|
boolean readAlias = false;
|
|
|
|
String props = null;
|
|
String path = parser.nextWord();
|
|
String token;
|
|
while ((token = parser.nextWord()) != null) {
|
|
if (!readAlias && parser.isMatch("as")) {
|
|
// next token is alias
|
|
parser.nextWord();
|
|
readAlias = true;
|
|
|
|
} else if ('(' == token.charAt(0)) {
|
|
props = token;
|
|
parser.nextWord();
|
|
break;
|
|
|
|
} else if (isFindFetchEnd()) {
|
|
break;
|
|
|
|
} else if (!readAlias) {
|
|
readAlias = true;
|
|
|
|
} else {
|
|
throw new PersistenceException("Expected (props) or new 'fetch' 'where' but got " + token);
|
|
}
|
|
}
|
|
if (props != null) {
|
|
props = props.substring(1, props.length() - 1);
|
|
}
|
|
return new OrmQueryProperties(path, props);
|
|
}
|
|
|
|
private boolean isFindFetchEnd() {
|
|
return isFetch() || parser.isMatch("where") || parser.isMatch("order", "by");
|
|
}
|
|
}
|