Fixed database update due to renaming folders
[pub/Android/ownCloud.git] / src / com / owncloud / android / datamodel / FileDataStorageManager.java
index 1f7ee4c..be01655 100644 (file)
@@ -145,6 +145,29 @@ public class FileDataStorageManager implements DataStorageManager {
                                     + e.getMessage());
                 }
             }
+        } else if (fileExists(file.getFileId())) {      // for renamed files; no more delete and create
+                OCFile oldFile = getFileById(file.getFileId());
+                if (file.getStoragePath() == null && oldFile.getStoragePath() != null)
+                    file.setStoragePath(oldFile.getStoragePath());
+                if (!file.isDirectory());
+                    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
+
+                overriden = true;
+                if (getContentResolver() != null) {
+                    getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv,
+                            ProviderTableMeta._ID + "=?",
+                            new String[] { String.valueOf(file.getFileId()) });
+                } else {
+                    try {
+                        getContentProvider().update(ProviderTableMeta.CONTENT_URI,
+                                cv, ProviderTableMeta._ID + "=?",
+                                new String[] { String.valueOf(file.getFileId()) });
+                    } catch (RemoteException e) {
+                        Log.e(TAG,
+                                "Fail to insert insert file to database "
+                                        + e.getMessage());
+                    }
+                }
         } else {
             Uri result_uri = null;
             if (getContentResolver() != null) {
@@ -201,11 +224,12 @@ public class FileDataStorageManager implements DataStorageManager {
             cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
 
             if (fileExists(file.getRemotePath())) {
-                OCFile tmpfile = getFileByPath(file.getRemotePath());
-                file.setStoragePath(tmpfile.getStoragePath());
+                OCFile oldFile = getFileByPath(file.getRemotePath());
+                if (file.getStoragePath() == null && oldFile.getStoragePath() != null)
+                    file.setStoragePath(oldFile.getStoragePath());
                 if (!file.isDirectory());
                     cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
-                file.setFileId(tmpfile.getFileId());
+                file.setFileId(oldFile.getFileId());
 
                 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
                         withValues(cv).
@@ -213,6 +237,19 @@ public class FileDataStorageManager implements DataStorageManager {
                                         new String[] { String.valueOf(file.getFileId()) })
                         .build());
                 
+            } else if (fileExists(file.getFileId())) {
+                    OCFile oldFile = getFileById(file.getFileId());
+                    if (file.getStoragePath() == null && oldFile.getStoragePath() != null)
+                        file.setStoragePath(oldFile.getStoragePath());
+                    if (!file.isDirectory());
+                        cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
+
+                    operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
+                            withValues(cv).
+                            withSelection(  ProviderTableMeta._ID + "=?", 
+                                            new String[] { String.valueOf(file.getFileId()) })
+                            .build());
+                    
             } else {
                 operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
             }
@@ -463,5 +500,76 @@ public class FileDataStorageManager implements DataStorageManager {
             }
         }
     }
+    
+    
+    /**
+     * Updates database for a folder that was moved to a different location.
+     * 
+     * TODO explore better (faster) implementations
+     * TODO throw exceptions up !
+     */
+    @Override
+    public void moveDirectory(OCFile dir, String newPath) {
+        // TODO check newPath
+        
+        if (dir != null && dir.isDirectory() && dir.fileExists() && !dir.getFileName().equals(OCFile.PATH_SEPARATOR)) {
+            /// 1. get all the descendants of 'dir' in a single QUERY (including 'dir')
+            Cursor c = null;
+            if (getContentProvider() != null) {
+                try {
+                    c = getContentProvider().query(ProviderTableMeta.CONTENT_URI, 
+                                                    null,
+                                                    ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ?",
+                                                    new String[] { mAccount.name, dir.getRemotePath() + "%" }, null);
+                } catch (RemoteException e) {
+                    Log.e(TAG, e.getMessage());
+                }
+            } else {
+                c = getContentResolver().query(ProviderTableMeta.CONTENT_URI, 
+                                                null,
+                                                ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ?",
+                                                new String[] { mAccount.name, dir.getRemotePath() + "%" }, null);
+            }
+
+            /// 2. prepare a batch of update operations to change all the descendants
+            ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(c.getCount());
+            ContentValues cv = new ContentValues();
+            int lengthOfOldPath = dir.getRemotePath().length();
+            String defaultSavePath = FileDownloader.getSavePath(mAccount.name);
+            int lengthOfOldStoragePath = defaultSavePath.length() + lengthOfOldPath;
+            if (c.moveToFirst()) {
+                do {
+                    OCFile child = createFileInstance(c);
+                    cv.put(ProviderTableMeta.FILE_PATH, newPath + child.getRemotePath().substring(lengthOfOldPath));
+                    if (child.getStoragePath() != null && child.getStoragePath().startsWith(defaultSavePath)) {
+                        cv.put(ProviderTableMeta.FILE_STORAGE_PATH, defaultSavePath + newPath + child.getStoragePath().substring(lengthOfOldStoragePath));
+                    }
+                    operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
+                                                                        withValues(cv).
+                                                                        withSelection(  ProviderTableMeta._ID + "=?", 
+                                                                                new String[] { String.valueOf(child.getFileId()) })
+                                                                                .build());
+                } while (c.moveToNext());
+            }
+            c.close();
+            
+            /// 3. apply updates in batch
+            try {
+                if (getContentResolver() != null) {
+                    getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations);
+                
+                } else {
+                    getContentProvider().applyBatch(operations);
+                }
+                
+            } catch (OperationApplicationException e) {
+                Log.e(TAG, "Fail to update descendants of " + dir.getFileId() + " in database", e);
+                
+            } catch (RemoteException e) {
+                Log.e(TAG, "Fail to update desendants of " + dir.getFileId() + " in database", e);
+            }
+            
+        }
+    }
 
 }