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] Create folder #2923

Merged
merged 7 commits into from
Aug 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -26,7 +26,8 @@ import com.owncloud.android.domain.authentication.usecases.SupportsOAuth2UseCase
import com.owncloud.android.domain.capabilities.usecases.GetCapabilitiesAsLiveDataUseCase
import com.owncloud.android.domain.capabilities.usecases.GetStoredCapabilitiesUseCase
import com.owncloud.android.domain.capabilities.usecases.RefreshCapabilitiesFromServerAsyncUseCase
import com.owncloud.android.domain.files.RefreshFolderFromServerAsyncUseCase
import com.owncloud.android.domain.files.usecases.CreateFolderAsyncUseCase
import com.owncloud.android.domain.files.usecases.RefreshFolderFromServerAsyncUseCase
import com.owncloud.android.domain.server.usecases.GetServerInfoAsyncUseCase
import com.owncloud.android.domain.sharing.sharees.GetShareesAsyncUseCase
import com.owncloud.android.domain.sharing.shares.usecases.CreatePrivateShareAsyncUseCase
Expand Down Expand Up @@ -56,6 +57,7 @@ val useCaseModule = module {
factory { RefreshCapabilitiesFromServerAsyncUseCase(get()) }

// Files
factory { CreateFolderAsyncUseCase(get()) }
factory { RefreshFolderFromServerAsyncUseCase(get()) }

// Sharing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,29 @@

import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.resources.files.chunks.CreateRemoteChunkFolderOperation;
import com.owncloud.android.lib.resources.files.CreateRemoteFolderOperation;
import timber.log.Timber;

public class CreateChunksFolderOperation extends CreateFolderOperation {

/**
* Constructor
*
* @param remotePath Path in which create the chunks folder in server
* @param remotePath Path in which create the chunks folder in server
*/
public CreateChunksFolderOperation(String remotePath) {
super(remotePath, false);
}

@Override
protected RemoteOperationResult run(OwnCloudClient client) {
CreateRemoteChunkFolderOperation createRemoteChunkFolderOperation = new CreateRemoteChunkFolderOperation(
CreateRemoteFolderOperation createRemoteFolderOperation = new CreateRemoteFolderOperation(
mRemotePath,
mCreateFullPath
mCreateFullPath,
true
);

RemoteOperationResult result = createRemoteChunkFolderOperation.execute(client);
RemoteOperationResult result = createRemoteFolderOperation.execute(client);

if (result.isSuccess()) {
Timber.w("Remote chunks folder " + mRemotePath + " was created");
Expand All @@ -52,4 +53,4 @@ protected RemoteOperationResult run(OwnCloudClient client) {

return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ public CreateFolderOperation(String remotePath, boolean createFullPath) {
protected RemoteOperationResult run(OwnCloudClient client) {
CreateRemoteFolderOperation createRemoteFolderOperation = new CreateRemoteFolderOperation(
mRemotePath,
mCreateFullPath
mCreateFullPath,
false
);
RemoteOperationResult result = createRemoteFolderOperation.execute(client);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 32,
"identityHash": "89b7a96730784521dc5c2fea2bdf9e11",
"identityHash": "b6b83a1ac05f23c3f494fd32a8f753e1",
"entities": [
{
"tableName": "capabilities",
Expand Down Expand Up @@ -199,24 +199,36 @@
},
{
"tableName": "files",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `owner` TEXT NOT NULL, `parentId` INTEGER, `length` INTEGER NOT NULL, `creationTimestamp` INTEGER NOT NULL, `modifiedTimestamp` INTEGER NOT NULL, `remotePath` TEXT NOT NULL, `mimeType` TEXT NOT NULL, `etag` TEXT NOT NULL, `permissions` TEXT NOT NULL, `remoteId` TEXT NOT NULL, `privateLink` TEXT NOT NULL)",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `parentId` INTEGER, `owner` TEXT NOT NULL, `remotePath` TEXT NOT NULL, `remoteId` TEXT, `length` INTEGER NOT NULL, `creationTimestamp` INTEGER, `modifiedTimestamp` INTEGER NOT NULL, `mimeType` TEXT NOT NULL, `etag` TEXT, `permissions` TEXT, `privateLink` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "parentId",
"columnName": "parentId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "owner",
"columnName": "owner",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "parentId",
"columnName": "parentId",
"affinity": "INTEGER",
"fieldPath": "remotePath",
"columnName": "remotePath",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": false
},
{
Expand All @@ -229,20 +241,14 @@
"fieldPath": "creationTimestamp",
"columnName": "creationTimestamp",
"affinity": "INTEGER",
"notNull": true
"notNull": false
},
{
"fieldPath": "modifiedTimestamp",
"columnName": "modifiedTimestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "remotePath",
"columnName": "remotePath",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "mimeType",
"columnName": "mimeType",
Expand All @@ -253,25 +259,19 @@
"fieldPath": "etag",
"columnName": "etag",
"affinity": "TEXT",
"notNull": true
"notNull": false
},
{
"fieldPath": "permissions",
"columnName": "permissions",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "remoteId",
"columnName": "remoteId",
"affinity": "TEXT",
"notNull": true
"notNull": false
},
{
"fieldPath": "privateLink",
"columnName": "privateLink",
"affinity": "TEXT",
"notNull": true
"notNull": false
}
],
"primaryKey": {
Expand Down Expand Up @@ -441,7 +441,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '89b7a96730784521dc5c2fea2bdf9e11')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'b6b83a1ac05f23c3f494fd32a8f753e1')"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@ import com.owncloud.android.domain.files.model.OCFile
interface RemoteFileDataSource {
fun checkPathExistence(path: String, checkUserCredentials: Boolean): Boolean

fun createFolder(remotePath: String, createFullPath: Boolean, isChunksFolder: Boolean)

fun refreshFolder(remotePath: String): List<OCFile>
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,31 @@ class OCRemoteFileDataSource(
private val fileService: FileService,
private val remoteFileMapper: RemoteFileMapper
) : RemoteFileDataSource {
override fun checkPathExistence(path: String, checkUserCredentials: Boolean): Boolean =
fileService.checkPathExistence(path = path, isUserLogged = checkUserCredentials).data

override fun checkPathExistence(
path: String,
checkUserCredentials: Boolean
): Boolean =
fileService.checkPathExistence(
path = path,
isUserLogged = checkUserCredentials
).data

override fun createFolder(
remotePath: String,
createFullPath: Boolean,
isChunksFolder: Boolean
): Unit =
fileService.createFolder(
remotePath = remotePath,
createFullPath = createFullPath,
isChunkFolder = isChunksFolder
).data

override fun refreshFolder(remotePath: String): List<OCFile> =
// Assert not null, service should return an empty list if no files there.
fileService.refreshFolder(remotePath).data.map { remoteFileMapper.toModel(it)!! }
fileService.refreshFolder(
remotePath = remotePath
).data.map { remoteFileMapper.toModel(it)!! }

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ abstract class FileDao {
"FROM ${ProviderMeta.ProviderTableMeta.FILES_TABLE_NAME} " +
"WHERE id = :id"

private const val SELECT_FILE_FROM_OWNER_WITH_REMOTE_ID =
private const val SELECT_FILE_FROM_OWNER_WITH_REMOTE_PATH =
"SELECT * " +
"FROM ${ProviderMeta.ProviderTableMeta.FILES_TABLE_NAME} " +
"WHERE owner = :owner " +
"AND remoteId = :remoteId"
"AND remotePath = :remotePath"

private const val DELETE_FILE_WITH_ID =
"DELETE FROM ${ProviderMeta.ProviderTableMeta.FILES_TABLE_NAME} " +
Expand All @@ -50,10 +50,10 @@ abstract class FileDao {
id: Long
): OCFileEntity?

@Query(SELECT_FILE_FROM_OWNER_WITH_REMOTE_ID)
@Query(SELECT_FILE_FROM_OWNER_WITH_REMOTE_PATH)
abstract fun getFileFromOwnerAndRemoteId(
owner: String,
remoteId: String
remotePath: String
): OCFileEntity?

@Insert(onConflict = OnConflictStrategy.REPLACE)
Expand All @@ -65,7 +65,7 @@ abstract class FileDao {
): Long {
val localFile: OCFileEntity? = getFileFromOwnerAndRemoteId(
owner = ocFileEntity.owner,
remoteId = ocFileEntity.remoteId
remotePath = ocFileEntity.remotePath
)
if (localFile == null) {
return insert(ocFileEntity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ data class OCFileEntity(
var parentId: Long? = null,
val owner: String,
val remotePath: String,
val remoteId: String,
val remoteId: String?,
val length: Long,
val creationTimestamp: Long,
val creationTimestamp: Long?,
val modifiedTimestamp: Long,
val mimeType: String,
val etag: String,
val permissions: String,
val privateLink: String
val etag: String?,
val permissions: String?,
val privateLink: String?
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package com.owncloud.android.data.files.repository
import com.owncloud.android.data.files.datasources.LocalFileDataSource
import com.owncloud.android.data.files.datasources.RemoteFileDataSource
import com.owncloud.android.domain.files.FileRepository
import com.owncloud.android.domain.files.model.MIME_DIR
import com.owncloud.android.domain.files.model.OCFile

class OCFileRepository(
Expand All @@ -31,6 +32,30 @@ class OCFileRepository(
override fun checkPathExistence(path: String, userLogged: Boolean): Boolean =
remoteFileDataSource.checkPathExistence(path, userLogged)

override fun createFolder(
remotePath: String,
parentFolder: OCFile
) {
remoteFileDataSource.createFolder(
remotePath = remotePath,
createFullPath = false,
isChunksFolder = false
).also {
localFileDataSource.saveFilesInFolder(
folder = parentFolder,
listOfFiles = listOf(
OCFile(
remotePath = remotePath,
owner = parentFolder.owner,
modifiedTimestamp = System.currentTimeMillis(),
length = 0,
mimeType = MIME_DIR
)
)
)
}
}

override fun refreshFolder(remotePath: String) {
remoteFileDataSource.refreshFolder(remotePath).also {
localFileDataSource.saveFilesInFolder(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ package com.owncloud.android.data.file.datasource

import com.owncloud.android.data.files.datasources.implementation.OCRemoteFileDataSource
import com.owncloud.android.data.files.datasources.mapper.RemoteFileMapper
import com.owncloud.android.lib.resources.files.services.implementation.OCFileService
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.resources.files.services.implementation.OCFileService
import com.owncloud.android.testutil.OC_FILE
import com.owncloud.android.testutil.OC_SERVER_INFO
import com.owncloud.android.utils.createRemoteOperationResultMock
import io.mockk.every
Expand All @@ -32,7 +33,6 @@ import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
import java.lang.Exception

class OCRemoteFileDataSourceTest {
private lateinit var ocRemoteFileDataSource: OCRemoteFileDataSource
Expand Down Expand Up @@ -87,4 +87,30 @@ class OCRemoteFileDataSourceTest {

ocRemoteFileDataSource.checkPathExistence(OC_SERVER_INFO.baseUrl, true)
}

@Test
fun createFolderSuccess() {
val createFolderRemoteResult: RemoteOperationResult<Unit> =
createRemoteOperationResultMock(data = Unit, isSuccess = true)

every {
ocFileService.createFolder(remotePath = OC_FILE.remotePath, createFullPath = false, isChunkFolder = false)
} returns createFolderRemoteResult

val createFolderResult = ocRemoteFileDataSource.createFolder(OC_FILE.remotePath, false, false)

assertNotNull(createFolderResult)
assertEquals(createFolderRemoteResult.data, createFolderResult)

verify { ocFileService.createFolder(any(), any(), any()) }
}

@Test(expected = Exception::class)
fun createFolderException() {
every {
ocFileService.createFolder(OC_FILE.remotePath, false, false)
} throws Exception()

ocRemoteFileDataSource.createFolder(OC_FILE.remotePath, false, false)
}
}
Loading