Page 2 of 2

Re: bug SQLRDD, xHarbour and BCC 5.8.2

Posted: Mon Mar 11, 2013 3:00 pm
by nageswaragunupudi
If you plan to use an array of recno()'s for using xbrowse and are prepared to spend a little time in constructing the array initially, I suggest a simpler way.

=========
aKeyNos := Array( OrdKeyCount() )
// OrdKeyCount() works in SQLRDD.
DBGOTOP()
n := 1
DBEVAL( { || aKeyNos[ n ] := RECNO(), n++ } )
DBGOTOP()

@ <r>, <c> XBROWSE oBrw OF oWnd ALIAS <OurAlias> ;
COLUMNS .......<usual clauses> ;
ROWS aKeyNos

Please note the clause ROWS aKeyNos

The browse should work perfectly.

You do not need to write any special code for ordkeyno() and ordkeygoto()

Re: bug SQLRDD, xHarbour and BCC 5.8.2

Posted: Mon Mar 11, 2013 6:05 pm
by nageswaragunupudi
For those colleagues who are comfortable with the use of array of key numbers, I have made a derived class.

Code: Select all

#include 'fivewin.ch'
#include 'hbcompat.ch'
#include 'xbrowse.ch'

//------------------------------------------------------------------//

CLASS TQBrowse FROM TXBrowse

   CLASSDATA lRegistered AS LOGICAL // This is compulsory for derived classes
   DATA bColClass INIT { || TQBrwColumn() }

   //
   DATA aSQKeys      INIT Array( 0 )
   DATA lDescend     INIT .f.
   //
   METHOD Adjust()
   METHOD SetRDD( lAddColumns, lAutoOrder, aFldNames, aRows )
   METHOD Paint()
   //
   METHOD SQKeyNo( n )
   METHOD BuildSqKeyArray()

ENDCLASS

//----------------------------------------------------------------------------//

METHOD Adjust() CLASS TQBrowse

   ::Super:Adjust()

   if ValType( ::aSQKeys ) == 'A'
      ( ::cAlias )->( ::BuildSqKeyArray() )
   endif

return Self

//----------------------------------------------------------------------------//

METHOD SetRDD( lAddColumns, lAutoOrder, aFldNames, aRows ) CLASS TQBrowse

   ::Super:SetRDD( lAddColumns, lAutoOrder, aFldNames, aRows )

   ::bKeyCount       := { || ( ::cAlias )->( OrdKeyCount() ) }
   ::bKeyNo          := { |n| ( ::cAlias )->( ::SQKeyNo( n ) ) }

return nil

//----------------------------------------------------------------------------//

METHOD Paint() CLASS TQBrowse

   if ValType( ::aSqKeys ) == 'A' .and. Len( ::aSqKeys ) != ::nLen
      // in rare cases of addition / deletion of records
      ( ::cAlias )->( ::BuildSqKeyArray() )
   endif

return ::Super:Paint()

//----------------------------------------------------------------------------//

METHOD SQKeyNo( nGoTo ) CLASS TQBrowse

   local nRet

   if Empty( ::aSqKeys )
      nRet  := If( nGoTo == nil, OrdKeyNo(), OrdKeyGoTo( nGoTo ) )
   else
      if nGoTo == nil
         nRet  := AScan( ::aSqKeys, RecNo() )
         if ::lDescend
            nRet  := ::nLen - nRet + 1
         endif
      else
         if ::lDescend
            nGoTo    := ::nLen - nGoTo + 1
         endif
         DbGoTo( ::aSqKeys[ nGoTo ] )
      endif
   endif

return nRet

//----------------------------------------------------------------------------//

METHOD BuildSqKeyArray() CLASS TQBrowse

   local nKey, nRec := RecNo()

   CursorWait()

   ::lDescend     := .f.
   if ! Empty( OrdSetFocus() )
      ::lDescend  := OrdDescend()
   endif
   ::aSqKeys      := Array( ::nLen := OrdKeyCount() )

   DbGoTop()
   if ::lDescend
      nKey        := Len( ::aSqKeys )
      DBEVAL( { || ::aSqKeys[ nKey ] := RecNo(), nKey-- } )
   else
      nKey        := 1
      DBEVAL( { || ::aSqKeys[ nKey ] := RecNo(), nKey++ } )
   endif
   DbGoTo( nRec )

return nil

//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//

CLASS TQBrwColumn FROM TXBrwColumn

   METHOD SetOrder()

ENDCLASS

//----------------------------------------------------------------------------//

METHOD SetOrder() CLASS TQBrwColumn

   local lSorted
   local cAlias   := ::oBrw:cAlias
   local cOrder   := ( cAlias )->( OrdSetFocus() )
   local nRec     := RecNo()

   lSorted     := ::Super:SetOrder()

   if lSorted .and. ValType( ::oBrw:aSqKeys ) == 'A'
      ::oBrw:lDescend   := ( cAlias )->( OrdDescend() )

      if ( cAlias )->( OrdSetFocus() ) == cOrder
      else
         ( cAlias )->( ::oBrw:BuildSqKeyArray() )
      endif
      DbGoTo( nRec )
   endif

return lSorted

//----------------------------------------------------------------------------//
 
You may use this new class in your program:

1. oBrw := TQBrowse():New( oWnd )

OR

2. @ r,c XBROWSE <........ clauses .......> CLASS TQBrowse()

I have tested with MySql tables on my local MySql server and performance is okay.
I shall be glad to have feedback from the users.

Re: bug SQLRDD, xHarbour and BCC 5.8.2

Posted: Wed Jun 19, 2013 6:41 am
by kokookao2007
HI nageswaragunupudi:

Thank you for TQBrowse() Solution.

It is as good as what you said .

The only problem is when browse a Big Table ( more than 10k records) ,
First time need 10-20 seconds , second time need 3-5 seconds.

Do you have any Idea about a Big Table ?

Re: bug SQLRDD, xHarbour and BCC 5.8.2

Posted: Wed Jun 19, 2013 8:02 am
by nageswaragunupudi
You are right.
But we made xbrowse *more* compatible with sqlrdd in the latest versions, without this overhead.
For most purposes behavior is on par with other RDDs.

Re: bug SQLRDD, xHarbour and BCC 5.8.2

Posted: Wed Jun 19, 2013 9:30 am
by Antonio Linares
Kokoo,

Many thanks for sharing your solution with all :-)

I really enjoy when someone is able to bypass a limitation, even if his code is not the best implementation. But it shows creativity and the wish to solve problems, very good :-)