lunes, 31 de agosto de 2009

TMySQL contrib

Amigos,

Muchos nos preguntamos de donde bajar los fuentes de esta fabulosa contribución de xHarbour.

Aquí el link de todas las contribuciones de xHarbour.

XHARBOUR CONTRIB

Saludos

jueves, 25 de junio de 2009

De vuelta VeRCE

Amigos,

Pues con la novedad que hemos decidido darle nueva sangre al VeRCE, recodificando todo para darle más velocidad a la hora de compilar.

Espero comentarios para incluir en VeRCE, he enterado a Juán Carlos Salínas Ojeda de este proyecto sobre el VeRCE para que esté al pendiente y pueda ayudarnos en la nueva era.

Se espera la participación de los colegas que usan VeRCE para hacer una herramienta más estable y mas amigable.

Saludos

Transacciones en MySql

Amigos,

A petición de un gran amigo de la comunidad César Cortez.

Como hacer transacciones con TMySql.

oMysql:begintransaction()
lError := .f.
oCliente:fieldput( "saldo", nSaldo )
lError := oCliente:update()
IF !lError
oVenta:fieldput( "venta", nVenta )
oVenta:fieldput( "cliente", cCliente )
lError := oVenta:append()
ENDIF

IF !lError
oMysql:Commit()
ELSE
oMysql:rollback()
ENDIF

Es un ejemplo sencillo, pero es para que tengan un idea de como aplicarlo.

Saludos

domingo, 7 de junio de 2009

Función para browsear TYMSQL

Aquí la función que se ha usado y se seguirá usando por lo menos eso espero.

FUNCTION MySetBrowse( oBrw, oDataSource )
local lRet := .t.
local bGoTop, bGoBottom, bSkipper
local cClsName

bGoTop := { || oDataSource:GoTop() }
bGoBottom := { || oDataSource:GoBottom() }
bSkipper := { | n | oDataSource:Skipper( n ) }

cClsName := upper( oBrw:ClassName() )

oBrw:bGoTop := bGoTop
oBrw:bGoBottom := bGoBottom

IF cClsName == "TWBROWSE"
oBrw:bSkip := { | n | oDataSource:Skip( n ) }
ELSE
oBrw:bSkip := bSkipper
ENDIF

if cClsName == "TXBROWSE"
oBrw:bBof := { || oDataSource:Bof() }
oBrw:bEof := { || oDataSource:Eof() }
oBrw:bBookMark :={ | n | if( n == nil, oDataSource:RecNo(), oDataSource:GoTo( n ) ) }
oBrw:bKeyNo := { || oDataSource:RecNo() }
oBrw:bKeyCount := { || oDataSource:RecCount() }
ELSE
oBrw:bLogicLen := { || oDataSource:RecCount() }
ENDIF
if oBrw:oVScroll() != nil
oBrw:oVscroll():SetRange( 1, oDataSource:RecCount() )
ENDIF
oBrw:Refresh()

return( lRet )

//**

Bueno, ahí está

Saludos

martes, 26 de mayo de 2009

Acceder a MySQL con una Aplicacion simple:

Hola amigos,,,
Aqui os dejo un ejemplo simple de como acceder a una base de datos de MySQL y hacer un Browse,,, con TWBrowse.... luego veremos como hacer la Altas, Bajas y Reportes, pero eso si, utilizando pura sentencia SQL,,,

# include "fivewin.ch"
Static oWnd, oMySQl, oDBase, lConecta, lOkDb
//----------------------------------------------------------------------------------------Function Main()
local cHost, cUser, cPass, lOk, nPortlocal cDbName
lOk := .f.
lConecta := lOkDb := .f.
//-------parametros de entrada-------------------------------------//
cHost := "localhost" // en modo local
cUser := "pruebas" // usuario
cPass := "pruebas" // password
cDbName := "pruebas" // nombre de la base de datos
nPort := "3306"
//--------aqui nos conectamos al servidor--------------------------
ConectaMySQL(cHost, cUser, cPass, nPort)
If !lConecta
MsgInfo( "No Hay Conexión Con El Servidor " + cHost "" )
Return(.f.)
EndIf

oDBase := AbreDbMySQL(oMySQL, oDBase, cDbName)
If !lOkDb
MsgInfo( "No Se Puede Crear la Base De Datos " + cDbName + CHR(34), "" )
Return(.f.)
EndIF

DEFINE WINDOW oWnd
ACTIVATE WINDOW oWnd MAXIMIZED ;
ON INIT AMB(oWnd, oMySQL, oDBase) // siempre envio los handles,,,,,
Return(nil)
//--------------------------------------------------------------------
Function ConectaMySQL(cHost, cUser, cPass, nPuerto )
oMySQL := TMySQLServer():New(cHost, cUser, cPass, nPuerto)
IF oMySQL:NetErr()
lConecta := .f.
ELse
lConecta := .t.
EndIF
Return(lConecta)
//---------------------------------------------------------------------
Function AbreDbMySQL(oMySQL, oDBase, cDbName)
cDBName := AllTrim(cDbName)
oMySQL:Query( "CREATE DATABASE IF NOT EXISTS " + cDBName )
oDBase := oMySQL:SelectDB( cDBName )
IF oMySQL:NetErr()
lOkDb := .f.
Else
lOkDb := .t.
EndIF
Return(oDBase)

//-------esta funcion puede estar en otro prg---------------------
Function AMB(oWnd, oMySQL, oDBase)
local oSalir, oNuevo, oModif, oImpri, oElimi, tCargalocal oDlg, oLbx, oDatos, eDatos, oOrden
local nOrden, oAlgo, lAlgolocal aCol, oBrw, cQuery, nCont, nLen, aListaaCol := ARRAY(2)

cQuery := "SELECT * FROM kardex WHERE cod_producto = '20071121223230' ORDER BY num_movimiento LIMIT 500"
oDatos := oMySQL:Query(cQuery , .t. )
If oDatos:RecCount() == 0 && si no tiene datos...
oDatos:End()
MsgInfo("No hay registros")
Return(Nil)
EndIf

DEFINE DIALOG oDlg ; RESOURCE "PRODUCTOSTW" ; TITLE "FWH + HARBOUR + TMySQL + MySQL"

REDEFINE LISTBOX oLbx ;
FIELDS STR(MyCampo(oDatos, "ingreso"),12,2), ;
STR(MyCampo(oDatos, "egreso"),12,2), ;
STR(MyCampo(oDatos, "saldo"),12,2) ;
HEADERS "Campo1", ;
"Campo2", ;
"Campo3" ;
SIZES 150, 150, 150 ;
ID 200 OF oDlg
MySetbrowse(oLbx, oDatos ) // importante para la navegacion

ACTIVATE DIALOG oDlg CENTER //ON INIT createxb( oDatos, oDlg )
Return(nil)
*/
//----esta funcion permite manejar las tablas aun sin datos---------------
Function MyCampo(oBjeto, nCampo, nEnt, nDec)
local cCampo, cRet, nCol, nCont, cField, nPos
If VALTYPE(nCampo) = "C" // vino el nombre de un campo
nCampo := ALLTRIM(nCampo)
nPos := oBjeto:FieldPos(nCampo)
If nPos = 0 // no existe en campo en mencion
Msginfo("No Existe el Campo Indicado <" + nCampo + ">", "Error")
Return("")
EndIf
Else
nPos := nCampo
EndIf

DO CASE
CASE oBjeto:FieldType(nPos) = "N"
cCampo := 0
CASE oBjeto:FieldType(nPos) = "C"
cCampo := ""
CASE oBjeto:FieldType(nPos) = "L"
cCampo := ".f."
CASE oBjeto:FieldType(nPos) = "D"
cCampo := CTOD(" / / /")
OTHER cCampo := ""
ENDCASE

If oBjeto:RecCount() = 0
Return(cCampo)
EndIF
IF oBjeto:FieldType(nPos) = "U"
Return(cCampo)
EndIf
cCampo := oBjeto:FieldGet(nPos)
Return(cCampo)

Script de compilación de la LIB TMySQL

Bueno amigos,

Retomando la escritura.

Pues resulta que ayudando al amigo Dutch, hemos descubierto que las lib de TMySQL deben de estar en la posición siguiente para poder utilizar sin errores o GPF la lib mencionada.

SCRIPT Erróneo
ECHO %CC_LIB%\c0w32.obj + > b32.bc
ECHO %ARCHIVO%.obj, + >> b32.bc
ECHO xh%ARCHIVO%.exe, + >> b32.bc
ECHO %ARCHIVO%.map, + >> b32.bc
ECHO %FWH_LIB%\fivehc.lib + >> b32.bc
ECHO %FWH_LIB%\fivehx.lib + >> b32.bc
<< aquí el error >>
ECHO Y:\TSuperLib\TMySql\LIB\mysql.lib + >> b32.bc
ECHO Y:\TSuperLib\TMySql\LIB\libmysql.lib + >> b32.bc
<< termina error >>
ECHO %CC_LIB%\cw32.lib + >> b32.bc
ECHO %CC_LIB%\Import32.lib + >> b32.bc
ECHO %CC_LIB%\PSDK\msimg32.lib + >> b32.bc
ECHO %XC_LIB%\pcrepos.lib + >> b32.bc
rem La LIB FMSTAT.LIB es para sacar la estadistica de memoria
rem quitar si no se quiere
ECHO %XC_LIB%\ct.lib + >> b32.bc
ECHO %XC_LIB%\rtl.lib + >> b32.bc
ECHO %XC_LIB%\vm.lib + >> b32.bc
ECHO %XC_LIB%\gtgui.lib + >> b32.bc
ECHO %XC_LIB%\lang.lib + >> b32.bc
ECHO %XC_LIB%\macro.lib + >> b32.bc
ECHO %XC_LIB%\debug.lib + >> b32.bc
ECHO %XC_LIB%\common.lib + >> b32.bc
ECHO %XC_LIB%\pp.lib + >> b32.bc
ECHO %XC_LIB%\rdd.lib + >> b32.bc
ECHO %XC_LIB%\tip.lib + >> b32.bc
rem Poner el controlador o controladores que se vayan a usar
ECHO %XC_LIB%\dbfntx.lib + >> b32.bc
ECHO %XC_LIB%\dbfcdx.lib + >> b32.bc
ECHO %XC_LIB%\hsx.lib + >> b32.bc
ECHO %XC_LIB%\hbsix.lib + >> b32.bc
ECHO %XC_LIB%\dbffpt.lib >> b32.bc

SCRIPT Correcto
ECHO %CC_LIB%\c0w32.obj + > b32.bc
ECHO %ARCHIVO%.obj, + >> b32.bc
ECHO xh%ARCHIVO%.exe, + >> b32.bc
ECHO %ARCHIVO%.map, + >> b32.bc
<< aquí la corrección o lo correcto >>
ECHO Y:\TSuperLib\TMySql\LIB\mysql.lib + >> b32.bc
ECHO Y:\TSuperLib\TMySql\LIB\libmysql.lib + >> b32.bc
<< termina error >>
ECHO %FWH_LIB%\fivehc.lib + >> b32.bc
ECHO %FWH_LIB%\fivehx.lib + >> b32.bc
ECHO %CC_LIB%\cw32.lib + >> b32.bc
ECHO %CC_LIB%\Import32.lib + >> b32.bc
ECHO %CC_LIB%\PSDK\msimg32.lib + >> b32.bc
ECHO %XC_LIB%\pcrepos.lib + >> b32.bc
rem La LIB FMSTAT.LIB es para sacar la estadistica de memoria
rem quitar si no se quiere
ECHO %XC_LIB%\ct.lib + >> b32.bc
ECHO %XC_LIB%\rtl.lib + >> b32.bc
ECHO %XC_LIB%\vm.lib + >> b32.bc
ECHO %XC_LIB%\gtgui.lib + >> b32.bc
ECHO %XC_LIB%\lang.lib + >> b32.bc
ECHO %XC_LIB%\macro.lib + >> b32.bc
ECHO %XC_LIB%\debug.lib + >> b32.bc
ECHO %XC_LIB%\common.lib + >> b32.bc
ECHO %XC_LIB%\pp.lib + >> b32.bc
ECHO %XC_LIB%\rdd.lib + >> b32.bc
ECHO %XC_LIB%\tip.lib + >> b32.bc
rem Poner el controlador o controladores que se vayan a usar
ECHO %XC_LIB%\dbfntx.lib + >> b32.bc
ECHO %XC_LIB%\dbfcdx.lib + >> b32.bc
ECHO %XC_LIB%\hsx.lib + >> b32.bc
ECHO %XC_LIB%\hbsix.lib + >> b32.bc
ECHO %XC_LIB%\dbffpt.lib >> b32.bc

Entonces la nota sería, las lib de tmysql deben de ir exactamente al inicio donde se incluyen las LIB forzosamente. Si se hiciera de la manera incorrecta pues saldrían errores aleatorios y GPF.

Saludos

martes, 7 de abril de 2009

SQL como SQL

Hola amigos,Veamos, empezaremos por el principio:
Luego de batallar con las DBFs desde 1986 (full Clipper), en diciembre del 2006, por una cuestion de orgullo, decidi entrar de lleno al manejo de MySQL, vi un par de opciones, opte por una libreria que no usaba ODBC, la verdad es que tuve que batallar casi solo con el tema
del manejo de las tablas,,,,
20 años pensando en DBF, conociendolas al reves y al derecho, los tiempos cambian y las tecnologias tambien,,,
En el foro se dio mucha importancia en una momento a SQLWIN, pero el ultimo post es de feb2009, ADO la usa algunos seguidores, pero,,,, SQL se debe usar como SQL,,,
Utilizar MySQL como si tubieran tablas DBF, me parece usar un formula 1 con llantas de bicicleta, no desmerezco las DBFs, me dieron mucho, pero la potencia de SQL es otra cosa,,,
TMySQL me parece una muy buena libreria (fuentes abiertas) para acceder a MySQL, empeze con unas pruebas basicas, "INSERT, UPDATE, DELETE,SELECT,CREATE,DROP,ALTER" ups,,, ya estaba con todo el MySQL encima,,,
Pues es eso mismo, el poder de cada sentencia de MySQL o SQL en general es fabuloso, ademas la curva de aprendizaje en corta, basicamente con lo que tiene TMySQL se pueden hacer aplicaciones comerciales estupendas,,, ya mismo estoy desarrollando una app para Hoteles, y de momento todo funciona ok, incluso ya se resolvio el manejo de los "store procedure" (gracias William) entre otras cosillas, pero basicamente TMySQL debe ser potenciada, afinada y formar parte integral de la comunidad Fivewin.
Amigos lectores, animense a entra al mundo SQL, y TMySQL es la mejor opcion para MySQL, recuerden, las fuentes estan disponibles, y claro, estoy a vuestra disposicion para cualquier consulta a nivel de MySQL,,, si no tengo la respuesta, tendre el numero de telefono del que la sabe...
Salu2
Willi Quintana