Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

793 lines
23 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1994-1997, Microsoft Corporation.
  4. //
  5. // File: rowseek.cxx
  6. //
  7. // Contents: Classes which encapsulate a positioning operation
  8. // for a table.
  9. //
  10. // Classes: CRowSeekDescription
  11. // CRowSeekNext
  12. // CRowSeekAt
  13. // CRowSeekAtRatio
  14. // CRowSeekByBookmark
  15. //
  16. // History: 06 Apr 1995 AlanW Created
  17. //
  18. //--------------------------------------------------------------------------
  19. #include <pch.cxx>
  20. #pragma hdrstop
  21. #include <query.hxx>
  22. #include <sizeser.hxx>
  23. #include "tabledbg.hxx"
  24. #include "rowseek.hxx"
  25. //+---------------------------------------------------------------------------
  26. //
  27. // Member: CRowSeekDescription::MarshalledSize, public
  28. //
  29. // Synopsis: Return Serialized size of a CRowSeekDescription structure
  30. //
  31. // Arguments: - none -
  32. //
  33. // Returns: unsigned - size in bytes of serialized structure.
  34. //
  35. // Notes: The returned size should be the maximum of the serialized
  36. // size on input and output. None of the seek descriptions
  37. // grow on output, so the input size may be larger than the
  38. // output size.
  39. //
  40. // History: 02 May 1995 AlanW Created
  41. //
  42. //----------------------------------------------------------------------------
  43. unsigned
  44. CRowSeekDescription::MarshalledSize(
  45. ) const {
  46. //
  47. // Determine the size of the serialized seek description
  48. //
  49. CSizeSerStream stmSize;
  50. Marshall(stmSize);
  51. return stmSize.Size();
  52. }
  53. //+---------------------------------------------------------------------------
  54. //
  55. // Member: CRowSeekDescription::MarshallBase, public
  56. //
  57. // Synopsis: Serialize the base CRowSeekDescription structure
  58. //
  59. // Arguments: [stm] -- stream structure is serialized into
  60. // [eType] -- type descriminator for derived class
  61. //
  62. // Returns: nothing
  63. //
  64. // History: 29 Jan 1995 AlanW Created
  65. //
  66. //----------------------------------------------------------------------------
  67. void
  68. CRowSeekDescription::MarshallBase(
  69. PSerStream & stm,
  70. DWORD eType
  71. ) const {
  72. stm.PutULong(eType);
  73. stm.PutULong(GetChapter());
  74. }
  75. //+---------------------------------------------------------------------------
  76. //
  77. // Member: CRowSeekNext::Marshall, public
  78. //
  79. // Synopsis: Serialize a CRowSeekNext structure
  80. //
  81. // Arguments: [stm] -- stream structure is serialized into
  82. //
  83. // Returns: nothing
  84. //
  85. // History: 29 Jan 1995 AlanW Created
  86. //
  87. //----------------------------------------------------------------------------
  88. void
  89. CRowSeekNext::Marshall(
  90. PSerStream & stm
  91. ) const {
  92. CRowSeekDescription::MarshallBase( stm, eRowSeekCurrent );
  93. stm.PutULong(GetSkip());
  94. }
  95. //+---------------------------------------------------------------------------
  96. //
  97. // Member: CRowSeekAt::Marshall, public
  98. //
  99. // Synopsis: Serialize a CRowSeekAt structure
  100. //
  101. // Arguments: [stm] -- stream structure is serialized into
  102. //
  103. // Returns: nothing
  104. //
  105. // History: 29 Jan 1995 AlanW Created
  106. //
  107. //----------------------------------------------------------------------------
  108. void
  109. CRowSeekAt::Marshall(
  110. PSerStream & stm
  111. ) const {
  112. CRowSeekDescription::MarshallBase( stm, eRowSeekAt );
  113. stm.PutULong(Bmk());
  114. stm.PutLong(Offset());
  115. stm.PutULong(ULONG(_hRegion));
  116. }
  117. //+---------------------------------------------------------------------------
  118. //
  119. // Member: CRowSeekAtRatio::Marshall, public
  120. //
  121. // Synopsis: Serialize a CRowSeekAtRatio structure
  122. //
  123. // Arguments: [stm] -- stream structure is serialized into
  124. //
  125. // Returns: nothing
  126. //
  127. // History: 29 Jan 1995 AlanW Created
  128. //
  129. //----------------------------------------------------------------------------
  130. void CRowSeekAtRatio::Marshall( PSerStream & stm) const
  131. {
  132. CRowSeekDescription::MarshallBase( stm, eRowSeekAtRatio );
  133. stm.PutULong(RatioNumerator());
  134. stm.PutULong(RatioDenominator());
  135. stm.PutULong(ULONG(_hRegion));
  136. }
  137. //+---------------------------------------------------------------------------
  138. //
  139. // Member: CRowSeekByBookmark::Marshall, public
  140. //
  141. // Synopsis: Serialize a CRowSeekByBookmark structure
  142. //
  143. // Arguments: [stm] -- stream structure is serialized into
  144. //
  145. // Returns: nothing
  146. //
  147. // Notes: When serializing ByBookmarks, we only do bookmarks
  148. // or statuses, not both. Only one must exist in the structure.
  149. //
  150. // History: 29 Jan 1995 AlanW Created
  151. //
  152. //----------------------------------------------------------------------------
  153. void CRowSeekByBookmark::Marshall(PSerStream & stm) const
  154. {
  155. Win4Assert(_cBookmarks == 0 || _cValidRet == 0);
  156. CRowSeekDescription::MarshallBase( stm, eRowSeekByBookmark );
  157. stm.PutULong(_cBookmarks);
  158. for (unsigned i = 0; i < _cBookmarks; i++)
  159. stm.PutULong(_aBookmarks[i]);
  160. stm.PutULong(_cValidRet);
  161. for (i = 0; i < _cValidRet; i++)
  162. stm.PutULong(_ascRet[i]);
  163. }
  164. //+---------------------------------------------------------------------------
  165. //
  166. // Member: CRowSeekNext::CRowSeekNext, public
  167. //
  168. // Synopsis: DeSerialize a CRowSeekNext structure
  169. //
  170. // Arguments: [stm] -- input stream structure is read from
  171. // [iVersion] -- input stream version
  172. //
  173. // Returns: nothing
  174. //
  175. // History: 06 Apr 1995 AlanW Created
  176. //
  177. //----------------------------------------------------------------------------
  178. CRowSeekNext::CRowSeekNext( PDeSerStream & stm, int iVersion ) :
  179. CRowSeekDescription( eRowSeekCurrent, 0 )
  180. {
  181. SetChapter( stm.GetULong() );
  182. SetSkip( stm.GetULong() );
  183. }
  184. //+---------------------------------------------------------------------------
  185. //
  186. // Member: CRowSeekAt::CRowSeekAt, public
  187. //
  188. // Synopsis: DeSerialize a CRowSeekAt structure
  189. //
  190. // Arguments: [stm] -- input stream structure is read from
  191. //
  192. // Returns: nothing
  193. //
  194. // History: 06 Apr 1995 AlanW Created
  195. //
  196. //----------------------------------------------------------------------------
  197. CRowSeekAt::CRowSeekAt( PDeSerStream & stm, int iVersion ) :
  198. CRowSeekDescription( eRowSeekAt, 0 )
  199. {
  200. SetChapter( stm.GetULong() );
  201. _bmkOffset = stm.GetULong();
  202. _cRowsOffset = stm.GetLong();
  203. _hRegion = (HWATCHREGION) stm.GetULong();
  204. }
  205. //+---------------------------------------------------------------------------
  206. //
  207. // Member: CRowSeekAtRatio::CRowSeekAtRatio, public
  208. //
  209. // Synopsis: DeSerialize a CRowSeekAtRatio structure
  210. //
  211. // Arguments: [stm] -- input stream structure is read from
  212. //
  213. // Returns: nothing
  214. //
  215. // History: 06 Apr 1995 AlanW Created
  216. //
  217. //----------------------------------------------------------------------------
  218. CRowSeekAtRatio::CRowSeekAtRatio( PDeSerStream & stm, int iVersion ) :
  219. CRowSeekDescription( eRowSeekAtRatio, 0 )
  220. {
  221. SetChapter( stm.GetULong() );
  222. _ulNumerator = stm.GetULong();
  223. _ulDenominator = stm.GetULong();
  224. _hRegion = (HWATCHREGION) stm.GetULong();
  225. }
  226. //+---------------------------------------------------------------------------
  227. //
  228. // Member: CRowSeekByBookmark::CRowSeekByBookmark, public
  229. //
  230. // Synopsis: DeSerialize a CRowSeekByBookmark structure
  231. //
  232. // Arguments: [stm] -- input stream structure is read from
  233. //
  234. // Returns: nothing
  235. //
  236. // History: 06 Apr 1995 AlanW Created
  237. //
  238. //----------------------------------------------------------------------------
  239. CRowSeekByBookmark::CRowSeekByBookmark( PDeSerStream & stm, int iVersion ) :
  240. CRowSeekDescription( eRowSeekByBookmark, 0 ),
  241. _aBookmarks( 0 ),
  242. _ascRet( 0 )
  243. {
  244. SetChapter( stm.GetULong() );
  245. _cBookmarks = stm.GetULong();
  246. if (_cBookmarks)
  247. {
  248. // Protect agains unreasonable requests, which probably are attacks
  249. if ( _cBookmarks >= 65536 )
  250. THROW( CException( E_INVALIDARG ) );
  251. _aBookmarks = new CI_TBL_BMK [ _cBookmarks ];
  252. for (unsigned i = 0; i < _cBookmarks; i++)
  253. _aBookmarks[i] = stm.GetULong();
  254. }
  255. _maxRet = _cValidRet = stm.GetULong();
  256. if (_cValidRet)
  257. {
  258. // Protect against unreasonable requests, which probably are attacks
  259. if ( _cValidRet >= 65536 )
  260. THROW( CException( E_INVALIDARG ) );
  261. _ascRet = new SCODE [ _cValidRet ];
  262. for (unsigned i = 0; i < _cValidRet; i++)
  263. _ascRet[i] = stm.GetULong();
  264. }
  265. //
  266. // We don't expect both bookmarks and statuses.
  267. //
  268. Win4Assert(_cBookmarks == 0 || _cValidRet == 0);
  269. }
  270. //+---------------------------------------------------------------------------
  271. //
  272. // Member: CRowSeekByBookmark::~CRowSeekByBookmark, public
  273. //
  274. // Synopsis: Destroy a CRowSeekByBookmark structure
  275. //
  276. // Returns: nothing
  277. //
  278. // History: 29 Jan 1995 AlanW Created
  279. //
  280. //----------------------------------------------------------------------------
  281. CRowSeekByBookmark::~CRowSeekByBookmark( )
  282. {
  283. delete _aBookmarks;
  284. delete _ascRet;
  285. }
  286. //+-------------------------------------------------------------------------
  287. //
  288. // Member: CRowSeekNext::GetRows, public
  289. //
  290. // Synopsis: Retrieve row data for a table cursor
  291. //
  292. // Arguments: [rCursor] - the cursor to fetch data for
  293. // [rTable] - the table from which data is fetched
  294. // [rFetchParams] - row fetch parameters and buffer pointers
  295. // [pSeekDescOut] - pointer to seek description for restart
  296. //
  297. // Returns: SCODE - the status of the operation.
  298. //
  299. // Notes:
  300. //
  301. // History: 07 Apr 1995 Alanw Created
  302. //
  303. //--------------------------------------------------------------------------
  304. SCODE
  305. CRowSeekNext::GetRows(
  306. CTableCursor& rCursor,
  307. CTableSource& rTable,
  308. CGetRowsParams& rFetchParams,
  309. XPtr<CRowSeekDescription>& pSeekDescOut) const
  310. {
  311. LONG cRowsToSkip = GetSkip();
  312. if (cRowsToSkip)
  313. {
  314. tbDebugOut(( DEB_IWARN, "CRowSeekNext::GetRows - non-zero skip count %d\n",
  315. cRowsToSkip ));
  316. }
  317. WORKID widStart;
  318. if ( rTable.IsFirstGetNextRows() )
  319. {
  320. //
  321. // For the first GetNextRows call, the start position is
  322. // beginning of table if cRowsToSkip is positive, and end
  323. // of table if its negative. For subsequent calls, the
  324. // current position is the start position.
  325. //
  326. if ( cRowsToSkip >= 0 )
  327. widStart = WORKID_TBLBEFOREFIRST;
  328. else
  329. widStart = WORKID_TBLAFTERLAST;
  330. }
  331. else
  332. widStart = rTable.GetCurrentPosition( GetChapter() );
  333. WORKID widEnd = widStart;
  334. //
  335. // OffsetSameDirFetch implements the skip of one row that
  336. // Oledb::GetNextRows requires on the first fetch
  337. // when scrolling and fetching are in the same direction,
  338. // and for subsequent fetches when the fetch is in the
  339. // same direction as previous fetch. When the direction is
  340. // reversed the first wid fetched is same as the last wid
  341. // returned from the previous call, and offsetSameDirFetch
  342. // is 0 in this case.
  343. //
  344. LONG offsetSameDirFetch = 0;
  345. if ( rTable.IsFirstGetNextRows() )
  346. {
  347. if ( cRowsToSkip >= 0 && rFetchParams.GetFwdFetch() )
  348. offsetSameDirFetch = 1;
  349. else if ( cRowsToSkip < 0 && !rFetchParams.GetFwdFetch() )
  350. offsetSameDirFetch = -1;
  351. }
  352. else
  353. {
  354. if ( rFetchParams.GetFwdFetch() == rTable.GetFwdFetchPrev() )
  355. {
  356. if ( rFetchParams.GetFwdFetch() )
  357. offsetSameDirFetch = 1;
  358. else
  359. offsetSameDirFetch = -1;
  360. }
  361. }
  362. SCODE scRet = rTable.GetRowsAt( 0, // no watch region
  363. widStart,
  364. GetChapter(),
  365. cRowsToSkip + offsetSameDirFetch,
  366. rCursor.GetBindings(),
  367. rFetchParams,
  368. widEnd );
  369. //
  370. // Don't attempt to save the widEnd if the positioning
  371. // operation got us past the end of the table. Storing
  372. // widEnd in rCursor will cause us to be stuck at the
  373. // end, with no way to get any more rows. In this situation,
  374. // we don't expect to have successfully transferred any rows.
  375. //
  376. // NOTE: don't throw, the error may need to be seen by caller
  377. // in CRowset::_FetchRows
  378. //
  379. if ( WORKID_TBLAFTERLAST == widEnd ||
  380. WORKID_TBLBEFOREFIRST == widEnd ||
  381. ( scRet == DB_E_BADSTARTPOSITION && cRowsToSkip == 0 ) )
  382. {
  383. Win4Assert(rFetchParams.RowsTransferred() == 0);
  384. return DB_S_ENDOFROWSET;
  385. }
  386. if (SUCCEEDED(scRet))
  387. {
  388. rTable.SetCurrentPosition( GetChapter(), widEnd );
  389. rTable.SetFwdFetchPrev( rFetchParams.GetFwdFetch() );
  390. rTable.ResetFirstGetNextRows();
  391. }
  392. else
  393. {
  394. tbDebugOut(( DEB_WARN, "CRowSeekNext::GetRows failed, sc=%x\n",
  395. scRet ));
  396. }
  397. if (DB_S_BLOCKLIMITEDROWS == scRet)
  398. {
  399. Win4Assert(rFetchParams.RowsTransferred() > 0);
  400. pSeekDescOut.Set(new CRowSeekNext(GetChapter(), 0) );
  401. }
  402. return scRet;
  403. }
  404. //+-------------------------------------------------------------------------
  405. //
  406. // Member: CRowSeekAt::GetRows, public
  407. //
  408. // Synopsis: Retrieve row data for a table cursor
  409. //
  410. // Arguments: [rCursor] - the cursor to fetch data for
  411. // [rTable] - the table from which data is fetched
  412. // [rFetchParams] - row fetch parameters and buffer pointers
  413. // [pSeekDescOut] - pointer to seek description for restart
  414. //
  415. // Returns: SCODE - the status of the operation.
  416. //
  417. // Notes:
  418. //
  419. // History: 07 Apr 1995 Alanw Created
  420. //
  421. //--------------------------------------------------------------------------
  422. SCODE
  423. CRowSeekAt::GetRows(
  424. CTableCursor& rCursor,
  425. CTableSource& rTable,
  426. CGetRowsParams& rFetchParams,
  427. XPtr<CRowSeekDescription>& pSeekDescOut) const
  428. {
  429. WORKID widStart = Bmk();
  430. LONG iRowOffset = Offset();
  431. SCODE scRet = rTable.GetRowsAt( _hRegion,
  432. widStart,
  433. GetChapter(),
  434. iRowOffset,
  435. rCursor.GetBindings(),
  436. rFetchParams,
  437. widStart );
  438. // The first fetch took care of the hRegion manipulation
  439. // set the new seek descriptor's hRegion to 0
  440. if (DB_S_BLOCKLIMITEDROWS == scRet)
  441. {
  442. Win4Assert(rFetchParams.RowsTransferred() > 0);
  443. pSeekDescOut.Set(new CRowSeekAt(0,
  444. GetChapter(),
  445. rFetchParams.GetFwdFetch() ? 1 : -1,
  446. widStart) );
  447. }
  448. return scRet;
  449. }
  450. //+-------------------------------------------------------------------------
  451. //
  452. // Member: CRowSeekAtRatio::GetRows, public
  453. //
  454. // Synopsis: Retrieve row data for a table cursor
  455. //
  456. // Arguments: [rCursor] - the cursor to fetch data for
  457. // [rTable] - the table from which data is fetched
  458. // [rFetchParams] - row fetch parameters and buffer pointers
  459. // [pSeekDescOut] - pointer to seek description for restart
  460. //
  461. // Returns: SCODE - the status of the operation.
  462. //
  463. // Notes:
  464. //
  465. // History: 07 Apr 1995 Alanw Created
  466. //
  467. //--------------------------------------------------------------------------
  468. SCODE
  469. CRowSeekAtRatio::GetRows(
  470. CTableCursor& rCursor,
  471. CTableSource& rTable,
  472. CGetRowsParams& rFetchParams,
  473. XPtr<CRowSeekDescription>& pSeekDescOut) const
  474. {
  475. WORKID widRestart = widInvalid;
  476. SCODE scRet = rTable.GetRowsAtRatio( _hRegion,
  477. RatioNumerator(),
  478. RatioDenominator(),
  479. GetChapter(),
  480. rCursor.GetBindings(),
  481. rFetchParams,
  482. widRestart );
  483. // The first fetch took care of the hRegion manipulation
  484. // set the new seek descriptor's hRegion to 0
  485. if (DB_S_BLOCKLIMITEDROWS == scRet)
  486. {
  487. Win4Assert(rFetchParams.RowsTransferred() > 0);
  488. pSeekDescOut.Set(new CRowSeekAt(0, GetChapter(), 1, widRestart) );
  489. }
  490. return scRet;
  491. }
  492. //+-------------------------------------------------------------------------
  493. //
  494. // Member: CRowSeekByBookmark::GetRows, public
  495. //
  496. // Synopsis: Retrieve row data for a table cursor
  497. //
  498. // Arguments: [rCursor] - the cursor to fetch data for
  499. // [rTable] - the table from which data is fetched
  500. // [rFetchParams] - row fetch parameters and buffer pointers
  501. // [pSeekDescOut] - pointer to seek description for restart
  502. //
  503. // Returns: SCODE - the status of the operation.
  504. //
  505. //
  506. // History: 07 Apr 1995 Alanw Created
  507. //
  508. //--------------------------------------------------------------------------
  509. SCODE
  510. CRowSeekByBookmark::GetRows(
  511. CTableCursor& rCursor,
  512. CTableSource& rTable,
  513. CGetRowsParams& rFetchParams,
  514. XPtr<CRowSeekDescription>& pSeekDescOut) const
  515. {
  516. unsigned cFailed = 0;
  517. ULONG cSavedRowsReq = rFetchParams.RowsToTransfer();
  518. Win4Assert(_cBookmarks > 0);
  519. Win4Assert(cSavedRowsReq <= _cBookmarks);
  520. Win4Assert(0 == rFetchParams.RowsTransferred() && cSavedRowsReq > 0);
  521. rFetchParams.SetRowsRequested(0);
  522. SCODE scRet = S_OK;
  523. TRY
  524. {
  525. XPtr<CRowSeekByBookmark> pSeekOut(
  526. new CRowSeekByBookmark(GetChapter(), _cBookmarks) );
  527. BOOL fFailed = FALSE;
  528. // Iterate over bookmarks, calling rTable.GetRowsAt for each
  529. for (unsigned i = 0; i < cSavedRowsReq; i++)
  530. {
  531. if (! fFailed)
  532. rFetchParams.IncrementRowsRequested( );
  533. WORKID widNext = _aBookmarks[i];
  534. if (widNext == widInvalid)
  535. {
  536. scRet = DB_E_BADBOOKMARK;
  537. }
  538. else
  539. {
  540. TRY
  541. {
  542. scRet = rTable.GetRowsAt( 0, // no watch region
  543. widNext,
  544. GetChapter(),
  545. 0,
  546. rCursor.GetBindings(),
  547. rFetchParams,
  548. widNext );
  549. }
  550. CATCH( CException, e )
  551. {
  552. scRet = e.GetErrorCode();
  553. Win4Assert( scRet != STATUS_ACCESS_VIOLATION &&
  554. scRet != STATUS_NO_MEMORY );
  555. }
  556. END_CATCH;
  557. if (! SUCCEEDED(scRet) && scRet != STATUS_BUFFER_TOO_SMALL )
  558. scRet = DB_E_BOOKMARKSKIPPED;
  559. }
  560. if (scRet == DB_S_ENDOFROWSET)
  561. scRet = S_OK;
  562. if ( STATUS_BUFFER_TOO_SMALL == scRet ||
  563. DB_S_BLOCKLIMITEDROWS == scRet )
  564. {
  565. scRet = DB_S_BLOCKLIMITEDROWS;
  566. break;
  567. }
  568. //
  569. // set per-row error status
  570. //
  571. pSeekOut->_SetStatus(i, scRet);
  572. if (FAILED(scRet))
  573. {
  574. cFailed++;
  575. fFailed = TRUE;
  576. }
  577. else
  578. fFailed = FALSE;
  579. }
  580. pSeekDescOut.Set( pSeekOut.Acquire() );
  581. }
  582. CATCH( CException, e )
  583. {
  584. scRet = e.GetErrorCode();
  585. }
  586. END_CATCH;
  587. if (cFailed)
  588. return DB_S_ERRORSOCCURRED;
  589. else if (0 == rFetchParams.RowsTransferred())
  590. return STATUS_BUFFER_TOO_SMALL;
  591. else
  592. return S_OK;
  593. }
  594. //+-------------------------------------------------------------------------
  595. //
  596. // Member: CRowSeekByBookmark::_SetStatus, private
  597. //
  598. // Synopsis: Set row status for a bookmark lookup
  599. //
  600. // Arguments: [iBmk] - index of bookmark to set status for
  601. // [scRet] - the status to be saved
  602. //
  603. // Returns: Nothing
  604. //
  605. // History: 12 Apr 1995 Alanw Created
  606. //
  607. //--------------------------------------------------------------------------
  608. void
  609. CRowSeekByBookmark::_SetStatus(
  610. unsigned iBmk,
  611. SCODE scRet
  612. ) {
  613. Win4Assert( iBmk < _maxRet );
  614. if (_ascRet == 0)
  615. _ascRet = new SCODE[_maxRet];
  616. _ascRet[iBmk] = scRet;
  617. if (iBmk >= _cValidRet)
  618. {
  619. Win4Assert( iBmk == _cValidRet );
  620. _cValidRet = iBmk + 1;
  621. }
  622. }
  623. //+-------------------------------------------------------------------------
  624. //
  625. // Member: CRowSeekDescription::MergeResults, public
  626. //
  627. // Synopsis: Update seek description state after a transfer
  628. //
  629. // Arguments: [pRowSeek] - row seek description after transfer
  630. //
  631. // Returns: Nothing
  632. //
  633. // Notes: Used only in user mode. Does nothing for CRowSeekNext,
  634. // CRowSeekAt and CRowSeekAtRatio.
  635. //
  636. // History: 02 May 1995 Alanw Created
  637. //
  638. //--------------------------------------------------------------------------
  639. void
  640. CRowSeekDescription::MergeResults(
  641. CRowSeekDescription * pRowSeek )
  642. {
  643. return;
  644. }
  645. //+-------------------------------------------------------------------------
  646. //
  647. // Member: CRowSeekByBookmark::MergeResults, public
  648. //
  649. // Synopsis: Update seek description state after a transfer
  650. //
  651. // Arguments: [pRowSeek] - row seek description after transfer
  652. //
  653. // Returns: Nothing
  654. //
  655. // Notes: Used only in user mode. Transfers statuses into
  656. // original rowseek and bookmarks from original to
  657. // result rowseek.
  658. //
  659. // History: 02 May 1995 Alanw Created
  660. //
  661. //--------------------------------------------------------------------------
  662. void
  663. CRowSeekByBookmark::MergeResults(
  664. CRowSeekDescription * pRowSeekDesc)
  665. {
  666. Win4Assert(pRowSeekDesc->IsByBmkRowSeek());
  667. CRowSeekByBookmark* pRowSeek = (CRowSeekByBookmark*) pRowSeekDesc;
  668. Win4Assert(_cBookmarks > 0 &&
  669. pRowSeek->_cValidRet > 0 && pRowSeek->_cBookmarks == 0);
  670. //
  671. // Transfer return statuses to this object from the other
  672. //
  673. unsigned iBaseRet = _cValidRet;
  674. for (unsigned i=0; i < pRowSeek->_cValidRet; i++)
  675. {
  676. _SetStatus( i+iBaseRet, pRowSeek->_ascRet[i] );
  677. }
  678. delete [] pRowSeek->_ascRet;
  679. pRowSeek->_ascRet = 0;
  680. pRowSeek->_cValidRet = pRowSeek->_maxRet = 0;
  681. //
  682. // Transfer bookmarks from this object to the other.
  683. //
  684. if (_cBookmarks - _cValidRet > 0)
  685. {
  686. pRowSeek->_cBookmarks = _cBookmarks - _cValidRet;
  687. pRowSeek->_aBookmarks = new CI_TBL_BMK[ pRowSeek->_cBookmarks ];
  688. for (unsigned i=0; i<pRowSeek->_cBookmarks; i++)
  689. {
  690. pRowSeek->_aBookmarks[i] = _aBookmarks[ i+_cValidRet ];
  691. }
  692. }
  693. }