| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- //
- // DatabaseHelper.swift
- // MTP2_iOS
- //
- // Created by zhongyuan on 2018/6/9.
- // Copyright © 2018年 zhongyuan.All rights reserved.
- //
- import UIKit
- import CoreData
- enum DataBaseError: Error {
- case NoFindUser
- case NoFindSelfGoods
- }
- /// Database Helper
- class DatabaseHelper {
-
- // MARK: - 属性列表
- /// 全局单例
- static let appDelegate = UIApplication.shared.delegate as! AppDelegate
-
- // MARK: - 生命周期
- static func firstOpenInitialData() {
- /// 判断是否第一次运行
- if !UserDefaultsUtils.isFirstOpen() { return }
- /// 初始化可能与登录相关的错误码
- var errorCodeInfos = [MoErrorInfo]()
- errorCodeInfos.append(MoErrorInfo(description: "账号或密码不匹配", errorcode: "1003", errorid: 1003, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
- errorCodeInfos.append(MoErrorInfo(description: "无效账号", errorcode: "1004", errorid: 1004, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
- errorCodeInfos.append(MoErrorInfo(description: "账号类型不匹配", errorcode: "1005", errorid: 1005, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
- errorCodeInfos.append(MoErrorInfo(description: "账号不在线", errorcode: "1006", errorid: 1006, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
- errorCodeInfos.append(MoErrorInfo(description: "操作权限不够", errorcode: "1007", errorid: 1007, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
- errorCodeInfos.append(MoErrorInfo(description: "会员无账户在线", errorcode: "1008", errorid: 1008, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
- errorCodeInfos.append(MoErrorInfo(description: "账户在别处登录", errorcode: "1009", errorid: 1009, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
- errorCodeInfos.append(MoErrorInfo(description: "值为空", errorcode: "1010", errorid: 1010, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
- errorCodeInfos.append(MoErrorInfo(description: "登录账户已经存在", errorcode: "1011", errorid: 1011, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
- errorCodeInfos.append(MoErrorInfo(description: "软件版本过低不能登录", errorcode: "1012", errorid: 1012, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
- errorCodeInfos.append(MoErrorInfo(description: "IP地址不在允许范围内", errorcode: "1013", errorid: 1013, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
- errorCodeInfos.append(MoErrorInfo(description: "地址查询错误,请稍候重试", errorcode: "1025", errorid: 1025, modulecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", operatecode: "ERR_ORDERWRTRADE_FIXEDPRICE_PRICE_INVALID", rownumber: ""))
-
- try? updateErrorInfos(errorInfos: errorCodeInfos)
- }
-
- // MARK: - 账户相关
- /// 获取指定用户id的本地用户信息对象
- ///
- /// - Parameter userID: 用户id
- /// - Returns: 用户信息对象
- static func getUser(loginID: String) throws -> UserEntity? {
- let fetchRequest: NSFetchRequest<UserEntity> = UserEntity.fetchRequest()
- fetchRequest.predicate = NSPredicate(format: "loginID == %@", loginID)
- let result = try DatabaseHelper.appDelegate.backGroundObjectContext.fetch(fetchRequest)
- return result.count != 0 ? result[0] : nil
- }
- /// 获取所有保存的用户信息
- ///
- /// - Parameter type: 类型,0为实盘(默认值);1为模拟盘
- /// - Returns: 用户信息数组
- /// - Throws: 数据库操作错误
- static func getUsers() throws -> [UserEntity]? {
- let fetchRequest: NSFetchRequest<UserEntity> = UserEntity.fetchRequest()
- fetchRequest.sortDescriptors = [NSSortDescriptor(key: "loginDate", ascending: false)]
- let result = try DatabaseHelper.appDelegate.backGroundObjectContext.fetch(fetchRequest)
- return result.count != 0 ? result : nil
- }
-
- /// - Parameters:
- /// - userID: 用户id
- /// - loginID: 登录id
- /// - type: 类型,0为实盘(默认值);1为模拟盘
- /// - Throws: 数据库操作错误
- static func addUser(userID: UInt32, loginID: String, _ loginDate: Date = Date()) throws {
- if let userEntity = try getUser(loginID: loginID) {
- userEntity.loginDate = loginDate
- } else {
- guard let userEntity = NSEntityDescription.insertNewObject(forEntityName: "UserEntity", into: DatabaseHelper.appDelegate.backGroundObjectContext) as? UserEntity else { return }
- userEntity.userID = Int64(Int32(userID))
- userEntity.loginID = loginID
- userEntity.loginDate = loginDate
- }
-
- DatabaseHelper.appDelegate.backGroundObjectContext.perform {
- if DatabaseHelper.appDelegate.backGroundObjectContext.hasChanges {
- try? DatabaseHelper.appDelegate.backGroundObjectContext.save()
- }
- }
- }
-
- /// 删除用户信息
- /// - Parameter loginID: loginID
- static func deleteUser(loginID: String) throws {
- do {
- if let userEntity = try getUser(loginID: loginID) {
- DatabaseHelper.appDelegate.backGroundObjectContext.perform {
- DatabaseHelper.appDelegate.backGroundObjectContext.delete(appDelegate.backGroundObjectContext.object(with: userEntity.objectID))
- if DatabaseHelper.appDelegate.backGroundObjectContext.hasChanges {
- try? DatabaseHelper.appDelegate.backGroundObjectContext.save()
- }
- }
- }
- } catch {
- throw DataBaseError.NoFindUser
- }
- }
-
- // MARK: - 错误码、枚举相关
- static func updateErrorInfos(errorInfos: [MoErrorInfo]) throws {
- /// 数据为空不做任何处理
- if errorInfos.count <= 0 { return }
- appDelegate.backGroundObjectContext.perform {
- for moErrorInfo in errorInfos {
- if try! getError(errorcode: moErrorInfo.errorcode) == nil {
- /// FIXME: 可能会报 EXC_BAD_ACCESS
- guard let entity = NSEntityDescription.insertNewObject(forEntityName: "ErrorCodeEntity", into: appDelegate.backGroundObjectContext) as? ErrorCodeEntity else { return }
- entity.errordesc = moErrorInfo.description
- entity.rownumber = moErrorInfo.rownumber
- entity.operatecode = moErrorInfo.operatecode
- entity.errorid = Int64(moErrorInfo.errorid)
- entity.errorcode = moErrorInfo.errorcode
- }
- }
- if appDelegate.backGroundObjectContext.hasChanges {
- try? appDelegate.backGroundObjectContext.save()
- }
- }
- }
-
- /// 移出所有错误码信息
- /// - Throws: Throws
- static func deleteAllErrorInfos() throws {
- let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ErrorCodeEntity")
- let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
- try appDelegate.backGroundObjectContext.execute(batchDeleteRequest)
- }
-
- /// 获取对应的错误码信息
- /// - Parameter errorCode: errorCode
- /// - Throws: Throws
- /// - Returns: ErrorCodeEntity
- static func getError(errorcode: String) throws -> ErrorCodeEntity? {
- let fetchRequest: NSFetchRequest<ErrorCodeEntity> = ErrorCodeEntity.fetchRequest()
- fetchRequest.predicate = NSPredicate(format: "errorcode == %@", errorcode)
- let result = try appDelegate.backGroundObjectContext.fetch(fetchRequest)
- return result.count != 0 ? result[0] : nil
- }
-
- /// 获取所有得错误码信息
- /// - Parameter divisions: divisions
- static func getAllErrorInfos() throws -> [ErrorCodeEntity] {
- let fetchRequest: NSFetchRequest<ErrorCodeEntity> = ErrorCodeEntity.fetchRequest()
- fetchRequest.sortDescriptors = [NSSortDescriptor(key: "errorid", ascending: true)]
- let errors = (try? appDelegate.backGroundObjectContext.fetch(fetchRequest)) ?? []
- return errors
- }
-
- /// 添加枚举到数据库
- /// - Parameter enumInfos: enumInfos
- /// - Throws: throws
- static func addEnumInfos(enumInfos: [MoEnum]) throws {
- /// 异常
- if enumInfos.count <= 0 { return }
- appDelegate.backGroundObjectContext.perform {
- for enumInfo in enumInfos {
- /// FIXME: 可能会报 EXC_BAD_ACCESS
- guard let enumEntity = NSEntityDescription.insertNewObject(forEntityName: "EnumEntity", into: appDelegate.backGroundObjectContext) as? EnumEntity else { return }
- enumEntity.setupWith(enumInfo: enumInfo)
- }
-
- if appDelegate.backGroundObjectContext.hasChanges {
- try? appDelegate.backGroundObjectContext.save()
- }
- }
- }
-
- /// 移出所有的枚举信息
- /// - Throws: Throws
- static func deleteAllEnumInfos() throws {
- let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "EnumEntity")
- let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
- try appDelegate.backGroundObjectContext.execute(batchDeleteRequest)
- }
-
- /// 获取特定的枚举信息
- /// - Parameter autoid: autoid
- /// - Throws: Throws
- /// - Returns: EnumEntity
- static func getEnumInfo(autoid: Int16) throws -> EnumEntity? {
- let fetchRequest: NSFetchRequest<EnumEntity> = EnumEntity.fetchRequest()
- fetchRequest.sortDescriptors = [NSSortDescriptor(key: "autoid", ascending: true)]
- fetchRequest.predicate = NSPredicate(format: "autoid == %d", autoid)
- let result = try appDelegate.backGroundObjectContext.fetch(fetchRequest)
- /// 执行回调
- return result.count != 0 ? result[0] : nil
- }
-
- /// 获取特定的枚举信息
- /// - Parameter enumdiccode: autoid
- /// - Throws: Throws
- /// - Returns: EnumEntity
- static func getEnumInfo(enumdiccode: String?) throws -> [MoEnum]? {
- let fetchRequest: NSFetchRequest<EnumEntity> = EnumEntity.fetchRequest()
- fetchRequest.sortDescriptors = [NSSortDescriptor(key: "autoid", ascending: true)]
- if let code = enumdiccode { fetchRequest.predicate = NSPredicate(format: "enumdiccode == %@", code) }
- let result = try appDelegate.backGroundObjectContext.fetch(fetchRequest)
- /// 执行回调
- return result.count != 0 ? result.compactMap({ $0.toMoEnum() }) : nil
- }
-
- // MARK: - 区域信息
- /// 添加区域信息到数据库
- /// - Parameter divisions: divisions
- static func addDivisions(_ divisions: [MoDivisions]) throws {
- /// 异常
- if divisions.count <= 0 {
- return
- }
- /// 先移出所有的地区区域信息
- try deleteAllDivisions()
-
- appDelegate.backGroundObjectContext.perform {
- for info in divisions {
- /// 可能会报 EXC_BAD_ACCESS
- guard let cityEntity = NSEntityDescription.insertNewObject(forEntityName: "CityEntity", into: appDelegate.backGroundObjectContext) as? CityEntity else { return }
- cityEntity.setupWith(division: info)
- }
- if appDelegate.backGroundObjectContext.hasChanges {
- try? appDelegate.backGroundObjectContext.save()
- }
- }
- }
-
- /// 移出所有的区域信息
- /// - Throws: Throws
- static func deleteAllDivisions() throws {
- let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "CityEntity")
- let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
- try appDelegate.backGroundObjectContext.execute(batchDeleteRequest)
- }
-
- /// 获取所有的区域信息
- /// - Parameter divisions: divisions
- static func getAllDivisions() throws -> [MoDivisions] {
- let fetchRequest: NSFetchRequest<CityEntity> = CityEntity.fetchRequest()
- fetchRequest.sortDescriptors = [NSSortDescriptor(key: "autoid", ascending: true)]
- let citys = try appDelegate.backGroundObjectContext.fetch(fetchRequest)
- let divisions = citys.compactMap({ $0.toDivisions() })
- return divisions
- }
-
- // MARK: - 商品相关
- static func insertGoodsInfos(_ goodsInfos: [MoGoodsInfo]) throws {
- /// 先移出商品
- do {
- for goods in goodsInfos {
- let exist = try? getGoodsInfo(ById: goods.goodsid)
- if exist ?? false { removeGoodsInfo(goods.goodsid) }
- }
- }
-
- appDelegate.backGroundObjectContext.performAndWait {
- do {
- for obj in goodsInfos {
- guard let goodsInfoEntity = NSEntityDescription.insertNewObject(forEntityName: "GoodsInfoEntity", into: appDelegate.backGroundObjectContext) as? GoodsInfoEntity else {
- continue
- }
- goodsInfoEntity.setupWith(goodsInfo: obj)
- }
- if appDelegate.backGroundObjectContext.hasChanges {
- try appDelegate.backGroundObjectContext.save()
- } else {
- dPrint("商品本地化失败")
- }
- } catch {
- fatalError("商品数据插入失败")
- }
- }
- }
-
- /// 判断指定商品信息是否存在
- ///
- /// - Parameter Id: 商品ID
- /// - Returns: yes: 存在 no: 不存在
- /// - Throws:
- static func getGoodsInfo(ById Id: Int) throws -> Bool {
- let fetchRequest: NSFetchRequest<GoodsInfoEntity> = GoodsInfoEntity.fetchRequest()
- fetchRequest.predicate = NSPredicate(format: "goodsid == %ld", Int32(Id))
- let count = try appDelegate.backGroundObjectContext.count(for: fetchRequest)
- return count > 0
- }
-
- /// 获取所有商品信息
- ///
- /// - Returns: 所有保存的商品信息
- /// - Throws:
- static func getGoodsInfo() throws -> [MoGoodsInfo] {
- let fetchRequest: NSFetchRequest<GoodsInfoEntity> = GoodsInfoEntity.fetchRequest()
- fetchRequest.sortDescriptors = [NSSortDescriptor(key: "goodsid", ascending: true)]
- let goodsInfos = try appDelegate.backGroundObjectContext.fetch(fetchRequest)
- let moGoodsInfos = goodsInfos.compactMap({ $0.toMoGoodsInfo() })
- return moGoodsInfos
- }
-
- /// 判断本地数据库是否有数据
- ///
- /// - Returns: yes: 存在 no: 不存在
- /// - Throws:
- static func goodsInfoIsExist() -> Bool {
- let fetchRequest: NSFetchRequest<GoodsInfoEntity> = GoodsInfoEntity.fetchRequest()
- do {
- let count = try appDelegate.backGroundObjectContext.count(for: fetchRequest)
- return count > 0
- } catch {
- fatalError()
- }
- }
-
- /// 根据查询条件获取符合条件的商品
- ///
- /// - Parameter searchCondition: 查询条件
- /// - Returns: 符合条件的商品
- /// - Throws:
- static func getGoodsInfo(ByCondition searchCondition: String) throws -> [MoGoodsInfo] {
-
- guard !searchCondition.isEmpty else { return [] }
-
- let fetchRequest: NSFetchRequest<GoodsInfoEntity> = GoodsInfoEntity.fetchRequest()
- if RegularUtils.checkNumber(with: searchCondition) {
- let regularString = ".*\(searchCondition).*"
- fetchRequest.predicate = NSPredicate(format: "searchCondition MATCHES %@", regularString)
- } else {
- var regularString = ".*"
- for s in searchCondition.uppercased() {
- regularString.append(s)
- regularString.append(".*")
- }
- fetchRequest.predicate = NSPredicate(format: "searchCondition MATCHES %@", regularString)
- }
-
- /// 排序
- fetchRequest.sortDescriptors = [NSSortDescriptor(key: "goodscode", ascending: true)]
- let goodsInfos = try appDelegate.backGroundObjectContext.fetch(fetchRequest)
- let moGoodsInfos = goodsInfos.compactMap({ $0.toMoGoodsInfo() })
- return moGoodsInfos
- }
-
- /// 删除所有的商品数据信息
- static func removeAllGoodsInfo() {
- /// 获取上下文对象
- let viewContext = appDelegate.persistentContainer.viewContext
- /// 获取实例
- let entity = NSFetchRequest<NSFetchRequestResult>(entityName: "GoodsInfoEntity")
- let deleteRequest = NSBatchDeleteRequest(fetchRequest: entity)
- let _ = try? viewContext.persistentStoreCoordinator?.execute(deleteRequest, with: viewContext)
-
- appDelegate.backGroundObjectContext.perform {
- if appDelegate.backGroundObjectContext.hasChanges {
- do {
- _ = try? viewContext.persistentStoreCoordinator?.execute(deleteRequest, with: viewContext)
- }
- }
- }
- }
-
- /// 删除所有的商品数据信息
- static func removeGoodsInfo(_ goodsid: Int) {
- /// 获取上下文对象
- let viewContext = appDelegate.persistentContainer.viewContext
- /// 获取实例
- let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "GoodsInfoEntity")
- fetchRequest.predicate = NSPredicate(format: "goodsid == %ld", Int64(goodsid))
- let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
- let _ = try? viewContext.persistentStoreCoordinator?.execute(deleteRequest, with: viewContext)
-
- appDelegate.backGroundObjectContext.perform {
- if appDelegate.backGroundObjectContext.hasChanges {
- do {
- _ = try? viewContext.persistentStoreCoordinator?.execute(deleteRequest, with: viewContext)
- }
- }
- }
- }
-
- /// 根据goodsid获取对应的商品数据
- /// - Parameter goodsid: goodsid
- static func getMoGoodsInfo(where goodsids: [Int]) throws -> [MoGoodsInfo]? {
- /// 获取商品数据
- var goodsInfo: [MoGoodsInfo] = []
- let fetchRequest: NSFetchRequest<GoodsInfoEntity> = GoodsInfoEntity.fetchRequest()
- for goodsid in goodsids {
- fetchRequest.predicate = NSPredicate(format: "goodsid == %ld", Int64(goodsid))
- let goodsInfos = try appDelegate.backGroundObjectContext.fetch(fetchRequest)
- if goodsInfos.count != 0 { goodsInfo.append(goodsInfos[0].toMoGoodsInfo()) }
- }
- return goodsInfo
- }
- }
-
|