FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posts: 883
Joined: Tue Oct 11, 2005 11:57 AM
ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Thu Apr 10, 2008 04:27 PM

Hi a todos.

Hize esta clase para manejar los recordset de ADO como lo hace la tDataBase de Fivewin

Es mi primera version y cualquier ayuda sera bienvenida, no esta terminada y las cooperaciones son bienvenidas.

La probe con Mysql 5 sin ningun tipo de problema, la pueden descargar de aqui, mis correos estan en su interior para reportar problemas o coas quelequieran agregar.

Se aceptan sugerencias, codigo, trucos, cualquier cosa que podamos usar para mejorarla.

http://200.72.140.34/privado/adobase.rar

Desde Chile
Adolfo

;-) Ji,ji,ji... buena la cosa... "all you need is code"

http://www.xdata.cl - Desarrollo Inteligente
----------
Asus TUF F15, 32GB Ram, 2 * 1 TB NVME M.2, GTX 1650
Posts: 1144
Joined: Mon Feb 05, 2007 07:15 PM
ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Thu Apr 10, 2008 10:02 PM

Adolfo,

personalmente quiero felicitarte por tu contribucion,

los que venimos de dbf a sql la verdad se nos complica

bastante,

ya tenia tiempo esperando algo como la database,

pero para ADO,

vamos a probar,,

saludos.

Cesar Cortes Cruz

SysCtrl Software

Mexico



' Sin +- FWH es mejor "
Posts: 1074
Joined: Fri Oct 07, 2005 01:56 PM
ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Thu Apr 10, 2008 10:13 PM

Gracias adolfo por la contribucion

Saludos
Patricio

__________________________________________________________________
Version: Harbour 3.2.0dev (r1307082134),Compiler: Borland C++ 5.8.2 (32-bit)
PCode version: 0.3, FWH 13.2
http://www.sialm.cl
Posts: 883
Joined: Tue Oct 11, 2005 11:57 AM
ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Thu Apr 10, 2008 10:30 PM

Gracias...

Si alguien puede probarla con Postgress, Oracle, SQL Server u otro RDBMS, por favor que comente los resultados.

Eso

;-) Ji,ji,ji... buena la cosa... "all you need is code"

http://www.xdata.cl - Desarrollo Inteligente
----------
Asus TUF F15, 32GB Ram, 2 * 1 TB NVME M.2, GTX 1650
Posts: 1446
Joined: Mon Oct 10, 2005 02:38 PM
Re: ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Fri Apr 11, 2008 08:20 AM
Adolfo wrote:Hi a todos.

Hize esta clase para manejar los recordset de ADO como lo hace la tDataBase de Fivewin

Es mi primera version y cualquier ayuda sera bienvenida, no esta terminada y las cooperaciones son bienvenidas.

La probe con Mysql 5 sin ningun tipo de problema, la pueden descargar de aqui, mis correos estan en su interior para reportar problemas o coas quelequieran agregar.

Se aceptan sugerencias, codigo, trucos, cualquier cosa que podamos usar para mejorarla.


http://200.72.140.34/privado/adobase.rar

Desde Chile
Adolfo


Gracias,

Es muy posible que me sea util en un futuro, estoy muy acostumbrado a trabajar con TDbf de Manuel Expósito (muy parecida a la TDatabase).

Entiendo que también puede trabajar con Harbour, cierto?

En el método New() para que sirven oClass, aDatas := {}, aMethods := {} ?

A ver que te parecen estas sencillas modificaciones:
/* ******************** */
METHOD New( oConnect, cTable, cSelect ) CLASS TAdoBase
...

::=oRs:Count
::aBuffer := Array( ::nFields )
::Load()

...
return Self
/* ******************** */
METHOD Load() CLASS TAdoBase

local n:=0

//::aBuffer := Array( ::nFields )
for n = 1 to ::nFields
::aBuffer[ n ] := ::AdoGetValue( n - 1 )
next

if ::lOemAnsi
::OemToAnsi()
endif

return nil
/* ******************** */
METHOD SetBuffer( lOnOff ) CLASS TAdoBase

DEFAULT lOnOff := .t.

if lOnOff != nil
::lBuffer = lOnOff
endif

if ::lBuffer
::Load()
else
//::aBuffer := nil
::ClearBuffer()
endif

return ::lBuffer
/* ******************** */
METHOD Find( uExpr ) CLASS TAdoBase

local lFound:=.f.

DEFAULT lSoft := .f.

::oRs:MoveFirst()
::oRs:Find( uExpr )

If !::oRs:Eof()
lFound:=.T.
Endif

if ::lBuffer
if lFound // Inicio Nuevo
::Load()
Else
::ClearBuffer()
EndIf // Fin nuevo
endif

return lFound
/* ******************** */
METHOD Seek( uExpr ) CLASS TAdoBase

local lFound:=.f.

DEFAULT lSoft := .f.

If ::oRs:Supports( adIndex ) .and. ::oRs:Supports( adSeek )
::oRs:Seek( uExpr )

If !::oRs:Eof()
lFound:=.T.
Endif
Endif

if ::lBuffer
if lFound // Inicio Nuevo
::Load()
Else
::ClearBuffer()
EndIf // Fin nuevo
endif

return lFound
/* ******************** */


Saludos
Carlos G.

Un Saludo

Carlos G.



FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home

Posts: 1446
Joined: Mon Oct 10, 2005 02:38 PM
Re: ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Fri Apr 11, 2008 08:30 AM

Hola,

más cosas:

/ *** */
METHOD End() CLASS TAdoBase

::Close()
Self := nil

return( .t. )
/ *** */

Saludos
Carlos G.

Un Saludo

Carlos G.



FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home

Posts: 883
Joined: Tue Oct 11, 2005 11:57 AM
ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Fri Apr 11, 2008 12:15 PM

Gracias...

Modificamos, revisamos y actualizamos la version.

Mas tests, pruebas...se reciben comentarios.

Desde Chile

;-) Ji,ji,ji... buena la cosa... "all you need is code"

http://www.xdata.cl - Desarrollo Inteligente
----------
Asus TUF F15, 32GB Ram, 2 * 1 TB NVME M.2, GTX 1650
Posts: 883
Joined: Tue Oct 11, 2005 11:57 AM
ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Fri Apr 11, 2008 01:34 PM

Cambios realizados....

Gracias Carlos G.

Nueva Version en

http://200.72.140.34/privado/adobase.rar

Desde Chile
Adolfo

;-) Ji,ji,ji... buena la cosa... "all you need is code"

http://www.xdata.cl - Desarrollo Inteligente
----------
Asus TUF F15, 32GB Ram, 2 * 1 TB NVME M.2, GTX 1650
Posts: 1446
Joined: Mon Oct 10, 2005 02:38 PM
Nombre de columnas en un RecordSet en ADO.
Posted: Fri Apr 11, 2008 06:45 PM

Hola Adolfo,

Podrías decirme como puedo obtener los nombres de las columnas de un RecordSet?

Saludos
Carlos G.

Un Saludo

Carlos G.



FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home

Posts: 1446
Joined: Mon Oct 10, 2005 02:38 PM
Más sugerencias para tu clase.
Posted: Fri Apr 11, 2008 06:51 PM

Hola Adolfo,

Siguiendo con tu clase, creo que sería posible añadir otras pequeñas mejoras, a ver que te parecen.

En los siguientes METHOD yo los acabaría con 'Return Self':

_AnsiToOem, _FieldPut, _OemToAnsi, Blank, ClearBuffer, Delete, GOTO, Load, Save.

Esto permitiría hacer cosas así:

oMiTADOBase:Fieldput(5, "calimero" ):Save()
oMiTADOBase:_AnsiToOem():Save()
Msgalert( "Registro Borrado:" + Str( oMiTADOBase:Goto( 3 ):Delete():Recno() , 4, 0 ), "Atención!" )
oMiTADOBase:ClearBuffer():Fieldput(5, "calimero" ):Save()

Modificaría los siguientes METHOD:
/ **** */
METHOD Blank() CLASS TAdoBase

   ::oRs:MoveLast()
   //::Load()
   ::ClearBuffer()
   ::lNew:=.T.

return nil
/ **** */
METHOD SetBuffer( lOnOff ) CLASS TAdoBase

Local Old_lBuffer := ::lBuffer

//DEFAULT lOnOff := .t.

if lOnOff != nil

   ::lBuffer = lOnOff


   if ::lBuffer
      ::Load()
   else
      ::ClearBuffer()
   endif

EndIf

return Old_lBuffer
/ **** */

Saludos
Carlos G.

Un Saludo

Carlos G.



FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home

Posts: 1144
Joined: Mon Feb 05, 2007 07:15 PM
ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Fri Apr 11, 2008 07:01 PM

Holas ADOlfo,

probando con acces me tira un error

te envie a tu correo hotmail el ejemplo,

saludos..

Application

Path and name: C:\SYSCTRL\TESTADO\TESTADO.Exe (32 bits)
Size: 483,840 bytes
Time from start: 0 hours 0 mins 0 secs
Error occurred at: 04/11/08, 13:04:34
Error description: Error ADODB.recordset/6 DISP_E_UNKNOWNNAME: OPEN
Args:

Stack Calls

Called from: win32ole.prg => TOLEAUTO:OPEN(0)
Called from: adobase.prg => TADOBASE:NEW(165)
Called from: testado.prg => TESTADO(17)

Cesar Cortes Cruz

SysCtrl Software

Mexico



' Sin +- FWH es mejor "
Posts: 883
Joined: Tue Oct 11, 2005 11:57 AM
ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Sun Apr 13, 2008 12:40 AM

Holas..

Estoy haciendo las modificaciones sugeridas por Carlos, y agregando mas opciones al metodo Info. para mejor informacion al desarrollar.

Segun la documentacion leida no se pueden usar ciertos tipos de bloqueos con ubicaciones y tipos de cursores. Lo ideal es que se pueda informar antes de seguir.

Carlos .. para los nombres de la columnas usa

oRs:Fields( nField ):Name

Puedes Recuperarlas asi.

For n= 1 to ( oRs:Fields:Count )
AADD( oRsNames, oRs:Fields( n-1 ):Name )
Next

Eso...

SysCtrl2
Reviso el Problema con ACCESS, el error me indica que el Recordset no tiene el metodo open asociado.... :?

Eso es muy raro... con que compilador trabajas, Harbour, xHarbour, version, tienes alguna clase propia de OLE o algo asi...?

Sigo en las pruebas y comento.

;-) Ji,ji,ji... buena la cosa... "all you need is code"

http://www.xdata.cl - Desarrollo Inteligente
----------
Asus TUF F15, 32GB Ram, 2 * 1 TB NVME M.2, GTX 1650
Posts: 1446
Joined: Mon Oct 10, 2005 02:38 PM
ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Sun Apr 13, 2008 06:29 PM
Adolfo wrote:Carlos .. para los nombres de la columnas usa

oRs:Fields( nField ):Name

Puedes Recuperarlas asi.

For n= 1 to ( oRs:Count )
AADD( oRsNames, oRs:Fields( n-1 ):Name )
Next


Gracias, no me di cuenta que ya estaba en :New().

Más sugerencias.

Después de capturar los nombres de las columnas en el método NEW(), antes del Return Self, añade:

FieldToData( Self )

y añade este código al final de TADOBase.PRG:
/* ******************************* */
//----------------------------------------------------------------------------//
// Es una adaptación del código de TDBF de Manuel Expósito para TADOBase.
// C.Gelabert 13/04/2008
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
// Este función crea un MESSAGE para cada columna.

static function FieldToData( oADODb )

AEval( oADODb:aFldNames, ;
{ | cName, i | GenDataField( oADODb, i ) } ) )

return( oADODb )

//----------------------------------------------------------------------------//
// Se define el MESSAGE de una columna para tomar y dar valores.

static function GenDataField( oADODb, nPos )

Local cNameMethod := oADODb:aFldNames[ nPos ]

//#ifdef __HARBOUR__
local nClassH := oADODb:ClassH

__clsAddMsg( nClassH, cNameMethod, ;
{ | oADODb | oADODb:_FieldGet( nPos ) }, HB_OO_MSG_INLINE )
__clsAddMsg( nClassH, "_" + cNameMethod, ;
{ | oADODb, Val | oADODb:_FieldPut( nPos, Val ) }, HB_OO_MSG_INLINE )
//#else

/* Aquí de momento nada de nada. */

//#endif

return( cNameMethod )

//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
/* ******************************* */

Estas funciones lo que hacen es crear un MESSAGE para cada columna con el nombre de ésta.
Esto permite que cuando se realiza:
cDomiciliocliente := oADODb:domicilio (por ejemplo)
se esté invocando al MESSAGE DOMICILIO que ahora existirá realmente, y por tanto la gestión de errores no se utilizará.
En consecuencia se optimiza la ejecución del código.

Espero que funcione, yo no lo he probado.
Si es así podrás eliminar "ERROR HANDLER OnError( )" y el METHOD OnError().

Saludos
Carlos G.

Un Saludo

Carlos G.



FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home

Posts: 71
Joined: Fri Jan 11, 2008 06:55 AM
ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Sun Apr 13, 2008 08:41 PM
FiveWiDi wrote:
//----------------------------------------------------------------------------//
// Se define el MESSAGE de una columna para tomar y dar valores.

static function GenDataField( oADODb, nPos )

Local cNameMethod := oADODb:aFldNames[ nPos ]

//#ifdef __HARBOUR__
local nClassH := oADODb:ClassH

__clsAddMsg( nClassH, cNameMethod, ;
{ | oADODb | oADODb:_FieldGet( nPos ) }, HB_OO_MSG_INLINE )
__clsAddMsg( nClassH, "_" + cNameMethod, ;
{ | oADODb, Val | oADODb:_FieldPut( nPos, Val ) }, HB_OO_MSG_INLINE )
//#else

/* Aquí de momento nada de nada. */

//#endif

return( cNameMethod )

//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
/* ******************************* */

Estas funciones lo que hacen es crear un MESSAGE para cada columna con el nombre de ésta.
Esto permite que cuando se realiza:
cDomiciliocliente := oADODb:domicilio (por ejemplo)
se esté invocando al MESSAGE DOMICILIO que ahora existirá realmente, y por tanto la gestión de errores no se utilizará.
En consecuencia se optimiza la ejecución del código.

Espero que funcione, yo no lo he probado.
Si es así podrás eliminar "ERROR HANDLER OnError( )" y el METHOD OnError().


Difiero un poco de esta optimizacion ...
Efectivamente si debe de ser mas rapida ...
Pero Solo sirve si vas a utilizar un solo Objeto de esa clase ya que si lo que deseas, es usar diversos objetos al mismo tiempo, los campos no deberian ser iguales a los de otro objeto, ya que el acceso seria al campo del ultimo objeto creado y no al que probablemente quieras tener acceso (ya sea cualquier objeto creado anteriormente)...

Esta es una mala practica de la Utilizacion de Clases ...

Saludos,

Andres Reyes
{{{ ---- xharbour + Borland C --- }}}
Posts: 1446
Joined: Mon Oct 10, 2005 02:38 PM
ADOBASE, Nueva clase para manipular RECORDSET de ADO
Posted: Sun Apr 13, 2008 09:29 PM
andresreyes_mzt wrote:
FiveWiDi wrote:
//----------------------------------------------------------------------------//
// Se define el MESSAGE de una columna para tomar y dar valores.

static function GenDataField( oADODb, nPos )

Local cNameMethod := oADODb:aFldNames[ nPos ]

//#ifdef __HARBOUR__
local nClassH := oADODb:ClassH

__clsAddMsg( nClassH, cNameMethod, ;
{ | oADODb | oADODb:_FieldGet( nPos ) }, HB_OO_MSG_INLINE )
__clsAddMsg( nClassH, "_" + cNameMethod, ;
{ | oADODb, Val | oADODb:_FieldPut( nPos, Val ) }, HB_OO_MSG_INLINE )
//#else

/* Aquí de momento nada de nada. */

//#endif

return( cNameMethod )

//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
/* ******************************* */

Estas funciones lo que hacen es crear un MESSAGE para cada columna con el nombre de ésta.
Esto permite que cuando se realiza:
cDomiciliocliente := oADODb:domicilio (por ejemplo)
se esté invocando al MESSAGE DOMICILIO que ahora existirá realmente, y por tanto la gestión de errores no se utilizará.
En consecuencia se optimiza la ejecución del código.

Espero que funcione, yo no lo he probado.
Si es así podrás eliminar "ERROR HANDLER OnError( )" y el METHOD OnError().


Difiero un poco de esta optimizacion ...
Efectivamente si debe de ser mas rapida ...
Pero Solo sirve si vas a utilizar un solo Objeto de esa clase ya que si lo que deseas, es usar diversos objetos al mismo tiempo, los campos no deberian ser iguales a los de otro objeto, ya que el acceso seria al campo del ultimo objeto creado y no al que probablemente quieras tener acceso (ya sea cualquier objeto creado anteriormente)...

Esta es una mala practica de la Utilizacion de Clases ...

Saludos,

Andres Reyes


Cuanta razón tienes.

Me dejé una cosa importantísima que hace TDBF, y es crear una 'nueva' clase para cada DBF diferente que va a utilizar. Supongo que teniendo en cuenta ese 'pequeño' detalle deja de ser una mala práctica.

Adolfo, por lo tanto, lo que he sugerido no vale sin esa asignación previa.

En fin, si puedo seguiré mirando como hacerlo.

Saludos y gracias por estar al quite; hubiese destrozado la clase.
Carlos G.

Un Saludo

Carlos G.



FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home