MainFrm.cpp
Upload User: jsxglz
Upload Date: 2007-01-03
Package Size: 117k
Code Size: 43k
Category:

SQL Server

Development Platform:

Visual C++

  1. // MainFrm.cpp : implementation of the CMainFrame class
  2. //
  3. #include "stdafx.h"
  4. #include "InteractiveSQL.h"
  5. #include "MainFrm.h"
  6. #include "SelectTables.h"
  7. #include "ProceduresDlg.h"
  8. #include "MySheet.h"
  9. #include "catsets.h"
  10. #include "DrvInfo.h"
  11. #include "ConfigureDlg.h"
  12. #include "QueryOptionsDlg.h"
  13. #include "ExecuteSQLProc.h"
  14.  
  15. #ifdef _DEBUG
  16. #define new DEBUG_NEW
  17. #undef THIS_FILE
  18. static char THIS_FILE[] = __FILE__;
  19. #endif
  20. extern CInteractiveSQLApp theApp;
  21. const CString g_szODBCJTDriver = "ODBCJT32.DLL";
  22. const char* g_szNoData = "<No Data>";
  23. const char* g_szRefresh = "<Refresh>";
  24. // Configure
  25. extern const char* g_szConfigure;
  26. extern const char* g_szLoginTimeOut;
  27. extern const char* g_szQueryTimeOut;
  28. // Query options
  29. extern const char* g_szQueryOptions;
  30. extern const char* g_szThreadPriority;
  31. extern const char* g_szTimeCritical;
  32. extern const char* g_szHighest;
  33. extern const char* g_szAboveNormal;
  34. extern const char* g_szNormal;
  35. extern const char* g_szBelowNormal;
  36. extern const char* g_szLowest;
  37. // For SQLCancel
  38. extern const char* g_szFunctionSequenceError;
  39. // IsTextDataSrc
  40. const char* g_szText = "Text";
  41. /////////////////////////////////////////////////////////////////////////////
  42. // CMainFrame
  43. IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
  44. BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  45. //{{AFX_MSG_MAP(CMainFrame)
  46. ON_WM_CREATE()
  47. ON_COMMAND(ID_SQL_LOGON, OnSqlLogon)
  48. ON_COMMAND(ID_SQL_EXECUTE, OnSqlExecute)
  49. ON_UPDATE_COMMAND_UI(ID_SQL_EXECUTE, OnUpdateSqlExecute)
  50. ON_COMMAND(ID_SQL_LOGOFF, OnSqlLogoff)
  51. ON_UPDATE_COMMAND_UI(ID_SQL_LOGOFF, OnUpdateSqlLogoff)
  52. ON_UPDATE_COMMAND_UI(ID_SQL_LOGON, OnUpdateSqlLogon)
  53. ON_WM_SIZE()
  54. ON_COMMAND(ID_SQL_SELECT_TABLES, OnSqlSelectTables)
  55. ON_UPDATE_COMMAND_UI(ID_SQL_SELECT_TABLES, OnUpdateSqlSelectTables)
  56. ON_CBN_SELCHANGE(IDW_COMBO, OnSelChangeDatabase)
  57. ON_COMMAND(ID_SQL_SELECT_PROCEDURES, OnSqlSelectProcedures)
  58. ON_UPDATE_COMMAND_UI(ID_SQL_SELECT_PROCEDURES, OnUpdateSqlSelectProcedures)
  59. ON_COMMAND(ID_SQL_OBJECTS, OnSqlObjects)
  60. ON_COMMAND(ID_VIEW_PREV_RESULT_SET, OnViewPrevResultSet)
  61. ON_UPDATE_COMMAND_UI(ID_VIEW_PREV_RESULT_SET, OnUpdateViewPrevResultSet)
  62. ON_COMMAND(ID_VIEW_NEXT_RESULT_SET, OnViewNextResultSet)
  63. ON_UPDATE_COMMAND_UI(ID_VIEW_NEXT_RESULT_SET, OnUpdateViewNextResultSet)
  64. ON_COMMAND(ID_VIEW_FIRST_RESULT_SET, OnViewFirstResultSet)
  65. ON_UPDATE_COMMAND_UI(ID_VIEW_FIRST_RESULT_SET, OnUpdateViewFirstResultSet)
  66. ON_COMMAND(ID_VIEW_LAST_RESULT_SET, OnViewLastResultSet)
  67. ON_UPDATE_COMMAND_UI(ID_VIEW_LAST_RESULT_SET, OnUpdateViewLastResultSet)
  68. ON_UPDATE_COMMAND_UI(ID_SQL_OBJECTS, OnUpdateSqlObjects)
  69. ON_COMMAND(ID_HELP_ODBC_INFO, OnHelpOdbcInfo)
  70. ON_UPDATE_COMMAND_UI(ID_HELP_ODBC_INFO, OnUpdateHelpOdbcInfo)
  71. ON_COMMAND(ID_SQL_CANCEL, OnSqlCancel)
  72. ON_UPDATE_COMMAND_UI(ID_SQL_CANCEL, OnUpdateSqlCancel)
  73. ON_COMMAND(ID_SERVER_CONFIGURE, OnServerConfigure)
  74. ON_COMMAND(ID_QUERY_OPTIONS, OnQueryOptions)
  75. ON_UPDATE_COMMAND_UI(IDW_COMBO, OnUpdateCombo)
  76. ON_COMMAND(ID_QUERY_NEW, OnQueryNew)
  77. ON_UPDATE_COMMAND_UI(ID_QUERY_NEW, OnUpdateQueryNew)
  78. ON_WM_CLOSE()
  79. //}}AFX_MSG_MAP
  80. ON_UPDATE_COMMAND_UI(ID_INDICATOR_RESULT_SET, OnUpdateIndicatorResultSetInfo)
  81. ON_MESSAGE(WM_EXECUTION_COMPLETE, OnExecutionComplete)
  82. END_MESSAGE_MAP()
  83. static UINT indicators[] =
  84. {
  85. ID_SEPARATOR,
  86. ID_INDICATOR_EXECUTION_TIME,
  87. ID_SERVER_NAME_INDICATOR,
  88. ID_INDICATOR_RESULT_SET,
  89. ID_INDICATOR_CAPS,
  90. ID_INDICATOR_NUM,
  91. ID_INDICATOR_SCRL,
  92. };
  93. /////////////////////////////////////////////////////////////////////////////
  94. // CMainFrame construction/destruction
  95. CMainFrame::CMainFrame()
  96. {
  97. m_bOKToSize = false;
  98. m_nExecutionTimePaneNo = 1;
  99. m_nResultSetPaneNo = 2;
  100. m_nServerPaneNo = 3;
  101. m_nID = 2000;
  102. m_nIndex = 0;
  103. m_strStatusText = "CDatabase::m_hdbc == <NULL>";
  104. m_strODBCDSN = "DSN: <NULL>";
  105. m_strExecutionTime = "Execution Time: <n/a>";
  106. m_strMSSQLServer = _T("Microsoft SQL Server");
  107. m_strSQLAnyWhere =_T("Sybase SQL Anywhere");
  108. m_strSybaseOpenServer = _T("SQL Server");
  109. m_strOracle = _T("Oracle");
  110. m_bIsJetDriver = FALSE;
  111. m_bIsTSQLSupported = FALSE;
  112. m_bIsMultiSetSupported = FALSE;
  113. m_bExecuting = FALSE;
  114. m_bSQLCancelSupported = FALSE;
  115. m_bCanceled = FALSE;
  116. m_nLoginTimeOut = AfxGetApp()->GetProfileInt(g_szConfigure, g_szLoginTimeOut, 0);
  117. m_nQueryTimeOut = AfxGetApp()->GetProfileInt(g_szConfigure, g_szQueryTimeOut, 0);
  118. m_nThreadPriority = GetThreadPriority(AfxGetApp()->GetProfileString(g_szQueryOptions,
  119. g_szThreadPriority));
  120. m_pSet = NULL;
  121. }
  122. CMainFrame::~CMainFrame()
  123. {
  124. ClearGridList();
  125. if(m_font.m_hObject)
  126. {
  127. m_font.Detach();
  128. m_font.m_hObject = NULL;
  129. }
  130. if(m_pSet)
  131. {
  132. delete m_pSet;
  133. m_pSet = NULL;
  134. }
  135. }
  136. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  137. {
  138. if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
  139. return -1;
  140. if(!m_wndToolBar.Create(this) ||
  141. !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
  142. {
  143. TRACE0("Failed to create toolbarn");
  144. return -1;      // fail to create
  145. }
  146. if (!m_wndStatusBar.Create(this) ||
  147. !m_wndStatusBar.SetIndicators(indicators,
  148.   sizeof(indicators)/sizeof(UINT)))
  149. {
  150. TRACE0("Failed to create status barn");
  151. return -1;      // fail to create
  152. }
  153. CRect rect;
  154. UINT nIndex = m_wndToolBar.GetToolBarCtrl().CommandToIndex(IDW_COMBO);
  155. m_wndToolBar.SetButtonInfo(nIndex, IDW_COMBO, TBBS_SEPARATOR, 150);
  156. m_wndToolBar.GetToolBarCtrl().GetItemRect(nIndex, &rect);
  157. rect.top = 2;
  158. rect.bottom = rect.top + 250 /*drop height*/;
  159. if(!m_comboBox.Create(CBS_DROPDOWNLIST | CBS_SORT | WS_VISIBLE |
  160. WS_TABSTOP | WS_VSCROLL, rect, &m_wndToolBar, IDW_COMBO))
  161. {
  162. TRACE("Failed to create combo-boxn");
  163. return FALSE;
  164. }
  165. LOGFONT logFont;
  166. memset(&logFont, 0, sizeof(logFont));
  167. logFont.lfHeight = -11;
  168. logFont.lfWeight = 400;
  169. lstrcpy(logFont.lfFaceName, "MS Sans Serif");
  170. if(!m_font.CreateFontIndirect(&logFont))
  171. TRACE("Could Not create font for Combon");
  172. else
  173. m_comboBox.SetFont(&m_font);
  174. m_comboBox.EnableWindow(FALSE);
  175. // TODO: Remove this if you don't want tool tips or a resizeable toolbar
  176. m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
  177. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  178. // TODO: Delete these three lines if you don't want the toolbar to
  179. // be dockable
  180. m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
  181. EnableDocking(CBRS_ALIGN_ANY);
  182. DockControlBar(&m_wndToolBar);
  183. m_wndToolBar.ModifyStyle(0, TBSTYLE_FLAT);
  184. return 0;
  185. }
  186. BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
  187. {
  188. // TODO: Modify the Window class or styles here by modifying
  189. //  the CREATESTRUCT cs
  190. cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE
  191. | WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_MAXIMIZE;
  192. return CFrameWnd::PreCreateWindow(cs);
  193. }
  194. /////////////////////////////////////////////////////////////////////////////
  195. // CMainFrame diagnostics
  196. #ifdef _DEBUG
  197. void CMainFrame::AssertValid() const
  198. {
  199. CFrameWnd::AssertValid();
  200. }
  201. void CMainFrame::Dump(CDumpContext& dc) const
  202. {
  203. CFrameWnd::Dump(dc);
  204. }
  205. #endif //_DEBUG
  206. /////////////////////////////////////////////////////////////////////////////
  207. // CMainFrame message handlers
  208. BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
  209. {
  210. if(!m_wndSplitter.CreateStatic(this, 2, 1))
  211. {
  212. TRACE0("Failed to CreateStaticSplittern");
  213. return FALSE;
  214. }
  215.  
  216. if(!m_wndSplitter.CreateView(0, 0,
  217. RUNTIME_CLASS(CSQLView), CSize(0, 0), pContext))
  218. {
  219. TRACE0("Failed to create third panen");
  220. return FALSE;
  221. }
  222. // CResultView must be the last in the creation process.
  223. // There can be only one CRichEditDoc per CRichEditView
  224. if(!m_wndSplitter.CreateView(1, 0,
  225. RUNTIME_CLASS(CResultView), CSize(0, 0), pContext))
  226. {
  227. TRACE0("Failed to create first panen");
  228. return FALSE;
  229. }
  230. CSQLView* pSQLView = GetSQLView();
  231. if(pSQLView)
  232. pSQLView->SetFocus();
  233. m_bOKToSize = true;
  234. return TRUE;
  235. }
  236. void CMainFrame::OnSqlLogon() 
  237. {
  238. CWaitCursor wait;
  239. if(!m_database.IsOpen())
  240. ConnectDataSource();
  241. else
  242. {
  243. if(!CloneProcess(false))
  244. {
  245. ::MessageBeep(MB_ICONEXCLAMATION);
  246. AfxMessageBox("Error cloning <this> process.");
  247. }
  248. }
  249. }
  250. void CMainFrame::ConnectDataSource()
  251. {
  252. CWaitCursor wait;
  253. CString sMsg;
  254. try
  255. {
  256. m_dwStart = ::GetTickCount();
  257. m_database.SetLoginTimeout(m_nLoginTimeOut);
  258. BOOL bOpen = FALSE;
  259. if(theApp.m_strConnectString.IsEmpty())
  260. bOpen = m_database.Open(NULL, FALSE, FALSE, "ODBC;", FALSE);
  261. else
  262. {
  263. m_wndStatusBar.SetPaneText(0, "Establishing connection...");
  264. bOpen = m_database.OpenEx(theApp.m_strConnectString, CDatabase::noOdbcDialog);
  265. }
  266. if(bOpen)
  267. {
  268. UCHAR buffer[200];
  269. SWORD cbData;
  270. ::SQLGetInfo(m_database.m_hdbc, SQL_SERVER_NAME, (PTR)buffer, 200, &cbData);
  271. m_strServerName = buffer;
  272. ::SQLGetInfo(m_database.m_hdbc, SQL_DBMS_NAME, (PTR)buffer, 200, &cbData);
  273. m_strDBMS = buffer;
  274. ::SQLGetInfo(m_database.m_hdbc, SQL_DATA_SOURCE_NAME, (PTR)buffer, 200, &cbData);
  275. m_strODBCDSN = buffer;
  276. if(m_strServerName.IsEmpty())
  277. m_strServerName = m_strDBMS;
  278. m_bIsJetDriver = IsODBCJetDriver();
  279. if(m_bIsJetDriver)
  280. m_strServerName = m_database.GetDatabaseName();
  281. m_bIsTSQLSupported = (!m_strDBMS.CompareNoCase(m_strSQLAnyWhere) ||
  282. !m_strDBMS.CompareNoCase(m_strSybaseOpenServer) ||
  283. !m_strDBMS.CompareNoCase(m_strMSSQLServer));
  284. m_pSet = new CRecordsetEx(&m_database);
  285. if(m_bIsTSQLSupported)
  286. {
  287. if(!FillCombo())
  288. TRACE("Error filling combo.n");
  289. }
  290. else
  291. {
  292. m_comboBox.AddString("<Not supported>");
  293. m_comboBox.SetCurSel(0);
  294. m_comboBox.EnableWindow(FALSE);
  295. }
  296. m_bIsMultiSetSupported = IsMultiResultSetsSupported();
  297. m_bSQLCancelSupported = IsSQLCancelSupported();
  298. sMsg.Format("Connected to <%s>. %s", m_strServerName,
  299. m_bIsTSQLSupported ? CString("Database context changed to <"
  300. + (m_strDBName.IsEmpty() ? "Unknown" : m_strDBName) + ">.")
  301. : (const char*)CString(""));
  302. m_strStatusText.Format("DSN: %s", (const char*)m_strODBCDSN);
  303. SetExecutionTime();
  304. }
  305. }
  306. catch(CDBException* e)
  307. {
  308.    if(e)
  309.    {
  310.    if(!e->m_strError.IsEmpty())
  311.    sMsg.Format("%s%s", (LPCTSTR)e->m_strError, (LPCTSTR)e->m_strStateNativeOrigin);
  312.    else
  313.    sMsg = e->m_strStateNativeOrigin;
  314.    m_strStatusText.Format("CDBException::m_nRetCode == %d", e->m_nRetCode);
  315.    e->Delete();
  316.    }
  317.    TRACE("%sn", (LPCTSTR)sMsg);
  318. }
  319. catch(CMemoryException* e)
  320. {
  321. m_strStatusText = "Out-of-memory.";
  322. sMsg = m_strStatusText;
  323. if(e)
  324. e->Delete();
  325. }
  326. if(!sMsg.IsEmpty())
  327. OnExceptionClear(sMsg);
  328. if(!theApp.m_strConnectString.IsEmpty())
  329. {
  330. m_wndStatusBar.SetPaneText(0, "");
  331. theApp.m_strConnectString.Empty();
  332. }
  333. }
  334. void CMainFrame::OnSqlLogoff() 
  335. {
  336. CWaitCursor wait;
  337. if(m_database.IsOpen())
  338. {
  339. m_wndStatusBar.SetPaneText(m_nResultSetPaneNo, "Please wait...");
  340. m_database.Close();
  341. OnExceptionClear(CString(""));
  342. m_comboBox.ResetContent();
  343. m_comboBox.EnableWindow(FALSE);
  344. m_strDBName.Empty();
  345. m_strServerName.Empty();
  346. m_strStatusText = "CDatabase::m_hdbc == <NULL>";
  347. m_strODBCDSN = "DSN: <NULL>";
  348. m_strExecutionTime = "Execution Time: <n/a>";
  349. m_nID = 2000;
  350. m_nIndex = 0;
  351. if(m_pSet)
  352. {
  353. delete m_pSet;
  354. m_pSet = NULL;
  355. }
  356. }
  357. }
  358. void CMainFrame::OnSqlExecute() 
  359. {
  360. m_dwStart = ::GetTickCount();
  361. m_strExecutionTime = "Execution Time: <Working...>";
  362. m_wndStatusBar.SetPaneText(m_nExecutionTimePaneNo, m_strExecutionTime);
  363. m_strStatusText = "Executing...";
  364. m_wndStatusBar.SetPaneText(m_nResultSetPaneNo, m_strStatusText);
  365. OnExceptionClear(CString(""));
  366. CStringEx sSQL = GetSQLView()->GetRichEditCtrl().GetSelText();
  367. if(sSQL.IsEmpty())
  368. GetSQLView()->GetRichEditCtrl().GetWindowText(sSQL);
  369. BOOL bProcText = FALSE;
  370. if(m_bIsTSQLSupported)
  371. {
  372. const char* lpszBuff = "sp_helptext ";
  373. int nPos = sSQL.FindNoCase(lpszBuff);
  374. if(nPos != -1)
  375. {
  376. bProcText = TRUE;
  377. CString sObjName = sSQL.Mid(nPos + strlen(lpszBuff));
  378. nPos = sObjName.FindOneOf("nrt ");
  379. if(nPos != -1)
  380. sObjName = sObjName.Left(nPos);
  381. CString sText;
  382. if(!m_strDBMS.CompareNoCase(m_strSQLAnyWhere) ||
  383. !m_strDBMS.CompareNoCase(m_strSybaseOpenServer))
  384. {
  385. if(!IsObjectExists(sObjName))
  386. sText.Format("Object '%s' does not exist in the database.",
  387. (const char*)sObjName);
  388. }
  389. if(sText.IsEmpty())
  390. sText = GetProcedureText(sSQL, sObjName);
  391. if(!sText.IsEmpty())
  392. DisplayProcedureText(sText);
  393. SetExecutionTime();
  394. }
  395. }
  396. if(!bProcText)
  397. if(!ExecuteSQLEx(sSQL))
  398. TRACE("Error executing SQL: %sn", (LPCTSTR)sSQL);
  399. }
  400. BOOL CMainFrame::ExecuteSQLEx(const CStringEx& sSQL)
  401. {
  402. m_ThreadParam.m_strSQL = sSQL;
  403. m_ThreadParam.m_pView = GetResultView();
  404. m_ThreadParam.m_pFrame = this;
  405. m_bExecuting = TRUE;
  406. CWinThread* pThread = AfxBeginThread(ExecuteSQLProc, &m_ThreadParam, m_nThreadPriority);
  407. ASSERT(pThread);
  408. return pThread ? 1 : 0;
  409. }
  410. CSQLView* CMainFrame::GetSQLView()
  411. {
  412. return static_cast<CSQLView*>(m_wndSplitter.GetPane(0, 0));
  413. }
  414. CResultView* CMainFrame::GetResultView()
  415. {
  416. CResultView* pResultView = NULL;
  417. if(m_wndSplitter.m_hWnd != NULL)
  418. pResultView = static_cast<CResultView*>(m_wndSplitter.GetPane(1, 0));
  419. return pResultView;
  420. }
  421. void CMainFrame::OnSize(UINT nType, int cx, int cy) 
  422. {
  423. if(m_bOKToSize)
  424. {
  425. CRect rect;
  426. GetClientRect(&rect);
  427. m_wndSplitter.SetRowInfo(0, rect.Height()/2, 0);
  428. }
  429. CFrameWnd::OnSize(nType, cx, cy);
  430. }
  431. void CMainFrame::OnSqlSelectTables() 
  432. {
  433. CWaitCursor wait;
  434. CSelectTables dlg;
  435. if(dlg.DoModal() == IDOK)
  436. {
  437. m_dwStart = ::GetTickCount();
  438. m_strExecutionTime = "Execution Time: <Working...>";
  439. m_wndStatusBar.SetPaneText(m_nExecutionTimePaneNo, m_strExecutionTime);
  440. m_strStatusText = "Executing...";
  441. m_wndStatusBar.SetPaneText(m_nResultSetPaneNo, m_strStatusText); 
  442. OnExceptionClear(CString(""));
  443. CString sBuff;
  444. GetSQLView()->GetRichEditCtrl().GetWindowText(sBuff);
  445. int nStart = sBuff.GetLength();
  446. sBuff += dlg.m_strSQL;
  447. if(m_bIsJetDriver && dlg.m_bTextOnly && dlg.m_strType.Find("VIEW") != -1)
  448. sBuff += " -- CDaoQueryDef::GetSQL()";
  449. int nEnd = sBuff.GetLength();
  450. CSQLView* pSQLView = GetSQLView();
  451. ASSERT(pSQLView);
  452. pSQLView->GetRichEditCtrl().SetWindowText(sBuff);
  453. pSQLView->GetRichEditCtrl().SetSel(nStart+2, nEnd);
  454. pSQLView->SetFocus();
  455. if(dlg.m_bTextOnly && dlg.m_strType.Find("VIEW") != -1 &&
  456. (m_bIsTSQLSupported || m_bIsJetDriver ||
  457. !m_strDBMS.CompareNoCase(m_strOracle)))
  458. {
  459. CString sText;
  460. if(!m_bIsJetDriver)
  461. sText = GetProcedureText(dlg.m_strSQL, dlg.m_strObjName);
  462. else
  463. sText = GetQueryDef(m_database.GetDatabaseName(), dlg.m_strSQL.Mid(2));
  464. if(!sText.IsEmpty())
  465. DisplayProcedureText(sText);
  466. SetExecutionTime();
  467. }
  468. else
  469. {
  470. if(!ExecuteSQLEx(dlg.m_strSQL))
  471. TRACE("Error executing sql.n");
  472. }
  473. }
  474. }
  475. void CMainFrame::OnUpdateSqlSelectTables(CCmdUI* pCmdUI) 
  476. {
  477. pCmdUI->Enable(m_database.IsOpen() && !m_bExecuting);
  478. }
  479. void CMainFrame::OnExceptionClear(const CString& sMsg)
  480. {
  481. ClearGridList();
  482. CResultView* pResultView = GetResultView();
  483. ASSERT(pResultView);
  484. pResultView->m_strObjName.Empty();
  485. pResultView->GetRichEditCtrl().SetWindowText(sMsg);
  486. pResultView->SetWrapToWindow();
  487. pResultView->GetRichEditCtrl().SetSel(1, 1); // Scroll up!
  488. pResultView->GetRichEditCtrl().UpdateWindow();
  489. m_nID = 2000;
  490. m_nIndex = 0;
  491. SetResultSetInfo();
  492. }
  493. BOOL CMainFrame::FillCombo()
  494. {
  495. BOOL bRet = FALSE;
  496. CString sMsg;
  497. m_comboBox.ResetContent();
  498. try
  499. {
  500. CString sBuff = "SELECT name FROM master..sysdatabases ORDER BY name";
  501. CRecordsetEx set(&m_database);
  502. bRet = set.ExecDirect(sBuff);
  503. if(bRet)
  504. {
  505. if(set.IsBOF())
  506. {
  507. m_comboBox.AddString(g_szNoData);
  508. m_comboBox.SetCurSel(0);
  509. m_comboBox.EnableWindow(FALSE);
  510. }
  511. else
  512. {
  513. while(!set.IsEOF())
  514. {
  515. set.GetFieldValue((short)0, sBuff);
  516. m_comboBox.AddString(sBuff);
  517. set.MoveNext();
  518. }
  519. m_comboBox.InsertString(m_comboBox.GetCount(), g_szRefresh);
  520. m_comboBox.EnableWindow();
  521. }
  522. if(!SelectDatabase())
  523. TRACE("Error selecting database context.n");
  524. }
  525. }
  526. catch(CDBException* e)
  527. {
  528. sMsg.Format("CDBException::m_nRetCode == %d", e->m_nRetCode);
  529. if(e)
  530. e->Delete();
  531. }
  532. catch(CMemoryException* e)
  533. {
  534. sMsg = "Out-of-memory.";
  535. if(e)
  536. e->Delete();
  537. }
  538. if(!bRet)
  539. {
  540. m_comboBox.AddString(sMsg);
  541. m_comboBox.SetCurSel(0);
  542. m_comboBox.EnableWindow(FALSE);
  543. }
  544. return bRet;
  545. }
  546. void CMainFrame::OnSelChangeDatabase()
  547. {
  548. CWaitCursor wait;
  549. CString sBuff, sDBName, sMsg;
  550. m_comboBox.GetWindowText(sDBName);
  551. if(!sDBName.CompareNoCase(g_szNoData))
  552. ;
  553. else if(!sDBName.CompareNoCase(g_szRefresh))
  554. {
  555. m_dwStart = ::GetTickCount();
  556. m_strExecutionTime = "Execution Time: <Working...>";
  557. m_wndStatusBar.SetPaneText(m_nExecutionTimePaneNo, m_strExecutionTime);
  558. if(!FillCombo())
  559. TRACE("Error filling combo.n");
  560. SetExecutionTime();
  561. }
  562. else
  563. {
  564. if(sDBName != m_strDBName)
  565. {
  566. m_dwStart = ::GetTickCount();
  567. m_strExecutionTime = "Execution Time: <Working...>";
  568. m_wndStatusBar.SetPaneText(m_nExecutionTimePaneNo, m_strExecutionTime);
  569. OnExceptionClear(CString(""));
  570. try
  571. {
  572. sBuff = "use " + sDBName;
  573. m_database.ExecuteSQL(sBuff);
  574. m_strDBName = sDBName;
  575. sMsg.Format("Database context changed to <%s>.", (const char*)m_strDBName);
  576. m_comboBox.SelectString(-1, m_strDBName);
  577. m_strStatusText.Format("DSN: %s", (const char*)m_strODBCDSN);
  578. }
  579. catch(CDBException* e)
  580. {
  581.    if(e)
  582.    {
  583. if(!e->m_strError.IsEmpty())
  584. sMsg.Format("%s%s", (LPCTSTR)e->m_strError, (LPCTSTR)e->m_strStateNativeOrigin);
  585. else
  586. sMsg = e->m_strStateNativeOrigin;
  587. m_comboBox.SelectString(-1, m_strDBName);
  588. m_strStatusText.Format("CDBException::m_nRetCode == %d", e->m_nRetCode);
  589. e->Delete();
  590. }
  591. }
  592. OnExceptionClear(sMsg);
  593. SetExecutionTime();
  594. }
  595. }
  596. }
  597. void CMainFrame::OnSqlSelectProcedures() 
  598. {
  599. CWaitCursor wait;
  600. CProceduresDlg dlg;
  601. if(dlg.DoModal() == IDOK)
  602. {
  603. m_dwStart = ::GetTickCount();
  604. m_strExecutionTime = "Execution Time: <Working...>";
  605. m_wndStatusBar.SetPaneText(m_nExecutionTimePaneNo, m_strExecutionTime);
  606. m_strStatusText = "Executing...";
  607. m_wndStatusBar.SetPaneText(m_nResultSetPaneNo, m_strStatusText); 
  608. OnExceptionClear(CString(""));
  609. CStringEx sBuff;
  610. CRichEditCtrl& edit = GetSQLView()->GetRichEditCtrl();
  611. edit.GetWindowText(sBuff);
  612. sBuff += "rnrn";
  613. int nStart = sBuff.GetLength();
  614. CString sSQL;
  615. if(!m_strDBMS.CompareNoCase(m_strSybaseOpenServer) ||
  616.    !m_strDBMS.CompareNoCase(m_strMSSQLServer) ||
  617.    !m_strDBMS.CompareNoCase(m_strSQLAnyWhere))
  618. sSQL = "sp_helptext " + dlg.m_strProcedureName;
  619. if(!m_strDBMS.CompareNoCase(m_strOracle))
  620. {
  621. sSQL = "select TEXT from ALL_SOURCE where type = 'PROCEDURE' and NAME = '";
  622. sSQL += dlg.m_strProcedureName + "'" ;
  623. }
  624. if(m_bIsJetDriver)
  625. sSQL = dlg.m_strProcedureName;
  626. sBuff += sSQL;
  627. if(m_bIsJetDriver)
  628. sBuff += " -- CDaoQueryDef::GetSQL()";
  629. int nEnd = sBuff.GetLength();
  630. edit.SetWindowText(sBuff);
  631. edit.SetSel(nStart, nEnd);
  632. CString sText;
  633. if(m_bIsJetDriver)
  634. sText = GetQueryDef(m_database.GetDatabaseName(), sSQL);
  635. else
  636. sText = GetProcedureText(sSQL, dlg.m_strProcedureName);
  637. if(!sText.IsEmpty())
  638. DisplayProcedureText(sText);
  639. GetSQLView()->SetFocus();
  640. SetExecutionTime();
  641. }
  642. }
  643. void CMainFrame::OnUpdateSqlSelectProcedures(CCmdUI* pCmdUI) 
  644. {
  645. pCmdUI->Enable(m_database.IsOpen() && !m_bExecuting);
  646. }
  647. void CMainFrame::OnSqlObjects() 
  648. {
  649. CRect rect;
  650. UINT nIndex = m_wndToolBar.GetToolBarCtrl().CommandToIndex(ID_SQL_OBJECTS);
  651. m_wndToolBar.GetToolBarCtrl().GetItemRect(nIndex, &rect);
  652. rect.top = rect.bottom;
  653. m_wndToolBar.ClientToScreen(&rect.TopLeft());
  654. CMenu menu;
  655. if(menu.CreatePopupMenu())
  656. {
  657. DWORD dwFlags = MF_ENABLED | MF_STRING;
  658. menu.AppendMenu(dwFlags, ID_SQL_SELECT_TABLES, _T("&Tables...tF8"));
  659. menu.AppendMenu(dwFlags, ID_SQL_SELECT_PROCEDURES, _T("&Procedures...tF9"));
  660. menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, rect.left, rect.top+4, this);
  661. }
  662. }
  663. CString CMainFrame::GetProcedureText(CString& sSQL, const CString& sObjName)
  664. {
  665. CString sText;
  666. if(!m_strDBMS.CompareNoCase(m_strSQLAnyWhere))
  667. {
  668. sSQL.Format("SELECT text FROM syscomments where id = object_id('%s') ",
  669. (const char*)sObjName);
  670. sSQL += "order by number, colid2, colid";
  671. }
  672. try
  673. {
  674. m_database.SetQueryTimeout(m_nQueryTimeOut);
  675. CRecordsetEx set(&m_database);
  676. if(set.ExecDirect(sSQL))
  677. {
  678. CString sBuff;
  679. if(!set.IsBOF() && set.GetODBCFieldCount())
  680. {
  681. while(!set.IsEOF())
  682. {
  683. set.GetFieldValue((short)0, sBuff);
  684. sText += sBuff;
  685. set.MoveNext();
  686. }
  687. }
  688. // while <::SQLMoreResults> loop. Also, reset the cursor state
  689. // Microsoft SQL Server, SybaseSQLAnywhere, and Oracle will bail
  690. // here.
  691. while(set.FlushResultSet())
  692. {
  693. // Clean up the old column info and build  new one
  694. set.AllocAndCacheFieldInfo();
  695. if(!set.IsBOF() && set.GetODBCFieldCount())
  696. {
  697. sText += "nn";
  698. set.MoveNext();
  699. while(!set.IsEOF())
  700. {
  701. set.GetFieldValue((short)0, sBuff);
  702. sText += sBuff;
  703. set.MoveNext();
  704. }
  705. }
  706. }
  707. GetResultView()->m_strObjName = sObjName;
  708. }
  709. }
  710. catch(CDBException* e)
  711. {
  712.    if(e)
  713.    {
  714. CString sMsg;
  715. if(!e->m_strError.IsEmpty())
  716. sMsg.Format("%s%s", (LPCTSTR)e->m_strError, (LPCTSTR)e->m_strStateNativeOrigin);
  717. else
  718. sMsg = e->m_strStateNativeOrigin;
  719. m_strStatusText.Format("CDBException::m_nRetCode == %d", e->m_nRetCode);
  720. OnExceptionClear(sMsg);
  721. e->Delete();
  722.    }
  723. }
  724. catch(CMemoryException* e)
  725. {
  726. m_strStatusText = "Out-of-memory";
  727. OnExceptionClear(m_strStatusText);
  728. if(e)
  729. e->Delete();
  730. }
  731. return sText;
  732. }
  733. CString CMainFrame::GetQueryDef(const CString& sDBName, const CString& sSQL)
  734. {
  735. CString sText;
  736. try
  737. {
  738. CDaoDatabase db;
  739. db.Open(sDBName);
  740. CDaoQueryDef qDef(&db);
  741. qDef.Open(sSQL);
  742. sText = qDef.GetSQL();
  743. GetResultView()->m_strObjName = sSQL;
  744. }
  745. catch(CDaoException* e)
  746. {
  747. if(e)
  748. {
  749. CString sMsg;
  750. if(e->m_pErrorInfo)
  751. {
  752. sMsg.Format("%s (%d)", (LPCTSTR)e->m_pErrorInfo->m_strDescription,
  753. e->m_pErrorInfo->m_lErrorCode);
  754. }
  755. else
  756. {
  757. sMsg.Format(
  758. _T("ERROR:CDaoExceptionnn")
  759. _T("SCODE_CODE      =%dn")
  760. _T("SCODE_FACILITY  =%dn")
  761. _T("SCODE_SEVERITY  =%dn")
  762. _T("ResultFromScode =%dn"),
  763. SCODE_CODE      (e->m_scode),
  764. SCODE_FACILITY  (e->m_scode),
  765. SCODE_SEVERITY  (e->m_scode),
  766. ResultFromScode (e->m_scode));
  767. }
  768. m_strStatusText.Format("CDaoException::m_lErrorCode == %d",
  769. e->m_pErrorInfo->m_lErrorCode);
  770. OnExceptionClear(sMsg);
  771. e->Delete();
  772. }
  773. }
  774. catch(CMemoryException* e)
  775. {
  776. m_strStatusText = "Out-of-memory";
  777. OnExceptionClear(m_strStatusText);
  778. if(e)
  779. e->Delete();
  780. }
  781. return sText;
  782. }
  783. void CMainFrame::DisplayProcedureText(const CString& sText)
  784. {
  785. ClearGridList();
  786. CResultView* pResultView = GetResultView();
  787. ASSERT(pResultView);
  788. pResultView->GetRichEditCtrl().SetWindowText(sText);
  789. pResultView->SetWrapNone();
  790. pResultView->GetRichEditCtrl().SetSel(1, 1); // Scroll up!
  791. pResultView->GetRichEditCtrl().UpdateWindow();
  792. m_strStatusText.Format("# of lines of text: %d",
  793. pResultView->GetRichEditCtrl().GetLineCount());
  794. }
  795. BOOL CMainFrame::IsObjectExists(const CString& sObjName)
  796. {
  797. bool bExists = false;
  798. try
  799. {
  800. CString sBuff;
  801. CRecordsetEx set(&m_database);
  802. sBuff.Format("select object_id('%s')", (const char*)sObjName);
  803. if(set.ExecDirect(sBuff))
  804. {
  805. set.GetFieldValue((short)0, sBuff);
  806. if(!sBuff.IsEmpty())
  807. bExists = true;
  808. }
  809. }
  810. catch(CDBException* e)
  811. {
  812.    if(e)
  813.    {
  814. CString sMsg;
  815. if(!e->m_strError.IsEmpty())
  816. sMsg.Format("%s%s", (LPCTSTR)e->m_strError, (LPCTSTR)e->m_strStateNativeOrigin);
  817. else
  818. sMsg = e->m_strStateNativeOrigin;
  819. TRACE("sMsg: %sn", (const char*)sMsg);
  820. e->Delete();
  821.    }
  822. }
  823. catch(CMemoryException* e)
  824. {
  825. TRACE("Out-of-memory.");
  826. if(e)
  827. e->Delete();
  828. }
  829. return bExists;
  830. }
  831. void CMainFrame::ClearGridList()
  832. {
  833. for(POSITION pos = m_GridList.GetHeadPosition(); pos != NULL;)
  834. {
  835. CMSFlexGrid* pGridCtrl =  (CMSFlexGrid*)m_GridList.GetNext(pos);
  836. if(pGridCtrl)
  837. {
  838. delete pGridCtrl;
  839. pGridCtrl = NULL;
  840. }
  841. }
  842. if(!m_GridList.IsEmpty())
  843. m_GridList.RemoveAll();
  844. CResultView* pResultView = GetResultView();
  845. if(pResultView)
  846. pResultView->m_pGridCtrl = NULL;
  847. }
  848. void CMainFrame::SetResultSetInfo()
  849. {
  850. HGDIOBJ hOldFont = NULL;
  851. HFONT hFont = (HFONT)m_wndStatusBar.SendMessage(WM_GETFONT);
  852. CClientDC dc(NULL);
  853. if(hFont != NULL) 
  854. hOldFont = dc.SelectObject(hFont);
  855. // Result set info
  856. UINT nID, nStyle;
  857. int nWidth;
  858. m_wndStatusBar.GetPaneInfo(m_nResultSetPaneNo, nID, nStyle, nWidth);
  859. CSize size = dc.GetTextExtent(m_strStatusText);
  860. m_wndStatusBar.SetPaneInfo(m_nResultSetPaneNo, nID, nStyle, size.cx);
  861. if(m_strStatusText.IsEmpty())
  862. m_strStatusText.Format("DSN: %s", (const char*)m_strODBCDSN);
  863. m_wndStatusBar.SetPaneText(m_nResultSetPaneNo, m_strStatusText);
  864. // Server info
  865. if(m_strServerName.IsEmpty())
  866. m_strServerName = "Server Name: <NULL>";
  867. m_wndStatusBar.GetPaneInfo(m_nServerPaneNo, nID, nStyle, nWidth);
  868. size = dc.GetTextExtent(m_strServerName);
  869. m_wndStatusBar.SetPaneInfo(m_nServerPaneNo, nID, nStyle, size.cx);
  870. m_wndStatusBar.SetPaneText(m_nServerPaneNo, m_strServerName);
  871. // Execution time info
  872. m_wndStatusBar.GetPaneInfo(m_nExecutionTimePaneNo, nID, nStyle, nWidth);
  873. size = dc.GetTextExtent(m_strExecutionTime);
  874. m_wndStatusBar.SetPaneInfo(m_nExecutionTimePaneNo, nID, nStyle, size.cx);
  875. m_wndStatusBar.SetPaneText(m_nExecutionTimePaneNo, m_strExecutionTime);
  876. }
  877. void CMainFrame::OnUpdateIndicatorResultSetInfo(CCmdUI* pCmdUI)
  878. {
  879. SetResultSetInfo();
  880. pCmdUI->Enable(TRUE);
  881. }
  882. void CMainFrame::OnViewPrevResultSet() 
  883. {
  884. POSITION pos = m_GridList.FindIndex(m_nIndex-2);
  885. DisplayResults((CMSFlexGrid*)m_GridList.GetAt(pos), --m_nIndex);
  886. }
  887. void CMainFrame::OnViewNextResultSet() 
  888. {
  889. POSITION pos = m_GridList.FindIndex(m_nIndex);
  890. DisplayResults((CMSFlexGrid*)m_GridList.GetAt(pos), ++m_nIndex);
  891. }
  892. void CMainFrame::OnViewFirstResultSet() 
  893. {
  894. m_nIndex = 0;
  895. POSITION pos = m_GridList.FindIndex(m_nIndex);
  896. DisplayResults((CMSFlexGrid*)m_GridList.GetAt(pos), ++m_nIndex);
  897. }
  898. void CMainFrame::OnViewLastResultSet() 
  899. {
  900. m_nIndex = m_GridList.GetCount();
  901. POSITION pos = m_GridList.FindIndex(--m_nIndex);
  902. DisplayResults((CMSFlexGrid*)m_GridList.GetAt(pos), ++m_nIndex);
  903. }
  904. void CMainFrame::OnUpdateViewPrevResultSet(CCmdUI* pCmdUI) 
  905. {
  906. pCmdUI->Enable(m_nIndex > 1 && !m_bExecuting);
  907. }
  908. void CMainFrame::OnUpdateViewNextResultSet(CCmdUI* pCmdUI) 
  909. {
  910. pCmdUI->Enable((m_GridList.GetCount() > m_nIndex) && !m_bExecuting);
  911. }
  912. void CMainFrame::OnUpdateViewFirstResultSet(CCmdUI* pCmdUI) 
  913. {
  914. OnUpdateViewPrevResultSet(pCmdUI);
  915. }
  916. void CMainFrame::OnUpdateViewLastResultSet(CCmdUI* pCmdUI) 
  917. {
  918. OnUpdateViewNextResultSet(pCmdUI);
  919. }
  920. void CMainFrame::DisplayResults(CMSFlexGrid* pGridCtrl, const int& nCurrentSet)
  921. {
  922. if(m_GridList.GetCount() > 1)
  923. HideResultSets();
  924. CResultView* pResultView = GetResultView();
  925. ASSERT(pResultView);
  926. CRect rect;
  927. pResultView->GetWindowRect(&rect);
  928. pGridCtrl->MoveWindow(0, 0, rect.Width(), rect.Height());
  929. pGridCtrl->ShowWindow(SW_SHOW);
  930. pGridCtrl->UpdateWindow();
  931. pResultView->m_pGridCtrl = pGridCtrl;
  932. pResultView->UpdateWindow();
  933. m_strStatusText.Format("Result set %d of %d; %d Row(s); %d Column(s)", nCurrentSet,
  934. m_GridList.GetCount(), pGridCtrl->GetRows()-1, pGridCtrl->GetCols());
  935. if(GetFocus() == pResultView)
  936. pGridCtrl->SetFocus();
  937. }
  938. void CMainFrame::HideResultSets()
  939. {
  940. int nResultSet = m_GridList.GetCount();
  941. for(int n = 0; n < nResultSet; n++)
  942. ((CMSFlexGrid*)m_GridList.GetAt(m_GridList.FindIndex(n)))->ShowWindow(SW_HIDE);
  943. }
  944. void CMainFrame::OnUpdateSqlObjects(CCmdUI* pCmdUI) 
  945. {
  946. pCmdUI->Enable(m_database.IsOpen() && !m_bExecuting);
  947. }
  948. void CMainFrame::OnUpdateSqlLogon(CCmdUI* pCmdUI) 
  949. {
  950. pCmdUI->Enable(TRUE);
  951. }
  952. void CMainFrame::OnUpdateSqlLogoff(CCmdUI* pCmdUI) 
  953. {
  954. pCmdUI->Enable(m_database.IsOpen() && !m_bExecuting);
  955. }
  956. void CMainFrame::OnUpdateSqlExecute(CCmdUI* pCmdUI) 
  957. {
  958. pCmdUI->Enable(m_database.IsOpen() && 
  959. GetSQLView()->GetRichEditCtrl().GetTextLength() &&
  960. !m_bExecuting);
  961. }
  962. void CMainFrame::OnHelpOdbcInfo()
  963. {
  964. CWaitCursor wait;
  965. // Create our property sheet
  966. CMyPropertySheet sheet(_T("ODBC Driver Info"));
  967. // Create all our property pages
  968. CDriverInfo    DriverInfoPage(&m_database);
  969. CFunctions     FunctionsPage(&m_database);
  970. CSupportedSQL  SupportedSQLPage(&m_database);
  971. CDataTypes     DataTypesPage(&m_database);
  972. CIdentifiers   IdentifiersPage(&m_database);
  973. CLimits        LimitsPage(&m_database);
  974. CMisc1         Misc1Page(&m_database);
  975. CMisc2         Misc2Page(&m_database);
  976. // Add the pages to our sheet
  977. sheet.AddPage(&DriverInfoPage);
  978. sheet.AddPage(&FunctionsPage);
  979. sheet.AddPage(&SupportedSQLPage);
  980. sheet.AddPage(&DataTypesPage);
  981. sheet.AddPage(&IdentifiersPage);
  982. sheet.AddPage(&LimitsPage);
  983. sheet.AddPage(&Misc1Page);
  984. sheet.AddPage(&Misc2Page);
  985. sheet.DoModal();
  986. }
  987. void CMainFrame::OnUpdateHelpOdbcInfo(CCmdUI* pCmdUI) 
  988. {
  989. pCmdUI->Enable(m_database.IsOpen() && !m_bExecuting);
  990. }
  991. BOOL CMainFrame::IsODBCJetDriver()
  992. {
  993. UCHAR buffer[200];
  994. SWORD cbData;
  995. ::SQLGetInfo(m_database.m_hdbc, SQL_DRIVER_NAME, (PTR)buffer, 200, &cbData);
  996. CString sBuff = buffer;
  997. return !sBuff.CompareNoCase(g_szODBCJTDriver);
  998. }
  999. BOOL CMainFrame::IsMultiResultSetsSupported()
  1000. {
  1001. UCHAR buffer[200];
  1002. SWORD cbData;
  1003. ::SQLGetInfo(m_database.m_hdbc, SQL_MULT_RESULT_SETS, (PTR)buffer, 200, &cbData);
  1004. return (CString(buffer) == _T("Y"));
  1005. }
  1006. void CMainFrame::OnSqlCancel() 
  1007. {
  1008. if(m_pSet->m_hstmt)
  1009. {
  1010. m_strStatusText = "Canceling...";
  1011. m_wndStatusBar.SetPaneText(m_nResultSetPaneNo, m_strStatusText);
  1012. if(m_pSet->IsOpen())
  1013. m_pSet->Cancel();
  1014. m_bCanceled = TRUE;
  1015. ::MessageBeep(MB_ICONEXCLAMATION);
  1016. OnExceptionClear(CString("Query canceled by user."));
  1017. m_strStatusText = "Canceled";
  1018. LONG lIdle = 0;
  1019. while(AfxGetApp()->OnIdle(lIdle++));
  1020. }
  1021. }
  1022. void CMainFrame::OnUpdateSqlCancel(CCmdUI* pCmdUI) 
  1023. {
  1024. pCmdUI->Enable(m_database.IsOpen() && m_bExecuting && m_bSQLCancelSupported);
  1025. }
  1026. void CMainFrame::OnServerConfigure() 
  1027. {
  1028. CConfigureDlg dlg;
  1029. if(dlg.DoModal() == IDOK)
  1030. {
  1031. m_nLoginTimeOut = dlg.m_nLoginTimeOut;
  1032. m_nQueryTimeOut = dlg.m_nQueryTimeOut;
  1033. }
  1034. }
  1035. void CMainFrame::OnQueryOptions() 
  1036. {
  1037. CQueryOptionsDlg dlg;
  1038. if(dlg.DoModal() == IDOK)
  1039. m_nThreadPriority = GetThreadPriority(dlg.m_strThreadPriority);
  1040. }
  1041. int CMainFrame::GetThreadPriority(const CString& sPriority)
  1042. {
  1043. int nThreadPriority;
  1044. if(!sPriority.CompareNoCase(g_szTimeCritical))
  1045. nThreadPriority = THREAD_PRIORITY_TIME_CRITICAL;
  1046. else if(!sPriority.CompareNoCase(g_szHighest))
  1047. nThreadPriority = THREAD_PRIORITY_HIGHEST;
  1048. else if(!sPriority.CompareNoCase(g_szAboveNormal))
  1049. nThreadPriority = THREAD_PRIORITY_ABOVE_NORMAL;
  1050. else if(!sPriority.CompareNoCase(g_szNormal))
  1051. nThreadPriority = THREAD_PRIORITY_NORMAL;
  1052. else if(!sPriority.CompareNoCase(g_szBelowNormal))
  1053. nThreadPriority = THREAD_PRIORITY_BELOW_NORMAL;
  1054. else if(!sPriority.CompareNoCase(g_szLowest))
  1055. nThreadPriority = THREAD_PRIORITY_LOWEST;
  1056. else
  1057. nThreadPriority = THREAD_PRIORITY_NORMAL;
  1058. return nThreadPriority;
  1059. }
  1060. CMSFlexGrid* CMainFrame::GetGrid()
  1061. {
  1062. CResultView* pResultView = GetResultView();
  1063. ASSERT(pResultView);
  1064. CRect rect;
  1065. pResultView->GetWindowRect(&rect);
  1066. pResultView->ScreenToClient(rect);
  1067. CMSFlexGrid* pGridCtrl = new CMSFlexGrid();
  1068. ASSERT(pGridCtrl);
  1069. if(!pGridCtrl->Create(NULL, NULL, WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL,
  1070. rect, pResultView, m_nID++))
  1071. TRACE("Failed to create GridCtrl.n");
  1072. else
  1073. {
  1074. m_GridList.AddTail(pGridCtrl);
  1075. pGridCtrl->SetCols(0);
  1076. pGridCtrl->SetRows(1);
  1077. pGridCtrl->MoveWindow(rect);
  1078. pGridCtrl->SetBackColorBkg((unsigned long)RGB(255, 255, 255));
  1079. pGridCtrl->SetBorderStyle((unsigned long)0);
  1080. pGridCtrl->SetAllowUserResizing((long)1);
  1081. pGridCtrl->SetFocusRect((long)0);
  1082. pGridCtrl->SetHighLight((long)1);
  1083. pGridCtrl->ShowWindow(SW_HIDE);
  1084. }
  1085. return pGridCtrl;
  1086. }
  1087. void CMainFrame::SetGridHeaderInfo(CMSFlexGrid* pGrid, CRecordsetEx* pSet)
  1088. {
  1089. ASSERT(pGrid);
  1090. ASSERT(pSet);
  1091. CStringEx sBuff;
  1092. CODBCFieldInfo fieldInfo;
  1093. int nPrecision;
  1094. int nFieldLength;
  1095. int nArbitraryFactor = 110;
  1096. int nCols = pSet->GetODBCFieldCount();
  1097. UINT nMaxWidth = 32767;
  1098. pGrid->SetCols(nCols);
  1099. for(int n = 0; n < nCols; n++)
  1100. {
  1101. pSet->GetODBCFieldInfo(n, fieldInfo);
  1102. sBuff.Format("%s", (LPCTSTR)fieldInfo.m_strName);
  1103. nFieldLength = fieldInfo.m_strName.GetLength();
  1104. if(fieldInfo.m_nPrecision < (UDWORD)nFieldLength)
  1105. nPrecision = nFieldLength;
  1106. else if(fieldInfo.m_nPrecision > nMaxWidth)
  1107. nPrecision = nMaxWidth;
  1108. else
  1109. nPrecision = fieldInfo.m_nPrecision;
  1110. pGrid->SetColWidth(n, (nPrecision+fieldInfo.m_nScale)*nArbitraryFactor);
  1111. pGrid->SetTextMatrix(0, n, fieldInfo.m_strName);
  1112. }
  1113. }
  1114. void CMainFrame::OnUpdateCombo(CCmdUI* pCmdUI) 
  1115. {
  1116. pCmdUI->Enable(m_database.IsOpen() && m_bIsTSQLSupported && !m_bExecuting);
  1117. }
  1118. BOOL CMainFrame::SelectDatabase()
  1119. {
  1120. bool bRet = true;
  1121. if(m_pSet->IsOpen())
  1122. m_pSet->Close();
  1123. if(!m_pSet->ExecDirect(CString("select db_name() dbname")))
  1124. bRet = false;
  1125. else
  1126. {
  1127. if(!m_pSet->IsBOF())
  1128. {
  1129. m_pSet->GetFieldValue((short)0, m_strDBName);
  1130. m_comboBox.SelectString(-1, m_strDBName);
  1131. }
  1132. }
  1133. if(m_pSet->IsOpen())
  1134. m_pSet->Close();
  1135. return bRet;
  1136. }
  1137. LONG CMainFrame::OnExecutionComplete(UINT wParam, LONG lParam)
  1138. {
  1139. BOOL bCaughtException = wParam;
  1140. if(!bCaughtException && !m_bCanceled)
  1141. {
  1142. try
  1143. {
  1144. CString sBuff;
  1145. std::string sRow;
  1146. int nCols = m_pSet->GetODBCFieldCount();
  1147. int nTotalCols = 0;
  1148. long lRow = 0;
  1149. COleVariant vRow(lRow);
  1150. if(nCols)
  1151. {
  1152. nTotalCols += nCols;
  1153. CMSFlexGrid* pGridCtrl = GetGrid();
  1154. ASSERT(pGridCtrl);
  1155. SetGridHeaderInfo(pGridCtrl, m_pSet);
  1156. if(!m_bCanceled && !m_pSet->IsBOF())
  1157. {
  1158. while(!m_bCanceled && !m_pSet->IsEOF())
  1159. {
  1160. for(int n = 0; n < nCols; n++)
  1161. {
  1162. m_pSet->GetFieldValue(n, sBuff);
  1163. sRow += (const char*)sBuff;
  1164. sRow += "t";
  1165. }
  1166. pGridCtrl->AddItem(sRow.c_str(), (vRow = ++lRow));
  1167. sRow.erase();
  1168. m_pSet->MoveNext();
  1169. m_wndToolBar.Pump();
  1170. }
  1171. }
  1172. }
  1173. // while <::SQLMoreResults> loop. Also reset the cursor state
  1174. while(!m_bCanceled && m_pSet->FlushResultSet())
  1175. {   
  1176. // Clean up the old column info and build new one
  1177. m_pSet->AllocAndCacheFieldInfo();
  1178. nCols = m_pSet->GetODBCFieldCount();
  1179. lRow = 0;
  1180. if(nCols)
  1181. {
  1182. nTotalCols += nCols;
  1183. CMSFlexGrid* pGridCtrl = GetGrid();
  1184. ASSERT(pGridCtrl);
  1185. SetGridHeaderInfo(pGridCtrl, m_pSet);
  1186. if(!m_bCanceled && !m_pSet->IsBOF())
  1187. {
  1188. m_pSet->MoveNext();
  1189. while(!m_bCanceled && !m_pSet->IsEOF())
  1190. {     
  1191. for(int n = 0; n < nCols; n++)
  1192. {
  1193. m_pSet->GetFieldValue(n, sBuff);
  1194. sRow += (const char*)sBuff; 
  1195. sRow += "t";
  1196. }
  1197. pGridCtrl->AddItem(sRow.c_str(), (vRow = ++lRow));
  1198. sRow.erase();
  1199. m_pSet->MoveNext();
  1200. m_wndToolBar.Pump();
  1201. }
  1202. }
  1203. }
  1204. }
  1205. if(!m_bCanceled)
  1206. {
  1207. if(nTotalCols)
  1208. {
  1209. POSITION pos = m_GridList.FindIndex(m_nIndex);
  1210. DisplayResults((CMSFlexGrid*)m_GridList.GetAt(pos), ++m_nIndex);
  1211. }
  1212. else
  1213. {
  1214. if(m_bIsTSQLSupported)
  1215. m_strStatusText = GetRowCount("select @@rowcount") + " Row(s) affected";
  1216. else if(!m_strDBMS.CompareNoCase(m_strOracle))
  1217. m_strStatusText = GetRowCount("select SQL%ROWCOUNT from DUAL") + " Row(s) affected";
  1218. else
  1219. ;
  1220. OnExceptionClear("The command(s) completed successfully.");
  1221. }
  1222. }
  1223. }
  1224. catch(CDBException* e)
  1225. {
  1226.    bCaughtException = TRUE;
  1227.    
  1228.    if(e)
  1229.    {
  1230.    CString sMsg;
  1231.    if(e->m_strStateNativeOrigin.Find(g_szFunctionSequenceError) != -1)
  1232.    {
  1233.    m_bCanceled = TRUE;
  1234.    sMsg = "Query canceled by user.";
  1235.    m_strStatusText = "Canceled";
  1236.    }
  1237.    else
  1238.    {
  1239.    if(!e->m_strError.IsEmpty())
  1240.    sMsg.Format("%s%s", (LPCTSTR)e->m_strError, (LPCTSTR)e->m_strStateNativeOrigin);
  1241.    else
  1242.    sMsg = e->m_strStateNativeOrigin;
  1243.    m_strStatusText.Format("CDBException::m_nRetCode == %d", e->m_nRetCode);
  1244.    }
  1245.        
  1246.    OnExceptionClear(sMsg);
  1247.    
  1248.    e->Delete();
  1249.    }
  1250. }
  1251. catch(CMemoryException* e)
  1252. {
  1253. bCaughtException = TRUE;
  1254. m_strStatusText = "Out-of-memory";
  1255. OnExceptionClear(m_strStatusText);
  1256. if(e)
  1257. e->Delete();
  1258. }
  1259. catch(COleException* e)
  1260. {
  1261. bCaughtException = TRUE;
  1262. if(e)
  1263. {
  1264. TCHAR szMsg[255];
  1265. e->GetErrorMessage(szMsg, 255);
  1266. m_strStatusText = szMsg;
  1267. OnExceptionClear(m_strStatusText);
  1268. e->Delete();
  1269. }
  1270. }
  1271. catch(COleDispatchException* e)
  1272. {
  1273. if(e)
  1274. {
  1275. bCaughtException = TRUE;
  1276. m_strStatusText = e->m_strDescription;
  1277. OnExceptionClear(m_strStatusText);
  1278. e->Delete();
  1279. }
  1280. }
  1281. catch(...)
  1282. {
  1283. bCaughtException = TRUE;
  1284. if(!m_bCanceled)
  1285. {
  1286. m_strStatusText = "<Unknown error>";
  1287. OnExceptionClear(m_strStatusText);
  1288. }
  1289. }
  1290. }
  1291. if(m_bIsTSQLSupported && !m_bCanceled && !bCaughtException)
  1292. {
  1293. if(m_ThreadParam.m_strSQL.FindNoCase(_T("USE ")) != -1)
  1294. {
  1295. if(!SelectDatabase())
  1296. TRACE("Error selecting database context.n");
  1297. }
  1298. }
  1299. if(!m_bCanceled && m_pSet->IsOpen())
  1300. {
  1301. m_pSet->Close();
  1302. m_pSet->m_hstmt = NULL;
  1303. }
  1304. m_bExecuting = FALSE;
  1305. m_bCanceled = FALSE;
  1306. SetExecutionTime();
  1307. LONG lIdle = 0;
  1308. while(AfxGetApp()->OnIdle(lIdle++));
  1309. return 0L;
  1310. }
  1311. BOOL CMainFrame::IsSQLCancelSupported()
  1312. {
  1313. UWORD  bSQLCancelSupported;
  1314. ::SQLGetFunctions(m_database.m_hdbc, SQL_API_SQLCANCEL, &bSQLCancelSupported);
  1315. return bSQLCancelSupported;
  1316. }
  1317. BOOL CMainFrame::IsTextDataSource()
  1318. {
  1319. UCHAR buffer[200];
  1320. SWORD cbData;
  1321. ::SQLGetInfo(m_database.m_hdbc, SQL_DBMS_NAME, (PTR)buffer, 200, &cbData);
  1322. CString sBuff = buffer;
  1323. return !sBuff.CompareNoCase(g_szText);
  1324. }
  1325. CString CMainFrame::GetRowCount(const CString& sSQL)
  1326. {
  1327. CString sBuff;
  1328. if(m_pSet->IsOpen())
  1329. m_pSet->Close();
  1330. if(m_pSet->ExecDirect(sSQL))
  1331. {
  1332. if(!m_pSet->IsBOF())
  1333. m_pSet->GetFieldValue((short)0, sBuff);
  1334. }
  1335. if(m_pSet->IsOpen())
  1336. m_pSet->Close();
  1337. return sBuff;
  1338. }
  1339. void CMainFrame::SetExecutionTime()
  1340. {
  1341. DWORD dwDiff = ::GetTickCount() - m_dwStart;
  1342. COleDateTimeSpan span(0, 0, 0, dwDiff/1000);
  1343. m_strExecutionTime.Format("Execution Time: %02d:%02d:%02d.%03d",
  1344. span.GetHours(), span.GetMinutes(), span.GetSeconds(), dwDiff%1000);
  1345. }
  1346. BOOL CMainFrame::CloneProcess(const bool& bNewQuery)
  1347. {
  1348. STARTUPINFO si;
  1349. PROCESS_INFORMATION pi;
  1350. memset(&si, 0, sizeof(si));
  1351. si.cb = sizeof(si);
  1352. CString strCommandLine = CString(""") + theApp.m_pszExeName + CString("" ");
  1353. if(bNewQuery)
  1354. strCommandLine += m_database.GetConnect();
  1355. TRACE("%sn", (const char*)strCommandLine);
  1356. return ::CreateProcess(
  1357. NULL,
  1358. const_cast<LPTSTR>((LPCTSTR)strCommandLine),
  1359. NULL,
  1360. NULL,
  1361. FALSE,
  1362. 0,
  1363. NULL,
  1364. NULL,
  1365. &si,
  1366. &pi
  1367. );
  1368. }
  1369. void CMainFrame::OnQueryNew() 
  1370. {
  1371. if(!CloneProcess())
  1372. {
  1373. ::MessageBeep(MB_ICONEXCLAMATION);
  1374. AfxMessageBox("Error cloning <this> process.");
  1375. }
  1376. }
  1377. void CMainFrame::OnUpdateQueryNew(CCmdUI* pCmdUI) 
  1378. {
  1379. pCmdUI->Enable(m_database.IsOpen());
  1380. }
  1381. /////////////////////////////////////////////////////////////////////////////
  1382. // Helpers for saving/restoring window state
  1383. static TCHAR BASED_CODE szSection[] = _T("Settings");
  1384. static TCHAR BASED_CODE szWindowPos[] = _T("WindowPos");
  1385. static TCHAR szFormat[] = _T("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d");
  1386. static BOOL PASCAL ReadWindowPlacement(LPWINDOWPLACEMENT pwp)
  1387. {
  1388. CWinApp* pApp = AfxGetApp();
  1389. CString strBuffer = pApp->GetProfileString(szSection, szWindowPos);
  1390. if(strBuffer.IsEmpty())
  1391. return FALSE;
  1392. WINDOWPLACEMENT wp;
  1393. int nRead = _stscanf(strBuffer, szFormat,
  1394. &wp.flags, &wp.showCmd,
  1395. &wp.ptMinPosition.x, &wp.ptMinPosition.y,
  1396. &wp.ptMaxPosition.x, &wp.ptMaxPosition.y,
  1397. &wp.rcNormalPosition.left, &wp.rcNormalPosition.top,
  1398. &wp.rcNormalPosition.right, &wp.rcNormalPosition.bottom);
  1399. if(nRead != 10)
  1400. return FALSE;
  1401. wp.length = sizeof(wp);
  1402. *pwp = wp;
  1403. return TRUE;
  1404. }
  1405. static void PASCAL WriteWindowPlacement(LPWINDOWPLACEMENT pwp)
  1406. {
  1407. TCHAR szBuffer[sizeof("-32767")*8 + sizeof("65535")*2];
  1408. wsprintf(szBuffer, szFormat,
  1409. pwp->flags, pwp->showCmd,
  1410. pwp->ptMinPosition.x, pwp->ptMinPosition.y,
  1411. pwp->ptMaxPosition.x, pwp->ptMaxPosition.y,
  1412. pwp->rcNormalPosition.left, pwp->rcNormalPosition.top,
  1413. pwp->rcNormalPosition.right, pwp->rcNormalPosition.bottom);
  1414. AfxGetApp()->WriteProfileString(szSection, szWindowPos, szBuffer);
  1415. }
  1416. /////////////////////////////////////////////////////////////////////////////
  1417. void CMainFrame::InitialShowWindow(UINT nCmdShow)
  1418. {
  1419. WINDOWPLACEMENT wp;
  1420. if(!ReadWindowPlacement(&wp))
  1421. CenterWindow();
  1422. else
  1423. {
  1424. if(nCmdShow != SW_SHOWNORMAL)
  1425. wp.showCmd = nCmdShow;
  1426. else
  1427. nCmdShow = wp.showCmd;
  1428. SetWindowPlacement(&wp);
  1429. }
  1430. ShowWindow(nCmdShow);
  1431. UpdateWindow();
  1432. }
  1433. void CMainFrame::OnClose() 
  1434. {
  1435. bool bOKToClose = true;
  1436. if(m_bExecuting)
  1437. {
  1438. ::MessageBeep(MB_ICONEXCLAMATION);
  1439. CString sMsg = "A query execution is in progress. Are you sure you wish to cancel?";
  1440. if(AfxMessageBox(sMsg, MB_YESNO) == IDNO)
  1441. bOKToClose = false;
  1442. else
  1443. {
  1444. if(m_pSet->m_hstmt)
  1445. {
  1446. m_strStatusText = "Canceling...";
  1447. m_wndStatusBar.SetPaneText(m_nResultSetPaneNo, m_strStatusText);
  1448. if(m_pSet->IsOpen())
  1449. m_pSet->Cancel();
  1450. m_bCanceled = TRUE;
  1451. m_bExecuting = FALSE;
  1452. m_strStatusText = "Canceled";
  1453. OnExceptionClear(CString("Query canceled."));
  1454. SetExecutionTime();
  1455. m_wndStatusBar.SetPaneText(m_nExecutionTimePaneNo, m_strExecutionTime);
  1456. }
  1457. }
  1458. }
  1459. if(bOKToClose)
  1460. {
  1461. WINDOWPLACEMENT wp;
  1462. wp.length = sizeof(wp);
  1463. if(GetWindowPlacement(&wp))
  1464. {
  1465. wp.flags = 0;
  1466. if(IsZoomed())
  1467. wp.flags |= WPF_RESTORETOMAXIMIZED;
  1468. if(wp.showCmd == SW_SHOWMINIMIZED)
  1469. ;
  1470. else
  1471. WriteWindowPlacement(&wp);
  1472. }
  1473. CFrameWnd::OnClose();
  1474. }
  1475. }