X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/9060663f66a4c518bd428d4d68e035b64e24c26c..bcc972d63d3ed1d76b51a8a03a27e809983dc756:/src/com/owncloud/android/providers/FileContentProvider.java?ds=inline diff --git a/src/com/owncloud/android/providers/FileContentProvider.java b/src/com/owncloud/android/providers/FileContentProvider.java index 8673d4f3..9e7cd3fd 100644 --- a/src/com/owncloud/android/providers/FileContentProvider.java +++ b/src/com/owncloud/android/providers/FileContentProvider.java @@ -21,9 +21,12 @@ package com.owncloud.android.providers; import java.util.ArrayList; import java.util.HashMap; -import com.owncloud.android.Log_OC; +import com.owncloud.android.R; +import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.db.ProviderMeta; import com.owncloud.android.db.ProviderMeta.ProviderTableMeta; +import com.owncloud.android.utils.Log_OC; + import android.content.ContentProvider; @@ -90,19 +93,9 @@ public class FileContentProvider extends ContentProvider { 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"; + private UriMatcher mUriMatcher; - 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); - } - @Override public int delete(Uri uri, String where, String[] whereArgs) { //Log_OC.d(TAG, "Deleting " + uri + " at provider " + this); @@ -234,14 +227,27 @@ public class FileContentProvider extends ContentProvider { throw new IllegalArgumentException("Unknown uri id: " + uri); } - long rowId = db.insert(ProviderTableMeta.DB_NAME, null, values); - if (rowId > 0) { - Uri insertedFileUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, rowId); - //Log_OC.d(TAG, "Inserted " + values.getAsString(ProviderTableMeta.FILE_PATH) + " at provider " + this); - return insertedFileUri; + String remotePath = values.getAsString(ProviderTableMeta.FILE_PATH); + String accountName = values.getAsString(ProviderTableMeta.FILE_ACCOUNT_OWNER); + String[] projection = new String[] {ProviderTableMeta._ID, ProviderTableMeta.FILE_PATH, ProviderTableMeta.FILE_ACCOUNT_OWNER }; + String where = ProviderTableMeta.FILE_PATH + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?"; + String[] whereArgs = new String[] {remotePath, accountName}; + Cursor doubleCheck = query(db, uri, projection, where, whereArgs, null); + if (doubleCheck == null || !doubleCheck.moveToFirst()) { // ugly patch; serious refactorization is needed to reduce work in FileDataStorageManager and bring it to FileContentProvider + long rowId = db.insert(ProviderTableMeta.DB_NAME, null, values); + if (rowId > 0) { + Uri insertedFileUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, rowId); + //Log_OC.d(TAG, "Inserted " + values.getAsString(ProviderTableMeta.FILE_PATH) + " at provider " + this); + return insertedFileUri; + } else { + //Log_OC.d(TAG, "Error while inserting " + values.getAsString(ProviderTableMeta.FILE_PATH) + " at provider " + this); + throw new SQLException("ERROR " + uri); + } } else { - //Log_OC.d(TAG, "Error while inserting " + values.getAsString(ProviderTableMeta.FILE_PATH) + " at provider " + this); - throw new SQLException("ERROR " + uri); + // file is already inserted; race condition, let's avoid a duplicated entry + Uri insertedFileUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, doubleCheck.getLong(doubleCheck.getColumnIndex(ProviderTableMeta._ID))); + doubleCheck.close(); + return insertedFileUri; } } @@ -249,6 +255,15 @@ public class FileContentProvider extends ContentProvider { @Override public boolean onCreate() { mDbHelper = new DataBaseHelper(getContext()); + + String authority = getContext().getResources().getString(R.string.authority); + mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); + mUriMatcher.addURI(authority, null, ROOT_DIRECTORY); + mUriMatcher.addURI(authority, "file/", SINGLE_FILE); + mUriMatcher.addURI(authority, "file/#", SINGLE_FILE); + mUriMatcher.addURI(authority, "dir/", DIRECTORY); + mUriMatcher.addURI(authority, "dir/#", DIRECTORY); + return true; } @@ -301,17 +316,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 +350,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 +402,7 @@ public class FileContentProvider extends ContentProvider { @Override public ContentProviderResult[] applyBatch (ArrayList 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 +417,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; }