解决多线程情况下写数据库导致的数据库崩溃问题
This commit is contained in:
parent
c251e80145
commit
3b15c7b050
|
@ -99,7 +99,6 @@ namespace ver_2
|
||||||
|
|
||||||
// 保存路径表
|
// 保存路径表
|
||||||
sqlite3_exec(m_sqlite, "create table save_filenames (filename text)", NULL, NULL, NULL);
|
sqlite3_exec(m_sqlite, "create table save_filenames (filename text)", NULL, NULL, NULL);
|
||||||
|
|
||||||
// 设备配置表
|
// 设备配置表
|
||||||
sqlite3_exec(m_sqlite, "create table device_params (name text, value_type text, value text)", NULL, NULL, NULL);
|
sqlite3_exec(m_sqlite, "create table device_params (name text, value_type text, value text)", NULL, NULL, NULL);
|
||||||
|
|
||||||
|
@ -114,32 +113,25 @@ namespace ver_2
|
||||||
|
|
||||||
std::vector<MainTableInfo> tables;
|
std::vector<MainTableInfo> tables;
|
||||||
|
|
||||||
char** result = NULL;
|
sqlite3_stmt* stmt = NULL;
|
||||||
int rows, cols;
|
ret = sqlite3_prepare(m_sqlite, "select * from table_", -1, &stmt, NULL);
|
||||||
ret = sqlite3_get_table(m_sqlite, "select * from table_", &result, &rows, &cols, NULL);
|
assert(0 == ret);
|
||||||
assert(0 == ret && rows > 0 && cols == 2);
|
|
||||||
|
|
||||||
for (int i = 0; i < rows; i++)
|
ret = sqlite3_step(stmt);
|
||||||
|
while (SQLITE_ROW == ret)
|
||||||
{
|
{
|
||||||
MainTableInfo info;
|
MainTableInfo info;
|
||||||
for (int j = 0; j < cols; j++)
|
info.id = sqlite3_column_int(stmt, 0);
|
||||||
{
|
info.tableName = (const char*)sqlite3_column_text(stmt, 1);
|
||||||
if (0 == strcmp("id", result[j]))
|
|
||||||
{
|
|
||||||
info.id = atoi(result[(i + 1) * cols + j]);
|
|
||||||
}
|
|
||||||
else if (0 == strcmp("name", result[j]))
|
|
||||||
{
|
|
||||||
info.tableName = result[(i + 1) * cols + j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tables.push_back(info);
|
tables.push_back(info);
|
||||||
|
|
||||||
|
ret = sqlite3_step(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_free_table(result);
|
ret = sqlite3_finalize(stmt);
|
||||||
assert(!tables.empty());
|
assert(0 == ret);
|
||||||
|
|
||||||
|
assert(!tables.empty());
|
||||||
std::sort(tables.begin(), tables.end(), MainTableSort);
|
std::sort(tables.begin(), tables.end(), MainTableSort);
|
||||||
m_currBatchId = tables[tables.size() - 1].tableName;
|
m_currBatchId = tables[tables.size() - 1].tableName;
|
||||||
}
|
}
|
||||||
|
@ -185,6 +177,14 @@ namespace ver_2
|
||||||
StopScan(errInfo);
|
StopScan(errInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ManagerV2::ScanImage(const ScanImageParam* param)
|
||||||
|
{
|
||||||
|
assert(NULL != param && this == param->mgr);
|
||||||
|
|
||||||
|
m_saveFilePathList.push_back(param->fileName);
|
||||||
|
RestoreSaveFilePathList(m_saveFilePathList);
|
||||||
|
}
|
||||||
|
|
||||||
void ManagerV2::SetSaneEvent(SaneEvent event, void* param)
|
void ManagerV2::SetSaneEvent(SaneEvent event, void* param)
|
||||||
{
|
{
|
||||||
assert(NULL != event && NULL != param);
|
assert(NULL != event && NULL != param);
|
||||||
|
@ -353,10 +353,8 @@ namespace ver_2
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
imagePath = imagePath2;
|
imagePath = imagePath2;
|
||||||
HGBase_EnterLock(m_lock);
|
|
||||||
m_saveFilePathList.push_back(imagePath);
|
m_saveFilePathList.push_back(imagePath);
|
||||||
RestoreSaveFilePathList(m_saveFilePathList);
|
RestoreSaveFilePathList(m_saveFilePathList);
|
||||||
HGBase_LeaveLock(m_lock);
|
|
||||||
|
|
||||||
errInfo.clear();
|
errInfo.clear();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -367,7 +365,6 @@ namespace ver_2
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
errInfo = "错误";
|
errInfo = "错误";
|
||||||
|
|
||||||
HGBase_EnterLock(m_lock);
|
|
||||||
for (int i = 0; i < (int)m_saveFilePathList.size(); ++i)
|
for (int i = 0; i < (int)m_saveFilePathList.size(); ++i)
|
||||||
{
|
{
|
||||||
if (filePath == m_saveFilePathList[i])
|
if (filePath == m_saveFilePathList[i])
|
||||||
|
@ -383,14 +380,12 @@ namespace ver_2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RestoreSaveFilePathList(m_saveFilePathList);
|
RestoreSaveFilePathList(m_saveFilePathList);
|
||||||
HGBase_LeaveLock(m_lock);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ManagerV2::ClearGlobalFileSavePath(std::string& errInfo)
|
int ManagerV2::ClearGlobalFileSavePath(std::string& errInfo)
|
||||||
{
|
{
|
||||||
HGBase_EnterLock(m_lock);
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < (int)m_saveFilePathList.size())
|
while (i < (int)m_saveFilePathList.size())
|
||||||
{
|
{
|
||||||
|
@ -413,7 +408,6 @@ namespace ver_2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RestoreSaveFilePathList(m_saveFilePathList);
|
RestoreSaveFilePathList(m_saveFilePathList);
|
||||||
HGBase_LeaveLock(m_lock);
|
|
||||||
|
|
||||||
HGBase_DeleteDir(m_globalCfg.fileSavePath.c_str());
|
HGBase_DeleteDir(m_globalCfg.fileSavePath.c_str());
|
||||||
errInfo.clear();
|
errInfo.clear();
|
||||||
|
@ -530,10 +524,8 @@ namespace ver_2
|
||||||
int ret = SaveImage(outImage, outImagePath);
|
int ret = SaveImage(outImage, outImagePath);
|
||||||
if (0 == ret)
|
if (0 == ret)
|
||||||
{
|
{
|
||||||
HGBase_EnterLock(m_lock);
|
|
||||||
m_saveFilePathList.push_back(outImagePath);
|
m_saveFilePathList.push_back(outImagePath);
|
||||||
RestoreSaveFilePathList(m_saveFilePathList);
|
RestoreSaveFilePathList(m_saveFilePathList);
|
||||||
HGBase_LeaveLock(m_lock);
|
|
||||||
errInfo.clear();
|
errInfo.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,10 +592,8 @@ namespace ver_2
|
||||||
}
|
}
|
||||||
|
|
||||||
outImagePath = outImagePath2;
|
outImagePath = outImagePath2;
|
||||||
HGBase_EnterLock(m_lock);
|
|
||||||
m_saveFilePathList.push_back(outImagePath);
|
m_saveFilePathList.push_back(outImagePath);
|
||||||
RestoreSaveFilePathList(m_saveFilePathList);
|
RestoreSaveFilePathList(m_saveFilePathList);
|
||||||
HGBase_LeaveLock(m_lock);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,10 +662,8 @@ namespace ver_2
|
||||||
if (0 == SaveImage(img, imgPath))
|
if (0 == SaveImage(img, imgPath))
|
||||||
{
|
{
|
||||||
outImagePathList.push_back(imgPath);
|
outImagePathList.push_back(imgPath);
|
||||||
HGBase_EnterLock(m_lock);
|
|
||||||
m_saveFilePathList.push_back(imgPath);
|
m_saveFilePathList.push_back(imgPath);
|
||||||
RestoreSaveFilePathList(m_saveFilePathList);
|
RestoreSaveFilePathList(m_saveFilePathList);
|
||||||
HGBase_LeaveLock(m_lock);
|
|
||||||
errInfo.clear();
|
errInfo.clear();
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
@ -762,10 +750,8 @@ namespace ver_2
|
||||||
}
|
}
|
||||||
|
|
||||||
outZipPath = outZipPath2;
|
outZipPath = outZipPath2;
|
||||||
HGBase_EnterLock(m_lock);
|
|
||||||
m_saveFilePathList.push_back(outZipPath);
|
m_saveFilePathList.push_back(outZipPath);
|
||||||
RestoreSaveFilePathList(m_saveFilePathList);
|
RestoreSaveFilePathList(m_saveFilePathList);
|
||||||
HGBase_LeaveLock(m_lock);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,10 +774,8 @@ namespace ver_2
|
||||||
{
|
{
|
||||||
if (0 == SaveImage(img, outImagePath))
|
if (0 == SaveImage(img, outImagePath))
|
||||||
{
|
{
|
||||||
HGBase_EnterLock(m_lock);
|
|
||||||
m_saveFilePathList.push_back(outImagePath);
|
m_saveFilePathList.push_back(outImagePath);
|
||||||
RestoreSaveFilePathList(m_saveFilePathList);
|
RestoreSaveFilePathList(m_saveFilePathList);
|
||||||
HGBase_LeaveLock(m_lock);
|
|
||||||
errInfo.clear();
|
errInfo.clear();
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
@ -965,10 +949,8 @@ namespace ver_2
|
||||||
{
|
{
|
||||||
if (0 == SaveImage(image, outImagePath))
|
if (0 == SaveImage(image, outImagePath))
|
||||||
{
|
{
|
||||||
HGBase_EnterLock(m_lock);
|
|
||||||
m_saveFilePathList.push_back(outImagePath);
|
m_saveFilePathList.push_back(outImagePath);
|
||||||
RestoreSaveFilePathList(m_saveFilePathList);
|
RestoreSaveFilePathList(m_saveFilePathList);
|
||||||
HGBase_LeaveLock(m_lock);
|
|
||||||
errInfo.clear();
|
errInfo.clear();
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
@ -1237,32 +1219,25 @@ namespace ver_2
|
||||||
|
|
||||||
std::vector<MainTableInfo> tables;
|
std::vector<MainTableInfo> tables;
|
||||||
|
|
||||||
char** result = NULL;
|
sqlite3_stmt* stmt = NULL;
|
||||||
int rows, cols;
|
int ret = sqlite3_prepare(m_sqlite, "select * from table_", -1, &stmt, NULL);
|
||||||
int ret = sqlite3_get_table(m_sqlite, "select * from table_", &result, &rows, &cols, NULL);
|
assert(0 == ret);
|
||||||
assert(0 == ret && rows > 0 && cols == 2);
|
|
||||||
|
|
||||||
for (int i = 0; i < rows; i++)
|
ret = sqlite3_step(stmt);
|
||||||
|
while (SQLITE_ROW == ret)
|
||||||
{
|
{
|
||||||
MainTableInfo info;
|
MainTableInfo info;
|
||||||
for (int j = 0; j < cols; j++)
|
info.id = sqlite3_column_int(stmt, 0);
|
||||||
{
|
info.tableName = (const char*)sqlite3_column_text(stmt, 1);
|
||||||
if (0 == strcmp("id", result[j]))
|
|
||||||
{
|
|
||||||
info.id = atoi(result[(i + 1) * cols + j]);
|
|
||||||
}
|
|
||||||
else if (0 == strcmp("name", result[j]))
|
|
||||||
{
|
|
||||||
info.tableName = result[(i + 1) * cols + j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tables.push_back(info);
|
tables.push_back(info);
|
||||||
|
|
||||||
|
ret = sqlite3_step(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_free_table(result);
|
ret = sqlite3_finalize(stmt);
|
||||||
assert(!tables.empty());
|
assert(0 == ret);
|
||||||
|
|
||||||
|
assert(!tables.empty());
|
||||||
std::sort(tables.begin(), tables.end(), MainTableSort);
|
std::sort(tables.begin(), tables.end(), MainTableSort);
|
||||||
for (int i = 0; i < (int)tables.size(); ++i)
|
for (int i = 0; i < (int)tables.size(); ++i)
|
||||||
batchIdList.push_back(tables[i].tableName);
|
batchIdList.push_back(tables[i].tableName);
|
||||||
|
@ -1616,10 +1591,8 @@ namespace ver_2
|
||||||
if (SaveToFile((const HGByte*)imgData, imgSize, imagePath2))
|
if (SaveToFile((const HGByte*)imgData, imgSize, imagePath2))
|
||||||
{
|
{
|
||||||
imagePath = imagePath2;
|
imagePath = imagePath2;
|
||||||
HGBase_EnterLock(m_lock);
|
|
||||||
m_saveFilePathList.push_back(imagePath);
|
m_saveFilePathList.push_back(imagePath);
|
||||||
RestoreSaveFilePathList(m_saveFilePathList);
|
RestoreSaveFilePathList(m_saveFilePathList);
|
||||||
HGBase_LeaveLock(m_lock);
|
|
||||||
|
|
||||||
errInfo.clear();
|
errInfo.clear();
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
@ -1686,6 +1659,10 @@ namespace ver_2
|
||||||
int ret;
|
int ret;
|
||||||
char sql[1024];
|
char sql[1024];
|
||||||
|
|
||||||
|
ret = sqlite3_exec(m_sqlite, "begin", NULL, NULL, NULL);
|
||||||
|
assert(0 == ret);
|
||||||
|
|
||||||
|
bool ok = true;
|
||||||
for (int i = 0; i < (int)tables.size(); ++i)
|
for (int i = 0; i < (int)tables.size(); ++i)
|
||||||
{
|
{
|
||||||
if (tables[i].idx >= insertPos)
|
if (tables[i].idx >= insertPos)
|
||||||
|
@ -1693,9 +1670,22 @@ namespace ver_2
|
||||||
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
|
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
|
||||||
m_currBatchId.c_str(), tables[i].idx + 1, tables[i].id);
|
m_currBatchId.c_str(), tables[i].idx + 1, tables[i].id);
|
||||||
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
|
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
|
||||||
assert(0 == ret);
|
if (0 != ret)
|
||||||
|
{
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
ret = sqlite3_exec(m_sqlite, "rollback", NULL, NULL, NULL);
|
||||||
|
assert(0 == ret);
|
||||||
|
delete[] thumbData;
|
||||||
|
delete[] imgData;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(sql, "insert into 'table_%s' (idx, format, tag, image, thumb) values ('%d', '%s', '%s', ?, ?)", m_currBatchId.c_str(),
|
sprintf(sql, "insert into 'table_%s' (idx, format, tag, image, thumb) values ('%d', '%s', '%s', ?, ?)", m_currBatchId.c_str(),
|
||||||
insertPos, imgFormat.c_str(), imageTag.c_str());
|
insertPos, imgFormat.c_str(), imageTag.c_str());
|
||||||
|
@ -1708,6 +1698,16 @@ namespace ver_2
|
||||||
assert(0 == ret);
|
assert(0 == ret);
|
||||||
sqlite3_step(stmt);
|
sqlite3_step(stmt);
|
||||||
ret = sqlite3_finalize(stmt);
|
ret = sqlite3_finalize(stmt);
|
||||||
|
if (0 != ret)
|
||||||
|
{
|
||||||
|
ret = sqlite3_exec(m_sqlite, "rollback", NULL, NULL, NULL);
|
||||||
|
assert(0 == ret);
|
||||||
|
delete[] thumbData;
|
||||||
|
delete[] imgData;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sqlite3_exec(m_sqlite, "commit", NULL, NULL, NULL);
|
||||||
assert(0 == ret);
|
assert(0 == ret);
|
||||||
|
|
||||||
if (!m_bindFolder.empty())
|
if (!m_bindFolder.empty())
|
||||||
|
@ -3515,36 +3515,27 @@ namespace ver_2
|
||||||
{
|
{
|
||||||
tables.clear();
|
tables.clear();
|
||||||
|
|
||||||
char** result = NULL;
|
sqlite3_stmt* stmt = NULL;
|
||||||
char sql[256];
|
char sql[256];
|
||||||
sprintf(sql, "select id, idx, format from 'table_%s'", m_currBatchId.c_str());
|
sprintf(sql, "select id, idx, format from 'table_%s'", m_currBatchId.c_str());
|
||||||
int rows, cols;
|
int ret = sqlite3_prepare(m_sqlite, sql, -1, &stmt, NULL);
|
||||||
int ret = sqlite3_get_table(m_sqlite, sql, &result, &rows, &cols, NULL);
|
|
||||||
assert(0 == ret);
|
assert(0 == ret);
|
||||||
|
|
||||||
for (int i = 0; i < rows; i++)
|
ret = sqlite3_step(stmt);
|
||||||
|
while (SQLITE_ROW == ret)
|
||||||
{
|
{
|
||||||
BatchTableInfo info;
|
BatchTableInfo info;
|
||||||
for (int j = 0; j < cols; j++)
|
info.id = sqlite3_column_int(stmt, 0);
|
||||||
{
|
info.idx = sqlite3_column_int(stmt, 1);
|
||||||
if (0 == strcmp("id", result[j]))
|
info.format = (const char *)sqlite3_column_text(stmt, 2);
|
||||||
{
|
|
||||||
info.id = atoi(result[(i + 1) * cols + j]);
|
|
||||||
}
|
|
||||||
else if (0 == strcmp("idx", result[j]))
|
|
||||||
{
|
|
||||||
info.idx = atoi(result[(i + 1) * cols + j]);
|
|
||||||
}
|
|
||||||
else if (0 == strcmp("format", result[j]))
|
|
||||||
{
|
|
||||||
info.format = result[(i + 1) * cols + j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tables.push_back(info);
|
tables.push_back(info);
|
||||||
|
|
||||||
|
ret = sqlite3_step(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_free_table(result);
|
ret = sqlite3_finalize(stmt);
|
||||||
|
assert(0 == ret);
|
||||||
|
|
||||||
std::sort(tables.begin(), tables.end(), BatchTableSort);
|
std::sort(tables.begin(), tables.end(), BatchTableSort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3937,8 +3928,17 @@ namespace ver_2
|
||||||
int ret = p->SaveImage(img, imagePath);
|
int ret = p->SaveImage(img, imagePath);
|
||||||
if (0 == ret)
|
if (0 == ret)
|
||||||
{
|
{
|
||||||
p->m_saveFilePathList.push_back(imagePath);
|
ScanImageParam* scanImageParam = new ScanImageParam;
|
||||||
p->RestoreSaveFilePathList(p->m_saveFilePathList);
|
scanImageParam->mgr = p;
|
||||||
|
scanImageParam->fileName = imagePath;
|
||||||
|
|
||||||
|
HGMsg msg;
|
||||||
|
msg.id = MSGID_SCAN_IMAGE;
|
||||||
|
msg.data = scanImageParam;
|
||||||
|
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(p->m_msgPump, &msg))
|
||||||
|
{
|
||||||
|
delete scanImageParam;
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL != p->m_saneImageCallback)
|
if (NULL != p->m_saneImageCallback)
|
||||||
p->m_saneImageCallback(imagePath.c_str(), p->m_saneImageParam);
|
p->m_saneImageCallback(imagePath.c_str(), p->m_saneImageParam);
|
||||||
|
|
|
@ -130,6 +130,8 @@ namespace ver_2
|
||||||
void CloseDev(const CloseDevParam* param);
|
void CloseDev(const CloseDevParam* param);
|
||||||
// 扫描完成
|
// 扫描完成
|
||||||
void ScanFinish(const ScanFinishParam* param);
|
void ScanFinish(const ScanFinishParam* param);
|
||||||
|
// 扫描图像
|
||||||
|
void ScanImage(const ScanImageParam* param);
|
||||||
|
|
||||||
// 设置回调
|
// 设置回调
|
||||||
void SetSaneEvent(SaneEvent event, void* param);
|
void SetSaneEvent(SaneEvent event, void* param);
|
||||||
|
|
|
@ -96,6 +96,7 @@ namespace ver_2
|
||||||
{
|
{
|
||||||
MSGID_CLOSE_DEVICE = 3L,
|
MSGID_CLOSE_DEVICE = 3L,
|
||||||
MSGID_SCAN_FINISH,
|
MSGID_SCAN_FINISH,
|
||||||
|
MSGID_SCAN_IMAGE,
|
||||||
MSGID_WS_COMMAND,
|
MSGID_WS_COMMAND,
|
||||||
MSGID_WS_EVENT
|
MSGID_WS_EVENT
|
||||||
};
|
};
|
||||||
|
@ -114,6 +115,12 @@ namespace ver_2
|
||||||
ManagerV2* mgr;
|
ManagerV2* mgr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ScanImageParam
|
||||||
|
{
|
||||||
|
ManagerV2* mgr;
|
||||||
|
std::string fileName;
|
||||||
|
};
|
||||||
|
|
||||||
struct WSCmdParam
|
struct WSCmdParam
|
||||||
{
|
{
|
||||||
WSServer* svr;
|
WSServer* svr;
|
||||||
|
|
|
@ -116,6 +116,13 @@ namespace ver_2
|
||||||
delete param;
|
delete param;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MSGID_SCAN_IMAGE:
|
||||||
|
{
|
||||||
|
ScanImageParam* param = (ScanImageParam*)msg->data;
|
||||||
|
param->mgr->ScanImage(param);
|
||||||
|
delete param;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MSGID_WS_COMMAND:
|
case MSGID_WS_COMMAND:
|
||||||
{
|
{
|
||||||
WSCmdParam* param = (WSCmdParam*)msg->data;
|
WSCmdParam* param = (WSCmdParam*)msg->data;
|
||||||
|
|
Loading…
Reference in New Issue