use of org.litepal.tablemanager.model.GenericModel in project LitePal by LitePalFramework.
the class DataHandler method setGenericValueToModel.
/**
* Get generic value from generic tables, then set the value into the baseObj.
* @param baseObj
* The model to set into.
* @param supportedGenericFields
* List of all supported generic fields.
* @param genericModelMap
* Use HashMap to cache the query information at first loop. Then the rest loop can
* get query information directly to speed up.
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
protected void setGenericValueToModel(DataSupport baseObj, List<Field> supportedGenericFields, Map<Field, GenericModel> genericModelMap) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
for (Field field : supportedGenericFields) {
String tableName, genericValueColumnName, genericValueIdColumnName, getMethodName;
Cursor cursor = null;
GenericModel genericModel = genericModelMap.get(field);
if (genericModel == null) {
tableName = DBUtility.getGenericTableName(baseObj.getClassName(), field.getName());
genericValueColumnName = DBUtility.convertToValidColumnName(field.getName());
genericValueIdColumnName = DBUtility.getGenericValueIdColumnName(baseObj.getClassName());
getMethodName = genGetColumnMethod(field);
GenericModel model = new GenericModel();
model.setTableName(tableName);
model.setValueColumnName(genericValueColumnName);
model.setValueIdColumnName(genericValueIdColumnName);
model.setGetMethodName(getMethodName);
genericModelMap.put(field, model);
} else {
tableName = genericModel.getTableName();
genericValueColumnName = genericModel.getValueColumnName();
genericValueIdColumnName = genericModel.getValueIdColumnName();
getMethodName = genericModel.getGetMethodName();
}
try {
cursor = mDatabase.query(tableName, null, genericValueIdColumnName + " = ?", new String[] { String.valueOf(baseObj.getBaseObjId()) }, null, null, null);
if (cursor.moveToFirst()) {
do {
int columnIndex = cursor.getColumnIndex(BaseUtility.changeCase(genericValueColumnName));
if (columnIndex != -1) {
setToModelByReflection(baseObj, field, columnIndex, getMethodName, cursor);
}
} while (cursor.moveToNext());
}
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}
use of org.litepal.tablemanager.model.GenericModel in project LitePal by LitePalFramework.
the class DataHandler method setAssociatedModel.
/**
* Finds the associated models of baseObj, then set them into baseObj.
*
* @param baseObj
* The class of base object.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private void setAssociatedModel(DataSupport baseObj) {
if (fkInOtherModel == null) {
return;
}
for (AssociationsInfo info : fkInOtherModel) {
Cursor cursor = null;
String associatedClassName = info.getAssociatedClassName();
boolean isM2M = info.getAssociationType() == Const.Model.MANY_TO_MANY;
try {
List<Field> supportedFields = getSupportedFields(associatedClassName);
List<Field> supportedGenericFields = getSupportedGenericFields(associatedClassName);
if (isM2M) {
String tableName = baseObj.getTableName();
String associatedTableName = DBUtility.getTableNameByClassName(associatedClassName);
String intermediateTableName = DBUtility.getIntermediateTableName(tableName, associatedTableName);
StringBuilder sql = new StringBuilder();
sql.append("select * from ").append(associatedTableName).append(" a inner join ").append(intermediateTableName).append(" b on a.id = b.").append(associatedTableName + "_id").append(" where b.").append(tableName).append("_id = ?");
cursor = DataSupport.findBySQL(BaseUtility.changeCase(sql.toString()), String.valueOf(baseObj.getBaseObjId()));
} else {
String foreignKeyColumn = getForeignKeyColumnName(DBUtility.getTableNameByClassName(info.getSelfClassName()));
String associatedTableName = DBUtility.getTableNameByClassName(associatedClassName);
cursor = mDatabase.query(BaseUtility.changeCase(associatedTableName), null, foreignKeyColumn + "=?", new String[] { String.valueOf(baseObj.getBaseObjId()) }, null, null, null, null);
}
if (cursor != null && cursor.moveToFirst()) {
SparseArray<QueryInfoCache> queryInfoCacheSparseArray = new SparseArray<QueryInfoCache>();
Map<Field, GenericModel> genericModelMap = new HashMap<Field, GenericModel>();
do {
DataSupport modelInstance = (DataSupport) createInstanceFromClass(Class.forName(associatedClassName));
giveBaseObjIdValue(modelInstance, cursor.getLong(cursor.getColumnIndexOrThrow("id")));
setValueToModel(modelInstance, supportedFields, null, cursor, queryInfoCacheSparseArray);
setGenericValueToModel(modelInstance, supportedGenericFields, genericModelMap);
if (info.getAssociationType() == Const.Model.MANY_TO_ONE || isM2M) {
Field field = info.getAssociateOtherModelFromSelf();
Collection collection = (Collection) getFieldValue(baseObj, field);
if (collection == null) {
if (isList(field.getType())) {
collection = new ArrayList();
} else {
collection = new HashSet();
}
DynamicExecutor.setField(baseObj, field.getName(), collection, baseObj.getClass());
}
collection.add(modelInstance);
} else if (info.getAssociationType() == Const.Model.ONE_TO_ONE) {
setFieldValue(baseObj, info.getAssociateOtherModelFromSelf(), modelInstance);
}
} while (cursor.moveToNext());
queryInfoCacheSparseArray.clear();
genericModelMap.clear();
}
} catch (Exception e) {
throw new DataSupportException(e.getMessage(), e);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}
use of org.litepal.tablemanager.model.GenericModel in project LitePal by LitePalFramework.
the class DataHandler method query.
/**
* Query the table of the given model, returning a model list over the
* result set.
*
* @param modelClass
* The model to compile the query against.
* @param columns
* A list of which columns to return. Passing null will return
* all columns, which is discouraged to prevent reading data from
* storage that isn't going to be used.
* @param selection
* A filter declaring which rows to return, formatted as an SQL
* WHERE clause (excluding the WHERE itself). Passing null will
* return all rows for the given table.
* @param selectionArgs
* You may include ?s in selection, which will be replaced by the
* values from selectionArgs, in order that they appear in the
* selection. The values will be bound as Strings.
* @param groupBy
* A filter declaring how to group rows, formatted as an SQL
* GROUP BY clause (excluding the GROUP BY itself). Passing null
* will cause the rows to not be grouped.
* @param having
* A filter declare which row groups to include in the cursor, if
* row grouping is being used, formatted as an SQL HAVING clause
* (excluding the HAVING itself). Passing null will cause all row
* groups to be included, and is required when row grouping is
* not being used.
* @param orderBy
* How to order the rows, formatted as an SQL ORDER BY clause
* (excluding the ORDER BY itself). Passing null will use the
* default sort order, which may be unordered.
* @param limit
* Limits the number of rows returned by the query, formatted as
* LIMIT clause. Passing null denotes no LIMIT clause.
* @param foreignKeyAssociations
* Associated classes which have foreign keys in the current
* model's table.
* @return A model list. The list may be empty.
*/
@SuppressWarnings("unchecked")
protected <T> List<T> query(Class<T> modelClass, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, List<AssociationsInfo> foreignKeyAssociations) {
List<T> dataList = new ArrayList<T>();
Cursor cursor = null;
try {
List<Field> supportedFields = getSupportedFields(modelClass.getName());
List<Field> supportedGenericFields = getSupportedGenericFields(modelClass.getName());
String[] customizedColumns = DBUtility.convertSelectClauseToValidNames(getCustomizedColumns(columns, supportedGenericFields, foreignKeyAssociations));
String tableName = getTableName(modelClass);
cursor = mDatabase.query(tableName, customizedColumns, selection, selectionArgs, groupBy, having, orderBy, limit);
if (cursor.moveToFirst()) {
SparseArray<QueryInfoCache> queryInfoCacheSparseArray = new SparseArray<QueryInfoCache>();
Map<Field, GenericModel> genericModelMap = new HashMap<Field, GenericModel>();
do {
T modelInstance = (T) createInstanceFromClass(modelClass);
giveBaseObjIdValue((DataSupport) modelInstance, cursor.getLong(cursor.getColumnIndexOrThrow("id")));
setValueToModel(modelInstance, supportedFields, foreignKeyAssociations, cursor, queryInfoCacheSparseArray);
setGenericValueToModel((DataSupport) modelInstance, supportedGenericFields, genericModelMap);
if (foreignKeyAssociations != null) {
setAssociatedModel((DataSupport) modelInstance);
}
dataList.add(modelInstance);
} while (cursor.moveToNext());
queryInfoCacheSparseArray.clear();
genericModelMap.clear();
}
return dataList;
} catch (Exception e) {
throw new DataSupportException(e.getMessage(), e);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
use of org.litepal.tablemanager.model.GenericModel in project LitePal by LitePalFramework.
the class LitePalBase method manyToAnyConditions.
/**
* Deals with one to any association conditions. e.g. Song and Album. An
* album have many songs, and a song belongs to one album. So if there's an
* Album model defined in Song with private modifier, and in Album there's a
* List or Set with generic type of Song and declared as private modifier,
* they are one2many association. If there's no List or Set defined in
* Album, they will become one2one associations. If there's also a Song
* model defined in Album with private modifier, maybe the album just have
* one song, they are one2one association too.
*
* When it's many2one association, it's easy to just simply add a foreign id
* column to the many side model's table. But when it comes to many2many
* association, it can not be done without intermediate join table in
* database. LitePal assumes that this join table's name is the
* concatenation of the two target table names in alphabetical order.
*
* @param className
* Source class name.
* @param field
* A field of source class.
* @param action
* Between {@link org.litepal.LitePalBase#GET_ASSOCIATIONS_ACTION} and
* {@link org.litepal.LitePalBase#GET_ASSOCIATION_INFO_ACTION}
*
* @throws ClassNotFoundException
*/
private void manyToAnyConditions(String className, Field field, int action) throws ClassNotFoundException {
if (isCollection(field.getType())) {
String genericTypeName = getGenericTypeName(field);
// this genericTypeName class.
if (LitePalAttr.getInstance().getClassNames().contains(genericTypeName)) {
Class<?> reverseDynamicClass = Class.forName(genericTypeName);
Field[] reverseFields = reverseDynamicClass.getDeclaredFields();
// Look up if there's a reverse association
// definition in the reverse class.
boolean reverseAssociations = false;
for (int i = 0; i < reverseFields.length; i++) {
Field reverseField = reverseFields[i];
// Only map private fields
if (!Modifier.isStatic(reverseField.getModifiers())) {
Class<?> reverseFieldTypeClass = reverseField.getType();
// associations.
if (className.equals(reverseFieldTypeClass.getName())) {
if (action == GET_ASSOCIATIONS_ACTION) {
addIntoAssociationModelCollection(className, genericTypeName, genericTypeName, Const.Model.MANY_TO_ONE);
} else if (action == GET_ASSOCIATION_INFO_ACTION) {
addIntoAssociationInfoCollection(className, genericTypeName, genericTypeName, field, reverseField, Const.Model.MANY_TO_ONE);
}
reverseAssociations = true;
} else // association.
if (isCollection(reverseFieldTypeClass)) {
String reverseGenericTypeName = getGenericTypeName(reverseField);
if (className.equals(reverseGenericTypeName)) {
if (action == GET_ASSOCIATIONS_ACTION) {
addIntoAssociationModelCollection(className, genericTypeName, null, Const.Model.MANY_TO_MANY);
} else if (action == GET_ASSOCIATION_INFO_ACTION) {
addIntoAssociationInfoCollection(className, genericTypeName, null, field, reverseField, Const.Model.MANY_TO_MANY);
}
reverseAssociations = true;
}
}
}
}
// are many2one unidirectional associations.
if (!reverseAssociations) {
if (action == GET_ASSOCIATIONS_ACTION) {
addIntoAssociationModelCollection(className, genericTypeName, genericTypeName, Const.Model.MANY_TO_ONE);
} else if (action == GET_ASSOCIATION_INFO_ACTION) {
addIntoAssociationInfoCollection(className, genericTypeName, genericTypeName, field, null, Const.Model.MANY_TO_ONE);
}
}
} else if (BaseUtility.isGenericTypeSupported(genericTypeName) && action == GET_ASSOCIATIONS_ACTION) {
Column annotation = field.getAnnotation(Column.class);
if (annotation != null && annotation.ignore()) {
return;
}
GenericModel genericModel = new GenericModel();
genericModel.setTableName(DBUtility.getGenericTableName(className, field.getName()));
genericModel.setValueColumnName(DBUtility.convertToValidColumnName(field.getName()));
genericModel.setValueColumnType(getColumnType(genericTypeName));
genericModel.setValueIdColumnName(DBUtility.getGenericValueIdColumnName(className));
mGenericModels.add(genericModel);
}
}
}
Aggregations