Index: src/ch/MainWnd.cpp =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -41,6 +41,7 @@ #include "../libchcore/TCoreException.h" #include "../libicpf/exception.h" #include "../libchcore/TTaskManagerStatsSnapshot.h" +#include "../libchcore/TTaskManagerSerializer.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -76,7 +77,7 @@ m_pdlgStatus(NULL), m_pdlgMiniView(NULL), m_dwLastTime(0), - m_tasks(), + m_spTasks(), m_spTaskMgrStats(new chcore::TTaskManagerStatsSnapshot) { } @@ -185,29 +186,31 @@ // Create the tray icon ShowTrayIcon(); + CString strTasksDir = GetTasksDirectory(); + CString strTMPath = strTasksDir + _T("tasks.sqlite"); + + chcore::TTaskManagerSerializerPtr spSerializer(new chcore::TTaskManagerSerializer(chcore::PathFromString(strTMPath), chcore::PathFromString(strTasksDir))); + m_spTasks.reset(new chcore::TTaskManager(spSerializer)); + // initialize CTaskArray - m_tasks.Create(m_pFeedbackFactory); + m_spTasks->Create(m_pFeedbackFactory); // load last state LOG_INFO(_T("Loading existing tasks...")); - CString strPath; - GetApp().GetProgramDataPath(strPath); - strPath += _T("\\Tasks\\"); - m_tasks.SetTasksDir(chcore::PathFromString(strPath)); // load tasks - m_tasks.LoadDataProgress(); + m_spTasks->Load(); // import tasks specified at command line (before loading current tasks) const TCommandLineParser& cmdLine = GetApp().GetCommandLine(); ProcessCommandLine(cmdLine); // start processing of the tasks loaded above and added by a command line - m_tasks.TasksRetryProcessing(); + m_spTasks->TasksRetryProcessing(); // start clipboard monitoring LOG_INFO(_T("Starting clipboard monitor...")); - CClipboardMonitor::StartMonitor(&m_tasks); + CClipboardMonitor::StartMonitor(m_spTasks.get()); EUpdatesFrequency eFrequency = (EUpdatesFrequency)GetPropValue(GetConfig()); if(eFrequency != eFreq_Never) @@ -361,9 +364,9 @@ } case WM_MOUSEMOVE: { - if (m_tasks.GetSize() != 0) + if (m_spTasks->GetSize() != 0) { - m_tasks.GetStatsSnapshot(m_spTaskMgrStats); + m_spTasks->GetStatsSnapshot(m_spTaskMgrStats); _sntprintf(text, _MAX_PATH, _T("%s - %.0f %%"), GetApp().GetAppName(), m_spTaskMgrStats->GetCombinedProgress() * 100.0); m_ctlTray.SetTooltipText(text); @@ -387,7 +390,7 @@ void CMainWnd::ShowStatusWindow(const chcore::TTaskPtr& spSelect) { - m_pdlgStatus=new CStatusDlg(&m_tasks, this); // self deleting + m_pdlgStatus=new CStatusDlg(m_spTasks.get(), this); // self deleting m_pdlgStatus->m_spInitialSelection = spSelect; m_pdlgStatus->m_bLockInstance=true; m_pdlgStatus->m_bAutoDelete=true; @@ -419,17 +422,17 @@ case 1023: // autosave timer KillTimer(1023); - m_tasks.SaveData(); + m_spTasks->Store(); SetTimer(1023, GetPropValue(GetConfig()), NULL); break; case 3245: // auto-delete finished tasks timer KillTimer(3245); if (GetPropValue(GetConfig())) { - size_t stSize = m_tasks.GetSize(); - m_tasks.RemoveAllFinished(); - if(m_tasks.GetSize() != stSize && m_pdlgStatus && m_pdlgStatus->m_bLock && IsWindow(m_pdlgStatus->m_hWnd)) + size_t stSize = m_spTasks->GetSize(); + m_spTasks->RemoveAllFinished(); + if(m_spTasks->GetSize() != stSize && m_pdlgStatus && m_pdlgStatus->m_bLock && IsWindow(m_pdlgStatus->m_hWnd)) m_pdlgStatus->SendMessage(WM_UPDATESTATUS); } @@ -438,7 +441,7 @@ case 8743: { // wait state handling section - m_tasks.ResumeWaitingTasks((size_t)GetPropValue(GetConfig())); + m_spTasks->ResumeWaitingTasks((size_t)GetPropValue(GetConfig())); break; } } @@ -506,7 +509,7 @@ chcore::SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_NEXTCOPY_STRING)); // create task with the above definition - chcore::TTaskPtr spTask = m_tasks.CreateTask(tTaskDefinition); + chcore::TTaskPtr spTask = m_spTasks->CreateTask(tTaskDefinition); // add to task list and start processing spTask->BeginProcessing(); @@ -527,7 +530,7 @@ cmdLineParser.ParseCommandLine(pszBuffer); ProcessCommandLine(cmdLineParser); - m_tasks.TasksRetryProcessing(); + m_spTasks->TasksRetryProcessing(); return TRUE; } @@ -554,7 +557,7 @@ try { - chcore::TTaskPtr spTask = m_tasks.ImportTask(strPath); + chcore::TTaskPtr spTask = m_spTasks->ImportTask(strPath); if(spTask) spTask->Store(); bImported = true; @@ -589,7 +592,7 @@ void CMainWnd::OnShowMiniView() { - m_pdlgMiniView=new CMiniViewDlg(&m_tasks, &CStatusDlg::m_bLock, this); // self-deleting + m_pdlgMiniView=new CMiniViewDlg(m_spTasks.get(), &CStatusDlg::m_bLock, this); // self-deleting m_pdlgMiniView->m_bAutoDelete=true; m_pdlgMiniView->m_bLockInstance=true; m_pdlgMiniView->Create(); @@ -616,7 +619,7 @@ chcore::SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_NEXTCOPY_STRING)); // new task - chcore::TTaskPtr spTask = m_tasks.CreateTask(tTaskDefinition); + chcore::TTaskPtr spTask = m_spTasks->CreateTask(tTaskDefinition); // start spTask->BeginProcessing(); @@ -629,7 +632,7 @@ { case WM_MINIVIEWDBLCLK: { - chcore::TTaskPtr spTask = m_tasks.GetTaskBySessionUniqueID(lParam); + chcore::TTaskPtr spTask = m_spTasks->GetTaskByTaskID(lParam); ShowStatusWindow(spTask); break; } @@ -908,13 +911,10 @@ // kill thread that monitors clipboard CClipboardMonitor::StopMonitor(); - m_tasks.StopAllTasks(); + m_spTasks->StopAllTasks(); - // save - m_tasks.SaveData(); - // delete all tasks - m_tasks.RemoveAll(); + m_spTasks->ClearBeforeExit(); } void CMainWnd::OnAppExit() @@ -934,3 +934,11 @@ pDlg->Create(); } + +CString CMainWnd::GetTasksDirectory() const +{ + CString strPath; + GetApp().GetProgramDataPath(strPath); + strPath += _T("\\Tasks\\"); + return strPath; +} Index: src/ch/MainWnd.h =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/ch/MainWnd.h (.../MainWnd.h) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/ch/MainWnd.h (.../MainWnd.h) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -48,6 +48,8 @@ void ProcessCommandLine(const TCommandLineParser& rCommandLine); + CString GetTasksDirectory() const; + afx_msg void OnPopupShowStatus(); afx_msg void OnPopupShowOptions(); afx_msg void OnClose(); @@ -73,7 +75,7 @@ CTrayIcon m_ctlTray; - chcore::TTaskManager m_tasks; + chcore::TTaskManagerPtr m_spTasks; chcore::IFeedbackHandlerFactory* m_pFeedbackFactory; chcore::TSharedMemory m_tCHExtharedMemory; Index: src/ch/MiniViewDlg.cpp =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/ch/MiniViewDlg.cpp (.../MiniViewDlg.cpp) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/ch/MiniViewDlg.cpp (.../MiniViewDlg.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -232,7 +232,7 @@ pItem->m_strText = strPath; pItem->m_uiPos = boost::numeric_cast(spTaskStats->GetCombinedProgress() * 100.0); - pItem->m_stTaskUniqueSessionID = spTaskStats->GetSessionUniqueID(); + pItem->m_tTaskID = spTaskStats->GetTaskID(); } } } @@ -275,7 +275,7 @@ pItem->m_crColor=GetSysColor(COLOR_HIGHLIGHT); pItem->m_strText=GetResManager().LoadString(IDS_MINIVIEWALL_STRING); pItem->m_uiPos = boost::numeric_cast(m_spTaskMgrStats->GetCombinedProgress() * 100.0); - pItem->m_stTaskUniqueSessionID = NO_TASK_SESSION_UNIQUE_ID; + pItem->m_tTaskID = chcore::NoTaskID; // get rid of the rest m_ctlStatus.SetSmoothProgress(GetPropValue(GetConfig())); @@ -436,7 +436,7 @@ if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size()) return; - chcore::TTaskPtr spTask = pDlg->m_pTasks->GetTaskBySessionUniqueID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_stTaskUniqueSessionID); + chcore::TTaskPtr spTask = pDlg->m_pTasks->GetTaskByTaskID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_tTaskID); if(spTask) spTask->PauseProcessing(); else @@ -544,7 +544,7 @@ if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size()) return; - chcore::TTaskPtr spTask = pDlg->m_pTasks->GetTaskBySessionUniqueID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_stTaskUniqueSessionID); + chcore::TTaskPtr spTask = pDlg->m_pTasks->GetTaskByTaskID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_tTaskID); if (spTask) { if(spTask->GetTaskState() == chcore::eTaskState_Waiting) @@ -589,7 +589,7 @@ if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size()) return; - chcore::TTaskPtr spTask = pDlg->m_pTasks->GetTaskBySessionUniqueID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_stTaskUniqueSessionID); + chcore::TTaskPtr spTask = pDlg->m_pTasks->GetTaskByTaskID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_tTaskID); if(spTask) spTask->CancelProcessing(); else @@ -644,7 +644,7 @@ if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size()) return; - chcore::TTaskPtr spTask = pDlg->m_pTasks->GetTaskBySessionUniqueID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_stTaskUniqueSessionID); + chcore::TTaskPtr spTask = pDlg->m_pTasks->GetTaskByTaskID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_tTaskID); if(spTask) spTask->RestartProcessing(); else @@ -802,8 +802,8 @@ if(iSel == LB_ERR || (size_t)iSel >= m_ctlStatus.m_vItems.size()) return; - size_t stSessionUniqueID = m_ctlStatus.m_vItems.at(iSel)->m_stTaskUniqueSessionID; - GetParent()->PostMessage(WM_MINIVIEWDBLCLK, 0, (LPARAM)stSessionUniqueID); + chcore::taskid_t tTaskID = m_ctlStatus.m_vItems.at(iSel)->m_tTaskID; + GetParent()->PostMessage(WM_MINIVIEWDBLCLK, 0, tTaskID); } void CMiniViewDlg::OnLanguageChanged() Index: src/ch/ProgressListBox.h =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/ch/ProgressListBox.h (.../ProgressListBox.h) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/ch/ProgressListBox.h (.../ProgressListBox.h) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -19,6 +19,8 @@ #ifndef __PROGRESSLISTBOX_H__ #define __PROGRESSLISTBOX_H__ +#include "../libchcore/TaskID.h" + ///////////////////////////////////////////////////////////////////////////// // CProgressListBox window struct _PROGRESSITEM_ @@ -30,7 +32,7 @@ COLORREF m_crColor; - size_t m_stTaskUniqueSessionID; + chcore::taskid_t m_tTaskID; }; class CProgressListBox : public CListBox Index: src/ch/StatusDlg.cpp =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/ch/StatusDlg.cpp (.../StatusDlg.cpp) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/ch/StatusDlg.cpp (.../StatusDlg.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -231,7 +231,7 @@ return; int iCurrentBufferIndex = 0; - chcore::TTaskStatsSnapshotPtr spTaskStats = m_spTaskMgrStats->GetTaskStatsForSessionUniqueID(GetSelectedItemSessionUniqueID()); + chcore::TTaskStatsSnapshotPtr spTaskStats = m_spTaskMgrStats->GetTaskStatsForTaskID(GetSelectedItemSessionUniqueID()); if(spTaskStats) { chcore::TSubTaskStatsSnapshotPtr spSubTaskStats = spTaskStats->GetSubTasksStats().GetCurrentSubTaskSnapshot(); @@ -253,7 +253,7 @@ { POSITION pos = m_ctlStatusList.GetFirstSelectedItemPosition(); int nPos = m_ctlStatusList.GetNextSelectedItem(pos); - return m_pTasks->GetTaskBySessionUniqueID(m_ctlStatusList.GetItemData(nPos)); + return m_pTasks->GetTaskByTaskID(m_ctlStatusList.GetItemData(nPos)); } return chcore::TTaskPtr(); @@ -592,7 +592,7 @@ void CStatusDlg::RefreshStatus() { // remember address of a current selection - size_t stSelectedTaskSessionUniqueID = GetSelectedItemSessionUniqueID(); + size_t stSelectedTaskID = GetSelectedItemSessionUniqueID(); // get all the stats needed m_pTasks->GetStatsSnapshot(m_spTaskMgrStats); @@ -608,7 +608,7 @@ SetTaskListEntry(stIndex, spTaskStats); // right side update - if(spTaskStats->GetSessionUniqueID() == stSelectedTaskSessionUniqueID) + if(spTaskStats->GetTaskID() == stSelectedTaskID) UpdateTaskStatsDetails(spTaskStats); } @@ -658,12 +658,13 @@ if(!spTask) return; - unsigned long lResult = (unsigned long)(ShellExecute(this->m_hWnd, _T("open"), _T("notepad.exe"), spTask->GetRelatedPath(chcore::TTask::ePathType_TaskLogFile).ToString(), NULL, SW_SHOWNORMAL)); + unsigned long lResult = (unsigned long)(ShellExecute(this->m_hWnd, _T("open"), _T("notepad.exe"), + spTask->GetLogPath().ToString(), NULL, SW_SHOWNORMAL)); if(lResult < 32) { ictranslate::CFormat fmt(GetResManager().LoadString(IDS_SHELLEXECUTEERROR_STRING)); fmt.SetParam(_t("%errno"), lResult); - fmt.SetParam(_t("%path"), spTask->GetRelatedPath(chcore::TTask::ePathType_TaskLogFile).ToString()); + fmt.SetParam(_t("%path"), spTask->GetLogPath().ToString()); AfxMessageBox(fmt); } } @@ -982,7 +983,7 @@ lvi.iSubItem = 0; lvi.pszText = (PTSTR)(PCTSTR)strStatusText; lvi.cchTextMax = lstrlen(lvi.pszText); - lvi.lParam = spTaskStats->GetSessionUniqueID(); + lvi.lParam = spTaskStats->GetTaskID(); lvi.iImage = GetImageFromStatus(spTaskStats->GetTaskState()); if(boost::numeric_cast(stPos) < m_ctlStatusList.GetItemCount()) m_ctlStatusList.SetItem(&lvi); @@ -1055,7 +1056,6 @@ void CStatusDlg::UpdateTaskStatsDetails(const chcore::TTaskStatsSnapshotPtr& spTaskStats) { chcore::TSubTaskStatsSnapshotPtr spSubTaskStats = spTaskStats->GetSubTasksStats().GetCurrentSubTaskSnapshot(); - _ASSERTE(spSubTaskStats != NULL); if(!spSubTaskStats) return; @@ -1130,7 +1130,7 @@ GetDlgItem(IDC_DESTINATIONOBJECT_STATIC)->SetWindowText(spTaskStats->GetDestinationPath()); GetDlgItem(IDC_THREADPRIORITY_STATIC)->SetWindowText(GetResManager().LoadString(IDS_PRIORITY0_STRING + PriorityToIndex(spTaskStats->GetThreadPriority()))); - GetDlgItem(IDC_TASKID_STATIC)->SetWindowText(spTaskStats->GetTaskID()); + GetDlgItem(IDC_TASKID_STATIC)->SetWindowText(spTaskStats->GetTaskName()); } void CStatusDlg::SetWindowTitle(PCTSTR pszText) Index: src/libchcore/ITaskManagerSerializer.h =================================================================== diff -u --- src/libchcore/ITaskManagerSerializer.h (revision 0) +++ src/libchcore/ITaskManagerSerializer.h (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,44 @@ +// ============================================================================ +// Copyright (C) 2001-2012 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __ITASKMANAGERSERIALIZER_H__ +#define __ITASKMANAGERSERIALIZER_H__ + +#include "libchcore.h" +#include "ITaskSerializer.h" +#include "TTaskInfo.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API ITaskManagerSerializer +{ +public: + virtual ~ITaskManagerSerializer() {} + + virtual void Setup() = 0; + virtual void Store(const TTaskInfoContainer& tTasksInfo) = 0; + virtual void Load(TTaskInfoContainer& tTasksInfo) = 0; + + virtual ITaskSerializerPtr CreateTaskSerializer(const TSmartPath& pathSerialize) = 0; +}; + +typedef boost::shared_ptr ITaskManagerSerializerPtr; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/ITaskSerializer.h =================================================================== diff -u --- src/libchcore/ITaskSerializer.h (revision 0) +++ src/libchcore/ITaskSerializer.h (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,40 @@ +// ============================================================================ +// Copyright (C) 2001-2013 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __ITASKSERIALIZER_H__ +#define __ITASKSERIALIZER_H__ + +#include "libchcore.h" +#include "TPath.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API ITaskSerializer +{ +public: + virtual ~ITaskSerializer() {} + + virtual TSmartPath GetPath() const = 0; + virtual void Setup() = 0; +}; + +typedef boost::shared_ptr ITaskSerializerPtr; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TSQLiteDatabase.cpp =================================================================== diff -u -r3397fd021739bea537248415a7b4fc2712dd2320 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TSQLiteDatabase.cpp (.../TSQLiteDatabase.cpp) (revision 3397fd021739bea537248415a7b4fc2712dd2320) +++ src/libchcore/TSQLiteDatabase.cpp (.../TSQLiteDatabase.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -41,6 +41,7 @@ TSQLiteDatabase::~TSQLiteDatabase() { int iResult = sqlite3_close_v2(m_pDBHandle); // handles properly the NULL DB Handle + iResult; _ASSERTE(iResult == SQLITE_OK); } Index: src/libchcore/TSQLiteException.cpp =================================================================== diff -u -r3397fd021739bea537248415a7b4fc2712dd2320 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TSQLiteException.cpp (.../TSQLiteException.cpp) (revision 3397fd021739bea537248415a7b4fc2712dd2320) +++ src/libchcore/TSQLiteException.cpp (.../TSQLiteException.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -34,6 +34,11 @@ m_iSQLiteError(iSQLiteError) { } + + int TSQLiteException::GetSQLiteError() const + { + return m_iSQLiteError; + } } END_CHCORE_NAMESPACE Index: src/libchcore/TSQLiteException.h =================================================================== diff -u -r3397fd021739bea537248415a7b4fc2712dd2320 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TSQLiteException.h (.../TSQLiteException.h) (revision 3397fd021739bea537248415a7b4fc2712dd2320) +++ src/libchcore/TSQLiteException.h (.../TSQLiteException.h) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -35,6 +35,8 @@ TSQLiteException(EGeneralErrors eErrorCode, int iSQLiteError, const wchar_t* pszMsg, const wchar_t* pszFile, size_t stLineNumber, const wchar_t* pszFunction); TSQLiteException(EGeneralErrors eErrorCode, int iSQLiteError, const char* pszMsg, const wchar_t* pszFile, size_t stLineNumber, const wchar_t* pszFunction); + int GetSQLiteError() const; + private: int m_iSQLiteError; }; Index: src/libchcore/TSQLiteStatement.cpp =================================================================== diff -u -r3397fd021739bea537248415a7b4fc2712dd2320 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TSQLiteStatement.cpp (.../TSQLiteStatement.cpp) (revision 3397fd021739bea537248415a7b4fc2712dd2320) +++ src/libchcore/TSQLiteStatement.cpp (.../TSQLiteStatement.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -38,6 +38,7 @@ TSQLiteStatement::~TSQLiteStatement() { int iResult = sqlite3_finalize(m_pStatement); + iResult; _ASSERTE(iResult == SQLITE_OK); } @@ -114,6 +115,16 @@ THROW_SQLITE_EXCEPTION(eErr_SQLiteBindError, iResult, _T("Cannot bind a parameter")); } + void TSQLiteStatement::BindValue(int iColumn, unsigned int uiValue) + { + BindValue(iColumn, *(int*)&uiValue); + } + + void TSQLiteStatement::BindValue(int iColumn, unsigned long long ullValue) + { + BindValue(iColumn, *(long long*)&ullValue); + } + void TSQLiteStatement::BindValue(int iColumn, PCTSTR pszText) { if(!m_pStatement) @@ -184,6 +195,17 @@ THROW_SQLITE_EXCEPTION(eErr_SQLiteBindError, iResult, _T("Cannot reset statement")); } + unsigned int TSQLiteStatement::GetUInt(int iCol) + { + int iVal = GetInt(iCol); + return *(unsigned int*)&iVal; + } + + unsigned long long TSQLiteStatement::GetUInt64(int iCol) + { + long long llVal = GetInt64(iCol); + return *(unsigned long long*)&llVal; + } } END_CHCORE_NAMESPACE Index: src/libchcore/TSQLiteStatement.h =================================================================== diff -u -r3397fd021739bea537248415a7b4fc2712dd2320 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TSQLiteStatement.h (.../TSQLiteStatement.h) (revision 3397fd021739bea537248415a7b4fc2712dd2320) +++ src/libchcore/TSQLiteStatement.h (.../TSQLiteStatement.h) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -50,7 +50,9 @@ void BindValue(int iColumn, double dValue); void BindValue(int iColumn, int iValue); + void BindValue(int iColumn, unsigned int uiValue); void BindValue(int iColumn, long long llValue); + void BindValue(int iColumn, unsigned long long ullValue); void BindValue(int iColumn, PCTSTR pszText); void ClearBindings(); @@ -60,7 +62,9 @@ double GetDouble(int iCol); int GetInt(int iCol); + unsigned int GetUInt(int iCol); long long GetInt64(int iCol); + unsigned long long GetUInt64(int iCol); TString GetText(int iCol); private: Index: src/libchcore/TSQLiteTransaction.cpp =================================================================== diff -u -r3397fd021739bea537248415a7b4fc2712dd2320 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TSQLiteTransaction.cpp (.../TSQLiteTransaction.cpp) (revision 3397fd021739bea537248415a7b4fc2712dd2320) +++ src/libchcore/TSQLiteTransaction.cpp (.../TSQLiteTransaction.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -41,6 +41,7 @@ if(m_bTransactionStarted && m_spDatabase->GetInTransaction()) { int iResult = sqlite3_exec((sqlite3*)m_spDatabase->GetHandle(), "ROLLBACK TRANSACTION;", NULL, NULL, NULL); + iResult; _ASSERTE(iResult == SQLITE_OK); m_spDatabase->SetInTransaction(false); } Index: src/libchcore/TSerializerException.cpp =================================================================== diff -u --- src/libchcore/TSerializerException.cpp (revision 0) +++ src/libchcore/TSerializerException.cpp (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,34 @@ +// ============================================================================ +// Copyright (C) 2001-2013 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "TSerializerException.h" + +BEGIN_CHCORE_NAMESPACE + +TSerializerException::TSerializerException(EGeneralErrors eErrorCode, const wchar_t* pszMsg, const wchar_t* pszFile, size_t stLineNumber, const wchar_t* pszFunction) : + TBaseException(eErrorCode, pszMsg, pszFile, stLineNumber, pszFunction) +{ +} + +TSerializerException::TSerializerException(EGeneralErrors eErrorCode, const char* pszMsg, const wchar_t* pszFile, size_t stLineNumber, const wchar_t* pszFunction) : + TBaseException(eErrorCode, pszMsg, pszFile, stLineNumber, pszFunction) +{ +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TSerializerException.h =================================================================== diff -u --- src/libchcore/TSerializerException.h (revision 0) +++ src/libchcore/TSerializerException.h (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,39 @@ +// ============================================================================ +// Copyright (C) 2001-2013 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TSERIALIZEREXCEPTION_H__ +#define __TSERIALIZEREXCEPTION_H__ + +#include "libchcore.h" +#include "TBaseException.h" + +#define THROW_SERIALIZER_EXCEPTION(error_code, err_msg)\ + throw TSerializerException(error_code, err_msg, __FILEW__, __LINE__, __FUNCTIONW__) + +BEGIN_CHCORE_NAMESPACE + +class TSerializerException : public TBaseException +{ +public: + TSerializerException(EGeneralErrors eErrorCode, const wchar_t* pszMsg, const wchar_t* pszFile, size_t stLineNumber, const wchar_t* pszFunction); + TSerializerException(EGeneralErrors eErrorCode, const char* pszMsg, const wchar_t* pszFile, size_t stLineNumber, const wchar_t* pszFunction); +}; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TSerializerVersion.cpp =================================================================== diff -u --- src/libchcore/TSerializerVersion.cpp (revision 0) +++ src/libchcore/TSerializerVersion.cpp (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,99 @@ +// ============================================================================ +// Copyright (C) 2001-2013 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "TSerializerVersion.h" +#include "TSQLiteTransaction.h" +#include "ErrorCodes.h" +#include "TSerializerException.h" +#include "TSQLiteStatement.h" +#include "TSQLiteException.h" +#include "sqlite3\sqlite3.h" + +BEGIN_CHCORE_NAMESPACE + +using namespace sqlite; + +TSerializerVersion::TSerializerVersion(const TSQLiteDatabasePtr& spDatabase) : + m_spDatabase(spDatabase) +{ + if(!spDatabase) + THROW_SERIALIZER_EXCEPTION(eErr_InvalidArgument, _T("No database provided")); +} + +TSerializerVersion::~TSerializerVersion() +{ +} + +void TSerializerVersion::Setup() +{ + TSQLiteTransaction tTransaction(m_spDatabase); + TSQLiteStatement tStatement(m_spDatabase); + + tStatement.Prepare(_T("SELECT count(*) FROM sqlite_master WHERE type=?1 AND name=?2")); + tStatement.BindValue(1, _T("table")); + tStatement.BindValue(2, _T("version")); + if(tStatement.Step() != TSQLiteStatement::eStep_HasRow) + THROW_SQLITE_EXCEPTION(eErr_InternalProblem, SQLITE_ERROR, _T("Problem accessing sqlite_master table")); + + int iVersionCount = tStatement.GetInt(0); + if(iVersionCount == 0) + { + // create table + tStatement.Prepare(_T("CREATE TABLE IF NOT EXISTS version(db_version INT NOT NULL)")); + tStatement.Step(); + + tStatement.Prepare(_T("INSERT INTO version(db_version) VALUES(?1)")); + tStatement.BindValue(1, 0); + tStatement.Step(); + } + + tTransaction.Commit(); +} + +int TSerializerVersion::GetVersion() +{ + TSQLiteTransaction tTransaction(m_spDatabase); + TSQLiteStatement tStatement(m_spDatabase); + + // when table does not exist the sqlite error is just SQLITE_ERROR when preparing statement + tStatement.Prepare(_T("SELECT db_version FROM version")); + if(tStatement.Step() == TSQLiteStatement::eStep_HasRow) + { + tTransaction.Commit(); + return tStatement.GetInt(0); + } + + tTransaction.Commit(); + return 0; +} + +void TSerializerVersion::SetVersion(int iNewVersion) +{ + TSQLiteTransaction tTransaction(m_spDatabase); + TSQLiteStatement tStatement(m_spDatabase); + + // create table + tStatement.Prepare(_T("UPDATE version SET db_version=?1")); + tStatement.BindValue(1, iNewVersion); + tStatement.Step(); + + tTransaction.Commit(); +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TSerializerVersion.h =================================================================== diff -u --- src/libchcore/TSerializerVersion.h (revision 0) +++ src/libchcore/TSerializerVersion.h (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,47 @@ +// ============================================================================ +// Copyright (C) 2001-2012 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TSERIALIZERVERSION_H__ +#define __TSERIALIZERVERSION_H__ + +#include "libchcore.h" +#include "TSQLiteDatabase.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API TSerializerVersion +{ +public: + TSerializerVersion(const sqlite::TSQLiteDatabasePtr& spDatabase); + ~TSerializerVersion(); + + void Setup(); + + int GetVersion(); + void SetVersion(int iNewVersion); + +private: +#pragma warning(push) +#pragma warning(disable: 4251) + sqlite::TSQLiteDatabasePtr m_spDatabase; +#pragma warning(pop) +}; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TTask.cpp =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TTask.cpp (.../TTask.cpp) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TTask.cpp (.../TTask.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -40,19 +40,17 @@ //////////////////////////////////////////////////////////////////////////// // TTask members -TTask::TTask(IFeedbackHandler* piFeedbackHandler, size_t stSessionUniqueID) : +TTask::TTask(const ITaskSerializerPtr& spSerializer, IFeedbackHandler* piFeedbackHandler) : m_log(), m_piFeedbackHandler(piFeedbackHandler), m_arrSourcePathsInfo(m_tTaskDefinition.GetSourcePaths()), m_files(m_tTaskDefinition.GetSourcePaths()), m_bForce(false), m_bContinue(false), - m_bRareStateModified(false), - m_bOftenStateModified(false), - m_stSessionUniqueID(stSessionUniqueID), m_eCurrentState(eTaskState_None), m_tSubTaskContext(m_tTaskDefinition, m_arrSourcePathsInfo, m_files, m_cfgTracker, m_log, piFeedbackHandler, m_workerThread, m_fsLocal), - m_tSubTasksArray() + m_tSubTasksArray(), + m_spSerializer(spSerializer) { BOOST_ASSERT(piFeedbackHandler); } @@ -122,8 +120,9 @@ SetTaskPropValue(m_tTaskDefinition.GetConfiguration(), nPriority); } -void TTask::Load(const TSmartPath& strPath) +void TTask::Load() { +/* using Serializers::Serialize; boost::unique_lock lock(m_lock); @@ -175,11 +174,12 @@ // m_localStats.SetTimeElapsed(timeElapsed); m_arrSourcePathsInfo.Serialize(readSerializer, false); - m_files.Serialize(readSerializer, true); + m_files.Serialize(readSerializer, true);*/ } void TTask::Store() { +/* using Serializers::Serialize; boost::upgrade_lock lock(m_lock); @@ -192,7 +192,7 @@ if(m_strFilePath.IsEmpty()) { boost::upgrade_to_unique_lock upgraded_lock(lock); - m_strFilePath = m_strTaskDirectory + PathFromWString(m_tTaskDefinition.GetTaskUniqueID() + _T(".cht")); + m_strFilePath = m_strTaskDirectory + PathFromWString(m_tTaskDefinition.GetTaskName() + _T(".cht")); } // store task definition only if changed @@ -229,7 +229,7 @@ m_arrSourcePathsInfo.Serialize(writeSerializer, false); m_files.Serialize(writeSerializer, true); - } + }*/ } void TTask::KillThread() @@ -241,9 +241,6 @@ { boost::unique_lock lock(m_lock); - m_bRareStateModified = true; - m_bOftenStateModified = true; - m_workerThread.StartThread(DelegateThreadProc, this, GetTaskPropValue(m_tTaskDefinition.GetConfiguration())); } @@ -285,8 +282,6 @@ { KillThread(); SetTaskState(eTaskState_Paused); - - m_bOftenStateModified = true; } } @@ -297,7 +292,6 @@ { KillThread(); SetTaskState(eTaskState_Cancelled); - m_bOftenStateModified = true; } } @@ -313,8 +307,7 @@ m_tLocalStats.GetSnapshot(spSnapshot); - spSnapshot->SetTaskID(m_tTaskDefinition.GetTaskUniqueID()); - spSnapshot->SetSessionUniqueID(GetSessionUniqueID()); + spSnapshot->SetTaskName(m_tTaskDefinition.GetTaskName()); spSnapshot->SetThreadPriority(GetTaskPropValue(m_tTaskDefinition.GetConfiguration())); spSnapshot->SetDestinationPath(m_tTaskDefinition.GetDestinationPath().ToString()); spSnapshot->SetFilters(m_afFilters); @@ -351,26 +344,6 @@ } } -void TTask::DeleteProgress() -{ - TPathContainer vFilesToRemove; - - // separate scope for shared locking - { - boost::shared_lock lock(m_lock); - - vFilesToRemove.Add(GetRelatedPath(ePathType_TaskDefinition)); - vFilesToRemove.Add(GetRelatedPath(ePathType_TaskRarelyChangingState)); - vFilesToRemove.Add(GetRelatedPath(ePathType_TaskOftenChangingState)); - vFilesToRemove.Add(GetRelatedPath(ePathType_TaskLogFile)); - } - - for(size_t stIndex = 0; stIndex < vFilesToRemove.GetCount(); ++stIndex) - { - DeleteFile(vFilesToRemove.GetAt(stIndex).ToString()); - } -} - bool TTask::CanBegin() { bool bRet=true; @@ -387,18 +360,6 @@ return bRet; } -void TTask::SetTaskDirectory(const TSmartPath& strDir) -{ - boost::unique_lock lock(m_lock); - m_strTaskDirectory = strDir; -} - -TSmartPath TTask::GetTaskDirectory() const -{ - boost::shared_lock lock(m_lock); - return m_strTaskDirectory; -} - void TTask::SetForceFlag(bool bFlag) { boost::unique_lock lock(m_lock); @@ -495,10 +456,8 @@ TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue; // initialize log file - TSmartPath pathLogFile = GetRelatedPath(ePathType_TaskLogFile); + m_log.init(m_pathLog.ToString(), 262144, icpf::log_file::level_debug, false, false); - m_log.init(pathLogFile.ToString(), 262144, icpf::log_file::level_debug, false, false); - // start operation OnBeginOperation(); @@ -570,7 +529,6 @@ m_files.Clear(); // get rid of m_files contents; rare state not modified, since incomplete cache is not being stored // save progress before killed - m_bOftenStateModified = true; Store(); // reset flags @@ -643,43 +601,6 @@ m_workerThread.SignalThreadToStop(); } -TSmartPath TTask::GetRelatedPath(EPathType ePathType) -{ - boost::shared_lock lock(m_lock); - - return GetRelatedPathNL(ePathType); -} - -TSmartPath TTask::GetRelatedPathNL(EPathType ePathType) -{ - BOOST_ASSERT(!m_strTaskDirectory.IsEmpty() || !m_strFilePath.IsEmpty()); - if(m_strTaskDirectory.IsEmpty() && m_strFilePath.IsEmpty()) - THROW_CORE_EXCEPTION(eErr_MissingTaskSerializationPath); - - // in all cases we would like to have task definition path defined - TSmartPath strFilePath = m_strFilePath; - if(strFilePath.IsEmpty()) - strFilePath = m_strTaskDirectory + PathFromWString(m_tTaskDefinition.GetTaskUniqueID() + _T(".cht")); - - switch(ePathType) - { - case ePathType_TaskDefinition: - return strFilePath; - - case ePathType_TaskRarelyChangingState: - return strFilePath.AppendCopy(PathFromString(_T(".rstate")), false); - - case ePathType_TaskOftenChangingState: - return strFilePath.AppendCopy(PathFromString(_T(".ostate")), false); - - case ePathType_TaskLogFile: - return strFilePath.AppendCopy(PathFromString(_T(".log")), false); - - default: - THROW_CORE_EXCEPTION(eErr_UnhandledCase); - } -} - void TTask::OnCfgOptionChanged(const TStringSet& rsetChanges, void* pParam) { TTask* pTask = (TTask*)pParam; @@ -697,4 +618,19 @@ return m_tLocalStats.IsRunning(); } +TSmartPath TTask::GetSerializerPath() const +{ + return m_spSerializer->GetPath(); +} + +chcore::TSmartPath TTask::GetLogPath() const +{ + return m_pathLog; +} + +void TTask::SetLogPath(const TSmartPath& pathLog) +{ + m_pathLog = pathLog; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TTask.h =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TTask.h (.../TTask.h) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TTask.h (.../TTask.h) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -33,6 +33,7 @@ #include "TSubTaskArray.h" #include "TSubTaskContext.h" #include "TTaskStatsSnapshot.h" +#include "ITaskSerializer.h" BEGIN_CHCORE_NAMESPACE @@ -43,14 +44,8 @@ class LIBCHCORE_API TTask { -public: - enum EPathType - { - ePathType_TaskDefinition, - ePathType_TaskRarelyChangingState, - ePathType_TaskOftenChangingState, - ePathType_TaskLogFile, - }; +private: + TTask(const ITaskSerializerPtr& spSerializer, IFeedbackHandler* piFeedbackHandler); public: ~TTask(); @@ -66,10 +61,12 @@ void SetBufferSizes(const TBufferSizes& bsSizes); void GetBufferSizes(TBufferSizes& bsSizes); + TSmartPath GetLogPath() const; + // thread void SetPriority(int nPriority); - void Load(const TSmartPath& strPath); + void Load(); void Store(); void BeginProcessing(); @@ -82,21 +79,14 @@ void GetStatsSnapshot(TTaskStatsSnapshotPtr& spSnapshot); - void SetTaskDirectory(const TSmartPath& strDir); - TSmartPath GetTaskDirectory() const; - void SetForceFlag(bool bFlag = true); bool GetForceFlag(); - size_t GetSessionUniqueID() const { return m_stSessionUniqueID; } - - TSmartPath GetRelatedPath(EPathType ePathType); - private: - TTask(IFeedbackHandler* piFeedbackHandler, size_t stSessionUniqueID); - void SetTaskDefinition(const TTaskDefinition& rTaskDefinition); + void SetLogPath(const TSmartPath& pathLog); + // methods are called when task is being added or removed from the global task array /// Method is called when this task is being added to a TTaskManager object void OnRegisterTask(); @@ -120,8 +110,6 @@ void SetStatusNL(UINT nStatus, UINT nMask); UINT GetStatusNL(UINT nMask = 0xffffffff); - void DeleteProgress(); - void SetForceFlagNL(bool bFlag = true); bool GetForceFlagNL(); @@ -135,11 +123,15 @@ void KillThread(); void RequestStopThread(); - TSmartPath GetRelatedPathNL(EPathType ePathType); - static void OnCfgOptionChanged(const TStringSet& rsetChanges, void* pParam); + TSmartPath GetSerializerPath() const; private: +#pragma warning(push) +#pragma warning(disable: 4251) + ITaskSerializerPtr m_spSerializer; +#pragma warning(pop) + // task initial information (needed to start a task); might be a bit processed. TTaskDefinition m_tTaskDefinition; @@ -163,15 +155,8 @@ bool m_bForce; // if the continuation of tasks should be independent of max concurrently running task limit bool m_bContinue; // allows task to continue - TSmartPath m_strTaskDirectory; // base path at which the files will be stored - TSmartPath m_strFilePath; // exact filename with path to the task definition file - - bool m_bRareStateModified; // rarely changing state has been modified - bool m_bOftenStateModified; // rarely changing state has been modified - - size_t m_stSessionUniqueID; ///< Per-session unique ID for this task - // other helpers + TSmartPath m_pathLog; icpf::log_file m_log; ///< Log file where task information will be stored // Local filesystem access Index: src/libchcore/TTaskDefinition.cpp =================================================================== diff -u -r548382442cbf7bed7f744b279ce3f66b54992724 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TTaskDefinition.cpp (.../TTaskDefinition.cpp) (revision 548382442cbf7bed7f744b279ce3f66b54992724) +++ src/libchcore/TTaskDefinition.cpp (.../TTaskDefinition.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -36,16 +36,16 @@ TTaskDefinition::TTaskDefinition() : m_bModified(false), - m_strTaskUniqueID(), + m_strTaskName(), m_ullTaskVersion(CURRENT_TASK_VERSION) { boost::uuids::random_generator gen; boost::uuids::uuid u = gen(); - m_strTaskUniqueID = boost::lexical_cast(u).c_str(); + m_strTaskName = boost::lexical_cast(u).c_str(); } TTaskDefinition::TTaskDefinition(const TTaskDefinition& rSrc) : - m_strTaskUniqueID(rSrc.m_strTaskUniqueID), + m_strTaskName(rSrc.m_strTaskName), m_vSourcePaths(rSrc.m_vSourcePaths), m_pathDestinationPath(rSrc.m_pathDestinationPath), m_tOperationPlan(rSrc.m_tOperationPlan), @@ -63,7 +63,7 @@ { if(this != &rSrc) { - m_strTaskUniqueID = rSrc.m_strTaskUniqueID; + m_strTaskName = rSrc.m_strTaskName; m_vSourcePaths = rSrc.m_vSourcePaths; m_pathDestinationPath = rSrc.m_pathDestinationPath; m_tOperationPlan = rSrc.m_tOperationPlan; @@ -76,9 +76,9 @@ } // Task unique id -TString TTaskDefinition::GetTaskUniqueID() const +TString TTaskDefinition::GetTaskName() const { - return m_strTaskUniqueID; + return m_strTaskName; } // Source paths @@ -170,7 +170,7 @@ tTaskInfo.Read(strPath.ToString()); // clear everything - m_strTaskUniqueID.Clear(); + m_strTaskName.Clear(); m_vSourcePaths.Clear(); m_pathDestinationPath.Clear(); @@ -180,11 +180,11 @@ // get information from config file // task unique id - use if provided, generate otherwise - if(!GetConfigValue(tTaskInfo, _T("TaskDefinition.UniqueID"), m_strTaskUniqueID) || m_strTaskUniqueID.IsEmpty()) + if(!GetConfigValue(tTaskInfo, _T("TaskDefinition.UniqueID"), m_strTaskName) || m_strTaskName.IsEmpty()) { boost::uuids::random_generator gen; boost::uuids::uuid u = gen(); - m_strTaskUniqueID = boost::lexical_cast(u).c_str(); + m_strTaskName = boost::lexical_cast(u).c_str(); m_bModified = true; } @@ -236,7 +236,7 @@ // get information from config file // task unique id - use if provided, generate otherwise - SetConfigValue(tTaskInfo, _T("TaskDefinition.UniqueID"), m_strTaskUniqueID); + SetConfigValue(tTaskInfo, _T("TaskDefinition.UniqueID"), m_strTaskName); // basic information SetConfigValue(tTaskInfo, _T("TaskDefinition.SourcePaths.Path"), m_vSourcePaths); @@ -262,7 +262,7 @@ // get information from config file // task unique id - use if provided, generate otherwise - SetConfigValue(tTaskInfo, _T("TaskDefinition.UniqueID"), m_strTaskUniqueID); + SetConfigValue(tTaskInfo, _T("TaskDefinition.UniqueID"), m_strTaskName); // basic information SetConfigValue(tTaskInfo, _T("TaskDefinition.SourcePaths.Path"), m_vSourcePaths); @@ -285,7 +285,7 @@ tTaskInfo.ReadFromString(strInput); // clear everything - m_strTaskUniqueID.Clear(); + m_strTaskName.Clear(); m_vSourcePaths.Clear(); m_pathDestinationPath.Clear(); @@ -295,11 +295,11 @@ // get information from config file // task unique id - use if provided, generate otherwise - if(!GetConfigValue(tTaskInfo, _T("TaskDefinition.UniqueID"), m_strTaskUniqueID) || m_strTaskUniqueID.IsEmpty()) + if(!GetConfigValue(tTaskInfo, _T("TaskDefinition.UniqueID"), m_strTaskName) || m_strTaskName.IsEmpty()) { boost::uuids::random_generator gen; boost::uuids::uuid u = gen(); - m_strTaskUniqueID = boost::lexical_cast(u).c_str(); + m_strTaskName = boost::lexical_cast(u).c_str(); m_bModified = true; } Index: src/libchcore/TTaskDefinition.h =================================================================== diff -u -r5fd6beaad9f1eccb664b997d151acb59961e4827 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TTaskDefinition.h (.../TTaskDefinition.h) (revision 5fd6beaad9f1eccb664b997d151acb59961e4827) +++ src/libchcore/TTaskDefinition.h (.../TTaskDefinition.h) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -45,7 +45,7 @@ TTaskDefinition& operator=(const TTaskDefinition& rSrc); // Task unique ID - TString GetTaskUniqueID() const; + TString GetTaskName() const; // Source paths void AddSourcePath(const TSmartPath& tPath); @@ -78,7 +78,7 @@ void LoadFromString(const TString& strInput); private: - TString m_strTaskUniqueID; ///< Unique ID of the task that will process this request (generated automatically) + TString m_strTaskName; ///< Unique ID of the task that will process this request (generated automatically) // basic information TPathContainer m_vSourcePaths; Index: src/libchcore/TTaskInfo.cpp =================================================================== diff -u --- src/libchcore/TTaskInfo.cpp (revision 0) +++ src/libchcore/TTaskInfo.cpp (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,272 @@ +// ============================================================================ +// Copyright (C) 2001-2013 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "TTaskInfo.h" +#include "TCoreException.h" + +BEGIN_CHCORE_NAMESPACE + +TTaskInfoEntry::TTaskInfoEntry() : + m_tTaskID(0), + m_iOrder(0), + m_iModificationType(eMod_None) +{ +} + +TTaskInfoEntry::TTaskInfoEntry(taskid_t tTaskID, const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask, int iModification /*= eMod_None*/) : + m_tTaskID(tTaskID), + m_pathTask(pathTask), + m_iOrder(iOrder), + m_spTask(spTask), + m_iModificationType(iModification) +{ +} + +taskid_t TTaskInfoEntry::GetTaskID() const +{ + return m_tTaskID; +} + +void TTaskInfoEntry::SetTaskID(taskid_t tTaskID) +{ + m_tTaskID = tTaskID; +} + +TSmartPath TTaskInfoEntry::GetTaskPath() const +{ + return m_pathTask; +} + +void TTaskInfoEntry::SetTaskPath(const TSmartPath& strTaskPath) +{ + SetModification(eMod_TaskPath, eMod_TaskPath); + m_pathTask = strTaskPath; +} + +TTaskPtr TTaskInfoEntry::GetTask() const +{ + return m_spTask; +} + +void TTaskInfoEntry::SetTask(const TTaskPtr& spTask) +{ + m_spTask = spTask; +} + +int TTaskInfoEntry::GetOrder() const +{ + return m_iOrder; +} + +void TTaskInfoEntry::SetOrder(int iOrder) +{ + SetModification(eMod_Order, eMod_Order); + m_iOrder = iOrder; +} + +int TTaskInfoEntry::GetModifications() const +{ + return m_iModificationType; +} + +void TTaskInfoEntry::SetModification(int iModification, int iMask) +{ + m_iModificationType &= ~iMask; + m_iModificationType |= iModification; +} + +void TTaskInfoEntry::ResetModifications() +{ + m_iModificationType = 0; +} + +bool TTaskInfoEntry::IsAdded() const +{ + return m_iModificationType & eMod_Added; +} + +bool TTaskInfoEntry::IsModified() const +{ + return (m_iModificationType & ~eMod_Added) != eMod_None; +} + + +TTaskInfoContainer::TTaskInfoContainer() +{ +} + +void TTaskInfoContainer::Add(taskid_t tTaskID, const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask) +{ + m_vTaskInfos.push_back(TTaskInfoEntry(tTaskID, pathTask, iOrder, spTask, TTaskInfoEntry::eMod_Added)); +} + +void TTaskInfoContainer::RemoveAt(size_t stIndex) +{ + if(stIndex >= m_vTaskInfos.size()) + THROW_CORE_EXCEPTION(eErr_BoundsExceeded); + + std::vector::iterator iter = m_vTaskInfos.begin() + stIndex; + taskid_t tTaskID = (*iter).GetTaskID(); + m_vTaskInfos.erase(m_vTaskInfos.begin() + stIndex); + m_setRemovedTasks.insert(tTaskID); +} + +void TTaskInfoContainer::Clear() +{ + BOOST_FOREACH(TTaskInfoEntry& rEntry, m_vTaskInfos) + { + m_setRemovedTasks.insert(rEntry.GetTaskID()); + } + m_vTaskInfos.clear(); +} + +TTaskInfoEntry& TTaskInfoContainer::GetAt(size_t stIndex) +{ + if(stIndex >= m_vTaskInfos.size()) + THROW_CORE_EXCEPTION(eErr_BoundsExceeded); + + return m_vTaskInfos[stIndex]; +} + +const TTaskInfoEntry& TTaskInfoContainer::GetAt(size_t stIndex) const +{ + if(stIndex >= m_vTaskInfos.size()) + THROW_CORE_EXCEPTION(eErr_BoundsExceeded); + + return m_vTaskInfos[stIndex]; +} + +size_t TTaskInfoContainer::GetCount() const +{ + return m_vTaskInfos.size(); +} + +bool TTaskInfoContainer::GetByTaskID(taskid_t tTaskID, TTaskInfoEntry& rInfo) const +{ + for(std::vector::const_iterator iter = m_vTaskInfos.begin(); iter != m_vTaskInfos.end(); ++iter) + { + if((*iter).GetTaskID() == tTaskID) + { + rInfo = *iter; + return true; + } + } + + return false; +} + +bool TTaskInfoContainer::IsEmpty() const +{ + return m_vTaskInfos.empty(); +} + +void TTaskInfoContainer::GetDiffAndResetModifications(TTaskInfoContainer& rDiff) +{ + rDiff.Clear(); + rDiff.ClearModifications(); + + rDiff.m_setRemovedTasks.insert(m_setRemovedTasks.begin(), m_setRemovedTasks.end()); + BOOST_FOREACH(TTaskInfoEntry& rEntry, m_vTaskInfos) + { + if(rEntry.GetModifications() != TTaskInfoEntry::eMod_None) + rDiff.m_vTaskInfos.push_back(rEntry); + } + + ClearModifications(); +} + +bool TTaskInfoContainer::HasDeletions() const +{ + return !m_setRemovedTasks.empty(); +} + +bool TTaskInfoContainer::HasAdditions() const +{ + BOOST_FOREACH(const TTaskInfoEntry& rEntry, m_vTaskInfos) + { + if(rEntry.IsAdded()) + return true; + } + + return false; +} + +bool TTaskInfoContainer::HasModifications() const +{ + BOOST_FOREACH(const TTaskInfoEntry& rEntry, m_vTaskInfos) + { + // if marked as added, we don't consider it modified anymore + if(rEntry.IsModified()) + return true; + } + + return false; +} + +size_t TTaskInfoContainer::GetDeletedCount() const +{ + return m_setRemovedTasks.size(); +} + +chcore::taskid_t TTaskInfoContainer::GetDeletedAt(size_t stIndex) const +{ + if(stIndex >= m_setRemovedTasks.size()) + THROW_CORE_EXCEPTION(eErr_BoundsExceeded); + + std::set::const_iterator iter = m_setRemovedTasks.begin(); + std::advance(iter, stIndex); + + return *iter; +} + +void TTaskInfoContainer::RestoreModifications(const TTaskInfoContainer& tDataDiff) throw() +{ + m_setRemovedTasks.insert(tDataDiff.m_setRemovedTasks.begin(), tDataDiff.m_setRemovedTasks.end()); + + for(std::vector::const_iterator iterOther = tDataDiff.m_vTaskInfos.begin(); iterOther != tDataDiff.m_vTaskInfos.end(); ++iterOther) + { + bool bFound = false; + + for(std::vector::iterator iterThis = m_vTaskInfos.begin(); iterThis != m_vTaskInfos.end(); ++iterThis) + { + if((*iterThis).GetTaskID() == (*iterOther).GetTaskID()) + { + (*iterThis).SetModification((*iterOther).GetModifications(), (*iterOther).GetModifications()); + bFound = true; + break; + } + } + + // this method is used in catch clause, so no exception allowed here + _ASSERTE(bFound); + } +} + +void TTaskInfoContainer::ClearModifications() +{ + m_setRemovedTasks.clear(); + + BOOST_FOREACH(TTaskInfoEntry& rEntry, m_vTaskInfos) + { + // if marked as added, we don't consider it modified anymore + rEntry.ResetModifications(); + } +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TTaskInfo.h =================================================================== diff -u --- src/libchcore/TTaskInfo.h (revision 0) +++ src/libchcore/TTaskInfo.h (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,118 @@ +// ============================================================================ +// Copyright (C) 2001-2013 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TTASKINFO_H__ +#define __TTASKINFO_H__ + +#include "libchcore.h" +#include "TString.h" +#include +#include "TPath.h" +#include "TaskID.h" + +BEGIN_CHCORE_NAMESPACE + +class TTask; +typedef boost::shared_ptr TTaskPtr; + +class LIBCHCORE_API TTaskInfoEntry +{ +public: + enum EModificationInfo + { + eMod_None = 0, + eMod_Added = 1, + eMod_TaskPath = 4, + eMod_Order = 8, + }; + +public: + TTaskInfoEntry(); + TTaskInfoEntry(taskid_t tTaskID, const TSmartPath& pathTask, int iOrder, const TTaskPtr& spTask, int iModification = eMod_None); + + taskid_t GetTaskID() const; + void SetTaskID(taskid_t tTaskID); + + TSmartPath GetTaskPath() const; + void SetTaskPath(const TSmartPath& pathTask); + + TTaskPtr GetTask() const; + void SetTask(const TTaskPtr& spTask); + + int GetOrder() const; + void SetOrder(int iOrder); + + int GetModifications() const; + void SetModification(int iModification, int iMask); + void ResetModifications(); + + bool IsAdded() const; + bool IsModified() const; + +private: + taskid_t m_tTaskID; + TSmartPath m_pathTask; +#pragma warning(push) +#pragma warning(disable:4251) + TTaskPtr m_spTask; +#pragma warning(pop) + int m_iOrder; + int m_iModificationType; // added/modified/not changed (wo deleted status) +}; + +class LIBCHCORE_API TTaskInfoContainer +{ +public: + TTaskInfoContainer(); + + void Add(taskid_t tTaskID, const TSmartPath& strPath, int iOrder, const TTaskPtr& spTask); + void RemoveAt(size_t stIndex); + + TTaskInfoEntry& GetAt(size_t stIndex); + const TTaskInfoEntry& GetAt(size_t stIndex) const; + + bool GetByTaskID(taskid_t tTaskID, TTaskInfoEntry& rInfo) const; + + size_t GetCount() const; + bool IsEmpty() const; + + void Clear(); + + size_t GetDeletedCount() const; + taskid_t GetDeletedAt(size_t stIndex) const; + + // modifications management + void GetDiffAndResetModifications(TTaskInfoContainer& rDiff); + void RestoreModifications(const TTaskInfoContainer& tDataDiff) throw(); + void ClearModifications(); + + bool HasDeletions() const; + bool HasAdditions() const; + bool HasModifications() const; + +private: +#pragma warning(push) +#pragma warning(disable:4251) + std::vector m_vTaskInfos; + std::set m_setRemovedTasks; +#pragma warning(pop) +}; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TTaskManager.cpp =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TTaskManager.cpp (.../TTaskManager.cpp) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TTaskManager.cpp (.../TTaskManager.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -28,14 +28,20 @@ #include "TTaskManagerStatsSnapshot.h" #include "TCoreException.h" #include "ErrorCodes.h" +#include "TTaskInfo.h" +#include +#include +#include +#include BEGIN_CHCORE_NAMESPACE //////////////////////////////////////////////////////////////////////////////// // TTaskManager members -TTaskManager::TTaskManager() : +TTaskManager::TTaskManager(const ITaskManagerSerializerPtr& spSerializer) : m_piFeedbackFactory(NULL), - m_stNextSessionUniqueID(NO_TASK_SESSION_UNIQUE_ID + 1) + m_stNextTaskID(NoTaskID + 1), + m_spSerializer(spSerializer) { } @@ -53,14 +59,21 @@ TTaskPtr TTaskManager::CreateTask(const TTaskDefinition& tTaskDefinition) { - TTaskPtr spTask = CreateEmptyTask(); - if(spTask) - { - spTask->SetTaskDefinition(tTaskDefinition); - Add(spTask); - spTask->Store(); - } + TString strUuid = GetUuid(); + TSmartPath pathTaskSerializer = CreateTaskSerializePath(strUuid); + TSmartPath pathTaskLog = CreateTaskLogPath(strUuid); + IFeedbackHandler* piHandler = CreateNewFeedbackHandler(); + ITaskSerializerPtr spSerializer = m_spSerializer->CreateTaskSerializer(pathTaskSerializer); + + TTaskPtr spTask(new TTask(spSerializer, piHandler)); + spTask->SetLogPath(pathTaskLog); + spTask->SetTaskDefinition(tTaskDefinition); + + Add(spTask); + + spTask->Store(); + return spTask; } @@ -73,165 +86,136 @@ return CreateTask(tTaskDefinition); } -TTaskPtr TTaskManager::CreateEmptyTask() -{ - BOOST_ASSERT(m_piFeedbackFactory); - if(!m_piFeedbackFactory) - return TTaskPtr(); - - IFeedbackHandler* piHandler = m_piFeedbackFactory->Create(); - if(!piHandler) - return TTaskPtr(); - - BOOST_ASSERT(m_stNextSessionUniqueID != NO_TASK_SESSION_UNIQUE_ID); - TTaskPtr spTask(new TTask(piHandler, m_stNextSessionUniqueID++)); - - // NO_TASK_SESSION_UNIQUE_ID is a special value so it should not be used to identify tasks - if(m_stNextSessionUniqueID == NO_TASK_SESSION_UNIQUE_ID) - ++m_stNextSessionUniqueID; - - return spTask; -} - size_t TTaskManager::GetSize() const { boost::shared_lock lock(m_lock); - return m_vTasks.size(); + return m_tTasks.GetCount(); } TTaskPtr TTaskManager::GetAt(size_t nIndex) const { boost::shared_lock lock(m_lock); - - _ASSERTE(nIndex >= 0 && nIndex < m_vTasks.size()); - if(nIndex >= m_vTasks.size()) - THROW_CORE_EXCEPTION(eErr_InvalidArgument); - - return m_vTasks.at(nIndex); + const TTaskInfoEntry& rInfo = m_tTasks.GetAt(nIndex); + return rInfo.GetTask(); } -TTaskPtr TTaskManager::GetTaskBySessionUniqueID(size_t stSessionUniqueID) const +TTaskPtr TTaskManager::GetTaskByTaskID(taskid_t tTaskID) const { - if(stSessionUniqueID == NO_TASK_SESSION_UNIQUE_ID) + if(tTaskID == NoTaskID) return TTaskPtr(); - TTaskPtr spFoundTask; + TTaskInfoEntry tEntry; boost::shared_lock lock(m_lock); - BOOST_FOREACH(const TTaskPtr& spTask, m_vTasks) - { - if(spTask->GetSessionUniqueID() == stSessionUniqueID) - { - spFoundTask = spTask; - break; - } - } - return spFoundTask; + if(!m_tTasks.GetByTaskID(tTaskID, tEntry)) + return TTaskPtr(); + + return tEntry.GetTask(); } -size_t TTaskManager::Add(const TTaskPtr& spNewTask) +void TTaskManager::Add(const TTaskPtr& spNewTask) { if(!spNewTask) THROW_CORE_EXCEPTION(eErr_InvalidArgument); boost::unique_lock lock(m_lock); - // here we know load succeeded - spNewTask->SetTaskDirectory(m_pathTasksDir); - m_vTasks.push_back(spNewTask); + int iOrder = 1; + if(!m_tTasks.IsEmpty()) + { + const TTaskInfoEntry& rEntry = m_tTasks.GetAt(m_tTasks.GetCount() - 1); + iOrder = rEntry.GetOrder() + 1; + } - spNewTask->OnRegisterTask(); + m_tTasks.Add(m_stNextTaskID++, spNewTask->GetSerializerPath(), iOrder, spNewTask); - return m_vTasks.size() - 1; + spNewTask->OnRegisterTask(); } -void TTaskManager::RemoveAt(size_t stIndex, size_t stCount) +void TTaskManager::ClearBeforeExit() { - boost::unique_lock lock(m_lock); + StopAllTasks(); - _ASSERTE(stIndex >= m_vTasks.size() || stIndex + stCount > m_vTasks.size()); - if(stIndex >= m_vTasks.size() || stIndex + stCount > m_vTasks.size()) - THROW_CORE_EXCEPTION(eErr_InvalidArgument); + // ensure everything is stored so that we can resume processing in the future + Store(); - for(std::vector::iterator iterTask = m_vTasks.begin() + stIndex; iterTask != m_vTasks.begin() + stIndex + stCount; ++iterTask) + // now remove all tasks without serializing anymore (prevent accidental + // serialization) { - TTaskPtr& spTask = *iterTask; - - // kill task if needed - spTask->KillThread(); - - spTask->OnUnregisterTask(); + boost::unique_lock lock(m_lock); + m_tTasks.Clear(); + m_tTasks.ClearModifications(); } - - // remove elements from array - m_vTasks.erase(m_vTasks.begin() + stIndex, m_vTasks.begin() + stIndex + stCount); } -void TTaskManager::RemoveAll() -{ - boost::unique_lock lock(m_lock); - - StopAllTasksNL(); - - m_vTasks.clear(); -} - void TTaskManager::RemoveAllFinished() { - std::vector vTasksToRemove; + std::vector vTasksToRemove; // separate scope for locking { boost::unique_lock lock(m_lock); - size_t stIndex = m_vTasks.size(); + size_t stIndex = m_tTasks.GetCount(); while(stIndex--) { - TTaskPtr spTask = m_vTasks.at(stIndex); + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); // delete only when the thread is finished if((spTask->GetTaskState() == eTaskState_Finished || spTask->GetTaskState() == eTaskState_Cancelled)) { + spTask->KillThread(); + spTask->OnUnregisterTask(); - vTasksToRemove.push_back(spTask); - m_vTasks.erase(m_vTasks.begin() + stIndex); + vTasksToRemove.push_back(rEntry.GetTaskPath()); + m_tTasks.RemoveAt(stIndex); } } } - BOOST_FOREACH(TTaskPtr& spTask, vTasksToRemove) + BOOST_FOREACH(TSmartPath& spTaskPath, vTasksToRemove) { // delete associated files - spTask->DeleteProgress(); + DeleteFile(spTaskPath.ToString()); } } void TTaskManager::RemoveFinished(const TTaskPtr& spSelTask) { - boost::unique_lock lock(m_lock); + std::vector vTasksToRemove; - // this might be optimized by copying tasks to a local table in critical section, and then deleting progress files outside of the critical section - for(std::vector::iterator iterTask = m_vTasks.begin(); iterTask != m_vTasks.end(); ++iterTask) + // separate scope for locking { - TTaskPtr& spTask = *iterTask; + boost::unique_lock lock(m_lock); - if(spTask == spSelTask && (spTask->GetTaskState() == eTaskState_Finished || spTask->GetTaskState() == eTaskState_Cancelled)) + size_t stIndex = m_tTasks.GetCount(); + while(stIndex--) { - // kill task if needed - spTask->KillThread(); + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); - spTask->OnUnregisterTask(); + // delete only when the thread is finished + if(spTask == spSelTask && (spTask->GetTaskState() == eTaskState_Finished || spTask->GetTaskState() == eTaskState_Cancelled)) + { + spTask->KillThread(); - // delete associated files - spTask->DeleteProgress(); + spTask->OnUnregisterTask(); - m_vTasks.erase(iterTask); - - return; + vTasksToRemove.push_back(rEntry.GetTaskPath()); + m_tTasks.RemoveAt(stIndex); + break; + } } } + + BOOST_FOREACH(TSmartPath& spTaskPath, vTasksToRemove) + { + // delete associated files + DeleteFile(spTaskPath.ToString()); + } } void TTaskManager::StopAllTasks() @@ -252,8 +236,11 @@ if(stTasksToRun > 0) { - BOOST_FOREACH(TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); + // turn on some thread - find something with wait state if(spTask->GetTaskState() == eTaskState_Waiting) { @@ -265,105 +252,46 @@ } } -void TTaskManager::SaveData() -{ - boost::shared_lock lock(m_lock); - BOOST_FOREACH(TTaskPtr& spTask, m_vTasks) - { - spTask->Store(); - } -} - -void TTaskManager::LoadDataProgress() -{ - if(m_pathTasksDir.IsEmpty()) - THROW_CORE_EXCEPTION(eErr_MissingTaskSerializationPath); - - TTaskPtr spTask; - TSmartPath pathFound; - WIN32_FIND_DATA wfd; - bool bExceptionEncountered = false; - - const size_t stMaxMsgSize = 4096; - boost::shared_array spMsgBuffer(new wchar_t[stMaxMsgSize]); - spMsgBuffer[0] = _T('\0'); - - // find all CH Task files - TSmartPath pathToFind = m_pathTasksDir + PathFromString(_T("*.cht")); - - HANDLE hFind = ::FindFirstFile(pathToFind.ToString(), &wfd); - BOOL bContinue = TRUE; - while(hFind != INVALID_HANDLE_VALUE && bContinue) - { - pathFound = m_pathTasksDir + PathFromString(wfd.cFileName); - // load data - spTask = CreateEmptyTask(); - try - { - spTask->Load(pathFound); - - // add read task to array - Add(spTask); - } - catch(icpf::exception& e) - { - e.get_info(spMsgBuffer.get(), stMaxMsgSize); - bExceptionEncountered = true; - } - catch(std::exception& e) - { - _tcsncpy_s(spMsgBuffer.get(), stMaxMsgSize, CA2CT(e.what()), _TRUNCATE); - bExceptionEncountered = true; - } - - if(bExceptionEncountered) - { - TString strFmt = _T("Cannot load task data: %path (reason: %reason)"); - strFmt.Replace(_T("%path"), pathFound.ToString()); - strFmt.Replace(_T("%reason"), spMsgBuffer.get()); - - LOG_ERROR(strFmt); - - bExceptionEncountered = false; - } - bContinue = ::FindNextFile(hFind, &wfd); - } - - ::FindClose(hFind); -} - void TTaskManager::TasksBeginProcessing() { boost::shared_lock lock(m_lock); - BOOST_FOREACH(TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); spTask->BeginProcessing(); } } void TTaskManager::TasksPauseProcessing() { boost::shared_lock lock(m_lock); - BOOST_FOREACH(TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); spTask->PauseProcessing(); } } void TTaskManager::TasksResumeProcessing() { boost::shared_lock lock(m_lock); - BOOST_FOREACH(TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); spTask->ResumeProcessing(); } } void TTaskManager::TasksRestartProcessing() { boost::shared_lock lock(m_lock); - BOOST_FOREACH(TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); spTask->RestartProcessing(); } } @@ -372,8 +300,10 @@ { boost::shared_lock lock(m_lock); bool bChanged=false; - BOOST_FOREACH(TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); if(spTask->RetryProcessing()) bChanged = true; } @@ -384,8 +314,10 @@ void TTaskManager::TasksCancelProcessing() { boost::shared_lock lock(m_lock); - BOOST_FOREACH(TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); spTask->CancelProcessing(); } } @@ -399,8 +331,11 @@ else { boost::shared_lock lock(m_lock); - BOOST_FOREACH(TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); + ETaskCurrentState eState = spTask->GetTaskState(); bFlag = (eState == eTaskState_Finished || eState == eTaskState_Cancelled || eState == eTaskState_Paused || eState == eTaskState_Error); @@ -412,12 +347,6 @@ return bFlag; } -void TTaskManager::SetTasksDir(const TSmartPath& pathDir) -{ - boost::unique_lock lock(m_lock); - m_pathTasksDir = pathDir; -} - void TTaskManager::GetStatsSnapshot(TTaskManagerStatsSnapshotPtr& spSnapshot) const { if(!spSnapshot) @@ -428,10 +357,13 @@ boost::shared_lock lock(m_lock); size_t stRunningTasks = 0; - BOOST_FOREACH(const TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + const TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); TTaskStatsSnapshotPtr spStats(new TTaskStatsSnapshot); spTask->GetStatsSnapshot(spStats); + spStats->SetTaskID(rEntry.GetTaskID()); if(spStats->IsTaskRunning() && spStats->GetTaskState()) ++stRunningTasks; @@ -450,8 +382,10 @@ size_t stRunningTasks = 0; - BOOST_FOREACH(const TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + const TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); if(spTask->IsRunning() && spTask->GetTaskState() == eTaskState_Processing) ++stRunningTasks; } @@ -462,16 +396,114 @@ void TTaskManager::StopAllTasksNL() { // kill all unfinished tasks - send kill request - BOOST_FOREACH(TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); spTask->RequestStopThread(); } // wait for finishing - BOOST_FOREACH(TTaskPtr& spTask, m_vTasks) + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); spTask->KillThread(); } } +IFeedbackHandler* TTaskManager::CreateNewFeedbackHandler() +{ + BOOST_ASSERT(m_piFeedbackFactory); + if(!m_piFeedbackFactory) + return NULL; + + IFeedbackHandler* piHandler = m_piFeedbackFactory->Create(); + + return piHandler; +} + +void TTaskManager::Store() +{ + // store this container information + TTaskInfoContainer tDataDiff; + { + boost::shared_lock lock(m_lock); + m_tTasks.GetDiffAndResetModifications(tDataDiff); + } + + try + { + m_spSerializer->Store(tDataDiff); + } + catch(const std::exception&) + { + boost::unique_lock lock(m_lock); + m_tTasks.RestoreModifications(tDataDiff); + + throw; + } + + // trigger storing tasks + boost::shared_lock lock(m_lock); + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) + { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + TTaskPtr spTask = rEntry.GetTask(); + + spTask->Store(); + } + +} + +void TTaskManager::Load() +{ + boost::unique_lock lock(m_lock); + + if(!m_tTasks.IsEmpty()) + THROW_CORE_EXCEPTION(eErr_InternalProblem); + + m_spSerializer->Load(m_tTasks); + + // clear all modifications of freshly loaded tasks (in case serializer does + // not reset the modification state) + m_tTasks.ClearModifications(); + + // load tasks + for(size_t stIndex = 0; stIndex < m_tTasks.GetCount(); ++stIndex) + { + TTaskInfoEntry& rEntry = m_tTasks.GetAt(stIndex); + + if(!rEntry.GetTask()) + { + IFeedbackHandler* piHandler = CreateNewFeedbackHandler(); + ITaskSerializerPtr spSerializer = m_spSerializer->CreateTaskSerializer(rEntry.GetTaskPath()); + + TTaskPtr spTask(new TTask(spSerializer, piHandler)); + spTask->Load(); + + rEntry.SetTask(spTask); + } + } +} + +TString TTaskManager::GetUuid() +{ + boost::uuids::random_generator gen; + boost::uuids::uuid u = gen(); + return boost::lexical_cast(u).c_str(); +} + +TSmartPath TTaskManager::CreateTaskLogPath(const TString& strUuid) const +{ + TSmartPath pathLog = m_pathLogDir + PathFromString(TString(_T("Task-")) + strUuid + _T(".log")); + return pathLog; +} + +chcore::TSmartPath TTaskManager::CreateTaskSerializePath(const TString& strUuid) const +{ + TSmartPath pathLog = m_pathLogDir + PathFromString(TString(_T("Task-")) + strUuid + _T(".sqlite")); + return pathLog; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TTaskManager.h =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TTaskManager.h (.../TTaskManager.h) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TTaskManager.h (.../TTaskManager.h) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -23,48 +23,46 @@ #include "FeedbackHandlerBase.h" #include "TPath.h" #include "TTaskManagerStatsSnapshot.h" +#include "TTaskInfo.h" +#include "ITaskManagerSerializer.h" BEGIN_CHCORE_NAMESPACE class TTaskDefinition; class TTask; typedef boost::shared_ptr TTaskPtr; -// special value representing no task -#define NO_TASK_SESSION_UNIQUE_ID 0 - /////////////////////////////////////////////////////////////////////////// // TTaskManager - class LIBCHCORE_API TTaskManager { public: - TTaskManager(); + TTaskManager(const ITaskManagerSerializerPtr& spSerializer); ~TTaskManager(); void Create(IFeedbackHandlerFactory* piFeedbackHandlerFactory); + void Store(); + void Load(); + TTaskPtr CreateTask(const TTaskDefinition& tTaskDefinition); + TTaskPtr ImportTask(const TSmartPath& strTaskPath); size_t GetSize() const; TTaskPtr GetAt(size_t stIndex) const; - TTaskPtr GetTaskBySessionUniqueID(size_t stSessionUniqueID) const; + TTaskPtr GetTaskByTaskID(taskid_t tTaskID) const; - size_t Add(const TTaskPtr& spNewTask); + void Add(const TTaskPtr& spNewTask); - void RemoveAt(size_t stIndex, size_t stCount = 1); - void RemoveAll(); + void ClearBeforeExit(); void RemoveAllFinished(); void RemoveFinished(const TTaskPtr& spSelTask); void ResumeWaitingTasks(size_t stMaxRunningTasks); void StopAllTasks(); - void SaveData(); - void LoadDataProgress(); - void TasksBeginProcessing(); void TasksPauseProcessing(); void TasksResumeProcessing(); @@ -74,32 +72,38 @@ bool AreAllFinished(); - void SetTasksDir(const TSmartPath& pathDir); - void GetStatsSnapshot(TTaskManagerStatsSnapshotPtr& spSnapshot) const; size_t GetCountOfRunningTasks() const; protected: void StopAllTasksNL(); - TTaskPtr CreateEmptyTask(); + IFeedbackHandler* CreateNewFeedbackHandler(); -public: - TSmartPath m_pathTasksDir; + TSmartPath CreateTaskLogPath(const TString& strUuid) const; + TSmartPath CreateTaskSerializePath(const TString& strUuid) const; + static TString GetUuid(); private: #pragma warning(push) #pragma warning(disable: 4251) mutable boost::shared_mutex m_lock; - std::vector m_vTasks; // vector with tasks objects #pragma warning(pop) - size_t m_stNextSessionUniqueID; // global counter for providing unique ids for tasks per session (launch of the program) + TTaskInfoContainer m_tTasks; // serializable -protected: + TSmartPath m_pathLogDir; // config-based, not serializable + taskid_t m_stNextTaskID; // serializable + IFeedbackHandlerFactory* m_piFeedbackFactory; +#pragma warning(push) +#pragma warning(disable: 4251) + ITaskManagerSerializerPtr m_spSerializer; +#pragma warning(pop) }; +typedef boost::shared_ptr TTaskManagerPtr; + END_CHCORE_NAMESPACE #endif Index: src/libchcore/TTaskManagerSerializer.cpp =================================================================== diff -u --- src/libchcore/TTaskManagerSerializer.cpp (revision 0) +++ src/libchcore/TTaskManagerSerializer.cpp (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,170 @@ +// ============================================================================ +// Copyright (C) 2001-2013 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "TTaskManagerSerializer.h" +#include "TSQLiteDatabase.h" +#include "TSQLiteTransaction.h" +#include "TSQLiteException.h" +#include "TSerializerVersion.h" +#include "TSQLiteStatement.h" +#include "TTaskSerializer.h" +#include "TTaskInfo.h" +#include + +BEGIN_CHCORE_NAMESPACE + +using namespace sqlite; + +TTaskManagerSerializer::TTaskManagerSerializer(const TSmartPath& pathDB, const TSmartPath& pathTasksDir) : + m_bSetupExecuted(false), + m_pathDB(pathDB), + m_pathTasksDir(pathTasksDir) +{ +} + +TTaskManagerSerializer::~TTaskManagerSerializer() +{ +} + +void TTaskManagerSerializer::Setup() +{ + TSQLiteDatabasePtr spDatabase = GetDatabase(); + TSQLiteTransaction tTransaction(spDatabase); + + // check version of the database + TSerializerVersion tVersion(spDatabase); + tVersion.Setup(); + + // if version is 0, then this is the fresh database with (almost) no tables inside + if(tVersion.GetVersion() == 0) + { + TSQLiteStatement tStatement(spDatabase); + tStatement.Prepare(_T("CREATE TABLE tasks(task_id BIGINT UNIQUE, task_order INT, path VARCHAR(32768))")); + tStatement.Step(); + + // and finally set the database version to current one + tVersion.SetVersion(1); + } + + tTransaction.Commit(); + + m_bSetupExecuted = true; +} + +void TTaskManagerSerializer::Store(const TTaskInfoContainer& tTasksInfo) +{ + if(!m_bSetupExecuted) + Setup(); + + TSQLiteDatabasePtr spDatabase(GetDatabase()); + TSQLiteTransaction tTransaction(spDatabase); + + TSQLiteStatement tStatement(spDatabase); + + // first delete existing items + if(tTasksInfo.HasDeletions()) + { + tStatement.Prepare(_T("DELETE FROM tasks WHERE task_id = ?1")); + + for(size_t stIndex = 0; stIndex < tTasksInfo.GetDeletedCount(); ++stIndex) + { + taskid_t tTaskID = tTasksInfo.GetDeletedAt(stIndex); + + tStatement.BindValue(1, tTaskID); + tStatement.Step(); + } + } + + if(tTasksInfo.HasAdditions()) + { + tStatement.Prepare(_T("INSERT INTO tasks(task_id, task_order, path) VALUES(?1, ?2, ?3)")); + + for(size_t stIndex = 0; stIndex < tTasksInfo.GetCount(); ++stIndex) + { + const TTaskInfoEntry& rEntry = tTasksInfo.GetAt(stIndex); + if(rEntry.IsAdded()) + { + tStatement.BindValue(1, rEntry.GetTaskID()); + tStatement.BindValue(2, rEntry.GetOrder()); + tStatement.BindValue(3, rEntry.GetTaskPath().ToString()); + tStatement.Step(); + } + } + } + + if(tTasksInfo.HasModifications()) + { + // right now both order and path are updated regardless if only one of them changed. + // might be optimized in the future (not optimizing now as expected traffic is very low). + tStatement.Prepare(_T("UPDATE tasks SET task_order=?2, path=?3 WHERE task_id=?1")); + + for(size_t stIndex = 0; stIndex < tTasksInfo.GetCount(); ++stIndex) + { + const TTaskInfoEntry& rEntry = tTasksInfo.GetAt(stIndex); + if(rEntry.IsModified()) + { + tStatement.BindValue(1, rEntry.GetTaskID()); + tStatement.BindValue(2, rEntry.GetOrder()); + tStatement.BindValue(3, rEntry.GetTaskPath().ToString()); + tStatement.Step(); + } + } + } + + tTransaction.Commit(); +} + +void TTaskManagerSerializer::Load(TTaskInfoContainer& tTasksInfo) +{ + if(!m_bSetupExecuted) + Setup(); + + tTasksInfo.Clear(); + + TSQLiteDatabasePtr spDatabase(GetDatabase()); + TSQLiteTransaction tTransaction(spDatabase); + + TSQLiteStatement tStatement(spDatabase); + + tStatement.Prepare(_T("SELECT task_id, task_order, path FROM tasks")); + while(tStatement.Step() == TSQLiteStatement::eStep_HasRow) + { + taskid_t tTaskID = boost::numeric_cast(tStatement.GetUInt64(0)); + int iOrder = tStatement.GetInt(1); + TString strPath = tStatement.GetText(2); + + tTasksInfo.Add(tTaskID, PathFromWString(strPath), iOrder, TTaskPtr()); + } +} + +sqlite::TSQLiteDatabasePtr TTaskManagerSerializer::GetDatabase() +{ + if(!m_spDatabase) + m_spDatabase.reset(new TSQLiteDatabase(m_pathDB.ToString())); + + return m_spDatabase; +} + +chcore::ITaskSerializerPtr TTaskManagerSerializer::CreateTaskSerializer(const TSmartPath& pathSerialize) +{ + TTaskSerializerPtr spTaskSerializer(new TTaskSerializer(pathSerialize)); + return spTaskSerializer; +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TTaskManagerSerializer.h =================================================================== diff -u --- src/libchcore/TTaskManagerSerializer.h (revision 0) +++ src/libchcore/TTaskManagerSerializer.h (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,63 @@ +// ============================================================================ +// Copyright (C) 2001-2012 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TTASKMANAGERSERIALIZER_H__ +#define __TTASKMANAGERSERIALIZER_H__ + +#include "libchcore.h" +#include "ITaskManagerSerializer.h" +#include "TSQLiteDatabase.h" +#include "TPath.h" + +BEGIN_CHCORE_NAMESPACE + +class TTaskInfoContainer; + +class LIBCHCORE_API TTaskManagerSerializer : public ITaskManagerSerializer +{ +public: + TTaskManagerSerializer(const TSmartPath& pathDB, const TSmartPath& pathTasksDir); + ~TTaskManagerSerializer(); + + virtual ITaskSerializerPtr CreateTaskSerializer(const TSmartPath& pathSerialize); + + virtual void Setup(); // creates or migrates tables + + void Store(const TTaskInfoContainer& tTasksInfo); + void Load(TTaskInfoContainer& tTasksInfo); + +protected: + sqlite::TSQLiteDatabasePtr GetDatabase(); + +private: + TSmartPath m_pathDB; + TSmartPath m_pathTasksDir; + +#pragma warning(push) +#pragma warning(disable: 4251) + sqlite::TSQLiteDatabasePtr m_spDatabase; +#pragma warning(pop) + + bool m_bSetupExecuted; +}; + +typedef boost::shared_ptr TTaskManagerSerializerPtr; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TTaskManagerStatsSnapshot.cpp =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TTaskManagerStatsSnapshot.cpp (.../TTaskManagerStatsSnapshot.cpp) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TTaskManagerStatsSnapshot.cpp (.../TTaskManagerStatsSnapshot.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -79,11 +79,11 @@ return m_vTasksSnapshots[stIndex]; } -TTaskStatsSnapshotPtr TTaskManagerStatsSnapshot::GetTaskStatsForSessionUniqueID(size_t stSessionUniqueID) const +TTaskStatsSnapshotPtr TTaskManagerStatsSnapshot::GetTaskStatsForTaskID(taskid_t tTaskID) const { BOOST_FOREACH(TTaskStatsSnapshotPtr spStats, m_vTasksSnapshots) { - if(spStats->GetSessionUniqueID() == stSessionUniqueID) + if(spStats->GetTaskID() == tTaskID) return spStats; } Index: src/libchcore/TTaskManagerStatsSnapshot.h =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TTaskManagerStatsSnapshot.h (.../TTaskManagerStatsSnapshot.h) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TTaskManagerStatsSnapshot.h (.../TTaskManagerStatsSnapshot.h) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -41,7 +41,7 @@ void AddTaskStats(const TTaskStatsSnapshotPtr& spStats); size_t GetTaskStatsCount() const; TTaskStatsSnapshotPtr GetTaskStatsAt(size_t stIndex) const; - TTaskStatsSnapshotPtr GetTaskStatsForSessionUniqueID(size_t stSessionUniqueID) const; + TTaskStatsSnapshotPtr GetTaskStatsForTaskID(taskid_t tTaskID) const; size_t GetRunningTasks() const { return m_stRunningTasks; } void SetRunningTasks(size_t stRunningTasks) { m_stRunningTasks = stRunningTasks; } Index: src/libchcore/TTaskSerializer.cpp =================================================================== diff -u --- src/libchcore/TTaskSerializer.cpp (revision 0) +++ src/libchcore/TTaskSerializer.cpp (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,39 @@ +// ============================================================================ +// Copyright (C) 2001-2013 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "TTaskSerializer.h" + +chcore::TTaskSerializer::TTaskSerializer(const TSmartPath& pathDB) : + m_pathDB(pathDB) +{ +} + +chcore::TTaskSerializer::~TTaskSerializer() +{ +} + +void chcore::TTaskSerializer::Setup() +{ + +} + +chcore::TSmartPath chcore::TTaskSerializer::GetPath() const +{ + return m_pathDB; +} Index: src/libchcore/TTaskSerializer.h =================================================================== diff -u --- src/libchcore/TTaskSerializer.h (revision 0) +++ src/libchcore/TTaskSerializer.h (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,53 @@ +// ============================================================================ +// Copyright (C) 2001-2013 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TTASKSERIALIZER_H__ +#define __TTASKSERIALIZER_H__ + +#include "libchcore.h" +#include "ITaskSerializer.h" +#include "TString.h" +#include "TSQLiteDatabase.h" +#include "TPath.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API TTaskSerializer : public ITaskSerializer +{ +public: + TTaskSerializer(const TSmartPath& pathDB); + ~TTaskSerializer(); + + virtual TSmartPath GetPath() const; + + virtual void Setup(); + +private: + TSmartPath m_pathDB; + +#pragma warning(push) +#pragma warning(disable: 4251) + sqlite::TSQLiteDatabasePtr m_spDatabase; +#pragma warning(pop) +}; + +typedef boost::shared_ptr TTaskSerializerPtr; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TTaskStatsSnapshot.cpp =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TTaskStatsSnapshot.cpp (.../TTaskStatsSnapshot.cpp) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TTaskStatsSnapshot.cpp (.../TTaskStatsSnapshot.cpp) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -42,7 +42,6 @@ m_bIgnoreDirectories(false), m_bCreateEmptyFiles(false), m_ullCurrentBufferSize(0), - m_stSessionUniqueID(0), m_bCacheFilled(false), m_ullProcessedCount(0), m_ullTotalCount(0), @@ -68,7 +67,6 @@ m_bIgnoreDirectories = false; m_bCreateEmptyFiles = false; m_ullCurrentBufferSize = 0; - m_stSessionUniqueID = 0; m_bCacheFilled = false; m_ullProcessedCount = 0; m_ullTotalCount = 0; Index: src/libchcore/TTaskStatsSnapshot.h =================================================================== diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/TTaskStatsSnapshot.h (.../TTaskStatsSnapshot.h) (revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8) +++ src/libchcore/TTaskStatsSnapshot.h (.../TTaskStatsSnapshot.h) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -30,6 +30,7 @@ #include "TFileFiltersArray.h" #include "EOperationTypes.h" #include "ETaskCurrentState.h" +#include "TaskID.h" BEGIN_CHCORE_NAMESPACE @@ -40,6 +41,10 @@ void Clear(); + // task ID + taskid_t GetTaskID() const { return m_tTaskID; } + void SetTaskID(taskid_t val) { m_tTaskID = val; } + // subtasks' stats const TSubTaskArrayStatsSnapshot& GetSubTasksStats() const { return m_tSubTasksStats; } TSubTaskArrayStatsSnapshot& GetSubTasksStats() { return m_tSubTasksStats; } @@ -79,8 +84,8 @@ ETaskCurrentState GetTaskState() const { return m_eTaskState; } void SetTaskState(ETaskCurrentState val) { m_eTaskState = val; } - TString GetTaskID() const { return m_strTaskID; } - void SetTaskID(const TString& val) { m_strTaskID = val; } + TString GetTaskName() const { return m_strTaskID; } + void SetTaskName(const TString& val) { m_strTaskID = val; } EOperationType GetOperationType() const { return m_eOperationType; } void SetOperationType(EOperationType val) { m_eOperationType = val; } @@ -94,15 +99,14 @@ void SetCurrentBufferSize(unsigned long long ullSize) { m_ullCurrentBufferSize = ullSize; } unsigned long long GetCurrentBufferSize() const { return m_ullCurrentBufferSize; } - size_t GetSessionUniqueID() const { return m_stSessionUniqueID; } - void SetSessionUniqueID(size_t val) { m_stSessionUniqueID = val; } - private: void CalculateProgressAndSpeeds() const; private: TSubTaskArrayStatsSnapshot m_tSubTasksStats; + taskid_t m_tTaskID; + bool m_bTaskIsRunning; unsigned long long m_ullTimeElapsed; @@ -115,7 +119,6 @@ bool m_bIgnoreDirectories; bool m_bCreateEmptyFiles; unsigned long long m_ullCurrentBufferSize; - size_t m_stSessionUniqueID; // cache for items calculated on-demand mutable bool m_bCacheFilled; Index: src/libchcore/TaskID.h =================================================================== diff -u --- src/libchcore/TaskID.h (revision 0) +++ src/libchcore/TaskID.h (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,31 @@ +// ============================================================================ +// Copyright (C) 2001-2013 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TASKID_H__ +#define __TASKID_H__ + +#include "libchcore.h" + +BEGIN_CHCORE_NAMESPACE + +typedef size_t taskid_t; +enum ENoTaskID { NoTaskID = 0 }; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/Tests/TestsTaskManagerSerializer.cpp =================================================================== diff -u --- src/libchcore/Tests/TestsTaskManagerSerializer.cpp (revision 0) +++ src/libchcore/Tests/TestsTaskManagerSerializer.cpp (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -0,0 +1,14 @@ +#include "stdafx.h" +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include "../TTaskManagerSerializer.h" + +using namespace chcore; + +TEST(TaskManagerSerializer, BasicTest) +{ + TTaskManagerSerializer tSerializer(PathFromString(_T("c:\\projects\\abc.sqlite")), PathFromString(_T("c:\\projects\\"))); + tSerializer.Setup(); + + EXPECT_TRUE(true); +} Index: src/libchcore/libchcore.vc90.vcproj =================================================================== diff -u -r3397fd021739bea537248415a7b4fc2712dd2320 -rb1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0 --- src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision 3397fd021739bea537248415a7b4fc2712dd2320) +++ src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision b1ecc12ba4c1f2a7b4acd6e82fc4193535e55ff0) @@ -928,6 +928,10 @@ Name="Task" > + + @@ -1203,11 +1207,55 @@ RelativePath=".\TWorkerThreadController.h" > + + + + + + + + + + + + + + + + + + + + + + @@ -1225,40 +1273,52 @@ - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + +