2004-10-06 05:40 UTC-0500 David Arturo Macias Corona <dmacias@mail.udg.mx>

+ harbour/contrib/mysql/difer.txt
    Describe modifications to programs of harbour\contrib\mysql, in Spanish
  + harbour/contrib/mysql/diffeng.txt
    Describe modifications to programs of harbour\contrib\mysql, in English
This commit is contained in:
David Arturo Macias Corona
2004-10-06 10:43:16 +00:00
parent 2f1ddb94d5
commit 32441bc82b
3 changed files with 506 additions and 0 deletions

View File

@@ -8,6 +8,13 @@
2002-12-01 23:12 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
2004-10-06 05:40 UTC-0500 David Arturo Macias Corona <dmacias@mail.udg.mx>
+ harbour/contrib/mysql/difer.txt
Describe modifications to programs of harbour\contrib\mysql, in Spanish
+ harbour/contrib/mysql/diffeng.txt
Describe modifications to programs of harbour\contrib\mysql, in English
2004-10-05 05:39 UTC-0500 David Arturo Macias Corona <dmacias@mail.udg.mx>
* harbour/contrib/mysql/tmysql.prg
* harbour/contrib/mysql/tsqlbrw.prg

View File

@@ -0,0 +1,251 @@
/*
* $Id $
*/
Febrero 2004
I.Q. David Arturo Macias Corona
Modificaciones a los programas de harbour\contrib\mysql
Programa TMySql.prg *****************************************
Clase TMySQLRow ---------------------------------------------
- DATA nueva TMySQLRow:aOriValue
Almacena los valores originales de aRow, en la creacion del objeto TMySQLRow
Tiene la misma funcion de TMySQLTable:aOldValue
- TMySQLRow:New()
Asignar una copia de TMySQLRow:aRow en TMySQLRow:aOriValue
- TMySQLRow:FielPut()
Comparar ::aRow[nNum]==NIL en vez de Empty(::aRow[nNum])
Empty() puede ser cadena nula, valor 0, fecha nula, valor .F.
- TMySQLRow:FieldPos()
Reduccion de codigo con misma funcionalidad para calcular nPos
- TMySQLRow:FieldLen()
Retornar 0 en vez de cadena nula como valor de excepcion
- TMySQLRow:FieldDec()
Retornar 0 en vez de cadena nula como valor de excepcion
Clase TMySQLQuery -------------------------------------------
- DATA nueva TMySQLQuery:lBof
Cambio en la aplicacion de TMySQLQuery:Bof()
- DATA nueva TMySQLQuery:lEof
Cambio en la aplicacion de TMySQLQuery:Eof()
- DATA nueva TMySQLQuery:lFieldAsData
Se aplica por compatibilidad
Usar nombres de los campos como elementos DATA de TMySQLQuery
Los nombres de campos pueden coincidir con nombres de DATA en TMySQLQuery o
TMySQLTable, lo cual puede sustituir valores y confundir las operaciones y
el funcionamiento de las clases
Usando TMySQLQuery:lFieldAsData := .F. se evita este conflicto
- DATA nueva TMySQLQuery:aRow
Se usa para almacenar los valores de los campos de la fila actual, en
sustitucion de los nombres de los campos como elementos DATA de TMySQLQuery
Todas las operaciones sobre campos se hacen sobre esta matriz de valores
- Metodo TMySQLQuery:Bof()
Cambio en la definicion para reproducir el comportamiento con Clipper
BOF() verdadero se aplica cuando se intenta ir antes del primer registro logico,
y no debe usarse para indicar que el puntero esta en el registro 1
La definicion anterior causa que procesos como:
WHILE ! oQuery:BOF()
...
oQuery:SKIP(-1)
ENDD
no muestren el registro 1
Con la nueva definicion se corrige este comportamiento
- Metodo TMySQLQuery:Eof()
Cambio en la definicion para reproducir el comportamiento con Clipper
EOF() verdadero se aplica cuando se intenta ir despues del ultimo registro logico,
y no debe usarse para indicar que el puntero esta en el ultimo registro
La definicion anterior causa que procesos como:
WHILE ! oQuery:EOF()
...
oQuery:SKIP()
ENDD
no muestren el ultimo registro
Con la nueva definicion se corrige este comportamiento
Con EOF() verdadero, el puntero de registro se ubica en LASTREC()+1
- TMySQLQuery:New()
Aplicacion de TMySQLQuery:lBof, TMySQLQuery:lEof, TMySQLQuery:lFieldAsData,
TMySQLQuery:aRow
- TMySQLQuery:Skip()
Aplicacion de TMySQLQuery:lBof, TMySQLQuery:lEof para determinar movimientos
antes del primer y despues del ultimo registros logicos
Solamente el movimiento con SKIP puede establecer BOF() verdadero
- TMySQLQuery:Skip()
Aplicar NIL para retorno. DBSKIP() retorna NIL
- TMySQLQuery:GetRow()
Aplicacion de TMySQLQuery:lBof, TMySQLQuery:lEof, TMySQLQuery:lFieldAsData,
TMySQLQuery:aRow
= Se usar TMySQLQuery:aRow en lugar de la variable local aRow
= La fila por omision se aplica a TMySQLQuery:nCurRow, en lugar de mover la
posicion del puntero
= Se determinan TMySQLQuery:lBof, TMySQLQuery:lEof
TMySQLQuery:bof(): el puntero queda ubicado en fila 1
TMySQLQuery:eof(): el puntero queda ubicado en TMySQLQuery:lastrec()+1
= En TMySQLQuery:lastrec()+1 se usa el registro fantasma con valores nulos en cada
tipo de campo
- TMySQLQuery:GetRow()
= Correccion de error por tipo de dato en tipos logico y numericos
= Supresion de mensajes con Alert() y MsgInfo() que causarian detencion en procesos
desatendidos
- TMySQLQuery:FieldPos()
Reduccion de codigo con misma funcionalidad para calcular nPos
- TMySQLQuery:FieldGet()
= Se usa TMySQLQuery:aRow[nNum] en lugar de la variable DATA correspondiente al
nombre del campo
- TMySQLQuery:FieldLen()
Retornar 0 en vez de cadena nula como valor de excepcion
- TMySQLQuery:FieldDec()
Retornar 0 en vez de cadena nula como valor de excepcion
Clase TMySQLTable -------------------------------------------
- Metodo TMySQLTable:Update()
= Se agregaron los parametros:
+ lOldRecord: Usar los valores originales del registro para localizarlo
+ lRefresh: renovar la consulta al servidor MySQL para actualizar la informacion
seleccionada para el programa Cliente
- Metodo TMySQLTable:Delete()
= Se agregaron los parametros:
+ lOldRecord: Usar los valores originales del registro para localizarlo
+ lRefresh: renovar la consulta al servidor MySQL para actualizar la informacion
seleccionada para el programa Cliente
- Metodo TMySQLTable:Append()
= Se agregaron los parametros:
+ lRefresh: renovar la consulta al servidor MySQL para actualizar la informacion
seleccionada para el programa Cliente
- Metodo TMySQLTable:GetBlankRow()
= Se agregaron los parametros:
+ lSetValues: aplicar valores como si correspondieran a la fila actual
- Nuevo Metodo TMySQLTable:SetBlankRow()
Aplica TMySQLTable:GetBlankRow( .T. ), con valor de lSetValues verdadero
- TMySQLTable:Skip()
Aplicar NIL para retorno. DBSKIP() retorna NIL
- TMySQLTable:Update(oRow, lOldRecord, lRefresh)
= Aplicacion de TMySQLRow:aOriValue, TMySQLTable:aRow
= Aplicacion de los parametros:
+ lOldRecord, omision .F.
En caso de aplicar lOldRecord:
* Usando fila actual: Utiliza los valores TMySQLQuery:aOldValue
* Usando fila proporcionada: Utiliza los valores TMySQLRow:aOriValue
La localizacion se basa en la coincidencia de valores de TODOS los campos,
usando los valores originales de la fila
ADVERTENCIA: Si hay mas de una fila que coincida en TODOS los campos, entonces
todas estas filas con valores comunes seran cambiadas
Se aplico esta aproximacion para auxiliar en la localizacion de filas cuando
no existen indices, o la llave primaria es insuficiente para determinar la
unicidad del registro. Sin embargo, no se puede garantizar la correspondencia
del registro si existen varios iguales
Es una alternativa al uso de TMySQLRow/TMySQLTable:MakePrimaryKeyWhere(), ya que
esta ultima esta basada en campos que forman parte de una llave primaria
+ lRefresh, omision .T.
Renueva la consulta al servidor MySQL para actualizar la informacion seleccionada
para el programa Cliente. Es muy conveniente en caso de modificacion de informacion
= Se mantiene el mismo apuntador de registro
= Para una fila proporcionada, se actualiza TMySQLRow:aOriValue con los valores
actuales de TMySQLRow:aRow
- TMySQLTable:Delete(oRow, lOldRecord, lRefresh)
= Aplicacion de TMySQLRow:aOriValue, TMySQLTable:aRow
= Aplicacion de los parametros:
+ lOldRecord, omision .F.
En caso de aplicar lOldRecord:
* Usando fila actual: Utiliza los valores TMySQLQuery:aOldValue
* Usando fila proporcionada: Utiliza los valores TMySQLRow:aOriValue
La localizacion se basa en la coincidencia de valores de TODOS los campos,
usando los valores originales de la fila
ADVERTENCIA: Si hay mas de una fila que coincida en TODOS los campos, entonces
todas estas filas con valores comunes seran cambiadas
Se aplico esta aproximacion para auxiliar en la localizacion de filas cuando
no existen indices, o la llave primaria es insuficiente para determinar la
unicidad del registro. Sin embargo, no se puede garantizar la correspondencia
del registro si existen varios iguales
Es una alternativa al uso de TMySQLRow/TMySQLTable:MakePrimaryKeyWhere(), ya que
esta ultima esta basada en campos que forman parte de una llave primaria
+ lRefresh, omision .T.
Renueva la consulta al servidor MySQL para actualizar la informacion seleccionada
para el programa Cliente. Es muy conveniente en caso de modificacion de informacion
= Se mantiene el mismo apuntador de registro
= Para una fila proporcionada, se actualiza TMySQLRow:aOriValue con los valores
actuales de TMySQLRow:aRow
- Metodo TMySQLTable:Append(oRow, lRefresh)
= Aplicacion de TMySQLRow:aOriValue, TMySQLTable:aRow
= Aplicacion de los parametros:
+ lRefresh, omision .T.
Renueva la consulta al servidor MySQL para actualizar la informacion seleccionada
para el programa Cliente. Es muy conveniente en caso de modificacion de informacion
= Se ubica el apuntador en TMySQLTable:lastrec()+1, antes de renovar la consulta
Observacion: a pesar de reiteradas pruebas, no se pudo determinar en que manera
establece el servidor MySQL la posicion de la fila insertada. Sin usar indices, en
ocasiones la insertaba adjunta al puntero actual, en tanto que en otras ocasiones
la insertaba en posiciones ubicadas a 1200 o 1300 filas con respecto al puntero
actual, o al final de la tabla (alrededor de 2880 filas)
= Para una fila proporcionada, se actualiza TMySQLRow:aOriValue con los valores
actuales de TMySQLRow:aRow
Ademas, se inicializan TMySQLRow:aDirty y TMySQLRow:aOldValue
- TMySQLTable:GetBlankRow(lSetValues)
= Aplicacion de los parametros:
+ lSetValues, omision .F.
Este metodo proporciona un objeto TMySQLRow con valores por omision para el tipo de
dato en cada campo. Como la fila generada NO es la fila actual del objeto TMySQLTable,
entonces no deben modificarse los valores de TMySQLTable:aRow y TMySQLTable:aOldValue
En caso de que se desee hacer esta modificacion, como si la fila vacia fuera la fila
actual de la tabla, entonces podra aplicarse con este parametro con valor verdadero
o con el nuevo metodo TMySQLTable:SetBlankRow()
- TMySQLTable:FielPut()
= Comparar ::aRow[nNum]==NIL en vez de Empty(::aRow[nNum])
Empty() puede ser cadena nula, valor 0, fecha nula, .F.
= Se aplica TMySQLTable:aRow[nNum] para contener el valor del campo
= De acuerdo a TMySQLTable:lFieldAsData, se actualiza el elemento DATA de TMySQLTable
correspondiente al nombre del campo
Programa TSqlBrw.prg ************************************
- Skipper()
Modificacion del control de movimiento para aplicar las nuevas definiciones para
TMySQLQuery:Bof() y TMySQLQuery:Eof()

View File

@@ -0,0 +1,248 @@
/*
* $Id $
*/
February 2004
I.Q. David Arturo Macias Corona
Modifications to programs of harbour\contrib\mysql
TMySql.prg Program *****************************************
Class TMySQLRow ---------------------------------------------
- DATA new TMySQLRow:aOriValue
Store originals values of aRow, during creation of TMySQLRow object
Have same function of TMySQLTable:aOldValue
- TMySQLRow:New()
Assign an copy of TMySQLRow:aRow in TMySQLRow:aOriValue
- TMySQLRow:FielPut()
Compare ::aRow[nNum]==NIL in place of Empty(::aRow[nNum])
Empty() can be an null string, value 0, null date, value .F.
- TMySQLRow:FieldPos()
Reduction of code with same functionality for calculate nPos
- TMySQLRow:FieldLen()
Return 0 in place of null string as exception value
- TMySQLRow:FieldDec()
Return 0 in place of null string as exception value
Class TMySQLQuery -------------------------------------------
- DATA new TMySQLQuery:lBof
Change in application of TMySQLQuery:Bof()
- DATA new TMySQLQuery:lEof
Change in application of TMySQLQuery:Eof()
- DATA new TMySQLQuery:lFieldAsData
Is applied for compatibility
Use field names as DATA elements of TMySQLQuery
Field names can match with DATA names in TMySQLQuery or
TMySQLTable, which can substitute values and confuse operations and behaviour
of classes
Using TMySQLQuery:lFieldAsData := .F. can avoid this trouble
- DATA new TMySQLQuery:aRow
Used to store fields values of current row, in
place of fields names as DATA elements of TMySQLQuery
All operations on fields are made using this array of values
- Method TMySQLQuery:Bof()
Change in definition to reproduce Clipper behaviour
BOF() true is applied when is tryed an movement before of first logical record,
and must not be used to indicate record pointer is placed on record 1
Previous definition cause processes like this:
WHILE ! oQuery:BOF()
...
oQuery:SKIP(-1)
ENDD
do not show record 1
With new definition this behaviour are corrected
- Method TMySQLQuery:Eof()
Change in definition to reproduce Clipper behaviour
EOF() true is applied when is tryed an movement beyond of last logical record,
and must not be used to indicate record pointer is placed on last record
Previous definition cause processes like this:
WHILE ! oQuery:EOF()
...
oQuery:SKIP()
ENDD
do not show last record
With new definition this behaviour are corrected
With EOF() true, record pointer is placed in LASTREC()+1
- TMySQLQuery:New()
Application of TMySQLQuery:lBof, TMySQLQuery:lEof, TMySQLQuery:lFieldAsData,
TMySQLQuery:aRow
- TMySQLQuery:Skip()
Application of TMySQLQuery:lBof, TMySQLQuery:lEof to determinate movements
before of first and beyond of last logical records
Only SKIP movement can set BOF() true
- TMySQLQuery:Skip()
Apply NIL for return. DBSKIP() return NIL
- TMySQLQuery:GetRow()
Application of TMySQLQuery:lBof, TMySQLQuery:lEof, TMySQLQuery:lFieldAsData,
TMySQLQuery:aRow
= TMySQLQuery:aRow is used in place of local variable aRow
= Default row is applied to TMySQLQuery:nCurRow, in place to move record pointer
position
= TMySQLQuery:lBof, TMySQLQuery:lEof are determinated
TMySQLQuery:bof(): pointer is placed in row 1
TMySQLQuery:eof(): pointer is placed in TMySQLQuery:lastrec()+1
= In TMySQLQuery:lastrec()+1 phantom record is used with null values in each
field type
- TMySQLQuery:GetRow()
= Correction of error caused for data type in logical and numerics types
= Supresion of messages with Alert() and MsgInfo() which cause halting in batch processes
- TMySQLQuery:FieldPos()
Reduction of code with same functionality for calculate nPos
- TMySQLQuery:FieldGet()
= TMySQLQuery:aRow[nNum] is used in place of DATA variable corresponding to
field name
- TMySQLQuery:FieldLen()
Return 0 in place of null string as exception value
- TMySQLQuery:FieldDec()
Return 0 in place of null string as exception value
Class TMySQLTable -------------------------------------------
- Method TMySQLTable:Update()
= Parameters added:
+ lOldRecord: Use original values of record for locate it
+ lRefresh: refresh query to MySQL server to update information
selected for Client program
- Method TMySQLTable:Delete()
= Parameters added:
+ lOldRecord: Use original values of record for locate it
+ lRefresh: refresh query to MySQL server to update information
selected for Client program
- Method TMySQLTable:Append()
= Parameters added:
+ lRefresh: refresh query to MySQL server to update information
selected for Client program
- Method TMySQLTable:GetBlankRow()
= Parameters added:
+ lSetValues: apply values as if they belong to current row
- New Method TMySQLTable:SetBlankRow()
Apply TMySQLTable:GetBlankRow( .T. ), with true value for lSetValues
- TMySQLTable:Skip()
Apply NIL for return. DBSKIP() return NIL
- TMySQLTable:Update(oRow, lOldRecord, lRefresh)
= Application of TMySQLRow:aOriValue, TMySQLTable:aRow
= Application of parameters:
+ lOldRecord, default .F.
In case of lOldRecord application:
* Using current row: Use values of TMySQLQuery:aOldValue
* Using given row: Use values of TMySQLRow:aOriValue
Locating is based in matching of values of ALL fields,
using original values of row
WARNING: If there are more than one row matching in ALL fields, then
all this rows with common values will be changed
This approach is applied to help in row locating when there are not indexes,
or primary key are not enought to determinate record unicity.
But, can not be guaranted record correspondence if there are many equals
This is an alternative to use of TMySQLRow/TMySQLTable:MakePrimaryKeyWhere(), because
this last is based in fields belonging to an primary key
+ lRefresh, default .T.
Refresh query to MySQL server to update information selected for Client program
Is very convenient in case of information changes
= Same record pointer is keep
= For an given row, TMySQLRow:aOriValue is updated with current values of
TMySQLRow:aRow
- TMySQLTable:Delete(oRow, lOldRecord, lRefresh)
= Application of TMySQLRow:aOriValue, TMySQLTable:aRow
= Application of parameters:
+ lOldRecord, default .F.
In case of lOldRecord application:
* Using current row: Use values of TMySQLQuery:aOldValue
* Using given row: Use values of TMySQLRow:aOriValue
Locating is based in matching of values of ALL fields,
using original values of row
WARNING: If there are more than one row matching in ALL fields, then
all this rows with common values will be changed
This approach is applied to help in row locating when there are not indexes,
or primary key are not enought to determinate record unicity.
But, can not be guaranted record correspondence if there are many equals
This is an alternative to use of TMySQLRow/TMySQLTable:MakePrimaryKeyWhere(), because
this last is based in fields belonging to an primary key
+ lRefresh, default .T.
Refresh query to MySQL server to update information selected for Client program
Is very convenient in case of information changes
= Same record pointer is keep
= For an given row, TMySQLRow:aOriValue is updated with current values of
TMySQLRow:aRow
- Metodo TMySQLTable:Append(oRow, lRefresh)
= Application of TMySQLRow:aOriValue, TMySQLTable:aRow
= Application of parameters:
+ lRefresh, default .T.
Refresh query to MySQL server to update information selected for Client program
Is very convenient in case of information changes
= Record pointer is placed in TMySQLTable:lastrec()+1, before query refresh
Observation: even with many tests, I was unable to determinate in which way
set MySQL server position of inserted row. Without indexes, in times
were inserted behind to current pointer, while in other times
were inserted in positions located at 1200 or 1300 rows relative to current pointer,
or at end of table (around 2880 rows)
= For an given row, TMySQLRow:aOriValue is updated with current values of
TMySQLRow:aRow
Too, TMySQLRow:aDirty and TMySQLRow:aOldValue are reseted
- TMySQLTable:GetBlankRow(lSetValues)
= Application of parameters:
+ lSetValues, default .F.
This method give an TMySQLRow object with default values for data type in each field
As created row IS NOT current row of TMySQLTable object,
then must not be modified values of TMySQLTable:aRow and TMySQLTable:aOldValue
In case of need to make this modification, as if empty file is wanted current row of
table, then this parameter can be applied with true value
or with new method TMySQLTable:SetBlankRow()
- TMySQLTable:FielPut()
= Comparar ::aRow[nNum]==NIL en vez de Empty(::aRow[nNum])
Compare ::aRow[nNum]==NIL in place of Empty(::aRow[nNum])
Empty() can be an null string, value 0, empty date, value .F.
= TMySQLTable:aRow[nNum] is applied to store field value
= Based in TMySQLTable:lFieldAsData, is updated DATA element of TMySQLTable
corresponding to field name
Program TSqlBrw.prg ************************************
- Skipper()
Modification of movement control in order to apply new definitions of
TMySQLQuery:Bof() and TMySQLQuery:Eof()