home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / po7_win / object10 / odyn.cpp < prev    next >
C/C++ Source or Header  |  1995-04-13  |  38KB  |  1,461 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 ODynaset and ODynasetMark classes
  13.                            
  14.     CREATED    ********   11/22/94
  15.     RWOOLARD    MODIFIED    03/20/95
  16.                 bug#    260389    GetFieldValue() should check its arguments
  17.                         260789    All 'Chunk' code should check column type is a long 
  18.                         260868    AppendChuknk shuld not accept NULL pointer
  19.                         262112    Loop counter in DuplicateRecord should start from 0
  20.                         271055    OEF/BOF return -1 on success
  21.                            263418    GetFieldValue does not work with dates
  22. */
  23.  
  24. #include "windows.h"
  25. #include <ole2.h>
  26. #include <olenls.h>       
  27. #include <dispatch.h>  
  28.  
  29. #ifndef ORACL_ORACLE
  30. #include "oracl.h"
  31. #endif
  32.  
  33. #ifndef ORAOBJI_ORACLE
  34. #include "oraobji.h"
  35. #endif
  36.  
  37. #ifndef _OracleInProcServer_H_
  38. #include <oratlb.h>
  39. #endif
  40.  
  41. static const IID IID_IOraDynaset =
  42. {0xf0051a80, 0x00b3, 0x101b, { 0xad, 0xf2, 0x04, 0x02, 0x1c, 0x00, 0x70, 0x02 } };
  43. static const IID IID_IOraStream =
  44. {0x06beb9e0, 0xce61, 0x101b, { 0xb9, 0xd1, 0x04, 0x02, 0x1c, 0x00, 0x70, 0x02 } };
  45. static const IID IID_IOraMStream =
  46. {0x08c70d00, 0xce61, 0x101b, { 0xb9, 0xd1, 0x04, 0x02, 0x1c, 0x00, 0x70, 0x02 } };
  47.  
  48. // ----- ODynaset -----------------------------------------------
  49.  
  50. ODynaset::ODynaset(void)
  51. {
  52.     m_sqlstmt = 0;  // no sql statement yet
  53. }
  54.  
  55. ODynaset::ODynaset(const ODynaset &other)
  56. {
  57.     m_sqlstmt = 0;  // no sql statement yet
  58.     Copy(other);
  59. }
  60.  
  61. ODynaset::ODynaset(const ODatabase &odb, const char *sqlst, long options)
  62. {
  63.     m_sqlstmt = 0;  // no sql statement yet
  64.     Open(odb, sqlst, options);
  65. }
  66.  
  67. ODynaset::~ODynaset(void) 
  68. {
  69.     Cleanup();
  70. }
  71.  
  72. oresult ODynaset::Close(void)
  73. {
  74.     return(Cleanup());
  75. }
  76.  
  77. oresult ODynaset::Open(const ODatabase &odb, const char *sqlst, long options)
  78. {
  79.     if (!odb.IsOpen())
  80.     { // unopened database
  81.         SetInternalError(OERROR_INVPARENT);
  82.         return(OFAILURE);
  83.     }
  84.     if (!sqlst)
  85.     {
  86.         SetInternalError(OERROR_BADARG);
  87.         return(OFAILURE);
  88.     }
  89.     
  90.     odb.ErrorReset();
  91.     IDispatch *dyni = ((_IOraDatabase *) (odb.Internal()))->get_CreateDynaset((char *) sqlst, options);
  92.     
  93.     return(OpenHelper(dyni, odb.Internal()));
  94. }
  95.  
  96. ODynaset ODynaset::Clone(void) const
  97. {
  98.     ODynaset clonedyn;
  99.     
  100.     if (ActionGetStart(&clonedyn) != OSUCCESS)
  101.         return(clonedyn); // returning unopened object - indicates error
  102.     
  103.     IDispatch *dyni = ((_IOraDynaset *) (Internal()))->get_Clone();
  104.     
  105.     oresult ores = clonedyn.OpenHelper(dyni, Internal());
  106.     if (ores != OSUCCESS)
  107.         clonedyn.Close();  // make sure it isn't partly opened
  108.     
  109.     return(clonedyn);
  110. }  
  111.  
  112. oresult ODynaset::OpenHelper(void *id, void *otheri)
  113. {
  114.     if (!id) 
  115.     { // couldn't create dynaset - error is on other object
  116.         SetOtherError(otheri);
  117.         return(OFAILURE);
  118.     }
  119.     
  120.     Cleanup();
  121.         
  122.     IDispatch *idisp = (IDispatch *) id;
  123.     
  124.     void *tempi;    
  125.     HRESULT hc = idisp->QueryInterface(IID_IOraDynaset, &tempi);
  126.     idisp->Release();
  127.     if (FAILED(hc))
  128.     { // couldn't get the interface
  129.         SetInternalError(OERROR_NOINTER);
  130.         return(OFAILURE);
  131.     }
  132.     
  133.     return(SetObjectInterface(tempi));
  134. }
  135.  
  136. OFieldCollection ODynaset::GetFields(void) const
  137. {
  138.     OFieldCollection fs;
  139.     
  140.     if (ActionGetStart(&fs) != OSUCCESS)
  141.         return(fs); // returning unopened object - indicates error
  142.     
  143.     IDispatch *connect = ((_IOraDynaset *) (Internal()))->get_Fields();
  144.  
  145.     fs.OpenHelper((void *) connect, Internal());
  146.     
  147.     return(fs);
  148. }
  149.  
  150. OSession ODynaset::GetSession(void) const
  151. {
  152.     OSession sess;
  153.     
  154.     if (ActionGetStart(&sess) != OSUCCESS)
  155.         return(sess); // returning unopened object - indicates error
  156.     
  157.     IDispatch *connect = ((_IOraDynaset *) (Internal()))->get_Session();
  158.     
  159.     sess.OpenHelper((void *) connect, Internal());
  160.     
  161.     return(sess);
  162. }
  163.  
  164. ODatabase ODynaset::GetDatabase(void) const
  165. {
  166.     ODatabase odb;
  167.     
  168.     if (ActionGetStart(&odb) != OSUCCESS)
  169.         return(odb); // returning unopened object - indicates error
  170.     
  171.     IDispatch *db = ((_IOraDynaset *) (Internal()))->get_Database();
  172.     
  173.     odb.OpenHelper((void *) db, Internal());
  174.     
  175.     return(odb);
  176. }
  177.  
  178. OField ODynaset::GetField(int index) const
  179. {
  180.     return(GetFields().GetField(index));
  181. }
  182.      
  183. OField ODynaset::GetField(const char *fieldname) const
  184. {
  185.     int index = GetFieldIndex(fieldname);
  186.     if (index < 0)
  187.     { // bad index
  188.         OField closedfield;
  189.         closedfield.SetInternalError(OERROR_INVPARENT);
  190.         return(closedfield);
  191.     }
  192.     
  193.     return(GetFields().GetField(index));
  194. }
  195.  
  196. OConnection ODynaset::GetConnection(void) const
  197. {
  198.     OConnection conn;
  199.     
  200.     if (ActionGetStart(&conn) != OSUCCESS)
  201.         return(conn); // returning unopened object - indicates error
  202.     
  203.     IDispatch *connect = ((_IOraDynaset *) (Internal()))->get_Connection();
  204.     
  205.     conn.OpenHelper((void *) connect, Internal());
  206.     
  207.     return(conn);
  208. }
  209.  
  210. ODynasetMark ODynaset::GetMark(void) const
  211. {
  212.     ODynasetMark mrk;
  213.     
  214.     if (ActionGetStart(&mrk) != OSUCCESS)
  215.         return(mrk); // returning unopened object - indicates error
  216.     
  217.     void *obji = (void *) ((_IOraDynaset *) Internal())->get_Bookmark();
  218.     mrk.OpenHelper(obji, Internal());
  219.     
  220.     return(mrk);    
  221. }
  222.  
  223. ODynasetMark ODynaset::GetLastModifiedMark(void) const
  224. {
  225.     ODynasetMark mrk;
  226.     
  227.     if (ActionGetStart(&mrk) != OSUCCESS)
  228.         return(mrk); // returning unopened object - indicates error
  229.     
  230.     void *obji = (void *) ((_IOraDynaset *) Internal())->get_LastModified();
  231.     mrk.OpenHelper(obji, Internal());
  232.     
  233.     return(mrk);    
  234. }
  235.  
  236. // overloaded assignment operator
  237. ODynaset &ODynaset::operator=(const ODynaset &other)
  238. {
  239.     if (&other == this)
  240.         return(*this); // self assignment - do nothing
  241.     
  242.     // clear out our old state
  243.     if (OSUCCESS == Cleanup())
  244.     {
  245.         Copy(other); // call copy constructor
  246.     }
  247.     // if the cleanup failed (possible but unlikely) we don't do the copy
  248.     //    and as a result, we pass on the unmodified (or partly cleaned!) object
  249.     
  250.     return(*this);
  251.  
  252. oresult ODynaset::Copy(const ODynaset &other)
  253. {
  254.     // don't copy the sql statement
  255.     m_sqlstmt = 0;
  256.     
  257.     return(OOracleObject::Copy(other));
  258. }
  259.  
  260. oresult ODynaset::Cleanup(void)
  261. {
  262.     if (m_sqlstmt)
  263.     {
  264.         OObjectFreeString(m_sqlstmt);
  265.         m_sqlstmt = 0;
  266.     }
  267.     
  268.     return(OOracleObject::Cleanup());
  269. }   
  270.  
  271. oresult ODynaset::Refresh(void)
  272. {
  273.     if (ActionStart() != OSUCCESS)
  274.         return(OFAILURE);
  275.     
  276.     ((_IOraDynaset *) Internal())->Refresh();  // fires refresh advisory
  277.     if (ErrorNumber() == OERROR_NONE)
  278.     {
  279.         return(OSUCCESS);
  280.     }
  281.     else
  282.         return(OFAILURE);    
  283. }
  284.     
  285. oresult ODynaset::SetSQL(const char *sql_statement)
  286. {
  287.     if (ActionStart() != OSUCCESS)
  288.         return(OFAILURE);
  289.     if (!sql_statement)
  290.     {
  291.         SetInternalError(OERROR_BADARG);
  292.         return(OFAILURE);
  293.     }
  294.     
  295.     // this will invalidate our current sql statement
  296.     if (m_sqlstmt)
  297.     {
  298.         OObjectFreeString(m_sqlstmt);
  299.         m_sqlstmt = 0;
  300.     }
  301.     
  302.     // we need to hand in a real BSTR
  303.     BSTR tempcp = OObjectAllocString(sql_statement); 
  304.     if (!tempcp)
  305.     {
  306.         SetInternalError(OERROR_MEMORY);
  307.         return(OFAILURE);
  308.     }
  309.     ((_IOraDynaset *) Internal())->put_SQL(tempcp);
  310.     
  311.     if (ErrorNumber() == OERROR_NONE)
  312.     { // success, might as well remember the sql statment
  313.         m_sqlstmt = tempcp;  // now we don't need to free tempcp
  314.         return(OSUCCESS);
  315.     }
  316.     else
  317.     {
  318.         OObjectFreeString(tempcp);
  319.         return(OFAILURE);
  320.     }    
  321. }
  322.     
  323. const char *ODynaset::GetSQL(void) const
  324. {
  325.     if (ActionStart() != OSUCCESS)
  326.         return(NULL);
  327.     
  328.     // we always refetch the SQL statement, just in case
  329.     //   a copy of this ODynaset changed the underlying dynaset's
  330.     //   SQL statement
  331.     
  332.     // we need a non-const version of "this" to change m_sqlstmt
  333.     ODynaset *this2p = (ODynaset *) this;
  334.     
  335.     if (m_sqlstmt)
  336.     {
  337.         OObjectFreeString(m_sqlstmt);
  338.         this2p->m_sqlstmt = 0;
  339.     }
  340.     
  341.     this2p->m_sqlstmt = ((_IOraDynaset *) Internal())->get_SQL();
  342.     
  343.     return(m_sqlstmt);
  344. }
  345.  
  346. oresult ODynaset::MoveFirst(void)
  347. {
  348.     if (ActionStart() != OSUCCESS)
  349.         return(OFAILURE);
  350.     
  351.     ((_IOraDynaset *) Internal())->MoveFirst();
  352.     
  353.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  354. }
  355.  
  356. oresult ODynaset::MoveLast(void)
  357. {
  358.     if (ActionStart() != OSUCCESS)
  359.         return(OFAILURE);
  360.     
  361.     ((_IOraDynaset *) Internal())->MoveLast();
  362.     
  363.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  364. }
  365.  
  366. oresult ODynaset::MoveNext(oboolean gopast)
  367. {
  368.     if (ActionStart() != OSUCCESS)
  369.         return(OFAILURE);
  370.     
  371.     if (gopast)
  372.         ((_IOraDynaset *) Internal())->MoveNext();
  373.     else
  374.     {
  375.         ((_IOraDynaset *) Internal())->_moveNext();
  376.     }
  377.     
  378.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  379. }
  380.  
  381. oresult ODynaset::MovePrev(oboolean gopast)
  382. {
  383.     if (ActionStart() != OSUCCESS)
  384.         return(OFAILURE);
  385.     
  386.     if (gopast)
  387.         ((_IOraDynaset *) Internal())->MovePrevious();
  388.     else
  389.     {
  390.         ((_IOraDynaset *) Internal())->_movePrev();
  391.     }
  392.     
  393.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  394. }
  395.  
  396. oresult ODynaset::MoveToMark(const ODynasetMark &odmark)
  397. {
  398.     if (ActionStart() != OSUCCESS)
  399.         return(OFAILURE);
  400.     
  401.     if (!odmark.IsOpen())
  402.     {
  403.         SetInternalError(OERROR_INVBKMRK);
  404.         return(OFAILURE);
  405.     }
  406.     const BSTR themark = ((const BSTR) (odmark.Internal())); // get the mark
  407.     ((_IOraDynaset *) Internal())->put_Bookmark(themark);
  408.     
  409.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  410. }
  411.  
  412. oboolean ODynaset::IsEOF(void) const
  413. {
  414.     if (ActionStart() != OSUCCESS)
  415.         return(TRUE);
  416.     
  417. // BUG #271055 get_EOF returns -1 on success !!
  418.     return(((_IOraDynaset *) Internal())->get_EOF() ? TRUE : FALSE);
  419. }
  420.  
  421. oboolean ODynaset::IsBOF(void) const
  422. {
  423.     if (ActionStart() != OSUCCESS)
  424.         return(TRUE);
  425.     
  426. // BUG #271055 get_BOF returns -1 on success !!
  427.     return(((_IOraDynaset *) Internal())->get_BOF() ? TRUE : FALSE);
  428. }
  429.  
  430. oboolean ODynaset::IsFirst(void) const
  431. {
  432.     if (ActionStart() != OSUCCESS)
  433.         return(FALSE);          
  434.         
  435.     return(((_IOraDynaset *) Internal())->get_IsFirst() ? TRUE : FALSE);
  436. }
  437.  
  438. oboolean ODynaset::IsLast(void) const
  439. {
  440.     if (ActionStart() != OSUCCESS)
  441.         return(FALSE);
  442.     
  443.     int    test = ((_IOraDynaset *) Internal())->get_IsLast();    
  444.     return(test ? TRUE : FALSE);
  445. }
  446.  
  447. oboolean ODynaset::IsValidRecord(void) const
  448. {
  449.     // we tell if the current row is valid by trying to get a bookmark
  450.     if (ActionStart() != OSUCCESS)
  451.         return(FALSE);
  452.     
  453.     ODynasetMark tempmark = GetMark();
  454.     // if that failed then an error will be set on bookmark (which goes away
  455.     //    and on the dynaset
  456.     
  457.     return (tempmark.IsOpen());
  458. }   
  459.  
  460. oboolean ODynaset::CanTransact(void) const
  461. {
  462.     if (ActionStart() != OSUCCESS)
  463.         return(FALSE);
  464.     
  465.     BOOL cantran = ((_IOraDynaset *) Internal())->get_Transactions();
  466.     return(cantran ? TRUE : FALSE);    
  467. }
  468.  
  469. oboolean ODynaset::CanUpdate(void) const
  470. {
  471.     if (ActionStart() != OSUCCESS)
  472.         return(FALSE);
  473.     
  474.     BOOL canup = ((_IOraDynaset *) Internal())->get_Updatable();
  475.     return(canup ? TRUE : FALSE);    
  476. }
  477.  
  478. oboolean ODynaset::CanRefresh(void) const
  479. {
  480.     // can always refresh if we're open
  481.     return (IsOpen());
  482. }
  483.  
  484. oboolean ODynaset::CanScroll(void) const
  485. {
  486.     // we can always scroll if we can mark
  487.     return CanMark();
  488. }
  489.  
  490. oboolean ODynaset::CanMark(void) const
  491. {
  492.     if (ActionStart() != OSUCCESS)
  493.         return(FALSE);
  494.     
  495.     BOOL canmark = ((_IOraDynaset *) Internal())->get_Bookmarkable();
  496.     return(canmark ? TRUE : FALSE);    
  497. }
  498.  
  499. long ODynaset::GetOptions(void) const
  500. {
  501.     if (ActionStart() != OSUCCESS)
  502.         return(ODYNASET_DEFAULT);
  503.     
  504.     return(((_IOraDynaset *) Internal())->get_Options());    
  505. }
  506.  
  507. int ODynaset::GetEditMode(void) const
  508. {
  509.     int editmode;
  510.     
  511.     if (ActionStart() != OSUCCESS)
  512.         return(ODYNASET_EDIT_NOEDIT);
  513.     
  514.     editmode = ((_IOraDynaset *) Internal())->get_EditMode();
  515.     
  516.     return(editmode); // values are ODYNASET_EDIT_*
  517. }
  518.  
  519. oresult ODynaset::StartEdit(void)
  520. {
  521.     if (ActionStart() != OSUCCESS)
  522.         return(OFAILURE);
  523.     
  524.     ((_IOraDynaset *) Internal())->Edit();
  525.     
  526.     return((0 == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  527. }
  528.  
  529. oresult ODynaset::CancelEdit(void)
  530. {
  531.     if (ActionStart() != OSUCCESS)
  532.         return(OFAILURE);
  533.     
  534.     ((_IOraDynaset *) Internal())->UpdateControls();
  535.     
  536.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  537. }
  538.  
  539. oresult ODynaset::Update(void)
  540. {
  541.     if (ActionStart() != OSUCCESS)
  542.         return(OFAILURE);
  543.     
  544.     ((_IOraDynaset *) Internal())->Update();
  545.     
  546.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  547. }
  548.  
  549. oresult ODynaset::AddNewRecord(void)
  550. {
  551.     if (ActionStart() != OSUCCESS)
  552.         return(OFAILURE);
  553.     
  554.     ((_IOraDynaset *) Internal())->AddNew();
  555.     
  556.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  557. }
  558.  
  559. // special struct for DuplicateRecord
  560. struct VarList
  561. {
  562.     VARIANT  *val;
  563.     VarList   *next;
  564. };
  565.  
  566. oresult ODynaset::DuplicateRecord(void)
  567. {
  568.     if (ActionStart() != OSUCCESS)
  569.         return(OFAILURE);
  570.     
  571.     if (!IsValidRecord())
  572.     {
  573.         SetInternalError(OERROR_INVRECORD);
  574.         return(OFAILURE);
  575.     }
  576.     
  577.     // first get all the values of the current record
  578.     
  579.     // start list of values
  580.     VarList *vhead = new VarList;
  581.     VarList *curr = vhead;
  582.     
  583.     short findex;
  584.     int nfields = GetFieldCount();
  585. //BUG #262112    
  586.     for (findex = 0; findex < nfields; findex++)
  587.     {
  588.         curr->val = new VARIANT;
  589.         VariantInit(curr->val);
  590.         ((_IOraDynaset *) Internal())->_getFieldValue(curr->val, findex);
  591.         
  592.         if (findex < nfields - 1)
  593.         { // start next item
  594.             curr->next = new VarList;
  595.             curr = curr->next;
  596.         }
  597.         else
  598.         { // this is the last item
  599.             curr->next = 0;
  600.         }
  601.     }
  602.     
  603.     // now add a new record
  604.     ((_IOraDynaset *) Internal())->AddNew();                                       
  605.     
  606.     if (OERROR_NONE == ErrorNumber())
  607.     { // we were able to add the new record.  Set field values
  608.         findex = 0;
  609.         curr = vhead;
  610.         while (curr)
  611.         {
  612.             ((_IOraDynaset *) Internal())->_updateFieldValue(curr->val, findex++);
  613.             if (OERROR_NONE != ErrorNumber())
  614.                 break;  // bail out on error
  615.             curr = curr->next;
  616.         }
  617.     }
  618.     
  619.     // now get rid of all of the values
  620.     curr = vhead;
  621.     VarList *nextp;
  622.     while (curr)
  623.     {
  624.         nextp = curr->next;
  625.         VariantClear(curr->val);
  626.         delete curr->val;
  627.         delete curr;
  628.         curr = nextp;
  629.     }
  630.     
  631.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  632. }
  633.  
  634. oresult ODynaset::DeleteRecord(void)
  635. {
  636.     if (ActionStart() != OSUCCESS)
  637.         return(OFAILURE);
  638.     
  639.     ((_IOraDynaset *) Internal())->Delete();
  640.     
  641.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  642. }
  643.  
  644. int ODynaset::GetFieldCount(void) const
  645. {
  646.     if (ActionStart() != OSUCCESS)
  647.         return(0);
  648.     
  649.     return(((_IOraDynaset *) Internal())->_getFieldCount());
  650. }    
  651.  
  652. long ODynaset::GetRecordCount(void) const
  653. {
  654.     if (ActionStart() != OSUCCESS)
  655.         return(0);
  656.     
  657.     return(((_IOraDynaset *) Internal())->get_RecordCount());
  658. }    
  659.  
  660. int ODynaset::GetFieldIndex(const char *fieldname) const
  661. {
  662.     if (ActionStart() != OSUCCESS)
  663.         return(-1);
  664.     if (!fieldname)
  665.     {
  666.         SetInternalError(OERROR_BADARG);
  667.         return(-1);
  668.     }
  669.     
  670.     // pass in a real BSTR for fieldname (ARGHH)
  671.     BSTR tempf = OObjectAllocString(fieldname);
  672.     int index = ((_IOraDynaset *) Internal())->_getFieldIndex((char *) tempf);
  673.     OObjectFreeString(tempf);
  674.     
  675.     return((0 == ErrorNumber()) ? index : -1);    
  676. }
  677.  
  678. oboolean ODynaset::IsFieldTruncated(int index) const
  679. {
  680.     if (ActionStart() != OSUCCESS)
  681.         return(FALSE);
  682.  
  683.     int ftype = GetFieldServerType(index);
  684. //BUG #260789    
  685.     if (ftype != OTYPE_LONG && ftype != OTYPE_LONGRAW)
  686.     { // this field isn't a long
  687.         SetInternalError(OERROR_BADARG);
  688.         return(FALSE);
  689.     }
  690.     
  691.     int istrunc = ((_IOraDynaset *) (Internal()))->_isFieldTruncated(index);
  692.     return(istrunc ? TRUE : FALSE);  
  693. }
  694.  
  695. oboolean ODynaset::IsFieldTruncated(const char *fieldname) const
  696. {
  697.     int index = GetFieldIndex(fieldname);
  698.     if (index < 0)
  699.         return(FALSE);
  700.     return(IsFieldTruncated(index));
  701. }
  702.  
  703. short ODynaset::GetFieldServerType(int index) const
  704. {
  705.     if (ActionStart() != OSUCCESS)
  706.         return(0);
  707.     
  708.     return (short) (((_IOraDynaset *) (Internal()))->_getFieldServerType(index));
  709. }
  710.  
  711. short ODynaset::GetFieldServerType(const char *fieldname) const
  712. {
  713.     int index = GetFieldIndex(fieldname);
  714.     if (index < 0)
  715.         return(0);
  716.     return (GetFieldServerType(index));
  717. }
  718.  
  719. short ODynaset::GetFieldPrecision(int index) const
  720. {
  721.     if (ActionStart() != OSUCCESS)
  722.         return(0);
  723.     
  724.     return (short) (((_IOraDynaset *) (Internal()))->_getFieldPrecision(index));
  725. }
  726.  
  727. short ODynaset::GetFieldPrecision(const char *fieldname) const
  728. {
  729.     int index = GetFieldIndex(fieldname);
  730.     if (index < 0)
  731.         return(0);
  732.     return(GetFieldPrecision(index));
  733. }
  734.  
  735. short ODynaset::GetFieldScale(int index) const
  736. {
  737.     if (ActionStart() != OSUCCESS)
  738.         return(0);
  739.     
  740.     return (short) (((_IOraDynaset *) (Internal()))->_getFieldScale(index));
  741. }
  742.  
  743. short ODynaset::GetFieldScale(const char *fieldname) const
  744. {
  745.     int index = GetFieldIndex(fieldname);
  746.     if (index < 0)
  747.         return(0);
  748.     return(GetFieldScale(index));
  749. }
  750.  
  751. long ODynaset::GetFieldSize(int index) const
  752. {
  753.     if (ActionStart() != OSUCCESS)
  754.         return(0);
  755.     
  756.     return(((_IOraDynaset *) (Internal()))->_getFieldSize(index));
  757. }
  758.  
  759. long ODynaset::GetFieldSize(const char *fieldname) const
  760. {
  761.     int index = GetFieldIndex(fieldname);
  762.     if (index < 0)
  763.         return(0);
  764.     return(GetFieldSize(index));
  765. }
  766.  
  767. long ODynaset::GetFieldServerSize(int index) const
  768. {
  769.     if (ActionStart() != OSUCCESS)
  770.         return(0);
  771.     
  772.     return(((_IOraDynaset *) (Internal()))->_getFieldDataSize(index));
  773. }
  774.  
  775. long ODynaset::GetFieldServerSize(const char *fieldname) const
  776. {
  777.     int index = GetFieldIndex(fieldname);
  778.     if (index < 0)
  779.         return(0);
  780.     return(GetFieldServerSize(index));
  781. }
  782.  
  783. oboolean ODynaset::IsFieldNullOK(int index) const
  784. {
  785.      if (ActionStart() != OSUCCESS)
  786.         return(FALSE);
  787.     
  788.     int isok = ((_IOraDynaset *) (Internal()))->_isFieldNullOK(index);
  789.     return(isok ? TRUE : FALSE);
  790. }
  791.  
  792. oboolean ODynaset::IsFieldNullOK(const char *fieldname) const
  793. {
  794.     int index = GetFieldIndex(fieldname);
  795.     if (index < 0)
  796.         return(0);
  797.     return(IsFieldNullOK(index));
  798. }
  799.  
  800. oresult ODynaset::GetFieldValue(int index, OValue *val) const
  801. {                   
  802. //BUG #260389
  803.     if (! val)
  804.     {
  805.         SetInternalError(OERROR_BADARG);
  806.         return(OFAILURE);
  807.     }
  808.         
  809.     if (ActionStart() != OSUCCESS)
  810.     {
  811.         val->Clear(); // clear it
  812.         return(OFAILURE);
  813.     }
  814.     
  815.     // get pointer to OOLEvar inside the OValue
  816.     //   we then directly set the VARIANT in the OOLEvar - which sets the OValue
  817.     OOLEvar *vres = (OOLEvar *) val->Internal();
  818.     ((_IOraDynaset *) Internal())->_getFieldValue(vres->GetVariant(), index);
  819.     vres->HaveSetVariant();
  820.     
  821.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  822. }
  823.  
  824. oresult ODynaset::GetFieldValue(const char *fieldname, OValue *val) const
  825. {
  826. //BUG #260389
  827.     if (! val || ! fieldname)
  828.     {
  829.         SetInternalError(OERROR_BADARG);
  830.         return(OFAILURE);
  831.     }
  832.         
  833.     int index = GetFieldIndex(fieldname);
  834.     if (index < 0)
  835.         return(OFAILURE);  // return without calling GetFieldValue so errors don't get muddled
  836.     return(GetFieldValue(index, val));
  837. }
  838.  
  839. oresult ODynaset::GetFieldValue(int index, int *val) const
  840. {
  841. //BUG #260389
  842.     if (! val)
  843.     {
  844.         SetInternalError(OERROR_BADARG);
  845.         return(OFAILURE);
  846.     }
  847.         
  848.     if (ActionStart() != OSUCCESS)
  849.         return(OFAILURE);
  850.  
  851.     OOLEvar vres;
  852.     ((_IOraDynaset *) Internal())->_getFieldValue(vres.GetVariant(), index);
  853.     vres.HaveSetVariant();
  854.     
  855.     return(vres.GetValue(val));
  856. }
  857.  
  858. oresult ODynaset::GetFieldValue(const char *fieldname, int *val) const
  859. {
  860. //BUG #260389
  861.     if (! val || ! fieldname)
  862.     {
  863.         SetInternalError(OERROR_BADARG);
  864.         return(OFAILURE);
  865.     }
  866.         
  867.     int index = GetFieldIndex(fieldname);
  868.     if (index < 0)
  869.         return(OFAILURE);  // return without calling GetFieldValue so errors don't get muddled
  870.     return(GetFieldValue(index, val));
  871. }
  872.  
  873. oresult ODynaset::GetFieldValue(int index, long *val) const
  874. {
  875. //BUG #260389
  876.     if (! val)
  877.     {
  878.         SetInternalError(OERROR_BADARG);
  879.         return(OFAILURE);
  880.     }
  881.         
  882.     if (ActionStart() != OSUCCESS)
  883.         return(OFAILURE);
  884.  
  885.     OOLEvar vres;
  886.     ((_IOraDynaset *) Internal())->_getFieldValue(vres.GetVariant(), index);
  887.     vres.HaveSetVariant();
  888.     
  889.     return(vres.GetValue(val));
  890. }
  891.  
  892. oresult ODynaset::GetFieldValue(const char *fieldname, long *val) const
  893. {
  894. //BUG #260389
  895.     if (! val || ! fieldname)
  896.     {
  897.         SetInternalError(OERROR_BADARG);
  898.         return(OFAILURE);
  899.     }
  900.         
  901.     int index = GetFieldIndex(fieldname);
  902.     if (index < 0)
  903.         return(OFAILURE);  // return without calling GetFieldValue so errors don't get muddled
  904.     return(GetFieldValue(index, val));
  905. }
  906.  
  907. oresult ODynaset::GetFieldValue(int index, double *val) const
  908. {
  909. //BUG #260389
  910.     if (! val)
  911.     {
  912.         SetInternalError(OERROR_BADARG);
  913.         return(OFAILURE);
  914.     }
  915.         
  916.     if (ActionStart() != OSUCCESS)
  917.         return(OFAILURE);
  918.  
  919.     OOLEvar vres;
  920.     ((_IOraDynaset *) Internal())->_getFieldValue(vres.GetVariant(), index);
  921.     vres.HaveSetVariant();
  922.     
  923.     return(vres.GetValue(val));
  924. }
  925.  
  926. oresult ODynaset::GetFieldValue(const char *fieldname, double *val) const
  927. {
  928. //BUG #260389
  929.     if (! val || ! fieldname)
  930.     {
  931.         SetInternalError(OERROR_BADARG);
  932.         return(OFAILURE);
  933.     }
  934.         
  935.     int index = GetFieldIndex(fieldname);
  936.     if (index < 0)
  937.         return(OFAILURE);  // return without calling GetFieldValue so errors don't get muddled
  938.     return(GetFieldValue(index, val));
  939. }
  940.  
  941. oresult ODynaset::GetFieldValue(int index, char *val, unsigned short maxlen) const
  942. {
  943. //BUG #260389
  944.     if (! val || maxlen < 1)
  945.     {
  946.         SetInternalError(OERROR_BADARG);
  947.         return(OFAILURE);
  948.     }
  949.     
  950.     // we need to get the value and then copy the characters - up to the maximum length
  951.     OValue oval;
  952.     
  953.     if (GetFieldValue(index, &oval) != OSUCCESS)
  954.         return(OFAILURE);
  955.  
  956. // BUG #263418    GetFieldValue does not work with dates   
  957.     // what is the length of the string?
  958.     OOLEvar *vres = (OOLEvar *) oval.Internal();
  959.     // Need to call the GetValue method just to convert the OOLEvar into a string.
  960.     // This is required if the variant is a date, but not if it is a string already.
  961.     // The overhead of doing this is no more than that of getting the variant type
  962.     // and only calling for dates. Note that buf is just a pointer and will be set
  963.     // point at the string, but it is never used.
  964.     const char *buf;
  965.     vres->GetValue (&buf);
  966.     // now we can get the length
  967.     unsigned int slen = vres->GetStringLength();
  968.     if (slen > (unsigned int) maxlen-1)
  969.         slen = maxlen-1; // -1 to leave space for null termination
  970.     
  971.     // copy string (DBCS problem)
  972.     memcpy(val, (const char *) oval, slen);
  973.     // null terminate
  974.     val[slen] = '\0';
  975.     
  976.     return(OSUCCESS);
  977. }
  978.  
  979. oresult ODynaset::GetFieldValue(const char *fieldname, char *val, unsigned short maxlen) const
  980. {
  981. //BUG #260389
  982.     if (! val || ! fieldname || maxlen < 1)
  983.     {
  984.         SetInternalError(OERROR_BADARG);
  985.         return(OFAILURE);
  986.     }
  987.         
  988.     int index = GetFieldIndex(fieldname);
  989.     if (index < 0)
  990.         return(OFAILURE);  // return without calling GetFieldValue so errors don't get muddled
  991.     return(GetFieldValue(index, val, maxlen));
  992. }
  993.  
  994. oresult ODynaset::GetFieldValue(int index, void __huge *longval, long len, long *readlen) const
  995. {
  996. //BUG #260389
  997.     if (! longval || len < 1 || ! readlen)
  998.     {
  999.         SetInternalError(OERROR_BADARG);
  1000.         return(OFAILURE);
  1001.     }
  1002.         
  1003.     if (ActionStart() != OSUCCESS)
  1004.     {
  1005.         *readlen = 0;
  1006.         return(OFAILURE);
  1007.     }
  1008.     int ftype = GetFieldServerType(index);
  1009. //BUG #260789    
  1010.     if (ftype != OTYPE_LONG && ftype != OTYPE_LONGRAW)
  1011.     { // this field isn't a long (which we don't allow yet)
  1012.         *readlen = 0;
  1013.         SetInternalError(OERROR_BADTYPE);
  1014.         return(OFAILURE);
  1015.     }
  1016.  
  1017.     if (len < 1)
  1018.     { // this field isn't a long, or negative length (which we don't allow yet)
  1019.         *readlen = 0;
  1020.         SetInternalError(OERROR_BADARG);
  1021.         return(OFAILURE);
  1022.     }
  1023.     
  1024.     // fetch the long field value
  1025.     OOLEvar vres;
  1026.     ((_IOraDynaset *) Internal())->_fetchLongFieldValue(vres.GetVariant(), index, len);
  1027.     vres.HaveSetVariant();
  1028.     
  1029.     if (vres.IsNull())
  1030.     { // there was nothing in the field
  1031.         *readlen = 0;
  1032.         return(OSUCCESS);
  1033.     }
  1034.     
  1035.     // we've got something - try to get data from it
  1036.     VARIANT *varp = vres.GetVariant();
  1037.     if (V_VT(varp) != VT_UNKNOWN)
  1038.     { // we don't have expected interface
  1039.         SetInternalError(OERROR_SYSTEM);
  1040.         return(OFAILURE);
  1041.     }
  1042.     
  1043.     // get the _IOraStream interface
  1044.     IUnknown *unkp = V_UNKNOWN(varp);
  1045.     void *istr;    
  1046.     HRESULT hc = unkp->QueryInterface(IID_IOraMStream, &istr);
  1047.     // unkp->Release(); don't release because VARIANT owns it
  1048.     if (FAILED(hc))
  1049.     { // couldn't get the interface
  1050.         SetInternalError(OERROR_NOINTER);
  1051.         return(OFAILURE);
  1052.     }
  1053.     
  1054.     // use the _IOraStream interface to copy the bytes
  1055.     // figure out how long the stream is
  1056.     long pos;
  1057.     ((_IOraMStream *) istr)->Seek(0L, STREAM_SEEK_CUR, &pos);
  1058.     if (pos < len)
  1059.     { // we weren't able to read as many bytes as asked for
  1060.         len = pos; // adjust # of bytes we will try to read
  1061.         /*
  1062.             With 16bit OCI we will only be able to tell the length
  1063.             of the long (before reading it all) if len < 64K.  So
  1064.             if len >= 64K pos will always == len
  1065.         */
  1066.     }
  1067.     
  1068.     // now seek to beginning
  1069.     ((_IOraMStream *) istr)->Seek(0L, STREAM_SEEK_SET, &pos);
  1070.     
  1071.     // and read
  1072.     hc = ((_IOraMStream *) istr)->Read(longval, len, readlen);
  1073.     
  1074.     ((_IOraMStream *) istr)->Release();
  1075.     if (FAILED(hc))
  1076.     {
  1077.         SetInternalError(GetScode(hc));
  1078.         return(OFAILURE);
  1079.     }    
  1080.     
  1081.     return(OSUCCESS);
  1082. }
  1083.  
  1084. oresult ODynaset::GetFieldValue(const char *fieldname, void __huge *longval, long len, long *readlen) const
  1085. {
  1086. //BUG #260389
  1087.     if (! longval || ! fieldname || ! readlen)
  1088.     {
  1089.         SetInternalError(OERROR_BADARG);
  1090.         return(OFAILURE);
  1091.     }
  1092.         
  1093.     int index = GetFieldIndex(fieldname);
  1094.     if (index < 0)
  1095.         return(OFAILURE);  // return without calling GetFieldValue so errors don't get muddled
  1096.     return(GetFieldValue(index, longval, len, readlen));
  1097. }
  1098.  
  1099. oresult ODynaset::GetFieldChunk(int index, void *chunkp, long offset, unsigned short len) const 
  1100. {
  1101.     if (! chunkp || len < 1 || offset < 1)
  1102.     {
  1103.         SetInternalError(OERROR_BADARG);
  1104.         return(OFAILURE);
  1105.     }
  1106.         
  1107.     if (ActionStart() != OSUCCESS)
  1108.         return(OFAILURE);
  1109.     
  1110.     int fieldtype = GetFieldServerType (index);
  1111. //BUG #260789    
  1112.     if (fieldtype != OTYPE_LONG && fieldtype != OTYPE_LONGRAW)
  1113.     {
  1114.         SetInternalError (OERROR_BADTYPE);
  1115.         return(OFAILURE);
  1116.     }
  1117.     
  1118.     BSTR tempp;
  1119.     HRESULT hc = ((_IOraDynaset *) Internal())->_getFieldChunk(&tempp, index, offset, len);
  1120.     if (FAILED(hc))
  1121.     { // couldn't get the interface
  1122.         SetInternalError(OERROR_NOINTER);
  1123.     }
  1124.  
  1125.     if (ErrorNumber() != OERROR_NONE)
  1126.     {
  1127.         // clean up
  1128.         SysFreeString(tempp);
  1129.         return(OFAILURE);
  1130.     }
  1131.     else
  1132.     { // copy the string to the user's buffer
  1133.         memcpy((void *) chunkp, (const void *) tempp, len);
  1134.         
  1135.         // clean up
  1136.         SysFreeString(tempp);
  1137.         return(OSUCCESS);
  1138.     }
  1139. }
  1140.  
  1141. oresult ODynaset::GetFieldChunk(const char *fieldname, void *chunkp, long offset, unsigned short len) const
  1142. {
  1143.     if (! fieldname)
  1144.     {   // Other bad arguments are handled by the overloaded GetFieldChunk called at end of routine
  1145.         SetInternalError(OERROR_BADARG);
  1146.         return(OFAILURE);
  1147.     }
  1148.  
  1149.     int index = GetFieldIndex(fieldname);
  1150.     if (index < 0)
  1151.         return(OFAILURE);  // return without calling GetFieldValue so errors don't get muddled
  1152.     return(GetFieldChunk(index, chunkp, offset, len));
  1153. }
  1154.  
  1155. oresult ODynaset::SetFieldValue(int index, const void __huge *longval, long len)
  1156. {
  1157.     if (ActionStart() != OSUCCESS)
  1158.         return(OFAILURE);
  1159.     
  1160.     // create the IOraStream interface
  1161.     _IOraMStream *istr;
  1162.     ((_IOraDynaset *) Internal())->_createMStream(&istr);
  1163.     
  1164.     // now write the data to the stream
  1165.     long readlen;
  1166.     HRESULT hc = istr->Write((void *) longval, len, &readlen);
  1167.     if (FAILED(hc) || readlen != len)
  1168.     {
  1169.         istr->Release();
  1170.         SetInternalError(OERROR_MEMORY);
  1171.         return(OFAILURE);
  1172.     }
  1173.     
  1174.     // hand this to the field
  1175.     VARIANT val;
  1176.     VariantInit(&val);
  1177.     V_VT(&val) = VT_UNKNOWN;
  1178.     V_UNKNOWN(&val) = istr;
  1179.     
  1180.     ((_IOraDynaset *) Internal())->_updateFieldValue(&val, index);
  1181.     
  1182.     VariantClear(&val);  // releases stream
  1183.     
  1184.     return((ErrorNumber() == OERROR_NONE) ? OSUCCESS : OFAILURE); 
  1185. }
  1186.  
  1187. oresult ODynaset::SetFieldValue(const char *fieldname, const void __huge *longval, long len)
  1188. {
  1189.     int index = GetFieldIndex(fieldname);
  1190.     if (index < 0)
  1191.         return(OFAILURE);  // return without calling GetFieldValue so errors don't get muddled
  1192.     return(SetFieldValue(index, longval, len));
  1193. }
  1194.  
  1195. //BUG #260868
  1196. oresult ODynaset::AppendFieldChunk(int index, const void *chunkp, unsigned short len)
  1197. {
  1198.     if (! chunkp || len < 1)
  1199.     {
  1200.         SetInternalError (OERROR_BADARG);
  1201.         return(OFAILURE);
  1202.     }
  1203.     if (ActionStart() != OSUCCESS)
  1204.         return(OFAILURE);
  1205.         
  1206.     int fieldtype = GetFieldServerType (index);
  1207. //BUG #260789    
  1208.     if (fieldtype != OTYPE_LONG && fieldtype != OTYPE_LONGRAW)
  1209.     {   // This field is not a long
  1210.         SetInternalError (OERROR_BADTYPE);
  1211.         return(OFAILURE);
  1212.     }
  1213.     
  1214.     // create a tempbuffer with the data in it
  1215.     char *tempb = OObjectAllocStringLen((char *) chunkp, len);
  1216.     if (!tempb)
  1217.     {
  1218.         SetInternalError(OERROR_MEMORY);
  1219.         return(OFAILURE);
  1220.     }
  1221.     
  1222.     HRESULT hc = ((_IOraDynaset *) Internal())->_appendChunk(tempb, index);
  1223.     if (FAILED(hc))
  1224.     { // couldn't get the interface
  1225.         SetInternalError(OERROR_NOINTER);
  1226.     }
  1227.  
  1228.     OObjectFreeString(tempb);
  1229.     
  1230.     return((ErrorNumber() == OERROR_NONE) ? OSUCCESS : OFAILURE);
  1231. }
  1232.  
  1233. //BUG #260868
  1234. oresult ODynaset::AppendFieldChunk(const char *fieldname, const void *chunkp, unsigned short len)
  1235. {
  1236.     if (! fieldname)
  1237.     {
  1238.         SetInternalError (OERROR_BADARG);
  1239.         return(OFAILURE);
  1240.     }
  1241.  
  1242.     int index = GetFieldIndex(fieldname);
  1243.     if (index < 0)
  1244.         return(OFAILURE);  // return without calling GetFieldValue so errors don't get muddled 
  1245.     
  1246.     return(AppendFieldChunk(index, chunkp, len));
  1247. }
  1248.  
  1249. oresult ODynaset::SetFieldValue(int index, const OValue &val)
  1250. {
  1251.     if (ActionStart() != OSUCCESS)
  1252.         return(OFAILURE);
  1253.  
  1254.     VARIANT *vres = ((OOLEvar *) (val.Internal()))->GetVariant();
  1255.     
  1256.     // set field value
  1257.     ((_IOraDynaset *) Internal())->_updateFieldValue(vres, index);
  1258.  
  1259.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  1260. }
  1261.  
  1262. oresult ODynaset::SetFieldValue(const char *fieldname, const OValue &val)
  1263. {
  1264.     int index = GetFieldIndex(fieldname);
  1265.     if (index < 0)
  1266.         return(OFAILURE);  // return without calling SetFieldValue so errors don't get muddled
  1267.     return(SetFieldValue(index, val));
  1268. }
  1269.  
  1270. oresult ODynaset::SetFieldValue(int index, int val)
  1271. {
  1272.     if (ActionStart() != OSUCCESS)
  1273.         return(OFAILURE);
  1274.  
  1275.     // set up VARIANT
  1276.     OOLEvar vres;
  1277.     vres.SetValue(val);
  1278.     
  1279.     // set field value
  1280.     ((_IOraDynaset *) Internal())->_updateFieldValue(vres.GetVariant(), index);
  1281.  
  1282.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  1283. }
  1284.  
  1285. oresult ODynaset::SetFieldValue(const char *fieldname, int val)
  1286. {
  1287.     int index = GetFieldIndex(fieldname);
  1288.     if (index < 0)
  1289.         return(OFAILURE);  // return without calling SetFieldValue so errors don't get muddled
  1290.     return(SetFieldValue(index, val));
  1291. }
  1292.  
  1293. oresult ODynaset::SetFieldValue(int index, long val)
  1294. {
  1295.     if (ActionStart() != OSUCCESS)
  1296.         return(OFAILURE);
  1297.  
  1298.     // set up VARIANT
  1299.     OOLEvar vres;
  1300.     vres.SetValue(val);
  1301.     
  1302.     // set field value
  1303.     ((_IOraDynaset *) Internal())->_updateFieldValue(vres.GetVariant(), index);
  1304.  
  1305.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  1306. }
  1307.  
  1308. oresult ODynaset::SetFieldValue(const char *fieldname, long val)
  1309. {
  1310.     int index = GetFieldIndex(fieldname);
  1311.     if (index < 0)
  1312.         return(OFAILURE);  // return without calling SetFieldValue so errors don't get muddled
  1313.     return(SetFieldValue(index, val));
  1314. }
  1315.  
  1316. oresult ODynaset::SetFieldValue(int index, double val)
  1317. {
  1318.     if (ActionStart() != OSUCCESS)
  1319.         return(OFAILURE);
  1320.  
  1321.     // set up VARIANT
  1322.     OOLEvar vres;
  1323.     vres.SetValue(val);
  1324.     
  1325.     // set field value
  1326.     ((_IOraDynaset *) Internal())->_updateFieldValue(vres.GetVariant(), index);
  1327.  
  1328.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  1329. }
  1330.  
  1331. oresult ODynaset::SetFieldValue(const char *fieldname, double val)
  1332. {
  1333.     int index = GetFieldIndex(fieldname);
  1334.     if (index < 0)
  1335.         return(OFAILURE);  // return without calling SetFieldValue so errors don't get muddled
  1336.     return(SetFieldValue(index, val));
  1337. }
  1338.  
  1339. oresult ODynaset::SetFieldValue(int index, const char *val)
  1340. {
  1341.     if (ActionStart() != OSUCCESS)
  1342.         return(OFAILURE);
  1343.  
  1344.     // set up VARIANT
  1345.     OOLEvar vres;
  1346.     vres.SetValue(val);
  1347.     
  1348.     // set field value
  1349.     ((_IOraDynaset *) Internal())->_updateFieldValue(vres.GetVariant(), index);
  1350.  
  1351.     return((OERROR_NONE == ErrorNumber()) ? OSUCCESS : OFAILURE);    
  1352. }
  1353.  
  1354. oresult ODynaset::SetFieldValue(const char *fieldname, const char *val)
  1355. {
  1356.     int index = GetFieldIndex(fieldname);
  1357.     if (index < 0)
  1358.         return(OFAILURE);  // return without calling SetFieldValue so errors don't get muddled
  1359.     return(SetFieldValue(index, val));
  1360. }
  1361.  
  1362. // ----- ODynasetMark -----------------------------------------------
  1363.  
  1364. ODynasetMark::ODynasetMark(void)
  1365. {
  1366.     m_markdata = 0;  // nothing marked yet
  1367.  
  1368. ODynasetMark::ODynasetMark(const ODynasetMark &other)
  1369. {
  1370.     if (other.m_markdata)
  1371.         m_markdata = OObjectAllocStringLen(other.m_markdata, OObjectStringLen(other.m_markdata));
  1372.     else
  1373.         m_markdata = 0;
  1374. }
  1375.  
  1376. ODynasetMark::~ODynasetMark(void)
  1377. {
  1378.     Cleanup();
  1379. }
  1380.  
  1381. char *ODynasetMark::Internal(void) const
  1382. {
  1383.     return m_markdata;
  1384. }
  1385.  
  1386. oboolean ODynasetMark::IsOpen(void) const
  1387. {
  1388.     return (m_markdata ? TRUE : FALSE);
  1389. }
  1390.  
  1391. ODynasetMark &ODynasetMark::operator=(const ODynasetMark &other)
  1392. {
  1393.     if (&other == this)
  1394.         return(*this);  // self reference
  1395.      
  1396.     Cleanup();  // drop current data
  1397.     
  1398.     if (other.m_markdata)
  1399.         m_markdata = OObjectAllocStringLen(other.m_markdata, OObjectStringLen(other.m_markdata));
  1400.     else
  1401.         m_markdata = 0;
  1402.     
  1403.     return(*this);
  1404. }
  1405.  
  1406. int ODynasetMark::operator==(const ODynasetMark &other) const
  1407. {
  1408.     // closed marks never equal anything
  1409.     if (!m_markdata || ! other.m_markdata)
  1410.         return(0);
  1411.     
  1412.     // just do a bytewise comparison of the mark data
  1413.     // markdata is a BSTR - compare for its full length (even over null bytes)
  1414.     unsigned int marklen = OObjectStringLen(m_markdata);
  1415.     
  1416.     if (0 == memcmp(m_markdata, other.m_markdata, marklen))
  1417.         return(1); // complete match
  1418.     else
  1419.         return(0); // not equal
  1420. }
  1421.  
  1422. int ODynasetMark::operator!=(const ODynasetMark &other) const
  1423. {
  1424.     return(!(this->operator==(other)));
  1425. }
  1426.  
  1427. oresult ODynasetMark::Close(void)
  1428. {
  1429.     return(Cleanup());
  1430. }
  1431.  
  1432. oresult ODynasetMark::Cleanup(void)
  1433. {
  1434.     if (m_markdata)
  1435.         OObjectFreeString(m_markdata);
  1436.     
  1437.     m_markdata = 0;
  1438.     
  1439.     return(OSUCCESS);
  1440. }
  1441.  
  1442. oresult ODynasetMark::OpenHelper(void *obji, void *otheri)
  1443. {
  1444.     Cleanup();
  1445.     if (!obji)
  1446.     {
  1447.         SetOtherError(otheri);
  1448.         return(OFAILURE);
  1449.     }
  1450.     
  1451.     // otherwise everything is fine
  1452.     m_markdata = (char *) obji;
  1453.     ErrorReset();
  1454.     
  1455.     return(OSUCCESS);   
  1456. }
  1457.  
  1458.  
  1459.