Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New arch] Migrate OCUpload to new database #3710

Merged
merged 38 commits into from
Jul 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b0eb4a4
Created new TransferStatus in domain layer
JuancaG05 Jul 5, 2022
3de8f7e
Created TransferResult in domain layer
JuancaG05 Jul 5, 2022
a19b4b4
Created OCTransfer in domain layer
JuancaG05 Jul 5, 2022
fad99d3
Created TransferRepository interface in domain layer
JuancaG05 Jul 6, 2022
6ba77ae
Created OCTransferEntity in data layer
JuancaG05 Jul 6, 2022
76cff8c
Created TransferDao in data layer
JuancaG05 Jul 6, 2022
c461441
Removed unnecessary methods from TransferRepository
JuancaG05 Jul 7, 2022
0d3eafa
Fix a method of TransferDao
JuancaG05 Jul 7, 2022
b2e35dc
Updated Room database with new table "transfers"
JuancaG05 Jul 7, 2022
2fc0267
Created LocalTransferDataSource interface in data layer
JuancaG05 Jul 7, 2022
3dae2ce
Changed some methods of Repository and LocalDataSource interfaces
JuancaG05 Jul 8, 2022
9bfd9e5
Created LocalTransferDataSource implementation in data layer and adde…
JuancaG05 Jul 8, 2022
1917a19
Created OCTransferRepository implementation in data layer and fixed s…
JuancaG05 Jul 8, 2022
ed91c1c
Added necessary dependency injection
JuancaG05 Jul 11, 2022
99cfc5f
Deprecate old OCUpload datamodel
JuancaG05 Jul 11, 2022
16c79f0
Move UploadFilesFromSAFUseCase to new arch
JuancaG05 Jul 12, 2022
aaf91ab
Move UploadFileFromContentUriWorker to new arch
JuancaG05 Jul 12, 2022
ebfa59b
Fix mistake in TransferDao
JuancaG05 Jul 12, 2022
f96ba9b
Move UploadFileFromFileSystemWorker to new arch
JuancaG05 Jul 12, 2022
960bc62
Move UploadFilesFromSystemUseCase to new arch
JuancaG05 Jul 12, 2022
574f772
Move CameraUploadsWorker to new arch
JuancaG05 Jul 13, 2022
8d504b1
Adapted every use of UploadFilesFromSystemUseCase to new arch
JuancaG05 Jul 13, 2022
d023eda
Changed main execution of UploadFilesFromSystemUseCase to IO thread
JuancaG05 Jul 13, 2022
6a54f94
Move UploadFileInConflictUseCase to new arch
JuancaG05 Jul 13, 2022
83d1b3a
Move RetryUploadFromSystemUseCase to new arch
JuancaG05 Jul 13, 2022
3b842dd
Move RetryUploadFromContentUriUseCase to new arch
JuancaG05 Jul 13, 2022
3d7bc4b
Move RetryFailedUploadsUseCase to new arch
JuancaG05 Jul 14, 2022
40577d0
Removed unused imports
JuancaG05 Jul 14, 2022
34ba67d
Move RetryFailedUploadsForAccountUseCase to new arch
JuancaG05 Jul 14, 2022
439f743
Move CancelUploadWithIdUseCase to new arch
JuancaG05 Jul 14, 2022
e40d536
Move CancelUploadsFromAccountUseCase to new arch
JuancaG05 Jul 14, 2022
b36cc05
Move CancelUploadForFileUseCase to new arch
JuancaG05 Jul 14, 2022
de04b77
Clear old UploadsStorageManager code
JuancaG05 Jul 14, 2022
dde2063
CR changes applied
JuancaG05 Jul 15, 2022
86bc0c4
Fixed Ktlint errors
JuancaG05 Jul 15, 2022
ac578a7
Fixed some other Ktlint errors
JuancaG05 Jul 15, 2022
7fb840d
Fixed more Ktlint errors
JuancaG05 Jul 15, 2022
e943e8e
Improvements on RetryUploadFromContentUriUseCase
JuancaG05 Jul 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

import java.io.File;

@Deprecated
/**
* Stores all information in order to start upload operations. PersistentUploadObject can
* be stored persistently by {@link UploadsStorageManager}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,42 +94,6 @@ public UploadsStorageManager(ContentResolver contentResolver) {
mContentResolver = contentResolver;
}

/**
* Stores an upload object in DB.
*
* @param ocUpload Upload object to store
* @return upload id, -1 if the insert process fails.
*/
public long storeUpload(OCUpload ocUpload) {
Timber.v("Inserting " + ocUpload.getLocalPath() + " with status=" + ocUpload.getUploadStatus());

ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.UPLOADS_LOCAL_PATH, ocUpload.getLocalPath());
cv.put(ProviderTableMeta.UPLOADS_REMOTE_PATH, ocUpload.getRemotePath());
cv.put(ProviderTableMeta.UPLOADS_ACCOUNT_NAME, ocUpload.getAccountName());
cv.put(ProviderTableMeta.UPLOADS_FILE_SIZE, ocUpload.getFileSize());
cv.put(ProviderTableMeta.UPLOADS_STATUS, ocUpload.getUploadStatus().value);
cv.put(ProviderTableMeta.UPLOADS_LOCAL_BEHAVIOUR, ocUpload.getLocalAction());
cv.put(ProviderTableMeta.UPLOADS_FORCE_OVERWRITE, ocUpload.isForceOverwrite() ? 1 : 0);
cv.put(ProviderTableMeta.UPLOADS_IS_CREATE_REMOTE_FOLDER, ocUpload.createsRemoteFolder() ? 1 : 0);
cv.put(ProviderTableMeta.UPLOADS_LAST_RESULT, ocUpload.getLastResult().getValue());
cv.put(ProviderTableMeta.UPLOADS_CREATED_BY, ocUpload.getCreatedBy());
cv.put(ProviderTableMeta.UPLOADS_TRANSFER_ID, ocUpload.getTransferId());

Uri result = getDB().insert(ProviderTableMeta.CONTENT_URI_UPLOADS, cv);

Timber.d("storeUpload returns with: " + result + " for file: " + ocUpload.getLocalPath());
if (result == null) {
Timber.e("Failed to insert item " + ocUpload.getLocalPath() + " into upload db.");
return -1;
} else {
long new_id = Long.parseLong(result.getPathSegments().get(1));
ocUpload.setUploadId(new_id);
notifyObserversNow();
return new_id;
}
}

/**
* Update an upload object in DB.
*
Expand Down Expand Up @@ -164,63 +128,6 @@ public int updateUpload(OCUpload ocUpload) {
return result;
}

private int updateUploadInternal(Cursor c, UploadStatus status, UploadResult result, String remotePath,
String localPath) {
int r = 0;
while (c.moveToNext()) {
// read upload object and update
OCUpload upload = createOCUploadFromCursor(c);

String path = getStringFromColumnOrThrow(c, ProviderTableMeta.UPLOADS_LOCAL_PATH);
Timber.v("Updating " + path + " with status:" + status + " and result:" + (result == null ? "null" :
result.toString()) + " (old:" + upload.toFormattedString() + ")");

upload.setUploadStatus(status);
upload.setLastResult(result);
upload.setRemotePath(remotePath);
if (localPath != null) {
upload.setLocalPath(localPath);
}
upload.setUploadEndTimestamp(Calendar.getInstance().getTimeInMillis());

// store update upload object to db
r = updateUpload(upload);
}

return r;
}

/**
* Update upload status of file uniquely referenced by id.
*
* @param id upload id.
* @param status new status.
* @param result new result of upload operation
* @param remotePath path of the file to upload in the ownCloud storage
* @param localPath path of the file to upload in the device storage
* @return 1 if file status was updated, else 0.
*/
public int updateUploadStatus(long id, UploadStatus status, UploadResult result, String remotePath,
String localPath) {
int returnValue = 0;
Cursor c = getDB().query(
ProviderTableMeta.CONTENT_URI_UPLOADS,
null,
ProviderTableMeta._ID + "=?",
new String[]{String.valueOf(id)},
null
);

if (c.getCount() != 1) {
Timber.e(c.getCount() + " items for id=" + id
+ " available in UploadDb. Expected 1. Failed to update upload db.");
} else {
returnValue = updateUploadInternal(c, status, result, remotePath, localPath);
}
c.close();
return returnValue;
}

/**
* Should be called when some value of this DB was changed. All observers
* are informed.
Expand All @@ -231,64 +138,6 @@ public void notifyObserversNow() {
notifyObservers();
}

/**
* Remove an upload from the uploads list, known its target account and remote path.
*
* @param upload Upload instance to remove from persisted storage.
* @return true when the upload was stored and could be removed.
*/
public int removeUpload(OCUpload upload) {
int result = getDB().delete(
ProviderTableMeta.CONTENT_URI_UPLOADS,
ProviderTableMeta._ID + "=?",
new String[]{Long.toString(upload.getUploadId())}
);
Timber.d("delete returns " + result + " for upload " + upload);
if (result > 0) {
notifyObserversNow();
}
return result;
}

/**
* Remove an upload from the uploads list, known its target account and remote path.
*
* @param accountName Name of the OC account target of the upload to remove.
* @param remotePath Absolute path in the OC account target of the upload to remove.
* @return true when one or more upload entries were removed
*/
public int removeUpload(String accountName, String remotePath) {
int result = getDB().delete(
ProviderTableMeta.CONTENT_URI_UPLOADS,
ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "=? AND " + ProviderTableMeta.UPLOADS_REMOTE_PATH + "=?",
new String[]{accountName, remotePath}
);
Timber.d("delete returns " + result + " for file " + remotePath + " in " + accountName);
if (result > 0) {
notifyObserversNow();
}
return result;
}

/**
* Remove all the uploads of a given account from the uploads list.
*
* @param accountName Name of the OC account target of the uploads to remove.
* @return true when one or more upload entries were removed
*/
public int removeUploads(String accountName) {
int result = getDB().delete(
ProviderTableMeta.CONTENT_URI_UPLOADS,
ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "=?",
new String[]{accountName}
);
Timber.d("delete returns " + result + " for uploads in " + accountName);
if (result > 0) {
notifyObserversNow();
}
return result;
}

public OCUpload[] getAllStoredUploads() {
return getUploads(null, null, null);
}
Expand Down Expand Up @@ -368,19 +217,6 @@ public OCUpload[] getCurrentAndPendingUploads() {
);
}

/**
* Get all failed uploads.
*/
public OCUpload[] getFailedUploads() {
return getUploads(
ProviderTableMeta.UPLOADS_STATUS + "== ?",
new String[]{
String.valueOf(UploadStatus.UPLOAD_FAILED.value)
},
null
);
}

/**
* Get all uploads which where successfully completed.
*/
Expand Down Expand Up @@ -442,37 +278,4 @@ public long clearSuccessfulUploads() {
}
return result;
}

/**
* Changes the status of any in progress upload from UploadStatus.UPLOAD_IN_PROGRESS
* to UploadStatus.UPLOAD_FAILED
*
* @return Number of uploads which status was changed.
*/
public int failInProgressUploads(UploadResult uploadResult) {
Timber.v("Updating state of any killed upload");

ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.UPLOADS_STATUS, UploadStatus.UPLOAD_FAILED.getValue());
cv.put(
ProviderTableMeta.UPLOADS_LAST_RESULT,
uploadResult != null ? uploadResult.getValue() : UploadResult.UNKNOWN.getValue()
);
cv.put(ProviderTableMeta.UPLOADS_UPLOAD_END_TIMESTAMP, Calendar.getInstance().getTimeInMillis());

int result = getDB().update(
ProviderTableMeta.CONTENT_URI_UPLOADS,
cv,
ProviderTableMeta.UPLOADS_STATUS + "=?",
new String[]{String.valueOf(UploadStatus.UPLOAD_IN_PROGRESS.getValue())}
);

if (result == 0) {
Timber.v("No upload was killed");
} else {
Timber.w("%s uploads where abruptly interrupted", result);
notifyObserversNow();
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
*
* @author David González Verdugo
* @author Abel García de Prada
* Copyright (C) 2021 ownCloud GmbH.
* @author Juan Carlos Garrote Gascón
*
* Copyright (C) 2022 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
Expand All @@ -26,18 +28,20 @@ import com.owncloud.android.MainApp.Companion.dataFolder
import com.owncloud.android.data.OwncloudDatabase
import com.owncloud.android.data.authentication.datasources.LocalAuthenticationDataSource
import com.owncloud.android.data.authentication.datasources.implementation.OCLocalAuthenticationDataSource
import com.owncloud.android.data.folderbackup.datasources.FolderBackupLocalDataSource
import com.owncloud.android.data.folderbackup.datasources.implementation.FolderBackupLocalDataSourceImpl
import com.owncloud.android.data.capabilities.datasources.LocalCapabilitiesDataSource
import com.owncloud.android.data.capabilities.datasources.implementation.OCLocalCapabilitiesDataSource
import com.owncloud.android.data.files.datasources.LocalFileDataSource
import com.owncloud.android.data.files.datasources.implementation.OCLocalFileDataSource
import com.owncloud.android.data.folderbackup.datasources.FolderBackupLocalDataSource
import com.owncloud.android.data.folderbackup.datasources.implementation.FolderBackupLocalDataSourceImpl
import com.owncloud.android.data.preferences.datasources.SharedPreferencesProvider
import com.owncloud.android.data.preferences.datasources.implementation.SharedPreferencesProviderImpl
import com.owncloud.android.data.sharing.shares.datasources.LocalShareDataSource
import com.owncloud.android.data.sharing.shares.datasources.implementation.OCLocalShareDataSource
import com.owncloud.android.data.storage.LocalStorageProvider
import com.owncloud.android.data.storage.ScopedStorageProvider
import com.owncloud.android.data.transfers.datasources.LocalTransferDataSource
import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource
import com.owncloud.android.data.user.datasources.LocalUserDataSource
import com.owncloud.android.data.user.datasources.implementation.OCLocalUserDataSource
import org.koin.android.ext.koin.androidContext
Expand All @@ -51,6 +55,7 @@ val localDataSourceModule = module {
single { OwncloudDatabase.getDatabase(androidContext()).shareDao() }
single { OwncloudDatabase.getDatabase(androidContext()).userDao() }
single { OwncloudDatabase.getDatabase(androidContext()).folderBackUpDao() }
single { OwncloudDatabase.getDatabase(androidContext()).transferDao() }

single<SharedPreferencesProvider> { SharedPreferencesProviderImpl(get()) }
single<LocalStorageProvider> { ScopedStorageProvider(dataFolder, androidContext()) }
Expand All @@ -61,4 +66,5 @@ val localDataSourceModule = module {
factory<LocalShareDataSource> { OCLocalShareDataSource(get()) }
factory<LocalUserDataSource> { OCLocalUserDataSource(get()) }
factory<FolderBackupLocalDataSource> { FolderBackupLocalDataSourceImpl(get()) }
factory<LocalTransferDataSource> { OCLocalTransferDataSource(get()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
* ownCloud Android client application
*
* @author David González Verdugo
* Copyright (C) 2020 ownCloud GmbH.
* @author Abel García de Prada
* @author Juan Carlos Garrote Gascón
*
* Copyright (C) 2022 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
Expand All @@ -27,6 +30,7 @@ import com.owncloud.android.data.oauth.OAuthRepositoryImpl
import com.owncloud.android.data.server.repository.OCServerInfoRepository
import com.owncloud.android.data.sharing.sharees.repository.OCShareeRepository
import com.owncloud.android.data.sharing.shares.repository.OCShareRepository
import com.owncloud.android.data.transfers.repository.OCTransferRepository
import com.owncloud.android.data.user.repository.OCUserRepository
import com.owncloud.android.domain.authentication.AuthenticationRepository
import com.owncloud.android.domain.authentication.oauth.OAuthRepository
Expand All @@ -36,6 +40,7 @@ import com.owncloud.android.domain.files.FileRepository
import com.owncloud.android.domain.server.ServerInfoRepository
import com.owncloud.android.domain.sharing.sharees.ShareeRepository
import com.owncloud.android.domain.sharing.shares.ShareRepository
import com.owncloud.android.domain.transfers.TransferRepository
import com.owncloud.android.domain.user.UserRepository
import org.koin.dsl.module

Expand All @@ -49,4 +54,5 @@ val repositoryModule = module {
factory<UserRepository> { OCUserRepository(get(), get()) }
factory<OAuthRepository> { OAuthRepositoryImpl(get()) }
factory<FolderBackupRepository> { FolderBackupRepositoryImpl(get()) }
factory<TransferRepository> { OCTransferRepository(get()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
* ownCloud Android client application
*
* @author David González Verdugo
* Copyright (C) 2020 ownCloud GmbH.
* @author Abel García de Prada
* @author Juan Carlos Garrote Gascón
*
* Copyright (C) 2022 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
Expand Down Expand Up @@ -73,6 +76,7 @@ import com.owncloud.android.usecases.transfers.downloads.DownloadFileUseCase
import com.owncloud.android.usecases.transfers.downloads.GetLiveDataForDownloadingFileUseCase
import com.owncloud.android.usecases.transfers.downloads.GetLiveDataForFinishedDownloadsFromAccountUseCase
import com.owncloud.android.usecases.transfers.uploads.CancelUploadForFileUseCase
import com.owncloud.android.usecases.transfers.uploads.RetryUploadFromSystemUseCase
import com.owncloud.android.usecases.transfers.uploads.UploadFileInConflictUseCase
import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSAFUseCase
import com.owncloud.android.usecases.transfers.uploads.UploadFilesFromSystemUseCase
Expand Down Expand Up @@ -131,10 +135,11 @@ val useCaseModule = module {
factory { DownloadFileUseCase(get()) }
factory { GetLiveDataForDownloadingFileUseCase(get()) }
factory { GetLiveDataForFinishedDownloadsFromAccountUseCase(get()) }
factory { UploadFilesFromSAFUseCase(get()) }
factory { UploadFilesFromSystemUseCase(get()) }
factory { UploadFileInConflictUseCase(get()) }
factory { CancelUploadForFileUseCase(get()) }
factory { UploadFilesFromSAFUseCase(get(), get()) }
factory { UploadFilesFromSystemUseCase(get(), get()) }
factory { UploadFileInConflictUseCase(get(), get()) }
factory { CancelUploadForFileUseCase(get(), get()) }
factory { RetryUploadFromSystemUseCase(get(), get()) }

// User
factory { GetStoredQuotaUseCase(get()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import com.owncloud.android.presentation.viewmodels.settings.SettingsSecurityVie
import com.owncloud.android.presentation.viewmodels.settings.SettingsVideoUploadsViewModel
import com.owncloud.android.presentation.viewmodels.settings.SettingsViewModel
import com.owncloud.android.presentation.viewmodels.sharing.OCShareViewModel
import com.owncloud.android.presentation.viewmodels.transfers.TransfersViewModel
import com.owncloud.android.ui.dialog.RemoveAccountDialogViewModel
import com.owncloud.android.ui.preview.PreviewImageViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
Expand Down Expand Up @@ -87,4 +88,5 @@ val viewModelModule = module {
viewModel { FileDetailsViewModel(get(), get(), get(), get(), get()) }
viewModel { FileOperationsViewModel(get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { MainFileListViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { TransfersViewModel(get(), get(), get()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
import android.content.Context;

import androidx.work.WorkManager;
import com.owncloud.android.data.OwncloudDatabase;
import com.owncloud.android.data.transfers.datasources.implementation.OCLocalTransferDataSource;
import com.owncloud.android.data.transfers.repository.OCTransferRepository;
import com.owncloud.android.domain.files.model.OCFile;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
Expand Down Expand Up @@ -229,7 +232,9 @@ protected RemoteOperationResult run(OwnCloudClient client) {
*/
private void requestForUpload(OCFile file) {
WorkManager workManager = WorkManager.getInstance(mContext);
UploadFileInConflictUseCase uploadFileInConflictUseCase = new UploadFileInConflictUseCase(workManager);
// Workaround... should be removed as soon as possible
OCTransferRepository transferRepository = new OCTransferRepository(new OCLocalTransferDataSource(OwncloudDatabase.Companion.getDatabase(mContext).transferDao()));
UploadFileInConflictUseCase uploadFileInConflictUseCase = new UploadFileInConflictUseCase(workManager, transferRepository);
UploadFileInConflictUseCase.Params params = new UploadFileInConflictUseCase.Params(
file.getOwner(),
file.getStoragePath(),
Expand Down
Loading