In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.
Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.
Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.
Sincronizar tablas Maridb
Sincronizar tablas Maridb
Hola a todos,
Alguien ha hecho algo de forma manual que permita sincronizar 2 tablas una local y otra en la nube de
Mariadb ?.
La idea es mantener actualizada una información en la nube de lo que ocurre con la tabla local, no se puede usar
la opción de configurar los servidores para que se hagan automáticas por lo que no disponemos de configurar el servidor de
Mariadb en la nube, por lo que deberá hacerse de forma manual .
Si alguno ha desarrollado algo me vendría bien un poco de ayuda.
Saludos a todos,
Alguien ha hecho algo de forma manual que permita sincronizar 2 tablas una local y otra en la nube de
Mariadb ?.
La idea es mantener actualizada una información en la nube de lo que ocurre con la tabla local, no se puede usar
la opción de configurar los servidores para que se hagan automáticas por lo que no disponemos de configurar el servidor de
Mariadb en la nube, por lo que deberá hacerse de forma manual .
Si alguno ha desarrollado algo me vendría bien un poco de ayuda.
Saludos a todos,
Jose David Angulo Urzola
Auditoria y Sistemas Ltda.
Cartagena-Colombia
Auditoria y Sistemas Ltda.
Cartagena-Colombia
Re: Sincronizar tablas Maridb
Buenas, nosotros lo hemos desarrollado a través de un Webdatasouce y mantenemos sincronizado el escritorio con la Web. Espero que este código te sirva de orientación, sino ponte en contacto conmigo.
//En caso de trabajar con un WebDataSource externo y existir en él una tabla con el mismo nombre
//replica los registros indicados en la Web por su Id
Function SynchronizeWebExt(cOrigen, cDestino, xId, lDelete, lTruncateBefore)
Local lControl:=.F., aCampos:={}, aDatos:={}, aCamposOrigen:={}, nCampo:=0, cValores:="", aValores :={}
Local lSuccess:=.T.
Default cDestino to cOrigen
Default lDelete To .F. //Si el procedimiento es de borrado en lugar de ser inserción/edición
Default lTruncateBefore To .F. //Antes de realizar la operaci´çon se vacia la totalidad de la tabla
cOrigen := SubStr(cOrigen,At(".",cOrigen)+1)
cDestino := SubStr(cDestino ,At(".",cDestino )+1)
//Si no se ha configurado el WebDataSource Externo esto no vale para nada
If Appdata:oWebDataSourceExt=Nil
Return .F.
Endif
//El xId tiene que venir con algo si no no hay que hacer nada
if Vacio(xId)
LogDebug("No se puede sincronizar un contenido de xId Vacio para "+cOrigen+" >>> "+cDestino+" en la BBDD "+Appdata:cWebDatabaseExt)
Return .F.
Endif
//Tiene que existir el origen en la BBDD de trabajo o en la de control
if Vacio(Appdata:oSqlSource:GetTables(cOrigen))
lControl:=.T.
if Vacio(Appdata:oControlDb:GetTables(cOrigen))
LogDebug("No se puede encontrar el archivo de origen "+cOrigen+" para la sincronización Web")
Return .F.
Endif
Endif
//Abrir la BBDD de la Web externa si no lo está
If !Appdata:oWebDataSourceExt:lConnected()
Appdata:oWebDataSourceExt:lConnected:=.T.
Endif
//Tiene que existir el destino en la BBDD de la Web externa
Appdata:oWebDataSourceExt:lConnected:=.T.
If Vacio(Appdata:oWebDataSourceExt:GetTables(cDestino))
Appdata:oWebDataSourceExt:lConnected:=.F.
LogDebug("No se puede encontrar el archivo de destino "+cDestino+" para la sincronización Web")
Return .F.
Endif
//Lista de campos del origen y del destino para ver que hay que sincronizar
aCamposOrigen:=IF(!lControl,Appdata:oSqlSource:QueryArray("describe "+cOrigen),Appdata:oControlDb:QueryArray("describe "+cOrigen))
aCampos:=Appdata:oWebDataSourceExt:QueryArray("describe "+cDestino)
For nCampo:=1 to Len(aCampos)
If AScan(aCamposOrigen,{|x| Lower(x[1])==Lower(aCampos[nCampo,1]) })=0
HB_ADel(aCampos,nCampo,.T.)
nCampo--
Endif
Next
//El Id siempre tiene que ser un array y monodimensional
If ValType(xId)<>"A"
xId:={xId}
Endif
//Añadir o actualizar registros en la web
Appdata:oWebDataSourceExt:BeginTrans()
If !lDelete
//Si se ha pedido lTruncateBefore vaciar la tabla antes de empezar
If lTruncateBefore
Appdata:oWebDataSourceExt:Execute("truncate "+cDestino)
Endif
If !lControl
aDatos:=Appdata:oSqlSource:QueryArray("select "+ArrayToChar(aCampos,",",1)+" from "+cOrigen+" where id in("+ArrayToChar(xId,",")+")" )
Else
aDatos:=Appdata:oControlDb:QueryArray("select "+ArrayToChar(aCampos,",",1)+" from "+cOrigen+" where id in("+ArrayToChar(xId,",")+")" )
Endif
Appdata:oWebDataSourceExt:BeginTrans()
For Each aValores in aDatos
cValores+=" ("+Concat(aValores,,.T.)+"), "
If Len(cValores)>60000
lSuccess := IF(!Appdata:oWebDataSourceExt:Execute("replace into "+cDestino+" ("+ArrayToChar(aCampos,",",1)+") Values "+HB_StrShrink(cValores,2)) .Or. !lSuccess, .F.,.T.)
cValores:=""
If Mod(aValores:__enumIndex,8)=0 //Para prevenir el tamaño máximo de la instrucción Http que se envia al servidor Apache via WebDataSource
Appdata:oWebDataSourceExt:CommitTrans()
Appdata:oWebDataSourceExt:BeginTrans()
Endif
Endif
If !lSuccess
Exit
Endif
Next
lSuccess := IF(!Appdata:oWebDataSourceExt:Execute("replace into "+cDestino+" ("+ArrayToChar(aCampos,",",1)+") Values "+HB_StrShrink(cValores,2)) .Or. !lSuccess, .F.,.T.)
Else //Eliminar registros en la web
lSuccess := Appdata:oWebDataSourceExt:Execute("delete from "+cDestino+" where id in("+ArrayToChar(xId,",")+")")
Endif
If !lSuccess
Appdata:oWebDataSourceExt:RollBackTrans()
Else
Appdata:oWebDataSourceExt:CommitTrans()
Endif
//Cerrar la BBDD de la Web externa
Appdata:oWebDataSourceExt:lConnected:=.F.
Return lSuccess
//------------------------------------------------------------------------------
//En caso de trabajar con un WebDataSource externo y existir en él una tabla con el mismo nombre
//replica los registros indicados en la Web por su Id
Function SynchronizeWebExt(cOrigen, cDestino, xId, lDelete, lTruncateBefore)
Local lControl:=.F., aCampos:={}, aDatos:={}, aCamposOrigen:={}, nCampo:=0, cValores:="", aValores :={}
Local lSuccess:=.T.
Default cDestino to cOrigen
Default lDelete To .F. //Si el procedimiento es de borrado en lugar de ser inserción/edición
Default lTruncateBefore To .F. //Antes de realizar la operaci´çon se vacia la totalidad de la tabla
cOrigen := SubStr(cOrigen,At(".",cOrigen)+1)
cDestino := SubStr(cDestino ,At(".",cDestino )+1)
//Si no se ha configurado el WebDataSource Externo esto no vale para nada
If Appdata:oWebDataSourceExt=Nil
Return .F.
Endif
//El xId tiene que venir con algo si no no hay que hacer nada
if Vacio(xId)
LogDebug("No se puede sincronizar un contenido de xId Vacio para "+cOrigen+" >>> "+cDestino+" en la BBDD "+Appdata:cWebDatabaseExt)
Return .F.
Endif
//Tiene que existir el origen en la BBDD de trabajo o en la de control
if Vacio(Appdata:oSqlSource:GetTables(cOrigen))
lControl:=.T.
if Vacio(Appdata:oControlDb:GetTables(cOrigen))
LogDebug("No se puede encontrar el archivo de origen "+cOrigen+" para la sincronización Web")
Return .F.
Endif
Endif
//Abrir la BBDD de la Web externa si no lo está
If !Appdata:oWebDataSourceExt:lConnected()
Appdata:oWebDataSourceExt:lConnected:=.T.
Endif
//Tiene que existir el destino en la BBDD de la Web externa
Appdata:oWebDataSourceExt:lConnected:=.T.
If Vacio(Appdata:oWebDataSourceExt:GetTables(cDestino))
Appdata:oWebDataSourceExt:lConnected:=.F.
LogDebug("No se puede encontrar el archivo de destino "+cDestino+" para la sincronización Web")
Return .F.
Endif
//Lista de campos del origen y del destino para ver que hay que sincronizar
aCamposOrigen:=IF(!lControl,Appdata:oSqlSource:QueryArray("describe "+cOrigen),Appdata:oControlDb:QueryArray("describe "+cOrigen))
aCampos:=Appdata:oWebDataSourceExt:QueryArray("describe "+cDestino)
For nCampo:=1 to Len(aCampos)
If AScan(aCamposOrigen,{|x| Lower(x[1])==Lower(aCampos[nCampo,1]) })=0
HB_ADel(aCampos,nCampo,.T.)
nCampo--
Endif
Next
//El Id siempre tiene que ser un array y monodimensional
If ValType(xId)<>"A"
xId:={xId}
Endif
//Añadir o actualizar registros en la web
Appdata:oWebDataSourceExt:BeginTrans()
If !lDelete
//Si se ha pedido lTruncateBefore vaciar la tabla antes de empezar
If lTruncateBefore
Appdata:oWebDataSourceExt:Execute("truncate "+cDestino)
Endif
If !lControl
aDatos:=Appdata:oSqlSource:QueryArray("select "+ArrayToChar(aCampos,",",1)+" from "+cOrigen+" where id in("+ArrayToChar(xId,",")+")" )
Else
aDatos:=Appdata:oControlDb:QueryArray("select "+ArrayToChar(aCampos,",",1)+" from "+cOrigen+" where id in("+ArrayToChar(xId,",")+")" )
Endif
Appdata:oWebDataSourceExt:BeginTrans()
For Each aValores in aDatos
cValores+=" ("+Concat(aValores,,.T.)+"), "
If Len(cValores)>60000
lSuccess := IF(!Appdata:oWebDataSourceExt:Execute("replace into "+cDestino+" ("+ArrayToChar(aCampos,",",1)+") Values "+HB_StrShrink(cValores,2)) .Or. !lSuccess, .F.,.T.)
cValores:=""
If Mod(aValores:__enumIndex,8)=0 //Para prevenir el tamaño máximo de la instrucción Http que se envia al servidor Apache via WebDataSource
Appdata:oWebDataSourceExt:CommitTrans()
Appdata:oWebDataSourceExt:BeginTrans()
Endif
Endif
If !lSuccess
Exit
Endif
Next
lSuccess := IF(!Appdata:oWebDataSourceExt:Execute("replace into "+cDestino+" ("+ArrayToChar(aCampos,",",1)+") Values "+HB_StrShrink(cValores,2)) .Or. !lSuccess, .F.,.T.)
Else //Eliminar registros en la web
lSuccess := Appdata:oWebDataSourceExt:Execute("delete from "+cDestino+" where id in("+ArrayToChar(xId,",")+")")
Endif
If !lSuccess
Appdata:oWebDataSourceExt:RollBackTrans()
Else
Appdata:oWebDataSourceExt:CommitTrans()
Endif
//Cerrar la BBDD de la Web externa
Appdata:oWebDataSourceExt:lConnected:=.F.
Return lSuccess
//------------------------------------------------------------------------------
BiSoft Desarrollo de software profesional
http://www.bisoft.es
http://www.bisoft.es
- ignacio
- Site Admin
- Mensajes: 9271
- Registrado: Lun Abr 06, 2015 8:00 pm
- Ubicación: Madrid, Spain
- Contactar:
Re: Sincronizar tablas Maridb
Buenas noches,
Simplemente utilice los evento del dataset local para actualizar todo en remoto
Saludos
Simplemente utilice los evento del dataset local para actualizar todo en remoto
Saludos
Re: Sincronizar tablas Maridb
Bingen,
muchas gracias por tu aporte.
Podrias publicar la funcioón Concat() que estas usando.
muchas gracias por tu aporte.
Podrias publicar la funcioón Concat() que estas usando.
bingen escribió: ↑Sab Ene 08, 2022 7:38 am Buenas, nosotros lo hemos desarrollado a través de un Webdatasouce y mantenemos sincronizado el escritorio con la Web. Espero que este código te sirva de orientación, sino ponte en contacto conmigo.
//En caso de trabajar con un WebDataSource externo y existir en él una tabla con el mismo nombre
//replica los registros indicados en la Web por su Id
Function SynchronizeWebExt(cOrigen, cDestino, xId, lDelete, lTruncateBefore)
Local lControl:=.F., aCampos:={}, aDatos:={}, aCamposOrigen:={}, nCampo:=0, cValores:="", aValores :={}
Local lSuccess:=.T.
Default cDestino to cOrigen
Default lDelete To .F. //Si el procedimiento es de borrado en lugar de ser inserción/edición
Default lTruncateBefore To .F. //Antes de realizar la operaci´çon se vacia la totalidad de la tabla
cOrigen := SubStr(cOrigen,At(".",cOrigen)+1)
cDestino := SubStr(cDestino ,At(".",cDestino )+1)
//Si no se ha configurado el WebDataSource Externo esto no vale para nada
If Appdata:oWebDataSourceExt=Nil
Return .F.
Endif
//El xId tiene que venir con algo si no no hay que hacer nada
if Vacio(xId)
LogDebug("No se puede sincronizar un contenido de xId Vacio para "+cOrigen+" >>> "+cDestino+" en la BBDD "+Appdata:cWebDatabaseExt)
Return .F.
Endif
//Tiene que existir el origen en la BBDD de trabajo o en la de control
if Vacio(Appdata:oSqlSource:GetTables(cOrigen))
lControl:=.T.
if Vacio(Appdata:oControlDb:GetTables(cOrigen))
LogDebug("No se puede encontrar el archivo de origen "+cOrigen+" para la sincronización Web")
Return .F.
Endif
Endif
//Abrir la BBDD de la Web externa si no lo está
If !Appdata:oWebDataSourceExt:lConnected()
Appdata:oWebDataSourceExt:lConnected:=.T.
Endif
//Tiene que existir el destino en la BBDD de la Web externa
Appdata:oWebDataSourceExt:lConnected:=.T.
If Vacio(Appdata:oWebDataSourceExt:GetTables(cDestino))
Appdata:oWebDataSourceExt:lConnected:=.F.
LogDebug("No se puede encontrar el archivo de destino "+cDestino+" para la sincronización Web")
Return .F.
Endif
//Lista de campos del origen y del destino para ver que hay que sincronizar
aCamposOrigen:=IF(!lControl,Appdata:oSqlSource:QueryArray("describe "+cOrigen),Appdata:oControlDb:QueryArray("describe "+cOrigen))
aCampos:=Appdata:oWebDataSourceExt:QueryArray("describe "+cDestino)
For nCampo:=1 to Len(aCampos)
If AScan(aCamposOrigen,{|x| Lower(x[1])==Lower(aCampos[nCampo,1]) })=0
HB_ADel(aCampos,nCampo,.T.)
nCampo--
Endif
Next
//El Id siempre tiene que ser un array y monodimensional
If ValType(xId)<>"A"
xId:={xId}
Endif
//Añadir o actualizar registros en la web
Appdata:oWebDataSourceExt:BeginTrans()
If !lDelete
//Si se ha pedido lTruncateBefore vaciar la tabla antes de empezar
If lTruncateBefore
Appdata:oWebDataSourceExt:Execute("truncate "+cDestino)
Endif
If !lControl
aDatos:=Appdata:oSqlSource:QueryArray("select "+ArrayToChar(aCampos,",",1)+" from "+cOrigen+" where id in("+ArrayToChar(xId,",")+")" )
Else
aDatos:=Appdata:oControlDb:QueryArray("select "+ArrayToChar(aCampos,",",1)+" from "+cOrigen+" where id in("+ArrayToChar(xId,",")+")" )
Endif
Appdata:oWebDataSourceExt:BeginTrans()
For Each aValores in aDatos
cValores+=" ("+Concat(aValores,,.T.)+"), "
If Len(cValores)>60000
lSuccess := IF(!Appdata:oWebDataSourceExt:Execute("replace into "+cDestino+" ("+ArrayToChar(aCampos,",",1)+") Values "+HB_StrShrink(cValores,2)) .Or. !lSuccess, .F.,.T.)
cValores:=""
If Mod(aValores:__enumIndex,8)=0 //Para prevenir el tamaño máximo de la instrucción Http que se envia al servidor Apache via WebDataSource
Appdata:oWebDataSourceExt:CommitTrans()
Appdata:oWebDataSourceExt:BeginTrans()
Endif
Endif
If !lSuccess
Exit
Endif
Next
lSuccess := IF(!Appdata:oWebDataSourceExt:Execute("replace into "+cDestino+" ("+ArrayToChar(aCampos,",",1)+") Values "+HB_StrShrink(cValores,2)) .Or. !lSuccess, .F.,.T.)
Else //Eliminar registros en la web
lSuccess := Appdata:oWebDataSourceExt:Execute("delete from "+cDestino+" where id in("+ArrayToChar(xId,",")+")")
Endif
If !lSuccess
Appdata:oWebDataSourceExt:RollBackTrans()
Else
Appdata:oWebDataSourceExt:CommitTrans()
Endif
//Cerrar la BBDD de la Web externa
Appdata:oWebDataSourceExt:lConnected:=.F.
Return lSuccess
//------------------------------------------------------------------------------
Jose David Angulo Urzola
Auditoria y Sistemas Ltda.
Cartagena-Colombia
Auditoria y Sistemas Ltda.
Cartagena-Colombia
Re: Sincronizar tablas Maridb
Aqui la tienes pero no es mas que una función que concatena valores en un string al estilo del Concat de MySql. Lo que pasa es que a su vez llama a otras funciones ...... te paso todo lo que hace falta
//Devuelve la suma de n datos de cualquier tipo como un string
Function Concat(aValues,cSeparator,lSql)
Local nItem:=0, cValue:="", cResult:=""
Default lSql to .F.
If cSeparator=Nil
cSeparator:=If(!lSql," ",",")
Endif
For nItem:=1 to Len(aValues)
If lSql
IF ValType(aValues[nItem])="C" .And. ( Left(aValues[nItem],12)=="{\rtf1\ansi\" .Or. Left(aValues[nItem],14)=="{\\rtf1\\ansi\" )
aValues[nItem]:=XA_RtfToTxt(aValues[nItem])
Endif
cValue:=ValToSql(aValues[nItem])
Else
cValue:=AllString(aValues[nItem])
Endif
cResult:=cResult+cValue+cSeparator
Next
Return Left(cResult,Len(cResult)-Len(cSeparator))
//*/
// FUNCION que comprueba cadenas a enviar a sentencias Sql para ver si tienen apóstrofo o comillas y que no fallen
// @author Bingen Ugaldebere
// @param xSql Valor de cualquier tipo para montar la sentencia Sql, si es un DateTime puede ser un char '2015-12-01 12:30:00' o un array {Fecha,hora}
// @return Cadena montada para su uso en sentencias Sql
///
FUNCTION ValToSql( xSql )
Local cSql:=""
DO CASE
CASE ValType( xSql ) = "U" .Or. xSql=Nil
cSql := "Null"
CASE ValType( xSql ) = "C" .OR. ValType( xSql ) = "M"
cSql := "'" + StrSql( xSql ) + "'"
CASE ValType( xSql ) = "T" //TimeStamp con milisegundos
cSql := iif( Empty( xSql ), "'0000-00-00 00:00:00'", "'"+SqlDatetime(CToD(Left(ToString(xSql),10)),SubStr(ToString(xSql),12,8))+"'" )
CASE ValType( xSql ) = "DT" .Or. ( ValType( xSql ) = "A" .And. EsFecha(xSql[1]) .And. EsHora(xSql[2]) )
cSql := iif( Empty( xSql ), "'0000-00-00 00:00:00'", "'"+SqlDatetime( xSql[1], xSql[2] )+"'" )
CASE ValType( xSql ) = "D"
cSql := iif( Empty( xSql ), "'0000-00-00'", "'"+DToSQL( xSql )+"'" )
CASE ValType( xSql ) = "L"
cSql := IF( xSql, "1", "0" )
OTHERWISE
cSql := StrSQL(AllString( xSql ))
END
RETURN cSql
**/
* FUNCION que Convierte una fecha y hora a un DATETIME de MySql YYYY-MM-DD HH:MM:SS
* @author Bingen Ugaldebere
* @param dDate Fecha de referencia
* @return cadena con el 'YYYY-MM-DD HH:MM:SS'
*/
Function SqlDatetime(dDate,cTime)
Local cDate
Default dDate to Date()
Default cTime to Time()
cDate:=Dtoc(dDate)
If Len(cTime)=5 //Por si la hora viene sin segundos
cTime+=":00"
Endif
Return IF(Vacio(dDate),"0000-00-00",Right(cDate,4)+"-"+Substr(cDate,4,2)+"-"+Left(cDate,2))+" "+IF(Vacio(cTime),"00:00:00",cTime)
**/
* FUNCION Indica si un dato esta vacio de verdad con .T. o .F.
* @author Bingen Ugaldebere
* @param xValue Valor a considerar si está vacio de cualquier tipo
* @param xReturnValue [Opcional] Si no se indica este valor se devuelve simpre .T. / .F.
* pero si se indica se devuelve xReturnValue si está vacio pero se devuelve xValue si no lo está
* @param lNil [Opcional] Si se indica .T. también los campos de texto que sean "Nil" se considerarán como vacios, con .F. no se tienen en cuenta
* @return .T. / .F. o xReturnValue (si esta vacio y se ha suministrado)
*/
Function Vacio(xValue, xReturnValue, lNil)
Local lVacio:=.F.
Default xReturnValue To .T. //Valor de retorno por defecto If Vacio( cCiudad, "Bilbao")
Default lNil To .F. //EN caso de ser un tipo "C" con valor "NIL" y lNil:=.T devuelve la cadena "NIL"
Do CAse
Case xValue=Nil
lVacio:=.T.
Case ValType(xValue)="D" //Date
lVacio:=xValue=Ctod(" - - ")
Case ValType(xValue)="T" //DateTime
lVacio:=ToString(xValue)==" - - 00:00:00.000"
Case ValType(xValue)="A" //Array
lVacio:=Len(xValue)=0
Case ValType(xValue)="L" //Boolean
lVacio:=xValue=.F.
Case ValType(xValue)="N" //Numeric
lVacio:=xValue=0
Case ValType(xValue)="B" //Codeblock
lVacio:= ToString(xValue) == "{|| ... }"
Case ValType(xValue)="C" .And. lNil .And. Upper(xValue)=="NIL" //Char
lVacio:=.T.
CASE ValType(xValue)="H" //Hash
lVacio:= Empty( xValue )
OtherWise
lVacio:=Len(AllString(xValue))=0
EndCAse
Return IF(lVacio,xReturnValue,IF(ValType(xReturnValue)<>"L",xValue,.F.))
**/
* FUNCION que Devuelve .T. si una variable suministrada en realidad es una fecha
* @author Bingen Ugaldebere
* @param xFecha Fecha en formato Date o Character
* @return .T. / .F.
*/
Function EsFecha( xFecha )
Return Alltrim(ToString(xFecha)) == Dtoc(CToD(Alltrim(ToString(xFecha))))
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// FUNCION : ValHora(cHora) -> lCorrecto
// DESCRIPCION: Valida una cadena como expresión horaria del tipo HH:MM:SS
//
// PARAMETROS : <cHora> = Cadena con formato HH:MM:SS que representa una expresión horaria.
// El separador de horas y minutos puede ser cualquiera, pero tiene que existir.
//
// REGRESA : <lCorrecto> - Valor lógico que indica si la cadena <cHora> es una expresión horaria
// con el formato HH:MM:SS
//
// EJEMPLO : cHora := SPACE(8)
// @ 0, 0 SAY "Indique hora: " GET cHora PICTURE "99:99:99" VALID ValHora(cHora)
//
// -> La función ValHora() no dejará continuar el prgorama hasta que la expresión
// horaria sea correcta.
//
// A U T O R : Grupo Eidos (Librerias en Clipper 5, Ra-ma, Addison-Wesley Iberoamericana)
// F E C H A : 1992
//
FUNCTION ValHora( cHora )
// Control de errores
IF ValType( cHora ) != 'C'
RETURN .F.
END IF
cHora := AllTrim( cHora )
IF Len( cHora ) < 8
cHora := Left( cHora + "00:00:00", 8 )
ENDIF
RETURN Val( Left ( cHora, 2 ) ) <= 23 .AND. ;
Val( Left ( cHora, 2 ) ) >= 0 .AND. ;
Val( SubStr ( cHora, 4, 2 ) ) <= 59 .AND. ;
Val( SubStr ( cHora, 4, 2 ) ) >= 0 .AND. ;
Val( Right( cHora, 2 ) ) <= 59 .AND. ;
Val( Right( cHora, 2 ) ) >= 0
FUNCTION EsHora( cHora )
Return ValHora( cHora )
/
//Devuelve la suma de n datos de cualquier tipo como un string
Function Concat(aValues,cSeparator,lSql)
Local nItem:=0, cValue:="", cResult:=""
Default lSql to .F.
If cSeparator=Nil
cSeparator:=If(!lSql," ",",")
Endif
For nItem:=1 to Len(aValues)
If lSql
IF ValType(aValues[nItem])="C" .And. ( Left(aValues[nItem],12)=="{\rtf1\ansi\" .Or. Left(aValues[nItem],14)=="{\\rtf1\\ansi\" )
aValues[nItem]:=XA_RtfToTxt(aValues[nItem])
Endif
cValue:=ValToSql(aValues[nItem])
Else
cValue:=AllString(aValues[nItem])
Endif
cResult:=cResult+cValue+cSeparator
Next
Return Left(cResult,Len(cResult)-Len(cSeparator))
//*/
// FUNCION que comprueba cadenas a enviar a sentencias Sql para ver si tienen apóstrofo o comillas y que no fallen
// @author Bingen Ugaldebere
// @param xSql Valor de cualquier tipo para montar la sentencia Sql, si es un DateTime puede ser un char '2015-12-01 12:30:00' o un array {Fecha,hora}
// @return Cadena montada para su uso en sentencias Sql
///
FUNCTION ValToSql( xSql )
Local cSql:=""
DO CASE
CASE ValType( xSql ) = "U" .Or. xSql=Nil
cSql := "Null"
CASE ValType( xSql ) = "C" .OR. ValType( xSql ) = "M"
cSql := "'" + StrSql( xSql ) + "'"
CASE ValType( xSql ) = "T" //TimeStamp con milisegundos
cSql := iif( Empty( xSql ), "'0000-00-00 00:00:00'", "'"+SqlDatetime(CToD(Left(ToString(xSql),10)),SubStr(ToString(xSql),12,8))+"'" )
CASE ValType( xSql ) = "DT" .Or. ( ValType( xSql ) = "A" .And. EsFecha(xSql[1]) .And. EsHora(xSql[2]) )
cSql := iif( Empty( xSql ), "'0000-00-00 00:00:00'", "'"+SqlDatetime( xSql[1], xSql[2] )+"'" )
CASE ValType( xSql ) = "D"
cSql := iif( Empty( xSql ), "'0000-00-00'", "'"+DToSQL( xSql )+"'" )
CASE ValType( xSql ) = "L"
cSql := IF( xSql, "1", "0" )
OTHERWISE
cSql := StrSQL(AllString( xSql ))
END
RETURN cSql
**/
* FUNCION que Convierte una fecha y hora a un DATETIME de MySql YYYY-MM-DD HH:MM:SS
* @author Bingen Ugaldebere
* @param dDate Fecha de referencia
* @return cadena con el 'YYYY-MM-DD HH:MM:SS'
*/
Function SqlDatetime(dDate,cTime)
Local cDate
Default dDate to Date()
Default cTime to Time()
cDate:=Dtoc(dDate)
If Len(cTime)=5 //Por si la hora viene sin segundos
cTime+=":00"
Endif
Return IF(Vacio(dDate),"0000-00-00",Right(cDate,4)+"-"+Substr(cDate,4,2)+"-"+Left(cDate,2))+" "+IF(Vacio(cTime),"00:00:00",cTime)
**/
* FUNCION Indica si un dato esta vacio de verdad con .T. o .F.
* @author Bingen Ugaldebere
* @param xValue Valor a considerar si está vacio de cualquier tipo
* @param xReturnValue [Opcional] Si no se indica este valor se devuelve simpre .T. / .F.
* pero si se indica se devuelve xReturnValue si está vacio pero se devuelve xValue si no lo está
* @param lNil [Opcional] Si se indica .T. también los campos de texto que sean "Nil" se considerarán como vacios, con .F. no se tienen en cuenta
* @return .T. / .F. o xReturnValue (si esta vacio y se ha suministrado)
*/
Function Vacio(xValue, xReturnValue, lNil)
Local lVacio:=.F.
Default xReturnValue To .T. //Valor de retorno por defecto If Vacio( cCiudad, "Bilbao")
Default lNil To .F. //EN caso de ser un tipo "C" con valor "NIL" y lNil:=.T devuelve la cadena "NIL"
Do CAse
Case xValue=Nil
lVacio:=.T.
Case ValType(xValue)="D" //Date
lVacio:=xValue=Ctod(" - - ")
Case ValType(xValue)="T" //DateTime
lVacio:=ToString(xValue)==" - - 00:00:00.000"
Case ValType(xValue)="A" //Array
lVacio:=Len(xValue)=0
Case ValType(xValue)="L" //Boolean
lVacio:=xValue=.F.
Case ValType(xValue)="N" //Numeric
lVacio:=xValue=0
Case ValType(xValue)="B" //Codeblock
lVacio:= ToString(xValue) == "{|| ... }"
Case ValType(xValue)="C" .And. lNil .And. Upper(xValue)=="NIL" //Char
lVacio:=.T.
CASE ValType(xValue)="H" //Hash
lVacio:= Empty( xValue )
OtherWise
lVacio:=Len(AllString(xValue))=0
EndCAse
Return IF(lVacio,xReturnValue,IF(ValType(xReturnValue)<>"L",xValue,.F.))
**/
* FUNCION que Devuelve .T. si una variable suministrada en realidad es una fecha
* @author Bingen Ugaldebere
* @param xFecha Fecha en formato Date o Character
* @return .T. / .F.
*/
Function EsFecha( xFecha )
Return Alltrim(ToString(xFecha)) == Dtoc(CToD(Alltrim(ToString(xFecha))))
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// FUNCION : ValHora(cHora) -> lCorrecto
// DESCRIPCION: Valida una cadena como expresión horaria del tipo HH:MM:SS
//
// PARAMETROS : <cHora> = Cadena con formato HH:MM:SS que representa una expresión horaria.
// El separador de horas y minutos puede ser cualquiera, pero tiene que existir.
//
// REGRESA : <lCorrecto> - Valor lógico que indica si la cadena <cHora> es una expresión horaria
// con el formato HH:MM:SS
//
// EJEMPLO : cHora := SPACE(8)
// @ 0, 0 SAY "Indique hora: " GET cHora PICTURE "99:99:99" VALID ValHora(cHora)
//
// -> La función ValHora() no dejará continuar el prgorama hasta que la expresión
// horaria sea correcta.
//
// A U T O R : Grupo Eidos (Librerias en Clipper 5, Ra-ma, Addison-Wesley Iberoamericana)
// F E C H A : 1992
//
FUNCTION ValHora( cHora )
// Control de errores
IF ValType( cHora ) != 'C'
RETURN .F.
END IF
cHora := AllTrim( cHora )
IF Len( cHora ) < 8
cHora := Left( cHora + "00:00:00", 8 )
ENDIF
RETURN Val( Left ( cHora, 2 ) ) <= 23 .AND. ;
Val( Left ( cHora, 2 ) ) >= 0 .AND. ;
Val( SubStr ( cHora, 4, 2 ) ) <= 59 .AND. ;
Val( SubStr ( cHora, 4, 2 ) ) >= 0 .AND. ;
Val( Right( cHora, 2 ) ) <= 59 .AND. ;
Val( Right( cHora, 2 ) ) >= 0
FUNCTION EsHora( cHora )
Return ValHora( cHora )
/
BiSoft Desarrollo de software profesional
http://www.bisoft.es
http://www.bisoft.es
Re: Sincronizar tablas Maridb
Como siempre Bingen muy oportuno.
Mil gracias,
Mil gracias,
Jose David Angulo Urzola
Auditoria y Sistemas Ltda.
Cartagena-Colombia
Auditoria y Sistemas Ltda.
Cartagena-Colombia
- ignacio
- Site Admin
- Mensajes: 9271
- Registrado: Lun Abr 06, 2015 8:00 pm
- Ubicación: Madrid, Spain
- Contactar:
Re: Sincronizar tablas Maridb
Un ejemplo utilizando DBFs locales con DBF es un servidor Web y una clase que hace todo el trabajo de sincronización:
Código: Seleccionar todo
METHOD DbfPostAppend( oSender ) CLASS TMainForm
LOCAL oRec := oSender:GetRecord()
IF !::oDbfSyncro:Send( 0, Lower(oSender:cAlias), oRec:ToJson(.t.) )
MsgAlert( "Los últimos cambios realizados no pudieron sincronizarse" + ;
CRLF + CRLF + ::oDbfSyncro:cLastError )
ENDIF
RETURN Nil
METHOD DbfPostSave( oSender ) CLASS TMainForm
LOCAL oRec := oSender:GetRecord()
IF oSender:lOnAppend() // Ya se ha grabado
RETURN NIL
ENDIF
IF !::oDbfSyncro:Send( oSender:Recno(), Lower(oSender:cAlias), oRec:ToJson(.t.) )
MsgAlert( "Los últimos cambios realizados no pudieron sincronizarse" + ;
CRLF + CRLF + ::oDbfSyncro:cLastError )
ENDIF
RETURN Nil
METHOD DbfCliPreDelete( oSender ) CLASS TMainForm
IF !::oDbfSyncro:Send( -oSender:Recno(), Lower(oSender:cAlias) ) // Se pasa el número de registro en negativo
MsgAlert( "Los últimos cambios realizados no pudieron sincronizarse" + ;
CRLF + CRLF + ::oDbfSyncro:cLastError )
ENDIF
RETURN Nil
Re: Sincronizar tablas Maridb
Ignacio,
muy buena opción,
Muy agradecido.
muy buena opción,
Muy agradecido.
Jose David Angulo Urzola
Auditoria y Sistemas Ltda.
Cartagena-Colombia
Auditoria y Sistemas Ltda.
Cartagena-Colombia