//
// CacheManage.swift
// MMore
//
// Created by life on 2017/4/17.
// Copyright ? 2017年 TT. All rights reserved.
//
import UIKit
import FMDB
import HandyJSON
//MARK:- 存儲(chǔ)配置表
public let serializationCache:String = "serializationCache"http://存儲(chǔ)序列化字段
enum cacheTableName {//表名 :以對應(yīng)數(shù)據(jù)庫名開頭
case db_login
case db_status
case db_useinfo //單聊用戶信息
}
class CacheManage: NSObject {
var databasePath: String!
// var database: FMDatabase?
var dataqueue:FMDatabaseQueue?
//數(shù)據(jù)庫名
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) {//不用單例是因?yàn)樾枰峁┙ǘ鄠€(gè)數(shù)據(jù)庫 sql_database
// super.init()
// let documentsDirectory = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]) as String
// databasePath = documentsDirectory.appending("/\(sqlName)")
// //判斷如果數(shù)據(jù)庫存在則不用init
// if !fileManager.fileExists(atPath: databasePath) {
// dataqueue = FMDatabaseQueue.init(path: databasePath)
// }
// }
}
extension CacheManage{//表結(jié)構(gòu)
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:- 按業(yè)務(wù)擴(kuò)展對應(yīng)方法
extension CacheManage {//MARK:- 單聊用戶信息
func getUserInfoByIdHX(userid:String)->UseInfoModel?{
let arr = CacheManage.shared.queryDataWith(tableName: .db_useinfo, dataDic:["user_id":userid]) //都會(huì)返回一個(gè)數(shù)組,即使空數(shù)組
if arr.count > 0 {
//字典轉(zhuǎn)模型
let dic = arr[0] as! [String:Any]?//一個(gè)id對應(yīng)一個(gè)數(shù)組元素,即字典
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:- 增刪改查原始語句
/// 創(chuàng)建表
///
/// - Parameters:
/// - tableName: 表名
/// - fieldDic: 字段
func creatTable(tableName:cacheTableName,fieldDic:Dictionary<String, String>?) {//創(chuàng)表
//1.構(gòu)造字符串字段
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.創(chuàng)表
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())")
}
}
}
}
/// 新增數(shù)據(jù)
///
/// - Parameters:
/// - tableName: 表名
/// - dataDic: 新增的數(shù)據(jù)
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
//有序列號(hào)字段就序列號(hào),沒有就不處理
if dataDic[serializationCache] != nil {
let data = NSKeyedArchiver.archivedData(withRootObject: dataDic[serializationCache] ?? "" ) as Data
serialDic[serializationCache] = data
}
//表不存在就創(chuàng)表
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)//傳的字段和表的字段要對應(yīng)才插入成功
})
}
/// 根據(jù)指定字段刪除 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)//空格算一個(gè)字符
}
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))//這里的賦值有漏洞,存在不對應(yīng)概率
}
})
}
/// 更新表格字段:根據(jù)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))
})
}
/// 根據(jù)Dic的鍵值對查詢表
///
/// - Parameters:
/// - tableName: 表名
/// - Dic: 字段和值
/// - Returns: 字典元素?cái)?shù)組
@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)//空格算一個(gè)字符
}
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)//對應(yīng)表的字段
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
}
}
iOS數(shù)據(jù)存儲(chǔ)通用配置
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
推薦閱讀更多精彩內(nèi)容
- 一、本期主題 看得見別人的好。 二、摘抄和感想 1.盡量跳出一個(gè)非此即彼的狀態(tài),動(dòng)用自己的元認(rèn)知能力,去尋找共贏的...
- 1 春天似乎跑步來到了我們中間,今天的天氣一下子變暖了。 吃過晚飯,七點(diǎn)一過,我們就準(zhǔn)備出發(fā)了,四個(gè)月來每晚的健走...