Actions
Customizations in database operations.
Introduction
Data manipulation is performed all the time, and it is common to have rules such as, for example:
- When removing a customer, their history must be removed.
- When canceling a product, it must be removed from orders and the total value adjusted.
- When completing a purchase, the data must be sent to another system that performs distribution.
Actions (actions) serve exactly this purpose: to inject code to be executed in specific situations when data manipulation occurs.
When inserting or updating any information, the save (save) and saved (saved) actions are executed:
save: Before executing the database command.saved: After executing the database command.
When removing, deleting, or erasing any information, the remove (remove) and removed (removed) actions are executed.
remove: Before executing the database command.removed: After executing the database command.
Thus, when we change something in a form, with operations to create, update, or remove information, distinct database operations are executed, and the respective actions (actions) are executed.
Have you heard of database triggers? A database trigger is executed whenever there are data modifications, so actions (actions) are similar to triggers, but at the code level.
Remember that each type of operation executes a distinct database command, namely:
- Create:
insert into ... - Update:
update ... - Remove:
delete from ...
When we execute one of these database commands through _db.execute(...), no action will be executed,
because the command is executed directly in the database without the possibility of interacting with actions.
In the actions code you can use any resource of the polyglot low-code framework.
Actions are executed when data manipulation happens in auto-generated backoffice forms by Netuno, or when we execute database operations in code using:
_db.insert(...),_db.form(...).insert(),_db.insertIfNotExits(...),_db.insertMany(...), among others._db.update(...),_db.form(...).update(),_db.updateMany(...), among others._db.delete(...),_db.form(...).delete(),_db.deleteMany(...), among others.
That is, when we use some mechanism of the polyglot low-code framework in code to perform data manipulation operations, the respective action will be executed if it exists.
However, if a command is executed directly in the database, then it will not be possible to execute the action.
It is recommended to avoid executing commands directly in the database so as not to bypass the data manipulation mechanisms that Netuno offers.
In the actions code, you can perform any operation associated with data manipulation.
Data Item
The data item (_dataItem) is a resource of the polyglot low-code framework that contains the entire data
relationship that is being created, updated, or removed.
Through the _dataItem resource, we can access all information and check details of the operation process
that is happening.
See the DataItem resource documentation to learn more details about what the
_dataItemresource supports.
Attention: The _dataItem resource is only available in the actions (actions) code.
Save, Store, Update, or Create New (Save)
To create an action that will be executed when a new record is created, or when something is updated, the script
of this action will be called save, which means that something is being saved to the database, for example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
my_app/server/actions/my_form/save.js
my_app/server/actions/my_form/save.ts
my_app/server/actions/my_form/save.py
my_app/server/actions/my_form/save.rb
my_app/server/actions/my_form/save.kts
my_app/server/actions/my_form/save.groovy
This action is executed before executing the database command.
When code is to be executed after the data is saved to the database, then we use the saved action, for example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
my_app/server/actions/my_form/saved.js
my_app/server/actions/my_form/saved.ts
my_app/server/actions/my_form/saved.py
my_app/server/actions/my_form/saved.rb
my_app/server/actions/my_form/saved.kts
my_app/server/actions/my_form/saved.groovy
This action is executed after the database command has been executed.
That is, inside the application in the server/actions folder we create a subfolder with the name of the form
(table), and inside it we place a script called save or saved, which contains the respective code to be
executed before or after the database command.
To distinguish whether it is a data creation, we can check with an if the result of the _dataItem.isInsert()
method, for example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isInsert()) {
// New data is being created...
}
if (_dataItem.isInsert()) {
// New data is being created...
}
if _dataItem.isInsert():
# New data is being created...
if _dataItem.isInsert()
# New data is being created...
end
if (_dataItem.isInsert()) {
// New data is being created...
}
if (_dataItem.isInsert()) {
// New data is being created...
}
To distinguish whether it is a data update, we can check with an if the result of the _dataItem.isUpdate()
method, for example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isUpdate()) {
// Data is being updated...
}
if (_dataItem.isUpdate()) {
// Data is being updated...
}
if _dataItem.isUpdate():
# Data is being updated...
if _dataItem.isUpdate()
# Data is being updated...
end
if (_dataItem.isUpdate()) {
// Data is being updated...
}
if (_dataItem.isUpdate()) {
// Data is being updated...
}
Get the ID
To get the ID (identifier) of the item that is being updated:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
_dataItem.getId()
Check What Is Modified
To check what is being modified, we can use getOldRecord() to get the old data in the database and compare it
with the new data getRecord(), for example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// Warning: The email is being changed!
}
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// Warning: The email is being changed!
}
if _dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email"):
# Warning: The email is being changed!
if _dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")
# Warning: The email is being changed!
end
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// Warning: The email is being changed!
}
if (_dataItem.getOldRecord().getString("email") != _dataItem.getRecord().getString("email")) {
// Warning: The email is being changed!
}
Generate Error
It is possible to generate an error to prevent the operation from proceeding. Error generation is normally done
before executing the database command, therefore in the save action, for example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("It is not allowed to change the email.")
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("It is not allowed to change the email.")
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("It is not allowed to change the email.")
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("It is not allowed to change the email.")
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("It is not allowed to change the email.")
_dataItem.setStatusWithError()
.setErrorTitle("Email")
.setErrorMessage("It is not allowed to change the email.")
Check If There Was an Error
It is possible to check if there was any error in the execution of the database command; several errors can occur, for example:
- It is not allowed to have duplicate emails.
- A required field was not filled in correctly.
- Among many others.
Error checking is normally performed after executing the database command, therefore in the saved action, for
example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isError()) {
// An error occurred and it was not possible to save the data...
}
if (_dataItem.isError()) {
// An error occurred and it was not possible to save the data...
}
if _dataItem.isError():
# An error occurred and it was not possible to save the data...
if _dataItem.isError()
# An error occurred and it was not possible to save the data...
end
if (_dataItem.isError()) {
// An error occurred and it was not possible to save the data...
}
if (_dataItem.isError()) {
// An error occurred and it was not possible to save the data...
}
Setup
It is possible to have a specific action that is executed only when data changes are made during database
configuration (setup).
For example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
my_app/server/actions/my_form/setup_save.jsmy_app/server/actions/my_form/setup_saved.js
my_app/server/actions/my_form/setup_save.tsmy_app/server/actions/my_form/setup_saved.ts
my_app/server/actions/my_form/setup_save.pymy_app/server/actions/my_form/setup_saved.py
my_app/server/actions/my_form/setup_save.rbmy_app/server/actions/my_form/setup_saved.rb
my_app/server/actions/my_form/setup_save.ktsmy_app/server/actions/my_form/setup_saved.kts
my_app/server/actions/my_form/setup_save.groovymy_app/server/actions/my_form/setup_saved.groovy
Remove, Delete, or Erase (Remove)
To create an action that will be executed when a record is removed, the script of this action will be called
remove, which means that something is being deleted from the database, for example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
my_app/server/actions/my_form/setup_remove.js
my_app/server/actions/my_form/setup_remove.ts
my_app/server/actions/my_form/setup_remove.py
my_app/server/actions/my_form/setup_remove.rb
my_app/server/actions/my_form/setup_remove.kts
my_app/server/actions/my_form/setup_remove.groovy
This action is executed before executing the database command.
When code is to be executed after the data is saved to the database, then we use the removed action, for example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
my_app/server/actions/my_form/setup_removed.js
my_app/server/actions/my_form/setup_removed.ts
my_app/server/actions/my_form/setup_removed.py
my_app/server/actions/my_form/setup_removed.rb
my_app/server/actions/my_form/setup_removed.kts
my_app/server/actions/my_form/setup_removed.groovy
This action is executed after the database command has been executed.
That is, inside the application in the server/actions folder we create a subfolder with the name of the form
(table), and inside it we place a script called remove or removed, which contains the respective code to be
executed before or after the database command.
Conflict with Relations
Depending on the data model, it may happen that when removing a record that is being used in a relation with another table, which is also another form, it cannot be removed to avoid breaking the relation.
So in the removed action that executes after the removal database command, we can check whether this error
occurs as follows:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"Could not remove because there is a relation with the table "
+ _dataItem.getRelationTable() + " using the ID " + _dataItem.getRelationItem().getInt("id")
)
}
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"Could not remove because there is a relation with the table "
+ _dataItem.getRelationTable() + " using the ID " + _dataItem.getRelationItem().getInt("id")
)
}
if _dataItem.isStatusAsError() and _dataItem.isStatusAsRelations():
_log.error(
"Could not remove because there is a relation with the table "
+ _dataItem.getRelationTable() + " using the ID " + _dataItem.getRelationItem().getInt("id")
)
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations())
_log.error(
"Could not remove because there is a relation with the table "
+ _dataItem.getRelationTable() + " using the ID " + _dataItem.getRelationItem().getInt("id")
)
end
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"Could not remove because there is a relation with the table "
+ _dataItem.getRelationTable() + " using the ID " + _dataItem.getRelationItem().getInt("id")
)
}
if (_dataItem.isStatusAsError() && _dataItem.isStatusAsRelations()) {
_log.error(
"Could not remove because there is a relation with the table "
+ _dataItem.getRelationTable() + " using the ID " + _dataItem.getRelationItem().getInt("id")
)
}
Alternatively, in the remove action, which executes before executing the database command that deletes the
record, we can implement the "cleanup" of other records that may have a relation, for example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_db.form("other_form")
.where(
_db.where("my_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("other_form")
.where(
_db.where("my_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("other_form")
.where(
_db.where("my_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("other_form")
.where(
_db.where("my_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("other_form")
.where(
_db.where("my_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
_db.form("other_form")
.where(
_db.where("my_form_id")
.equals(_dataItem.getRecord().getInt("id"))
)
.delete()
Setup
It is possible to have a specific action that is executed only when data removal is performed during database
configuration (setup).
For example:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
my_app/server/actions/my_form/setup_remove.jsmy_app/server/actions/my_form/setup_removed.js
my_app/server/actions/my_form/setup_remove.tsmy_app/server/actions/my_form/setup_removed.ts
my_app/server/actions/my_form/setup_remove.pymy_app/server/actions/my_form/setup_removed.py
my_app/server/actions/my_form/setup_remove.rbmy_app/server/actions/my_form/setup_removed.rb
my_app/server/actions/my_form/setup_remove.ktsmy_app/server/actions/my_form/setup_removed.kts
my_app/server/actions/my_form/setup_remove.groovymy_app/server/actions/my_form/setup_removed.groovy
Conclusion
With actions (actions), we can centralize specific operations that are related to the manipulation of certain
data.
It allows equipping with code that provides useful mechanisms to ensure integrity, facilitate tasks, perform integrations, carry out parallel operations, have additional checks, and much more.
Coding actions is simple and extremely useful; it is possible to extend with the use of any other resource of the polyglot low-code framework.
In the actions code you can use any resource of the polyglot low-code framework.
Consider using actions, and you can quickly verify how the ease obtained can enhance many useful strategies.