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.
 
 

641 lines
24 KiB

#include <sqlite3.h>
//
#include <stdio.h>
#include <time.h>
#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<User>(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("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<User>(where(c(&User::uid) == "admin"));
if (admin.size() == 0) {
storage.insert<User>({-1, "admin", "9973", 1, true}); // 管理员
}
auto user = storage.get_all<User>(where(c(&User::uid) == "user"));
if (user.size() == 0) {
storage.insert<User>({-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<Setting>(where(c(&Setting::id) == 1)).size() == 0) //
storage.insert(Setting{1, "stoped_gs", "消毒停止过氧化氢溶度", 0, 2000, 0, 1800});
if (storage.get_all<Setting>(where(c(&Setting::id) == 2)).size() == 0)
storage.insert(Setting{2, "continued_gs", "消毒继续过氧化氢溶度", 0, 2000, 0, 1500});
if (storage.get_all<Setting>(where(c(&Setting::id) == 3)).size() == 0)
storage.insert(Setting{3, "stoped_satur", "消毒停止过氧化氢相对饱和度", 0, 100, 0, 85});
if (storage.get_all<Setting>(where(c(&Setting::id) == 4)).size() == 0)
storage.insert(Setting{4, "continued_satur", "消毒继续过氧化氢相对饱和度", 0, 100, 0, 70});
if (storage.get_all<Setting>(where(c(&Setting::id) == 5)).size() == 0) //
storage.insert(Setting{5, "max_humidity", "允许消毒最大湿度", 0, 100, 0, 90});
if (storage.get_all<Setting>(where(c(&Setting::id) == 6)).size() == 0)
storage.insert(Setting{6, "drainage_pump_speed", "排液蠕动泵转速", 0, 90, 0, 90}); // g/min
if (storage.get_all<Setting>(where(c(&Setting::id) == 7)).size() == 0)
storage.insert(Setting{7, "injection_pump_speed", "喷射蠕动泵转速", 0, 50, 0, 50}); // g/min
if (storage.get_all<Setting>(where(c(&Setting::id) == 8)).size() == 0) //
storage.insert(Setting{8, "pre_heat_time_s", "预热时间", 0, 600, 0, 120});
if (storage.get_all<Setting>(where(c(&Setting::id) == 9)).size() == 0) //
storage.insert(Setting{9, "stoped_humi", "消毒停止相对湿度", 0, 100, 0, 85});
if (storage.get_all<Setting>(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<shared_ptr<User>> DBService::getAllUser() {
lock_guard<recursive_mutex> lock(lock_);
list<shared_ptr<User>> users;
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto all = usertable.get_all<User>();
for (auto& u : all) {
users.push_back(make_shared<User>(u));
}
return users;
}
void DBService::addUser(string uid, string passwd, int permission_level) {
lock_guard<recursive_mutex> 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<db::User> DBService::delUser(int id) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
/**
* @brief find admin user
*/
auto admin = usertable.get_all<User>(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<User>(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<User>(where(c(&User::id) == id));
return make_shared<User>(remove_user[0]);
}
shared_ptr<db::User> DBService::updateUserPermissionLevel(int id, int permission_level) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(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>(user[0]);
}
shared_ptr<db::User> DBService::changePasswd(string uid, string passwd) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(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>(user[0]);
}
shared_ptr<db::User> DBService::updateUserUid(int id, string uid, string& olduid) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(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>(user[0]);
}
json DBService::getAllUserJson() {
lock_guard<recursive_mutex> lock(lock_);
json j_users;
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto all = usertable.get_all<User>();
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<User> DBService::getUser(string uid) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(where(c(&User::uid) == uid));
if (user.size() == 0) {
return nullptr;
}
return make_shared<User>(user[0]);
}
list<shared_ptr<db::Setting>> DBService::getAllSetting() {
lock_guard<recursive_mutex> lock(lock_);
list<shared_ptr<db::Setting>> settings;
auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
settingtable.sync_schema();
auto all = settingtable.get_all<Setting>();
for (auto& s : all) {
settings.push_back(make_shared<Setting>(s));
}
return settings;
}
json DBService::getAllSettingJson() {
lock_guard<recursive_mutex> lock(lock_);
json j_settings;
auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
settingtable.sync_schema();
auto all = settingtable.get_all<Setting>();
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<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(where(c(&User::uid) == uid));
if (user.size() == 0) {
return false;
}
return true;
}
bool DBService::ispasswdCorrect(string uid, string passwd) {
lock_guard<recursive_mutex> lock(lock_);
auto usertable = make_storage(USER_DB_STRUCT);
usertable.sync_schema();
auto user = usertable.get_all<User>(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<recursive_mutex> lock(lock_);
auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
settingtable.sync_schema();
auto setting = settingtable.get_all<Setting>(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<recursive_mutex> 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<Setting>(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<recursive_mutex> lock(lock_);
auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
settingtable.sync_schema();
auto setting = settingtable.get_all<Setting>(where(c(&Setting::name) == name));
if (setting.size() == 0) {
return -1;
}
return setting[0].val;
}
list<shared_ptr<db::Formula>> DBService::getAllFormula() {
lock_guard<recursive_mutex> lock(lock_);
list<shared_ptr<db::Formula>> formulas;
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
auto all = formulatable.get_all<Formula>();
for (auto& f : all) {
formulas.push_back(make_shared<Formula>(f));
}
return formulas;
}
shared_ptr<db::Formula> DBService::getFormula(int id) {
lock_guard<recursive_mutex> lock(lock_);
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
auto formula = formulatable.get_all<Formula>(where(c(&Formula::id) == id));
if (formula.size() == 0) {
return nullptr;
}
return make_shared<Formula>(formula[0]);
}
json DBService::getAllFormulaJson() {
lock_guard<recursive_mutex> lock(lock_);
json j_formulas;
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
auto all = formulatable.get_all<Formula>();
for (auto& f : all) {
json j_formula;
j_formula["id"] = f.id;
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 stoped_gs, string continued_gs, string stoped_satur, string continued_satur, string stoped_humi,
string continued_humi, string injection_pump_speed) {
lock_guard<recursive_mutex> lock(lock_);
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
Formula f;
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 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(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<db::Formula> DBService::delFormula(int id) {
lock_guard<recursive_mutex> lock(lock_);
// remove_all
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
auto formula = formulatable.get_all<Formula>(where(c(&Formula::id) == id));
formulatable.remove_all<Formula>(where(c(&Formula::id) == id));
formulatable.sync_schema();
if (formula.size() == 0) {
return nullptr;
}
return make_shared<Formula>(formula[0]);
}
shared_ptr<db::Formula> DBService::updateFormula(int id, string column, string val) {
lock_guard<recursive_mutex> lock(lock_);
auto formulatable = make_storage(FORMULA_DB, FORMULA_DB_STRUCT);
formulatable.sync_schema();
auto formula = formulatable.get_all<Formula>(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>(formula[0]);
}
int DBService::getUserBehaviorRecordCount() {
lock_guard<recursive_mutex> 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<UserBehaviorRecord>(where(c(&UserBehaviorRecord::id) > 0));
}
int DBService::getUserBehaviorRecordTheFirstId() {
lock_guard<recursive_mutex> 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<UserBehaviorRecord>(order_by(&UserBehaviorRecord::id).asc());
if (all.size() == 0) {
return -1;
}
return all[0].id;
}
list<shared_ptr<db::UserBehaviorRecord>> DBService::getAllUserBehaviorRecord() {
lock_guard<recursive_mutex> 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<UserBehaviorRecord>(order_by(&UserBehaviorRecord::id).desc());
list<shared_ptr<db::UserBehaviorRecord>> user_behavior_records;
for (auto& u : all) {
user_behavior_records.push_back(make_shared<UserBehaviorRecord>(u));
}
return user_behavior_records;
}
json DBService::getUserBehaviorRecordDescJson(int page, int page_size) {
lock_guard<recursive_mutex> 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<UserBehaviorRecord>(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<recursive_mutex> 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<UserBehaviorRecord>(order_by(&UserBehaviorRecord::id).asc());
/**
* @brief 如果记录总数量大于5000条,删除第一条
*/
if (all.size() > USER_BEHAVIOR_RECORD_DB_MAX_RECORDS) {
user_behavior_record_table.remove_all<UserBehaviorRecord>(where(c(&UserBehaviorRecord::id) == all[0].id));
user_behavior_record_table.sync_schema();
}
return;
}
void DBService::cleanUserBehaviorRecord() {
lock_guard<recursive_mutex> lock(lock_);
system(fmt::format("rm -rf {}", USER_BEHAVIOR_RECORD_DB).c_str());
}