home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / po7_win / object10 / ofield.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-23  |  14.5 KB  |  626 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 OField class
  13.                            
  14.     CREATED    ********   11/22/94
  15.     RWOOLARD    MODIFIED    03/20/95
  16.                 bug#    262209  SetValue(NULL) causes GPF (in OValue)
  17.                         263418    GetFieldValue does not work with dates (in ODynaset)
  18.                         271184    SetValue succeeds when not in edit mode
  19. */
  20.  
  21. #include "windows.h"
  22. #include <ole2.h>
  23. #include <olenls.h>       
  24. #include <dispatch.h>  
  25.  
  26. #ifndef ORACL_ORACLE
  27. #include "oracl.h"
  28. #endif
  29.  
  30. #ifndef ORAOBJI_ORACLE
  31. #include "oraobji.h"
  32. #endif
  33.  
  34. #ifndef _OracleInProcServer_H_
  35. #include <oratlb.h>
  36. #endif
  37.  
  38. /*
  39.     Note that the C++ implementation of the field object does not use the _IOraField interface.
  40.     It simply uses the _IOraDynaset
  41. */
  42.  
  43. static const IID IID_IOraDynaset =
  44. {0xf0051a80, 0x00b3, 0x101b, { 0xad, 0xf2, 0x04, 0x02, 0x1c, 0x00, 0x70, 0x02 } };
  45.  
  46. // ----- OField -----------------------------------------------
  47.  
  48. OField::OField(void)
  49. {
  50.     m_name = 0; // don't know name yet
  51.     m_data = 0; 
  52.     m_index = 0;
  53.  
  54. OField::OField(const OField &other)
  55. {
  56.     m_name = 0;
  57.     m_data = 0;
  58.     m_index = 0;
  59.     Copy(other);
  60. }
  61.  
  62. OField::~OField(void)
  63. {
  64.     Cleanup();
  65. }
  66.  
  67. oresult OField::Copy(const OField &other)
  68. {
  69.     m_name = 0;
  70.     m_data = 0;
  71.     
  72.     m_index = other.m_index;
  73.     
  74.     return(OOracleObject::Copy(other));
  75. }
  76.  
  77. oresult OField::Close(void)
  78. {
  79.     return(Cleanup());
  80. }
  81.  
  82. oresult OField::Cleanup(void)
  83.     if (m_name)
  84.     {
  85.         OObjectFreeString(m_name);
  86.         m_name = 0;
  87.     }
  88.     
  89.     if (m_data)
  90.     {
  91.         OObjectFreeString(m_data);
  92.         m_data = 0;
  93.     }
  94.     
  95.     return(OOracleObject::Cleanup());   
  96. }
  97.  
  98. // overloaded assignment operator
  99. OField &OField::operator=(const OField &other)
  100. {
  101.     if (&other == this)
  102.         return(*this); // self assignment - do nothing
  103.     
  104.     // clear out our old state
  105.     if (OSUCCESS == Cleanup())
  106.     {
  107.         Copy(other); // call copy constructor
  108.     }
  109.     // if the cleanup failed (possible but unlikely) we don't do the copy
  110.     //    and as a result, we pass on the unmodified (or partly cleaned!) object
  111.     
  112.     return(*this);
  113.  
  114. ODynaset OField::GetDynaset(void) const
  115. {
  116.     ODynaset odyn;
  117.     
  118.     if (ActionGetStart(&odyn) != OSUCCESS)
  119.         return(odyn); // returning unopened object - indicates error
  120.     
  121.     // we just reopen the dynaset
  122.     ((IDispatch *) Internal())->AddRef(); // since we're adding another reference to it
  123.     
  124.     odyn.OpenHelper(Internal(), Internal());
  125.     
  126.     return(odyn);
  127. }
  128.  
  129. short OField::GetServerType(void) const
  130. {
  131.     if (ActionStart() != OSUCCESS)
  132.         return(0); // indicates error
  133.     
  134.     return (short) (((_IOraDynaset *) (Internal()))->_getFieldServerType(m_index));
  135. }
  136.  
  137.  
  138. short OField::GetPrecision(void) const
  139. {
  140.     if (ActionStart() != OSUCCESS)
  141.         return(0);
  142.     
  143.     return (short) (((_IOraDynaset *) (Internal()))->_getFieldPrecision(m_index));
  144. }
  145.  
  146.  
  147. short OField::GetScale(void) const
  148. {
  149.     if (ActionStart() != OSUCCESS)
  150.         return(0);
  151.     
  152.     return (short) (((_IOraDynaset *) (Internal()))->_getFieldScale(m_index));
  153. }
  154.  
  155. oboolean OField::IsTruncated(void) const
  156. {
  157.     if (ActionStart() != OSUCCESS)
  158.         return(FALSE);
  159.     
  160.     int ftype = GetServerType();
  161.     if (ftype != OTYPE_LONG && ftype != OTYPE_LONGRAW)
  162.     { // this field isn't a long
  163.         SetInternalError(OERROR_BADARG);
  164.         return(FALSE);
  165.     }
  166.     
  167.     int istrunc = ((_IOraDynaset *) (Internal()))->_isFieldTruncated(m_index);
  168.     return(istrunc ? TRUE : FALSE);  
  169. }
  170.  
  171. oboolean OField::IsNullOK(void) const
  172. {
  173.     if (ActionStart() != OSUCCESS)
  174.         return(FALSE);
  175.     
  176.     int isok = ((_IOraDynaset *) (Internal()))->_isFieldNullOK(m_index);
  177.     return(isok ? TRUE : FALSE);
  178. }
  179.  
  180. long OField::GetSize(void) const
  181. {
  182.     if (ActionStart() != OSUCCESS)
  183.         return(0);
  184.     
  185.     return(((_IOraDynaset *) Internal())->_getFieldSize(m_index));
  186. }
  187.  
  188. long OField::GetServerSize(void) const
  189. {
  190.     if (ActionStart() != OSUCCESS)
  191.         return(0);
  192.     
  193.     return(((_IOraDynaset *) Internal())->_getFieldDataSize(m_index));
  194. }
  195.  
  196. const char *OField::GetName(void) const
  197. {
  198.     if (ActionStart() != OSUCCESS)
  199.         return(NULL);
  200.     
  201.     if (!m_name)
  202.     {
  203.         char *cp = ((_IOraDynaset *) Internal())->_getFieldName(m_index);
  204.         /*
  205.             we want to change the state of this const field by changing
  206.             the value of m_name.  Note that we're not really changing the
  207.             field, we're only changing what we know about the field
  208.         */
  209.         OField *fp = (OField *) this;
  210.         fp->m_name = cp;
  211.     }
  212.     
  213.     return(m_name);
  214. }
  215.  
  216. oresult OField::GetValue(OValue *val) const
  217. {
  218.     if (! val)
  219.     {
  220.         SetInternalError(OERROR_BADARG);
  221.         return(OFAILURE);
  222.     }
  223.         
  224.     if (ActionStart() != OSUCCESS)
  225.     {
  226.         val->Clear(); // set value to NULL
  227.         return(OFAILURE); // error
  228.     }
  229.     
  230.     OOLEvar *vres = (OOLEvar *) val->Internal();
  231.     
  232.     ((_IOraDynaset *) Internal())->_getFieldValue(vres->GetVariant(), m_index);
  233.     vres->HaveSetVariant();
  234.     
  235.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  236.  
  237. oresult OField::GetValue(int *val) const
  238. {
  239.     if (! val)
  240.     {
  241.         SetInternalError(OERROR_BADARG);
  242.         return(OFAILURE);
  243.     }
  244.         
  245.     *val = (int) (*this);
  246.     return ((ErrorNumber() == OERROR_NONE) ? OSUCCESS : OFAILURE);
  247. }
  248.  
  249. oresult OField::GetValue(long *val) const
  250. {
  251.     if (! val)
  252.     {
  253.         SetInternalError(OERROR_BADARG);
  254.         return(OFAILURE);
  255.     }
  256.         
  257.     *val = (long) (*this);
  258.     return ((ErrorNumber() == OERROR_NONE) ? OSUCCESS : OFAILURE);
  259. }
  260.  
  261. oresult OField::GetValue(double *val) const
  262. {
  263.     if (! val)
  264.     {
  265.         SetInternalError(OERROR_BADARG);
  266.         return(OFAILURE);
  267.     }
  268.         
  269.     *val = (double) (*this);
  270.     return ((ErrorNumber() == OERROR_NONE) ? OSUCCESS : OFAILURE);
  271. }
  272.  
  273. oresult OField::GetValue(void __huge *longval, long len, long *readlen) const
  274. { // get a long value
  275.     if (! longval || ! readlen)
  276.     {
  277.         SetInternalError(OERROR_BADARG);
  278.         return(OFAILURE);
  279.     }
  280.         
  281.     // this is going to be heavyweight - so just call dynaset's code
  282.     ODynaset tempdyn = GetDynaset();
  283.     if (!tempdyn.IsOpen())
  284.         return(OFAILURE);  // error set in GetDynaset
  285.     
  286.     return(tempdyn.GetFieldValue(m_index, longval, len, readlen));    
  287. }
  288.  
  289. oresult OField::GetValue(const char **val) const
  290. {
  291.     if (! val)
  292.     {
  293.         SetInternalError(OERROR_BADARG);
  294.         return(OFAILURE);
  295.     }
  296.         
  297.     *val = (const char *) (*this);
  298.     return ((ErrorNumber() == OERROR_NONE) ? OSUCCESS : OFAILURE);
  299. }
  300.  
  301. oresult OField::SetValue(const OValue &val)
  302. {
  303.     if (ActionStart() != OSUCCESS)
  304.         return(OFAILURE);
  305.     
  306.     VARIANT *vres = ((OOLEvar *) (val.Internal()))->GetVariant();
  307.     
  308.     // set field value 
  309. //BUG #271184
  310.     HRESULT hr = ((_IOraDynaset *) Internal())->_updateFieldValue(vres, m_index);
  311.  
  312.     if (OERROR_NONE != ErrorNumber())
  313.         return OFAILURE;
  314.     else if (FAILED(hr))
  315.     {
  316.         SetInternalError(OERROR_INVRECORD);
  317.         return OFAILURE;
  318.     }
  319.     return OSUCCESS;    
  320. }      
  321.  
  322. oresult OField::SetValue(int val)
  323. {
  324.     if (ActionStart() != OSUCCESS)
  325.         return(OFAILURE);
  326.     
  327.     // set up VARIANT
  328.     OOLEvar vres;
  329.     vres.SetValue(val);
  330.     
  331.     // set field value
  332.     HRESULT hr = ((_IOraDynaset *) Internal())->_updateFieldValue(vres.GetVariant(), m_index);
  333.  
  334.     if (OERROR_NONE != ErrorNumber())
  335.         return OFAILURE;
  336.     else if (FAILED(hr))
  337.     {
  338.         SetInternalError(OERROR_INVRECORD);
  339.         return OFAILURE;
  340.     }
  341.     return OSUCCESS;
  342. }
  343.  
  344. oresult OField::SetValue(long val)
  345. {
  346.     if (ActionStart() != OSUCCESS)
  347.         return(OFAILURE);
  348.     
  349.     // set up VARIANT
  350.     OOLEvar vres;
  351.     vres.SetValue(val);
  352.     
  353.     // set field value
  354.     HRESULT hr = ((_IOraDynaset *) Internal())->_updateFieldValue(vres.GetVariant(), m_index);
  355.  
  356.     if (OERROR_NONE != ErrorNumber())
  357.         return OFAILURE;
  358.     else if (FAILED(hr))
  359.     {
  360.         SetInternalError(OERROR_INVRECORD);
  361.         return OFAILURE;
  362.     }
  363.     return OSUCCESS;    
  364. }
  365.  
  366. oresult OField::SetValue(double val)
  367. {
  368.     if (ActionStart() != OSUCCESS)
  369.         return(OFAILURE);
  370.     
  371.     // set up VARIANT
  372.     OOLEvar vres;
  373.     vres.SetValue(val);
  374.     
  375.     // set field value
  376.     HRESULT hr = ((_IOraDynaset *) Internal())->_updateFieldValue(vres.GetVariant(), m_index);
  377.  
  378.     if (OERROR_NONE != ErrorNumber())
  379.         return OFAILURE;
  380.     else if (FAILED(hr))
  381.     {
  382.         SetInternalError(OERROR_INVRECORD);
  383.         return OFAILURE;
  384.     }
  385.     return OSUCCESS;    
  386. }
  387.  
  388. oresult OField::SetValue(const char *val)
  389. {
  390.     if (ActionStart() != OSUCCESS)
  391.         return(OFAILURE);
  392.     
  393.     // set up VARIANT
  394.     OOLEvar vres;
  395.     vres.SetValue(val);
  396.     
  397.     // set field value
  398.     HRESULT hr = ((_IOraDynaset *) Internal())->_updateFieldValue(vres.GetVariant(), m_index);
  399.  
  400.     if (OERROR_NONE != ErrorNumber())
  401.         return OFAILURE;
  402.     else if (FAILED(hr))
  403.     {
  404.         SetInternalError(OERROR_INVRECORD);
  405.         return OFAILURE;
  406.     }
  407.     return OSUCCESS;    
  408. }
  409.  
  410. oresult OField::SetValue(const void __huge *longval, long len)
  411. { // set a long value
  412.     // this is going to be heavyweight - so just call dynaset's code
  413.     ODynaset tempdyn = GetDynaset();
  414.     if (!tempdyn.IsOpen())
  415.         return(OFAILURE);  // error set in GetDynaset
  416.     
  417.     return(tempdyn.SetFieldValue(m_index, longval, len));    
  418. }
  419.  
  420. oresult OField::AppendChunk(const void *chunkp, unsigned short numbytes)
  421. {
  422.     if (numbytes < 1)
  423.     {
  424.         SetInternalError (OERROR_BADARG);
  425.         return(OFAILURE);
  426.     }
  427.  
  428.     int fieldtype = GetServerType ();
  429.     if (fieldtype != OTYPE_LONG && fieldtype != OTYPE_LONGRAW)
  430.     {
  431.         SetInternalError (OERROR_BADTYPE);
  432.         return(OFAILURE);
  433.     }
  434.     
  435.     if (ActionStart() != OSUCCESS)
  436.         return(OFAILURE);
  437.     
  438.     // create a tempbuffer with the data in it
  439.     BSTR tempb = OObjectAllocStringLen((char *) chunkp, numbytes);
  440.     if (!tempb)
  441.     {
  442.         SetInternalError(OERROR_MEMORY);
  443.         return(OFAILURE);
  444.     }
  445.     
  446.     HRESULT hc = ((_IOraDynaset *) Internal())->_appendChunk(tempb, m_index);
  447.     if (FAILED(hc))
  448.     { // couldn't get the interface
  449.         SetInternalError(OERROR_NOINTER);
  450.     }
  451.     
  452.     OObjectFreeString(tempb);
  453.     
  454.     return((ErrorNumber() == OERROR_NONE) ? OSUCCESS : OFAILURE);
  455. }
  456.  
  457. oresult OField::GetChunk(const char **chunkp, long offset, unsigned short numbytes) const
  458. {
  459.     *chunkp = NULL;  // in case of error
  460.  
  461.     if (offset < 1 || numbytes < 1)
  462.     {
  463.         SetInternalError (OERROR_BADARG);
  464.         return(OFAILURE);
  465.     }
  466.     
  467.     int fieldtype = GetServerType ();
  468.     if (fieldtype != OTYPE_LONG && fieldtype != OTYPE_LONGRAW)
  469.     {
  470.         SetInternalError (OERROR_BADTYPE);
  471.         return(OFAILURE);
  472.     }
  473.     
  474.     if (ActionStart() != OSUCCESS)
  475.         return(OFAILURE);
  476.     
  477.     // we need a non-const version of "this" to manipulate m_data
  478.     OField *this2p = (OField *) this;
  479.     
  480.     if (m_data)
  481.     {
  482.         OObjectFreeString(this2p->m_data);
  483.         this2p->m_data = 0;
  484.     }
  485.     
  486.     HRESULT hc = ((_IOraDynaset *) Internal())->_getFieldChunk(&(this2p->m_data), m_index, offset,numbytes);
  487.     if (FAILED(hc))
  488.     { // couldn't get the interface
  489.         SetInternalError(OERROR_NOINTER);
  490.     }
  491.  
  492.     if (ErrorNumber() != OERROR_NONE)
  493.     {
  494.         // free the memory, if any
  495.         OObjectFreeString(this2p->m_data);
  496.         this2p->m_data = 0;
  497.         
  498.         return(OFAILURE);
  499.     }
  500.     else
  501.     { // success
  502.         *chunkp = m_data;
  503.         return(OSUCCESS);
  504.     }
  505. }                                           
  506.  
  507. oresult OField::OpenHelper(void *obji, void *otheri)
  508. {    
  509.     Cleanup();
  510.     if (!obji)
  511.     { // some error
  512.         SetOtherError(otheri);
  513.         return(OFAILURE);
  514.     }
  515.     
  516.     // obji is the field interface pointer.  We also want the dynaset interface and an index
  517.     
  518.     // get the dynaset & index
  519.     
  520.     IDispatch *idisp = ((_IOraField *) obji)->getDynaset();
  521.     
  522.     void *tempi;
  523.     HRESULT hc = idisp->QueryInterface(IID_IOraDynaset, &tempi);
  524.     idisp->Release();
  525.     if (FAILED(hc))
  526.     { // couldn't get the interface
  527.         ((IDispatch *) obji)->Release(); // we don't want field interface anymore
  528.         SetInternalError(OERROR_NOINTER);
  529.         return(OFAILURE);
  530.     }
  531.     
  532.     if (SetObjectInterface(tempi) != OSUCCESS)
  533.     {
  534.         ((IDispatch *) obji)->Release(); // we don't want field interface anymore
  535.         SetInternalError(OERROR_NOINTER);
  536.         return(OFAILURE);
  537.     }
  538.     
  539.     // now we have the dynaset - get the field's index
  540.     // we aren't going to keep the name
  541.     char *fname = ((_IOraField *) obji)->get_Name();
  542.     m_index = (short) ((_IOraDynaset *) Internal())->_getFieldIndex(fname);
  543.     OObjectFreeString(fname);
  544.     
  545.     // we're done
  546.     ((IDispatch *) obji)->Release(); // we don't want field interface anymore
  547.         
  548.     return(OSUCCESS);
  549. }
  550.  
  551. OField::operator int() const
  552. {
  553.     if (ActionStart() != OSUCCESS)
  554.         return(0);
  555.     
  556.     int val;
  557.     OOLEvar vres;
  558.     ((_IOraDynaset *) Internal())->_getFieldValue(vres.GetVariant(), m_index);
  559.     vres.HaveSetVariant();
  560.     
  561.     vres.GetValue(&val);
  562.     return(val);
  563. }
  564.  
  565. OField::operator long() const
  566. {
  567.     if (ActionStart() != OSUCCESS)
  568.         return(0);
  569.     
  570.     long val;
  571.     OOLEvar vres;
  572.     ((_IOraDynaset *) Internal())->_getFieldValue(vres.GetVariant(), m_index);
  573.     vres.HaveSetVariant();
  574.     
  575.     vres.GetValue(&val);
  576.     return(val);
  577. }
  578.  
  579. OField::operator double() const
  580. {
  581.     if (ActionStart() != OSUCCESS)
  582.         return(0.0);
  583.     
  584.     double val;
  585.     OOLEvar vres;
  586.     ((_IOraDynaset *) Internal())->_getFieldValue(vres.GetVariant(), m_index);
  587.     vres.HaveSetVariant();
  588.     
  589.     vres.GetValue(&val);
  590.     return(val);
  591. }
  592.  
  593. OField::operator const char *() const
  594. {
  595.     if (ActionStart() != OSUCCESS)
  596.         return(NULL);
  597.     
  598.     // for memory management we need non-const version of "this"
  599.     OField *of2 = (OField *) this;
  600.     
  601.     if (m_data)
  602.     {
  603.         OObjectFreeString(m_data);
  604.         of2->m_data = 0;
  605.     }
  606.     
  607.     OOLEvar vres;
  608.     const char *val;
  609.     ((_IOraDynaset *) Internal())->_getFieldValue(vres.GetVariant(), m_index);
  610.     vres.HaveSetVariant();
  611.     // now the string is in a BSTR owned by the VARIANT in vres
  612.     
  613.     vres.GetValue(&val); // get a pointer to the string
  614.     
  615.     // copy it so we don't lose it when vres is destroyed
  616.     of2->m_data = OObjectAllocString((const char *) val);
  617.     return(m_data);
  618. }
  619.  
  620.  
  621.  
  622.