From 003beec5b6f9914dfc48687b4bdaada596b79bd7 Mon Sep 17 00:00:00 2001 From: Ammar Githam Date: Tue, 8 Jun 2021 21:15:27 +0900 Subject: [PATCH] Convert RecentSearchDao, RecentSearchDataSource and RecentSearchRepository to kotlin --- .../instagrabber/db/dao/RecentSearchDao.kt | 32 ++-- .../db/datasources/RecentSearchDataSource.kt | 78 ++++----- .../db/repositories/RecentSearchRepository.kt | 148 +++++------------- .../responses/search/SearchResponse.kt | 18 ++- .../viewmodels/SearchFragmentViewModel.java | 73 +++++---- 5 files changed, 128 insertions(+), 221 deletions(-) diff --git a/app/src/main/java/awais/instagrabber/db/dao/RecentSearchDao.kt b/app/src/main/java/awais/instagrabber/db/dao/RecentSearchDao.kt index 94266524..b4ed3d4e 100644 --- a/app/src/main/java/awais/instagrabber/db/dao/RecentSearchDao.kt +++ b/app/src/main/java/awais/instagrabber/db/dao/RecentSearchDao.kt @@ -1,37 +1,29 @@ -package awais.instagrabber.db.dao; +package awais.instagrabber.db.dao -import androidx.room.Dao; -import androidx.room.Delete; -import androidx.room.Insert; -import androidx.room.Query; -import androidx.room.Update; - -import java.util.List; - -import awais.instagrabber.db.entities.RecentSearch; -import awais.instagrabber.models.enums.FavoriteType; +import androidx.room.* +import awais.instagrabber.db.entities.RecentSearch +import awais.instagrabber.models.enums.FavoriteType @Dao -public interface RecentSearchDao { - +interface RecentSearchDao { @Query("SELECT * FROM recent_searches ORDER BY last_searched_on DESC") - List getAllRecentSearches(); + suspend fun getAllRecentSearches(): List @Query("SELECT * FROM recent_searches WHERE `ig_id` = :igId AND `type` = :type") - RecentSearch getRecentSearchByIgIdAndType(String igId, FavoriteType type); + suspend fun getRecentSearchByIgIdAndType(igId: String, type: FavoriteType): RecentSearch? @Query("SELECT * FROM recent_searches WHERE instr(`name`, :query) > 0") - List findRecentSearchesWithNameContaining(String query); + suspend fun findRecentSearchesWithNameContaining(query: String): List @Insert - Long insertRecentSearch(RecentSearch recentSearch); + suspend fun insertRecentSearch(recentSearch: RecentSearch) @Update - void updateRecentSearch(RecentSearch recentSearch); + suspend fun updateRecentSearch(recentSearch: RecentSearch) @Delete - void deleteRecentSearch(RecentSearch recentSearch); + suspend fun deleteRecentSearch(recentSearch: RecentSearch) // @Query("DELETE from recent_searches") // void deleteAllRecentSearches(); -} +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/db/datasources/RecentSearchDataSource.kt b/app/src/main/java/awais/instagrabber/db/datasources/RecentSearchDataSource.kt index 9fd950a8..67149ea9 100644 --- a/app/src/main/java/awais/instagrabber/db/datasources/RecentSearchDataSource.kt +++ b/app/src/main/java/awais/instagrabber/db/datasources/RecentSearchDataSource.kt @@ -1,57 +1,43 @@ -package awais.instagrabber.db.datasources; +package awais.instagrabber.db.datasources -import android.content.Context; +import android.content.Context +import awais.instagrabber.db.AppDatabase +import awais.instagrabber.db.dao.RecentSearchDao +import awais.instagrabber.db.entities.RecentSearch +import awais.instagrabber.models.enums.FavoriteType -import androidx.annotation.NonNull; +class RecentSearchDataSource private constructor(private val recentSearchDao: RecentSearchDao) { -import java.util.List; + suspend fun getRecentSearchByIgIdAndType(igId: String, type: FavoriteType): RecentSearch? = + recentSearchDao.getRecentSearchByIgIdAndType(igId, type) -import awais.instagrabber.db.AppDatabase; -import awais.instagrabber.db.dao.RecentSearchDao; -import awais.instagrabber.db.entities.RecentSearch; -import awais.instagrabber.models.enums.FavoriteType; + suspend fun getAllRecentSearches(): List = recentSearchDao.getAllRecentSearches() -public class RecentSearchDataSource { - private static final String TAG = RecentSearchDataSource.class.getSimpleName(); - - private static RecentSearchDataSource INSTANCE; - - private final RecentSearchDao recentSearchDao; - - private RecentSearchDataSource(final RecentSearchDao recentSearchDao) { - this.recentSearchDao = recentSearchDao; + suspend fun insertOrUpdateRecentSearch(recentSearch: RecentSearch) { + if (recentSearch.id != 0) { + recentSearchDao.updateRecentSearch(recentSearch) + return + } + recentSearchDao.insertRecentSearch(recentSearch) } - public static synchronized RecentSearchDataSource getInstance(@NonNull Context context) { - if (INSTANCE == null) { - synchronized (RecentSearchDataSource.class) { - if (INSTANCE == null) { - final AppDatabase database = AppDatabase.getDatabase(context); - INSTANCE = new RecentSearchDataSource(database.recentSearchDao()); + suspend fun deleteRecentSearch(recentSearch: RecentSearch) = recentSearchDao.deleteRecentSearch(recentSearch) + + companion object { + private lateinit var INSTANCE: RecentSearchDataSource + + @JvmStatic + @Synchronized + fun getInstance(context: Context): RecentSearchDataSource { + if (!this::INSTANCE.isInitialized) { + synchronized(RecentSearchDataSource::class.java) { + if (!this::INSTANCE.isInitialized) { + val database = AppDatabase.getDatabase(context) + INSTANCE = RecentSearchDataSource(database.recentSearchDao()) + } } } + return INSTANCE } - return INSTANCE; } - - public RecentSearch getRecentSearchByIgIdAndType(@NonNull final String igId, @NonNull final FavoriteType type) { - return recentSearchDao.getRecentSearchByIgIdAndType(igId, type); - } - - @NonNull - public final List getAllRecentSearches() { - return recentSearchDao.getAllRecentSearches(); - } - - public final void insertOrUpdateRecentSearch(@NonNull final RecentSearch recentSearch) { - if (recentSearch.getId() != 0) { - recentSearchDao.updateRecentSearch(recentSearch); - return; - } - recentSearchDao.insertRecentSearch(recentSearch); - } - - public final void deleteRecentSearch(@NonNull final RecentSearch recentSearch) { - recentSearchDao.deleteRecentSearch(recentSearch); - } -} +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/db/repositories/RecentSearchRepository.kt b/app/src/main/java/awais/instagrabber/db/repositories/RecentSearchRepository.kt index 1ee00613..6ff754da 100644 --- a/app/src/main/java/awais/instagrabber/db/repositories/RecentSearchRepository.kt +++ b/app/src/main/java/awais/instagrabber/db/repositories/RecentSearchRepository.kt @@ -1,124 +1,52 @@ -package awais.instagrabber.db.repositories; +package awais.instagrabber.db.repositories -import androidx.annotation.NonNull; +import awais.instagrabber.db.datasources.RecentSearchDataSource +import awais.instagrabber.db.entities.RecentSearch +import awais.instagrabber.models.enums.FavoriteType +import java.time.LocalDateTime -import java.time.LocalDateTime; -import java.util.List; +class RecentSearchRepository private constructor(private val recentSearchDataSource: RecentSearchDataSource) { + suspend fun getRecentSearch(igId: String, type: FavoriteType): RecentSearch? = recentSearchDataSource.getRecentSearchByIgIdAndType(igId, type) -import awais.instagrabber.db.datasources.RecentSearchDataSource; -import awais.instagrabber.db.entities.RecentSearch; -import awais.instagrabber.models.enums.FavoriteType; -import awais.instagrabber.utils.AppExecutors; + suspend fun getAllRecentSearches(): List = recentSearchDataSource.getAllRecentSearches() -public class RecentSearchRepository { - private static final String TAG = RecentSearchRepository.class.getSimpleName(); + suspend fun insertOrUpdateRecentSearch(recentSearch: RecentSearch) = + insertOrUpdateRecentSearch(recentSearch.igId, recentSearch.name, recentSearch.username, recentSearch.picUrl, recentSearch.type) - private static RecentSearchRepository instance; - - private final AppExecutors appExecutors; - private final RecentSearchDataSource recentSearchDataSource; - - private RecentSearchRepository(final AppExecutors appExecutors, final RecentSearchDataSource recentSearchDataSource) { - this.appExecutors = appExecutors; - this.recentSearchDataSource = recentSearchDataSource; - } - - public static RecentSearchRepository getInstance(final RecentSearchDataSource recentSearchDataSource) { - if (instance == null) { - instance = new RecentSearchRepository(AppExecutors.INSTANCE, recentSearchDataSource); + private suspend fun insertOrUpdateRecentSearch( + igId: String, + name: String, + username: String?, + picUrl: String?, + type: FavoriteType, + ) { + var recentSearch = recentSearchDataSource.getRecentSearchByIgIdAndType(igId, type) + recentSearch = if (recentSearch == null) { + RecentSearch(igId, name, username, picUrl, type, LocalDateTime.now()) + } else { + RecentSearch(recentSearch.id, igId, name, username, picUrl, type, LocalDateTime.now()) } - return instance; + recentSearchDataSource.insertOrUpdateRecentSearch(recentSearch) } - public void getRecentSearch(@NonNull final String igId, - @NonNull final FavoriteType type, - final RepositoryCallback callback) { - // request on the I/O thread - appExecutors.getDiskIO().execute(() -> { - final RecentSearch recentSearch = recentSearchDataSource.getRecentSearchByIgIdAndType(igId, type); - // notify on the main thread - appExecutors.getMainThread().execute(() -> { - if (callback == null) return; - if (recentSearch == null) { - callback.onDataNotAvailable(); - return; - } - callback.onSuccess(recentSearch); - }); - }); + suspend fun deleteRecentSearchByIgIdAndType(igId: String, type: FavoriteType) { + val recentSearch = recentSearchDataSource.getRecentSearchByIgIdAndType(igId, type) + if (recentSearch != null) { + recentSearchDataSource.deleteRecentSearch(recentSearch) + } } - public void getAllRecentSearches(final RepositoryCallback> callback) { - // request on the I/O thread - appExecutors.getDiskIO().execute(() -> { - final List recentSearches = recentSearchDataSource.getAllRecentSearches(); - // notify on the main thread - appExecutors.getMainThread().execute(() -> { - if (callback == null) return; - callback.onSuccess(recentSearches); - }); - }); - } + suspend fun deleteRecentSearch(recentSearch: RecentSearch) = recentSearchDataSource.deleteRecentSearch(recentSearch) - public void insertOrUpdateRecentSearch(@NonNull final RecentSearch recentSearch, - final RepositoryCallback callback) { - insertOrUpdateRecentSearch(recentSearch.getIgId(), recentSearch.getName(), recentSearch.getUsername(), recentSearch.getPicUrl(), - recentSearch.getType(), callback); - } + companion object { + private lateinit var instance: RecentSearchRepository - public void insertOrUpdateRecentSearch(@NonNull final String igId, - @NonNull final String name, - final String username, - final String picUrl, - @NonNull final FavoriteType type, - final RepositoryCallback callback) { - // request on the I/O thread - appExecutors.getDiskIO().execute(() -> { - RecentSearch recentSearch = recentSearchDataSource.getRecentSearchByIgIdAndType(igId, type); - recentSearch = recentSearch == null - ? new RecentSearch(igId, name, username, picUrl, type, LocalDateTime.now()) - : new RecentSearch(recentSearch.getId(), igId, name, username, picUrl, type, LocalDateTime.now()); - recentSearchDataSource.insertOrUpdateRecentSearch(recentSearch); - // notify on the main thread - appExecutors.getMainThread().execute(() -> { - if (callback == null) return; - callback.onSuccess(null); - }); - }); - } - - public void deleteRecentSearchByIgIdAndType(@NonNull final String igId, - @NonNull final FavoriteType type, - final RepositoryCallback callback) { - // request on the I/O thread - appExecutors.getDiskIO().execute(() -> { - final RecentSearch recentSearch = recentSearchDataSource.getRecentSearchByIgIdAndType(igId, type); - if (recentSearch != null) { - recentSearchDataSource.deleteRecentSearch(recentSearch); + @JvmStatic + fun getInstance(recentSearchDataSource: RecentSearchDataSource): RecentSearchRepository { + if (!this::instance.isInitialized) { + instance = RecentSearchRepository(recentSearchDataSource) } - // notify on the main thread - appExecutors.getMainThread().execute(() -> { - if (callback == null) return; - if (recentSearch == null) { - callback.onDataNotAvailable(); - return; - } - callback.onSuccess(null); - }); - }); + return instance + } } - - public void deleteRecentSearch(@NonNull final RecentSearch recentSearch, - final RepositoryCallback callback) { - // request on the I/O thread - appExecutors.getDiskIO().execute(() -> { - - recentSearchDataSource.deleteRecentSearch(recentSearch); - // notify on the main thread - appExecutors.getMainThread().execute(() -> { - if (callback == null) return; - callback.onSuccess(null); - }); - }); - } -} +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/repositories/responses/search/SearchResponse.kt b/app/src/main/java/awais/instagrabber/repositories/responses/search/SearchResponse.kt index 25f148ca..932af2a0 100644 --- a/app/src/main/java/awais/instagrabber/repositories/responses/search/SearchResponse.kt +++ b/app/src/main/java/awais/instagrabber/repositories/responses/search/SearchResponse.kt @@ -1,10 +1,12 @@ package awais.instagrabber.repositories.responses.search -class SearchResponse(// app - val list: List, - // browser - val users: List, - val places: List, - val hashtags: List, - // universal - val status: String) \ No newline at end of file +data class SearchResponse( + // app + val list: List?, + // browser + val users: List?, + val places: List?, + val hashtags: List?, + // universal + val status: String?, +) \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/viewmodels/SearchFragmentViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/SearchFragmentViewModel.java index 18811a7d..6ddb915e 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/SearchFragmentViewModel.java +++ b/app/src/main/java/awais/instagrabber/viewmodels/SearchFragmentViewModel.java @@ -25,7 +25,6 @@ import awais.instagrabber.db.entities.Favorite; import awais.instagrabber.db.entities.RecentSearch; import awais.instagrabber.db.repositories.FavoriteRepository; import awais.instagrabber.db.repositories.RecentSearchRepository; -import awais.instagrabber.db.repositories.RepositoryCallback; import awais.instagrabber.models.Resource; import awais.instagrabber.models.enums.FavoriteType; import awais.instagrabber.repositories.responses.search.SearchItem; @@ -182,17 +181,17 @@ public class SearchFragmentViewModel extends AppStateViewModel { private void showRecentSearchesAndFavorites() { final SettableFuture> recentResultsFuture = SettableFuture.create(); final SettableFuture> favoritesFuture = SettableFuture.create(); - recentSearchRepository.getAllRecentSearches(new RepositoryCallback>() { - @Override - public void onSuccess(final List result) { - recentResultsFuture.set(result); - } - - @Override - public void onDataNotAvailable() { - recentResultsFuture.set(Collections.emptyList()); - } - }); + recentSearchRepository.getAllRecentSearches( + CoroutineUtilsKt.getContinuation((recentSearches, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null) { + Log.e(TAG, "showRecentSearchesAndFavorites: ", throwable); + recentResultsFuture.set(Collections.emptyList()); + return; + } + //noinspection unchecked + recentResultsFuture.set((List) recentSearches); + }), Dispatchers.getIO()) + ); favoriteRepository.getAllFavorites( CoroutineUtilsKt.getContinuation((favorites, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { if (throwable != null) { @@ -290,9 +289,9 @@ public class SearchFragmentViewModel extends AppStateViewModel { case TOP: list = ImmutableList .builder() - .addAll(body.getUsers()) - .addAll(body.getHashtags()) - .addAll(body.getPlaces()) + .addAll(body.getUsers() == null ? Collections.emptyList() : body.getUsers()) + .addAll(body.getHashtags() == null ? Collections.emptyList() : body.getHashtags()) + .addAll(body.getPlaces() == null ? Collections.emptyList() : body.getPlaces()) .build(); break; case USER: @@ -315,15 +314,16 @@ public class SearchFragmentViewModel extends AppStateViewModel { try { final RecentSearch recentSearch = RecentSearch.fromSearchItem(searchItem); if (recentSearch == null) return; - recentSearchRepository.insertOrUpdateRecentSearch(recentSearch, new RepositoryCallback() { - @Override - public void onSuccess(final Void result) { - // Log.d(TAG, "onSuccess: inserted recent: " + recentSearch); - } - - @Override - public void onDataNotAvailable() {} - }); + recentSearchRepository.insertOrUpdateRecentSearch( + recentSearch, + CoroutineUtilsKt.getContinuation((unit, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null) { + Log.e(TAG, "saveToRecentSearches: ", throwable); + // return; + } + // Log.d(TAG, "onSuccess: inserted recent: " + recentSearch); + }), Dispatchers.getIO()) + ); } catch (Exception e) { Log.e(TAG, "saveToRecentSearches: ", e); } @@ -336,19 +336,18 @@ public class SearchFragmentViewModel extends AppStateViewModel { if (recentSearch == null) return null; final MutableLiveData> data = new MutableLiveData<>(); data.postValue(Resource.loading(null)); - recentSearchRepository.deleteRecentSearchByIgIdAndType(recentSearch.getIgId(), recentSearch.getType(), new RepositoryCallback() { - @Override - public void onSuccess(final Void result) { - // Log.d(TAG, "onSuccess: deleted"); - data.postValue(Resource.success(new Object())); - } - - @Override - public void onDataNotAvailable() { - // Log.e(TAG, "onDataNotAvailable: not deleted"); - data.postValue(Resource.error("Error deleting recent item", null)); - } - }); + recentSearchRepository.deleteRecentSearchByIgIdAndType( + recentSearch.getIgId(), + recentSearch.getType(), + CoroutineUtilsKt.getContinuation((unit, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null) { + Log.e(TAG, "deleteRecentSearch: ", throwable); + data.postValue(Resource.error("Error deleting recent item", null)); + return; + } + data.postValue(Resource.success(new Object())); + }), Dispatchers.getIO()) + ); return data; } }