数据库操作(810,811)指令,数据库读写实现
This commit is contained in:
1 parent
1096dbb42f
commit
64d820b24c
8 files changed
+640
-350
No files matched your search
+372
-243
@@ -16,274 +16,403 @@
|
||||
#include <dbhelper.h>
|
||||
#define DB_NAME "/SC828.db"
|
||||
int db_HelperInit;
|
||||
rt_mq_t db_mq = RT_NULL; //
|
||||
sqlite3 **db;
|
||||
|
||||
// 消息队列对象与缓冲区(静态分配)
|
||||
//static struct rt_mq db_mq;
|
||||
//static char mq_pool[DB_QUEUE_SIZE * sizeof(struct db_command)];
|
||||
|
||||
// 全局数据库连接与状态
|
||||
static sqlite3 *g_db = RT_NULL;
|
||||
static rt_bool_t db_enabled = RT_FALSE; // 是否允许数据库操作
|
||||
static rt_mutex_t state_mutex = RT_NULL; // 状态访问锁
|
||||
|
||||
// 函数前向声明
|
||||
static void return_timeout(struct db_command *cmd);
|
||||
static void return_disabled(struct db_command *cmd);
|
||||
static void handle_db_command(struct db_command *cmd);
|
||||
static int callback(void *result_str, int argc, char **argv, char **azColName);
|
||||
static const char *sql_upgrade_workorder_steps =
|
||||
"CREATE TABLE WorkorderSteps ("
|
||||
"WorkOrder VARCHAR,"
|
||||
"DYELOT VARCHAR,"
|
||||
"ProgramID VARCHAR,"
|
||||
"Program VARCHAR,"
|
||||
"ReDye INT DEFAULT (0),"
|
||||
"Mode VARCHAR,"
|
||||
"Step INT,"
|
||||
"StepID VARCHAR,"
|
||||
"StepName VARCHAR,"
|
||||
"ParameterName VARCHAR,"
|
||||
"Parameter1 DOUBLE,"
|
||||
"Parameter2 DOUBLE,"
|
||||
"Parameter3 DOUBLE,"
|
||||
"Parameter4 DOUBLE,"
|
||||
"Parameter5 DOUBLE,"
|
||||
"Parameter6 INT,"
|
||||
"Parameter7 INT,"
|
||||
"Parameter8 INT,"
|
||||
"Parameter9 INT,"
|
||||
"Parameter10 INT,"
|
||||
"Remark VARCHAR,"
|
||||
"StepTime INT,"
|
||||
"StepID_S1 VARCHAR,"
|
||||
"StepID_S2 VARCHAR,"
|
||||
"StepID_S3 VARCHAR,"
|
||||
"StepName_S1 VARCHAR,"
|
||||
"StepName_S2 VARCHAR,"
|
||||
"StepName_S3 VARCHAR,"
|
||||
"Parameter1_S1 DOUBLE,"
|
||||
"Parameter1_S2 DOUBLE,"
|
||||
"Parameter1_S3 DOUBLE,"
|
||||
"Parameter2_S1 DOUBLE,"
|
||||
"Parameter2_S2 DOUBLE,"
|
||||
"Parameter2_S3 DOUBLE,"
|
||||
"Parameter3_S1 DOUBLE,"
|
||||
"Parameter3_S2 DOUBLE,"
|
||||
"Parameter3_S3 DOUBLE,"
|
||||
"Parameter4_S1 DOUBLE,"
|
||||
"Parameter4_S2 DOUBLE,"
|
||||
"Parameter4_S3 DOUBLE,"
|
||||
"Parameter5_S1 DOUBLE,"
|
||||
"Parameter5_S2 DOUBLE,"
|
||||
"Parameter5_S3 DOUBLE"
|
||||
"); ";
|
||||
"CREATE TABLE WorkorderSteps (WorkOrder VARCHAR,DYELOT VARCHAR,ProgramID VARCHAR,Program VARCHAR,ReDye INT DEFAULT (0),"
|
||||
"Mode VARCHAR,Step INT,StepID VARCHAR,StepName VARCHAR,ParameterName VARCHAR,P1 DOUBLE,P2 DOUBLE,P3 DOUBLE,"
|
||||
"P4 DOUBLE,P5 DOUBLE,P6 INT,P7 INT,P8 INT,P9 INT,P10 INT,Remark VARCHAR,StepTime INT,StepID_S1 VARCHAR,"
|
||||
"StepID_S2 VARCHAR,StepID_S3 VARCHAR,StepName_S1 VARCHAR,StepName_S2 VARCHAR,StepName_S3 VARCHAR,P1_S1 DOUBLE,"
|
||||
"P1_S2 DOUBLE,P1_S3 DOUBLE,P2_S1 DOUBLE,P2_S2 DOUBLE,P2_S3 DOUBLE,P3_S1 DOUBLE,P3_S2 DOUBLE,P3_S3 DOUBLE,"
|
||||
"P4_S1 DOUBLE,P4_S2 DOUBLE,P4_S3 DOUBLE,P5_S1 DOUBLE,P5_S2 DOUBLE,P5_S3 DOUBLE); ";
|
||||
|
||||
static const char *sql_upgrade_workorder_set =
|
||||
"CREATE TABLE WorkOrderSet ("
|
||||
"WorkOrder VARCHAR,"
|
||||
"ReDye INT DEFAULT (0),"
|
||||
"PumpSpeed INT,"
|
||||
"Blower INT,"
|
||||
"Swing INT,"
|
||||
"ClothWheel INT,"
|
||||
"Nozzle INT"
|
||||
"); ";
|
||||
"CREATE TABLE WorkOrderSet (WorkOrder VARCHAR,ReDye INT DEFAULT (0),PumpSpeed INT,Blower INT,Swing INT,ClothWheel INT,Nozzle INT); ";
|
||||
|
||||
static const char *sql_upgrade_workorder =
|
||||
"CREATE TABLE WorkOrder ("
|
||||
"WorkOrder VARCHAR,"
|
||||
"Dyelot VARCHAR,"
|
||||
"ReDye INT DEFAULT (0),"
|
||||
"ProgramName VARCHAR,"
|
||||
"StartTime DATETIME,"
|
||||
"EndTime DATETIME,"
|
||||
"Time TEXT,"
|
||||
"lock INT,"
|
||||
"State INT,"
|
||||
"ProgramID VARCHAR,"
|
||||
"Machines VARCHAR,"
|
||||
"color VARCHAR,"
|
||||
"ColorNumber VARCHAR,"
|
||||
"Client VARCHAR,"
|
||||
"ClothWeight VARCHAR,"
|
||||
"ClothSpecies VARCHAR,"
|
||||
"BathRatio VARCHAR,"
|
||||
"Total VARCHAR,"
|
||||
"USER VARCHAR,"
|
||||
"ColorName VARCHAR,"
|
||||
"Remark TEXT"
|
||||
"); ";
|
||||
"CREATE TABLE WorkOrder (WorkOrder VARCHAR,Dyelot VARCHAR,ReDyeINT DEFAULT (0),ProgramNameVARCHAR,StartTime DATETIME,EndTime DATETIME,"
|
||||
"Time TEXT,lock INT,State INT,ProgramID VARCHAR,Machines VARCHAR,color VARCHAR,ColorNumber VARCHAR,Client VARCHAR,ClothWeight VARCHAR,"
|
||||
"ClothSpecies VARCHAR,BathRatio VARCHAR,Total VARCHAR,USER VARCHAR,ColorName VARCHAR,Remark TEXT); ";
|
||||
|
||||
static const char *sql_upgrade_run_table =
|
||||
// "PRAGMA foreign_keys = OFF; "
|
||||
// "BEGIN TRANSACTION; "
|
||||
// "CREATE TABLE sqlitestudio_temp_table AS SELECT * FROM RUN; "
|
||||
// "DROP TABLE RUN; "
|
||||
"CREATE TABLE RUN ("
|
||||
"WorkOrder VARCHAR,"
|
||||
"DYELOT VARCHAR,"
|
||||
"ReDye INT DEFAULT (0),"
|
||||
"RUN INT,"
|
||||
"Mode VARCHAR,"
|
||||
"ProgramID VARCHAR,"
|
||||
"Program VARCHAR,"
|
||||
"StepID VARCHAR,"
|
||||
"Step INT,"
|
||||
"StepName VARCHAR,"
|
||||
"ParameterName VARCHAR,"
|
||||
"Parameter1 DOUBLE,"
|
||||
"Parameter2 DOUBLE,"
|
||||
"Parameter3 DOUBLE,"
|
||||
"Parameter4 DOUBLE,"
|
||||
"Parameter5 DOUBLE,"
|
||||
"Parameter6 INT,"
|
||||
"Parameter7 INT,"
|
||||
"Parameter8 INT,"
|
||||
"Parameter9 INT,"
|
||||
"Parameter10 INT,"
|
||||
"Remark VARCHAR,"
|
||||
"StepTime INT,"
|
||||
"StepID_S1 VARCHAR,"
|
||||
"StepID_S2 VARCHAR,"
|
||||
"StepID_S3 VARCHAR,"
|
||||
"StepName_S1 VARCHAR,"
|
||||
"StepName_S2 VARCHAR,"
|
||||
"StepName_S3 VARCHAR,"
|
||||
"Parameter1_S1 DOUBLE,"
|
||||
"Parameter1_S2 DOUBLE,"
|
||||
"Parameter1_S3 DOUBLE,"
|
||||
"Parameter2_S1 DOUBLE,"
|
||||
"Parameter2_S2 DOUBLE,"
|
||||
"Parameter2_S3 DOUBLE,"
|
||||
"Parameter3_S1 DOUBLE,"
|
||||
"Parameter3_S2 DOUBLE,"
|
||||
"Parameter3_S3 DOUBLE,"
|
||||
"Parameter4_S1 DOUBLE,"
|
||||
"Parameter4_S2 DOUBLE,"
|
||||
"Parameter4_S3 DOUBLE,"
|
||||
"Parameter5_S1 DOUBLE,"
|
||||
"Parameter5_S2 DOUBLE,"
|
||||
"Parameter5_S3 DOUBLE"
|
||||
");";
|
||||
"CREATE TABLE RUN (WorkOrder VARCHAR,DYELOT VARCHAR,ProgramID VARCHAR,Program VARCHAR,ReDye INT DEFAULT (0),"
|
||||
"Mode VARCHAR,Step INT,StepID VARCHAR,StepName VARCHAR,ParameterName VARCHAR,P1 DOUBLE,P2 DOUBLE,P3 DOUBLE,"
|
||||
"P4 DOUBLE,P5 DOUBLE,P6 INT,P7 INT,P8 INT,P9 INT,P10 INT,Remark VARCHAR,StepTime INT,StepID_S1 VARCHAR,"
|
||||
"StepID_S2 VARCHAR,StepID_S3 VARCHAR,StepName_S1 VARCHAR,StepName_S2 VARCHAR,StepName_S3 VARCHAR,P1_S1 DOUBLE,"
|
||||
"P1_S2 DOUBLE,P1_S3 DOUBLE,P2_S1 DOUBLE,P2_S2 DOUBLE,P2_S3 DOUBLE,P3_S1 DOUBLE,P3_S2 DOUBLE,P3_S3 DOUBLE,"
|
||||
"P4_S1 DOUBLE,P4_S2 DOUBLE,P4_S3 DOUBLE,P5_S1 DOUBLE,P5_S2 DOUBLE,P5_S3 DOUBLE); ";
|
||||
|
||||
static const char *sql_upgrade_dyelot_table =
|
||||
"CREATE TABLE Dyelot ("
|
||||
"WorkOrder VARCHAR,"
|
||||
"Dyelot VARCHAR,"
|
||||
"ReDye INT,"
|
||||
"Machine VARCHAR,"
|
||||
"Step INT,"
|
||||
"Tank INT,"
|
||||
"State INT,"
|
||||
"ProductCode VARCHAR,"
|
||||
"ProductName VARCHAR,"
|
||||
"ProductType INT,"
|
||||
"Grams FLOAT,"
|
||||
"Amount FLOAT,"
|
||||
"CALL_TIME VARCHAR,"
|
||||
"DispenseEndTime VARCHAR,"
|
||||
"Type INT"
|
||||
"); ";
|
||||
"CREATE TABLE Dyelot (WorkOrder VARCHAR,Dyelot VARCHAR,ReDye INT,Machine VARCHAR,Step INT,Tank INT,State INT,ProductCode VARCHAR,"
|
||||
"ProductName VARCHAR,ProductType INT,Grams FLOAT,Amount FLOAT,CALL_TIME VARCHAR,DispenseEndTime VARCHAR,Type INT); ";
|
||||
|
||||
static const char *sql_upgrade_iolog_table =
|
||||
// "CREATE TABLE sqlitestudio_temp_table AS SELECT * FROM IOLog; "
|
||||
// "DROP TABLE IOLog; "
|
||||
"CREATE TABLE IOLog ("
|
||||
"ID varchar(32),"
|
||||
"IOName varchar(32),"
|
||||
"type varchar(32),"
|
||||
"Value DOUBLE DEFAULT (0),"
|
||||
"DIO BOOLEAN,"
|
||||
"AIO INTEGER DEFAULT (0),"
|
||||
"PLC varchar(32)"
|
||||
"); ";
|
||||
"CREATE TABLE IOLog (ID varchar,IOName varchar,type varchar,Value DOUBLE DEFAULT (0),DIO BOOLEAN,AIO INTEGER DEFAULT (0),PLC varchar); ";
|
||||
|
||||
static const char *sql_upgrade_chart_table =
|
||||
"CREATE TABLE Chart ("
|
||||
"WorkOrder varchar(32),"
|
||||
"DYELOT varchar(32),"
|
||||
"ReDye INTEGER ,"
|
||||
"Name varchar(32),"
|
||||
"Time varchar(32),"
|
||||
"MTT DOUBLE DEFAULT (0),"
|
||||
"MTL DOUBLE DEFAULT (0),"
|
||||
"STTA DOUBLE DEFAULT (0),"
|
||||
"STLA DOUBLE DEFAULT (0),"
|
||||
"STTB DOUBLE DEFAULT (0),"
|
||||
"STLB DOUBLE DEFAULT (0),"
|
||||
"STTC DOUBLE DEFAULT (0),"
|
||||
"STLC DOUBLE DEFAULT (0),"
|
||||
"MTH DOUBLE DEFAULT (0),"
|
||||
"MST DOUBLE DEFAULT (0),"
|
||||
"MSL DOUBLE DEFAULT (0),"
|
||||
"MUT DOUBLE DEFAULT (0)"
|
||||
"); ";
|
||||
"CREATE TABLE Chart (WorkOrder varchar,DYELOT varchar,ReDye INTEGER,Name varchar,Time varchar,MTT DOUBLE DEFAULT (0),MTL DOUBLE DEFAULT (0),"
|
||||
"STTA DOUBLE DEFAULT (0),STLA DOUBLE DEFAULT (0),STTB DOUBLE DEFAULT (0),STLB DOUBLE DEFAULT (0),STTC DOUBLE DEFAULT (0),"
|
||||
"STLC DOUBLE DEFAULT (0),MTH DOUBLE DEFAULT (0),MST DOUBLE DEFAULT (0),MSL DOUBLE DEFAULT (0),MUT DOUBLE DEFAULT (0)); ";
|
||||
|
||||
void db_sqlite(void *parameter)
|
||||
// ------------------------
|
||||
// 内部工具函数
|
||||
// ------------------------
|
||||
|
||||
/**
|
||||
* @brief 返回超时错误(排队时间过长)
|
||||
*/
|
||||
static void return_timeout(struct db_command *cmd) {
|
||||
cmd->result_code = -RT_ETIMEOUT;
|
||||
rt_strncpy(cmd->result, "Cmd timeout: waited too long in queue", MAX_RESULT_LEN - 1);
|
||||
if (cmd->reply_sem) {
|
||||
rt_sem_release(cmd->reply_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 返回“数据库已禁用”错误
|
||||
*/
|
||||
static void return_disabled(struct db_command *cmd) {
|
||||
cmd->result_code = -RT_ENODEV;
|
||||
rt_strncpy(cmd->result, "Error: Database is disabled", MAX_RESULT_LEN - 1);
|
||||
if (cmd->reply_sem) {
|
||||
rt_sem_release(cmd->reply_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SELECT 查询回调函数
|
||||
*/
|
||||
static int callback(void *result_str, int argc, char **argv, char **azColName) {
|
||||
char *str = (char *)result_str;
|
||||
int len = rt_strlen(str);
|
||||
for (int i = 0; i < argc; i++) {
|
||||
rt_snprintf(str + len, MAX_RESULT_LEN - len, "%s=%s|",
|
||||
azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
len = rt_strlen(str);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 执行具体 SQL 操作
|
||||
*/
|
||||
static void handle_db_command(struct db_command *cmd) {
|
||||
char *err_msg = 0;
|
||||
int rc;
|
||||
|
||||
switch (cmd->type) {
|
||||
case DB_CMD_INSERT:
|
||||
case DB_CMD_DELETE:
|
||||
case DB_CMD_UPDATE:
|
||||
case DB_CMD_EXEC:
|
||||
rc = sqlite3_exec(g_db, cmd->sql, 0, 0, &err_msg);
|
||||
if (rc != SQLITE_OK) {
|
||||
cmd->result_code = rc;
|
||||
rt_strncpy(cmd->result, err_msg, MAX_RESULT_LEN - 1);
|
||||
sqlite3_free(err_msg);
|
||||
} else {
|
||||
cmd->result_code = 0;
|
||||
rt_strncpy(cmd->result, "OK", MAX_RESULT_LEN - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case DB_CMD_SELECT:
|
||||
cmd->result[0] = '\0';
|
||||
rc = sqlite3_exec(g_db, cmd->sql, callback, cmd->result, &err_msg);
|
||||
if (rc != SQLITE_OK) {
|
||||
cmd->result_code = rc;
|
||||
rt_strncpy(cmd->result, err_msg, MAX_RESULT_LEN - 1);
|
||||
sqlite3_free(err_msg);
|
||||
} else {
|
||||
cmd->result_code = 0;
|
||||
if (cmd->result[0] == '\0')
|
||||
rt_strncpy(cmd->result, "No data", MAX_RESULT_LEN - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case DB_CMD_EXIT:
|
||||
rt_strncpy(cmd->result, "Exit", MAX_RESULT_LEN - 1);
|
||||
cmd->result_code = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
cmd->result_code = -1;
|
||||
rt_strncpy(cmd->result, "Invalid command", MAX_RESULT_LEN - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// 外部接口实现
|
||||
// ------------------------
|
||||
|
||||
/**
|
||||
* @brief 外部调用:立即关闭数据库并禁用所有操作
|
||||
*/
|
||||
void close_db_immediately(void) {
|
||||
if (!state_mutex) return;
|
||||
|
||||
rt_mutex_take(state_mutex, RT_WAITING_FOREVER);
|
||||
{
|
||||
if (g_db) {
|
||||
sqlite3_close(g_db);
|
||||
g_db = RT_NULL;
|
||||
}
|
||||
db_enabled = RT_FALSE;
|
||||
}
|
||||
rt_mutex_release(state_mutex);
|
||||
rt_kprintf("Database disabled.\n");
|
||||
}
|
||||
|
||||
void db_sqlite_init_full(void)
|
||||
{
|
||||
if (access(DB_NAME, F_OK) == 0)
|
||||
{
|
||||
rt_kprintf("DB open\n");
|
||||
if (db_connect(DB_NAME) == RT_EOK){
|
||||
if(db_table_is_exist("WorkorderSteps")<=0){
|
||||
if(db_create_database(sql_upgrade_workorder_steps)==0)
|
||||
{rt_kprintf("WorkorderSteps Created successfully \n");}else{rt_kprintf("WorkorderSteps Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("WorkOrderSet")<=0){
|
||||
if(db_create_database(sql_upgrade_workorder_set)==0)
|
||||
{rt_kprintf("WorkOrderSet Created successfully \n");}else{rt_kprintf("WorkOrderSet Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("WorkOrder")<=0){
|
||||
if(db_create_database(sql_upgrade_workorder)==0)
|
||||
{rt_kprintf("WorkOrder Created successfully \n");}else{rt_kprintf("WorkOrder Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("RUN")<=0){
|
||||
if(db_create_database(sql_upgrade_run_table)==0)
|
||||
{rt_kprintf("RUN Created successfully \n");}else{rt_kprintf("RUN Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("Dyelot")<=0){
|
||||
if(db_create_database(sql_upgrade_dyelot_table)==0)
|
||||
{rt_kprintf("Dyelot Created successfully \n");}else{rt_kprintf("Dyelot Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("IOLog")<=0){
|
||||
if(db_create_database(sql_upgrade_iolog_table)==0)
|
||||
{rt_kprintf("IOLog Created successfully \n");}else{rt_kprintf("IOLog Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("Chart")<=0){
|
||||
if(db_create_database(sql_upgrade_chart_table)==0)
|
||||
{rt_kprintf("Chart Created successfully \n");}else{rt_kprintf("Chart Creation failed \n");}
|
||||
}
|
||||
{
|
||||
rt_kprintf("DB open\n");
|
||||
if (db_connect(DB_NAME) == RT_EOK){
|
||||
if(db_table_is_exist("WorkorderSteps")<=0){
|
||||
if(db_create_database(sql_upgrade_workorder_steps)==0)
|
||||
{rt_kprintf("WorkorderSteps Created successfully \n");}else{rt_kprintf("WorkorderSteps Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("WorkOrderSet")<=0){
|
||||
if(db_create_database(sql_upgrade_workorder_set)==0)
|
||||
{rt_kprintf("WorkOrderSet Created successfully \n");}else{rt_kprintf("WorkOrderSet Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("WorkOrder")<=0){
|
||||
if(db_create_database(sql_upgrade_workorder)==0)
|
||||
{rt_kprintf("WorkOrder Created successfully \n");}else{rt_kprintf("WorkOrder Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("RUN")<=0){
|
||||
if(db_create_database(sql_upgrade_run_table)==0)
|
||||
{rt_kprintf("RUN Created successfully \n");}else{rt_kprintf("RUN Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("Dyelot")<=0){
|
||||
if(db_create_database(sql_upgrade_dyelot_table)==0)
|
||||
{rt_kprintf("Dyelot Created successfully \n");}else{rt_kprintf("Dyelot Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("IOLog")<=0){
|
||||
if(db_create_database(sql_upgrade_iolog_table)==0)
|
||||
{rt_kprintf("IOLog Created successfully \n");}else{rt_kprintf("IOLog Creation failed \n");}
|
||||
}
|
||||
if(db_table_is_exist("Chart")<=0){
|
||||
if(db_create_database(sql_upgrade_chart_table)==0)
|
||||
{rt_kprintf("Chart Created successfully \n");}else{rt_kprintf("Chart Creation failed \n");}
|
||||
}
|
||||
}else{
|
||||
rt_kprintf("DB ok\n");
|
||||
db_connect(DB_NAME);
|
||||
}
|
||||
|
||||
}else{
|
||||
rt_kprintf("DB open failed \n");
|
||||
sqlite3_open(DB_NAME, db);
|
||||
//创建表
|
||||
db_create_database(sql_upgrade_workorder_steps);
|
||||
db_create_database(sql_upgrade_workorder_set);
|
||||
db_create_database(sql_upgrade_workorder);
|
||||
db_create_database(sql_upgrade_run_table);
|
||||
db_create_database(sql_upgrade_dyelot_table);
|
||||
db_create_database(sql_upgrade_iolog_table);
|
||||
db_create_database(sql_upgrade_chart_table);
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
rt_kprintf("DB open failed \n");
|
||||
sqlite3_open(DB_NAME, db);
|
||||
//创建表
|
||||
db_create_database(sql_upgrade_workorder_steps);
|
||||
db_create_database(sql_upgrade_workorder_set);
|
||||
db_create_database(sql_upgrade_workorder);
|
||||
db_create_database(sql_upgrade_run_table);
|
||||
db_create_database(sql_upgrade_dyelot_table);
|
||||
db_create_database(sql_upgrade_iolog_table);
|
||||
db_create_database(sql_upgrade_chart_table);
|
||||
/**
|
||||
* @brief 数据库处理线程入口函数
|
||||
*/
|
||||
static void db_sqlite(void *parameter) {
|
||||
struct db_command cmd;
|
||||
rt_tick_t max_wait_ticks = rt_tick_from_millisecond(DB_MAX_WAITING_MS);
|
||||
|
||||
// 检查并初始化数据库文件
|
||||
db_sqlite_init_full();
|
||||
|
||||
// ✅ 使用 rt_mq_create 动态创建消息队列
|
||||
db_mq = rt_mq_create("db_mq", sizeof(struct db_command), DB_QUEUE_SIZE, RT_IPC_FLAG_FIFO);
|
||||
if (db_mq == RT_NULL) {
|
||||
rt_kprintf("Failed to create message queue 'db_mq'!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建状态锁
|
||||
state_mutex = rt_mutex_create("db_lock", RT_IPC_FLAG_FIFO);
|
||||
if (!state_mutex) {
|
||||
rt_kprintf("Failed to create db_lock mutex!\n");
|
||||
rt_mq_delete(db_mq); // 创建失败要清理
|
||||
db_mq = RT_NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// db_HelperInit = db_helper_init();
|
||||
// if(db_HelperInit =RT_EOK){
|
||||
// rt_kprintf("HelperInit database\n");
|
||||
// }else {
|
||||
// sqlite3_open(DB_NAME, db);
|
||||
// db_ = db_create_database("CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);");
|
||||
// if(db_=0){rt_kprintf("database ok\n");}else{rt_kprintf("database no\n");}
|
||||
// }
|
||||
/* int fd = 0;
|
||||
const char *dbname = db_get_name();
|
||||
fd = open(dbname, O_RDONLY);
|
||||
if (fd > 0)
|
||||
rt_kprintf("%s exist\r\n", dbname);
|
||||
else
|
||||
rt_kprintf("%s not exist\r\n");
|
||||
const char *sql = "CREATE TABLE IF NOT EXISTS student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
|
||||
rt_kprintf("sql cmd: %s\r\n\r\n", sql);
|
||||
int ret = db_create_database(sql);
|
||||
rt_kprintf("sql ret: %d\r\n", ret);*/
|
||||
// 默认启用数据库
|
||||
db_enabled = RT_TRUE;
|
||||
|
||||
// sqlite3_os_init();
|
||||
/* int rc = db_connect("/rt.db");
|
||||
if (rc <0) {
|
||||
const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
|
||||
int db_create_database(sql);
|
||||
}*/
|
||||
rt_kprintf("Database handler started. Path: %s\n", DB_NAME);
|
||||
|
||||
while (1) {
|
||||
// 接收命令
|
||||
if (rt_mq_recv(db_mq, &cmd, sizeof(struct db_command), RT_WAITING_FOREVER) != RT_EOK)
|
||||
continue;
|
||||
|
||||
// 1. 检查排队超时
|
||||
rt_tick_t now = rt_tick_get();
|
||||
if ((now - cmd.send_tick) > max_wait_ticks) {
|
||||
int wait_ms = (now - cmd.send_tick) * 1000 / RT_TICK_PER_SECOND;
|
||||
rt_kprintf("DROP cmd[type=%d]: waited %dms > limit(%dms)\n", cmd.type, wait_ms, DB_MAX_WAITING_MS);
|
||||
return_timeout(&cmd);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2. 获取当前启用状态
|
||||
rt_bool_t current_enabled;
|
||||
rt_mutex_take(state_mutex, RT_WAITING_FOREVER);
|
||||
current_enabled = db_enabled;
|
||||
rt_mutex_release(state_mutex);
|
||||
|
||||
// 3. 若已禁用 → 返回错误
|
||||
if (!current_enabled) {
|
||||
rt_kprintf("Rejected cmd[type=%d]: database is disabled\n", cmd.type);
|
||||
return_disabled(&cmd);
|
||||
if (cmd.type == DB_CMD_EXIT) break;
|
||||
continue;
|
||||
}
|
||||
// 4. 打开数据库(如果未打开)
|
||||
rt_mutex_take(state_mutex, RT_WAITING_FOREVER);
|
||||
{
|
||||
if (!g_db && current_enabled) {
|
||||
int rc = sqlite3_open(DB_NAME, &g_db);
|
||||
if (rc != SQLITE_OK) {
|
||||
rt_kprintf("Failed to open DB at %s: %s\n", DB_NAME, sqlite3_errmsg(g_db));
|
||||
sqlite3_close(g_db);
|
||||
g_db = RT_NULL;
|
||||
rt_mutex_release(state_mutex);
|
||||
return_disabled(&cmd);
|
||||
continue;
|
||||
} else {
|
||||
rt_kprintf("Opened database: %s\n", DB_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
rt_mutex_release(state_mutex);
|
||||
|
||||
// 5. 执行命令
|
||||
handle_db_command(&cmd);
|
||||
|
||||
// 6. 返回结果
|
||||
if (cmd.reply_sem) {
|
||||
rt_sem_release(cmd.reply_sem);
|
||||
}
|
||||
|
||||
// 7. 退出命令
|
||||
if (cmd.type == DB_CMD_EXIT) break;
|
||||
}
|
||||
|
||||
// ✅ 清理资源
|
||||
if (g_db) {
|
||||
sqlite3_close(g_db);
|
||||
g_db = RT_NULL;
|
||||
}
|
||||
db_enabled = RT_FALSE;
|
||||
|
||||
if (state_mutex) {
|
||||
rt_mutex_delete(state_mutex);
|
||||
state_mutex = RT_NULL;
|
||||
}
|
||||
|
||||
// ✅ 删除动态消息队列
|
||||
if (db_mq) {
|
||||
rt_mq_delete(db_mq);
|
||||
db_mq = RT_NULL;
|
||||
}
|
||||
|
||||
rt_kprintf("Database handler exited.\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 向数据库发送命令并等待响应
|
||||
*
|
||||
* @param type 命令类型(INSERT/SELECT等)
|
||||
* @param sql SQL 语句字符串
|
||||
* @param timeout_ms 超时时间(毫秒),0 表示不等待
|
||||
* @return RT_EOK 成功,RT_ETIMEOUT 超时,RT_ERROR 失败
|
||||
*/
|
||||
rt_err_t db_send_command(enum db_cmd_type type, const char* sql, rt_int32_t timeout_ms)
|
||||
{
|
||||
struct db_command cmd;
|
||||
rt_sem_t sem = RT_NULL;
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
// 1. 创建临时信号量用于同步
|
||||
sem = rt_sem_create("db_rep", 0, RT_IPC_FLAG_FIFO);
|
||||
if (sem == RT_NULL)
|
||||
{
|
||||
rt_kprintf("Failed to create reply semaphore!\n");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
// 2. 构造命令
|
||||
rt_memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.type = type;
|
||||
rt_strncpy(cmd.sql, sql, MAX_SQL_LEN - 1);
|
||||
cmd.reply_sem = sem;
|
||||
cmd.send_tick = rt_tick_get();
|
||||
|
||||
// 3. 发送命令到消息队列
|
||||
if (rt_mq_send(db_mq, &cmd, sizeof(cmd)) != RT_EOK)
|
||||
{
|
||||
rt_kprintf("Failed to send command to db_mq!\n");
|
||||
rt_sem_delete(sem);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
// 4. 等待数据库线程处理完成(超时保护)
|
||||
if (timeout_ms > 0)
|
||||
{
|
||||
rt_int32_t tick = rt_tick_from_millisecond(timeout_ms);
|
||||
result = rt_sem_take(sem, tick);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = rt_sem_take(sem, RT_WAITING_FOREVER); // 永久等待(慎用)
|
||||
}
|
||||
|
||||
// 5. 检查结果
|
||||
if (result == RT_EOK)
|
||||
{
|
||||
rt_kprintf("SQL executed: code=%d\n", cmd.result_code);
|
||||
if (type == DB_CMD_SELECT || strlen(cmd.result) > 0)
|
||||
{
|
||||
rt_kprintf("Result: %s\n", cmd.result);
|
||||
}
|
||||
}
|
||||
else if (result == -RT_ETIMEOUT)
|
||||
{
|
||||
rt_kprintf("Database response timeout!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("Wait failed: %d\n", result);
|
||||
}
|
||||
|
||||
// 6. 删除信号量
|
||||
rt_sem_delete(sem);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 线程 */
|
||||
@@ -291,7 +420,7 @@ void thread_DB_SQLite(void)
|
||||
{
|
||||
/* 初始化线程 1,名称是 thread1,入口是 thread1_entry*/
|
||||
rt_thread_t tid;
|
||||
tid = rt_thread_create("db_sqlite", db_sqlite, RT_NULL, 1024*64, 3, 15);
|
||||
tid = rt_thread_create("db_sqlite", db_sqlite, RT_NULL, 1024*16, 3, 15);
|
||||
|
||||
if (tid != RT_NULL)
|
||||
{
|
||||
|
||||
@@ -10,6 +10,113 @@
|
||||
#ifndef APPLICATIONS_DB_DB_SQLITE_H_
|
||||
#define APPLICATIONS_DB_SQLITE_SYS_H_
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ========================
|
||||
* 配置参数
|
||||
* ======================== */
|
||||
#ifndef MAX_SQL_LEN
|
||||
#define MAX_SQL_LEN (1024) /**< SQL 语句最大长度 */
|
||||
#endif
|
||||
|
||||
#ifndef MAX_RESULT_LEN
|
||||
#define MAX_RESULT_LEN (1024) /**< 结果字符串最大长度 */
|
||||
#endif
|
||||
|
||||
#ifndef DB_MAX_WAITING_MS
|
||||
#define DB_MAX_WAITING_MS (5000) /**< 命令最大等待时间(毫秒),默认 5 秒 */
|
||||
#endif
|
||||
|
||||
#ifndef DB_QUEUE_SIZE
|
||||
#define DB_QUEUE_SIZE (8) /**< 消息队列容量(最多缓存 8 条命令) */
|
||||
#endif
|
||||
|
||||
/* 补充常见错误码(如果 RT-Thread 未定义) */
|
||||
#ifndef RT_ENODEV
|
||||
#define RT_ENODEV (-5)
|
||||
#endif
|
||||
|
||||
#ifndef RT_ETIMEOUT
|
||||
#define RT_ETIMEOUT (-4)
|
||||
#endif
|
||||
|
||||
|
||||
/* ========================
|
||||
* 命令类型枚举
|
||||
* ======================== */
|
||||
enum db_cmd_type
|
||||
{
|
||||
DB_CMD_INSERT, /**< 插入数据 */
|
||||
DB_CMD_DELETE, /**< 删除数据 */
|
||||
DB_CMD_UPDATE, /**< 更新数据 */
|
||||
DB_CMD_SELECT, /**< 查询数据(返回结果字符串) */
|
||||
DB_CMD_EXEC, /**< 执行任意 SQL(无结果集) */
|
||||
DB_CMD_EXIT /**< 退出数据库线程(内部使用) */
|
||||
};
|
||||
|
||||
/* ========================
|
||||
* 数据库命令结构体
|
||||
* ======================== */
|
||||
struct db_command
|
||||
{
|
||||
enum db_cmd_type type; /**< 命令类型 */
|
||||
char sql[MAX_SQL_LEN]; /**< SQL 语句内容 */
|
||||
rt_uint32_t result_code; /**< 返回码(SQLite code 或负的 RT-Error) */
|
||||
char result[MAX_RESULT_LEN]; /**< 结果或错误信息 */
|
||||
rt_sem_t reply_sem; /**< 回应信号量(由调用方创建,用于同步) */
|
||||
rt_tick_t send_tick; /**< 发送时刻的系统 tick,用于超时检测 */
|
||||
};
|
||||
|
||||
/* ========================
|
||||
* 全局变量声明
|
||||
* ======================== */
|
||||
/**
|
||||
* 消息队列句柄:用于向数据库线程发送命令
|
||||
* 必须在 .c 文件中定义为:rt_mq_t db_mq = RT_NULL;
|
||||
*/
|
||||
extern rt_mq_t db_mq;
|
||||
|
||||
|
||||
/* ========================
|
||||
* 函数接口声明
|
||||
* ======================== */
|
||||
|
||||
/**
|
||||
* @brief 启动数据库处理线程
|
||||
*
|
||||
* 创建一个名为 "data_sqlite" 的线程,初始化 SQLite 数据库,
|
||||
* 并开始监听 db_mq 中的 SQL 请求。
|
||||
*
|
||||
* @note 若已运行,多次调用无效。
|
||||
*/
|
||||
void thread_DB_SQLite(void);
|
||||
|
||||
/**
|
||||
* @brief 立即关闭数据库并禁止后续操作
|
||||
*
|
||||
* 关闭当前数据库连接,并设置禁用标志。
|
||||
* 之后所有新请求将立即失败,返回“数据库已禁用”。
|
||||
*
|
||||
* @note 此函数是线程安全的。
|
||||
*/
|
||||
void close_db_immediately(void);
|
||||
|
||||
/**
|
||||
* @brief 向数据库发送命令并等待响应
|
||||
*
|
||||
* @param type 命令类型(INSERT/SELECT等)
|
||||
* @param sql SQL 语句字符串
|
||||
* @param timeout_ms 超时时间(毫秒),0 表示不等待
|
||||
* @return RT_EOK 成功,RT_ETIMEOUT 超时,RT_ERROR 失败
|
||||
*/
|
||||
rt_err_t db_send_command(enum db_cmd_type type, const char* sql, rt_int32_t timeout_ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APPLICATIONS_DB_DB_SQLITE_H_ */
|
||||
Reference in new issue
Block a user