All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avaje.ebeaninternal.server.querydefn.OrmQueryDetailParser Maven / Gradle / Ivy

There is a newer version: 8.1.1
Show newest version
package com.avaje.ebeaninternal.server.querydefn;

import javax.persistence.PersistenceException;

/**
 * Parses a Object relational query statement into a OrmQueryDetail and OrmQueryAttributes.
 * 

* The reason they are split into detail and attributes is that the AutoTune feature is used to * replace the OrmQueryDetail leaving the attributes unchanged. *

*/ public class OrmQueryDetailParser { private final OrmQueryDetail detail = new OrmQueryDetail(); private int maxRows; private int firstRow; private String rawWhereClause; private String rawOrderBy; 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 if (parser.isMatch("where")) { readWhere(); } else if (parser.isMatch("order", "by")) { readOrderBy(); } else if (parser.isMatch("limit")) { readLimit(); } else { throw new PersistenceException("Query expected 'fetch', 'where','order by' or 'limit' keyword but got [" + parser.getWord() + "] \r " + parser.getOql()); } } private void readLimit() { try { String maxLimit = parser.nextWord(); maxRows = Integer.parseInt(maxLimit); String offsetKeyword = parser.nextWord(); if (offsetKeyword != null) { if (!parser.isMatch("offset")) { throw new PersistenceException("expected offset keyword but got " + parser.getWord()); } String firstRowLimit = parser.nextWord(); firstRow = Integer.parseInt(firstRowLimit); parser.nextWord(); } } catch (NumberFormatException e) { String msg = "Expected an integer for maxRows or firstRows in limit offset clause"; throw new PersistenceException(msg, e); } } private void readOrderBy() { // read the by parser.nextWord(); StringBuilder sb = new StringBuilder(); while (parser.nextWord() != null) { if (parser.isMatch("limit")) { break; } else { String w = parser.getWord(); if (!w.startsWith("(")) { sb.append(" "); } sb.append(w); } } rawOrderBy = sb.toString().trim(); if (!parser.isFinished()) { readLimit(); } } private void readWhere() { int nextMode = 0; StringBuilder sb = new StringBuilder(); while ((parser.nextWord()) != null) { if (parser.isMatch("order", "by")) { nextMode = 1; break; } else if (parser.isMatch("limit")) { nextMode = 2; break; } else { sb.append(" ").append(parser.getWord()); } } String whereClause = sb.toString().trim(); if (!whereClause.isEmpty()) { rawWhereClause = whereClause; } if (nextMode == 1) { readOrderBy(); } else if (nextMode == 2) { readLimit(); } } 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"); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy