Skip to content

Commit 4e788a2

Browse files
committed
wip
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
1 parent b73671f commit 4e788a2

3 files changed

Lines changed: 127 additions & 106 deletions

File tree

app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt

Lines changed: 2 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -172,57 +172,6 @@ interface FileDao {
172172
@Query("DELETE FROM filelist WHERE file_owner = :fileOwner AND path = :remotePath")
173173
fun deleteFileByRemotePath(fileOwner: String, remotePath: String): Int
174174

175-
@Query(
176-
"""
177-
UPDATE filelist
178-
SET path = :newPathPrefix || SUBSTR(path, :oldPrefixLength + 1)
179-
WHERE path LIKE :oldPathPattern AND file_owner = :fileOwner
180-
"""
181-
)
182-
fun moveDescendantPaths(oldPathPattern: String, oldPrefixLength: Int, newPathPrefix: String, fileOwner: String)
183-
184-
@Query(
185-
"""
186-
UPDATE filelist
187-
SET path_decrypted = :newPathPrefix || SUBSTR(path_decrypted, :oldPrefixLength + 1)
188-
WHERE path LIKE :oldPathPattern AND file_owner = :fileOwner AND is_encrypted = 0
189-
"""
190-
)
191-
fun moveDescendantDecryptedPaths(
192-
oldPathPattern: String,
193-
oldPrefixLength: Int,
194-
newPathPrefix: String,
195-
fileOwner: String
196-
)
197-
198-
@Query(
199-
"""
200-
UPDATE filelist
201-
SET media_path = :newStoragePrefix || SUBSTR(media_path, :oldStoragePrefixLength + 1)
202-
WHERE path LIKE :oldPathPattern AND file_owner = :fileOwner
203-
AND media_path IS NOT NULL AND media_path LIKE :oldStoragePrefix || '%'
204-
"""
205-
)
206-
fun moveDescendantStoragePaths(
207-
oldPathPattern: String,
208-
oldStoragePrefix: String,
209-
oldStoragePrefixLength: Int,
210-
newStoragePrefix: String,
211-
fileOwner: String
212-
)
213-
214-
@Query(
215-
"UPDATE filelist SET parent = :newParentId WHERE path = :filePath AND file_owner = :fileOwner"
216-
)
217-
fun updateParent(filePath: String, fileOwner: String, newParentId: Long)
218-
219-
@Query(
220-
"""
221-
SELECT media_path FROM filelist
222-
WHERE path LIKE :oldPathPattern AND file_owner = :fileOwner
223-
AND media_path IS NOT NULL AND media_path != ''
224-
AND (content_type LIKE 'image/%' OR content_type LIKE 'video/%')
225-
"""
226-
)
227-
fun getMediaPathsUnderPath(oldPathPattern: String, fileOwner: String): List<String>
175+
@Update
176+
fun updateAll(entities: List<FileEntity>)
228177
}

app/src/main/java/com/nextcloud/utils/extensions/FileDataStorageManagerExtensions.kt

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,18 @@
77

88
package com.nextcloud.utils.extensions
99

10+
import com.nextcloud.client.database.dao.FileDao
1011
import com.nextcloud.client.database.entity.toOCCapability
1112
import com.owncloud.android.datamodel.FileDataStorageManager
1213
import com.owncloud.android.datamodel.OCFile
14+
import com.owncloud.android.lib.common.utils.Log_OC
1315
import com.owncloud.android.lib.resources.shares.OCShare
1416
import com.owncloud.android.lib.resources.status.OCCapability
17+
import com.owncloud.android.utils.FileStorageUtils
18+
import com.owncloud.android.utils.MimeTypeUtil
1519
import kotlinx.coroutines.Dispatchers
1620
import kotlinx.coroutines.withContext
21+
import java.io.File
1722

1823
suspend fun FileDataStorageManager.saveShares(shares: List<OCShare>, accountName: String) {
1924
withContext(Dispatchers.IO) {
@@ -58,3 +63,119 @@ fun FileDataStorageManager.getNonEncryptedSubfolders(id: Long, accountName: Stri
5863

5964
suspend fun FileDataStorageManager.getCapabilitiesByAccountName(accountName: String): OCCapability =
6065
capabilityDao.getByAccountName(accountName).toOCCapability()
66+
67+
fun FileDataStorageManager.moveLocalFile(ocFile: OCFile?, targetPath: String, targetParentPath: String) {
68+
Log_OC.d(
69+
FileDataStorageManager.TAG,
70+
("moveLocalFile ==> ocFile: "
71+
+ (ocFile?.remotePath)
72+
+ " targetPath: "
73+
+ targetPath
74+
+ " targetParentPath: "
75+
+ targetParentPath)
76+
)
77+
78+
if (ocFile == null) {
79+
Log_OC.e(FileDataStorageManager.TAG, "moveLocalFile: file is null, skipping")
80+
return
81+
}
82+
83+
if (!ocFile.fileExists()) {
84+
Log_OC.e(FileDataStorageManager.TAG, "moveLocalFile: file does not exist, skipping")
85+
return
86+
}
87+
88+
if (OCFile.ROOT_PATH == ocFile.fileName) {
89+
Log_OC.e(FileDataStorageManager.TAG, "moveLocalFile: cannot move root path")
90+
return
91+
}
92+
93+
if (ocFile.remotePath == targetPath) {
94+
Log_OC.e(FileDataStorageManager.TAG, "moveLocalFile: source and target paths are identical, skipping")
95+
return
96+
}
97+
98+
val targetParent = getFileByPath(targetParentPath)
99+
if (targetParent == null) {
100+
Log_OC.e(FileDataStorageManager.TAG, "moveLocalFile: target parent folder not found: $targetParentPath")
101+
return
102+
}
103+
104+
if (!targetParent.isFolder) {
105+
Log_OC.e(FileDataStorageManager.TAG, "moveLocalFile: target parent is not a folder: $targetParentPath")
106+
return
107+
}
108+
109+
val oldPath: String = ocFile.remotePath
110+
val accountName = user.accountName
111+
val defaultSavePath = FileStorageUtils.getSavePath(accountName)
112+
113+
val originalMediaPaths =
114+
fileDao.moveFileEntities(oldPath, targetPath, defaultSavePath, targetParent.getFileId(), accountName)
115+
116+
val localFile = File(FileStorageUtils.getDefaultSavePathFor(accountName, ocFile))
117+
if (!localFile.exists()) {
118+
Log_OC.d(FileDataStorageManager.TAG, "moveLocalFile: no local file to move at " + localFile.getAbsolutePath())
119+
return
120+
}
121+
122+
val targetFile = File(defaultSavePath + targetPath)
123+
val targetFolder = targetFile.getParentFile()
124+
if (targetFolder != null && !targetFolder.exists() && !targetFolder.mkdirs()) {
125+
Log_OC.e(
126+
FileDataStorageManager.TAG,
127+
"moveLocalFile: failed to create parent folder " + targetFolder.absolutePath
128+
)
129+
}
130+
131+
if (!localFile.renameTo(targetFile)) {
132+
Log_OC.e(
133+
FileDataStorageManager.TAG, ("moveLocalFile: failed to rename " + localFile.absolutePath
134+
+ " to " + targetFile.absolutePath)
135+
)
136+
return
137+
}
138+
139+
for (originalMediaPath in originalMediaPaths) {
140+
deleteFileInMediaScan(originalMediaPath)
141+
val newMediaPath = defaultSavePath + targetPath + originalMediaPath.substring(
142+
(defaultSavePath + oldPath).length
143+
)
144+
FileDataStorageManager.triggerMediaScan(newMediaPath)
145+
}
146+
}
147+
148+
149+
private fun FileDao.moveFileEntities(
150+
oldPath: String,
151+
targetPath: String,
152+
defaultSavePath: String,
153+
targetParentId: Long,
154+
accountName: String
155+
): List<String> {
156+
val entities = getFolderWithDescendants("$oldPath%", accountName)
157+
val oldStoragePrefix = defaultSavePath + oldPath
158+
val newStoragePrefix = defaultSavePath + targetPath
159+
160+
val originalMediaPaths = entities
161+
.filter { MimeTypeUtil.isMedia(it.contentType) && it.storagePath?.startsWith(oldStoragePrefix) == true }
162+
.mapNotNull { it.storagePath }
163+
164+
val updated = entities.map { entity ->
165+
val currentPath = entity.path.orEmpty()
166+
val newPath = targetPath + currentPath.substring(oldPath.length)
167+
entity.copy(
168+
path = newPath,
169+
pathDecrypted = if (entity.isEncrypted == 0) newPath else entity.pathDecrypted,
170+
storagePath = if (entity.storagePath?.startsWith(oldStoragePrefix) == true) {
171+
newStoragePrefix + entity.storagePath.substring(oldStoragePrefix.length)
172+
} else {
173+
entity.storagePath
174+
},
175+
parent = if (currentPath == oldPath) targetParentId else entity.parent
176+
)
177+
}
178+
179+
updateAll(updated)
180+
return originalMediaPaths
181+
}

app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
import android.content.ContentUris;
2222
import android.content.ContentValues;
2323
import android.content.Context;
24-
import android.media.MediaScannerConnection;
2524
import android.content.OperationApplicationException;
2625
import android.database.Cursor;
26+
import android.media.MediaScannerConnection;
2727
import android.net.Uri;
2828
import android.os.RemoteException;
2929
import android.provider.MediaStore;
@@ -48,8 +48,8 @@
4848
import com.nextcloud.model.ShareeEntry;
4949
import com.nextcloud.utils.date.DateFormatPattern;
5050
import com.nextcloud.utils.extensions.DateExtensionsKt;
51+
import com.nextcloud.utils.extensions.FileDataStorageManagerExtensionsKt;
5152
import com.nextcloud.utils.extensions.FileExtensionsKt;
52-
import com.nextcloud.utils.extensions.StringExtensionsKt;
5353
import com.owncloud.android.MainApp;
5454
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
5555
import com.owncloud.android.lib.common.network.WebdavEntry;
@@ -94,7 +94,7 @@
9494

9595
@SuppressFBWarnings("CE")
9696
public class FileDataStorageManager {
97-
private static final String TAG = FileDataStorageManager.class.getSimpleName();
97+
public static final String TAG = FileDataStorageManager.class.getSimpleName();
9898

9999
private static final String AND = " = ? AND ";
100100
private static final String FAILED_TO_INSERT_MSG = "Fail to insert insert file to database ";
@@ -1108,58 +1108,9 @@ private boolean removeLocalFolder(File localFolder) {
11081108

11091109
/**
11101110
* Updates database and file system for a file or folder that was moved to a different location.
1111-
* <p>
1112-
* TODO explore better (faster) implementations TODO throw exceptions up !
11131111
*/
11141112
public void moveLocalFile(OCFile ocFile, String targetPath, String targetParentPath) {
1115-
if (!ocFile.fileExists() || OCFile.ROOT_PATH.equals(ocFile.getFileName())) {
1116-
return;
1117-
}
1118-
1119-
OCFile targetParent = getFileByPath(targetParentPath);
1120-
if (targetParent == null) {
1121-
throw new IllegalStateException("Parent folder of the target path does not exist!!");
1122-
}
1123-
1124-
String oldPath = ocFile.getRemotePath();
1125-
String accountName = user.getAccountName();
1126-
String oldPathPattern = oldPath + "%";
1127-
String defaultSavePath = FileStorageUtils.getSavePath(accountName);
1128-
String oldStoragePrefix = defaultSavePath + oldPath;
1129-
String newStoragePrefix = defaultSavePath + targetPath;
1130-
1131-
List<String> originalMediaPaths = fileDao.getMediaPathsUnderPath(oldPathPattern, accountName);
1132-
1133-
fileDao.moveDescendantDecryptedPaths(oldPathPattern, oldPath.length(), targetPath, accountName);
1134-
fileDao.moveDescendantPaths(oldPathPattern, oldPath.length(), targetPath, accountName);
1135-
fileDao.moveDescendantStoragePaths(
1136-
targetPath + "%", oldStoragePrefix, oldStoragePrefix.length(), newStoragePrefix, accountName
1137-
);
1138-
fileDao.updateParent(targetPath, accountName, targetParent.getFileId());
1139-
1140-
String originalLocalPath = FileStorageUtils.getDefaultSavePathFor(accountName, ocFile);
1141-
File localFile = new File(originalLocalPath);
1142-
1143-
if (!localFile.exists()) {
1144-
return;
1145-
}
1146-
1147-
File targetFile = new File(defaultSavePath + targetPath);
1148-
File targetFolder = targetFile.getParentFile();
1149-
if (targetFolder != null && !targetFolder.exists() && !targetFolder.mkdirs()) {
1150-
Log_OC.e(TAG, "Unable to create parent folder " + targetFolder.getAbsolutePath());
1151-
}
1152-
1153-
boolean renamed = localFile.renameTo(targetFile);
1154-
if (!renamed) {
1155-
return;
1156-
}
1157-
1158-
for (String originalMediaPath : originalMediaPaths) {
1159-
deleteFileInMediaScan(originalMediaPath);
1160-
String newMediaPath = newStoragePrefix + originalMediaPath.substring(oldStoragePrefix.length());
1161-
triggerMediaScan(newMediaPath);
1162-
}
1113+
FileDataStorageManagerExtensionsKt.moveLocalFile(this, ocFile, targetPath, targetParentPath);
11631114
}
11641115

11651116
public void copyLocalFile(OCFile ocFile, String targetPath) {

0 commit comments

Comments
 (0)