mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Split BookmarkItemsDao apart and converted to Kotlin
This commit is contained in:
parent
95ad51e204
commit
8772a5a208
9 changed files with 341 additions and 359 deletions
|
|
@ -15,8 +15,7 @@ import com.facebook.drawee.backends.pipeline.Fresco
|
||||||
import com.facebook.imagepipeline.core.ImagePipelineConfig
|
import com.facebook.imagepipeline.core.ImagePipelineConfig
|
||||||
import fr.free.nrw.commons.auth.LoginActivity
|
import fr.free.nrw.commons.auth.LoginActivity
|
||||||
import fr.free.nrw.commons.auth.SessionManager
|
import fr.free.nrw.commons.auth.SessionManager
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao
|
|
||||||
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao
|
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao
|
||||||
import fr.free.nrw.commons.category.CategoryDao
|
import fr.free.nrw.commons.category.CategoryDao
|
||||||
import fr.free.nrw.commons.concurrency.BackgroundPoolExceptionHandler
|
import fr.free.nrw.commons.concurrency.BackgroundPoolExceptionHandler
|
||||||
|
|
@ -258,7 +257,7 @@ class CommonsApplication : MultiDexApplication() {
|
||||||
Timber.e(e)
|
Timber.e(e)
|
||||||
}
|
}
|
||||||
BookmarkPicturesDao.Table.onDelete(db)
|
BookmarkPicturesDao.Table.onDelete(db)
|
||||||
BookmarkItemsDao.Table.onDelete(db)
|
BookmarkItemsTable.onDelete(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package fr.free.nrw.commons.bookmarks.items;
|
package fr.free.nrw.commons.bookmarks.items;
|
||||||
|
|
||||||
import static fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.COLUMN_ID;
|
import static fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_ID;
|
||||||
import static fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.TABLE_NAME;
|
import static fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.TABLE_NAME;
|
||||||
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,6 @@ class BookmarkItemsController @Inject constructor() {
|
||||||
* @return a list of DepictedItem objects.
|
* @return a list of DepictedItem objects.
|
||||||
*/
|
*/
|
||||||
fun loadFavoritesItems(): List<DepictedItem> {
|
fun loadFavoritesItems(): List<DepictedItem> {
|
||||||
return bookmarkItemsDao?.allBookmarksItems ?: emptyList()
|
return bookmarkItemsDao?.getAllBookmarksItems() ?: emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,329 +0,0 @@
|
||||||
package fr.free.nrw.commons.bookmarks.items;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.ContentProviderClient;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
import fr.free.nrw.commons.category.CategoryItem;
|
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Provider;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles database operations for bookmarked items
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class BookmarkItemsDao {
|
|
||||||
|
|
||||||
private final Provider<ContentProviderClient> clientProvider;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public BookmarkItemsDao(
|
|
||||||
@Named("bookmarksItem") final Provider<ContentProviderClient> clientProvider) {
|
|
||||||
this.clientProvider = clientProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find all persisted items bookmarks on database
|
|
||||||
* @return list of bookmarks
|
|
||||||
*/
|
|
||||||
public List<DepictedItem> getAllBookmarksItems() {
|
|
||||||
final List<DepictedItem> items = new ArrayList<>();
|
|
||||||
final ContentProviderClient db = clientProvider.get();
|
|
||||||
try (final Cursor cursor = db.query(
|
|
||||||
BookmarkItemsContentProvider.BASE_URI,
|
|
||||||
Table.ALL_FIELDS,
|
|
||||||
null,
|
|
||||||
new String[]{},
|
|
||||||
null)) {
|
|
||||||
while (cursor != null && cursor.moveToNext()) {
|
|
||||||
items.add(fromCursor(cursor));
|
|
||||||
}
|
|
||||||
} catch (final RemoteException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} finally {
|
|
||||||
db.release();
|
|
||||||
}
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Look for a bookmark in database and in order to insert or delete it
|
|
||||||
* @param depictedItem : Bookmark object
|
|
||||||
* @return boolean : is bookmark now favorite ?
|
|
||||||
*/
|
|
||||||
public boolean updateBookmarkItem(final DepictedItem depictedItem) {
|
|
||||||
final boolean bookmarkExists = findBookmarkItem(depictedItem.getId());
|
|
||||||
if (bookmarkExists) {
|
|
||||||
deleteBookmarkItem(depictedItem);
|
|
||||||
} else {
|
|
||||||
addBookmarkItem(depictedItem);
|
|
||||||
}
|
|
||||||
return !bookmarkExists;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a Bookmark to database
|
|
||||||
* @param depictedItem : Bookmark to add
|
|
||||||
*/
|
|
||||||
private void addBookmarkItem(final DepictedItem depictedItem) {
|
|
||||||
final ContentProviderClient db = clientProvider.get();
|
|
||||||
try {
|
|
||||||
db.insert(BookmarkItemsContentProvider.BASE_URI, toContentValues(depictedItem));
|
|
||||||
} catch (final RemoteException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} finally {
|
|
||||||
db.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a bookmark from database
|
|
||||||
* @param depictedItem : Bookmark to delete
|
|
||||||
*/
|
|
||||||
private void deleteBookmarkItem(final DepictedItem depictedItem) {
|
|
||||||
final ContentProviderClient db = clientProvider.get();
|
|
||||||
try {
|
|
||||||
db.delete(BookmarkItemsContentProvider.uriForName(depictedItem.getId()), null, null);
|
|
||||||
} catch (final RemoteException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} finally {
|
|
||||||
db.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a bookmark from database based on its name
|
|
||||||
* @param depictedItemID : Bookmark to find
|
|
||||||
* @return boolean : is bookmark in database ?
|
|
||||||
*/
|
|
||||||
public boolean findBookmarkItem(final String depictedItemID) {
|
|
||||||
if (depictedItemID == null) { //Avoiding NPE's
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final ContentProviderClient db = clientProvider.get();
|
|
||||||
try (final Cursor cursor = db.query(
|
|
||||||
BookmarkItemsContentProvider.BASE_URI,
|
|
||||||
Table.ALL_FIELDS,
|
|
||||||
Table.COLUMN_ID + "=?",
|
|
||||||
new String[]{depictedItemID},
|
|
||||||
null
|
|
||||||
)) {
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (final RemoteException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} finally {
|
|
||||||
db.release();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recives real data from cursor
|
|
||||||
* @param cursor : Object for storing database data
|
|
||||||
* @return DepictedItem
|
|
||||||
*/
|
|
||||||
@SuppressLint("Range")
|
|
||||||
DepictedItem fromCursor(final Cursor cursor) {
|
|
||||||
final String fileName = cursor.getString(cursor.getColumnIndex(Table.COLUMN_NAME));
|
|
||||||
final String description
|
|
||||||
= cursor.getString(cursor.getColumnIndex(Table.COLUMN_DESCRIPTION));
|
|
||||||
final String imageUrl = cursor.getString(cursor.getColumnIndex(Table.COLUMN_IMAGE));
|
|
||||||
final String instanceListString
|
|
||||||
= cursor.getString(cursor.getColumnIndex(Table.COLUMN_INSTANCE_LIST));
|
|
||||||
final List<String> instanceList = StringToArray(instanceListString);
|
|
||||||
final String categoryNameListString = cursor.getString(cursor
|
|
||||||
.getColumnIndex(Table.COLUMN_CATEGORIES_NAME_LIST));
|
|
||||||
final List<String> categoryNameList = StringToArray(categoryNameListString);
|
|
||||||
final String categoryDescriptionListString = cursor.getString(cursor
|
|
||||||
.getColumnIndex(Table.COLUMN_CATEGORIES_DESCRIPTION_LIST));
|
|
||||||
final List<String> categoryDescriptionList = StringToArray(categoryDescriptionListString);
|
|
||||||
final String categoryThumbnailListString = cursor.getString(cursor
|
|
||||||
.getColumnIndex(Table.COLUMN_CATEGORIES_THUMBNAIL_LIST));
|
|
||||||
final List<String> categoryThumbnailList = StringToArray(categoryThumbnailListString);
|
|
||||||
final List<CategoryItem> categoryList = convertToCategoryItems(categoryNameList,
|
|
||||||
categoryDescriptionList, categoryThumbnailList);
|
|
||||||
final boolean isSelected
|
|
||||||
= Boolean.parseBoolean(cursor.getString(cursor
|
|
||||||
.getColumnIndex(Table.COLUMN_IS_SELECTED)));
|
|
||||||
final String id = cursor.getString(cursor.getColumnIndex(Table.COLUMN_ID));
|
|
||||||
|
|
||||||
return new DepictedItem(
|
|
||||||
fileName,
|
|
||||||
description,
|
|
||||||
imageUrl,
|
|
||||||
instanceList,
|
|
||||||
categoryList,
|
|
||||||
isSelected,
|
|
||||||
id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<CategoryItem> convertToCategoryItems(List<String> categoryNameList,
|
|
||||||
List<String> categoryDescriptionList, List<String> categoryThumbnailList) {
|
|
||||||
List<CategoryItem> categoryItems = new ArrayList<>();
|
|
||||||
for(int i=0; i<categoryNameList.size(); i++){
|
|
||||||
categoryItems.add(new CategoryItem(categoryNameList.get(i),
|
|
||||||
categoryDescriptionList.get(i),
|
|
||||||
categoryThumbnailList.get(i), false));
|
|
||||||
}
|
|
||||||
return categoryItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts string to List
|
|
||||||
* @param listString comma separated single string from of list items
|
|
||||||
* @return List of string
|
|
||||||
*/
|
|
||||||
private List<String> StringToArray(final String listString) {
|
|
||||||
final String[] elements = listString.split(",");
|
|
||||||
return Arrays.asList(elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts string to List
|
|
||||||
* @param list list of items
|
|
||||||
* @return string comma separated single string of items
|
|
||||||
*/
|
|
||||||
private String ArrayToString(final List<String> list) {
|
|
||||||
if (list != null) {
|
|
||||||
return StringUtils.join(list, ',');
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes data from DepictedItem and create a content value object
|
|
||||||
* @param depictedItem depicted item
|
|
||||||
* @return ContentValues
|
|
||||||
*/
|
|
||||||
private ContentValues toContentValues(final DepictedItem depictedItem) {
|
|
||||||
|
|
||||||
final List<String> namesOfCommonsCategories = new ArrayList<>();
|
|
||||||
for (final CategoryItem category :
|
|
||||||
depictedItem.getCommonsCategories()) {
|
|
||||||
namesOfCommonsCategories.add(category.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<String> descriptionsOfCommonsCategories = new ArrayList<>();
|
|
||||||
for (final CategoryItem category :
|
|
||||||
depictedItem.getCommonsCategories()) {
|
|
||||||
descriptionsOfCommonsCategories.add(category.getDescription());
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<String> thumbnailsOfCommonsCategories = new ArrayList<>();
|
|
||||||
for (final CategoryItem category :
|
|
||||||
depictedItem.getCommonsCategories()) {
|
|
||||||
thumbnailsOfCommonsCategories.add(category.getThumbnail());
|
|
||||||
}
|
|
||||||
|
|
||||||
final ContentValues cv = new ContentValues();
|
|
||||||
cv.put(Table.COLUMN_NAME, depictedItem.getName());
|
|
||||||
cv.put(Table.COLUMN_DESCRIPTION, depictedItem.getDescription());
|
|
||||||
cv.put(Table.COLUMN_IMAGE, depictedItem.getImageUrl());
|
|
||||||
cv.put(Table.COLUMN_INSTANCE_LIST, ArrayToString(depictedItem.getInstanceOfs()));
|
|
||||||
cv.put(Table.COLUMN_CATEGORIES_NAME_LIST, ArrayToString(namesOfCommonsCategories));
|
|
||||||
cv.put(Table.COLUMN_CATEGORIES_DESCRIPTION_LIST,
|
|
||||||
ArrayToString(descriptionsOfCommonsCategories));
|
|
||||||
cv.put(Table.COLUMN_CATEGORIES_THUMBNAIL_LIST,
|
|
||||||
ArrayToString(thumbnailsOfCommonsCategories));
|
|
||||||
cv.put(Table.COLUMN_IS_SELECTED, depictedItem.isSelected());
|
|
||||||
cv.put(Table.COLUMN_ID, depictedItem.getId());
|
|
||||||
return cv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Table of bookmarksItems data
|
|
||||||
*/
|
|
||||||
public static final class Table {
|
|
||||||
public static final String TABLE_NAME = "bookmarksItems";
|
|
||||||
public static final String COLUMN_NAME = "item_name";
|
|
||||||
public static final String COLUMN_DESCRIPTION = "item_description";
|
|
||||||
public static final String COLUMN_IMAGE = "item_image_url";
|
|
||||||
public static final String COLUMN_INSTANCE_LIST = "item_instance_of";
|
|
||||||
public static final String COLUMN_CATEGORIES_NAME_LIST = "item_name_categories";
|
|
||||||
public static final String COLUMN_CATEGORIES_DESCRIPTION_LIST = "item_description_categories";
|
|
||||||
public static final String COLUMN_CATEGORIES_THUMBNAIL_LIST = "item_thumbnail_categories";
|
|
||||||
public static final String COLUMN_IS_SELECTED = "item_is_selected";
|
|
||||||
public static final String COLUMN_ID = "item_id";
|
|
||||||
|
|
||||||
public static final String[] ALL_FIELDS = {
|
|
||||||
COLUMN_NAME,
|
|
||||||
COLUMN_DESCRIPTION,
|
|
||||||
COLUMN_IMAGE,
|
|
||||||
COLUMN_INSTANCE_LIST,
|
|
||||||
COLUMN_CATEGORIES_NAME_LIST,
|
|
||||||
COLUMN_CATEGORIES_DESCRIPTION_LIST,
|
|
||||||
COLUMN_CATEGORIES_THUMBNAIL_LIST,
|
|
||||||
COLUMN_IS_SELECTED,
|
|
||||||
COLUMN_ID
|
|
||||||
};
|
|
||||||
|
|
||||||
static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME;
|
|
||||||
static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
|
||||||
+ COLUMN_NAME + " STRING,"
|
|
||||||
+ COLUMN_DESCRIPTION + " STRING,"
|
|
||||||
+ COLUMN_IMAGE + " STRING,"
|
|
||||||
+ COLUMN_INSTANCE_LIST + " STRING,"
|
|
||||||
+ COLUMN_CATEGORIES_NAME_LIST + " STRING,"
|
|
||||||
+ COLUMN_CATEGORIES_DESCRIPTION_LIST + " STRING,"
|
|
||||||
+ COLUMN_CATEGORIES_THUMBNAIL_LIST + " STRING,"
|
|
||||||
+ COLUMN_IS_SELECTED + " STRING,"
|
|
||||||
+ COLUMN_ID + " STRING PRIMARY KEY"
|
|
||||||
+ ");";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates table
|
|
||||||
* @param db SQLiteDatabase
|
|
||||||
*/
|
|
||||||
public static void onCreate(final SQLiteDatabase db) {
|
|
||||||
db.execSQL(CREATE_TABLE_STATEMENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes database
|
|
||||||
* @param db SQLiteDatabase
|
|
||||||
*/
|
|
||||||
public static void onDelete(final SQLiteDatabase db) {
|
|
||||||
db.execSQL(DROP_TABLE_STATEMENT);
|
|
||||||
onCreate(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates database
|
|
||||||
* @param db SQLiteDatabase
|
|
||||||
* @param from starting
|
|
||||||
* @param to end
|
|
||||||
*/
|
|
||||||
public static void onUpdate(final SQLiteDatabase db, int from, final int to) {
|
|
||||||
if (from == to) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (from < 18) {
|
|
||||||
// doesn't exist yet
|
|
||||||
from++;
|
|
||||||
onUpdate(db, from, to);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (from == 18) {
|
|
||||||
// table added in version 19
|
|
||||||
onCreate(db);
|
|
||||||
from++;
|
|
||||||
onUpdate(db, from, to);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,223 @@
|
||||||
|
package fr.free.nrw.commons.bookmarks.items
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.ContentProviderClient
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.database.Cursor
|
||||||
|
import android.os.RemoteException
|
||||||
|
import androidx.core.content.contentValuesOf
|
||||||
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsContentProvider.BASE_URI
|
||||||
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsContentProvider.uriForName
|
||||||
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_CATEGORIES_DESCRIPTION_LIST
|
||||||
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_CATEGORIES_NAME_LIST
|
||||||
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_CATEGORIES_THUMBNAIL_LIST
|
||||||
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_DESCRIPTION
|
||||||
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_ID
|
||||||
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_IMAGE
|
||||||
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_INSTANCE_LIST
|
||||||
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_IS_SELECTED
|
||||||
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_NAME
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Named
|
||||||
|
import javax.inject.Provider
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles database operations for bookmarked items
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
class BookmarkItemsDao @Inject constructor(
|
||||||
|
@param:Named("bookmarksItem") private val clientProvider: Provider<ContentProviderClient>
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* Find all persisted items bookmarks on database
|
||||||
|
* @return list of bookmarks
|
||||||
|
*/
|
||||||
|
fun getAllBookmarksItems(): List<DepictedItem> {
|
||||||
|
val items: MutableList<DepictedItem> = mutableListOf()
|
||||||
|
val db = clientProvider.get()
|
||||||
|
try {
|
||||||
|
db.query(
|
||||||
|
BASE_URI,
|
||||||
|
BookmarkItemsTable.ALL_FIELDS,
|
||||||
|
null,
|
||||||
|
arrayOf(),
|
||||||
|
null
|
||||||
|
).use { cursor ->
|
||||||
|
while (cursor != null && cursor.moveToNext()) {
|
||||||
|
items.add(fromCursor(cursor))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
throw RuntimeException(e)
|
||||||
|
} finally {
|
||||||
|
db.release()
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look for a bookmark in database and in order to insert or delete it
|
||||||
|
* @param depictedItem : Bookmark object
|
||||||
|
* @return boolean : is bookmark now favorite ?
|
||||||
|
*/
|
||||||
|
fun updateBookmarkItem(depictedItem: DepictedItem): Boolean {
|
||||||
|
val bookmarkExists = findBookmarkItem(depictedItem.id)
|
||||||
|
if (bookmarkExists) {
|
||||||
|
deleteBookmarkItem(depictedItem)
|
||||||
|
} else {
|
||||||
|
addBookmarkItem(depictedItem)
|
||||||
|
}
|
||||||
|
return !bookmarkExists
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a Bookmark to database
|
||||||
|
* @param depictedItem : Bookmark to add
|
||||||
|
*/
|
||||||
|
private fun addBookmarkItem(depictedItem: DepictedItem) {
|
||||||
|
val db = clientProvider.get()
|
||||||
|
try {
|
||||||
|
db.insert(BASE_URI, toContentValues(depictedItem))
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
throw RuntimeException(e)
|
||||||
|
} finally {
|
||||||
|
db.release()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a bookmark from database
|
||||||
|
* @param depictedItem : Bookmark to delete
|
||||||
|
*/
|
||||||
|
private fun deleteBookmarkItem(depictedItem: DepictedItem) {
|
||||||
|
val db = clientProvider.get()
|
||||||
|
try {
|
||||||
|
db.delete(uriForName(depictedItem.id), null, null)
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
throw RuntimeException(e)
|
||||||
|
} finally {
|
||||||
|
db.release()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a bookmark from database based on its name
|
||||||
|
* @param depictedItemID : Bookmark to find
|
||||||
|
* @return boolean : is bookmark in database ?
|
||||||
|
*/
|
||||||
|
fun findBookmarkItem(depictedItemID: String?): Boolean {
|
||||||
|
if (depictedItemID == null) { //Avoiding NPE's
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val db = clientProvider.get()
|
||||||
|
try {
|
||||||
|
db.query(
|
||||||
|
BASE_URI,
|
||||||
|
BookmarkItemsTable.ALL_FIELDS,
|
||||||
|
COLUMN_ID + "=?",
|
||||||
|
arrayOf(depictedItemID),
|
||||||
|
null
|
||||||
|
).use { cursor ->
|
||||||
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
throw RuntimeException(e)
|
||||||
|
} finally {
|
||||||
|
db.release()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recives real data from cursor
|
||||||
|
* @param cursor : Object for storing database data
|
||||||
|
* @return DepictedItem
|
||||||
|
*/
|
||||||
|
@SuppressLint("Range")
|
||||||
|
fun fromCursor(cursor: Cursor) = with(cursor) {
|
||||||
|
DepictedItem(
|
||||||
|
getString(COLUMN_NAME),
|
||||||
|
getString(COLUMN_DESCRIPTION),
|
||||||
|
getString(COLUMN_IMAGE),
|
||||||
|
getStringArray(COLUMN_INSTANCE_LIST),
|
||||||
|
convertToCategoryItems(
|
||||||
|
getStringArray(COLUMN_CATEGORIES_NAME_LIST),
|
||||||
|
getStringArray(COLUMN_CATEGORIES_DESCRIPTION_LIST),
|
||||||
|
getStringArray(COLUMN_CATEGORIES_THUMBNAIL_LIST)
|
||||||
|
),
|
||||||
|
getString(COLUMN_IS_SELECTED).toBoolean(),
|
||||||
|
getString(COLUMN_ID)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Cursor.getStringArray(name: String): List<String> =
|
||||||
|
stringToArray(getString(name))
|
||||||
|
|
||||||
|
@SuppressLint("Range")
|
||||||
|
private fun Cursor.getString(name: String): String =
|
||||||
|
getString(getColumnIndex(name))
|
||||||
|
|
||||||
|
private fun convertToCategoryItems(
|
||||||
|
categoryNameList: List<String>,
|
||||||
|
categoryDescriptionList: List<String>,
|
||||||
|
categoryThumbnailList: List<String>
|
||||||
|
): List<CategoryItem> {
|
||||||
|
return buildList {
|
||||||
|
for (i in categoryNameList.indices) {
|
||||||
|
add(
|
||||||
|
CategoryItem(
|
||||||
|
categoryNameList[i],
|
||||||
|
categoryDescriptionList[i],
|
||||||
|
categoryThumbnailList[i],
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts string to List
|
||||||
|
* @param listString comma separated single string from of list items
|
||||||
|
* @return List of string
|
||||||
|
*/
|
||||||
|
private fun stringToArray(listString: String?): List<String> {
|
||||||
|
if (listString.isNullOrEmpty()) return emptyList();
|
||||||
|
val elements = listString.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||||
|
return listOf(*elements)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts string to List
|
||||||
|
* @param list list of items
|
||||||
|
* @return string comma separated single string of items
|
||||||
|
*/
|
||||||
|
private fun arrayToString(list: List<String?>?): String? {
|
||||||
|
return list?.joinToString(",")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes data from DepictedItem and create a content value object
|
||||||
|
* @param depictedItem depicted item
|
||||||
|
* @return ContentValues
|
||||||
|
*/
|
||||||
|
private fun toContentValues(depictedItem: DepictedItem): ContentValues {
|
||||||
|
return contentValuesOf(
|
||||||
|
COLUMN_NAME to depictedItem.name,
|
||||||
|
COLUMN_DESCRIPTION to depictedItem.description,
|
||||||
|
COLUMN_IMAGE to depictedItem.imageUrl,
|
||||||
|
COLUMN_INSTANCE_LIST to arrayToString(depictedItem.instanceOfs),
|
||||||
|
COLUMN_CATEGORIES_NAME_LIST to arrayToString(depictedItem.commonsCategories.map { it.name }),
|
||||||
|
COLUMN_CATEGORIES_DESCRIPTION_LIST to arrayToString(depictedItem.commonsCategories.map { it.description }),
|
||||||
|
COLUMN_CATEGORIES_THUMBNAIL_LIST to arrayToString(depictedItem.commonsCategories.map { it.thumbnail }),
|
||||||
|
COLUMN_IS_SELECTED to depictedItem.isSelected,
|
||||||
|
COLUMN_ID to depictedItem.id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
package fr.free.nrw.commons.bookmarks.items
|
||||||
|
|
||||||
|
import android.database.sqlite.SQLiteDatabase
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table of bookmarksItems data
|
||||||
|
*/
|
||||||
|
object BookmarkItemsTable {
|
||||||
|
const val TABLE_NAME = "bookmarksItems"
|
||||||
|
const val COLUMN_NAME = "item_name"
|
||||||
|
const val COLUMN_DESCRIPTION = "item_description"
|
||||||
|
const val COLUMN_IMAGE = "item_image_url"
|
||||||
|
const val COLUMN_INSTANCE_LIST = "item_instance_of"
|
||||||
|
const val COLUMN_CATEGORIES_NAME_LIST = "item_name_categories"
|
||||||
|
const val COLUMN_CATEGORIES_DESCRIPTION_LIST = "item_description_categories"
|
||||||
|
const val COLUMN_CATEGORIES_THUMBNAIL_LIST = "item_thumbnail_categories"
|
||||||
|
const val COLUMN_IS_SELECTED = "item_is_selected"
|
||||||
|
const val COLUMN_ID = "item_id"
|
||||||
|
|
||||||
|
val ALL_FIELDS = arrayOf(
|
||||||
|
COLUMN_NAME,
|
||||||
|
COLUMN_DESCRIPTION,
|
||||||
|
COLUMN_IMAGE,
|
||||||
|
COLUMN_INSTANCE_LIST,
|
||||||
|
COLUMN_CATEGORIES_NAME_LIST,
|
||||||
|
COLUMN_CATEGORIES_DESCRIPTION_LIST,
|
||||||
|
COLUMN_CATEGORIES_THUMBNAIL_LIST,
|
||||||
|
COLUMN_IS_SELECTED,
|
||||||
|
COLUMN_ID
|
||||||
|
)
|
||||||
|
|
||||||
|
const val DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS $TABLE_NAME"
|
||||||
|
|
||||||
|
val CREATE_TABLE_STATEMENT =
|
||||||
|
"""CREATE TABLE $TABLE_NAME (
|
||||||
|
$COLUMN_NAME STRING,
|
||||||
|
$COLUMN_DESCRIPTION STRING,
|
||||||
|
$COLUMN_IMAGE STRING,
|
||||||
|
$COLUMN_INSTANCE_LIST STRING,
|
||||||
|
$COLUMN_CATEGORIES_NAME_LIST STRING,
|
||||||
|
$COLUMN_CATEGORIES_DESCRIPTION_LIST STRING,
|
||||||
|
$COLUMN_CATEGORIES_THUMBNAIL_LIST STRING,
|
||||||
|
$COLUMN_IS_SELECTED STRING,
|
||||||
|
$COLUMN_ID STRING PRIMARY KEY
|
||||||
|
);""".trimIndent()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates table
|
||||||
|
*
|
||||||
|
* @param db SQLiteDatabase
|
||||||
|
*/
|
||||||
|
fun onCreate(db: SQLiteDatabase) {
|
||||||
|
db.execSQL(CREATE_TABLE_STATEMENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes database
|
||||||
|
*
|
||||||
|
* @param db SQLiteDatabase
|
||||||
|
*/
|
||||||
|
fun onDelete(db: SQLiteDatabase) {
|
||||||
|
db.execSQL(DROP_TABLE_STATEMENT)
|
||||||
|
onCreate(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates database
|
||||||
|
*
|
||||||
|
* @param db SQLiteDatabase
|
||||||
|
* @param from starting
|
||||||
|
* @param to end
|
||||||
|
*/
|
||||||
|
fun onUpdate(db: SQLiteDatabase, from: Int, to: Int) {
|
||||||
|
if (from == to) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from < 18) {
|
||||||
|
// doesn't exist yet
|
||||||
|
onUpdate(db, from + 1, to)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from == 18) {
|
||||||
|
// table added in version 19
|
||||||
|
onCreate(db)
|
||||||
|
onUpdate(db, from + 1, to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,8 +4,7 @@ import android.content.Context
|
||||||
import android.database.sqlite.SQLiteDatabase
|
import android.database.sqlite.SQLiteDatabase
|
||||||
import android.database.sqlite.SQLiteException
|
import android.database.sqlite.SQLiteException
|
||||||
import android.database.sqlite.SQLiteOpenHelper
|
import android.database.sqlite.SQLiteOpenHelper
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao
|
|
||||||
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao
|
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao
|
||||||
import fr.free.nrw.commons.category.CategoryDao
|
import fr.free.nrw.commons.category.CategoryDao
|
||||||
import fr.free.nrw.commons.explore.recentsearches.RecentSearchesDao
|
import fr.free.nrw.commons.explore.recentsearches.RecentSearchesDao
|
||||||
|
|
@ -31,7 +30,7 @@ class DBOpenHelper(
|
||||||
override fun onCreate(db: SQLiteDatabase) {
|
override fun onCreate(db: SQLiteDatabase) {
|
||||||
CategoryDao.Table.onCreate(db)
|
CategoryDao.Table.onCreate(db)
|
||||||
BookmarkPicturesDao.Table.onCreate(db)
|
BookmarkPicturesDao.Table.onCreate(db)
|
||||||
BookmarkItemsDao.Table.onCreate(db)
|
BookmarkItemsTable.onCreate(db)
|
||||||
RecentSearchesDao.Table.onCreate(db)
|
RecentSearchesDao.Table.onCreate(db)
|
||||||
RecentLanguagesDao.Table.onCreate(db)
|
RecentLanguagesDao.Table.onCreate(db)
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +38,7 @@ class DBOpenHelper(
|
||||||
override fun onUpgrade(db: SQLiteDatabase, from: Int, to: Int) {
|
override fun onUpgrade(db: SQLiteDatabase, from: Int, to: Int) {
|
||||||
CategoryDao.Table.onUpdate(db, from, to)
|
CategoryDao.Table.onUpdate(db, from, to)
|
||||||
BookmarkPicturesDao.Table.onUpdate(db, from, to)
|
BookmarkPicturesDao.Table.onUpdate(db, from, to)
|
||||||
BookmarkItemsDao.Table.onUpdate(db, from, to)
|
BookmarkItemsTable.onUpdate(db, from, to)
|
||||||
RecentSearchesDao.Table.onUpdate(db, from, to)
|
RecentSearchesDao.Table.onUpdate(db, from, to)
|
||||||
RecentLanguagesDao.Table.onUpdate(db, from, to)
|
RecentLanguagesDao.Table.onUpdate(db, from, to)
|
||||||
deleteTable(db, CONTRIBUTIONS_TABLE)
|
deleteTable(db, CONTRIBUTIONS_TABLE)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class BookmarkItemsControllerTest {
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
MockitoAnnotations.openMocks(this)
|
MockitoAnnotations.openMocks(this)
|
||||||
whenever(bookmarkDao!!.allBookmarksItems)
|
whenever(bookmarkDao!!.getAllBookmarksItems())
|
||||||
.thenReturn(mockBookmarkList)
|
.thenReturn(mockBookmarkList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,20 +18,20 @@ import com.nhaarman.mockitokotlin2.mock
|
||||||
import com.nhaarman.mockitokotlin2.verify
|
import com.nhaarman.mockitokotlin2.verify
|
||||||
import com.nhaarman.mockitokotlin2.whenever
|
import com.nhaarman.mockitokotlin2.whenever
|
||||||
import fr.free.nrw.commons.TestCommonsApplication
|
import fr.free.nrw.commons.TestCommonsApplication
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.COLUMN_CATEGORIES_DESCRIPTION_LIST
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_CATEGORIES_DESCRIPTION_LIST
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.COLUMN_CATEGORIES_NAME_LIST
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_CATEGORIES_NAME_LIST
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.COLUMN_CATEGORIES_THUMBNAIL_LIST
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_CATEGORIES_THUMBNAIL_LIST
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.COLUMN_DESCRIPTION
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_DESCRIPTION
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.COLUMN_ID
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_ID
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.COLUMN_IMAGE
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_IMAGE
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.COLUMN_INSTANCE_LIST
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_INSTANCE_LIST
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.COLUMN_IS_SELECTED
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_IS_SELECTED
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.COLUMN_NAME
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.COLUMN_NAME
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.CREATE_TABLE_STATEMENT
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.CREATE_TABLE_STATEMENT
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.DROP_TABLE_STATEMENT
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.DROP_TABLE_STATEMENT
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.onCreate
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.onCreate
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.onDelete
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.onDelete
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.onUpdate
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsTable.onUpdate
|
||||||
import fr.free.nrw.commons.category.CategoryItem
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
|
|
@ -135,7 +135,7 @@ class BookmarkItemsDaoTest {
|
||||||
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull()))
|
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull()))
|
||||||
.thenReturn(createCursor(14))
|
.thenReturn(createCursor(14))
|
||||||
|
|
||||||
val result = testObject.allBookmarksItems
|
val result = testObject.getAllBookmarksItems()
|
||||||
|
|
||||||
Assert.assertEquals(14, (result.size))
|
Assert.assertEquals(14, (result.size))
|
||||||
}
|
}
|
||||||
|
|
@ -145,20 +145,20 @@ class BookmarkItemsDaoTest {
|
||||||
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenThrow(
|
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenThrow(
|
||||||
RemoteException(""),
|
RemoteException(""),
|
||||||
)
|
)
|
||||||
testObject.allBookmarksItems
|
testObject.getAllBookmarksItems()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getAllItemsBookmarksReturnsEmptyList_emptyCursor() {
|
fun getAllItemsBookmarksReturnsEmptyList_emptyCursor() {
|
||||||
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull()))
|
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull()))
|
||||||
.thenReturn(createCursor(0))
|
.thenReturn(createCursor(0))
|
||||||
Assert.assertTrue(testObject.allBookmarksItems.isEmpty())
|
Assert.assertTrue(testObject.getAllBookmarksItems().isEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getAllItemsBookmarksReturnsEmptyList_nullCursor() {
|
fun getAllItemsBookmarksReturnsEmptyList_nullCursor() {
|
||||||
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(null)
|
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(null)
|
||||||
Assert.assertTrue(testObject.allBookmarksItems.isEmpty())
|
Assert.assertTrue(testObject.getAllBookmarksItems().isEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -167,7 +167,7 @@ class BookmarkItemsDaoTest {
|
||||||
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(mockCursor)
|
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(mockCursor)
|
||||||
whenever(mockCursor.moveToFirst()).thenReturn(false)
|
whenever(mockCursor.moveToFirst()).thenReturn(false)
|
||||||
|
|
||||||
testObject.allBookmarksItems
|
testObject.getAllBookmarksItems()
|
||||||
|
|
||||||
verify(mockCursor).close()
|
verify(mockCursor).close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue