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.

412 lines
17 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include <sqlite3.h>
  2. //
  3. #include <stdio.h>
  4. #include "db_service.hpp"
  5. //
  6. #include "iflytop/components/sqlite_orm/sqlite_orm.hpp"
  7. using namespace std;
  8. using namespace iflytop;
  9. using namespace iflytop::db;
  10. using namespace sqlite_orm;
  11. using namespace nlohmann;
  12. // 数据库工具使用手册
  13. // auto notJohn = storage.get_all<User>(where(c(&User::firstName) != "John"));
  14. // 主键必须是int,或者不要主键
  15. #define USER_DB_STRUCT \
  16. USER_DB, /**/ \
  17. make_table("users", /**/ \
  18. make_column("id", &User::id, primary_key().autoincrement()), /**/ \
  19. make_column("uid", &User::uid), /**/ \
  20. make_column("passwd", &User::passwd), /**/ \
  21. make_column("permission_level", &User::permission_level), /**/ \
  22. make_column("visible", &User::visible))
  23. #define SETTING_DB_STRUCT \
  24. make_table("settings", /**/ \
  25. make_column("id", &Setting::id, primary_key()), /**/ \
  26. make_column("name", &Setting::name), /**/ \
  27. make_column("name_ch", &Setting::name_ch), /**/ \
  28. make_column("val_lower_limit", &Setting::val_lower_limit), /**/ \
  29. make_column("val_upper_limit", &Setting::val_upper_limit), /**/ \
  30. make_column("permission_level", &Setting::permission_level), /**/ \
  31. make_column("val", &Setting::val))
  32. #define DISINFECTION_RECORD_DB_STRUCT \
  33. DISINFECTION_RECORD_DB, \
  34. make_table("disinfection_records", /**/ \
  35. make_column("id", &DisinfectionRecord::id, primary_key().autoincrement()), /**/ \
  36. make_column("uuid", &DisinfectionRecord::uuid), /**/ \
  37. make_column("uid", &DisinfectionRecord::uid), /**/ \
  38. make_column("date", &DisinfectionRecord::date), /**/ \
  39. make_column("loglevel", &DisinfectionRecord::loglevel), /**/ \
  40. make_column("duration", &DisinfectionRecord::duration)), /**/ \
  41. make_table("sensor_records", /**/ \
  42. make_column("id", &SensorRecord::id, primary_key().autoincrement()), /**/ \
  43. make_column("disinfection_id", &SensorRecord::disinfection_id), /**/ \
  44. make_column("date", &SensorRecord::date), /**/ \
  45. make_column("heating_strip", &SensorRecord::heating_strip), /**/ \
  46. make_column("air_compressor", &SensorRecord::air_compressor), /**/ \
  47. make_column("sprinkler_pump", &SensorRecord::sprinkler_pump), /**/ \
  48. make_column("disinfectant_volume", &SensorRecord::disinfectant_volume), /**/ \
  49. make_column("h2o2_1", &SensorRecord::h2o2_1), /**/ \
  50. make_column("temp_1", &SensorRecord::temp_1), /**/ \
  51. make_column("humid_1", &SensorRecord::humid_1), /**/ \
  52. make_column("saturation_1", &SensorRecord::saturation_1), /**/ \
  53. make_column("h2o2_2", &SensorRecord::h2o2_2), /**/ \
  54. make_column("temp_2", &SensorRecord::temp_2), /**/ \
  55. make_column("humid_2", &SensorRecord::humid_2), /**/ \
  56. make_column("saturation_2", &SensorRecord::saturation_2), /**/ \
  57. make_column("h2o2_3", &SensorRecord::h2o2_3), /**/ \
  58. make_column("temp_3", &SensorRecord::temp_3), /**/ \
  59. make_column("humid_3", &SensorRecord::humid_3), /**/ \
  60. make_column("saturation_3", &SensorRecord::saturation_3))
  61. DBService::DBService(/* args */) {}
  62. void DBService::initialize() {
  63. /**
  64. * @brief
  65. */
  66. //
  67. init_usr_db();
  68. init_setting_db();
  69. init_disinfection_record_db();
  70. json settings = getAllSettingJson();
  71. logger->info("settings: {}", settings.dump());
  72. }
  73. void DBService::init_usr_db() {
  74. bool suc = false;
  75. do {
  76. try {
  77. logger->info("init user db");
  78. auto storage = make_storage(USER_DB_STRUCT);
  79. storage.sync_schema();
  80. auto admin = storage.get_all<User>(where(c(&User::uid) == "admin"));
  81. if (admin.size() == 0) {
  82. storage.insert<User>({-1, "admin", "9973", 0, true}); // 管理员
  83. }
  84. auto user = storage.get_all<User>(where(c(&User::uid) == "user"));
  85. if (user.size() == 0) {
  86. storage.insert<User>({-1, "user", "0000", 3, true}); // 普通用户
  87. }
  88. suc = true;
  89. } catch (const std::exception& e) {
  90. logger->error("init user db failed: {}", e.what());
  91. system("rm -rf user.db");
  92. sleep(1);
  93. }
  94. } while (!suc);
  95. }
  96. void DBService::init_setting_db() {
  97. bool suc = false;
  98. #if 0
  99. id setting_name setting_name_ch val_upper_limit val_lower_limit permission_level val
  100. 0 stoped_gs 0 2000 1 1000
  101. 1 continued_gs 0 2000 1 800
  102. 2 stoped_satur 0 100 1 80
  103. 3 continued_satur 0 100 1 60
  104. 4 max_humidity 湿 0 100 1 90
  105. 5 drainage_pump_speed 0 2000 2 500
  106. 6 injection_pump_speed 0 2000 2 500
  107. #endif
  108. do {
  109. try {
  110. logger->info("init setting db");
  111. auto storage = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  112. storage.sync_schema();
  113. if (storage.get_all<Setting>(where(c(&Setting::id) == 1)).size() == 0) //
  114. storage.insert(Setting{1, "stoped_gs", "消毒停止过氧化氢溶度", 0, 2000, 0, 1800});
  115. if (storage.get_all<Setting>(where(c(&Setting::id) == 2)).size() == 0)
  116. storage.insert(Setting{2, "continued_gs", "消毒继续过氧化氢溶度", 0, 2000, 0, 1500});
  117. if (storage.get_all<Setting>(where(c(&Setting::id) == 3)).size() == 0)
  118. storage.insert(Setting{3, "stoped_satur", "消毒停止过氧化氢相对饱和度", 0, 100, 0, 85});
  119. if (storage.get_all<Setting>(where(c(&Setting::id) == 4)).size() == 0)
  120. storage.insert(Setting{4, "continued_satur", "消毒继续过氧化氢相对饱和度", 0, 100, 0, 70});
  121. if (storage.get_all<Setting>(where(c(&Setting::id) == 5)).size() == 0) //
  122. storage.insert(Setting{5, "max_humidity", "允许消毒最大湿度", 0, 100, 0, 90});
  123. if (storage.get_all<Setting>(where(c(&Setting::id) == 6)).size() == 0)
  124. storage.insert(Setting{6, "drainage_pump_speed", "排液蠕动泵转速", 0, 40, 0, 40}); // g/min
  125. if (storage.get_all<Setting>(where(c(&Setting::id) == 7)).size() == 0)
  126. storage.insert(Setting{7, "injection_pump_speed", "喷射蠕动泵转速", 0, 40, 0, 40}); // g/min
  127. if (storage.get_all<Setting>(where(c(&Setting::id) == 8)).size() == 0) //
  128. storage.insert(Setting{8, "pre_heat_time_s", "预热时间", 0, 600, 0, 120});
  129. if (storage.get_all<Setting>(where(c(&Setting::id) == 9)).size() == 0) //
  130. storage.insert(Setting{9, "stoped_humi", "消毒停止相对湿度", 0, 100, 0, 85});
  131. if (storage.get_all<Setting>(where(c(&Setting::id) == 10)).size() == 0) //
  132. storage.insert(Setting{10, "continued_humi", "消毒继续相对湿度", 0, 100, 0, 70});
  133. suc = true;
  134. } catch (const std::exception& e) {
  135. logger->error("init setting db failed: {}", e.what());
  136. system("rm -rf setting.db");
  137. sleep(1);
  138. }
  139. } while (!suc);
  140. }
  141. void DBService::init_disinfection_record_db() {
  142. bool suc = false;
  143. do {
  144. try {
  145. logger->info("init disinfection record db");
  146. auto storage = make_storage(DISINFECTION_RECORD_DB_STRUCT);
  147. storage.sync_schema();
  148. suc = true;
  149. } catch (const std::exception& e) {
  150. logger->error("init disinfection record db failed: {}", e.what());
  151. system("rm -rf disinfection_record.db");
  152. sleep(1);
  153. }
  154. } while (!suc);
  155. }
  156. list<shared_ptr<User>> DBService::getAllUser() {
  157. list<shared_ptr<User>> users;
  158. auto usertable = make_storage(USER_DB_STRUCT);
  159. usertable.sync_schema();
  160. auto all = usertable.get_all<User>();
  161. for (auto& u : all) {
  162. users.push_back(make_shared<User>(u));
  163. }
  164. return users;
  165. }
  166. void DBService::addUser(string uid, string passwd, int permission_level) {
  167. auto usertable = make_storage(USER_DB_STRUCT);
  168. usertable.sync_schema();
  169. logger->info("add user: {} {} {}", uid, passwd, permission_level);
  170. usertable.insert(User{-1, uid, passwd, permission_level, true});
  171. }
  172. void DBService::delUser(int id) {
  173. auto usertable = make_storage(USER_DB_STRUCT);
  174. usertable.sync_schema();
  175. /**
  176. * @brief find admin user
  177. */
  178. auto admin = usertable.get_all<User>(where(c(&User::uid) == "admin"));
  179. ZCHECK(admin.size() == 1, "admin user not found");
  180. if (admin[0].id == id) {
  181. logger->error("can not delete admin user");
  182. return;
  183. }
  184. auto remove_user = usertable.get_all<User>(where(c(&User::id) == id));
  185. if (remove_user.size() == 0) {
  186. logger->error("remove user fail, user not found");
  187. return;
  188. }
  189. logger->info("delete user: {}:{}", id, remove_user[0].uid);
  190. usertable.remove<User>(where(c(&User::id) == id));
  191. }
  192. void DBService::updateUserPermissionLevel(int id, int permission_level) {
  193. auto usertable = make_storage(USER_DB_STRUCT);
  194. usertable.sync_schema();
  195. auto user = usertable.get_all<User>(where(c(&User::id) == id));
  196. if (user.size() == 0) {
  197. logger->error("update user permission level fail, user not found");
  198. return;
  199. }
  200. logger->info("update user permission level: {} {} -> {}", id, user[0].permission_level, permission_level);
  201. user[0].permission_level = permission_level;
  202. usertable.update(user[0]);
  203. }
  204. json DBService::getAllUserJson() {
  205. json j_users;
  206. auto usertable = make_storage(USER_DB_STRUCT);
  207. usertable.sync_schema();
  208. auto all = usertable.get_all<User>();
  209. for (auto& u : all) {
  210. json j_user;
  211. j_user["uid"] = u.uid;
  212. j_user["passwd"] = u.passwd;
  213. j_user["permission_level"] = u.permission_level;
  214. j_user["visible"] = u.visible;
  215. j_users.push_back(j_user);
  216. }
  217. return j_users;
  218. }
  219. shared_ptr<User> DBService::getUser(string uid) {
  220. auto usertable = make_storage(USER_DB_STRUCT);
  221. usertable.sync_schema();
  222. auto user = usertable.get_all<User>(where(c(&User::uid) == uid));
  223. if (user.size() == 0) {
  224. return nullptr;
  225. }
  226. return make_shared<User>(user[0]);
  227. }
  228. list<shared_ptr<db::Setting>> DBService::getAllSetting() {
  229. list<shared_ptr<db::Setting>> settings;
  230. auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  231. settingtable.sync_schema();
  232. auto all = settingtable.get_all<Setting>();
  233. for (auto& s : all) {
  234. settings.push_back(make_shared<Setting>(s));
  235. }
  236. return settings;
  237. }
  238. json DBService::getAllSettingJson() {
  239. json j_settings;
  240. auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  241. settingtable.sync_schema();
  242. auto all = settingtable.get_all<Setting>();
  243. for (auto& s : all) {
  244. json j_setting;
  245. j_setting["id"] = s.id;
  246. j_setting["name"] = s.name;
  247. j_setting["name_ch"] = s.name_ch;
  248. j_setting["val"] = s.val;
  249. j_setting["val_lower_limit"] = s.val_lower_limit;
  250. j_setting["val_upper_limit"] = s.val_upper_limit;
  251. j_setting["permission_level"] = s.permission_level;
  252. j_setting["val"] = s.val;
  253. j_settings.push_back(j_setting);
  254. }
  255. return j_settings;
  256. }
  257. bool DBService::setSettingVal(int id, int val) {
  258. auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  259. settingtable.sync_schema();
  260. auto setting = settingtable.get_all<Setting>(where(c(&Setting::id) == id));
  261. if (setting.size() == 0) {
  262. return false;
  263. }
  264. if (setting[0].val < setting[0].val_lower_limit || setting[0].val > setting[0].val_upper_limit) {
  265. return false;
  266. }
  267. setting[0].val = val;
  268. settingtable.update(setting[0]);
  269. return true;
  270. }
  271. bool DBService::setSettingVal(string setting_name, int val) {
  272. logger->info("set setting val: {} {}", setting_name, val);
  273. auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  274. settingtable.sync_schema();
  275. auto setting = settingtable.get_all<Setting>(where(c(&Setting::name) == setting_name));
  276. if (setting.size() == 0) {
  277. logger->error("set setting val failed: {} not found", setting_name);
  278. return false;
  279. }
  280. if (setting[0].val < setting[0].val_lower_limit || setting[0].val > setting[0].val_upper_limit) {
  281. logger->error("set setting val failed: {} out of range", setting_name);
  282. return false;
  283. }
  284. setting[0].val = val;
  285. Setting s = setting[0];
  286. settingtable.update(s);
  287. settingtable.sync_schema();
  288. return true;
  289. }
  290. int DBService::getSettingVal(string name) {
  291. auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  292. settingtable.sync_schema();
  293. auto setting = settingtable.get_all<Setting>(where(c(&Setting::name) == name));
  294. if (setting.size() == 0) {
  295. return -1;
  296. }
  297. return setting[0].val;
  298. }
  299. json DBService::getAllRecords(string disinfection_id) {
  300. json j_records;
  301. auto recordtable = make_storage(DISINFECTION_RECORD_DB_STRUCT);
  302. // int id;
  303. // string disinfection_id;
  304. // string date;
  305. // int heating_strip;
  306. // int air_compressor;
  307. // int sprinkler_pump;
  308. // int disinfectant_volume;
  309. // int h2o2_1;
  310. // int temp_1;
  311. // int humid_1;
  312. // int saturation_1;
  313. // int h2o2_2;
  314. // int temp_2;
  315. // int humid_2;
  316. // int saturation_2;
  317. // int h2o2_3;
  318. // int temp_3;
  319. // int humid_3;
  320. // int saturation_3;
  321. recordtable.sync_schema();
  322. auto all = recordtable.get_all<SensorRecord>(where(c(&SensorRecord::disinfection_id) == disinfection_id));
  323. for (auto& r : all) {
  324. json j_record;
  325. j_record["id"] = r.id;
  326. j_record["disinfection_id"] = r.disinfection_id;
  327. j_record["date"] = r.date;
  328. j_record["heating_strip"] = r.heating_strip;
  329. j_record["air_compressor"] = r.air_compressor;
  330. j_record["sprinkler_pump"] = r.sprinkler_pump;
  331. j_record["disinfectant_volume"] = r.disinfectant_volume;
  332. j_record["h2o2_1"] = r.h2o2_1;
  333. j_record["temp_1"] = r.temp_1;
  334. j_record["humid_1"] = r.humid_1;
  335. j_record["saturation_1"] = r.saturation_1;
  336. j_record["h2o2_2"] = r.h2o2_2;
  337. j_record["temp_2"] = r.temp_2;
  338. j_record["humid_2"] = r.humid_2;
  339. j_record["saturation_2"] = r.saturation_2;
  340. j_record["h2o2_3"] = r.h2o2_3;
  341. j_record["temp_3"] = r.temp_3;
  342. j_record["humid_3"] = r.humid_3;
  343. j_record["saturation_3"] = r.saturation_3;
  344. j_records.push_back(j_record);
  345. }
  346. return j_records;
  347. }
  348. void DBService::insertSensorRecord(shared_ptr<db::SensorRecord> record) {
  349. if (!record) {
  350. logger->error("insert sensor record failed: record is null");
  351. return;
  352. }
  353. auto recordtable = make_storage(DISINFECTION_RECORD_DB_STRUCT);
  354. recordtable.sync_schema();
  355. recordtable.insert(*record);
  356. }
  357. void DBService::insertDisinfectionRecord(shared_ptr<db::DisinfectionRecord> record) {
  358. if (!record) {
  359. logger->error("insert disinfection record failed: record is null");
  360. return;
  361. }
  362. auto recordtable = make_storage(DISINFECTION_RECORD_DB_STRUCT);
  363. recordtable.sync_schema();
  364. recordtable.insert(*record);
  365. }
  366. void DBService::setDisinfectionRecordDuration(string disinfection_id, int duration) {
  367. auto recordtable = make_storage(DISINFECTION_RECORD_DB_STRUCT);
  368. recordtable.sync_schema();
  369. auto record = recordtable.get_all<DisinfectionRecord>(where(c(&DisinfectionRecord::uuid) == disinfection_id));
  370. if (record.size() == 0) {
  371. logger->error("set disinfection record duration failed: {} not found", disinfection_id);
  372. return;
  373. }
  374. record[0].duration = duration;
  375. recordtable.update(record[0]);
  376. }