02 - Database DB2 for i02a - SQL02c - Varie Database DB2 for i04d - IFS

Esploriamo l’IFS con i servizi DB2

La ricca “famiglia” di servizi del DB2 for i ha visto recentemente la nascita di una nuova categoria: i servizi IFS. Questo gruppo di servizi è disponibile da IBM i 7.3 con l’aggiornamento DB2 SF99703 Level 16 (ma è meglio considerare solo il Level 17, dal momento che il 16 ha causato alcuni problemi… vedi qui).

Questi nuovi servizi restituiscono informazioni sugli oggetti che si trovano in cartelle IFS; dei 4 servizi disponibili, il più interessante è IFS_OBJECT_STATISTICS, una funzione che restituisce una tabella con l’elenco dei file presenti in una directory specificata (o a partire dalla directory specificata), con tutte le informazioni correlate.
Questa funzione facilita notevolmente il reperimento del contenuto di una cartella e delle sue sottocartelle, che si può ottenere anche con i comandi RTVDIRINF o PRTDIRINF o con la complicata API Qp0lGetAttr() (Get Attributes). Questi metodi “standard” non permettono però di indirizzare l’output verso un file, cosa che si può fare al volo con l’SQL.
Qui vediamo una istruzione che crea un file con il contenuto di una cartella, delle sue sottocartelle ed alcune informazioni sui singoli file:

CREATE TABLE mduca1.ifsdir AS (
SELECT 
 CAST(path_name AS CHAR(100)) path, object_type, data_size, object_owner, 
 CAST(data_change_timestamp AS TIMESTAMP) last_chg
FROM TABLE (QSYS2.IFS_OBJECT_STATISTICS(
 START_PATH_NAME => '/home/mduca')) t
ORDER BY path_name
) WITH DATA

Ecco il contenuto della tabella:

La funzione IFS_OBJECT_STATISTICS ha quattro parametri:

  • START_PATH_NAME: nome della directory di partenza
  • SUBTREE_DIRECTORIES: se posto a NO, non vengono analizzate le sottocartelle. Il default è YES
  • OBJECT_TYPE_LIST: elenco di uno o più tipi di oggetto da estrarre. Si possono indicare i tipi di oggetto standard (*PGM, *FILE) oppure i valori speciali *ALLDIR, *ALLSTMF, *MBR, *NOQSYS, che filtrano solo alcune tipologie di oggetti
  • OMIT_LIST: elenco di oggetti da omettere dalla lista.

La funzione opera anche sui normali oggetti di sistema, a partire dal percorso /QSYS.LIB. Per questo tipo di analisi però le prestazioni sono molto migliori se si utilizza la funzione SQL specifica OBJECT_STATISTICS.
La funzione IFS si dimostra utile quando dobbiamo verificare in un programma l’esistenza o meno di un determinato file in una cartella IFS (o a partire da una cartella radice). Di seguito un esempio di programma RPG che riceve in input due parametri: il nome del percorso ed il nome del file, e restituisce un flag che indica se il file specificato esiste.

       //---------------------------------------------------------------
       //
       // Test IFS_OBJECT_STATISTICS table function
       //
       // Returns a boolean to inform the given file is found in the 
       //  given starting directory or in a subdirectory
       //
       //---------------------------------------------------------------
       ctl-opt decedit('0,') datedit(*dmy.)
       dftactgrp(*no) actgrp(*caller)
       option(*srcstmt : *nodebugio : *noexpdds)
       fixnbr(*zoned : *inputpacked);

       // *ENTRY
       dcl-pi FAQ40010A;
          dcl-parm pPath   char(100);
          dcl-parm pFile   char(80);
          dcl-parm pFound  ind;
       end-pi;
       // variabili
       dcl-s found         ind ;
       dcl-s fullPath      varchar(180) ;
       //--------------------------------------------------------------
       Exec SQL
       SET OPTION   COMMIT=*none,
                    CLOSQLCSR=*endmod,
                    ALWCPYDTA=*yes
       ;

       fullPath = %trim (pPath) + '/' + %trim(pFile) ;

       Exec SQL
       SET :found = (SELECT DISTINCT '1'
       FROM TABLE (qsys2.ifs_object_statistics(
        START_PATH_NAME => :fullPath )) t
       )
       ;
       if SQLCODE <> 0;
          found = *off;
       endif;

       *inLR = *on;
       return;

La ricerca in questo caso ignora la differenza tra maiuscole e minuscole.
Vediamo anche una variante del primo programma; questo riceve la directory iniziale, il nome del file e restituisce il percorso completo di dove è stato trovato il file (comprendendo le sottodirectory). Tramite la funzione UPPER anche questa ricerca è stata resa case-insensitive.

       //---------------------------------------------------------------
       //
       // Test IFS_OBJECT_STATISTICS table function
       //
       // Returns full path if file found in starting directory or in
       //  a subdirectory
       //---------------------------------------------------------------
       ctl-opt decedit('0,') datedit(*dmy.)
       dftactgrp(*no) actgrp(*caller)
       option(*srcstmt : *nodebugio : *noexpdds)
       fixnbr(*zoned : *inputpacked);

       // *ENTRY
       dcl-pi FAQ40010B;
          dcl-parm pPath        char(100);
          dcl-parm pFile        char(80);
          dcl-parm pFullPath    char(180);
       end-pi;
       // variabili

       //--------------------------------------------------------------
       Exec SQL
       SET OPTION   COMMIT=*none,
                    CLOSQLCSR=*endmod,
                    ALWCPYDTA=*yes
       ;

       pFullPath = *blank ;
       Exec SQL
       SET :pFullPath = (SELECT
       COALESCE(MIN(path_name), '**NOT FOUND**')
       FROM TABLE (qsys2.ifs_object_statistics(
        START_PATH_NAME => TRIM(:pPath) )) t
       WHERE LOCATE(TRIM(UPPER(:pFile)), UPPER(path_name)) <> 0
       )
       ;

       *inLR = *on;
       return;

Questo programma restituisce solo la prima directory dove viene reperito il file, volendo è possibile dichiarare un cursore e restituire in una schiera tutti i percorsi in cui viene trovato il file, incluse le sottodirectory.

Attenzione: eseguendo le funzioni dei servizi IFS in un job con il CCSID “generico” 65535 si può incorrere in un errore SQL0332 dal momento che alcune colonne delle tabella restituite sono codificate con CCSID 1200, per il quale non è definita la tabella di conversione con il 65535. Per ovviare al problema è sufficiente impostare il job con un CCSID specifico (es. 280 per i sistemi in italiano).

DOCUMENTAZIONE
Servizi IFS : https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/rzajq/rzajqservicesifs.htm
IFS_OBJECT_STATISTICS: https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/rzajq/rzajqudfifsobjstat.htm
OBJECT_STATISTICS: https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/rzajq/rzajqudfobjectstat.htm

About author

Senior Analyst/Developer e divulgatore in ambito IBM i. Già collaboratore dell'edizione italiana della rivista "System i News" ed autore di diverse pubblicazioni su tools e tecniche di sviluppo in ambiente IBM i.

Rispondi

%d blogger hanno fatto clic su Mi Piace per questo: