iOS數(shù)據(jù)存儲(chǔ)通用配置

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


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(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)知能力,去尋找共贏的...
    楊振林閱讀 269評論 0 0
  • 不知道是因?yàn)榈搅四硞€(gè)年齡段,還是因?yàn)楦星槭莻€(gè)高頻話題,終于開始有所意識(shí),也試著思考關(guān)于愛情的問題。 以前的自己,以...
    棉棉墨依閱讀 194評論 0 0
  • 1 春天似乎跑步來到了我們中間,今天的天氣一下子變暖了。 吃過晚飯,七點(diǎn)一過,我們就準(zhǔn)備出發(fā)了,四個(gè)月來每晚的健走...
    清清小胖閱讀 479評論 2 9
  • t60,大學(xué)生戶外運(yùn)動(dòng),大學(xué)生戶外運(yùn)動(dòng)安全,沙發(fā)客
    分芬閱讀 91評論 0 0