OC-577: Modify FileDataStorageManager to call updateSubtreeSize. OC-523
[pub/Android/ownCloud.git] / src / com / owncloud / android / datamodel / FileDataStorageManager.java
1 /* ownCloud Android client application
2 * Copyright (C) 2012 Bartek Przybylski
3 * Copyright (C) 2012-2013 ownCloud Inc.
4 *
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.
8 *
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.
13 *
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/>.
16 *
17 */
18
19 package com.owncloud.android.datamodel;
20
21 import java.io.File;
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;
27
28 import com.owncloud.android.DisplayUtils;
29 import com.owncloud.android.Log_OC;
30 import com.owncloud.android.db.ProviderMeta;
31 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
32 import com.owncloud.android.utils.FileStorageUtils;
33
34 import android.accounts.Account;
35 import android.content.ContentProviderClient;
36 import android.content.ContentProviderOperation;
37 import android.content.ContentProviderResult;
38 import android.content.ContentResolver;
39 import android.content.ContentValues;
40 import android.content.OperationApplicationException;
41 import android.database.Cursor;
42 import android.net.Uri;
43 import android.os.RemoteException;
44
45 public class FileDataStorageManager implements DataStorageManager {
46
47 private ContentResolver mContentResolver;
48 private ContentProviderClient mContentProvider;
49 private Account mAccount;
50
51 private static String TAG = "FileDataStorageManager";
52
53 public FileDataStorageManager(Account account, ContentResolver cr) {
54 mContentProvider = null;
55 mContentResolver = cr;
56 mAccount = account;
57 }
58
59 public FileDataStorageManager(Account account, ContentProviderClient cp) {
60 mContentProvider = cp;
61 mContentResolver = null;
62 mAccount = account;
63 }
64
65 @Override
66 public OCFile getFileByPath(String path) {
67 Cursor c = getCursorForValue(ProviderTableMeta.FILE_PATH, path);
68 OCFile file = null;
69 if (c.moveToFirst()) {
70 file = createFileInstance(c);
71 }
72 c.close();
73 if (file == null && OCFile.PATH_SEPARATOR.equals(path)) {
74 return createRootDir(); // root should always exist
75 }
76 return file;
77 }
78
79
80 private OCFile createRootDir() {
81 OCFile file = new OCFile(OCFile.PATH_SEPARATOR);
82 file.setMimetype("DIR");
83 file.setParentId(DataStorageManager.ROOT_PARENT_ID);
84 saveFile(file);
85 return file;
86 }
87
88 @Override
89 public OCFile getFileById(long id) {
90 Cursor c = getCursorForValue(ProviderTableMeta._ID, String.valueOf(id));
91 OCFile file = null;
92 if (c.moveToFirst()) {
93 file = createFileInstance(c);
94 }
95 c.close();
96 return file;
97 }
98
99 public OCFile getFileByLocalPath(String path) {
100 Cursor c = getCursorForValue(ProviderTableMeta.FILE_STORAGE_PATH, path);
101 OCFile file = null;
102 if (c.moveToFirst()) {
103 file = createFileInstance(c);
104 }
105 c.close();
106 return file;
107 }
108
109 @Override
110 public boolean fileExists(long id) {
111 return fileExists(ProviderTableMeta._ID, String.valueOf(id));
112 }
113
114 @Override
115 public boolean fileExists(String path) {
116 return fileExists(ProviderTableMeta.FILE_PATH, path);
117 }
118
119 @Override
120 public boolean saveFile(OCFile file) {
121 boolean overriden = false;
122 ContentValues cv = new ContentValues();
123 cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
124 cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
125 cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
126 cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
127 cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
128 cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
129 if (file.getParentId() != 0)
130 cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
131 cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
132 if (!file.isDirectory())
133 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
134 cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
135 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
136 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
137 cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
138
139 boolean sameRemotePath = fileExists(file.getRemotePath());
140 if (sameRemotePath ||
141 fileExists(file.getFileId()) ) { // for renamed files; no more delete and create
142
143 if (sameRemotePath) {
144 OCFile oldFile = getFileByPath(file.getRemotePath());
145 file.setFileId(oldFile.getFileId());
146 }
147
148 overriden = true;
149 if (getContentResolver() != null) {
150 getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv,
151 ProviderTableMeta._ID + "=?",
152 new String[] { String.valueOf(file.getFileId()) });
153 } else {
154 try {
155 getContentProvider().update(ProviderTableMeta.CONTENT_URI,
156 cv, ProviderTableMeta._ID + "=?",
157 new String[] { String.valueOf(file.getFileId()) });
158 } catch (RemoteException e) {
159 Log_OC.e(TAG,
160 "Fail to insert insert file to database "
161 + e.getMessage());
162 }
163 }
164 } else {
165 Uri result_uri = null;
166 if (getContentResolver() != null) {
167 result_uri = getContentResolver().insert(
168 ProviderTableMeta.CONTENT_URI_FILE, cv);
169 } else {
170 try {
171 result_uri = getContentProvider().insert(
172 ProviderTableMeta.CONTENT_URI_FILE, cv);
173 } catch (RemoteException e) {
174 Log_OC.e(TAG,
175 "Fail to insert insert file to database "
176 + e.getMessage());
177 }
178 }
179 if (result_uri != null) {
180 long new_id = Long.parseLong(result_uri.getPathSegments()
181 .get(1));
182 file.setFileId(new_id);
183 }
184 }
185
186 if (file.isDirectory() && file.needsUpdatingWhileSaving())
187 for (OCFile f : getDirectoryContent(file))
188 saveFile(f);
189
190 Log_OC.d(TAG, ".........file Time= " + DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()));
191 updateSubtreeSize(file.getParentId());
192
193 return overriden;
194 }
195
196
197 @Override
198 public void saveFiles(List<OCFile> files) {
199
200 Iterator<OCFile> filesIt = files.iterator();
201 ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(files.size());
202 OCFile file = null;
203
204 // prepare operations to perform
205 while (filesIt.hasNext()) {
206 file = filesIt.next();
207 ContentValues cv = new ContentValues();
208 cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
209 cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
210 cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
211 cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
212 cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
213 cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
214 if (file.getParentId() != 0)
215 cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
216 cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
217 if (!file.isDirectory())
218 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
219 cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
220 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
221 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
222 cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
223
224 if (fileExists(file.getRemotePath())) {
225 OCFile oldFile = getFileByPath(file.getRemotePath());
226 file.setFileId(oldFile.getFileId());
227 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
228 withValues(cv).
229 withSelection( ProviderTableMeta._ID + "=?",
230 new String[] { String.valueOf(file.getFileId()) })
231 .build());
232
233 } else if (fileExists(file.getFileId())) {
234 OCFile oldFile = getFileById(file.getFileId());
235 if (file.getStoragePath() == null && oldFile.getStoragePath() != null)
236 file.setStoragePath(oldFile.getStoragePath());
237 if (!file.isDirectory());
238 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
239
240 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
241 withValues(cv).
242 withSelection( ProviderTableMeta._ID + "=?",
243 new String[] { String.valueOf(file.getFileId()) })
244 .build());
245
246 } else {
247 operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
248 }
249 }
250
251 // apply operations in batch
252 ContentProviderResult[] results = null;
253 try {
254 if (getContentResolver() != null) {
255 results = getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations);
256
257 } else {
258 results = getContentProvider().applyBatch(operations);
259 }
260
261 } catch (OperationApplicationException e) {
262 Log_OC.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
263
264 } catch (RemoteException e) {
265 Log_OC.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
266 }
267
268 // update new id in file objects for insertions
269 if (results != null) {
270 long newId;
271 for (int i=0; i<results.length; i++) {
272 if (results[i].uri != null) {
273 newId = Long.parseLong(results[i].uri.getPathSegments().get(1));
274 files.get(i).setFileId(newId);
275 //Log_OC.v(TAG, "Found and added id in insertion for " + files.get(i).getRemotePath());
276 }
277 }
278 }
279
280 for (OCFile aFile : files) {
281 if (aFile.isDirectory() && aFile.needsUpdatingWhileSaving())
282 saveFiles(getDirectoryContent(aFile));
283 }
284
285 }
286
287 public void setAccount(Account account) {
288 mAccount = account;
289 }
290
291 public Account getAccount() {
292 return mAccount;
293 }
294
295 public void setContentResolver(ContentResolver cr) {
296 mContentResolver = cr;
297 }
298
299 public ContentResolver getContentResolver() {
300 return mContentResolver;
301 }
302
303 public void setContentProvider(ContentProviderClient cp) {
304 mContentProvider = cp;
305 }
306
307 public ContentProviderClient getContentProvider() {
308 return mContentProvider;
309 }
310
311 @Override
312 public Vector<OCFile> getDirectoryContent(OCFile f) {
313 Vector<OCFile> ret = new Vector<OCFile>();
314 if (f != null && f.isDirectory() && f.getFileId() != -1) {
315
316 Uri req_uri = Uri.withAppendedPath(
317 ProviderTableMeta.CONTENT_URI_DIR,
318 String.valueOf(f.getFileId()));
319 Cursor c = null;
320
321 if (getContentProvider() != null) {
322 try {
323 c = getContentProvider().query(req_uri, null,
324 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
325 new String[] { mAccount.name }, null);
326 } catch (RemoteException e) {
327 Log_OC.e(TAG, e.getMessage());
328 return ret;
329 }
330 } else {
331 c = getContentResolver().query(req_uri, null,
332 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
333 new String[] { mAccount.name }, null);
334 }
335
336 if (c.moveToFirst()) {
337 do {
338 OCFile child = createFileInstance(c);
339 ret.add(child);
340 } while (c.moveToNext());
341 }
342
343 c.close();
344
345 Collections.sort(ret);
346
347 }
348 return ret;
349 }
350
351 private boolean fileExists(String cmp_key, String value) {
352 Cursor c;
353 if (getContentResolver() != null) {
354 c = getContentResolver()
355 .query(ProviderTableMeta.CONTENT_URI,
356 null,
357 cmp_key + "=? AND "
358 + ProviderTableMeta.FILE_ACCOUNT_OWNER
359 + "=?",
360 new String[] { value, mAccount.name }, null);
361 } else {
362 try {
363 c = getContentProvider().query(
364 ProviderTableMeta.CONTENT_URI,
365 null,
366 cmp_key + "=? AND "
367 + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
368 new String[] { value, mAccount.name }, null);
369 } catch (RemoteException e) {
370 Log_OC.e(TAG,
371 "Couldn't determine file existance, assuming non existance: "
372 + e.getMessage());
373 return false;
374 }
375 }
376 boolean retval = c.moveToFirst();
377 c.close();
378 return retval;
379 }
380
381 private Cursor getCursorForValue(String key, String value) {
382 Cursor c = null;
383 if (getContentResolver() != null) {
384 c = getContentResolver()
385 .query(ProviderTableMeta.CONTENT_URI,
386 null,
387 key + "=? AND "
388 + ProviderTableMeta.FILE_ACCOUNT_OWNER
389 + "=?",
390 new String[] { value, mAccount.name }, null);
391 } else {
392 try {
393 c = getContentProvider().query(
394 ProviderTableMeta.CONTENT_URI,
395 null,
396 key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER
397 + "=?", new String[] { value, mAccount.name },
398 null);
399 } catch (RemoteException e) {
400 Log_OC.e(TAG, "Could not get file details: " + e.getMessage());
401 c = null;
402 }
403 }
404 return c;
405 }
406
407 private OCFile createFileInstance(Cursor c) {
408 OCFile file = null;
409 if (c != null) {
410 file = new OCFile(c.getString(c
411 .getColumnIndex(ProviderTableMeta.FILE_PATH)));
412 file.setFileId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
413 file.setParentId(c.getLong(c
414 .getColumnIndex(ProviderTableMeta.FILE_PARENT)));
415 file.setMimetype(c.getString(c
416 .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)));
417 if (!file.isDirectory()) {
418 file.setStoragePath(c.getString(c
419 .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));
420 if (file.getStoragePath() == null) {
421 // 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
422 File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
423 if (f.exists()) {
424 file.setStoragePath(f.getAbsolutePath());
425 file.setLastSyncDateForData(f.lastModified());
426 }
427 }
428 }
429 file.setFileLength(c.getLong(c
430 .getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH)));
431 file.setCreationTimestamp(c.getLong(c
432 .getColumnIndex(ProviderTableMeta.FILE_CREATION)));
433 file.setModificationTimestamp(c.getLong(c
434 .getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));
435 file.setModificationTimestampAtLastSyncForData(c.getLong(c
436 .getColumnIndex(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA)));
437 file.setLastSyncDateForProperties(c.getLong(c
438 .getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE)));
439 file.setLastSyncDateForData(c.getLong(c.
440 getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA)));
441 file.setKeepInSync(c.getInt(
442 c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false);
443 }
444 return file;
445 }
446
447 @Override
448 public void removeFile(OCFile file, boolean removeLocalCopy) {
449 Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, ""+file.getFileId());
450 if (getContentProvider() != null) {
451 try {
452 getContentProvider().delete(file_uri,
453 ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
454 new String[]{mAccount.name});
455 } catch (RemoteException e) {
456 e.printStackTrace();
457 }
458 } else {
459 getContentResolver().delete(file_uri,
460 ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
461 new String[]{mAccount.name});
462 }
463 if (file.isDown() && removeLocalCopy) {
464 new File(file.getStoragePath()).delete();
465 }
466 if (file.isDirectory() && removeLocalCopy) {
467 File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
468 if (f.exists() && f.isDirectory() && (f.list() == null || f.list().length == 0)) {
469 f.delete();
470 }
471 }
472
473 updateSubtreeSize(file.getParentId());
474 }
475
476 @Override
477 public void removeDirectory(OCFile dir, boolean removeDBData, boolean removeLocalContent) {
478 // TODO consider possible failures
479 if (dir != null && dir.isDirectory() && dir.getFileId() != -1) {
480 Vector<OCFile> children = getDirectoryContent(dir);
481 if (children.size() > 0) {
482 OCFile child = null;
483 for (int i=0; i<children.size(); i++) {
484 child = children.get(i);
485 if (child.isDirectory()) {
486 removeDirectory(child, removeDBData, removeLocalContent);
487 } else {
488 if (removeDBData) {
489 removeFile(child, removeLocalContent);
490 } else if (removeLocalContent) {
491 if (child.isDown()) {
492 new File(child.getStoragePath()).delete();
493 }
494 }
495 }
496 }
497 }
498 if (removeDBData) {
499 removeFile(dir, true);
500 }
501
502 updateSubtreeSize(dir.getParentId());
503 }
504 }
505
506
507 /**
508 * Updates database for a folder that was moved to a different location.
509 *
510 * TODO explore better (faster) implementations
511 * TODO throw exceptions up !
512 */
513 @Override
514 public void moveDirectory(OCFile dir, String newPath) {
515 // TODO check newPath
516
517 if (dir != null && dir.isDirectory() && dir.fileExists() && !dir.getFileName().equals(OCFile.PATH_SEPARATOR)) {
518 /// 1. get all the descendants of 'dir' in a single QUERY (including 'dir')
519 Cursor c = null;
520 if (getContentProvider() != null) {
521 try {
522 c = getContentProvider().query(ProviderTableMeta.CONTENT_URI,
523 null,
524 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ?",
525 new String[] { mAccount.name, dir.getRemotePath() + "%" }, null);
526 } catch (RemoteException e) {
527 Log_OC.e(TAG, e.getMessage());
528 }
529 } else {
530 c = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
531 null,
532 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ?",
533 new String[] { mAccount.name, dir.getRemotePath() + "%" }, null);
534 }
535
536 /// 2. prepare a batch of update operations to change all the descendants
537 ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(c.getCount());
538 int lengthOfOldPath = dir.getRemotePath().length();
539 String defaultSavePath = FileStorageUtils.getSavePath(mAccount.name);
540 int lengthOfOldStoragePath = defaultSavePath.length() + lengthOfOldPath;
541 if (c.moveToFirst()) {
542 do {
543 ContentValues cv = new ContentValues(); // don't take the constructor out of the loop and clear the object
544 OCFile child = createFileInstance(c);
545 cv.put(ProviderTableMeta.FILE_PATH, newPath + child.getRemotePath().substring(lengthOfOldPath));
546 if (child.getStoragePath() != null && child.getStoragePath().startsWith(defaultSavePath)) {
547 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, defaultSavePath + newPath + child.getStoragePath().substring(lengthOfOldStoragePath));
548 }
549 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
550 withValues(cv).
551 withSelection( ProviderTableMeta._ID + "=?",
552 new String[] { String.valueOf(child.getFileId()) })
553 .build());
554 } while (c.moveToNext());
555 }
556 c.close();
557
558 /// 3. apply updates in batch
559 try {
560 if (getContentResolver() != null) {
561 getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations);
562
563 } else {
564 getContentProvider().applyBatch(operations);
565 }
566
567 } catch (OperationApplicationException e) {
568 Log_OC.e(TAG, "Fail to update descendants of " + dir.getFileId() + " in database", e);
569
570 } catch (RemoteException e) {
571 Log_OC.e(TAG, "Fail to update desendants of " + dir.getFileId() + " in database", e);
572 }
573
574 }
575 }
576
577 @Override
578 public Vector<OCFile> getDirectoryImages(OCFile directory) {
579 Vector<OCFile> ret = new Vector<OCFile>();
580 if (directory != null) {
581 // TODO better implementation, filtering in the access to database (if possible) instead of here
582 Vector<OCFile> tmp = getDirectoryContent(directory);
583 OCFile current = null;
584 for (int i=0; i<tmp.size(); i++) {
585 current = tmp.get(i);
586 if (current.isImage()) {
587 ret.add(current);
588 }
589 }
590 }
591 return ret;
592 }
593
594 @Override
595 public Vector<OCFile> getFilesbyParent(long parentId) {
596
597 Vector<OCFile> ret = new Vector<OCFile>();
598
599 Uri req_uri = Uri.withAppendedPath(
600 ProviderTableMeta.CONTENT_URI_DIR,
601 String.valueOf(parentId));
602 Cursor c = null;
603
604 if (getContentProvider() != null) {
605 try {
606 c = getContentProvider().query(req_uri, null,
607 ProviderTableMeta.FILE_PARENT + "=?" ,
608 new String[] { String.valueOf(parentId)}, null);
609 } catch (RemoteException e) {
610 Log_OC.e(TAG, e.getMessage());
611 return ret;
612 }
613 } else {
614 c = getContentResolver().query(req_uri, null,
615 ProviderTableMeta.FILE_PARENT + "=?" ,
616 new String[] { String.valueOf(parentId)}, null);
617 }
618
619 if (c.moveToFirst()) {
620 do {
621 OCFile child = createFileInstance(c);
622 ret.add(child);
623 } while (c.moveToNext());
624 }
625
626 c.close();
627
628 Collections.sort(ret);
629
630 return ret;
631 }
632
633 /**
634 * Calculate and save the folderSize on DB
635 * @param id
636 */
637 @Override
638 public void saveFolderSize(long id) {
639 long folderSize = 0;
640
641 Vector<OCFile> files = getFilesbyParent(id);
642
643 Log_OC.d(TAG, "Folder " + String.valueOf(id) + "--- Number of Files = " + String.valueOf(files.size()));
644
645 for (OCFile f: files)
646 {
647 folderSize = folderSize + f.getFileLength();
648 Log_OC.d(TAG, "Folder Size = " + String.valueOf(folderSize));
649 }
650
651 updatefolderSize(id, folderSize);
652 }
653
654 /**
655 * Update the size value of a folder on DB
656 */
657 @Override
658 public int updatefolderSize(long id, long size) {
659 ContentValues cv = new ContentValues();
660 cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, size);
661 int result = getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, ProviderTableMeta._ID + "=?",
662 new String[] { String.valueOf(id) });
663 return result;
664 }
665
666 /**
667 * Update the size of a subtree of folder from a file to the root
668 * @param parentId: parent of the file
669 */
670 private void updateSubtreeSize(long parentId) {
671
672 OCFile file;
673
674 while (parentId != 0) {
675
676 Log_OC.d(TAG, "parent = " + parentId);
677 // Update the size of the parent
678 saveFolderSize(parentId);
679
680 // search the next parent
681 file = getFileById(parentId);
682 parentId = file.getParentId();
683
684 }
685
686 }
687
688 }