cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail());
cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
-
+ cv.put(ProviderTableMeta.FILE_IN_CONFLICT, file.isInConflict());
+
boolean sameRemotePath = fileExists(file.getRemotePath());
if (sameRemotePath || fileExists(file.getFileId())) { // for renamed files; no more delete and create
cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail());
cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
+ cv.put(ProviderTableMeta.FILE_IN_CONFLICT, file.isInConflict());
boolean existsByPath = fileExists(file.getRemotePath());
if (existsByPath || fileExists(file.getFileId())) {
c.getColumnIndex(ProviderTableMeta.FILE_UPDATE_THUMBNAIL)) == 1 ? true : false);
file.setDownloading(c.getInt(
c.getColumnIndex(ProviderTableMeta.FILE_IS_DOWNLOADING)) == 1 ? true : false);
-
+ file.setInConflict(c.getInt(
+ c.getColumnIndex(ProviderTableMeta.FILE_IN_CONFLICT)) == 1 ? true : false);
+
}
return file;
}
ProviderTableMeta.FILE_IS_DOWNLOADING,
file.isDownloading() ? 1 : 0
);
+ cv.put(
+ ProviderTableMeta.FILE_IN_CONFLICT,
+ file.isInConflict() ? 1 : 0
+ );
boolean existsByPath = fileExists(file.getRemotePath());
if (existsByPath || fileExists(file.getFileId())) {
}
+ public void saveConflict(long fileId, boolean inConflict) {
+ ContentValues cv = new ContentValues();
+ cv.put(ProviderTableMeta.FILE_IN_CONFLICT, inConflict);
+ if (getContentResolver() != null) {
+ getContentResolver().update(
+ ProviderTableMeta.CONTENT_URI_FILE,
+ cv,
+ ProviderTableMeta._ID + "=?",
+ new String[] { String.valueOf(fileId)}
+ );
+ } else {
+ try {
+ getContentProviderClient().update(
+ ProviderTableMeta.CONTENT_URI_FILE,
+ cv,
+ ProviderTableMeta._ID + "=?",
+ new String[]{String.valueOf(fileId)}
+ );
+ } catch (RemoteException e) {
+ Log_OC.e(TAG, "Failed saving conflict in database " + e.getMessage());
+ }
+ }
+ }
}
private boolean mIsDownloading;
+ private boolean mInConflict;
+
/**
* Create new {@link OCFile} with given path.
mPublicLink = source.readString();
mPermissions = source.readString();
mRemoteId = source.readString();
- mNeedsUpdateThumbnail = source.readInt() == 0;
- mIsDownloading = source.readInt() == 0;
+ mNeedsUpdateThumbnail = source.readInt() == 1;
+ mIsDownloading = source.readInt() == 1;
+ mInConflict = source.readInt() == 1;
}
dest.writeString(mRemoteId);
dest.writeInt(mNeedsUpdateThumbnail ? 1 : 0);
dest.writeInt(mIsDownloading ? 1 : 0);
+ dest.writeInt(mInConflict ? 1 : 0);
}
/**
mRemoteId = null;
mNeedsUpdateThumbnail = false;
mIsDownloading = false;
+ mInConflict = false;
}
/**
this.mIsDownloading = isDownloading;
}
- public boolean isSynchronizing() {
- // TODO real implementation
- return false;
+ public boolean isInConflict() {
+ return mInConflict;
}
+ public void setInConflict(boolean inConflict) {
+ mInConflict = inConflict;
+ }
}
public class ProviderMeta {\r
\r
public static final String DB_NAME = "filelist";\r
- public static final int DB_VERSION = 10;\r
+ public static final int DB_VERSION = 11;\r
\r
private ProviderMeta() {\r
}\r
public static final String FILE_REMOTE_ID = "remote_id";\r
public static final String FILE_UPDATE_THUMBNAIL = "update_thumbnail";\r
public static final String FILE_IS_DOWNLOADING= "is_downloading";\r
+ public static final String FILE_IN_CONFLICT = "in_conflict";\r
\r
public static final String FILE_DEFAULT_SORT_ORDER = FILE_NAME\r
+ " collate nocase asc";\r
\r
public static final String OCSHARES_DEFAULT_SORT_ORDER = OCSHARES_FILE_SOURCE \r
+ " collate nocase asc";\r
- \r
+\r
\r
}\r
}\r
}
// loop to update every child
- OCFile remoteFile = null, localFile = null;
+ OCFile remoteFile = null, localFile = null, updatedFile = null;
+ RemoteFile r;
for (int i=1; i<folderAndFiles.size(); i++) {
/// new OCFile instance with the data from the server
- remoteFile = FileStorageUtils.fillOCFile((RemoteFile) folderAndFiles.get(i));
- remoteFile.setParentId(mLocalFolder.getFileId());
+ r = (RemoteFile) folderAndFiles.get(i);
+ remoteFile = FileStorageUtils.fillOCFile(r);
+
+ /// new OCFile instance to merge fresh data from server with local state
+ updatedFile = FileStorageUtils.fillOCFile(r);
+ updatedFile.setParentId(mLocalFolder.getFileId());
/// retrieve local data for the read file
// localFile = mStorageManager.getFileByPath(remoteFile.getRemotePath());
localFile = localFilesMap.remove(remoteFile.getRemotePath());
- /// add to the remoteFile (the new one) data about LOCAL STATE (not existing in server)
- remoteFile.setLastSyncDateForProperties(mCurrentSyncTime);
+ /// add to updatedFile data about LOCAL STATE (not existing in server)
+ updatedFile.setLastSyncDateForProperties(mCurrentSyncTime);
if (localFile != null) {
- // some properties of local state are kept unmodified
- remoteFile.setFileId(localFile.getFileId());
- remoteFile.setFavorite(localFile.isFavorite());
- remoteFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
- remoteFile.setModificationTimestampAtLastSyncForData(
+ updatedFile.setFileId(localFile.getFileId());
+ updatedFile.setFavorite(localFile.isFavorite());
+ updatedFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
+ updatedFile.setModificationTimestampAtLastSyncForData(
localFile.getModificationTimestampAtLastSyncForData()
);
- remoteFile.setStoragePath(localFile.getStoragePath());
+ updatedFile.setStoragePath(localFile.getStoragePath());
// eTag will not be updated unless file CONTENTS are synchronized
- remoteFile.setEtag(localFile.getEtag());
- if (remoteFile.isFolder()) {
- remoteFile.setFileLength(localFile.getFileLength());
+ updatedFile.setEtag(localFile.getEtag());
+ if (updatedFile.isFolder()) {
+ updatedFile.setFileLength(localFile.getFileLength());
// TODO move operations about size of folders to FileContentProvider
} else if (mRemoteFolderChanged && remoteFile.isImage() &&
remoteFile.getModificationTimestamp() !=
localFile.getModificationTimestamp()) {
- remoteFile.setNeedsUpdateThumbnail(true);
+ updatedFile.setNeedsUpdateThumbnail(true);
Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
}
- remoteFile.setPublicLink(localFile.getPublicLink());
- remoteFile.setShareByLink(localFile.isShareByLink());
+ updatedFile.setPublicLink(localFile.getPublicLink());
+ updatedFile.setShareByLink(localFile.isShareByLink());
+ updatedFile.setInConflict(localFile.isInConflict());
} else {
// remote eTag will not be updated unless file CONTENTS are synchronized
- remoteFile.setEtag("");
+ updatedFile.setEtag("");
}
/// check and fix, if needed, local storage path
- FileStorageUtils.searchForLocalFileInDefaultPath(remoteFile, mAccount);
+ FileStorageUtils.searchForLocalFileInDefaultPath(updatedFile, mAccount);
/// prepare content synchronization for kept-in-sync files
- if (remoteFile.isFavorite()) {
+ if (updatedFile.isFavorite()) {
SynchronizeFileOperation operation = new SynchronizeFileOperation( localFile,
remoteFile,
mAccount,
mFilesToSyncContents.add(operation);
}
- updatedFiles.add(remoteFile);
+ updatedFiles.add(updatedFile);
}
// save updated contents in local database
mLocalFile.getLocalModificationTimestamp() > mLocalFile.getLastSyncDateForData()
);
- Log_OC.d(TAG, "TOKENs checked to SYNC " + mRemotePath );
- Log_OC.d(TAG, " server#modificationTimestamp " + mServerFile.getModificationTimestamp());
- Log_OC.d(TAG, " local#modificationTimestampAtLastSyncForData " + mServerFile.getModificationTimestampAtLastSyncForData());
- Log_OC.d(TAG, " local#modificationTimestamp " + mLocalFile.getLocalModificationTimestamp());
- Log_OC.d(TAG, " local#lastSyncDateForData " + mLocalFile.getLastSyncDateForData());
-
/// decide action to perform depending upon changes
//if (!mLocalFile.getEtag().isEmpty() && localChanged && serverChanged) {
if (localChanged && serverChanged) {
result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
+ getStorageManager().saveConflict(mLocalFile.getFileId(), true);
} else if (localChanged) {
if (mSyncFileContents && mAllowUploads) {
mServerFile.setLastSyncDateForData(mLocalFile.getLastSyncDateForData());
mServerFile.setStoragePath(mLocalFile.getStoragePath());
mServerFile.setParentId(mLocalFile.getParentId());
+ mServerFile.setEtag(mLocalFile.getEtag());
getStorageManager().saveFile(mServerFile);
}
}
// loop to synchronize every child
- OCFile remoteFile = null, localFile = null;
+ OCFile remoteFile = null, localFile = null, updatedFile = null;
+ RemoteFile r;
for (int i=1; i<folderAndFiles.size(); i++) {
/// new OCFile instance with the data from the server
- remoteFile = FileStorageUtils.fillOCFile((RemoteFile)folderAndFiles.get(i));
- remoteFile.setParentId(mLocalFolder.getFileId());
+ r = (RemoteFile) folderAndFiles.get(i);
+ remoteFile = FileStorageUtils.fillOCFile(r);
+
+ /// new OCFile instance to merge fresh data from server with local state
+ updatedFile = FileStorageUtils.fillOCFile(r);
+ updatedFile.setParentId(mLocalFolder.getFileId());
/// retrieve local data for the read file
// localFile = mStorageManager.getFileByPath(remoteFile.getRemotePath());
localFile = localFilesMap.remove(remoteFile.getRemotePath());
- /// add to the remoteFile (the new one) data about LOCAL STATE (not existing in server)
- remoteFile.setLastSyncDateForProperties(mCurrentSyncTime);
+ /// add to updatedFile data about LOCAL STATE (not existing in server)
+ updatedFile.setLastSyncDateForProperties(mCurrentSyncTime);
if (localFile != null) {
- // some properties of local state are kept unmodified
- remoteFile.setFileId(localFile.getFileId());
- remoteFile.setFavorite(localFile.isFavorite());
- remoteFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
- remoteFile.setModificationTimestampAtLastSyncForData(
+ updatedFile.setFileId(localFile.getFileId());
+ updatedFile.setFavorite(localFile.isFavorite());
+ updatedFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
+ updatedFile.setModificationTimestampAtLastSyncForData(
localFile.getModificationTimestampAtLastSyncForData()
);
- remoteFile.setStoragePath(localFile.getStoragePath());
- // eTag will not be updated unless contents are synchronized
- remoteFile.setEtag(localFile.getEtag());
- if (remoteFile.isFolder()) {
- remoteFile.setFileLength(localFile.getFileLength());
+ updatedFile.setStoragePath(localFile.getStoragePath());
+ // eTag will not be updated unless file CONTENTS are synchronized
+ updatedFile.setEtag(localFile.getEtag());
+ if (updatedFile.isFolder()) {
+ updatedFile.setFileLength(localFile.getFileLength());
// TODO move operations about size of folders to FileContentProvider
} else if (mRemoteFolderChanged && remoteFile.isImage() &&
remoteFile.getModificationTimestamp() !=
localFile.getModificationTimestamp()) {
- remoteFile.setNeedsUpdateThumbnail(true);
+ updatedFile.setNeedsUpdateThumbnail(true);
Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
}
- remoteFile.setPublicLink(localFile.getPublicLink());
- remoteFile.setShareByLink(localFile.isShareByLink());
+ updatedFile.setPublicLink(localFile.getPublicLink());
+ updatedFile.setShareByLink(localFile.isShareByLink());
+ updatedFile.setInConflict(localFile.isInConflict());
} else {
- // remote eTag will not be updated unless contents are synchronized
- remoteFile.setEtag("");
+ // remote eTag will not be updated unless file CONTENTS are synchronized
+ updatedFile.setEtag("");
}
/// check and fix, if needed, local storage path
- searchForLocalFileInDefaultPath(remoteFile);
+ searchForLocalFileInDefaultPath(updatedFile);
/// classify file to sync/download contents later
if (remoteFile.isFolder()) {
}
- updatedFiles.add(remoteFile);
+ updatedFiles.add(updatedFile);
}
// save updated contents in local database
/// this should result in direct upload of files that were locally modified
SynchronizeFileOperation operation = new SynchronizeFileOperation(
child,
- child, // cheating with the remote file to get an upadte to server; to refactor
+ (child.isInConflict() ? null : child),
mAccount,
true,
mContext
ProviderTableMeta.FILE_UPDATE_THUMBNAIL);
mFileProjectionMap.put(ProviderTableMeta.FILE_IS_DOWNLOADING,
ProviderTableMeta.FILE_IS_DOWNLOADING);
+ mFileProjectionMap.put(ProviderTableMeta.FILE_IN_CONFLICT,
+ ProviderTableMeta.FILE_IN_CONFLICT);
}
private static final int SINGLE_FILE = 1;
+ ProviderTableMeta.FILE_PERMISSIONS + " TEXT null,"
+ ProviderTableMeta.FILE_REMOTE_ID + " TEXT null,"
+ ProviderTableMeta.FILE_UPDATE_THUMBNAIL + " INTEGER," //boolean
- + ProviderTableMeta.FILE_IS_DOWNLOADING + " INTEGER);" //boolean
+ + ProviderTableMeta.FILE_IS_DOWNLOADING + " INTEGER," //boolean
+ + ProviderTableMeta.FILE_IN_CONFLICT + " INTEGER);" //boolean
);
// Create table ocshares
if (!upgraded)
Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
", newVersion == " + newVersion);
+
+ if (oldVersion < 11 && newVersion >= 11) {
+ Log_OC.i("SQL", "Entering in the #11 ADD in onUpgrade");
+ db.beginTransaction();
+ try {
+ db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
+ " ADD COLUMN " + ProviderTableMeta.FILE_IN_CONFLICT + " INTEGER " +
+ " DEFAULT 0");
+ upgraded = true;
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ }
+ if (!upgraded)
+ Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
+ ", newVersion == " + newVersion);
+
}
}
localStateView.setImageResource(R.drawable.uploading_file_indicator);\r
localStateView.setVisibility(View.VISIBLE);\r
\r
+ } else if (file.isInConflict()) { // conflict\r
+ localStateView.setImageResource(R.drawable.conflict_file_indicator);\r
+ localStateView.setVisibility(View.VISIBLE);\r
+\r
} else if (file.isDown()) {\r
localStateView.setImageResource(R.drawable.local_file_indicator);\r
localStateView.setVisibility(View.VISIBLE);\r