Search in sources :

Example 21 with SQLProperty

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

the class BindTableGenerator method buldIndexes.

public static Pair<String, String> buldIndexes(final SQLiteEntity entity, boolean unique, int counter) {
    Pair<String, String> result = new Pair<>();
    result.value0 = "";
    result.value1 = "";
    ModelAnnotation annotationTable = entity.getAnnotation(BindTable.class);
    if (annotationTable == null)
        return result;
    List<String> indexes = null;
    String uniqueString;
    if (unique) {
        uniqueString = "UNIQUE ";
        indexes = annotationTable.getAttributeAsArray(AnnotationAttributeType.UNIQUE_INDEXES);
    } else {
        uniqueString = "";
        indexes = annotationTable.getAttributeAsArray(AnnotationAttributeType.INDEXES);
    }
    if (indexes == null || indexes.size() == 0)
        return result;
    // CREATE INDEX index_name ON tab_name (column1, column2)
    // Matcher matcher = patternIndex.matcher(rawIndexes);
    List<String> listCreateIndex = new ArrayList<>();
    List<String> listDropIndex = new ArrayList<>();
    for (String index : indexes) {
        String createIndex = String.format(" CREATE %sINDEX idx_%s_%s on %s (%s)", uniqueString, entity.getTableName(), counter++, entity.getTableName(), index);
        String dropIndex = String.format(" DROP INDEX IF EXISTS idx_%s_%s", entity.getTableName(), counter);
        final One<Integer> fieldCounter = new One<Integer>(0);
        createIndex = JQLChecker.getInstance().replace(new JQLContext() {

            @Override
            public String getContextDescription() {
                return "While table definition generation for entity " + entity.getName();
            }
        }, createIndex, new JQLReplacerListenerImpl(null) {

            @Override
            public String onColumnName(String columnName) {
                fieldCounter.value0++;
                SQLProperty property = entity.findPropertyByName(columnName);
                AssertKripton.assertTrue(property != null, "class '%s' in @%s(indexes) use unknown property '%s'", entity.getName(), BindTable.class.getSimpleName(), columnName);
                return property.columnName;
            }

            @Override
            public String onColumnFullyQualifiedName(String tableName, String columnName) {
                AssertKripton.fail("Inconsistent state");
                return null;
            }
        });
        AssertKripton.assertTrue(fieldCounter.value0 > 0, "class '%s' have @%s(indexes) with no well formed indexes", entity.getName(), BindTable.class.getSimpleName());
        listCreateIndex.add(createIndex);
        listDropIndex.add(dropIndex);
    }
    result.value0 = StringUtils.join(listCreateIndex, ";");
    result.value1 = StringUtils.join(listDropIndex, ";");
    return result;
}
Also used : JQLContext(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLContext) One(com.abubusoft.kripton.common.One) ArrayList(java.util.ArrayList) BindTable(com.abubusoft.kripton.android.annotation.BindTable) JQLReplacerListenerImpl(com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLReplacerListenerImpl) ModelAnnotation(com.abubusoft.kripton.processor.core.ModelAnnotation) SQLProperty(com.abubusoft.kripton.processor.sqlite.model.SQLProperty) Pair(com.abubusoft.kripton.common.Pair)

Example 22 with SQLProperty

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

the class BindTableGenerator method generateColumnsArray.

/**
 * generate columns array.
 *
 * @param entity
 */
private void generateColumnsArray(Finder<SQLProperty> entity) {
    // generate columns array
    Builder sp = FieldSpec.builder(ArrayTypeName.of(String.class), "COLUMNS", Modifier.STATIC, Modifier.PRIVATE, Modifier.FINAL);
    String s = "";
    StringBuilder buffer = new StringBuilder();
    for (SQLProperty property : entity.getCollection()) {
        buffer.append(s + "COLUMN_" + columnNameToUpperCaseConverter.convert(property.getName()));
        s = ", ";
    }
    classBuilder.addField(sp.addJavadoc("Columns array\n").initializer("{" + buffer.toString() + "}").build());
    classBuilder.addMethod(MethodSpec.methodBuilder("columns").addModifiers(Modifier.PUBLIC).addJavadoc("Columns array\n").addAnnotation(Override.class).returns(ArrayTypeName.of(String.class)).addStatement("return COLUMNS").build());
    classBuilder.addMethod(MethodSpec.methodBuilder("name").addModifiers(Modifier.PUBLIC).addJavadoc("table name\n").addAnnotation(Override.class).returns(TypeName.get(String.class)).addStatement("return TABLE_NAME").build());
}
Also used : Builder(com.squareup.javapoet.FieldSpec.Builder) SQLProperty(com.abubusoft.kripton.processor.sqlite.model.SQLProperty)

Example 23 with SQLProperty

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

the class BindTableGenerator method visit.

@Override
public void visit(SQLiteDatabaseSchema schema, SQLiteEntity entity) throws Exception {
    int indexCounter = 0;
    // generate the class name that represents the table
    String classTableName = getTableClassName(entity.getSimpleName());
    PackageElement pkg = elementUtils.getPackageOf(entity.getElement());
    String packageName = pkg.isUnnamed() ? null : pkg.getQualifiedName().toString();
    AnnotationProcessorUtilis.infoOnGeneratedClasses(BindDataSource.class, packageName, classTableName);
    classBuilder = TypeSpec.classBuilder(classTableName).addModifiers(Modifier.PUBLIC).addSuperinterface(SQLiteTable.class);
    BindTypeContext context = new BindTypeContext(classBuilder, TypeUtility.typeName(packageName, classTableName), Modifier.STATIC, Modifier.PRIVATE);
    // javadoc for class
    classBuilder.addJavadoc("<p>");
    classBuilder.addJavadoc("\nEntity <code>$L</code> is associated to table <code>$L</code>\n", entity.getSimpleName(), entity.getTableName());
    classBuilder.addJavadoc("This class represents table associated to entity.\n");
    classBuilder.addJavadoc("</p>\n");
    JavadocUtility.generateJavadocGeneratedBy(classBuilder);
    classBuilder.addJavadoc(" @see $T\n", TypeUtility.className(entity.getName()));
    {
        // @formatter:off
        // table_name
        FieldSpec fieldSpec = FieldSpec.builder(String.class, "TABLE_NAME", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("\"$L\"", entity.getTableName()).addJavadoc("Costant represents typeName of table $L\n", entity.getTableName()).build();
        classBuilder.addField(fieldSpec);
    // @formatter:on
    }
    StringBuilder bufferTable = new StringBuilder();
    StringBuilder bufferForeignKey = new StringBuilder();
    // shared between create table and drop table
    StringBuilder bufferIndexesCreate = new StringBuilder();
    StringBuilder bufferDropTable = new StringBuilder();
    StringBuilder bufferIndexesDrop = new StringBuilder();
    bufferTable.append("CREATE TABLE " + entity.getTableName());
    // define column typeName set
    String separator = "";
    bufferTable.append(" (");
    // for each column, that need to be persisted on table
    for (SQLProperty item : entity.getCollection()) {
        bufferTable.append(separator);
        bufferTable.append(item.columnName);
        bufferTable.append(" " + SQLTransformer.columnTypeAsString(item));
        switch(item.columnType) {
            case PRIMARY_KEY:
                bufferTable.append(" PRIMARY KEY AUTOINCREMENT");
                break;
            case UNIQUE:
                bufferTable.append(" UNIQUE");
                break;
            case INDEXED:
                bufferIndexesCreate.append(String.format(" CREATE INDEX idx_%s_%s ON %s(%s);", entity.getTableName(), item.columnName, entity.getTableName(), item.columnName));
                bufferIndexesDrop.append(String.format(" DROP INDEX IF EXISTS idx_%s_%s;", entity.getTableName(), item.columnName));
                break;
            case STANDARD:
                break;
        }
        boolean nullable = item.isNullable();
        // null
        if (!nullable && item.columnType != ColumnType.PRIMARY_KEY) {
            bufferTable.append(" NOT NULL");
        }
        // foreign key
        String foreignClassName = item.foreignClassName;
        if (item.hasForeignKeyClassName()) {
            SQLiteEntity reference = model.getEntity(foreignClassName);
            if (reference == null) {
                // check if we have a DAO associated into DataSource
                // definition
                boolean found = false;
                for (SQLiteDaoDefinition daoDefinition : schema.getCollection()) {
                    if (daoDefinition.getEntityClassName().equals(foreignClassName)) {
                        found = true;
                    }
                }
                if (!found) {
                    throw new NoDaoElementFound(schema, TypeUtility.className(foreignClassName));
                } else {
                    throw new InvalidBeanTypeException(item, foreignClassName);
                }
            }
            // long/Long
            if (!TypeUtility.isTypeIncludedIn(item.getPropertyType().getTypeName(), Long.class, Long.TYPE)) {
                throw new InvalidForeignKeyTypeException(item);
            }
            bufferForeignKey.append(", FOREIGN KEY(" + item.columnName + ") REFERENCES " + reference.getTableName() + "(" + reference.getPrimaryKey().columnName + ")");
            if (item.onDeleteAction != ForeignKeyAction.NO_ACTION) {
                bufferForeignKey.append(" ON DELETE " + item.onDeleteAction.toString().replaceAll("_", " "));
            }
            if (item.onUpdateAction != ForeignKeyAction.NO_ACTION) {
                bufferForeignKey.append(" ON UPDATE " + item.onUpdateAction.toString().replaceAll("_", " "));
            }
            // Same entity can not be own dependency.
            if (!entity.equals(reference)) {
                entity.referedEntities.add(reference);
            }
        }
        separator = ", ";
    }
    // add foreign key
    bufferTable.append(bufferForeignKey.toString());
    bufferTable.append(");");
    // add indexes creation one table
    if (bufferIndexesCreate.length() > 0) {
        bufferTable.append(bufferIndexesCreate.toString());
    }
    // add multicolumn indexes (UNIQUE)
    {
        Pair<String, String> multiIndexes = buldIndexes(entity, true, indexCounter);
        if (!StringUtils.isEmpty(multiIndexes.value0)) {
            bufferTable.append(multiIndexes.value0 + ";");
            bufferIndexesDrop.append(multiIndexes.value1 + ";");
        }
    }
    // add multicolumn indexes (NOT UNIQUE)
    {
        Pair<String, String> multiIndexes = buldIndexes(entity, false, indexCounter);
        if (!StringUtils.isEmpty(multiIndexes.value0)) {
            bufferTable.append(multiIndexes.value0 + ";");
            bufferIndexesDrop.append(multiIndexes.value1 + ";");
        }
    }
    {
        // create table SQL
        // @formatter:off
        FieldSpec.Builder fieldSpec = FieldSpec.builder(String.class, "CREATE_TABLE_SQL").addModifiers(Modifier.STATIC, Modifier.FINAL, Modifier.PUBLIC);
        // @formatter:on
        // @formatter:off
        fieldSpec.addJavadoc("<p>\nDDL to create table $L\n</p>\n", entity.getTableName());
        fieldSpec.addJavadoc("\n<pre>$L</pre>\n", bufferTable.toString());
        // @formatter:on
        classBuilder.addField(fieldSpec.initializer("$S", bufferTable.toString()).build());
    }
    // with tables
    if (bufferIndexesDrop.length() > 0) {
        bufferDropTable.append(bufferIndexesDrop.toString());
    }
    bufferDropTable.append("DROP TABLE IF EXISTS " + entity.getTableName() + ";");
    {
        // @formatter:off
        FieldSpec fieldSpec = FieldSpec.builder(String.class, "DROP_TABLE_SQL").addModifiers(Modifier.STATIC, Modifier.FINAL, Modifier.PUBLIC).initializer("$S", bufferDropTable.toString()).addJavadoc("<p>\nDDL to drop table $L\n</p>\n", entity.getTableName()).addJavadoc("\n<pre>$L</pre>\n", bufferDropTable.toString()).build();
        // @formatter:on
        classBuilder.addField(fieldSpec);
    }
    // define column typeName set
    for (ModelProperty item : entity.getCollection()) {
        item.accept(this);
    }
    ManagedPropertyPersistenceHelper.generateFieldPersistance(context, entity.getCollection(), PersistType.BYTE, true, Modifier.STATIC, Modifier.PUBLIC);
    model.sqlForCreate.add(bufferTable.toString());
    model.sqlForDrop.add(bufferDropTable.toString());
    generateColumnsArray(entity);
    TypeSpec typeSpec = classBuilder.build();
    JavaWriterHelper.writeJava2File(filer, packageName, typeSpec);
}
Also used : InvalidForeignKeyTypeException(com.abubusoft.kripton.processor.exceptions.InvalidForeignKeyTypeException) Builder(com.squareup.javapoet.FieldSpec.Builder) InvalidBeanTypeException(com.abubusoft.kripton.processor.exceptions.InvalidBeanTypeException) SQLiteTable(com.abubusoft.kripton.android.sqlite.SQLiteTable) BindTypeContext(com.abubusoft.kripton.processor.bind.BindTypeContext) FieldSpec(com.squareup.javapoet.FieldSpec) SQLiteDaoDefinition(com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition) NoDaoElementFound(com.abubusoft.kripton.processor.exceptions.NoDaoElementFound) SQLProperty(com.abubusoft.kripton.processor.sqlite.model.SQLProperty) ModelProperty(com.abubusoft.kripton.processor.core.ModelProperty) PackageElement(javax.lang.model.element.PackageElement) SQLiteEntity(com.abubusoft.kripton.processor.sqlite.model.SQLiteEntity) Pair(com.abubusoft.kripton.common.Pair) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 24 with SQLProperty

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

the class ModifyBeanHelper method buildJavadoc.

/**
 * @param methodBuilder
 * @param updateMode
 * @param method
 * @param beanNameParameter
 * @param whereCondition
 * @param listUsedProperty
 * @param attributesUsedInWhereConditions
 */
public String buildJavadoc(MethodSpec.Builder methodBuilder, boolean updateMode, final SQLiteModelMethod method, String beanNameParameter, String whereCondition, List<SQLProperty> listUsedProperty, List<String> attributesUsedInWhereConditions) {
    // SQLDaoDefinition daoDefinition = method.getParent();
    // SQLEntity entity = daoDefinition.getEntity();
    // in this case, only one parameter can exists for method
    Pair<String, TypeName> beanParameter = method.getParameters().get(0);
    String sqlResult;
    // generate javadoc
    StringBuilder buffer = new StringBuilder();
    StringBuilder bufferQuestion = new StringBuilder();
    String separator = "";
    for (SQLProperty property : listUsedProperty) {
        // this line generate ${bean.attribute}
        // buffer.append(String.format("%s%s=${%s.%s}", separator,
        // property.columnName,
        // method.findParameterAliasByName(beanNameParameter),
        // property.getName()));
        // this line genearate only ${attribute}
        buffer.append(String.format("%s%s=${%s}", separator, property.columnName, property.getName()));
        bufferQuestion.append(separator);
        bufferQuestion.append(property.columnName + "=");
        bufferQuestion.append("'\"+StringUtils.checkSize(_contentValues.get(\"" + property.columnName + "\"))+\"'");
        separator = ", ";
    }
    String sqlForJavaDoc = extractSQLForJavaDoc(method);
    sqlResult = method.jql.value;
    if (updateMode) {
        // query
        methodBuilder.addJavadoc("<h2>SQL update:</h2>\n");
        methodBuilder.addJavadoc("<pre>$L</pre>", sqlForJavaDoc);
        methodBuilder.addJavadoc("\n\n");
        // list of updated fields
        // Set<String>
        // updateColumns=JQLChecker.getInstance().extractColumnsToUpdate(method.jql.value,
        // entity);
        methodBuilder.addJavadoc("<h2>Updated columns:</h2>\n");
        methodBuilder.addJavadoc("<dl>\n");
        for (SQLProperty property : listUsedProperty) {
            String resolvedName = method.findParameterAliasByName(beanParameter.value0);
            methodBuilder.addJavadoc("\t<dt>$L</dt><dd>is mapped to <strong>$L</strong></dd>\n", property.columnName, "${" + resolvedName + "." + property.getName() + "}");
        }
        methodBuilder.addJavadoc("</dl>");
        methodBuilder.addJavadoc("\n\n");
    } else {
        // String where =
        // SqlUtility.replaceParametersWithQuestion(whereCondition, "%s");
        // sqlResult = String.format("DELETE %s %s ",
        // daoDefinition.getEntity().getTableName(), where);
        methodBuilder.addJavadoc("<h2>SQL delete:</h2>\n");
        methodBuilder.addJavadoc("<pre>");
        // methodBuilder.addJavadoc("DELETE $L $L",
        // daoDefinition.getEntity().getTableName(), whereCondition);
        methodBuilder.addJavadoc("$L", sqlForJavaDoc);
        methodBuilder.addJavadoc("</pre>");
        methodBuilder.addJavadoc("\n\n");
    }
    if (attributesUsedInWhereConditions.size() > 0) {
        // list of attributes used in where condition
        methodBuilder.addJavadoc("<h2>Parameters used in where conditions:</h2>\n");
        methodBuilder.addJavadoc("<dl>\n");
        for (String attribute : attributesUsedInWhereConditions) {
            methodBuilder.addJavadoc("\t<dt>$L</dt>", "${" + method.findParameterAliasByName(beanParameter.value0) + "." + method.findParameterAliasByName(attribute) + "}");
            methodBuilder.addJavadoc("<dd>is mapped to method's parameter <strong>$L.$L</strong></dd>\n", beanParameter.value0, attribute);
        }
        methodBuilder.addJavadoc("</dl>");
        methodBuilder.addJavadoc("\n\n");
    }
    // dynamic conditions
    if (method.hasDynamicWhereConditions()) {
        methodBuilder.addJavadoc("<h2>Method's parameters and associated dynamic parts:</h2>\n");
        methodBuilder.addJavadoc("<dl>\n");
        if (method.hasDynamicWhereConditions()) {
            methodBuilder.addJavadoc("<dt>$L</dt><dd>is part of where conditions resolved at runtime. In above SQL it is displayed as #{$L}</dd>", method.dynamicWhereParameterName, JQLDynamicStatementType.DYNAMIC_WHERE);
        }
        methodBuilder.addJavadoc("\n</dl>");
        methodBuilder.addJavadoc("\n\n");
    }
    // update bean have only one parameter: the bean to update
    for (Pair<String, TypeName> param : method.getParameters()) {
        methodBuilder.addJavadoc("@param $L", param.value0);
        if (method.isThisDynamicWhereConditionsName(param.value0)) {
            methodBuilder.addJavadoc("\n\tis used as dynamic where conditions\n");
        } else {
            methodBuilder.addJavadoc("\n\tis used as $L\n", "${" + method.findParameterAliasByName(param.value0) + "}");
        }
    }
    return sqlResult;
}
Also used : TypeName(com.squareup.javapoet.TypeName) SQLProperty(com.abubusoft.kripton.processor.sqlite.model.SQLProperty)

Example 25 with SQLProperty

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

the class ModifyBeanHelper method generateWhereCondition.

/**
 * @param methodBuilder
 * @param method
 * @param analyzer
 */
public void generateWhereCondition(MethodSpec.Builder methodBuilder, SQLiteModelMethod method, SqlAnalyzer analyzer) {
    SQLiteDaoDefinition daoDefinition = method.getParent();
    SQLiteEntity entity = daoDefinition.getEntity();
    String beanParamName = method.getParameters().get(0).value0;
    SQLProperty property;
    boolean nullable;
    TypeName beanClass = typeName(entity.getElement());
    for (String item : analyzer.getUsedBeanPropertyNames()) {
        property = entity.findPropertyByName(item);
        // methodBuilder.addCode("_sqlWhereParams.add(");
        methodBuilder.addCode("_contentValues.addWhereArgs(");
        nullable = TypeUtility.isNullable(property);
        if (nullable && !(property.hasTypeAdapter())) {
            // transform null in ""
            methodBuilder.addCode("($L==null?\"\":", getter(beanParamName, beanClass, property));
        }
        // check for string conversion
        TypeUtility.beginStringConversion(methodBuilder, property);
        SQLTransformer.javaProperty2WhereCondition(methodBuilder, method, beanParamName, beanClass, property);
        // check for string conversion
        TypeUtility.endStringConversion(methodBuilder, property);
        if (nullable && !(property.hasTypeAdapter())) {
            methodBuilder.addCode(")");
        }
        methodBuilder.addCode(");\n");
    }
}
Also used : TypeName(com.squareup.javapoet.TypeName) SQLProperty(com.abubusoft.kripton.processor.sqlite.model.SQLProperty) SQLiteEntity(com.abubusoft.kripton.processor.sqlite.model.SQLiteEntity) SQLiteDaoDefinition(com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition)

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