Verificarea "in masa" (VerificaListaCIF ... 'MASA') pica pe ORA-01795 peste 1000 de coduri, iar esecul trimitea tot lotul la ANAF, cu pauze de o secunda la fiecare 100 de coduri. Pe langa asta, fiecare rand servit din cache era salvat inapoi in istoric si logat separat. - programe/validare.prg: CitesteIstoricPentruCoduri citeste pe transe de maxim 1000 de coduri legate cu OR in aceeasi interogare (fara obiecte noi in baza, compatibil cu Oracle 10g); plasa de siguranta cere codurile neacoperite o singura data, nu cod cu cod; SalveazaIstoricDinCursor sare peste randurile cu sursa CACHE*; bucla de log per rand devine o singura linie cu totalul. - clase/overificari.vc2: completarea tabelului de parteneri foloseste index pe codul normalizat si SEEK in loc de LOCATE cu UDF (era patratic). - utile/Teste/cache_anaf/: harness-uri de masurare si non-regresie pentru timpii de mai jos. Masurat pe MARIUSM_AUTO, cu ANAF blocat: 1000 de coduri 5,1 s -> 0,318 s; 1001 coduri 16,6 s cu ORA-01795 -> 0,553 s fara eroare; 3000 de coduri 1,565 s; 200 de coduri din cache 3,93 s -> 0,05 s, cu 0 randuri noi in istoric; completarea tabelului pentru 2000 de parteneri 11,97 s -> 0,028 s. Randurile intoarse si verdictele raman identice. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JCzVWfqscv1xyo5uvJiWiW
248 lines
9.5 KiB
Plaintext
248 lines
9.5 KiB
Plaintext
* test_timp_completare_tabel.prg - masoara PARTEA DE APELANT a verificarii in masa: bucla care
|
|
* muta rezultatele din crsANAF in tabelul afisat (crsVerificareParteneri), din
|
|
* frm_verificare_parteneri.do_verifica (COMUN\clase\overificari.vc2:2741-2756).
|
|
*
|
|
* Bucla reala face, pentru fiecare rezultat, un LOCATE cu expresie care apeleaza un UDF
|
|
* (loVerificare.GetCodTara) pe fiecare rand parcurs => N x N apeluri de functie.
|
|
* Se compara cu aceeasi completare pe cursor indexat (SEEK).
|
|
*
|
|
* Fara Oracle in bucla masurata: cursoarele sunt construite local, deci timpul e pur VFP.
|
|
*
|
|
* Rulare: vfp9.exe -A -T "...\test_timp_completare_tabel.prg"
|
|
|
|
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
|
|
gcTestLog = "D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\test_timp_completare_tabel_log.txt"
|
|
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcTestLog)
|
|
|
|
ON ERROR DO ErrCompl 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'
|
|
DO WrLog3 WITH 'mediu OK'
|
|
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
|
|
|
|
* goLog dezactivat aici: masor doar bucla de VFP, nu scrierea in log
|
|
goLog.cLogFile = 'D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\_log_inexistent.txt'
|
|
|
|
LOCAL lnI
|
|
FOR lnI = 1 TO 4
|
|
DO MasoaraLot WITH IIF(lnI = 1, 200, IIF(lnI = 2, 500, IIF(lnI = 3, 1000, 2000)))
|
|
ENDFOR
|
|
|
|
DO TestSemanticaData
|
|
|
|
DO WrLog3 WITH 'GATA ' + TTOC(DATETIME())
|
|
QUIT
|
|
|
|
* verifica varianta LOCATE (A) vs SEEK+SKIP (C) pe acelasi cod fiscal cu mai multe randuri
|
|
* cu date diferite - trebuie sa aleaga acelasi rand (primul, in ordinea fizica, care satisface conditia)
|
|
PROCEDURE TestSemanticaData
|
|
LOCAL loVerificare, ldData
|
|
loVerificare = CREATEOBJECT('verificarecod', .F., .F.)
|
|
ldData = DATE()
|
|
|
|
DO WrLog3 WITH ''
|
|
DO WrLog3 WITH '=== test semantica: acelasi cod, date diferite ==='
|
|
|
|
* caz 1: doua randuri cu data GRESITA inaintea celui cu data corecta -> trebuie 2 SKIP pana la potrivire
|
|
DO ConstrTabelDuplicat WITH ldData - 60, ldData - 30, ldData
|
|
DO VerificaSemantica WITH loVerificare, ldData, 'caz 1 (2 SKIP pana la data corecta)', 'PARTENER 3'
|
|
|
|
* caz 2: randul cu data GOALA vine inaintea celui cu data corecta -> primul (cu data goala) trebuie ales
|
|
DO ConstrTabelDuplicat WITH ldData - 30, {}, ldData
|
|
DO VerificaSemantica WITH loVerificare, ldData, 'caz 2 (data goala inaintea celei corecte)', 'PARTENER 2'
|
|
ENDPROC
|
|
|
|
PROCEDURE ConstrTabelDuplicat
|
|
LPARAMETERS tdData1, tdData2, tdData3
|
|
IF USED('crsTabel')
|
|
USE IN crsTabel
|
|
ENDIF
|
|
CREATE CURSOR crsTabel (ales L, denumire C(100) NULL, cod_fiscal C(30) NULL, Valid L NULL, ;
|
|
firma C(100) NULL, cod C(100) NULL, adresa C(250) NULL, judet C(100) NULL, regcom C(30) NULL, ;
|
|
datatvamfin C(30) NULL, platitortvamfin L NULL, IsCIF L NULL, duplicat L, atribut_fiscal C(2), ;
|
|
stare C(100), atentie C(100), cod_fiscalfro C(30) NULL, tvaincasare L, splittva L, inactiv L, Data D NULL)
|
|
INSERT INTO crsTabel (cod_fiscal, denumire, Valid, IsCIF, Data) VALUES ('RO9999999', 'ALT PARTENER', .T., .T., tdData1)
|
|
INSERT INTO crsTabel (cod_fiscal, denumire, Valid, IsCIF, Data) VALUES ('RO1234567', 'PARTENER 1', .T., .T., tdData1)
|
|
INSERT INTO crsTabel (cod_fiscal, denumire, Valid, IsCIF, Data) VALUES ('RO1234567', 'PARTENER 2', .T., .T., tdData2)
|
|
INSERT INTO crsTabel (cod_fiscal, denumire, Valid, IsCIF, Data) VALUES ('RO1234567', 'PARTENER 3', .T., .T., tdData3)
|
|
ENDPROC
|
|
|
|
PROCEDURE VerificaSemantica
|
|
LPARAMETERS toVerificare, tdData, tcEticheta, tcAsteptat
|
|
LOCAL lcCheieCauta, llGasit, lcRezA, lcRezC
|
|
|
|
* varianta A: LOCATE cu UDF, exact bucla veche
|
|
SELECT crsTabel
|
|
LOCATE FOR ALLTRIM(STRTRAN(cod_fiscal, toVerificare.GetCodTara(cod_fiscal), '')) = '1234567' AND (EMPTY(NVL(data, {})) OR data = tdData)
|
|
lcRezA = IIF(FOUND(), ALLTRIM(denumire), '<niciunul>')
|
|
|
|
* varianta C: SEEK pe cod_fiscalfro + SKIP cat timp cheia ramane egala, pana la data care se potriveste
|
|
SELECT crsTabel
|
|
REPLACE ALL cod_fiscalfro WITH ALLTRIM(STRTRAN(cod_fiscal, toVerificare.GetCodTara(cod_fiscal), ''))
|
|
INDEX ON cod_fiscalfro TAG cfro
|
|
lcCheieCauta = PADR('1234567', 30)
|
|
llGasit = .F.
|
|
IF SEEK(lcCheieCauta, 'crsTabel', 'cfro')
|
|
llGasit = .T.
|
|
DO WHILE !(EMPTY(NVL(data, {})) OR data = tdData)
|
|
SKIP
|
|
IF EOF() OR cod_fiscalfro <> lcCheieCauta
|
|
llGasit = .F.
|
|
EXIT
|
|
ENDIF
|
|
ENDDO
|
|
ENDIF
|
|
lcRezC = IIF(llGasit, ALLTRIM(denumire), '<niciunul>')
|
|
|
|
DO WrLog3 WITH ' ' + tcEticheta + ': A=' + lcRezA + ' C=' + lcRezC + ' asteptat=' + tcAsteptat
|
|
DO WrLog3 WITH IIF(lcRezA == lcRezC AND lcRezA == tcAsteptat, ' PASS', ' FAIL')
|
|
USE IN (SELECT('crsTabel'))
|
|
ENDPROC
|
|
|
|
|
|
PROCEDURE MasoaraLot
|
|
LPARAMETERS tnN
|
|
LOCAL lnT1, lnT2, lnT3, lnK, loVerificare, ldData
|
|
loVerificare = CREATEOBJECT('verificarecod', .F., .F.)
|
|
ldData = DATE()
|
|
|
|
DO WrLog3 WITH ''
|
|
DO WrLog3 WITH '=== lot ' + TRANSFORM(tnN) + ' parteneri ==='
|
|
|
|
* rezultatele ANAF/cache (forma crsANAF, doar campurile folosite de bucla)
|
|
IF USED('crsRezANAF')
|
|
USE IN crsRezANAF
|
|
ENDIF
|
|
CREATE CURSOR crsRezANAF (cui N(13), denumire V(100), adresa C(244), mesaj V(100), ;
|
|
tva L, tvaincasare L, splittva L, inactiv L)
|
|
FOR lnK = 1 TO tnN
|
|
INSERT INTO crsRezANAF (cui, denumire, adresa, mesaj, tva, tvaincasare, splittva, inactiv) ;
|
|
VALUES (10000000 + lnK, 'FIRMA ' + ALLTRIM(STR(lnK)), 'ADRESA ' + ALLTRIM(STR(lnK)), '', .T., .F., .F., .F.)
|
|
ENDFOR
|
|
|
|
* varianta 1: exact bucla din overificari.vc2
|
|
DO ConstrTabel WITH tnN
|
|
lnT1 = SECONDS()
|
|
SELECT crsRezANAF
|
|
SCAN
|
|
SCATTER NAME loRec
|
|
WITH loRec
|
|
SELECT crsTabel
|
|
LOCATE FOR ALLTRIM(STRTRAN(cod_fiscal, loVerificare.GetCodTara(cod_fiscal), '')) = ALLTRIM(STR(.cui)) AND (EMPTY(NVL(data, {})) OR data = ldData)
|
|
IF FOUND()
|
|
REPLACE firma WITH .denumire, adresa WITH .adresa, stare WITH .mesaj, ;
|
|
cod WITH ALLTRIM(STR(.cui)), tvaincasare WITH .tvaincasare, ;
|
|
splittva WITH .splittva, inactiv WITH .inactiv
|
|
ENDIF
|
|
ENDWITH
|
|
SELECT crsRezANAF
|
|
ENDSCAN
|
|
lnT1 = SECONDS() - lnT1
|
|
DO WrLog3 WITH 'A LOCATE + UDF (cod real) = ' + TRANSFORM(ROUND(lnT1, 3)) + ' s'
|
|
SELECT COUNT(*) AS n FROM crsTabel WHERE !EMPTY(NVL(firma, '')) INTO CURSOR crsCtrl1
|
|
DO WrLog3 WITH ' randuri completate: ' + TRANSFORM(crsCtrl1.n)
|
|
USE IN (SELECT('crsCtrl1'))
|
|
|
|
* varianta 2: aceeasi completare pe cursor indexat
|
|
DO ConstrTabel WITH tnN
|
|
lnT2 = SECONDS()
|
|
SELECT crsTabel
|
|
REPLACE ALL cod_fiscalfro WITH ALLTRIM(STRTRAN(STRTRAN(UPPER(NVL(cod_fiscal, '')), 'RO', ''), ' ', ''))
|
|
INDEX ON cod_fiscalfro TAG cfro
|
|
SELECT crsRezANAF
|
|
SCAN
|
|
SCATTER NAME loRec
|
|
WITH loRec
|
|
IF SEEK(PADR(ALLTRIM(STR(.cui)), 30), 'crsTabel', 'cfro')
|
|
SELECT crsTabel
|
|
REPLACE firma WITH .denumire, adresa WITH .adresa, stare WITH .mesaj, ;
|
|
cod WITH ALLTRIM(STR(.cui)), tvaincasare WITH .tvaincasare, ;
|
|
splittva WITH .splittva, inactiv WITH .inactiv
|
|
ENDIF
|
|
ENDWITH
|
|
SELECT crsRezANAF
|
|
ENDSCAN
|
|
lnT2 = SECONDS() - lnT2
|
|
DO WrLog3 WITH 'B SEEK pe cursor indexat = ' + TRANSFORM(ROUND(lnT2, 3)) + ' s'
|
|
SELECT COUNT(*) AS n FROM crsTabel WHERE !EMPTY(NVL(firma, '')) INTO CURSOR crsCtrl2
|
|
DO WrLog3 WITH ' randuri completate: ' + TRANSFORM(crsCtrl2.n)
|
|
USE IN (SELECT('crsCtrl2'))
|
|
DO WrLog3 WITH 'raport A/B = ' + TRANSFORM(ROUND(lnT1 / MAX(lnT2, 0.001), 1)) + 'x'
|
|
|
|
* varianta 3: exact codul propus in overificari.vc2 (SEEK + parcurgere pe cheie egala pentru data)
|
|
DO ConstrTabel WITH tnN
|
|
lnT3 = SECONDS()
|
|
SELECT crsTabel
|
|
REPLACE ALL cod_fiscalfro WITH ALLTRIM(STRTRAN(cod_fiscal, loVerificare.GetCodTara(cod_fiscal), ''))
|
|
INDEX ON cod_fiscalfro TAG cfro
|
|
SELECT crsRezANAF
|
|
SCAN
|
|
SCATTER NAME loRec
|
|
WITH loRec
|
|
lcCheieCauta = PADR(ALLTRIM(STR(.cui)), 30)
|
|
SELECT crsTabel
|
|
llGasit = .F.
|
|
IF SEEK(m.lcCheieCauta, 'crsTabel', 'cfro')
|
|
llGasit = .T.
|
|
DO WHILE !(EMPTY(NVL(data, {})) OR data = ldData)
|
|
SKIP
|
|
IF EOF() OR cod_fiscalfro <> m.lcCheieCauta
|
|
llGasit = .F.
|
|
EXIT
|
|
ENDIF
|
|
ENDDO
|
|
ENDIF
|
|
IF llGasit
|
|
REPLACE firma WITH .denumire, adresa WITH .adresa, stare WITH .mesaj, ;
|
|
cod WITH ALLTRIM(STR(.cui)), tvaincasare WITH .tvaincasare, ;
|
|
splittva WITH .splittva, inactiv WITH .inactiv
|
|
ENDIF
|
|
ENDWITH
|
|
SELECT crsRezANAF
|
|
ENDSCAN
|
|
lnT3 = SECONDS() - lnT3
|
|
DO WrLog3 WITH 'C SEEK + SKIP pe cheie (cod propus) = ' + TRANSFORM(ROUND(lnT3, 3)) + ' s'
|
|
SELECT COUNT(*) AS n FROM crsTabel WHERE !EMPTY(NVL(firma, '')) INTO CURSOR crsCtrl3
|
|
DO WrLog3 WITH ' randuri completate: ' + TRANSFORM(crsCtrl3.n)
|
|
USE IN (SELECT('crsCtrl3'))
|
|
DO WrLog3 WITH 'raport A/C = ' + TRANSFORM(ROUND(lnT1 / MAX(lnT3, 0.001), 1)) + 'x'
|
|
ENDPROC
|
|
|
|
PROCEDURE ConstrTabel
|
|
LPARAMETERS tnN
|
|
LOCAL lnK
|
|
IF USED('crsTabel')
|
|
USE IN crsTabel
|
|
ENDIF
|
|
CREATE CURSOR crsTabel (ales L, denumire C(100) NULL, cod_fiscal C(30) NULL, Valid L NULL, ;
|
|
firma C(100) NULL, cod C(100) NULL, adresa C(250) NULL, judet C(100) NULL, regcom C(30) NULL, ;
|
|
datatvamfin C(30) NULL, platitortvamfin L NULL, IsCIF L NULL, duplicat L, atribut_fiscal C(2), ;
|
|
stare C(100), atentie C(100), cod_fiscalfro C(30) NULL, tvaincasare L, splittva L, inactiv L, Data D)
|
|
FOR lnK = 1 TO tnN
|
|
INSERT INTO crsTabel (cod_fiscal, denumire, Valid, IsCIF, Data) ;
|
|
VALUES ('RO' + ALLTRIM(STR(10000000 + lnK)), 'PARTENER ' + ALLTRIM(STR(lnK)), .T., .T., DATE())
|
|
ENDFOR
|
|
ENDPROC
|
|
|
|
PROCEDURE WrLog3
|
|
LPARAMETERS tcText
|
|
STRTOFILE(TRANSFORM(tcText) + CHR(13) + CHR(10), gcTestLog, .T.)
|
|
ENDPROC
|
|
|
|
PROCEDURE ErrCompl
|
|
LPARAMETERS tnError, tcMessage, tcProgram, tnLine
|
|
DO WrLog3 WITH 'EROARE ' + TRANSFORM(tnError) + ' [' + TRANSFORM(tcMessage) + '] in ' + ;
|
|
TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLine)
|
|
RETURN
|
|
ENDPROC
|