speedup search

This commit is contained in:
tobiasKaminsky 2017-05-03 13:14:30 +02:00 committed by Mario Danic
parent 6c2d881dfe
commit 33ed0626ff
2 changed files with 97 additions and 60 deletions

View file

@ -1,21 +1,20 @@
/** /**
* ownCloud Android client application * ownCloud Android client application
* * <p>
* Copyright (C) 2012 Bartek Przybylski * Copyright (C) 2012 Bartek Przybylski
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2015 ownCloud Inc.
* * <p>
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, * it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation. * as published by the Free Software Foundation.
* * <p>
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* * <p>
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/ */
package com.owncloud.android.datamodel; package com.owncloud.android.datamodel;
@ -164,7 +163,7 @@ public class FileDataStorageManager {
// TODO better implementation, filtering in the access to database instead of here // TODO better implementation, filtering in the access to database instead of here
Vector<OCFile> tmp = getFolderContent(folder, onlyOnDevice); Vector<OCFile> tmp = getFolderContent(folder, onlyOnDevice);
OCFile current = null; OCFile current = null;
for (int i=0; i<tmp.size(); i++) { for (int i = 0; i < tmp.size(); i++) {
current = tmp.get(i); current = tmp.get(i);
if (MimeTypeUtil.isImage(current)) { if (MimeTypeUtil.isImage(current)) {
ret.add(current); ret.add(current);
@ -253,7 +252,7 @@ public class FileDataStorageManager {
public OCFile saveFileWithParent(OCFile file, Context context) { public OCFile saveFileWithParent(OCFile file, Context context) {
if (file.getParentId() != 0 || file.getRemotePath().equals("/")) { if (file.getParentId() != 0 || file.getRemotePath().equals("/")) {
saveFile(file); // nothing needed
} else { } else {
String remotePath = file.getRemotePath(); String remotePath = file.getRemotePath();
@ -313,7 +312,7 @@ public class FileDataStorageManager {
OCFile folder, Collection<OCFile> updatedFiles, Collection<OCFile> filesToRemove OCFile folder, Collection<OCFile> updatedFiles, Collection<OCFile> filesToRemove
) { ) {
Log_OC.d(TAG, "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size() Log_OC.d(TAG, "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size()
+ " children and " + filesToRemove.size() + " files to remove"); + " children and " + filesToRemove.size() + " files to remove");
ArrayList<ContentProviderOperation> operations = ArrayList<ContentProviderOperation> operations =
@ -371,7 +370,7 @@ public class FileDataStorageManager {
// prepare operations to remove files in the given folder // prepare operations to remove files in the given folder
String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND +
ProviderTableMeta.FILE_PATH + "=?"; ProviderTableMeta.FILE_PATH + "=?";
String [] whereArgs = null; String[] whereArgs = null;
for (OCFile file : filesToRemove) { for (OCFile file : filesToRemove) {
if (file.getParentId() == folder.getFileId()) { if (file.getParentId() == folder.getFileId()) {
whereArgs = new String[]{mAccount.name, file.getRemotePath()}; whereArgs = new String[]{mAccount.name, file.getRemotePath()};
@ -536,7 +535,7 @@ public class FileDataStorageManager {
Uri folder_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, "" + folder.getFileId()); // URI Uri folder_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, "" + folder.getFileId()); // URI
// for recursive deletion // for recursive deletion
String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH + "=?"; String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH + "=?";
String [] whereArgs = new String[]{mAccount.name, folder.getRemotePath()}; String[] whereArgs = new String[]{mAccount.name, folder.getRemotePath()};
int deleted = 0; int deleted = 0;
if (getContentProviderClient() != null) { if (getContentProviderClient() != null) {
try { try {
@ -830,9 +829,9 @@ public class FileDataStorageManager {
if (c != null && c.moveToFirst()) { if (c != null && c.moveToFirst()) {
do { do {
OCFile child = createFileInstance(c); OCFile child = createFileInstance(c);
if (child.isFolder() || !onlyOnDevice || child.isDown()) { if (child.isFolder() || !onlyOnDevice || child.isDown()) {
ret.add(child); ret.add(child);
} }
} while (c.moveToNext()); } while (c.moveToNext());
c.close(); c.close();
} }
@ -1024,7 +1023,7 @@ public class FileDataStorageManager {
* Retrieves an stored {@link OCShare} given its id. * Retrieves an stored {@link OCShare} given its id.
* *
* @param id Identifier. * @param id Identifier.
* @return Stored {@link OCShare} given its id. * @return Stored {@link OCShare} given its id.
*/ */
public OCShare getShareById(long id) { public OCShare getShareById(long id) {
OCShare share = null; OCShare share = null;
@ -1082,7 +1081,7 @@ public class FileDataStorageManager {
.query(ProviderTableMeta.CONTENT_URI_SHARE, .query(ProviderTableMeta.CONTENT_URI_SHARE,
null, null,
key + AND key + AND
+ ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?", + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?",
new String[]{value, mAccount.name}, new String[]{value, mAccount.name},
null null
); );
@ -1096,7 +1095,7 @@ public class FileDataStorageManager {
null null
); );
} catch (RemoteException e) { } catch (RemoteException e) {
Log_OC.w(TAG, "Could not get details, assuming share does not exist: "+ e.getMessage()); Log_OC.w(TAG, "Could not get details, assuming share does not exist: " + e.getMessage());
c = null; c = null;
} }
} }
@ -1104,14 +1103,13 @@ public class FileDataStorageManager {
} }
/** /**
* Get first share bound to a file with a known path and given {@link ShareType}. * Get first share bound to a file with a known path and given {@link ShareType}.
* *
* @param path Path of the file. * @param path Path of the file.
* @param type Type of the share to get * @param type Type of the share to get
* @param shareWith Target of the share. Ignored in type is {@link ShareType#PUBLIC_LINK} * @param shareWith Target of the share. Ignored in type is {@link ShareType#PUBLIC_LINK}
* @return First {@link OCShare} instance found in DB bound to the file in 'path' * @return First {@link OCShare} instance found in DB bound to the file in 'path'
*/ */
public OCShare getFirstShareByPathAndType(String path, ShareType type, String shareWith) { public OCShare getFirstShareByPathAndType(String path, ShareType type, String shareWith) {
Cursor cursor = null; Cursor cursor = null;
@ -1121,12 +1119,12 @@ public class FileDataStorageManager {
String selection = ProviderTableMeta.OCSHARES_PATH + AND String selection = ProviderTableMeta.OCSHARES_PATH + AND
+ ProviderTableMeta.OCSHARES_SHARE_TYPE + AND + ProviderTableMeta.OCSHARES_SHARE_TYPE + AND
+ ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" ; + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
if (!ShareType.PUBLIC_LINK.equals(type)) { if (!ShareType.PUBLIC_LINK.equals(type)) {
selection += " AND " + ProviderTableMeta.OCSHARES_SHARE_WITH + "=?"; selection += " AND " + ProviderTableMeta.OCSHARES_SHARE_WITH + "=?";
} }
String [] selectionArgs; String[] selectionArgs;
if (ShareType.PUBLIC_LINK.equals(type)) { if (ShareType.PUBLIC_LINK.equals(type)) {
selectionArgs = new String[]{ selectionArgs = new String[]{
path, path,
@ -1219,7 +1217,7 @@ public class FileDataStorageManager {
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, false); cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, false);
cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, ""); cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PARENT + "=?"; String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PARENT + "=?";
String [] whereArgs = new String[] { mAccount.name , String.valueOf(folder.getFileId()) }; String[] whereArgs = new String[]{mAccount.name, String.valueOf(folder.getFileId())};
if (getContentResolver() != null) { if (getContentResolver() != null) {
getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs); getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs);
@ -1233,13 +1231,13 @@ public class FileDataStorageManager {
} }
} }
private void resetShareFlagInAFile(String filePath){ private void resetShareFlagInAFile(String filePath) {
ContentValues cv = new ContentValues(); ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, false); cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, false);
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, false); cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, false);
cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, ""); cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH+ "=?"; String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH + "=?";
String [] whereArgs = new String[] { mAccount.name , filePath }; String[] whereArgs = new String[]{mAccount.name, filePath};
if (getContentResolver() != null) { if (getContentResolver() != null) {
getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs); getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs);
@ -1426,7 +1424,7 @@ public class FileDataStorageManager {
Uri share_uri = ProviderTableMeta.CONTENT_URI_SHARE; Uri share_uri = ProviderTableMeta.CONTENT_URI_SHARE;
String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + AND + String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + AND +
ProviderTableMeta._ID + "=?"; ProviderTableMeta._ID + "=?";
String [] whereArgs = new String[]{mAccount.name, Long.toString(share.getId())}; String[] whereArgs = new String[]{mAccount.name, Long.toString(share.getId())};
if (getContentProviderClient() != null) { if (getContentProviderClient() != null) {
try { try {
getContentProviderClient().delete(share_uri, where, whereArgs); getContentProviderClient().delete(share_uri, where, whereArgs);
@ -1443,16 +1441,16 @@ public class FileDataStorageManager {
// Reset flags & Remove shares for this files // Reset flags & Remove shares for this files
String filePath = ""; String filePath = "";
for (OCShare share: shares) { for (OCShare share : shares) {
if (filePath != share.getPath()){ if (filePath != share.getPath()) {
filePath = share.getPath(); filePath = share.getPath();
resetShareFlagInAFile(filePath); resetShareFlagInAFile(filePath);
operations = prepareRemoveSharesInFile(filePath, operations); operations = prepareRemoveSharesInFile(filePath, operations);
} }
} }
// Add operations to insert shares // Add operations to insert shares
operations = prepareInsertShares(shares, operations); operations = prepareInsertShares(shares, operations);
// apply operations in batch // apply operations in batch
if (operations.size() > 0) { if (operations.size() > 0) {
@ -1593,7 +1591,7 @@ public class FileDataStorageManager {
if (folder != null) { if (folder != null) {
String where = ProviderTableMeta.OCSHARES_PATH + AND String where = ProviderTableMeta.OCSHARES_PATH + AND
+ ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?"; + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
String [] whereArgs = new String[]{ "", mAccount.name }; String[] whereArgs = new String[]{"", mAccount.name};
Vector<OCFile> files = getFolderContent(folder, false); Vector<OCFile> files = getFolderContent(folder, false);
@ -1627,15 +1625,15 @@ public class FileDataStorageManager {
} }
public ArrayList<OCShare> getSharesWithForAFile(String filePath, String accountName){ public ArrayList<OCShare> getSharesWithForAFile(String filePath, String accountName) {
// Condition // Condition
String where = ProviderTableMeta.OCSHARES_PATH + AND String where = ProviderTableMeta.OCSHARES_PATH + AND
+ ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + AND + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + AND
+ " (" + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR " + " (" + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR "
+ ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR " + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR "
+ ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR " + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR "
+ ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? ) "; + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? ) ";
String [] whereArgs = new String[]{ filePath, accountName , String[] whereArgs = new String[]{filePath, accountName,
Integer.toString(ShareType.USER.getValue()), Integer.toString(ShareType.USER.getValue()),
Integer.toString(ShareType.GROUP.getValue()), Integer.toString(ShareType.GROUP.getValue()),
Integer.toString(ShareType.EMAIL.getValue()), Integer.toString(ShareType.EMAIL.getValue()),
@ -1734,7 +1732,7 @@ public class FileDataStorageManager {
ProviderTableMeta.CONTENT_URI_FILE, ProviderTableMeta.CONTENT_URI_FILE,
cv, cv,
ProviderTableMeta._ID + "=?", ProviderTableMeta._ID + "=?",
new String[] { String.valueOf(file.getFileId())} new String[]{String.valueOf(file.getFileId())}
); );
} else { } else {
try { try {
@ -1871,7 +1869,7 @@ public class FileDataStorageManager {
} }
public OCCapability saveCapabilities(OCCapability capability){ public OCCapability saveCapabilities(OCCapability capability) {
// Prepare capabilities data // Prepare capabilities data
ContentValues cv = new ContentValues(); ContentValues cv = new ContentValues();
@ -1958,7 +1956,7 @@ public class FileDataStorageManager {
return exists; return exists;
} }
private Cursor getCapabilityCursorForAccount(String accountName){ private Cursor getCapabilityCursorForAccount(String accountName) {
Cursor c = null; Cursor c = null;
if (getContentResolver() != null) { if (getContentResolver() != null) {
c = getContentResolver() c = getContentResolver()
@ -1981,7 +1979,8 @@ public class FileDataStorageManager {
return c; return c;
} }
public OCCapability getCapability(String accountName){
public OCCapability getCapability(String accountName) {
OCCapability capability = null; OCCapability capability = null;
Cursor c = getCapabilityCursorForAccount(accountName); Cursor c = getCapabilityCursorForAccount(accountName);
@ -2065,6 +2064,19 @@ public class FileDataStorageManager {
} }
} }
public void saveVirtuals(VirtualFolderType type, List<ContentValues> values) {
if (getContentResolver() != null) {
getContentResolver().bulkInsert(ProviderTableMeta.CONTENT_URI_VIRTUAL, values.toArray(new ContentValues[values.size()]));
} else {
try {
getContentProviderClient().bulkInsert(ProviderTableMeta.CONTENT_URI_VIRTUAL, values.toArray(new ContentValues[values.size()]));
} catch (RemoteException e) {
Log_OC.e(TAG, FAILED_TO_INSERT_MSG + e.getMessage(), e);
}
}
}
public void saveVirtual(VirtualFolderType type, OCFile file) { public void saveVirtual(VirtualFolderType type, OCFile file) {
ContentValues cv = new ContentValues(); ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.VIRTUAL_TYPE, type.toString()); cv.put(ProviderTableMeta.VIRTUAL_TYPE, type.toString());
@ -2112,7 +2124,7 @@ public class FileDataStorageManager {
if (c != null && c.moveToFirst()) { if (c != null && c.moveToFirst()) {
do { do {
OCFile child = createFileInstanceFromVirtual(c); OCFile child = createFileInstanceFromVirtual(c);
ocFiles.add(child); ocFiles.add(child);
} while (c.moveToNext()); } while (c.moveToNext());
c.close(); c.close();
} }

View file

@ -24,6 +24,7 @@ package com.owncloud.android.ui.adapter;
import android.accounts.Account; import android.accounts.Account;
import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
@ -48,6 +49,7 @@ import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.datamodel.ThumbnailsCacheManager; import com.owncloud.android.datamodel.ThumbnailsCacheManager;
import com.owncloud.android.datamodel.VirtualFolderType; import com.owncloud.android.datamodel.VirtualFolderType;
import com.owncloud.android.db.PreferenceManager; import com.owncloud.android.db.PreferenceManager;
import com.owncloud.android.db.ProviderMeta;
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@ -485,10 +487,14 @@ public class FileListListAdapter extends BaseAdapter {
public void setData(ArrayList<Object> objects, ExtendedListFragment.SearchType searchType) { public void setData(ArrayList<Object> objects, ExtendedListFragment.SearchType searchType) {
mFiles = new Vector<>(); mFiles = new Vector<>();
if (searchType.equals(ExtendedListFragment.SearchType.SHARED_FILTER)) {
parseShares(objects); // early exit
} else { if (objects.size() > 0) {
parseVirtuals(objects, searchType); if (searchType.equals(ExtendedListFragment.SearchType.SHARED_FILTER)) {
parseShares(objects);
} else {
parseVirtuals(objects, searchType);
}
} }
if (!searchType.equals(ExtendedListFragment.SearchType.PHOTO_SEARCH) && if (!searchType.equals(ExtendedListFragment.SearchType.PHOTO_SEARCH) &&
@ -558,14 +564,33 @@ public class FileListListAdapter extends BaseAdapter {
mStorageManager.deleteVirtuals(type); mStorageManager.deleteVirtuals(type);
ArrayList<ContentValues> contentValues = new ArrayList<>();
for (int i = 0; i < objects.size(); i++) { for (int i = 0; i < objects.size(); i++) {
OCFile ocFile = FileStorageUtils.fillOCFile((RemoteFile) objects.get(i)); OCFile ocFile;
searchForLocalFileInDefaultPath(ocFile);
ocFile = mStorageManager.saveFileWithParent(ocFile, mContext); // try to find it in database
mStorageManager.saveVirtual(type, ocFile); ocFile = mStorageManager.getFileByPath(((RemoteFile) objects.get(i)).getRemotePath());
if (ocFile == null) {
// new
ocFile = FileStorageUtils.fillOCFile((RemoteFile) objects.get(i));
searchForLocalFileInDefaultPath(ocFile);
ocFile = mStorageManager.saveFileWithParent(ocFile, mContext);
}
if (!onlyImages || MimeTypeUtil.isImage(ocFile)) {
mFiles.add(ocFile);
}
ContentValues cv = new ContentValues();
cv.put(ProviderMeta.ProviderTableMeta.VIRTUAL_TYPE, type.toString());
cv.put(ProviderMeta.ProviderTableMeta.VIRTUAL_OCFILE_ID, ocFile.getFileId());
contentValues.add(cv);
} }
mFiles.addAll(mStorageManager.getVirtualFolderContent(type, onlyImages)); mStorageManager.saveVirtuals(type, contentValues);
} }
/** /**