【Swift】GRDB數據庫本地存儲聊天記錄

  

//
//  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
            }
        }
    }
}

   使用示例:

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)

    }

 

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章