/** * Find all the fields in the class. But not each field is supported to add a column to the table. * Only the basic data types and String are supported. This method will intercept all the types * which are not supported and return a new list of supported fields. * * @param className The full name of the class. * @return A list of supported fields */ protected List<Field> getSupportedFields(String className) { List<Field> fieldList = classFieldsMap.get(className); if (fieldList == null) { List<Field> supportedFields = new ArrayList<Field>(); Class<?> dynamicClass; try { dynamicClass = Class.forName(className); } catch (ClassNotFoundException e) { throw new DatabaseGenerateException(DatabaseGenerateException.CLASS_NOT_FOUND + className); } Field[] fields = dynamicClass.getDeclaredFields(); for (Field field : fields) { Column annotation = field.getAnnotation(Column.class); if (annotation != null && annotation.ignore()) { continue; } int modifiers = field.getModifiers(); if (!Modifier.isStatic(modifiers)) { Class<?> fieldTypeClass = field.getType(); String fieldType = fieldTypeClass.getName(); if (BaseUtility.isFieldTypeSupported(fieldType)) { supportedFields.add(field); } } } classFieldsMap.put(className, supportedFields); return supportedFields; } return fieldList; }
int onDeleteAll(Class<?> modelClass, String... conditions) { BaseUtility.checkConditionsCorrect(conditions); analyzeAssociations(modelClass); int rowsAffected = deleteAllCascade(modelClass, conditions); rowsAffected += mDatabase.delete( getTableName(modelClass), getWhereClause(conditions), getWhereArgs(conditions)); getForeignKeyTableToDelete().clear(); return rowsAffected; }
private int deleteAllCascade(Class<?> modelClass, String... conditions) { int rowsAffected = 0; for (String associatedTableName : getForeignKeyTableToDelete()) { String tableName = getTableName(modelClass); String fkName = getForeignKeyColumnName(tableName); StringBuilder whereClause = new StringBuilder(); whereClause.append(fkName).append(" in (select id from "); whereClause.append(tableName); if (conditions != null && conditions.length > 0) { whereClause.append(" where ").append(buildConditionString(conditions)); } whereClause.append(")"); rowsAffected += mDatabase.delete( associatedTableName, BaseUtility.changeCase(whereClause.toString()), null); } return rowsAffected; }
/** * Analyze the associations of modelClass and store the associated tables. The associated tables * might be used when deleting referenced data of a specified row. * * @param modelClass To get associations of this class. */ private void analyzeAssociations(Class<?> modelClass) { Collection<AssociationsInfo> associationInfos = getAssociationInfo(modelClass.getName()); for (AssociationsInfo associationInfo : associationInfos) { String associatedTableName = DBUtility.getTableNameByClassName(associationInfo.getAssociatedClassName()); if (associationInfo.getAssociationType() == Const.Model.MANY_TO_ONE || associationInfo.getAssociationType() == Const.Model.ONE_TO_ONE) { String classHoldsForeignKey = associationInfo.getClassHoldsForeignKey(); if (!modelClass.getName().equals(classHoldsForeignKey)) { getForeignKeyTableToDelete().add(associatedTableName); } } else if (associationInfo.getAssociationType() == Const.Model.MANY_TO_MANY) { String joinTableName = DBUtility.getIntermediateTableName(getTableName(modelClass), associatedTableName); joinTableName = BaseUtility.changeCase(joinTableName); getForeignKeyTableToDelete().add(joinTableName); } } }
/** * The open interface for other classes in CRUD package to delete multiple rows. Using tableName * to decide which table to delete from, and conditions representing the WHERE part of an SQL * statement. * * @param tableName Which table to delete from. * @param conditions A string array representing the WHERE part of an SQL statement. * @return The number of rows affected. */ int onDeleteAll(String tableName, String... conditions) { BaseUtility.checkConditionsCorrect(conditions); return mDatabase.delete(tableName, getWhereClause(conditions), getWhereArgs(conditions)); }
/** * If two tables are associated, one table have a foreign key column. The foreign key column name * will be the associated table name with _id appended. * * @param associatedTableName The associated table name. * @return The foreign key column name. */ protected String getForeignKeyColumnName(String associatedTableName) { return BaseUtility.changeCase(associatedTableName + "_id"); }