// // PQSingletoRealmUtil.swift // PQSpeed // // Created by SanW on 2020/7/7. // Copyright © 2020 BytesFlow. All rights reserved. // import RealmSwift import UIKit import BFCommonKit public class PQSingletoRealmUtil: NSObject { public var schemaVersion : UInt64 = 32 public var realmEntry: Realm? { let config = Realm.Configuration( schemaVersion: schemaVersion, migrationBlock: { _, oldSchemaVersion in if oldSchemaVersion < 1 {} } ) Realm.Configuration.defaultConfiguration = config do { let realmEntry = try Realm(configuration: config, queue: DispatchQueue.main) return realmEntry } catch let error as NSError { // handle error BFLog(message: "Realm-realm创建失败:\(error)") } return nil } public static let shared = PQSingletoRealmUtil() // 根据不同的用户ID 初始化不同的数据库 th1 public func getDraftDB(uid: String) -> Realm { let docPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)[0] as String let dbPath = docPath.appending("/\(uid)Draft.realm") BFLog(message: "生成登录人数据库地址\(dbPath)") var config = Realm.Configuration( schemaVersion: schemaVersion, migrationBlock: { _, oldSchemaVersion in if oldSchemaVersion < 1 {} } ) config.fileURL = URL(string: dbPath)! let defaultRealm = try! Realm(configuration: config) return defaultRealm } /// 写入单个数据 /// - Parameter objects: <#objects description#> /// - Returns: <#description#> public func saveObject(object: Object) { do { try realmEntry?.write { realmEntry?.add(object, update: .modified) BFLog(message: "Realm-添加单个数据成功:\(object)") } } catch let error as NSError { // handle error BFLog(message: "Realm-添加单个数据失败:\(error)") } } /// 写入多个数据 /// - Parameter objects: <#objects description#> /// - Returns: <#description#> public func saveObjects(objects: [Object]) { do { try realmEntry?.write { realmEntry?.add(objects, update: .modified) BFLog(message: "Realm-添加多个数据成功:\(objects)") } } catch let error as NSError { // handle error BFLog(message: "Realm-添加多个数据失败:\(error)") } } /// 写入本地存储数据 /// - Parameter objects: <#objects description#> /// - Returns: <#description#> public func saveLocalSaveObject(uniqueId: String, isSelected: Bool) { let currentObject = queryLocalStoreObjects(uniqueId: uniqueId) if (currentObject?.count ?? 0) > 0 { do { try realmEntry?.write { currentObject?.first?.isSelected = isSelected (currentObject?.first as? PQLocalStoreModel)?.currentDate = systemCurrentDate() BFLog(message: "Realm-本地已存储数据更新成功:\(currentObject)") } } catch let error as NSError { // handle error BFLog(message: "Realm-本地已存储数据更新失败:\(error)") } } else { let storeObject = PQLocalStoreModel() storeObject.uniqueId = uniqueId storeObject.isSelected = isSelected // 未存在则保存 BFLog(message: "Realm-本地数据未存储,开始存储") saveObject(object: storeObject) } } /// 查询本地缓存数据 /// - Returns: <#description#> public func queryLocalStoreObjects(uniqueId: String) -> Results? { return queryObjects(PQLocalStoreModel.self, filter: "uniqueId == '\(uniqueId)'") } /// 查询所有未过期视频缓存数据 /// - Returns: description public func queryVideoObjects() -> Results? { // "isSelected == false AND date >= \(Int(Date.init().timeIntervalSince1970) - 24 * 60)" return queryObjects(PQVideoListModel.self, filter: "isSelected == false") } /// 删除已缓存视频数据 /// - Returns: <#description#> public func deleteAllCacheObject() { guard let deleteObjecs = realmEntry?.objects(PQVideoListModel.self) else { BFLog(message: "Realm-删除已缓存为空") return } do { try realmEntry?.write { realmEntry?.delete(deleteObjecs) BFLog(message: "Realm-删除已缓存视频成功") } } catch let error as NSError { // handle error BFLog(message: "Realm-删除已缓存视频失败:\(error)") } } /// 根据条件查询数据 /// - Parameters: /// - type: 类型 /// - filter: <#filter description#> /// - Returns: <#description#> public func queryObjects(_ type: PQBaseModel.Type, filter: String) -> Results? { let puppies = realmEntry?.objects(type).filter(filter) BFLog(message: "查询已缓存数据:type = \(type) \(puppies ?? nil)") return puppies } public func deleteObject() { guard let deleteObjecs = realmEntry?.objects(PQVideoListModel.self).filter("isSelected == true") else { return } do { try realmEntry?.write { realmEntry?.delete(deleteObjecs) BFLog(message: "Realm-删除已缓存视频成功") } } catch let error as NSError { // handle error BFLog(message: "Realm-删除已缓存视频失败:\(error)") } } /// 删除 /// - Returns: <#description#> public func deleteObject(object: PQVideoListModel) { let videoId: Int = object.videoId guard let deleteObjecs = realmEntry?.objects(PQVideoListModel.self).filter("videoId == \(videoId)") else { return } do { try realmEntry?.write { realmEntry?.delete(deleteObjecs) BFLog(message: "Realm-删除已缓存视频成功") } } catch let error as NSError { // handle error BFLog(message: "Realm-删除已缓存视频失败:\(error)") } } public func deleteObject(_ type: PQBaseModel.Type, filter: String) { guard let deleteObjecs = queryObjects(type, filter: filter) else { return } do { try realmEntry?.write { realmEntry?.delete(deleteObjecs) BFLog(message: "Realm-删除已缓存视频成功") } } catch let error as NSError { // handle error BFLog(message: "Realm-删除已缓存视频失败:\(error)") } } /// 更新缓存视频是否读取过 /// - Parameter object: <#object description#> /// - Returns: <#description#> public func updateObject(object: PQVideoListModel) { guard let newObject = realmEntry?.objects(PQVideoListModel.self).filter("videoId == \(object.videoId)") else { BFLog(message: "更新 newObject 为空") return } BFLog(message: "更新 newObject = \(newObject)") do { try realmEntry?.write { newObject.first?.isSelected = true BFLog(message: "Realm-更新缓存视频已播放成功:\(newObject)") } } catch let error as NSError { // handle error BFLog(message: "Realm-更新缓存视频已播放失败:\(error)") } } override private init() { super.init() } override public func copy() -> Any { return self } override public func mutableCopy() -> Any { return self } // MARK: - add by ak 数据库操作 V2 方法 // MARK: add /// 添加一个 /// /// - Parameter object: 添加元素 public func realmAdd(realm: Realm, object: Object) { try! realm.write { realm.add(object, update: .modified) } } /// 添加多个 /// /// - Parameter objects: 添加数组 public func realmAdds(realm: Realm, objects: [Object]) { try! realm.write { realm.add(objects, update: .modified) } } // MARK: delete /// 删除一个 /// /// - Parameter object: 删除元素 public func realmDelete(realm: Realm, object: Object) { try! realm.write { realm.delete(object) } } /// 删除多个 /// /// - Parameter objects: 元素数组 public func realmDeletes(realm: Realm, objects: [Object]) { try! realm.write { realm.delete(objects) } } /// 条件删除 /// /// - Parameters: /// - object: 元素类型 /// - predicate: 条件 public func realmDeletesWithPredicate(realm: Realm, object: Object.Type, predicate: NSPredicate) { let results: [Object] = realmQueryWithParameters(realm: realm, object: object, predicate: predicate) if results.count > 0 { try! realm.write { realm.delete(results) } } } /// 删除该类型所有 /// /// - Parameter object: 元素类型 public func realmDeleteTypeList(realm: Realm, object: Object.Type) { let objListResults = realmQueryWithType(realm: realm, object: object) if objListResults.count > 0 { try! realm.write { realm.delete(objListResults) } } } /// 删除当前数据库所有 public func realmDeleteAll(realm: Realm) { try! realm.write { realm.deleteAll() } } // MARK: update /// 更新元素(元素必须有主键) /// /// - Parameter object: 要更新的元素 public func realmUpdte(realm: Realm, object _: Object) { try! realm.write { // realm.up(object, update: true) } } /// 更新元素集合(元素必须有主键) /// /// - Parameter objects: 元素集合(集合内元素所有属性都要有值) public func realmUpdtes(realm: Realm, objects _: [Object]) { try! realm.write { // realm.add(objects, update: true) } } /// 更新操作 -> 对于realm搜索结果集当中的元素,在action当中直接负值即可修改 /// /// - Parameter action:操作 public func realmUpdateWithTranstion(realm: Realm, action: (Bool) -> Void) { try! realm.write { action(true) } } // MARK: query /// 查询元素 /// - Parameter type: 元素类型 /// - Parameter filter: 查询条件 public func reamlQueryObjects(realm: Realm, _ type: Object.Type, filter: String) -> Results? { let puppies = realm.objects(type).filter(filter) BFLog(message: "查询已缓存数据:type = \(type) \(puppies)") return puppies } public func reamlQueryObjectsV2(realm: Realm, _ type: Object.Type, filter: String) -> String { var json: String? try! realm.write { let puppies: Results = realm.objects(type).filter(filter) BFLog(message: "查询已缓存数据:type = \(type) \(puppies)") if puppies.count > 0 { json = (puppies.first as? PQEditProjectModel)!.toJSONString(prettyPrint: false) } } return json ?? "" } /// 查询元素 /// /// - Parameters: /// - object: 元素类型 /// - Returns: 查询结果 public func realmQueryWith(realm: Realm, object: Object.Type) -> [Object] { let results = realmQueryWithType(realm: realm, object: object) var resultsArray = [Object]() if results.count > 0 { for i in 0...results.count - 1 { resultsArray.append(results[i]) } } return resultsArray } /// 查询元素 /// /// - Parameters: /// - object: 元素类型 /// - predicate: 查询条件 /// - Returns: 查询结果 public func realmQueryWithParameters(realm: Realm, object: Object.Type, predicate: NSPredicate) -> [Object] { let results = realmQueryWith(realm: realm, object: object, predicate: predicate) var resultsArray = [Object]() if results.count > 0 { for i in 0...results.count - 1 { resultsArray.append(results[i]) } } return resultsArray } /// 分页查询 /// /// - Parameters: /// - object: 查询类型 /// - fromIndex: 起始页 /// - pageSize: 每页多少个 /// - Returns: 查询结果 public func realmQueryWithParametersPage(realm: Realm, object: Object.Type, fromIndex: Int, pageSize: Int) -> [Object] { let results = realmQueryWithType(realm: realm, object: object) var resultsArray = [Object]() if results.count <= pageSize * (fromIndex - 1) || fromIndex <= 0 { return resultsArray } if results.count > 0 { for i in pageSize * (fromIndex - 1)...fromIndex * pageSize - 1 { resultsArray.append(results[i]) } } return resultsArray } /// 条件排序查询 /// /// - Parameters: /// - object: 查询类型 /// - predicate: 查询条件 /// - sortedKey: 排序key /// - isAssending: 是否升序 /// - Returns: 查询结果 public func realmQueryWithParametersAndSorted(realm: Realm, object: Object.Type, predicate: NSPredicate, sortedKey: String, isAssending: Bool) -> [Object] { let results = realmQueryWithSorted(realm: realm, object: object, predicate: predicate, sortedKey: sortedKey, isAssending: isAssending) var resultsArray = [Object]() if results.count > 0 { for i in 0...results.count - 1 { resultsArray.append(results[i]) } } return resultsArray } /// 分页条件排序查询 /// /// - Parameters: /// - object: 查询类型 /// - predicate: 查询条件 /// - sortedKey: 排序key /// - isAssending: 是否升序 /// - fromIndex: 起始页 /// - pageSize: 每页多少个 /// - Returns: 查询结果 public func realmQueryWithParametersAndSortedAndPaged(realm: Realm, object: Object.Type, predicate: NSPredicate, sortedKey: String, isAssending: Bool, fromIndex: Int, pageSize: Int) -> [Object] { let results = realmQueryWithSorted(realm: realm, object: object, predicate: predicate, sortedKey: sortedKey, isAssending: isAssending) var resultsArray = [Object]() if results.count <= pageSize * (fromIndex - 1) || fromIndex <= 0 { return resultsArray } if results.count > 0 { for i in pageSize * (fromIndex - 1)...fromIndex * pageSize - 1 { resultsArray.append(results[i]) } } return resultsArray } // MARK: private method /// 按类型查询 /// /// - Parameter object: 查询元素类型 /// - Returns: 查询结果 public func realmQueryWithType(realm: Realm, object: Object.Type) -> Results { return realm.objects(object) } /// 条件查询 /// /// - Parameters: /// - object: 查询元素类型 /// - predicate: 查询条件 /// - Returns: 查询结果 public func realmQueryWith(realm: Realm, object: Object.Type, predicate: NSPredicate) -> Results { return realm.objects(object).filter(predicate) } /// 条件排序查询 /// /// - Parameters: /// - object: 查询类型 /// - predicate: 查询条件 /// - sortedKey: 排序key /// - isAssending: 是否升序 /// - Returns: 查询结果 public func realmQueryWithSorted(realm: Realm, object: Object.Type, predicate: NSPredicate, sortedKey: String, isAssending: Bool) -> Results { return realm.objects(object).filter(predicate) .sorted(byKeyPath: sortedKey, ascending: isAssending) } }