diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt index 164df5698362..384c1b7d9f03 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt @@ -41,11 +41,31 @@ interface FileDao { @Query("SELECT * FROM filelist WHERE remote_id = :remoteId LIMIT 1") suspend fun getFileByRemoteId(remoteId: String): FileEntity? - @Query("SELECT * FROM filelist WHERE parent = :parentId ORDER BY ${ProviderTableMeta.FILE_DEFAULT_SORT_ORDER}") - fun getFolderContent(parentId: Long): List + @Query( + """ + SELECT ${ProviderTableMeta._ID} + FROM filelist + WHERE parent = :parentId + ORDER BY ${ProviderTableMeta.FILE_DEFAULT_SORT_ORDER} + """ + ) + fun getFolderContentIds(parentId: Long): List - @Query("SELECT * FROM filelist WHERE parent = :parentId ORDER BY ${ProviderTableMeta.FILE_DEFAULT_SORT_ORDER}") - suspend fun getFolderContentSuspended(parentId: Long): List + @Query( + """ + SELECT ${ProviderTableMeta._ID} + FROM filelist + WHERE parent = :parentId + ORDER BY ${ProviderTableMeta.FILE_DEFAULT_SORT_ORDER} + """ + ) + suspend fun getFolderContentIdsSuspended(parentId: Long): List + + @Query("SELECT * FROM filelist WHERE ${ProviderTableMeta._ID} IN (:ids)") + fun getFilesByIds(ids: List): List + + @Query("SELECT * FROM filelist WHERE ${ProviderTableMeta._ID} IN (:ids)") + suspend fun getFilesByIdsSuspended(ids: List): List @Query( "SELECT * FROM filelist WHERE modified >= :startDate" + @@ -145,7 +165,7 @@ interface FileDao { @Query( """ - SELECT * + SELECT ${ProviderTableMeta._ID} FROM filelist WHERE file_owner = :accountName AND ( @@ -156,18 +176,18 @@ interface FileDao { ORDER BY ${ProviderTableMeta.FILE_DEFAULT_SORT_ORDER} """ ) - suspend fun getSharedFiles(accountName: String): List + suspend fun getSharedFileIds(accountName: String): List @Query( """ - SELECT * + SELECT ${ProviderTableMeta._ID} FROM filelist WHERE file_owner = :fileOwner AND favorite = 1 ORDER BY ${ProviderTableMeta.FILE_DEFAULT_SORT_ORDER} """ ) - suspend fun getFavoriteFiles(fileOwner: String): List + suspend fun getFavoriteFileIds(fileOwner: String): List @Query("SELECT remote_id FROM filelist WHERE file_owner = :accountName AND remote_id IS NOT NULL") fun getAllRemoteIds(accountName: String): List diff --git a/app/src/main/java/com/nextcloud/utils/extensions/FileDataStorageManagerExtensions.kt b/app/src/main/java/com/nextcloud/utils/extensions/FileDataStorageManagerExtensions.kt index b8c854613e47..4616a8cb2b0c 100644 --- a/app/src/main/java/com/nextcloud/utils/extensions/FileDataStorageManagerExtensions.kt +++ b/app/src/main/java/com/nextcloud/utils/extensions/FileDataStorageManagerExtensions.kt @@ -7,6 +7,7 @@ package com.nextcloud.utils.extensions +import com.nextcloud.client.database.entity.FileEntity import com.nextcloud.client.database.entity.model.ShareeKey import com.nextcloud.client.database.entity.toOCCapability import com.owncloud.android.datamodel.FileDataStorageManager @@ -116,3 +117,28 @@ fun FileDataStorageManager.getNonEncryptedSubfolders(id: Long, accountName: Stri suspend fun FileDataStorageManager.getCapabilitiesByAccountName(accountName: String): OCCapability = capabilityDao.getByAccountName(accountName).toOCCapability() + +private const val FILE_ID_CHUNK_SIZE = 100 + +private fun List.toEntitiesInOrder(loadChunk: (List) -> List): List { + val byId = chunked(FILE_ID_CHUNK_SIZE).flatMap(loadChunk).associateBy { it.id } + return mapNotNull { byId[it] } +} + +fun FileDataStorageManager.getFolderContentEntities(parentId: Long): List = + fileDao.getFolderContentIds(parentId).toEntitiesInOrder(fileDao::getFilesByIds) + +suspend fun FileDataStorageManager.getFolderContentEntitiesSuspended(parentId: Long): List = + fileDao.getFolderContentIdsSuspended(parentId).toEntitiesInOrderSuspended(this) + +suspend fun FileDataStorageManager.getSharedFileEntities(accountName: String): List = + fileDao.getSharedFileIds(accountName).toEntitiesInOrderSuspended(this) + +suspend fun FileDataStorageManager.getFavoriteFileEntities(accountName: String): List = + fileDao.getFavoriteFileIds(accountName).toEntitiesInOrderSuspended(this) + +private suspend fun List.toEntitiesInOrderSuspended(storageManager: FileDataStorageManager): List { + val entities = chunked(FILE_ID_CHUNK_SIZE).flatMap { storageManager.fileDao.getFilesByIdsSuspended(it) } + val byId = entities.associateBy { it.id } + return mapNotNull { byId[it] } +} diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index 1db87a82ea63..7c8ef61add6a 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -1317,7 +1317,7 @@ private List getFolderContent(long parentId, boolean onlyOnDevice) { Log_OC.d(TAG, "getFolderContent - start"); List folderContent = new ArrayList<>(); - List files = fileDao.getFolderContent(parentId); + List files = FileDataStorageManagerExtensionsKt.getFolderContentEntities(this, parentId); for (FileEntity fileEntity : files) { OCFile child = createFileInstance(fileEntity); if (!onlyOnDevice || child.existsOnDevice()) { diff --git a/app/src/main/java/com/owncloud/android/datamodel/OCFileListAdapterDataProviderImpl.kt b/app/src/main/java/com/owncloud/android/datamodel/OCFileListAdapterDataProviderImpl.kt index 3f09d4d6e276..b389203b6370 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/OCFileListAdapterDataProviderImpl.kt +++ b/app/src/main/java/com/owncloud/android/datamodel/OCFileListAdapterDataProviderImpl.kt @@ -8,6 +8,7 @@ package com.owncloud.android.datamodel import com.nextcloud.client.database.entity.FileEntity +import com.nextcloud.utils.extensions.getFolderContentEntitiesSuspended import com.owncloud.android.ui.adapter.helper.OCFileListAdapterDataProvider @Suppress("ReturnCount") @@ -17,7 +18,7 @@ class OCFileListAdapterDataProviderImpl(private val storageManager: FileDataStor storageManager.offlineOperationsRepository.convertToOCFiles(id) override suspend fun getFolderContent(id: Long): List = - storageManager.fileDao.getFolderContentSuspended(id) + storageManager.getFolderContentEntitiesSuspended(id) override fun createFileInstance(entity: FileEntity): OCFile = storageManager.createFileInstance(entity) } diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListSearchTask.kt b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListSearchTask.kt index e63a6188fd72..1b24f96f319f 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListSearchTask.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListSearchTask.kt @@ -15,6 +15,8 @@ import android.content.ContentValues import androidx.lifecycle.lifecycleScope import com.nextcloud.client.account.User import com.nextcloud.client.preferences.AppPreferences +import com.nextcloud.utils.extensions.getFavoriteFileEntities +import com.nextcloud.utils.extensions.getSharedFileEntities import com.owncloud.android.R import com.owncloud.android.datamodel.FileDataStorageManager import com.owncloud.android.datamodel.OCFile @@ -103,9 +105,9 @@ class OCFileListSearchTask( fragment: OCFileListFragment ): List { val files = if (searchType == SearchRemoteOperation.SearchType.SHARED_FILTER) { - storageManager.fileDao.getSharedFiles(currentUser.accountName) + storageManager.getSharedFileEntities(currentUser.accountName) } else { - storageManager.fileDao.getFavoriteFiles(currentUser.accountName) + storageManager.getFavoriteFileEntities(currentUser.accountName) }.mapNotNull { storageManager.createFileInstance(it) } return sortSearchData(files, fragmentSearchType, fragment)