NCManageDatabase.swift 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734
  1. //
  2. // NCManageDatabase.swift
  3. // Nextcloud
  4. //
  5. // Created by Marino Faggiana on 06/05/17.
  6. // Copyright © 2017 Marino Faggiana. All rights reserved.
  7. //
  8. // Author Marino Faggiana <marino.faggiana@nextcloud.com>
  9. // Author Henrik Storch <henrik.storch@nextcloud.com>
  10. //
  11. // This program is free software: you can redistribute it and/or modify
  12. // it under the terms of the GNU General Public License as published by
  13. // the Free Software Foundation, either version 3 of the License, or
  14. // (at your option) any later version.
  15. //
  16. // This program is distributed in the hope that it will be useful,
  17. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. // GNU General Public License for more details.
  20. //
  21. // You should have received a copy of the GNU General Public License
  22. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. //
  24. import UIKit
  25. import RealmSwift
  26. import NCCommunication
  27. import SwiftyJSON
  28. import CoreMedia
  29. class NCManageDatabase: NSObject {
  30. @objc static let shared: NCManageDatabase = {
  31. let instance = NCManageDatabase()
  32. return instance
  33. }()
  34. override init() {
  35. let dirGroup = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.shared.capabilitiesGroups)
  36. let databaseFilePath = dirGroup?.appendingPathComponent(NCGlobal.shared.appDatabaseNextcloud + "/" + NCGlobal.shared.databaseDefault)
  37. let bundleUrl: URL = Bundle.main.bundleURL
  38. let bundlePathExtension: String = bundleUrl.pathExtension
  39. let isAppex: Bool = bundlePathExtension == "appex"
  40. // Disable file protection for directory DB
  41. // https://docs.mongodb.com/realm/sdk/ios/examples/configure-and-open-a-realm/#std-label-ios-open-a-local-realm
  42. if let folderPathURL = dirGroup?.appendingPathComponent(NCGlobal.shared.appDatabaseNextcloud) {
  43. let folderPath = folderPathURL.path
  44. do {
  45. try FileManager.default.setAttributes([FileAttributeKey.protectionKey: FileProtectionType.completeUntilFirstUserAuthentication], ofItemAtPath: folderPath)
  46. } catch {
  47. print("Dangerous error")
  48. }
  49. }
  50. if isAppex {
  51. // App Extension config
  52. let config = Realm.Configuration(
  53. fileURL: dirGroup?.appendingPathComponent(NCGlobal.shared.appDatabaseNextcloud + "/" + NCGlobal.shared.databaseDefault),
  54. schemaVersion: NCGlobal.shared.databaseSchemaVersion,
  55. objectTypes: [tableMetadata.self, tableLocalFile.self, tableDirectory.self, tableTag.self, tableAccount.self, tableCapabilities.self, tableE2eEncryption.self, tableE2eEncryptionLock.self, tableShare.self, tableChunk.self, tableAvatar.self]
  56. )
  57. Realm.Configuration.defaultConfiguration = config
  58. } else {
  59. // App config
  60. let configCompact = Realm.Configuration(
  61. fileURL: databaseFilePath,
  62. schemaVersion: NCGlobal.shared.databaseSchemaVersion,
  63. migrationBlock: { migration, oldSchemaVersion in
  64. if oldSchemaVersion < 61 {
  65. migration.deleteData(forType: tableShare.className())
  66. }
  67. if oldSchemaVersion < 74 {
  68. migration.enumerateObjects(ofType: tableLocalFile.className()) { oldObject, newObject in
  69. newObject!["ocId"] = oldObject!["fileID"]
  70. }
  71. migration.enumerateObjects(ofType: tableTrash.className()) { oldObject, newObject in
  72. newObject!["fileId"] = oldObject!["fileID"]
  73. }
  74. migration.enumerateObjects(ofType: tableTag.className()) { oldObject, newObject in
  75. newObject!["ocId"] = oldObject!["fileID"]
  76. }
  77. migration.enumerateObjects(ofType: tableE2eEncryptionLock.className()) { oldObject, newObject in
  78. newObject!["ocId"] = oldObject!["fileID"]
  79. }
  80. }
  81. if oldSchemaVersion < 87 {
  82. migration.deleteData(forType: tableActivity.className())
  83. migration.deleteData(forType: tableActivityPreview.className())
  84. migration.deleteData(forType: tableActivitySubjectRich.className())
  85. migration.deleteData(forType: tableExternalSites.className())
  86. migration.deleteData(forType: tableGPS.className())
  87. migration.deleteData(forType: tableTag.className())
  88. }
  89. if oldSchemaVersion < 120 {
  90. migration.deleteData(forType: tableCapabilities.className())
  91. migration.deleteData(forType: tableComments.className())
  92. }
  93. if oldSchemaVersion < 134 {
  94. migration.deleteData(forType: tableDirectEditingCreators.className())
  95. migration.deleteData(forType: tableDirectEditingEditors.className())
  96. migration.deleteData(forType: tableExternalSites.className())
  97. }
  98. if oldSchemaVersion < 141 {
  99. migration.enumerateObjects(ofType: tableAccount.className()) { oldObject, newObject in
  100. newObject!["urlBase"] = oldObject!["url"]
  101. }
  102. }
  103. if oldSchemaVersion < 162 {
  104. migration.enumerateObjects(ofType: tableAccount.className()) { oldObject, newObject in
  105. newObject!["userId"] = oldObject!["userID"]
  106. migration.deleteData(forType: tableMetadata.className())
  107. }
  108. }
  109. if oldSchemaVersion < 212 {
  110. migration.deleteData(forType: tableDirectory.className())
  111. migration.deleteData(forType: tableE2eEncryption.className())
  112. migration.deleteData(forType: tableE2eEncryptionLock.className())
  113. migration.deleteData(forType: tableMetadata.className())
  114. migration.deleteData(forType: tableShare.className())
  115. migration.deleteData(forType: tableTrash.className())
  116. migration.deleteData(forType: tableVideo.className())
  117. // Delete OLD avatar image
  118. if var pathUrl = CCUtility.getDirectoryGroup() {
  119. pathUrl.appendPathComponent(NCGlobal.shared.appUserData)
  120. do {
  121. let fileURLs = try FileManager.default.contentsOfDirectory(at: pathUrl, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
  122. for fileURL in fileURLs {
  123. try FileManager.default.removeItem(at: fileURL)
  124. }
  125. } catch { }
  126. }
  127. }
  128. if oldSchemaVersion < 222 && NCUtility.shared.SYSTEM_VERSION_LESS_THAN(version: "13") {
  129. migration.deleteData(forType: tableMetadata.className())
  130. migration.deleteData(forType: tableDirectory.className())
  131. }
  132. }, shouldCompactOnLaunch: { totalBytes, usedBytes in
  133. // totalBytes refers to the size of the file on disk in bytes (data + free space)
  134. // usedBytes refers to the number of bytes used by data in the file
  135. // Compact if the file is over 100MB in size and less than 50% 'used'
  136. let oneHundredMB = 100 * 1024 * 1024
  137. return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
  138. }
  139. )
  140. do {
  141. _ = try Realm(configuration: configCompact)
  142. } catch {
  143. if let databaseFilePath = databaseFilePath {
  144. do {
  145. #if !EXTENSION
  146. NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: NCGlobal.shared.dismissAfterSecondLong, type: NCContentPresenter.messageType.info, errorCode: NCGlobal.shared.errorInternalError, priority: .max)
  147. #endif
  148. try FileManager.default.removeItem(at: databaseFilePath)
  149. } catch {}
  150. }
  151. }
  152. let config = Realm.Configuration(
  153. fileURL: dirGroup?.appendingPathComponent(NCGlobal.shared.appDatabaseNextcloud + "/" + NCGlobal.shared.databaseDefault),
  154. schemaVersion: NCGlobal.shared.databaseSchemaVersion
  155. )
  156. Realm.Configuration.defaultConfiguration = config
  157. }
  158. // Verify Database, if corrupr remove it
  159. do {
  160. _ = try Realm()
  161. } catch {
  162. if let databaseFilePath = databaseFilePath {
  163. do {
  164. #if !EXTENSION
  165. NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: NCGlobal.shared.dismissAfterSecondLong, type: NCContentPresenter.messageType.info, errorCode: NCGlobal.shared.errorInternalError, priority: .max)
  166. #endif
  167. try FileManager.default.removeItem(at: databaseFilePath)
  168. } catch {}
  169. }
  170. }
  171. // Open Real
  172. _ = try! Realm()
  173. }
  174. // MARK: -
  175. // MARK: Utility Database
  176. @objc func clearTable(_ table: Object.Type, account: String? = nil) {
  177. let realm = try! Realm()
  178. do {
  179. try realm.safeWrite {
  180. var results: Results<Object>
  181. if let account = account {
  182. results = realm.objects(table).filter("account == %@", account)
  183. } else {
  184. results = realm.objects(table)
  185. }
  186. realm.delete(results)
  187. }
  188. } catch let error {
  189. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  190. }
  191. }
  192. @objc func clearDatabase(account: String?, removeAccount: Bool) {
  193. self.clearTable(tableActivity.self, account: account)
  194. self.clearTable(tableActivityLatestId.self, account: account)
  195. self.clearTable(tableActivityPreview.self, account: account)
  196. self.clearTable(tableActivitySubjectRich.self, account: account)
  197. self.clearTable(tableAvatar.self)
  198. self.clearTable(tableCapabilities.self, account: account)
  199. self.clearTable(tableChunk.self, account: account)
  200. self.clearTable(tableComments.self, account: account)
  201. self.clearTable(tableDirectEditingCreators.self, account: account)
  202. self.clearTable(tableDirectEditingEditors.self, account: account)
  203. self.clearTable(tableDirectory.self, account: account)
  204. self.clearTable(tableE2eEncryption.self, account: account)
  205. self.clearTable(tableE2eEncryptionLock.self, account: account)
  206. self.clearTable(tableExternalSites.self, account: account)
  207. self.clearTable(tableGPS.self, account: nil)
  208. self.clearTable(tableLocalFile.self, account: account)
  209. self.clearTable(tableMetadata.self, account: account)
  210. self.clearTable(tablePhotoLibrary.self, account: account)
  211. self.clearTable(tableShare.self, account: account)
  212. self.clearTable(tableTag.self, account: account)
  213. self.clearTable(tableTip.self)
  214. self.clearTable(tableTrash.self, account: account)
  215. self.clearTable(tableUserStatus.self, account: account)
  216. self.clearTable(tableVideo.self, account: account)
  217. if removeAccount {
  218. self.clearTable(tableAccount.self, account: account)
  219. }
  220. }
  221. @objc func removeDB() {
  222. let realmURL = Realm.Configuration.defaultConfiguration.fileURL!
  223. let realmURLs = [
  224. realmURL,
  225. realmURL.appendingPathExtension("lock"),
  226. realmURL.appendingPathExtension("note"),
  227. realmURL.appendingPathExtension("management")
  228. ]
  229. for URL in realmURLs {
  230. do {
  231. try FileManager.default.removeItem(at: URL)
  232. } catch let error {
  233. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  234. }
  235. }
  236. }
  237. @objc func getThreadConfined(_ object: Object) -> Any {
  238. // id tradeReference = [[NCManageDatabase shared] getThreadConfined:metadata];
  239. return ThreadSafeReference(to: object)
  240. }
  241. @objc func putThreadConfined(_ tableRef: Any) -> Object? {
  242. // tableMetadata *metadataThread = (tableMetadata *)[[NCManageDatabase shared] putThreadConfined:tradeReference];
  243. let realm = try! Realm()
  244. return realm.resolve(tableRef as! ThreadSafeReference<Object>)
  245. }
  246. @objc func isTableInvalidated(_ object: Object) -> Bool {
  247. return object.isInvalidated
  248. }
  249. // MARK: -
  250. // MARK: Table Avatar
  251. @objc func addAvatar(fileName: String, etag: String) {
  252. let realm = try! Realm()
  253. do {
  254. try realm.safeWrite {
  255. // Add new
  256. let addObject = tableAvatar()
  257. addObject.date = NSDate()
  258. addObject.etag = etag
  259. addObject.fileName = fileName
  260. addObject.loaded = true
  261. realm.add(addObject, update: .all)
  262. }
  263. } catch let error {
  264. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  265. }
  266. }
  267. func getTableAvatar(fileName: String) -> tableAvatar? {
  268. let realm = try! Realm()
  269. guard let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first else {
  270. return nil
  271. }
  272. return tableAvatar.init(value: result)
  273. }
  274. func clearAllAvatarLoaded() {
  275. let realm = try! Realm()
  276. do {
  277. try realm.safeWrite {
  278. let results = realm.objects(tableAvatar.self)
  279. for result in results {
  280. result.loaded = false
  281. realm.add(result, update: .all)
  282. }
  283. }
  284. } catch let error {
  285. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  286. }
  287. }
  288. @discardableResult
  289. func setAvatarLoaded(fileName: String) -> UIImage? {
  290. let realm = try! Realm()
  291. let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName
  292. var image: UIImage?
  293. do {
  294. try realm.safeWrite {
  295. if let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first {
  296. if let imageAvatar = UIImage(contentsOfFile: fileNameLocalPath) {
  297. result.loaded = true
  298. image = imageAvatar
  299. } else {
  300. realm.delete(result)
  301. }
  302. }
  303. }
  304. } catch let error {
  305. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  306. }
  307. return image
  308. }
  309. func getImageAvatarLoaded(fileName: String) -> UIImage? {
  310. let realm = try! Realm()
  311. let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName
  312. let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first
  313. if result == nil {
  314. NCUtilityFileSystem.shared.deleteFile(filePath: fileNameLocalPath)
  315. return nil
  316. } else if result?.loaded == false {
  317. return nil
  318. }
  319. return UIImage(contentsOfFile: fileNameLocalPath)
  320. }
  321. // MARK: -
  322. // MARK: Table Capabilities
  323. @objc func addCapabilitiesJSon(_ data: Data, account: String) {
  324. let realm = try! Realm()
  325. do {
  326. try realm.safeWrite {
  327. let addObject = tableCapabilities()
  328. addObject.account = account
  329. addObject.jsondata = data
  330. realm.add(addObject, update: .all)
  331. }
  332. } catch let error {
  333. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  334. }
  335. }
  336. @objc func getCapabilities(account: String) -> String? {
  337. let realm = try! Realm()
  338. guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first else {
  339. return nil
  340. }
  341. guard let jsondata = result.jsondata else {
  342. return nil
  343. }
  344. let json = JSON(jsondata)
  345. return json.rawString()?.replacingOccurrences(of: "\\/", with: "/")
  346. }
  347. @objc func getCapabilitiesServerString(account: String, elements: [String]) -> String? {
  348. let realm = try! Realm()
  349. guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first else {
  350. return nil
  351. }
  352. guard let jsondata = result.jsondata else {
  353. return nil
  354. }
  355. let json = JSON(jsondata)
  356. return json[elements].string
  357. }
  358. @objc func getCapabilitiesServerInt(account: String, elements: [String]) -> Int {
  359. let realm = try! Realm()
  360. guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first,
  361. let jsondata = result.jsondata else {
  362. return 0
  363. }
  364. let json = JSON(jsondata)
  365. return json[elements].intValue
  366. }
  367. @objc func getCapabilitiesServerBool(account: String, elements: [String], exists: Bool) -> Bool {
  368. let realm = try! Realm()
  369. guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first else {
  370. return false
  371. }
  372. guard let jsondata = result.jsondata else {
  373. return false
  374. }
  375. let json = JSON(jsondata)
  376. if exists {
  377. return json[elements].exists()
  378. } else {
  379. return json[elements].boolValue
  380. }
  381. }
  382. @objc func getCapabilitiesServerArray(account: String, elements: [String]) -> [String]? {
  383. let realm = try! Realm()
  384. var resultArray: [String] = []
  385. guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first else {
  386. return nil
  387. }
  388. guard let jsondata = result.jsondata else {
  389. return nil
  390. }
  391. let json = JSON(jsondata)
  392. if let results = json[elements].array {
  393. for result in results {
  394. resultArray.append(result.string ?? "")
  395. }
  396. return resultArray
  397. }
  398. return nil
  399. }
  400. // MARK: -
  401. // MARK: Table Chunk
  402. func getChunkFolder(account: String, ocId: String) -> String {
  403. let realm = try! Realm()
  404. if let result = realm.objects(tableChunk.self).filter("account == %@ AND ocId == %@", account, ocId).first {
  405. return result.chunkFolder
  406. }
  407. return NSUUID().uuidString
  408. }
  409. func getChunks(account: String, ocId: String) -> [String] {
  410. let realm = try! Realm()
  411. var filesNames: [String] = []
  412. let results = realm.objects(tableChunk.self).filter("account == %@ AND ocId == %@", account, ocId).sorted(byKeyPath: "fileName", ascending: true)
  413. for result in results {
  414. filesNames.append(result.fileName)
  415. }
  416. return filesNames
  417. }
  418. func addChunks(account: String, ocId: String, chunkFolder: String, fileNames: [String]) {
  419. let realm = try! Realm()
  420. var size: Int64 = 0
  421. do {
  422. try realm.safeWrite {
  423. for fileName in fileNames {
  424. let object = tableChunk()
  425. size += NCUtilityFileSystem.shared.getFileSize(filePath: CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName)!)
  426. object.account = account
  427. object.chunkFolder = chunkFolder
  428. object.fileName = fileName
  429. object.index = ocId + fileName
  430. object.ocId = ocId
  431. object.size = size
  432. realm.add(object, update: .all)
  433. }
  434. }
  435. } catch let error {
  436. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  437. }
  438. }
  439. func getChunk(account: String, fileName: String) -> tableChunk? {
  440. let realm = try! Realm()
  441. if let result = realm.objects(tableChunk.self).filter("account == %@ AND fileName == %@", account, fileName).first {
  442. return tableChunk.init(value: result)
  443. } else {
  444. return nil
  445. }
  446. }
  447. func deleteChunk(account: String, ocId: String, fileName: String) {
  448. let realm = try! Realm()
  449. do {
  450. try realm.safeWrite {
  451. let result = realm.objects(tableChunk.self).filter(NSPredicate(format: "account == %@ AND ocId == %@ AND fileName == %@", account, ocId, fileName))
  452. realm.delete(result)
  453. }
  454. } catch let error {
  455. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  456. }
  457. }
  458. func deleteChunks(account: String, ocId: String) {
  459. let realm = try! Realm()
  460. do {
  461. try realm.safeWrite {
  462. let result = realm.objects(tableChunk.self).filter(NSPredicate(format: "account == %@ AND ocId == %@", account, ocId))
  463. realm.delete(result)
  464. }
  465. } catch let error {
  466. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  467. }
  468. }
  469. // MARK: -
  470. // MARK: Table Direct Editing
  471. @objc func addDirectEditing(account: String, editors: [NCCommunicationEditorDetailsEditors], creators: [NCCommunicationEditorDetailsCreators]) {
  472. let realm = try! Realm()
  473. do {
  474. try realm.safeWrite {
  475. let resultsCreators = realm.objects(tableDirectEditingCreators.self).filter("account == %@", account)
  476. realm.delete(resultsCreators)
  477. let resultsEditors = realm.objects(tableDirectEditingEditors.self).filter("account == %@", account)
  478. realm.delete(resultsEditors)
  479. for creator in creators {
  480. let addObject = tableDirectEditingCreators()
  481. addObject.account = account
  482. addObject.editor = creator.editor
  483. addObject.ext = creator.ext
  484. addObject.identifier = creator.identifier
  485. addObject.mimetype = creator.mimetype
  486. addObject.name = creator.name
  487. addObject.templates = creator.templates
  488. realm.add(addObject)
  489. }
  490. for editor in editors {
  491. let addObject = tableDirectEditingEditors()
  492. addObject.account = account
  493. for mimeType in editor.mimetypes {
  494. addObject.mimetypes.append(mimeType)
  495. }
  496. addObject.name = editor.name
  497. if editor.name.lowercased() == NCGlobal.shared.editorOnlyoffice {
  498. addObject.editor = NCGlobal.shared.editorOnlyoffice
  499. } else {
  500. addObject.editor = NCGlobal.shared.editorText
  501. }
  502. for mimeType in editor.optionalMimetypes {
  503. addObject.optionalMimetypes.append(mimeType)
  504. }
  505. addObject.secure = editor.secure
  506. realm.add(addObject)
  507. }
  508. }
  509. } catch let error {
  510. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  511. }
  512. }
  513. @objc func getDirectEditingCreators(account: String) -> [tableDirectEditingCreators]? {
  514. let realm = try! Realm()
  515. let results = realm.objects(tableDirectEditingCreators.self).filter("account == %@", account)
  516. if results.count > 0 {
  517. return Array(results.map { tableDirectEditingCreators.init(value: $0) })
  518. } else {
  519. return nil
  520. }
  521. }
  522. @objc func getDirectEditingCreators(predicate: NSPredicate) -> [tableDirectEditingCreators]? {
  523. let realm = try! Realm()
  524. let results = realm.objects(tableDirectEditingCreators.self).filter(predicate)
  525. if results.count > 0 {
  526. return Array(results.map { tableDirectEditingCreators.init(value: $0) })
  527. } else {
  528. return nil
  529. }
  530. }
  531. @objc func getDirectEditingEditors(account: String) -> [tableDirectEditingEditors]? {
  532. let realm = try! Realm()
  533. let results = realm.objects(tableDirectEditingEditors.self).filter("account == %@", account)
  534. if results.count > 0 {
  535. return Array(results.map { tableDirectEditingEditors.init(value: $0) })
  536. } else {
  537. return nil
  538. }
  539. }
  540. // MARK: -
  541. // MARK: Table Directory
  542. @objc func copyObject(directory: tableDirectory) -> tableDirectory {
  543. return tableDirectory.init(value: directory)
  544. }
  545. /*
  546. @objc func addDirectoryRichWorkspace(ocId: String, richWorkspace: String?) {
  547. let realm = try! Realm()
  548. do {
  549. try realm.safeWrite {
  550. if let result = realm.objects(tableDirectory.self).filter("ocId == %@", ocId).first {
  551. result.richWorkspace = richWorkspace
  552. }
  553. }
  554. } catch let error {
  555. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  556. }
  557. }
  558. */
  559. @objc func addDirectory(encrypted: Bool, favorite: Bool, ocId: String, fileId: String, etag: String? = nil, permissions: String? = nil, serverUrl: String, account: String) {
  560. let realm = try! Realm()
  561. do {
  562. try realm.safeWrite {
  563. var addObject = tableDirectory()
  564. let result = realm.objects(tableDirectory.self).filter("ocId == %@", ocId).first
  565. if result != nil {
  566. addObject = result!
  567. } else {
  568. addObject.ocId = ocId
  569. }
  570. addObject.account = account
  571. addObject.e2eEncrypted = encrypted
  572. addObject.favorite = favorite
  573. addObject.fileId = fileId
  574. if let etag = etag {
  575. addObject.etag = etag
  576. }
  577. if let permissions = permissions {
  578. addObject.permissions = permissions
  579. }
  580. addObject.serverUrl = serverUrl
  581. realm.add(addObject, update: .all)
  582. }
  583. } catch let error {
  584. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  585. }
  586. }
  587. @objc func deleteDirectoryAndSubDirectory(serverUrl: String, account: String) {
  588. let realm = try! Realm()
  589. let results = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl BEGINSWITH %@", account, serverUrl)
  590. // Delete table Metadata & LocalFile
  591. for result in results {
  592. self.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", result.account, result.serverUrl))
  593. self.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", result.ocId))
  594. }
  595. // Delete table Dirrectory
  596. do {
  597. try realm.safeWrite {
  598. realm.delete(results)
  599. }
  600. } catch let error {
  601. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  602. }
  603. }
  604. @objc func setDirectory(serverUrl: String, serverUrlTo: String? = nil, etag: String? = nil, ocId: String? = nil, fileId: String? = nil, encrypted: Bool, richWorkspace: String? = nil, account: String) {
  605. let realm = try! Realm()
  606. do {
  607. try realm.safeWrite {
  608. guard let result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else {
  609. return
  610. }
  611. let directory = tableDirectory.init(value: result)
  612. realm.delete(result)
  613. directory.e2eEncrypted = encrypted
  614. if let etag = etag {
  615. directory.etag = etag
  616. }
  617. if let ocId = ocId {
  618. directory.ocId = ocId
  619. }
  620. if let fileId = fileId {
  621. directory.fileId = fileId
  622. }
  623. if let serverUrlTo = serverUrlTo {
  624. directory.serverUrl = serverUrlTo
  625. }
  626. if let richWorkspace = richWorkspace {
  627. directory.richWorkspace = richWorkspace
  628. }
  629. realm.add(directory, update: .all)
  630. }
  631. } catch let error {
  632. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  633. }
  634. }
  635. @objc func getTableDirectory(predicate: NSPredicate) -> tableDirectory? {
  636. let realm = try! Realm()
  637. guard let result = realm.objects(tableDirectory.self).filter(predicate).first else {
  638. return nil
  639. }
  640. return tableDirectory.init(value: result)
  641. }
  642. @objc func getTablesDirectory(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableDirectory]? {
  643. let realm = try! Realm()
  644. let results = realm.objects(tableDirectory.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
  645. if results.count > 0 {
  646. return Array(results.map { tableDirectory.init(value: $0) })
  647. } else {
  648. return nil
  649. }
  650. }
  651. @objc func renameDirectory(ocId: String, serverUrl: String) {
  652. let realm = try! Realm()
  653. do {
  654. try realm.safeWrite {
  655. let result = realm.objects(tableDirectory.self).filter("ocId == %@", ocId).first
  656. result?.serverUrl = serverUrl
  657. }
  658. } catch let error {
  659. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  660. }
  661. }
  662. @objc func setDirectory(serverUrl: String, offline: Bool, account: String) {
  663. let realm = try! Realm()
  664. do {
  665. try realm.safeWrite {
  666. let result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first
  667. result?.offline = offline
  668. }
  669. } catch let error {
  670. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  671. }
  672. }
  673. @discardableResult
  674. @objc func setDirectory(richWorkspace: String?, serverUrl: String, account: String) -> tableDirectory? {
  675. let realm = try! Realm()
  676. var result: tableDirectory?
  677. do {
  678. try realm.safeWrite {
  679. result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first
  680. result?.richWorkspace = richWorkspace
  681. }
  682. } catch let error {
  683. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  684. }
  685. if let result = result {
  686. return tableDirectory.init(value: result)
  687. } else {
  688. return nil
  689. }
  690. }
  691. // MARK: -
  692. // MARK: Table e2e Encryption
  693. @objc func addE2eEncryption(_ e2e: tableE2eEncryption) {
  694. let realm = try! Realm()
  695. do {
  696. try realm.safeWrite {
  697. realm.add(e2e, update: .all)
  698. }
  699. } catch let error {
  700. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  701. }
  702. }
  703. @objc func deleteE2eEncryption(predicate: NSPredicate) {
  704. let realm = try! Realm()
  705. do {
  706. try realm.safeWrite {
  707. let results = realm.objects(tableE2eEncryption.self).filter(predicate)
  708. realm.delete(results)
  709. }
  710. } catch let error {
  711. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  712. }
  713. }
  714. @objc func getE2eEncryption(predicate: NSPredicate) -> tableE2eEncryption? {
  715. let realm = try! Realm()
  716. guard let result = realm.objects(tableE2eEncryption.self).filter(predicate).sorted(byKeyPath: "metadataKeyIndex", ascending: false).first else {
  717. return nil
  718. }
  719. return tableE2eEncryption.init(value: result)
  720. }
  721. @objc func getE2eEncryptions(predicate: NSPredicate) -> [tableE2eEncryption]? {
  722. guard self.getActiveAccount() != nil else {
  723. return nil
  724. }
  725. let realm = try! Realm()
  726. let results: Results<tableE2eEncryption>
  727. results = realm.objects(tableE2eEncryption.self).filter(predicate)
  728. if results.count > 0 {
  729. return Array(results.map { tableE2eEncryption.init(value: $0) })
  730. } else {
  731. return nil
  732. }
  733. }
  734. @objc func renameFileE2eEncryption(serverUrl: String, fileNameIdentifier: String, newFileName: String, newFileNamePath: String) {
  735. guard let activeAccount = self.getActiveAccount() else {
  736. return
  737. }
  738. let realm = try! Realm()
  739. realm.beginWrite()
  740. guard let result = realm.objects(tableE2eEncryption.self).filter("account == %@ AND serverUrl == %@ AND fileNameIdentifier == %@", activeAccount.account, serverUrl, fileNameIdentifier).first else {
  741. realm.cancelWrite()
  742. return
  743. }
  744. let object = tableE2eEncryption.init(value: result)
  745. realm.delete(result)
  746. object.fileName = newFileName
  747. object.fileNamePath = newFileNamePath
  748. realm.add(object)
  749. do {
  750. try realm.commitWrite()
  751. } catch let error {
  752. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  753. }
  754. }
  755. // MARK: -
  756. // MARK: Table e2e Encryption Lock
  757. @objc func getE2ETokenLock(account: String, serverUrl: String) -> tableE2eEncryptionLock? {
  758. let realm = try! Realm()
  759. guard let result = realm.objects(tableE2eEncryptionLock.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else {
  760. return nil
  761. }
  762. return tableE2eEncryptionLock.init(value: result)
  763. }
  764. @objc func setE2ETokenLock(account: String, serverUrl: String, fileId: String, e2eToken: String) {
  765. let realm = try! Realm()
  766. do {
  767. try realm.safeWrite {
  768. let addObject = tableE2eEncryptionLock()
  769. addObject.account = account
  770. addObject.fileId = fileId
  771. addObject.serverUrl = serverUrl
  772. addObject.e2eToken = e2eToken
  773. realm.add(addObject, update: .all)
  774. }
  775. } catch let error {
  776. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  777. }
  778. }
  779. @objc func deteleE2ETokenLock(account: String, serverUrl: String) {
  780. let realm = try! Realm()
  781. do {
  782. try realm.safeWrite {
  783. if let result = realm.objects(tableE2eEncryptionLock.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first {
  784. realm.delete(result)
  785. }
  786. }
  787. } catch let error {
  788. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  789. }
  790. }
  791. // MARK: -
  792. // MARK: Table External Sites
  793. @objc func addExternalSites(_ externalSite: NCCommunicationExternalSite, account: String) {
  794. let realm = try! Realm()
  795. do {
  796. try realm.safeWrite {
  797. let addObject = tableExternalSites()
  798. addObject.account = account
  799. addObject.idExternalSite = externalSite.idExternalSite
  800. addObject.icon = externalSite.icon
  801. addObject.lang = externalSite.lang
  802. addObject.name = externalSite.name
  803. addObject.url = externalSite.url
  804. addObject.type = externalSite.type
  805. realm.add(addObject)
  806. }
  807. } catch let error {
  808. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  809. }
  810. }
  811. @objc func deleteExternalSites(account: String) {
  812. let realm = try! Realm()
  813. do {
  814. try realm.safeWrite {
  815. let results = realm.objects(tableExternalSites.self).filter("account == %@", account)
  816. realm.delete(results)
  817. }
  818. } catch let error {
  819. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  820. }
  821. }
  822. @objc func getAllExternalSites(account: String) -> [tableExternalSites]? {
  823. let realm = try! Realm()
  824. let results = realm.objects(tableExternalSites.self).filter("account == %@", account).sorted(byKeyPath: "idExternalSite", ascending: true)
  825. if results.count > 0 {
  826. return Array(results.map { tableExternalSites.init(value: $0) })
  827. } else {
  828. return nil
  829. }
  830. }
  831. // MARK: -
  832. // MARK: Table GPS
  833. @objc func addGeocoderLocation(_ location: String, placemarkAdministrativeArea: String, placemarkCountry: String, placemarkLocality: String, placemarkPostalCode: String, placemarkThoroughfare: String, latitude: String, longitude: String) {
  834. let realm = try! Realm()
  835. realm.beginWrite()
  836. // Verify if exists
  837. guard realm.objects(tableGPS.self).filter("latitude == %@ AND longitude == %@", latitude, longitude).first == nil else {
  838. realm.cancelWrite()
  839. return
  840. }
  841. // Add new GPS
  842. let addObject = tableGPS()
  843. addObject.latitude = latitude
  844. addObject.location = location
  845. addObject.longitude = longitude
  846. addObject.placemarkAdministrativeArea = placemarkAdministrativeArea
  847. addObject.placemarkCountry = placemarkCountry
  848. addObject.placemarkLocality = placemarkLocality
  849. addObject.placemarkPostalCode = placemarkPostalCode
  850. addObject.placemarkThoroughfare = placemarkThoroughfare
  851. realm.add(addObject)
  852. do {
  853. try realm.commitWrite()
  854. } catch let error {
  855. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  856. }
  857. }
  858. @objc func getLocationFromGeoLatitude(_ latitude: String, longitude: String) -> String? {
  859. let realm = try! Realm()
  860. let result = realm.objects(tableGPS.self).filter("latitude == %@ AND longitude == %@", latitude, longitude).first
  861. return result?.location
  862. }
  863. // MARK: -
  864. // MARK: Table LocalFile
  865. @objc func copyObject(localFile: tableLocalFile) -> tableLocalFile {
  866. return tableLocalFile.init(value: localFile)
  867. }
  868. func addLocalFile(metadata: tableMetadata) {
  869. let realm = try! Realm()
  870. do {
  871. try realm.safeWrite {
  872. let addObject = getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) ?? tableLocalFile()
  873. addObject.account = metadata.account
  874. addObject.etag = metadata.etag
  875. addObject.exifDate = NSDate()
  876. addObject.exifLatitude = "-1"
  877. addObject.exifLongitude = "-1"
  878. addObject.ocId = metadata.ocId
  879. addObject.fileName = metadata.fileName
  880. realm.add(addObject, update: .all)
  881. }
  882. } catch let error {
  883. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  884. }
  885. }
  886. func addLocalFile(account: String, etag: String, ocId: String, fileName: String) {
  887. let realm = try! Realm()
  888. do {
  889. try realm.safeWrite {
  890. let addObject = tableLocalFile()
  891. addObject.account = account
  892. addObject.etag = etag
  893. addObject.exifDate = NSDate()
  894. addObject.exifLatitude = "-1"
  895. addObject.exifLongitude = "-1"
  896. addObject.ocId = ocId
  897. addObject.fileName = fileName
  898. realm.add(addObject, update: .all)
  899. }
  900. } catch let error {
  901. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  902. }
  903. }
  904. @objc func deleteLocalFile(predicate: NSPredicate) {
  905. let realm = try! Realm()
  906. do {
  907. try realm.safeWrite {
  908. let results = realm.objects(tableLocalFile.self).filter(predicate)
  909. realm.delete(results)
  910. }
  911. } catch let error {
  912. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  913. }
  914. }
  915. @objc func setLocalFile(ocId: String, fileName: String?, etag: String?) {
  916. let realm = try! Realm()
  917. do {
  918. try realm.safeWrite {
  919. let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first
  920. if let fileName = fileName {
  921. result?.fileName = fileName
  922. }
  923. if let etag = etag {
  924. result?.etag = etag
  925. }
  926. }
  927. } catch let error {
  928. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  929. }
  930. }
  931. @objc func setLocalFile(ocId: String, exifDate: NSDate?, exifLatitude: String, exifLongitude: String, exifLensModel: String?) {
  932. let realm = try! Realm()
  933. do {
  934. try realm.safeWrite {
  935. if let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first {
  936. result.exifDate = exifDate
  937. result.exifLatitude = exifLatitude
  938. result.exifLongitude = exifLongitude
  939. if exifLensModel?.count ?? 0 > 0 {
  940. result.exifLensModel = exifLensModel
  941. }
  942. }
  943. }
  944. } catch let error {
  945. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  946. }
  947. }
  948. @objc func getTableLocalFile(predicate: NSPredicate) -> tableLocalFile? {
  949. let realm = try! Realm()
  950. guard let result = realm.objects(tableLocalFile.self).filter(predicate).first else {
  951. return nil
  952. }
  953. return tableLocalFile.init(value: result)
  954. }
  955. @objc func getTableLocalFiles(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableLocalFile] {
  956. let realm = try! Realm()
  957. let results = realm.objects(tableLocalFile.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
  958. return Array(results.map { tableLocalFile.init(value: $0) })
  959. }
  960. @objc func setLocalFile(ocId: String, offline: Bool) {
  961. let realm = try! Realm()
  962. do {
  963. try realm.safeWrite {
  964. let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first
  965. result?.offline = offline
  966. }
  967. } catch let error {
  968. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  969. }
  970. }
  971. // MARK: -
  972. // MARK: Table Photo Library
  973. @discardableResult
  974. @objc func addPhotoLibrary(_ assets: [PHAsset], account: String) -> Bool {
  975. let realm = try! Realm()
  976. do {
  977. try realm.safeWrite {
  978. var creationDateString = ""
  979. for asset in assets {
  980. let addObject = tablePhotoLibrary()
  981. addObject.account = account
  982. addObject.assetLocalIdentifier = asset.localIdentifier
  983. addObject.mediaType = asset.mediaType.rawValue
  984. if let creationDate = asset.creationDate {
  985. addObject.creationDate = creationDate as NSDate
  986. creationDateString = String(describing: creationDate)
  987. } else {
  988. creationDateString = ""
  989. }
  990. if let modificationDate = asset.modificationDate {
  991. addObject.modificationDate = modificationDate as NSDate
  992. }
  993. addObject.idAsset = "\(account)\(asset.localIdentifier)\(creationDateString)"
  994. realm.add(addObject, update: .all)
  995. }
  996. }
  997. } catch let error {
  998. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  999. return false
  1000. }
  1001. return true
  1002. }
  1003. @objc func getPhotoLibraryIdAsset(image: Bool, video: Bool, account: String) -> [String]? {
  1004. let realm = try! Realm()
  1005. var predicate = NSPredicate()
  1006. if image && video {
  1007. predicate = NSPredicate(format: "account == %@ AND (mediaType == %d OR mediaType == %d)", account, PHAssetMediaType.image.rawValue, PHAssetMediaType.video.rawValue)
  1008. } else if image {
  1009. predicate = NSPredicate(format: "account == %@ AND mediaType == %d", account, PHAssetMediaType.image.rawValue)
  1010. } else if video {
  1011. predicate = NSPredicate(format: "account == %@ AND mediaType == %d", account, PHAssetMediaType.video.rawValue)
  1012. }
  1013. let results = realm.objects(tablePhotoLibrary.self).filter(predicate)
  1014. let idsAsset = results.map { $0.idAsset }
  1015. return Array(idsAsset)
  1016. }
  1017. // MARK: -
  1018. // MARK: Table Share
  1019. @objc func addShare(urlBase: String, account: String, shares: [NCCommunicationShare]) {
  1020. let realm = try! Realm()
  1021. realm.beginWrite()
  1022. for share in shares {
  1023. let addObject = tableShare()
  1024. let fullPath = NCUtilityFileSystem.shared.getHomeServer(account: account) + share.path
  1025. let serverUrl = NCUtilityFileSystem.shared.deletingLastPathComponent(account: account, serverUrl: fullPath)
  1026. let fileName = NSString(string: fullPath).lastPathComponent
  1027. addObject.account = account
  1028. addObject.fileName = fileName
  1029. addObject.serverUrl = serverUrl
  1030. addObject.canEdit = share.canEdit
  1031. addObject.canDelete = share.canDelete
  1032. addObject.date = share.date
  1033. addObject.displaynameFileOwner = share.displaynameFileOwner
  1034. addObject.displaynameOwner = share.displaynameOwner
  1035. addObject.expirationDate = share.expirationDate
  1036. addObject.fileParent = share.fileParent
  1037. addObject.fileSource = share.fileSource
  1038. addObject.fileTarget = share.fileTarget
  1039. addObject.hideDownload = share.hideDownload
  1040. addObject.idShare = share.idShare
  1041. addObject.itemSource = share.itemSource
  1042. addObject.itemType = share.itemType
  1043. addObject.label = share.label
  1044. addObject.mailSend = share.mailSend
  1045. addObject.mimeType = share.mimeType
  1046. addObject.note = share.note
  1047. addObject.parent = share.parent
  1048. addObject.password = share.password
  1049. addObject.path = share.path
  1050. addObject.permissions = share.permissions
  1051. addObject.sendPasswordByTalk = share.sendPasswordByTalk
  1052. addObject.shareType = share.shareType
  1053. addObject.shareWith = share.shareWith
  1054. addObject.shareWithDisplayname = share.shareWithDisplayname
  1055. addObject.storage = share.storage
  1056. addObject.storageId = share.storageId
  1057. addObject.token = share.token
  1058. addObject.uidOwner = share.uidOwner
  1059. addObject.uidFileOwner = share.uidFileOwner
  1060. addObject.url = share.url
  1061. addObject.userClearAt = share.userClearAt
  1062. addObject.userIcon = share.userIcon
  1063. addObject.userMessage = share.userMessage
  1064. addObject.userStatus = share.userStatus
  1065. realm.add(addObject, update: .all)
  1066. }
  1067. do {
  1068. try realm.commitWrite()
  1069. } catch let error {
  1070. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  1071. }
  1072. }
  1073. @objc func getTableShares(account: String) -> [tableShare] {
  1074. let realm = try! Realm()
  1075. let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
  1076. let results = realm.objects(tableShare.self).filter("account == %@", account).sorted(by: sortProperties)
  1077. return Array(results.map { tableShare.init(value: $0) })
  1078. }
  1079. func getTableShares(metadata: tableMetadata) -> (firstShareLink: tableShare?, share: [tableShare]?) {
  1080. let realm = try! Realm()
  1081. let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
  1082. let firstShareLink = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@ AND shareType == 3", metadata.account, metadata.serverUrl, metadata.fileName).first
  1083. if firstShareLink == nil {
  1084. let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", metadata.account, metadata.serverUrl, metadata.fileName).sorted(by: sortProperties)
  1085. return(firstShareLink: firstShareLink, share: Array(results.map { tableShare.init(value: $0) }))
  1086. } else {
  1087. let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@ AND idShare != %d", metadata.account, metadata.serverUrl, metadata.fileName, firstShareLink!.idShare).sorted(by: sortProperties)
  1088. return(firstShareLink: firstShareLink, share: Array(results.map { tableShare.init(value: $0) }))
  1089. }
  1090. }
  1091. func getTableShare(account: String, idShare: Int) -> tableShare? {
  1092. let realm = try! Realm()
  1093. guard let result = realm.objects(tableShare.self).filter("account = %@ AND idShare = %d", account, idShare).first else {
  1094. return nil
  1095. }
  1096. return tableShare.init(value: result)
  1097. }
  1098. @objc func getTableShares(account: String, serverUrl: String) -> [tableShare] {
  1099. let realm = try! Realm()
  1100. let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
  1101. let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).sorted(by: sortProperties)
  1102. return Array(results.map { tableShare.init(value: $0) })
  1103. }
  1104. @objc func getTableShares(account: String, serverUrl: String, fileName: String) -> [tableShare] {
  1105. let realm = try! Realm()
  1106. let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
  1107. let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", account, serverUrl, fileName).sorted(by: sortProperties)
  1108. return Array(results.map { tableShare.init(value: $0) })
  1109. }
  1110. @objc func deleteTableShare(account: String, idShare: Int) {
  1111. let realm = try! Realm()
  1112. realm.beginWrite()
  1113. let result = realm.objects(tableShare.self).filter("account == %@ AND idShare == %d", account, idShare)
  1114. realm.delete(result)
  1115. do {
  1116. try realm.commitWrite()
  1117. } catch let error {
  1118. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  1119. }
  1120. }
  1121. @objc func deleteTableShare(account: String) {
  1122. let realm = try! Realm()
  1123. realm.beginWrite()
  1124. let result = realm.objects(tableShare.self).filter("account == %@", account)
  1125. realm.delete(result)
  1126. do {
  1127. try realm.commitWrite()
  1128. } catch let error {
  1129. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  1130. }
  1131. }
  1132. // MARK: -
  1133. // MARK: Table Tag
  1134. @objc func addTag(_ ocId: String, tagIOS: Data?, account: String) {
  1135. let realm = try! Realm()
  1136. do {
  1137. try realm.safeWrite {
  1138. // Add new
  1139. let addObject = tableTag()
  1140. addObject.account = account
  1141. addObject.ocId = ocId
  1142. addObject.tagIOS = tagIOS
  1143. realm.add(addObject, update: .all)
  1144. }
  1145. } catch let error {
  1146. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  1147. }
  1148. }
  1149. @objc func deleteTag(_ ocId: String) {
  1150. let realm = try! Realm()
  1151. realm.beginWrite()
  1152. let result = realm.objects(tableTag.self).filter("ocId == %@", ocId)
  1153. realm.delete(result)
  1154. do {
  1155. try realm.commitWrite()
  1156. } catch let error {
  1157. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  1158. }
  1159. }
  1160. @objc func getTags(predicate: NSPredicate) -> [tableTag] {
  1161. let realm = try! Realm()
  1162. let results = realm.objects(tableTag.self).filter(predicate)
  1163. return Array(results.map { tableTag.init(value: $0) })
  1164. }
  1165. @objc func getTag(predicate: NSPredicate) -> tableTag? {
  1166. let realm = try! Realm()
  1167. guard let result = realm.objects(tableTag.self).filter(predicate).first else {
  1168. return nil
  1169. }
  1170. return tableTag.init(value: result)
  1171. }
  1172. // MARK: -
  1173. // MARK: Table Tip
  1174. @objc func tipExists(_ tipName: String) -> Bool {
  1175. let realm = try! Realm()
  1176. guard (realm.objects(tableTip.self).where {
  1177. $0.tipName == tipName
  1178. }.first) == nil else {
  1179. return true
  1180. }
  1181. return false
  1182. }
  1183. @objc func addTip(_ tipName: String) {
  1184. let realm = try! Realm()
  1185. do {
  1186. try realm.safeWrite {
  1187. let addObject = tableTip()
  1188. addObject.tipName = tipName
  1189. realm.add(addObject, update: .all)
  1190. }
  1191. } catch let error {
  1192. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  1193. }
  1194. }
  1195. // MARK: -
  1196. // MARK: Table Trash
  1197. @objc func addTrash(account: String, items: [NCCommunicationTrash]) {
  1198. let realm = try! Realm()
  1199. do {
  1200. try realm.safeWrite {
  1201. for trash in items {
  1202. let object = tableTrash()
  1203. object.account = account
  1204. object.contentType = trash.contentType
  1205. object.date = trash.date
  1206. object.directory = trash.directory
  1207. object.fileId = trash.fileId
  1208. object.fileName = trash.fileName
  1209. object.filePath = trash.filePath
  1210. object.hasPreview = trash.hasPreview
  1211. object.iconName = trash.iconName
  1212. object.size = trash.size
  1213. object.trashbinDeletionTime = trash.trashbinDeletionTime
  1214. object.trashbinFileName = trash.trashbinFileName
  1215. object.trashbinOriginalLocation = trash.trashbinOriginalLocation
  1216. object.classFile = trash.classFile
  1217. realm.add(object, update: .all)
  1218. }
  1219. }
  1220. } catch let error {
  1221. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  1222. }
  1223. }
  1224. @objc func deleteTrash(filePath: String?, account: String) {
  1225. let realm = try! Realm()
  1226. var predicate = NSPredicate()
  1227. do {
  1228. try realm.safeWrite {
  1229. if filePath == nil {
  1230. predicate = NSPredicate(format: "account == %@", account)
  1231. } else {
  1232. predicate = NSPredicate(format: "account == %@ AND filePath == %@", account, filePath!)
  1233. }
  1234. let result = realm.objects(tableTrash.self).filter(predicate)
  1235. realm.delete(result)
  1236. }
  1237. } catch let error {
  1238. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  1239. }
  1240. }
  1241. @objc func deleteTrash(fileId: String?, account: String) {
  1242. let realm = try! Realm()
  1243. var predicate = NSPredicate()
  1244. do {
  1245. try realm.safeWrite {
  1246. if fileId == nil {
  1247. predicate = NSPredicate(format: "account == %@", account)
  1248. } else {
  1249. predicate = NSPredicate(format: "account == %@ AND fileId == %@", account, fileId!)
  1250. }
  1251. let result = realm.objects(tableTrash.self).filter(predicate)
  1252. realm.delete(result)
  1253. }
  1254. } catch let error {
  1255. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  1256. }
  1257. }
  1258. func getTrash(filePath: String, sort: String?, ascending: Bool?, account: String) -> [tableTrash]? {
  1259. let realm = try! Realm()
  1260. let sort = sort ?? "date"
  1261. let ascending = ascending ?? false
  1262. let results = realm.objects(tableTrash.self).filter("account == %@ AND filePath == %@", account, filePath).sorted(byKeyPath: sort, ascending: ascending)
  1263. return Array(results.map { tableTrash.init(value: $0) })
  1264. }
  1265. @objc func getTrashItem(fileId: String, account: String) -> tableTrash? {
  1266. let realm = try! Realm()
  1267. guard let result = realm.objects(tableTrash.self).filter("account == %@ AND fileId == %@", account, fileId).first else {
  1268. return nil
  1269. }
  1270. return tableTrash.init(value: result)
  1271. }
  1272. // MARK: -
  1273. // MARK: Table UserStatus
  1274. @objc func addUserStatus(_ userStatuses: [NCCommunicationUserStatus], account: String, predefined: Bool) {
  1275. let realm = try! Realm()
  1276. do {
  1277. try realm.safeWrite {
  1278. let results = realm.objects(tableUserStatus.self).filter("account == %@ AND predefined == %@", account, predefined)
  1279. realm.delete(results)
  1280. for userStatus in userStatuses {
  1281. let object = tableUserStatus()
  1282. object.account = account
  1283. object.clearAt = userStatus.clearAt
  1284. object.clearAtTime = userStatus.clearAtTime
  1285. object.clearAtType = userStatus.clearAtType
  1286. object.icon = userStatus.icon
  1287. object.id = userStatus.id
  1288. object.message = userStatus.message
  1289. object.predefined = userStatus.predefined
  1290. object.status = userStatus.status
  1291. object.userId = userStatus.userId
  1292. realm.add(object)
  1293. }
  1294. }
  1295. } catch let error {
  1296. NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
  1297. }
  1298. }
  1299. }
  1300. // MARK: -
  1301. extension Realm {
  1302. public func safeWrite(_ block: (() throws -> Void)) throws {
  1303. if isInWriteTransaction {
  1304. try block()
  1305. } else {
  1306. try write(block)
  1307. }
  1308. }
  1309. }