ADO RDD xHarbour

AHF
Posts: 837
Joined: Fri Feb 10, 2006 12:14 pm

Re: ADO RDD xHarbour

Post by AHF »

Lucas,

Use this in adordd (i dont know if your version has already ADO_FILTERTEXT

if not place this in ADORDD_GETFUNCTABLE
aADOFunc[ UR_FILTERTEXT ] := (@ADO_FILTERTEXT())

and replace with this

Code: Select all

STATIC FUNCTION ADO_FILTERTEXT(nWa,cFilterExp)
 LOCAL aWAData := USRRDD_AREADATA( nWA )
 
 cFilterExp := aWAData[WA_CFILTERACTIVE]
 
   RETURN HB_SUCCESS
 
dbfilter() and dbinfo() return cfilter expression.
Regards
Antonio H Ferreira
User avatar
lucasdebeltran
Posts: 1303
Joined: Tue Jul 21, 2009 8:12 am
Contact:

Re: ADO RDD xHarbour

Post by lucasdebeltran »

Antonio,

OrdKeyCount() seems ok, but reccount() gets wrong results, adding more records that the ones concerning the filter.

Have you tested with xBrowse().
Muchas gracias. Many thanks.

Un saludo, Best regards,

Harbour 3.2.0dev, Borland C++ 5.82 y FWH 13.06 [producción]

Implementando MSVC 2010, FWH64 y ADO.

Abandonando uso xHarbour y SQLRDD.
User avatar
lucasdebeltran
Posts: 1303
Joined: Tue Jul 21, 2009 8:12 am
Contact:

Re: ADO RDD xHarbour

Post by lucasdebeltran »

Antonio,

I tested same filter with DBFCDX and RecCount() also is different in DBFCDX from OrdKeyCount(). I am lost.

This is how xBrowse sets the RDD:

Code: Select all

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

   local oCol, aStruct
   local cAlias, cAdsKeyNo, cAdsKeyCount
   local nFields, nFor, n, uData
   local bOnSkip

   if Empty( ::cAlias )
      ::cAlias := Alias()
      if Empty( ::cAlias )
         return nil
      endif
   endif

   if ::lCreated
      if ::nDataType == DATATYPE_RDD
         if SameDbfStruct( Self, Alias() )
            return nil
         endif
      endif
      ::cAlias := Alias()
      ::ClearBlocks()
      ::aCols  := {}
   endif

   DEFAULT lAddColumns      := Empty( ::aCols ) .or. ! Empty( aFldNames )
   DEFAULT lAutoOrder       := ::lAutoSort
   ::lAutoSort              := lAutoOrder

   cAlias      := ::cAlias
   if ValType( aRows ) == 'A' .and. Len( aRows ) > 0

      if ValType( aRows[ 1 ] ) == 'A'
         bOnSkip        := { | oBrw | ( oBrw:cAlias )->( DbGoTo( oBrw:aArrayData[ oBrw:nArrayAt ][ 1 ] ) ) }
      else
         bOnSkip        := { | oBrw | ( oBrw:cAlias )->( DbGoTo( oBrw:aArrayData[ oBrw:nArrayAt ] ) ) }
      endif
      ::SetArray( aRows, .f., 0, .f., bOnSkip )
      ::nDataType       := nOr( DATATYPE_RDD, DATATYPE_ARRAY )
      lAutoOrder        := .f.
   else
      ::nDataType := DATATYPE_RDD
   endif

   ::lSqlRDD := ( ( ::cAlias )->( RddName() ) == "SQLRDD" )
   if ::lSqlRDD
      DEFAULT ::bKeyNo  := { |n| 0 }
   endif

   DEFAULT ::bGoTop    := {|| ( ::cAlias )->( DbGoTop() ) },;
           ::bGoBottom := {|| ( ::cAlias )->( DbGoBottom() ) },;
           ::bSkip     := {| n | ( ::cAlias )->( DbSkipper( IfNil( n, 1 ) ) ) },;
           ::bBof      := {|| ( ::cAlias )->( Bof() ) },;
           ::bEof      := {|| ( ::cAlias )->( Eof() ) },;
           ::bBookMark := {| n | iif( n == nil,;
                                     ( ::cAlias )->( RecNo() ),;
                                     ( ::cAlias )->( DbGoto( n );
                                    ) ) }

   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, " +;
                         "Round( " + cAlias + "->( ADSGetRelKeyPos() ) * Self:nLen, 0 ), "+;
                         cAlias + "->( ADSSetRelKeyPos( n / Self:nLen ) ) ) }"

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

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

      ::lRelyOnKeyNo      := .f.
   else
       DEFAULT ::bKeyNo    := {| n | iif( n == nil,;
                                        ( ::cAlias )->( OrdKeyNo() ),;
                                        ( ::cAlias )->( OrdKeyGoto( n );
                                        ) ) },;
               ::bKeyCount := {|| ( ::cAlias )->( If( eof() .and. bof(), 0, OrdKeyCount() ) ) }

      ::lRelyOnKeyNo := If( Set( _SET_DELETED ), "DELETED()" $ Upper( DbFilter() ), .t. )
   Endif
   if ::lSqlRDD
      ::lRelyOnKeyNo    := .f.
   endif

   ::lReadOnly    := ( ( ::cAlias )->( DbInfo( DBI_ISREADONLY ) ) == .t. )
   aStruct        := ( ::cAlias )->( dbstruct() )

   if lAddColumns
      if Empty( aFldNames )
         aFldNames   := { '*' }
      endif
      for each uData in aFldNames
         if ValType( uData ) == 'C' .and. uData == '*'
            for nFor := 1 to ( ::cAlias )->( FCount() )
               ( ::cAlias )->( SetColFromRDD( ::AddCol(), nFor ) )
            next
         else
            ( ::cAlias )->( SetColFromRDD( ::AddCol(), uData, aStruct ) )
         endif
      next
   endif

   (::cAlias)->( OrderTagInfo( aStruct, 8 ) )

   for nFor := 1 to Len( ::aCols )
      if ( n := AScan( aStruct, { |a| a[ 1 ] == Upper( ::aCols[ nFor ]:cHeader ) } ) ) > 0
         ::aCols[ nFor ]:cSortOrder    := aStruct[ n ][ 8 ]
         ::aCols[ nFor ]:cOrdBag       := ( cAlias )->( OrdBagName( ::aCols[ nFor ]:cSortOrder ) )
      endif
   next nFor

   DEFAULT ::bSeek  := { |c,u| ( ::cAlias )->( ::RddIncrSeek( c, @u ) ) }

   if ( ::cAlias )->( DbInfo( DBI_SHARED ) )
      ::bLock     := { || ( ::cAlias )->( DbrLock() ) }
      ::bUnlock   := { || ( ::cAlias )->( DbrUnlock() ) }
   endif

   ::bDelete   := { || ( ::cAlias )->( If( ::nLen > 0 .and. Eval( ::bLock ), ( DbDelete(), Eval( ::bUnlock ), ;
                       If( Set( _SET_DELETED ), ( DbSkip(1), If( Eof(), DbGoBottom(), nil ) ), nil ) ;
                       ), nil ) ) }

   if Empty( ::cTitle )
      ::cTitle := cFileNoExt( ( ::cAlias )->( DBINFO( DBI_FULLPATH ) ) )
   endif

   if ::lCreated
      ::Adjust()
      ::Refresh()
   endif

return nil

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

 
Muchas gracias. Many thanks.

Un saludo, Best regards,

Harbour 3.2.0dev, Borland C++ 5.82 y FWH 13.06 [producción]

Implementando MSVC 2010, FWH64 y ADO.

Abandonando uso xHarbour y SQLRDD.
AHF
Posts: 837
Joined: Fri Feb 10, 2006 12:14 pm

Re: ADO RDD xHarbour

Post by AHF »

Lucas,


I cant work with xBrowse()

Code: Select all

STATIC FUNCTION ADO_RECCOUNT( nWA, nRecords )
   LOCAL oRecordSet := USRRDD_AREADATA( nWA )[ WA_RECORDSET ],nRecNo

   IF oRecordSet:RecordCount() < 0
      nRecords := ADORECCOUNT(nWA,oRecordSet) // AHF SEE FUNCTION FOR EXPLANATION oRecordSet:RecordCount()
      
   ELSE
      ADO_RECID(nWA,@nRecNo)
      IF nRecNo > oRecordSet:RecordCount()
         nRecords := nRecNo
      ELSE
         nRecords :=  oRecordSet:RecordCount()
      ENDIF  
   ENDIF
   
   RETURN HB_SUCCESS
In order to avoid multiple calls of adoreccount Ive decided for this strategy.

ADORECCOUT only gets called if :recordcount <0 //not supported

Then because recno (autoinc field) can be greater than recordcount
if it is we assume reccount as recno
Otherwise reccount = recordcount

if you place in a dynamic say connected to a browse "recno() / lastrec()" you will see that if recno is greater than recordcount recno and lastrec will be always the same.

Maybe the logic its not correct. Without filters its ok.
Regards
Antonio H Ferreira
User avatar
lucasdebeltran
Posts: 1303
Joined: Tue Jul 21, 2009 8:12 am
Contact:

Re: ADO RDD xHarbour

Post by lucasdebeltran »

Antonio,

This is the same ADO_RECCOUNT() as current, isn´t it?.

Why can´t you work with xBrowse()?.

It was introduced since 2002-2003 in FWH.
Muchas gracias. Many thanks.

Un saludo, Best regards,

Harbour 3.2.0dev, Borland C++ 5.82 y FWH 13.06 [producción]

Implementando MSVC 2010, FWH64 y ADO.

Abandonando uso xHarbour y SQLRDD.
AHF
Posts: 837
Joined: Fri Feb 10, 2006 12:14 pm

Re: ADO RDD xHarbour

Post by AHF »

Lucas,
I tested same filter with DBFCDX and RecCount() also is different in DBFCDX from OrdKeyCount(). I am lost.
Im not sure what you mean.

Recno() = record number in the table
OrdKeyNo() record number in the index
OrdKeyCount() = total records in the index (if index with condition this will never be the same as reccount)
Reccount() = total records in the table

The index records are logical so not the same as table records.
In adordd OrdKeyNo = AbsolutePositon and OrdKeyCount = RecordCount
LastRec Reccount = see function my previous post
Recno = value of fieldrecno

Does filter works without indexes? Here ok
Does filter works with indexes without conditions? Here ok
Does Filter works with indexes with conditions? didnt try but it should since the filter its applied to the recordset and the recordset its build with where clause matching index condition.

All this without adding or changing keys being filtered.

So in xbrowse what is your bskip ?

::bSkip := {| n | ( ::cAlias )->( DbSkipper( IfNil( n, 1 ) ) ) },;

adordd should be treated as any dbf rdd.
Regards
Antonio H Ferreira
AHF
Posts: 837
Joined: Fri Feb 10, 2006 12:14 pm

Re: ADO RDD xHarbour

Post by AHF »

Lucas,

Try this:

Code: Select all

USE table
 msginfo("total recs "+str(lastrec())+" ordkeycount "+str(ordkeycount()))
 SET FILTER TO whatever
 msginfo("total recs "+str(lastrec())+" ordkeycount "+str(ordkeycount()))
 dbgotop()
 do while !eof()
    msginfo(" recno "+str(recno())+" total recs "+str(lastrec())+" ordkeycount "+str(ordkeycount()))
    skip
 enddo
 
what did you get?
Regards
Antonio H Ferreira
User avatar
lucasdebeltran
Posts: 1303
Joined: Tue Jul 21, 2009 8:12 am
Contact:

Re: ADO RDD xHarbour

Post by lucasdebeltran »

Antonio,
adordd should be treated as any dbf rdd.
Yes, it should be but in fact does not.

The problem happens when the filter cover more that one record.

With one record is fine.

Also, it happens only with xBrowse().

Which version of Fivewin are you using?.

Thank you.
Muchas gracias. Many thanks.

Un saludo, Best regards,

Harbour 3.2.0dev, Borland C++ 5.82 y FWH 13.06 [producción]

Implementando MSVC 2010, FWH64 y ADO.

Abandonando uso xHarbour y SQLRDD.
AHF
Posts: 837
Joined: Fri Feb 10, 2006 12:14 pm

Re: ADO RDD xHarbour

Post by AHF »

Lucas,

Fivewin october 2008

I think this is not implemented in adordd !
This is not used in our converted app.

Code: Select all

     
bKeyNo,;     // SETGET codeblock to be used for positioning the vertical scrollbar

DEFAULT ::bKeyNo    := {| n | iif( n == nil,;
                                        ( ::cAlias )->( OrdKeyNo() ),;
                                        ( ::cAlias )->( [b]OrdKeyGoto( n )[/b];

 
Are you using this?

So it did function in browse() and in my previous example?
Regards
Antonio H Ferreira
User avatar
lucasdebeltran
Posts: 1303
Joined: Tue Jul 21, 2009 8:12 am
Contact:

Re: ADO RDD xHarbour

Post by lucasdebeltran »

Antonio,

I sent you an email with a test function for xBrowse().

Browse() sometimes fails, less than xBrowse(), but also Browse() sometimes does not reflect all records within a FIlter.
Muchas gracias. Many thanks.

Un saludo, Best regards,

Harbour 3.2.0dev, Borland C++ 5.82 y FWH 13.06 [producción]

Implementando MSVC 2010, FWH64 y ADO.

Abandonando uso xHarbour y SQLRDD.
AHF
Posts: 837
Joined: Fri Feb 10, 2006 12:14 pm

Re: ADO RDD xHarbour

Post by AHF »

Lucas,

Ok Ill check it.

Did this function?

Code: Select all

USE table
 msginfo("total recs "+str(lastrec())+" ordkeycount "+str(ordkeycount()))
 SET FILTER TO whatever
 msginfo("total recs "+str(lastrec())+" ordkeycount "+str(ordkeycount()))
 dbgotop()
 do while !eof()
    msginfo(" recno "+str(recno())+" total recs "+str(lastrec())+" ordkeycount "+str(ordkeycount()))
    skip
 enddo
Regards
Antonio H Ferreira
AHF
Posts: 837
Joined: Fri Feb 10, 2006 12:14 pm

Re: ADO RDD xHarbour

Post by AHF »

Lucas,

I notice in your code

Code: Select all

INDEX ON DELETED() TAG DELETED TO TMP MEMORY ADDITIVE
    OrdSetFocus( 1 ) // this does nothing
   place my func check state here
 
adordd creates the index but does not opened. You must issue SET INDEX TO. Isnt this the normal procedure with other rdds ?
Ive post a function to check the state of all tables in previous post. Can you use it there and see.
Regards
Antonio H Ferreira
User avatar
lucasdebeltran
Posts: 1303
Joined: Tue Jul 21, 2009 8:12 am
Contact:

Re: ADO RDD xHarbour

Post by lucasdebeltran »

Antonio,

The full statement is:

Code: Select all


      if ( uData )->( RDDNAME() ) == 'DBFCDX' .and. ( uData )->( OrdCount() ) == 0 .and. ;
         ( uData )->( LastRec() ) <= 1000
         ( uData )->( MakeTmpIndex() )
      endif

 
So the MakeTmpIndex() is not executed as RDDNAME() is not DBFCDX.
Muchas gracias. Many thanks.

Un saludo, Best regards,

Harbour 3.2.0dev, Borland C++ 5.82 y FWH 13.06 [producción]

Implementando MSVC 2010, FWH64 y ADO.

Abandonando uso xHarbour y SQLRDD.
AHF
Posts: 837
Joined: Fri Feb 10, 2006 12:14 pm

Re: ADO RDD xHarbour

Post by AHF »

Lucas,

Ive made a small and I think that we cant use :find on :filter dont know why and its doesnt make sense but all indicates to that.

After using :find with :filter recordset goes nuts.

Does Mr. Rao knows anything about this ?

Ill try tomorrow a workaround.
Regards
Antonio H Ferreira
AHF
Posts: 837
Joined: Fri Feb 10, 2006 12:14 pm

Re: ADO RDD xHarbour

Post by AHF »

Lucas,

Check your email new adordd with filters working.

The problem was with :find that you cant use with active :filter.

Please try it and let me know results.

Thanks.
Regards
Antonio H Ferreira
Post Reply