You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
547 lines
28 KiB
547 lines
28 KiB
1 year ago
|
//
|
||
|
// DataBaseManager.swift
|
||
|
// FunDoHealth
|
||
|
//
|
||
|
// Created by ecell on 2018/6/8.
|
||
|
// Copyright © 2020年 ecell. All rights reserved.
|
||
|
//
|
||
|
|
||
|
import Foundation
|
||
|
import FMDB
|
||
|
|
||
|
/// 通用路径
|
||
|
let ecellBasicPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,FileManager.SearchPathDomainMask.userDomainMask,true).first!
|
||
|
|
||
|
// MARK:- 常量
|
||
|
fileprivate struct Metric {
|
||
|
/// 数据库名称
|
||
|
static let dataBasePath = ecellBasicPath + "/" + "Lookfit.sqlite"
|
||
|
/// 数据表名
|
||
|
static let table_step = "table_step"
|
||
|
static let table_sleep = "table_sleep"
|
||
|
static let table_heartRate = "table_heartRate"
|
||
|
static let table_sport = "table_sport"
|
||
|
static let table_temperature = "table_temperature"
|
||
|
static let table_bloodPressure = "table_bloodPressure"
|
||
|
static let table_bloodOxygen = "table_bloodOxygen"
|
||
|
/// 数据类型获取对应的数据标名称
|
||
|
static func tableName(dataType: DataType) -> String {
|
||
|
switch dataType {
|
||
|
case .step: return table_step
|
||
|
case .sleep: return table_sleep
|
||
|
case .heartRate: return table_heartRate
|
||
|
case .sport: return table_sport
|
||
|
case .temperature: return table_temperature
|
||
|
case .bloodPressure: return table_bloodPressure
|
||
|
case .bloodOxygen: return table_bloodOxygen
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 数据类型
|
||
|
public enum DataType: Int {
|
||
|
case step
|
||
|
case sleep
|
||
|
case heartRate
|
||
|
case sport
|
||
|
case temperature
|
||
|
case bloodPressure
|
||
|
case bloodOxygen
|
||
|
}
|
||
|
|
||
|
/// 数据查询类型
|
||
|
enum DataQueryType: Int {
|
||
|
case day
|
||
|
case week
|
||
|
case month
|
||
|
case year
|
||
|
case all
|
||
|
}
|
||
|
|
||
|
/// 数据查询闭包
|
||
|
typealias ResultClosure = ([BaseJsonModel]) -> ()
|
||
|
|
||
|
/// 数据表最近插入数据时间
|
||
|
typealias LastRecordClosure = (Int?) -> ()
|
||
|
|
||
|
// MARK:- 初始化
|
||
|
final class DataBaseManager: NSObject {
|
||
|
/// 单例
|
||
|
static let shared = DataBaseManager()
|
||
|
/// 需要在oc中调用此单例
|
||
|
@objc public class func ocShareInstance() -> DataBaseManager {
|
||
|
return shared
|
||
|
}
|
||
|
|
||
|
private override init() {
|
||
|
super.init()
|
||
|
createDataTables()
|
||
|
}
|
||
|
/// 数据库
|
||
|
let dataBase = FMDatabaseQueue(path: Metric.dataBasePath)
|
||
|
|
||
|
/// 创建表
|
||
|
private func createDataTables() {
|
||
|
dataBase?.inDatabase { (db) in
|
||
|
// 运动数据表
|
||
|
db.executeUpdate("CREATE TABLE IF NOT EXISTS \(Metric.table_sport) (id INTEGER PRIMARY KEY, macID TEXT NOT NULL, verison INTEGER NOT NULL, sportType INTEGER NOT NULL, dataDate TEXT NOT NULL, duration INTEGER NOT NULL, distance INTEGER NOT NULL, calorie FLOAT NOT NULL, stepNumber INTEGER NOT NULL, heartMax INTEGER NOT NULL, heartAvg INTEGER NOT NULL, heartMin INTEGER NOT NULL, stepFrequencyMax INTEGER NOT NULL, stepFrequencyAvg INTEGER NOT NULL, stepFrequencyMin INT NOT NULL, paceMax INTEGER NOT NULL, paceAvg INTEGER NOT NULL, paceMin INTEGER NOT NULL, startAltitude INTEGER NOT NULL, endAltitude INTEGER NOT NULL, gpsCount INTEGER NOT NULL, kmCount INTEGER NOT NULL, stepCount INTEGER NOT NULL, heartCount INTEGER NOT NULL, trainDetailCount INTEGER NOT NULL, gpsTimestamp INTEGER NOT NULL, gpsDeatail TEXT NULL, kmDetail TEXT NULL, stepTimestamp INTEGER NOT NULL, stepDetail TEXT NULL, hrsTimestamp INTEGER NOT NULL, hrsDetail TEXT NULL, swimmingDetail TEXT NULL);", withArgumentsIn: [])
|
||
|
// 计步数据表
|
||
|
db.executeUpdate("CREATE TABLE IF NOT EXISTS \(Metric.table_step) (id INTEGER PRIMARY KEY, macID TEXT NOT NULL, dataDate TEXT NOT NULL, stepNumber INTEGER NOT NULL, stepDistance INTEGER NOT NULL, stepCalorie FLOAT NOT NULL, stepDuration INTEGER NOT NULL, stepDetails TEXT NULL);", withArgumentsIn: [])
|
||
|
// 心率数据表
|
||
|
db.executeUpdate("CREATE TABLE IF NOT EXISTS \(Metric.table_heartRate) (id INTEGER PRIMARY KEY, macID TEXT NOT NULL, dataDate TEXT NOT NULL, heartMax INTEGER NOT NULL, heartMin INTEGER NOT NULL, heartAvg INTEGER NOT NULL, heartDetails TEXT NULL);", withArgumentsIn: [])
|
||
|
// 睡眠数据表
|
||
|
db.executeUpdate("CREATE TABLE IF NOT EXISTS \(Metric.table_sleep) (id INTEGER PRIMARY KEY, macID TEXT NOT NULL, dataDate TEXT NOT NULL, deepSleepDuration INTEGER NOT NULL, lightSleepDuration INTEGER NOT NULL, awakeDuration INTEGER NOT NULL, totalSleepDuration INTEGER NOT NULL, fallingSleepTimes TEXT NOT NULL, awakeTimes TEXT NOT NULL, awakeNumber INTEGER NOT NULL, sleepDetails TEXT NULL);", withArgumentsIn: [])
|
||
|
// 体温数据表
|
||
|
db.executeUpdate("CREATE TABLE IF NOT EXISTS \(Metric.table_temperature) (id INTEGER PRIMARY KEY, macID TEXT NOT NULL, dataDate TEXT NOT NULL, temperatureMax DOUBLE NOT NULL, temperatureMin DOUBLE NOT NULL, temperatureAvg DOUBLE NOT NULL, temperatureDetails TEXT NULL);", withArgumentsIn: [])
|
||
|
// 血压数据表
|
||
|
db.executeUpdate("CREATE TABLE IF NOT EXISTS \(Metric.table_bloodPressure) (id INTEGER PRIMARY KEY, macID TEXT NOT NULL, dataDate TEXT NOT NULL, sbpMax INTEGER NOT NULL, sbpMin INTEGER NOT NULL, sbpAvg INTEGER NOT NULL, dbpMax INTEGER NOT NULL, dbpMin INTEGER NOT NULL, dbpAvg INTEGER NOT NULL, details TEXT NULL);", withArgumentsIn: [])
|
||
|
// 血氧数据表
|
||
|
db.executeUpdate("CREATE TABLE IF NOT EXISTS \(Metric.table_bloodOxygen) (id INTEGER PRIMARY KEY, macID TEXT NOT NULL, dataDate TEXT NOT NULL, bloodOxygenMax INTEGER NOT NULL, bloodOxygenMin INTEGER NOT NULL, bloodOxygenAvg INTEGER NOT NULL, details TEXT NULL);", withArgumentsIn: [])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// MARK:- 插入数据
|
||
|
extension DataBaseManager {
|
||
|
/// 插入数据
|
||
|
/// - Parameters:
|
||
|
/// - models: 数据模型数组
|
||
|
/// - dataType: 数据类型
|
||
|
func insertModels(models: [BaseJsonModel], dataType: DataType) {
|
||
|
// 插入表名
|
||
|
let tableName = Metric.tableName(dataType: dataType)
|
||
|
switch dataType {
|
||
|
case .sport:
|
||
|
dataBase?.inTransaction({ (db, rollback) in
|
||
|
for model in models {
|
||
|
guard let model = model as? SportModel else { continue }
|
||
|
// 是否存在旧数据
|
||
|
if let _ = SportModel.deserialize(from: querySingleData(db: db, dataDate: model.dataDate, dataType: .sport)) {
|
||
|
continue
|
||
|
}
|
||
|
// 插入数据
|
||
|
let insertSQL = "INSERT INTO \(tableName) (macID,dataDate,verison,sportType,duration,distance,calorie,stepNumber,heartMax,heartAvg,heartMin,stepFrequencyMax,stepFrequencyAvg,stepFrequencyMin,paceMax,paceAvg,paceMin,startAltitude,endAltitude,gpsCount,kmCount,stepCount,heartCount,trainDetailCount,gpsTimestamp,gpsDeatail,kmDetail,stepTimestamp,stepDetail,hrsTimestamp,hrsDetail,swimmingDetail) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"
|
||
|
db.executeUpdate(insertSQL, withArgumentsIn: [model.macID, model.dataDate, model.verison, model.sportType, model.duration, model.distance, model.calorie, model.stepNumber, model.heartMax, model.heartAvg, model.heartMin, model.stepFrequencyMax, model.stepFrequencyAvg, model.stepFrequencyMin, model.paceMax, model.paceAvg, model.paceMin, model.startAltitude, model.endAltitude, model.gpsCount, model.kmCount, model.stepCount, model.heartCount, model.trainDetailCount, model.gpsTimestamp, model.gpsDeatail, model.kmDetail, model.stepTimestamp, model.stepDetail, model.hrsTimestamp, model.hrsDetail, model.swimmingDetail])
|
||
|
}
|
||
|
})
|
||
|
case .sleep:
|
||
|
dataBase?.inTransaction({ (db, rollback) in
|
||
|
for model in models {
|
||
|
guard let model = model as? SleepModel else { continue }
|
||
|
// 是否存在旧数据
|
||
|
if let _ = SleepModel.deserialize(from: querySingleData(db: db, dataDate: model.dataDate, dataType: .sleep)) {
|
||
|
// 更新数据
|
||
|
let updateSQL = "UPDATE \(tableName) SET macID='\(model.macID)', deepSleepDuration='\(model.deepSleepDuration)', lightSleepDuration='\(model.lightSleepDuration)', awakeDuration='\(model.awakeDuration)', totalSleepDuration='\(model.totalSleepDuration)', fallingSleepTimes='\(model.fallingSleepTimes)', awakeTimes='\(model.awakeTimes)', awakeNumber='\(model.awakeNumber)', sleepDetails='\(model.sleepDetails)' WHERE dataDate='\(model.dataDate)'"
|
||
|
db.executeUpdate(updateSQL, withArgumentsIn: [])
|
||
|
continue
|
||
|
}
|
||
|
// 插入数据
|
||
|
let insertSQL = "INSERT INTO \(tableName) (macID,dataDate,deepSleepDuration,lightSleepDuration,awakeDuration,totalSleepDuration,fallingSleepTimes,awakeTimes,awakeNumber,sleepDetails) VALUES (?,?,?,?,?,?,?,?,?,?);"
|
||
|
db.executeUpdate(insertSQL, withArgumentsIn: [model.macID, model.dataDate, model.deepSleepDuration, model.lightSleepDuration, model.awakeDuration, model.totalSleepDuration, model.fallingSleepTimes, model.awakeTimes, model.awakeNumber, model.sleepDetails])
|
||
|
}
|
||
|
})
|
||
|
case .step:
|
||
|
dataBase?.inTransaction({ (db, rollback) in
|
||
|
for model in models {
|
||
|
guard let model = model as? StepModel else { continue }
|
||
|
// 是否存在旧数据
|
||
|
if let _ = StepModel.deserialize(from: querySingleData(db: db, dataDate: model.dataDate, dataType: .step)) {
|
||
|
// 更新数据
|
||
|
let updateSQL = "UPDATE \(tableName) SET macID='\(model.macID)', stepNumber='\(model.stepNumber)', stepDistance='\(model.stepDistance)', stepCalorie='\(model.stepCalorie)', stepDuration='\(model.stepDuration)', stepDetails='\(model.stepDetails)' WHERE dataDate='\(model.dataDate)'"
|
||
|
db.executeUpdate(updateSQL, withArgumentsIn: [])
|
||
|
continue
|
||
|
}
|
||
|
// 插入数据
|
||
|
let insertSQL = "INSERT INTO \(tableName) (macID,dataDate,stepNumber,stepDistance,stepCalorie,stepDuration,stepDetails) VALUES (?,?,?,?,?,?,?);"
|
||
|
db.executeUpdate(insertSQL, withArgumentsIn: [model.macID, model.dataDate, model.stepNumber, model.stepDistance, model.stepCalorie, model.stepDuration, model.stepDetails])
|
||
|
}
|
||
|
})
|
||
|
case .heartRate:
|
||
|
dataBase?.inTransaction({ (db, rollback) in
|
||
|
for model in models {
|
||
|
guard let model = model as? HeartRateModel else { continue }
|
||
|
// 是否存在旧数据
|
||
|
if let _ = HeartRateModel.deserialize(from: querySingleData(db: db, dataDate: model.dataDate, dataType: .heartRate)) {
|
||
|
// 更新数据
|
||
|
let updateSQL = "UPDATE \(tableName) SET macID='\(model.macID)', heartMax='\(model.heartMax)', heartMin='\(model.heartMin)', heartAvg='\(model.heartAvg)', heartDetails='\(model.heartDetails)' WHERE dataDate='\(model.dataDate)'"
|
||
|
db.executeUpdate(updateSQL, withArgumentsIn: [])
|
||
|
continue
|
||
|
}
|
||
|
// 插入数据
|
||
|
let insertSQL = "INSERT INTO \(tableName) (macID,dataDate,heartMax,heartMin,heartAvg,heartDetails) VALUES (?,?,?,?,?,?);"
|
||
|
db.executeUpdate(insertSQL, withArgumentsIn: [model.macID, model.dataDate, model.heartMax, model.heartMin, model.heartAvg, model.heartDetails])
|
||
|
}
|
||
|
})
|
||
|
case .temperature:
|
||
|
dataBase?.inTransaction({ (db, rollback) in
|
||
|
for model in models {
|
||
|
guard let model = model as? TemperatureModel else { continue }
|
||
|
// 是否存在旧数据
|
||
|
if let _ = TemperatureModel.deserialize(from: querySingleData(db: db, dataDate: model.dataDate, dataType: .temperature)) {
|
||
|
// 更新数据
|
||
|
let updateSQL = "UPDATE \(tableName) SET macID='\(model.macID)', temperatureMax='\(model.temperatureMax)', temperatureMin='\(model.temperatureMin)', temperatureAvg='\(model.temperatureAvg)', temperatureDetails='\(model.temperatureDetails)' WHERE dataDate='\(model.dataDate)'"
|
||
|
db.executeUpdate(updateSQL, withArgumentsIn: [])
|
||
|
continue
|
||
|
}
|
||
|
// 插入数据
|
||
|
let insertSQL = "INSERT INTO \(tableName) (macID,dataDate,temperatureMax,temperatureMin,temperatureAvg,temperatureDetails) VALUES (?,?,?,?,?,?);"
|
||
|
db.executeUpdate(insertSQL, withArgumentsIn: [model.macID, model.dataDate, model.temperatureMax, model.temperatureMin, model.temperatureAvg, model.temperatureDetails])
|
||
|
}
|
||
|
})
|
||
|
case .bloodPressure:
|
||
|
dataBase?.inTransaction({ (db, rollback) in
|
||
|
for model in models {
|
||
|
guard let model = model as? BloodPressureModel else { continue }
|
||
|
// 是否存在旧数据
|
||
|
if let _ = BloodPressureModel.deserialize(from: querySingleData(db: db, dataDate: model.dataDate, dataType: .bloodPressure)) {
|
||
|
// 更新数据
|
||
|
let updateSQL = "UPDATE \(tableName) SET macID='\(model.macID)', sbpMax='\(model.sbpMax)', sbpMin='\(model.sbpMin)', sbpAvg='\(model.sbpAvg)', dbpMax='\(model.dbpMax)', dbpMin='\(model.dbpMin)', dbpAvg='\(model.dbpAvg)', details='\(model.details)' WHERE dataDate='\(model.dataDate)'"
|
||
|
db.executeUpdate(updateSQL, withArgumentsIn: [])
|
||
|
continue
|
||
|
}
|
||
|
// 插入数据
|
||
|
let insertSQL = "INSERT INTO \(tableName) (macID,dataDate,sbpMax,sbpMin,sbpAvg,dbpMax,dbpMin,dbpAvg,details) VALUES (?,?,?,?,?,?,?,?,?);"
|
||
|
db.executeUpdate(insertSQL, withArgumentsIn: [model.macID, model.dataDate, model.sbpMax, model.sbpMin, model.sbpAvg, model.dbpMax, model.dbpMax, model.dbpAvg, model.details])
|
||
|
}
|
||
|
})
|
||
|
case .bloodOxygen:
|
||
|
dataBase?.inTransaction({ (db, rollback) in
|
||
|
for model in models {
|
||
|
guard let model = model as? BloodOxygenModel else { continue }
|
||
|
// 是否存在旧数据
|
||
|
if let _ = BloodOxygenModel.deserialize(from: querySingleData(db: db, dataDate: model.dataDate, dataType: .bloodOxygen)) {
|
||
|
// 更新数据
|
||
|
let updateSQL = "UPDATE \(tableName) SET macID='\(model.macID)', bloodOxygenMax='\(model.bloodOxygenMax)', bloodOxygenMin='\(model.bloodOxygenMin)', bloodOxygenAvg='\(model.bloodOxygenAvg)', details='\(model.details)' WHERE dataDate='\(model.dataDate)'"
|
||
|
db.executeUpdate(updateSQL, withArgumentsIn: [])
|
||
|
continue
|
||
|
}
|
||
|
// 插入数据
|
||
|
let insertSQL = "INSERT INTO \(tableName) (macID,dataDate,bloodOxygenMax,bloodOxygenMin,bloodOxygenAvg,details) VALUES (?,?,?,?,?,?);"
|
||
|
db.executeUpdate(insertSQL, withArgumentsIn: [model.macID, model.dataDate, model.bloodOxygenMax, model.bloodOxygenMin, model.bloodOxygenAvg, model.details])
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// MARK:- 数据查询
|
||
|
extension DataBaseManager {
|
||
|
/// 查询睡眠数据
|
||
|
/// - Parameters:
|
||
|
/// - dataDate: 日期
|
||
|
/// - queryType: 查询类型
|
||
|
/// - handle: 数组
|
||
|
func querySleepModel(dataDate: String, queryType: DataQueryType, _ handle: @escaping ResultClosure) {
|
||
|
var querySQL = ""
|
||
|
let tableName = Metric.table_sleep
|
||
|
switch queryType {
|
||
|
case .day:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE dataDate = '\(dataDate)'"
|
||
|
case .week:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%W', strftime('%s', '\(dataDate)'), 'unixepoch', 'weekday 6') = STRFTIME('%Y-%W', strftime('%s', dataDate), 'unixepoch', 'weekday 6') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
case .month:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%m', strftime('%s', '\(dataDate)'), 'unixepoch') = STRFTIME('%Y-%m', strftime('%s', dataDate), 'unixepoch') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
default:
|
||
|
break
|
||
|
}
|
||
|
dataBase?.inDatabase { (db) in
|
||
|
guard let resultSet = db.executeQuery(querySQL, withArgumentsIn: []) else {
|
||
|
DispatchQueue.main.async {
|
||
|
handle([])
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
var models: [SleepModel] = []
|
||
|
while resultSet.next() {
|
||
|
if let model = SleepModel.deserialize(from: resultSet.resultDictionary as? [String: Any]) {
|
||
|
models.append(model)
|
||
|
}
|
||
|
}
|
||
|
resultSet.close()
|
||
|
DispatchQueue.main.async {
|
||
|
handle(models)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 查询心率数据
|
||
|
/// - Parameters:
|
||
|
/// - dataDate: 日期
|
||
|
/// - queryType: 查询类型
|
||
|
/// - handle: 数组
|
||
|
func queryHeartRateData(dataDate: String, queryType: DataQueryType, _ handle: @escaping ResultClosure) {
|
||
|
var querySQL = ""
|
||
|
let tableName = Metric.table_heartRate
|
||
|
switch queryType {
|
||
|
case .day:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE dataDate = '\(dataDate)'"
|
||
|
case .week:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%W', strftime('%s', '\(dataDate)'), 'unixepoch', 'weekday 6') = STRFTIME('%Y-%W', strftime('%s', dataDate), 'unixepoch', 'weekday 6') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
case .month:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%m', strftime('%s', '\(dataDate)'), 'unixepoch') = STRFTIME('%Y-%m', strftime('%s', dataDate), 'unixepoch') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
default:
|
||
|
break
|
||
|
}
|
||
|
dataBase?.inDatabase { (db) in
|
||
|
guard let resultSet = db.executeQuery(querySQL, withArgumentsIn: []) else {
|
||
|
DispatchQueue.main.async {
|
||
|
handle([])
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
var models: [HeartRateModel] = []
|
||
|
while resultSet.next() {
|
||
|
if let model = HeartRateModel.deserialize(from: resultSet.resultDictionary as? [String: Any]) {
|
||
|
models.append(model)
|
||
|
}
|
||
|
}
|
||
|
resultSet.close()
|
||
|
DispatchQueue.main.async {
|
||
|
handle(models)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 查询计步数据
|
||
|
/// - Parameters:
|
||
|
/// - dataDate: 日期
|
||
|
/// - queryType: 查询类型
|
||
|
/// - handle: 数组
|
||
|
func queryStepModel(dataDate: String, queryType: DataQueryType, _ handle: @escaping ResultClosure) {
|
||
|
var querySQL = ""
|
||
|
let tableName = Metric.table_step
|
||
|
switch queryType {
|
||
|
case .day:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE dataDate = '\(dataDate)'"
|
||
|
case .week:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%W', strftime('%s', '\(dataDate)'), 'unixepoch', 'weekday 6') = STRFTIME('%Y-%W', strftime('%s', dataDate), 'unixepoch', 'weekday 6') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
case .month:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%m', strftime('%s', '\(dataDate)'), 'unixepoch') = STRFTIME('%Y-%m', strftime('%s', dataDate), 'unixepoch') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
default:
|
||
|
break
|
||
|
}
|
||
|
dataBase?.inDatabase { (db) in
|
||
|
guard let resultSet = db.executeQuery(querySQL, withArgumentsIn: []) else {
|
||
|
DispatchQueue.main.async {
|
||
|
handle([])
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
var models: [StepModel] = []
|
||
|
while resultSet.next() {
|
||
|
if let model = StepModel.deserialize(from: resultSet.resultDictionary as? [String: Any]) {
|
||
|
models.append(model)
|
||
|
}
|
||
|
}
|
||
|
resultSet.close()
|
||
|
DispatchQueue.main.async {
|
||
|
handle(models)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 查询运动数据
|
||
|
///
|
||
|
/// - Parameters:
|
||
|
/// - date: 日期或时间戳
|
||
|
/// - queryType: 查询类型
|
||
|
/// - handle: db,运动数组
|
||
|
func querySportData(dataDate: String, queryType: DataQueryType, _ handle: @escaping ResultClosure) {
|
||
|
var querySQL = ""
|
||
|
let tableName = Metric.table_sport
|
||
|
switch queryType {
|
||
|
case .day:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%m-%d', strftime('%s', '\(dataDate)'), 'unixepoch') = STRFTIME('%Y-%m-%d', strftime('%s', dataDate), 'unixepoch') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
case .week:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%W', strftime('%s', '\(dataDate)'), 'unixepoch', 'weekday 6') = STRFTIME('%Y-%W', strftime('%s', dataDate), 'unixepoch', 'weekday 6') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
case .month:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%m', strftime('%s', '\(dataDate)'), 'unixepoch') = STRFTIME('%Y-%m', strftime('%s', dataDate), 'unixepoch') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
default:
|
||
|
break
|
||
|
}
|
||
|
dataBase?.inDatabase { (db) in
|
||
|
guard let resultSet = db.executeQuery(querySQL, withArgumentsIn: []) else {
|
||
|
DispatchQueue.main.async {
|
||
|
handle([])
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
var models: [SportModel] = []
|
||
|
while resultSet.next() {
|
||
|
if let model = SportModel.deserialize(from: resultSet.resultDictionary as? [String: Any]) {
|
||
|
models.append(model)
|
||
|
}
|
||
|
}
|
||
|
resultSet.close()
|
||
|
DispatchQueue.main.async {
|
||
|
handle(models)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 查询体温数据
|
||
|
/// - Parameters:
|
||
|
/// - dataDate: 日期
|
||
|
/// - queryType: 查询类型
|
||
|
/// - handle: 数组
|
||
|
func queryTemperatureData(dataDate: String, queryType: DataQueryType, _ handle: @escaping ResultClosure) {
|
||
|
var querySQL = ""
|
||
|
let tableName = Metric.table_temperature
|
||
|
switch queryType {
|
||
|
case .day:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE dataDate = '\(dataDate)'"
|
||
|
case .week:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%W', strftime('%s', '\(dataDate)'), 'unixepoch', 'weekday 6') = STRFTIME('%Y-%W', strftime('%s', dataDate), 'unixepoch', 'weekday 6') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
case .month:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%m', strftime('%s', '\(dataDate)'), 'unixepoch') = STRFTIME('%Y-%m', strftime('%s', dataDate), 'unixepoch') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
default:
|
||
|
break
|
||
|
}
|
||
|
dataBase?.inDatabase { (db) in
|
||
|
guard let resultSet = db.executeQuery(querySQL, withArgumentsIn: []) else {
|
||
|
DispatchQueue.main.async {
|
||
|
handle([])
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
var models: [TemperatureModel] = []
|
||
|
while resultSet.next() {
|
||
|
if let model = TemperatureModel.deserialize(from: resultSet.resultDictionary as? [String: Any]) {
|
||
|
models.append(model)
|
||
|
}
|
||
|
}
|
||
|
resultSet.close()
|
||
|
DispatchQueue.main.async {
|
||
|
handle(models)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 查询血压数据
|
||
|
/// - Parameters:
|
||
|
/// - dataDate: 日期
|
||
|
/// - queryType: 查询类型
|
||
|
/// - handle: 数组
|
||
|
func queryBloodPressureData(dataDate: String, queryType: DataQueryType, _ handle: @escaping ResultClosure) {
|
||
|
var querySQL = ""
|
||
|
let tableName = Metric.table_bloodPressure
|
||
|
switch queryType {
|
||
|
case .day:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE dataDate = '\(dataDate)'"
|
||
|
case .week:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%W', strftime('%s', '\(dataDate)'), 'unixepoch', 'weekday 6') = STRFTIME('%Y-%W', strftime('%s', dataDate), 'unixepoch', 'weekday 6') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
case .month:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%m', strftime('%s', '\(dataDate)'), 'unixepoch') = STRFTIME('%Y-%m', strftime('%s', dataDate), 'unixepoch') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
default:
|
||
|
break
|
||
|
}
|
||
|
dataBase?.inDatabase { (db) in
|
||
|
guard let resultSet = db.executeQuery(querySQL, withArgumentsIn: []) else {
|
||
|
DispatchQueue.main.async {
|
||
|
handle([])
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
var models: [BloodPressureModel] = []
|
||
|
while resultSet.next() {
|
||
|
if let model = BloodPressureModel.deserialize(from: resultSet.resultDictionary as? [String: Any]) {
|
||
|
models.append(model)
|
||
|
}
|
||
|
}
|
||
|
resultSet.close()
|
||
|
DispatchQueue.main.async {
|
||
|
handle(models)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 查询血氧数据
|
||
|
/// - Parameters:
|
||
|
/// - dataDate: 日期
|
||
|
/// - queryType: 查询类型
|
||
|
/// - handle: 数组
|
||
|
func queryBloodOxygenData(dataDate: String, queryType: DataQueryType, _ handle: @escaping ResultClosure) {
|
||
|
var querySQL = ""
|
||
|
let tableName = Metric.table_bloodOxygen
|
||
|
switch queryType {
|
||
|
case .day:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE dataDate = '\(dataDate)'"
|
||
|
case .week:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%W', strftime('%s', '\(dataDate)'), 'unixepoch', 'weekday 6') = STRFTIME('%Y-%W', strftime('%s', dataDate), 'unixepoch', 'weekday 6') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
case .month:
|
||
|
querySQL = "SELECT *FROM \(tableName) WHERE strftime('%Y-%m', strftime('%s', '\(dataDate)'), 'unixepoch') = STRFTIME('%Y-%m', strftime('%s', dataDate), 'unixepoch') ORDER BY strftime('%s',dataDate) ASC"
|
||
|
default:
|
||
|
break
|
||
|
}
|
||
|
dataBase?.inDatabase { (db) in
|
||
|
guard let resultSet = db.executeQuery(querySQL, withArgumentsIn: []) else {
|
||
|
DispatchQueue.main.async {
|
||
|
handle([])
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
var models: [BloodOxygenModel] = []
|
||
|
while resultSet.next() {
|
||
|
if let model = BloodOxygenModel.deserialize(from: resultSet.resultDictionary as? [String: Any]) {
|
||
|
models.append(model)
|
||
|
}
|
||
|
}
|
||
|
resultSet.close()
|
||
|
DispatchQueue.main.async {
|
||
|
handle(models)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 查询插入记录中最近的一条记录时间
|
||
|
/// - Parameters:
|
||
|
/// - dataType: 数据类型
|
||
|
func queryLastRecordData(dataType: DataType, _ handle: @escaping LastRecordClosure) {
|
||
|
dataBase?.inDatabase { (db) in
|
||
|
let querySQL = "SELECT max(dataDate) as maxdate FROM \(Metric.tableName(dataType: dataType)) order by id DESC limit 1"
|
||
|
guard let resultSet = db.executeQuery(querySQL, withArgumentsIn: []) else {
|
||
|
DispatchQueue.main.async {
|
||
|
handle(nil)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
// 获取最后一条数据的时间戳
|
||
|
var timestamp: Int?
|
||
|
if resultSet.next() {
|
||
|
if let maxDate = resultSet.string(forColumn: "maxdate") {
|
||
|
timestamp = DateClass.timeStrToTimestamp(maxDate, formatStr: dataType == .sport ? "yyyy-MM-dd HH:mm:ss" : "yyyy-MM-dd")
|
||
|
}
|
||
|
}
|
||
|
resultSet.close()
|
||
|
DispatchQueue.main.async {
|
||
|
handle(timestamp)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 内部使用单个数查询
|
||
|
/// - Parameters:
|
||
|
/// - db: 数据库
|
||
|
/// - dataDate: 数据时间
|
||
|
/// - dataType: 数据类型
|
||
|
private func querySingleData(db: FMDatabase, dataDate: String, dataType: DataType) -> [String: Any]? {
|
||
|
// 通用字段
|
||
|
let tableName = Metric.tableName(dataType: dataType)
|
||
|
let querySQL = "SELECT *FROM \(tableName) WHERE dataDate='\(dataDate)'"
|
||
|
let results = db.executeQuery(querySQL, withArgumentsIn: [])
|
||
|
guard let resultSet = results else {
|
||
|
return nil
|
||
|
}
|
||
|
var result: [String : Any]?
|
||
|
while resultSet.next() {
|
||
|
result = resultSet.resultDictionary as? [String : Any]
|
||
|
}
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|