FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour ADO RDD xHarbour
Posts: 1303
Joined: Tue Jul 21, 2009 08:12 AM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 03:04 PM

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.
Posts: 1303
Joined: Tue Jul 21, 2009 08:12 AM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 03:17 PM
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 (fw): Select all Collapse
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.
Posts: 838
Joined: Fri Feb 10, 2006 12:14 PM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 03:37 PM
Lucas,


I cant work with xBrowse()

Code (fw): Select all Collapse
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
Posts: 1303
Joined: Tue Jul 21, 2009 08:12 AM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 03:46 PM

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.
Posts: 838
Joined: Fri Feb 10, 2006 12:14 PM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 03:55 PM
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
Posts: 838
Joined: Fri Feb 10, 2006 12:14 PM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 04:04 PM
Lucas,

Try this:

Code (fw): Select all Collapse
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
Posts: 1303
Joined: Tue Jul 21, 2009 08:12 AM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 04:08 PM
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.
Posts: 838
Joined: Fri Feb 10, 2006 12:14 PM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 04:43 PM
Lucas,

Fivewin october 2008

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

Code (fw): Select all Collapse
     
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
Posts: 1303
Joined: Tue Jul 21, 2009 08:12 AM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 05:00 PM

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.
Posts: 838
Joined: Fri Feb 10, 2006 12:14 PM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 05:03 PM
Lucas,

Ok Ill check it.

Did this function?

Code (fw): Select all Collapse
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
Posts: 838
Joined: Fri Feb 10, 2006 12:14 PM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 05:32 PM
Lucas,

I notice in your code

Code (fw): Select all Collapse
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
Posts: 1303
Joined: Tue Jul 21, 2009 08:12 AM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 05:54 PM
Antonio,

The full statement is:

Code (fw): Select all Collapse
      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.
Posts: 838
Joined: Fri Feb 10, 2006 12:14 PM
Re: ADO RDD xHarbour
Posted: Mon May 25, 2015 08:14 PM

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
Posts: 838
Joined: Fri Feb 10, 2006 12:14 PM
Re: ADO RDD xHarbour
Posted: Tue May 26, 2015 07:25 AM

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
Posts: 838
Joined: Fri Feb 10, 2006 12:14 PM
Re: ADO RDD xHarbour
Posted: Tue May 26, 2015 08:31 AM

Lucas,

ConnectionTimeout does not function the way we needed this only avoids the timeout default of 15s of ado.
If you set it to 0 ado will try forever otherwise throws error.
I think we should set it to 60 seconds then ask the user if he likes to continue trying.

The DBA from our client advise us to do the following:

Place a timer pinging to the server
When it fails close the connection and open a new one.
The recordsets should remain ok
I just don't know if then we would need a :filter to have all pending records updates and to skip through all of them issuing the updates failed during the time of the lost connection.

Or

Configure the OleDb or ODBC to avoid that enabling automatic reconnect.

How can we catch the connection lost error?

Do you or anyone have any experience with this. Mr Rao? Enrico? Rick?

Regards

Antonio H Ferreira