// // DataManager.swift // GRDBDemo // // Created by Apple on 2021/4/21. // import GRDB struct DataBaseName { /// 數據庫名字 static let test = "conversation.db" } /// 數據庫表名 struct TableName { static let message = "ChatMessage" } /// 數據庫鏈接 class DBManager: NSObject { /// 數據庫路徑 private static var dbPath: String = { // 獲取工程內容數據庫名字 let filePath: String = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first!.appending("/\(DataBaseName.test)") //print("數據庫地址:", filePath as Any) return filePath }() /// 數據庫配置 private static var configuration: Configuration = { // 配置 var configuration = Configuration() // 設置超時 configuration.busyMode = Database.BusyMode.timeout(5.0) // 試圖訪問鎖着的數據 //configuration.busyMode = Database.BusyMode.immediateError return configuration }() // MARK: 建立數據 多線程 /// 數據庫 用於多線程事務處理 static var dbQueue: DatabaseQueue = { // 建立數據庫 let db = try! DatabaseQueue(path: DBManager.dbPath, configuration: DBManager.configuration) db.releaseMemory() // 設備版本 return db }() }
// // ChatMessage.swift // GRDBDemo // // Created by Apple on 2021/4/21. // import Foundation import GRDB /// 聊天消息類 struct ChatMessage: Codable { var messageId : String? var messageType : String? var messageContent : String? var senderId : String? var targetId : String? private enum Columns: String, CodingKey, ColumnExpression { case messageId case messageType case messageContent case senderId case targetId } } extension ChatMessage: MutablePersistableRecord, FetchableRecord { /// 獲取數據庫對象 private static let dbQueue: DatabaseQueue = DBManager.dbQueue //MARK: 建立 /// 建立數據庫 private static func createTable() -> Void { try! self.dbQueue.inDatabase { (db) -> Void in // 判斷是否存在數據庫 if try db.tableExists(TableName.message) { debugPrint("表已經存在") return } // 建立數據庫表 try db.create(table: TableName.message, temporary: false, ifNotExists: true, body: { (t) in t.column(Columns.messageId.rawValue, Database.ColumnType.text) t.column(Columns.messageType.rawValue, Database.ColumnType.text) t.column(Columns.messageContent.rawValue, Database.ColumnType.text) t.column(Columns.senderId.rawValue, Database.ColumnType.text) t.column(Columns.targetId.rawValue, Database.ColumnType.text) }) } } //MARK: 插入 /// 插入單個數據 static func insert(message: ChatMessage) -> Void { // 判斷是否存在 guard ChatMessage.query(messageId: message.messageId!) == nil else { debugPrint("插入消息 內容重複") // 更新 self.update(message: message) return } // 建立表 self.createTable() // 事務 try! self.dbQueue.inTransaction { (db) -> Database.TransactionCompletion in do { var messageTemp = message // 插入到數據庫 try messageTemp.insert(db) return Database.TransactionCompletion.commit } catch { return Database.TransactionCompletion.rollback } } } //MARK: 查詢一條記錄 static func query(messageId: String) -> ChatMessage? { // 建立數據庫 self.createTable() // 返回查詢結果 return try! self.dbQueue.unsafeRead({ (db) -> ChatMessage? in return try ChatMessage.filter(Column(Columns.messageId.rawValue) == messageId).fetchOne(db) }) } //MARK:查詢與某人聊天的多條記錄 - 從第幾頁開始 static func query(userId:String,page:Int) -> [ChatMessage] { // 建立數據庫 self.createTable() return try! self.dbQueue.unsafeRead({ (db) -> [ChatMessage] in return try ChatMessage.fetchAll(db, sql: "Select * from ChatMessage where senderId = '\(userId)' or targetId = '\(userId)' limit \(20 * page),20") }) } /// 查詢全部 static func queryAll() -> [ChatMessage] { // 建立數據庫 self.createTable() // 返回查詢結果 return try! self.dbQueue.unsafeRead({ (db) -> [ChatMessage] in return try ChatMessage.fetchAll(db) }) } //MARK: 更新 /// 更新 static func update(message: ChatMessage) -> Void { /// 建立數據庫表 self.createTable() // 事務 更新場景 try! self.dbQueue.inTransaction { (db) -> Database.TransactionCompletion in do { // 賦值 try message.update(db) return Database.TransactionCompletion.commit } catch { return Database.TransactionCompletion.rollback } } } //MARK: 刪除 /// 根據messageId刪除聊天記錄 static func delete(messageId: String) -> Void { // 查詢 guard let message = self.query(messageId: messageId) else { return } // 刪除 self.delete(message: message) } /// 刪除單個聊天信息 static func delete(message: ChatMessage) -> Void { // 是否有數據庫表 self.createTable() // 事務 try! self.dbQueue.inTransaction { (db) -> Database.TransactionCompletion in do { // 刪除數據 try message.delete(db) return Database.TransactionCompletion.commit } catch { return Database.TransactionCompletion.rollback } } } }
使用示例:sql
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let user1 = ChatMessage(messageId: "1010", messageType: "text", messageContent: "12345", senderId: "1", targetId: "2") ChatMessage.insert(message: user1) let user2 = ChatMessage(messageId: "1012", messageType: "text", messageContent: "12345", senderId: "123", targetId: "2") ChatMessage.insert(message: user2) let user3 = ChatMessage(messageId: "1013", messageType: "text", messageContent: "12345", senderId: "1", targetId: "123") ChatMessage.insert(message: user3) let user4 = ChatMessage(messageId: "1014", messageType: "text", messageContent: "12345", senderId: "1", targetId: "2") ChatMessage.insert(message: user4) let user5 = ChatMessage(messageId: "1015", messageType: "text", messageContent: "12345", senderId: "1", targetId: "123") ChatMessage.insert(message: user5) let user6 = ChatMessage(messageId: "1016", messageType: "text", messageContent: "12345", senderId: "123", targetId: "2") ChatMessage.insert(message: user6) let user7 = ChatMessage(messageId: "1017", messageType: "text", messageContent: "12345", senderId: "1", targetId: "2") ChatMessage.insert(message: user7) let user8 = ChatMessage(messageId: "1018", messageType: "text", messageContent: "12345", senderId: "1", targetId: "123") ChatMessage.insert(message: user8) let message1 = ChatMessage.query(userId: "123", page: 0) print(message1) }