FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour another error in class DataRow
Posts: 1303
Joined: Tue Jul 21, 2009 08:12 AM
another error in class DataRow
Posted: Sun Jun 09, 2013 10:08 AM
Hello,

I am trying to add a new record:

Code (fw): Select all Collapse
#include "fivewin.ch"
#include "dbinfo.ch"
#include "adodef.ch"
#include "xbrowse.ch"
#include "Set.ch"


REQUEST HB_Lang_ES
REQUEST HB_CODEPAGE_ESWIN




FUNCTION MAIN()

聽 聽local cStr, oCn, oRs
聽 聽local oData


聽 聽// Idioma espa帽ol
聽 聽HB_LangSelect("ES") // Para mensajes, fechas, etc..
聽 聽HB_CDPSELECT("ESWIN") // Para ordenaci贸n, requiere CodePage.lib

聽 聽// Driver CDX----------------------------------------------------------------
聽 聽REQUEST DBFCDX, DBFFPT

聽 聽RDDSETDEFAULT( "DBFCDX")

聽 聽SET DATE TO ITALIAN
聽 聽SET EPOCH TO 1990


聽 聽cStr 聽:= "Driver={MySQL ODBC 3.51 Driver};Server=db4free.net;" + ;
聽 聽 聽 聽 聽 聽 "Database=pruebasado;User=pruebasado;Password=123456;Option=3;"

聽 聽oCn 聽 := FW_OpenAdoConnection( cStr )




聽 聽oRs 聽 := FW_OpenRecordSet( oCn, "select * from clientes" )

聽 聽if oRs = nil
聽 聽 聽 msgstop("error opening recordset")
聽 聽 聽 oCn:Close()
聽 聽 聽 RETURN NIL
聽 聽endif


聽 聽xbrowser oRs


oData := TDataRow():New( oRs, nil, .T. )
oData:registro := 1
oData:nombre 聽 := "Cliente a帽adido por Lucas3"
oData:email 聽 聽:= "mi email"

MsgInfo(oData:Modified(), "IsModified")

oData:Save()


xbrowser oRs


聽oCn:Close()
聽QUIT


RETURN NIL
//----------------------------------------------------------------------------//





This is the error:

Application
===========
Path and name: C:\ADO\DATAROW.exe (32 bits)
Size: 2,876,928 bytes
Compiler version: Harbour 3.2.0dev (Rev. 18881)
FiveWin Version: FWH 13.05
Windows version: 6.1, Build 7601 Service Pack 1

Time from start: 0 hours 0 mins 5 secs
Error occurred at: 09-06-13, 12:05:44
Error description: Error BASE/1004 Message not found: TDATAROW:ADDNEW

Stack Calls
===========
Called from: .\source\function\HARBOUR.PRG => _CLSSETERROR( 234 )
Called from: .\source\classes\DATAROW.PRG => TDATAROW:ADDNEW( 543 )
Called from: .\source\classes\DATAROW.PRG => TDATAROW:SAVEADO( 355 )
Called from: .\source\classes\DATAROW.PRG => TDATAROW:SAVE( 279 )
Called from: datarow.prg => MAIN( 79 )


Thank you.

What is the problem?.
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: error in class DataRow
Posted: Sun Jun 09, 2013 12:35 PM

Hello,

Also, you have to control when modifying the table -oRs:Update()- that the record has not been deleted or modified in the meantime by another user in the network?.

How can be controlled that?.

Thank you.

Best regards

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: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: error in class DataRow
Posted: Sun Jun 09, 2013 05:21 PM

About the runtime error:
This is a bug in datarow.prg. Thanks for testing and finding it out.
In line 355, please change
::AddNew()
as
oRs:AddNew()

Next question about multiiuser issues:
1. If recordset is opened with adLockOptimistic:
If other user modified the same record we get a runtime error when we call oRs:Update. So catch the error in TRY/CATCH block and dealwith it.
2. If the recordset is opened in Batch Optimistic mode and if the provider is OLEDB
In most cases ReSync() works
First call oRs:ReSync( adAffectCurrent, adResyncUnderlyingValues ) // ( 1, 1 )
RecordSet reads current values into underlyingvalues

Each field has 3 values
:Value ( as modified by us )
:OriginalValue ( at the time recordset was read )
:UnderlyingValue ( After above resync, this is the present value on the Server)

If :Value <> :OriginalValue -> we modified the value after reading the recset
If :OriginalValue <> :UnderlyingValue --> Other user modified the value after we read the recordset.

Now in the program you decide if you want to overwrite or cancel edit and re-read new values from the server.

I do not think you can do with MySql ( I did not test ) because it is not full OLEDB provider but only ODBC driver.
We can use such features for mssql,oracle,etc

Regards



G. N. Rao.

Hyderabad, India
Posts: 1303
Joined: Tue Jul 21, 2009 08:12 AM
Re: error in class DataRow
Posted: Mon Jun 10, 2013 03:56 PM
Mr. Nages,

Thank you very much. Now I get:

Application
===========
Path and name: C:\tests\enrico.exe (32 bits)
Size: 2,878,464 bytes
Compiler version: Harbour 3.2.0dev (Rev. 18881)
FiveWin Version: FWH 13.05
Windows version: 6.1, Build 7601 Service Pack 1

Time from start: 0 hours 0 mins 2 secs
Error occurred at: 10-06-13, 17:55:01
Error description: Error BASE/1066 Error de argumento: conditional
Args:
[ 1] = U

Stack Calls
===========
Called from: enrico.prg => TDATAROW:SAVEADO( 556 )
Called from: enrico.prg => TDATAROW:SAVE( 467 )
Called from: enrico.prg => MAIN( 108 )





This is a working sample:

Code (fw): Select all Collapse
#include "fivewin.ch"
#include "dbinfo.ch"
#include "adodef.ch"
#include "xbrowse.ch"
#include "Set.ch"
#include "dbstruct.ch"


REQUEST HB_Lang_ES
REQUEST HB_CODEPAGE_ESWIN


#define STRIM( cStr, nChr ) Left( cStr, Len( cStr ) - nChr )
#define NTRIM( nNumber ) LTrim( Str( nNumber ) )





STATIC cCadena



//----------------------------------------------------------------------------------------
FUNCTION MAIN()

聽 聽local cStr, oCn, oRs
聽 聽local oData

聽 聽local lCreaTabla := .f.

聽 聽LOCAL aEstructura := { { "CODIGO" 聽 聽, "N", 04, 0 }, ;
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 { "NOMBRE" 聽 聽, "C", 70, 0 } }



聽 聽// Idioma espa帽ol
聽 聽HB_LangSelect("ES") // Para mensajes, fechas, etc..
聽 聽HB_CDPSELECT("ESWIN") // Para ordenaci贸n, requiere CodePage.lib

聽 聽// Driver CDX----------------------------------------------------------------
聽 聽REQUEST DBFCDX, DBFFPT

聽 聽RDDSETDEFAULT( "DBFCDX")

聽 聽SET DATE TO ITALIAN
聽 聽SET EPOCH TO 1990





聽 聽cCadena := 'Provider='+"Microsoft.Jet.OLEDB.4.0"+';Data Source='+HB_DIRBASE()+"ACCESS.MDB"


聽 聽IF !FILE("ACCESS.MDB")
聽 聽 聽 MSGALERT( FW_CreateMDB( "ACCESS.MDB" ), "CREATED ACCESS.MDB")
聽 聽 聽 lCreaTabla := .T.
聽 聽ENDIF





聽 聽oCn 聽 := FW_OpenAdoConnection( HB_DIRBASE()+"ACCESS.MDB" )




聽 聽IF lCreaTabla
聽 聽 聽 ADDTABLE( "JET", "CLIENTES", aEstructura )
聽 聽ENDIF






聽 聽oRs 聽 := FW_OpenRecordSet( oCn, "select * from CLIENTES" )

聽 聽if oRs = nil
聽 聽 聽 FW_ShowAdoError( oCn )
聽 聽 聽 oCn:Close()
聽 聽 聽 RETURN NIL
聽 聽endif




xbrowser oRs



/*
聽oData := TDataRow():New( oRs )
?oData:nombre
?len(oData:nombre)
*/


oData := TDataRow():New( oRs, nil, .T. )
oData:CODIGO 聽 := NRANDOM(2)
oData:NOMBRE 聽 := "Cliente a帽adido por Lucas3 "+cValToChar(time())
//oData:email 聽 聽:= "mi email "+cValToChar(Time())

MsgInfo(oData:Modified(), "IsModified")

oData:Save()




xbrowser oRs




聽oRs:Close()
聽oCn:Close()
聽QUIT


RETURN NIL
//----------------------------------------------------------------------------//







STATIC FUNCTION ADDTABLE( cMot, cTab, aFld )

聽 聽 LOCAL cQuery := "CREATE TABLE " + cTab + " ( "

聽 聽 LOCAL cType

聽 聽 LOCAL i

聽 聽 DEFAULT cMot := "JET"



聽 聽 IF cMot == "JET"
聽 聽 聽 聽 cQuery += "Id COUNTER PRIMARY KEY, "
聽 聽 ELSEIF cMot == "MSSQL"
聽 聽 聽 聽 cQuery += "Id INT IDENTITY PRIMARY KEY, "
聽 聽 ELSEIF cMot == "MYSQL"
聽 聽 聽 聽 cQuery += "Id SERIAL, "
聽 聽 ENDIF

聽 聽 FOR i = 1 TO LEN( aFld )
聽 聽 聽 聽 cType = aFld[ i, DBS_TYPE ]

聽 聽 聽 聽 DO CASE
聽 聽 聽 聽 聽 聽 CASE cType = "C"
聽 聽 聽 聽 聽 聽 聽 聽 cQuery += aFld[ i, DBS_NAME ] + " VARCHAR ( " + NTRIM( aFld[ i, DBS_LEN ] ) + " ), "
聽 聽 聽 聽 聽 聽 CASE cType = "N"
聽 聽 聽 聽 聽 聽 聽 聽 cQuery += aFld[ i, DBS_NAME ] + " NUMERIC ( " + NTRIM( aFld[ i, DBS_LEN ] ) + ", " + NTRIM( aFld[ i, DBS_DEC ] ) + " ), "
聽 聽 聽 聽 聽 聽 CASE cType = "D"
聽 聽 聽 聽 聽 聽 聽 聽 cQuery += aFld[ i, DBS_NAME ] + " DATETIME, "
聽 聽 聽 聽 聽 聽 CASE cType = "L"
聽 聽 聽 聽 聽 聽 聽 聽 cQuery += aFld[ i, DBS_NAME ] + " INT, "
聽 聽 聽 聽 聽 聽 CASE cType = "M"
聽 聽 聽 聽 聽 聽 聽 聽 IF cMot == "JET"
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 cQuery += "[" + aFld[ i, DBS_NAME ] + "]" + " MEMO, "
聽 聽 聽 聽 聽 聽 聽 聽 ELSEIF cMot == "MSSQL"
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 cQuery += "[" + aFld[ i, DBS_NAME ] + "]" + " TEXT, "
聽 聽 聽 聽 聽 聽 聽 聽 ELSEIF cMot == "MYSQL"
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 cQuery += aFld[ i, DBS_NAME ] + " TEXT, "
聽 聽 聽 聽 聽 聽 聽 聽 ENDIF
聽 聽 聽 聽 ENDCASE
聽 聽 NEXT

聽 聽 cQuery = STRIM( cQuery, 2 ) + " )"

聽 聽 SQLEXEC( cQuery )

RETURN NIL





FUNCTION SQLEXEC( cQuery )

聽 聽 LOCAL cCns := cCadena //"Your connectionstring here"

聽 聽 LOCAL oCn2 := CREATEOBJECT( "ADODB.Connection" )

聽 聽 oCn2:CursorLocation = adUseClient

聽 聽 oCn2:Open( cCns )

聽 聽 oCn2:Execute( cQuery )

聽 聽 oCn2:Close()

聽RETURN NIL







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




Thank you.

Best regards
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: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: another error in class DataRow
Posted: Mon Jun 10, 2013 08:31 PM
Mr Lucas

Probably, your error is in this line:
Code (fw): Select all Collapse
      if aPair[ 3 ] .and. ! ( oField:Value == uVal )

Please change it as
Code (fw): Select all Collapse
      if IfNil(aPair[ 3 ], .t. ) .and. ! ( oField:Value == uVal )


Is it appropriate to publish entire new classes of FWH here?
Regards



G. N. Rao.

Hyderabad, India
Posts: 1303
Joined: Tue Jul 21, 2009 08:12 AM
Re: another error in class DataRow
Posted: Mon Jun 10, 2013 08:44 PM

Dear Mr. Nages,

Thank you very much. It is working OK now.

I remove the class, but it is useless as some new functions at olefuncs.prg and xbrowse.prg are needed.

Also, I published it because I need to fix the class according to your instructions at oRs:AddNew().

I very much like the concept and design of that class.

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: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: another error in class DataRow
Posted: Tue Jun 11, 2013 05:52 AM

Mr Lucas

Thanks for pointing out the two bugs.
Wish you test with DBF, Ado and oBrw. ( Only edits for oBrw )
Now it works for TDatabase also. In the next version we extend it to all kinds of classes.

Advantage of this class is that once the programmer specifies the datasource, he can work independent of the datasource and is not worried about reading and saving. This enables common code to work with different datasources.

At present the default edit dialog is simple. We plan to include handling of images, memos, Rtf, etc without any programming effort.
Any suggestions/criticism welcome.

Regards



G. N. Rao.

Hyderabad, India

Continue the discussion