student_dao.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-03-10 lizhen9880 first version
  9. */
  10. #include <rtthread.h>
  11. #include <string.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <dfs_posix.h>
  15. #include "sqlite3.h"
  16. #include "dbhelper.h"
  17. #include "student_dao.h"
  18. #define DBG_ENABLE
  19. #define DBG_SECTION_NAME "app.student_dao"
  20. #define DBG_LEVEL DBG_INFO
  21. #define DBG_COLOR
  22. #include <rtdbg.h>
  23. static int student_insert_bind(sqlite3_stmt *stmt, int index, void *arg)
  24. {
  25. int rc;
  26. rt_list_t *h = arg, *pos, *n;
  27. student_t *s = RT_NULL;
  28. rt_list_for_each_safe(pos, n, h)
  29. {
  30. s = rt_list_entry(pos, student_t, list);
  31. sqlite3_reset(stmt); //reset the stmt
  32. sqlite3_bind_text(stmt, 1, s->name, strlen(s->name), NULL); //bind the 1st data,is a string
  33. sqlite3_bind_int(stmt, 2, s->score); //bind the 1st data,is a int
  34. rc = sqlite3_step(stmt); //execute the stmt by step
  35. }
  36. if (rc != SQLITE_DONE)
  37. return rc;
  38. return SQLITE_OK;
  39. }
  40. int student_add(rt_list_t *h)
  41. {
  42. return db_nonquery_operator("insert into student(name,score) values (?,?);", student_insert_bind, h);
  43. }
  44. int student_del(int id)
  45. {
  46. return db_nonquery_by_varpara("delete from student where id=?;", "%d", id);
  47. }
  48. int student_del_all(void)
  49. {
  50. return db_nonquery_operator("delete from student;", 0, 0);
  51. }
  52. static int student_update_bind(sqlite3_stmt *stmt, int index, void *arg)
  53. {
  54. int rc;
  55. student_t *s = arg;
  56. sqlite3_bind_text(stmt, 1, s->name, strlen(s->name), NULL);
  57. sqlite3_bind_int(stmt, 2, s->score);
  58. sqlite3_bind_int(stmt, 3, s->id);
  59. rc = sqlite3_step(stmt);
  60. if (rc != SQLITE_DONE)
  61. return rc;
  62. return SQLITE_OK;
  63. }
  64. int student_update(student_t *s)
  65. {
  66. return db_nonquery_operator("update student set name=?,score=? where id=?;", student_update_bind, s);
  67. }
  68. static int student_create(sqlite3_stmt *stmt, void *arg)
  69. {
  70. student_t *s = arg;
  71. int ret = sqlite3_step(stmt);
  72. if (ret != SQLITE_ROW)
  73. {
  74. return 0;
  75. }
  76. else
  77. {
  78. s->id = db_stmt_get_int(stmt, 0);
  79. db_stmt_get_text(stmt, 1, s->name);
  80. s->score = db_stmt_get_int(stmt, 2);
  81. }
  82. return ret;
  83. }
  84. int student_get_by_id(student_t *s, int id)
  85. {
  86. int res = db_query_by_varpara("select * from student where id=?;", student_create, s, "%d", id);
  87. return res;
  88. }
  89. void student_free_list(rt_list_t *h)
  90. {
  91. rt_list_t *head = h, *pos, *n;
  92. student_t *p = RT_NULL;
  93. rt_list_for_each_safe(pos, n, head)
  94. {
  95. p = rt_list_entry(pos, student_t, list);
  96. rt_free(p);
  97. }
  98. rt_free(head);
  99. }
  100. void student_print_list(rt_list_t *q)
  101. {
  102. student_t *s = NULL;
  103. for (s = rt_list_entry((q)->next, student_t, list);
  104. &s->list != (q);
  105. s = rt_list_entry(s->list.next, student_t, list))
  106. {
  107. rt_kprintf("id:%d\tname:%s\tscore:%d\n", s->id, s->name, s->score);
  108. }
  109. }
  110. static int student_create_queue(sqlite3_stmt *stmt, void *arg)
  111. {
  112. rt_list_t *q = arg;
  113. student_t *s;
  114. int ret, count = 0;
  115. ret = sqlite3_step(stmt);
  116. if (ret != SQLITE_ROW)
  117. {
  118. return 0;
  119. }
  120. do
  121. {
  122. s = rt_calloc(sizeof(student_t), 1);
  123. if (!s)
  124. {
  125. LOG_E("No enough memory!");
  126. goto __create_student_fail;
  127. }
  128. s->id = db_stmt_get_int(stmt, 0);
  129. db_stmt_get_text(stmt, 1, s->name);
  130. s->score = db_stmt_get_int(stmt, 2);
  131. rt_list_insert_before(q, &(s->list));
  132. count++;
  133. } while ((ret = sqlite3_step(stmt)) == SQLITE_ROW);
  134. return count;
  135. __create_student_fail:
  136. return -1;
  137. }
  138. int student_get_all(rt_list_t *q)
  139. {
  140. return db_query_by_varpara("select * from student;", student_create_queue, q, RT_NULL);
  141. }
  142. static void list_all(void)
  143. {
  144. rt_kprintf("test get all students\n");
  145. rt_list_t *h = rt_calloc(sizeof(student_t), 1);
  146. rt_list_init(h);
  147. int ret = student_get_all(h);
  148. if (ret >= 0)
  149. {
  150. student_print_list(h);
  151. rt_kprintf("record(s):%d\n", ret);
  152. }
  153. else
  154. {
  155. rt_kprintf("Get students information failed");
  156. }
  157. student_free_list(h);
  158. return;
  159. }
  160. int student_get_by_score(rt_list_t *h, int ls, int hs, enum order_type order)
  161. {
  162. char sql[128];
  163. rt_snprintf(sql, 128, "select * from student where score between %d and %d ORDER BY score %s;", ls, hs, order == ASC ? "ASC" : "DESC");
  164. return db_query_by_varpara(sql, student_create_queue, h, RT_NULL);
  165. }
  166. static void list_by_score(int ls, int hs, enum order_type order)
  167. {
  168. rt_list_t *h = rt_calloc(sizeof(rt_list_t), 1);
  169. rt_list_init(h);
  170. rt_kprintf("the student list of score between %d and %d:\n", ls, hs);
  171. int ret = student_get_by_score(h, ls, hs, order);
  172. if (ret >= 0)
  173. {
  174. student_print_list(h);
  175. rt_kprintf("record(s):%d\n", ret);
  176. }
  177. else
  178. {
  179. LOG_E("Get students information failed!");
  180. }
  181. student_free_list(h);
  182. return;
  183. }
  184. static void stu(uint8_t argc, char **argv)
  185. {
  186. if (argc < 2)
  187. {
  188. list_all();
  189. return;
  190. }
  191. else
  192. {
  193. char *cmd = argv[1];
  194. int rand = 0;
  195. if (rt_strcmp(cmd, "add") == 0)
  196. {
  197. int i = 0, count = 0;
  198. if (argc >= 3)
  199. {
  200. count = atol(argv[2]);
  201. }
  202. if (count == 0)
  203. {
  204. count = 1;
  205. }
  206. rt_tick_t ticks = rt_tick_get();
  207. rand = ticks;
  208. rt_list_t *h = (rt_list_t *)rt_calloc(1, sizeof(rt_list_t));
  209. rt_list_init(h);
  210. for (i = 0; i < count; i++)
  211. {
  212. student_t *s = (student_t *)rt_calloc(1, sizeof(student_t));
  213. rand += i;
  214. rand %= 99999;
  215. s->score = (rand % 81) + 20;
  216. sprintf(s->name, "Student%d", rand);
  217. rt_list_insert_before(h, &(s->list));
  218. }
  219. int res = student_add(h);
  220. student_free_list(h);
  221. if (res != SQLITE_OK)
  222. {
  223. LOG_E("add failed!");
  224. }
  225. else
  226. {
  227. ticks = rt_tick_get() - ticks;
  228. rt_kprintf("Insert %d record(s): %dms, speed: %dms/record\n", count,
  229. ticks * 1000 / RT_TICK_PER_SECOND, ticks * 1000 / RT_TICK_PER_SECOND / count);
  230. }
  231. }
  232. else if (rt_strcmp(cmd, "del") == 0)
  233. {
  234. if (argc == 2)
  235. {
  236. if (student_del_all() == SQLITE_OK)
  237. {
  238. rt_kprintf("Del all record success!\n");
  239. }
  240. else
  241. {
  242. rt_kprintf("Del all record failed!\n");
  243. }
  244. }
  245. else
  246. {
  247. rt_uint32_t id = atol(argv[2]);
  248. if (student_del(id) == SQLITE_OK)
  249. {
  250. rt_kprintf("Del record success with id:%d\n", id);
  251. }
  252. else
  253. {
  254. rt_kprintf("Del record failed with id:%d\n", id);
  255. }
  256. }
  257. }
  258. else if (rt_strcmp(cmd, "update") == 0)
  259. {
  260. /* update student record by id */
  261. if (argc >= 5)
  262. {
  263. student_t *s = rt_calloc(sizeof(student_t), 1);
  264. s->id = atol(argv[2]);
  265. rt_strncpy(s->name, argv[3], rt_strlen(argv[3]));
  266. s->score = atol(argv[4]);
  267. if (student_update(s) == SQLITE_OK)
  268. {
  269. rt_kprintf("update record success!\n");
  270. }
  271. else
  272. {
  273. rt_kprintf("update record failed!\n");
  274. }
  275. rt_free(s);
  276. }
  277. else
  278. {
  279. rt_kprintf("usage: stu update id name score\n");
  280. }
  281. }
  282. else if (rt_strcmp(cmd, "score") == 0)
  283. {
  284. /* query student's score between LOW and HIGH. */
  285. if (argc >= 4)
  286. {
  287. enum order_type order = ASC;
  288. int ls = atol(argv[2]);
  289. int hs = atol(argv[3]);
  290. if (rt_strcmp(argv[4], "-d") == 0)
  291. {
  292. order = DESC;
  293. }
  294. list_by_score(ls, hs, order);
  295. }
  296. else
  297. {
  298. rt_kprintf("usage: stu score LOW HIGH [OPTION]\n"
  299. "desc:query student's score between LOW and HIGH.\n"
  300. "OPTION(default ascending):\n -a:ascending\n -d:descending\n"
  301. "e.g: stu score 60 100 or stu score -d 60 100\n");
  302. }
  303. }
  304. else
  305. {
  306. student_t *s = rt_calloc(sizeof(student_t), 1);
  307. rt_uint32_t id = atol(argv[1]);
  308. if (student_get_by_id(s, id) > 0)
  309. {
  310. rt_kprintf("id:%d\t\tname:%s\tscore:%d\n", s->id, s->name, s->score);
  311. }
  312. else
  313. {
  314. rt_kprintf("no record with id:%d\n", id);
  315. }
  316. rt_free(s);
  317. }
  318. }
  319. }
  320. MSH_CMD_EXPORT(stu, student add del update query);
  321. static int create_student_tbl(void)
  322. {
  323. int fd = 0;
  324. db_set_name("/stu_info.db");
  325. fd = open(db_get_name(), O_RDONLY);
  326. rt_kprintf(db_get_name());
  327. if (fd < 0)
  328. {
  329. /* there is not the .db file.create db and table */
  330. const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
  331. return db_create_database(sql);
  332. }
  333. else if (db_table_is_exist("student") > 0)
  334. {
  335. /* there is the table int db.close the db. */
  336. close(fd);
  337. LOG_I("The table has already existed!\n");
  338. return RT_EOK;
  339. }
  340. else
  341. {
  342. /* there is not the table int db.create the table */
  343. const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
  344. return db_create_database(sql);
  345. }
  346. }
  347. MSH_CMD_EXPORT(create_student_tbl, create sqlite db);