Page 1 of 1

behavior of dc_dbseek using softseek with dc_setscopearray

Posted: Wed Oct 12, 2016 1:24 pm
by gnewcomb
What is the expected behavior of dc_dbseek( cKey, .T. ) when a dc_setscopearray has been set and cKey is not found? It seems to always position to EOF instead of the record greater than cKey.

Re: behavior of dc_dbseek using softseek with dc_setscopearr

Posted: Wed Oct 12, 2016 1:36 pm
by rdonnay
It's not really possible to do a soft-seek when using DC_SetScopeArray().

What record would it seek to?

Re: behavior of dc_dbseek using softseek with dc_setscopearr

Posted: Wed Oct 12, 2016 2:09 pm
by gnewcomb
Shouldn't it move to the next record in the scope array past the cKey value? If you added the 3 lines below to DC_DbSeek would that work?

Code: Select all

FUNCTION DC_DbSeek(cKey, lSoftseek, cIndexTag, lSeekLast, xDataSource )

LOCAL lFound := .f.
LOCAL xScopeTop, xScopeBot
LOCAL lExact, xValue, i, xCargo
LOCAL aScopeArray := DC_SetScopeArray()
LOCAL cDataType := Valtype(xDataSource)

IF cDataType == 'O' // It's an SQLexpress cursor

  lFound := xDataSource:seek( cKey, lSoftSeek )
  IF DC_IsSQLCargo( xDataSource, @xCargo )
    xCargo[DCSQL_CARGO_FOUND] := lFound
  ENDIF
  RETURN lFound

ELSEIF cDataType == 'N' // It's an ADS SQL cursor
  // AdsSeek( nIndex, @cKey, cLength, nDataType, nSeekType, @lFound )
  RETURN .F.

ELSEIF DC_ScopeAds() .AND. _SetRdd()='ADSDBE'
//roger
  RETURN dbSeek( cKey, lSoftSeek, cIndexTag, lSeekLast )

ENDIF

IF !Empty(aScopeArray)
  FOR i := 1 TO Len(aScopeArray)
    IF Valtype(aScopeArray[i]) = 'A'
      GOTO aScopeArray[i,1]
    ELSE
      GOTO aScopeArray[i]
    ENDIF
    IF &(IndexKey(0)) = cKey
      DC_SetScopeArrayPointer(i)
      RETURN .T.
    ELSEIF lSoftSeek .AND. &(IndexKey(0)) > cKey                 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      DC_SetScopeArrayPointer(i)                                 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      RETURN .F.                                                 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
    ENDIF
  NEXT
  GO BOTTOM
  SKIP
  RETURN .F.
ELSEIF !DC_ScopeExpress()
  lExact := Set(_SET_EXACT,.f.)
  xValue := _DbSeek( cKey, lSoftSeek, cIndexTag, lSeekLast )
  Set(_SET_EXACT,lExact)
  RETURN xValue
ENDIF

lExact := Set(_SET_EXACT,.f.)
DEFAULT lSoftseek := Set(_SET_SOFTSEEK)

* perform the Xbase seek first
  lFound := _DbSeek(cKey, lSoftseek, cIndexTag, lSeekLast )

* set DC_Bof, DC_Eof
  DC_Eof(eof())
  DC_Bof(bof())

* Roger: return only after setting DC_Eof(), DC_Bof()
* IF !lFound   // Roger: Xbase is changed, can no longer trust this flag.
  IF eof()
    Set(_SET_EXACT,lExact)
    RETURN .f. // lFound : Note: I think that suits most cases.
  ENDIF

  xScopeTop := DC_SetScope( 0 )
  xScopeBot := DC_SetScope( 1 )

  IF Valtype(xScopeTop)#'U' .AND. _ScopeKey( xScopeTop ) < xScopeTop
    * IF Set(_SET_SOFTSEEK)  //  possible bug??
    IF Set(_SET_SOFTSEEK) .OR. lSoftSeek
      DC_DbGoTop()
    ELSE
      _dbGoBottom()
      _dbSkip()
      DC_Eof(.t.)       // Roger: should set this ??
    ENDIF
  ELSEIF Valtype(xScopeBot)#'U' .AND. _ScopeKey( xScopeBot ) > xScopeBot
    _dbGoBottom()
    _dbSkip()
    DC_Eof(.t.)         // Roger: should set this ??
  ENDIF

  lFound := ! DC_Eof()

Set(_SET_EXACT,lExact)

RETURN lFound

Re: behavior of dc_dbseek using softseek with dc_setscopearr

Posted: Wed Oct 12, 2016 4:31 pm
by rdonnay
This sounds complicated.
I have to think about this.

If you have modified the code to work the way you want, then maybe you should just copy it to My_dbSeek().

Re: behavior of dc_dbseek using softseek with dc_setscopearr

Posted: Wed Oct 12, 2016 8:01 pm
by gnewcomb
I was just wondering if I was using DC_SetScopeArray() as it was intended. I am creating a subset of "filtered" records using a controlling index and would still like to be able to search on the controlling index. My next question was going to be why does DC_DbSeek() not seek using aScopeArray when the table is an ADSDBE table. It just returns the Alaska dbSeek(). A custom My_dbSeek() sounds like the way I need to go.