home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / po7_win / object10 / osession.cpp < prev    next >
C/C++ Source or Header  |  1995-04-03  |  16KB  |  643 lines

  1. /* Copyright (c) Oracle Corporation 1994.  All Rights Reserved */
  2.  
  3. /*
  4.     This source code is provided as a debugging aid for developers
  5.     who have purchased Oracle Objects for OLE    .  Please see the
  6.     online help for documentation of these classes.
  7. */
  8.  
  9. /*
  10.     Oracle Objects for OLE     C++ Classes
  11.     
  12.     This file implements the OSession, OConnection and OClient classes
  13.                            
  14.     CREATED    ********   11/22/94
  15.     RWOOLARD    MODIFIED    03/20/95
  16.                 bug#    263010    GetNamedSession returns default when name NULL
  17. */
  18.  
  19. #include "windows.h"
  20. #include <ole2.h>
  21. #include <olenls.h>       
  22. #include <dispatch.h>  
  23.  
  24. #ifndef ORACL_ORACLE
  25. #include "oracl.h"
  26. #endif
  27.  
  28. #ifndef _OracleInProcServer_H_
  29. #include <oratlb.h>
  30. #endif
  31.  
  32. #ifndef ORAOBJI_ORACLE
  33. #include "oraobji.h"
  34. #endif
  35.  
  36. static const CLSID CLSID_XOSession = 
  37. {0x3893b4a0, 0xffd8, 0x101a, { 0xad, 0xf2, 0x04, 0x02, 0x1c, 0x00, 0x70, 0x02 } };
  38.  
  39. static const IID IID_IOraSession =
  40. {0xa16bec60, 0x134a, 0x101b, { 0x91, 0x9e, 0x04, 0x02, 0x1c, 0x00, 0x70, 0x02 } };
  41. static const IID IID_IOraClient =
  42. {0x8041eee0, 0x134a, 0x101b, { 0x91, 0x9e, 0x04, 0x02, 0x1c, 0x00, 0x70, 0x02 } };
  43. static const IID IID_IOraConnection =
  44. {0xbea85c00, 0x134a, 0x101b, { 0x91, 0x9e, 0x04, 0x02, 0x1c, 0x00, 0x70, 0x02 } };   
  45.  
  46. // ----- OSession -----------------------------------------------
  47.  
  48. OSession::OSession(void)
  49. {
  50.     m_name = 0;
  51.     m_errtext = 0;
  52.     m_version = 0;
  53. }
  54.  
  55. OSession::OSession(const OSession &other) // copy constructor
  56. {
  57.     m_name = 0;
  58.     m_errtext = 0;
  59.     m_version = 0;
  60.     Copy(other); // call internal copier
  61. }
  62.  
  63. OSession::OSession(const char *sname)
  64. { // create & open a session
  65.     m_name = 0;
  66.     m_errtext = 0;
  67.     m_version = 0;
  68.     if (sname)
  69.         Open(sname);
  70.     else
  71.         Open();
  72. }
  73.  
  74. // create a brand new session from scratch.  One way or another we always start from here
  75. //    because all the rest of the objects hang off this initial session
  76.  
  77. OSession::~OSession(void)
  78. {
  79.     Cleanup();
  80. }
  81.  
  82. oresult OSession::Open(void)
  83. {
  84.     Cleanup();
  85.     
  86.     if (!CheckOLE())
  87.     { // OLE isn't initialized
  88.         SetInternalError(OERROR_SYSTEM);
  89.         return(OFAILURE);
  90.     }
  91.  
  92.     void *tempi;
  93.     HRESULT hr = CoCreateInstance(CLSID_XOSession, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
  94.                                   IID_IOraSession, &tempi);
  95.     
  96.     if (FAILED(hr))
  97.     { // can't create session object
  98.         // we could save the HRESULT for later use
  99.         SetInternalError(OERROR_SYSTEM);
  100.         return(OFAILURE);
  101.     }
  102.     
  103.     return(SetObjectInterface(tempi));                              
  104. }
  105.  
  106. // open a new named session
  107. oresult OSession::Open(const char *sname)
  108. {
  109.     // get the client object
  110.     OSession sess;
  111.     sess.Open();  // open the default session
  112.     OClient oCl = sess.GetClient();
  113.     if (!oCl.IsOpen())
  114.     { // no client object not opened yet
  115.         SetInternalError(OERROR_INVPARENT);
  116.         return(OFAILURE);
  117.     }
  118.     if (!sname)
  119.     {
  120.         SetInternalError(OERROR_BADARG);
  121.         return(OFAILURE);
  122.     }
  123.     
  124.     oCl.ErrorReset();
  125.     BSTR cp = OObjectAllocString(sname);
  126.     IDispatch *connect = ((_IOraClient *) (oCl.Internal()))->get_CreateSession(cp);
  127.     OObjectFreeString(cp);
  128.     
  129.     return(OpenHelper((void *) connect, oCl.Internal()));
  130. }
  131.  
  132. OSession OSession::GetNamedSession(const char *sname)
  133. {
  134.     OSession nameds;
  135.  
  136.     // temporary OSession on default session
  137.     OSession defsess(0);
  138.  
  139.     if (!defsess.IsOpen())
  140.     { // can't open default session - probably not initialized
  141.         nameds.SetInternalError(OERROR_INVPARENT);
  142.         return(nameds); // return of closed session indicates error
  143.     }
  144.     
  145.     if (!sname || !strcmp (sname, ""))
  146.         return(defsess);  // user just wanted default session
  147.     
  148.     // otherwise - fetch the named session
  149.     BSTR tempname = OObjectAllocString(sname);
  150.     IDispatch *sess = ((_IOraSession *) (defsess.Internal()))->get_ConnectSession(tempname);
  151.     OObjectFreeString((char *) tempname);
  152.     
  153.     // new session
  154.     nameds.OpenHelper((void *) sess, defsess.Internal());
  155.     
  156.     return(nameds);
  157. }
  158.  
  159. OConnectionCollection OSession::GetConnections(void) const
  160. {
  161.     OConnectionCollection cset;
  162.     
  163.     if (ActionGetStart(&cset) != OSUCCESS)
  164.         return(cset); // returning unopened object - indicates error
  165.     
  166.     IDispatch *connect = ((_IOraSession *) (Internal()))->get_Connections();
  167.     
  168.     cset.OpenHelper((void *) connect, Internal());
  169.     
  170.     return(cset);
  171. }
  172.  
  173. OClient OSession::GetClient(void) const
  174. {
  175.     OClient cl;
  176.     
  177.     if (ActionGetStart(&cl) != OSUCCESS)
  178.         return(cl); // returning unopened object - indicates error
  179.     
  180.     IDispatch *connect = ((_IOraSession *) (Internal()))->get_Client();
  181.     
  182.     cl.OpenHelper((void *) connect, Internal());
  183.     
  184.     return(cl);
  185. }
  186.  
  187. oresult OSession::OpenHelper(void *idisp, void *otheri)
  188. {
  189.     if (!idisp)
  190.     { // couldn't create session - error is on other object
  191.         SetOtherError(otheri);
  192.         return(OFAILURE);
  193.     }
  194.     IDispatch *connect = (IDispatch *) idisp;
  195.     
  196.     Cleanup(); // clear out this object
  197.     
  198.     void *tempi;
  199.     HRESULT hc = connect->QueryInterface(IID_IOraSession, &tempi);
  200.     connect->Release();
  201.     if (FAILED(hc))
  202.     { // couldn't get the interface
  203.         SetInternalError(OERROR_NOINTER);
  204.         return(OFAILURE);
  205.     }
  206.     
  207.     return(SetObjectInterface(tempi));
  208. }
  209.  
  210. oresult OSession::Close(void)
  211. {
  212.     return(Cleanup());
  213. }
  214.  
  215. // overloaded assignment operator
  216. OSession &OSession::operator=(const OSession &other)
  217. {
  218.     if (&other == this)
  219.         return(*this); // self assignment - do nothing
  220.     
  221.     // clear out our old state
  222.     if (OSUCCESS == Cleanup())
  223.     {
  224.         Copy(other); // call copy constructor
  225.     }
  226.     // if the cleanup failed (possible but unlikely) we don't do the copy
  227.     //    and as a result, we pass on the unmodified (or partly cleaned!) object
  228.     
  229.     return(*this);
  230.  
  231. // routine to do all cleanup for OSession
  232. oresult OSession::Cleanup(void)
  233. {
  234.     if (m_name)
  235.     {
  236.         OObjectFreeString(m_name);
  237.         m_name = 0;
  238.     }
  239.     if (m_errtext)
  240.     {
  241.         OObjectFreeString(m_errtext);
  242.         m_errtext = 0;
  243.     }   
  244.     if (m_version)
  245.     {
  246.         OObjectFreeString(m_version);
  247.         m_version = 0;
  248.     }   
  249.     
  250.     return(OOracleObject::Cleanup());
  251. }    
  252.  
  253. oresult OSession::Copy(const OSession &other)
  254. {
  255.     // don't bother copying strings
  256.     m_name = 0;
  257.     m_errtext = 0;
  258.     m_version = 0;
  259.     
  260.     return(OOracleObject::Copy(other));
  261. }
  262.  
  263. const char *OSession::GetName(void) const
  264. {
  265.     if (ActionStart() != OSUCCESS)
  266.         return(NULL);
  267.     
  268.     if (!m_name)
  269.     {
  270.         char *cp = ((_IOraSession *) Internal())->get_Name();
  271.         
  272.         /*
  273.             we want to change the state of this const session by changing
  274.             the value of m_name.  Note that we're not really changing the
  275.             session, we're only changing what we know about the session
  276.         */                                                             
  277.         OSession *sessp = (OSession *) this;  // un-const the this pointer
  278.         sessp->m_name = cp;
  279.     }
  280.     return(m_name);
  281. }
  282.  
  283. const char *OSession::GetVersion(void) const
  284. {
  285.     // the version never changes, so if we have it, it is valid
  286.     if (m_version)
  287.         return(m_version);
  288.     
  289.     if (ActionStart() != OSUCCESS)
  290.         return(NULL);
  291.     
  292.     char *cp = ((_IOraSession *) Internal())->get_OipVersionNumber();
  293.         
  294.     /*
  295.         we want to change the state of this const session by changing
  296.         the value of m_version.  Note that we're not really changing the
  297.         session, we're only changing what we know about the session
  298.     */                                                             
  299.     OSession *sessp = (OSession *) this;  // un-const the this pointer
  300.     sessp->m_version = cp;
  301.     
  302.     return(m_version);
  303. }
  304.  
  305. long OSession::ServerErrorNumber(void) const
  306. {
  307.     if (ActionStart() != OSUCCESS)
  308.         return(0);
  309.     
  310.     long errno = ((_IOraSession *) Internal())->get_LastServerErr();
  311.     
  312.     return(errno);
  313. }
  314.  
  315. const char *OSession::GetServerErrorText(void) const
  316. {
  317.     if (ActionStart() != OSUCCESS)
  318.         return("");
  319.     
  320.     /*
  321.         we want to change the state of this const session by changing
  322.         the value of m_errtext.  Note that we're not really changing the
  323.         session, we're only changing what we know about the session
  324.     */                                                             
  325.     OSession *sessp = (OSession *) this;  // un-const the this pointer
  326.  
  327.     if (m_errtext)
  328.     { // discard old error text (to make sure we always get latest error)
  329.         OObjectFreeString(m_errtext);
  330.         sessp->m_errtext = 0;
  331.     }
  332.     
  333.     char *cp = ((_IOraSession *) Internal())->get_LastServerErrText();
  334.  
  335.     sessp->m_errtext = cp;
  336.  
  337.     return(m_errtext);
  338. }
  339.  
  340. oresult OSession::ServerErrorReset(void)
  341. {
  342.     if (ActionStart() != OSUCCESS)
  343.         return(OFAILURE);
  344.     
  345.     ((_IOraSession *) Internal())->LastServerErrReset();
  346.     
  347.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);
  348. }
  349.  
  350. oresult OSession::BeginTransaction(void)
  351. {
  352.     if (ActionStart() != OSUCCESS)
  353.         return(OFAILURE);
  354.     
  355.     ((_IOraSession *) Internal())->BeginTrans();
  356.  
  357.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);
  358. }
  359.  
  360. oresult OSession::Commit(oboolean startnew)
  361. {
  362.     if (ActionStart() != OSUCCESS)
  363.         return(OFAILURE);
  364.     
  365.     ((_IOraSession *) Internal())->CommitTrans();
  366.     long errno = ErrorNumber();
  367.     
  368.     if (0 == errno && startnew)
  369.     { // the commit worked.  start new transaction if user requested it
  370.         return(BeginTransaction());
  371.     }
  372.     
  373.     return((OERROR_NONE == errno) ? OSUCCESS : OFAILURE);
  374. }
  375.  
  376. oresult OSession::Rollback(oboolean startnew)
  377. {
  378.     if (ActionStart() != OSUCCESS)
  379.         return(OFAILURE);
  380.     
  381.     ((_IOraSession *) Internal())->Rollback();
  382.     long errno = ErrorNumber();
  383.     
  384.     if (OERROR_NONE == errno && startnew)
  385.     { // the rollback worked.  start new transaction if user requested it
  386.         return(BeginTransaction());
  387.     }
  388.     
  389.     return((OERROR_NONE == errno) ? OSUCCESS : OFAILURE);
  390. }
  391.  
  392. oresult OSession::ResetTransaction(void)
  393. {
  394.     if (ActionStart() != OSUCCESS)
  395.         return(OFAILURE);
  396.     
  397.     ((_IOraSession *) Internal())->ResetTrans();
  398.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);
  399. }
  400.  
  401. // ----- OClient -----------------------------------------------
  402.  
  403. OClient::OClient(void)
  404. {
  405.     m_name = 0;
  406. }
  407.  
  408. OClient::OClient(const OClient &other)
  409. {
  410.     m_name = 0;
  411.     Copy(other);
  412. }
  413.  
  414. OClient::~OClient(void)
  415. {
  416.     Cleanup();
  417. }
  418.  
  419. // overloaded assignment operator
  420. OClient &OClient::operator=(const OClient &other)
  421. {
  422.     if (&other == this)
  423.         return(*this); // self assignment - do nothing
  424.     
  425.     // clear out our old state
  426.     if (OSUCCESS == Cleanup())
  427.     {
  428.         Copy(other); // call copy constructor
  429.     }
  430.     // if the cleanup failed (possible but unlikely) we don't do the copy
  431.     //    and as a result, we pass on the unmodified (or partly cleaned!) object
  432.     
  433.     return(*this);
  434.  
  435. oresult OClient::Cleanup(void)
  436. {
  437.     if (m_name)
  438.     {
  439.         OObjectFreeString(m_name);
  440.         m_name = 0;
  441.     }
  442.     
  443.     return(OOracleObject::Cleanup());
  444. }
  445.  
  446. oresult OClient::Copy(const OClient &other)
  447. {
  448.     m_name = 0; // don't bother copying string
  449.     
  450.     return(OOracleObject::Copy(other));
  451. }
  452.  
  453. oresult OClient::OpenHelper(void *obji, void *otheri)
  454. {
  455.     if (!obji)
  456.     { // couldn't create client - error is on other object
  457.         SetOtherError(otheri);
  458.         return(OFAILURE);
  459.     }
  460.     IDispatch *connect = (IDispatch *) obji;
  461.     
  462.     Cleanup(); // clear out this object
  463.     
  464.     void *tempi;
  465.     HRESULT hc = connect->QueryInterface(IID_IOraClient, &tempi);
  466.     connect->Release();
  467.     if (FAILED(hc))
  468.     { // couldn't get the interface
  469.         SetInternalError(OERROR_NOINTER);
  470.         return(OFAILURE);
  471.     }
  472.     
  473.     return(SetObjectInterface(tempi));
  474. }
  475.  
  476. oresult OClient::Close(void)
  477. {
  478.     return(Cleanup());
  479. }
  480.  
  481. const char *OClient::GetName(void) const
  482. {
  483.     if (ActionStart() != OSUCCESS)
  484.         return(NULL);
  485.     
  486.     if (!m_name)
  487.     {
  488.         char *cp = ((_IOraClient *) Internal())->get_Name();
  489.         OClient *clp = (OClient *) this;  // un-const this
  490.         clp->m_name = cp;
  491.     }
  492.     
  493.     return(m_name);
  494. }
  495.  
  496. OSessionCollection OClient::GetSessions(void) const
  497. {
  498.     OSessionCollection cset;
  499.     
  500.     if (ActionGetStart(&cset) != OSUCCESS)
  501.         return(cset); // returning unopened object - indicates error
  502.     
  503.     IDispatch *connect = ((_IOraClient *) (Internal()))->get_Sessions();
  504.     
  505.     cset.OpenHelper((void *) connect, Internal());
  506.     
  507.     return(cset);
  508. }
  509.  
  510. // ----- OConnection -----------------------------------------------
  511.  
  512. OConnection::OConnection(void)
  513. {
  514.     // we don't have strings yet
  515.     m_dbname = 0;
  516.     m_dbconnect = 0;
  517. }
  518.  
  519. OConnection::OConnection(const OConnection &other)
  520. {
  521.     m_dbname = 0;
  522.     m_dbconnect = 0;
  523.     Copy(other);
  524. }
  525.  
  526. OConnection::~OConnection(void)
  527. {
  528.     Cleanup();
  529. }
  530.  
  531. // overloaded assignment operator
  532. OConnection &OConnection::operator=(const OConnection &other)
  533. {
  534.     if (&other == this)
  535.         return(*this); // self assignment - do nothing
  536.     
  537.     // clear out our old state
  538.     if (OSUCCESS == Cleanup())
  539.     {
  540.         Copy(other); // call copy constructor
  541.     }
  542.     // if the cleanup failed (possible but unlikely) we don't do the copy
  543.     //    and as a result, we pass on the unmodified (or partly cleaned!) object
  544.     
  545.     return(*this);
  546.  
  547. oresult OConnection::Close(void)
  548. {
  549.     return(Cleanup());
  550. }
  551.  
  552. oresult OConnection::Cleanup(void)
  553. {
  554.     if (m_dbname)
  555.     {
  556.         OObjectFreeString(m_dbname);
  557.         m_dbname = 0;
  558.     }
  559.     if (m_dbconnect)
  560.     {
  561.         OObjectFreeString(m_dbconnect);
  562.         m_dbconnect = 0;
  563.     }
  564.     
  565.     return(OOracleObject::Cleanup());
  566. }
  567.  
  568. oresult OConnection::Copy(const OConnection &other)
  569. {
  570.     m_dbname = 0;
  571.     m_dbconnect = 0;
  572.     
  573.     return(OOracleObject::Copy(other));
  574. }
  575.  
  576. oresult OConnection::OpenHelper(void *idisp, void *otheri)
  577.     Cleanup();
  578.         
  579.     if (!idisp)
  580.     {  // couldn't create connection.  error is on parent object
  581.         SetOtherError(otheri);
  582.         return(OFAILURE);
  583.     }
  584.     IDispatch *connect = (IDispatch *) idisp;  // cast, for convenience
  585.     
  586.     void *tempi;
  587.     HRESULT hc = connect->QueryInterface(IID_IOraConnection, &tempi);
  588.     connect->Release();
  589.     if (FAILED(hc))
  590.     { // couldn't get the interface
  591.         SetInternalError(OERROR_NOINTER);
  592.         return(OFAILURE);
  593.     }
  594.     
  595.     return(SetObjectInterface(tempi));
  596. }
  597.  
  598. OSession OConnection::GetSession(void) const
  599. {
  600.     OSession sess;
  601.     
  602.     if (ActionGetStart(&sess) != OSUCCESS)
  603.         return(sess); // returning unopened object - indicates error
  604.     
  605.     IDispatch *connect = ((_IOraConnection *) (Internal()))->get_Session();
  606.     sess.OpenHelper((void *) connect, Internal());
  607.     
  608.     return(sess);
  609. }
  610.  
  611. const char *OConnection::GetConnectString(void) const
  612. {
  613.     if (ActionStart() != OSUCCESS)
  614.         return(NULL);
  615.     
  616.     if (!m_dbconnect)
  617.     {
  618.         char *cp = ((_IOraConnection *) Internal())->get_Connect();
  619.         OConnection *connp = (OConnection *) this;  // un-const this
  620.         connp->m_dbconnect = cp;
  621.     }
  622.     return(m_dbconnect);
  623. }
  624.  
  625. const char *OConnection::GetDatabaseName(void) const
  626. {
  627.     if (ActionStart() != OSUCCESS)
  628.         return(NULL);
  629.     
  630.     if (!m_dbname)
  631.     {
  632.         char *cp = ((_IOraConnection *) Internal())->get_DatabaseName();
  633.         OConnection *connp = (OConnection *) this;  // un-const this
  634.         connp->m_dbname = cp;
  635.     }
  636.     return(m_dbname);
  637. }
  638.  
  639.