* test_timp_masa_peste1000.prg - continuarea masuratorii din test_timp_verificare_masa.prg:
*   1. curata randurile ramase in ISTORIC_CODURI_FISCALE peste watermark-ul rularii anterioare
*   2. costul unei scrieri goLog (STRTOFILE additive) in functie de marimea fisierului de log
*   3. costul unui apel CitesteIstoricPentruCoduri cu UN singur cod (plasa de siguranta)
*   4. rularea completa VerificaListaCIF pe un lot de peste 1000 de coduri (ANAF blocat),
*      unde interogarea de cache pica pe ORA-01795 si se ajunge cod-cu-cod
*
* Rulare: vfp9.exe -A -T "...\test_timp_masa_peste1000.prg" [watermark]

LPARAMETERS tcWatermark

SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET NULLDISPLAY TO ''
CLOSE DATABASES

PUBLIC gcTestLog, gnApeluriANAF, gcMockUltimMesaj, gnMockUltimTip, gnMockRaspuns
gcTestLog = "D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\test_timp_masa_peste1000_log.txt"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcTestLog)
gnApeluriANAF = 0
gcMockUltimMesaj = ''
gnMockUltimTip = 0
gnMockRaspuns = 6

ON ERROR DO ErrP1000 WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT

DO D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
	DO WrLog2 WITH 'EROARE: conectare Oracle esuata - GATA'
	QUIT
ENDIF
DO WrLog2 WITH 'mediu OK, schema=' + gcS
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE

* mock_amessagebox NU acopera apelurile de amessagebox facute din oproceduri_comune.prg
* (VFP rezolva intai in fisierul de proceduri curent), iar oexecutor.oExecuta deschide un
* formular modal la orice eroare SQL - headless asta blocheaza procesul. Deci inlocuiesc
* executorul cu o subclasa care nu deschide dialogul si numara erorile.
PUBLIC gnErorriSQL, gcUltimaEroareSQL
gnErorriSQL = 0
gcUltimaEroareSQL = ''
LOCAL loExecNou
loExecNou = CREATEOBJECT('oexec_fara_dialog')
loExecNou.nHandle = gnHandle
goExecutor = loExecNou
DO WrLog2 WITH 'executor inlocuit (fara dialog modal la eroare SQL)'

LOCAL lnWm, lcSql, lnT, lnI, lnRep
lnWm = IIF(TYPE('tcWatermark') = 'C' AND !EMPTY(tcWatermark), INT(VAL(tcWatermark)), 0)

*==========================================================
* 1. curatenie dupa rularea anterioara
*==========================================================
IF lnWm > 0
	lcSql = 'SELECT COUNT(*) AS N FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(lnWm)
	IF goExecutor.oExecuta(lcSql, 'crsRest')
		DO WrLog2 WITH 'randuri peste watermark ' + TRANSFORM(lnWm) + ': ' + TRANSFORM(crsRest.N)
		USE IN (SELECT('crsRest'))
	ENDIF
	=goExecutor.oExecuta('DELETE FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(lnWm))
	=goExecutor.oExecuta('COMMIT')
	DO WrLog2 WITH 'curatenie facuta (ID > ' + TRANSFORM(lnWm) + ')'
ELSE
	DO WrLog2 WITH 'fara watermark - nu sterg nimic'
ENDIF

PUBLIC gnIdMaxIstoric
gnIdMaxIstoric = 0
IF goExecutor.oExecuta('SELECT NVL(MAX(ID),0) AS IDMAX FROM ISTORIC_CODURI_FISCALE', 'crsWm2')
	gnIdMaxIstoric = crsWm2.IDMAX
	USE IN (SELECT('crsWm2'))
ENDIF
DO WrLog2 WITH 'watermark nou = ' + TRANSFORM(gnIdMaxIstoric)

*==========================================================
* 2. costul unei scrieri de log, in functie de marimea fisierului
*==========================================================
DO WrLog2 WITH ''
DO WrLog2 WITH '=== 2. cost STRTOFILE additive (asta face goLog.Log) ==='
LOCAL lcF, lcLinie
lcLinie = REPLICATE('x', 120) + CHR(13) + CHR(10)
lnRep = 300

lcF = 'D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\_probalog_mic.txt'
STRTOFILE('', lcF)
lnT = SECONDS()
FOR lnI = 1 TO lnRep
	STRTOFILE(lcLinie, lcF, .T.)
ENDFOR
lnT = SECONDS() - lnT
DO WrLog2 WITH '2a fisier ~0 MB: ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 2)) + ' ms/scriere (' + TRANSFORM(ROUND(lnT, 3)) + ' s / ' + TRANSFORM(lnRep) + ')'

lcF = 'D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\_probalog_mare.txt'
STRTOFILE(REPLICATE(lcLinie, 40000), lcF)
DO WrLog2 WITH '   fisier mare pregatit: ' + TRANSFORM(ROUND(FSIZE(lcF) / 1048576, 2)) + ' MB'
lnT = SECONDS()
FOR lnI = 1 TO lnRep
	STRTOFILE(lcLinie, lcF, .T.)
ENDFOR
lnT = SECONDS() - lnT
DO WrLog2 WITH '2b fisier ' + TRANSFORM(ROUND(FSIZE(lcF) / 1048576, 2)) + ' MB: ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 2)) + ' ms/scriere (' + TRANSFORM(ROUND(lnT, 3)) + ' s)'

* pentru comparatie: acelasi volum scris cu handle deschis o singura data
lcF = 'D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\_probalog_handle.txt'
IF FILE(lcF)
	ERASE (lcF)
ENDIF
LOCAL lnH
lnH = FCREATE(lcF)
lnT = SECONDS()
FOR lnI = 1 TO lnRep
	=FPUTS(lnH, lcLinie)
ENDFOR
=FCLOSE(lnH)
lnT = SECONDS() - lnT
DO WrLog2 WITH '2c acelasi volum, handle deschis o data: ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 3)) + ' ms/scriere'

*==========================================================
* 3. costul plasei de siguranta: o interogare per cod
*==========================================================
DO WrLog2 WITH ''
DO WrLog2 WITH '=== 3. CitesteIstoricPentruCoduri cu UN cod (plasa de siguranta) ==='
LOCAL loVer, lnZile
loVer = CREATEOBJECT('VerificareANAFTimp2')
lnZile = loVer.ZileCache()

lcSql = 'SELECT COD_FISCAL_N FROM (SELECT DISTINCT COD_FISCAL_N FROM ISTORIC_CODURI_FISCALE'
lcSql = lcSql + ' WHERE COD_FISCAL_N IS NOT NULL AND DATAORAV_ANAF IS NOT NULL'
lcSql = lcSql + ' AND SYSDATE - DATAORAV_ANAF <= ' + TRANSFORM(lnZile)
lcSql = lcSql + ' ORDER BY COD_FISCAL_N) WHERE ROWNUM <= 1200'
=goExecutor.oExecuta(lcSql, 'crsCod2')

IF USED('cLot')
	USE IN cLot
ENDIF
CREATE CURSOR cLot (cod_fiscal C(30) NULL, data D NULL)
SELECT crsCod2
SCAN
	INSERT INTO cLot (cod_fiscal, data) VALUES (ALLTRIM(TRANSFORM(crsCod2.COD_FISCAL_N)), DATE())
	SELECT crsCod2
ENDSCAN
USE IN (SELECT('crsCod2'))
DO WrLog2 WITH 'coduri proaspete disponibile: ' + TRANSFORM(RECCOUNT('cLot'))

IF USED('crsUnul')
	USE IN crsUnul
ENDIF
lnRep = MIN(100, RECCOUNT('cLot'))
lnT = SECONDS()
SELECT cLot
GO TOP
FOR lnI = 1 TO lnRep
	=loVer.CitesteIstoricPentruCoduri(ALLTRIM(NVL(cLot.cod_fiscal, '')), DATE(), 'crsUnul', 'CACHE_INDISP')
	SELECT cLot
	SKIP
ENDFOR
lnT = SECONDS() - lnT
DO WrLog2 WITH '3a ' + TRANSFORM(lnRep) + ' apeluri cu un singur cod = ' + TRANSFORM(ROUND(lnT, 3)) + ' s'
DO WrLog2 WITH '   = ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 2)) + ' ms/cod -> ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 1)) + ' s la 1000 de coduri'

*==========================================================
* 4. flux complet peste limita de 1000
*==========================================================
DO WrLog2 WITH ''
DO WrLog2 WITH '=== 4. VerificaListaCIF pe lot > 1000 coduri (ANAF blocat) ==='
IF USED('cLot1001')
	USE IN cLot1001
ENDIF
CREATE CURSOR cLot1001 (cod_fiscal C(30) NULL, data D NULL)
SELECT cLot
SCAN
	INSERT INTO cLot1001 (cod_fiscal, data) VALUES (cLot.cod_fiscal, DATE())
	SELECT cLot
ENDSCAN
FOR lnI = RECCOUNT('cLot1001') + 1 TO 1001
	INSERT INTO cLot1001 (cod_fiscal, data) VALUES (ALLTRIM(STR(9000000 + lnI)), DATE())
ENDFOR
DO WrLog2 WITH 'lot = ' + TRANSFORM(RECCOUNT('cLot1001')) + ' coduri; START ' + TTOC(DATETIME())
gnApeluriANAF = 0
lnT = SECONDS()
=loVer.VerificaListaCIF('cLot1001', DATE(), 'crsRez1001', 'MASA')
lnT = SECONDS() - lnT
DO WrLog2 WITH '   erori SQL in flux: ' + TRANSFORM(gnErorriSQL) + ' [' + LEFT(gcUltimaEroareSQL, 90) + ']'
DO WrLog2 WITH '4a TOTAL = ' + TRANSFORM(ROUND(lnT, 3)) + ' s pentru ' + TRANSFORM(RECCOUNT('cLot1001')) + ' coduri'
DO WrLog2 WITH '   randuri intoarse: ' + TRANSFORM(IIF(USED('crsRez1001'), RECCOUNT('crsRez1001'), 0))
DO WrLog2 WITH '   apeluri ANAF (blocate): ' + TRANSFORM(gnApeluriANAF)
DO WrLog2 WITH '   ultim dialog interceptat: [' + LEFT(gcMockUltimMesaj, 100) + ']'

* acelasi lot, dar sub limita (1000 de coduri) - reper
IF USED('cLot1000')
	USE IN cLot1000
ENDIF
CREATE CURSOR cLot1000 (cod_fiscal C(30) NULL, data D NULL)
SELECT cLot1001
GO TOP
FOR lnI = 1 TO 1000
	INSERT INTO cLot1000 (cod_fiscal, data) VALUES (cLot1001.cod_fiscal, DATE())
	SELECT cLot1001
	SKIP
ENDFOR
DO WrLog2 WITH 'lot de reper = ' + TRANSFORM(RECCOUNT('cLot1000')) + ' coduri'
gnApeluriANAF = 0
lnT = SECONDS()
=loVer.VerificaListaCIF('cLot1000', DATE(), 'crsRez1000', 'MASA')
lnT = SECONDS() - lnT
DO WrLog2 WITH '4b TOTAL = ' + TRANSFORM(ROUND(lnT, 3)) + ' s pentru 1000 de coduri (sub limita IN)'
DO WrLog2 WITH '   randuri intoarse: ' + TRANSFORM(IIF(USED('crsRez1000'), RECCOUNT('crsRez1000'), 0))
DO WrLog2 WITH '   apeluri ANAF (blocate): ' + TRANSFORM(gnApeluriANAF)

*==========================================================
* 5. flux la 3000 de coduri (reale + sintetice) - dovada ca scaleaza peste 1000
*==========================================================
DO WrLog2 WITH ''
DO WrLog2 WITH '=== 5. VerificaListaCIF pe lot de 3000 coduri (ANAF blocat) ==='
IF USED('cLot3000')
	USE IN cLot3000
ENDIF
CREATE CURSOR cLot3000 (cod_fiscal C(30) NULL, data D NULL)
SELECT cLot1001
GO TOP
SCAN
	INSERT INTO cLot3000 (cod_fiscal, data) VALUES (cLot1001.cod_fiscal, DATE())
	SELECT cLot1001
ENDSCAN
FOR lnI = RECCOUNT('cLot3000') + 1 TO 3000
	INSERT INTO cLot3000 (cod_fiscal, data) VALUES (ALLTRIM(STR(9500000 + lnI)), DATE())
ENDFOR
DO WrLog2 WITH 'lot = ' + TRANSFORM(RECCOUNT('cLot3000')) + ' coduri; START ' + TTOC(DATETIME())
gnApeluriANAF = 0
gnErorriSQL = 0
lnT = SECONDS()
=loVer.VerificaListaCIF('cLot3000', DATE(), 'crsRez3000', 'MASA')
lnT = SECONDS() - lnT
DO WrLog2 WITH '   erori SQL in flux: ' + TRANSFORM(gnErorriSQL) + ' [' + LEFT(gcUltimaEroareSQL, 90) + ']'
DO WrLog2 WITH '5a TOTAL = ' + TRANSFORM(ROUND(lnT, 3)) + ' s pentru ' + TRANSFORM(RECCOUNT('cLot3000')) + ' coduri'
DO WrLog2 WITH '   randuri intoarse: ' + TRANSFORM(IIF(USED('crsRez3000'), RECCOUNT('crsRez3000'), 0))
DO WrLog2 WITH '   apeluri ANAF (blocate): ' + TRANSFORM(gnApeluriANAF)

*==========================================================
DO WrLog2 WITH ''
DO CurataP1000
DO WrLog2 WITH 'GATA ' + TTOC(DATETIME())
QUIT


PROCEDURE WrLog2
	LPARAMETERS tcText
	STRTOFILE(TRANSFORM(tcText) + CHR(13) + CHR(10), gcTestLog, .T.)
ENDPROC

PROCEDURE ErrP1000
	LPARAMETERS tnError, tcMessage, tcProgram, tnLine
	DO WrLog2 WITH 'EROARE ' + TRANSFORM(tnError) + ' [' + TRANSFORM(tcMessage) + '] in ' + ;
		TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLine)
	RETURN
ENDPROC

PROCEDURE CurataP1000
	IF TYPE('gnIdMaxIstoric') <> 'N' OR gnIdMaxIstoric <= 0
		DO WrLog2 WITH 'curatenie SARITA - watermark invalid'
		RETURN
	ENDIF
	=goExecutor.oExecuta('DELETE FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(gnIdMaxIstoric))
	=goExecutor.oExecuta('COMMIT')
	DO WrLog2 WITH 'curatenie: sterse randurile cu ID > ' + TRANSFORM(gnIdMaxIstoric)
ENDPROC


DEFINE CLASS oexec_fara_dialog AS oexecutor

	FUNCTION oExecuta
		LPARAMETERS tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect
		LOCAL lcSql, lcCursor, lnHandle, lnRez
		lcSql = IIF(EMPTY(tcSql), This.cSql, tcSql)
		lcCursor = IIF(EMPTY(tcCursor), This.cCursor, tcCursor)
		lnHandle = IIF(EMPTY(tnHandle), This.nHandle, tnHandle)
		lnRez = This.oExecute(lcSql, lcCursor, tlProgress, tcTitluProgress, lnHandle)
		IF lnRez < 1
			gnErorriSQL = gnErorriSQL + 1
			gcUltimaEroareSQL = TRANSFORM(This.cEroare)
		ENDIF
		RETURN (lnRez >= 1)
	ENDFUNC

ENDDEFINE


DEFINE CLASS VerificareANAFTimp2 AS VerificareANAF

	PROCEDURE OrdineCache
		LPARAMETERS tcTraseu
		RETURN 'CACHE,ANAF'
	ENDPROC

	PROCEDURE ANAF_SincronWebService_PlatitorTva
		LPARAMETERS tcCursorListaCIF, tdData, tcAlias
		gnApeluriANAF = gnApeluriANAF + 1
		RETURN IIF(EMPTY(tcAlias), 'crsANAF', tcAlias)
	ENDPROC

ENDDEFINE
