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