Azioni (Actions)
Personalizzazioni nelle operazioni di database.
Introduzione
Continuamente vengono effettuate manipolazioni di dati, ed è comune avere regole come, ad esempio:
- Quando si rimuove un cliente, deve essere rimosso anche il suo storico.
- Quando si annulla un prodotto, è necessario rimuoverlo dagli ordini e adeguare il valore totale.
- Quando si finalizza un acquisto, è necessario inviare i dati a un altro sistema che si occupa della distribuzione.
Le azioni (actions) servono proprio a questo: a iniettare codice da eseguire in situazioni specifiche quando avviene una manipolazione dei dati.
Quando si inserisce o si modifica qualche informazione, vengono eseguite le azioni di salvataggio (save) e salvato (saved):
save: Prima di eseguire il comando nel database.saved: Dopo aver eseguito il comando nel database.
Invece, quando si rimuove, cancella o elimina qualche informazione, vengono eseguite le azioni di rimozione (remove) e rimosso (removed).
remove: Prima di eseguire il comando nel database.removed: Dopo aver eseguito il comando nel database.
Quindi, quando modifichiamo qualcosa in un modulo, con operazioni di creazione, modifica o rimozione di informazioni, vengono eseguite operazioni distinte nel database e vengono eseguite le rispettive azioni (actions).
Hai mai sentito parlare di trigger del database? Il trigger del database viene eseguito ogni volta che ci sono modifiche ai dati, quindi le azioni (actions) sono simili ai trigger, ma a livello di codice.
Ricorda che ogni tipo di operazione esegue un comando distinto nel database, ovvero:
- Creare:
insert into ... - Modificare:
update ... - Rimuovere:
delete from ...
Quando eseguiamo uno di questi comandi del database tramite _db.execute(...), nessuna azione verrà eseguita,
perché il comando viene eseguito direttamente nel database senza la possibilità di interagire con le azioni.
Nel codice delle azioni è possibile utilizzare qualsiasi risorsa della framework low-code poliglotta.
Le azioni vengono eseguite quando avviene qualche manipolazione dei dati nei moduli di backoffice auto-generati da Netuno, oppure quando eseguiamo operazioni nel database nel codice utilizzando:
_db.insert(...),_db.form(...).insert(),_db.insertIfNotExits(...),_db.insertMany(...), tra gli altri._db.update(...),_db.form(...).update(),_db.updateMany(...), tra gli altri._db.delete(...),_db.form(...).delete(),_db.deleteMany(...), tra gli altri.
In altre parole, quando utilizziamo nel codice qualche meccanismo della framework low-code poliglotta per realizzare le operazioni di manipolazione dei dati, verrà eseguita la rispettiva azione, se esiste.
Tuttavia, se viene eseguito un comando direttamente nel database, non sarà possibile eseguire l'azione.
Si raccomanda di evitare di eseguire comandi direttamente nel database per non aggirare i meccanismi di manipolazione dei dati offerti da Netuno.
Nel codice delle azioni è possibile realizzare qualsiasi operazione associata alla manipolazione dei dati.
Elemento Dati (Data Item)
L'elemento dati (_dataItem) è una risorsa della framework low-code poliglotta che contiene l'intera relazione dei dati
che viene creata, modificata o rimossa.
Tramite la risorsa _dataItem possiamo accedere a tutte le informazioni e verificare i dettagli del processo dell'operazione
in corso.
Consulta la documentazione della risorsa DataItem per maggiori dettagli su ciò che la risorsa
_dataItemsupporta.
Attenzione: La risorsa _dataItem è disponibile solo nel codice delle azioni (actions).
Salvare, Memorizzare, Modificare o Creare Nuovo (Save)
Per creare un'azione (action) che verrà eseguita quando viene creato un nuovo record, o quando viene modificato qualcosa, lo script
di questa azione sarà chiamato save, che significa che qualcosa viene salvato nel database, per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
mia_app/server/actions/mio_modulo/save.js
mia_app/server/actions/mio_modulo/save.ts
mia_app/server/actions/mio_modulo/save.py
mia_app/server/actions/mio_modulo/save.rb
mia_app/server/actions/mio_modulo/save.kts
mia_app/server/actions/mio_modulo/save.groovy
Questa azione viene eseguita prima di eseguire il comando nel database.
Quando si vuole eseguire codice dopo che i dati sono stati salvati nel database, allora utilizziamo l'azione
saved, per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
mia_app/server/actions/mio_modulo/saved.js
mia_app/server/actions/mio_modulo/saved.ts
mia_app/server/actions/mio_modulo/saved.py
mia_app/server/actions/mio_modulo/saved.rb
mia_app/server/actions/mio_modulo/saved.kts
mia_app/server/actions/mio_modulo/saved.groovy
Questa azione viene eseguita dopo aver eseguito il comando nel database.
In altre parole, all'interno dell'applicazione, nella cartella server/actions, creiamo una sottocartella con il nome del modulo (tabella), e
all'interno inseriamo uno script chiamato save o saved, che contiene il codice rispettivo da eseguire prima
o dopo il comando nel database.
Per distinguere se si tratta di una creazione di dati, possiamo verificare con un if il risultato del metodo
_dataItem.isInsert(), per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isInsert()) {
// Si stanno creando nuovi dati...
}
if (_dataItem.isInsert()) {
// Si stanno creando nuovi dati...
}
if _dataItem.isInsert():
# Si stanno creando nuovi dati...
if _dataItem.isInsert()
# Si stanno creando nuovi dati...
end
if (_dataItem.isInsert()) {
// Si stanno creando nuovi dati...
}
if (_dataItem.isInsert()) {
// Si stanno creando nuovi dati...
}
Per distinguere se si tratta di una modifica dei dati, possiamo verificare con un if il risultato del metodo
_dataItem.isUpdate(), per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isUpdate()) {
// I dati stanno venendo modificati...
}
if (_dataItem.isUpdate()) {
// I dati stanno venendo modificati...
}
if _dataItem.isUpdate():
# I dati stanno venendo modificati...
if _dataItem.isUpdate()
# I dati stanno venendo modificati...
end
if (_dataItem.isUpdate()) {
// I dati stanno venendo modificati...
}
if (_dataItem.isUpdate()) {
// I dati stanno venendo modificati...
}
Ottenere l'ID
Per ottenere l'ID (identificatore) dell'elemento che viene modificato:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
Verificare cosa viene Modificato
Per verificare cosa viene modificato, possiamo utilizzare getOldRecord() per ottenere i dati precedenti
nel database e confrontarli con i nuovi dati getRecord(), per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// Attenzione: L'email sta venendo modificata!
}
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// Attenzione: L'email sta venendo modificata!
}
if _dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email"):
# Attenzione: L'email sta venendo modificata!
if _dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")
# Attenzione: L'email sta venendo modificata!
end
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// Attenzione: L'email sta venendo modificata!
}
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// Attenzione: L'email sta venendo modificata!
}
Generare un Errore
È possibile generare un errore per impedire che l'operazione prosegua; la generazione dell'errore normalmente avviene prima di
eseguire il comando nel database, quindi nell'azione save, per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("Non è consentito modificare l'email.")
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("Non è consentito modificare l'email.")
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("Non è consentito modificare l'email.")
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("Non è consentito modificare l'email.")
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("Non è consentito modificare l'email.")
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("Non è consentito modificare l'email.")
Verificare se si è Verificato un Errore
È possibile verificare se si è verificato qualche errore nell'esecuzione del comando nel database; diversi errori possono verificarsi, per esempio:
- Non è consentito avere email duplicate.
- Un campo obbligatorio non è stato compilato correttamente.
- Tra molti altri.
La verifica degli errori viene normalmente effettuata dopo l'esecuzione del comando nel database, quindi nell'azione
saved, per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isError()) {
// Si è verificato un errore e non è stato possibile salvare i dati...
}
if (_dataItem.isError()) {
// Si è verificato un errore e non è stato possibile salvare i dati...
}
if _dataItem.isError():
# Si è verificato un errore e non è stato possibile salvare i dati...
if _dataItem.isError()
# Si è verificato un errore e non è stato possibile salvare i dati...
end
if (_dataItem.isError()) {
// Si è verificato un errore e non è stato possibile salvare i dati...
}
if (_dataItem.isError()) {
// Si è verificato un errore e non è stato possibile salvare i dati...
}
Setup
È possibile avere una action specifica che viene eseguita solo quando vengono realizzate modifiche ai dati durante la
configurazione (setup) del database.
Per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
mia_app/server/actions/mio_modulo/setup_save.jsmia_app/server/actions/mio_modulo/setup_saved.js
mia_app/server/actions/mio_modulo/setup_save.tsmia_app/server/actions/mio_modulo/setup_saved.ts
mia_app/server/actions/mio_modulo/setup_save.pymia_app/server/actions/mio_modulo/setup_saved.py
mia_app/server/actions/mio_modulo/setup_save.rbmia_app/server/actions/mio_modulo/setup_saved.rb
mia_app/server/actions/mio_modulo/setup_save.ktsmia_app/server/actions/mio_modulo/setup_saved.kts
mia_app/server/actions/mio_modulo/setup_save.groovymia_app/server/actions/mio_modulo/setup_saved.groovy
Rimuovere, Cancellare o Eliminare (Remove)
Per creare un'azione (action) che verrà eseguita quando viene rimosso qualche record, lo script di questa azione sarà chiamato
remove, che significa che qualcosa viene eliminato nel database, per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
mia_app/server/actions/mio_modulo/setup_remove.js
mia_app/server/actions/mio_modulo/setup_remove.ts
mia_app/server/actions/mio_modulo/setup_remove.py
mia_app/server/actions/mio_modulo/setup_remove.rb
mia_app/server/actions/mio_modulo/setup_remove.kts
mia_app/server/actions/mio_modulo/setup_remove.groovy
Questa azione viene eseguita prima di eseguire il comando nel database.
Quando si vuole eseguire codice dopo che i dati sono stati salvati nel database, allora utilizziamo l'azione
removed, per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
mia_app/server/actions/mio_modulo/setup_removed.js
mia_app/server/actions/mio_modulo/setup_removed.ts
mia_app/server/actions/mio_modulo/setup_removed.py
mia_app/server/actions/mio_modulo/setup_removed.rb
mia_app/server/actions/mio_modulo/setup_removed.kts
mia_app/server/actions/mio_modulo/setup_removed.groovy
Questa azione viene eseguita dopo aver eseguito il comando nel database.
In altre parole, all'interno dell'applicazione, nella cartella server/actions, creiamo una sottocartella con il nome del modulo (tabella), e
all'interno inseriamo uno script chiamato remove o removed, che contiene il codice rispettivo da eseguire prima
o dopo il comando nel database.
Conflitto con le Relazioni
A seconda del modello di dati, può accadere che, rimuovendo un record utilizzato nella relazione con un'altra tabella, anch'essa un altro modulo, non sia possibile rimuoverlo per evitare che la relazione si rompa.
Allora nell'azione removed, che viene eseguita dopo il comando di rimozione nel database, possiamo verificare se si verifica questo
errore nel modo seguente:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"Non è stato possibile rimuovere perché c'è una relazione con la tabella "
+ _dataItem.getRelationTable() +" utilizzando l'ID " + _dataItem.getRelationItem().getInt("id")
)
}
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"Non è stato possibile rimuovere perché c'è una relazione con la tabella "
+ _dataItem.getRelationTable() +" utilizzando l'ID " + _dataItem.getRelationItem().getInt("id")
)
}
if _dataItem.isStatusAsError() and _dataItem.isStatusAsRelations():
_log.error(
"Non è stato possibile rimuovere perché c'è una relazione con la tabella "
+ _dataItem.getRelationTable() +" utilizzando l'ID " + _dataItem.getRelationItem().getInt("id")
)
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations())
_log.error(
"Non è stato possibile rimuovere perché c'è una relazione con la tabella "
+ _dataItem.getRelationTable() +" utilizzando l'ID " + _dataItem.getRelationItem().getInt("id")
)
end
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"Non è stato possibile rimuovere perché c'è una relazione con la tabella "
+ _dataItem.getRelationTable() +" utilizzando l'ID " + _dataItem.getRelationItem().getInt("id")
)
}
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"Non è stato possibile rimuovere perché c'è una relazione con la tabella "
+ _dataItem.getRelationTable() +" utilizzando l'ID " + _dataItem.getRelationItem().getInt("id")
)
}
In alternativa, nell'azione remove, che viene eseguita prima di realizzare il comando del database che elimina il record,
possiamo implementare la "pulizia" di altri record che possono avere una relazione, per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_db.form("altro_modulo")
.where(
_db.where("mio_modulo_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("altro_modulo")
.where(
_db.where("mio_modulo_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("altro_modulo")
.where(
_db.where("mio_modulo_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("altro_modulo")
.where(
_db.where("mio_modulo_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("altro_modulo")
.where(
_db.where("mio_modulo_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("altro_modulo")
.where(
_db.where("mio_modulo_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
Setup
È possibile avere una action specifica che viene eseguita solo quando viene realizzata la rimozione di dati durante la
configurazione (setup) del database.
Per esempio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
mia_app/server/actions/mio_modulo/setup_remove.jsmia_app/server/actions/mio_modulo/setup_removed.js
mia_app/server/actions/mio_modulo/setup_remove.tsmia_app/server/actions/mio_modulo/setup_removed.ts
mia_app/server/actions/mio_modulo/setup_remove.pymia_app/server/actions/mio_modulo/setup_removed.py
mia_app/server/actions/mio_modulo/setup_remove.rbmia_app/server/actions/mio_modulo/setup_removed.rb
mia_app/server/actions/mio_modulo/setup_remove.ktsmia_app/server/actions/mio_modulo/setup_removed.kts
mia_app/server/actions/mio_modulo/setup_remove.groovymia_app/server/actions/mio_modulo/setup_removed.groovy
Conclusione
Con le azioni (actions) possiamo centralizzare operazioni specifiche che sono correlate alla manipolazione di
determinati dati.
Consente di aggiungere codice che fornisce meccanismi utili per garantire l'integrità, facilitare le attività, realizzare integrazioni, eseguire operazioni parallele, avere verifiche aggiuntive e molto altro.
Codificare le azioni è semplice ed estremamente utile; è possibile estenderle con l'utilizzo di qualsiasi altra risorsa della framework low-code poliglotta.
Nel codice delle azioni è possibile utilizzare qualsiasi risorsa della framework low-code poliglotta.
Considera l'utilizzo delle azioni e rapidamente potrai verificare come la facilità ottenuta possa potenziare molte strategie utili.