So now we come to the speculative fiction part of the events series. CanCreate events are not something I’ve used so we’re making this up as we go. I’ve been playing around with them and doing some thinking on where and how they might be applicable. canCreate events are a bit different than the others. They prevent you from creating an object or assigning a stereotype instead of automating some task. As I read through the examples, it seemed that these might be a bit more applicable in model types other than data models.
I’m generally not one to modify a tool to restrict someone from using an entire metaclass. Most of the metaclasses in an RDBMS are there for a reason, and to take away a potentially useful tool seems like a bad idea to me. Perhaps your company or DBAs have decided that “thou shalt not use views” or “thou shalt not use triggers” and if so, then restricting them with a canCreate trigger might be acceptable. But not recommended.
So, thinking through the way we use models, I came up with a couple of cases for using the canCreate event.
1) Restricting the use of a metaclass (“thou shalt not use triggers”)
2) Ensuring that pre-conditions or model configuration is completed before allowing the modeler to create objects
3) Restricting the use of a stereotype
I’m going to do one example the shows demonstrates the first two cases, then we’ll handle stereotypes (poorly) separately.
Let me stress again that removing a metaclass entirely is NOT something I would typically recommend. However, at least on one of my projects, I can actually think of a place where I might use it. We currently have a team of modelers working on a Teradata implementation. In this environment we’re building a set of base tables which will store data for a variety of user groups in one database. Access to these tables will be managed through a set of view layers. Each group will have their own view database. Any physical structures such as indexes must be in the shared table database. Each database has its own model, so by flagging the model as either a view or table database, I can use a canCreate trigger to ensure that the view databases don’t contain any tables. We’ll create an extended attribute at the model level and make sure that the modeler has set the database type before they create any tables. I think that this targeted, conditional use of canCreate triggers, which require you to make a few “declarations” at the model level when you start are probably the right way to go and could potentially be useful.
So, let’s walk through an example.
First, I’m going to create an extended attribute on the model metaclass. I’ll call it DatabaseType and give it three potential values: “view”, “table” and “not set” (which will be the default). Using a default makes sure someone actually goes in and sets the value. Then, we’ll put our canCreate event on the table metaclass.
Notice that for the canCreate event the function has a “parent” parameter rather than the obj property that points to a specific object. For objects such as tables or views, this will be the model. For columns, indexes, etc. this will be the table.
Here’s the code:
Function %CanCreate%(parent) if parent.GetExtendedAttributeText("DatabaseType") = "View" then %CanCreate% = False elseif parent.GetExtendedAttributeText("DatabaseType") = "Not Set" then %CanCreate% = False else %CanCreate% = True end if End Function
This will prevent anyone from creating a table without setting the DatabaseType property at the model level to “table”. I have several extended model files that rely on setting a set of model level attributes that are used by initialization events and other scripts to automate common tasks. Using canCreate triggers, I could ensure that model level variables are set before we begin.
Next case.. restricting use of a stereotype. I thought long and hard on a good example for this and honestly I could not come up with one. I’m sure there’s one out there, please send ’em if you’ve got ’em, but I just couldn’t come up with it. I’m going to use a bad example, just so we can illustrate the point.
So, for the sake of argument, here goes. I’ve decided to classify my tables as associative, attributive or independent. In addition, I’m going to assign all of my columns political parties. Naturally, an independent table can’t contain Republican or Democratic columns (independent or green columns are fine). Did I mention this is a bad example? For this example, I’m going to use a stereotype to indicates an independent table. There are some rules I could use to determine this programmatically but that’s probably another post.
So, here’s what we end up with.
As you can see, we’ve got two stereotypes, each with a canCreate event. The code is the same in both triggers.
Function %CanCreate%(parent) ' Implement your creation validation rule on <parent> here ' and return True in case of success if parent.stereotype = "Independent" then %CanCreate% = False else %CanCreate% = True end if End Function
Here the parent property points to the enclosing table. We evaluate the stereotype and return true or false, where false indicates you cannot utilize the stereotype and true indicates you can.
Notice that our table marked as Independent only allows columns to be assigned to the Green or Independent party.
So, another event down. If you have a good use for the canCreate event in a data model, please do comment here or e-mail me. I’d really love a better example.