FoxInCloud
Error in com Mode
Gravatar is a globally recognized avatar based on your email address. Error in com Mode
  Arcadio Bianco
  All
  Feb 29, 2020 @ 07:31am

I am very close to running my application in production, however, in tests with my team, I am facing some problems with simultaneous access in COM mode. If 2 users perform actions at the same time, this is showing me an ajax error. In file mode this problem does not occur. Does anyone have any idea what it might be? I'm uploading a video of the error.

https://youtu.be/5J5C9lUCVs0

&& Click Button code
LPARAMETERS nButton, nShift, nXcoord, nYcoord && Implementation documentation: see code inherited from aw.vcx!aw???.Click() (click 'View Parent Code')

IF (Type('m.thisForm.wlHTMLgen') == 'L' AND m.thisForm.wlHTMLgen) && Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/01/2018 16:23



  RETURN .T. && Process event on server (your code after this IF ... ENDIF block)

ENDIF && Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/01/2018 16:23

WITH thisform
     IF !thisform.metodo_pad.conecta_banco(.T.)
	 RETURN .F.
     ENDIF 	

    .forpag_id_caixa1  = CURREC.ID 
    .descricao_caixa1  = CAST(NVL(thisform.combobox_padrao1.DisplayValue,"") as M)
    .desctipfor_caixa1 = CAST(NVL(thisform.combobox_padrao2.DisplayValue,"") as M)
   
    IF .sel = 1 && Ver pq se da certo
        .tipfor_caixa1     = 1
        .desctipfor_caixa1 = "ENTRADA"
        *.forpag_id_caixa1  = 1
    ELSE 
        .tipfor_caixa1     = ICASE(SUBSTR(.desctipfor_caixa1,1,1) = "E",1,SUBSTR(.desctipfor_caixa1,1,1) = "S",2,0)
        .desctipfor_caixa1 = ICASE(SUBSTR(.desctipfor_caixa1,1,1) = "E","ENTRADA",SUBSTR(.desctipfor_caixa1,1,1) = "S","SAIDA","")
    ENDIF 


    IF NVL(.forpag_id_caixa1,0) = 0
        thisForm.wMessageBox('', "Informe a forma de recebimento",48,"Atenção")
        thisform.combobox_padrao1.SetFocus()
        RETURN .F.
    ENDIF
    
    IF EMPTY(.descricao_caixa1)
        thisForm.wMessageBox('', "Informe a forma de recebimento",48,"Atenção")
        thisform.combobox_padrao1.SetFocus()
        RETURN .F.
    ENDIF

    IF EMPTY(.desctipfor_caixa1)
        thisForm.wMessageBox('', "Informe se é uma entrada ou saida",48,"Atenção")
        thisform.combobox_padrao1.SetFocus()
        RETURN .F.
    ENDIF
    
    IF NVL(.tipfor_caixa1,0) = 0
        thisForm.wMessageBox('', "Informe se é uma entrada ou saida",48,"Atenção")
        thisform.combobox_padrao1.SetFocus()
        RETURN .F.    
    ENDIF 
    
    IF NUM_STR(thisform.textbox_padrao5.Value,10,2,"N") <= 0 &&thisform.teXTBOX_PADRAO5.Value <= 0
        thisForm.wMessageBox('', "Informe o valor corretamente",48,"Atenção")
        thisform.textbox_padrao5.SetFocus()
        RETURN
    ENDIF
    IF .alteracao = .F.
        .atualizaitens(1)
	.limpaitens()
    ELSE
        .atualizaitens(2)
	.gRID_padrao1.Enabled = .T.
	 .limpaitens()
        .alteracao = .F.
        .combobox_padrao1.Enabled = .T.
    ENDIF
    IF thisform.sel = 1 	
        .somafom()
    ENDIF
    .gRID_padrao1.Refresh()
    .combobox_padrao1.SetFocus()
ENDWITH



&& Atualizaitens Method
 LPARAMETERS __opc  && 1 para incluir e 2 para atualizar

WITH thisform
    LOCAL M.ID AS Integer  
	IF __opc = 1
	    SELECT CRCAIXA1
            APPEND BLANK IN CRCAIXA1          
            M.ID = thisform.metodo_pad.gera_id("caixa1_id_seq")
 	ELSE 
            M.ID = CRCAIXA1.ID
	ENDIF 

	REPLACE ;
	DESCRICAO  WITH .descricao_caixa1,;  
	DESCTIPFOR WITH .desctipfor_caixa1,;   
	TIPFOR     WITH .tipfor_caixa1,; 
        VALFOR     WITH NUM_STR(thisform.textbox_padrao5.Value,10,2,"N"),;
        OBSCAI     WITH thisform.textbox_padrao3.Value, ;
        FORPAG_ID  WITH .forpag_id_caixa1,;
   	ID         WITH M.ID ;   	  	 	
    IN CRCAIXA1    
    
ENDWITH 
&& Limpaitens method
thisform.combobox_padrao2.Value = "ENTRADA" 
thisform.combobox_padrao2.DisplayValue = "ENTRADA" 
THISFORM.TEXtbox_padrao3.Value  = ""
IF thisform.wlWeb = .F.
    thisform.textbox_padrao5.Value = 0.00
    thisform.textbox_padrao5.InputMask  = "9,999.99"
ELSE
    thisform.textbox_padrao5.Value = "0.00"
    thisform.textbox_padrao5.InputMask  = ""    
ENDIF    


Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  FoxInCloud Support - Thierry N.
  Arcadio Bianco
  Feb 29, 2020 @ 11:38am

Hi Arcadio

Congratulation for going to production!

From what I can see (video a little blurred), the error occurs in one of your programs. Please share the full error text so that we can discuss:

use wwRequestLog
browse for error
go bottom
&& locate the error near the end of the log
_cliptext = queryStr
&& the paste here
Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  FoxInCloud Support - Thierry N.
  Feb 29, 2020 @ 12:01pm

Thanks! Without help from everyone here on the forum this would not be possible. As for the problem, I realized that it is related to _screen.handle, since the same value is different between users and this is related to the connection to the database. Is there any treatment that I should do specifically for objects _screen ?

The error occurs exactly in this method below where the _screen is different between users.

thisform.metodo_pad.gera_id()

LPARAMETERS __NOMESEQ
DO CASE
    USE IN SELECT("MAXIMO")
    CASE ALLTRIM(_screen.tipobanco) = "POSTGRESQL"
        LOCAL M.INSTRUCAOSQL AS String 
        TEXT TO M.INSTRUCAOSQL NOSHOW 
            SELECT CAST(NEXTVAL(?__NOMESEQ) AS CHAR(13)) AS NEXTVAL
        ENDTEXT          
        M.FEZ = SQLEXEC(_screen.handle,M.INSTRUCAOSQL,[MAXIMO])
        RETURN VAL(MAXIMO.NEXTVAL)
    CASE ALLTRIM(_screen.tipobanco) = "SQL SERVER"                
        LOCAL M.INSTRUCAOSQL AS String 
        TEXT TO M.INSTRUCAOSQL NOSHOW
            SELECT SEQ + 1 AS SEQ FROM SEQUENCIA TABLOCK WHERE TABELA = ?__NOMESEQ
        ENDTEXT 
        M.FEZ = SQLEXEC(_screen.handle,M.INSTRUCAOSQL,[MAXIMO])
        M.FEZ = SQLEXEC(_screen.handle,[UPDATE SEQUENCIA SET SEQ = ?MAXIMO.SEQ WHERE TABELA = ?__NOMESEQ])
        RETURN MAXIMO.SEQ
ENDCASE
Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  FoxInCloud Support - Thierry N.
  Feb 29, 2020 @ 12:08pm

awajax.lSuccess(.f.): Error detected at code line #[no, av of method 'awajax.useraction' "FoxInCloud could not process this request: Awajax.useraction() - Error while executing method 'cad_atend1_scx.button_padrao3.Clickinet()': Method or procedure atualizaitens(): error #9 ("Data type mismatch") at code line #0 Parameters received:

  • Value : -N/A-
  • Object : button_padrao3 > Event: click > Property: none > Method: none" Call stack: 1 .processhit > 2 .process > 3 .routerequest > 4 easyprocess.process > 5 wwprocess.process > 6 easyprocess.domevent > 7 easyprocess.ajaxformrequest > 8 awajax.formrequest > 9 awajax.useraction

Exe: "C:\seazure\easylabwebfoxpro\easytest.exe", version 1.0.1397 of 2020-02-28 02:15:44 PM (4 hours ago) Process ID: 16628 Client: 189.69.166.140 userID: 5NM0PNJJX URL: http://portal.softeasy.com.br:81/easytest/DOMEvent.easy?&Event=click&ObjAddr=cad_atend1_scx-button_padrao3&UserID=5NM0PNJJX&PageInit=&nReq=57 Form variables: nKeyCode=, nButton=1, nShiftAltCtrl=0, nXcoord=508, nYcoord=165, nRow=1178, nCol=538, lastKey=13, version=2.29.0, sync=false, vpw=1381, vph=686, userID=5NM0PNJJX, reqID=1309_5PJ12EH5P-001, nInet=0.000, nCli=0.008 FAS version: 2.29.0 of 2019‑06‑06 12:05:12 PM GMT (8 months ago) Table New: 'C:\tempfic\5NM0PNJJX_5nm0pnjjx_cad_atend1_scx_New.DBF' can't be found

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  Arcadio Bianco
  Feb 29, 2020 @ 12:10pm

If I remove a part where it passes through the _screen.handle leaving a fixed value the problem does not occur

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  FoxInCloud Support - Thierry N.
  Arcadio Bianco
  Feb 29, 2020 @ 12:27pm

Arcadio,

You need to use one handle per server, shared by every users; make sure to set _screen.handle in xxxSets.init() and keep it unchanged; you can exclude it from the custom _screen.properties that FoxInCloud saves automatically for each user like this:

define class xxxServer as awServer
…
_ScreenPropertiesSaveNot = 'handle, …'

Please read the documentation on _ScreenPropertiesSave and _ScreenPropertiesSaveNot in xxxServer.prg

All your remote views or CAD share the same _screen.handle ; eg. with views:

procedure dataEnvironment.OpenTables
…
USE v_ordonnance IN 0 NODATA AGAIN CONNSTRING(_screen.handle) SHARED
…

Gilles has used this technique against a PostGre Database without any issue for almost 10 years.

Cheers

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  FoxInCloud Support - Thierry N.
  Feb 29, 2020 @ 12:53pm

The "handle" property is created in xxxinit and it has different values ??between users. Do I need to inform her in _ScreenPropertiesSave? I had understood that this was not necessary. Only if it has the same value among users should it be informed in _ScreenPropertiesSaveNot. Is my thinking correct or not? Follow below my xxxinit.

* =====================================================
DEFINE CLASS easySets as awSets of awPublic.prg && Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/03/2018 10:40
* =====================================================

&& This class is the standard implementation of application environment setting code.
&& FoxInCloud RECOMMENDS using a class as its .Destroy() method restores
&& the development environment, thus respect each developer's preferred settings.
&& If you prefer a procedural implementations, see down this file for more details.
&& If you prefer a procedural implementations, see down this file for more details.

&& To start your test FoxInCloud server, type in your Command Window:

* do <path to>easyTest

* ---------------------
PROCEDURE Init
lparameters ;
  result; && @ result of application startup - appears in .../foxincloud-status.xxx, and in server log if !m.success 
, toAppHost as awAppHost of awAppHost.fxp && Application Host object (Web mode only) 

* toAppHost gives you access to:
* - any PROTECTED property you've added to your server class - see class easyServer in easyServer.prg
* - you application's configuration object in m.toAppHost.oConfigApp - see class easyAppConfig in easyServer.prg
* - many other properties and methods that you can discover by setting a break point and typing 'm.toAppHost.' to trigger intellisense

* HINT: In your code, you may take advantage of the following properties and methods:
#if .F. && documentation
this.wlWeb && application runs in Web mode 
this.wlLAN && (this.wlLAN = !this.wlWeb) application runs in LAN (desktop) mode 
this.lDevMode && application runs in the IDE 
this.lAutomation && App works in COM mode (this.wlWeb only) 
#endif

local success as Boolean

success = DoDefault(@m.result) && IMPORTANT! sets the above properties 
if !m.success
  return .f.
endif

* PLEASE NOTE
* --------------------------------------------------------------------------------------------
* FoxInCloud Adaptation Assistant has recycled the following code from
* 'c:\seazure\easylabwebfoxpro\prg\inicio.prg'.
* This code has the main configuration features for your application.
* You probably need to review it to operate correctly in Web mode,
* especially regarding the PATHes and tests specific to LAN mode.
* Note: the awPublic.prg!wlWeb() function indicates if application runs in Web mode.
* --------------------------------------------------------------------------------------------
* If you perform a new installation after some manual modifications,
* FoxInCloud Adaptation Assistant will detect it and propose to check
* and/or save the file before eventually replace it
* --------------------------------------------------------------------------------------------

* If anything serious happens during class initialization, set:
* success = .F.
* result = [the reason(s) why environment could not be set and/or application should not start]
* in Web mode, this error will get written into the application log, and a mail sent to administrator.
* in LAN mode, you could do something similar


* Before this code executes, FoxInCloud Application Server has set CurDir() to
* the application's main folder, where project resides
* (C:\seazure\easylabwebfoxpro\)
* All the following pathes are relative to this folder …
*SET STEP ON 
SET PATH TO ".\CLASSE\;.\FIGURA\;.\FORM\;.\IMG\BMP\;.\IMG\ICO\;.\MENU\;.\PRG\" ADDITIVE
SET PATH TO ".\_Libs\xfrx\" ADDITIVE

IF !InList(_VFP.StartMode, 2, 3, 5) && In COM automation mode, Visual FoxPro implicitly performs a SET PROCEDURE and a SET CLASSLIB to the entire server by default when you instantiate an .exe or .dll COM server - if you reissue SET PROC or SET CLASSLIB repeatedly, COM object performance will drop sharply 

  SET PROCEDURE TO acessoftp,conecta,conecta_interface,figuras,foxbarcode,ftp,funcao,gpimage2,inicio,inicio_appse,inicio_fila,inicio_interface,inicio_libexa,inicio_sms,inicio_soroteca,inicio_triagem,menunew,registry,setobjrf,som,vfptranslator,zip,menufic,utilityreportlistener ADDITIVE

  ClassLibAdd("_base.vcx,_controls.vcx,_webview.vcx,_ws3client.vcx,ambiente.vcx,barra.vcx,dados.vcx,foxcharts.vcx,lanca.vcx,laudo.vcx,msoexp.vcx,padrao.vcx,rtfbar.vcx,sfmenu.vcx,systray.vcx,termo.vcx,themedtitlebar.vcx,themedtitlebarbase.vcx,treeview.vcx,txtext"+"control19.vcx,vfp-skin2.vcx,easy.vcx") && modify command abDev
  EXTERNAL PROCEDURE ClassLibAdd

ENDIF

PUBLIC M.VERSAOEL, M.VERMAJOR AS Character, M.VERMINOR AS Character, M.VERREV AS Character  && Variaveis que informam qual é a versao do sistema
PUBLIC M.VISUEMTELA AS Boolean && Variavel para ser usada pela visualizacao do  mapa de trabalho
PUBLIC oPARAM       && Objeto com as configuracoes gerais do sistema
PUBLIC _prot        && Objeto de protecao do sistema
PUBLIC oMENS        && Objeto para exibir corretamente a barra de informacoes no rodapé do sistema
PUBLIC M.VERSAOEL   && Variavel que informa qual é a versao do sistema
PUBLIC M.DATLICATU  && Data atual em que a licença do sistema se expira
PUBLIC M.oFOXBARCODE
PUBLIC oMENU        && Objeto com as propiedades do menu
PUBLIC M.FIGLAUDO
LOCAL M.TITPROG as String, M.IDPARAM AS Integer
PUBLIC oOPERADOR AS Object
PUBLIC M.OBARRA as Toolbar
PUBLIC m.OBJMENU as Object
PUBLIC M.ID_ATU 
PUBLIC M.PATHTMP
*M.ID_ATU = NULL

&& Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/02/2018 19:57
*-FIC-  (see above) SET PATH TO (Home(1) + 'Tools\' + 'AB\') ADDITIVE
*-FIC-  (see above) AB() && loads FoxInCloud public modules located in the above folder, and shared on GitHub: https://github.com/FoxInCloud/FoxInCloud-AB.git
*-FIC-  (see above) SET CLASSLIB TO (Addbs(JustPath(Sys(16))) + '..\CLASSE\EASY.VCX') ADDITIVE && easy.vcx derives from aw.vcx
&& Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/02/2018 19:57

&& /!\ make sure all SET PATH/LIBRary/CLASslib/PROCedure
&& executed after this line have the ADDITIVE clause


&& Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/02/2018 10:06:32
*-FIC-  (see above) SET PATH TO (Home(1) + 'Tools\' + 'AB\') ADDITIVE
*-FIC-  (see above) AB() && loads FoxInCloud public modules located in the above folder, and shared on GitHub: https://github.com/FoxInCloud/FoxInCloud-AB.git
*-FIC-  (see above) SET CLASSLIB TO (Addbs(JustPath(Sys(16))) + '..\CLASSE\EASY.VCX') ADDITIVE && easy.vcx derives from aw.vcx
&& Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/02/2018 10:06:32

&& /!\ make sure all SET PATH/LIBRary/CLASslib/PROCedure
&& executed after this line have the ADDITIVE clause


&& Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/01/2018 19:18:49
*-FIC-  (see above) SET PATH TO (Home(1) + 'Tools\' + 'AB\') ADDITIVE
*-FIC-  (see above) AB() && loads FoxInCloud public modules located in the above folder, and shared on GitHub: https://github.com/FoxInCloud/FoxInCloud-AB.git
*-FIC-  (see above) SET CLASSLIB TO (Addbs(JustPath(Sys(16))) + '..\CLASSE\EASY.VCX') ADDITIVE && easy.vcx derives from aw.vcx
&& Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/01/2018 19:18:49

&& /!\ make sure all SET PATH/LIBRary/CLASslib/PROCedure
&& executed after this line have the ADDITIVE clause


&& Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/01/2018 15:56
*-FIC-  (see above) SET PATH TO (Home(1) + 'Tools\' + 'AB\') ADDITIVE
*-FIC-  (see above) AB() && loads FoxInCloud public modules located in the above folder, and shared on GitHub: https://github.com/FoxInCloud/FoxInCloud-AB.git
*-FIC-  (see above) SET CLASSLIB TO (Addbs(JustPath(Sys(16))) + '..\CLASSE\EASY.VCX') ADDITIVE && easy.vcx derives from aw.vcx
&& Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/01/2018 15:56

&& /!\ make sure all SET PATH/LIBRary/CLASslib/PROCedure
&& executed after this line have the ADDITIVE clause

*-FIC- (see above) PUBLIC M.VERSAOEL, M.VERMAJOR AS Character, M.VERMINOR AS Character, M.VERREV AS Character  && Variaveis que informam qual é a versao do sistema
M.VERSAOEL = ""
M.VERMAJOR = ""
M.VERMINOR = ""
M.VERREV = ""
*CLOSE DATABASES ALL
*SET SYSMENU OFF
SET NOTIFY CURSOR OFF
SET NOTIFY OFF
SET STATUS OFF
SET DATE BRITISH
SET CONSOLE OFF
SET CONFIRM ON
SET SAFETY OFF
SET BELL OFF
SET REPORTBEHAVIOR 80
SET MESSAGE TO ""
SET TALK OFF
SET NULL OFF
SET NULLDISPLAY TO ""
SET ESCAPE OFF
SET TABLEPROMPT OFF
*-FIC-  (see above) SET PROCEDURE TO PRG\FUNCAO.PRG, PRG\REGISTRY.PRG, PRG\ZIP.PRG , PRG\VFPTRANSLATOR.PRG, PRG\ACESSOFTP.PRG, PRG\FTP.PRG, PRG\FOXBARCODE.PRG, PRG\GPIMAGE2.PRG, PRG\MENUNEW.PRG
*-FIC-  (see above) SET CLASSLIB TO classe\ambiente, classe\dados, classe\padrao, classe\lanca ,classe\laudo, classe\termo, classe\barra ,classe\menu, classe\vfp-skin2 ADDITIVE
*-FIC-  (see above) SET CLASSLIB TO classe\_base, classe\treeview, classe\foxcharts, classe\gdiplusx, classe\rtfbar, classe\txtextcontrol19, classe\themedtitlebar, classe\themedtitlebarbase ADDITIVE
*-FIC-  (see above) SET CLASSLIB TO classe\_ws3client.vcx, classe\sfmenu.vcx, classe\_controls.vcx, classe\_webview.vcx  ADDITIVE
*!*	IF SYSMETRIC(1) = 800
*!*	    _screen.picture     = 'FundoEasylab800.jpg'
*!*	ELSE
*!*	    IF SYSMETRIC(1) = 1024
*!*	        _screen.picture     = 'FundoEasylab1024.jpg'
*!*	    ELSE
*!*	        _screen.picture     = 'FundoEasylab.jpg'
*!*	    ENDIF
*!*	ENDIF
IF this.wlWeb = .F.
	DO CASE
	        CASE SYSMETRIC(1) = 1024
	        	_screen.picture   = "C:\SE\EASYLABFOXPRO\FIGURA\LAB1024.JPG"

	        CASE SYSMETRIC(1) = 1280
	        	_screen.picture   = "C:\SE\EASYLABFOXPRO\FIGURA\LAB1280.JPG"

	        CASE SYSMETRIC(1) = 1366
	        	_screen.picture   = "C:\SE\EASYLABFOXPRO\FIGURA\LAB1366.JPG"

	        CASE SYSMETRIC(1) = 1440
	        	_screen.picture   = "C:\SE\EASYLABFOXPRO\FIGURA\LAB1440.JPG"

	        CASE SYSMETRIC(1) = 1920 OR SYSMETRIC(1) = 1536
	        	_screen.picture   = "C:\SE\EASYLABFOXPRO\FIGURA\LAB1920.JPG"

	        OTHERWISE
	         	_screen.picture   = "C:\SE\EASYLABFOXPRO\FIGURA\LAB1024.JPG"
	ENDCASE

	_screen.icon        = "c:\se\easylabfoxpro\figura\easylabnew.ico"
	_screen.Closable    = .T.
ENDIF 

_screen.AddObject("metodo_pad","metodo_pad")

*-FIC- (see above) PUBLIC M.VISUEMTELA AS Boolean && Variavel para ser usada pela visualizacao do  mapa de trabalho
M.VISUEMTELA = .F.

*-FIC- (see above) PUBLIC oPARAM       && Objeto com as configuracoes gerais do sistema
*-FIC- (see above) PUBLIC _prot        && Objeto de protecao do sistema
*-FIC- (see above) PUBLIC oMENS        && Objeto para exibir corretamente a barra de informacoes no rodapé do sistema
*-FIC- (see above) PUBLIC M.VERSAOEL   && Variavel que informa qual é a versao do sistema
*-FIC- (see above) PUBLIC M.DATLICATU  && Data atual em que a licença do sistema se expira
*-FIC- (see above) PUBLIC M.oFOXBARCODE
M.oFOXBARCODE = CREATEOBJECT("FoxBarcode")
*-FIC- (see above) PUBLIC oMENU        && Objeto com as propiedades do menu
*-FIC- (see above) PUBLIC M.FIGLAUDO
M.FIGLAUDO = 0
*SET STEP ON
IF !FILE("FoxTools.fll")
    *-FIC- Replaced by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/01/2018 15:56
    *-FIC- MESSAGEBOX("Para o número da versão ficar disponivel no sistema é necessario o arquivo FOXTOOLS.FLL estar na pasta do
    *-FIC- sistema, baixe o mesmo no link http://www.softeasy.com.br/UTILS/foxtools.fll ou por favor entrar em contato com o
    *-FIC- suporte técnico.",48,"Atenção")

*-FIC-  (In web mode, no user can attend modal state at app startup, please condition with [if this.wlLAN])     wMessageBox("Para o número da versão ficar disponivel no sistema é necessario o arquivo FOXTOOLS.FLL estar na pasta do sistema, baixe o mesmo no link http://www.softeasy.com.br/UTILS/foxtools.fll ou por favor entrar em contato com o suporte técnico.",48,"Atenção")
ELSE
	*** Informações sobre o Sistema ***
*-FIC-  (see above) 	set library to FoxTools additive
	IF this.wlWeb = .F.
		dimension vSW_Info(12)
		GetFileVersion( sys(16,0), @vSW_Info )

		*!*	vSW_Info(1)                          &&      1 Comentários / Comments
		*!*	vSW_Info(2)                          &&      2 Nome da empresa / Company Name
		*!*	vSW_Info(3)                          &&      3 Descrição do arquivo / File Description
		*!*	vSW_Info(4)                          &&      4 Versão do arquivo / File Version
		*!*	vSW_Info(5)                          &&      5 Nome interno / Internal Name
		*!*	vSW_Info(6)                          &&      6 Direitos Legais de Copyright / Legal Copyright
		*!*	vSW_Info(7)                          &&      7 Marcas Legais registradas / Legal Trademarks
		*!*	vSW_Info(8)                          &&      8 Nome original do arquivo / Original File Name
		*!*	vSW_Info(9)                          &&      9 Construção privada / Private Build
		*!*	vSW_Info(10)                         &&      10 Nome do produto / Product Name
		*!*	vSW_Info(11)                         &&      11 Versão do produto / Product Version
		*!*	vSW_Info(12)                         &&      12 Construção especial / Special Build
		M.VERSAOEL = vSW_Info(4)
		M.VERMAJOR = ALLTRIM(GETWORDNUM(M.VERSAOEL, 1, "."))
		M.VERMINOR = ALLTRIM(GETWORDNUM(M.VERSAOEL, 2, "."))
	    M.VERREV = ALLTRIM(GETWORDNUM(M.VERSAOEL, 3, "."))
    ENDIF 	    
ENDIF

*-FIC- (see above) LOCAL M.TITPROG as String, M.IDPARAM AS Integer

TRY
    M.TITPROG  = "Easylab Sistema de Gestão Laboratorial Versão " + M.VERSAOEL + " - Softeasy Tecnologia "
    CATCH
    M.VERSAOEL = "99.99.99"
    M.TITPROG  = "Easylab Sistema de Gestão Laboratorial Versão " + M.VERSAOEL + " - Softeasy Tecnologia "
ENDTRY

IF this.wlWeb = .F.
	IF IsAppRunning(M.TITPROG)
	    QUIT
	ENDIF

	IF VAL(STR(VAL(STRTRAN(VERSION(4),".","")),15)) < 90000007423
	    *-FIC- Replaced by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/01/2018 15:56
	    *-FIC- MESSAGEBOX("Para o funcionamento correto do sistema é necessario a atualização das dlls do mesmo, favor entrar em
	    *-FIC- contato com o suporte técnico",48,"Atenção")

	*-FIC-  (In web mode, no user can attend modal state at app startup, please condition with [if this.wlLAN])     wMessageBox("Para o funcionamento correto do sistema é necessario a atualização das dlls do mesmo, favor entrar em contato com o suporte técnico",48,"Atenção")
	    *QUIT
	ENDIF

	IF !FILE("SYSTEM.APP")
	    *-FIC- Replaced by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/01/2018 15:56
	    *-FIC- MESSAGEBOX("Para o funcionamento correto do sistema é necessario o arquivo SYSTEM.APP estar na pasta do sistema, favor
	    *-FIC- entrar em contato com o suporte técnico",48,"Atenção")

	*-FIC-  (In web mode, no user can attend modal state at app startup, please condition with [if this.wlLAN])     wMessageBox("Para o funcionamento correto do sistema é necessario o arquivo SYSTEM.APP estar na pasta do sistema, favor entrar em contato com o suporte técnico",48,"Atenção")
	    *QUIT
	ENDIF

	IF !FILE("richtx32.ocx")
	    *-FIC- Replaced by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/01/2018 15:56
	    *-FIC- MESSAGEBOX("Para o funcionamento correto do sistema é necessario o arquivo RICHTX32.OCX estar na pasta do sistema,
	    *-FIC- favor entrar em contato com o suporte técnico",48,"Atenção")

	*-FIC-  (In web mode, no user can attend modal state at app startup, please condition with [if this.wlLAN])     wMessageBox("Para o funcionamento correto do sistema é necessario o arquivo RICHTX32.OCX estar na pasta do sistema, favor entrar em contato com o suporte técnico",48,"Atenção")
	ENDIF

	IF !FILE("TX4OLE19.OCX")
	    *-FIC- Replaced by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/01/2018 15:56
	    *-FIC- MESSAGEBOX("Para o funcionamento correto do sistema é necessario o arquivo TX4OLE19.OCX estar na pasta do sistema,
	    *-FIC- favor fazer o download no link www.softeasy.com.br/UTILS/comrtf19arqs.zip ou entrar em contato com o suporte
	    *-FIC- técnico",48,"Atenção")

	*-FIC-  (In web mode, no user can attend modal state at app startup, please condition with [if this.wlLAN])     wMessageBox("Para o funcionamento correto do sistema é necessario o arquivo TX4OLE19.OCX estar na pasta do sistema, favor fazer o download no link www.softeasy.com.br/UTILS/comrtf19arqs.zip ou entrar em contato com o suporte técnico",48,"Atenção")
	ENDIF

	_screen.Caption     = M.TITPROG
	_screen.Themes      = .T.
	_screen.WindowState = 2
ENDIF 

ON SHUTDOWN sair()

ON ERROR DO CTRERRO With Upper(Message()), Program(), LTrim(Str(LineNo()))
*On Error Do TrataErro With Error( ), Message( ), Message(1), Program( ), Lineno( )

_screen.AddProperty("sist_apoio",0)     && Informa se o sistema é o de apoio
_screen.AddProperty("opera",0)          && Propriedade do operador logado no sistema
_screen.AddProperty("nomeopera","")     && Propriedade com o nome operador logado no sistema
_screen.AddProperty("valorbusca",0)     && Local para armazenar valores entre cadastros
_screen.AddProperty("valorbusca2",0)    && Local para armazenar valores entre cadastros
_screen.AddProperty("handle",0)         && Cria propriedade de conexao com o banco de dados
_screen.AddProperty("Confirma",0)       && Confirma ou não a deleção do registro
_screen.AddProperty("Codigocaixa",0)    && Codigo do caixa atual
_screen.AddProperty("Justificativa","") && Justificativa
_screen.AddProperty("tipobanco","")
_screen.AddProperty("internet",0)
_screen.AddProperty("captionform","")   && Guarda caption do form
_screen.AddProperty("visivelmapa",.F.)   && para botao sair mapa ficar visivel
_screen.AddProperty("demo",.F.)
_screen.AddProperty("gravapos",.F.)
_screen.AddProperty("gravaset",.F.)
_screen.AddProperty("gravagrade",.F.)
_screen.AddProperty("gravaposimp",.F.)
_screen.AddProperty("mapa_id",0)
_screen.AddProperty("exameanterior",0)
_screen.AddProperty("assope",0)          && Propriedade do operador que assinou o exame
_screen.AddProperty("postopadrao","")   && Guarda posto padrao para cadastro rapido
_screen.AddProperty("dataentregaf","")     && Propriedade com o a frase FALTA MATERIAL - MEDRADIUS MACEIO
_screen.AddProperty("inter",.F.)         && saber se esta no sistema interface
_screen.AddProperty("fila",.F.)         && saber se esta no sistema fila
_screen.AddProperty("temvalesp",.F.) && saber se tem valor especial para copiar
_screen.AddProperty("tipografico",0)     && Propriedade tipo de grafico para preencher combo
_screen.AddProperty("subtitulo","")     && Propriedade sub titulo grafico
_screen.AddProperty("usagrafico",.F.)     && Propriedade usa grafico laudo
_screen.AddProperty("temexadesc",.F.) && saber se tem exames descobertos para copiar
*_screen.AddProperty("etq",.F.)
_screen.AddProperty("liberacaopac",0)  && Indica qual foi a liberacao no paciente 8-so o exame 9-todos exames 0-nenhum
_screen.AddProperty("lancou",0)
_screen.AddProperty("custopac",0)
_screen.AddProperty("altcustopac",.F.)
_screen.AddProperty("caminhotxt","")  && caminho txt colocado para arquivo tipo mtx - Edgar - 06.06.2011
_screen.AddProperty("datlicatu","")  && propriedade de data licença atual
_screen.AddProperty("cripto_pass",0)
_screen.AddProperty("cmdatu","")
_screen.AddProperty("ultimaacao",TIME()) && grava o hora da ultima acao do operador no sistema
_screen.AddProperty("ope_verificado",0)
_screen.AddProperty("posamopdf",IIF(VARTYPE(__posamopdf) = "C",__posamopdf,""))
_screen.AddProperty("isdll",.F.)
_screen.AddProperty("isapp",.F.)
_screen.AddProperty("visu_laudoimp",.F.)
_screen.AddProperty("fillibconv","")
_screen.AddProperty("fillibset",0)
_screen.AddProperty("fillibpos","")
_screen.AddProperty("filtdev",.F.)
_screen.AddProperty("pedcarteirinha",.F.) && pedir para ler carteirinha do usuario da unimed - usa validador para compor a trilha1 e trilha2
_screen.AddProperty("valcarteirinha","") && conteudo carteirinha do usuario da unimed - usa validador para compor a trilha1 e trilha2
_screen.AddProperty("validadorindcli","") && indicação clinica para gerar no validador online
_screen.AddProperty("laudoweb",.F.)
_screen.AddProperty("idfila",0) && guardar id fila para atualizar o movpac_id
_screen.AddProperty("senha_certificado_rt_atu","")
_screen.AddProperty("restelalib",0)
_screen.AddProperty("dthorachecon",CTOT(""))
_screen.AddProperty("rascunho_lau",0)
_screen.AddProperty("medicorea_id",0)
_screen.AddProperty("nome_medrea","")
_screen.AddProperty("crm_medrea","")
_screen.AddProperty("prontu_id",0)
_screen.AddProperty("alteraplano",.F.)
_screen.AddProperty("incluiureg",0)
_screen.AddProperty("regidatu",NULL)
_screen.AddProperty("dominio",NULL)
_screen.AddProperty("cmdatu_dominio","")
_screen.AddProperty("handle_dominio",0)
_screen.AddProperty("id_dominio",0)
_screen.AddProperty("ihandle",0)
_screen.AddProperty("debug_web",.F.)
_screen.AddProperty("atendinclusoag",.F.)
_screen.AddProperty("movpac_id_atendinclusoag",0)


 
return m.success && application won't start if .F. 
endproc

* ---------------------
PROCEDURE Destroy

* add here [or move from this.init()]
* the instructions you need to execute when application unloads,
* such as garbage collection and/or RemoveProperty(_Screen, ...)

return DoDefault()
* You don't need to restore Set("Path"), Set("Procedure") and Set("Classlib")
* as DoDefault() does this automatically.
endproc

* =====================================================
ENDDEFINE && CLASS easySets && Added by FoxInCloud Adaptation Assistant version 2.26 (source mode) on 06/03/2018 10:40
* =====================================================


&& This is a sample program for SETting application's environment
&& Ideally your application's LAN (desktop) and WEB versions SHARE this module
&& You may use either of these three implementations (see properties in easyServer.prg):

&& Implementation              .cAppSetsLib    .cAppSets     .lAppSetsClass
&& ---------------------       -------------   ----------    ---------------
&& 1-Instantiate 'easySets'     'easySets.prg'   'easySets'     .T.
&& 2-Execute this program      'easySets.prg'   ''            .F.
&& 3-Execute 'easySets' proc    'easySets.prg'   'easySets'     .F.

&& Notes:
&& - In Web mode, as usually in LAN/desktop mode, when this module executes,
&& Curdir() is main program's folder where the project sits: '..\' in this case
&& - As FoxInCloud executes application in a Session class,
&& dataSession-dependant SETtings don't need be restored





#IF .F. && move or delete this line if you intend to adapt this code  && 

&& SAMPLE IMPLEMENTATION # 1 (RECOMMENDED): instantiate an 'easySets' class
* ===================================================
&& In this implementation this.Destroy() restores initial environment (useful during development)
* ===================================================
DEFINE CLASS easySets as awSets of awPublic.prg

* ---------------------
PROCEDURE Init
lparameters ;
  result; && @ result of application startup - appears in .../foxincloud-status.easy 
, toAppHost as awAppHost of awAppHost.fxp && Web Application Host object 
	
* m.toAppHost provides access to:
* - any PROTECTED property added to your server class > modify command easyServer.prg - class easyServer
* - your application's configuration object in m.toAppHost.oConfigApp > modify command easyServer.prg - class easyAppConfig
* - many other properties and methods that you can discover by setting a break point and typing 'm.toAppHost.' to trigger intellisense

* HINT
* Your code can take advantage of the following properties and methods:
#if .F.
this.wlWeb && = !this.wlLAN && application runs in Web mode 
this.wlLAN && = !this.wlWeb && application runs in LAN (desktop) mode 
this.lDevMode && application runs in development mode 
this.Set(<setting>, <value> [, 1,2,...]) && performs a SET and restores with this.destroy() - see abDev.prg!abSet 
#endIf

local success as Boolean
success = DoDefault(@m.result) && sets this.wlWeb, this.wlLAN, this.lDevMode, this.oConfigApp (from easyTest|Prod.ini) 
if m.success

	&& at this point, curdir() is folder where main program sits, you can easily add child folders to set('path')
	SET PATH TO 'progs,forms,reports,images,data' ADDITIVE && ADDITIVE don't forget! 
	
	if !this.lAutomation && in automation mode, VFP automatically SETs PROCEDURE and CLASSLIB to any file included - reSETting to these files can cause a runtime error
		SET PROCEDURE TO myStuff1, myStuff2 ADDITIVE && ADDITIVE don't forget! 
		SET CLASSLIB TO myClasses ADDITIVE && ADDITIVE don't forget! 
	endIf
	
	SET DELETED OFF
	SET SAFETY OFF
	SET DATE AMERICAN
	
	if m.this.wlLAN
		SET TALK OFF
	endIf
	
	OPEN DATABASE myDatabase
	
	wMenu('set sysmenu to') && remove system menu 
	do myMenu.mpr && installs application's menu 
	
endif

* FoxInCloud Application Server instantiates forms dynamically, you should not execute any form here
* In Web mode, easyProcess.Index (modify command easyServer) executes your startup form (eg login or splash)
* In LAN mode, your startup program should display the initial form after this has completed


* If anything serious happens during class initialization, set:
* success = .F.
* result = [the reason(s) why environment could not be set and/or application should not start]
* in Web mode, this error will get written into the application log, and a mail sent to administrator.
* in LAN mode, you could do something similar

return m.success
endProc

* ---------------------
PROCEDURE Destroy

* here, restore environment items that are not handled automatically
endProc

* ---------------------
hidden procedure Init_dataSession_for_child_forms_launched_at_startup
lparameters ;
  result as String; && @ error if any 
, toAppHost as awAppHost of awAppHost.fxp; && Application Host object 

* sample method
* for child forms launched at server startup, use the aliases they would normally find in a parent form dataSession
* ouvre les alias dont les écrans enfant lancés au démarrage ont besoin hors du contexte de leur écran parent

if Empty(m.toAppHost.uFormsLaunchAtStartup)
	return
endIf

local success as Boolean

success = .T.

open database easy

if lInList('myForm1.scx', m.toAppHost.uFormsLaunchAtStartup)
	success = this.use('view1;view2;table1,Alias1') and m.success
endIf

if lInList('myForm2.scx', m.toAppHost.uFormsLaunchAtStartup)
	success = this.use('view2;view3;table2') and m.success
endIf

return m.success
endProc

* ---------------------
hidden procedure use
lparameters ;
  result as String; && @ error if any 
, aliases; && Aliases to use 

* sample method
* uses a list of tables and/or views
* ouvre une liste de tables et/ou de vues

local success as Boolean;
, aView[1] as String;
, nView as Integer;
, aTable[1] as String;
, cTable as String;
, cAlias as String;
, cNoData as String;
, oException as Exception;

nView = ADBObjects(aView, "VIEW")

success = .T.

if ALines(m.aTable, m.aliases, 5, ';') > 0
	for each cTable in m.aTable
		
		try
			cAlias = Evl(GetWordNum(m.cTable, 2, ','), JustStem(m.cTable))
			cTable = JustStem(GetWordNum(m.cTable, 1, ','))
			if !Used(m.cAlias)
				cNoData = Iif(Ascan(m.aView, m.cTable, 1, -1, 1, 7) > 0, 'NODATA', '')
				use (m.cTable) alias (m.cAlias) in 0 again shared &cNoData
			endIf

			do case
			case Lower(m.cTable) == Lower('countryCodes')
				&& this view requires data loaded; eg view on a referential table such as country codes ...
				local parm1, parm2
				parm1 = someValue
				parm2 = otherValue
				Requery(m.cAlias)
			endCase
		catch to oException
			success = cResultAdd(@m.result, cException(m.oException)) && cResultAdd(), cException(): modify command abDev
		endtry
	endFor
endIf

return m.success
endProc

ENDDEFINE && CLASS easySets






&& SAMPLE IMPLEMENTATION # 2: execute 'easySets.prg'
* ---------------------------------------------------
SET PATH TO 'progs,forms,reports,images,data' ADDITIVE && ADDITIVE don't forget! 

if !wlAutomation()
	SET PROCEDURE TO myStuff1, myStuff2 ADDITIVE && ADDITIVE don't forget! 
	SET CLASSLIB TO myClasses ADDITIVE && ADDITIVE don't forget! 
endIf

SET DELETED OFF
SET SAFETY OFF
SET DATE AMERICAN

OPEN DATABASE myDatabase

&& ...

&& SAMPLE IMPLEMENTATION # 3: execute 'easySets' procedure
* ---------------------------------------------------
PROCEDURE easySets

SET PATH TO 'progs,forms,reports,images,data' ADDITIVE && ADDITIVE don't forget! 

if !wlAutomation()
	SET PROCEDURE TO myStuff1, myStuff2 ADDITIVE && ADDITIVE don't forget! 
	SET CLASSLIB TO myClasses ADDITIVE && ADDITIVE don't forget! 
endIf

SET DELETED OFF
SET SAFETY OFF
SET DATE AMERICAN

OPEN DATABASE myDatabase

&& ...

endProc


#endIf  && move this if you intend to adapt this code  && 

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  FoxInCloud Support - Thierry N.
  Arcadio Bianco
  Feb 29, 2020 @ 02:40pm
procedure xxxSets.Init()
_screen.AddProperty("handle", sqlstringconnect(…)) && not 0

define class xxxServer as awServer
…
_ScreenPropertiesSaveNot = 'handle, …'
Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  FoxInCloud Support - Thierry N.
  Mar 1, 2020 @ 10:14pm

It seems that the error is related to the time to update the environment and the connection between users, due to the value of handle being different between them because they are different databases. I includes a "While" in the command that generates the sequential and apparently solved the problem.

LPARAMETERS __opc  && 1 para incluir e 2 para atualizar

WITH thisform
    LOCAL M.ID AS Integer  
	IF __opc = 1
	     SELECT CRCAIXA1
	     APPEND BLANK IN CRCAIXA1          
             M.ID = 0
             DO WHILE M.ID = 0 && While Included
                 M.ID = CAST(.metodo_pad.gera_id("caixa1_id_seq") AS I)
             ENDDO  
 	ELSE 
            M.ID = CRCAIXA1.ID
	ENDIF 

	REPLACE ;
	DESCRICAO  WITH .descricao_caixa1,;  
	DESCTIPFOR WITH .desctipfor_caixa1,;   
	TIPFOR     WITH .tipfor_caixa1,; 
        VALFOR     WITH NUM_STR(thisform.textbox_padrao5.Value,10,2,"N"),;
        OBSCAI     WITH thisform.textbox_padrao3.Value, ;
        FORPAG_ID  WITH .forpag_id_caixa1,;
   	ID         WITH M.ID ;   	  	 	
       IN CRCAIXA1    
ENDWITH 
Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Gilles Lajot-Sarthou
  Arcadio Bianco
  Mar 1, 2020 @ 10:46pm

Hi Arcadio

I have made the same thing in my code.. Insert a SqlStringConnect() in a do while enddo..

				iDebut = SECONDS()
				DO WHILE .T.
					DOEVENTS
					_SCREEN._gnconnect = SQLSTRINGCONNECT(m.cChaineConnexion, .T.)
					IF NVL(_SCREEN._gnconnect, 0) > 0
						=SQLSETPROP(_SCREEN._gnconnect,"ConnectTimeOut",30) && timeout 30 secondes
						* Connexion réussie
						=STRTOFILE(TTOC(DATETIME()) + ': ' + ALLTRIM(STR(_VFP.PROCESSID)) + '-->' + 'Connexion N°' + ALLTRIM(STR(_SCREEN._gnconnect)) + CHR(13) + CHR(10), _SCREEN._locale + '_postgresql.log', 1)
						lReturn = .T.
						EXIT
					ENDIF
					IF SECONDS() > m.iDebut + 30
						* Echec connexion
						EXIT
					ENDIF
					=Sleep(150)
				ENDDO

Regards Gilles

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  FoxInCloud Support - Thierry N.
  Arcadio Bianco
  Mar 2, 2020 @ 03:34am

OK, I now understand that each user (I guess based on the company he/she belongs to/works for) needs a specific database handle.

As we have no experience with such an architecture I would rather install one site and one application per client company: company1.easysoft.com, company2.easysoft.com, etc., each in a separate folder with a separate EXE; it'd require that you either have one project per company (just for generating specific COM object GUID) or manipulate _VFP.activeProject.GUID programmatically when generating the web EXEs per company.

However, your system should theoretically work fine, for the reasons hereafter.

FoxInCloud restores the application environment, including _Screen.properties, as a VERY FIRST STEP before doing anything on the application; you can see it on the FoxInCloud Web App Dashboard such as this one, column restoring app. state for user.

So, if your server saves _Screen.handle (thus not add handle it to xxxServer._ScreenPropertiesSaveNot as I wrote earlier, before having the full picture), FoxInCloud restores it before querying any view or CAD, and it should always be so.

Of course, as the user can call any master form in any order (using an URL in history), he/she can query a form while having _screen.handle = 0 and get into trouble. To overcome this, you NEED to check that ONLY THE LOGIN FORM (setting _screen.handle for the user) has .wlAnonymousAllowed = .T..

That's all I can tell for now…

Update: a side benefit of having one site and app per company is that it makes it easier to upgrade a company on another server when traffic increases. By merging all companies into a single application you may get into troubles at some point down the road.

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  FoxInCloud Support - Thierry N.
  Mar 2, 2020 @ 05:25am

Hi Thierry,

I understood what you said. I will think here. However, I don't think I should be no "handle" errors just because of the fact that there are quick actions between different user sessions. As for my idea of several customers using the same installation, this would not be mandatory, it would be just another way of using our app. We are considering all possible scenarios and the scenario of several customers in a single installation would be more possible for smaller customers.

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  FoxInCloud Support - Thierry N.
  Arcadio Bianco
  Mar 2, 2020 @ 05:33am

quick actions between different user sessions

whether user actions are quick or slow makes NO difference at all.

User status, including app environment:

  • is saved after EACH user action
  • is restored before executing user action whenever the current user is different from the previous user on the current server.

Please keep in mind that, in production, you'll run several logical servers (COM/EXE) on the same machine (WC supports up to 32). So users will switch between logical servers.

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Gilles Lajot-Sarthou
  Arcadio Bianco
  Mar 2, 2020 @ 07:15am

Arcadio

In this case, what are the reasons why the users of the different client companies would not use the same database with the same PostGresQL handle? This is what I do, I just add in each table a column to identify the company of the connected customer and all my views or SQLEXE commands () use this column to filter the records accessible by the user. This requires, of course, that the data structure of the database is the same for all tables and for all client companies.

Gilles

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  Gilles Lajot-Sarthou
  Mar 2, 2020 @ 07:18am

Hello Giles,

We would have to totally rewrite our software for that. My idea is good as long as it works, since the customer's postrgresql database could in theory be anywhere.

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  Arcadio Bianco
  Mar 2, 2020 @ 07:28am

For some reason, if access quickly enters the sessions, the _screen.tipobanco property is going blank and that is the reason for the problem. However, I did not identify the cause of this. It is reported correctly in xxxsets.ini. Follow below the link video with the problem.

https://youtu.be/VyBMt-wQxa4

&& gera_id method.
LPARAMETERS __NOMESEQ
DO CASE
    USE IN SELECT("MAXIMO")
    CASE ALLTRIM(_screen.tipobanco) = "POSTGRESQL" OR ALLTRIM(_screen.tipobanco) = "CACHE" 
        LOCAL M.INSTRUCAOSQL AS String 
        TEXT TO M.INSTRUCAOSQL NOSHOW 
            SELECT CAST(NEXTVAL(?__NOMESEQ) AS CHAR(13)) AS NEXTVAL
        ENDTEXT          
        IF SQLEXEC(_screen.handle,M.INSTRUCAOSQL,[MAXIMO]) > 0
            *SELECT maximo
            *COPY TO C:\seazure\easylabwebfoxpro\maximo   
            STRTOFILE(CAST(_screen.dominio as m),"C:\seazure\easylabwebfoxpro\a.txt")        
            RETURN CAST(MAXIMO.NEXTVAL as i)
        ELSE 
            STRTOFILE(CAST(_screen.dominio as m),"C:\seazure\easylabwebfoxpro\b.txt")   
            RETURN 0
        ENDIF     
    CASE ALLTRIM(_screen.tipobanco) = "SQL SERVER"                
        LOCAL M.INSTRUCAOSQL AS String 
        TEXT TO M.INSTRUCAOSQL NOSHOW
            SELECT SEQ + 1 AS SEQ FROM SEQUENCIA TABLOCK WHERE TABELA = ?__NOMESEQ
        ENDTEXT 
        M.FEZ = SQLEXEC(_screen.handle,M.INSTRUCAOSQL,[MAXIMO])
        M.FEZ = SQLEXEC(_screen.handle,[UPDATE SEQUENCIA SET SEQ = ?MAXIMO.SEQ WHERE TABELA = ?__NOMESEQ])
        STRTOFILE(CAST(_screen.dominio as m),"C:\seazure\easylabwebfoxpro\c.txt")   
        RETURN MAXIMO.SEQ
ENDCASE
STRTOFILE(CAST(_screen.dominio as m),"C:\seazure\easylabwebfoxpro\d.txt")  
STRTOFILE(CAST(__NOMESEQ as m),"C:\seazure\easylabwebfoxpro\e.txt")    
STRTOFILE(CAST(_screen.tipobanco as m),"C:\seazure\easylabwebfoxpro\e.txt") 
Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Vincent H.
  Arcadio Bianco
  Mar 2, 2020 @ 07:51am

Hi Arcadio,

For STRTOFILE(), you should have a different file for each screen, right ?

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  Vincent H.
  Mar 2, 2020 @ 07:56am

I used the strtofile to debug, as it is a difficult problem to find. The right thing would be to generate only A.txt and never d.txt and e.txt. Something is erasing the _screen.tipobanco property

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  FoxInCloud Support - Thierry N.
  Arcadio Bianco
  Mar 2, 2020 @ 09:03am

It is reported correctly in xxxsets.ini

do you mean xxxSets.init()?

I see no reason why the problem would occur in COM mode and not in IDE mode.

As you know the reason for the problem (empty(_Screen.tipobanco)), you can:

0- to be sure your *.fxp are in sync, do atPJcompile

1- set a breakpoint on this condition (ctrl+B opens the form) :

2- disable the breakpoint, close the debugger and start the server:

3- when your test case is ready (both browsers on the test user and the test form), re-enable the breakpoint and open the debugger:

The program will stop on the instruction that blanks _Screen.tipoBanco.

Just a guess, I suspect an *_assign() method that is not adapted.

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Gilles Lajot-Sarthou
  Arcadio Bianco
  Mar 2, 2020 @ 11:20pm

Hi Arcadio It is possible that the connection to the database server is busy and that the SQLEXEC () command is not executed by the database. Before launching an SQLEXEC () command, I test the status of the database engine with the BUSY function (at least for PostGresql):

FUNCTION SqlPasBloque AS Boolean
	LOCAL lretour AS Boolean , iDebut AS INTEGER , iTimeOut AS INTEGER

	=open_dbc()
	iTimeOut = 30
	iDebut = SECONDS()
	DO WHILE .T.
		DOEVENTS
		IF NOT SQLGETPROP(_SCREEN._gnconnect, 'ConnectBusy')
			lretour = .T.
			EXIT
		ENDIF
		IF SECONDS() > m.iDebut + m.iTimeOut
			lretour = .F.
			EXIT
		ENDIF
		=Sleep(150)
	ENDDO
	* WAIT CLEAR
	RETURN m.lretour
ENDFUNC
IF SqlPasBloque()
= SQLEXEC(_SCREEN._gnconnect, m.p_Action, m.p_curseur)
ENDIF

regards Gilles

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  Gilles Lajot-Sarthou
  Mar 3, 2020 @ 06:42am

Perfect Gilles,

I will implement this in my system, Thanks. However the biggest problem is to lose the value contained in the property. Thierry will help me find this out in a private consultation.

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  FoxInCloud Support - Thierry N.
  Arcadio Bianco
  Mar 3, 2020 @ 12:48pm

Hi Arcadio,

Regarding the ability to switch connection across users, as you use CursorAdapters, you can change .dataSource at run time.

If you really need to do that, I have several possible solutions to be discussed in private support.

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  FoxInCloud Support - Thierry N.
  Mar 3, 2020 @ 03:28pm

The multiple datasource is even working the way I showed in the topic, https://support.west-wind.com/Thread5GN1DN3X5.wwt, I don't know if it's the best way, but it's working. Just informing the datasource in init simply, it didn't work. Perhaps it is related to the same problem as the property "_screen.tipobanco"

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  FoxInCloud Support - Thierry N.
  Arcadio Bianco
  Mar 4, 2020 @ 01:58am

Hi Arcadio,

This multi-database handles scenario is quite touchy and I suggest you run full tests (combining all scenarios) before putting it in production.

To make it work you need to swap cursorAdapter.DataSource for each user and one simple way to do that is to make sure that your cursorAdapters are members of form.dataEnvironment and add ”dataSource” to cursorAdapter.wcPropSave.

But again, as we have never experienced such a scenario, it requires heavy testing.

Also, You need to consider the many-to-many relation between servers and users; if a user gets a handle on one server, you’ll need to somehow get him another handle on another server.

To overcome this, I would create a pool of connections with a table between companies, users and handles; upon each request, I would set _screen.handle to what is appropriate to the user and set CAD.dataSource to _screen.handle in CAD.dataSource_assign(), thus ignoring what was saved.

Update: forgot about the 2019 thread you mention. All this is confusing. Please take some time to clearly state your issues. Thanks.

Gravatar is a globally recognized avatar based on your email address. re: Error in com Mode
  Arcadio Bianco
  FoxInCloud Support - Thierry N.
  Mar 4, 2020 @ 10:13am

cursorAdapter.wcPropSave.

I'll check that out.

Thanks!

© 1996-2020