Convert RecentSearchDao, RecentSearchDataSource and RecentSearchRepository to kotlin

This commit is contained in:
Ammar Githam 2021-06-08 21:15:27 +09:00
parent c49b44f212
commit 003beec5b6
5 changed files with 128 additions and 221 deletions

View File

@ -1,37 +1,29 @@
package awais.instagrabber.db.dao; package awais.instagrabber.db.dao
import androidx.room.Dao; import androidx.room.*
import androidx.room.Delete; import awais.instagrabber.db.entities.RecentSearch
import androidx.room.Insert; import awais.instagrabber.models.enums.FavoriteType
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
import awais.instagrabber.db.entities.RecentSearch;
import awais.instagrabber.models.enums.FavoriteType;
@Dao @Dao
public interface RecentSearchDao { interface RecentSearchDao {
@Query("SELECT * FROM recent_searches ORDER BY last_searched_on DESC") @Query("SELECT * FROM recent_searches ORDER BY last_searched_on DESC")
List<RecentSearch> getAllRecentSearches(); suspend fun getAllRecentSearches(): List<RecentSearch>
@Query("SELECT * FROM recent_searches WHERE `ig_id` = :igId AND `type` = :type") @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") @Query("SELECT * FROM recent_searches WHERE instr(`name`, :query) > 0")
List<RecentSearch> findRecentSearchesWithNameContaining(String query); suspend fun findRecentSearchesWithNameContaining(query: String): List<RecentSearch>
@Insert @Insert
Long insertRecentSearch(RecentSearch recentSearch); suspend fun insertRecentSearch(recentSearch: RecentSearch)
@Update @Update
void updateRecentSearch(RecentSearch recentSearch); suspend fun updateRecentSearch(recentSearch: RecentSearch)
@Delete @Delete
void deleteRecentSearch(RecentSearch recentSearch); suspend fun deleteRecentSearch(recentSearch: RecentSearch)
// @Query("DELETE from recent_searches") // @Query("DELETE from recent_searches")
// void deleteAllRecentSearches(); // void deleteAllRecentSearches();
} }

View File

@ -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; suspend fun getAllRecentSearches(): List<RecentSearch> = recentSearchDao.getAllRecentSearches()
import awais.instagrabber.db.dao.RecentSearchDao;
import awais.instagrabber.db.entities.RecentSearch;
import awais.instagrabber.models.enums.FavoriteType;
public class RecentSearchDataSource { suspend fun insertOrUpdateRecentSearch(recentSearch: RecentSearch) {
private static final String TAG = RecentSearchDataSource.class.getSimpleName(); if (recentSearch.id != 0) {
recentSearchDao.updateRecentSearch(recentSearch)
private static RecentSearchDataSource INSTANCE; return
}
private final RecentSearchDao recentSearchDao; recentSearchDao.insertRecentSearch(recentSearch)
private RecentSearchDataSource(final RecentSearchDao recentSearchDao) {
this.recentSearchDao = recentSearchDao;
} }
public static synchronized RecentSearchDataSource getInstance(@NonNull Context context) { suspend fun deleteRecentSearch(recentSearch: RecentSearch) = recentSearchDao.deleteRecentSearch(recentSearch)
if (INSTANCE == null) {
synchronized (RecentSearchDataSource.class) { companion object {
if (INSTANCE == null) { private lateinit var INSTANCE: RecentSearchDataSource
final AppDatabase database = AppDatabase.getDatabase(context);
INSTANCE = new RecentSearchDataSource(database.recentSearchDao()); @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<RecentSearch> 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);
}
}

View File

@ -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; class RecentSearchRepository private constructor(private val recentSearchDataSource: RecentSearchDataSource) {
import java.util.List; suspend fun getRecentSearch(igId: String, type: FavoriteType): RecentSearch? = recentSearchDataSource.getRecentSearchByIgIdAndType(igId, type)
import awais.instagrabber.db.datasources.RecentSearchDataSource; suspend fun getAllRecentSearches(): List<RecentSearch> = recentSearchDataSource.getAllRecentSearches()
import awais.instagrabber.db.entities.RecentSearch;
import awais.instagrabber.models.enums.FavoriteType;
import awais.instagrabber.utils.AppExecutors;
public class RecentSearchRepository { suspend fun insertOrUpdateRecentSearch(recentSearch: RecentSearch) =
private static final String TAG = RecentSearchRepository.class.getSimpleName(); insertOrUpdateRecentSearch(recentSearch.igId, recentSearch.name, recentSearch.username, recentSearch.picUrl, recentSearch.type)
private static RecentSearchRepository instance; private suspend fun insertOrUpdateRecentSearch(
igId: String,
private final AppExecutors appExecutors; name: String,
private final RecentSearchDataSource recentSearchDataSource; username: String?,
picUrl: String?,
private RecentSearchRepository(final AppExecutors appExecutors, final RecentSearchDataSource recentSearchDataSource) { type: FavoriteType,
this.appExecutors = appExecutors; ) {
this.recentSearchDataSource = recentSearchDataSource; var recentSearch = recentSearchDataSource.getRecentSearchByIgIdAndType(igId, type)
} recentSearch = if (recentSearch == null) {
RecentSearch(igId, name, username, picUrl, type, LocalDateTime.now())
public static RecentSearchRepository getInstance(final RecentSearchDataSource recentSearchDataSource) { } else {
if (instance == null) { RecentSearch(recentSearch.id, igId, name, username, picUrl, type, LocalDateTime.now())
instance = new RecentSearchRepository(AppExecutors.INSTANCE, recentSearchDataSource);
} }
return instance; recentSearchDataSource.insertOrUpdateRecentSearch(recentSearch)
} }
public void getRecentSearch(@NonNull final String igId, suspend fun deleteRecentSearchByIgIdAndType(igId: String, type: FavoriteType) {
@NonNull final FavoriteType type, val recentSearch = recentSearchDataSource.getRecentSearchByIgIdAndType(igId, type)
final RepositoryCallback<RecentSearch> callback) { if (recentSearch != null) {
// request on the I/O thread recentSearchDataSource.deleteRecentSearch(recentSearch)
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);
});
});
} }
public void getAllRecentSearches(final RepositoryCallback<List<RecentSearch>> callback) { suspend fun deleteRecentSearch(recentSearch: RecentSearch) = recentSearchDataSource.deleteRecentSearch(recentSearch)
// request on the I/O thread
appExecutors.getDiskIO().execute(() -> {
final List<RecentSearch> recentSearches = recentSearchDataSource.getAllRecentSearches();
// notify on the main thread
appExecutors.getMainThread().execute(() -> {
if (callback == null) return;
callback.onSuccess(recentSearches);
});
});
}
public void insertOrUpdateRecentSearch(@NonNull final RecentSearch recentSearch, companion object {
final RepositoryCallback<Void> callback) { private lateinit var instance: RecentSearchRepository
insertOrUpdateRecentSearch(recentSearch.getIgId(), recentSearch.getName(), recentSearch.getUsername(), recentSearch.getPicUrl(),
recentSearch.getType(), callback);
}
public void insertOrUpdateRecentSearch(@NonNull final String igId, @JvmStatic
@NonNull final String name, fun getInstance(recentSearchDataSource: RecentSearchDataSource): RecentSearchRepository {
final String username, if (!this::instance.isInitialized) {
final String picUrl, instance = RecentSearchRepository(recentSearchDataSource)
@NonNull final FavoriteType type,
final RepositoryCallback<Void> 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<Void> callback) {
// request on the I/O thread
appExecutors.getDiskIO().execute(() -> {
final RecentSearch recentSearch = recentSearchDataSource.getRecentSearchByIgIdAndType(igId, type);
if (recentSearch != null) {
recentSearchDataSource.deleteRecentSearch(recentSearch);
} }
// notify on the main thread return instance
appExecutors.getMainThread().execute(() -> { }
if (callback == null) return;
if (recentSearch == null) {
callback.onDataNotAvailable();
return;
}
callback.onSuccess(null);
});
});
} }
}
public void deleteRecentSearch(@NonNull final RecentSearch recentSearch,
final RepositoryCallback<Void> 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);
});
});
}
}

View File

@ -1,10 +1,12 @@
package awais.instagrabber.repositories.responses.search package awais.instagrabber.repositories.responses.search
class SearchResponse(// app data class SearchResponse(
val list: List<SearchItem>, // app
// browser val list: List<SearchItem>?,
val users: List<SearchItem>, // browser
val places: List<SearchItem>, val users: List<SearchItem>?,
val hashtags: List<SearchItem>, val places: List<SearchItem>?,
// universal val hashtags: List<SearchItem>?,
val status: String) // universal
val status: String?,
)

View File

@ -25,7 +25,6 @@ import awais.instagrabber.db.entities.Favorite;
import awais.instagrabber.db.entities.RecentSearch; import awais.instagrabber.db.entities.RecentSearch;
import awais.instagrabber.db.repositories.FavoriteRepository; import awais.instagrabber.db.repositories.FavoriteRepository;
import awais.instagrabber.db.repositories.RecentSearchRepository; import awais.instagrabber.db.repositories.RecentSearchRepository;
import awais.instagrabber.db.repositories.RepositoryCallback;
import awais.instagrabber.models.Resource; import awais.instagrabber.models.Resource;
import awais.instagrabber.models.enums.FavoriteType; import awais.instagrabber.models.enums.FavoriteType;
import awais.instagrabber.repositories.responses.search.SearchItem; import awais.instagrabber.repositories.responses.search.SearchItem;
@ -182,17 +181,17 @@ public class SearchFragmentViewModel extends AppStateViewModel {
private void showRecentSearchesAndFavorites() { private void showRecentSearchesAndFavorites() {
final SettableFuture<List<RecentSearch>> recentResultsFuture = SettableFuture.create(); final SettableFuture<List<RecentSearch>> recentResultsFuture = SettableFuture.create();
final SettableFuture<List<Favorite>> favoritesFuture = SettableFuture.create(); final SettableFuture<List<Favorite>> favoritesFuture = SettableFuture.create();
recentSearchRepository.getAllRecentSearches(new RepositoryCallback<List<RecentSearch>>() { recentSearchRepository.getAllRecentSearches(
@Override CoroutineUtilsKt.getContinuation((recentSearches, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
public void onSuccess(final List<RecentSearch> result) { if (throwable != null) {
recentResultsFuture.set(result); Log.e(TAG, "showRecentSearchesAndFavorites: ", throwable);
} recentResultsFuture.set(Collections.emptyList());
return;
@Override }
public void onDataNotAvailable() { //noinspection unchecked
recentResultsFuture.set(Collections.emptyList()); recentResultsFuture.set((List<RecentSearch>) recentSearches);
} }), Dispatchers.getIO())
}); );
favoriteRepository.getAllFavorites( favoriteRepository.getAllFavorites(
CoroutineUtilsKt.getContinuation((favorites, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { CoroutineUtilsKt.getContinuation((favorites, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
if (throwable != null) { if (throwable != null) {
@ -290,9 +289,9 @@ public class SearchFragmentViewModel extends AppStateViewModel {
case TOP: case TOP:
list = ImmutableList list = ImmutableList
.<SearchItem>builder() .<SearchItem>builder()
.addAll(body.getUsers()) .addAll(body.getUsers() == null ? Collections.emptyList() : body.getUsers())
.addAll(body.getHashtags()) .addAll(body.getHashtags() == null ? Collections.emptyList() : body.getHashtags())
.addAll(body.getPlaces()) .addAll(body.getPlaces() == null ? Collections.emptyList() : body.getPlaces())
.build(); .build();
break; break;
case USER: case USER:
@ -315,15 +314,16 @@ public class SearchFragmentViewModel extends AppStateViewModel {
try { try {
final RecentSearch recentSearch = RecentSearch.fromSearchItem(searchItem); final RecentSearch recentSearch = RecentSearch.fromSearchItem(searchItem);
if (recentSearch == null) return; if (recentSearch == null) return;
recentSearchRepository.insertOrUpdateRecentSearch(recentSearch, new RepositoryCallback<Void>() { recentSearchRepository.insertOrUpdateRecentSearch(
@Override recentSearch,
public void onSuccess(final Void result) { CoroutineUtilsKt.getContinuation((unit, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
// Log.d(TAG, "onSuccess: inserted recent: " + recentSearch); if (throwable != null) {
} Log.e(TAG, "saveToRecentSearches: ", throwable);
// return;
@Override }
public void onDataNotAvailable() {} // Log.d(TAG, "onSuccess: inserted recent: " + recentSearch);
}); }), Dispatchers.getIO())
);
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "saveToRecentSearches: ", e); Log.e(TAG, "saveToRecentSearches: ", e);
} }
@ -336,19 +336,18 @@ public class SearchFragmentViewModel extends AppStateViewModel {
if (recentSearch == null) return null; if (recentSearch == null) return null;
final MutableLiveData<Resource<Object>> data = new MutableLiveData<>(); final MutableLiveData<Resource<Object>> data = new MutableLiveData<>();
data.postValue(Resource.loading(null)); data.postValue(Resource.loading(null));
recentSearchRepository.deleteRecentSearchByIgIdAndType(recentSearch.getIgId(), recentSearch.getType(), new RepositoryCallback<Void>() { recentSearchRepository.deleteRecentSearchByIgIdAndType(
@Override recentSearch.getIgId(),
public void onSuccess(final Void result) { recentSearch.getType(),
// Log.d(TAG, "onSuccess: deleted"); CoroutineUtilsKt.getContinuation((unit, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> {
data.postValue(Resource.success(new Object())); if (throwable != null) {
} Log.e(TAG, "deleteRecentSearch: ", throwable);
data.postValue(Resource.error("Error deleting recent item", null));
@Override return;
public void onDataNotAvailable() { }
// Log.e(TAG, "onDataNotAvailable: not deleted"); data.postValue(Resource.success(new Object()));
data.postValue(Resource.error("Error deleting recent item", null)); }), Dispatchers.getIO())
} );
});
return data; return data;
} }
} }