Chi ha chiamato il mio programma ?

In alcune situazioni, in un programma RPG può essere necessario eseguire della logica differenziata che dipende dalla funzione che lo ha richiamato. Normalmente si tende a gestire questo comportamento passando al programma un opportuno parametro, ma nel caso di programmi che agiscono molto “in profondità”, la catena dei richiami può essere abbastanza lunga ed avere più livelli; in questo caso è necessario assicurarsi che un parametro impostato dal primo programma si propaghi correttamente fino al programma finale.
Un’altra soluzione è quella di sapere se il programma corrente è stato richiamato da un altro programma, direttamente oppure nella catena di richiami; in questo modo a seconda del chiamante si potranno eseguire le logiche opportune.
E per questo scopo, chi ci viene in aiuto se non l’accoppiata DB2 + SQL ? Nella sempre più ricca collezione di servizi DB2, nella sezione “Application Services” troviamo la funzione di tabella STACK_INFO, che restituisce l’elenco delle chiamate del job.

Grazie a questa funzione, con una semplice query possiamo sapere facilmente se un determinato programma fa parte della catena dei richiami:

SELECT COUNT(*)
FROM TABLE (QSYS2.STACK_INFO('*')) s
WHERE program_library_name NOT LIKE 'QSYS%'
  AND program_name = 'MYPGM'
; 

Se il conteggio restituisce un valore maggiore o uguale a 1, sappiamo che il programma corrente è stato richiamato da MYPGM. Con la funzione scalare COUNT otterremo sempre un valore, anche nel caso in cui il programma non sia presente nell’elenco. Questa query esclude dalla selezione le librerie di sistema che iniziano con QSYS.
La funzione ha due parametri:

  • job_name: identificativo di un job. ‘*’ indica il job corrente
  • thread_id: identificativo di un processo (opzionale)

I parametri job_name e thread_id ci permettono di ottenere l’elenco dei richiami anche di job e processi diversi da quello corrente, il che agevola eventuali verifiche su altri job attivi.
Le informazioni restituite da STACK_INFO sono numerose, tra le più utili abbiamo il nome della procedura chiamante ed il numero della specifica del richiamo.

Nel caso la verifica del chiamante dovesse essere eseguita in molti programmi, niente di meglio che incapsulare questa logica in una procedura di un programma di servizio.
Di seguito il source di una procedura di service program, che riceve un parametro (il programma da ricercare) e restituisce un flag booleano che indica se il programma specificato nel parametro fa parte della catena dei richiami.
Il sorgente completo è disponibile su GitHub a questo link:
https://github.com/MD2706GIT/FAQ400

      //********************************************************************
      // isCalledFrom - Check if a given program is in call stack
      //
      // INPUT Parms:
      // - pPgm         - Program name            CHAR(10)
      //
      // OUTPUT Parms:
      // - Flag "1"=found "0"=not found           BOOLEAN
      //
      //********************************************************************
       dcl-proc  isCalledFrom   export;
          dcl-pi isCalledFrom   ind;
             dcl-parm pPgm   char(10)  const ;    // program name
          end-pi;

          dcl-s found        ind;

          monitor;
            found = *off;
            Exec SQL
            SET :found:indNull = (SELECT DISTINCT '1'
            FROM TABLE (QSYS2.STACK_INFO('*')) s
            WHERE program_library_name NOT LIKE 'QSYS%'
              AND program_name = :pPgm
            )
            ;
            if indNull = -1;
               found = *off;
            endif;

          on-error;
            found = *off;
          endmon;
          return found;

       end-proc;

Ecco un semplice esempio di richiamo della procedura:

       dcl-s found         ind ;                      
       . . .
       found    = isCalledFrom('FAQ40012B') ;   

DOCUMENTAZIONE:
STACK_INFO :
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/rzajq/rzajqudfstackinfo.htm

Related Posts
DB2 for i SQL – Stringhe – POSSTR-LOCATE-LOCATE_IN_STRING (IT)

Introduzione Spesso, nelle nostre applicazioni, abbiamo la necessità di lavorare con le stringhe di testo e l'SQL del DB2 può Read more

DB2 for i & SQL – FAQ & Howto (Part. 1) (IT)

Database DB2 e SQL ... forse lo strumento più potente e completo che abbiamo sulla piattaforma IBM i: ecco una Read more

Annuncio IBM i 7.4

Arriva direttamente con l'uovo di Pasqua questo annuncio IBM per le novità della versione IBM i 7.4, versione iNext secondo Read more

Generated Always Columns – Approfondimenti (IT)

Introduzione "Generated Always Column": sono colonne, campi, di una tabella il cui contenuto è controllato direttamente dal sistema ... e Read more

Recent Posts

VsCode Extension: Bob Cozzi’s RPG IV to RPG Free Conversion

L’estensione “RPG IV to Free Format Conversion” sviluppata da Bob Cozzi (Cozzi Research) è pensata per semplificare la conversione di…

1 mese ago

IBM i & SQL Tips #010 – Localizzare programmi nella Call Stack con STACK_INFO

Ciao a tutti, oggi voglio segnalarvi un altro interessante contributo di Massimo Duca, parte della sua ormai nota serie IBM…

1 mese ago

Display file DDS Edit per VsCode, nuova preview.

Incuriosito da alcuni messaggi di Cristian Larsen su Linkedin (New Release - Display File DDS Edit v.0.10.1) ho voluto scaricare…

2 mesi ago

Project Bob: il nuovo strumento AI di IBM per sviluppo COBOL su IBM Z e RPG su IBM i

Ciao a tutti,oggi voglio segnalarvi un annuncio che potrebbe segnare una svolta per lo sviluppo applicativo su ambienti IBM: Project…

2 mesi ago

IBM i & SQL Tips #6: chiamare API REST e analizzare le risposte JSON con SQL

Voglio segnalarvi un nuovo articolo molto interessante di Massimo Duca nella serie IBM i & SQL Tips. In questo sesto…

3 mesi ago

Come funziona il passaggio di parametri a un programma IBM i (RPG / Cobol)

Ciao a tutti, voglio segnalarvi un post molto utile di Marco Riva sul suo sito Markonetools, in cui spiega in…

3 mesi ago