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
} else {
oldFile = getFileById(file.getFileId());
}
- changesSizeOfAncestors = (oldFile.getFileLength() != file.getFileLength());
overriden = true;
if (getContentResolver() != null) {
}
}
} else {
- changesSizeOfAncestors = true;
Uri result_uri = null;
if (getContentResolver() != null) {
result_uri = getContentResolver().insert(
}
if (file.isFolder()) {
- calculateFolderSize(file.getFileId());
+ updateFolderSize(file.getFileId());
if (file.needsUpdatingWhileSaving()) {
for (OCFile f : getFolderContent(file))
saveFile(f);
}
}
- if (changesSizeOfAncestors || file.isFolder()) {
- updateSizesToTheRoot(file.getParentId());
- }
-
return overriden;
}
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) {
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());
}
}
- // update metadata of folder --> TODO MOVE UPDATE OF SIZE TO CONTENTPROVIDER
+ // update metadata of folder
ContentValues cv = new ContentValues();
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, folder.getFileLength());
+ cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, folderSize);
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, folder.getMimetype());
cv.put(ProviderTableMeta.FILE_NAME, folder.getFileName());
cv.put(ProviderTableMeta.FILE_PARENT, folder.getParentId());
cv.put(ProviderTableMeta.FILE_PATH, folder.getRemotePath());
- if (!folder.isFolder()) {
- cv.put(ProviderTableMeta.FILE_STORAGE_PATH, folder.getStoragePath());
- }
cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, folder.getLastSyncDateForProperties());
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, folder.getLastSyncDateForData());
/**
- * Calculate and save the folderSize on DB
+ *
* @param id
*/
- public void calculateFolderSize(long id) {
- long folderSize = 0;
-
- Vector<OCFile> files = getFolderContent(id);
-
- for (OCFile f: files)
- {
- folderSize = folderSize + f.getFileLength();
+ 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());
+ }
}
-
- updateSize(id, folderSize);
}
-
+
public void removeFile(OCFile file, boolean removeDBData, boolean removeLocalCopy) {
if (file != null) {
if (file.isFolder()) {
} else {
getContentResolver().delete(file_uri, where, whereArgs);
}
- if (file.getFileLength() > 0) {
- updateSizesToTheRoot(file.getParentId()); // TODO move to content provider
- }
}
if (removeLocalCopy && file.isDown()) {
boolean success = new File(file.getStoragePath()).delete();
} else {
getContentResolver().delete(folder_uri, where, whereArgs);
}
- if (folder.getFileLength() > 0) {
- updateSizesToTheRoot(folder.getParentId()); // TODO move to FileContentProvider
- }
}
private void removeLocalFolder(File folder) {
return file;
}
- /**
+ /*
* 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);
}
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 != FileDataStorageManager.ROOT_PARENT_ID) {
// Update the size of the parent
- calculateFolderSize(parentId);
+ updateFolderSize(parentId);
// search the next parent
file = getFileById(parentId);
parentId = file.getParentId();
}
-
}
+ */
}
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
-import android.util.Log;
/**
* The ContentProvider for the ownCloud App.
ProviderTableMeta.FILE_ETAG);
}
- private static final String TAG = FileContentProvider.class.getSimpleName();
private static final int SINGLE_FILE = 1;
private static final int DIRECTORY = 2;
private static final int ROOT_DIRECTORY = 3;
private static final UriMatcher mUriMatcher;
+
+ public static final String METHOD_UPDATE_FOLDER_SIZE = "updateFolderSize";
+
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, null, ROOT_DIRECTORY);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/", SINGLE_FILE);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/#", SINGLE_FILE);
+ mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/", DIRECTORY);
mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/#", DIRECTORY);
}
if (children != null && children.moveToFirst()) {
long childId;
boolean isDir;
- String remotePath;
+ //String remotePath;
while (!children.isAfterLast()) {
childId = children.getLong(children.getColumnIndex(ProviderTableMeta._ID));
isDir = "DIR".equals(children.getString(children.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)));
- remotePath = children.getString(children.getColumnIndex(ProviderTableMeta.FILE_PATH));
+ //remotePath = children.getString(children.getColumnIndex(ProviderTableMeta.FILE_PATH));
if (isDir) {
count += delete(db, ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_DIR, childId), null, null);
} else {
case ROOT_DIRECTORY:
break;
case DIRECTORY:
+ String folderId = uri.getPathSegments().get(1);
sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="
- + uri.getPathSegments().get(1));
+ + folderId);
break;
case SINGLE_FILE:
if (uri.getPathSegments().size() > 1) {
// 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;
private int update(SQLiteDatabase db, Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- return db.update(ProviderTableMeta.DB_NAME, values, selection, selectionArgs);
+ switch (mUriMatcher.match(uri)) {
+ case DIRECTORY:
+ return updateFolderSize(db, selectionArgs[0]);
+ default:
+ return db.update(ProviderTableMeta.DB_NAME, values, selection, selectionArgs);
+ }
}
+ 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();
+ }
+ ContentValues cv = new ContentValues();
+ cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, size);
+ count = db.update(ProviderTableMeta.DB_NAME, cv, updateWhere, whereArgs);
+ }
+ return count;
+ }
+
+
@Override
public ContentProviderResult[] applyBatch (ArrayList<ContentProviderOperation> operations) throws OperationApplicationException {
//Log.d(TAG, "applying batch in provider " + this + " (temporary: " + isTemporary() + ")" );
return results;
}
-
+
class DataBaseHelper extends SQLiteOpenHelper {
public DataBaseHelper(Context context) {
}
// synchronize children folders
List<OCFile> children = synchFolderOp.getChildren();
- fetchChildren(children); // beware of the 'hidden' recursion here!
-
- // update folder size again after recursive synchronization
- getStorageManager().calculateFolderSize(folder.getFileId());
- sendStickyBroadcast(true, folder.getRemotePath(), null); // notify again
+ fetchChildren(folder, children); // beware of the 'hidden' recursion here!
} else {
// in failures, the statistics for the global result are updated
*
* @param files Files to recursively synchronize.
*/
- private void fetchChildren(List<OCFile> files) {
+ private void fetchChildren(OCFile parent, List<OCFile> files) {
int i;
for (i=0; i < files.size() && !mCancellation; i++) {
OCFile newFile = files.get(i);
if (newFile.isFolder()) {
synchronizeFolder(newFile, false);
+ // update the size of the parent folder again after recursive synchronization
+ getStorageManager().updateFolderSize(parent.getFileId());
+ sendStickyBroadcast(true, parent.getRemotePath(), null); // notify again to refresh size in UI
}
}