Page 2 of 2

Re: HRB V/S LIB

Posted: Thu Apr 13, 2017 3:19 pm
by serge_girard
Hello Luis, That won't change much? Now you will have to install new HRB instead of EXE?

Serge

Re: HRB V/S LIB

Posted: Thu Apr 13, 2017 4:23 pm
by Anand
+1, and a very small one. Most probably just copy to exe folder.

Regards,

Anand

Re: HRB V/S LIB

Posted: Fri Apr 14, 2017 7:16 am
by serge_girard
Anand, I use a BAT file to start up my programs. In this batch file 2 programs are executed. The first program just looks in a MySQL table if a new version of the main program is avaiable. If so the old main program is renamed and a new copy is downloaded. Then the second program is started which by then maybe the latest version. Of course MySQL / libmysql.dll is required but this works perfect. From my place I upload the EXE and choose to whom it may serve.

Serge

Re: HRB V/S LIB

Posted: Fri Apr 14, 2017 9:32 am
by Anand
Good idea. Thanks

Regards,

Anand

Re: HRB V/S LIB

Posted: Thu May 18, 2017 6:05 am
by mol
Hi!
I want to refresh this topic.
What about speed of functions placed in .hrb files? Is it comparable to functions located in .exe?

Re: HRB V/S LIB

Posted: Thu May 18, 2017 6:18 am
by dragancesu
I use a BAT file to start up my programs. In this batch file 2 programs are executed. The first program just looks in a MySQL table if a new version of the main program is avaiable. If so the old main program is renamed and a new copy is downloaded. Then the second program is started which by then maybe the latest version. Of course MySQL / libmysql.dll is required but this works perfect. From my place I upload the EXE and choose to whom it may serve.
if I understand you solved the problem of synchronization / update of new versions

Can you put some code how are you doing?

Whether it can work in the startup section of the windows?

thanks

Re: HRB V/S LIB

Posted: Thu May 18, 2017 7:53 am
by serge_girard
Hi Dragan,

I use in my BAT file 2 EXE:

The first is a short program which runs locally on several PC at different locations. Each time a new version is
ready to be implemented I transfer the EXE to a MySQL database.

Structure is simple: FILE C(30), POS N(10), STATUS (C1), EXE_FILE (Longblob)

STATUS == 'N' indicates that a new version is ready to be downloaded for a specific POS (or all).

So the first program checkes if there is a new version.
If there is:
- I rename the existant EXE to the same name with date + sequential number in order to have a backup of the previous version.
- I retrieve the EXE into a var and from this var I create a EXE file (Buff_To_File).

Then the program is ready and quits and the batch will continue with the new version.
The second program (the main program which is all about) will do the same for the first program (this seldom happens, of course)

So there are 3 programs involved:
2 remote
1 HQ.

From the HQ program I can copy a new EXE to this MySQL database and reset the STATUS to 'N' and the I can check if all went OK.

You will need libmysql.dll on each PC and a remote MySQL database for your tables.


I include a short extract (not compile tested) which does the thing.

Code: Select all

#include "hmg.ch"


FUNCTION MAIN()
/*************/
PARAMETERS xPOS

// CHECK xPOS !!

// GET  xDB_HOST,xDB_USER,xDB_PW,xDB_NAME


IF SQL_Connect(xDB_HOST,xDB_USER,xDB_PW,xDB_NAME)  == Nil 
   // CONTINUE
	QUIT
ENDIF

NEW_VERSION()
 
SQL_Disconnect()

RETURN





FUNCTION NEW_VERSION()
/******************/
cQuery1	:= " SELECT EXE_FILE "  
cQuery1	+= " FROM NEW_VERSION "  
cQuery1	+= " WHERE FILE		= 'ZZZ' "			 
cQuery1	+= " AND   STATUS		= 'N' "				 
cQuery1	+= " AND   POS 		= '" + xPOS + "' "				 
cSQL		:= cQuery1
cQuery1	:= dbo:Query( cQuery1 )
IF cQuery1:NetErr()												
   ? PROCNAME(), '010', cQuery1:Error() , cSQL  
   RETURN 
ENDIF 


NIEUW := FALSE

IF cQuery1:LastRec() == 0
	RETURN
ELSE
   aCurRow		:= cQuery1:GetRow(1)
   cEXE  	   := aCurRow:fieldGet(1)
   IF EMPTY(cEXE)
      RETURN
   ELSE
      // COPY TO ..
      dDATUM = DTOC(DATE())
      dDATUM = STRTRAN(dDATUM,"/","") 
      dDATUM = STRTRAN(dDATUM,"-","") 
      nVOLG  = 1
	
      DO WHILE .T.  
         cOLDFILE = "&XSTAT_PATH\ZZZ" + dDATUM + ALLTRIM(STR(nVOLG,3,0)) + ".EXE"
         IF !FILE(cOLDFILE)
            EXIT
         ENDIF
         nVOLG++
      ENDDO

      IF FRENAME("&XSTAT_PATH\ZZZ.EXE", cOLDFILE)  == -1
         QUIT
      ENDIF

      NIEUW := Buff_To_File(cEXE, "&XSTAT_PATH\ZZZ.EXE")

      IF !NIEUW
         ? 'Kopieeren nieuwe ZZZ is fout' , 'OK'
         // RESTORE PREV VERSION 
         IF FRENAME(cOLDFILE, "&XSTAT_PATH\ZZZ.EXE" )  == -1
            QUIT
         ENDIF
         RETURN
      ENDIF
   ENDIF
ENDIF


IF NIEUW
 	IF FRENAME("&XSTAT_PATH\ZZZ.EXE", cOLDFILE)  == -1
		QUIT
	ENDIF
 
	cQuery1	:= " UPDATE NEW_VERSION "	   
	cQuery1	:= " SET   STATUS    = 'X' " 
   cQuery1	+= " WHERE FILE		= 'ZZZ' "			 
   cQuery1	+= " AND   STATUS		= 'N' "				 
   cQuery1	+= " AND   POS 		= '" + xPOS + "' "				 
	cSQL		:= cQuery1
	cQuery1	:= dbo:Query( cQuery1 )

	IF cQuery1:NetErr()					// hier fout							
		?  PROCNAME(), '013', cQuery1:Error() , cSQL 
		RETURN
	ENDIF
 
ENDIF


RETURN


FUNCTION Buff_To_File(cBuff, cNEW_FILE)
/*************************************/
LOCAL fh, nLen

fh := FCREATE(cNEW_FILE,0)

IF fh > - 1
	nLen	:= FWRITE(fh, cBuff) 
	FCLOSE(fh)

	IF nLen == LEN(cBuff)
      RETURN .T.	 
	ELSE
		RETURN .F.
	ENDIF
ENDIF

RETURN .F.	 
No magic, no tricks...

For inserting EXE I use this code:

Code: Select all

cEXE_File   := File_To_Buff( LclFile0 )
cQuery1	:= " INSERT INTO NEW_VERSION "  
etc...



FUNCTION File_To_Buff(cFile)
/*******************************************************************************************************************/
local cBuff:="", fh, nLen
local lRetVal:=.f.
local cFile_in := cFile


fh	:= FOPEN(cFile_in,0)

IF fh > -1
   // determine length of file
   nLen := FSEEK(fh, 0, 2)

   IF nLen > 0
		//move file pointer back to begin of file
		FSEEK(fh, 0, 0)
		cBuff	:= SPACE(nLen)
		FREAD(fh, @cBuff, nLen)
		 
		// escapes
		cBuff	:= STRTRAN(cBuff, CHR(92), "\\")
		cBuff	:= STRTRAN(cBuff, CHR(0), "\0")
		cBuff	:= STRTRAN(cBuff, CHR(39), "\'")
		cBuff	:= STRTRAN(cBuff, CHR(34), '\"')
	ENDIF 
ELSE
   cBuff := "OFF"       
ENDIF
     
FCLOSE(fh)

RETURN(cBuff)
Serge

Re: HRB V/S LIB

Posted: Fri May 19, 2017 12:43 am
by luisvasquezcl
Wow im impresive. Thanks serge. Best regards
Luis vasquez

Re: HRB V/S LIB

Posted: Fri May 19, 2017 3:56 am
by franco
Like I said before, so much to learn, so little time.
Serge with this is a great sample, to me seems you are saving the exe file in a table. Then extracting it at the other end. Is this so.
I know before you mentioned you upload each night from pos to HQ. Does each pos have its own folder in the server to upload the tables to.
I am still trying to figure out sql of some type, but having trouble understanding. I will get it I know.
Nice work ... Franco

Re: HRB V/S LIB

Posted: Fri May 19, 2017 7:46 am
by serge_girard
No folder/dir for each POS. Each POS has it's unique POS_NO.
EXE is indeed saved in MySQL table. About 5-6Mb and it is downloaded really quickly. Most users will not notice, except after downloading I give a message saying that a new version has been installed.

Serge