diff --git a/harbour/ChangeLog b/harbour/ChangeLog index b43a2e83a4..6eecf02f7d 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,13 @@ 2002-12-01 23:12 UTC+0100 Foo Bar */ +2004-10-06 05:40 UTC-0500 David Arturo Macias Corona + + 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 * harbour/contrib/mysql/tmysql.prg * harbour/contrib/mysql/tsqlbrw.prg diff --git a/harbour/contrib/mysql/difer.txt b/harbour/contrib/mysql/difer.txt new file mode 100644 index 0000000000..81b9e5e382 --- /dev/null +++ b/harbour/contrib/mysql/difer.txt @@ -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() + diff --git a/harbour/contrib/mysql/diffeng.txt b/harbour/contrib/mysql/diffeng.txt new file mode 100644 index 0000000000..94277278e7 --- /dev/null +++ b/harbour/contrib/mysql/diffeng.txt @@ -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() +