/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.client.soda;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.List;
/**
* Object model of an EPL statement.
* <p>
* Applications can create an object model by instantiating this class and then setting the various clauses.
* When done, use {@link com.espertech.esper.client.EPAdministrator} to create a statement from the model.
* <p>
* Alternativly, a given textual EPL can be compiled into an object model representation via the compile method on
* {@link com.espertech.esper.client.EPAdministrator}.
* <p>
* Use the toEPL method to generate a textual EPL from an object model.
* <p>
* Minimally, and EPL statement consists of the select-clause and the where-clause. These are represented by {@link SelectClause}
* and {@link FromClause} respectively.
* <p>
* Here is a short example that create a simple EPL statement such as "select page, responseTime from PageLoad" :
* <pre>
* EPStatementObjectModel model = new EPStatementObjectModel();
* model.setSelectClause(SelectClause.create("page", "responseTime"));
* model.setPropertyEvalSpec(FromClause.create(FilterStream.create("PageLoad")));
* </pre>
* <p>
* The select-clause and from-clause must be set for the statement object model to be useable by the
* administrative API. All other clauses a optional.
* <p>
* Please see the documentation set for further examples.
*/
public class EPStatementObjectModel implements Serializable {
private static final long serialVersionUID = 0L;
private List<AnnotationPart> annotations;
private List<ExpressionDeclaration> expressionDeclarations;
private List<ScriptExpression> scriptExpressions;
private String contextName;
private UpdateClause updateClause;
private CreateVariableClause createVariable;
private CreateTableClause createTable;
private CreateWindowClause createWindow;
private CreateIndexClause createIndex;
private CreateSchemaClause createSchema;
private CreateContextClause createContext;
private CreateDataFlowClause createDataFlow;
private CreateExpressionClause createExpression;
private OnClause onExpr;
private InsertIntoClause insertInto;
private SelectClause selectClause;
private FromClause fromClause;
private Expression whereClause;
private GroupByClause groupByClause;
private Expression havingClause;
private OutputLimitClause outputLimitClause;
private OrderByClause orderByClause;
private RowLimitClause rowLimitClause;
private MatchRecognizeClause matchRecognizeClause;
private ForClause forClause;
private String treeObjectName;
private FireAndForgetClause fireAndForgetClause;
private IntoTableClause intoTableClause;
/**
* Ctor.
*/
public EPStatementObjectModel() {
}
/**
* Specify an insert-into-clause.
*
* @param insertInto specifies the insert-into-clause, or null to indicate that the clause is absent
*/
public void setInsertInto(InsertIntoClause insertInto) {
this.insertInto = insertInto;
}
/**
* Specify an insert-into-clause.
*
* @param insertInto specifies the insert-into-clause, or null to indicate that the clause is absent
* @return model
*/
public EPStatementObjectModel insertInto(InsertIntoClause insertInto) {
this.insertInto = insertInto;
return this;
}
/**
* Return the insert-into-clause, or null to indicate that the clause is absent.
*
* @return specification of the insert-into-clause, or null if none present
*/
public InsertIntoClause getInsertInto() {
return insertInto;
}
/**
* Specify a select-clause.
*
* @param selectClause specifies the select-clause, the select-clause cannot be null and must be set
*/
public void setSelectClause(SelectClause selectClause) {
this.selectClause = selectClause;
}
/**
* Specify a select-clause.
*
* @param selectClause specifies the select-clause, the select-clause cannot be null and must be set
* @return model
*/
public EPStatementObjectModel selectClause(SelectClause selectClause) {
this.selectClause = selectClause;
return this;
}
/**
* Return the select-clause.
*
* @return specification of the select-clause
*/
public SelectClause getSelectClause() {
return selectClause;
}
/**
* Specify a from-clause.
*
* @param fromClause specifies the from-clause, the from-clause cannot be null and must be set
*/
public void setFromClause(FromClause fromClause) {
this.fromClause = fromClause;
}
/**
* Specify a from-clause.
*
* @param fromClause specifies the from-clause, the from-clause cannot be null and must be set
* @return model
*/
public EPStatementObjectModel fromClause(FromClause fromClause) {
this.fromClause = fromClause;
return this;
}
/**
* Return the where-clause, or null to indicate that the clause is absent.
*
* @return specification of the where-clause, or null if none present
*/
public Expression getWhereClause() {
return whereClause;
}
/**
* Specify a where-clause.
*
* @param whereClause specifies the where-clause, which is optional and can be null
*/
public void setWhereClause(Expression whereClause) {
this.whereClause = whereClause;
}
/**
* Specify a where-clause.
*
* @param whereClause specifies the where-clause, which is optional and can be null
* @return model
*/
public EPStatementObjectModel whereClause(Expression whereClause) {
this.whereClause = whereClause;
return this;
}
/**
* Return the from-clause.
*
* @return specification of the from-clause
*/
public FromClause getFromClause() {
return fromClause;
}
/**
* Return the group-by-clause, or null to indicate that the clause is absent.
*
* @return specification of the group-by-clause, or null if none present
*/
public GroupByClause getGroupByClause() {
return groupByClause;
}
/**
* Specify a group-by-clause.
*
* @param groupByClause specifies the group-by-clause, which is optional and can be null
*/
public void setGroupByClause(GroupByClause groupByClause) {
this.groupByClause = groupByClause;
}
/**
* Specify a group-by-clause.
*
* @param groupByClause specifies the group-by-clause, which is optional and can be null
* @return model
*/
public EPStatementObjectModel groupByClause(GroupByClause groupByClause) {
this.groupByClause = groupByClause;
return this;
}
/**
* Return the having-clause, or null to indicate that the clause is absent.
*
* @return specification of the having-clause, or null if none present
*/
public Expression getHavingClause() {
return havingClause;
}
/**
* Specify a having-clause.
*
* @param havingClause specifies the having-clause, which is optional and can be null
*/
public void setHavingClause(Expression havingClause) {
this.havingClause = havingClause;
}
/**
* Specify a having-clause.
*
* @param havingClause specifies the having-clause, which is optional and can be null
* @return model
*/
public EPStatementObjectModel havingClause(Expression havingClause) {
this.havingClause = havingClause;
return this;
}
/**
* Return the order-by-clause, or null to indicate that the clause is absent.
*
* @return specification of the order-by-clause, or null if none present
*/
public OrderByClause getOrderByClause() {
return orderByClause;
}
/**
* Specify an order-by-clause.
*
* @param orderByClause specifies the order-by-clause, which is optional and can be null
*/
public void setOrderByClause(OrderByClause orderByClause) {
this.orderByClause = orderByClause;
}
/**
* Specify an order-by-clause.
*
* @param orderByClause specifies the order-by-clause, which is optional and can be null
* @return model
*/
public EPStatementObjectModel orderByClause(OrderByClause orderByClause) {
this.orderByClause = orderByClause;
return this;
}
/**
* Return the output-rate-limiting-clause, or null to indicate that the clause is absent.
*
* @return specification of the output-rate-limiting-clause, or null if none present
*/
public OutputLimitClause getOutputLimitClause() {
return outputLimitClause;
}
/**
* Specify an output-rate-limiting-clause.
*
* @param outputLimitClause specifies the output-rate-limiting-clause, which is optional and can be null
*/
public void setOutputLimitClause(OutputLimitClause outputLimitClause) {
this.outputLimitClause = outputLimitClause;
}
/**
* Specify an output-rate-limiting-clause.
*
* @param outputLimitClause specifies the output-rate-limiting-clause, which is optional and can be null
* @return model
*/
public EPStatementObjectModel outputLimitClause(OutputLimitClause outputLimitClause) {
this.outputLimitClause = outputLimitClause;
return this;
}
/**
* Renders the object model in it's EPL syntax textual representation.
*
* @return EPL representing the statement object model
* @throws IllegalStateException if required clauses do not exist
*/
public String toEPL() {
StringWriter writer = new StringWriter();
toEPL(new EPStatementFormatter(false), writer);
return writer.toString();
}
/**
* Rendering using the provided writer.
*
* @param writer to use
*/
public void toEPL(StringWriter writer) {
toEPL(new EPStatementFormatter(false), writer);
}
/**
* Rendering using the provided formatter.
*
* @param formatter to use
* @return rendered string
*/
public String toEPL(EPStatementFormatter formatter) {
StringWriter writer = new StringWriter();
toEPL(formatter, writer);
return writer.toString();
}
/**
* Renders the object model in it's EPL syntax textual representation, using a whitespace-formatter as provided.
*
* @param formatter the formatter to use
* @param writer writer to use
* @throws IllegalStateException if required clauses do not exist
*/
public void toEPL(EPStatementFormatter formatter, StringWriter writer) {
AnnotationPart.toEPL(writer, annotations, formatter);
ExpressionDeclaration.toEPL(writer, expressionDeclarations, formatter);
ScriptExpression.toEPL(writer, scriptExpressions, formatter);
if (contextName != null) {
formatter.beginContext(writer);
writer.append("context ");
writer.append(contextName);
}
if (createIndex != null) {
formatter.beginCreateIndex(writer);
createIndex.toEPL(writer);
return;
} else if (createSchema != null) {
formatter.beginCreateSchema(writer);
createSchema.toEPL(writer);
return;
} else if (createExpression != null) {
formatter.beginCreateExpression(writer);
createExpression.toEPL(writer);
return;
} else if (createContext != null) {
formatter.beginCreateContext(writer);
createContext.toEPL(writer, formatter);
return;
} else if (createWindow != null) {
formatter.beginCreateWindow(writer);
createWindow.toEPL(writer);
if (fromClause != null) {
FilterStream fs = (FilterStream) fromClause.getStreams().get(0);
if (fs.isRetainUnion()) {
writer.write(" retain-union");
}
}
writer.write(" as ");
if ((selectClause == null) || (selectClause.getSelectList().isEmpty()) && !createWindow.getColumns().isEmpty()) {
createWindow.toEPLCreateTablePart(writer);
} else {
selectClause.toEPL(writer, formatter, false, false);
fromClause.toEPL(writer, formatter);
createWindow.toEPLInsertPart(writer);
}
return;
} else if (createVariable != null) {
formatter.beginCreateVariable(writer);
createVariable.toEPL(writer);
return;
} else if (createTable != null) {
formatter.beginCreateTable(writer);
createTable.toEPL(writer);
return;
} else if (createDataFlow != null) {
formatter.beginCreateDataFlow(writer);
createDataFlow.toEPL(writer, formatter);
return;
}
boolean displayWhereClause = true;
if (updateClause != null) {
formatter.beginUpdate(writer);
updateClause.toEPL(writer);
} else if (onExpr != null) {
formatter.beginOnTrigger(writer);
writer.write("on ");
fromClause.getStreams().get(0).toEPL(writer, formatter);
if (onExpr instanceof OnDeleteClause) {
formatter.beginOnDelete(writer);
writer.write("delete from ");
((OnDeleteClause) onExpr).toEPL(writer);
} else if (onExpr instanceof OnUpdateClause) {
formatter.beginOnUpdate(writer);
writer.write("update ");
((OnUpdateClause) onExpr).toEPL(writer);
} else if (onExpr instanceof OnSelectClause) {
OnSelectClause onSelect = (OnSelectClause) onExpr;
if (insertInto != null) {
insertInto.toEPL(writer, formatter, true);
}
selectClause.toEPL(writer, formatter, true, onSelect.isDeleteAndSelect());
writer.write(" from ");
onSelect.toEPL(writer);
} else if (onExpr instanceof OnSetClause) {
OnSetClause onSet = (OnSetClause) onExpr;
onSet.toEPL(writer, formatter);
} else if (onExpr instanceof OnMergeClause) {
OnMergeClause merge = (OnMergeClause) onExpr;
merge.toEPL(writer, whereClause, formatter);
displayWhereClause = false;
} else {
OnInsertSplitStreamClause split = (OnInsertSplitStreamClause) onExpr;
insertInto.toEPL(writer, formatter, true);
selectClause.toEPL(writer, formatter, true, false);
if (whereClause != null) {
writer.write(" where ");
whereClause.toEPL(writer, ExpressionPrecedenceEnum.MINIMUM);
}
split.toEPL(writer, formatter);
displayWhereClause = false;
}
} else {
if (intoTableClause != null) {
intoTableClause.toEPL(writer);
}
if (selectClause == null) {
throw new IllegalStateException("Select-clause has not been defined");
}
if (fromClause == null) {
throw new IllegalStateException("From-clause has not been defined");
}
if (fireAndForgetClause instanceof FireAndForgetUpdate) {
FireAndForgetUpdate update = (FireAndForgetUpdate) fireAndForgetClause;
writer.append("update ");
fromClause.toEPLOptions(writer, formatter, false);
writer.append(" ");
UpdateClause.renderEPLAssignments(writer, update.getAssignments());
} else if (fireAndForgetClause instanceof FireAndForgetInsert) {
FireAndForgetInsert insert = (FireAndForgetInsert) fireAndForgetClause;
insertInto.toEPL(writer, formatter, true);
if (insert.isUseValuesKeyword()) {
writer.append(" values (");
String delimiter = "";
for (SelectClauseElement element : selectClause.getSelectList()) {
writer.write(delimiter);
element.toEPLElement(writer);
delimiter = ", ";
}
writer.append(")");
} else {
selectClause.toEPL(writer, formatter, true, false);
}
} else if (fireAndForgetClause instanceof FireAndForgetDelete) {
writer.append("delete ");
fromClause.toEPLOptions(writer, formatter, true);
} else {
if (insertInto != null) {
insertInto.toEPL(writer, formatter, true);
}
selectClause.toEPL(writer, formatter, true, false);
fromClause.toEPLOptions(writer, formatter, true);
}
}
if (matchRecognizeClause != null) {
matchRecognizeClause.toEPL(writer);
}
if (whereClause != null && displayWhereClause) {
formatter.beginWhere(writer);
writer.write("where ");
whereClause.toEPL(writer, ExpressionPrecedenceEnum.MINIMUM);
}
if (groupByClause != null) {
formatter.beginGroupBy(writer);
writer.write("group by ");
groupByClause.toEPL(writer);
}
if (havingClause != null) {
formatter.beginHaving(writer);
writer.write("having ");
havingClause.toEPL(writer, ExpressionPrecedenceEnum.MINIMUM);
}
if (outputLimitClause != null) {
formatter.beginOutput(writer);
writer.write("output ");
outputLimitClause.toEPL(writer);
}
if (orderByClause != null) {
formatter.beginOrderBy(writer);
writer.write("order by ");
orderByClause.toEPL(writer);
}
if (rowLimitClause != null) {
formatter.beginLimit(writer);
writer.write("limit ");
rowLimitClause.toEPL(writer);
}
if (forClause != null) {
formatter.beginFor(writer);
forClause.toEPL(writer);
}
}
/**
* Returns the create-window clause for creating named windows, or null if this statement does not
* create a named window.
*
* @return named window creation clause
*/
public CreateWindowClause getCreateWindow() {
return createWindow;
}
/**
* Sets the create-window clause for creating named windows, or null if this statement does not
* create a named window.
*
* @param createWindow is the named window creation clause
*/
public void setCreateWindow(CreateWindowClause createWindow) {
this.createWindow = createWindow;
}
/**
* Returns the on-delete clause for deleting from named windows, or null if this statement
* does not delete from a named window
*
* @return on delete clause
*/
public OnClause getOnExpr() {
return onExpr;
}
/**
* Sets the on-delete or on-select clause for selecting or deleting from named windows, or null if this statement
* does not on-select or on-delete from a named window
*
* @param onExpr is the on-expression (on-select and on-delete) clause to set
*/
public void setOnExpr(OnClause onExpr) {
this.onExpr = onExpr;
}
/**
* Returns the create-variable clause if this is a statement creating a variable, or null if not.
*
* @return create-variable clause
*/
public CreateVariableClause getCreateVariable() {
return createVariable;
}
/**
* Sets the create-variable clause if this is a statement creating a variable, or null if not.
*
* @param createVariable create-variable clause
*/
public void setCreateVariable(CreateVariableClause createVariable) {
this.createVariable = createVariable;
}
/**
* Returns the row limit specification, or null if none supplied.
*
* @return row limit spec if any
*/
public RowLimitClause getRowLimitClause() {
return rowLimitClause;
}
/**
* Sets the row limit specification, or null if none applicable.
*
* @param rowLimitClause row limit spec if any
*/
public void setRowLimitClause(RowLimitClause rowLimitClause) {
this.rowLimitClause = rowLimitClause;
}
/**
* Returns the update specification.
*
* @return update spec if defined
*/
public UpdateClause getUpdateClause() {
return updateClause;
}
/**
* Sets the update specification.
*
* @param updateClause update spec if defined
*/
public void setUpdateClause(UpdateClause updateClause) {
this.updateClause = updateClause;
}
/**
* Returns annotations.
*
* @return annotations
*/
public List<AnnotationPart> getAnnotations() {
return annotations;
}
/**
* Sets annotations.
*
* @param annotations to set
*/
public void setAnnotations(List<AnnotationPart> annotations) {
this.annotations = annotations;
}
/**
* Match-recognize clause.
*
* @return clause
*/
public MatchRecognizeClause getMatchRecognizeClause() {
return matchRecognizeClause;
}
/**
* Sets match-recognize clause.
*
* @param clause to set
*/
public void setMatchRecognizeClause(MatchRecognizeClause clause) {
this.matchRecognizeClause = clause;
}
/**
* Returns create-index clause.
*
* @return clause
*/
public CreateIndexClause getCreateIndex() {
return createIndex;
}
/**
* Sets create-index clause.
*
* @param createIndex to set
*/
public void setCreateIndex(CreateIndexClause createIndex) {
this.createIndex = createIndex;
}
/**
* Returns the create-schema clause.
*
* @return clause
*/
public CreateSchemaClause getCreateSchema() {
return createSchema;
}
/**
* Sets the create-schema clause.
*
* @param createSchema clause to set
*/
public void setCreateSchema(CreateSchemaClause createSchema) {
this.createSchema = createSchema;
}
/**
* Returns the create-context clause.
*
* @return clause
*/
public CreateContextClause getCreateContext() {
return createContext;
}
/**
* Sets the create-context clause.
*
* @param createContext clause to set
*/
public void setCreateContext(CreateContextClause createContext) {
this.createContext = createContext;
}
/**
* Returns the for-clause.
*
* @return for-clause
*/
public ForClause getForClause() {
return forClause;
}
/**
* Sets the for-clause.
*
* @param forClause for-clause
*/
public void setForClause(ForClause forClause) {
this.forClause = forClause;
}
/**
* Returns the expression declarations, if any.
*
* @return expression declarations
*/
public List<ExpressionDeclaration> getExpressionDeclarations() {
return expressionDeclarations;
}
/**
* Sets the expression declarations, if any.
*
* @param expressionDeclarations expression declarations to set
*/
public void setExpressionDeclarations(List<ExpressionDeclaration> expressionDeclarations) {
this.expressionDeclarations = expressionDeclarations;
}
/**
* Returns the context name if context dimensions apply to statement.
*
* @return context name
*/
public String getContextName() {
return contextName;
}
/**
* Sets the context name if context dimensions apply to statement.
*
* @param contextName context name
*/
public void setContextName(String contextName) {
this.contextName = contextName;
}
/**
* Returns the scripts defined.
*
* @return scripts
*/
public List<ScriptExpression> getScriptExpressions() {
return scriptExpressions;
}
/**
* Sets the scripts.
*
* @param scriptExpressions to set
*/
public void setScriptExpressions(List<ScriptExpression> scriptExpressions) {
this.scriptExpressions = scriptExpressions;
}
/**
* Returns the "create dataflow" part, if present.
*
* @return create dataflow clause
*/
public CreateDataFlowClause getCreateDataFlow() {
return createDataFlow;
}
/**
* Sets the "create dataflow" part,.
*
* @param createDataFlow create dataflow clause
*/
public void setCreateDataFlow(CreateDataFlowClause createDataFlow) {
this.createDataFlow = createDataFlow;
}
/**
* Returns the internal expression id assigned for tools to identify the expression.
*
* @return object name
*/
public String getTreeObjectName() {
return treeObjectName;
}
/**
* Sets an internal expression id assigned for tools to identify the expression.
*
* @param treeObjectName object name
*/
public void setTreeObjectName(String treeObjectName) {
this.treeObjectName = treeObjectName;
}
/**
* Returns the create-expression clause, if any
*
* @return clause
*/
public CreateExpressionClause getCreateExpression() {
return createExpression;
}
/**
* Sets the create-expression clause, if any
*
* @param createExpression clause
*/
public void setCreateExpression(CreateExpressionClause createExpression) {
this.createExpression = createExpression;
}
/**
* Returns fire-and-forget (on-demand) query information for FAF select, insert, update and delete.
*
* @return fire and forget query information
*/
public FireAndForgetClause getFireAndForgetClause() {
return fireAndForgetClause;
}
/**
* Sets fire-and-forget (on-demand) query information for FAF select, insert, update and delete.
*
* @param fireAndForgetClause fire and forget query information
*/
public void setFireAndForgetClause(FireAndForgetClause fireAndForgetClause) {
this.fireAndForgetClause = fireAndForgetClause;
}
/**
* Returns the into-table clause, or null if none found.
*
* @return into-table clause
*/
public IntoTableClause getIntoTableClause() {
return intoTableClause;
}
/**
* Sets the into-table clause, or null if none found.
*
* @param intoTableClause into-table clause
*/
public void setIntoTableClause(IntoTableClause intoTableClause) {
this.intoTableClause = intoTableClause;
}
/**
* Returns the create-table clause if present or null if not present
*
* @return create-table clause
*/
public CreateTableClause getCreateTable() {
return createTable;
}
/**
* Sets the create-table clause if present or null if not present
*
* @param createTable create-table clause
*/
public void setCreateTable(CreateTableClause createTable) {
this.createTable = createTable;
}
}