From d0ab9ff67b4205c7d843f8284a5d1a00498f89ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Wed, 2 Nov 2022 22:32:38 +0100 Subject: [PATCH] Setup base Room configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- app/build.gradle | 5 +- .../client/database/NextcloudDatabase.kt | 65 +++++++++ .../database/entity/ArbitraryDataEntity.kt | 41 ++++++ .../database/entity/CapabilityEntity.kt | 129 ++++++++++++++++++ .../database/entity/ExternalLinkEntity.kt | 47 +++++++ .../client/database/entity/FileEntity.kt | 119 ++++++++++++++++ .../database/entity/FilesystemEntity.kt | 49 +++++++ .../client/database/entity/ShareEntity.kt | 73 ++++++++++ .../database/entity/SyncedFolderEntity.kt | 61 +++++++++ .../client/database/entity/UploadEntity.kt | 65 +++++++++ .../client/database/entity/VirtualEntity.kt | 39 ++++++ .../com/nextcloud/client/di/AppModule.java | 9 ++ .../com/owncloud/android/db/ProviderMeta.java | 2 +- .../providers/FileContentProvider.java | 128 +++++++++-------- build.gradle | 1 + 15 files changed, 776 insertions(+), 57 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt create mode 100644 app/src/main/java/com/nextcloud/client/database/entity/ArbitraryDataEntity.kt create mode 100644 app/src/main/java/com/nextcloud/client/database/entity/CapabilityEntity.kt create mode 100644 app/src/main/java/com/nextcloud/client/database/entity/ExternalLinkEntity.kt create mode 100644 app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt create mode 100644 app/src/main/java/com/nextcloud/client/database/entity/FilesystemEntity.kt create mode 100644 app/src/main/java/com/nextcloud/client/database/entity/ShareEntity.kt create mode 100644 app/src/main/java/com/nextcloud/client/database/entity/SyncedFolderEntity.kt create mode 100644 app/src/main/java/com/nextcloud/client/database/entity/UploadEntity.kt create mode 100644 app/src/main/java/com/nextcloud/client/database/entity/VirtualEntity.kt diff --git a/app/build.gradle b/app/build.gradle index b4bd5e098a..184d7694bf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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) { diff --git a/app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt b/app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt new file mode 100644 index 0000000000..0e64954f36 --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt @@ -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 . + * + */ + +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 + // } + // } + // } +} diff --git a/app/src/main/java/com/nextcloud/client/database/entity/ArbitraryDataEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/ArbitraryDataEntity.kt new file mode 100644 index 0000000000..50daac2027 --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/entity/ArbitraryDataEntity.kt @@ -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 . + * + */ + +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? +) diff --git a/app/src/main/java/com/nextcloud/client/database/entity/CapabilityEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/CapabilityEntity.kt new file mode 100644 index 0000000000..6b84e94893 --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/entity/CapabilityEntity.kt @@ -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 . + * + */ + +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? +) diff --git a/app/src/main/java/com/nextcloud/client/database/entity/ExternalLinkEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/ExternalLinkEntity.kt new file mode 100644 index 0000000000..fad73b9315 --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/entity/ExternalLinkEntity.kt @@ -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 . + * + */ + +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 +) diff --git a/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt new file mode 100644 index 0000000000..8777b79625 --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt @@ -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 . + * + */ + +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? +) diff --git a/app/src/main/java/com/nextcloud/client/database/entity/FilesystemEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/FilesystemEntity.kt new file mode 100644 index 0000000000..a9827f94cb --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/entity/FilesystemEntity.kt @@ -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 . + * + */ + +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 +) diff --git a/app/src/main/java/com/nextcloud/client/database/entity/ShareEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/ShareEntity.kt new file mode 100644 index 0000000000..c58a431902 --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/entity/ShareEntity.kt @@ -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 . + * + */ + +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? +) diff --git a/app/src/main/java/com/nextcloud/client/database/entity/SyncedFolderEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/SyncedFolderEntity.kt new file mode 100644 index 0000000000..0a23c6b885 --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/entity/SyncedFolderEntity.kt @@ -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 . + * + */ + +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 +) diff --git a/app/src/main/java/com/nextcloud/client/database/entity/UploadEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/UploadEntity.kt new file mode 100644 index 0000000000..4af4590e9d --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/entity/UploadEntity.kt @@ -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 . + * + */ + +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? +) diff --git a/app/src/main/java/com/nextcloud/client/database/entity/VirtualEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/VirtualEntity.kt new file mode 100644 index 0000000000..8299dff003 --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/entity/VirtualEntity.kt @@ -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 . + * + */ + +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 +) diff --git a/app/src/main/java/com/nextcloud/client/di/AppModule.java b/app/src/main/java/com/nextcloud/client/di/AppModule.java index 1a623f0e5a..d707fc8288 100644 --- a/app/src/main/java/com/nextcloud/client/di/AppModule.java +++ b/app/src/main/java/com/nextcloud/client/di/AppModule.java @@ -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(); diff --git a/app/src/main/java/com/owncloud/android/db/ProviderMeta.java b/app/src/main/java/com/owncloud/android/db/ProviderMeta.java index 9980058262..23fc26a8b1 100644 --- a/app/src/main/java/com/owncloud/android/db/ProviderMeta.java +++ b/app/src/main/java/com/owncloud/android/db/ProviderMeta.java @@ -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 diff --git a/app/src/main/java/com/owncloud/android/providers/FileContentProvider.java b/app/src/main/java/com/owncloud/android/providers/FileContentProvider.java index a109d8e9ab..8f95ba60ee 100644 --- a/app/src/main/java/com/owncloud/android/providers/FileContentProvider.java +++ b/app/src/main/java/com/owncloud/android/providers/FileContentProvider.java @@ -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 FILE_PROJECTION_MAP; static { - HashMap tempMap = new HashMap<>(); + HashMap 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) { diff --git a/build.gradle b/build.gradle index 1cb1dc6964..1c41addfe8 100644 --- a/build.gradle +++ b/build.gradle @@ -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" }