//
// CacheManage.swift
// MMore
//
// Created by life on 2017/4/17.
// Copyright © 2017年 TT. All rights reserved.
//
import UIKit
import FMDB
import HandyJSON
//MARK:- 存储配置表
public let serializationCache:String = "serializationCache"//存储序列化字段
enum cacheTableName {//表名 :以对应数据库名开头
case db_login
case db_status
case db_useinfo //单聊用户信息
}
class CacheManage: NSObject {
var databasePath: String!
// var database: FMDatabase?
var dataqueue:FMDatabaseQueue?
//数据库名
let sql_database = "db.sqlite"
fileprivate var fileManager: FileManager = FileManager.default
static let shared: CacheManage = CacheManage()
override init() { //初始化
let documentsDirectory = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]) as String
databasePath = documentsDirectory.appending("/\(sql_database)")
dataqueue = FMDatabaseQueue.init(path: databasePath)
}
// @discardableResult init(sqlName: String) {//不用单例是因为需要提供建多个数据库 sql_database
// super.init()
// let documentsDirectory = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]) as String
// databasePath = documentsDirectory.appending("/\(sqlName)")
// //判断如果数据库存在则不用init
// if !fileManager.fileExists(atPath: databasePath) {
// dataqueue = FMDatabaseQueue.init(path: databasePath)
// }
// }
}
extension CacheManage{//表结构
func getFieldDicWith(tableName:cacheTableName) -> Dictionary<String,String> {
var dic = [String:String]()
switch tableName {
case cacheTableName.db_login:
dic = [serializationCache:"BLOB","store_id":"TEXT","m_auth":"TEXT","user_name":"TEXT"]
case cacheTableName.db_status:
dic = ["aaaa":"TEXT","bbbb":"TEXT","cccc":"TEXT"]
case cacheTableName.db_useinfo:
dic = ["nickName":"TEXT","user_id":"TEXT","avator":"TEXT"]
}
return dic
}
}
//MARK:- 按业务扩展对应方法
extension CacheManage {//MARK:- 单聊用户信息
func getUserInfoByIdHX(userid:String)->UseInfoModel?{
let arr = CacheManage.shared.queryDataWith(tableName: .db_useinfo, dataDic:["user_id":userid]) //都会返回一个数组,即使空数组
if arr.count > 0 {
//字典转模型
let dic = arr[0] as! [String:Any]?//一个id对应一个数组元素,即字典
let useInfoModel = JSONDeserializer<UseInfoModel>.deserializeFrom(dict: dic as NSDictionary?)
return useInfoModel
}else{
return nil
}
}
func saveUserInfoWith(userId:String,avatorUrl:String,nickName:String){
var userInfoDic = [String:Any]()
userInfoDic["nickName"] = nickName
userInfoDic["user_id"] = userId
userInfoDic["avator"] = avatorUrl
CacheManage.shared.saveDataWith(tableName: .db_useinfo, dataDic: userInfoDic)
}
}
//-----------------------------------------------------------------------------
extension CacheManage{ //MARK:- 增删改查原始语句
/// 创建表
///
/// - Parameters:
/// - tableName: 表名
/// - fieldDic: 字段
func creatTable(tableName:cacheTableName,fieldDic:Dictionary<String, String>?) {//创表
//1.构造字符串字段
func fieldStrWithDictionary(fieldDic:Dictionary<String, String>) -> String {
//拼接查询语句
let dicKey=Array(fieldDic.keys)
var str:String = ""
for temp in dicKey {
str += temp + " " + fieldDic[temp]! + " NOT NULL,"
}
//裁剪字符串
let index = str.index(str.endIndex, offsetBy: -1)
let fieldStr = str.substring(to: index)
return fieldStr
}
//2.创表
let fieldStr = fieldStrWithDictionary(fieldDic: fieldDic!)
let sql = "CREATE TABLE IF NOT EXISTS \(tableName) (id integer PRIMARY KEY, \(fieldStr));"
dataqueue?.inDatabase { (db:FMDatabase?) in
if (db?.open())! {
if !(db?.executeStatements(sql))! {
print("Error: \(db?.lastErrorMessage())")
}
}
}
}
/// 新增数据
///
/// - Parameters:
/// - tableName: 表名
/// - dataDic: 新增的数据
func saveDataWith(tableName:cacheTableName,dataDic:Dictionary<String, Any>) {//增
//处理字符串
func getFieldsWith(fieldDic:Dictionary<String, String>,Dic:Dictionary<String, Any>)->(String,String,Array<Any>){
let fieldKeys=Array(fieldDic.keys)
var keysStr:String = ""
var flagStr:String = ""
var valueArray:Array = [Any]()
for temp in fieldKeys {
keysStr += temp + ","
flagStr += "?,"
valueArray.append(Dic[temp] ?? "")
}
let fieldStr = keysStr.subStringLastChar(originalStr: keysStr, num: -1)
let flaggStr = flagStr.subStringLastChar(originalStr: flagStr, num: -1)
return (fieldStr,flaggStr,valueArray)
}
var serialDic = [String:Any]()
serialDic = dataDic
//有序列号字段就序列号,没有就不处理
if dataDic[serializationCache] != nil {
let data = NSKeyedArchiver.archivedData(withRootObject: dataDic[serializationCache] ?? "" ) as Data
serialDic[serializationCache] = data
}
//表不存在就创表
let fieldDic = getFieldDicWith(tableName: tableName)
creatTable(tableName: tableName, fieldDic: fieldDic)
dataqueue?.inDatabase({ (db:FMDatabase?) in
//添加新增语句
let fieldTuples = getFieldsWith(fieldDic: fieldDic,Dic:serialDic)
let insertSql = "INSERT INTO \(tableName)(\(fieldTuples.0)) VALUES (\(fieldTuples.1));"
db?.executeUpdate(insertSql, withArgumentsIn: fieldTuples.2)//传的字段和表的字段要对应才插入成功
})
}
/// 根据指定字段删除 or dic==nil 则删掉表
///
/// - Parameters:
/// - tableName: 表名
/// - dic: 指定字段及值for字典形式
func delectDataWith(tableName:cacheTableName,dic:Dictionary<String,Any>? = nil) {//删
func getFieldsWith(fieldDic:Dictionary<String, String>)->(String){
let fieldKeys=Array(fieldDic.keys)
var keysStr:String = ""
if fieldKeys.count == 1 {
keysStr += fieldKeys[0] + " = ? "
}else{
for temp in fieldKeys {
keysStr += temp + " = ? and "
}
keysStr = keysStr.subStringLastChar(originalStr: keysStr, num: -4)//空格算一个字符
}
return keysStr
}
dataqueue?.inDatabase({ (db:FMDatabase?) in
if dic == nil { //删表
let delectSql = "DELETE FROM \(tableName)"
db?.executeUpdate(delectSql, withArgumentsIn: nil)
}else{
let fieldStringS = getFieldsWith(fieldDic: dic as! Dictionary<String, String>)
let delectSql = "DELETE FROM \(tableName) WHERE \(fieldStringS)"
db?.executeUpdate(delectSql, withArgumentsIn: Array(dic!.values))//这里的赋值有漏洞,存在不对应概率
}
})
}
/// 更新表格字段:根据whereDic更新dataDic
///
/// - Parameters:
/// - tableName: 表名
/// - dataDic: 修改字段及值
/// - whereDic: 查询字段及值
func updateDataWith(tableName:cacheTableName,dataDic:Dictionary<String, Any>,whereDic:Dictionary<String, Any>){
func subStr(Dic:Dictionary<String, Any>)->String{
let Keys=Array(Dic.keys)
var str = ""
for temp in Keys {
str = temp + "=?,"
}
str = str.subStringLastChar(originalStr: str, num: -1)
return str
}
dataqueue?.inDatabase({ (db:FMDatabase?) in
let fieldStr = subStr(Dic: dataDic)
let whereStr = subStr(Dic: whereDic)
let qudateSQL = "UPDATE \(tableName) SET \(fieldStr) WHERE \(whereStr)"
db?.executeUpdate(qudateSQL, withArgumentsIn: Array(dataDic.values) + Array(whereDic.values))
})
}
/// 根据Dic的键值对查询表
///
/// - Parameters:
/// - tableName: 表名
/// - Dic: 字段和值
/// - Returns: 字典元素数组
@discardableResult func queryDataWith(tableName:cacheTableName,dataDic:Dictionary<String, Any>) -> [Any?] {
//1.
func getFieldsWith(fieldDic:Dictionary<String, String>)->(String){
let fieldKeys=Array(fieldDic.keys)
var keysStr:String = ""
if fieldKeys.count == 1 {
keysStr += fieldKeys[0] + " = ? "
}else{
for temp in fieldKeys {
keysStr += temp + " = ? and "
}
keysStr = keysStr.subStringLastChar(originalStr: keysStr, num: -4)//空格算一个字符
}
return keysStr
}
//2.
let queryStr = getFieldsWith(fieldDic: dataDic as! Dictionary<String, String>)
var ArgumentDic = [String:Any]()
var ArgumentArr = [Dictionary<String, Any>]()
dataqueue?.inDatabase({ (db:FMDatabase?) in
if (db?.tableExists(String(describing: tableName)))! {//判断表是否存在
let selectSQL = "SELECT * FROM \(tableName) WHERE \(queryStr)"
let rs = db?.executeQuery(selectSQL, withArgumentsIn: Array(dataDic.values))
let fieldDic = self.getFieldDicWith(tableName: tableName)
while (rs?.next())! {
let Keys = Array(fieldDic.keys)//对应表的字段
for temp in Keys {
switch fieldDic[temp]! as String {
case "TEXT":
ArgumentDic[temp] = rs?.string(forColumn: temp)
case "BLOB":
let data = rs?.data(forColumn: temp)
ArgumentDic[temp] = NSKeyedUnarchiver.unarchiveObject(with: data! ) //反序列化
case "INTEGER":
ArgumentDic[temp] = rs?.int(forColumn: temp)
case "DATETIME":
ArgumentDic[temp] = rs?.date(forColumn: temp)
default:
ArgumentDic[temp] = rs?.object(forColumnName: temp)
}
}
ArgumentArr.append(ArgumentDic)
}
}
})
return ArgumentArr
}
}
网友评论