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.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<RecentSearch> getAllRecentSearches();
suspend fun getAllRecentSearches(): List<RecentSearch>
@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<RecentSearch> findRecentSearchesWithNameContaining(String query);
suspend fun findRecentSearchesWithNameContaining(query: String): List<RecentSearch>
@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();
}
}

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;
import awais.instagrabber.db.dao.RecentSearchDao;
import awais.instagrabber.db.entities.RecentSearch;
import awais.instagrabber.models.enums.FavoriteType;
suspend fun getAllRecentSearches(): List<RecentSearch> = 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<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;
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<RecentSearch> = 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<RecentSearch> 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<List<RecentSearch>> callback) {
// 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);
});
});
}
suspend fun deleteRecentSearch(recentSearch: RecentSearch) = recentSearchDataSource.deleteRecentSearch(recentSearch)
public void insertOrUpdateRecentSearch(@NonNull final RecentSearch recentSearch,
final RepositoryCallback<Void> 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<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);
@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<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
class SearchResponse(// app
val list: List<SearchItem>,
// browser
val users: List<SearchItem>,
val places: List<SearchItem>,
val hashtags: List<SearchItem>,
// universal
val status: String)
data class SearchResponse(
// app
val list: List<SearchItem>?,
// browser
val users: List<SearchItem>?,
val places: List<SearchItem>?,
val hashtags: List<SearchItem>?,
// 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.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<List<RecentSearch>> recentResultsFuture = SettableFuture.create();
final SettableFuture<List<Favorite>> favoritesFuture = SettableFuture.create();
recentSearchRepository.getAllRecentSearches(new RepositoryCallback<List<RecentSearch>>() {
@Override
public void onSuccess(final List<RecentSearch> 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<RecentSearch>) 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
.<SearchItem>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<Void>() {
@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<Resource<Object>> data = new MutableLiveData<>();
data.postValue(Resource.loading(null));
recentSearchRepository.deleteRecentSearchByIgIdAndType(recentSearch.getIgId(), recentSearch.getType(), new RepositoryCallback<Void>() {
@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;
}
}