X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/6e2949f6816e2cb8a33cd2114a1c6cabd5371dfe..a8fade7369bc8d1752dc4ba5fe07935cac84e96f:/src/com/owncloud/android/datamodel/FileDataStorageManager.java diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java index 1b0f083e..eaeaf985 100644 --- a/src/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.List; import java.util.Vector; +import com.owncloud.android.DisplayUtils; import com.owncloud.android.Log_OC; import com.owncloud.android.db.ProviderMeta; import com.owncloud.android.db.ProviderMeta.ProviderTableMeta; @@ -46,9 +47,9 @@ public class FileDataStorageManager implements DataStorageManager { private ContentResolver mContentResolver; private ContentProviderClient mContentProvider; private Account mAccount; - + private static String TAG = "FileDataStorageManager"; - + public FileDataStorageManager(Account account, ContentResolver cr) { mContentProvider = null; mContentResolver = cr; @@ -75,7 +76,7 @@ public class FileDataStorageManager implements DataStorageManager { return file; } - + private OCFile createRootDir() { OCFile file = new OCFile(OCFile.PATH_SEPARATOR); file.setMimetype("DIR"); @@ -94,7 +95,7 @@ public class FileDataStorageManager implements DataStorageManager { c.close(); return file; } - + public OCFile getFileByLocalPath(String path) { Cursor c = getCursorForValue(ProviderTableMeta.FILE_STORAGE_PATH, path); OCFile file = null; @@ -125,7 +126,7 @@ public class FileDataStorageManager implements DataStorageManager { cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength()); cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype()); cv.put(ProviderTableMeta.FILE_NAME, file.getFileName()); - if (file.getParentId() != 0) + if (file.getParentId() != DataStorageManager.ROOT_PARENT_ID) cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId()); cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath()); if (!file.isDirectory()) @@ -134,15 +135,21 @@ public class FileDataStorageManager implements DataStorageManager { cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties()); cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData()); cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0); + cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag()); boolean sameRemotePath = fileExists(file.getRemotePath()); + boolean changesSizeOfAncestors = false; if (sameRemotePath || - fileExists(file.getFileId()) ) { // for renamed files; no more delete and create - + fileExists(file.getFileId()) ) { // for renamed files; no more delete and create + + OCFile oldFile = null; if (sameRemotePath) { - OCFile oldFile = getFileByPath(file.getRemotePath()); + oldFile = getFileByPath(file.getRemotePath()); file.setFileId(oldFile.getFileId()); + } else { + oldFile = getFileById(file.getFileId()); } + changesSizeOfAncestors = (oldFile.getFileLength() != file.getFileLength()); overriden = true; if (getContentResolver() != null) { @@ -161,6 +168,7 @@ public class FileDataStorageManager implements DataStorageManager { } } } else { + changesSizeOfAncestors = true; Uri result_uri = null; if (getContentResolver() != null) { result_uri = getContentResolver().insert( @@ -179,20 +187,28 @@ public class FileDataStorageManager implements DataStorageManager { long new_id = Long.parseLong(result_uri.getPathSegments() .get(1)); file.setFileId(new_id); - } + } } - if (file.isDirectory() && file.needsUpdatingWhileSaving()) - for (OCFile f : getDirectoryContent(file)) - saveFile(f); - + if (file.isDirectory()) { + calculateFolderSize(file.getFileId()); + if (file.needsUpdatingWhileSaving()) { + for (OCFile f : getDirectoryContent(file)) + saveFile(f); + } + } + + if (changesSizeOfAncestors || file.isDirectory()) { + updateSizesToTheRoot(file.getParentId()); + } + return overriden; } @Override public void saveFiles(List files) { - + Iterator filesIt = files.iterator(); ArrayList operations = new ArrayList(files.size()); OCFile file = null; @@ -207,7 +223,7 @@ public class FileDataStorageManager implements DataStorageManager { cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength()); cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype()); cv.put(ProviderTableMeta.FILE_NAME, file.getFileName()); - if (file.getParentId() != 0) + if (file.getParentId() != DataStorageManager.ROOT_PARENT_ID) cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId()); cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath()); if (!file.isDirectory()) @@ -216,51 +232,63 @@ public class FileDataStorageManager implements DataStorageManager { cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties()); cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData()); cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0); + cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag()); if (fileExists(file.getRemotePath())) { OCFile oldFile = getFileByPath(file.getRemotePath()); file.setFileId(oldFile.getFileId()); + + if (file.isDirectory()) { + cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, oldFile.getFileLength()); + file.setFileLength(oldFile.getFileLength()); + } + operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI). withValues(cv). withSelection( ProviderTableMeta._ID + "=?", - new String[] { String.valueOf(file.getFileId()) }) - .build()); - + 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()); + 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()); + else { + cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, oldFile.getFileLength()); + file.setFileLength(oldFile.getFileLength()); + } + + operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI). + withValues(cv). + withSelection( ProviderTableMeta._ID + "=?", + new String[] { String.valueOf(file.getFileId()) }) + .build()); - 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()); } } - + // apply operations in batch ContentProviderResult[] results = null; try { if (getContentResolver() != null) { results = getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations); - + } else { results = getContentProvider().applyBatch(operations); } - + } catch (OperationApplicationException e) { Log_OC.e(TAG, "Fail to update/insert list of files to database " + e.getMessage()); - + } catch (RemoteException e) { Log_OC.e(TAG, "Fail to update/insert list of files to database " + e.getMessage()); } - + // update new id in file objects for insertions if (results != null) { long newId; @@ -279,7 +307,7 @@ public class FileDataStorageManager implements DataStorageManager { } } - + public void setAccount(Account account) { mAccount = account; } @@ -303,46 +331,56 @@ public class FileDataStorageManager implements DataStorageManager { public ContentProviderClient getContentProvider() { return mContentProvider; } - + @Override public Vector getDirectoryContent(OCFile f) { - Vector ret = new Vector(); if (f != null && f.isDirectory() && f.getFileId() != -1) { + return getDirectoryContent(f.getFileId()); - Uri req_uri = Uri.withAppendedPath( - ProviderTableMeta.CONTENT_URI_DIR, - String.valueOf(f.getFileId())); - Cursor c = null; + } else { + return new Vector(); + } + } - if (getContentProvider() != null) { - try { - c = getContentProvider().query(req_uri, null, - ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", - new String[] { mAccount.name }, null); - } catch (RemoteException e) { - Log_OC.e(TAG, e.getMessage()); - return ret; - } - } else { - c = getContentResolver().query(req_uri, null, - ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", - new String[] { mAccount.name }, null); - } + private Vector getDirectoryContent(long parentId) { - if (c.moveToFirst()) { - do { - OCFile child = createFileInstance(c); - ret.add(child); - } while (c.moveToNext()); + Vector ret = new Vector(); + + Uri req_uri = Uri.withAppendedPath( + ProviderTableMeta.CONTENT_URI_DIR, + String.valueOf(parentId)); + Cursor c = null; + + if (getContentProvider() != null) { + try { + c = getContentProvider().query(req_uri, null, + ProviderTableMeta.FILE_PARENT + "=?" , + new String[] { String.valueOf(parentId)}, null); + } catch (RemoteException e) { + Log_OC.e(TAG, e.getMessage()); + return ret; } + } else { + c = getContentResolver().query(req_uri, null, + ProviderTableMeta.FILE_PARENT + "=?" , + new String[] { String.valueOf(parentId)}, null); + } - c.close(); - - Collections.sort(ret); - + if (c.moveToFirst()) { + do { + OCFile child = createFileInstance(c); + ret.add(child); + } while (c.moveToNext()); } + + c.close(); + + Collections.sort(ret); + return ret; } + + private boolean fileExists(String cmp_key, String value) { Cursor c; @@ -353,7 +391,7 @@ public class FileDataStorageManager implements DataStorageManager { cmp_key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", - new String[] { value, mAccount.name }, null); + new String[] { value, mAccount.name }, null); } else { try { c = getContentProvider().query( @@ -361,7 +399,7 @@ public class FileDataStorageManager implements DataStorageManager { null, cmp_key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", - new String[] { value, mAccount.name }, null); + new String[] { value, mAccount.name }, null); } catch (RemoteException e) { Log_OC.e(TAG, "Couldn't determine file existance, assuming non existance: " @@ -383,14 +421,14 @@ public class FileDataStorageManager implements DataStorageManager { key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", - new String[] { value, mAccount.name }, null); + new String[] { value, mAccount.name }, null); } else { try { c = getContentProvider().query( ProviderTableMeta.CONTENT_URI, null, key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER - + "=?", new String[] { value, mAccount.name }, + + "=?", new String[] { value, mAccount.name }, null); } catch (RemoteException e) { Log_OC.e(TAG, "Could not get file details: " + e.getMessage()); @@ -435,26 +473,28 @@ public class FileDataStorageManager implements DataStorageManager { file.setLastSyncDateForData(c.getLong(c. getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA))); file.setKeepInSync(c.getInt( - c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false); + c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false); + file.setEtag(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_ETAG))); + } return file; } - + @Override public void removeFile(OCFile file, boolean removeLocalCopy) { Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, ""+file.getFileId()); if (getContentProvider() != null) { try { getContentProvider().delete(file_uri, - ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?", - new String[]{mAccount.name}); + ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?", + new String[]{mAccount.name}); } catch (RemoteException e) { e.printStackTrace(); } } else { getContentResolver().delete(file_uri, - ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?", - new String[]{mAccount.name}); + ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?", + new String[]{mAccount.name}); } if (file.isDown() && removeLocalCopy) { new File(file.getStoragePath()).delete(); @@ -465,6 +505,10 @@ public class FileDataStorageManager implements DataStorageManager { f.delete(); } } + + if (file.getFileLength() > 0) { + updateSizesToTheRoot(file.getParentId()); + } } @Override @@ -492,10 +536,14 @@ public class FileDataStorageManager implements DataStorageManager { if (removeDBData) { removeFile(dir, true); } + + if (dir.getFileLength() > 0) { + updateSizesToTheRoot(dir.getParentId()); + } } } - - + + /** * Updates database for a folder that was moved to a different location. * @@ -505,24 +553,24 @@ public class FileDataStorageManager implements DataStorageManager { @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); + null, + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ? ", + new String[] { mAccount.name, dir.getRemotePath() + "%" }, ProviderTableMeta.FILE_PATH + " ASC "); } catch (RemoteException e) { Log_OC.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); + null, + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ? ", + new String[] { mAccount.name, dir.getRemotePath() + "%" }, ProviderTableMeta.FILE_PATH + " ASC "); } /// 2. prepare a batch of update operations to change all the descendants @@ -539,30 +587,30 @@ public class FileDataStorageManager implements DataStorageManager { 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()); + 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_OC.e(TAG, "Fail to update descendants of " + dir.getFileId() + " in database", e); - + } catch (RemoteException e) { Log_OC.e(TAG, "Fail to update desendants of " + dir.getFileId() + " in database", e); } - + } } @@ -583,4 +631,65 @@ public class FileDataStorageManager implements DataStorageManager { return ret; } + /** + * Calculate and save the folderSize on DB + * @param id + */ + @Override + public void calculateFolderSize(long id) { + long folderSize = 0; + + Vector files = getDirectoryContent(id); + + for (OCFile f: files) + { + folderSize = folderSize + f.getFileLength(); + } + + updateSize(id, folderSize); + } + + /** + * Update the size value of an OCFile in DB + */ + private int updateSize(long id, long size) { + ContentValues cv = new ContentValues(); + cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, size); + int result = -1; + if (getContentResolver() != null) { + result = getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, ProviderTableMeta._ID + "=?", + new String[] { String.valueOf(id) }); + } else { + try { + result = getContentProvider().update(ProviderTableMeta.CONTENT_URI, cv, ProviderTableMeta._ID + "=?", + new String[] { String.valueOf(id) }); + } catch (RemoteException e) { + Log_OC.e(TAG,"Fail to update size column into database " + e.getMessage()); + } + } + return result; + } + + /** + * Update the size of a subtree of folder from a file to the root + * @param parentId: parent of the file + */ + private void updateSizesToTheRoot(long parentId) { + + OCFile file; + + while (parentId != DataStorageManager.ROOT_PARENT_ID) { + + Log_OC.d(TAG, "parent = " + parentId); + // Update the size of the parent + calculateFolderSize(parentId); + + // search the next parent + file = getFileById(parentId); + parentId = file.getParentId(); + + } + + } + }