forked from xuos/xiuos
				
			
		
			
				
	
	
		
			745 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			745 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * Copyright (c) 2006-2020, RT-Thread Development Team
 | |
|  *
 | |
|  * SPDX-License-Identifier: Apache-2.0
 | |
|  *
 | |
|  * Change Logs:
 | |
|  * Date           Author       Notes
 | |
|  * 2020-03-10     lizhen9880   first version
 | |
|  */
 | |
| 
 | |
| /**
 | |
| * @file student_dao.c
 | |
| * @brief support SQLite demo using dbhelper api in XiUOS
 | |
| * @version 3.0 
 | |
| * @author AIIT XUOS Lab
 | |
| * @date 2023-10-25
 | |
| */
 | |
| 
 | |
| /*************************************************
 | |
| File name: student_dao.c
 | |
| Description: support SQLite demo using dbhelper api in XiUOS
 | |
| Others: 
 | |
| History: 
 | |
| 1. Date: 2023-10-25
 | |
| Author: AIIT XUOS Lab
 | |
| Modification: 
 | |
| 1、add XiUOS function.
 | |
| *************************************************/
 | |
| #include <transform.h>
 | |
| #ifdef ADD_RTTHREAD_FEATURES
 | |
| #include <rtthread.h>
 | |
| #include <dfs_posix.h>
 | |
| #endif
 | |
| #ifdef ADD_XIZI_FEATURES
 | |
| #include <list.h>
 | |
| #endif
 | |
| #include <string.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include "sqlite3.h"
 | |
| #include "dbhelper.h"
 | |
| #include "student_dao.h"
 | |
| 
 | |
| #define DBG_ENABLE
 | |
| #define DBG_SECTION_NAME "app.student_dao"
 | |
| #define DBG_LEVEL DBG_INFO
 | |
| #define DBG_COLOR
 | |
| #ifdef ADD_RTTHREAD_FEATURES
 | |
| #include <rtdbg.h>
 | |
| 
 | |
| static int student_insert_bind(sqlite3_stmt *stmt, int index, void *arg)
 | |
| {
 | |
|     int rc;
 | |
|     rt_list_t *h = arg, *pos, *n;
 | |
|     student_t *s = RT_NULL;
 | |
|     rt_list_for_each_safe(pos, n, h)
 | |
|     {
 | |
|         s = rt_list_entry(pos, student_t, list);
 | |
|         sqlite3_reset(stmt);                                        //reset the stmt
 | |
|         sqlite3_bind_text(stmt, 1, s->name, strlen(s->name), NULL); //bind the 1st data,is a string
 | |
|         sqlite3_bind_int(stmt, 2, s->score);                        //bind the 1st data,is a int
 | |
|         rc = sqlite3_step(stmt);                                    //execute the stmt by step
 | |
|     }
 | |
| 
 | |
|     if (rc != SQLITE_DONE)
 | |
|         return rc;
 | |
|     return SQLITE_OK;
 | |
| }
 | |
| int student_add(rt_list_t *h)
 | |
| {
 | |
|     return db_nonquery_operator("insert into student(name,score) values (?,?);", student_insert_bind, h);
 | |
| }
 | |
| 
 | |
| int student_del(int id)
 | |
| {
 | |
|     return db_nonquery_by_varpara("delete from student where id=?;", "%d", id);
 | |
| }
 | |
| 
 | |
| int student_del_all(void)
 | |
| {
 | |
|     return db_nonquery_operator("delete from student;", 0, 0);
 | |
| }
 | |
| 
 | |
| static int student_update_bind(sqlite3_stmt *stmt, int index, void *arg)
 | |
| {
 | |
|     int rc;
 | |
|     student_t *s = arg;
 | |
|     sqlite3_bind_text(stmt, 1, s->name, strlen(s->name), NULL);
 | |
|     sqlite3_bind_int(stmt, 2, s->score);
 | |
|     sqlite3_bind_int(stmt, 3, s->id);
 | |
|     rc = sqlite3_step(stmt);
 | |
|     if (rc != SQLITE_DONE)
 | |
|         return rc;
 | |
|     return SQLITE_OK;
 | |
| }
 | |
| int student_update(student_t *s)
 | |
| {
 | |
|     return db_nonquery_operator("update student set name=?,score=? where id=?;", student_update_bind, s);
 | |
| }
 | |
| 
 | |
| static int student_create(sqlite3_stmt *stmt, void *arg)
 | |
| {
 | |
|     student_t *s = arg;
 | |
|     int ret = sqlite3_step(stmt);
 | |
|     if (ret != SQLITE_ROW)
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         s->id = db_stmt_get_int(stmt, 0);
 | |
|         db_stmt_get_text(stmt, 1, s->name);
 | |
|         s->score = db_stmt_get_int(stmt, 2);
 | |
|     }
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| int student_get_by_id(student_t *s, int id)
 | |
| {
 | |
|     int res = db_query_by_varpara("select * from student where id=?;", student_create, s, "%d", id);
 | |
|     return res;
 | |
| }
 | |
| 
 | |
| void student_free_list(rt_list_t *h)
 | |
| {
 | |
|     rt_list_t *head = h, *pos, *n;
 | |
|     student_t *p = RT_NULL;
 | |
|     rt_list_for_each_safe(pos, n, head)
 | |
|     {
 | |
|         p = rt_list_entry(pos, student_t, list);
 | |
|         rt_free(p);
 | |
|     }
 | |
|     rt_free(head);
 | |
| }
 | |
| 
 | |
| void student_print_list(rt_list_t *q)
 | |
| {
 | |
|     student_t *s = NULL;
 | |
|     for (s = rt_list_entry((q)->next, student_t, list);
 | |
|          &s->list != (q);
 | |
|          s = rt_list_entry(s->list.next, student_t, list))
 | |
|     {
 | |
|         rt_kprintf("id:%d\tname:%s\tscore:%d\n", s->id, s->name, s->score);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int student_create_queue(sqlite3_stmt *stmt, void *arg)
 | |
| {
 | |
|     rt_list_t *q = arg;
 | |
|     student_t *s;
 | |
|     int ret, count = 0;
 | |
|     ret = sqlite3_step(stmt);
 | |
|     if (ret != SQLITE_ROW)
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
|     do
 | |
|     {
 | |
|         s = rt_calloc(sizeof(student_t), 1);
 | |
|         if (!s)
 | |
|         {
 | |
|             LOG_E("No enough memory!");
 | |
|             goto __create_student_fail;
 | |
|         }
 | |
|         s->id = db_stmt_get_int(stmt, 0);
 | |
|         db_stmt_get_text(stmt, 1, s->name);
 | |
|         s->score = db_stmt_get_int(stmt, 2);
 | |
|         rt_list_insert_before(q, &(s->list));
 | |
|         count++;
 | |
|     } while ((ret = sqlite3_step(stmt)) == SQLITE_ROW);
 | |
|     return count;
 | |
| __create_student_fail:
 | |
|     return -1;
 | |
| }
 | |
| 
 | |
| int student_get_all(rt_list_t *q)
 | |
| {
 | |
|     return db_query_by_varpara("select * from student;", student_create_queue, q, RT_NULL);
 | |
| }
 | |
| 
 | |
| static void list_all(void)
 | |
| {
 | |
|     rt_kprintf("test get all students\n");
 | |
|     rt_list_t *h = rt_calloc(sizeof(student_t), 1);
 | |
|     rt_list_init(h);
 | |
|     int ret = student_get_all(h);
 | |
|     if (ret >= 0)
 | |
|     {
 | |
|         student_print_list(h);
 | |
|         rt_kprintf("record(s):%d\n", ret);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         rt_kprintf("Get students information failed");
 | |
|     }
 | |
|     student_free_list(h);
 | |
|     return;
 | |
| }
 | |
| 
 | |
| int student_get_by_score(rt_list_t *h, int ls, int hs, enum order_type order)
 | |
| {
 | |
|     char sql[128];
 | |
| 
 | |
|     rt_snprintf(sql, 128, "select * from student where score between %d and %d ORDER BY score %s;", ls, hs, order == ASC ? "ASC" : "DESC");
 | |
|     return db_query_by_varpara(sql, student_create_queue, h, RT_NULL);
 | |
| }
 | |
| 
 | |
| static void list_by_score(int ls, int hs, enum order_type order)
 | |
| {
 | |
|     rt_list_t *h = rt_calloc(sizeof(rt_list_t), 1);
 | |
|     rt_list_init(h);
 | |
|     rt_kprintf("the student list of score between %d and %d:\n", ls, hs);
 | |
|     int ret = student_get_by_score(h, ls, hs, order);
 | |
|     if (ret >= 0)
 | |
|     {
 | |
|         student_print_list(h);
 | |
|         rt_kprintf("record(s):%d\n", ret);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         LOG_E("Get students information failed!");
 | |
|     }
 | |
|     student_free_list(h);
 | |
|     return;
 | |
| }
 | |
| 
 | |
| static void stu(uint8_t argc, char **argv)
 | |
| {
 | |
|     if (argc < 2)
 | |
|     {
 | |
|         list_all();
 | |
|         return;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         char *cmd = argv[1];
 | |
|         int rand = 0;
 | |
| 
 | |
|         if (rt_strcmp(cmd, "add") == 0)
 | |
|         {
 | |
|             int i = 0, count = 0;
 | |
|             if (argc >= 3)
 | |
|             {
 | |
|                 count = atol(argv[2]);
 | |
|             }
 | |
|             if (count == 0)
 | |
|             {
 | |
|                 count = 1;
 | |
|             }
 | |
|             rt_tick_t ticks = rt_tick_get();
 | |
|             rand = ticks;
 | |
|             rt_list_t *h = (rt_list_t *)rt_calloc(1, sizeof(rt_list_t));
 | |
|             rt_list_init(h);
 | |
|             for (i = 0; i < count; i++)
 | |
|             {
 | |
|                 student_t *s = (student_t *)rt_calloc(1, sizeof(student_t));
 | |
|                 rand += i;
 | |
|                 rand %= 99999;
 | |
|                 s->score = (rand % 81) + 20;
 | |
|                 sprintf(s->name, "Student%d", rand);
 | |
|                 rt_list_insert_before(h, &(s->list));
 | |
|             }
 | |
|             int res = student_add(h);
 | |
|             student_free_list(h);
 | |
|             if (res != SQLITE_OK)
 | |
|             {
 | |
|                 LOG_E("add failed!");
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 ticks = rt_tick_get() - ticks;
 | |
|                 rt_kprintf("Insert %d record(s): %dms, speed: %dms/record\n", count,
 | |
|                            ticks * 1000 / RT_TICK_PER_SECOND, ticks * 1000 / RT_TICK_PER_SECOND / count);
 | |
|             }
 | |
|         }
 | |
|         else if (rt_strcmp(cmd, "del") == 0)
 | |
|         {
 | |
|             if (argc == 2)
 | |
|             {
 | |
|                 if (student_del_all() == SQLITE_OK)
 | |
|                 {
 | |
|                     rt_kprintf("Del all record success!\n");
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     rt_kprintf("Del all record failed!\n");
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 rt_uint32_t id = atol(argv[2]);
 | |
|                 if (student_del(id) == SQLITE_OK)
 | |
|                 {
 | |
|                     rt_kprintf("Del record success with id:%d\n", id);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     rt_kprintf("Del record failed with id:%d\n", id);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         else if (rt_strcmp(cmd, "update") == 0)
 | |
|         {
 | |
|             /* update student record by id */
 | |
|             if (argc >= 5)
 | |
|             {
 | |
|                 student_t *s = rt_calloc(sizeof(student_t), 1);
 | |
|                 s->id = atol(argv[2]);
 | |
|                 rt_strncpy(s->name, argv[3], rt_strlen(argv[3]));
 | |
|                 s->score = atol(argv[4]);
 | |
|                 if (student_update(s) == SQLITE_OK)
 | |
|                 {
 | |
|                     rt_kprintf("update record success!\n");
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     rt_kprintf("update record failed!\n");
 | |
|                 }
 | |
|                 rt_free(s);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 rt_kprintf("usage: stu update id name score\n");
 | |
|             }
 | |
|         }
 | |
|         else if (rt_strcmp(cmd, "score") == 0)
 | |
|         {
 | |
|             /* query student's score between LOW and HIGH. */
 | |
|             if (argc >= 4)
 | |
|             {
 | |
|                 enum order_type order = ASC;
 | |
|                 int ls = atol(argv[2]);
 | |
|                 int hs = atol(argv[3]);
 | |
|                 if (rt_strcmp(argv[4], "-d") == 0)
 | |
|                 {
 | |
|                     order = DESC;
 | |
|                 }
 | |
|                 list_by_score(ls, hs, order);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 rt_kprintf("usage: stu score LOW HIGH [OPTION]\n"
 | |
|                            "desc:query student's score between LOW and HIGH.\n"
 | |
|                            "OPTION(default ascending):\n    -a:ascending\n    -d:descending\n"
 | |
|                            "e.g: stu score 60 100 or stu score -d 60 100\n");
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             student_t *s = rt_calloc(sizeof(student_t), 1);
 | |
|             rt_uint32_t id = atol(argv[1]);
 | |
|             if (student_get_by_id(s, id) > 0)
 | |
|             {
 | |
|                 rt_kprintf("id:%d\t\tname:%s\tscore:%d\n", s->id, s->name, s->score);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 rt_kprintf("no record with id:%d\n", id);
 | |
|             }
 | |
|             rt_free(s);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| MSH_CMD_EXPORT(stu, student add del update query);
 | |
| 
 | |
| static int create_student_tbl(void)
 | |
| {
 | |
|     int fd = 0;
 | |
|     db_set_name("/stu_info.db");
 | |
|     fd = open(db_get_name(), O_RDONLY);
 | |
|     rt_kprintf(db_get_name());
 | |
|     if (fd < 0)
 | |
|     {
 | |
|         /* there is not the .db file.create db and table */
 | |
|         const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
 | |
|         return db_create_database(sql);
 | |
|     }
 | |
|     else if (db_table_is_exist("student") > 0)
 | |
|     {
 | |
|         /* there is the table int db.close the db. */
 | |
|         close(fd);
 | |
|         LOG_I("The table has already existed!\n");
 | |
|         return RT_EOK;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         /* there is not the table int db.create the table */
 | |
|         const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
 | |
|         return db_create_database(sql);
 | |
|     }
 | |
| }
 | |
| MSH_CMD_EXPORT(create_student_tbl, create sqlite db);
 | |
| #endif
 | |
| 
 | |
| 
 | |
| static int student_insert_bind(sqlite3_stmt *stmt, int index, void *arg)
 | |
| {
 | |
|     int rc = 0;
 | |
|     DoublelistType *h = arg, *node, *node_next;
 | |
|     student_t *s = NULL;
 | |
|     DOUBLE_LIST_FOR_EACH_SAFE(node, node_next, h)
 | |
|     {
 | |
|         s = DOUBLE_LIST_ENTRY(node, student_t, list);
 | |
|         sqlite3_reset(stmt);                                        //reset the stmt
 | |
|         sqlite3_bind_text(stmt, 1, s->name, strlen(s->name), NULL); //bind the 1st data,is a string
 | |
|         sqlite3_bind_int(stmt, 2, s->score);                        //bind the 1st data,is a int
 | |
|         rc = sqlite3_step(stmt);                                    //execute the stmt by step
 | |
|     }
 | |
| 
 | |
|     if (rc != SQLITE_DONE)
 | |
|         return rc;
 | |
|     return SQLITE_OK;
 | |
| }
 | |
| 
 | |
| int student_add(DoublelistType *h)
 | |
| {
 | |
|     return db_nonquery_operator("insert into student(name,score) values (?,?);", student_insert_bind, h);
 | |
| }
 | |
| 
 | |
| int student_del(int id)
 | |
| {
 | |
|     return db_nonquery_by_varpara("delete from student where id=?;", "%d", id);
 | |
| }
 | |
| 
 | |
| int student_del_all(void)
 | |
| {
 | |
|     return db_nonquery_operator("delete from student;", 0, 0);
 | |
| }
 | |
| 
 | |
| static int student_update_bind(sqlite3_stmt *stmt, int index, void *arg)
 | |
| {
 | |
|     int rc;
 | |
|     student_t *s = arg;
 | |
|     sqlite3_bind_text(stmt, 1, s->name, strlen(s->name), NULL);
 | |
|     sqlite3_bind_int(stmt, 2, s->score);
 | |
|     sqlite3_bind_int(stmt, 3, s->id);
 | |
|     rc = sqlite3_step(stmt);
 | |
|     if (rc != SQLITE_DONE)
 | |
|         return rc;
 | |
|     return SQLITE_OK;
 | |
| }
 | |
| int student_update(student_t *s)
 | |
| {
 | |
|     return db_nonquery_operator("update student set name=?,score=? where id=?;", student_update_bind, s);
 | |
| }
 | |
| 
 | |
| static int student_create(sqlite3_stmt *stmt, void *arg)
 | |
| {
 | |
|     student_t *s = arg;
 | |
|     int ret = sqlite3_step(stmt);
 | |
|     if (ret != SQLITE_ROW)
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         s->id = db_stmt_get_int(stmt, 0);
 | |
|         db_stmt_get_text(stmt, 1, s->name);
 | |
|         s->score = db_stmt_get_int(stmt, 2);
 | |
|     }
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| int student_get_by_id(student_t *s, int id)
 | |
| {
 | |
|     int res = db_query_by_varpara("select * from student where id=?;", student_create, s, "%d", id);
 | |
|     return res;
 | |
| }
 | |
| 
 | |
| void student_free_list(DoublelistType *h)
 | |
| {
 | |
|     DoublelistType *head = h, *node, *node_next;
 | |
|     student_t *p = NULL;
 | |
|     DOUBLE_LIST_FOR_EACH_SAFE(node, node_next, head)
 | |
|     {
 | |
|         p = DOUBLE_LIST_ENTRY(node, student_t, list);
 | |
|         PrivFree(p);
 | |
|     }
 | |
|     PrivFree(head);
 | |
| }
 | |
| 
 | |
| void student_print_list(DoublelistType *q)
 | |
| {
 | |
|     student_t *s = NULL;
 | |
|     for (s = DOUBLE_LIST_ENTRY((q)->node_next, student_t, list);
 | |
|          &s->list != (q);
 | |
|          s = DOUBLE_LIST_ENTRY(s->list.node_next, student_t, list))
 | |
|     {
 | |
|         printf("id:%d\tname:%s\tscore:%d\n", s->id, s->name, s->score);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int student_create_queue(sqlite3_stmt *stmt, void *arg)
 | |
| {
 | |
|     DoublelistType *q = arg;
 | |
|     student_t *s;
 | |
|     int ret, count = 0;
 | |
|     ret = sqlite3_step(stmt);
 | |
|     if (ret != SQLITE_ROW)
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
|     do
 | |
|     {
 | |
|         s = PrivCalloc(1, sizeof(student_t));
 | |
|         if (!s)
 | |
|         {
 | |
|             printf("No enough memory!");
 | |
|             goto __create_student_fail;
 | |
|         }
 | |
|         s->id = db_stmt_get_int(stmt, 0);
 | |
|         db_stmt_get_text(stmt, 1, s->name);
 | |
|         s->score = db_stmt_get_int(stmt, 2);
 | |
|         AppDoubleListInsertNodeBefore(q, &(s->list));
 | |
|         count++;
 | |
|     } while ((ret = sqlite3_step(stmt)) == SQLITE_ROW);
 | |
|     return count;
 | |
| __create_student_fail:
 | |
|     return -1;
 | |
| }
 | |
| 
 | |
| int student_get_all(DoublelistType *q)
 | |
| {
 | |
|     return db_query_by_varpara("select * from student;", student_create_queue, q, NULL);
 | |
| }
 | |
| 
 | |
| static void list_all(void)
 | |
| {
 | |
|     printf("test get all students\n");
 | |
|     DoublelistType *h = PrivCalloc(1, sizeof(student_t));
 | |
|     AppInitDoubleList(h);
 | |
|     int ret = student_get_all(h);
 | |
|     if (ret >= 0)
 | |
|     {
 | |
|         student_print_list(h);
 | |
|         printf("record(s):%d\n", ret);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         printf("Get students information failed");
 | |
|     }
 | |
|     student_free_list(h);
 | |
|     return;
 | |
| }
 | |
| 
 | |
| int student_get_by_score(DoublelistType *h, int ls, int hs, enum order_type order)
 | |
| {
 | |
|     char sql[128];
 | |
| 
 | |
|     snprintf(sql, 128, "select * from student where score between %d and %d ORDER BY score %s;", ls, hs, order == ASC ? "ASC" : "DESC");
 | |
|     return db_query_by_varpara(sql, student_create_queue, h, NULL);
 | |
| }
 | |
| 
 | |
| static void list_by_score(int ls, int hs, enum order_type order)
 | |
| {
 | |
|     DoublelistType *h = PrivCalloc(1, sizeof(DoublelistType));
 | |
|     AppInitDoubleList(h);
 | |
|     printf("the student list of score between %d and %d:\n", ls, hs);
 | |
|     int ret = student_get_by_score(h, ls, hs, order);
 | |
|     if (ret >= 0)
 | |
|     {
 | |
|         student_print_list(h);
 | |
|         printf("record(s):%d\n", ret);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         printf("Get students information failed!");
 | |
|     }
 | |
|     student_free_list(h);
 | |
|     return;
 | |
| }
 | |
| 
 | |
| static int stu(int argc, char *argv[])
 | |
| {
 | |
|     if (argc < 2)
 | |
|     {
 | |
|         list_all();
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         char *cmd = argv[1];
 | |
|         int rand = 0;
 | |
| 
 | |
|         if (strcmp(cmd, "add") == 0)
 | |
|         {
 | |
|             int i = 0, count = 0;
 | |
|             if (argc >= 3)
 | |
|             {
 | |
|                 count = atol(argv[2]);
 | |
|             }
 | |
|             if (count == 0)
 | |
|             {
 | |
|                 count = 1;
 | |
|             }
 | |
|             int start_time = PrivGetTickTime();
 | |
|             rand = start_time;
 | |
|             DoublelistType *h = (DoublelistType *)PrivCalloc(1, sizeof(DoublelistType));
 | |
|             AppInitDoubleList(h);
 | |
|             for (i = 0; i < count; i++)
 | |
|             {
 | |
|                 student_t *s = (student_t *)PrivCalloc(1, sizeof(student_t));
 | |
|                 rand += i;
 | |
|                 rand %= 99999;
 | |
|                 s->score = (rand % 81) + 20;
 | |
|                 sprintf(s->name, "Student%d", rand);
 | |
|                 AppDoubleListInsertNodeBefore(h, &(s->list));
 | |
|             }
 | |
|             int res = student_add(h);
 | |
|             student_free_list(h);
 | |
|             if (res != SQLITE_OK)
 | |
|             {
 | |
|                 printf("add failed!");
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 int end_time = PrivGetTickTime() - start_time;
 | |
|                 printf("Insert %d record(s): %dms, speed: %dms/record\n", count,
 | |
|                            end_time, end_time / count);
 | |
|             }
 | |
|         }
 | |
|         else if (strcmp(cmd, "del") == 0)
 | |
|         {
 | |
|             if (argc == 2)
 | |
|             {
 | |
|                 if (student_del_all() == SQLITE_OK)
 | |
|                 {
 | |
|                     printf("Del all record success!\n");
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     printf("Del all record failed!\n");
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 uint32_t id = atol(argv[2]);
 | |
|                 if (student_del(id) == SQLITE_OK)
 | |
|                 {
 | |
|                     printf("Del record success with id:%d\n", id);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     printf("Del record failed with id:%d\n", id);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         else if (strcmp(cmd, "update") == 0)
 | |
|         {
 | |
|             /* update student record by id */
 | |
|             if (argc >= 5)
 | |
|             {
 | |
|                 student_t *s = PrivCalloc(sizeof(student_t), 1);
 | |
|                 s->id = atol(argv[2]);
 | |
|                 strncpy(s->name, argv[3], strlen(argv[3]));
 | |
|                 s->score = atol(argv[4]);
 | |
|                 if (student_update(s) == SQLITE_OK)
 | |
|                 {
 | |
|                     printf("update record success!\n");
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     printf("update record failed!\n");
 | |
|                 }
 | |
|                 PrivFree(s);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 printf("usage: stu update id name score\n");
 | |
|             }
 | |
|         }
 | |
|         else if (strcmp(cmd, "score") == 0)
 | |
|         {
 | |
|             /* query student's score between LOW and HIGH. */
 | |
|             if (argc >= 4)
 | |
|             {
 | |
|                 enum order_type order = ASC;
 | |
|                 int ls = atol(argv[2]);
 | |
|                 int hs = atol(argv[3]);
 | |
|                 if (strcmp(argv[4], "-d") == 0)
 | |
|                 {
 | |
|                     order = DESC;
 | |
|                 }
 | |
|                 list_by_score(ls, hs, order);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 printf("usage: stu score LOW HIGH [OPTION]\n"
 | |
|                            "desc:query student's score between LOW and HIGH.\n"
 | |
|                            "OPTION(default ascending):\n    -a:ascending\n    -d:descending\n"
 | |
|                            "e.g: stu score 60 100 or stu score -d 60 100\n");
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             student_t *s = PrivCalloc(sizeof(student_t), 1);
 | |
|             uint32_t id = atol(argv[1]);
 | |
|             if (student_get_by_id(s, id) > 0)
 | |
|             {
 | |
|                 printf("id:%d\t\tname:%s\tscore:%d\n", s->id, s->name, s->score);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 printf("no record with id:%d\n", id);
 | |
|             }
 | |
|             PrivFree(s);
 | |
|         }
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| PRIV_SHELL_CMD_FUNCTION(stu, student add del update query, PRIV_SHELL_CMD_MAIN_ATTR);
 | |
| 
 | |
| static int create_student_tbl(void)
 | |
| {
 | |
|     int fd = -1;
 | |
| 
 | |
|     //init sqlite3
 | |
|     db_helper_init();
 | |
| 
 | |
|     db_set_name("/stu_info.db");
 | |
| 
 | |
|     fd = PrivOpen("/stu_info.db", O_RDONLY);
 | |
|     printf(db_get_name());
 | |
|     printf(" fd %d\n", fd);
 | |
|     if (fd < 0)
 | |
|     {
 | |
|         /* there is not the .db file.create db and table */
 | |
|         const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
 | |
|         return db_create_database(sql);
 | |
|     }
 | |
|     else if (db_table_is_exist("student") > 0)
 | |
|     {
 | |
|         /* there is the table int db.close the db. */
 | |
|         PrivClose(fd);
 | |
|         printf("The table has already existed!\n");
 | |
|         return 0;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         /* there is not the table int db.create the table */
 | |
|         const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
 | |
|         return db_create_database(sql);
 | |
|     }
 | |
| }
 | |
| PRIV_SHELL_CMD_FUNCTION(create_student_tbl, create sqlite db, PRIV_SHELL_CMD_FUNC_ATTR);
 |