#include // #include #include #include "db_service.hpp" // #include "iflytop/components/sqlite_orm/sqlite_orm.hpp" using namespace std; using namespace iflytop; using namespace iflytop::db; using namespace sqlite_orm; using namespace nlohmann; // 数据库工具使用手册 // auto notJohn = storage.get_all(where(c(&User::firstName) != "John")); // 主键必须是int,或者不要主键 #define USER_DB_STRUCT \ USER_DB, /**/ \ make_table("users", /**/ \ make_column("id", &User::id, primary_key().autoincrement()), /**/ \ make_column("uid", &User::uid), /**/ \ make_column("passwd", &User::passwd), /**/ \ make_column("permission_level", &User::permission_level), /**/ \ make_column("visible", &User::visible)) #define SETTING_DB_STRUCT \ make_table("settings", /**/ \ make_column("id", &Setting::id, primary_key()), /**/ \ make_column("name", &Setting::name), /**/ \ make_column("name_ch", &Setting::name_ch), /**/ \ make_column("val_lower_limit", &Setting::val_lower_limit), /**/ \ make_column("val_upper_limit", &Setting::val_upper_limit), /**/ \ make_column("permission_level", &Setting::permission_level), /**/ \ make_column("val", &Setting::val)) #define FORMULA_DB_STRUCT \ make_table("formulas", /**/ \ make_column("id", &Formula::id, primary_key()), /**/ \ make_column("loglevel", &Formula::loglevel), /**/ \ make_column("formula_id", &Formula::formula_id), /**/ \ make_column("stoped_gs", &Formula::stoped_gs), /**/ \ make_column("continued_gs", &Formula::continued_gs), /**/ \ make_column("stoped_satur", &Formula::stoped_satur), /**/ \ make_column("continued_satur", &Formula::continued_satur), /**/ \ make_column("stoped_humi", &Formula::stoped_humi), /**/ \ make_column("continued_humi", &Formula::continued_humi), /**/ \ make_column("injection_pump_speed", &Formula::injection_pump_speed)) #define USER_BEHAVIOR_RECORD_STRUCT \ make_table("user_behavior_records", /**/ \ make_column("id", &UserBehaviorRecord::id, primary_key().autoincrement()), /**/ \ make_column("uid", &UserBehaviorRecord::uid), /**/ \ make_column("date", &UserBehaviorRecord::date), /**/ \ make_column("behavior", &UserBehaviorRecord::behavior), /**/ \ make_column("behaviorinfo", &UserBehaviorRecord::behaviorinfo)) DBService::DBService(/* args */) {} void DBService::initialize() { /** * @brief 初始化用户表 */ // init_usr_db(); init_setting_db(); json settings = getAllSettingJson(); logger->info("settings: {}", settings.dump()); } void DBService::init_usr_db() { bool suc = false; do { try { logger->info("init user db"); auto storage = make_storage(USER_DB_STRUCT); storage.sync_schema(); auto admin = storage.get_all(where(c(&User::uid) == "admin")); if (admin.size() == 0) { storage.insert({-1, "admin", "9973", 1, true}); // 管理员 } auto user = storage.get_all(where(c(&User::uid) == "user")); if (user.size() == 0) { storage.insert({-1, "user", "0000", 3, true}); // 普通用户 } suc = true; } catch (const std::exception& e) { logger->error("init user db failed: {}", e.what()); system("rm -rf user.db"); sleep(1); } } while (!suc); } void DBService::init_setting_db() { bool suc = false; #if 0 id setting_name setting_name_ch val_upper_limit val_lower_limit permission_level val 0 stoped_gs 消毒停止过氧化氢溶度 0 2000 1 1000 1 continued_gs 消毒继续过氧化氢溶度 0 2000 1 800 2 stoped_satur 消毒停止过氧化氢相对饱和度 0 100 1 80 3 continued_satur 消毒继续过氧化氢相对饱和度 0 100 1 60 4 max_humidity 允许消毒最大湿度 0 100 1 90 5 drainage_pump_speed 排液蠕动泵转速 0 2000 2 500 6 injection_pump_speed 喷射蠕动泵转速 0 2000 2 500 #endif do { try { logger->info("init setting db"); auto storage = make_storage(SETTING_DB, SETTING_DB_STRUCT); storage.sync_schema(); if (storage.get_all(where(c(&Setting::id) == 1)).size() == 0) // storage.insert(Setting{1, "stoped_gs", "消毒停止过氧化氢溶度", 0, 2000, 0, 1800}); if (storage.get_all(where(c(&Setting::id) == 2)).size() == 0) storage.insert(Setting{2, "continued_gs", "消毒继续过氧化氢溶度", 0, 2000, 0, 1500}); if (storage.get_all(where(c(&Setting::id) == 3)).size() == 0) storage.insert(Setting{3, "stoped_satur", "消毒停止过氧化氢相对饱和度", 0, 100, 0, 85}); if (storage.get_all(where(c(&Setting::id) == 4)).size() == 0) storage.insert(Setting{4, "continued_satur", "消毒继续过氧化氢相对饱和度", 0, 100, 0, 70}); if (storage.get_all(where(c(&Setting::id) == 5)).size() == 0) // storage.insert(Setting{5, "max_humidity", "允许消毒最大湿度", 0, 100, 0, 90}); if (storage.get_all(where(c(&Setting::id) == 6)).size() == 0) storage.insert(Setting{6, "drainage_pump_speed", "排液蠕动泵转速", 0, 90, 0, 90}); // g/min if (storage.get_all(where(c(&Setting::id) == 7)).size() == 0) storage.insert(Setting{7, "injection_pump_speed", "喷射蠕动泵转速", 0, 50, 0, 50}); // g/min if (storage.get_all(where(c(&Setting::id) == 8)).size() == 0) // storage.insert(Setting{8, "pre_heat_time_s", "预热时间", 0, 600, 0, 120}); if (storage.get_all(where(c(&Setting::id) == 9)).size() == 0) // storage.insert(Setting{9, "stoped_humi", "消毒停止相对湿度", 0, 100, 0, 85}); if (storage.get_all(where(c(&Setting::id) == 10)).size() == 0) // storage.insert(Setting{10, "continued_humi", "消毒继续相对湿度", 0, 100, 0, 70}); suc = true; } catch (const std::exception& e) { logger->error("init setting db failed: {}", e.what()); system("rm -rf setting.db"); sleep(1); } } while (!suc); } void DBService::init_formula_db() { bool suc = false; do { try { logger->info("init formula db"); auto storage = make_storage(FORMULA_DB, FORMULA_DB_STRUCT); storage.sync_schema(); suc = true; } catch (const std::exception& e) { logger->error("init setting db failed: {}", e.what()); system("rm -rf setting.db"); sleep(1); } } while (!suc); } list> DBService::getAllUser() { lock_guard lock(lock_); list> users; auto usertable = make_storage(USER_DB_STRUCT); usertable.sync_schema(); auto all = usertable.get_all(); for (auto& u : all) { users.push_back(make_shared(u)); } return users; } void DBService::addUser(string uid, string passwd, int permission_level) { lock_guard lock(lock_); auto usertable = make_storage(USER_DB_STRUCT); usertable.sync_schema(); logger->info("add user: {} {} {}", uid, passwd, permission_level); usertable.insert(User{-1, uid, passwd, permission_level, true}); } shared_ptr DBService::delUser(int id) { lock_guard lock(lock_); auto usertable = make_storage(USER_DB_STRUCT); usertable.sync_schema(); /** * @brief find admin user */ auto admin = usertable.get_all(where(c(&User::uid) == "admin")); ZCHECK(admin.size() == 1, "admin user not found"); if (admin[0].id == id) { logger->error("can not delete admin user"); return nullptr; } auto remove_user = usertable.get_all(where(c(&User::id) == id)); if (remove_user.size() == 0) { logger->error("remove user fail, user not found"); return nullptr; } logger->info("delete user: {}:{}", id, remove_user[0].uid); usertable.remove_all(where(c(&User::id) == id)); return make_shared(remove_user[0]); } shared_ptr DBService::updateUserPermissionLevel(int id, int permission_level) { lock_guard lock(lock_); auto usertable = make_storage(USER_DB_STRUCT); usertable.sync_schema(); auto user = usertable.get_all(where(c(&User::id) == id)); if (user.size() == 0) { logger->error("update user permission level fail, user not found"); return nullptr; } logger->info("update user permission level: {} {} -> {}", id, user[0].permission_level, permission_level); user[0].permission_level = permission_level; usertable.update(user[0]); return make_shared(user[0]); } shared_ptr DBService::changePasswd(string uid, string passwd) { lock_guard lock(lock_); auto usertable = make_storage(USER_DB_STRUCT); usertable.sync_schema(); auto user = usertable.get_all(where(c(&User::uid) == uid)); if (user.size() == 0) { logger->error("change passwd fail, user not found"); return nullptr; } logger->info("change passwd: {} {} -> {}", uid, user[0].passwd, passwd); user[0].passwd = passwd; usertable.update(user[0]); return make_shared(user[0]); } shared_ptr DBService::updateUserUid(int id, string uid, string& olduid) { lock_guard lock(lock_); auto usertable = make_storage(USER_DB_STRUCT); usertable.sync_schema(); auto user = usertable.get_all(where(c(&User::id) == id)); if (user.size() == 0) { logger->error("change user uid fail, user not found"); return nullptr; } olduid = user[0].uid; logger->info("change user uid: {} {} -> {}", id, user[0].uid, uid); user[0].uid = uid; usertable.update(user[0]); return make_shared(user[0]); } json DBService::getAllUserJson() { lock_guard lock(lock_); json j_users; auto usertable = make_storage(USER_DB_STRUCT); usertable.sync_schema(); auto all = usertable.get_all(); for (auto& u : all) { json j_user; j_user["id"] = u.id; j_user["uid"] = u.uid; j_user["passwd"] = u.passwd; j_user["permission_level"] = u.permission_level; j_user["visible"] = u.visible; j_users.push_back(j_user); } return j_users; } shared_ptr DBService::getUser(string uid) { lock_guard lock(lock_); auto usertable = make_storage(USER_DB_STRUCT); usertable.sync_schema(); auto user = usertable.get_all(where(c(&User::uid) == uid)); if (user.size() == 0) { return nullptr; } return make_shared(user[0]); } list> DBService::getAllSetting() { lock_guard lock(lock_); list> settings; auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT); settingtable.sync_schema(); auto all = settingtable.get_all(); for (auto& s : all) { settings.push_back(make_shared(s)); } return settings; } json DBService::getAllSettingJson() { lock_guard lock(lock_); json j_settings; auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT); settingtable.sync_schema(); auto all = settingtable.get_all(); for (auto& s : all) { json j_setting; j_setting["id"] = s.id; j_setting["name"] = s.name; j_setting["name_ch"] = s.name_ch; j_setting["val"] = s.val; j_setting["val_lower_limit"] = s.val_lower_limit; j_setting["val_upper_limit"] = s.val_upper_limit; j_setting["permission_level"] = s.permission_level; j_setting["val"] = s.val; j_settings.push_back(j_setting); } return j_settings; } bool DBService::isUserExist(string uid) { lock_guard lock(lock_); auto usertable = make_storage(USER_DB_STRUCT); usertable.sync_schema(); auto user = usertable.get_all(where(c(&User::uid) == uid)); if (user.size() == 0) { return false; } return true; } bool DBService::ispasswdCorrect(string uid, string passwd) { lock_guard lock(lock_); auto usertable = make_storage(USER_DB_STRUCT); usertable.sync_schema(); auto user = usertable.get_all(where(c(&User::uid) == uid)); if (user.size() == 0) { return false; } if (user[0].passwd == passwd) { return true; } return false; } bool DBService::setSettingVal(int id, int val) { lock_guard lock(lock_); auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT); settingtable.sync_schema(); auto setting = settingtable.get_all(where(c(&Setting::id) == id)); if (setting.size() == 0) { return false; } if (setting[0].val < setting[0].val_lower_limit || setting[0].val > setting[0].val_upper_limit) { return false; } setting[0].val = val; settingtable.update(setting[0]); return true; } bool DBService::setSettingVal(string setting_name, int val) { lock_guard lock(lock_); logger->info("set setting val: {} {}", setting_name, val); auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT); settingtable.sync_schema(); auto setting = settingtable.get_all(where(c(&Setting::name) == setting_name)); if (setting.size() == 0) { logger->error("set setting val failed: {} not found", setting_name); return false; } if (setting[0].val < setting[0].val_lower_limit || setting[0].val > setting[0].val_upper_limit) { logger->error("set setting val failed: {} out of range", setting_name); return false; } setting[0].val = val; Setting s = setting[0]; settingtable.update(s); settingtable.sync_schema(); return true; } int DBService::getSettingVal(string name) { lock_guard lock(lock_); auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT); settingtable.sync_schema(); auto setting = settingtable.get_all(where(c(&Setting::name) == name)); if (setting.size() == 0) { return -1; } return setting[0].val; } list> DBService::getAllFormula() { lock_guard lock(lock_); list> formulas; auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT); formulatable.sync_schema(); auto all = formulatable.get_all(); for (auto& f : all) { formulas.push_back(make_shared(f)); } return formulas; } shared_ptr DBService::getFormula(int id) { lock_guard lock(lock_); auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT); formulatable.sync_schema(); auto formula = formulatable.get_all(where(c(&Formula::id) == id)); if (formula.size() == 0) { return nullptr; } return make_shared(formula[0]); } json DBService::getAllFormulaJson() { lock_guard lock(lock_); json j_formulas; auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT); formulatable.sync_schema(); auto all = formulatable.get_all(); for (auto& f : all) { json j_formula; j_formula["id"] = f.id; j_formula["loglevel"] = f.loglevel; j_formula["formula_id"] = f.formula_id; j_formula["stoped_gs"] = f.stoped_gs; j_formula["continued_gs"] = f.continued_gs; j_formula["stoped_satur"] = f.stoped_satur; j_formula["continued_satur"] = f.continued_satur; j_formula["stoped_humi"] = f.stoped_humi; j_formula["continued_humi"] = f.continued_humi; j_formula["injection_pump_speed"] = f.injection_pump_speed; j_formulas.push_back(j_formula); } json jret; jret["formulas"] = j_formulas; jret["settings"] = getAllSettingJson(); return jret; } void DBService::addFormula(string formula_id,string loglevel, string stoped_gs, string continued_gs, string stoped_satur, string continued_satur, string stoped_humi, string continued_humi, string injection_pump_speed) { lock_guard lock(lock_); auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT); formulatable.sync_schema(); Formula f; f.loglevel = loglevel; f.formula_id = formula_id; f.stoped_gs = stoped_gs; f.continued_gs = continued_gs; f.stoped_satur = stoped_satur; f.continued_satur = continued_satur; f.stoped_humi = stoped_humi; f.continued_humi = continued_humi; f.injection_pump_speed = injection_pump_speed; formulatable.insert(f); formulatable.sync_schema(); } void DBService::addFormula(string formula_id, int loglevel, int stoped_gs, int continued_gs, int stoped_satur, int continued_satur, int stoped_humi, int continued_humi, int injection_pump_speed) { addFormula(formula_id, to_string(loglevel), to_string(stoped_gs), to_string(continued_gs), to_string(stoped_satur), to_string(continued_satur), to_string(stoped_humi), to_string(continued_humi), to_string(injection_pump_speed)); } shared_ptr DBService::delFormula(int id) { lock_guard lock(lock_); // remove_all auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT); formulatable.sync_schema(); auto formula = formulatable.get_all(where(c(&Formula::id) == id)); formulatable.remove_all(where(c(&Formula::id) == id)); formulatable.sync_schema(); if (formula.size() == 0) { return nullptr; } return make_shared(formula[0]); } shared_ptr DBService::updateFormula(int id, string column, string val) { lock_guard lock(lock_); auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT); formulatable.sync_schema(); auto formula = formulatable.get_all(where(c(&Formula::id) == id)); if (formula.size() == 0) { return nullptr; } if (column == "formula_id") { formula[0].formula_id = val; } else if (column == "stoped_gs") { formula[0].stoped_gs = val; } else if (column == "continued_gs") { formula[0].continued_gs = val; } else if (column == "stoped_satur") { formula[0].stoped_satur = val; } else if (column == "continued_satur") { formula[0].continued_satur = val; } else if (column == "stoped_humi") { formula[0].stoped_humi = val; } else if (column == "continued_humi") { formula[0].continued_humi = val; } else if (column == "injection_pump_speed") { formula[0].injection_pump_speed = val; } formulatable.update(formula[0]); formulatable.sync_schema(); return make_shared(formula[0]); } int DBService::getUserBehaviorRecordCount() { lock_guard lock(lock_); auto user_behavior_record_table = make_storage(USER_BEHAVIOR_RECORD_DB, USER_BEHAVIOR_RECORD_STRUCT); user_behavior_record_table.sync_schema(); return user_behavior_record_table.count(where(c(&UserBehaviorRecord::id) > 0)); } int DBService::getUserBehaviorRecordTheFirstId() { lock_guard lock(lock_); auto user_behavior_record_table = make_storage(USER_BEHAVIOR_RECORD_DB, USER_BEHAVIOR_RECORD_STRUCT); user_behavior_record_table.sync_schema(); auto all = user_behavior_record_table.get_all(order_by(&UserBehaviorRecord::id).asc()); if (all.size() == 0) { return -1; } return all[0].id; } list> DBService::getAllUserBehaviorRecord() { lock_guard lock(lock_); auto user_behavior_record_table = make_storage(USER_BEHAVIOR_RECORD_DB, USER_BEHAVIOR_RECORD_STRUCT); user_behavior_record_table.sync_schema(); auto all = user_behavior_record_table.get_all(order_by(&UserBehaviorRecord::id).desc()); list> user_behavior_records; for (auto& u : all) { user_behavior_records.push_back(make_shared(u)); } return user_behavior_records; } json DBService::getUserBehaviorRecordDescJson(int page, int page_size) { lock_guard lock(lock_); json j_user_behavior_records; auto user_behavior_record_table = make_storage(USER_BEHAVIOR_RECORD_DB, USER_BEHAVIOR_RECORD_STRUCT); user_behavior_record_table.sync_schema(); auto all = user_behavior_record_table.get_all(order_by(&UserBehaviorRecord::id).desc()); int i = 0; int from = page * page_size; int to = (page + 1) * page_size; for (auto& u : all) { if (i >= from && i < to) { json j_user_behavior_record; j_user_behavior_record["id"] = u.id; j_user_behavior_record["uid"] = u.uid; j_user_behavior_record["behavior"] = u.behavior; j_user_behavior_record["behaviorZH"] = user_behavior_to_str((user_behavior_t)u.behavior); j_user_behavior_record["behaviorinfo"] = u.behaviorinfo; j_user_behavior_record["date"] = u.date; j_user_behavior_records["iterms"].push_back(j_user_behavior_record); } else if (i >= to) { break; } i++; } j_user_behavior_records["total"] = all.size(); j_user_behavior_records["page"] = page; j_user_behavior_records["totalpage"] = all.size() / page_size + (all.size() % page_size == 0 ? 0 : 1); return j_user_behavior_records; } static string getTime() { struct tm tm = {0}; time_t t = ::time(nullptr); struct tm* tmp = localtime_r(&t, &tm); return fmt::format("{:0>4}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}", tm.tm_year + 1900, // tm.tm_mon + 1, // tm.tm_mday, // tm.tm_hour, // tm.tm_min, tm.tm_sec); } void DBService::addUserBehaviorRecord(string uid, int behavior, string behaviorinfo) { lock_guard lock(lock_); auto user_behavior_record_table = make_storage(USER_BEHAVIOR_RECORD_DB, USER_BEHAVIOR_RECORD_STRUCT); user_behavior_record_table.sync_schema(); UserBehaviorRecord u; u.uid = uid; u.behavior = behavior; u.behaviorinfo = behaviorinfo; u.date = getTime(); user_behavior_record_table.insert(u); user_behavior_record_table.sync_schema(); auto all = user_behavior_record_table.get_all(order_by(&UserBehaviorRecord::id).asc()); /** * @brief 如果记录总数量大于5000条,删除第一条 */ if (all.size() > USER_BEHAVIOR_RECORD_DB_MAX_RECORDS) { user_behavior_record_table.remove_all(where(c(&UserBehaviorRecord::id) == all[0].id)); user_behavior_record_table.sync_schema(); } return; } void DBService::cleanUserBehaviorRecord() { lock_guard lock(lock_); system(fmt::format("rm -rf {}", USER_BEHAVIOR_RECORD_DB).c_str()); }