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.

381 lines
16 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
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 root = storage.get_all<User>(where(c(&User::uid) == "root"));
  81. if (root.size() == 0) {
  82. storage.insert(User{-1, "root", "iflytop.com#9973", 0, 0}); // 超级用户
  83. }
  84. auto vendor = storage.get_all<User>(where(c(&User::uid) == "vendor"));
  85. if (vendor.size() == 0) {
  86. storage.insert<User>({-1, "vendor", "9973", 1, true}); // 厂商
  87. }
  88. auto admin = storage.get_all<User>(where(c(&User::uid) == "admin"));
  89. if (admin.size() == 0) {
  90. storage.insert<User>({-1, "admin", "9973", 2, true}); // 管理员
  91. }
  92. auto user = storage.get_all<User>(where(c(&User::uid) == "user"));
  93. if (user.size() == 0) {
  94. storage.insert<User>({-1, "user", "0000", 3, true}); // 普通用户
  95. }
  96. suc = true;
  97. } catch (const std::exception& e) {
  98. logger->error("init user db failed: {}", e.what());
  99. system("rm -rf user.db");
  100. sleep(1);
  101. }
  102. } while (!suc);
  103. }
  104. void DBService::init_setting_db() {
  105. bool suc = false;
  106. #if 0
  107. id setting_name setting_name_ch val_upper_limit val_lower_limit permission_level val
  108. 0 stoped_gs 0 2000 1 1000
  109. 1 continued_gs 0 2000 1 800
  110. 2 stoped_satur 0 100 1 80
  111. 3 continued_satur 0 100 1 60
  112. 4 max_humidity 湿 0 100 1 90
  113. 5 drainage_pump_speed 0 2000 2 500
  114. 6 injection_pump_speed 0 2000 2 500
  115. #endif
  116. do {
  117. try {
  118. logger->info("init setting db");
  119. auto storage = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  120. storage.sync_schema();
  121. if (storage.get_all<Setting>(where(c(&Setting::id) == 1)).size() == 0) //
  122. storage.insert(Setting{1, "stoped_gs", "消毒停止过氧化氢溶度", 0, 2000, 2, 1800});
  123. if (storage.get_all<Setting>(where(c(&Setting::id) == 2)).size() == 0)
  124. storage.insert(Setting{2, "continued_gs", "消毒继续过氧化氢溶度", 0, 2000, 2, 1500});
  125. if (storage.get_all<Setting>(where(c(&Setting::id) == 3)).size() == 0)
  126. storage.insert(Setting{3, "stoped_satur", "消毒停止过氧化氢相对饱和度", 0, 100, 2, 85});
  127. if (storage.get_all<Setting>(where(c(&Setting::id) == 4)).size() == 0)
  128. storage.insert(Setting{4, "continued_satur", "消毒继续过氧化氢相对饱和度", 0, 100, 2, 70});
  129. if (storage.get_all<Setting>(where(c(&Setting::id) == 5)).size() == 0) //
  130. storage.insert(Setting{5, "max_humidity", "允许消毒最大湿度", 0, 100, 2, 90});
  131. if (storage.get_all<Setting>(where(c(&Setting::id) == 6)).size() == 0)
  132. storage.insert(Setting{6, "drainage_pump_speed", "排液蠕动泵转速", 0, 350, 2, 300});
  133. if (storage.get_all<Setting>(where(c(&Setting::id) == 7)).size() == 0)
  134. storage.insert(Setting{7, "injection_pump_speed", "喷射蠕动泵转速", 0, 350, 2, 300});
  135. if (storage.get_all<Setting>(where(c(&Setting::id) == 8)).size() == 0) //
  136. storage.insert(Setting{8, "pre_heat_time_s", "预热时间", 0, 600, 2, 120});
  137. if (storage.get_all<Setting>(where(c(&Setting::id) == 9)).size() == 0) //
  138. storage.insert(Setting{9, "stoped_humi", "消毒停止相对湿度", 0, 100, 2, 85});
  139. if (storage.get_all<Setting>(where(c(&Setting::id) == 10)).size() == 0) //
  140. storage.insert(Setting{10, "continued_humi", "消毒继续相对湿度", 0, 100, 2, 70});
  141. suc = true;
  142. } catch (const std::exception& e) {
  143. logger->error("init setting db failed: {}", e.what());
  144. system("rm -rf setting.db");
  145. sleep(1);
  146. }
  147. } while (!suc);
  148. }
  149. void DBService::init_disinfection_record_db() {
  150. bool suc = false;
  151. do {
  152. try {
  153. logger->info("init disinfection record db");
  154. auto storage = make_storage(DISINFECTION_RECORD_DB_STRUCT);
  155. storage.sync_schema();
  156. suc = true;
  157. } catch (const std::exception& e) {
  158. logger->error("init disinfection record db failed: {}", e.what());
  159. system("rm -rf disinfection_record.db");
  160. sleep(1);
  161. }
  162. } while (!suc);
  163. }
  164. list<shared_ptr<User>> DBService::getAllUser() {
  165. list<shared_ptr<User>> users;
  166. auto usertable = make_storage(USER_DB_STRUCT);
  167. usertable.sync_schema();
  168. auto all = usertable.get_all<User>();
  169. for (auto& u : all) {
  170. users.push_back(make_shared<User>(u));
  171. }
  172. return users;
  173. }
  174. json DBService::getAllUserJson() {
  175. json j_users;
  176. auto usertable = make_storage(USER_DB_STRUCT);
  177. usertable.sync_schema();
  178. auto all = usertable.get_all<User>();
  179. for (auto& u : all) {
  180. json j_user;
  181. j_user["uid"] = u.uid;
  182. j_user["passwd"] = u.passwd;
  183. j_user["permission_level"] = u.permission_level;
  184. j_user["visible"] = u.visible;
  185. j_users.push_back(j_user);
  186. }
  187. return j_users;
  188. }
  189. shared_ptr<User> DBService::getUser(string uid) {
  190. auto usertable = make_storage(USER_DB_STRUCT);
  191. usertable.sync_schema();
  192. auto user = usertable.get_all<User>(where(c(&User::uid) == uid));
  193. if (user.size() == 0) {
  194. return nullptr;
  195. }
  196. return make_shared<User>(user[0]);
  197. }
  198. list<shared_ptr<db::Setting>> DBService::getAllSetting() {
  199. list<shared_ptr<db::Setting>> settings;
  200. auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  201. settingtable.sync_schema();
  202. auto all = settingtable.get_all<Setting>();
  203. for (auto& s : all) {
  204. settings.push_back(make_shared<Setting>(s));
  205. }
  206. return settings;
  207. }
  208. json DBService::getAllSettingJson() {
  209. json j_settings;
  210. auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  211. settingtable.sync_schema();
  212. auto all = settingtable.get_all<Setting>();
  213. for (auto& s : all) {
  214. json j_setting;
  215. j_setting["id"] = s.id;
  216. j_setting["name"] = s.name;
  217. j_setting["name_ch"] = s.name_ch;
  218. j_setting["val"] = s.val;
  219. j_setting["val_lower_limit"] = s.val_lower_limit;
  220. j_setting["val_upper_limit"] = s.val_upper_limit;
  221. j_setting["permission_level"] = s.permission_level;
  222. j_setting["val"] = s.val;
  223. j_settings.push_back(j_setting);
  224. }
  225. return j_settings;
  226. }
  227. bool DBService::setSettingVal(int id, int val) {
  228. auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  229. settingtable.sync_schema();
  230. auto setting = settingtable.get_all<Setting>(where(c(&Setting::id) == id));
  231. if (setting.size() == 0) {
  232. return false;
  233. }
  234. if (setting[0].val < setting[0].val_lower_limit || setting[0].val > setting[0].val_upper_limit) {
  235. return false;
  236. }
  237. setting[0].val = val;
  238. settingtable.update(setting[0]);
  239. return true;
  240. }
  241. bool DBService::setSettingVal(string setting_name, int val) {
  242. logger->info("set setting val: {} {}", setting_name, val);
  243. auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  244. settingtable.sync_schema();
  245. auto setting = settingtable.get_all<Setting>(where(c(&Setting::name) == setting_name));
  246. if (setting.size() == 0) {
  247. logger->error("set setting val failed: {} not found", setting_name);
  248. return false;
  249. }
  250. if (setting[0].val < setting[0].val_lower_limit || setting[0].val > setting[0].val_upper_limit) {
  251. logger->error("set setting val failed: {} out of range", setting_name);
  252. return false;
  253. }
  254. setting[0].val = val;
  255. Setting s = setting[0];
  256. settingtable.update(s);
  257. settingtable.sync_schema();
  258. return true;
  259. }
  260. int DBService::getSettingVal(string name) {
  261. auto settingtable = make_storage(SETTING_DB, SETTING_DB_STRUCT);
  262. settingtable.sync_schema();
  263. auto setting = settingtable.get_all<Setting>(where(c(&Setting::name) == name));
  264. if (setting.size() == 0) {
  265. return -1;
  266. }
  267. return setting[0].val;
  268. }
  269. json DBService::getAllRecords(string disinfection_id) {
  270. json j_records;
  271. auto recordtable = make_storage(DISINFECTION_RECORD_DB_STRUCT);
  272. // int id;
  273. // string disinfection_id;
  274. // string date;
  275. // int heating_strip;
  276. // int air_compressor;
  277. // int sprinkler_pump;
  278. // int disinfectant_volume;
  279. // int h2o2_1;
  280. // int temp_1;
  281. // int humid_1;
  282. // int saturation_1;
  283. // int h2o2_2;
  284. // int temp_2;
  285. // int humid_2;
  286. // int saturation_2;
  287. // int h2o2_3;
  288. // int temp_3;
  289. // int humid_3;
  290. // int saturation_3;
  291. recordtable.sync_schema();
  292. auto all = recordtable.get_all<SensorRecord>(where(c(&SensorRecord::disinfection_id) == disinfection_id));
  293. for (auto& r : all) {
  294. json j_record;
  295. j_record["id"] = r.id;
  296. j_record["disinfection_id"] = r.disinfection_id;
  297. j_record["date"] = r.date;
  298. j_record["heating_strip"] = r.heating_strip;
  299. j_record["air_compressor"] = r.air_compressor;
  300. j_record["sprinkler_pump"] = r.sprinkler_pump;
  301. j_record["disinfectant_volume"] = r.disinfectant_volume;
  302. j_record["h2o2_1"] = r.h2o2_1;
  303. j_record["temp_1"] = r.temp_1;
  304. j_record["humid_1"] = r.humid_1;
  305. j_record["saturation_1"] = r.saturation_1;
  306. j_record["h2o2_2"] = r.h2o2_2;
  307. j_record["temp_2"] = r.temp_2;
  308. j_record["humid_2"] = r.humid_2;
  309. j_record["saturation_2"] = r.saturation_2;
  310. j_record["h2o2_3"] = r.h2o2_3;
  311. j_record["temp_3"] = r.temp_3;
  312. j_record["humid_3"] = r.humid_3;
  313. j_record["saturation_3"] = r.saturation_3;
  314. j_records.push_back(j_record);
  315. }
  316. return j_records;
  317. }
  318. void DBService::insertSensorRecord(shared_ptr<db::SensorRecord> record) {
  319. if (!record) {
  320. logger->error("insert sensor record failed: record is null");
  321. return;
  322. }
  323. auto recordtable = make_storage(DISINFECTION_RECORD_DB_STRUCT);
  324. recordtable.sync_schema();
  325. recordtable.insert(*record);
  326. }
  327. void DBService::insertDisinfectionRecord(shared_ptr<db::DisinfectionRecord> record) {
  328. if (!record) {
  329. logger->error("insert disinfection record failed: record is null");
  330. return;
  331. }
  332. auto recordtable = make_storage(DISINFECTION_RECORD_DB_STRUCT);
  333. recordtable.sync_schema();
  334. recordtable.insert(*record);
  335. }
  336. void DBService::setDisinfectionRecordDuration(string disinfection_id, int duration) {
  337. auto recordtable = make_storage(DISINFECTION_RECORD_DB_STRUCT);
  338. recordtable.sync_schema();
  339. auto record = recordtable.get_all<DisinfectionRecord>(where(c(&DisinfectionRecord::uuid) == disinfection_id));
  340. if (record.size() == 0) {
  341. logger->error("set disinfection record duration failed: {} not found", disinfection_id);
  342. return;
  343. }
  344. record[0].duration = duration;
  345. recordtable.update(record[0]);
  346. }