ADOBASE, Nueva clase para manipular RECORDSET de ADO

ADOBASE, Nueva clase para manipular RECORDSET de ADO

Postby Adolfo » Thu Apr 10, 2008 4: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, 1 TB NVME M.2, 1 TB SSD, GTX 1650
User avatar
Adolfo
 
Posts: 846
Joined: Tue Oct 11, 2005 11:57 am
Location: Chile

Postby sysctrl2 » 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 "
User avatar
sysctrl2
 
Posts: 951
Joined: Mon Feb 05, 2007 7:15 pm

Postby Patricio Avalos Aguirre » 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
User avatar
Patricio Avalos Aguirre
 
Posts: 1059
Joined: Fri Oct 07, 2005 1:56 pm
Location: La Serena, Chile

Postby Adolfo » 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, 1 TB NVME M.2, 1 TB SSD, GTX 1650
User avatar
Adolfo
 
Posts: 846
Joined: Tue Oct 11, 2005 11:57 am
Location: Chile

Re: ADOBASE, Nueva clase para manipular RECORDSET de ADO

Postby FiveWiDi » Fri Apr 11, 2008 8: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
...

::nFields:=oRs:Fields: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.
FiveWiDi
 
Posts: 1060
Joined: Mon Oct 10, 2005 2:38 pm

Re: ADOBASE, Nueva clase para manipular RECORDSET de ADO

Postby FiveWiDi » Fri Apr 11, 2008 8:30 am

Hola,

más cosas:

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

::Close()
Self := nil

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

Saludos
Carlos G.
FiveWiDi
 
Posts: 1060
Joined: Mon Oct 10, 2005 2:38 pm

Postby Adolfo » 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, 1 TB NVME M.2, 1 TB SSD, GTX 1650
User avatar
Adolfo
 
Posts: 846
Joined: Tue Oct 11, 2005 11:57 am
Location: Chile

Postby Adolfo » Fri Apr 11, 2008 1: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, 1 TB NVME M.2, 1 TB SSD, GTX 1650
User avatar
Adolfo
 
Posts: 846
Joined: Tue Oct 11, 2005 11:57 am
Location: Chile

Nombre de columnas en un RecordSet en ADO.

Postby FiveWiDi » Fri Apr 11, 2008 6:45 pm

Hola Adolfo,

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

Saludos
Carlos G.
FiveWiDi
 
Posts: 1060
Joined: Mon Oct 10, 2005 2:38 pm

Más sugerencias para tu clase.

Postby FiveWiDi » Fri Apr 11, 2008 6: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.
FiveWiDi
 
Posts: 1060
Joined: Mon Oct 10, 2005 2:38 pm

Postby sysctrl2 » Fri Apr 11, 2008 7: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 "
User avatar
sysctrl2
 
Posts: 951
Joined: Mon Feb 05, 2007 7:15 pm

Postby Adolfo » 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, 1 TB NVME M.2, 1 TB SSD, GTX 1650
User avatar
Adolfo
 
Posts: 846
Joined: Tue Oct 11, 2005 11:57 am
Location: Chile

Postby FiveWiDi » Sun Apr 13, 2008 6:29 pm

Adolfo wrote: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


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.
FiveWiDi
 
Posts: 1060
Joined: Mon Oct 10, 2005 2:38 pm

Postby andresreyes_mzt » Sun Apr 13, 2008 8: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 --- }}}
User avatar
andresreyes_mzt
 
Posts: 71
Joined: Fri Jan 11, 2008 6:55 am
Location: Mexico

Postby FiveWiDi » Sun Apr 13, 2008 9: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.
FiveWiDi
 
Posts: 1060
Joined: Mon Oct 10, 2005 2:38 pm

Next

Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 85 guests

cron