sqlite C接口增删改查,数据库优化
3 FM001.03模块日志信息数据库设计
- 功能描述
数据库存储日志数有限,当数据库写满,数据库从头开始覆盖写。
模块日志在数据库中以表的形式存储,定义数据库表的格式。
数据写入数据库的接口和从数据库查询数据的查询接口定义。
- 设计意图和实现方法说明
- 数据写入策略
- 数据库数据的存储格式和写Flash 的数据格式保持一致,采用二进制方式存储
- 数据库相比于Flash,无法判断当前写到位置(当超过M条),所以设计一个WritePost表存储当前所有表中数据写到位置WriteRowid
- 由于Flash空间大小受限制,数据库最大只能写到M(M值待定)条,超过M条后,数据库从第一条开始用Update方式更新数据 (rowid 不可自增,手动填入)
- WriteRowid>MaxRowid,数据库未写满,采用写的方式写入,WriteRowid<=MaxRowid,数据库已写满,采用Update方式写入
模块日志数据库最大条数:100000条
- 数据库表设计
创建两个表,一个用于存储数据,一个用于存储当前数据库写的位置。
- 不采用自增,头部删除方案读取数据会很方便:尾部插入需要 vacuum去释放空间,但是VACUUM 命令通过复制主数据库中的内容到一个临时数据库文件,然后清空主数据库,并从副本中重新载入原始的数据库文件会占用双倍的空间,就适用于嵌入式数据库了。
- 插入时,数据库ID自增,当超过最大条数,用新的ID替换最小的ID,保持数据库中最大的ID永远是最新插入的记录。
- 按照ID顺序排序查询,最多查500条,select * from RECTLOG_TAB order by ID limit 0,11
模块信息表:
Rowid:作为主键INTEGER PRIMARY KEY
Data: Recordid+Alarm1+Alarm2+Temp1+Temp3+Temp4+Temp5+Volt+Curr+LimitCurr+
CRC16
数据库表写位置表:
Rowid:作为主键INTEGER PRIMARY KEY
Data:Recordid +WriteIndex+CRC16
- 数据库操作接口设计
写/更新接口:
当前写的Rowid>MaxRow,表明数据库还未写满,直接写入。
当前写的Rowid<=MaxRow,表明数据库还已写满,采用Update方式写入。
采用insert命令写入,写入后需要读出进行校验才认为写成功。
Data_Sqlite3WriteOneRecord
{
RecordId+RectInfoBuf+CheckNO
IF(CurrWriteRowid<=MaxRow)
{
/* Update Table Set RectInfo=‘%s’, Where Rowid=%d */
Sqlite3_Update(Dest);
}
Else
{
/* Insert in to Table(Rowid,RectInfo) valuese (‘%ld’,Bindata) */
Sqlite3_Write(Dest);
}
//LOG_ReadOneRecord()
//(Read==Write?) //success
//{
//CurrWriteRowid++;
//ss}
}
查询接口:
Data_Sqlite3ReadOneRecord
{
/* Insert in to Table(Rowid,RectInfo) valuese (‘%ld’,Bindata) */
Sqlite3_Read(Dest);
(ldCheck==alCheck?)
{
}
If(iRequest<iRead)
{
FillEmpty();//取到的长度不足,剩下为空,兼容数据库结构发生改变。
}
}
删除接口:
暂时不做删除,Flash分区也不。
- 数据库性能优化设计
经试验发现,多条Insert操作提交和Prepare IO消耗非常严重
- 显式开启事务 (实测cpu占用减少20%)
所谓”事务“就是指一组SQL命令,这些命令要么一起执行,要么都不被执行。在SQLite中,每调用一次sqlite3_exec()函数,就会隐式地开启了一个事务,如果插入一条数据,就调用该函数一次,事务就会被反复地开启、关闭,会增大IO量。如果在插入数据前显式开启事务,插入后再一起提交,则会大大提高IO效率,进而加数据快插入速度。
开启事务只需在上述代码的前后各加一句开启与提交事务的命令即可:
[cpp] view plaincopy
sqlite3_exec(db,"begin;",0,0,0);
for(int i=0;i<nCount;++i)
{
std::stringstream ssm;
ssm<<"insert into t1 values("<<i<<","<<i*2<<","<<i/2<<","<<i*i<<")";
sqlite3_exec(db,ssm.str().c_str(),0,0,0);
}
sqlite3_exec(db,"commit;",0,0,0);
- 执行准备 (实测cpu占用减少20%)
SQLite执行SQL语句的时候,有两种方式:一种是使用前文提到的函数sqlite3_exec(),该函数直接调用包含SQL语句的字符串;另一种方法就是“执行准备”(类似于存储过程)操作,即先将SQL语句编译好,然后再一步一步(或一行一行)地执行。如果采用前者的话,就算开起了事务,SQLite仍然要对循环中每一句SQL语句进行“词法分析”和“语法分析”,这对于同时插入大量数据的操作来说,简直就是浪费时间。因此,要进一步提高插入效率的话,就应该使用后者
sqlite3_exec(db,"begin;",0,0,0);
sqlite3_stmt *stmt;
const char* sql = "insert into t1 values(?,?,?,?)";
sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,0);
for(int i=0;i<nCount;++i)
{
sqlite3_reset(stmt);
sqlite3_bind_int(stmt,1,i);
sqlite3_bind_int(stmt,1,i*2);
sqlite3_bind_int(stmt,1,i/2);
sqlite3_bind_double(stmt,1,i*i);
}
sqlite3_finalize(stmt);
sqlite3_exec(db,"commit;",0,0,0);
#include "sqlite_data_test.h"
//Write data queue number
#define SQL_MAX_DATA_TYPES 3
/*Global patameters */
static SQLITEDATA_QUEUE g_SQLITEDATA_QUEUE[SQL_MAX_DATA_TYPES]; //queue for write data
SQLITEGLOBAL g_SqliteGlobal;
//为两个全局变量加锁
// sqlite tables
/*Table 为什么不用多个列 ?
1.如果分成多个列,那么 以后每个不同的表,读写接口都会不一样,设计会很复杂
2.对于查询, 即使 填入多个列,如果按列查询,但是我们实际取还是要一条一条的取,循环处理条记录会需要新的接口去处理实现
尽量保持接口能够兼容
按照时间查询可以考虑,以后将时间作为一个item分开 时间作为结构体第一个参数传递: 但是取出来不好取
数据库不可以同时读写,所以每次写读需要加锁,每次读也要加锁(读在外面加锁,不单独对读一条加锁)
可以支持多线程写,但是必须采用等待方式写。 https://blog.csdn.net/u011726005/article/details/77754949
数据库锁机制:https://www.cnblogs.com/lijingcheng/p/4454884.html
数据库可以一个线程写,多个线程读,加读写锁:https://blog.csdn.net/lovecodeless/article/details/24968369
*/
SQLITETABLE g_SqliteTable[]=
{
{WRITERECORD_TABLEID, WRITERECORD_TAB, SQL_TABLE_NUM, "TAB_ID ", "INTEGER PRIMARY KEY", "RECORDID", "INTEGER NOT NULL"},
{RECTLOG_TABLEID, RECT_DATA_LOG, 60, "ID", "INTEGER PRIMARY KEY", "DATA ", "BLOB NOT NULL"},
{RECTLOGTEST_TABLEID, RECT_DATATEST_LOG, RECT_TABLE_MAXSIZE, "ID", "INTEGER PRIMARY KEY", "DATA ", "BLOB NOT NULL"}
//if add one table ,must change the SQL_TABLE_NUM value;
};
/*==========================================================================*
* FUNCTION : Sqlite_CreateDataBase
* PURPOSE : create a database
* CALLS : sqlite3_open :
* CALLED BY: DAT_InitSqlite
* RETURN :
* COMMENTS :
* CREATOR : Lemon DATE: 2018-08-16 16:50
*==========================================================================*/
static BOOL Sqlite_CloseDataBase()
{
sqlite3_close(g_SqliteGlobal.pSqlite3DB);
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR,"Database Closed at %s\n",time(NULL)); //str format
}
static BOOL Sqlite_OpenDataBase()
{
int iSqlRtn;
/*create a data base */
iSqlRtn=sqlite3_open(SQLITE_DATABASE,&g_SqliteGlobal.pSqlite3DB);
if(iSqlRtn!= SQLITE_OK
&& g_SqliteGlobal.pSqlite3DB!=NULL)
{
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR,"Create database Fail:%s \n",sqlite3_errmsg(g_SqliteGlobal.pSqlite3DB));
return FALSE;
}
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR,"Database Opened at %s\n",time(NULL)); //str format
return TRUE;
}
static BOOL Sqlite_CreateTables()
{
char szSqlTableCmd[SQLITE_CMD_LENTH_MAX]={0};
int iSqlRtn=0,i=0;
char *pszErrMsg = 0;
//2 excute create table cmd
//int iTabNum= sizeof(g_SqliteTable)/sizeof(SQLITETABLE);
int iTabNum=ITEM_OF(g_SqliteTable);
for(i=0;i<iTabNum;i++)
{
memset( szSqlTableCmd,0,SQLITE_CMD_LENTH_MAX);
/*Create table if table not exist Rectlog(Id INTEGER PRIMARY KEY, Data BLOB NOT NULL); */
snprintf(szSqlTableCmd,SQLITE_CMD_LENTH_MAX,
"CREATE TABLE IF NOT EXISTS %s (%s %s,%s %s)",
g_SqliteTable[i].szTabName,
g_SqliteTable[i].szId_ColName,
g_SqliteTable[i].szId_Entry,
g_SqliteTable[i].szData_ColName,
g_SqliteTable[i].szDataEntry);
iSqlRtn = sqlite3_exec(g_SqliteGlobal.pSqlite3DB, szSqlTableCmd, NULL, NULL, &pszErrMsg);
if( iSqlRtn != SQLITE_OK )
{
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR, "Create Table Error: %s\n", pszErrMsg); // SQLITE_OK donot need free pszErrMsg, YES
sqlite3_free(pszErrMsg);
return FALSE;
}
}
return TRUE;
}
static int Sqlite3_GetTableIdByName(char *pszTableName)
{
int i=0;
for(i=WRITERECORD_TABLEID+1;i<SQL_TABLE_NUM;i++) //skip writerecord_table
{
if(!strcmp(pszTableName,g_SqliteTable[i].szTabName))
{
return i;
}
}
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR, "Can Not Find Table: %s\n",pszTableName);
return -1;
}
/*设计可优化,如果数据库写满,WriteRecord加一个列,TURE/FALSE表明是Update还是Insert,
就不需要每次统计数据库最大值*/
static long long Sqlite3_GetSelectInt64(char *szSqlSelectCmd)
{
long long llValue=-1;
sqlite3_stmt* pStmt = NULL;//指针,指向sqlite3内部定义的一种"SQL语句 "
if(sqlite3_prepare(g_SqliteGlobal.pSqlite3DB, szSqlSelectCmd, -1, &pStmt, NULL) !=SQLITE_OK ) //select error
{
//AppLogOut(SQLITE_TASK, "Sqlite3 Prepare Error: %s\n");
return SQLITE_ERR;
}
if(sqlite3_step(pStmt) == SQLITE_ROW) //get one record SQLITE_DONE no record
{
llValue=sqlite3_column_int64(pStmt, 0); //
}
else //no record was found ,start from 1
{
//AppLogOut(SQLITE_TASK,APP_LOG_WARNING, "Sqlite3 No Record !\n");
llValue= SQLITE_NONE; //init value
}
sqlite3_finalize(pStmt);
return llValue;
}
/*
*/
static int Sqlite3_GetTabCurrWriteRecordIdByTabId(int iTableId)
{
int iValue;
int iWriteRecordId=0;
char szSqlSelectCmd[SQLITE_CMD_LENTH_MAX]={0};
snprintf(szSqlSelectCmd,SQLITE_CMD_LENTH_MAX,
"SELECT %s FROM %s WHERE %s = %d",
g_SqliteTable[WRITERECORD_TABLEID].szData_ColName,
g_SqliteTable[WRITERECORD_TABLEID].szTabName,
g_SqliteTable[WRITERECORD_TABLEID].szId_ColName,
iTableId);
iValue=Sqlite3_GetSelectInt64(szSqlSelectCmd);
if(iValue<0)
{
Sql_printf("Sqlite3 Get Correct RecordId: %ld\n",iValue);
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR, "Sqlite3 Get Correct RecordId: %ld\n",iValue);
}
else
{
iWriteRecordId=iValue;
}
return iWriteRecordId;
}
static long long Sqlite3_GetTableRowMax(int iTableId) //
{
long long llValue;
long long iRowCount;
char *pszErrMsg = 0;
sqlite3_stmt* pStmt = NULL;//指针,指向sqlite3内部定义的一种"SQL语句 "
char szSqlSelectCmd[SQLITE_CMD_LENTH_MAX]={0};
/*Max ,Count ? Max, 如果写入一条最大的就会导致写不成功,
读取,count 最大的那条误写入,读不到影响也不大
*/
snprintf(szSqlSelectCmd,SQLITE_CMD_LENTH_MAX,
"SELECT MAX(%s) FROM %s",
g_SqliteTable[iTableId].szId_ColName,
g_SqliteTable[iTableId].szTabName);
llValue =Sqlite3_GetSelectInt64(szSqlSelectCmd);
if(llValue<0)
{
Sql_printf("Sqlite3 Get Correct RecordId: %ld\n",llValue);
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR, "Sqlite3 Get Correct RecordId: %ld\n",iValue);
}
else
{
iRowCount=llValue;
}
return iRowCount;
}
static long long Sqlite3_GetTableRowCount(int iTableId) //
{
long long llValue;
long long iRowCount;
char *pszErrMsg = 0;
sqlite3_stmt* pStmt = NULL;//指针,指向sqlite3内部定义的一种"SQL语句 "
char szSqlSelectCmd[SQLITE_CMD_LENTH_MAX]={0};
/*Max ,Count ? Max, 如果写入一条最大的就会导致写不成功,
读取,count 最大的那条误写入,读不到影响也不大
*/
snprintf(szSqlSelectCmd,SQLITE_CMD_LENTH_MAX,
"SELECT COUNT(%s) FROM %s",
g_SqliteTable[iTableId].szId_ColName,
g_SqliteTable[iTableId].szTabName);
llValue =Sqlite3_GetSelectInt64(szSqlSelectCmd);
if(llValue<0)
{
Sql_printf("Sqlite3 Get Correct RecordId: %ld\n",llValue);
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR, "Sqlite3 Get Correct RecordId: %ld\n",iValue);
}
else
{
llValue=llValue;
}
return llValue;
}
/*==========================================================================*
* FUNCTION : Sqlite_CreateDataBase
* PURPOSE :-初始化,如果table写记录不存在,为每个table 在 writeRecord table中初始化当前写位置为0
* CALLS : :
* CALLED BY: Sqlite3_Write
* RETURN :
* COMMENTS :
* CREATOR : Lemon DATE: 2018-08-16 16:50
*==========================================================================*/
static BOOL Sqlite3_WriteRecordTableInit()
{
char szSqlSelectCmd[SQLITE_CMD_LENTH_MAX]={0};
char szSqlInsertCmd[SQLITE_CMD_LENTH_MAX]={0};
BOOL bNeedInitWriteRecord=FALSE;
int i,iSqlRtn=0;
char *pszErrMsg = 0;
sqlite3_stmt* pStmt = NULL;
for(i=1;i<SQL_TABLE_NUM;i++) //skip write record table
{
memset(szSqlSelectCmd,0,SQLITE_CMD_LENTH_MAX);
snprintf(szSqlSelectCmd,SQLITE_CMD_LENTH_MAX,
"SELECT * FROM %s WHERE %s = %d",
g_SqliteTable[WRITERECORD_TABLEID].szTabName,
g_SqliteTable[WRITERECORD_TABLEID].szId_ColName,
i);
if(sqlite3_prepare(g_SqliteGlobal.pSqlite3DB, szSqlSelectCmd, -1, &pStmt, NULL) !=SQLITE_OK ) //select error
{
//AppLogOut(SQLITE_TASK, "Sqlite3 Prepare Error: %s\n");
return FALSE;
}
if(sqlite3_step(pStmt) != SQLITE_ROW) //write record NULL wirte 0
{
bNeedInitWriteRecord=TRUE;
}
if(bNeedInitWriteRecord)
{
memset(szSqlInsertCmd,0,SQLITE_CMD_LENTH_MAX);
snprintf(szSqlInsertCmd,SQLITE_CMD_LENTH_MAX,
"INSERT INTO %s (%s,%s) VALUES ('\%d\','\%d\')" ,
g_SqliteTable[WRITERECORD_TABLEID].szTabName,
g_SqliteTable[WRITERECORD_TABLEID].szId_ColName,
g_SqliteTable[WRITERECORD_TABLEID].szData_ColName,
i,
0);
iSqlRtn = sqlite3_exec(g_SqliteGlobal.pSqlite3DB, szSqlInsertCmd, NULL, NULL, &pszErrMsg);
if( iSqlRtn != SQLITE_OK )
{
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR, "Create Table Error: %s\n", pszErrMsg); // SQLITE_OK donot need free pszErrMsg, YES
sqlite3_free(pszErrMsg);
return FALSE;
}
}
}
return TRUE;
}
static BOOL Sqlite3_TableFull(int iTableId)
{
return g_SqliteGlobal.bTableFull[iTableId];
}
static long long Sqlite3_GetTableMaxLenth(int iTableId)
{
return g_SqliteGlobal.llTableMaxSize[iTableId];
}
static void Sqlite3_SetTableFull(int iTableId)
{
g_SqliteGlobal.bTableFull[iTableId]=TRUE;
}
/*
写成功, Table中 总记录数+1,当前写位置+1
写失败, Table中 总记录数不变,当前写位置+1(防止由于某个ID被占用,导致数据一直写失败,情景1:写数据完成
,但是写当前写位置失败,导致下次写错误使用Update方式,)
*/
static BOOL Sqlite3_WriteControl(int iTableId ,int iCurrWriteRecordId)
{
BOOL bFistTime =TRUE,bFirstWrite=FALSE;
char szSqlInsertCmd[SQLITE_CMD_LENTH_MAX]={0};
int iValue=-1,iSqlRtn;
char *pszErrMsg = 0;
//写成功
//if(bWriteSuccess==SQL_OK)
//{
g_SqliteGlobal.iWriteRecordId[iTableId]++;
if(!Sqlite3_TableFull(iTableId))
{
long long len=Sqlite3_GetTableMaxLenth(iTableId);
//long long count=Sqlite3_GetTableRowCount(iTableId);
//printf("Table Max [%lld] [%lld] \n",len,g_SqliteGlobal.iWriteRecordId[iTableId]);
if(g_SqliteGlobal.iWriteRecordId[iTableId]>=len)
//&& count>=len )
{
printf("----Table Full------\n");
Sqlite3_SetTableFull(iTableId);
}
}
//}
//无论写成功还是失败,都应当跳过当前记录,从下一个开始写
//当写第10000条数据,写记录清0,下次从1开始写
snprintf(szSqlInsertCmd,SQLITE_CMD_LENTH_MAX,
"UPDATE %s SET %s= %d WHERE %s= %d " ,
g_SqliteTable[WRITERECORD_TABLEID].szTabName,
g_SqliteTable[WRITERECORD_TABLEID].szData_ColName,
g_SqliteGlobal.iWriteRecordId[iTableId],
g_SqliteTable[WRITERECORD_TABLEID].szId_ColName,
iTableId);
iSqlRtn = sqlite3_exec(g_SqliteGlobal.pSqlite3DB, szSqlInsertCmd, NULL, NULL, &pszErrMsg);
if( iSqlRtn != SQLITE_OK )
{
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR, "Create Table Error: %s\n", pszErrMsg); // SQLITE_OK donot need free pszErrMsg, YES
sqlite3_free(pszErrMsg);
Sql_printf(" CurrWriteRecodid [%d] of Table Write Error !\n",g_SqliteGlobal.iWriteRecordId[iTableId],g_SqliteTable[iTableId].szTabName);
return FALSE;
}
return TRUE;
}
static int Sqlite3_GetTableCurrWriteRecordId(int iTableId )
{
int iRecordId=g_SqliteGlobal.iWriteRecordId[iTableId];
return iRecordId;
}
static int Sqlite3_BlobBindAndStep(char *pszSqlite3Cmd,void *pWriteBuff, unsigned int iActualRecordSize)
{
sqlite3_stmt* pStmt = NULL;//指针,指向sqlite3内部定义的一种"SQL语句 "
if(sqlite3_prepare(g_SqliteGlobal.pSqlite3DB, pszSqlite3Cmd, -1, &pStmt, NULL) != SQLITE_OK) //-1 all charaters
{
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR, "sqlite3_prepare error\n");
Sql_printf(" sqlite3_prepare error \n");
return SQL_PREP_ERR;
}
if(sqlite3_bind_blob(pStmt, 1, pWriteBuff, iActualRecordSize, NULL)!=SQLITE_OK) //1 绑定参数的编号,这里是1 可循环绑定多个参数
{
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR, "sqlite3_bind_blod error:%s", sqlite3_errmsg(pDB));
Sql_printf(" sqlite3_bind_blob error\n");
sqlite3_finalize(pStmt);
return SQL_BIND_ERR;
}
if(sqlite3_step(pStmt) !=SQLITE_DONE) //execute Fail curr record write fail (ID重复 )
{
//AppLogOut(SQLITE_TASK,APP_LOG_ERROR, "sqlite3_step error:%s", sqlite3_errmsg(pDB));
Sql_printf("sqlite3_stepErr [%s ] \n",sqlite3_errmsg(g_SqliteGlobal.pSqlite3DB));
sqlite3_finalize(pStmt);
return SQL_STEP_ERR;
}
return SQL_OK;
}
static int Sqlite3_TableInsertBlobRecord(int iTableId,void *pWriteBuff, unsigned int iActualRecordSize,int iRecordId )
{
int iResult=0;
char szSqlInsertCmd[SQLITE_CMD_LENTH_MAX]={0};
snprintf(szSqlInsertCmd,SQLITE_CMD_LENTH_MAX,
"INSERT INTO %s (%s,%s) VALUES ('\%d\',?)" ,
g_SqliteTable[iTableId].szTabName,
g_SqliteTable[iTableId].szId_ColName,
g_SqliteTable[iTableId].szData_ColName,
iRecordId);
Sql_printf(" cmd %s \n",szSqlInsertCmd);
Sqlite3_BlobBindAndStep(szSqlInsertCmd,pWriteBuff,iActualRecordSize);
return iResult;
}
static int Sqlite3_TableUpdateBlobRecord(int iTableId,void *pWriteBuff, unsigned int iActualRecordSize,int iNewRecordId,int iOldRecordId )
{
int iResult=0;
char szSqlUpdateCmd[SQLITE_CMD_LENTH_MAX]={0};
snprintf(szSqlUpdateCmd,SQLITE_CMD_LENTH_MAX,
"UPDATE %s SET %s=(?),%s=(%ld) WHERE %s=%d;" ,
g_SqliteTable[iTableId].szTabName,
g_SqliteTable[iTableId].szData_ColName,
g_SqliteTable[iTableId].szId_ColName,
iNewRecordId,
g_SqliteTable[iTableId].szId_ColName,
iOldRecordId);
Sql_printf(" cmd %s \n",szSqlUpdateCmd);
iResult=Sqlite3_BlobBindAndStep(szSqlUpdateCmd,pWriteBuff,iActualRecordSize);
return iResult;
}
static BOOL Sqlite3_Write(char *pszTableName,void *pWriteBuff, unsigned int iActualRecordSize)
{
int iSqlRtn;
int iCount=0;
char *pszErrMsg = 0;
int iResult=0;
int iTableId,iNewRecordId=0,iOldRecordId=0;
BOOL bFirstWrite=0;
static BOOL bNeedReGetWriteRecordId=FALSE;
if(pWriteBuff==NULL
|| pszTableName==NULL
|| iActualRecordSize<0)
{
Sql_printf("Parameter Error \n");
return FALSE;
}
//1.get Tabid by table name
iTableId =Sqlite3_GetTableIdByName(pszTableName);
if(iTableId<0 ) //can not find table id
{
Sql_printf("Can not Find Table \n");
return FALSE;
}
//Sql_printf("Record Write[%ld], Count [%ld] \n",g_SqliteGlobal.iWriteRecordId[iTableId],g_SqliteGlobal.iTableTotalRecords[iTableId]);
//2. insert or update ?
iNewRecordId=Sqlite3_GetTableCurrWriteRecordId(iTableId)+1;
if(Sqlite3_TableFull(iTableId)) //insert
{
printf("------Update------- \n");
iOldRecordId=iNewRecordId-Sqlite3_GetTableMaxLenth(iTableId);
iResult=Sqlite3_TableUpdateBlobRecord(iTableId,pWriteBuff,iActualRecordSize,iNewRecordId,iOldRecordId);
}
else //update
{
printf("------InSert------- \n");
iResult=Sqlite3_TableInsertBlobRecord(iTableId,pWriteBuff,iActualRecordSize,iNewRecordId);
}
/*写成功,当前写为位置+1,数据库中总记录数+1
写失败,当前写位置+1,数据库中总记录数不变,跳过当前节点,,写下一个节点
*/
Sqlite3_WriteControl(iTableId,iNewRecordId); //FALSE record Write Fail
if(iResult== !SQL_OK)
{
Sql_printf("Inert Update Fail\n");
return FALSE;
}
return TRUE;
}
//static BOOL Read500Record(void *pRecordBuff,
// int iRecordSize,
// char *pszTableName,
// BOOL bInOrder,
// long long llOffset)
//{
// int iActualRecordSize;
// void * pRdBuff;
// BOOL bReadResult=FALSE;
//
// iActualRecordSize = iRecordSize ; //+ RECORD_ID_BYTES + CRC16_BYTES
// pRdBuff = (void *)NEW(char, iActualRecordSize*STEP);
//
// bReadResult= Sqlite3_Read500Records(pRdBuff,iRecordSize,pszTableName,bInOrder,llOffset);
//
// //Output record data
// memmove(pRecordBuff, (void *)(unsigned char *)pRdBuff, (unsigned)iRecordSize);
//
// DELETE(pRdBuff);
// return bReadResult; //Succeed
//}
struct tagRectLogMsg
{
int iEquipid;
int iRecordSize;
};
typedef struct tagRectLogMsg RECTLOGMSG;
static int Sqlite_Readcallback(void *data, int argc, char **argv, char **azColName)
{
int i;
int iRecordSize=0,iBufOffset=0;
char szRecordSizeBuf[16]={0},szOffsetBuf[16]={0};
memmove(szRecordSizeBuf,data,16);
memmove(szOffsetBuf,data+16,16);
iRecordSize=atoi(szRecordSizeBuf);
iBufOffset=atoi(szOffsetBuf);
if(argc!=1)
{
printf("Check Slect CMD \n");
}
memmove(data+32+iBufOffset*iRecordSize,argv[0],iRecordSize);
iBufOffset +=1;
memset(szOffsetBuf,0,16);
snprintf(szOffsetBuf,16,"%d",iBufOffset);
memmove(data+16,szOffsetBuf,16);
printf("Record size [%d],oFFset [%d] \n",iRecordSize,iBufOffset);
//memmove(data,(const void *)&argc,sizeof(int));
return 0;
}
static int Sqlite3_Read5000Records(void *pReadBuff, unsigned int iActualRecordSize,char *pszTableName,int iOffset,BOOL bInOrder)
{
#define STEP 500
char szSqlSelectCmd[SQLITE_CMD_LENTH_MAX];
int iSqlRtn;
char *pszErrMsg = 0;
int iCount=0,iTableId;
sqlite3_stmt* pStmt = NULL;//指针,指向sqlite3内部定义的一种"SQL语句 "
if(pReadBuff==NULL
|| pszTableName==NULL
|| iActualRecordSize<0)
{
Sql_printf("Parameter Error \n");
return 0;
}
iTableId =Sqlite3_GetTableIdByName(pszTableName);
if(iTableId<0 ) //can not find table id
{
Sql_printf("Can not Find Table \n");
return 0;
}
int iReadSize=0,i=0;
if(bInOrder)
{
snprintf(szSqlSelectCmd,SQLITE_CMD_LENTH_MAX,
"SELECT %s FROM %s ORDER BY ID LIMIT %d,%d " ,
g_SqliteTable[iTableId].szData_ColName,
g_SqliteTable[iTableId].szTabName,
iOffset,
STEP);
}
else
{
snprintf(szSqlSelectCmd,SQLITE_CMD_LENTH_MAX,
"SELECT %s FROM %s ORDER BY ID DESC LIMIT %d,%d " ,
g_SqliteTable[iTableId].szData_ColName,
g_SqliteTable[iTableId].szTabName,
iOffset,
STEP);
}
//snprintf(szSqlSelectCmd,SQLITE_CMD_LENTH_MAX,"SELECT %s FROM %s WHERE %s=%d" ,g_SqliteTable[iTableId].szData_ColName,g_SqliteTable[iTableId].szTabName,g_SqliteTable[iTableId].szId_ColName,222);
Sql_printf("Read cmd [%s] \n",szSqlSelectCmd);
int rc = sqlite3_exec(g_SqliteGlobal.pSqlite3DB, szSqlSelectCmd, Sqlite_Readcallback, (void*)pReadBuff, &pszErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", pszErrMsg);
sqlite3_free(pszErrMsg);
}
else
{
int Num=0;
char szBuf[16]={0};
memmove(szBuf,pReadBuff+16,16);
Num=atoi(szBuf);
fprintf(stdout, "Operation done successfully [%d]\n",Num);
return Num;
}
//if(sqlite3_prepare(g_SqliteGlobal.pSqlite3DB, szSqlSelectCmd, -1, &pStmt, NULL)!= SQLITE_OK)
//{
// fprintf(stderr, "sqlite3_prepare error\n");
// return 0;
//}
//if(sqlite3_step(pStmt) == SQLITE_ROW) //查询到一条数据 SQLITE_DONE 没有查询到数据
//{
// for(i=0;i<100;i++)
// {
//
// iReadSize = sqlite3_column_bytes(pStmt, i); //left most is 0-> RowId,1 LOG
// Sql_printf("Log size [%d] [%d] \n" ,iReadSize,sqlite3_column_blob(pStmt, i));
// if(iReadSize!=iActualRecordSize)
// {
// //Sql_printf("Read Size Error iReadSize[%d], [%d] [%s]\n",iReadSize,iActualRecordSize,sqlite3_column_blob(pStmt, i));
// //sqlite3_finalize(pStmt);
// //return i;
// }
// //sqlite3_column_blob 返回表头某一项的二进制数据指针
// memmove(pReadBuff+i*iActualRecordSize, sqlite3_column_blob(pStmt, i),iReadSize);
// }
//}
//else
//{
// Sql_printf("NO Record Found\n");
//}
//sqlite3_finalize(pStmt);
return 0 ;
}
static BOOL ReadMoreRecords_Order(void *pRecordBuff,int iRecordSize,int *piRecords,char *pszTableName,BOOL bInOrder) //bDeserialize倒序取出
{
#define INT_SIZE 16
void *pRecord;
int iResult=0;
int iReadRecordId=0;
int iOffset=0,iEffectRecrods=0,iMaxRecordsToRead;
int iTableId =Sqlite3_GetTableIdByName(pszTableName);
iMaxRecordsToRead= *piRecords;
pRecord = (void *)NEW(char, iRecordSize*STEP+32);
char szBuf[16]={0},szOffbuf[16]={0};
snprintf(szBuf,sizeof(szBuf),"%d",iRecordSize);
snprintf(szOffbuf,sizeof(szOffbuf),"%d",0);
//memmove(szBuf,pRecord,16);
先传入 Sqlite3_Read5000Records 的callback 表明 每个recordsize ,然后传出 用来获取最终获取的个数
memmove(pRecord,szBuf,INT_SIZE);
memmove(pRecord+16,szOffbuf,INT_SIZE);
//iRecordSize=atoi(szBuf);
printf("%d %s ---iRecordSize\n",atoi(szBuf),szBuf);
if(pRecord == NULL)
{
return FALSE;
}
iEffectRecrods=0;
for(iOffset=0;iOffset<iMaxRecordsToRead;)
{
//先将 pRecord
memset(pRecord,0,iRecordSize*STEP+32);
memmove(pRecord,szBuf,INT_SIZE);
memmove(pRecord+16,szOffbuf,INT_SIZE);
iResult=Sqlite3_Read5000Records(pRecord,iRecordSize,pszTableName,iOffset,bInOrder);
if(iResult>0)
{
memmove((void*)((char *)pRecordBuff + iEffectRecrods * iRecordSize) ,
pRecord+INT_SIZE*2,
(unsigned)iRecordSize*iResult);
iEffectRecrods+=iResult;
}
iOffset+=STEP;
}
DELETE(pRecord);
*piRecords=iEffectRecrods;
Sql_printf("ReadMoreRecords Max Recrods [%d],iEffectRecrods[%d]\n",iMaxRecordsToRead,iEffectRecrods);
return TRUE;
}
static BOOL Sqlite3_Read(void *pReadBuff, unsigned int iActualRecordSize,char *pszTableName,int iRowid)
{
char szSqlSelectCmd[SQLITE_CMD_LENTH_MAX];
int iSqlRtn;
char *pszErrMsg = 0;
int iCount=0,iTableId;
sqlite3_stmt* pStmt = NULL;//指针,指向sqlite3内部定义的一种"SQL语句 "
if(pReadBuff==NULL
|| pszTableName==NULL
|| iActualRecordSize<0)
{
Sql_printf("Parameter Error \n");
return FALSE;
}
iTableId =Sqlite3_GetTableIdByName(pszTableName);
if(iTableId<0 ) //can not find table id
{
Sql_printf("Can not Find Table \n");
return FALSE;
}
int iReadSize=0;
snprintf(szSqlSelectCmd,SQLITE_CMD_LENTH_MAX,"SELECT %s FROM %s WHERE %s=%d" ,g_SqliteTable[iTableId].szData_ColName,g_SqliteTable[iTableId].szTabName,g_SqliteTable[iTableId].szId_ColName,iRowid);
//Sql_printf("Read cmd [%s] \n",szSqlSelectCmd);
if(sqlite3_prepare(g_SqliteGlobal.pSqlite3DB, szSqlSelectCmd, -1, &pStmt, NULL)!= SQLITE_OK)
{
fprintf(stderr, "sqlite3_prepare error\n");
return ;
}
if(sqlite3_step(pStmt) == SQLITE_ROW) //查询到一条数据 SQLITE_DONE 没有查询到数据
{
iReadSize = sqlite3_column_bytes(pStmt, 0); //left most is 0-> RowId,1 LOG
//Sql_printf("Log size [%d] \n" ,iReadSize);
if(iReadSize!=iActualRecordSize)
{
Sql_printf("Read Size Error iReadSize[%d], [%d]\n",iReadSize,iActualRecordSize);
sqlite3_finalize(pStmt);
return FALSE;
}
//sqlite3_column_blob 返回表头某一项的二进制数据指针
memmove(pReadBuff, sqlite3_column_blob(pStmt, 0),iReadSize);
}
else
{
Sql_printf("NO Record Found\n");
}
sqlite3_finalize(pStmt);
return TRUE ;
}
static BOOL ReadOneRecord(void *pRecordBuff,
int iRecordSize,
char *pszTableName,
int iRecordId)
{
int iActualRecordSize;
void * pRdBuff;
BOOL bReadResult=FALSE;
iActualRecordSize = iRecordSize ; //+ RECORD_ID_BYTES + CRC16_BYTES
pRdBuff = (void *)NEW(char, iActualRecordSize);
bReadResult= Sqlite3_Read(pRdBuff,iRecordSize,pszTableName,iRecordId);
//Output record data
memmove(pRecordBuff, (void *)(unsigned char *)pRdBuff, (unsigned)iRecordSize);
DELETE(pRdBuff);
return bReadResult; //Succeed
}
/*历史告警,历史数据 控制日志是按时间倒序的*/
//static int Sqlite3_ReadControl(int iTableId,int iStartPos,int iOffset)
//{
// int iRecordId=0;
// int iHeadPos=g_SqliteGlobal.iReadRecordId[iTableId];
//
// if(iStartPos>0) //顺序
// {
// //数据库写满
//
// if(g_SqliteGlobal.iReadTotalRecords[iTableId]==g_SqliteTable[iTableId].iMaxRecords)
// {
// iRecordId=iHeadPos+iStartPos+iOffset;
// if(iRecordId>g_SqliteTable[iTableId].iMaxRecords)
// {
// iRecordId=iRecordId-g_SqliteTable[iTableId].iMaxRecords;
// }
//
// }
// else
// {
// iRecordId=0+iStartPos+iOffset; //从数据库头开始
// if(iRecordId>g_SqliteGlobal.iReadRecordId[iTableId])
// {
// iRecordId=-1;
// }
// }
// }
// else // 倒序
// {
// iRecordId=iHeadPos-ABS(iStartPos)-iOffset;
// if(g_SqliteGlobal.iReadTotalRecords[iTableId]==g_SqliteTable[iTableId].iMaxRecords)
// {
// if(iRecordId<=0) //到达数据库头部
// {
// iRecordId=iRecordId+g_SqliteTable[iTableId].iMaxRecords;
// }
// }
// }
//
// return iRecordId;
//
//}
/*从当前RecordId+iStartNO开始 查找n条记录*/
//static BOOL ReadMoreRecords(void *pRecordBuff,int iRecordSize,int *piRecords,char *pszTableName,int iStartPos) //bDeserialize倒序取出
//{
// void *pRecord;
// BOOL iResult=FALSE;
// int iReadRecordId=0;
// int iOffset=0,iEffectRecrods=0,iMaxRecordsToRead;
// int iTableId =Sqlite3_GetTableIdByName(pszTableName);
// int iTotalRecords=g_SqliteGlobal.iTableTotalRecords[iTableId];
//
// iMaxRecordsToRead=MIN( *piRecords,iTotalRecords);
//
// pRecord = (void *)NEW(char, iRecordSize);
// if(pRecord == NULL)
// {
// return FALSE;
// }
// iEffectRecrods=0;
//
// for(iOffset=0;iOffset<iMaxRecordsToRead;iOffset++)
// {
// iReadRecordId=Sqlite3_ReadControl(iTableId,iStartPos,iOffset); //recordid=start +offset
// if(iReadRecordId>0)
// {
// iResult=ReadOneRecord(pRecord,iRecordSize,pszTableName,iReadRecordId);
// if(iResult)
// {
// memmove((void*)((char *)pRecordBuff + iEffectRecrods * iRecordSize) ,
// pRecord,
// (unsigned)iRecordSize);
// iEffectRecrods++;
// }
// }
// }
// DELETE(pRecord);
// *piRecords=iEffectRecrods;
// Sql_printf("ReadMoreRecords Max Recrods [%d],iEffectRecrods[%d]\n",iMaxRecordsToRead,iEffectRecrods);
// return TRUE;
//}
HANDLE DAT_StorageOpen (const char *szTabName)
{
int i=0;
int iTableId=0;
SQLITEDATA_QUEUE * hReadHandle;
for(i=0;i<SQL_MAX_DATA_TYPES;i++) //skip writerecord_table
{
if(!strcmp(szTabName,g_SQLITEDATA_QUEUE[i].szTableName))
{
hReadHandle = NEW(SQLITEDATA_QUEUE, 1);
if( hReadHandle==NULL)
{
return NULL;
}
memmove((void*)hReadHandle,&g_SQLITEDATA_QUEUE[i],
(unsigned)sizeof(SQLITEDATA_QUEUE));
iTableId=Sqlite3_GetTableIdByName(hReadHandle->szTableName);
//g_SqliteGlobal.iReadRecordId[iTableId] = g_SqliteGlobal.iWriteRecordId[iTableId];
//g_SqliteGlobal.iReadTotalRecords[iTableId] = g_SqliteGlobal.iTableTotalRecords[iTableId];
return hReadHandle;
}
}
return NULL;
}
static void IntToBinchar32(DWORD dwValue,char BinBuff[33])
{
int i=0;
for(i=32;i>0;i--)
{
//printf("bib %d \n",dwValue&0x1);
//snprintf(&BinBuff[0]+i,1,"%d",dwValue&0x1);
BinBuff[i-1]=dwValue%2+'0';
dwValue=dwValue>>1;
}
BinBuff[32]='\0';
}
BOOL DAT_StorageClose( HANDLE hCurrData)
{
if (hCurrData == NULL)
{
return TRUE;
}
DELETE(hCurrData);
return TRUE;
}
static BOOL DAT_StorageReadRecords(HANDLE hCurrData,void *pRecordBuff,int *piRecords,BOOL bOrder)
{
int iRecordSize =0;
SQLITEDATA_QUEUE *pQueue;
pQueue = (SQLITEDATA_QUEUE *)hCurrData;
iRecordSize=pQueue->iRecordSize;
int iStartNO=1;
if( hCurrData==NULL
|| pRecordBuff==NULL)
{
return FALSE;
}
//Sql_printf("----- iRecords[%d]---\n",*piRecords);
//Mutex_Lock(g_hMutexReadRecTrack[iDataTrackIndex], DM_LOCK_WAIT_TIME);
ReadMoreRecords_Order(pRecordBuff,iRecordSize,piRecords,pQueue->szTableName,bOrder);
Sql_printf("----- iRecords End [%d] size [%d]---\n",*piRecords,iRecordSize);
return TRUE;
}
static int Web_QueryRectLogRecordsByStep(void **ppBuf,int iTimes)
{
int iRecords=QUERT_HISDATASTEP;
HANDLE hHisData=DAT_StorageOpen(RECT_DATA_LOG);
RECTRECORD *pRectDataRecord = NEW(RECTRECORD,iRecords);
memset(pRectDataRecord, 0, iRecords * sizeof(RECTRECORD));
DAT_StorageReadRecords(hHisData,(void *)pRectDataRecord,&iRecords,TRUE);
if(iRecords>0)
{
*ppBuf = (void *)pRectDataRecord;
if(iTimes==QUERY_HISDATATIM-1)
{
//DAT_StorageClose(hCurrData);
}
Sql_printf("---Times-[%d]IRecrod ---[%d] \n",iTimes,iRecords);
}
else
{
DELETE(pRectDataRecord);
pRectDataRecord = NULL;
//*ppBuf = NULL;
//DAT_StorageClose(hCurrData);
Sql_printf("---Times[%d]IRecrod=0 Freee \n",iTimes);
}
DAT_StorageClose(hHisData);
return iRecords;
}
static BOOL USB_BackUsbSafelyWrite(char *pMakeFileBuf,int istrlen, int istep, FILE *fp)
{
//if(access(BACKUSB_MOUNTEDFILE,F_OK )
// &&fp !=NULL) //usb mounted
if(1)
{
fwrite(pMakeFileBuf,istrlen ,istep, fp);
Sql_printf("Write \n");
return TRUE;
}
return FALSE;
}
static BOOL USB_BackUsbSafelyClose(FILE *fp)
{
if(fp !=NULL) //usb mounted
{
fclose(fp);
return TRUE;
}
return FALSE;
}
static USB_RectLogFileWriteHtmlTitle(FILE *fp)
{
char szFileTitle[1024]={0};
char szRectLogTable[1024]={0};
snprintf(szFileTitle,sizeof(szFileTitle),
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"\
"<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head><body>\n"\
"<style>body,html{padding:10px;margin:0;font-size:14px;line-height:25px;font-family:Arial;}table{border-left:#ddd solid 1px;border-top:#ddd solid 1px;margin-top:20px;}table td{border-right:#ddd solid 1px;border-bottom:#ddd solid 1px;height:30px;line-height:30px;padding:0 0 0 10px;font-size:14px;color:#333}table tr:first-child td{font-weight:bold;height:40px;line-height:40px;}</style>\n"\
);
USB_BackUsbSafelyWrite(szFileTitle,strlen(szFileTitle), 1, fp);
//写个隐藏的index每次根据index +;
//2 new a table for Rect USB log
snprintf(szRectLogTable,sizeof(szRectLogTable),
"<h2 align=\"center\">Rect Log</h2><br/>\n" \
"RectifierLog:All Rectifiers queried<br/>\n" \
"<table border=\"0\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">\n"\
"<tr><td>%s</td> \t<td>%-32s</td> \t<td>%-32s</td> \t<td>%-32s</td> \t<td>%-32s</td> \t<td>%-8s</td> \t<td>%-8s</td>"\
"\t<td>%-8s</td> \t<td>%-8s</td> \t<td>%-8s</td> \t<td>%-8s</td> \t<td>%-8s</td> \t<td>%-8s</td> " \
"\t\n",
"Index","SData1","Time","AData1", "AData2", "TData1","TData2",
"TData3","TData4","TData5","RData1","RData2","RData3");
USB_BackUsbSafelyWrite(szRectLogTable,strlen(szRectLogTable),1, fp);
}
#define USB_RECTLOG_NAME "download_RectLog.html"
static BOOLWeb_QueryRectLogToUSB(char *szExportDir)
{
int iLen =0 ,iFileLen= 0;
char *pMakeBuf = NULL, *pMakeFileBuf = NULL;
int iRecordNum = 0;
int iDataLen = 0;
char szTime[32];
int i=0,j=0,iRecordIndex=0,iFileDataMaxLen,iHisStepNum;
char szFileTitle[1024]={0};
RECTRECORD *pReturnData=NULL,*pDeleteRtn=NULL;
char szFilePath[128]={0};
//init query all history data, lange :chinese device :all devices
//time_t fromTime=1; //start from 1970/01/01
//time_t toTime=0x7FFFFFFF;
int iEquipID =-1;//all devices
int iLanguage=1;//chinese
int iFileDataStep=1000;
//in case of usb plug out during copying
/*if(!Web_IsUSBExist())
{
return FALSE;
}*/
iFileDataMaxLen = iFileDataStep * (sizeof( RECTRECORD)+ 150); //total data length
char Alarm1BinBuff[33]={0}, Alarm2BinBuff[33]={0};
// init file buf (200 record Max one time )
pMakeFileBuf = NEW(char, iFileDataMaxLen);
if(pMakeFileBuf == NULL)
{
return FALSE;
}
memset(pMakeFileBuf, 0, (size_t)iFileDataMaxLen);
snprintf(szFilePath,128,"%s/%s",szExportDir,USB_RECTLOG_NAME);
// 1 write file title info
FILE *fp = fopen(szFilePath,"wb");
if(fp==NULL)
{
printf("create file Err !!!\n");
DELETE(pMakeFileBuf);
return FALSE ;
}
USB_RectLogFileWriteHtmlTitle(fp);
// 2. repeatly full data log max 500 records every step
iRecordIndex=1;// record indes start from 1
int RectLogNum=0;
for(j=0;j<QUERY_HISDATATIM;j++)
{
//query his data by step (continue read )
RectLogNum=Web_QueryRectLogRecordsByStep((void *)&pReturnData,j);
pDeleteRtn=pReturnData;
if(RectLogNum<=0)
{
//DELETE(pDeleteRtn);
break;
}
while(pReturnData != NULL&& RectLogNum>0 )
{
//TimeToString(pReturnData->tSignalTime, TIME_CHN_FMT,
// szTime, sizeof(szTime));
memset(Alarm1BinBuff,0,33);
memset(Alarm2BinBuff,0,33);
Sql_printf("---- [%f] [%d][\n",pReturnData->fEnvirTemp,RectLogNum);
IntToBinchar32(pReturnData->dwAlarm1,Alarm1BinBuff);
IntToBinchar32(pReturnData->dwAlarm2,Alarm2BinBuff);
//TimeToString(pTraiReturnData->tSignalTime, TIME_CHN_FMT, szTime, sizeof(szTime));
iFileLen+=sprintf(pMakeFileBuf+iFileLen,
"\t<tr><td>%ld</td> \t<td>%-32s</td> \t<td>%-32s</td> \t<td>%-32s</td> \t<td>%-32s</td>" \
"\t<td>%.2lf</td> \t<td>%.2lf</td> \t<td>%.2lf</td> \t<td>%.2lf</td> \t<td>%.2lf</td>"\
" \t<td>%.2lf</td> \t<td>%.2lf</td> \t<td>%.2lf</td> " \
"\t\n",
iRecordIndex,
pReturnData->szSerialNumber,
szTime,
Alarm1BinBuff,
Alarm2BinBuff,
pReturnData->fEnvirTemp,
pReturnData->fDCMosTemp,
pReturnData->fPFCMosTemp,
pReturnData->fDCDiodTemp,
pReturnData->fOutPortTemp,
pReturnData->fRecfVolt,
pReturnData->fRecfCurr,
pReturnData->fRecfCurrLimitPoint);
pReturnData++;
iRecordIndex++;
i++;
RectLogNum--;
//write max 200 his_data one time
if( i>=iFileDataStep-1)
{
i=0;
iFileLen=0;
Sql_printf("Alarm1\n");
USB_BackUsbSafelyWrite(pMakeFileBuf,strlen(pMakeFileBuf), 1, fp);
Sql_printf("Alarm2\n");
//fwrite(pMakeFileBuf,strlen(pMakeFileBuf), 1, fp);
memset(pMakeFileBuf, 0, (size_t)iFileDataMaxLen);
}
}
// 3. write the last filebuf
USB_BackUsbSafelyWrite(pMakeFileBuf,strlen(pMakeFileBuf), 1, fp);
//fwrite(pMakeFileBuf,strlen(pMakeFileBuf), 1, fp);
//
if( pReturnData!=NULL)
{
Sql_printf("Free pReturnData \n");
DELETE(pDeleteRtn);
//pReturnData=NULL;
Sql_printf("2222\n");
}
}
// 4. wirte file end title
sprintf(szFileTitle, "</table></body>\n" \
"</html>
sqlite C接口增删改查,数据库优化相关推荐
- 关于Qt的CRUD增删改查数据库那些事,带GUI图像界面
关于Qt的CRUD增删改查数据库那些事,带GUI图像界面 首先感谢CSDN平台提供这样强大的分享平台. Qt Creator 的几个常用快捷键必须要会,开发事半功倍, Ctrl 简称 C C + i ...
- PHP增删改查数据库(前端+后台)
PHP增删改查数据库(前端+后台) 要求: 首页导航栏中内置功能 查看数据库 点击Edit修改数据库内容 点击Delete后删除数据库内此记录,返回首页输出删除成功. 向数据库里增加数据 向搜索框输入 ...
- 华山论剑之iOS中(数组,字典,SQLite,CoreData)的“增删改查“
我们的生活态度就应该是 "不抱怨" ! 其实我想写这篇文章很久了,因为自己做的iOS开发 ,对数据这一块有这极高的要求.所以一些必须的存储数据的使用,我们都有必要熟悉用法.在以前我 ...
- mybatis从零基础到增删改查数据库
本文是mybatis框架一个初步的入门总结,最全的最好的资料应该参考这个:http://mybatis.github.io/mybatis-3/zh/index.html 本文在Eclipse下搭建一 ...
- NODEJS增删改查数据库封装——阶段2
config.json {"sql": {"host": "localhost","port": 3306," ...
- Android学习--------实现增删改查数据库操作以及实现相似微信好友对话管理操作...
近期的一个实验用到东西挺多,特地总结一下. 要求功能: 1.第一个页面加入歌曲名和歌手,跳到第二个页面列表显示全部记录.使用sqlite数据库 2.对于第二个页面显示的信息能够进行删除和改动操作,并自 ...
- dat文本导入mysql_mysql学习笔记(九) 增删改查的优化
一.大批量插入数据当使用load命令导入数据的时候,可以适当的提高导入的速度.对于myisam存储引擎的表可以通过下述方法快速的导入大量的数据. Alter table tablename disab ...
- mysql增删改查 工具类_Hibernate增删改查数据库之二工具类
/** * Hibernate工具类(简单型) * 功能-完成会话工厂和会话的创建已经会话的关闭 * @author Owner * */ public class HibernateUtils { ...
- servlet+jsp数据库增删改查实例
个人觉得这种模式是MVC模式 1. 先写一个类,类里面有几个属性. 2. 写一个接口.里面有增删改查的方法. (写在service里) 3. ...
最新文章
- 如让自己想学不好shell编程都困难?
- java文件正确编写格式_java Srpingboot框架书写mapper代码的正确格式
- 学习总结初篇:发现问题
- 10种可提升Android应用程序运行效果的技巧
- 优先队列详解priority_queue .RP
- pp-tracking ubuntu 18.04使用GPU推理出现Segmentation fault
- PRML第三章之回归的线性模型
- 客户成功案例 | 台湾杜邦:提升制程能力的法宝 — 先进的数据分析
- DXGI抓屏优化扩展:GPU硬件编码保存文件即录像为MP4和FLV,外加麦克风+计算机声音
- 红米路由器ac2100怎样设置ipv6_红米路由器AC2100怎么用手机设置 | 192路由网
- (imooc笔记)短除法计算算 十进制 八进制 十六进制
- 齐齐哈尔大学计算机专业好么,齐齐哈尔大学(专业学位)计算机技术考研难吗
- 静态分析android程序之阅读smali代码
- POJ-3368(Frequent values)
- 报错解决:Reason: Failed to determine a suitable driver class
- 【数据结构与算法】之深入解析“铺瓷砖”的求解思路与算法示例
- 阿里云oss图片的常用处理方法小结
- chrome浏览器 快捷键设置
- PCIE高性能RAID固态存储卡
- 分布式架构之CAP理论/AP架构/CP架构
热门文章
- osgEarth示例分析——osgearth_elevation
- OpenCV:03图像的算数运算
- 【IntelliJ IDEA】idea多次重装打不开的解决办法
- echarts百度地图涟漪效果
- 计算机的好处和坏处的英语作文,电脑利与弊英语作文
- java string newline,Java BufferedWriter newLine()用法及代码示例
- 记一次微信支付回调失败的修复
- 阿里云 mysql 命令_是mysql命令
- 利用Android手机破解微信加密数据库EnMicroMsg.db文件
- 50句英语成语:别想望文生义