use of com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlBaseListener in project kripton by xcesco.
the class JQLBuilder method buildJQLSelect.
private static JQL buildJQLSelect(final SQLiteModelMethod method, final JQL result, Map<JQLDynamicStatementType, String> dynamicReplace, String preparedJql) {
final Class<? extends Annotation> annotation = BindSqlSelect.class;
final SQLiteDaoDefinition dao = method.getParent();
if (StringUtils.hasText(preparedJql)) {
result.value = preparedJql;
// in SELECT SQL only where statement can contains bind parameter
JQLChecker.getInstance().analyze(method, result, new JqlBaseListener() {
@Override
public void enterBind_parameter(Bind_parameterContext ctx) {
result.bindParameterOnWhereStatementCounter++;
}
});
JQLChecker.getInstance().replaceVariableStatements(method, preparedJql, new JQLReplaceVariableStatementListenerImpl() {
@Override
public String onWhere(String statement) {
result.annotatedWhere = true;
result.staticWhereConditions = true;
return null;
}
@Override
public String onOrderBy(String statement) {
result.annotatedOrderBy = true;
result.staticOrderBy = true;
return null;
}
@Override
public String onOffset(String statement) {
result.annotatedOffset = true;
return null;
}
@Override
public String onLimit(String statement) {
result.annotatedLimit = true;
return null;
}
@Override
public String onHaving(String statement) {
result.annotatedHaving = true;
return null;
}
@Override
public String onGroup(String statement) {
result.annotatedGroupBy = true;
return null;
}
});
} else {
// extract some informaction from method and bean
// use annotation's attribute value and exclude and bean definition
// to
// define field list
final Set<String> fields = extractFieldsFromAnnotation(method, BindSqlSelect.class, true);
boolean distinct = AnnotationUtility.extractAsBoolean(method.getElement(), annotation, AnnotationAttributeType.DISTINCT);
String annotatedGroupBy = AnnotationUtility.extractAsString(method.getElement(), annotation, AnnotationAttributeType.GROUP_BY);
String annotatedHaving = AnnotationUtility.extractAsString(method.getElement(), annotation, AnnotationAttributeType.HAVING);
StringBuilder builder = new StringBuilder();
builder.append(SELECT_KEYWORD + " ");
//
if (distinct) {
builder.append(DISTINCT_KEYWORD + " ");
}
// recreate fields
builder.append(forEachFields(fields, new OnFieldListener() {
@Override
public String onField(String item) {
return item;
}
}));
// entity name
builder.append(" " + FROM_KEYWORD + " " + dao.getEntitySimplyClassName());
// where
builder.append(defineWhereStatement(method, result, annotation, dynamicReplace));
// group by
if (StringUtils.hasText(annotatedGroupBy)) {
result.annotatedGroupBy = true;
builder.append(" " + GROUP_BY_KEYWORD + " " + annotatedGroupBy);
}
// having
if (StringUtils.hasText(annotatedHaving)) {
result.annotatedHaving = true;
builder.append(" " + HAVING_KEYWORD + " " + annotatedHaving);
}
// order by
builder.append(defineOrderByStatement(method, result, annotation, dynamicReplace));
// limit
builder.append(defineLimitStatement(method, result, annotation, dynamicReplace));
result.value = builder.toString();
}
result.operationType = JQLType.SELECT;
result.dynamicReplace = dynamicReplace;
return result;
}
use of com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlBaseListener in project kripton by xcesco.
the class JQLBuilder method buildJQLUpdate.
/**
* <pre>
* UPDATE bean01 SET text=${text} WHERE id=${id}
* </pre>
*
* @param method
* @param preparedJql
* @return
*/
private static JQL buildJQLUpdate(final SQLiteModelMethod method, final JQL result, Map<JQLDynamicStatementType, String> dynamicReplace, String preparedJql) {
final Class<? extends Annotation> annotation = BindSqlUpdate.class;
if (StringUtils.hasText(preparedJql)) {
result.value = preparedJql;
// UPDATE can contains bind parameter in column values and select
// statement
final One<Boolean> inWhereCondition = new One<Boolean>(false);
final One<Boolean> inColumnsToUpdate = new One<Boolean>(false);
JQLChecker.getInstance().analyze(method, result, new JqlBaseListener() {
@Override
public void enterProjected_columns(Projected_columnsContext ctx) {
if (inColumnsToUpdate.value0) {
result.containsSelectOperation = true;
}
}
@Override
public void enterConflict_algorithm(Conflict_algorithmContext ctx) {
result.conflictAlgorithmType = ConflictAlgorithmType.valueOf(ctx.getText().toUpperCase());
}
@Override
public void enterWhere_stmt(Where_stmtContext ctx) {
inWhereCondition.value0 = true;
}
@Override
public void exitWhere_stmt_clauses(Where_stmt_clausesContext ctx) {
inWhereCondition.value0 = false;
}
@Override
public void enterBind_parameter(Bind_parameterContext ctx) {
if (inWhereCondition.value0) {
result.bindParameterOnWhereStatementCounter++;
} else {
result.bindParameterAsColumnValueCounter++;
}
}
@Override
public void enterColumns_to_update(Columns_to_updateContext ctx) {
inColumnsToUpdate.value0 = true;
}
@Override
public void exitColumns_to_update(Columns_to_updateContext ctx) {
inColumnsToUpdate.value0 = false;
}
});
JQLChecker.getInstance().replaceVariableStatements(method, preparedJql, new JQLReplaceVariableStatementListenerImpl() {
@Override
public String onWhere(String statement) {
result.annotatedWhere = true;
result.staticWhereConditions = true;
return null;
}
});
if (result.containsSelectOperation) {
AssertKripton.assertTrueOrInvalidMethodSignException(method.getReturnClass().equals(TypeName.VOID), method, "defined JQL requires that method's return type is void");
}
} else {
final SQLiteDaoDefinition dao = method.getParent();
Set<String> fields;
ModifyType modifyType = SqlModifyBuilder.detectModifyType(method, JQLType.UPDATE);
if (modifyType == ModifyType.UPDATE_BEAN) {
fields = extractFieldsFromAnnotation(method, annotation, false);
} else {
fields = extractFieldsFromMethodParameters(method, annotation);
}
AssertKripton.assertTrueOrInvalidMethodSignException(fields.size() > 0, method, "no field was specified for update");
result.conflictAlgorithmType = ConflictAlgorithmType.valueOf(AnnotationUtility.extractAsEnumerationValue(method.getElement(), annotation, AnnotationAttributeType.CONFLICT_ALGORITHM_TYPE));
StringBuilder builder = new StringBuilder();
builder.append(UPDATE_KEYWORD);
builder.append(" " + result.conflictAlgorithmType.getSqlForInsert());
// entity name
builder.append(dao.getEntitySimplyClassName());
// recreate fields
final One<String> prefix = new One<>("");
if (result.hasParamBean()) {
prefix.value0 = result.paramBean + ".";
}
builder.append(" " + SET_KEYWORD + " ");
builder.append(forEachFields(fields, new OnFieldListener() {
@Override
public String onField(String item) {
return item + "=${" + prefix.value0 + item + "}";
}
}));
builder.append(defineWhereStatement(method, result, annotation, dynamicReplace));
result.value = builder.toString();
}
result.operationType = JQLType.UPDATE;
result.dynamicReplace = dynamicReplace;
return result;
}
use of com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlBaseListener in project kripton by xcesco.
the class JQLBuilder method buildJQLInsert.
/**
* <pre>
*
* INSERT INTO person (name, surname, birth_city, birth_day) VALUES (${name}, ${surname}, ${birthCity}, ${birthDay})
* </pre>
*
* @param method
* @param preparedJql
* @return
*/
private static JQL buildJQLInsert(SQLiteModelMethod method, final JQL result, String preparedJql) {
if (StringUtils.hasText(preparedJql)) {
result.value = preparedJql;
// INSERT can contains bind parameter in column values and select
// statement
final One<Boolean> inColumnValueSet = new One<Boolean>(false);
final One<Boolean> inWhereStatement = new One<Boolean>(false);
JQLChecker.getInstance().analyze(method, result, new JqlBaseListener() {
@Override
public void enterConflict_algorithm(Conflict_algorithmContext ctx) {
result.conflictAlgorithmType = ConflictAlgorithmType.valueOf(ctx.getText().toUpperCase());
}
@Override
public void enterProjected_columns(Projected_columnsContext ctx) {
result.containsSelectOperation = true;
}
@Override
public void enterWhere_stmt(Where_stmtContext ctx) {
inWhereStatement.value0 = true;
}
@Override
public void exitWhere_stmt(Where_stmtContext ctx) {
inWhereStatement.value0 = false;
}
@Override
public void enterColumn_value_set(Column_value_setContext ctx) {
inColumnValueSet.value0 = true;
}
@Override
public void exitColumn_value_set(Column_value_setContext ctx) {
inColumnValueSet.value0 = false;
}
@Override
public void enterBind_parameter(Bind_parameterContext ctx) {
if (inWhereStatement.value0) {
result.bindParameterOnWhereStatementCounter++;
} else if (inColumnValueSet.value0) {
result.bindParameterAsColumnValueCounter++;
}
AssertKripton.assertTrue(inWhereStatement.value0 || inColumnValueSet.value0, "unknown situation!");
}
});
if (result.containsSelectOperation) {
AssertKripton.assertTrueOrInvalidMethodSignException(method.getReturnClass().equals(TypeName.VOID), method, "defined JQL requires that method's return type is void");
}
// ASSERT: a INSERT-SELECT SQL can not contains parameters on values
// section.
} else {
// use annotation's attribute value and exclude and bean definition
// to
final Class<? extends Annotation> annotation = BindSqlInsert.class;
final SQLiteDaoDefinition dao = method.getParent();
final boolean includePrimaryKey = AnnotationUtility.extractAsBoolean(method.getElement(), annotation, AnnotationAttributeType.INCLUDE_PRIMARY_KEY);
// define field list
// every method parameter can be used only as insert field
InsertType insertResultType = SqlInsertBuilder.detectInsertType(method);
Set<String> fields;
if (insertResultType == InsertType.INSERT_BEAN) {
fields = extractFieldsFromAnnotation(method, annotation, includePrimaryKey);
} else {
fields = extractFieldsFromMethodParameters(method, annotation);
}
result.conflictAlgorithmType = ConflictAlgorithmType.valueOf(AnnotationUtility.extractAsEnumerationValue(method.getElement(), annotation, AnnotationAttributeType.CONFLICT_ALGORITHM_TYPE));
StringBuilder builder = new StringBuilder();
builder.append(INSERT_KEYWORD);
builder.append(" " + result.conflictAlgorithmType.getSqlForInsert());
builder.append(INTO_KEYWORD);
builder.append(" " + dao.getEntitySimplyClassName());
builder.append(" (");
builder.append(forEachFields(fields, new OnFieldListener() {
@Override
public String onField(String item) {
return item;
}
}));
builder.append(") ");
builder.append(VALUES_KEYWORD);
final One<String> prefix = new One<>("");
if (result.hasParamBean()) {
prefix.value0 = result.paramBean + ".";
}
builder.append(" (");
builder.append(forEachFields(fields, new OnFieldListener() {
@Override
public String onField(String item) {
return "${" + prefix.value0 + item + "}";
}
}));
builder.append(")");
result.value = builder.toString();
}
result.operationType = JQLType.INSERT;
result.dynamicReplace = new HashMap<>();
return result;
}
use of com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlBaseListener in project kripton by xcesco.
the class JQLBuilder method buildJQLDelete.
/**
* <pre>
* DELETE person WHERE id = ${bean.id} AND #{where}
* </pre>
*
* @param method
* @param preparedJql
* @return
*/
private static JQL buildJQLDelete(SQLiteModelMethod method, final JQL result, Map<JQLDynamicStatementType, String> dynamicReplace, String preparedJql) {
final SQLiteDaoDefinition dao = method.getParent();
if (StringUtils.hasText(preparedJql)) {
// in DELETE SQL only where statement can contains bind parameter
result.value = preparedJql;
JQLChecker.getInstance().analyze(method, result, new JqlBaseListener() {
@Override
public void enterBind_parameter(Bind_parameterContext ctx) {
result.bindParameterOnWhereStatementCounter++;
}
});
// where management
JQLChecker.getInstance().replaceVariableStatements(method, preparedJql, new JQLReplaceVariableStatementListenerImpl() {
@Override
public String onWhere(String statement) {
result.annotatedWhere = true;
result.staticWhereConditions = true;
return null;
}
});
// if (result.containsSelectOperation) {
// AssertKripton.failWithInvalidMethodSignException(!TypeUtility.typeName(Void.TYPE).equals(method.getReturnClass()),
// method,
// "method that contains SQL with inner SELECT can return only
// void");
// }
} else {
StringBuilder builder = new StringBuilder();
builder.append(DELETE_KEYWORD + " " + FROM_KEYWORD);
// entity name
builder.append(" " + dao.getEntitySimplyClassName());
builder.append(defineWhereStatement(method, result, BindSqlDelete.class, dynamicReplace));
result.value = builder.toString();
}
result.operationType = JQLType.DELETE;
result.dynamicReplace = dynamicReplace;
return result;
}
use of com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlBaseListener in project kripton by xcesco.
the class TestJqlChecker method testOK.
/**
* <p>
* OK
* </p>
*
* @throws Throwable
*/
@Test
public void testOK() throws Throwable {
String sql = "SELECT id, action, number, countryCode, contactName, contactId FROM phone_number WHERE number = ${bean.number} and number like ${bean.number} || '%' and #{" + JQLDynamicStatementType.DYNAMIC_WHERE + "}";
log(sql);
JQL jql = new JQL();
jql.value = sql;
JQLChecker jsqChecker = JQLChecker.getInstance();
jsqChecker.analyze(dummyContext, jql, new JqlBaseListener() {
@Override
public void enterBind_parameter(Bind_parameterContext ctx) {
TestJqlChecker.this.log("xx parameter name %s", ctx.bind_parameter_name().getText());
}
@Override
public void enterBind_dynamic_sql(Bind_dynamic_sqlContext ctx) {
TestJqlChecker.this.log("xx dynamic %s", ctx.bind_parameter_name().getText());
}
@Override
public void enterColumn_name(Column_nameContext ctx) {
super.enterColumn_name(ctx);
log("column " + ctx.getText());
}
});
jsqChecker.extractPlaceHoldersAsList(new JQLContext() {
@Override
public String getContextDescription() {
return "test context";
}
}, jql.value);
log("replaced " + jsqChecker.replace(dummyContext, jql, new JQLReplacerListenerImpl(null) {
@Override
public String onDynamicSQL(JQLDynamicStatementType dynamicStatement) {
return String.format("\"+%s+\"", dynamicStatement);
}
@Override
public String onBindParameter(String bindParameterName) {
return "?";
}
@Override
public String onColumnFullyQualifiedName(String tableName, String columnName) {
// TODO Auto-generated method stub
return null;
}
}));
log("aa");
}
Aggregations