xbrowse / ADS failure

xbrowse / ADS failure

Postby TimStone » Sat Oct 24, 2015 11:07 pm

In another thread, we identified there is still a continuing problem with xBrowse and ADS.

When we open a browse and the dbf does not have an index opened, when going towards the end of the file, the pointer has an error. We have shown this consistently and it has also been previously reported by at least one other person. If an index is open, the error does not occur.

The previous threads on this topic were specific and the error was noted, but no fix has yet taken place.

The specific build uses FWH 15.09 xBrowse, Harbour, MSVC 2013, and ADS Server mode.

Can we please go back and get this resolved correctly ? Thank you. Although the temporary work around is to set the index before browsing the file, often we want to go to the last records added and natural order ( no index ) is the fastest way.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: xbrowse / ADS failure

Postby Giovany Vecchi » Tue Oct 27, 2015 4:46 pm

All these navigation problems xbrowse already decided to put runs on TADs class, The Linear Sr could study and add in xBrowse class.

In xbrowse.prg method SetRdd() change:
Code: Select all  Expand view

   If ( "ADS"$( ::cAlias )->( RddName() ) .or. 'ADT' $ ( ::cAlias )->( RddName() ) ) //.and. ;
      //( ::cAlias )->( LastRec() ) > 200

      // Modified in FWH 9.06
      // AdsGetRelKeyPos() returns approximate position as % and when multipilied by 100 and rounded off
      // returns incorrect values occassionally on smaller  tables. OrdKeyNo() mapped to AdsKeyNo() gives reliable
      // result in such cases. For large tables OrdKeyNo() is unacceptably slow. Limit of 200 is chosen because
      // 0.5% is 1/200.

      cAdsKeyNo    := "{| n, Self | iif( n == nil, " +;
                         "nCalcRelPos( " + cAlias + "->( ADSGetRelKeyPos() ) * Self:nLen, Self ), "+;
                         cAlias + "->( ADSSetRelKeyPos( n / Self:nLen ) ) ) }"

      cAdsKeyCount := "{|| " + cAlias + "->( ADSKeyCount(,,1) )}"

      DEFAULT ::bKeyNo    := &cAdsKeyNo ,;
              ::bKeyCount := &cAdsKeyCount

 


Function nCalcRalPos()
Code: Select all  Expand view

FUNCTION nCalcRelPos(f_nVal,f_oXBrw)
  Local nLenRegs := f_oXBrw:nLen, nRowPos := f_oXBrw:nRowSel
  Local nRetorno := 0
 
  nRetorno := Round(f_nVal,3)
 
  If nRetorno == 0
    nRetorno := 1
  EndIf

  If nRetorno < nRowPos
    nRetorno := nRowPos
  EndIf  

  nRetorno := Int(nRetorno)

RETURN nRetorno
 


When I use the TADS class I use the tCtrlxBrw class ()
here is the class, most only works with TADS ().

Class tCtrlxbrw:
Code: Select all  Expand view

#Include "Fivewin.ch"
#Include "xBrowse.ch"

#Define df_BaseMySql    1

Class tCtrlxBrw

  Data oXBrwCtrl, oDbDs_DataBaseAds
  Data bStrData
  Data oGetDsFilter, nTpCampoFilter, cCampoFilter, lLastRecZero
  Data bChangeBrw
 
  Method New(f_oXBrowse,f_oDbDs_DataBaseAds) Constructor
  Method End()

  Method SetTAds()
 
  Method tCtrlxBrw_Skip(f_nKip)
 
  Method tCtrlxBrw_Seek(f_oBjCol,f_uVar)
  Method tCtrlxBrw_EditFilterRdd()
  Method tCtrlxBrw_EditFilterSql()
  Method tCtrlxBrw_EditChange()
  Method tCtrlxBrw_EditClearChar(f_cTxt, f_nTipo)


Endclass
//-----------------------------------------------------------------------------
Method New(f_oXBrowse,f_oDbDs_DataBaseAds,f_aGetFilter) Class tCtrlxBrw
  Local oSelf

  // f_aGetFilter[1] > oBjeto Get
  // f_aGetFilter[2] > Tipo Filtro 1=SetAof contains / 2=Sql select Contains
  // f_aGetFilter[3] > Nome do campo a pesquisar
   
  ///Override Method Skip In Class Txbrowse With oSelf:tCtrlxBrw_Skip

  ::lLastRecZero := .F.

  ::oDbDs_DataBaseAds     := f_oDbDs_DataBaseAds
  ::oXBrwCtrl             := f_oXBrowse
 
  ::oXBrwCtrl:cAlias      := ::oDbDs_DataBaseAds:cAlias
 
  If !Hb_IsNil(f_aGetFilter)

    ::oGetDsFilter    := f_aGetFilter[1]
    ::nTpCampoFilter  := f_aGetFilter[2]
    ::cCampoFilter    := f_aGetFilter[3]
   
    If f_aGetFilter[2] == 2 // Sql Contains
      ::oGetDsFilter:bChange := {||::tCtrlxBrw_EditFilterSql()}
   
    ElseIf f_aGetFilter[2] == 1 // Rdd set aof

      ::oGetDsFilter:bChange := {||::tCtrlxBrw_EditFilterRdd()}
     
    EndIf

    ::bChangeBrw := ::oXBrwCtrl:bChange
    ::oXBrwCtrl:bChange    := {||::tCtrlxBrw_EditChange()}
    ::oXBrwCtrl:bGotFocus  := {||::tCtrlxBrw_EditChange()}
   
  EndIf  

  ::oXBrwCtrl:bClrSel := {|| { CLR_BLACK, CLR_HGRAY} } // Giovany
  ::SetTAds()
  ::oDbDs_DataBaseAds:Refresh()

Return Self
//-----------------------------------------------------------------------------
Method End() Class tCtrlxBrw

Self := Nil

Return Nil
//-----------------------------------------------------------------------------
Method SetTAds() Class tCtrlxBrw
  Local nTpGetRelPos := 1, cTmpQry := "", nTmp := 0

  ::oDbDs_DataBaseAds:lBufferOnSkip := .T.
 
  If ::oDbDs_DataBaseAds:nOpenType == 3 // Open via Dataset
    cTmpQry := Upper(::oDbDs_DataBaseAds:cQrySql)
    If At("{STATIC}",cTmpQry) == 0
      nTpGetRelPos := 2
    Else
      nTpGetRelPos := 1
    EndIf
  Else
    nTpGetRelPos := 1
  EndIf

  If nTpGetRelPos == 2 // Open via Sql Dataset cursor vivo

    ::oXBrwCtrl:bKeyNo    := {| n, _Self | If( n == nil, ;
                                   nCalcRelPos((::oDbDs_DataBaseAds:GetRelKeyPos() * _Self:nLen) /10,::oXBrwCtrl) , ;
                                   ::oDbDs_DataBaseAds:SetRelKeyPos( Round(n / _Self:nLen,3) ) ) }

  Else // Viao Rdd ou Static Cursor

    ::oXBrwCtrl:bKeyNo    := {| n, _Self | If( n == nil, ;
                                 nCalcRelPos((::oDbDs_DataBaseAds:GetRelKeyPos() * _Self:nLen),::oXBrwCtrl ) , ;
                                 ::oDbDs_DataBaseAds:SetRelKeyPos( Round(n / _Self:nLen,3) ) ) }

  EndIf

  ::oXBrwCtrl:bBookMark := {| n | iif( n == nil,;
                               ::oDbDs_DataBaseAds:Recno() , ;
                               ::oDbDs_DataBaseAds:GoTo( n ) ) }

  ::oXBrwCtrl:bKeyCount := {|| ::oDbDs_DataBaseAds:KeyCount(1)  }
 
  ::oXBrwCtrl:bBof      := { ||  ::oDbDs_DataBaseAds:Bof() }
  ::oXBrwCtrl:bEof      := { ||  ::oDbDs_DataBaseAds:Eof() }
  ::oXBrwCtrl:bSkip     := { |n| Iif( n == Nil, n := 1, ), ::tCtrlxBrw_Skip( n )}
  ::oXBrwCtrl:bGoTop    := { ||  ::oDbDs_DataBaseAds:GoTop() }
  ::oXBrwCtrl:bGoBottom := { ||  ::oDbDs_DataBaseAds:GoBottom() }

  ::oDbDs_DataBaseAds:OnSkip()

Return Nil
//-----------------------------------------------------------------------------
Method tCtrlxBrw_Skip(f_nSkip) Class tCtrlxBrw
  Local nSkipper := 0
 
  Default f_nSkip := 1

  nSkipper := (::oDbDs_DataBaseAds:cAlias)->(DbSkipper(f_nSkip))

  ::oDbDs_DataBaseAds:OnSkip()
 
Return nSkipper  
//-----------------------------------------------------------------------------
Method tCtrlxBrw_Seek(f_oBjCol,f_uVar,f_lTpSeek) Class tCtrlxBrw
LOCAL nRecMarca := ::oDbDs_DataBaseAds:Recno(), cTpData := ""

  cTpData := VALTYPE(f_uVar)
 
  IF cTpData == "N"
     f_lTpSeek := .F.
  ELSEIF cTpData == "D"
     f_lTpSeek := .F.
  ELSEIF cTpData == "C"
     f_lTpSeek := .T.
  ENDIF
 
  //If ::oDbDs_DataBaseAds:nOpenType == 1
    f_oBjCol:SetOrder()
    ::oDbDs_DataBaseAds:Seek(f_uVar,f_oBjCol:cSortOrder,f_lTpSeek)
  //EndIf
 
  IF ::oDbDs_DataBaseAds:EOF()
 
     ::oDbDs_DataBaseAds:GoTo(nRecMarca)
     
     MSGSTOP("A ocorrencia solicitada não foi encontrada.",;
             "Procedimento abortado...")
 
  ENDIF
  ::oXBrwCtrl:Refresh(.T.)
 
  IF ::oXBrwCtrl:bChange != nil
     EVAL(::oXBrwCtrl:bChange)
  ENDIF

RETURN NIL
//-----------------------------------------------------------------------------
Method tCtrlxBrw_EditFilterRdd() Class tCtrlxBrw
  Local cTxtDigitacao := "", cAof := ""

  //::oGetDsFilter:Save()
  cTxtDigitacao := Alltrim(::tCtrlxBrw_EditClearChar(::oGetDsFilter:cText))

  If Len(cTxtDigitacao) < 5
    cTxtDigitacao := ""
  Else
    ::lLastRecZero := .F.
  EndIf
 
  If ::lLastRecZero
    Return Nil
  EndIf
  ///? cTxtDigitacao

  cAof := "CONTAINS("+::cCampoFilter+","+cTxtDigitacao+")"

    ::oGetDsFilter:oWnd:cTitle := cAof
    ::oGetDsFilter:oWnd:Refresh()
    ///msginfo(cAof)
   
    ::oDbDs_DataBaseAds:Filter(cAof)
    ::oDbDs_DataBaseAds:GoTop()
  ::oXBrwCtrl:Refresh(.T.)

  If Len(cTxtDigitacao) < 5
    ::lLastRecZero := .T.
  EndIf

Return Nil
//-----------------------------------------------------------------------------
Method tCtrlxBrw_EditFilterSql() Class tCtrlxBrw
  Local cTxtDigitacao := ""

  //::oGetDsFilter:Save()
  cTxtDigitacao := Alltrim(::tCtrlxBrw_EditClearChar(::oGetDsFilter:cText))

  If Len(cTxtDigitacao) < 5
    cTxtDigitacao := ""
  Else
    ::lLastRecZero := .F.
  EndIf
 
  If ::lLastRecZero
    Return Nil
  EndIf
  ///? cTxtDigitacao

  ::oDbDs_DataBaseAds:aVarsSql := {{"_TxtDigitacao_",cTxtDigitacao},;
                                   {"_Campo_",::cCampoFilter}}
 
  ::oDbDs_DataBaseAds:DsExecute()
  ::oXBrwCtrl:Refresh(.T.)

  If Len(cTxtDigitacao) < 5
    ::lLastRecZero := .T.
  EndIf

Return Nil
//-----------------------------------------------------------------------------
Method tCtrlxBrw_EditChange() Class tCtrlxBrw

  If ::oDbDs_DataBaseAds:LastRec() == 0
    Return Nil
  EndIf
 
  ::oGetDsFilter:VarPut(::oDbDs_DataBaseAds:VarGet(::cCampoFilter))
  ::oGetDsFilter:Refresh()
 
  If !Hb_IsNil(::bChangeBrw)
    Eval(::bChangeBrw)
  EndIf
 
Return Nil

//-----------------------------------------------------------------------------
Method tCtrlxBrw_EditClearChar(f_cTxt) Class tCtrlxBrw
  Local cRetTxt := f_cTxt
  Local iFor := 0, cAnd := ""
  Local aCharDeletes := { chr(34),"-",".","+","=","&","'","´"}
  Local aPalavras := {}
 
  cRetTxt := _CHAR_CLEAN(cRetTxt,{ " AND ",;
                                      " NEAR ",;
                                      " ANY "})

  For iFor := 1 To Len(aCharDeletes)
    cRetTxt := StrTran(cRetTxt,aCharDeletes[iFor]," ")
  Next

  aPalavras := Hb_aTokens(cRetTxt)

  cRetTxt := ""
  For iFor := 1 To Len(aPalavras)
    If Len(aPalavras[iFor]) > 3
      cRetTxt += (cAnd + Chr(34)+aPalavras[iFor])+Chr(34) //+ " "
      cAnd := " and "
    Endif
  Next

Return cRetTxt
///////////////////////////////////////////////////////////////////////////////
FUNCTION nCalcRelPos(f_nVal,f_oXBrw)
  Local nLenRegs := f_oXBrw:nLen, nRowPos := f_oXBrw:nRowSel
  Local nRetorno := 0
 
  nRetorno := Round(f_nVal,3)
 
  If nRetorno == 0
    nRetorno := 1
  EndIf

  If nRetorno < nRowPos
    nRetorno := nRowPos
  EndIf  

  nRetorno := Int(nRetorno)

RETURN nRetorno
///////////////////////////////////////////////////////////////////////////////
FUNCTION _CHAR_CLEAN(f_cTxt,f_aCaracteresRetira)
    Local cTxtRetorno := f_cTxt, iFor := 0
   
    For iFor := 1 To Len(f_aCaracteresRetira)
    cTxtRetorno := StrTran(cTxtRetorno,f_aCaracteresRetira[iFor],"")
  Next
   
RETURN cTxtRetorno

 


Exemplo com tAds

Code: Select all  Expand view

  ::oDb_BoletoNucleo  := DB_BOLNUCL():OpenRdd()

  ::oBrw361_Remessas                     := tXBrowse():New( ::oDlgBoletosGeral )
  ::oBrw361_Remessas:cAlias              := ::oDb_BoletoNucleo:cAlias
  ::oBrw361_Remessas:nMarqueeStyle       := MARQSTYLE_HIGHLROW
  ::oBrw361_Remessas:nRowDividerStyle    := LINESTYLE_BLACK
  ::oBrw361_Remessas:nColDividerStyle    := LINESTYLE_BLACK
  ::oBrw361_Remessas:nColSel             := 1
  ::oBrw361_Remessas:l2007               := .T.
  ::oBrw361_Remessas:nRowHeight          := 24
  ::oBrw361_Remessas:nHeaderHeight       := 24
  ::oBrw361_Remessas:bClrRowFocus        := {||{ GetSysColor( 9 ), GetSysColor( 16 )}}
  ::oBrw361_Remessas:lFooter             := .F.

  aadd(aColunas,Nil)
  nColTmp := Len(aColunas)
  aColunas[nColTmp] := ::oBrw361_Remessas:AddCol()
    With Object aColunas[nColTmp]
      :bStrData         := {||::oDb_BoletoNucleo:dProcesso}
      :cHeader          := "Dt. Imp. "
      :nWidth           := 90
      :nDataStrAlign    := AL_RIGHT
      :nHeadStrAlign    := AL_RIGHT
      :cSortOrder       := "dProcesso"
      :nEditType        := EDIT_GET
      //:cEditPicture     := "!"
      //:bEditValue       := {||}
      //:bEditWhen        := {||}
      //:bEditValid       := {||}
      //:aEditListTxt     := {}
      :AddResource("B16_BRWSEEK") // Bitmaps
      :AddResource("B16_LED_RED_1") // Bitmaps
      :nHeadBmpNo       := 1
      //:bBmpData         := {||}
      //:nBtnBmp          := 2
      //:bEditBlock       := {|oSelf|::Fun_Menus(01,oSelf)}
      :bOnPostEdit      := {|ooBj,vVar,nKey|::oCtrl361_Remessas:tCtrlxBrw_Seek(ooBj,vVar)} // Automatic seek on Presskey
      //:cFooter          := "Total"
      //:bFooter          := {||20+20}
      //:nFootStrAlign    := 1
    //:nTotal           := 0
    //:lTotal           := .T.
      //:nFootStrAlign    := 1
 
    End With

  aadd(aColunas,Nil)
  nColTmp := Len(aColunas)
  aColunas[nColTmp] := ::oBrw361_Remessas:AddCol()
    With Object aColunas[nColTmp]
      :bStrData         := {||::oDb_BoletoNucleo:nOcorrencias}
      :cHeader          := "Qta "
      :nWidth           := 30
      :nDataStrAlign    := AL_RIGHT
      :nHeadStrAlign    := AL_RIGHT
 
    End With


  ::oBrw361_Remessas:SetRDD()
  ::oBrw361_Remessas:CreateFromResource(361)
   
  aColunas[1]:SetOrder()
  ::oBrw361_Remessas:GoTop()
  ::oBrw361_Remessas:SetFocus()
  ::oBrw361_Remessas:Refresh()

  ::oCtrl361_Remessas  := tCtrlxBrw():New(::oBrw361_Remessas,::oDb_BoletoNucleo) // Class tCtrlxBrw control xbrowse


 
User avatar
Giovany Vecchi
 
Posts: 222
Joined: Mon Jun 05, 2006 9:39 pm
Location: Brasil

Re: xbrowse / ADS failure

Postby TimStone » Wed Oct 28, 2015 3:57 pm

I appreciate the alternative, but I really think the most appropriate solution is to get a fix for the bug !

Antonio ? Did you receive a response to your inquiries ?

The problem does not exist with xHarbour ( .com ) builds, or DBFCDX, only ADS with Harbour ... so surely we can get the error fixed.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: xbrowse / ADS failure

Postby Antonio Linares » Wed Oct 28, 2015 10:19 pm

Tim,

Could you prepare a small and self contained example without using FWH that reproduces the error ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42079
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: xbrowse / ADS failure

Postby TimStone » Wed Oct 28, 2015 10:28 pm

Antonio,

This has been discussed in another thread, and Rao identified the exact lines in the xBrowse code that creates the error.

In addition, others had the exact same result.

He indicated he knew what was causing the error, but then the topic was never resolved.

Thanks for testing. From the result of your tests we understand that OrdKeyGoTo() works with dbfcdx RDD even when there is no index and with ADS RDD it fails. When I made this change in 2009 I am sure it was working and at that time most of my applications were using ADSCDX.

If you are using Harbour we need to check with xHarbour version also.
Surprisingly it appears these functions are working:
AdsGetRelKeyPos
AdsSetRelKeyPos
AdsGetKeyCount
Theoretically, these functions also should depend on the index still they work.

Interestingly there is AdsGetKeyPos() function in ACE but no comparable function to OrdKeyGoTo()

I suggest you please continue with the change we proposed earlier.
I study both xHarbour and Harbour versions of the RDD source and also Advantage documentation and implement a dependable solution.


That dependable solution was never provided.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: xbrowse / ADS failure

Postby Antonio Linares » Wed Oct 28, 2015 10:34 pm

We need Rao help on this
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42079
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: xbrowse / ADS failure

Postby TimStone » Mon Nov 02, 2015 3:47 pm

Did you get in touch with him ?
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: xbrowse / ADS failure

Postby nageswaragunupudi » Mon Nov 02, 2015 4:19 pm

Mr Tim

I'll get back on this very soon
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10622
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: xbrowse / ADS failure

Postby nageswaragunupudi » Sun Dec 06, 2015 10:43 am

Resolved in FWH 15.10
Please see
viewtopic.php?f=3&t=31485&p=184767#p184767
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10622
Joined: Sun Nov 19, 2006 5:22 am
Location: India


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 75 guests