Преглед изворни кода

Grant consistency of size of folders with every update operation

David A. Velasco пре 11 година
родитељ
комит
9d490aaab2

+ 25 - 20
src/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -233,10 +233,8 @@ public class FileDataStorageManager {
 
         if (file.isFolder()) {
             updateFolderSize(file.getFileId());
-            if (file.needsUpdatingWhileSaving()) {
-                for (OCFile f : getFolderContent(file))
-                    saveFile(f);
-            }
+        } else {
+            updateFolderSize(file.getParentId());
         }
         
         return overriden;
@@ -255,7 +253,6 @@ public class FileDataStorageManager {
         Log_OC.d(TAG,  "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size() + " children and " + filesToRemove.size() + " files to remove");
 
         ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(updatedFiles.size());
-        long folderSize = 0;
 
         // prepare operations to insert or update files to save in the given folder
         for (OCFile file : updatedFiles) {
@@ -264,7 +261,6 @@ public class FileDataStorageManager {
             cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
             cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
             cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
-            folderSize += file.getFileLength();
             cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
             cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
             //cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
@@ -350,7 +346,7 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_MODIFIED, folder.getModificationTimestamp());
         cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, folder.getModificationTimestampAtLastSyncForData());
         cv.put(ProviderTableMeta.FILE_CREATION, folder.getCreationTimestamp());
-        cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, folderSize);
+        cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, 0);   // FileContentProvider calculates the right size
         cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, folder.getMimetype());
         cv.put(ProviderTableMeta.FILE_NAME, folder.getFileName());
         cv.put(ProviderTableMeta.FILE_PARENT, folder.getParentId());
@@ -405,6 +401,8 @@ public class FileDataStorageManager {
             }
         }
         
+        updateFolderSize(folder.getFileId());
+        
     }
 
 
@@ -412,20 +410,25 @@ public class FileDataStorageManager {
      * 
      * @param id
      */
-    public void updateFolderSize(long id) {
-        if (getContentResolver() != null) {
-            getContentResolver().update(ProviderTableMeta.CONTENT_URI_DIR, null,
-                    ProviderTableMeta._ID + "=?",
-                    new String[] { String.valueOf(id) });
-        } else {
-            try {
-                getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_DIR, null,
-                    ProviderTableMeta._ID + "=?",
-                    new String[] { String.valueOf(id) });
-                
-            } catch (RemoteException e) {
-                Log_OC.e(TAG, "Exception in update of folder size through compatibility patch " + e.getMessage());
+    private void updateFolderSize(long id) {
+        if (id > FileDataStorageManager.ROOT_PARENT_ID) {
+            Log_OC.d(TAG, "Updating size of " + id);
+            if (getContentResolver() != null) {
+                getContentResolver().update(ProviderTableMeta.CONTENT_URI_DIR, null,
+                        ProviderTableMeta._ID + "=?",
+                        new String[] { String.valueOf(id) });
+            } else {
+                try {
+                    getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_DIR, null,
+                        ProviderTableMeta._ID + "=?",
+                        new String[] { String.valueOf(id) });
+                    
+                } catch (RemoteException e) {
+                    Log_OC.e(TAG, "Exception in update of folder size through compatibility patch " + e.getMessage());
+                }
             }
+        } else {
+            Log_OC.e(TAG,  "not updating size for folder " + id);
         }
     }
     
@@ -450,6 +453,7 @@ public class FileDataStorageManager {
                     } else {
                         getContentResolver().delete(file_uri, where, whereArgs);
                     }
+                    updateFolderSize(file.getParentId());
                 }
                 if (removeLocalCopy && file.isDown()) {
                     boolean success = new File(file.getStoragePath()).delete();
@@ -489,6 +493,7 @@ public class FileDataStorageManager {
         } else {
             getContentResolver().delete(folder_uri, where, whereArgs); 
         }
+        updateFolderSize(folder.getParentId());
     }
 
     private void removeLocalFolder(File folder) {

+ 45 - 25
src/com/owncloud/android/providers/FileContentProvider.java

@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 
 import com.owncloud.android.Log_OC;
+import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.db.ProviderMeta;
 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
 
@@ -301,17 +302,6 @@ public class FileContentProvider extends ContentProvider {
         // DB case_sensitive
         db.execSQL("PRAGMA case_sensitive_like = true");
         Cursor c = sqlQuery.query(db, projection, selection, selectionArgs, null, null, order);
-        if (mUriMatcher.match(uri) == DIRECTORY && c != null && c.moveToFirst()) {
-            long size = 0;
-            while (!c.isAfterLast()) {
-                size += c.getLong(c.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH));
-                c.moveToNext();
-            }
-            ContentValues cv = new ContentValues();
-            cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, size);
-            db.update(ProviderTableMeta.DB_NAME, cv, ProviderTableMeta._ID + "=?", new String[] {uri.getPathSegments().get(1)});
-        }
-
         c.setNotificationUri(getContext().getContentResolver(), uri);
         return c;
     }
@@ -346,21 +336,51 @@ public class FileContentProvider extends ContentProvider {
     
     private int updateFolderSize(SQLiteDatabase db, String folderId) {
         int count = 0;
-        Uri selectUri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, folderId);
-        String[] selectProjection = new String[] { ProviderTableMeta.FILE_CONTENT_LENGTH };
-        String selectWhere = ProviderTableMeta.FILE_PARENT + "=?";
-        String updateWhere = ProviderTableMeta._ID + "=?";
         String [] whereArgs = new String[] { folderId };
-        Cursor childrenLengths = query(db, selectUri, selectProjection, selectWhere, whereArgs, null);
-        if (childrenLengths != null && childrenLengths.moveToFirst()) {
-            long size = 0;
-            while (!childrenLengths.isAfterLast()) {
-                size += childrenLengths.getLong(childrenLengths.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH));
-                childrenLengths.moveToNext();
+        
+        // read current size saved for the folder 
+        long folderSize = 0;
+        long folderParentId = -1;
+        Uri selectFolderUri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, folderId);
+        String[] folderProjection = new String[] { ProviderTableMeta.FILE_CONTENT_LENGTH,  ProviderTableMeta.FILE_PARENT};
+        String folderWhere = ProviderTableMeta._ID + "=?";
+        Cursor folderCursor = query(db, selectFolderUri, folderProjection, folderWhere, whereArgs, null);
+        if (folderCursor != null && folderCursor.moveToFirst()) {
+            folderSize = folderCursor.getLong(folderCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH));;
+            folderParentId = folderCursor.getLong(folderCursor.getColumnIndex(ProviderTableMeta.FILE_PARENT));;
+        }
+        folderCursor.close();
+        
+        // read and sum sizes of children
+        long childrenSize = 0;
+        Uri selectChildrenUri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, folderId);
+        String[] childrenProjection = new String[] { ProviderTableMeta.FILE_CONTENT_LENGTH,  ProviderTableMeta.FILE_PARENT};
+        String childrenWhere = ProviderTableMeta.FILE_PARENT + "=?";
+        Cursor childrenCursor = query(db, selectChildrenUri, childrenProjection, childrenWhere, whereArgs, null);
+        if (childrenCursor != null && childrenCursor.moveToFirst()) {
+            while (!childrenCursor.isAfterLast()) {
+                childrenSize += childrenCursor.getLong(childrenCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH));
+                childrenCursor.moveToNext();
             }
+        }
+        childrenCursor.close();
+        
+        // update if needed
+        if (folderSize != childrenSize) {
+            Log_OC.d("FileContentProvider", "Updating " + folderSize + " to " + childrenSize);
             ContentValues cv = new ContentValues();
-            cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, size);
-            count = db.update(ProviderTableMeta.DB_NAME, cv, updateWhere, whereArgs);
+            cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, childrenSize);
+            count = db.update(ProviderTableMeta.DB_NAME, cv, folderWhere, whereArgs);
+            
+            // propagate update until root
+            if (folderParentId > FileDataStorageManager.ROOT_PARENT_ID) {
+                Log_OC.d("FileContentProvider", "Propagating update to " + folderParentId);
+                updateFolderSize(db, String.valueOf(folderParentId));
+            } else {
+                Log_OC.d("FileContentProvider", "NOT propagating to " + folderParentId);
+            }
+        } else {
+            Log_OC.d("FileContentProvider", "NOT updating, sizes are " + folderSize + " and " + childrenSize);
         }
         return count;
     }
@@ -368,7 +388,7 @@ public class FileContentProvider extends ContentProvider {
     
     @Override
     public ContentProviderResult[] applyBatch (ArrayList<ContentProviderOperation> operations) throws OperationApplicationException {
-        //Log.d(TAG, "applying batch in provider " + this + " (temporary: " + isTemporary() + ")" );
+        Log_OC.d("FileContentProvider", "applying batch in provider " + this + " (temporary: " + isTemporary() + ")" );
         ContentProviderResult[] results = new ContentProviderResult[operations.size()];
         int i=0;
         
@@ -383,7 +403,7 @@ public class FileContentProvider extends ContentProvider {
         } finally {
             db.endTransaction();
         }
-        //Log.d(TAG, "applied batch in provider " + this);
+        Log_OC.d("FileContentProvider", "applied batch in provider " + this);
         return results;
     }
 

+ 1 - 1
src/com/owncloud/android/syncadapter/FileSyncAdapter.java

@@ -320,7 +320,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
                 if(syncDown) {
                     synchronizeFolder(newFile);
                     // update the size of the parent folder again after recursive synchronization 
-                    getStorageManager().updateFolderSize(parent.getFileId());  
+                    //getStorageManager().updateFolderSize(parent.getFileId());  
                     sendStickyBroadcast(true, parent.getRemotePath(), null);        // notify again to refresh size in UI
                 }
             }