1 /* ownCloud Android client application
2 * Copyright (C) 2012 Bartek Przybylski
3 * Copyright (C) 2012-2013 ownCloud Inc.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2,
7 * as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 package com
.owncloud
.android
.datamodel
;
22 import java
.util
.ArrayList
;
23 import java
.util
.Collections
;
24 import java
.util
.Iterator
;
25 import java
.util
.List
;
26 import java
.util
.Vector
;
28 import com
.owncloud
.android
.Log_OC
;
29 import com
.owncloud
.android
.db
.ProviderMeta
;
30 import com
.owncloud
.android
.db
.ProviderMeta
.ProviderTableMeta
;
31 import com
.owncloud
.android
.utils
.FileStorageUtils
;
33 import android
.accounts
.Account
;
34 import android
.content
.ContentProviderClient
;
35 import android
.content
.ContentProviderOperation
;
36 import android
.content
.ContentProviderResult
;
37 import android
.content
.ContentResolver
;
38 import android
.content
.ContentValues
;
39 import android
.content
.OperationApplicationException
;
40 import android
.database
.Cursor
;
41 import android
.net
.Uri
;
42 import android
.os
.RemoteException
;
44 public class FileDataStorageManager
{
46 public static final int ROOT_PARENT_ID
= 0;
48 private ContentResolver mContentResolver
;
49 private ContentProviderClient mContentProviderClient
;
50 private Account mAccount
;
52 private static String TAG
= FileDataStorageManager
.class.getSimpleName();
55 public FileDataStorageManager(Account account
, ContentResolver cr
) {
56 mContentProviderClient
= null
;
57 mContentResolver
= cr
;
61 public FileDataStorageManager(Account account
, ContentProviderClient cp
) {
62 mContentProviderClient
= cp
;
63 mContentResolver
= null
;
68 public void setAccount(Account account
) {
72 public Account
getAccount() {
76 public void setContentResolver(ContentResolver cr
) {
77 mContentResolver
= cr
;
80 public ContentResolver
getContentResolver() {
81 return mContentResolver
;
84 public void setContentProviderClient(ContentProviderClient cp
) {
85 mContentProviderClient
= cp
;
88 public ContentProviderClient
getContentProviderClient() {
89 return mContentProviderClient
;
93 public OCFile
getFileByPath(String path
) {
94 Cursor c
= getCursorForValue(ProviderTableMeta
.FILE_PATH
, path
);
96 if (c
.moveToFirst()) {
97 file
= createFileInstance(c
);
100 if (file
== null
&& OCFile
.ROOT_PATH
.equals(path
)) {
101 return createRootDir(); // root should always exist
107 public OCFile
getFileById(long id
) {
108 Cursor c
= getCursorForValue(ProviderTableMeta
._ID
, String
.valueOf(id
));
110 if (c
.moveToFirst()) {
111 file
= createFileInstance(c
);
117 public OCFile
getFileByLocalPath(String path
) {
118 Cursor c
= getCursorForValue(ProviderTableMeta
.FILE_STORAGE_PATH
, path
);
120 if (c
.moveToFirst()) {
121 file
= createFileInstance(c
);
127 public boolean fileExists(long id
) {
128 return fileExists(ProviderTableMeta
._ID
, String
.valueOf(id
));
131 public boolean fileExists(String path
) {
132 return fileExists(ProviderTableMeta
.FILE_PATH
, path
);
136 public Vector
<OCFile
> getFolderContent(OCFile f
) {
137 if (f
!= null
&& f
.isFolder() && f
.getFileId() != -1) {
138 return getFolderContent(f
.getFileId());
141 return new Vector
<OCFile
>();
146 public Vector
<OCFile
> getFolderImages(OCFile folder
) {
147 Vector
<OCFile
> ret
= new Vector
<OCFile
>();
148 if (folder
!= null
) {
149 // TODO better implementation, filtering in the access to database (if possible) instead of here
150 Vector
<OCFile
> tmp
= getFolderContent(folder
);
151 OCFile current
= null
;
152 for (int i
=0; i
<tmp
.size(); i
++) {
153 current
= tmp
.get(i
);
154 if (current
.isImage()) {
163 public boolean saveFile(OCFile file
) {
164 boolean overriden
= false
;
165 ContentValues cv
= new ContentValues();
166 cv
.put(ProviderTableMeta
.FILE_MODIFIED
, file
.getModificationTimestamp());
167 cv
.put(ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA
, file
.getModificationTimestampAtLastSyncForData());
168 cv
.put(ProviderTableMeta
.FILE_CREATION
, file
.getCreationTimestamp());
169 cv
.put(ProviderTableMeta
.FILE_CONTENT_LENGTH
, file
.getFileLength());
170 cv
.put(ProviderTableMeta
.FILE_CONTENT_TYPE
, file
.getMimetype());
171 cv
.put(ProviderTableMeta
.FILE_NAME
, file
.getFileName());
172 //if (file.getParentId() != DataStorageManager.ROOT_PARENT_ID)
173 cv
.put(ProviderTableMeta
.FILE_PARENT
, file
.getParentId());
174 cv
.put(ProviderTableMeta
.FILE_PATH
, file
.getRemotePath());
175 if (!file
.isFolder())
176 cv
.put(ProviderTableMeta
.FILE_STORAGE_PATH
, file
.getStoragePath());
177 cv
.put(ProviderTableMeta
.FILE_ACCOUNT_OWNER
, mAccount
.name
);
178 cv
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE
, file
.getLastSyncDateForProperties());
179 cv
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA
, file
.getLastSyncDateForData());
180 cv
.put(ProviderTableMeta
.FILE_KEEP_IN_SYNC
, file
.keepInSync() ?
1 : 0);
181 cv
.put(ProviderTableMeta
.FILE_ETAG
, file
.getEtag());
183 boolean sameRemotePath
= fileExists(file
.getRemotePath());
184 boolean changesSizeOfAncestors
= false
;
185 if (sameRemotePath
||
186 fileExists(file
.getFileId()) ) { // for renamed files; no more delete and create
188 OCFile oldFile
= null
;
189 if (sameRemotePath
) {
190 oldFile
= getFileByPath(file
.getRemotePath());
191 file
.setFileId(oldFile
.getFileId());
193 oldFile
= getFileById(file
.getFileId());
195 changesSizeOfAncestors
= (oldFile
.getFileLength() != file
.getFileLength());
198 if (getContentResolver() != null
) {
199 getContentResolver().update(ProviderTableMeta
.CONTENT_URI
, cv
,
200 ProviderTableMeta
._ID
+ "=?",
201 new String
[] { String
.valueOf(file
.getFileId()) });
204 getContentProviderClient().update(ProviderTableMeta
.CONTENT_URI
,
205 cv
, ProviderTableMeta
._ID
+ "=?",
206 new String
[] { String
.valueOf(file
.getFileId()) });
207 } catch (RemoteException e
) {
209 "Fail to insert insert file to database "
214 changesSizeOfAncestors
= true
;
215 Uri result_uri
= null
;
216 if (getContentResolver() != null
) {
217 result_uri
= getContentResolver().insert(
218 ProviderTableMeta
.CONTENT_URI_FILE
, cv
);
221 result_uri
= getContentProviderClient().insert(
222 ProviderTableMeta
.CONTENT_URI_FILE
, cv
);
223 } catch (RemoteException e
) {
225 "Fail to insert insert file to database "
229 if (result_uri
!= null
) {
230 long new_id
= Long
.parseLong(result_uri
.getPathSegments()
232 file
.setFileId(new_id
);
236 if (file
.isFolder()) {
237 calculateFolderSize(file
.getFileId());
238 if (file
.needsUpdatingWhileSaving()) {
239 for (OCFile f
: getFolderContent(file
))
244 if (changesSizeOfAncestors
|| file
.isFolder()) {
245 updateSizesToTheRoot(file
.getParentId());
252 public void saveFiles(List
<OCFile
> files
) {
254 Iterator
<OCFile
> filesIt
= files
.iterator();
255 ArrayList
<ContentProviderOperation
> operations
= new ArrayList
<ContentProviderOperation
>(files
.size());
258 // prepare operations to perform
259 while (filesIt
.hasNext()) {
260 file
= filesIt
.next();
261 ContentValues cv
= new ContentValues();
262 cv
.put(ProviderTableMeta
.FILE_MODIFIED
, file
.getModificationTimestamp());
263 cv
.put(ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA
, file
.getModificationTimestampAtLastSyncForData());
264 cv
.put(ProviderTableMeta
.FILE_CREATION
, file
.getCreationTimestamp());
265 cv
.put(ProviderTableMeta
.FILE_CONTENT_LENGTH
, file
.getFileLength());
266 cv
.put(ProviderTableMeta
.FILE_CONTENT_TYPE
, file
.getMimetype());
267 cv
.put(ProviderTableMeta
.FILE_NAME
, file
.getFileName());
268 if (file
.getParentId() != FileDataStorageManager
.ROOT_PARENT_ID
)
269 cv
.put(ProviderTableMeta
.FILE_PARENT
, file
.getParentId());
270 cv
.put(ProviderTableMeta
.FILE_PATH
, file
.getRemotePath());
271 if (!file
.isFolder())
272 cv
.put(ProviderTableMeta
.FILE_STORAGE_PATH
, file
.getStoragePath());
273 cv
.put(ProviderTableMeta
.FILE_ACCOUNT_OWNER
, mAccount
.name
);
274 cv
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE
, file
.getLastSyncDateForProperties());
275 cv
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA
, file
.getLastSyncDateForData());
276 cv
.put(ProviderTableMeta
.FILE_KEEP_IN_SYNC
, file
.keepInSync() ?
1 : 0);
277 cv
.put(ProviderTableMeta
.FILE_ETAG
, file
.getEtag());
279 if (fileExists(file
.getRemotePath())) {
280 OCFile oldFile
= getFileByPath(file
.getRemotePath());
281 file
.setFileId(oldFile
.getFileId());
283 if (file
.isFolder()) {
284 cv
.put(ProviderTableMeta
.FILE_CONTENT_LENGTH
, oldFile
.getFileLength());
285 file
.setFileLength(oldFile
.getFileLength());
288 operations
.add(ContentProviderOperation
.newUpdate(ProviderTableMeta
.CONTENT_URI
).
290 withSelection( ProviderTableMeta
._ID
+ "=?",
291 new String
[] { String
.valueOf(file
.getFileId()) })
294 } else if (fileExists(file
.getFileId())) {
295 OCFile oldFile
= getFileById(file
.getFileId());
296 if (file
.getStoragePath() == null
&& oldFile
.getStoragePath() != null
)
297 file
.setStoragePath(oldFile
.getStoragePath());
299 if (!file
.isFolder())
300 cv
.put(ProviderTableMeta
.FILE_STORAGE_PATH
, file
.getStoragePath());
302 cv
.put(ProviderTableMeta
.FILE_CONTENT_LENGTH
, oldFile
.getFileLength());
303 file
.setFileLength(oldFile
.getFileLength());
306 operations
.add(ContentProviderOperation
.newUpdate(ProviderTableMeta
.CONTENT_URI
).
308 withSelection( ProviderTableMeta
._ID
+ "=?",
309 new String
[] { String
.valueOf(file
.getFileId()) })
313 operations
.add(ContentProviderOperation
.newInsert(ProviderTableMeta
.CONTENT_URI
).withValues(cv
).build());
317 // apply operations in batch
318 ContentProviderResult
[] results
= null
;
320 if (getContentResolver() != null
) {
321 results
= getContentResolver().applyBatch(ProviderMeta
.AUTHORITY_FILES
, operations
);
324 results
= getContentProviderClient().applyBatch(operations
);
327 } catch (OperationApplicationException e
) {
328 Log_OC
.e(TAG
, "Fail to update/insert list of files to database " + e
.getMessage());
330 } catch (RemoteException e
) {
331 Log_OC
.e(TAG
, "Fail to update/insert list of files to database " + e
.getMessage());
334 // update new id in file objects for insertions
335 if (results
!= null
) {
337 for (int i
=0; i
<results
.length
; i
++) {
338 if (results
[i
].uri
!= null
) {
339 newId
= Long
.parseLong(results
[i
].uri
.getPathSegments().get(1));
340 files
.get(i
).setFileId(newId
);
341 //Log_OC.v(TAG, "Found and added id in insertion for " + files.get(i).getRemotePath());
346 for (OCFile aFile
: files
) {
347 if (aFile
.isFolder() && aFile
.needsUpdatingWhileSaving())
348 saveFiles(getFolderContent(aFile
));
355 * Calculate and save the folderSize on DB
358 public void calculateFolderSize(long id
) {
361 Vector
<OCFile
> files
= getFolderContent(id
);
363 for (OCFile f
: files
)
365 folderSize
= folderSize
+ f
.getFileLength();
368 updateSize(id
, folderSize
);
372 public void removeFile(OCFile file
, boolean removeLocalCopy
) {
373 Uri file_uri
= Uri
.withAppendedPath(ProviderTableMeta
.CONTENT_URI_FILE
, ""+file
.getFileId());
374 if (getContentProviderClient() != null
) {
376 getContentProviderClient().delete(file_uri
,
377 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+"=?",
378 new String
[]{mAccount
.name
});
379 } catch (RemoteException e
) {
383 getContentResolver().delete(file_uri
,
384 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+"=?",
385 new String
[]{mAccount
.name
});
387 if (file
.isDown() && removeLocalCopy
) {
388 new File(file
.getStoragePath()).delete();
390 if (file
.isFolder() && removeLocalCopy
) {
391 File f
= new File(FileStorageUtils
.getDefaultSavePathFor(mAccount
.name
, file
));
392 if (f
.exists() && f
.isDirectory() && (f
.list() == null
|| f
.list().length
== 0)) {
397 if (file
.getFileLength() > 0) {
398 updateSizesToTheRoot(file
.getParentId());
402 public void removeFolder(OCFile folder
, boolean removeDBData
, boolean removeLocalContent
) {
403 // TODO consider possible failures
404 if (folder
!= null
&& folder
.isFolder() && folder
.getFileId() != -1) {
405 Vector
<OCFile
> children
= getFolderContent(folder
);
406 if (children
.size() > 0) {
408 for (int i
=0; i
<children
.size(); i
++) {
409 child
= children
.get(i
);
410 if (child
.isFolder()) {
411 removeFolder(child
, removeDBData
, removeLocalContent
);
414 removeFile(child
, removeLocalContent
);
415 } else if (removeLocalContent
) {
416 if (child
.isDown()) {
417 new File(child
.getStoragePath()).delete();
424 removeFile(folder
, true
);
427 if (folder
.getFileLength() > 0) {
428 updateSizesToTheRoot(folder
.getParentId());
435 * Updates database for a folder that was moved to a different location.
437 * TODO explore better (faster) implementations
438 * TODO throw exceptions up !
440 public void moveFolder(OCFile folder
, String newPath
) {
441 // TODO check newPath
443 if (folder
!= null
&& folder
.isFolder() && folder
.fileExists() && !OCFile
.ROOT_PATH
.equals(folder
.getFileName())) {
444 /// 1. get all the descendants of 'dir' in a single QUERY (including 'dir')
446 if (getContentProviderClient() != null
) {
448 c
= getContentProviderClient().query(ProviderTableMeta
.CONTENT_URI
,
450 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=? AND " + ProviderTableMeta
.FILE_PATH
+ " LIKE ? ",
451 new String
[] { mAccount
.name
, folder
.getRemotePath() + "%" }, ProviderTableMeta
.FILE_PATH
+ " ASC ");
452 } catch (RemoteException e
) {
453 Log_OC
.e(TAG
, e
.getMessage());
456 c
= getContentResolver().query(ProviderTableMeta
.CONTENT_URI
,
458 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=? AND " + ProviderTableMeta
.FILE_PATH
+ " LIKE ? ",
459 new String
[] { mAccount
.name
, folder
.getRemotePath() + "%" }, ProviderTableMeta
.FILE_PATH
+ " ASC ");
462 /// 2. prepare a batch of update operations to change all the descendants
463 ArrayList
<ContentProviderOperation
> operations
= new ArrayList
<ContentProviderOperation
>(c
.getCount());
464 int lengthOfOldPath
= folder
.getRemotePath().length();
465 String defaultSavePath
= FileStorageUtils
.getSavePath(mAccount
.name
);
466 int lengthOfOldStoragePath
= defaultSavePath
.length() + lengthOfOldPath
;
467 if (c
.moveToFirst()) {
469 ContentValues cv
= new ContentValues(); // don't take the constructor out of the loop and clear the object
470 OCFile child
= createFileInstance(c
);
471 cv
.put(ProviderTableMeta
.FILE_PATH
, newPath
+ child
.getRemotePath().substring(lengthOfOldPath
));
472 if (child
.getStoragePath() != null
&& child
.getStoragePath().startsWith(defaultSavePath
)) {
473 cv
.put(ProviderTableMeta
.FILE_STORAGE_PATH
, defaultSavePath
+ newPath
+ child
.getStoragePath().substring(lengthOfOldStoragePath
));
475 operations
.add(ContentProviderOperation
.newUpdate(ProviderTableMeta
.CONTENT_URI
).
477 withSelection( ProviderTableMeta
._ID
+ "=?",
478 new String
[] { String
.valueOf(child
.getFileId()) })
480 } while (c
.moveToNext());
484 /// 3. apply updates in batch
486 if (getContentResolver() != null
) {
487 getContentResolver().applyBatch(ProviderMeta
.AUTHORITY_FILES
, operations
);
490 getContentProviderClient().applyBatch(operations
);
493 } catch (OperationApplicationException e
) {
494 Log_OC
.e(TAG
, "Fail to update descendants of " + folder
.getFileId() + " in database", e
);
496 } catch (RemoteException e
) {
497 Log_OC
.e(TAG
, "Fail to update desendants of " + folder
.getFileId() + " in database", e
);
504 private Vector
<OCFile
> getFolderContent(long parentId
) {
506 Vector
<OCFile
> ret
= new Vector
<OCFile
>();
508 Uri req_uri
= Uri
.withAppendedPath(
509 ProviderTableMeta
.CONTENT_URI_DIR
,
510 String
.valueOf(parentId
));
513 if (getContentProviderClient() != null
) {
515 c
= getContentProviderClient().query(req_uri
, null
,
516 ProviderTableMeta
.FILE_PARENT
+ "=?" ,
517 new String
[] { String
.valueOf(parentId
)}, null
);
518 } catch (RemoteException e
) {
519 Log_OC
.e(TAG
, e
.getMessage());
523 c
= getContentResolver().query(req_uri
, null
,
524 ProviderTableMeta
.FILE_PARENT
+ "=?" ,
525 new String
[] { String
.valueOf(parentId
)}, null
);
528 if (c
.moveToFirst()) {
530 OCFile child
= createFileInstance(c
);
532 } while (c
.moveToNext());
537 Collections
.sort(ret
);
543 private OCFile
createRootDir() {
544 OCFile file
= new OCFile(OCFile
.ROOT_PATH
);
545 file
.setMimetype("DIR");
546 file
.setParentId(FileDataStorageManager
.ROOT_PARENT_ID
);
551 private boolean fileExists(String cmp_key
, String value
) {
553 if (getContentResolver() != null
) {
554 c
= getContentResolver()
555 .query(ProviderTableMeta
.CONTENT_URI
,
558 + ProviderTableMeta
.FILE_ACCOUNT_OWNER
560 new String
[] { value
, mAccount
.name
}, null
);
563 c
= getContentProviderClient().query(
564 ProviderTableMeta
.CONTENT_URI
,
567 + ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=?",
568 new String
[] { value
, mAccount
.name
}, null
);
569 } catch (RemoteException e
) {
571 "Couldn't determine file existance, assuming non existance: "
576 boolean retval
= c
.moveToFirst();
581 private Cursor
getCursorForValue(String key
, String value
) {
583 if (getContentResolver() != null
) {
584 c
= getContentResolver()
585 .query(ProviderTableMeta
.CONTENT_URI
,
588 + ProviderTableMeta
.FILE_ACCOUNT_OWNER
590 new String
[] { value
, mAccount
.name
}, null
);
593 c
= getContentProviderClient().query(
594 ProviderTableMeta
.CONTENT_URI
,
596 key
+ "=? AND " + ProviderTableMeta
.FILE_ACCOUNT_OWNER
597 + "=?", new String
[] { value
, mAccount
.name
},
599 } catch (RemoteException e
) {
600 Log_OC
.e(TAG
, "Could not get file details: " + e
.getMessage());
607 private OCFile
createFileInstance(Cursor c
) {
610 file
= new OCFile(c
.getString(c
611 .getColumnIndex(ProviderTableMeta
.FILE_PATH
)));
612 file
.setFileId(c
.getLong(c
.getColumnIndex(ProviderTableMeta
._ID
)));
613 file
.setParentId(c
.getLong(c
614 .getColumnIndex(ProviderTableMeta
.FILE_PARENT
)));
615 file
.setMimetype(c
.getString(c
616 .getColumnIndex(ProviderTableMeta
.FILE_CONTENT_TYPE
)));
617 if (!file
.isFolder()) {
618 file
.setStoragePath(c
.getString(c
619 .getColumnIndex(ProviderTableMeta
.FILE_STORAGE_PATH
)));
620 if (file
.getStoragePath() == null
) {
621 // try to find existing file and bind it with current account; - with the current update of SynchronizeFolderOperation, this won't be necessary anymore after a full synchronization of the account
622 File f
= new File(FileStorageUtils
.getDefaultSavePathFor(mAccount
.name
, file
));
624 file
.setStoragePath(f
.getAbsolutePath());
625 file
.setLastSyncDateForData(f
.lastModified());
629 file
.setFileLength(c
.getLong(c
630 .getColumnIndex(ProviderTableMeta
.FILE_CONTENT_LENGTH
)));
631 file
.setCreationTimestamp(c
.getLong(c
632 .getColumnIndex(ProviderTableMeta
.FILE_CREATION
)));
633 file
.setModificationTimestamp(c
.getLong(c
634 .getColumnIndex(ProviderTableMeta
.FILE_MODIFIED
)));
635 file
.setModificationTimestampAtLastSyncForData(c
.getLong(c
636 .getColumnIndex(ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA
)));
637 file
.setLastSyncDateForProperties(c
.getLong(c
638 .getColumnIndex(ProviderTableMeta
.FILE_LAST_SYNC_DATE
)));
639 file
.setLastSyncDateForData(c
.getLong(c
.
640 getColumnIndex(ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA
)));
641 file
.setKeepInSync(c
.getInt(
642 c
.getColumnIndex(ProviderTableMeta
.FILE_KEEP_IN_SYNC
)) == 1 ? true
: false
);
643 file
.setEtag(c
.getString(c
.getColumnIndex(ProviderTableMeta
.FILE_ETAG
)));
650 * Update the size value of an OCFile in DB
652 private int updateSize(long id
, long size
) {
653 ContentValues cv
= new ContentValues();
654 cv
.put(ProviderTableMeta
.FILE_CONTENT_LENGTH
, size
);
656 if (getContentResolver() != null
) {
657 result
= getContentResolver().update(ProviderTableMeta
.CONTENT_URI
, cv
, ProviderTableMeta
._ID
+ "=?",
658 new String
[] { String
.valueOf(id
) });
661 result
= getContentProviderClient().update(ProviderTableMeta
.CONTENT_URI
, cv
, ProviderTableMeta
._ID
+ "=?",
662 new String
[] { String
.valueOf(id
) });
663 } catch (RemoteException e
) {
664 Log_OC
.e(TAG
,"Fail to update size column into database " + e
.getMessage());
671 * Update the size of a subtree of folder from a file to the root
672 * @param parentId: parent of the file
674 private void updateSizesToTheRoot(long parentId
) {
678 while (parentId
!= FileDataStorageManager
.ROOT_PARENT_ID
) {
680 // Update the size of the parent
681 calculateFolderSize(parentId
);
683 // search the next parent
684 file
= getFileById(parentId
);
685 parentId
= file
.getParentId();