Page 1 of 69

ADO RDD xHarbour

Posted: Fri Feb 27, 2015 9:05 am
by AHF
Hello,

Is there a stable Rdd for ADO working for basic operations such as replaces, browses, like other rdds?

Regards
Antonio

Re: ADO RDD xHarbour

Posted: Fri Feb 27, 2015 9:06 pm
by Antonio Linares

Re: ADO RDD xHarbour

Posted: Sat Feb 28, 2015 8:44 am
by AHF
Antonio,

I work already with ADO that way, however I'm converting an old and large application with FW and xHarbour and the way app is desinged it will be vey time consuming to make that approach.
The app doesnt has any kind of Tdata objects to encapsulate the Skips, replaces etc that are spreaded all around the code.
I have a low budget for this work so my idea is to using an rdd.
Meanwhile I've found out ADORDD from 2007.
It seems to me that all these basics actions are covered.

Do you think that this can work?
Do you have any ideas of another low cost approach?

Thanks

Re: ADO RDD xHarbour

Posted: Sat Feb 28, 2015 10:13 am
by Antonio Linares
Antonio,

Yes, ADORDD may help you, may it has never been tested in a large application so I don't know how it may behave.

If you have the time and energy to test it and to complete it then it may be a very good solution for you and for other users too.

I am not aware of any other solution except the commercial SQLRDD. Thats why I thought that a free ADORDD could be very usefull
and I started its development but had no time to do more :-)

Re: ADO RDD xHarbour

Posted: Sat Feb 28, 2015 10:24 am
by AHF
Antonio,

I'm think the only low cost way to use ADO is through an RDD for it.

If I'm startint from scratch or I have the process in a kind of Tdata object then pure ADO its ok but I think the big majority of Harbour users have still lots of "old" code thus it is very costly to adapt it.

I'm not so aware how to write RDD's :( .I'm checking adordd.prg but there are some things I do not know how they work. Is there some docs that can help me?

Re: ADO RDD xHarbour

Posted: Sat Feb 28, 2015 10:33 am
by Antonio Linares
Antonio,

lets do one thing. Go ahead and test it with some minor examples and I will help you from here.

If you get blocked, I will help you how to solve it and you will start understading it.

it is easier than it seems once you start working on it.

And again, this could help lots of users. So surely others will help you :-)

Tomorrow I am flying to Barcelona and will stay busy for a week or so, I take my laptop with me and an android tablet to play with FiveTouch ;-)

I will try to attend the forums and all of you, whenever I have some free time

Re: ADO RDD xHarbour

Posted: Sat Feb 28, 2015 11:29 am
by AHF
Antonio,

Agreed. I'm crossing my fingers.

First I'm trying to connect to traditional DBF files.

I have in Odbc UserDsn a VisualFoxpro driver.

The properties are:
"Microsoft FoxPro VFP Driver (*.dbf)"
"DSN=DBF trial"
"SourceDB="+folder with dbfs
"Description=ODBC for ADO"
"SourceType=DBF"
"BackgroundFetch=Yes"
"Exclusive=No"
"Null=Yes"
"Deleted=Yes"
"Collate=Machine"
"SetNoCountOn=No"

My con string is :
aWAData[ WA_CONNECTION ]:Open( "Provider=Microsoft.Jet.OLEDB.4.0;SourceDB=c:\dbfs" + ";Extended Properties=Microsoft foxpro VFP Driver (*.dbf);SourceType=DBF;User ID=;Password=;" )
It seems I get the connection.

When I run
oRecordSet:Open( aWAData[ WA_QUERY ] + aWAData[ WA_TABLENAME ], aWAData[ WA_CONNECTION ] )
I get this error:

Args:
[ 1] = C SELECT * FROM INSTALA
[ 2] = O SELECT * FROM INSTALA
argumentos { SELECT * FROM INSTALA, TOLEAUTO Object }
descrição DISP_E_UNKNOWNNAME
ficheiro <nenhuma>
genCode 41: Unknown or reserved
operação OPEN
osCode (Não é erro do sistema operativo)
severity 2
subCode 6
subSystem ADODB.Recordset
tries 0

With or without path I get the same error.
Shall I supply always path name in the fie string?
With indexes the same?

Besides this I notice there are missing some traditional RDD functions:
OrdSetFocus()
Recno()
How do we implement Recno() in traditional SQLdatabases?

Can I creat it like this:
aMyFunc[ UR_ORDSETFOCUS ] := ( @ADO_ORDSETFOCUS() )
I assume that when callig OrdSetFocus() the ADO_ORDSETFOCUS() will execute.

Re: ADO RDD xHarbour

Posted: Mon Mar 02, 2015 3:31 pm
by AHF
I'm using xHarbour 30.09.2008 and FW 8 and ado.prg from harbour 3.0.0.

I had to change in ado.prg win_OleCreateObject to CreateObject

I make a connection
.....
cStr := CFILEPATH(aOpenInfo[ UR_OI_NAME ])
cStr := SUBSTR(cStr,1,LEN(Cstr)-1)

aWAData[ WA_CONNECTION ]:Open( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+cstr+;
";Extended Properties=dBASE IV;User ID=;Password=")
......
UR_SUPER_SETFIELDEXTENT( nWA, nTotalFields := oRecordSet:Fields:Count )
.....
Recordsetopen "SELECT * FROM [INSTALA.DBF]
msginfo("Connected? "+cvaltochar(aWAData[ WA_CONNECTION ]:State= adStateOpen)) TRUE
MSGINFO("NUMBER OF FIELDS "+STR(nTotalFields)) = 22 CORRECT

FOR n := 1 TO nTotalFields
aField := Array( UR_FI_SIZE )
aField[ UR_FI_NAME ] := oRecordSet:Fields( n - 1 ):Name //ERROR LINE 428
aField[ UR_FI_TYPE ] := ADO_GETFIELDTYPE( oRecordSet:Fields( n - 1 ):Type )
aField[ UR_FI_TYPEEXT ] := 0
aField[ UR_FI_LEN ] := ADO_GETFIELDSIZE( aField[ UR_FI_TYPE ], oRecordSet:Fields( n - 1 ):DefinedSize )
aField[ UR_FI_DEC ] := 0
#ifdef UR_FI_FLAGS
aField[ UR_FI_FLAGS ] := 0
#endif
#ifdef UR_FI_STEP
aField[ UR_FI_STEP ] := 0
#endif
UR_SUPER_ADDFIELD( nWA, aField )
NEXT

I get this error:

Error description
=================
Args:
[ 1] = N 203000288
[ 2] = N 203000288
[ 3] = N 203000288
[ 4] = C 203000288
[ 5] = A 203000288
argumentos { 203000288, 0, 2, {00001564-0000-0010-8000-00AA006D2EA4}, }
descrição Invoke failed
ficheiro <nenhuma>
genCode 1: EG_ARG
operação __OLEINVOKEDISPATCH
osCode (Não é erro do sistema operativo)
severity 2
subCode 6001
subSystem BASE
tries 0
=================

Stack

Chamado de __OLEINVOKEDISPATCH(0)
Chamado de (b)ADODB.RECORDSET.6.0:WRAPINTERFACE(801)
Chamado de ADODB.RECORDSET.6.0:FIELDS(0)
Chamado de ADO_OPEN(428)
Chamado de DBUSEAREA(0)

Used classes

25 TYPELIB
26 ENUMTYPEINFO
27 CONSTANTTYPEINFO
28 OBJECTTYPEINFO
29 INTERFACETYPEINFO
30 METHODTYPEINFO
31 ARGUMENTTYPEINFO
32 PROPERTYTYPEINFO
33 TOLEAUTO
34 OLEWRAPPER
35 ADODB.CONNECTION.6.0
36 {00000514-0000-0010-8000-00AA006D2EA4}
37 {00001550-0000-0010-8000-00AA006D2EA4}
38 {00001550-0000-0010-8000-00AA006D2EA4}._CONNECTION
39 {00001550-0000-0010-8000-00AA006D2EA4}.PROPERTIES
40 {00000504-0000-0010-8000-00AA006D2EA4}
41 {00001550-0000-0010-8000-00AA006D2EA4}.PROPERTY
42 {00000503-0000-0010-8000-00AA006D2EA4}
43 {00001550-0000-0010-8000-00AA006D2EA4}._RECORDSET
44 {00001556-0000-0010-8000-00AA006D2EA4}
45 {00001550-0000-0010-8000-00AA006D2EA4}.FIELDS
46 {00001564-0000-0010-8000-00AA006D2EA4}
47 {00001550-0000-0010-8000-00AA006D2EA4}.FIELD
48 {00001569-0000-0010-8000-00AA006D2EA4}
49 {00001550-0000-0010-8000-00AA006D2EA4}.ERRORS
50 {00000501-0000-0010-8000-00AA006D2EA4}
51 {00001550-0000-0010-8000-00AA006D2EA4}.ERROR
52 {00000500-0000-0010-8000-00AA006D2EA4}
53 {00001550-0000-0010-8000-00AA006D2EA4}._COMMAND
54 {986761E8-7269-4890-AA65-AD7C03697A6D}
55 {00001550-0000-0010-8000-00AA006D2EA4}._PARAMETER
56 {0000150C-0000-0010-8000-00AA006D2EA4}
57 {00001550-0000-0010-8000-00AA006D2EA4}.PARAMETERS
58 {0000150D-0000-0010-8000-00AA006D2EA4}
59 ADODB.RECORDSET.6.0
60 {00000535-0000-0010-8000-00AA006D2EA4}
61 {00001556-0000-0010-8000-00AA006D2EA4}._RECORDSET
62 {00001556-0000-0010-8000-00AA006D2EA4}.PROPERTIES
63 {00001556-0000-0010-8000-00AA006D2EA4}.PROPERTY
64 {00001556-0000-0010-8000-00AA006D2EA4}.FIELDS
65 {00001556-0000-0010-8000-00AA006D2EA4}.FIELD
66 {00001556-0000-0010-8000-00AA006D2EA4}.ERROR
67 ADOX.CATALOG.6.0
68 {00000602-0000-0010-8000-00AA006D2EA4}
69 {00000603-0000-0010-8000-00AA006D2EA4}
70 {00000603-0000-0010-8000-00AA006D2EA4}._CATALOG
71 {00000603-0000-0010-8000-00AA006D2EA4}.TABLES
72 {00000611-0000-0010-8000-00AA006D2EA4}
73 {00000603-0000-0010-8000-00AA006D2EA4}.PROCEDURES
74 {00000626-0000-0010-8000-00AA006D2EA4}
75 {00000603-0000-0010-8000-00AA006D2EA4}.PROCEDURE
76 {00000625-0000-0010-8000-00AA006D2EA4}
77 {00000603-0000-0010-8000-00AA006D2EA4}.VIEWS
78 {00000614-0000-0010-8000-00AA006D2EA4}
79 {00000603-0000-0010-8000-00AA006D2EA4}.VIEW
80 {00000613-0000-0010-8000-00AA006D2EA4}
81 {00000603-0000-0010-8000-00AA006D2EA4}.GROUPS
82 {00000617-0000-0010-8000-00AA006D2EA4}
83 {00000603-0000-0010-8000-00AA006D2EA4}.USERS
84 {0000061A-0000-0010-8000-00AA006D2EA4}

What can I do to solve this?

Re: ADO RDD xHarbour

Posted: Tue Mar 03, 2015 8:46 am
by AHF
Forget my previous post I must use TOleAuto():New instead of CreateObject.

Now I get error :

1003 adordd 1: EG_ARG
Source : ADO_OPEN -> UR_SUPER_ADDFIELD( nWA, aField )

Re: ADO RDD xHarbour

Posted: Tue Mar 03, 2015 10:25 am
by Antonio Linares
Antonio,

What ADORDD version are you using ?

Where have you downloaded it from ?

Re: ADO RDD xHarbour

Posted: Tue Mar 03, 2015 10:40 am
by AHF
Im using RDDADO.prg from harbour 3.0.

Im only linking adordd.prg ( no other rdd lib explicit linked) to the app.

Re: ADO RDD xHarbour

Posted: Tue Mar 03, 2015 10:47 am
by Antonio Linares
Please copy the source code of ADO_OPEN here, thanks

Re: ADO RDD xHarbour

Posted: Tue Mar 03, 2015 10:55 am
by AHF
Im connecting dbf - DbaseIV

Code: Select all

STATIC FUNCTION ADO_OPEN( nWA, aOpenInfo )

   LOCAL aWAData := USRRDD_AREADATA( nWA )
   LOCAL cName, aField, oError, nResult
   LOCAL oRecordSet, nTotalFields, n,cstr

   /* When there is no ALIAS we will create new one using file name */
   IF Empty( aOpenInfo[ UR_OI_ALIAS ] )
      HB_FNAMESPLIT( aOpenInfo[ UR_OI_NAME ], , @cName )
      aOpenInfo[ UR_OI_ALIAS ] := cName
   ENDIF

   aOpenInfo[ UR_OI_NAME ] += ".dbf"
   
   hb_adoSetTable( aOpenInfo[ UR_OI_NAME ] )
   hb_adoSetEngine( "")
   hb_adoSetServer( "")
   hb_adoSetQuery( )
   hb_adoSetUser( "")
   hb_adoSetPassword( "" )

   IF Empty( aOpenInfo[ UR_OI_CONNECT ] )
      aWAData[ WA_CONNECTION ] :=  TOleAuto():New( "ADODB.Connection" )
      aWAData[ WA_TABLENAME ] := t_cTableName
      aWAData[ WA_QUERY ]    := t_cQuery
      aWAData[ WA_USERNAME ] := t_cUserName
      aWAData[ WA_PASSWORD ] := t_cPassword
      aWAData[ WA_SERVER ] := t_cServer
      aWAData[ WA_ENGINE ] := t_cEngine
      aWAData[ WA_CONNOPEN ] := .T.

      DO CASE

      case Lower( Right( aOpenInfo[ UR_OI_NAME ], 4 ) ) == ".dbf"
           cStr :=   CFILEPATH(aOpenInfo[ UR_OI_NAME ]) 
           cStr := SUBSTR(cStr,1,LEN(Cstr)-1)
 
           aWAData[ WA_CONNECTION ]:Open( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+cstr+;
            ";Extended Properties=dBASE IV;User ID=;Password=")   

      CASE Lower( Right( aOpenInfo[ UR_OI_NAME ], 4 ) ) == ".mdb"
         IF Empty( aWAData[ WA_PASSWORD ] )
            aWAData[ WA_CONNECTION ]:Open( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + aOpenInfo[ UR_OI_NAME ] )
         ELSE
            aWAData[ WA_CONNECTION ]:Open( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + aOpenInfo[ UR_OI_NAME ] + ";Jet OLEDB:Database Password=" + AllTrim( aWAData[ WA_PASSWORD ] ) )
         ENDIF

      CASE Lower( Right( aOpenInfo[ UR_OI_NAME ], 4 ) ) == ".xls"
         aWAData[ WA_CONNECTION ]:Open( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + aOpenInfo[ UR_OI_NAME ] + ";Extended Properties='Excel 8.0;HDR=YES';Persist Security Info=False" )

      CASE Lower( Right( aOpenInfo[ UR_OI_NAME ], 3 ) ) == ".db"
         aWAData[ WA_CONNECTION ]:Open( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + aOpenInfo[ UR_OI_NAME ] + ";Extended Properties='Paradox 3.x';" )

      CASE aWAData[ WA_ENGINE ] == "MYSQL"
         aWAData[ WA_CONNECTION ]:Open( "DRIVER={MySQL ODBC 3.51 Driver};" + ;
                                        "server=" + aWAData[ WA_SERVER ] + ;
                                        ";database=" + aOpenInfo[ UR_OI_NAME ] + ;
                                        ";uid=" + aWAData[ WA_USERNAME ] + ;
                                        ";pwd=" + aWAData[ WA_PASSWORD ] )

      case aWAData[ WA_ENGINE ] == "SQL"
         aWAData[ WA_CONNECTION ]:Open( "Provider=SQLOLEDB;" + ;
                                        "server=" + aWAData[ WA_SERVER ] + ;
                                        ";database=" + aOpenInfo[ UR_OI_NAME ] + ;
                                        ";uid=" + aWAData[ WA_USERNAME ] + ;
                                        ";pwd=" + aWAData[ WA_PASSWORD ] )

      CASE aWAData[ WA_ENGINE ] == "ORACLE"
         aWAData[ WA_CONNECTION ]:Open( "Provider=MSDAORA.1;" + ;
                                        "Persist Security Info=False" + ;
                                        iif( Empty( aWAData[ WA_SERVER ] ),;
                                        "", ";Data source=" + aWAData[ WA_SERVER ] ) + ;
                                        ";User ID=" + aWAData[ WA_USERNAME ] + ;
                                        ";Password=" + aWAData[ WA_PASSWORD ] )

      CASE aWAData[ WA_ENGINE ] == "FIREBIRD"
         aWAData[ WA_CONNECTION ]:Open( "Driver=Firebird/InterBase(r) driver;" + ;
                                        "Persist Security Info=False" +;
                                        ";Uid=" + aWAData[ WA_USERNAME ] +;
                                        ";Pwd=" + aWAData[ WA_PASSWORD ] +;
                                        ";DbName=" + aOpenInfo[ UR_OI_NAME ] )
      ENDCASE
   ELSE
      aWAData[ WA_CONNECTION ] :=  TOleAuto():New( "ADODB.Connection" )
      aWAData[ WA_TABLENAME ] := t_cTableName
      aWAData[ WA_QUERY ] := t_cQuery
      aWAData[ WA_USERNAME ] := t_cUserName
      aWAData[ WA_PASSWORD ] := t_cPassword
      aWAData[ WA_SERVER ] := t_cServer
      aWAData[ WA_ENGINE ] := t_cEngine
      aWAData[ WA_CONNOPEN ] := .F.
   ENDIF

   /* will be initilized */
   t_cQuery := ""

   IF Empty( aWAData[ WA_QUERY ] )
      aWAData[ WA_QUERY ] := "SELECT * FROM "
   ENDIF

   oRecordSet :=  TOleAuto():New( "ADODB.Recordset" )

   IF oRecordSet == NIL
      oError := ErrorNew()
      oError:GenCode     := EG_OPEN
      oError:SubCode     := 1001
      oError:Description := HB_LANGERRMSG( EG_OPEN )
      oError:FileName    := aOpenInfo[ UR_OI_NAME ]
      oError:OsCode      := 0 /* TODO */
      oError:CanDefault  := .T.

      UR_SUPER_ERROR( nWA, oError )
      RETURN HB_FAILURE
   ENDIF
   oRecordSet:CursorType     := adOpenDynamic
   oRecordSet:CursorLocation := adUseClient
   oRecordSet:LockType       := adLockPessimistic
   
   aWAData[ WA_TABLENAME ] := FW_QuotedColSQL(  CFILENOPATH(aWAData[ WA_TABLENAME ] ))

   IF aWAData[ WA_QUERY ] == "SELECT * FROM "
      oRecordSet:Open( aWAData[ WA_QUERY ] + aWAData[ WA_TABLENAME ], aWAData[ WA_CONNECTION ] )
   ELSE
      oRecordSet:Open( aWAData[ WA_QUERY ], aWAData[ WA_CONNECTION ] )
   ENDIF

   TRY
      aWAData[ WA_CATALOG ] :=  TOleAuto():New( "ADOX.Catalog" )
      aWAData[ WA_CATALOG ]:ActiveConnection := aWAData[ WA_CONNECTION ]
   CATCH
   END
   
   IF Empty( aWAData[ WA_CATALOG ] )
      TRY
         aWAData[ WA_CATALOG ] := aWAData[ WA_CONNECTION ]:OpenSchema( adSchemaIndexes )
      CATCH
      END
   ENDIF

   aWAData[ WA_RECORDSET ] := oRecordSet
   aWAData[ WA_BOF ] := aWAData[ WA_EOF ] := .F.

   UR_SUPER_SETFIELDEXTENT( nWA, nTotalFields := oRecordSet:Fields:Count )
   
   FOR n := 1 TO nTotalFields
      aField := Array( UR_FI_SIZE )
      aField[ UR_FI_NAME ]    := oRecordSet:Fields( n - 1 ):Name
      aField[ UR_FI_TYPE ]    := ADO_GETFIELDTYPE( oRecordSet:Fields( n - 1 ):Type )
      aField[ UR_FI_TYPEEXT ] := 0
      aField[ UR_FI_LEN ]     := ADO_GETFIELDSIZE( aField[ UR_FI_TYPE ], oRecordSet:Fields( n - 1 ):ActualSize )
      aField[ UR_FI_DEC ]     := 0
#ifdef UR_FI_FLAGS
      aField[ UR_FI_FLAGS ]   := 0
#endif
#ifdef UR_FI_STEP
      aField[ UR_FI_STEP ]    := 0
#endif
      UR_SUPER_ADDFIELD( nWA, aField )
   NEXT

   nResult := UR_SUPER_OPEN( nWA, aOpenInfo )

   IF nResult == HB_SUCCESS
      ADO_GOTOP( nWA )
   ENDIF

   RETURN nResult

Re: ADO RDD xHarbour

Posted: Thu Mar 05, 2015 8:31 am
by elvira
Hello,

If you post a full working sample and the source code of RDDADO.prg we can try to help!.

:D :D

Re: ADO RDD xHarbour

Posted: Thu Mar 05, 2015 8:57 am
by Antonio Linares
Antonio,

This is how it is done from Harbour\src\rdd\arrayrdd.prg

Code: Select all

      aField := Array( UR_FI_SIZE )
      aField[ UR_FI_NAME ]    := aFieldStruct[ DBS_NAME ]
      aField[ UR_FI_TYPE ]    := hb_Decode( aFieldStruct[ DBS_TYPE ], "C", HB_FT_STRING, "L", HB_FT_LOGICAL, "M", HB_FT_MEMO, "D", HB_FT_DATE, "N", iif( aFieldStruct[ DBS_DEC ] > 0, HB_FT_DOUBLE, HB_FT_INTEGER ) )
      aField[ UR_FI_TYPEEXT ] := 0
      aField[ UR_FI_LEN ]     := aFieldStruct[ DBS_LEN ]
      aField[ UR_FI_DEC ]     := aFieldStruct[ DBS_DEC ]
      UR_SUPER_ADDFIELD( nWA, aField )
Do MsgInfo( ADO_GETFIELDTYPE( oRecordSet:Fields( n - 1 ):Type ) ) and tell me what type you get. It seems as the error may come from there.

https://github.com/harbour/core/blob/ma ... rayrdd.prg