Hi everyone,
In every day life we encounter all kinds of tags, like in the store where we find price tags. These tags are essential for you to know what the price of a particular product is, but it also tells you whether or not the product is actually for sale and not there for decoration. Nowadays more and more price tags are shown on a smart display and can show the percentage of discount or other information. Tags in essence can hold important information.
But hey, we’re developing software here. Tags can also be significant for your software. The Software Factory allows you to define your own tags that you can link to many model entities. Here’s what our Documentation page says about tags:
A tag is a freely definable property that can be linked to rows of a table and can be provided with a value. They provide information that is not available in the Software Factory's meta model.
You can use tags administratively or in a meta control procedure (dynamic model) to manipulate your model. For example, to indicate whether a table is deprecated or should not contain mutation columns.
Deepdive
So, now you know what tags are but of course that raises the question, what can you achieve with it? There are infinite possibilities, but here are a couple use cases of using tags:
- Tagging tables that supply base data
- Tagging tables that need to be configured and will show a custom component, such as the Multi-file upload component
- Tagging tables that need a particular prefilter that for instance ensure the user cannot see data of another tenant (in case of multi-tenant environments)
- Tagging columns which need particular Default logic, such as replacing special characters or replacing spaces with underscores
- Tagging objects that will be aggregated in logic as literals, e.g. where t1.status in ('Option 1’, 'Option 2’). You can use this blog as inspiration.
- Tagging branches which can influence certain code should be or not be added to particular code files
- Tagging objects that should be excluded from parts of code; like excluding primary key columns from an aggregation or excluding non-editable views from getting a Default logic assignment
- Tagging columns that need a particular Conditional layout when generating definitions
- Tagging a column to generate a Unique index constraint using logic with corresponding message
- and many more…
Tags can be found in the Software Factory under Models > Model content > Tags (last detail in the list). You can also create Tags via an Object tag detail, for example menu group Data > Data model > tab Tables > tab Table tags > Look-up of field Tag
As you create tags, you can also mandate a value is given when linking this tag to an object. An example where this would be beneficial is when logic takes the tag value to trigger certain parts of its code or skip other parts.
Show and tell
As listed above, you can apply this on for many different purposes. The most telling and known usage is for adding Trace columns to a tagged table. But you can also turn it around and tag only the excluded tables; the tables that do not need Trace columns.
To start, create a tag for it over at menu group Models > Model content > tab Tags.
Now with this tag, you can add the tag to any number of your tables via the Table tags detail tab. In my case, I already have 33 tables tagged.
Code part
How do you use it? You can use it in a couple places but the one I will highlight is in menu group Enrichments > Dynamic model. To add trace columns dynamically, you will need to add a Meta control procedure. This control procedure is executed every time you perform a Generate definition of your branches. It will add Trace columns to your tables if they don't have them yet, and they are not excluded by our Tag.
To do so, you can use this code as an inspiration. This code will add an insert_user column to my tables:
-- Add the insert_user column
insert into col
(
model_id,
branch_id,
tab_id,
col_id,
order_no,
dom_id,
visible_for_filter,
filter_order_no,
visible_for_search,
search_order_no,
form_order_no,
grid_order_no,
card_list_order_no,
type_of_col,
grid_type_of_col,
form_field_in_next_grp,
form_next_grp_label,
form_next_grp_icon_id,
field_in_next_col,
insert_user,
insert_date_time,
update_user,
update_date_time,
generated_by_control_proc_id
)
select
t.model_id,
t.branch_id,
t.tab_id,
'insert_user',
10000,
'name',
1, -- Extended
10000,
1, -- Extended
10000,
10000,
10000,
10000,
1, -- Read-only
3, -- Hidden
1,
'mutation',
dbo.get_icon_id_for_icon(@model_id, @branch_id, 'icons8-hand-with-pen.svg', @control_proc_id),
1,
dbo.tsf_user(),
sysdatetime(),
dbo.tsf_user(),
sysdatetime(),
null -- @control_proc_id -- Prevent trace columns from becoming read-only
from tab t
where t.model_id = @model_id
and t.branch_id = @branch_id
and t.type_of_table = 0 -- Tables
and not exists (select 1
from tab_tag tt
where tt.model_id = t.model_id
and tt.branch_id = t.branch_id
and tt.tab_id = t.tab_id
and tt.tag_id = 'NO_TRACE_COLS')
and not exists (select 1
from col c
where c.model_id = t.model_id
and c.branch_id = t.branch_id
and c.tab_id = t.tab_id
and c.col_id = 'insert_user')
and (t.allow_add = 1 or t.allow_delete = 1 or t.allow_update = 1) -- Mutation allowed
Zooming in, this part of the code will ensure to exclude tables that otherwise would get Trace columns:
and not exists (select 1
from tab_tag tt
where tt.model_id = t.model_id
and tt.branch_id = t.branch_id
and tt.tab_id = t.tab_id
and tt.tag_id = 'NO_TRACE_COLS')
Conclusion
You can use tags for various situations and help you dynamically sculpt your model exactly how you desire. Whether it is for adding or not adding Trace columns to tables, adding prefilters, or ensuring a group of columns and parameters are always aligned in a particular way, tags in combination with Meta control procedures can help you achieve that. Do you have any other use cases? Share them below!