77
88package com.nextcloud.utils.extensions
99
10- import android.os.RemoteException
10+ import com.nextcloud.client.database.entity.model.ShareeKey
1111import com.nextcloud.client.database.entity.toOCCapability
1212import com.owncloud.android.datamodel.FileDataStorageManager
1313import com.owncloud.android.datamodel.OCFile
14- import com.owncloud.android.db.ProviderMeta.ProviderTableMeta
15- import com.owncloud.android.lib.common.utils.Log_OC
1614import com.owncloud.android.lib.resources.files.model.RemoteFile
1715import com.owncloud.android.lib.resources.shares.OCShare
18- import com.owncloud.android.lib.resources.shares.ShareType
1916import com.owncloud.android.lib.resources.status.OCCapability
2017import kotlinx.coroutines.Dispatchers
2118import kotlinx.coroutines.withContext
22- import kotlin.collections.asSequence
23-
24- // matches FileDataStorageManager.getSharesWithForAFile, excludes public link shares
25- private val shareableShareTypes = listOf (
26- ShareType .USER ,
27- ShareType .GROUP ,
28- ShareType .EMAIL ,
29- ShareType .FEDERATED ,
30- ShareType .FEDERATED_GROUP ,
31- ShareType .ROOM ,
32- ShareType .CIRCLE
33- )
19+
3420
3521// keeps queries well under SQLite's bound-parameter limit
3622private const val SHARE_PATH_QUERY_CHUNK_SIZE = 400
@@ -50,61 +36,17 @@ fun FileDataStorageManager.areShareesChanged(remoteFiles: List<RemoteFile>): Boo
5036 .toSet()
5137 }
5238
53- val existingShareesByPath = queryLocalShareeKeysByPath(newShareesByPath.keys, user.accountName)
39+ val existingShareesByPath = newShareesByPath.keys
40+ .chunked(SHARE_PATH_QUERY_CHUNK_SIZE )
41+ .flatMap { chunk -> shareDao.getShareeKeys(chunk, user.accountName, ShareeKey .shareableShareTypeValues) }
42+ .groupBy(ShareeKey ::path) { " ${it.shareWith} :${it.shareType} " }
43+ .mapValues { (_, keys) -> keys.toSet() }
5444
5545 return newShareesByPath.keys.any { path ->
5646 newShareesByPath[path].orEmpty() != existingShareesByPath[path].orEmpty()
5747 }
5848}
5949
60- private fun FileDataStorageManager.queryLocalShareeKeysByPath (
61- paths : Set <String >,
62- accountName : String
63- ): Map <String , Set <String >> {
64- val result = mutableMapOf<String , MutableSet <String >>()
65-
66- paths.toList().chunked(SHARE_PATH_QUERY_CHUNK_SIZE ).forEach { chunk ->
67- queryLocalShareeKeysChunk(chunk, accountName, result)
68- }
69-
70- return result
71- }
72-
73- private fun FileDataStorageManager.queryLocalShareeKeysChunk (
74- paths : List <String >,
75- accountName : String ,
76- result : MutableMap <String , MutableSet <String >>
77- ) {
78- val pathPlaceholders = paths.joinToString(" ," ) { " ?" }
79- val shareTypeFilter = shareableShareTypes.joinToString(" OR " ) { " ${ProviderTableMeta .OCSHARES_SHARE_TYPE } = ?" }
80- val selection = " ${ProviderTableMeta .OCSHARES_PATH } IN ($pathPlaceholders ) AND " +
81- " ${ProviderTableMeta .OCSHARES_ACCOUNT_OWNER } = ? AND ($shareTypeFilter )"
82- val selectionArgs = (paths + accountName + shareableShareTypes.map { it.value.toString() }).toTypedArray()
83-
84- val cursor = if (contentResolver != null ) {
85- contentResolver.query(ProviderTableMeta .CONTENT_URI_SHARE , null , selection, selectionArgs, null )
86- } else {
87- try {
88- contentProviderClient?.query(ProviderTableMeta .CONTENT_URI_SHARE , null , selection, selectionArgs, null )
89- } catch (e: RemoteException ) {
90- Log_OC .e(javaClass.simpleName, " Could not get list of shares: ${e.message} " , e)
91- null
92- }
93- }
94-
95- cursor?.use {
96- val pathIndex = it.getColumnIndex(ProviderTableMeta .OCSHARES_PATH )
97- val shareWithIndex = it.getColumnIndex(ProviderTableMeta .OCSHARES_SHARE_WITH )
98- val shareTypeIndex = it.getColumnIndex(ProviderTableMeta .OCSHARES_SHARE_TYPE )
99-
100- while (it.moveToNext()) {
101- val path = it.getString(pathIndex) ? : continue
102- val key = " ${it.getString(shareWithIndex)} :${it.getInt(shareTypeIndex)} "
103- result.getOrPut(path) { mutableSetOf () }.add(key)
104- }
105- }
106- }
107-
10850suspend fun FileDataStorageManager.saveShares (shares : List <OCShare >, accountName : String ) {
10951 withContext(Dispatchers .IO ) {
11052 val entities = shares.map { share ->
0 commit comments