Setup base Room configuration

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
This commit is contained in:
Álvaro Brey 2022-11-02 22:32:38 +01:00 committed by Tobias Kaminsky (Rebase PR Action)
parent e96390524a
commit d0ab9ff67b
15 changed files with 776 additions and 57 deletions

View file

@ -354,6 +354,10 @@ dependencies {
gplayImplementation "com.google.firebase:firebase-messaging:23.1.0"
implementation 'com.github.nextcloud.android-common:ui:0.3.0'
implementation "androidx.room:room-runtime:$roomVersion"
kapt "androidx.room:room-compiler:$roomVersion"
}
configurations.all {
@ -366,7 +370,6 @@ configurations.all {
}
}
}
}
tasks.withType(Test) {

View file

@ -0,0 +1,65 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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.nextcloud.client.database
import androidx.room.Database
import androidx.room.RoomDatabase
import com.nextcloud.client.database.entity.ArbitraryDataEntity
import com.nextcloud.client.database.entity.CapabilityEntity
import com.nextcloud.client.database.entity.ExternalLinkEntity
import com.nextcloud.client.database.entity.FileEntity
import com.nextcloud.client.database.entity.FilesystemEntity
import com.nextcloud.client.database.entity.ShareEntity
import com.nextcloud.client.database.entity.SyncedFolderEntity
import com.nextcloud.client.database.entity.UploadEntity
import com.nextcloud.client.database.entity.VirtualEntity
import com.owncloud.android.db.ProviderMeta
@Database(
entities = [
ArbitraryDataEntity::class,
CapabilityEntity::class,
ExternalLinkEntity::class,
FileEntity::class,
FilesystemEntity::class,
ShareEntity::class,
SyncedFolderEntity::class,
UploadEntity::class,
VirtualEntity::class
],
version = ProviderMeta.DB_VERSION
)
abstract class NextcloudDatabase : RoomDatabase() {
// companion object {
// val MIGRATION_1_64 = object : Migration(1, 64) {
// override fun migrate(database: SupportSQLiteDatabase) {
// TODO("Not yet implemented, use legacy migrations")
// }
// }
// val MIGRATION_64_65 = object : Migration(64, 65) {
// override fun migrate(database: SupportSQLiteDatabase) {
// // this is just for Room compatibility. No need for any migration
// }
// }
// }
}

View file

@ -0,0 +1,41 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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.nextcloud.client.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta
@Entity(tableName = ProviderTableMeta.ARBITRARY_DATA_TABLE_NAME)
data class ArbitraryDataEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ProviderTableMeta._ID)
val id: Int,
@ColumnInfo(name = ProviderTableMeta.ARBITRARY_DATA_CLOUD_ID)
val cloudId: String?,
@ColumnInfo(name = ProviderTableMeta.ARBITRARY_DATA_KEY)
val key: String?,
@ColumnInfo(name = ProviderTableMeta.ARBITRARY_DATA_VALUE)
val value: String?
)

View file

@ -0,0 +1,129 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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.nextcloud.client.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta
@Entity(tableName = ProviderTableMeta.CAPABILITIES_TABLE_NAME)
data class CapabilityEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ProviderTableMeta._ID)
val id: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME)
val accountName: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_VERSION_MAYOR)
val versionMajor: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_VERSION_MINOR)
val versionMinor: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_VERSION_MICRO)
val versionMicro: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_VERSION_STRING)
val versionString: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_VERSION_EDITION)
val versionEditor: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_EXTENDED_SUPPORT)
val extendedSupport: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_CORE_POLLINTERVAL)
val corePollinterval: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_API_ENABLED)
val sharingApiEnabled: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ENABLED)
val sharingPublicEnabled: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_PASSWORD_ENFORCED)
val sharingPublicPasswordEnforced: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENABLED)
val sharingPublicExpireDateEnabled: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_DAYS)
val sharingPublicExpireDateDays: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENFORCED)
val sharingPublicExpireDateEnforced: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_SEND_MAIL)
val sharingPublicSendMail: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_UPLOAD)
val sharingPublicUpload: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_USER_SEND_MAIL)
val sharingUserSendMail: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_RESHARING)
val sharingResharing: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_OUTGOING)
val sharingFederationOutgoing: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_INCOMING)
val sharingFederationIncoming: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_FILES_BIGFILECHUNKING)
val filesBigfilechunking: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_FILES_UNDELETE)
val filesUndelete: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_FILES_VERSIONING)
val filesVersioning: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_EXTERNAL_LINKS)
val externalLinks: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SERVER_NAME)
val serverName: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SERVER_COLOR)
val serverColor: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SERVER_TEXT_COLOR)
val serverTextColor: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SERVER_ELEMENT_COLOR)
val serverElementColor: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SERVER_SLOGAN)
val serverSlogan: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SERVER_LOGO)
val serverLogo: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SERVER_BACKGROUND_URL)
val serverBackgroundUrl: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_END_TO_END_ENCRYPTION)
val endToEndEncryption: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_ACTIVITY)
val activity: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SERVER_BACKGROUND_DEFAULT)
val serverBackgroundDefault: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SERVER_BACKGROUND_PLAIN)
val serverBackgroundPlain: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_RICHDOCUMENT)
val richdocument: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_RICHDOCUMENT_MIMETYPE_LIST)
val richdocumentMimetypeList: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_RICHDOCUMENT_DIRECT_EDITING)
val richdocumentDirectEditing: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_RICHDOCUMENT_TEMPLATES)
val richdocumentTemplates: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_RICHDOCUMENT_OPTIONAL_MIMETYPE_LIST)
val richdocumentOptionalMimetypeList: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ASK_FOR_OPTIONAL_PASSWORD)
val sharingPublicAskForOptionalPassword: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_RICHDOCUMENT_PRODUCT_NAME)
val richdocumentProductName: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_DIRECT_EDITING_ETAG)
val directEditingEtag: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_USER_STATUS)
val userStatus: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_USER_STATUS_SUPPORTS_EMOJI)
val userStatusSupportsEmoji: Int,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_ETAG)
val etag: String?,
@ColumnInfo(name = ProviderTableMeta.CAPABILITIES_FILES_LOCKING_VERSION)
val filesLockingVersion: String?
)

View file

@ -0,0 +1,47 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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.nextcloud.client.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta
@Entity(tableName = ProviderTableMeta.EXTERNAL_LINKS_TABLE_NAME)
data class ExternalLinkEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ProviderTableMeta._ID)
val id: Int,
@ColumnInfo(name = ProviderTableMeta.EXTERNAL_LINKS_ICON_URL)
val iconUrl: String?,
@ColumnInfo(name = ProviderTableMeta.EXTERNAL_LINKS_LANGUAGE)
val language: String?,
@ColumnInfo(name = ProviderTableMeta.EXTERNAL_LINKS_TYPE)
val type: Int,
@ColumnInfo(name = ProviderTableMeta.EXTERNAL_LINKS_NAME)
val name: String?,
@ColumnInfo(name = ProviderTableMeta.EXTERNAL_LINKS_URL)
val url: String,
@ColumnInfo(name = ProviderTableMeta.EXTERNAL_LINKS_REDIRECT)
val redirect: Int
)

View file

@ -0,0 +1,119 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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.nextcloud.client.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta
@Entity(tableName = ProviderTableMeta.FILE_TABLE_NAME)
data class FileEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ProviderTableMeta._ID)
val id: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_NAME)
val name: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_ENCRYPTED_NAME)
val encryptedName: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_PATH)
val path: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_PATH_DECRYPTED)
val pathDecrypted: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_PARENT)
val parent: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_CREATION)
val creation: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_MODIFIED)
val modified: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_CONTENT_TYPE)
val contentType: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_CONTENT_LENGTH)
val contentLength: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_STORAGE_PATH)
val storagePath: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_ACCOUNT_OWNER)
val accountOwner: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_LAST_SYNC_DATE)
val lastSyncDate: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA)
val lastSyncDateForData: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA)
val modifiedAtLastSyncForData: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_ETAG)
val etag: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_ETAG_ON_SERVER)
val etagOnServer: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_SHARED_VIA_LINK)
val sharedViaLink: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_PERMISSIONS)
val permissions: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_REMOTE_ID)
val remoteId: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_UPDATE_THUMBNAIL)
val updateThumbnail: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_IS_DOWNLOADING)
val isDownloading: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_FAVORITE)
val favorite: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_IS_ENCRYPTED)
val isEncrypted: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_ETAG_IN_CONFLICT)
val etagInConflict: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_SHARED_WITH_SHAREE)
val sharedWithSharee: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_MOUNT_TYPE)
val mountType: Int?,
@ColumnInfo(name = ProviderTableMeta.FILE_HAS_PREVIEW)
val hasPreview: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT)
val unreadCommentsCount: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_OWNER_ID)
val ownerId: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_OWNER_DISPLAY_NAME)
val ownerDisplayName: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_NOTE)
val note: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_SHAREES)
val sharees: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_RICH_WORKSPACE)
val richWorkspace: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_METADATA_SIZE)
val metadataSize: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_LOCKED)
val locked: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_LOCK_TYPE)
val lockType: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_LOCK_OWNER)
val lockOwner: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_LOCK_OWNER_DISPLAY_NAME)
val lockOwnerDisplayName: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_LOCK_OWNER_EDITOR)
val lockOwnerEditor: String?,
@ColumnInfo(name = ProviderTableMeta.FILE_LOCK_TIMESTAMP)
val lockTimestamp: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_LOCK_TIMEOUT)
val lockTimeout: Int,
@ColumnInfo(name = ProviderTableMeta.FILE_LOCK_TOKEN)
val lockToken: String?
)

View file

@ -0,0 +1,49 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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.nextcloud.client.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta
@Entity(tableName = ProviderTableMeta.FILESYSTEM_TABLE_NAME)
data class FilesystemEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ProviderTableMeta._ID)
val id: Int,
@ColumnInfo(name = ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH)
val localPath: String?,
@ColumnInfo(name = ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER)
val fileIsFolder: Int,
@ColumnInfo(name = ProviderTableMeta.FILESYSTEM_FILE_FOUND_RECENTLY)
val fileFoundRecently: Long,
@ColumnInfo(name = ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD)
val fileSentForUpload: Int,
@ColumnInfo(name = ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID)
val syncedFolderId: String?,
@ColumnInfo(name = ProviderTableMeta.FILESYSTEM_CRC32)
val crc32: String?,
@ColumnInfo(name = ProviderTableMeta.FILESYSTEM_FILE_MODIFIED)
val fileModified: Long
)

View file

@ -0,0 +1,73 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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.nextcloud.client.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta
@Entity(tableName = ProviderTableMeta.OCSHARES_TABLE_NAME)
data class ShareEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ProviderTableMeta._ID)
val id: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_FILE_SOURCE)
val fileSource: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_ITEM_SOURCE)
val itemSource: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_SHARE_TYPE)
val shareType: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_SHARE_WITH)
val shareWith: String?,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_PATH)
val path: String?,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_PERMISSIONS)
val permissions: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_SHARED_DATE)
val sharedDate: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_EXPIRATION_DATE)
val expirationDate: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_TOKEN)
val token: String?,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME)
val shareWithDisplayName: String?,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_IS_DIRECTORY)
val isDirectory: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_USER_ID)
val userId: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED)
val idRemoteShared: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER)
val accountOwner: String?,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_IS_PASSWORD_PROTECTED)
val isPasswordProtected: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_NOTE)
val note: String?,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_HIDE_DOWNLOAD)
val hideDownload: Int,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_SHARE_LINK)
val shareLink: String?,
@ColumnInfo(name = ProviderTableMeta.OCSHARES_SHARE_LABEL)
val shareLabel: String?
)

View file

@ -0,0 +1,61 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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.nextcloud.client.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta
@Entity(tableName = ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME)
data class SyncedFolderEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ProviderTableMeta._ID)
val id: Int,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_LOCAL_PATH)
val localPath: String?,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_REMOTE_PATH)
val remotePath: String?,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_WIFI_ONLY)
val wifiOnly: Int,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_CHARGING_ONLY)
val chargingOnly: Int,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_EXISTING)
val existing: Int,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_ENABLED)
val enabled: Int,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_ENABLED_TIMESTAMP_MS)
val enabledTimestampMs: Int,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_BY_DATE)
val subfolderByDate: Int,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_ACCOUNT)
val account: String?,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_UPLOAD_ACTION)
val uploadAction: Int,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_NAME_COLLISION_POLICY)
val nameCollisionPolicy: Int,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_TYPE)
val type: Int,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_HIDDEN)
val hidden: Int
)

View file

@ -0,0 +1,65 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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.nextcloud.client.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta
@Entity(tableName = ProviderTableMeta.UPLOADS_TABLE_NAME)
data class UploadEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ProviderTableMeta._ID)
val id: Int,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_LOCAL_PATH)
val localPath: String?,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_REMOTE_PATH)
val remotePath: String?,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_ACCOUNT_NAME)
val accountName: String?,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_FILE_SIZE)
val fileSize: Long?,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_STATUS)
val status: Int,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_LOCAL_BEHAVIOUR)
val localBehaviour: Int,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_UPLOAD_TIME)
val uploadTime: Int?,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_NAME_COLLISION_POLICY)
val nameCollisionPolicy: Int,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_IS_CREATE_REMOTE_FOLDER)
val isCreateRemoteFolder: Int,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_UPLOAD_END_TIMESTAMP)
val uploadEndTimestamp: Int?,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_LAST_RESULT)
val lastResult: Int?,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_IS_WHILE_CHARGING_ONLY)
val isWhileChargingOnly: Int,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_IS_WIFI_ONLY)
val isWifiOnly: Int,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_CREATED_BY)
val createdBy: Int,
@ColumnInfo(name = ProviderTableMeta.UPLOADS_FOLDER_UNLOCK_TOKEN)
val folderUnlockToken: String?
)

View file

@ -0,0 +1,39 @@
/*
* Nextcloud Android client application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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.nextcloud.client.database.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta
@Entity(tableName = ProviderTableMeta.VIRTUAL_TABLE_NAME)
data class VirtualEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = ProviderTableMeta._ID)
val id: Int,
@ColumnInfo(name = ProviderTableMeta.VIRTUAL_TYPE)
val type: String,
@ColumnInfo(name = ProviderTableMeta.VIRTUAL_OCFILE_ID)
val ocFileId: Int
)

View file

@ -39,6 +39,7 @@ import com.nextcloud.client.core.AsyncRunner;
import com.nextcloud.client.core.Clock;
import com.nextcloud.client.core.ClockImpl;
import com.nextcloud.client.core.ThreadPoolAsyncRunner;
import com.nextcloud.client.database.NextcloudDatabase;
import com.nextcloud.client.device.DeviceInfo;
import com.nextcloud.client.logger.FileLogHandler;
import com.nextcloud.client.logger.Logger;
@ -57,6 +58,7 @@ import com.owncloud.android.authentication.PassCodeManager;
import com.owncloud.android.datamodel.ArbitraryDataProvider;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.UploadsStorageManager;
import com.owncloud.android.db.ProviderMeta;
import com.owncloud.android.ui.activities.data.activities.ActivitiesRepository;
import com.owncloud.android.ui.activities.data.activities.ActivitiesServiceApi;
import com.owncloud.android.ui.activities.data.activities.ActivitiesServiceApiImpl;
@ -75,6 +77,7 @@ import javax.inject.Provider;
import javax.inject.Singleton;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.room.Room;
import dagger.Module;
import dagger.Provides;
@ -91,6 +94,12 @@ class AppModule {
return application;
}
@Provides
@Singleton
NextcloudDatabase database(Context context) {
return Room.databaseBuilder(context, NextcloudDatabase.class, ProviderMeta.DB_NAME).build();
}
@Provides
PackageManager packageManager(Application application) {
return application.getPackageManager();

View file

@ -35,7 +35,7 @@ import java.util.List;
*/
public class ProviderMeta {
public static final String DB_NAME = "filelist";
public static final int DB_VERSION = 64;
public static final int DB_VERSION = 65;
private ProviderMeta() {
// No instance

View file

@ -37,12 +37,12 @@ import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Binder;
import android.text.TextUtils;
import com.nextcloud.client.core.Clock;
import com.nextcloud.client.database.NextcloudDatabase;
import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.OCFile;
@ -68,6 +68,10 @@ import javax.inject.Inject;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.sqlite.db.SupportSQLiteDatabase;
import androidx.sqlite.db.SupportSQLiteOpenHelper;
import androidx.sqlite.db.SupportSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteQueryBuilder;
import dagger.android.AndroidInjection;
import third_parties.aosp.SQLiteTokenizer;
@ -118,7 +122,7 @@ public class FileContentProvider extends ContentProvider {
private static final Map<String, String> FILE_PROJECTION_MAP;
static {
HashMap<String,String> tempMap = new HashMap<>();
HashMap<String, String> tempMap = new HashMap<>();
for (String projection : ProviderTableMeta.FILE_ALL_COLUMNS) {
tempMap.put(projection, projection);
}
@ -127,7 +131,8 @@ public class FileContentProvider extends ContentProvider {
@Inject protected Clock clock;
private DataBaseHelper mDbHelper;
@Inject NextcloudDatabase database;
private SupportSQLiteOpenHelper mDbHelper;
private Context mContext;
private UriMatcher mUriMatcher;
@ -138,7 +143,7 @@ public class FileContentProvider extends ContentProvider {
}
int count;
SQLiteDatabase db = mDbHelper.getWritableDatabase();
SupportSQLiteDatabase db = mDbHelper.getWritableDatabase();
db.beginTransaction();
try {
count = delete(db, uri, where, whereArgs);
@ -150,7 +155,7 @@ public class FileContentProvider extends ContentProvider {
return count;
}
private int delete(SQLiteDatabase db, Uri uri, String where, String... whereArgs) {
private int delete(SupportSQLiteDatabase db, Uri uri, String where, String... whereArgs) {
if (isCallerNotAllowed(uri)) {
return -1;
}
@ -205,7 +210,7 @@ public class FileContentProvider extends ContentProvider {
return count;
}
private int deleteDirectory(SQLiteDatabase db, Uri uri, String where, String... whereArgs) {
private int deleteDirectory(SupportSQLiteDatabase db, Uri uri, String where, String... whereArgs) {
int count = 0;
Cursor children = query(uri, PROJECTION_CONTENT_TYPE, null, null, null);
@ -238,7 +243,7 @@ public class FileContentProvider extends ContentProvider {
return count;
}
private int deleteSingleFile(SQLiteDatabase db, Uri uri, String where, String... whereArgs) {
private int deleteSingleFile(SupportSQLiteDatabase db, Uri uri, String where, String... whereArgs) {
int count = 0;
try (Cursor c = query(db, uri, PROJECTION_REMOTE_ID, where, whereArgs, null)) {
@ -255,7 +260,7 @@ public class FileContentProvider extends ContentProvider {
return count;
}
private int deleteWithUri(SQLiteDatabase db, Uri uri, String where, String[] whereArgs) {
private int deleteWithUri(SupportSQLiteDatabase db, Uri uri, String where, String[] whereArgs) {
final String[] argsWithUri = VerificationUtils.prependUriFirstSegmentToSelectionArgs(whereArgs, uri);
return db.delete(ProviderTableMeta.FILE_TABLE_NAME,
ProviderTableMeta._ID + "=?"
@ -281,7 +286,7 @@ public class FileContentProvider extends ContentProvider {
}
Uri newUri;
SQLiteDatabase db = mDbHelper.getWritableDatabase();
SupportSQLiteDatabase db = mDbHelper.getWritableDatabase();
db.beginTransaction();
try {
newUri = insert(db, uri, values);
@ -293,7 +298,7 @@ public class FileContentProvider extends ContentProvider {
return newUri;
}
private Uri insert(SQLiteDatabase db, Uri uri, ContentValues values) {
private Uri insert(SupportSQLiteDatabase db, Uri uri, ContentValues values) {
// verify only for those requests that are not internal (files table)
switch (mUriMatcher.match(uri)) {
case ROOT_DIRECTORY:
@ -318,7 +323,7 @@ public class FileContentProvider extends ContentProvider {
// FileDataStorageManager and bring it to FileContentProvider
if (!doubleCheck.moveToFirst()) {
doubleCheck.close();
long rowId = db.insert(ProviderTableMeta.FILE_TABLE_NAME, null, values);
long rowId = db.insert(ProviderTableMeta.FILE_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values);
if (rowId > 0) {
return ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, rowId);
} else {
@ -337,7 +342,7 @@ public class FileContentProvider extends ContentProvider {
case SHARES:
Uri insertedShareUri;
long idShares = db.insert(ProviderTableMeta.OCSHARES_TABLE_NAME, null, values);
long idShares = db.insert(ProviderTableMeta.OCSHARES_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values);
if (idShares > 0) {
insertedShareUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_SHARE, idShares);
} else {
@ -350,7 +355,7 @@ public class FileContentProvider extends ContentProvider {
case CAPABILITIES:
Uri insertedCapUri;
long idCapabilities = db.insert(ProviderTableMeta.CAPABILITIES_TABLE_NAME, null, values);
long idCapabilities = db.insert(ProviderTableMeta.CAPABILITIES_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values);
if (idCapabilities > 0) {
insertedCapUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_CAPABILITIES, idCapabilities);
} else {
@ -360,7 +365,7 @@ public class FileContentProvider extends ContentProvider {
case UPLOADS:
Uri insertedUploadUri;
long uploadId = db.insert(ProviderTableMeta.UPLOADS_TABLE_NAME, null, values);
long uploadId = db.insert(ProviderTableMeta.UPLOADS_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values);
if (uploadId > 0) {
insertedUploadUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_UPLOADS, uploadId);
} else {
@ -370,7 +375,7 @@ public class FileContentProvider extends ContentProvider {
case SYNCED_FOLDERS:
Uri insertedSyncedFolderUri;
long syncedFolderId = db.insert(ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME, null, values);
long syncedFolderId = db.insert(ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values);
if (syncedFolderId > 0) {
insertedSyncedFolderUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_SYNCED_FOLDERS,
syncedFolderId);
@ -381,7 +386,7 @@ public class FileContentProvider extends ContentProvider {
case EXTERNAL_LINKS:
Uri insertedExternalLinkUri;
long externalLinkId = db.insert(ProviderTableMeta.EXTERNAL_LINKS_TABLE_NAME, null, values);
long externalLinkId = db.insert(ProviderTableMeta.EXTERNAL_LINKS_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values);
if (externalLinkId > 0) {
insertedExternalLinkUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_EXTERNAL_LINKS,
externalLinkId);
@ -392,7 +397,7 @@ public class FileContentProvider extends ContentProvider {
case ARBITRARY_DATA:
Uri insertedArbitraryDataUri;
long arbitraryDataId = db.insert(ProviderTableMeta.ARBITRARY_DATA_TABLE_NAME, null, values);
long arbitraryDataId = db.insert(ProviderTableMeta.ARBITRARY_DATA_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values);
if (arbitraryDataId > 0) {
insertedArbitraryDataUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_ARBITRARY_DATA,
arbitraryDataId);
@ -402,7 +407,7 @@ public class FileContentProvider extends ContentProvider {
return insertedArbitraryDataUri;
case VIRTUAL:
Uri insertedVirtualUri;
long virtualId = db.insert(ProviderTableMeta.VIRTUAL_TABLE_NAME, null, values);
long virtualId = db.insert(ProviderTableMeta.VIRTUAL_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values);
if (virtualId > 0) {
insertedVirtualUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_VIRTUAL, virtualId);
@ -413,7 +418,7 @@ public class FileContentProvider extends ContentProvider {
return insertedVirtualUri;
case FILESYSTEM:
Uri insertedFilesystemUri;
long filesystemId = db.insert(ProviderTableMeta.FILESYSTEM_TABLE_NAME, null, values);
long filesystemId = db.insert(ProviderTableMeta.FILESYSTEM_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values);
if (filesystemId > 0) {
insertedFilesystemUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILESYSTEM,
filesystemId);
@ -426,7 +431,7 @@ public class FileContentProvider extends ContentProvider {
}
}
private void updateFilesTableAccordingToShareInsertion(SQLiteDatabase db, ContentValues newShare) {
private void updateFilesTableAccordingToShareInsertion(SupportSQLiteDatabase db, ContentValues newShare) {
ContentValues fileValues = new ContentValues();
ShareType newShareType = ShareType.fromValue(newShare.getAsInteger(ProviderTableMeta.OCSHARES_SHARE_TYPE));
@ -456,14 +461,14 @@ public class FileContentProvider extends ContentProvider {
newShare.getAsString(ProviderTableMeta.OCSHARES_PATH),
newShare.getAsString(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER)
};
db.update(ProviderTableMeta.FILE_TABLE_NAME, fileValues, where, whereArgs);
db.update(ProviderTableMeta.FILE_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, fileValues, where, whereArgs);
}
@Override
public boolean onCreate() {
AndroidInjection.inject(this);
mDbHelper = new DataBaseHelper(getContext());
mDbHelper = database.getOpenHelper();
mContext = getContext();
if (mContext == null) {
@ -510,7 +515,7 @@ public class FileContentProvider extends ContentProvider {
}
Cursor result;
SQLiteDatabase db = mDbHelper.getReadableDatabase();
SupportSQLiteDatabase db = mDbHelper.getReadableDatabase();
db.beginTransaction();
try {
result = query(db, uri, projection, selection, selectionArgs, sortOrder);
@ -521,7 +526,7 @@ public class FileContentProvider extends ContentProvider {
return result;
}
private Cursor query(SQLiteDatabase db,
private Cursor query(SupportSQLiteDatabase db,
Uri uri,
String[] projectionArray,
String selection,
@ -531,49 +536,49 @@ public class FileContentProvider extends ContentProvider {
// verify only for those requests that are not internal
final int uriMatch = mUriMatcher.match(uri);
SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();
String tableName;
switch (uriMatch) {
case ROOT_DIRECTORY:
case DIRECTORY:
case SINGLE_FILE:
VerificationUtils.verifyWhere(selection); // prevent injection in public paths
sqlQuery.setTables(ProviderTableMeta.FILE_TABLE_NAME);
tableName = ProviderTableMeta.FILE_TABLE_NAME;
break;
case SHARES:
sqlQuery.setTables(ProviderTableMeta.OCSHARES_TABLE_NAME);
tableName = ProviderTableMeta.OCSHARES_TABLE_NAME;
break;
case CAPABILITIES:
sqlQuery.setTables(ProviderTableMeta.CAPABILITIES_TABLE_NAME);
tableName = ProviderTableMeta.CAPABILITIES_TABLE_NAME;
break;
case UPLOADS:
sqlQuery.setTables(ProviderTableMeta.UPLOADS_TABLE_NAME);
tableName = ProviderTableMeta.UPLOADS_TABLE_NAME;
break;
case SYNCED_FOLDERS:
sqlQuery.setTables(ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME);
tableName = ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME;
break;
case EXTERNAL_LINKS:
sqlQuery.setTables(ProviderTableMeta.EXTERNAL_LINKS_TABLE_NAME);
tableName = ProviderTableMeta.EXTERNAL_LINKS_TABLE_NAME;
break;
case ARBITRARY_DATA:
sqlQuery.setTables(ProviderTableMeta.ARBITRARY_DATA_TABLE_NAME);
tableName = ProviderTableMeta.ARBITRARY_DATA_TABLE_NAME;
break;
case VIRTUAL:
sqlQuery.setTables(ProviderTableMeta.VIRTUAL_TABLE_NAME);
tableName = ProviderTableMeta.VIRTUAL_TABLE_NAME;
break;
case FILESYSTEM:
sqlQuery.setTables(ProviderTableMeta.FILESYSTEM_TABLE_NAME);
tableName = ProviderTableMeta.FILESYSTEM_TABLE_NAME;
break;
default:
throw new IllegalArgumentException("Unknown uri id: " + uri);
}
SupportSQLiteQueryBuilder queryBuilder = SupportSQLiteQueryBuilder.builder(tableName);
// add ID to arguments if Uri has more than one segment
if (uriMatch != ROOT_DIRECTORY && uri.getPathSegments().size() > SINGLE_PATH_SEGMENT ) {
if (uriMatch != ROOT_DIRECTORY && uri.getPathSegments().size() > SINGLE_PATH_SEGMENT) {
String idColumn = uriMatch == DIRECTORY ? ProviderTableMeta.FILE_PARENT : ProviderTableMeta._ID;
sqlQuery.appendWhere(idColumn + "=?");
selection = idColumn + "=? AND " + selection;
selectionArgs = VerificationUtils.prependUriFirstSegmentToSelectionArgs(selectionArgs, uri);
}
@ -619,11 +624,12 @@ public class FileContentProvider extends ContentProvider {
// DB case_sensitive
db.execSQL("PRAGMA case_sensitive_like = true");
// only file list is accessible via content provider, so only this has to be protected with projectionMap
if ((uriMatch == ROOT_DIRECTORY || uriMatch == SINGLE_FILE ||
uriMatch == DIRECTORY) && projectionArray != null) {
sqlQuery.setProjectionMap(FILE_PROJECTION_MAP);
}
// TODO
// // only file list is accessible via content provider, so only this has to be protected with projectionMap
// if ((uriMatch == ROOT_DIRECTORY || uriMatch == SINGLE_FILE ||
// uriMatch == DIRECTORY) && projectionArray != null) {
// sqlQuery.setProjectionMap(FILE_PROJECTION_MAP);
// }
// if both are null, let them pass to query
if (selectionArgs == null && selection != null) {
@ -631,8 +637,20 @@ public class FileContentProvider extends ContentProvider {
selection = "(?)";
}
sqlQuery.setStrict(true);
Cursor c = sqlQuery.query(db, projectionArray, selection, selectionArgs, null, null, order);
// TODO
// sqlQuery.setStrict(true);
if (!TextUtils.isEmpty(selection)) {
queryBuilder.selection(selection, selectionArgs);
}
if (!TextUtils.isEmpty(order)) {
queryBuilder.orderBy(order);
}
if (projectionArray != null && projectionArray.length > 0) {
queryBuilder.columns(projectionArray);
}
final SupportSQLiteQuery supportSQLiteQuery = queryBuilder.create();
final Cursor c = db.query(supportSQLiteQuery);
c.setNotificationUri(mContext.getContentResolver(), uri);
return c;
}
@ -644,7 +662,7 @@ public class FileContentProvider extends ContentProvider {
}
int count;
SQLiteDatabase db = mDbHelper.getWritableDatabase();
SupportSQLiteDatabase db = mDbHelper.getWritableDatabase();
db.beginTransaction();
try {
count = update(db, uri, values, selection, selectionArgs);
@ -656,7 +674,7 @@ public class FileContentProvider extends ContentProvider {
return count;
}
private int update(SQLiteDatabase db, Uri uri, ContentValues values, String selection, String... selectionArgs) {
private int update(SupportSQLiteDatabase db, Uri uri, ContentValues values, String selection, String... selectionArgs) {
// verify contentValues and selection for public paths to prevent injection
switch (mUriMatcher.match(uri)) {
case ROOT_DIRECTORY:
@ -670,19 +688,19 @@ public class FileContentProvider extends ContentProvider {
case DIRECTORY:
return 0;
case SHARES:
return db.update(ProviderTableMeta.OCSHARES_TABLE_NAME, values, selection, selectionArgs);
return db.update(ProviderTableMeta.OCSHARES_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values, selection, selectionArgs);
case CAPABILITIES:
return db.update(ProviderTableMeta.CAPABILITIES_TABLE_NAME, values, selection, selectionArgs);
return db.update(ProviderTableMeta.CAPABILITIES_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values, selection, selectionArgs);
case UPLOADS:
return db.update(ProviderTableMeta.UPLOADS_TABLE_NAME, values, selection, selectionArgs);
return db.update(ProviderTableMeta.UPLOADS_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values, selection, selectionArgs);
case SYNCED_FOLDERS:
return db.update(ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME, values, selection, selectionArgs);
return db.update(ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values, selection, selectionArgs);
case ARBITRARY_DATA:
return db.update(ProviderTableMeta.ARBITRARY_DATA_TABLE_NAME, values, selection, selectionArgs);
return db.update(ProviderTableMeta.ARBITRARY_DATA_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values, selection, selectionArgs);
case FILESYSTEM:
return db.update(ProviderTableMeta.FILESYSTEM_TABLE_NAME, values, selection, selectionArgs);
return db.update(ProviderTableMeta.FILESYSTEM_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values, selection, selectionArgs);
default:
return db.update(ProviderTableMeta.FILE_TABLE_NAME, values, selection, selectionArgs);
return db.update(ProviderTableMeta.FILE_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values, selection, selectionArgs);
}
}
@ -695,7 +713,7 @@ public class FileContentProvider extends ContentProvider {
ContentProviderResult[] results = new ContentProviderResult[operations.size()];
int i = 0;
SQLiteDatabase database = mDbHelper.getWritableDatabase();
SupportSQLiteDatabase database = mDbHelper.getWritableDatabase();
database.beginTransaction(); // it's supposed that transactions can be nested
try {
for (ContentProviderOperation operation : operations) {

View file

@ -16,6 +16,7 @@ buildscript {
checkerVersion = "3.21.2"
exoplayerVersion = "2.18.1"
documentScannerVersion = "1.0.1"
roomVersion = "2.4.3"
ciBuild = System.getenv("CI") == "true"
}