Browse Source

add DB

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>
Marino Faggiana 2 years ago
parent
commit
feffd7a055

+ 1 - 0
.swiftlint.yml

@@ -65,6 +65,7 @@ excluded:
   - iOSClient/Data/NCManageDatabase+Metadata.swift
   - iOSClient/Data/NCManageDatabase+Directory.swift
   - iOSClient/Data/NCManageDatabase+Video.swift
+  - iOSClient/Data/NCManageDatabase+LayoutForView.swift
   - iOSClient/Data/NCManageDatabase+DashboardWidget.swift
   - iOSClient/Diagnostics/NCCapabilitiesViewController.swift
   - iOSClient/EmptyView/NCEmptyDataSet.swift

+ 14 - 0
Nextcloud.xcodeproj/project.pbxproj

@@ -448,6 +448,12 @@
 		F7BC287E26663F6C004D46C5 /* NCViewCertificateDetails.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7BC287D26663F6C004D46C5 /* NCViewCertificateDetails.storyboard */; };
 		F7BC288026663F85004D46C5 /* NCViewCertificateDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7BC287F26663F85004D46C5 /* NCViewCertificateDetails.swift */; };
 		F7BD71E62636EAFC00643C34 /* NCNetworkingE2EE.swift in Sources */ = {isa = PBXBuildFile; fileRef = F785EE9C246196DF00B3F945 /* NCNetworkingE2EE.swift */; };
+		F7BF9D822934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7BF9D812934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift */; };
+		F7BF9D832934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7BF9D812934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift */; };
+		F7BF9D842934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7BF9D812934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift */; };
+		F7BF9D852934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7BF9D812934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift */; };
+		F7BF9D862934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7BF9D812934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift */; };
+		F7BF9D872934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7BF9D812934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift */; };
 		F7C1EEA525053A9C00866ACC /* NCDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7C1EEA425053A9C00866ACC /* NCDataSource.swift */; };
 		F7C30DF6291BC0CA0017149B /* NCNetworkingE2EEUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7C30DF5291BC0CA0017149B /* NCNetworkingE2EEUpload.swift */; };
 		F7C30DF7291BC0D30017149B /* NCNetworkingE2EEUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7C30DF5291BC0CA0017149B /* NCNetworkingE2EEUpload.swift */; };
@@ -1078,6 +1084,7 @@
 		F7BE7C77290ADF15002ABB61 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Intent.strings; sourceTree = "<group>"; };
 		F7BE7C79290ADF16002ABB61 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Intent.strings"; sourceTree = "<group>"; };
 		F7BE7C7B290ADF16002ABB61 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Intent.strings"; sourceTree = "<group>"; };
+		F7BF9D812934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+LayoutForView.swift"; sourceTree = "<group>"; };
 		F7C1EEA425053A9C00866ACC /* NCDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCDataSource.swift; sourceTree = "<group>"; };
 		F7C30DF5291BC0CA0017149B /* NCNetworkingE2EEUpload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCNetworkingE2EEUpload.swift; sourceTree = "<group>"; };
 		F7C30DF9291BCF790017149B /* NCNetworkingE2EECreateFolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCNetworkingE2EECreateFolder.swift; sourceTree = "<group>"; };
@@ -1835,6 +1842,7 @@
 				AF4BF613275629E20081CEEF /* NCManageDatabase+Account.swift */,
 				F7D68FCB28CB9051009139F3 /* NCManageDatabase+DashboardWidget.swift */,
 				F78A10BE29322E8A008499B8 /* NCManageDatabase+Directory.swift */,
+				F7BF9D812934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift */,
 				AF4BF61827562A4B0081CEEF /* NCManageDatabase+Metadata.swift */,
 				F7E98C1527E0D0FC001F9F19 /* NCManageDatabase+Video.swift */,
 				F73D5E46246DE09200DF6467 /* NCElementsJSON.swift */,
@@ -2803,6 +2811,7 @@
 				F7245927289BB59300474787 /* ThreadSafeDictionary.swift in Sources */,
 				2C33C48223E2C475005F963B /* NotificationService.swift in Sources */,
 				AF4BF617275629E20081CEEF /* NCManageDatabase+Account.swift in Sources */,
+				F7BF9D872934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */,
 				D575039F27146F93008DC9DC /* String+Extensions.swift in Sources */,
 				F73D5E4A246DE09200DF6467 /* NCElementsJSON.swift in Sources */,
 				F79B646326CA661600838ACA /* UIControl+Extensions.swift in Sources */,
@@ -2835,6 +2844,7 @@
 				F7245925289BB59100474787 /* ThreadSafeDictionary.swift in Sources */,
 				F73D5E48246DE09200DF6467 /* NCElementsJSON.swift in Sources */,
 				F7EDE4E5262D7BBE00414FE6 /* NCSectionHeaderFooter.swift in Sources */,
+				F7BF9D852934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */,
 				F79EC78926316AC4004E59D6 /* NCPopupViewController.swift in Sources */,
 				F7C30DFB291BCF790017149B /* NCNetworkingE2EECreateFolder.swift in Sources */,
 				AF4BF61F27562B3F0081CEEF /* NCManageDatabase+Activity.swift in Sources */,
@@ -2914,6 +2924,7 @@
 				F783030028B4C45800B84583 /* NCGlobal.swift in Sources */,
 				F793E59D28B761E7005E4B02 /* NCNetworking.swift in Sources */,
 				F78302FC28B4C3F300B84583 /* NCElementsJSON.swift in Sources */,
+				F7BF9D832934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */,
 				F783030628B4C51E00B84583 /* String+Extensions.swift in Sources */,
 				F77ED59328C9CEA000E24ED0 /* ToolbarWidgetProvider.swift in Sources */,
 				F72A17D828B221E300F3F159 /* DashboardWidgetView.swift in Sources */,
@@ -2956,6 +2967,7 @@
 				AF4BF61B27562A4B0081CEEF /* NCManageDatabase+Metadata.swift in Sources */,
 				F70460542499095400BB98A7 /* NotificationCenter+MainThread.swift in Sources */,
 				F78A10C329322E8A008499B8 /* NCManageDatabase+Directory.swift in Sources */,
+				F7BF9D862934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */,
 				F7E98C1827E0D0FC001F9F19 /* NCManageDatabase+Video.swift in Sources */,
 				F785EEA42461A4A600B3F945 /* NCUtility.swift in Sources */,
 				F79B646226CA661600838ACA /* UIControl+Extensions.swift in Sources */,
@@ -3026,6 +3038,7 @@
 				F749C10C23C4A5340027D966 /* NCIntroViewController.swift in Sources */,
 				F710D2022405826100A6033D /* NCViewer+Menu.swift in Sources */,
 				F77A697D250A0FBC00FF1708 /* NCCollectionViewCommon+Menu.swift in Sources */,
+				F7BF9D822934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */,
 				AF7E504E27A2D8FF00B5E4AF /* UIBarButton+Extension.swift in Sources */,
 				F78A10BF29322E8A008499B8 /* NCManageDatabase+Directory.swift in Sources */,
 				F704B5E92430C0B800632F5F /* NCCreateFormUploadConflictCell.swift in Sources */,
@@ -3167,6 +3180,7 @@
 				F7A8D74328F1826F008BBE1C /* String+Extensions.swift in Sources */,
 				F7A8D73728F17E1E008BBE1C /* NCManageDatabase+Account.swift in Sources */,
 				F7A8D73B28F17E2C008BBE1C /* NCElementsJSON.swift in Sources */,
+				F7BF9D842934CA21009EE9A6 /* NCManageDatabase+LayoutForView.swift in Sources */,
 				F7A8D73C28F181BC008BBE1C /* NCBrand.swift in Sources */,
 				F7A8D74228F18261008BBE1C /* NCUtility.swift in Sources */,
 				F7A8D73A28F17E28008BBE1C /* NCManageDatabase+Video.swift in Sources */,

+ 0 - 301
iOSClient/Data/NCDatabase.swift

@@ -30,154 +30,6 @@ protocol DateCompareable {
     var dateKey: Date { get }
 }
 
-class tableAccount: Object, NCUserBaseUrl {
-
-    @objc dynamic var account = ""
-    @objc dynamic var active: Bool = false
-    @objc dynamic var address = ""
-    @objc dynamic var alias = ""
-    @objc dynamic var autoUpload: Bool = false
-    @objc dynamic var autoUploadCreateSubfolder: Bool = false
-    @objc dynamic var autoUploadDirectory = ""
-    @objc dynamic var autoUploadFileName = ""
-    @objc dynamic var autoUploadFull: Bool = false
-    @objc dynamic var autoUploadImage: Bool = false
-    @objc dynamic var autoUploadVideo: Bool = false
-    @objc dynamic var autoUploadWWAnPhoto: Bool = false
-    @objc dynamic var autoUploadWWAnVideo: Bool = false
-    @objc dynamic var backend = ""
-    @objc dynamic var backendCapabilitiesSetDisplayName: Bool = false
-    @objc dynamic var backendCapabilitiesSetPassword: Bool = false
-    @objc dynamic var businessSize: String = ""
-    @objc dynamic var businessType = ""
-    @objc dynamic var city = ""
-    @objc dynamic var country = ""
-    @objc dynamic var displayName = ""
-    @objc dynamic var email = ""
-    @objc dynamic var enabled: Bool = false
-    @objc dynamic var groups = ""
-    @objc dynamic var language = ""
-    @objc dynamic var lastLogin: Int64 = 0
-    @objc dynamic var locale = ""
-    @objc dynamic var mediaPath = ""
-    @objc dynamic var organisation = ""
-    @objc dynamic var password = ""
-    @objc dynamic var phone = ""
-    @objc dynamic var quota: Int64 = 0
-    @objc dynamic var quotaFree: Int64 = 0
-    @objc dynamic var quotaRelative: Double = 0
-    @objc dynamic var quotaTotal: Int64 = 0
-    @objc dynamic var quotaUsed: Int64 = 0
-    @objc dynamic var role = ""
-    @objc dynamic var storageLocation = ""
-    @objc dynamic var subadmin = ""
-    @objc dynamic var twitter = ""
-    @objc dynamic var urlBase = ""
-    @objc dynamic var user = ""
-    @objc dynamic var userId = ""
-    @objc dynamic var userStatusClearAt: NSDate?
-    @objc dynamic var userStatusIcon: String?
-    @objc dynamic var userStatusMessage: String?
-    @objc dynamic var userStatusMessageId: String?
-    @objc dynamic var userStatusMessageIsPredefined: Bool = false
-    @objc dynamic var userStatusStatus: String?
-    @objc dynamic var userStatusStatusIsUserDefined: Bool = false
-    @objc dynamic var website = ""
-    @objc dynamic var zip = ""
-
-    // HC
-    @objc dynamic var hcIsTrial: Bool = false
-    @objc dynamic var hcTrialExpired: Bool = false
-    @objc dynamic var hcTrialRemainingSec: Int64 = 0
-    @objc dynamic var hcTrialEndTime: NSDate?
-    @objc dynamic var hcAccountRemoveExpired: Bool = false
-    @objc dynamic var hcAccountRemoveRemainingSec: Int64 = 0
-    @objc dynamic var hcAccountRemoveTime: NSDate?
-    @objc dynamic var hcNextGroupExpirationGroup = ""
-    @objc dynamic var hcNextGroupExpirationGroupExpired: Bool = false
-    @objc dynamic var hcNextGroupExpirationExpiresTime: NSDate?
-    @objc dynamic var hcNextGroupExpirationExpires = ""
-
-    override static func primaryKey() -> String {
-        return "account"
-    }
-}
-
-class tableActivity: Object, DateCompareable {
-    var dateKey: Date { date as Date }
-
-    @objc dynamic var account = ""
-    @objc dynamic var idPrimaryKey = ""
-    @objc dynamic var action = "Activity"
-    @objc dynamic var date = NSDate()
-    @objc dynamic var idActivity: Int = 0
-    @objc dynamic var app = ""
-    @objc dynamic var type = ""
-    @objc dynamic var user = ""
-    @objc dynamic var subject = ""
-    @objc dynamic var subjectRich = ""
-    let subjectRichItem = List<tableActivitySubjectRich>()
-    @objc dynamic var icon = ""
-    @objc dynamic var link = ""
-    @objc dynamic var message = ""
-    @objc dynamic var objectType = ""
-    @objc dynamic var objectId: Int = 0
-    @objc dynamic var objectName = ""
-    @objc dynamic var note = ""
-    @objc dynamic var selector = ""
-    @objc dynamic var verbose: Bool = false
-
-    override static func primaryKey() -> String {
-        return "idPrimaryKey"
-    }
-}
-
-class tableActivityLatestId: Object {
-
-    @objc dynamic var account = ""
-    @objc dynamic var activityFirstKnown: Int = 0
-    @objc dynamic var activityLastGiven: Int = 0
-
-    override static func primaryKey() -> String {
-        return "account"
-    }
-}
-
-class tableActivityPreview: Object {
-
-    @objc dynamic var account = ""
-    @objc dynamic var filename = ""
-    @objc dynamic var idPrimaryKey = ""
-    @objc dynamic var idActivity: Int = 0
-    @objc dynamic var source = ""
-    @objc dynamic var link = ""
-    @objc dynamic var mimeType = ""
-    @objc dynamic var fileId: Int = 0
-    @objc dynamic var view = ""
-    @objc dynamic var isMimeTypeIcon: Bool = false
-
-    override static func primaryKey() -> String {
-        return "idPrimaryKey"
-    }
-}
-
-class tableActivitySubjectRich: Object {
-
-    @objc dynamic var account = ""
-    @objc dynamic var idActivity: Int = 0
-    @objc dynamic var idPrimaryKey = ""
-    @objc dynamic var id = ""
-    @objc dynamic var key = ""
-    @objc dynamic var link = ""
-    @objc dynamic var name = ""
-    @objc dynamic var path = ""
-    @objc dynamic var type = ""
-
-    override static func primaryKey() -> String {
-        return "idPrimaryKey"
-    }
-}
-
 class tableAvatar: Object {
 
     @objc dynamic var date = NSDate()
@@ -246,29 +98,6 @@ class tableDirectEditingCreators: Object {
     @objc dynamic var templates: Int = 0
 }
 
-class tableDashboardWidget: Object {
-    
-    @Persisted(primaryKey: true) var index = ""
-    @Persisted var account = ""
-    @Persisted var id = ""
-    @Persisted var title = ""
-    @Persisted var order: Int = 0
-    @Persisted var iconClass: String?
-    @Persisted var iconUrl: String?
-    @Persisted var widgetUrl: String?
-    @Persisted var itemIconsRound: Bool = false
-}
-
-class tableDashboardWidgetButton: Object {
-
-    @Persisted(primaryKey: true) var index = ""
-    @Persisted var account = ""
-    @Persisted var id = ""
-    @Persisted var type = ""
-    @Persisted var text = ""
-    @Persisted var link = ""
-}
-
 class tableDirectEditingEditors: Object {
 
     @objc dynamic var account = ""
@@ -279,25 +108,6 @@ class tableDirectEditingEditors: Object {
     @objc dynamic var secure: Int = 0
 }
 
-class tableDirectory: Object {
-
-    @objc dynamic var account = ""
-    @objc dynamic var colorFolder: String?
-    @objc dynamic var e2eEncrypted: Bool = false
-    @objc dynamic var etag = ""
-    @objc dynamic var favorite: Bool = false
-    @objc dynamic var fileId = ""
-    @objc dynamic var ocId = ""
-    @objc dynamic var offline: Bool = false
-    @objc dynamic var permissions = ""
-    @objc dynamic var richWorkspace: String?
-    @objc dynamic var serverUrl = ""
-
-    override static func primaryKey() -> String {
-        return "ocId"
-    }
-}
-
 class tableE2eEncryption: Object {
 
     @objc dynamic var account = ""
@@ -372,99 +182,6 @@ class tableLocalFile: Object {
     }
 }
 
-class tableMetadata: Object, NCUserBaseUrl {
-    override func isEqual(_ object: Any?) -> Bool {
-        if let object = object as? tableMetadata {
-            return self.fileId == object.fileId && self.account == object.account
-                   && self.path == object.path && self.fileName == object.fileName
-        } else {
-            return false
-        }
-    }
-
-    @objc dynamic var account = ""
-    @objc dynamic var assetLocalIdentifier = ""
-    @objc dynamic var checksums = ""
-    @objc dynamic var chunk: Bool = false
-    @objc dynamic var classFile = ""
-    @objc dynamic var commentsUnread: Bool = false
-    @objc dynamic var contentType = ""
-    @objc dynamic var creationDate = NSDate()
-    @objc dynamic var dataFingerprint = ""
-    @objc dynamic var date = NSDate()
-    @objc dynamic var directory: Bool = false
-    @objc dynamic var deleteAssetLocalIdentifier: Bool = false
-    @objc dynamic var downloadURL = ""
-    @objc dynamic var e2eEncrypted: Bool = false
-    @objc dynamic var edited: Bool = false
-    @objc dynamic var etag = ""
-    @objc dynamic var etagResource = ""
-    @objc dynamic var favorite: Bool = false
-    @objc dynamic var fileId = ""
-    @objc dynamic var fileName = ""
-    @objc dynamic var fileNameView = ""
-    @objc dynamic var hasPreview: Bool = false
-    @objc dynamic var iconName = ""
-    @objc dynamic var iconUrl = ""
-    @objc dynamic var isExtractFile: Bool = false
-    @objc dynamic var livePhoto: Bool = false
-    @objc dynamic var mountType = ""
-    @objc dynamic var name = ""                                             // for unifiedSearch is the provider.id
-    @objc dynamic var note = ""
-    @objc dynamic var ocId = ""
-    @objc dynamic var ownerId = ""
-    @objc dynamic var ownerDisplayName = ""
-    @objc public var lock = false
-    @objc public var lockOwner = ""
-    @objc public var lockOwnerEditor = ""
-    @objc public var lockOwnerType = 0
-    @objc public var lockOwnerDisplayName = ""
-    @objc public var lockTime: Date?
-    @objc public var lockTimeOut: Date?
-    @objc dynamic var path = ""
-    @objc dynamic var permissions = ""
-    @objc dynamic var quotaUsedBytes: Int64 = 0
-    @objc dynamic var quotaAvailableBytes: Int64 = 0
-    @objc dynamic var resourceType = ""
-    @objc dynamic var richWorkspace: String?
-    @objc dynamic var serverUrl = ""
-    @objc dynamic var session = ""
-    @objc dynamic var sessionError = ""
-    @objc dynamic var sessionSelector = ""
-    @objc dynamic var sessionTaskIdentifier: Int = 0
-    @objc dynamic var sharePermissionsCollaborationServices: Int = 0
-    let sharePermissionsCloudMesh = List<String>()
-    let shareType = List<Int>()
-    @objc dynamic var size: Int64 = 0
-    @objc dynamic var status: Int = 0
-    @objc dynamic var subline: String?
-    @objc dynamic var trashbinFileName = ""
-    @objc dynamic var trashbinOriginalLocation = ""
-    @objc dynamic var trashbinDeletionTime = NSDate()
-    @objc dynamic var uploadDate = NSDate()
-    @objc dynamic var url = ""
-    @objc dynamic var urlBase = ""
-    @objc dynamic var user = ""
-    @objc dynamic var userId = ""
-
-    override static func primaryKey() -> String {
-        return "ocId"
-    }
-}
-
-extension tableMetadata {
-    var fileExtension: String { (fileNameView as NSString).pathExtension }
-
-    var isPrintable: Bool {
-        classFile == NKCommon.typeClassFile.image.rawValue || ["application/pdf", "com.adobe.pdf"].contains(contentType) || contentType.hasPrefix("text/")
-    }
-
-    /// Returns false if the user is lokced out of the file. I.e. The file is locked but by somone else
-    func canUnlock(as user: String) -> Bool {
-        return !lock || (lockOwner == user && lockOwnerType == 0)
-    }
-}
-
 class tablePhotoLibrary: Object {
 
     @objc dynamic var account = ""
@@ -578,21 +295,3 @@ class tableUserStatus: Object {
     @objc dynamic var status: String?
     @objc dynamic var userId: String?
 }
-
-class tableVideo: Object {
-
-    @objc dynamic var account = ""
-    @objc dynamic var duration: Int64 = 0
-    @objc dynamic var ocId = ""
-    @objc dynamic var time: Int64 = 0
-    @objc dynamic var codecNameVideo: String?
-    @objc dynamic var codecNameAudio: String?
-    @objc dynamic var codecAudioChannelLayout: String?
-    @objc dynamic var codecAudioLanguage: String?
-    @objc dynamic var codecMaxCompatibility: Bool = false
-    @objc dynamic var codecQuality: String?
-
-    override static func primaryKey() -> String {
-        return "ocId"
-    }
-}

+ 73 - 0
iOSClient/Data/NCManageDatabase+Account.swift

@@ -25,6 +25,79 @@ import Foundation
 import RealmSwift
 import NextcloudKit
 
+class tableAccount: Object, NCUserBaseUrl {
+
+    @objc dynamic var account = ""
+    @objc dynamic var active: Bool = false
+    @objc dynamic var address = ""
+    @objc dynamic var alias = ""
+    @objc dynamic var autoUpload: Bool = false
+    @objc dynamic var autoUploadCreateSubfolder: Bool = false
+    @objc dynamic var autoUploadDirectory = ""
+    @objc dynamic var autoUploadFileName = ""
+    @objc dynamic var autoUploadFull: Bool = false
+    @objc dynamic var autoUploadImage: Bool = false
+    @objc dynamic var autoUploadVideo: Bool = false
+    @objc dynamic var autoUploadWWAnPhoto: Bool = false
+    @objc dynamic var autoUploadWWAnVideo: Bool = false
+    @objc dynamic var backend = ""
+    @objc dynamic var backendCapabilitiesSetDisplayName: Bool = false
+    @objc dynamic var backendCapabilitiesSetPassword: Bool = false
+    @objc dynamic var businessSize: String = ""
+    @objc dynamic var businessType = ""
+    @objc dynamic var city = ""
+    @objc dynamic var country = ""
+    @objc dynamic var displayName = ""
+    @objc dynamic var email = ""
+    @objc dynamic var enabled: Bool = false
+    @objc dynamic var groups = ""
+    @objc dynamic var language = ""
+    @objc dynamic var lastLogin: Int64 = 0
+    @objc dynamic var locale = ""
+    @objc dynamic var mediaPath = ""
+    @objc dynamic var organisation = ""
+    @objc dynamic var password = ""
+    @objc dynamic var phone = ""
+    @objc dynamic var quota: Int64 = 0
+    @objc dynamic var quotaFree: Int64 = 0
+    @objc dynamic var quotaRelative: Double = 0
+    @objc dynamic var quotaTotal: Int64 = 0
+    @objc dynamic var quotaUsed: Int64 = 0
+    @objc dynamic var role = ""
+    @objc dynamic var storageLocation = ""
+    @objc dynamic var subadmin = ""
+    @objc dynamic var twitter = ""
+    @objc dynamic var urlBase = ""
+    @objc dynamic var user = ""
+    @objc dynamic var userId = ""
+    @objc dynamic var userStatusClearAt: NSDate?
+    @objc dynamic var userStatusIcon: String?
+    @objc dynamic var userStatusMessage: String?
+    @objc dynamic var userStatusMessageId: String?
+    @objc dynamic var userStatusMessageIsPredefined: Bool = false
+    @objc dynamic var userStatusStatus: String?
+    @objc dynamic var userStatusStatusIsUserDefined: Bool = false
+    @objc dynamic var website = ""
+    @objc dynamic var zip = ""
+
+    // HC
+    @objc dynamic var hcIsTrial: Bool = false
+    @objc dynamic var hcTrialExpired: Bool = false
+    @objc dynamic var hcTrialRemainingSec: Int64 = 0
+    @objc dynamic var hcTrialEndTime: NSDate?
+    @objc dynamic var hcAccountRemoveExpired: Bool = false
+    @objc dynamic var hcAccountRemoveRemainingSec: Int64 = 0
+    @objc dynamic var hcAccountRemoveTime: NSDate?
+    @objc dynamic var hcNextGroupExpirationGroup = ""
+    @objc dynamic var hcNextGroupExpirationGroupExpired: Bool = false
+    @objc dynamic var hcNextGroupExpirationExpiresTime: NSDate?
+    @objc dynamic var hcNextGroupExpirationExpires = ""
+
+    override static func primaryKey() -> String {
+        return "account"
+    }
+}
+
 extension NCManageDatabase {
 
     @objc func addAccount(_ account: String, urlBase: String, user: String, password: String) {

+ 75 - 0
iOSClient/Data/NCManageDatabase+Activity.swift

@@ -26,6 +26,81 @@ import RealmSwift
 import NextcloudKit
 import SwiftyJSON
 
+class tableActivity: Object, DateCompareable {
+    var dateKey: Date { date as Date }
+
+    @objc dynamic var account = ""
+    @objc dynamic var idPrimaryKey = ""
+    @objc dynamic var action = "Activity"
+    @objc dynamic var date = NSDate()
+    @objc dynamic var idActivity: Int = 0
+    @objc dynamic var app = ""
+    @objc dynamic var type = ""
+    @objc dynamic var user = ""
+    @objc dynamic var subject = ""
+    @objc dynamic var subjectRich = ""
+    let subjectRichItem = List<tableActivitySubjectRich>()
+    @objc dynamic var icon = ""
+    @objc dynamic var link = ""
+    @objc dynamic var message = ""
+    @objc dynamic var objectType = ""
+    @objc dynamic var objectId: Int = 0
+    @objc dynamic var objectName = ""
+    @objc dynamic var note = ""
+    @objc dynamic var selector = ""
+    @objc dynamic var verbose: Bool = false
+
+    override static func primaryKey() -> String {
+        return "idPrimaryKey"
+    }
+}
+
+class tableActivityLatestId: Object {
+
+    @objc dynamic var account = ""
+    @objc dynamic var activityFirstKnown: Int = 0
+    @objc dynamic var activityLastGiven: Int = 0
+
+    override static func primaryKey() -> String {
+        return "account"
+    }
+}
+
+class tableActivityPreview: Object {
+
+    @objc dynamic var account = ""
+    @objc dynamic var filename = ""
+    @objc dynamic var idPrimaryKey = ""
+    @objc dynamic var idActivity: Int = 0
+    @objc dynamic var source = ""
+    @objc dynamic var link = ""
+    @objc dynamic var mimeType = ""
+    @objc dynamic var fileId: Int = 0
+    @objc dynamic var view = ""
+    @objc dynamic var isMimeTypeIcon: Bool = false
+
+    override static func primaryKey() -> String {
+        return "idPrimaryKey"
+    }
+}
+
+class tableActivitySubjectRich: Object {
+
+    @objc dynamic var account = ""
+    @objc dynamic var idActivity: Int = 0
+    @objc dynamic var idPrimaryKey = ""
+    @objc dynamic var id = ""
+    @objc dynamic var key = ""
+    @objc dynamic var link = ""
+    @objc dynamic var name = ""
+    @objc dynamic var path = ""
+    @objc dynamic var type = ""
+
+    override static func primaryKey() -> String {
+        return "idPrimaryKey"
+    }
+}
+
 extension NCManageDatabase {
     
     @objc func addActivity(_ activities: [NKActivity], account: String) {

+ 23 - 0
iOSClient/Data/NCManageDatabase+DashboardWidget.swift

@@ -25,6 +25,29 @@ import Foundation
 import RealmSwift
 import NextcloudKit
 
+class tableDashboardWidget: Object {
+
+    @Persisted(primaryKey: true) var index = ""
+    @Persisted var account = ""
+    @Persisted var id = ""
+    @Persisted var title = ""
+    @Persisted var order: Int = 0
+    @Persisted var iconClass: String?
+    @Persisted var iconUrl: String?
+    @Persisted var widgetUrl: String?
+    @Persisted var itemIconsRound: Bool = false
+}
+
+class tableDashboardWidgetButton: Object {
+
+    @Persisted(primaryKey: true) var index = ""
+    @Persisted var account = ""
+    @Persisted var id = ""
+    @Persisted var type = ""
+    @Persisted var text = ""
+    @Persisted var link = ""
+}
+
 extension NCManageDatabase {
 
     func getDashboardWidget(account: String, id: String) -> (tableDashboardWidget?, [tableDashboardWidgetButton]?) {

+ 19 - 0
iOSClient/Data/NCManageDatabase+Directory.swift

@@ -25,6 +25,25 @@ import Foundation
 import RealmSwift
 import NextcloudKit
 
+class tableDirectory: Object {
+
+    @objc dynamic var account = ""
+    @objc dynamic var colorFolder: String?
+    @objc dynamic var e2eEncrypted: Bool = false
+    @objc dynamic var etag = ""
+    @objc dynamic var favorite: Bool = false
+    @objc dynamic var fileId = ""
+    @objc dynamic var ocId = ""
+    @objc dynamic var offline: Bool = false
+    @objc dynamic var permissions = ""
+    @objc dynamic var richWorkspace: String?
+    @objc dynamic var serverUrl = ""
+
+    override static func primaryKey() -> String {
+        return "ocId"
+    }
+}
+
 extension NCManageDatabase {
 
     @objc func addDirectory(encrypted: Bool, favorite: Bool, ocId: String, fileId: String, etag: String? = nil, permissions: String? = nil, serverUrl: String, account: String) {

+ 103 - 0
iOSClient/Data/NCManageDatabase+LayoutForView.swift

@@ -0,0 +1,103 @@
+//
+//  NCManageDatabase+LayoutForView.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 28/11/22.
+//  Copyright © 2022 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) 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 General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+import Foundation
+import RealmSwift
+import NextcloudKit
+
+class NCDBLayoutForView: Object {
+
+    @Persisted(primaryKey: true) var index = ""
+    @Persisted var account = ""
+    @Persisted var keyStore = ""
+    @Persisted var layout: String = NCGlobal.shared.layoutList
+    @Persisted var sort: String = "fileName"
+    @Persisted var ascending: Bool = true
+    @Persisted var groupBy: String = "none"
+    @Persisted var directoryOnTop: Bool = true
+    @Persisted var titleButtonHeader: String = "_sorted_by_name_a_z_"
+    @Persisted var itemForLine: Int = 3
+}
+
+extension NCManageDatabase {
+
+    @discardableResult
+    func setLayoutForView(account: String, keyStore: String, layout: String? = nil, sort: String? = nil, ascending: Bool? = nil, groupBy: String? = nil, directoryOnTop: Bool? = nil, titleButtonHeader: String? = nil, itemForLine: Int? = nil) -> NCDBLayoutForView? {
+
+        let realm = try! Realm()
+        var addObject = NCDBLayoutForView()
+        let index = account + " " + keyStore
+
+        do {
+            try realm.write {
+                if let result = realm.objects(NCDBLayoutForView.self).filter("index == %@", index).first {
+                    addObject = result
+                }
+                addObject.index = index
+                addObject.account = account
+                addObject.keyStore = keyStore
+                if let layout = layout {
+                    addObject.layout = layout
+                }
+                if let sort = sort {
+                    addObject.sort = sort
+                }
+                if let sort = sort {
+                    addObject.sort = sort
+                }
+                if let ascending = ascending {
+                    addObject.ascending = ascending
+                }
+                if let groupBy = groupBy {
+                    addObject.groupBy = groupBy
+                }
+                if let directoryOnTop = directoryOnTop {
+                    addObject.directoryOnTop = directoryOnTop
+                }
+                if let titleButtonHeader = titleButtonHeader {
+                    addObject.titleButtonHeader = titleButtonHeader
+                }
+                if let itemForLine = itemForLine {
+                    addObject.itemForLine = itemForLine
+                }
+                realm.add(addObject, update: .all)
+            }
+        } catch let error {
+            NKCommon.shared.writeLog("Could not write to database: \(error)")
+        }
+
+        return NCDBLayoutForView.init(value: addObject)
+    }
+
+    func getLayoutForView(account: String, keyStore: String) -> NCDBLayoutForView? {
+
+        let realm = try! Realm()
+        let index = account + " " + keyStore
+
+        if let result = realm.objects(NCDBLayoutForView.self).filter("index == %@", index).first {
+            return NCDBLayoutForView.init(value: result)
+        } else {
+            return setLayoutForView(account: account, keyStore: keyStore)
+        }
+    }
+}

+ 93 - 0
iOSClient/Data/NCManageDatabase+Metadata.swift

@@ -25,6 +25,99 @@ import Foundation
 import RealmSwift
 import NextcloudKit
 
+class tableMetadata: Object, NCUserBaseUrl {
+    override func isEqual(_ object: Any?) -> Bool {
+        if let object = object as? tableMetadata {
+            return self.fileId == object.fileId && self.account == object.account
+                   && self.path == object.path && self.fileName == object.fileName
+        } else {
+            return false
+        }
+    }
+
+    @objc dynamic var account = ""
+    @objc dynamic var assetLocalIdentifier = ""
+    @objc dynamic var checksums = ""
+    @objc dynamic var chunk: Bool = false
+    @objc dynamic var classFile = ""
+    @objc dynamic var commentsUnread: Bool = false
+    @objc dynamic var contentType = ""
+    @objc dynamic var creationDate = NSDate()
+    @objc dynamic var dataFingerprint = ""
+    @objc dynamic var date = NSDate()
+    @objc dynamic var directory: Bool = false
+    @objc dynamic var deleteAssetLocalIdentifier: Bool = false
+    @objc dynamic var downloadURL = ""
+    @objc dynamic var e2eEncrypted: Bool = false
+    @objc dynamic var edited: Bool = false
+    @objc dynamic var etag = ""
+    @objc dynamic var etagResource = ""
+    @objc dynamic var favorite: Bool = false
+    @objc dynamic var fileId = ""
+    @objc dynamic var fileName = ""
+    @objc dynamic var fileNameView = ""
+    @objc dynamic var hasPreview: Bool = false
+    @objc dynamic var iconName = ""
+    @objc dynamic var iconUrl = ""
+    @objc dynamic var isExtractFile: Bool = false
+    @objc dynamic var livePhoto: Bool = false
+    @objc dynamic var mountType = ""
+    @objc dynamic var name = ""                                             // for unifiedSearch is the provider.id
+    @objc dynamic var note = ""
+    @objc dynamic var ocId = ""
+    @objc dynamic var ownerId = ""
+    @objc dynamic var ownerDisplayName = ""
+    @objc public var lock = false
+    @objc public var lockOwner = ""
+    @objc public var lockOwnerEditor = ""
+    @objc public var lockOwnerType = 0
+    @objc public var lockOwnerDisplayName = ""
+    @objc public var lockTime: Date?
+    @objc public var lockTimeOut: Date?
+    @objc dynamic var path = ""
+    @objc dynamic var permissions = ""
+    @objc dynamic var quotaUsedBytes: Int64 = 0
+    @objc dynamic var quotaAvailableBytes: Int64 = 0
+    @objc dynamic var resourceType = ""
+    @objc dynamic var richWorkspace: String?
+    @objc dynamic var serverUrl = ""
+    @objc dynamic var session = ""
+    @objc dynamic var sessionError = ""
+    @objc dynamic var sessionSelector = ""
+    @objc dynamic var sessionTaskIdentifier: Int = 0
+    @objc dynamic var sharePermissionsCollaborationServices: Int = 0
+    let sharePermissionsCloudMesh = List<String>()
+    let shareType = List<Int>()
+    @objc dynamic var size: Int64 = 0
+    @objc dynamic var status: Int = 0
+    @objc dynamic var subline: String?
+    @objc dynamic var trashbinFileName = ""
+    @objc dynamic var trashbinOriginalLocation = ""
+    @objc dynamic var trashbinDeletionTime = NSDate()
+    @objc dynamic var uploadDate = NSDate()
+    @objc dynamic var url = ""
+    @objc dynamic var urlBase = ""
+    @objc dynamic var user = ""
+    @objc dynamic var userId = ""
+
+    override static func primaryKey() -> String {
+        return "ocId"
+    }
+}
+
+extension tableMetadata {
+    var fileExtension: String { (fileNameView as NSString).pathExtension }
+
+    var isPrintable: Bool {
+        classFile == NKCommon.typeClassFile.image.rawValue || ["application/pdf", "com.adobe.pdf"].contains(contentType) || contentType.hasPrefix("text/")
+    }
+
+    /// Returns false if the user is lokced out of the file. I.e. The file is locked but by somone else
+    func canUnlock(as user: String) -> Bool {
+        return !lock || (lockOwner == user && lockOwnerType == 0)
+    }
+}
+
 extension NCManageDatabase {
 
     @objc func copyObject(metadata: tableMetadata) -> tableMetadata {

+ 18 - 0
iOSClient/Data/NCManageDatabase+Video.swift

@@ -25,6 +25,24 @@ import Foundation
 import RealmSwift
 import NextcloudKit
 
+class tableVideo: Object {
+
+    @objc dynamic var account = ""
+    @objc dynamic var duration: Int64 = 0
+    @objc dynamic var ocId = ""
+    @objc dynamic var time: Int64 = 0
+    @objc dynamic var codecNameVideo: String?
+    @objc dynamic var codecNameAudio: String?
+    @objc dynamic var codecAudioChannelLayout: String?
+    @objc dynamic var codecAudioLanguage: String?
+    @objc dynamic var codecMaxCompatibility: Bool = false
+    @objc dynamic var codecQuality: String?
+
+    override static func primaryKey() -> String {
+        return "ocId"
+    }
+}
+
 extension NCManageDatabase {
 
     func addVideoTime(metadata: tableMetadata, time: CMTime?, durationTime: CMTime?) {

+ 1 - 1
iOSClient/NCGlobal.swift

@@ -122,7 +122,7 @@ class NCGlobal: NSObject {
     // Database Realm
     //
     let databaseDefault                             = "nextcloud.realm"
-    let databaseSchemaVersion: UInt64               = 256
+    let databaseSchemaVersion: UInt64               = 257
     let fileAccounts: String                        = "accounts.json"
 
     // Intro selector