Search in sources :

Example 16 with SQLProperty

use of com.abubusoft.kripton.processor.sqlite.model.SQLProperty in project kripton by xcesco.

the class CodeBuilderUtility method extractUsedProperties.

/**
 * Generate code necessary to put bean properties in content values map.
 * Return primary key
 * @param methodBuilder
 *            used to code generation
 * @param method
 * @param elementUtils
 * @param daoDefinition
 * @param alreadyUsedBeanPropertiesNames
 *            optional
 *
 * @return primary key.
 */
public static List<SQLProperty> extractUsedProperties(Builder methodBuilder, SQLiteModelMethod method, Class<? extends Annotation> annotationClazz) {
    SQLiteDaoDefinition daoDefinition = method.getParent();
    SQLiteEntity entity = daoDefinition.getEntity();
    List<SQLProperty> listPropertyInContentValue = new ArrayList<SQLProperty>();
    Set<String> foundColumns = JQLChecker.getInstance().extractColumnsToInsertOrUpdate(method, method.jql.value, entity);
    // for each property in entity except primaryKey and excluded properties
    for (SQLProperty item : entity.getCollection()) {
        if (foundColumns.size() > 0 && !foundColumns.contains(item.getName())) {
            continue;
        }
        // add property to list of used properties
        listPropertyInContentValue.add(item);
    }
    return listPropertyInContentValue;
}
Also used : SQLProperty(com.abubusoft.kripton.processor.sqlite.model.SQLProperty) ArrayList(java.util.ArrayList) SQLiteEntity(com.abubusoft.kripton.processor.sqlite.model.SQLiteEntity) SQLiteDaoDefinition(com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition)

Example 17 with SQLProperty

use of com.abubusoft.kripton.processor.sqlite.model.SQLProperty in project kripton by xcesco.

the class JQLReplacerListenerImpl method resolveFullyQualifiedColumnName.

/**
 * given a fully qualified property name, it will be transformed in
 * associated column name. If class or property does not exist, an exception
 * will be thrown
 *
 * @param schema
 * @param method
 * @param className
 * @param propertyName
 * @return resolved name ex: "person.birth_date"
 */
public static String resolveFullyQualifiedColumnName(SQLiteDatabaseSchema schema, SQLiteModelMethod method, String className, String propertyName) {
    Finder<SQLProperty> currentEntity = method.getParent().getEntity();
    if (StringUtils.hasText(className)) {
        currentEntity = schema.getEntityBySimpleName(className);
        AssertKripton.assertTrueOrUnknownClassInJQLException(currentEntity != null, method, className);
    }
    SQLProperty currentProperty = currentEntity.findPropertyByName(propertyName);
    AssertKripton.assertTrueOrUnknownPropertyInJQLException(currentProperty != null, method, propertyName);
    return (StringUtils.hasText(className) ? currentEntity.getTableName() + "." : "") + currentProperty.columnName;
}
Also used : SQLProperty(com.abubusoft.kripton.processor.sqlite.model.SQLProperty)

Example 18 with SQLProperty

use of com.abubusoft.kripton.processor.sqlite.model.SQLProperty in project kripton by xcesco.

the class BindDataSourceSubProcessor method analyzeForeignKey.

private void analyzeForeignKey(SQLiteDatabaseSchema schema) {
    for (SQLiteEntity entity : schema.getEntities()) {
        for (SQLProperty property : entity.getCollection()) {
            if (property.hasForeignKeyClassName()) {
                SQLiteEntity reference = schema.getEntity(property.foreignClassName);
                AssertKripton.asserTrueOrUnspecifiedBeanException(reference != null, schema, entity, property.foreignClassName);
                if (!entity.equals(reference)) {
                    entity.referedEntities.add(reference);
                }
            }
        }
    }
    for (SQLiteDaoDefinition dao : schema.getCollection()) {
        if (dao.getElement().getAnnotation(BindDaoMany2Many.class) != null) {
            ClassName entity1 = TypeUtility.className(AnnotationUtility.extractAsClassName(dao.getElement(), BindDaoMany2Many.class, AnnotationAttributeType.ENTITY_1));
            ClassName entity2 = TypeUtility.className(AnnotationUtility.extractAsClassName(dao.getElement(), BindDaoMany2Many.class, AnnotationAttributeType.ENTITY_2));
            // only if dao has an entity
            if (dao.getEntity() != null) {
                // check foreign key to entity1 and entity2
                checkForeignKeyForM2M(schema, dao.getEntity(), entity1);
                checkForeignKeyForM2M(schema, dao.getEntity(), entity2);
            }
        }
    }
}
Also used : BindDaoMany2Many(com.abubusoft.kripton.android.annotation.BindDaoMany2Many) SQLProperty(com.abubusoft.kripton.processor.sqlite.model.SQLProperty) ClassName(com.squareup.javapoet.ClassName) SQLiteEntity(com.abubusoft.kripton.processor.sqlite.model.SQLiteEntity) SQLiteDaoDefinition(com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition)

Example 19 with SQLProperty

use of com.abubusoft.kripton.processor.sqlite.model.SQLProperty in project kripton by xcesco.

the class TestJqlChecker method testSelect01.

/**
 * extract projections from a select
 */
@Test
public void testSelect01() {
    // String sql="SELECT count(*) FROM channel WHERE
    // updateTime=${bean.updateTime}";
    String sql = "SELECT count(*) as alias1, field2, field3 as alias3, table1.field3 as alias3, table2.field4 as alias4 FROM channel WHERE updateTime=${ bean.field1 } and field=${ field2  } and #{" + JQLDynamicStatementType.DYNAMIC_WHERE + "}";
    String logSql = "SELECT count(*) as alias1, field2, field3 as alias3, table1.field3 as alias3, table2.field4 as alias4 FROM channel WHERE updateTime=? and field=? and \"+DYNAMIC_WHERE+\"";
    // String usedSql = "SELECT count(*) FROM channel WHERE
    // updateTime=${bean.updateTime}";
    JQL jql = new JQL();
    jql.value = sql;
    JQLChecker checker = JQLChecker.getInstance();
    // verify sql
    checker.verify(dummyContext, jql);
    Finder<SQLProperty> entityMock = new Finder<SQLProperty>() {

        @Override
        public String getSimpleName() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public List<SQLProperty> getCollection() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public SQLProperty findPropertyByName(String name) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public String getTableName() {
            // TODO Auto-generated method stub
            return null;
        }
    };
    // check projections
    Set<JQLProjection> projections = checker.extractProjections(dummyContext, jql.value, entityMock);
    {
        LinkedHashSet<JQLProjection> aspected = new LinkedHashSet<>();
        aspected.add(JQLProjection.ProjectionBuilder.create().type(ProjectionType.COMPLEX).expression("count(*)").alias("alias1").build());
        aspected.add(JQLProjection.ProjectionBuilder.create().type(ProjectionType.COLUMN).column("field2").build());
        aspected.add(JQLProjection.ProjectionBuilder.create().type(ProjectionType.COLUMN).column("field3").alias("alias3").build());
        aspected.add(JQLProjection.ProjectionBuilder.create().type(ProjectionType.COLUMN).table("table1").column("field3").alias("alias3").build());
        aspected.add(JQLProjection.ProjectionBuilder.create().type(ProjectionType.COLUMN).table("table2").column("field4").alias("alias4").build());
        checkCollectionExactly(projections, aspected);
    }
    // check bind parameters
    {
        List<JQLPlaceHolder> aspected = new ArrayList<>();
        aspected.add(new JQLPlaceHolder(JQLPlaceHolderType.PARAMETER, "bean.field1"));
        aspected.add(new JQLPlaceHolder(JQLPlaceHolderType.PARAMETER, "field2"));
        aspected.add(new JQLPlaceHolder(JQLPlaceHolderType.DYNAMIC_SQL, JQLDynamicStatementType.DYNAMIC_WHERE.toString()));
        List<JQLPlaceHolder> actual = checker.extractPlaceHoldersAsList(dummyContext, jql.value);
        checkCollectionExactly(actual, aspected);
    }
    // prepare for log
    String sqlLogResult = checker.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) {
            return null;
        }
    });
    assertEquals("sql for log generation failed", logSql, sqlLogResult);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) JQLChecker(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLChecker) JQL(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQL) Finder(com.abubusoft.kripton.processor.core.Finder) JQLPlaceHolder(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLPlaceHolder) JQLReplacerListenerImpl(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLReplacerListenerImpl) JQLDynamicStatementType(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQL.JQLDynamicStatementType) JQLProjection(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLProjection) SQLProperty(com.abubusoft.kripton.processor.sqlite.model.SQLProperty) ArrayList(java.util.ArrayList) List(java.util.List) BaseProcessorTest(base.BaseProcessorTest) Test(org.junit.Test)

Example 20 with SQLProperty

use of com.abubusoft.kripton.processor.sqlite.model.SQLProperty in project kripton by xcesco.

the class AbstractSelectCodeGenerator method generateCommonPart.

public void generateCommonPart(SQLiteModelMethod method, TypeSpec.Builder classBuilder, MethodSpec.Builder methodBuilder, Set<JQLProjection> fieldList, boolean mapFields, GenerationType generationType, TypeName forcedReturnType, JavadocPart... javadocParts) {
    SQLiteDaoDefinition daoDefinition = method.getParent();
    SQLiteEntity entity = daoDefinition.getEntity();
    // if true, field must be associate to ben attributes
    // TypeName returnType = method.getReturnClass();
    TypeName returnTypeName = forcedReturnType;
    if (returnTypeName == null) {
        returnTypeName = method.getReturnClass();
    }
    ModelAnnotation annotation = method.getAnnotation(BindSqlSelect.class);
    // parameters
    List<String> paramNames = new ArrayList<String>();
    List<String> paramGetters = new ArrayList<String>();
    List<TypeName> paramTypeNames = new ArrayList<TypeName>();
    List<String> usedBeanPropertyNames = new ArrayList<>();
    // used method parameters
    Set<String> usedMethodParameters = new HashSet<String>();
    final One<String> whereJQL = new One<>("");
    final One<String> havingJQL = new One<>("");
    final One<String> groupJQL = new One<>("");
    final One<String> orderJQL = new One<>("");
    // extract parts of jql statement
    JQLChecker.getInstance().replaceVariableStatements(method, method.jql.value, new JQLReplaceVariableStatementListenerImpl() {

        @Override
        public String onWhere(String statement) {
            whereJQL.value0 = statement;
            return null;
        }

        @Override
        public String onOrderBy(String statement) {
            orderJQL.value0 = statement;
            return null;
        }

        @Override
        public String onHaving(String statement) {
            havingJQL.value0 = statement;
            return null;
        }

        @Override
        public String onGroup(String statement) {
            groupJQL.value0 = statement;
            return null;
        }
    });
    SqlAnalyzer analyzer = new SqlAnalyzer();
    // String whereSQL =
    // annotation.getAttribute(AnnotationAttributeType.WHERE);
    analyzer.execute(BaseProcessor.elementUtils, method, whereJQL.value0);
    paramGetters.addAll(analyzer.getParamGetters());
    paramNames.addAll(analyzer.getParamNames());
    paramTypeNames.addAll(analyzer.getParamTypeNames());
    usedBeanPropertyNames.addAll(analyzer.getUsedBeanPropertyNames());
    usedMethodParameters.addAll(analyzer.getUsedMethodParameters());
    // String havingSQL =
    // annotation.getAttribute(AnnotationAttributeType.HAVING);
    analyzer.execute(BaseProcessor.elementUtils, method, havingJQL.value0);
    paramGetters.addAll(analyzer.getParamGetters());
    paramNames.addAll(analyzer.getParamNames());
    paramTypeNames.addAll(analyzer.getParamTypeNames());
    usedBeanPropertyNames.addAll(analyzer.getUsedBeanPropertyNames());
    usedMethodParameters.addAll(analyzer.getUsedMethodParameters());
    // String groupBySQL =
    // annotation.getAttribute(AnnotationAttributeType.GROUP_BY);
    analyzer.execute(BaseProcessor.elementUtils, method, groupJQL.value0);
    paramGetters.addAll(analyzer.getParamGetters());
    paramNames.addAll(analyzer.getParamNames());
    paramTypeNames.addAll(analyzer.getParamTypeNames());
    usedBeanPropertyNames.addAll(analyzer.getUsedBeanPropertyNames());
    usedMethodParameters.addAll(analyzer.getUsedMethodParameters());
    // String orderBySQL =
    // annotation.getAttribute(AnnotationAttributeType.ORDER_BY);
    analyzer.execute(BaseProcessor.elementUtils, method, orderJQL.value0);
    paramGetters.addAll(analyzer.getParamGetters());
    paramNames.addAll(analyzer.getParamNames());
    paramTypeNames.addAll(analyzer.getParamTypeNames());
    usedBeanPropertyNames.addAll(analyzer.getUsedBeanPropertyNames());
    usedMethodParameters.addAll(analyzer.getUsedMethodParameters());
    // add as used parameter dynamic components too
    if (method.hasDynamicWhereConditions()) {
        AssertKripton.assertTrueOrInvalidMethodSignException(!usedMethodParameters.contains(method.dynamicWhereParameterName), method, " parameter %s is used like SQL parameter and dynamic WHERE condition.", method.dynamicOrderByParameterName);
        usedMethodParameters.add(method.dynamicWhereParameterName);
        if (method.hasDynamicWhereArgs()) {
            AssertKripton.assertTrueOrInvalidMethodSignException(!usedMethodParameters.contains(method.dynamicWhereArgsParameterName), method, " parameter %s is used like SQL parameter and dynamic WHERE ARGS condition.", method.dynamicWhereArgsParameterName);
            usedMethodParameters.add(method.dynamicWhereArgsParameterName);
        }
    }
    if (method.hasDynamicOrderByConditions()) {
        AssertKripton.assertTrueOrInvalidMethodSignException(!usedMethodParameters.contains(method.dynamicOrderByParameterName), method, " parameter %s is used like SQL parameter and dynamic ORDER BY condition.", method.dynamicOrderByParameterName);
        usedMethodParameters.add(method.dynamicOrderByParameterName);
    }
    if (method.hasDynamicPageSizeConditions()) {
        AssertKripton.assertTrueOrInvalidMethodSignException(!usedMethodParameters.contains(method.dynamicPageSizeName), method, " parameter %s is used like SQL parameter and dynamic page size of LIMIT condition.", method.dynamicPageSizeName);
        usedMethodParameters.add(method.dynamicPageSizeName);
    }
    // generate method signature
    if (generationType.generateMethodSign) {
        generateMethodSignature(method, methodBuilder, returnTypeName);
    }
    // generate javadoc
    JavadocUtility.generateJavaDocForSelect(methodBuilder, paramNames, method, annotation, fieldList, selectType, javadocParts);
    if (generationType.generateMethodContent) {
        SplittedSql splittedSql = SqlSelectBuilder.generateSQL(method, methodBuilder, false);
        // retrieve content values
        methodBuilder.addStatement("$T _contentValues=contentValues()", KriptonContentValues.class);
        if (method.hasDynamicParts()) {
            generateSQLBuild(method, methodBuilder, splittedSql);
            methodBuilder.addStatement("String _sql=_sqlBuilder.toString()");
        } else {
            String sqlName = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, method.buildSQLName());
            String sql = SqlSelectBuilder.convertJQL2SQL(method, true);
            classBuilder.addField(FieldSpec.builder(String.class, sqlName, Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL).initializer("$S", sql).build());
            methodBuilder.addComment("query SQL is statically defined");
            methodBuilder.addStatement("String _sql=$L", sqlName);
        }
        // build where condition (common for every type of select)
        StringBuilder logArgsBuffer = new StringBuilder();
        methodBuilder.addComment("add where arguments");
        {
            String separator = "";
            TypeName paramTypeName;
            // String paramName;
            boolean nullable;
            int i = 0;
            boolean rawParameters;
            String beanName = null;
            beanName = method.findEntityProperty();
            for (String item : paramGetters) {
                rawParameters = paramNames.get(i).indexOf(".") == -1;
                methodBuilder.addCode("_contentValues.addWhereArgs(");
                logArgsBuffer.append(separator + "%s");
                paramTypeName = paramTypeNames.get(i);
                // code for query arguments
                nullable = TypeUtility.isNullable(paramTypeName);
                if (rawParameters) {
                    if (nullable && !method.hasAdapterForParam(item)) {
                        methodBuilder.addCode("($L==null?\"\":", item);
                    }
                    // check for string conversion
                    TypeUtility.beginStringConversion(methodBuilder, paramTypeName);
                    SQLTransformer.javaMethodParam2WhereConditions(methodBuilder, method, item, paramTypeName);
                    // check for string conversion
                    TypeUtility.endStringConversion(methodBuilder, paramTypeName);
                    if (nullable && !method.hasAdapterForParam(item)) {
                        methodBuilder.addCode(")");
                    }
                } else {
                    // eventually we take associated property
                    SQLProperty property = usedBeanPropertyNames.get(i) == null ? null : entity.get(usedBeanPropertyNames.get(i));
                    if (nullable && !(property != null) && !method.hasAdapterForParam(item)) {
                        methodBuilder.addCode("($L==null?\"\":", item);
                    }
                    // check for string conversion
                    TypeUtility.beginStringConversion(methodBuilder, paramTypeName);
                    // if (property != null) {
                    // SQLTransformer.javaProperty2WhereCondition(methodBuilder,
                    // method, item, paramTypeName, property);
                    // } else {
                    SQLTransformer.javaProperty2WhereCondition(methodBuilder, method, beanName, paramTypeName, property);
                    // }
                    // check for string conversion
                    TypeUtility.endStringConversion(methodBuilder, paramTypeName);
                    if (nullable && !(property != null) && !method.hasAdapterForParam(item)) {
                        methodBuilder.addCode(")");
                    }
                }
                separator = ", ";
                i++;
                methodBuilder.addCode(");\n");
            }
        }
        methodBuilder.addStatement("String[] _sqlArgs=_contentValues.whereArgsAsArray()");
        if (daoDefinition.isLogEnabled()) {
            // generate log section - BEGIN
            methodBuilder.addComment("log section BEGIN");
            methodBuilder.beginControlFlow("if (_context.isLogEnabled())");
            // manage log
            methodBuilder.addComment("manage log");
            methodBuilder.addStatement("$T.info(_sql)", Logger.class);
            // log for where parames
            SqlBuilderHelper.generateLogForWhereParameters(method, methodBuilder);
            // generate log section - END
            methodBuilder.endControlFlow();
            methodBuilder.addComment("log section END");
        }
        if (generationType.generateCloseableCursor) {
            methodBuilder.beginControlFlow("try ($T _cursor = database().rawQuery(_sql, _sqlArgs))", Cursor.class);
        } else {
            methodBuilder.addStatement("$T _cursor = database().rawQuery(_sql, _sqlArgs)", Cursor.class);
        }
        if (daoDefinition.isLogEnabled()) {
            // generate log section - BEGIN
            methodBuilder.addComment("log section BEGIN");
            methodBuilder.beginControlFlow("if (_context.isLogEnabled())");
            methodBuilder.addCode("$T.info(\"Rows found: %s\",_cursor.getCount());\n", Logger.class);
            // generate log section - END
            methodBuilder.endControlFlow();
            methodBuilder.addComment("log section END");
        }
        switch(selectType) {
            case LISTENER_CURSOR:
                {
                    ClassName readCursorListenerToExclude = ClassName.get(OnReadCursorListener.class);
                    checkUnusedParameters(method, usedMethodParameters, readCursorListenerToExclude);
                }
                break;
            case LISTENER_BEAN:
                {
                    ParameterizedTypeName readBeanListenerToExclude = ParameterizedTypeName.get(ClassName.get(OnReadBeanListener.class), TypeName.get(entity.getElement().asType()));
                    checkUnusedParameters(method, usedMethodParameters, readBeanListenerToExclude);
                }
                break;
            default:
                checkUnusedParameters(method, usedMethodParameters, null);
                break;
        }
    }
}
Also used : JQLReplaceVariableStatementListenerImpl(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLReplaceVariableStatementListenerImpl) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeName(com.squareup.javapoet.TypeName) One(com.abubusoft.kripton.common.One) ArrayList(java.util.ArrayList) SQLiteDaoDefinition(com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition) OnReadCursorListener(com.abubusoft.kripton.android.sqlite.OnReadCursorListener) SplittedSql(com.abubusoft.kripton.processor.sqlite.SqlSelectBuilder.SplittedSql) ModelAnnotation(com.abubusoft.kripton.processor.core.ModelAnnotation) SQLProperty(com.abubusoft.kripton.processor.sqlite.model.SQLProperty) ClassName(com.squareup.javapoet.ClassName) SQLiteEntity(com.abubusoft.kripton.processor.sqlite.model.SQLiteEntity) HashSet(java.util.HashSet) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName)

Aggregations

SQLProperty (com.abubusoft.kripton.processor.sqlite.model.SQLProperty)41 SQLiteEntity (com.abubusoft.kripton.processor.sqlite.model.SQLiteEntity)23 SQLiteDaoDefinition (com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition)22 TypeName (com.squareup.javapoet.TypeName)18 JQLReplacerListenerImpl (com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLReplacerListenerImpl)14 ArrayList (java.util.ArrayList)12 One (com.abubusoft.kripton.common.One)10 Pair (com.abubusoft.kripton.common.Pair)9 JQLChecker (com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLChecker)7 JQLProjection (com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLProjection)7 InvalidMethodSignException (com.abubusoft.kripton.processor.exceptions.InvalidMethodSignException)6 ModelProperty (com.abubusoft.kripton.processor.core.ModelProperty)5 LinkedHashSet (java.util.LinkedHashSet)5 SQLiteStatement (android.database.sqlite.SQLiteStatement)4 SQLTypeAdapterUtils (com.abubusoft.kripton.common.SQLTypeAdapterUtils)4 PropertyNotFoundException (com.abubusoft.kripton.processor.exceptions.PropertyNotFoundException)4 ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)4 BaseProcessorTest (base.BaseProcessorTest)3 ModelAnnotation (com.abubusoft.kripton.processor.core.ModelAnnotation)3 JQL (com.abubusoft.kripton.processor.sqlite.grammars.jql.JQL)3