|
@@ -1,22 +1,21 @@
|
|
/**
|
|
/**
|
|
- * Nextcloud Android client application
|
|
|
|
|
|
+ * Nextcloud Android client application
|
|
*
|
|
*
|
|
- * @author Andy Scherzinger
|
|
|
|
- * Copyright (C) 2016 Andy Scherzinger
|
|
|
|
- * Copyright (C) 2016 Nextcloud
|
|
|
|
- * <p>
|
|
|
|
- * This program is free software; you can redistribute it and/or
|
|
|
|
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
|
|
|
- * License as published by the Free Software Foundation; either
|
|
|
|
- * version 3 of the License, or any later version.
|
|
|
|
- * <p>
|
|
|
|
- * This program is distributed in the hope that it will be useful,
|
|
|
|
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
- * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
|
|
|
- * <p>
|
|
|
|
- * You should have received a copy of the GNU Affero General Public
|
|
|
|
- * License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
+ * Copyright (C) 2016 Andy Scherzinger
|
|
|
|
+ * Copyright (C) 2016 Nextcloud.
|
|
|
|
+ *
|
|
|
|
+ * This program is free software; you can redistribute it and/or
|
|
|
|
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
|
+ * version 3 of the License, or any later version.
|
|
|
|
+ *
|
|
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU Affero General Public
|
|
|
|
+ * License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
*/
|
|
package com.owncloud.android.datamodel;
|
|
package com.owncloud.android.datamodel;
|
|
|
|
|
|
@@ -29,14 +28,21 @@ import android.support.annotation.NonNull;
|
|
import com.owncloud.android.db.ProviderMeta;
|
|
import com.owncloud.android.db.ProviderMeta;
|
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
|
|
|
|
|
|
|
+import java.util.Observable;
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Database provider for handling the persistence aspects of synced folders.
|
|
* Database provider for handling the persistence aspects of synced folders.
|
|
*/
|
|
*/
|
|
-public class SyncedFolderProvider {
|
|
|
|
|
|
+public class SyncedFolderProvider extends Observable {
|
|
static private final String TAG = SyncedFolderProvider.class.getSimpleName();
|
|
static private final String TAG = SyncedFolderProvider.class.getSimpleName();
|
|
|
|
|
|
private ContentResolver mContentResolver;
|
|
private ContentResolver mContentResolver;
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * constructor.
|
|
|
|
+ *
|
|
|
|
+ * @param contentResolver the ContentResolver to work with.
|
|
|
|
+ */
|
|
public SyncedFolderProvider(ContentResolver contentResolver) {
|
|
public SyncedFolderProvider(ContentResolver contentResolver) {
|
|
if (contentResolver == null) {
|
|
if (contentResolver == null) {
|
|
throw new IllegalArgumentException("Cannot create an instance with a NULL contentResolver");
|
|
throw new IllegalArgumentException("Cannot create an instance with a NULL contentResolver");
|
|
@@ -58,6 +64,7 @@ public class SyncedFolderProvider {
|
|
Uri result = mContentResolver.insert(ProviderMeta.ProviderTableMeta.CONTENT_URI_SYNCED_FOLDERS, cv);
|
|
Uri result = mContentResolver.insert(ProviderMeta.ProviderTableMeta.CONTENT_URI_SYNCED_FOLDERS, cv);
|
|
|
|
|
|
if (result != null) {
|
|
if (result != null) {
|
|
|
|
+ notifyFolderSyncObservers();
|
|
return Long.parseLong(result.getPathSegments().get(1));
|
|
return Long.parseLong(result.getPathSegments().get(1));
|
|
} else {
|
|
} else {
|
|
Log_OC.e(TAG, "Failed to insert item " + syncedFolder.getLocalPath() + " into folder sync db.");
|
|
Log_OC.e(TAG, "Failed to insert item " + syncedFolder.getLocalPath() + " into folder sync db.");
|
|
@@ -65,29 +72,40 @@ public class SyncedFolderProvider {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * get all synced folder entries.
|
|
|
|
+ *
|
|
|
|
+ * @return all synced folder entries, empty if none have been found
|
|
|
|
+ */
|
|
public SyncedFolder[] getSyncedFolders() {
|
|
public SyncedFolder[] getSyncedFolders() {
|
|
- Cursor c = mContentResolver.query(
|
|
|
|
|
|
+ Cursor cursor = mContentResolver.query(
|
|
ProviderMeta.ProviderTableMeta.CONTENT_URI_SYNCED_FOLDERS,
|
|
ProviderMeta.ProviderTableMeta.CONTENT_URI_SYNCED_FOLDERS,
|
|
null,
|
|
null,
|
|
"1=1",
|
|
"1=1",
|
|
null,
|
|
null,
|
|
null
|
|
null
|
|
);
|
|
);
|
|
- SyncedFolder[] list = new SyncedFolder[c.getCount()];
|
|
|
|
- if (c.moveToFirst()) {
|
|
|
|
- do {
|
|
|
|
- SyncedFolder syncedFolder = createSyncedFolderFromCursor(c);
|
|
|
|
- if (syncedFolder == null) {
|
|
|
|
- Log_OC.e(TAG, "SyncedFolder could not be created from cursor");
|
|
|
|
- } else {
|
|
|
|
- list[c.getPosition()] = syncedFolder;
|
|
|
|
- }
|
|
|
|
- } while (c.moveToNext());
|
|
|
|
|
|
|
|
|
|
+ if (cursor != null) {
|
|
|
|
+ SyncedFolder[] list = new SyncedFolder[cursor.getCount()];
|
|
|
|
+ if (cursor.moveToFirst()) {
|
|
|
|
+ do {
|
|
|
|
+ SyncedFolder syncedFolder = createSyncedFolderFromCursor(cursor);
|
|
|
|
+ if (syncedFolder == null) {
|
|
|
|
+ Log_OC.e(TAG, "SyncedFolder could not be created from cursor");
|
|
|
|
+ } else {
|
|
|
|
+ list[cursor.getPosition()] = syncedFolder;
|
|
|
|
+ }
|
|
|
|
+ } while (cursor.moveToNext());
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ cursor.close();
|
|
|
|
+ return list;
|
|
|
|
+ } else {
|
|
|
|
+ Log_OC.e(TAG, "DB error creating read all cursor for synced folders.");
|
|
}
|
|
}
|
|
- c.close();
|
|
|
|
|
|
|
|
- return list;
|
|
|
|
|
|
+ return new SyncedFolder[0];
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -109,10 +127,7 @@ public class SyncedFolderProvider {
|
|
null
|
|
null
|
|
);
|
|
);
|
|
|
|
|
|
- if (cursor == null || cursor.getCount() != 1) {
|
|
|
|
- Log_OC.e(TAG, cursor.getCount() + " items for id=" + id + " available in UploadDb. Expected 1. Failed to " +
|
|
|
|
- "update upload db.");
|
|
|
|
- } else {
|
|
|
|
|
|
+ if (cursor != null && cursor.getCount() == 1) {
|
|
while (cursor.moveToNext()) {
|
|
while (cursor.moveToNext()) {
|
|
// read sync folder object and update
|
|
// read sync folder object and update
|
|
SyncedFolder syncedFolder = createSyncedFolderFromCursor(cursor);
|
|
SyncedFolder syncedFolder = createSyncedFolderFromCursor(cursor);
|
|
@@ -121,13 +136,29 @@ public class SyncedFolderProvider {
|
|
|
|
|
|
// update sync folder object in db
|
|
// update sync folder object in db
|
|
result = updateSyncFolder(syncedFolder);
|
|
result = updateSyncFolder(syncedFolder);
|
|
|
|
+
|
|
|
|
+ cursor.close();
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if (cursor == null) {
|
|
|
|
+ Log_OC.e(TAG, "Sync folder db cursor for ID=" + id + " in NULL.");
|
|
|
|
+ } else {
|
|
|
|
+ Log_OC.e(TAG, cursor.getCount() + " items for id=" + id + " available in sync folder database. " +
|
|
|
|
+ "Expected 1. Failed to update sync folder db.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- cursor.close();
|
|
|
|
|
|
+
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * find a synced folder by local path.
|
|
|
|
+ *
|
|
|
|
+ * @param localPath the local path of the local folder
|
|
|
|
+ * @return the synced folder if found, else null
|
|
|
|
+ */
|
|
public SyncedFolder findByLocalPath(String localPath) {
|
|
public SyncedFolder findByLocalPath(String localPath) {
|
|
|
|
+ SyncedFolder result = null;
|
|
Cursor cursor = mContentResolver.query(
|
|
Cursor cursor = mContentResolver.query(
|
|
ProviderMeta.ProviderTableMeta.CONTENT_URI_SYNCED_FOLDERS,
|
|
ProviderMeta.ProviderTableMeta.CONTENT_URI_SYNCED_FOLDERS,
|
|
null,
|
|
null,
|
|
@@ -136,28 +167,53 @@ public class SyncedFolderProvider {
|
|
null
|
|
null
|
|
);
|
|
);
|
|
|
|
|
|
- if (cursor == null || cursor.getCount() != 1) {
|
|
|
|
- Log_OC.e(TAG, cursor.getCount() + " items for local path=" + localPath + " available in sync folder db. " +
|
|
|
|
- "Expected 1. Failed to update sync folder db.");
|
|
|
|
- return null;
|
|
|
|
|
|
+ if (cursor != null && cursor.getCount() == 1) {
|
|
|
|
+ result = createSyncedFolderFromCursor(cursor);
|
|
|
|
+ cursor.close();
|
|
} else {
|
|
} else {
|
|
- return createSyncedFolderFromCursor(cursor);
|
|
|
|
|
|
+ if (cursor == null) {
|
|
|
|
+ Log_OC.e(TAG, "Sync folder db cursor for local path=" + localPath + " in NULL.");
|
|
|
|
+ } else {
|
|
|
|
+ Log_OC.e(TAG, cursor.getCount() + " items for local path=" + localPath
|
|
|
|
+ + " available in sync folder db. Expected 1. Failed to update sync folder db.");
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ return result;
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * update given synced folder.
|
|
|
|
+ *
|
|
|
|
+ * @param syncedFolder the synced folder to be updated.
|
|
|
|
+ * @return the number of rows updated.
|
|
|
|
+ */
|
|
private int updateSyncFolder(SyncedFolder syncedFolder) {
|
|
private int updateSyncFolder(SyncedFolder syncedFolder) {
|
|
Log_OC.v(TAG, "Updating " + syncedFolder.getLocalPath() + " with enabled=" + syncedFolder.isEnabled());
|
|
Log_OC.v(TAG, "Updating " + syncedFolder.getLocalPath() + " with enabled=" + syncedFolder.isEnabled());
|
|
|
|
|
|
ContentValues cv = createContentValuesFromSyncedFolder(syncedFolder);
|
|
ContentValues cv = createContentValuesFromSyncedFolder(syncedFolder);
|
|
|
|
|
|
- return mContentResolver.update(
|
|
|
|
|
|
+ int result = mContentResolver.update(
|
|
ProviderMeta.ProviderTableMeta.CONTENT_URI_UPLOADS,
|
|
ProviderMeta.ProviderTableMeta.CONTENT_URI_UPLOADS,
|
|
cv,
|
|
cv,
|
|
ProviderMeta.ProviderTableMeta._ID + "=?",
|
|
ProviderMeta.ProviderTableMeta._ID + "=?",
|
|
new String[]{String.valueOf(syncedFolder.getId())}
|
|
new String[]{String.valueOf(syncedFolder.getId())}
|
|
);
|
|
);
|
|
|
|
+
|
|
|
|
+ if (result > 0) {
|
|
|
|
+ notifyFolderSyncObservers();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return result;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * maps a cursor into a SyncedFolder object.
|
|
|
|
+ *
|
|
|
|
+ * @param cursor the cursor
|
|
|
|
+ * @return the mapped SyncedFolder, null if cursor is null
|
|
|
|
+ */
|
|
private SyncedFolder createSyncedFolderFromCursor(Cursor cursor) {
|
|
private SyncedFolder createSyncedFolderFromCursor(Cursor cursor) {
|
|
SyncedFolder syncedFolder = null;
|
|
SyncedFolder syncedFolder = null;
|
|
if (cursor != null) {
|
|
if (cursor != null) {
|
|
@@ -177,6 +233,12 @@ public class SyncedFolderProvider {
|
|
return syncedFolder;
|
|
return syncedFolder;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * create ContentValues object based on given SyncedFolder.
|
|
|
|
+ *
|
|
|
|
+ * @param syncedFolder the synced folder
|
|
|
|
+ * @return the corresponding ContentValues object
|
|
|
|
+ */
|
|
@NonNull
|
|
@NonNull
|
|
private ContentValues createContentValuesFromSyncedFolder(SyncedFolder syncedFolder) {
|
|
private ContentValues createContentValuesFromSyncedFolder(SyncedFolder syncedFolder) {
|
|
ContentValues cv = new ContentValues();
|
|
ContentValues cv = new ContentValues();
|
|
@@ -190,4 +252,13 @@ public class SyncedFolderProvider {
|
|
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_UPLOAD_ACTION, syncedFolder.getUploadAction());
|
|
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_UPLOAD_ACTION, syncedFolder.getUploadAction());
|
|
return cv;
|
|
return cv;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Inform all observers about data change.
|
|
|
|
+ */
|
|
|
|
+ private void notifyFolderSyncObservers() {
|
|
|
|
+ Log_OC.d(TAG, "notifying folder sync data observers");
|
|
|
|
+ setChanged();
|
|
|
|
+ notifyObservers();
|
|
|
|
+ }
|
|
}
|
|
}
|