Search in sources :

Example 1 with Property

use of com.coredata.db.Property in project CoreData by FangCloud-Android.

the class EntityProcessor method createEntityDao.

public void createEntityDao(TypeElement element) throws IOException {
    EntityDetail entityDetail = EntityDetail.parse(processingEnv, element);
    // 实体类的class
    ClassName classEntity = ClassName.bestGuess(element.asType().toString());
    if (entityDetail.getPrimaryKey() == null) {
        throw new RuntimeException(classEntity.reflectionName() + " 没有主键");
    }
    List<Property> propertyList = entityDetail.getProperties(processingEnv);
    // 1、找出tableName,PrimaryKeyName ok
    // 2、找出所有的PropertyConverter,并生成局部变量,类似 __TagListConverter ok
    // 3、找出所有关联对象 @Relation,并生成对应的dao 类似 __AuthorCoreDao ok
    // 4、onCreate方法,初始化 关联对象对应的 dao ok
    // 5、getInsertSql, 返回插入的sql语句 ok
    // 6、getCreateTableSql,返回建表语句
    // 7、getTableProperties,返回所有的表结构
    // 8、绑定数据
    // dao的java名字
    String daoName = String.format("%sCoreDaoImpl", entityDetail.getEntityName());
    TypeSpec.Builder daoTypeBuilder = TypeSpec.classBuilder(daoName).addModifiers(Modifier.PUBLIC, Modifier.FINAL).superclass(ParameterizedTypeName.get(classCoreDao, classEntity));
    List<Element> convertElements = entityDetail.getConvertElements(processingEnv);
    // static 代码块
    CodeBlock convertStaticBlock = CreateConvertStatement.buildConvertStatic(convertElements);
    if (convertStaticBlock != null) {
        daoTypeBuilder.addStaticBlock(convertStaticBlock);
    }
    // 创建convert
    List<FieldSpec> convertFieldSpecs = CreateConvertStatement.bindComvertFields(convertElements);
    if (convertFieldSpecs != null) {
        for (FieldSpec fieldSpec : convertFieldSpecs) {
            daoTypeBuilder.addField(fieldSpec);
        }
    }
    // onCreate方法
    // 创建关联的dao
    List<Element> relationElements = entityDetail.getRelationElements();
    MethodSpec.Builder onCreateMethodBuilder = MethodSpec.methodBuilder("onCreate").addModifiers(Modifier.PROTECTED).returns(void.class).addParameter(classCoreData, "coreData").addStatement("super.onCreate($N)", "coreData");
    for (Element relationElement : relationElements) {
        TypeMirror typeMirror = relationElement.asType();
        ClassName classRelation = ClassName.bestGuess(typeMirror.toString());
        String daoFieldName = Utils.relationDaoName(classRelation);
        FieldSpec fieldSpec = FieldSpec.builder(ParameterizedTypeName.get(classCoreDao, classRelation), daoFieldName, Modifier.PRIVATE).build();
        daoTypeBuilder.addField(fieldSpec);
        onCreateMethodBuilder.addStatement("$N = coreData.dao($T.class)", daoFieldName, classRelation);
    }
    MethodSpec onCreateMethod = onCreateMethodBuilder.build();
    // getCreateTableSql 方法,用来获取建表语句
    MethodSpec getCreateTableSqlMethod = MethodSpec.methodBuilder("getCreateTableSql").addModifiers(Modifier.PROTECTED).returns(String.class).addStatement("return $S", SqlBuilder.buildCreateSql(entityDetail.getTableName(), propertyList, true)).build();
    // getInsertSql 方法,用来获取插入语句
    MethodSpec getInsertSqlMethod = MethodSpec.methodBuilder("getInsertSql").addModifiers(Modifier.PROTECTED).returns(String.class).addStatement("return $S", Utils.getInsertSql(entityDetail.getTableName(), propertyList)).build();
    // bindStatement 用来绑定数据
    MethodSpec bindStatementMethod = new BindStatementMethod(processingEnv, entityDetail).build();
    // replaceInternal 方法,用来处理关系型数据
    MethodSpec replaceInternalMethod = new ReplaceInternalMethod(processingEnv, entityDetail).build();
    // 创建 getTableName 方法,返回tableName
    MethodSpec getTableNameMethod = MethodSpec.methodBuilder("getTableName").addModifiers(Modifier.PUBLIC).returns(String.class).addStatement("return $S", entityDetail.getTableName()).build();
    // 创建 getPrimaryKeyName 方法,返回 主键的名字
    MethodSpec getPrimaryKeyNameMethod = MethodSpec.methodBuilder("getPrimaryKeyName").addModifiers(Modifier.PUBLIC).returns(String.class).addStatement("return $S", Utils.getColumnName(entityDetail.getPrimaryKey())).build();
    // 创建 bindCursor 方法,绑定游标数据到模型
    MethodSpec bindCursorMethod = new BindCursorMethod(processingEnv, entityDetail).build();
    // 创建 getTableProperties 方法,返回所有字段相关的 Property
    ParameterizedTypeName listPropertyType = ParameterizedTypeName.get(ClassName.get(ArrayList.class), classCoreProperty);
    MethodSpec.Builder getTablePropertiesBuilder = MethodSpec.methodBuilder("getTableProperties").addModifiers(Modifier.PUBLIC).returns(ParameterizedTypeName.get(ClassName.get(List.class), classCoreProperty));
    getTablePropertiesBuilder.addStatement("$T list = new $T()", listPropertyType, listPropertyType);
    for (Property property : propertyList) {
        getTablePropertiesBuilder.addStatement("list.add(new $T($S, $T.class, $N))", classCoreProperty, property.name, Utils.getTypeNameByType(property.type), String.valueOf(property.primaryKey));
    }
    getTablePropertiesBuilder.addStatement("return list");
    daoTypeBuilder.addMethod(onCreateMethod).addMethod(getTableNameMethod).addMethod(getPrimaryKeyNameMethod).addMethod(getTablePropertiesBuilder.build()).addMethod(getCreateTableSqlMethod).addMethod(getInsertSqlMethod).addMethod(bindStatementMethod).addMethod(replaceInternalMethod).addMethod(bindCursorMethod);
    JavaFile javaFile = JavaFile.builder(entityDetail.getEntityPackageName(processingEnv), daoTypeBuilder.build()).build();
    javaFile.writeTo(processingEnv.getFiler());
    System.out.println(element.getSimpleName());
    System.out.println(processingEnv.getElementUtils().getPackageOf(element).getQualifiedName());
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) CodeBlock(com.squareup.javapoet.CodeBlock) ArrayList(java.util.ArrayList) BindCursorMethod(com.coredata.compiler.method.BindCursorMethod) FieldSpec(com.squareup.javapoet.FieldSpec) ReplaceInternalMethod(com.coredata.compiler.method.ReplaceInternalMethod) BindStatementMethod(com.coredata.compiler.method.BindStatementMethod) TypeMirror(javax.lang.model.type.TypeMirror) ClassName(com.squareup.javapoet.ClassName) JavaFile(com.squareup.javapoet.JavaFile) Property(com.coredata.db.Property) TypeSpec(com.squareup.javapoet.TypeSpec) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName)

Example 2 with Property

use of com.coredata.db.Property in project CoreData by FangCloud-Android.

the class BindCursorMethod method bind.

private void bind(MethodSpec.Builder builder) {
    // final int cursorIndexOfId = cursor.getColumnIndexOrThrow("id");
    // final int cursorIndexOfName = cursor.getColumnIndexOrThrow("name");
    // final int cursorIndexOfTags = cursor.getColumnIndexOrThrow("tags");
    // final int cursorIndexOfAuthor = cursor.getColumnIndexOrThrow("author_id");
    // final int cursorIndexOfContent = cursor.getColumnIndexOrThrow("desc_content");
    // final int cursorIndexOfEmail = cursor.getColumnIndexOrThrow("desc_email");
    // List<Book> bookList = new ArrayList<>();
    // Map<Integer, Book> authorIdWithBookMap = new HashMap<>();
    // while (cursor.moveToNext()) {
    // Book book = new Book();
    // book.id = cursor.getLong(cursorIndexOfId);
    // book.name = cursor.getString(cursorIndexOfName);
    // book.tags = __TagListConverter.convertToValue(cursor.getString(cursorIndexOfTags));
    // int authorId = cursor.getInt(cursorIndexOfAuthor);
    // book.desc = new Desc();
    // book.desc.content = cursor.getString(cursorIndexOfContent);
    // book.desc.email = cursor.getString(cursorIndexOfEmail);
    // bookList.add(book);
    // authorIdWithBookMap.put(authorId, book);
    // }
    // List<Author> authorList = __authorCoreDao.queryByKeys(authorIdWithBookMap.keySet().toArray(new Integer[]{}));
    // for (Author author : authorList) {
    // Book book = authorIdWithBookMap.get(author.getId());
    // if (book != null) {
    // book.author = author;
    // }
    // }
    // return bookList;
    TypeName typeNameEntity = ClassName.get(entityDetail.getEntityElement().asType());
    ParameterizedTypeName typeListEntity = ParameterizedTypeName.get(ClassName.get(ArrayList.class), typeNameEntity);
    List<Element> elementsForDb = entityDetail.getDbElements();
    List<Property> properties = entityDetail.getProperties(processingEnv);
    List<Element> relationElements = entityDetail.getRelationElements();
    for (Property property : properties) {
        builder.addStatement("int $N = cursor.getColumnIndexOrThrow($S)", "cursorIndexOf" + property.name, property.name);
    }
    // 创建自己的列表
    builder.addStatement("$T list = new $T()", typeListEntity, typeListEntity);
    // 创建多个关联数据的hashMap,主键类型为key
    for (Element relationElement : relationElements) {
        TypeElement typeRelation = (TypeElement) processingEnv.getTypeUtils().asElement(relationElement.asType());
        EntityDetail relationEntityDetail = EntityDetail.parse(processingEnv, typeRelation);
        Element primaryKeyElement = relationEntityDetail.getPrimaryKey();
        if (primaryKeyElement != null) {
            TypeMirror typeMirror = primaryKeyElement.asType();
            ParameterizedTypeName hashMapType = ParameterizedTypeName.get(ClassName.get(HashMap.class), ClassName.get(typeMirror).box(), typeNameEntity);
            builder.addStatement("$T __$NMap = new $T()", hashMapType, Utils.getColumnName(relationElement), hashMapType);
        }
    }
    builder.addCode("while (cursor.moveToNext()) {\n  ");
    // 创建一个对象
    String itemName = "entity";
    builder.addStatement("$T $N = new $T()", typeNameEntity, itemName, typeNameEntity);
    for (Element element : elementsForDb) {
        bindCursorToField(builder, element, itemName);
    }
    builder.addStatement("list.add(entity)");
    // 将对象放入相应关联对象对应的map
    builder.addCode("}\n");
    // 循环关联对象,赋值给主对象
    for (Element relationElement : relationElements) {
        ClassName classNameRelation = ClassName.bestGuess(relationElement.asType().toString());
        TypeElement typeRelationElement = (TypeElement) processingEnv.getTypeUtils().asElement(relationElement.asType());
        EntityDetail relationEntityDetail = EntityDetail.parse(processingEnv, typeRelationElement);
        Element primaryKeyElement = relationEntityDetail.getPrimaryKey();
        if (primaryKeyElement != null) {
            // List<Author> authorList = __authorCoreDao.queryByKeys(authorIdWithBookMap.keySet().toArray(new Integer[]{}));
            TypeName primaryTypeName = ClassName.get(primaryKeyElement.asType());
            ParameterizedTypeName listRelationType = ParameterizedTypeName.get(ClassName.get(List.class), classNameRelation);
            String listName = String.format("__%sList", typeRelationElement.getSimpleName());
            String mapName = String.format("__%sMap", Utils.getColumnName(relationElement));
            builder.addStatement("$T $N = $N.queryByKeys($N.keySet().toArray(new $T[]{}))", listRelationType, listName, Utils.relationDaoName(classNameRelation), mapName, primaryTypeName.box());
            builder.addCode("for($T item : $N){\n", classNameRelation, listName);
            builder.addStatement("  $T entity = $N.get($N)", typeNameEntity, mapName, Utils.methodGet(primaryKeyElement, "item"));
            builder.addCode("  if(entity != null){\n");
            builder.addStatement(Utils.methodSetFormat(relationElement, "entity"), "item");
            builder.addCode("  }\n");
            builder.addCode("}\n");
        }
    }
    builder.addStatement("return list");
}
Also used : ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeName(com.squareup.javapoet.TypeName) HashMap(java.util.HashMap) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) TypeMirror(javax.lang.model.type.TypeMirror) ClassName(com.squareup.javapoet.ClassName) ArrayList(java.util.ArrayList) List(java.util.List) EntityDetail(com.coredata.compiler.EntityDetail) Property(com.coredata.db.Property) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName)

Example 3 with Property

use of com.coredata.db.Property in project CoreData by FangCloud-Android.

the class SqlBuilder method buildCreateSql.

/**
 * 创建 建表的语句
 *
 * @param isNotExist
 * @return
 */
public static String buildCreateSql(String tableName, List<Property> properties, boolean isNotExist) {
    StringBuilder sql = new StringBuilder();
    sql.append("CREATE TABLE ").append(isNotExist ? "IF NOT EXISTS " : "").append("'").append(tableName).append("' (");
    int listSize = properties.size();
    for (int i = 0; i < listSize; i++) {
        Property property = properties.get(i);
        sql.append("'").append(property.name).append("' ");
        sql.append(SqlUtils.getSqlTypeByClazz(property.type));
        sql.append(property.primaryKey ? " PRIMARY KEY" : "");
        if (i < listSize - 1) {
            sql.append(",");
        }
    }
    sql.append(");");
    return sql.toString();
}
Also used : Property(com.coredata.db.Property)

Example 4 with Property

use of com.coredata.db.Property in project CoreData by FangCloud-Android.

the class Utils method getInsertSql.

public static String getInsertSql(String tableName, List<Property> propertyList) {
    String insertFormat = "INSERT OR REPLACE INTO `%s`(%s) VALUES (%s)";
    StringBuilder fieldBuilder = new StringBuilder();
    StringBuilder askBuilder = new StringBuilder();
    boolean isFirst = true;
    for (Property property : propertyList) {
        if (!isFirst) {
            fieldBuilder.append(",");
            askBuilder.append(",");
        }
        isFirst = false;
        fieldBuilder.append("`").append(property.name).append("`");
        askBuilder.append("?");
    }
    return String.format(insertFormat, tableName, fieldBuilder.toString(), askBuilder.toString());
}
Also used : Property(com.coredata.db.Property)

Example 5 with Property

use of com.coredata.db.Property in project CoreData by FangCloud-Android.

the class Utils method getProperties.

public static List<Property> getProperties(ProcessingEnvironment env, List<Element> elements, Element primaryKey) {
    Elements elementUtils = env.getElementUtils();
    Types typeUtils = env.getTypeUtils();
    List<Property> propertyList = new ArrayList<>();
    for (Element element : elements) {
        String columnName = Utils.getColumnName(element);
        TypeName dbBaseType;
        TypeMirror typeMirror = element.asType();
        TypeName typeNameElement = ClassName.get(typeMirror);
        if (Utils.isBaseType(typeNameElement)) {
            dbBaseType = typeNameElement;
        } else {
            TypeElement elementFieldType = (TypeElement) typeUtils.asElement(typeMirror);
            Relation annotationRelation = element.getAnnotation(Relation.class);
            if (annotationRelation != null) {
                // 关联数据
                Entity relationEntity = elementFieldType.getAnnotation(Entity.class);
                if (relationEntity == null) {
                    throw new IllegalStateException("@Relation 添加的属性必须是 @Entity 的类");
                }
                EntityDetail relationEntityDetail = EntityDetail.parse(env, elementFieldType);
                Element relationEntityPrimaryKey = relationEntityDetail.getPrimaryKey();
                if (relationEntityPrimaryKey == null) {
                    throw new IllegalStateException(relationEntityDetail.getEntityName() + "是关联类型,@Relation 属性必须有主键");
                }
                dbBaseType = ClassName.get(relationEntityPrimaryKey.asType());
            } else {
                Embedded embedded = element.getAnnotation(Embedded.class);
                if (embedded != null) {
                    // 内嵌数据, 循环解析内嵌结构的字段
                    List<Element> embeddedEleList = new ArrayList<>();
                    fillElementsForDbAndReturnPrimaryKey(env, embeddedEleList, (TypeElement) typeUtils.asElement(typeMirror));
                    propertyList.addAll(getProperties(env, embeddedEleList, null));
                    continue;
                } else {
                    Convert convert = element.getAnnotation(Convert.class);
                    if (convert != null) {
                        TypeName classConvertDb = Utils.getConvertDbType(convert);
                        if (Utils.isBaseType(classConvertDb)) {
                            dbBaseType = classConvertDb;
                        } else {
                            throw new IllegalStateException(element.getSimpleName() + "converter dbtype is not a base type");
                        }
                    } else {
                        throw new IllegalStateException(element.getSimpleName() + " is a complex structure field," + "must indicate it as @Relation or @Embedded, " + "or supply a @Convert for it");
                    }
                }
            }
        }
        propertyList.add(new Property(columnName, Utils.getTypeByTypeName(dbBaseType), element == primaryKey));
    }
    return propertyList;
}
Also used : Types(javax.lang.model.util.Types) Entity(com.coredata.annotation.Entity) TypeName(com.squareup.javapoet.TypeName) Convert(com.coredata.annotation.Convert) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) Elements(javax.lang.model.util.Elements) Relation(com.coredata.annotation.Relation) TypeMirror(javax.lang.model.type.TypeMirror) Embedded(com.coredata.annotation.Embedded) EntityDetail(com.coredata.compiler.EntityDetail) Property(com.coredata.db.Property)

Aggregations

Property (com.coredata.db.Property)6 ArrayList (java.util.ArrayList)4 Element (javax.lang.model.element.Element)3 TypeElement (javax.lang.model.element.TypeElement)3 TypeMirror (javax.lang.model.type.TypeMirror)3 EntityDetail (com.coredata.compiler.EntityDetail)2 ClassName (com.squareup.javapoet.ClassName)2 ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)2 TypeName (com.squareup.javapoet.TypeName)2 ContentValues (android.content.ContentValues)1 Cursor (android.database.Cursor)1 SQLException (android.database.SQLException)1 Convert (com.coredata.annotation.Convert)1 Embedded (com.coredata.annotation.Embedded)1 Entity (com.coredata.annotation.Entity)1 Relation (com.coredata.annotation.Relation)1 BindCursorMethod (com.coredata.compiler.method.BindCursorMethod)1 BindStatementMethod (com.coredata.compiler.method.BindStatementMethod)1 ReplaceInternalMethod (com.coredata.compiler.method.ReplaceInternalMethod)1 DbProperty (com.coredata.db.DbProperty)1