OsqlDlg.cpp
上传用户:xaxinn
上传日期:2007-01-03
资源大小:39k
文件大小:10k
源码类别:

Oracle数据库

开发平台:

Visual C++

  1. // OsqlDlg.cpp : implementation file
  2. //
  3. // Release 1, Copyright (C) 1999 Ben Bryant
  4. // This is sample source code, nothing more is implied. Use it only as such.
  5. // This software is provided 'as-is', without warranty. In no event will the
  6. // author be held liable for any damages arising from the use of this software.
  7. // Permission is granted to anyone to use this software for any purpose.
  8. // The origin of this software must not be misrepresented; you must not claim
  9. // that you wrote the original software. Altered source versions must be plainly
  10. // marked as such, and must not be misrepresented as being the original software.
  11. // Ben Bryant bcbryant@firstobject.com
  12. //
  13. #include "stdafx.h"
  14. #include "Osql.h"
  15. #include "OsqlDlg.h"
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. /////////////////////////////////////////////////////////////////////////////
  22. // COsqlDlg dialog
  23. COsqlDlg::COsqlDlg(CWnd* pParent /*=NULL*/)
  24. : CDialog(COsqlDlg::IDD, pParent)
  25. {
  26. //{{AFX_DATA_INIT(COsqlDlg)
  27. //}}AFX_DATA_INIT
  28. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  29. m_csTitle = "Osql 1.0";
  30. }
  31. void COsqlDlg::DoDataExchange(CDataExchange* pDX)
  32. {
  33. CDialog::DoDataExchange(pDX);
  34. //{{AFX_DATA_MAP(COsqlDlg)
  35. DDX_Control(pDX, IDC_EDIT_OUTPUT, m_cmdOutput);
  36. DDX_Control(pDX, IDC_EDIT_COMMAND, m_cmdInput);
  37. DDX_Control(pDX, IDC_BUTTON_DO, m_buttonDo);
  38. //}}AFX_DATA_MAP
  39. }
  40. BEGIN_MESSAGE_MAP(COsqlDlg, CDialog)
  41. //{{AFX_MSG_MAP(COsqlDlg)
  42. ON_WM_PAINT()
  43. ON_WM_QUERYDRAGICON()
  44. ON_BN_CLICKED(IDC_BUTTON_DO, OnButtonDo)
  45. ON_WM_SIZE()
  46. //}}AFX_MSG_MAP
  47. END_MESSAGE_MAP()
  48. /////////////////////////////////////////////////////////////////////////////
  49. // COsqlDlg message handlers
  50. BOOL COsqlDlg::OnInitDialog()
  51. {
  52. CDialog::OnInitDialog();
  53. SetIcon(m_hIcon, TRUE); // Set big icon
  54. SetIcon(m_hIcon, FALSE); // Set small icon
  55. // Set dialog title
  56. SetWindowText( m_csTitle );
  57. // Initialize command controls
  58. m_cmd.Init( this, &m_cmdOutput, &m_cmdInput, &m_buttonDo );
  59. // Initial resize
  60. CRect rect;
  61. GetClientRect( &rect );
  62. CalcSize( rect.Width(), rect.Height() );
  63. // Startup intro
  64. About();
  65. return TRUE;  // return TRUE  unless you set the focus to a control
  66. }
  67. void COsqlDlg::About()
  68. {
  69. Output( m_csTitle, CCmdOutCtrl::Large );
  70. m_cmdOutput.SetFontFace( "Arial" );
  71. Output( "Osql is a command line graphical user interface that helps you "
  72. "use PL/SQL to access Oracle databases. The source code features my COdb "
  73. "class which is a simple C++ wrapper for the Oracle Call Interface (OCI). "
  74. "Osql connects to databases through SQL*Net 8.0. The OCI, SQL*Net, SQL*Plus, "
  75. "and the PL/SQL extension of SQL are products of Oracle Corporation. "
  76. "The Osql program is provided 'as-is', without warranty. In no event will "
  77. "the author be held liable for any damages arising from the use of this "
  78. "software."
  79. );
  80. Output( "Copyright (C) 1999 Ben Bryant", CCmdOutCtrl::Bold );
  81. Output( "bcbryant@firstobject.com" );
  82. Output( "First Objective Software, Inc." );
  83. Output( "www.firstobject.com" );
  84. m_cmdOutput.SetFontFace();
  85. }
  86. void COsqlDlg::Help()
  87. {
  88. ShowWindow( SW_MAXIMIZE );
  89. m_cmdOutput.SetFontFace( "Arial" );
  90. Output(
  91. "You can immediately connect to an Oracle database, select from "
  92. "tables and execute SQL statements, much as you would in SQL*Plus "
  93. "without the semi-colons. As in SQL*Plus, there are also some non-SQL "
  94. "commands. Type a question mark to see a list of the commands available "
  95. "in Osql. Each command is listed with its named arguments and defaults "
  96. "if any. Only use semi-colons where they are required in PL/SQL blocks. "
  97. "If you enter something that does not start with any of these Osql "
  98. "commands, Osql tries to execute it as an SQL statement."
  99. );
  100. Output(
  101. "The interface for re-using and modifying chunks of commands and pl/sql "
  102. "blocks is handy. If you right click in the output area you can copy text "
  103. "to the command entry box or immediately run it. The command entry box "
  104. "resizes to fit multiple lines of text when you paste in a large pl/sql "
  105. "block or use ctrl-enter to start a new line. The escape key exits the "
  106. "program (closing the session if open). The first command you will need "
  107. "is the connect command. It works like SQL*Plus 8.0 and uses your Net80 "
  108. "configuration to connect to the Oracle database. No host name is "
  109. "necessary if the database is on the same machine."
  110. );
  111. m_cmdOutput.SetFontFace( "Courier New" );
  112. Output( "connect scott/tiger@host" );
  113. m_cmdOutput.SetFontFace( "Arial" );
  114. Output(
  115. "One of the differences from SQL*Plus is that semi-colons are not allowed "
  116. "except after anonymous blocks. This corresponds to what the OCI expects "
  117. "in an Execute statement. If you have the necessary permissions, you can "
  118. "try copying and pasting the following commands into Osql, one create "
  119. "command at a time:"
  120. );
  121. m_cmdOutput.SetFontFace( "Courier New" );
  122. Output( "create table table1 (n NUMBER(22), d date, c VARCHAR2(80) )" );
  123. Output( "create sequence sequence1" );
  124. Output(
  125. "create or replace package package1 isn"
  126. "  function add_entry (c in VARCHAR2 ) return NUMBER;n"
  127. "end package1;"
  128. );
  129. Output(
  130. "create or replace package body package1 isn"
  131. "  function add_entry (c in VARCHAR2 ) return NUMBER isn"
  132. "  n NUMBER(22);n"
  133. "  beginn"
  134. "    select sequence1.nextval into n from dual;n"
  135. "    insert into table1 values ( n, sysdate, c );n"
  136. "    return n;n"
  137. "  end add_entry;n"
  138. "end package1;"
  139. );
  140. m_cmdOutput.SetFontFace( "Arial" );
  141. Output(
  142. "After you have created these objects, you can try them out using the "
  143. "following commands:"
  144. );
  145. m_cmdOutput.SetFontFace( "Courier New" );
  146. Output( "declare n number(22); begin n := package1.add_entry( 'something' ); end;" );
  147. Output( "select * from table1" );
  148. m_cmdOutput.SetFontFace( "Arial" );
  149. Output( "Have Fun!!!" );
  150. m_cmdOutput.SetFontFace();
  151. }
  152. void COsqlDlg::CalcSize(int cx, int cy)
  153. {
  154. // Position controls according to size of dialog within margins
  155. m_cmd.MoveControls( CRect( 8, 6, cx-7, cy-7 ) );
  156. }
  157. void COsqlDlg::OnSize(UINT nType, int cx, int cy) 
  158. {
  159. CDialog::OnSize(nType, cx, cy);
  160. // Calculate child window sizes if they exist
  161. if ( ::IsWindow(m_buttonDo.m_hWnd) )
  162. CalcSize( cx, cy );
  163. }
  164. void COsqlDlg::OnPaint() 
  165. {
  166. if (IsIconic())
  167. {
  168. CPaintDC dc(this); // device context for painting
  169. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  170. // Center icon in client rectangle
  171. int cxIcon = GetSystemMetrics(SM_CXICON);
  172. int cyIcon = GetSystemMetrics(SM_CYICON);
  173. CRect rect;
  174. GetClientRect(&rect);
  175. int x = (rect.Width() - cxIcon + 1) / 2;
  176. int y = (rect.Height() - cyIcon + 1) / 2;
  177. // Draw the icon
  178. dc.DrawIcon(x, y, m_hIcon);
  179. }
  180. else
  181. {
  182. CDialog::OnPaint();
  183. }
  184. }
  185. HCURSOR COsqlDlg::OnQueryDragIcon()
  186. {
  187. return (HCURSOR) m_hIcon;
  188. }
  189. void COsqlDlg::OnButtonDo() 
  190. {
  191. CString csCommand;
  192. m_cmdInput.GetWindowText( csCommand );
  193. HRESULT hr = RunCommand( csCommand );
  194. if ( SUCCEEDED(hr) )
  195. m_cmdInput.SetCommandText( "" );
  196. m_cmdInput.SetFocus();
  197. }
  198. HRESULT COsqlDlg::RunCommand( CString csCommandLine ) 
  199. {
  200. // Array of commands
  201. // This makes it very easy to add commands with required arguments and defaults
  202. // Arguments are comma delimited, use the last argument to receive values with commas
  203. static const char* szaCommandDefns[] =
  204. {
  205. // Database commands
  206. "db.connect connectstring=/#user/password@host",
  207. "db.disconnect",
  208. "db.exec sql#explicit execute",
  209. "db.select sql#select a set of records",
  210. // Miscellaneous commands
  211. "misc.about",
  212. "misc.? command=*",
  213. "misc.help#instructions for using Osql",
  214. "misc.max max=1#maximize dialog, specify 0 to restore",
  215. // Terminator
  216. ""
  217. };
  218. // Parse command line
  219. m_cmd.ParseCommandLine( csCommandLine, szaCommandDefns );
  220. CString csCommand = m_cmd.GetCommand();
  221. Output( m_cmd.GetCommandLine(), CCmdOutCtrl::Bold );
  222. CString csService = m_cmd.GetService();
  223. CStringArray& csaArgs = *m_cmd.GetArgs();
  224. // Check command
  225. if ( csCommand.IsEmpty() )
  226. {
  227. // Command not recognized, pretend it was exec
  228. csCommand = "exec";
  229. csaArgs.Add( csCommandLine );
  230. csService = "db";
  231. }
  232. else if ( ! m_cmd.GetSyntaxError().IsEmpty() )
  233. {
  234. // Syntax error
  235. Output( m_cmd.GetSyntaxError() );
  236. csCommand.Empty();
  237. }
  238. // Prepare to do command
  239. CWaitCursor wait;
  240. HRESULT hr = 0;
  241. // Non-db commands
  242. if ( csCommand == "?" )
  243. {
  244. m_cmdOutput.OutputHelp( csaArgs[0], szaCommandDefns );
  245. return 0;
  246. }
  247. else if ( csCommand == "max" )
  248. {
  249. if ( atoi(csaArgs[0]) )
  250. ShowWindow( SW_MAXIMIZE );
  251. else
  252. ShowWindow( SW_RESTORE );
  253. }
  254. else if ( csCommand == "about" )
  255. About();
  256. else if ( csCommand == "help" )
  257. Help();
  258. // Database
  259. else if ( csCommand == "connect" )
  260. {
  261. m_db.StartLog();
  262. hr = m_db.Open( csaArgs[0] );
  263. Output( m_db.GetLog() );
  264. }
  265. else if ( csCommand == "disconnect" )
  266. hr = m_db.Close();
  267. else if ( csCommand == "exec" )
  268. hr = m_db.Exec( csaArgs[0] );
  269. else if ( csCommand == "select" )
  270. {
  271. // Set SQL in recordset and run it
  272. CString csSelect( csaArgs[0] );
  273. if ( csSelect.GetLength() < 7 || csSelect.Left(7) != "select " )
  274. csSelect = "select " + csSelect;
  275. hr = m_db.Select( csSelect );
  276. // Loop through results
  277. while ( SUCCEEDED(hr) && ! m_db.IsEOS() )
  278. {
  279. Output( m_db.GetResults() );
  280. m_db.FetchNext();
  281. hr = 0;
  282. }
  283. }
  284. if ( csService == "db" )
  285. Output( m_db.GetErrorDescription() );
  286. return hr;
  287. }