Su qualunque altra piattaforma il codice è un file in una cartella. Qui no, o almeno non
per tradizione: il codice sta dentro un file sorgente, che è un oggetto di tipo *FILE
in una libreria, e ogni programma è un membro di quel file.
Un file sorgente sta a un progetto come una cartella, ma è un oggetto del database. È il motivo per cui il sorgente si può interrogare in SQL, e anche per cui non ci si può mettere un nome lungo o una sottocartella.
I nomi che si incontrano
Per convenzione, un file sorgente per tipo di linguaggio:
| File | Contiene |
|---|---|
QRPGLESRC |
sorgenti RPG ILE e RPG con SQL incorporato |
QRPGSRC |
sorgenti RPG del vecchio modello, dove ci sono ancora |
QCLSRC |
sorgenti CL |
QDDSSRC |
descrizioni di file: fisici, logici, video, di stampa |
QCMDSRC |
definizioni di comandi |
QSQLSRC |
script SQL |
Il tipo di membro — RPGLE, SQLRPGLE, CLLE, PF, LF, DSPF, PRTF, CMD — è
un attributo del membro, non del file che lo contiene, e decide come l'editor lo colora e
quale compilatore ci si aspetta.
WRKMBRPDM FILE(PRODLIB/QRPGLESRC)
DSPFD FILE(PRODLIB/QRPGLESRC) TYPE(*MBRLIST)
E in SQL, che è il modo comodo per cercare qualcosa in tutti i sorgenti insieme:
SELECT SYSTEM_TABLE_SCHEMA, SYSTEM_TABLE_MEMBER, SOURCE_TYPE, LAST_SOURCE_UPDATE_TIMESTAMP
FROM QSYS2.SYSPARTITIONSTAT
WHERE SYSTEM_TABLE_NAME = 'QRPGLESRC'
Ogni membro è una riga del catalogo: SYSTEM_TABLE_MEMBER è il nome del membro,
SOURCE_TYPE il suo tipo, LAST_SOURCE_UPDATE_TIMESTAMP l'ultima modifica.
Nota
un file sorgente ha righe di lunghezza fissa, decisa quando lo si crea con
CRTSRCPF. Il valore di serie è 92: 6 caratteri di numero di sequenza, 6 di data, 80 di
codice. Chi vuole righe più lunghe lo crea con un RCDLEN maggiore: con 112, i caratteri
per il codice sono 100.
Il codice sull'IFS
Da diversi rilasci i compilatori accettano anche sorgenti come file dell'IFS, cioè file normali in cartelle normali, con nomi lunghi e senza limite di lunghezza riga.
CRTBNDRPG PGM(PRODLIB/FATTURE) SRCSTMF('/home/dev/fatture/fatture.rpgle')
Il motivo per cui questo conta non è l'estetica: è che un file su una cartella si mette sotto git. Il controllo di versione su membri di file sorgente si è sempre fatto con prodotti dedicati di change management, che funzionano e costano; con i sorgenti sull'IFS si usano gli stessi strumenti del resto del mondo, e chi arriva da fuori sa già usarli.
Consiglio
non è una scelta da fare per tutto il codice in una volta. La strada che funziona è tenere il codice storico dov'è e mettere sull'IFS quello che si scrive da ora, o il singolo applicativo che si sta rifacendo. I due modi convivono senza problemi: il compilatore produce lo stesso oggetto.
Dal sorgente all'oggetto
La compilazione non produce un file eseguibile: produce un oggetto nella libreria che si è indicata, con tutto quello che ne consegue; ha un proprietario, ha dei diritti, ha una descrizione, si salva e si ripristina come qualunque altra cosa.
CRTBNDRPG PGM(PRODLIB/FATTURE) SRCFILE(PRODLIB/QRPGLESRC) SRCMBR(FATTURE)
CRTBNDCL PGM(PRODLIB/LANCIA) SRCFILE(PRODLIB/QCLSRC) SRCMBR(LANCIA)
CRTPF FILE(PRODLIB/ORDINI) SRCFILE(PRODLIB/QDDSSRC) SRCMBR(ORDINI)
L'oggetto ricorda da dove è stato prodotto, e questa è una delle cose più utili del sistema:
DSPOBJD OBJ(PRODLIB/FATTURE) OBJTYPE(*PGM) DETAIL(*SERVICE)
Fra i dati di servizio ci sono file sorgente, membro e data e ora dell'ultimo aggiornamento del sorgente al momento della compilazione. Confrontarla con la data del membro dice se l'oggetto in produzione corrisponde al sorgente che si ha davanti.
Avvertenza
è il controllo da fare prima di toccare qualunque cosa in un ambiente che non si conosce. Un sorgente più recente dell'oggetto significa che qualcuno ha modificato il codice e non lo ha compilato, o che ha compilato altrove: ricompilare a quel punto manda in produzione modifiche che nessuno ha chiesto, e che nessuno ha provato.
SELECT OBJNAME, OBJTEXT, SOURCE_FILE, SOURCE_LIBRARY, SOURCE_MEMBER,
SOURCE_TIMESTAMP, OBJCREATED
FROM TABLE(QSYS2.OBJECT_STATISTICS('PRODLIB', '*PGM'))
ORDER BY SOURCE_TIMESTAMP DESC
L'elenco della compilazione
Ogni compilazione produce un file di spool: il compile listing. Contiene il sorgente numerato, gli errori, e (su richiesta) il codice espanso dopo le copie e dopo la precompilazione SQL.
È il posto in cui si guarda quando un errore non ha senso, perché mostra il codice
come lo ha visto il compilatore, che non è sempre quello che si è scritto: le /COPY
sono state espanse, e in un sorgente con SQL incorporato le istruzioni EXEC SQL sono
state riscritte in chiamate.
Consiglio
compilando con OPTION(*EVENTF) il compilatore scrive anche un file di
eventi, un membro del file EVFEVENT nella libreria dell'oggetto, che gli strumenti sul
PC leggono per mostrare gli errori sulla riga giusta invece di costringere a cercarli nel
listato.
Che cosa manca, rispetto ad altre piattaforme
Tre cose, e conviene saperlo subito invece di cercarle.
Non c'è un file di progetto. Non esiste un Makefile o un pom.xml di serie: l'ordine
di compilazione — prima i file, poi i moduli, poi i programmi — è conoscenza di chi
lavora lì, o sta dentro un prodotto di change management, o dentro un CL scritto a mano che
compila tutto in fila. Esistono strumenti moderni che colmano questo vuoto, e ne parla il
capitolo sugli strumenti.
Non c'è un ambiente virtuale. La separazione fra collaudo e produzione si fa con le librerie e con la lista librerie: stesso programma, librerie diverse. È il motivo per cui la lista librerie è un argomento da capire bene, e per cui un errore lì costa più che altrove.
Non c'è un pacchetto da distribuire. Si sposta un oggetto da una libreria all'altra, o si salva e si ripristina. Il rilascio in produzione è una copia di oggetti.
Commenti
Nessun commento ancora. Sii il primo a commentare!
Devi avere un account per commentare. Accedi · Registrati