Nieuwe functies

Introductie

Steeds worden nieuwe functies ontwikkeld. Op eigen initiatief maar ook op verzoek van de klant. Immers, GRIPOPDATA beschikt over de broncode en voegt binnen no-time de gewenste functionaliteit toe. In onderstaande zijn allemaal code-snippets voorbeelden beschikbaar. Let wel op: soms past de sql niet bij uw geselecteerde database.

Variabelen

Variabelen kunnen te pas en te onpas gebruikt worden. Er zijn voorgedefinieerde grip-variabelen die gebruikt kunnen worden maar middels VAR en MVAR kunnen ook variabelen gemaakt worden. Uitvragen van variabelen gaat middels dubbele vierkante haken er om heen [[variabele]] ..

Zoals iedere programmeertaal heeft GRIP ook variabelen. Er is onderscheid tussen statische (VAR) en vluchtige variabelen (MVAR)
Statische variabelen worden opgeslagen in grip_para tabel en zijn op later tijdstip weer op te halen ... Een risico met deze variabele is dat een ander proces toevallig dezelfde variabele gebruikt waardoor er een ongewenste situatie kan ontstaan ..

Men kan naar eigen behoefte variabelen definieren maar GRIP kent ook een aantal voorgedefinieerde GRIP-variabelen... Alle variabelen zijn varchar en kunnen heel groot worden ( > 10Mb )

-- VAR en MVAR --
statische en memory variabelen: 

VAR PARAM1 = variabele PARAM1 opgeslagen in tabel GRIP_PARA 
VAR PARAM2 = variabele PARAM2 opgeslagen in tabel GRIP_PARA 

memory-variabelen :
MVAR PARAM3 = memory variabele PARAM3 
MVAR PARAM4 = memory variabele PARAM4

of 

MVAR PARAM5 = vandaag is het [[YYYYMMDD]]

De voorgedefineerde variabelen kunnen ook gezien worden als functie-aanroepen die tekst retourneren. De volgende prefarb-grip-variabelen zijn beschikbaar :

DISP [[SCAN ALL_VARAIBELEN]]

BEGIN ALL_VARIABELEN
  [[CURRENT_CONNECTION]] : de etl/sql/functionaliteit gebruikt deze database-connectie  
  [[CON_TYPE]]           : de type van de connectie : sqlserver,oracle,postgresql,snowflake,mysql 
  [[CURRENT_SCHEMA]]     : het schema van de current-connectie
  [[CURRENT_DATABASE]]   : de naam van de current database ( staat onder ind e status-balk van de editor )
  [[CURRENT_USER]]       : de connected user van de connectie 
  [[MACADDRESS]]         : het macadress van de pc vanwaarop GRIP draait. 
  [[COMPANY]]            : de bedrijfsnaam die licentie afneemt. 
  [[HOST]]               : de servernaam waarop grip draait. 
  [[EXPIRATION_DATE]]    : de datum tot 
  [[CURRENT_DIR]]        : de huidige directory waar bestanden gezocht of geschreven wordt.
  [[CURRENT_DIR_]]       : idem maar dan zijn de backward-slash omgezt naar forward-slashed 
  [[DATA_DIR]]           : de directory waar de data staat
  [[DATA_DIR_]]          : de directory waar de data staat, maar met forward-slashes
  [[SELECTEDTEXT]]       : de geselecteerde text  
  [[SOURCE_FILE]]        : de current sourcefile waarin de code gezocht wordt . 
  [[OBJECT]]             : een variabele voor intern gebruik
  [[CHAINCALL]]          : een variabele voor intern gebruik

  [[USER]]               : current connected username
  [[DATABASE]]           : current connected database 
  [[LOGON_SCHEMA]]       : current logon schema

  [[YYYYMMDD]]           : datum-formaat
  [[DDMMYYYY]]           : datum-formaat
  [[SYSDATE]]            : datum-formaat
  [[NOW]]                : datum-formaat
  [[YYYY]]               : datum-formaat
  [[YYYYMM]]             : datum-formaat
  [[YYYY-MM-DD]]         : datum-formaat
  [[DD-MM-YYYY]]         : datum-formaat
  [[YYYY]]               : datum-formaat
  [[YYYY-MM]]            : datum-formaat
  [[IP]]                 : het ipnummer van de server 


  [[COMMAND]]        : het commando vanuit de HTML/browser
  [[FILENAME]]       : de bestandsnaam
  [[EMPTY]]          : NULL-waarde
  [[CR]]             : carriage-return 
  [[__]]             : regel-seperator, tbv opmaak. 
  [[BASE_FILENAME]]  : bestandsnaam op basis van mac-address. 
RETURN

TekstStreaming

Gedurende de doorontwikkeling is GRIP feitelijk een interpreter gaan worden: tekst wordt regelgeorienteerd gescanned en per regel wordt gekeken of een functie of variabele aangetroffen wordt. Een variabele wordt bepaald middels dubbele vierkante haken om de variabele te plaatsen , bv. [[SYSDATE]]. SYSDATE is een interne tekst-functie-variabele, zoals er veel meer aanwezig zijn. [[SYSDATE]] is de aanroep en deze string wordt geheel vervangen door diens waarde.

Iedere GRIP-script worden dus volledig geinterpreteerd, geparsed, hetgeen heel krachtige en compacte functionaliteit oplevert maar ook best cryptisch. Een advies is het simpel te houden zodat collega's de code ook blijft begrijpen.

onderstaande constructies zijn mogelijk: 

    MVAR TOPDESK_DBF = TOPDESK_ACC

    trunc_insert('| SOURCE my_stage_bron_view_v | TARGET my_stage_table_[[YYYY]] | SOURCE_DB [[TOPDESK_DBF]] | TARGET_DB MY_DWH  | ')

om even te kijken hoe de uiteindelijke aanroep er uit ziet, zonder hem uit te voeren: 

    DISP trunc_insert('| SOURCE my_stage_bron_view_v | TARGET my_stage_table_[[YYYY]] | SOURCE_DB [[TOPDESK_DBF]] | TARGET_DB MY_DWH  | ')


verder : 
  DISP deze variabelen worden gesubstitueerd : [[ENCODE grip ]] [[CURRENT_DIR]] en [[CURRENT_DIR_]]
  DISP [[DECODE Z3JpcA==]] [[YYYY]]

Geavanceerde tekstprocessing

Voor GRIP_HTTP functionaliteit kan heel efficient websites gebouwd worden voor bv KPI-schermen. GRIP_ETL draagt zorg voor actuele datamarts maar vervolgens moet e.e.a. nog in dashboards weergegegen worden. Vaak wordt powerBI daarvoor ingezet maar met weining inspanning kan met GRIP_HTML ook effectieve dashboards gerealiseerd worden.

Maar voor backend-programming zijn deze tekstprocessors ook heel handig, zeker in combinatie met SQLCALL, een routine die apart behandelt wordt.

  [[SCAN xx@yy.grp]] : deze variabele levert de tekst op die de SCAN oplevert. Kan gezien worden als een MACRO-aanroep, soort code-snippet aanroep/substitutie 
  [[GETENV xx]]      : ophalen van de DOS-environment-variabelen, zoals bv email of path ... 
  [[HTML> ]]         : variabele voor html-functionaliteit, zoals een TREE-navigator of google-script / dashboard 
  [[HTMLQRY ]]       : html-tabel op basis van een sql-query 
  [[SSQL xx ]]       : de query die via het label gevonden wordt, wordt uitgevoerd en diens waarde wordt geretourneerd. 
  [[SQL select xx]]  : het resultaat van deze eenvoudige sql-query wordt geretourneerd .. 
  [[DECODE grip ]]   : crypten van een tekst, waarde wordt teruggegeven..
  [[ENDCODE ]]       : decrypten van een gecrypte tekst 


vb:

 MVAR P1 = [[SQL select current_date ]]  
 MVAR P2 = [[ENCODE grip ]]

 DISP P1 heeft de waarde [[P1]] en de functie retourneert :  [[SQL select current_date  -10 ]] 
 DISP [[DECODE Z3JpcA==]] [[YYYY]] [[CURRENT_DIR]] en [[CURRENT_DIR_]]

geeft als resultaat: 
  Busy... grip_calls.grp 07/31/2023, 11:53:02
  [pg_duitsland,grip_parse,INFO 07/31/2023, 11:53:03] P1 heeft de waarde 2023-07-31 en de functie retourneert :  2023-07-21
  [pg_duitsland,grip_parse,INFO 07/31/2023, 11:53:03] grip 2023 C:\Users\dolf\PycharmProjects\pythonProject en C:/Users/dolf/PycharmProjects/pythonProject


nb: de xx@yy.grp bestaat uit 2 componenten: xx is de label of procedure, en optioneel is @ voor aangeven in welke file de label voorkomt.  


 VAR MyVar = 'Waarde van de variabele MyVar' op dag [[YYYY-MM-DD]] , variabele komt ook in grip_para terecht .. 
 MVAR MyMemoryVar = 'Value in Memory'  
 DISP [[MyVar]]


edit

Met edit gevolgd door een filenaam, wordt de file geopend en eventueel gecreeerd. Boven in de file wordt de weg terug mogelijk doordat edit file automatisch toegevoegd wordt aan de nieuwe file Indien te editen file geopend wordt, en indien deze een procedure 'AUTOEXEC' bevat, wordt deze code meteen uitgevoerd. Dit is handig voor bv het zetten van de WINDOWS-titel of selecteren of openen van een nieuwe connectie.

file wordt aangemaakt. 
edit  grip_calls.grp

BEGIN AUTOEXEC 
  TITLE **** redeneerscript **** [[DD-MM-YYYY]], licenced to Company [[COMPANY]]
  sound('a1')
RETURN


runpy

Vanuit GRIP kan eenvoudig Python aangeroepen worden. Tussen de GRIP-code kan eenvoudig pythoncode opgenomen worden waarbij wel rekening gehouden moet worden met het inpringen . Maar de Pythoncode kan ook als extern script aangeroepen worden. Soms schiet GRIP-functionaliteit te kort en kun je ontbrekende functionliteit in python realiseren. Parameteroverdracht gaat middels de [[variabelen]] constructie : het gehele python-script wordt vooraf geparsed en variabelen en functies worden vooraf uitgevoerd. De retour-parameters kunnen vanuit python teruggegeven worden aan GRIP.
De Pythonscript wordt appart gezet in [[CURRENT_DIR]]/data/[[MACADDRESS]].grp.py alvorens hij uitgevoerd wordt.

runpy('| SCAN label |') runpy('| FILE [[CURRENT_DIR_]]/data/mypy.py |')

PYRETURN dient als return bij een python-functie gebruikt te worden in de Pythonscript omdat de parser een RETURN opvat als einde code ...

 MVAR filename = grip_calls.grp
 runpy('| SCAN FILECHANGED |') 
 DISP return-value : [[FILECHANGED_RETURN_VALUE]]

BEGIN FILECHANGED
import os.path
import datetime as dt
import time 

def pyfie():
   PYRETURN 'test'

lt1 = datetime.strptime('2023-03-25 07:43:50', '%Y-%m-%d %H:%M:%S')
lt2 = datetime.strptime('2023-03-25 08:43:59', '%Y-%m-%d %H:%M:%S')

print("last modified: %s" % time.ctime(os.path.getmtime('[[CURRENT_DIR_]]/[[filename]]')))
print("created: %s"       % time.ctime(os.path.getctime('[[CURRENT_DIR_]]/[[filename]]')))

file_time_upd = dt.datetime.fromtimestamp(os.path.getmtime('[[CURRENT_DIR_]]/[[filename]]'))
file_time_cre = dt.datetime.fromtimestamp(os.path.getctime('[[CURRENT_DIR_]]/[[filename]]'))
print(file_time_upd.strftime("%Y-%m-%d %H:%M:%S"))
print(file_time_cre.strftime("%Y-%m-%d %H:%M:%S") , (file_time_upd - file_time_cre).total_seconds()  )

l_ret = int((lt2 - lt1).total_seconds()) 

print( 'aantal seconden geleden dat [[filename]] gewijzigd is:  ' ,  l_ret ,'seconden' )

grip_parse.parse_commander_( 'MVAR FILECHANGED_RETURN_VALUE = ' + str(l_ret)  ,[],  '' )  # retour-parameters naar GRIP toe. 

RETURN

de output: 

Busy... grip_doc.grp 07/31/2023, 12:33:00
last modified: Mon Jul 31 11:56:50 2023
created: Sun Jan  9 09:09:46 2022
2023-07-31 11:56:50
2022-01-09 09:09:46 49085223.614123
aantal seconden geleden dat grip_calls.grp gewijzigd is:   3609 seconden
[pg_duitsland,grip_parse,INFO 07/31/2023, 12:33:00] return-value : 3609


wait

Indien er wat ETL-flows parrallel kunnen terwijl na deze flows een flow mag starten totdat alle voorgaande flows klaar succesvol afgerond dienen te zijn, kan dat geregeld worden met een semafoor. Middels het commando WAIT (INIT) kan en semafoor gecreerd worden. Alle functionaliteit op deze SEMAFOOR wordt nu automatisch geregeld.

INIT       : aanmaak initialisatie van de semafoor
START      : start van een subflow op deze semafoor onder label X
STOP       : gereed melding van subflow op deze semafoor onder label X
SLEEP      : aantal seconden wachten tot volgende check van de status van de semafoor
TIMES      : aantal keren wachten 
MAIL       : Na aantal keren wachten wordt de WAIT afgekapt en wordt een mailtje verstuurd 
INFO       : Uitvragen van de toestand van de semafoor: hoeveel subflows draaien er momenteel . 
SOURCE_DB  : De registratie vindt plaats in een database/connectie opgegeven met deze  . 
WAIT       : Er wordt in een lus van Times-keer SLEEP-seconden gewacht. Indien alle labels / subflows gereed zijn
             wordt de lus beeindigd en gaat het processen na de wait verder. Indien maximaal gewacht is, wordt een mailtje gestuurd.  

Middels onderstaand worden 3 flows parallel gestart. commando ECALL geeft aan dat een nieuwe GRIP.EXE gestart wordt doe parrallel zijn werk gaat doen. Er wordt 5 seconden gewacht waarna de wait uitgevoerd wordt: Dit resulteert in een wachtlus totdat de 3 parrallel flows klaar zijn ..

CALL DEMO 

BEGIN DEMO
   wait ('| ACTIE INIT  | SEMAFOOR STAGE_PARALLEL_LOAD | LOG_INFO aanmaak eerste keer |' ) 
# 
   ECALL CALL PARALLEL_FLOW1
   ECALL CALL PARALLEL_FLOW2
   ECALL CALL PARALLEL_FLOW3
#
   DISP 30 seconden wachten omdat de paralle processen dan pas running zijn
   SLEEP 30
#
   DISP 
   wait('| ACTIE WAIT | SEMAFOOR STAGE_PARALLEL_LOAD | SLEEP 3 | MAIL dolf.jansonius@rivm.nl | TIMES 12   | ')
RETURN 


BEGIN PARALLEL_FLOW1
 SLEEP 1
 wait ('| ACTIE INIT  | SEMAFOOR STAGE_PARALLEL_LOAD |' ) 
 wait ('| ACTIE START | SEMAFOOR STAGE_PARALLEL_LOAD | LABEL proces_1   | ')
#
 wait('| ACTIE INFO  | SEMAFOOR STAGE_PARALLEL_LOAD   |  ') 
 SLEEP 35
#
 wait('| ACTIE STOP  | SEMAFOOR STAGE_PARALLEL_LOAD | LABEL proces_1   | ')
RETURN


BEGIN PARALLEL_FLOW2
 SLEEP 4
 wait ('| ACTIE START | SEMAFOOR STAGE_PARALLEL_LOAD | LABEL proces_2   | ')
#
 wait('| ACTIE INFO  | SEMAFOOR STAGE_PARALLEL_LOAD   |  ') 
 SLEEP 40
#
 wait('| ACTIE STOP  | SEMAFOOR STAGE_PARALLEL_LOAD | LABEL proces_2   | ')
RETURN


BEGIN PARALLEL_FLOW3
 SLEEP 8
 wait ('| ACTIE START | SEMAFOOR STAGE_PARALLEL_LOAD | LABEL proces_3   | ')
#
 wait('| ACTIE INFO  | SEMAFOOR STAGE_PARALLEL_LOAD   |  ') 
 SLEEP 45
#
 wait('| ACTIE STOP  | SEMAFOOR STAGE_PARALLEL_LOAD | LABEL proces_3   | ')
RETURN


write

Met write kan een file geschreven worden voor met bijvoorbeeld text voor een doelgroep of code om vervolgens uitgevoerd te worden. de SCAN-aanroep wordt weggeschreven in de FILE ...

  SCAN label     : de tekst van de label-scan wordt geschreven. 
  FILE filenaam  : de tekst van de file wordt geschreven 
  TEXT xxx       : de waarde van TEXT wordt geschreven 
  APPEND         : de tekst wordt toegevoegd 

Letwel: tekst van TEXT of van de SCAN wordt geinterpreteerd, alle variabelen worden gesubstitueerd.

bv :

write("| SCAN CRE_REGELS | FILE c:/data/brief.txt | APPEND |")

BEGIN CRE_REGELS
  Beste heer [[achternaam]]

Hoe gaat het ....   ?     

met vriendelijke groet, [[afzender]]
RETURN

of 

  MVAR MYFILE =  c:/data/mytext.txt
  WRITE ('| TEXT demo-tekst              | FILE [[MYFILE]]  |')
  REPEAT 10 WRITE ('| TEXT tekst[REPEAT] | FILE [[MYFILE]] | APPEND |')
  cmd notepad [[MYFILE]]


waitfor

Een flow gaat wachten totdat aan een bepaalde voorwaarde is voldaan. Deze voorwaarde wordt getoetst middels een sql-query. Indien de query een record geeft, dat weergeeft dat aan de conditie is voldaan, gaat het processen verder. In het andere geval gaat het proces SLEEP-seconden wachten en dat herhaalt hij TIMES-keer.

Indien een procesB op een serverB data nodig heeft van een andere serverA dan blijft procesB netzolang wachten totdat middels een query vast gesteld wordt dat procesB gedraaid heeft.

  SOURCE    : indien query records geeft, dan stop wait
  SQL       : indien query records geeft, dan stop wait
  SSQL      : indien query records geeft, dan stop wait
  TIMES     : aantal iteraties  ( default 5)
  SLEEP     : Aantal seconden sleep ( default 10 )
  SOURCE_DB : query wordt uitgevoerd op deze connectie ( default current connectie )
 waitfor('| SSQL CHECK_IF_READY  | TIMES 10 | SLEEP 10  | SOURCE_DB pg_duitsland | ')

 BEGIN CHECK_IF_READY
     select 'wanneer de query een record oplevert, is voldaan aan de wacht-conditie' where 1=2 
 RETURN     

AUTOEXEC

Indien een grip_source.grp een procedure AUTOEXEC bevat, wordt deze uitgevoerd met het openen van deze source.

BEGIN AUTOEXEC 
  TITLE *** DOLF.GRP development **** ---->> [[FILENAME]]
  DISP 'deze routine wordt bij opstart van deze source uitgevoerd ... '
RETURN

TITLE

Met commando TITLE kan de omschrijving van de GRIP-editor aangepast worden.

TITLE *** DOLF.GRP development **** ---->> [[FILENAME]]

find text

Middels find kan de grp-code doorzocht worden op bepaalde teksten. Er zijn 2 parameters die geset moeten worden :

 SET PARA FIND_LOC CHAR C:\Users\dolf\PycharmProjects\pythonProject
 SET PARA FIND_WILDCARD *.py

de logging ziet er uit zoals hieronder, bestanden die niet ascii zijn, worden vermeld met Error, er zijn 71 bestanden gevonden volgens de wildcard. 

 SS_boss,grip_aux,INFO 08/01/2023, 21:06:10]  looking for .. :  C:\Users\dolf\PycharmProjects\pythonProject, *.py ( SET PARA FIND_LOC CHAR xxx , SET PARA FIND_WILDCARD yyy ) 
[SS_boss,grip_pd,INFO 08/01/2023, 21:06:10]  Error met verwerken commando .. FIND_TXT_IN_FILE  C:\Users\dolf\PycharmProjects\pythonProject/grip_dt - reserve.py programmatuur
[SS_boss,grip_pd,INFO 08/01/2023, 21:06:11]  Aantal hits 71

query_to_xls

Met de functie QUERY_TO_XLS kan op eenvoudige wijze sql-data gemapped worden op een tabblad van een excel-bestand.

   MAIL      : indien aanwezig, dan wordt het excelbestand gemaild naar de geadresseerde
   START     : indien aanwezig, dan wordt het bestand nadat de data geplaatst is, geopend in EXCEL 
   DIRECTORY : de directory van het bestand 
   SHEET     : het tabblad dat vervangen wordt door de data van de query 
   REMOVE    : indien het tabblad bestaat, dan wordt deze verwijderd.  
   DEBUG     : indien bestaat, dan wordt het nodige aan debug-info geprint. 
   TARGET    : bestandsnaam    bv "c:/data/vaccinregistratieformulier 08-08-2022 totaal.xlsx"
   SOURCE    : query 
   SSQL      : query via label 
   ROWNUM    : aantal rijen / records
 CALL QUERY_TO_XLS

BEGIN QUERY_TO_XLS
 query_to_xls('| SHEET  1) grip_aud     | SSQL    grip_aud   | TARGET test_excel.xlsx | DIRECTORY  c:/data/ | ROWNUM 100 | ST ART |') 
 query_to_xls('| SHEET  2) grip_para    | SOURCE  grip_para  | TARGET test_excel.xlsx | DIRECTORY  c:/data/ | ROWNUM 100 | ST ART |') 
 query_to_xls('| SHEET  3) grip_log     | SOURCE  grip_log   | TARGET test_excel.xlsx | DIRECTORY  c:/data/ | ROWNUM 100 | START | REMOVE Sheet,Sheet2,Sheet3 |') 
RETURN

BEGIN grip_aud
 select * from grip_aud order by id desc 
RETURN 

buttons

Handige faciliteit om commando's vanuit menu te starten .. Na het CMD-token kan ieder gewenst commando vermeld worden.

CALL BUTTONS 

BEGIN BUTTONS 
  buttons ('| ACTIE ADD  | NR 1  |  TXT tonen GRIP_LOG            | CMD xbrowse  grip_log  | ') 
  buttons ('| ACTIE ADD  | NR 2  |  TXT tonen GRIP_AUD            | CMD xbrowse  grip_aud  |') 
  buttons ('| ACTIE ADD  | NR 3  |  TXT tonen GRIP_JOB            | CMD browse   select * from grip_job  |') 
  buttons ('| ACTIE ADD  | NR 4  |  TXT tonen GRIP_PARA           | CMD browse   grip_para |') 
  buttons ('| ACTIE ADD  | NR 5  |  TXT user_tables               | CMD browse   select * from user_tables |') 
  buttons ('| ACTIE ADD  | NR 6  |  TXT user_views                | CMD browse   select * from user_views |') 
  buttons ('| ACTIE ADD  | NR 7  |  TXT VERSIEBEHEER              | CMD versiebeheer | ')
  buttons ('| ACTIE ADD  | NR 8  |  TXT DROP DROP_TEMP_TABLES     | CMD DROP_TEMP_TABLES | ')
  buttons ('| ACTIE ADD  | NR 9  |  TXT REFRESH_META              | CMD REFRESH | ')
  buttons ('| ACTIE ADD  | NR 10 |  TXT aanmaak nieuwe executable | CMD mk_exe  | ')
  buttons ('| ACTIE ADD  | NR 11 |  TXT --------                  | CMD sound("w2")  | ')
  buttons ('| ACTIE ADD  | NR 16 |  TXT tada                      | CMD sound("x1")  | ')

  buttons ('| ACTIE SHOW  | TITLE GripMenu ')
RETURN

copyfile

Met copyfile kan een source gekopieerd worden naar een target-bestand waarbij in de content variabelen gebruikt worden welke dan gesubstitueerd worden .
Dus tijdens de kopieerslag wordt iedere variabele gesubstitueerd. Middels cmd notepad kan het resultaat bekeken worden. Het doeltabel kan een beslissingstabel-script zijn of bv een batchfile. Deze methodiek is erg flexibel omdat je feitelijk iedere parameter wel mee kan geven .. Middels 'MVAR' kunnen alle variabelen gedefinieerd worden welke nodig zijn. De SOURCE mag óók een bestand zijn van het web : bv

COPYFILE ('| SOURCE file  | TARGET tt|') :  file is bv c:/data/grip_doc.grp  of https://www.gripopdata.nl/programmatuur/grip_doc.grp
COPYFILE ('| SCAN   label | TARGET tt|') :  de tekst van de label wordt in een file geplaatst. Deze inzet heeft veel verwandschap met WRITE

In onderstaand voorbeeld is de opzet paralle verwerking te realiseren ... Naast 'MVAR'-variabelen kan ook 'VAR'-variabelen gebruikt worden, echter, MVAR zijn memory-variabele terwijl VAR-variabelen in tabel grip_para zitten met als gevaar dat een ander proces deze variabele veranderen kan wat ongewenst is ..

record_on('| FLOW PF_REDENEER_1 |')
  MVAR PARTITIE    = 1
  MVAR DIRECTORY   = c:/data/rivm/ 
  MVAR PRIKKEN_CLT = PRIKKEN_CLT_[[PARTITIE]]
  MVAR PRIKKEN     = PRIKKEN_[[PARTITIE]]
  MVAR password    = @#$#@!

  copyfile ('| SOURCE [[DIRECTORY]]CIMSprikken_v1 - psql.txt | TARGET [[DIRECTORY]]CIMSprikken_v1 - psql_[[PARTITIE]].txt |')
  redeneer ('| SOURCE [[DIRECTORY]]CIMSprikken_v1 - psql_[[PARTITIE]].txt | TARGET [[DIRECTORY]]REDENEER_[[PARTITIE]].csv | HOST localhost | USER postgres | PASSWORD [[password]] | PORT 5432 | DATABASE rivm_rvp_v4  | ')
record_off()

#cmd notepad [[DIRECTORY]]CIMSprikken_v1 - psql.txt

excel2

Deze routine of functie maakt het mogelijk om gegevens van een Excel-sheet in een tabel in te lezen. Als de tabel nog niet bestaat, wordt deze aangemaakt. Het ondersteunt ook het inlezen van meerdere Excel-bestanden met behulp van een wildcard en logt eventuele fouten in een aparte tabel (grip_debug) voor latere analyse en probleemoplossing.

  WILDCARD   :
  SOURCE     : 
  DROP       : de tabel wordt verwijderd en weer gecreerd op basis van de aangeboden data.
  TRUNCATE   : de tabel wordt vooraf leeggegooid 
  ACTIE      : PRINT voor tonen van uit te voeren statement, 
  CHUNK      : staat default op 1000 : de heveelheid records welke per keer ingelezen wordt. 
  DEBUG      : voor debug-informatie 
  TARGET     : de target-tabel, wordt aangemaakt indien hij niet bestaat. 
  TARGET_DB  : de target-database waar de target-tabel zich bevindt .. 
  HEADER_RC  : de locatie van de header ( ROW/COL) is default 1,1
  AREA_RRCC  : de range waar de data zich in bevindt : van r1-r2 en k1-k2 
  ROWNUM     : aantal records dat gelezen wordt .
  SAMPLE     : op basis van een sample wordt de target-tabel aangemaakt. 
  OFFSET     : aantal records vanaf ... 
  FAST       : bij bepaalde databases deze token plaatsen voor oplossen van laadproblematiek 
  NOHEADER   : de header is die van excel, A1,A2,A3 .. en niet bepaald vanuit de data .. 
  ENCODING   : | ENCODING utf8 |indien encoding-error optreedt, onderzoeken in welke taalset de code staat .. 
  NOSPECIALS : Rare tekens buiten (a..z,A..Z) worden verwijderd uit de tekst .. 
  ONCHANGED  : 

  WILDCARD   : Indien WILDCARD is gevuld, dan wordt op basis hiervan de set bestanden verwerkt. In geval van fout, wordt daar meldeing van gemaakt 
               en wordt het volgende bestand opgepakt.
  ACTIE      : PRINT voor tonen commandoos per file en PARSE voor uitvoeren van die commandoos 
  DIRECTORY  : directory waar de bestanden staan
  FREMOVE    : na verwerken wordt het bestand verwijderd 
  FRENAME    : na verwerken bestand wordt het gerenamed .. naar *_done
  ITERATIE   : indien ITERATIE 3, dan worden 3 bestanden verwerkt. 

voorbeelden :

    excel2('| SOURCE C:/data/xls_testbestand1.xlsx | SHEET all_tab_columns | DEB UG | CHUNK 200 | TARGET XLS_TBS | DR OP | TARG ET_DB |   ROWNUM 100 |  ')
    excel2('| DIRECTORY C:/data/ | WILDCARD xls*.xlsx | AC TIE PRINT | SHEET all_tab_columns | D EBUG | CHUNK 200 | TARGET XLS_TBS | ONCHANGED SECONDS 1 |  ROWNUM 100 |  ')

csv_to_table

Inlezen van CSV-files.

parameters:  
  SOURCE    *: bv c:/data/mijnbestand.csv. icm met DIRECTORY kan bij SOURCE een wildcard gebruikt worden waardoor een hele set bestanden verwerkt wordt.
  DIRECTORY  : Directory geeft de directory aan, terwijl SOURCE de wildcard mag bevatten. 
  TARGET    *: de naar van de target-file. Wordt aangemaakt op basis van de bron. Bevat de volgende bron langere attributen, dan zal de target-tabel aangepast moeten worden 
  TARGET_DB  : de doel-database waar de TARGET zich bevindt. Connection naam dient hier opgegeven te worden 
  DEBUG      : tonen debug informatie
  TRUNCATE   : Indien geplaatst, wordt, bij de eerste keer, de tabel leeggegooid, bij volgende csv-bestanden wordt de data toegevoegd
  DROP       : De tabel wordt verwijderd en weer opnieuw aangemaakt, met attribuut-sizes gebasseerd op de huidige data-set ..  
   --
  ONCHANGED  : Hiermee wordt aangegeven dat het bestand alleen verwerkt wordt indien na de laatste verwerking het bestand nog gewijzigd is. Wordt een bestand aangepast, zal
               hij een recentere timestamp hebben dan de laatste_keer_lezen, of wel de last_date_processed (ldp).  Deze registratie staat in grip_aud. De combinatie SOURCE
               TARGET wordt gezocht. Indien een hoop bestanden opnieuw ingelezen moeten worden kan dat door het commando tijdelijk te verwijderen. Ook kan middels additionele 
               parameter SECONDS,HOURS,DAYS gevolgd door een AANTAL, verder teruggekeken worden naar gemuteerde bestanden. 

               bv ONCHANGED DAYS 10 kijkt naar wijzigingen tot 10 dagen terug. 
   --
   DELIMITER  : Hiermee kan de delimiter opgegeven worden : voor | geldt 'pipe' Andere voorbeelden zjn ,;
   SKIPROWS   : de zoveelste rows worden geskipped.
   ENCODING   : bv. ENCODING utf8. 
   HEADERLINE : 
   NOHEADER   :               

  in geval van WILDCARD: 
  SPOOL   :  worden de statements getoond ipv uitgevoerd. Praktisch voor debuggen 
  FRENAME :  kan het verwerkte bestand gerenamed worden naar '_done'
  FREMOVE :  kan het verwerkte bestand verwijderd worden.  
  TIMES   :  numerieke waarde, hiermee kan met bv "| TIMES 3 | " 3 bestanden verwerkt worden.


  LOGGING  : succesvolle aanroepen worden gelogd in grip_audit, grip_debug en grip_log.

  ERRORS   : processing gaat door, fouten worden gelogd in o.a. grip_debug. Op fouten kan een query gemaakt worden welke middels mail naar de beheerder verstuurd kan worden. 

  PRAKTIJK : Indien de csv-bestanden erg varieren van inhoud, is deze facilteit kwetsbaar. Op enig moment zal de target-tabel voldoende 'groot' maar is er weer 
             een csv met een grotere kolom, zal de functie weer in error schieten. Middels ALTER table ALTER column kolomnaam VARCHAR 200 .. 

csv_to_table('| SOURCE c:/data/rivm/Business ruling CIMS en BICIMS kritieke data1.csv | TARGET stg_dqm_rules |  ONCHANGED SECONDS 2  |') 
csv_to_table('| SOURCE c:/data/rivm/Business ruling CIMS en BICIMS kritieke data2.csv | TARGET stg_dqm_rules |  ONCHANGED  HOURS 4 |') 
csv_to_table('| SOURCE c:/data/rivm/Business ruling CIMS en BICIMS kritieke data3.csv | TARGET stg_dqm_rules |  ONCHANGED SECONDS 2  |') 
csv_to_table('| SOURCE c:/data/rivm/Business ruling CIMS en BICIMS kritieke data4.csv | TARGET stg_dqm_rules |  ONCHANGED  HOURS 4 |') 

csv_to_table('| DIRECTORY  c:/data/rivm | SPO OL | SOURCE Business ruling CIMS en BICIMS kritieke data*.csv | TARGET stg_dqm_rules |   ONCHA NGED SECONDS 2000  |') 

Versiebeheer

Dit versiebeheer-mechanisme maakt gebruik van script- en view-bestanden die regel-georiënteerd worden opgeslagen in de grip_source-directory. Het houdt de geschiedenis van wijzigingen bij in de grip_source_hist tabel en maakt het mogelijk om gegevensversies terug te zetten naar eerdere pijldatums. Het wordt ook gebruikt om gegevensafkomst bij te houden door het genereren van create-scripts voor alle views die beschikbaar zijn onder de huidige connectie.

 SOURCE    : de directory-locatie van de sources / textfiles 
 WILDCARD  : de wildcard, bv *.grp
 LABEL     : het label waaronder de code geregistreerd wordt    
 CONTEXT   : de context waaronder de code geregistreerd wordt 
 TARGET_DB : de database/connectie van de grip_source tabel
txtfiles_2_dbf ('| SOURCE  C:/Users/dolf/PycharmProjects/pythonProject/ | WILDCARD *.grp,*.exe |')     
txtfiles_2_dbf ('| SOURCE  C:/Users/dolf/PycharmProjects/pythonProject/ | WILDCARD *.txt,*.grp | LABEL Programmatuur | CONTEXT myContext | TARGET_DB SS_boss | SHOWETL | ')

views_2_dbf    ('| LOG_INFO t2-versiebeheer van de views van current-schema | LABEL ETL_VIEWS | CONTEXT DEMO_VIEWS  | ')

2 views/overzichten voor welke versies er inmiddels bestaan

CALL ALL_SOURCE

BEGIN ALL_SOURCE
QRY
  select source, sum(1)  
  from GRIP_SOURCE 
  group by source
SHOW;
RETURN

BEGIN ALL_VERSIONS
QRY
  select 
    row_number() over ( partition by 1 order by date_created asc ) vrs
  , row_number() over ( partition by 1 order by date_created desc ) mvrs
  ,  x.* 
  from 
  (
    select  date_created 
    from xxx.grip_source_hist 
    where date_created is not null 
    group by date_created
    union 
    select  date_deleted 
    from xxx.grip_source_hist  
    where date_deleted is not null 
    group by date_deleted
  ) x
SHOW;
RETURN

Iterators

Repeat

In de GRIP-taal zijn een paar iterator-faciliteiten gerealiseerd die hieronder beschreven worden:

Het REPEAT-commando roept x-aantal keren het statement uit. Per iteratie kan gebuik gemaakt worden van de variabele [[REPEAT]] Deze variabele wordt steeds 1 waarde afgelaagd tot hij de waarde 1 kent.

REPEAT 10 CALL ROUTINE 

BEGIN ROUTINE
  DISP [[REPEAT]]
  DISP alle willekeurig mogelijke commando's 
QRY 
 insert into medewerkers ( id, medewerker_omschr )
 [[REPEAT]] , 'Medewerker_'[[REPEAT]]
EXEC;  
RETURN

scandate

Middels de scandate kan een range afgelopen worden waarbij per iteratie-stap de variabele SCANDATE of SCANDATE_ gebruikt kan worden


scandate("| VAN 2022-09-01 | TOT 2022-09-10 | CMD CALL VERWERK_API | ")

BEGIN VERWERK_API
  DISP de volgende iteratie-variabelen zijn te gebruiken : [[SCANDATE]] en [[SCANDATE_]]
  DISP alle willekeurig mogelijke commando's 
QRY
 select count(*) from grip_aud where date_created = '[[SCANDATE]]'
SHOW;
RETURN

scanlist('| LIST 1,2,3,4,5 | SCAN VERWERK_ELEMENT |')

Met scanlist kan een lijst verwerkt worden: per element wordt de procedure van SCAN aangeroepen waar variabele [[ELEMENT]] de waarde van het element bevat.

scanlist ( '| LIST  dolf.grp,grip_googleTREE_MENUcopy.grp,finan.grp,grip_graph.grp    | SCAN TOON |' )

BEGIN TOON
  DISP [[__]]  [[ELEMENT]]
RETURN

Middels de scandir wordt een directory gescanned op basis van wildcard. In 'variabelen' komen de specifieke waarden beschikbaar voor verdere processing. Met de parameter FORMAT kun je per bestand het commado opgeven waarbij de syntaxt wat anders is: Normaal is de syntax '| aa | bb | cc |' maar nu dient je ~! aa ! bb ! cc !~ te gebruiken. In plaats van het commando te definieren in FORMAT, wordt de code overzichtelijker door 'FORMAT CALL SCANDIR_ROUTINE' te kiezen, zodat in die routine overzichtelijkere logica kan worden gecodeerd.

scandir ('| ACTIE PRINT  | DIRECTORY [[CURRENT_DIR_]]/API_FILES | WILDCARD 2022-09-03*.json |  FORMAT json_to_table (~ FILE [[CURRENT_DIR_]]/API_FILES/<file> ! RENAME ! TARGET TRAPPER ! ROWS 100 ! BULK 100 ! SLO W !~) | ')
  DIRECTORY  : directory van de bestanden , bv c:\data
  WILDCARD   : de bestanden welke gefilterd dienen te worden 
  ACTIE      : PRINT voor display van statement, PARSE voor uitvoer van het statement (FORMAT) en EXEC is voor uitvoer van het FORMAT-commando op CMD-nivo. 
  ITERATIE   : Aantal iteraties 
  FORMAT     : staat voor het commando-string dat opgebouwd wordt.  
  ONERROR    : Indien er een fout optreedt, 
  FRENAME    : de gelezen file wordt gerenamed naar *_done, zodat hij de volgende keer buiten de WILDCARD valt. 
  FREMOVE    : de gelezen file wordt verwijderd van het filesystem 

Indien het DROP of TRUNCATE commando gebruikt wordt, zal bij de eerste iteratie daarwerkelijk de DROP danwel TRUNCATE uitgevoerd worden, daarna wordt het een APPEND-commando.

de volgende tokens kunnen in de FORMAT-string gebruikt worden: 

  <file>,<dir>,<truncate>,<drop>,<dirx>,<COMMANDS>  

de vertalingen zijn : 
 parser-vertaal-vertragers:  
 '(~'  ->  "(r'|"   
 '~)'  ->  "')" 
 '~'   ->  '"'  
 '!'   -> "|" 

of

scandir ('| FORMAT csv_to_table(~ SOURCE <dir>/<file> ! <drop> ! <truncate>   ! TARGET stg_financieel !~) |  | DIRECTORY c:/data/financieel | WILDCARD TXT2004*.TAB | ACTIE  PARSE | ONERROR STOPPER | ')

scandir ('| ACTIE PRINT  | DIRECTORY [[CURRENT_DIR_]]/API_FILES | WILDCARD *.json |  FORMAT  CALL SCANDIR_ROUTINE | ')
scandir ('| ACTIE PARSE  | DIRECTORY [[CURRENT_DIR_]]/API_FILES | WILDCARD *.json |  FORMAT  CALL SCANDIR_ROUTINE | ')


BEGIN SCANDIR_ROUTINE
    DISP [[CURRENT_DIR_]], [[FILE]], [[DIR]], [[DIR_]], [[TRUNCATE]], [[DROP]], [[ITERATIE]]  
RETURN

dirscan ('| DIRECTORY | WILDCARD | CALL xxx| ')

Voor aanroep van de procedure per gevonden bestand. Het gevonden bestand en proces-informaties is in variabeles beschikbaar

  • FILE
  • DIR
  • DIR_
  • TRUNCATE
  • DROP
  • ITERATIE

SHELL

Middels het SHELL commando kan op windows-nivo een applicatie gestart worden. De ERRORLEVEL is een WINDOWS-parameter waarmee je kunt uitlezen of een Executable succesvol geeindigd is of niet ... In de documentatie van de executable kun je gewaarworden welke exitcode voor succesvol staat. Meestal is die waarde 0. Op basis van deze code kan een OK_CMD flow of een NOK_CMD flow gestart worden.

BEGIN SHELL
   aanroepen van een batchfile of andere executable. De return-value of exitcode wordt opgevangen en op basis daarvan kan een vervolgflow aangeroepen worden. 
   de OK_VALUE is de waarde die de OK-flow op doet starten, anders wordt de NOK_CMD flow gestart. De flows starten is optioneel. In geval van een fout-situatie 
   kan bv een mailtje gestuurd worden. 

   shell( '| COMMAND c:/work/run.bat  C:/data/STG_PVS_DEP2_00001.csv_done 1 | OK_CMD JAJA | NOK_CMD NEENEE | OK_VALUE 0 | ')
RETURN

query_to_json

SOURCE    : tabel of view waarvan een json-tabel gegenereerd wordt. 
FILE      : bestandsnaam van de json-file
DIRECTORY : de directory. Is optioneel, directory kan ook in de FILE-part opgenomen worden.
TARGET_DB : de TARGET-tabel in dit schema wordt geraakt, tevens wordt in deze grip-tabellen gelogd
SOURCE_DB : de data van dit schema wordt opgehaald. 

query_to_json('| SOURCE STG_ANTWOORDEN  |  TOP 100  | FILE c:/data/ploop[[YYYYMMDD]] | CONN pg_duitsland  |')

more flow

FLOWER
[[CR]][[__]]
  Functionaliteit voor flows ... 
  record_on ('| FLOW PF_MYFLOW |')... record_off()  : alle statements tussen record_on/off worden opgenomen in tabel GRIP_JOB. In deze record_mode voeren alle commando's
                                                      niets uit. Nadat de gehele flow opgenomen is, kan de flow gestart worden middels flow_run('| FLOW xx |'). Alle statements 
                                                      behorende tot de flow worden in de volgorde van opname, uitgevoerd. In GRIP_JOB staat de definitie van de FLOW. Een eventueel
                                                      reeds aanwezig flow wordt geheel overschreven ...

BEGIN PF_SLEEPER
  DISP  Start van de PF_SLEEPER .... 
  sleep 3
  sleep 3
  sleep 3
  sleep 3
  DISP  Einde van de PF_SLEEPER .... 
RETURN

record_on('| FLOW PF_SLEEPER | CONNECTION pg_duitsland | FILE grip_doc.grp  |')
  DISP  Start van de PF_SLEEPER .... 
  sleep 3
  sleep 3
  sleep 3
  sleep 3
  DISP  Einde van de PF_SLEEPER .... 
record_off()

Flow's of ETL-jobs worden opgeslagen als metadata in de tabel GRIP_JOB. Middels onderstaande query kun je de metadata inzien :  

 browse select * from xxx.grip_job where parent = 'PF_SLEEPER' 

 of 

 select * from xxx.grip_job where parent = 'PF_SLEEPER' 



flow_run  ('| FLOW PF_SLEEPER  | ')  

                1) middels flow_run wordt de flow uitgevoerd : de statements van de flow, de flow-definitie in GRIP_JOB, worden in GRIP_JOB_RUN geplaatst. In 
                deze tabel zijn wat meer attributen aanwezig zoals status, start_dt, stop_dt, vnr,fnr  en error_info. Deze parameters zijn nodig voor de 
                uitvoer van de statements van de flow.  In een flow kunnen ook meerdere flow_runs voorkomen. Ook hier geldt dat de content van de aangeroepen 
                flow ingekopieerd wordt op de plek van de aanroep van die flow. Roep je 6x dezelfde flow aan, wordt dit voor iedere flow herhaald. 
                Roept een flow die aangeroepen wordt, óók weer een flow aan, wordt ook hiér weer de inkopieer-slag gedaan. Op het moment kan er tot 3 diep
                flows verwerkt worden. 
                2)
                Zodra de gehele flow opgebouwd is in GRIP_JOB_RUN, staat de hele set aan commando's in de juiste volgorde (vnr) voor uitvoer: alle 
                statussen staan op 'A_selected_for_start'. Steeds wordt het LAAGSTE vnr-nummer geselecteerd met status = 'A_selected_for_start', 'E_error'
                3) 
                Indien er met een statement een error optreedt, wordt de flow beeindigd en wordt de status op 'E_error' gezet. Gaat het statement goed, dan 
                wordt de status van dat statement op 'D_ready' gezet en wordt gezocht naar een volgend laagste vnr-nummer met status 'A_selected_for_start' of 'E_error'
                4)
                Middels parameter IGNORE_ERROR wordt het statement van de flow op 'I_Ignored' gezet ingeval van een error en gaat de flow verder met het volgende statement.
                Deze IGNORE_ERROR geldt alle statements van de FLOW. 

 frun( '| FLOW PF_SLEEPER  |') 

                De flow_run(' FLOW PF_SLEEPER ') wordt uitgevoerd, echter via de ECALL. Middels ECALL wordt de flow opgestart, via een losse GRIP-sessie die 
                parrallel zijn eigen gang gaat. De frun() is handig wanneer je vanuit de editor een flow wilt starten en ook wilt doorwerken zonder op de flow
                te hoeven wachten. 



flow_run  ('| FLOW PF_SLEEPER | IGNORE_ERROR | DEBUG |')  

                 Middels IGNORE_ERROR krijgt een Flow-stap die in ERROR gaat de status 'I_Ignored'... de flow gaat door met de volgende stap .. 
                 Aan het einde van de FLOW wordt het aantal fouten gerapporteerd. 
                 Met DEBUG wordt uitgebreid gelogd om inzicht te krijgen in de GRIP-processing.

flow_run  ('| FLOW PF_SLEEPER | IGNORE_ERROR | CONN pg_boekhouding  |')    
                 De FLOW wordt opgenomen in de CONNECTION pg_boekhouding. Hiermee geef je expliciet aan in welke database/schema/connectie je de flow gedefinieerd wilt hebben.
                 Per abuis wil het wel voorkomen dat een foute connectie geselecteerd is waardoor de flow in een verkeerd schema terecht komt.                                  

flow_drop ('| FLOW PF_SLEEPER  | ')

                 Een flow die in error staat wordt verwijderd uit GRIP_JOB_RUN. De flow wordt verplaatst naar GRIP_JOB_RUN_HIST. 

flow_drop ('| FLOW PF_SLEEPER  | DEF | ')

                 Met de DEF parameter erbij wordt tevens de definitie uit GRIP_JOB verwijderd. 
                 Deze functionaliteiten hebben betrekking op de current-user/schema. 


flow_skip_error ('| FLOW PF_SLEEPER  |')

                 Indien een FLOW in de error staat en de stap in error behoeft niet opgelost te worden, kan middels deze functie de flow doorgestart worden. 
                 Van de stap in error wordt de status op 'S_Skipped' gezet en vervolgt de flow zijn uitvoer met de volgende stap.     

 flow_info('| ALL |') 
     Tonen van 
 flow_info('| RUN |')
 flow_info('| DEF |')


  flow_drop ('| FLOW PF_SLEEPER  | DEF | ')
  flow_run('| FLOW PF_TESTFLOW_WITH_ERROR|')

logger

Programmas welke via de scheduler lopen, loggen welliswaar in tabellen, maar het is ook handig wanneer de printopdrachten gelogd worden in een log-file

  SETFILE   : aanmaak van een log-file .. 
  CLOSEFILE : loggen wordt beeindigd .. 
  REMOVE    : loggen wordt beeindigd en de logfile wordt opgeruimd.  

Handige toepassing : indien de laatste regel de REMOVE is maar die wordt door een fout-situatie niet behaald, heb je de logging totaan de foutsituatie ..

BEGIN   
  logger('| SETFILE c:/data/MYlogging[[GETENV USERNAME]].txt |') 

  DISP text voor logger 1
  DISP text voor logger 2 
  DISP text voor logger 3

  logger('| CLOSEFILE | REMOVE |') 
  logger('| CLOSEFILE  |')   
RETURN

dbexec

dbexec biedt je de mogelijkheid om dbms-statements uit te voeren . Het betreft 1-regel-commando's

een alternatief, voor meer regels is QRY ...EXEC; (let op de ; )

BEGIN CRE_VIEW
 dbexec drop view test_v
 QRY
   create or replace view test_v
   as select sysdate from dual 
 EXEC; 
RETURN 

build_sql()

Deze routine is een intern gebruikte functionaliteit waarmee mete-data-driven, de sql-query pgebouwd wordt .

SCAN : SSQL : SHOWETL : SQL : SOURCE : WHERE : LAST_DATE_PROCESSED :
LIMITED :

sqlcall('| |')

De select-columns zijn als variabelen beschikbaar in de aangeroepen grip_call-procedure . Deze functionaliteit is bijzonder krachtig wanneer je op eenvoudige robuuste manier data-driven wilt processen. De attributen van de query zijn als variabelen beschikbaar. De waarde null of None wordt None .

FILENAME : de CALL-procedure bevindt zich in bestand 'FILENAME', kan ook middels 'proc@file' DEBUG : voor tonen debug-informatie: zo wordt ook weergegeven hoe de variabelen heten en welke waarde ze bevatten. Middels copy-paste kan de debug-informatie gebruikt worden voor de code. ROWNUM : aantal regels/records te scannen NOREFRESH : steeds wanneer er wat met de database gebeurt, wordt de metadata verversd, hetgeen tijd kost. middels 'NOREFRESH' kan dit refreshen uitgezet worden. SQL / SOURCE / SSQL : voor koppelen van de SQL-query aan de functie. ( build_sql** ) CALL : per record wordt deze procedure aangeroepen.

sqlcall ( "| SQL select * from stg_dqm_rules_v | WHERE sql_teller is not null |  TOP 10 | CALL DQM_F1  | ")

BEGIN DQM_F1
  DISP [[sql_teller]] [[vnr]] [[sql_teller]]
RETURN

Middels onderstaand voorbeeld kun je table-driven trunc_inserts uitvoeren. Vaak is voor bron-replicatie dit wel een handige faciliteit.

sqlcall ( "| SSQL SQL_QRY | CALL DQM_F12  | ")

BEGIN DQM_F12
  DISP [[table_name]]
  DISP trunc_insert('| SOURCE [[table_name]] | TARGET [[table_name]]_HIST |')
RETURN

BEGIN SQL_QRY
  select 'grip_aud' table_name union
  select 'grip_job'
RETURN

edit grip_calls.grp

Met dit commando kun je snel naar een andere source. Indien deze niet bestaat, wordt de source aangemaakt.

edit grip_snmp.grp
edit try.grp

scanlist ('| |')

Met scanlist() kan een eenvoudige lijst met elementen geprocessed worden waarbij per per element de procesure aangeroepen wordt. In de procedure is variabele [ELEMENT] beschikbaar voor de beoogde functionaliteit.

SCAN : de procedure welke aangeroepen wordt LIST : de lijst met elementen, gescheiden door een comma.

  scanlist('', SCAN MyListProc )

  BEGIN  MyListProc  
     DISP Het aangeboden element is : [[ELEMENT]]
  RETURN




## runpy('| SCAN label| FILE file ')

Middels runpy() kan Python code uitgevoerd worden. Met SCAN wordt de code bij de label opgezocht en uitgevoerd. Met FILE <> wordt de code in het bestand uitgevoerd. 
De code wordt gecopieerd maar ook gescanned waardoor de code ook gepre-processed wordt: [[variabelen]] kunnen worden gebruikt maar ook bv het SCAN> commando . SCAN> wordt vervangen
door de text die gevonden wordt bij het label..


BEGIN TRY import openpyxl i-1

SCAN> DEF_PRINT_TEXT

print ('fase11')

wb = openpyxl.load_workbook('C:/data/rivm/Formdesk_verwerkings_resultaat_09-02-2023_DJ.xlsx', read_only=True )

ws = wb['4_CLT_MatchResultaat']

l_maxcol = ws.max_column l_maxrow = ws.max_row l_row = 1 l_col = 1 l_max_rows = 100

l_columns = {} l_dataset = []

l_header = -1

print ( l_maxcol ) print ( l_maxrow )

for row in ws.rows: if l_header == l_row or l_header == -1: # initialisatie header l_header = -2 # uitzetten van de werking for cell in row:
l_col = l_col +1
if l_row == l_header : l_column_name = cell.value else: l_column_name = 'k' + str(l_col)

       l_columns[l_column_name] = {}
       l_columns[l_column_name]['len_source']  = 0
       l_columns[l_column_name]['type_source'] = '?'
       l_columns[l_column_name]['len_target']  = 0
       l_columns[l_column_name]['type_target'] = '?'


l_row = l_row + 1

if l_row > l_max_rows : break 
l_dataset.append( row )

print ( l_header ) print ( l_columns )

print ( l_dataset )

wb.close() RETURN

BEGIN DEF_PRINT_TEXT def printer: print('hello wordl') RETURN

##sound
Middels een geluidsignaal kun je er op gewezen worden dat een bepaalde stap klaar is .. 
Er zijn een aantal geluiden beschikbaar . 

sound('x1') x1 .. x2

sound('r1') r1 .. r10

sound('w1') w1 .. w7

sound('a1') a1 .. a10


## passwords en keepass. 

keyring is een windows credential faciliteit... je kunt de Credential Manager opstarten middels links onder in te voeren : credential manager
Het onderhoudsscherm start op en selecteer 'Windows Credentials' en vervolgens rubriek 'Generic Credentials'


keyring_set ('| ENDPOINT keepass/grip_user/wachtwoord_keepass_123 |')

DISP [[ KEYRING keepass/grip_user ]]

In de grip_taal kunnen we nu middels [[ KEYRING xxx ]] beschikken over versleutelde waarde van xxx 


daarnaast is Keepass-begruik mogelijk middels  :

   keyring_set  ('| ENDPOINT keepass/keepass/wachtwoord123  |')

   keepass_init ( '| FILE C:/Users/dolf/PycharmProjects/pythonProject/grip.kdbx | PASSWORD [[ KEYRING keepass/keepass ]] |' ) of 
   keepass_init ( '| FILE C:/Users/dolf/PycharmProjects/pythonProject/grip.kdbx | PASSWORD wachtwoord123 |' ) 


   vervolgens kan de gehele keepass geprogrammeerd worden vanuit GRIP: 

keepass_set( '| ENDPOINT vpn/149/postgresql/werk  |  USERNAME blakie      |  PASSWORD  ploper1964!! | NOTES  dsadasdasdasdasdasd | ' ) 
keepass_set( '| ENDPOINT vpn/linux/sqlserver/werk |  USERNAME theboss$#@! |  PASSWORD  theboss$#@!  | NOTES  dsadasdasdasdasdasd | ' ) 
keepass_set( '| ENDPOINT vpn/gripop/oracle/grip   |  USERNAME pygrip      |  PASSWORD  gripopdata   | URL DRIVER={ODBC Driver 17 for SQL Server};SERVER=gripop;DATABASE=GRIP;UID=theboss$#@!;PWD={SGyGA1235sMQMkci1gn}  | ' )

DISP [[ KEEPASS vpn/149/postgresql/werk/username  ]]
DISP [[ KEEPASS vpn/linux/sqlserver/werk/notes  ]]
DISP [[ KEEPASS vpn/149/postgresql/werk/url  ]]


Middels [[ KEYPASS endpoint ]] kan het wachtwoord opeghaald worden maar ook NOTES of URL. URL zou gebruikt kunnen worden voor de gehele connectstring in keypass. 

Letwel op: een flow of prg draait onder een SYSTEM-user : dit is een andere user dan een ontwikkelaar .. en de KEYRING zal een andere zijn ... 
Wel kan een gemeenschappelijke Keepass gebruikt worden ... 


keepass_set( '| ENDPOINT localhost/macbook/mysql/werk | USERNAME root | PASSWORD gripopdata!! | NOTES Inloggen maar | ' )

add_conn ('| CONNECTION MySql1 | CON_TYPE mysql | MESSAGE MySql | SERVER 127.0.0.1 | PORT 3306 | DATABASE grip_sc | USERNAME [[ KEEPASS localhost/macbook/mysql/werk/username]] | SCHEMA grip_sc | GRIP_SCHEMA grip_sc | PASSWORD [[ KEEPASS localhost/macbook/mysql/werk/password]] | ODBCDSN {MySQL ODBC 8.0 Unicode Driver} | ')

close_con('| CONNECTION MySql1 |')

  data overzetten van connectie naar connectie .. kan dus van oracle naar sqlserver bv . 
  indien de target-tabel niet bestaat, wordt de structuur van de bron overgenomen. 


##copytab3

copytab3('||') 

DEBUG : voor debug info SOURCE_DB : de connectie van waar de data vandaan moet komen. TARGET_DB : de connectie waar de resultaatdata naar toe moet . TARGET : de naam van de target_tabel CHUNK : default 1000, de hoeveelheid records per keer / per iteratie ITERATIE : hoeveel CHUNK's , default 100000. ARRAY : arraysize , een oracle parameter ..

BINDVAR : default '?', kan ook %s zijn .. SHOWDATA : tonen debug-scripts SKIPCOLS :



## snmp

snmp ('|WALK | IPNR | PORT | OID | OMSCHRIJVING | SCAN | FILE | FILTER | ')

SNMP, ofwel Simple Network Management Protocol, is een veelgebruikt protocol voor het beheren en monitoren van netwerkapparaten en systemen. 
Het is een protocol op de toepassingslaag in het Internet Protocol (IP) suite en is ontworpen om de uitwisseling van beheerinformatie tussen netwerkapparaten te vergemakkelijken.

Middels GRIP_snmp kan op eenvoudige manier informatie over deze apparaten in uw netwerk verzameld worden voor rapportage-doeleinden/dashboards.  
Zo kunnen routers uitgelezen worden voor bijvoorbeeld aanwezigheid van personeel op basis van hun GSM. 

IPNR : IPnr van het apparaat in uw netwerk PORT : default 161 OID : het Object Identifier (OID),
OMSCHRIJVING : voor een specifieke oid kan de functionele omschrijving meegegeven worden voor een eventuele insert-statement SCAN : middels de SCAN parameter kan per OID een procedure aangeroepen worden voor vervolgacties. Een aantal variabelen met de huidige waarde is beschikbaar. FILE : de waarden worden weggeschreven naar een csv-bestand. FILTER : alleen weergave indien de zoekstring van het filter in de OID-waarde voorkomt.
WALK : Middels de WALK wordt vanaf de OID alle onderliggende (OID-nodes) iin de herarchische structuur gescanned. De gevonden waarden zijn in variabelen beschikbaar.


Een veel voorkomende OID in SNMP is 1.3.6.1.2.1, dat verwijst naar het Internet MIB (Management Information Base) subtree.

voorbeeld van de uitvoer:

1136 1.3.6.1.2.1.43.12.1.1.4.1.1 - SNMPv2-SMI::mib-2.43.12.1.1.4.1.1 = black 1137 1.3.6.1.2.1.43.12.1.1.4.1.2 - SNMPv2-SMI::mib-2.43.12.1.1.4.1.2 = cyan 1138 1.3.6.1.2.1.43.12.1.1.4.1.3 - SNMPv2-SMI::mib-2.43.12.1.1.4.1.3 = magenta 1139 1.3.6.1.2.1.43.12.1.1.4.1.4 - SNMPv2-SMI::mib-2.43.12.1.1.4.1.4 = yellow


beschikbare variabelen per walk via de SCAN lavbel beschikbaar voor bv een insert-statement  : 

SNMP_CODE         : de OID van de current node
SNMP_CODE_PRETTY  : de functionelere naam van de OID
SNMP_VALUE        : de waarde van de OID 
SNMP_OMSCHRIJVING : een meegegeven omschrijving van een specifieke OID. Heeft geen nut bij een WALK.
SNMP_IPNR         : het ipnummer van het apparaat.


DBEXEC insert into MY_SNMP_VALUES (code,waarde,date_time) values '[[IPNR]]',[[DNMP_CODE]]','SNMP_VALUE',current_time();

```

mkdoc()

bepaal_codec

bepaal_codec( '| INFILE C:/Users/dolf/PycharmProjects/pythonProject/dolf.grp | ' )

codec_convert(' |')

codec_convert('| INFILE C:/Users/dolf/PycharmProjects/pythonProject/dolf.grp | OUTFILE C:/Users/dolf/PycharmProjects/pythonProject/dolf.grp_jag | ENCODING_OUT utf-8 |')

INFILE       : ingaand bestand  
OUTFILE      : uitgaand bestand 
ENCODING_IN  : indien leeg, dan wordt de codec van ingaande bestand automatisch bepaald met bepaal_codec 
ENCODING_OUT : indien leeg, dan wordt de codec van ingaande bestand automatisch bepaald met bepaal_codec 
DEBUG        : voor relevante debug-informatie .

mdwrite ( )

mdwrite ('| SOURCE C:/Users/dolf/PycharmProjects/pythonProject/beheer | TARGET c:/data/beheer.html | ')

SOURCE : bestand-in , met speciale opmaak volgens de markdown specificaties
TARGET : het uit-betand, welke een HTML is