package com.raizlabs.android.dbflow.structure; import android.database.Cursor; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.raizlabs.android.dbflow.config.DatabaseConfig; import com.raizlabs.android.dbflow.config.DatabaseDefinition; import com.raizlabs.android.dbflow.config.FlowManager; import com.raizlabs.android.dbflow.config.TableConfig; import com.raizlabs.android.dbflow.sql.language.OperatorGroup; import com.raizlabs.android.dbflow.sql.language.SQLite; import com.raizlabs.android.dbflow.sql.queriable.ListModelLoader; import com.raizlabs.android.dbflow.sql.queriable.SingleModelLoader; import com.raizlabs.android.dbflow.structure.database.DatabaseWrapper; import com.raizlabs.android.dbflow.structure.database.FlowCursor; /** * Description: Provides a base retrieval class for all {@link Model} backed * adapters. */ @SuppressWarnings("NullableProblems") public abstract class RetrievalAdapter<TModel> { private SingleModelLoader<TModel> singleModelLoader; private ListModelLoader<TModel> listModelLoader; private TableConfig<TModel> tableConfig; public RetrievalAdapter(@NonNull DatabaseDefinition databaseDefinition) { DatabaseConfig databaseConfig = FlowManager.getConfig() .getConfigForDatabase(databaseDefinition.getAssociatedDatabaseClassFile()); if (databaseConfig != null) { tableConfig = databaseConfig.getTableConfigForTable(getModelClass()); if (tableConfig != null) { if (tableConfig.singleModelLoader() != null) { singleModelLoader = tableConfig.singleModelLoader(); } if (tableConfig.listModelLoader() != null) { listModelLoader = tableConfig.listModelLoader(); } } } } /** * Force loads the model from the DB. Even if caching is enabled it will requery the object. */ public void load(@NonNull TModel model) { load(model, FlowManager.getDatabaseForTable(getModelClass()).getWritableDatabase()); } /** * Force loads the model from the DB. Even if caching is enabled it will requery the object. */ public void load(@NonNull TModel model, DatabaseWrapper databaseWrapper) { getNonCacheableSingleModelLoader().load(databaseWrapper, SQLite.select() .from(getModelClass()) .where(getPrimaryConditionClause(model)).getQuery(), model); } /** * Assigns the {@link Cursor} data into the specified {@link TModel} * * @param model The model to assign cursor data to * @param cursor The cursor to load into the model */ public abstract void loadFromCursor(@NonNull FlowCursor cursor, @NonNull TModel model); /** * @param model The model to query values from * @return True if it exists as a row in the corresponding database table */ public boolean exists(@NonNull TModel model) { return exists(model, FlowManager.getDatabaseForTable(getModelClass()).getWritableDatabase()); } /** * @param model The model to query values from * @return True if it exists as a row in the corresponding database table */ public abstract boolean exists(@NonNull TModel model, @NonNull DatabaseWrapper databaseWrapper); /** * @param model The primary condition clause. * @return The clause that contains necessary primary conditions for this table. */ public abstract OperatorGroup getPrimaryConditionClause(@NonNull TModel model); /** * @return the model class this adapter corresponds to */ @NonNull public abstract Class<TModel> getModelClass(); @Nullable protected TableConfig<TModel> getTableConfig() { return tableConfig; } /** * @return A new {@link ListModelLoader}, caching will override this loader instance. */ @NonNull public ListModelLoader<TModel> getListModelLoader() { if (listModelLoader == null) { listModelLoader = createListModelLoader(); } return listModelLoader; } /** * @return A new {@link ListModelLoader}, caching will override this loader instance. */ @NonNull protected ListModelLoader<TModel> createListModelLoader() { return new ListModelLoader<>(getModelClass()); } /** * @return A new {@link SingleModelLoader}, caching will override this loader instance. */ @NonNull protected SingleModelLoader<TModel> createSingleModelLoader() { return new SingleModelLoader<>(getModelClass()); } @NonNull public SingleModelLoader<TModel> getSingleModelLoader() { if (singleModelLoader == null) { singleModelLoader = createSingleModelLoader(); } return singleModelLoader; } /** * @return A new instance of a {@link SingleModelLoader}. Subsequent calls do not cache * this object so it's recommended only calling this in bulk if possible. */ @NonNull public SingleModelLoader<TModel> getNonCacheableSingleModelLoader() { return new SingleModelLoader<>(getModelClass()); } /** * @return A new instance of a {@link ListModelLoader}. Subsequent calls do not cache * this object so it's recommended only calling this in bulk if possible. */ @NonNull public ListModelLoader<TModel> getNonCacheableListModelLoader() { return new ListModelLoader<>(getModelClass()); } /** * Overrides the default implementation and allows you to provide your own implementation. Defines * how a single {@link TModel} is loaded. * * @param singleModelLoader The loader to use. */ public void setSingleModelLoader(@NonNull SingleModelLoader<TModel> singleModelLoader) { this.singleModelLoader = singleModelLoader; } /** * Overrides the default implementation and allows you to provide your own implementation. Defines * how a list of {@link TModel} are loaded. * * @param listModelLoader The loader to use. */ public void setListModelLoader(@NonNull ListModelLoader<TModel> listModelLoader) { this.listModelLoader = listModelLoader; } }