Search in sources :

Example 1 with JqlBaseListener

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;
}
Also used : JqlBaseListener(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlBaseListener) Bind_parameterContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Bind_parameterContext) BindSqlSelect(com.abubusoft.kripton.android.annotation.BindSqlSelect) SQLiteDaoDefinition(com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition)

Example 2 with JqlBaseListener

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;
}
Also used : Projected_columnsContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Projected_columnsContext) Where_stmtContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Where_stmtContext) Conflict_algorithmContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Conflict_algorithmContext) One(com.abubusoft.kripton.common.One) Columns_to_updateContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Columns_to_updateContext) JqlBaseListener(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlBaseListener) Bind_parameterContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Bind_parameterContext) BindSqlUpdate(com.abubusoft.kripton.android.annotation.BindSqlUpdate) Where_stmt_clausesContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Where_stmt_clausesContext) SQLiteDaoDefinition(com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition) ModifyType(com.abubusoft.kripton.processor.sqlite.SqlModifyBuilder.ModifyType)

Example 3 with JqlBaseListener

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;
}
Also used : Projected_columnsContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Projected_columnsContext) Where_stmtContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Where_stmtContext) Conflict_algorithmContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Conflict_algorithmContext) One(com.abubusoft.kripton.common.One) JqlBaseListener(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlBaseListener) Bind_parameterContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Bind_parameterContext) BindSqlInsert(com.abubusoft.kripton.android.annotation.BindSqlInsert) SQLiteDaoDefinition(com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition) Column_value_setContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Column_value_setContext) InsertType(com.abubusoft.kripton.processor.sqlite.SqlInsertBuilder.InsertType)

Example 4 with JqlBaseListener

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;
}
Also used : BindSqlDelete(com.abubusoft.kripton.android.annotation.BindSqlDelete) JqlBaseListener(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlBaseListener) Bind_parameterContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Bind_parameterContext) SQLiteDaoDefinition(com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition)

Example 5 with JqlBaseListener

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");
}
Also used : JQLContext(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLContext) JQLChecker(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLChecker) JQLReplacerListenerImpl(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLReplacerListenerImpl) JQLDynamicStatementType(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQL.JQLDynamicStatementType) JQL(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQL) Bind_dynamic_sqlContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Bind_dynamic_sqlContext) JqlBaseListener(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlBaseListener) Column_nameContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Column_nameContext) Bind_parameterContext(com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Bind_parameterContext) BaseProcessorTest(base.BaseProcessorTest) Test(org.junit.Test)

Aggregations

JqlBaseListener (com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlBaseListener)12 One (com.abubusoft.kripton.common.One)7 Bind_parameterContext (com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Bind_parameterContext)7 Projected_columnsContext (com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Projected_columnsContext)4 SQLiteDaoDefinition (com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition)4 Bind_dynamic_sqlContext (com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Bind_dynamic_sqlContext)3 Where_stmtContext (com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Where_stmtContext)3 ArrayList (java.util.ArrayList)3 Column_nameContext (com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Column_nameContext)2 Column_name_setContext (com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Column_name_setContext)2 Column_value_setContext (com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Column_value_setContext)2 Columns_to_updateContext (com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Columns_to_updateContext)2 Conflict_algorithmContext (com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Conflict_algorithmContext)2 Sql_stmtContext (com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Sql_stmtContext)2 LinkedHashSet (java.util.LinkedHashSet)2 BaseProcessorTest (base.BaseProcessorTest)1 BindSqlDelete (com.abubusoft.kripton.android.annotation.BindSqlDelete)1 BindSqlInsert (com.abubusoft.kripton.android.annotation.BindSqlInsert)1 BindSqlSelect (com.abubusoft.kripton.android.annotation.BindSqlSelect)1 BindSqlUpdate (com.abubusoft.kripton.android.annotation.BindSqlUpdate)1