Reporting Schema Without Process Model
Reporting Schema Without Process Model
Reporting Schema Without Process Model
XML files follow internal object model used by DM and all properties of specific object can be found following
parent class link. There is an HTML presentation of XML files in doc directory (use index.html) which allow
faster navigation in class hierarchy – direct descendents of each class are also presented there.
Two important groups can be found in each XML file – properties and collections. They can be marked as
external which means that property or collection is stored outside the file that represents the object. As
example – Table has internal collection “columns” i.e. columns are stored in the file that represents table;
RelationalDesign class (representing relational model) has external collection Tables. Design class
(representing the whole design) has external property LogicalModel and external collection RelationalModels.
Each property has getter and setter method defined that can be used to get property or set it using scripting.
There are simple and complex properties. Simple properties (data types String, boolean, int, long…) are parts
of persistence of the object. Complex properties can be contained (their persistence is part of persistence of
the object) or referred - ID of referred object is stored in objects persistence though object is involved in setter
and getter method:
<property name="structuredType" dataType="oracle.dbtools.crest.model.design.datatypes.StructuredType" defaultValue=""
xmlName="structuredType" relatedProperty="use" relatedValue="3" xmlType="element" getter="getStructuredType" setter="setStructuredType"
reffered="true" search="true"/>
In some case simple String property holds object ID or list of object IDs – that’s related to dependencies
between objects during loading – it’s possible that referred object(s) may not be loaded when that property is
set.
Property can be marked as searchable and thus can be used in search, custom reports and set common
properties functionality. Some read only properties also are marked as searchable.
Complex properties could have methods for creating them or nullifying them (example – listOfValues in
ContainedObjectWithDomain) :
<property name="listOfValues" dataType="oracle.dbtools.crest.model.design.constraint.ConstraintEnumeration" isPropertyMap="true"
xmlName="listOfValues" xmlType="element" getter="getOwnValueList" setter="setOwnValueList" createPMap="createConstraintEnumeration"
itemXmlName="valueDef" keyXmlName="value" valueXmlName="description" removeItem="clearOwnValueList"/>
So listOfvalues can be created using instance of Column or Attribute – here is an example (script is bound to
logical model, gets entity by name, gets attribute by name, creates list of values if it’s not set for attribute, set it
on attribute and adds two values with description; :
ent = model.getEntitySet().getByName("PRODUCT INFORMATION");
if(ent!=null){
if(attr!=null){
attr.setUseDomainConstraints(false);
ce = attr.getOwnValueList();
if(ce==null){
ce = attr.createConstraintEnumeration();
attr.setOwnValueList(ce);
//ce.clearProperties();
ce.add("aaa","desc aaa");
ce.add("bbb","desc bbb");
attr.setDirty(true);
Collection definition provide createItem method that can be used to create item of that collection using instance
of surrounding object – back to Tables collection we see that table can be created using model.createTable().
And columns collection in Table shows the method for creating column:
col = table.createColumn();
ModelObject is the root of the hierarchy and each model is also instance of DesignPart class.
Changed object should be marked as changed using setDirty(true) method otherwise they won’t be saved
during save operation.
Each object has unique ID (method getObjectID() ) that can be used to get the object using method of Design
instance – in scripting it’ll be model.getDesign().getDesignObject( ID ) - that doesn’t cover objects in physical
models. Objects in relational and data types models have counterpart in physical model that has the same ID
and can be found through instance of physical model (StorageDesign class) – for relational model –
model.getStorageDesign().getStorageObject( ID ).
Tables in physical model are in TableProxySet – there is a special method for getting table by schema name
and table name due specific implementation of shemaObject in relational model and user that implements it in
physical model - getBySchemaImplAndName(String schema, String name) -
model.getStorageDesign().getTableProxySet().getBySchemaImplAndName(schema, name)
<codedEnum>
</codedEnum>
</property>
column. setLogicalDatatype(ldt);
Logical type, domain, structured type, ... can be get using related set and getByName() method:
lt_varchar = model.getDesign().getLogicalDatatypeSet().getByName("VARCHAR");
domain = model.getDesign().getDomainSet().getByName("my_domain");
Size or precision and scale can be set together with logical data type depending on data type presented –
character or numeric. Size, precision and scale will be displayed on diagram and included in DDL only if they
are enabled for logical data type set (Type administration)
First definition defines that name of FK should be set after property localFK Index is set.
And when all properties are set then method fk.addToTable() will be invoked.
Well this describes how DM do processing when model is loaded. Otherwise here is an example how to create
foreign key – Table2 has primary key PK_Table2 and column Col1 (in table1) match PK column in Table2:
col1 = table1.getElementByName("Col1");
if(col1!=null){
list.add(col1);
fk = table1.addForeignKey(PK_Table2,list);
V. Transformation scripts
Transformation script can be created using “Tools>Design Rules>Transformations” and then new script can be
created – need to set name, execution engine (Mozilla Rhino for Javascript comes with JDK), and model to
which scripts is bound – logical or relational. Variable that is initialized with related model is named model . In
its simplest form transformation script can be written in script window, save and executed or debugged (for
Javascript only).
Changes made with the script cannot be undone, so it’s recommended that design to be saved before
executing/debugging the script.
Once defined scripts can be executed from context menu for relational and logical model in the browser
(“Apply transformation scripts” in pop-up menu) – one or mere scripts can be executed at once:
VI. Code reuse - libraries
The code can be tested first in plain transformation script then can be moved in library for reuse. List of
functions defines functions that can be used in definitions of transformation scripts and design rules. There is
no parsing of the code so list of functions need to be created manually with names of functions that are defined
in the code and can be used in transformations and rules.
DM comes with predefined scrip named “Tables to lower case – Rhino” – here is the code transformed to
function in library – the code is surrounded by function definition
After code is transformed to function (lower_case) in library and function is defined in list of functions we can
create transformation script that uses library:
Library needs to be selected and function from library that will be executed. Library code appears in script
window but it cannot be edited and debugged.
Difference between transformation and design rule – design rule is bound to specific type of object (table,
column, entity..) and is invoked for each object in the related model while transformation is invoked only once.
Design rule should return true if it’s valid for processed object or false otherwise. Design rules also return to
DM error type (in variable errType) and error message (in variable errMessage). Error type could be Error (red
color), Warning (blue color) or something else set by customer (objects will be colored in yellow). Design rule
should not change the status if provided objects.
Following is defined for custom rule – name of the rule, object type, execution engine, error type (warning or
error – this can be changed in the script trough text set in errType variable). Variable field shows the name of
variable that will be initialized with provided object. Also library and function from that library need to be
selected. Library code is shown in “rule script” window but it’s not editable as it’s with transformation script
based on library.
IX. Usage of result from search functionality
Objects appearing in search result are available using method getLastSearchResult() of model or physical
model. Following code will cycle through all objects in search result:
objs = model.getLastSearchResult().toArray();
for(var i = 0;i<objs.length;i++){
obj = objs[i];
DM 4.0.2 comes with transformation that creates subview from table in search result:
objs = model.getLastSearchResult().toArray();
var dp;
var sv;
for(var i = 0;i<objs.length;i++){
obj = objs[i];
if(obj.getObjectTypeName().equals("Table")){
if(dp==null){
dp = obj.getDesignPart();
sv = dp.createDesignPartSubView();
//sv.setName("Name");
sv.getPlaceHolder().setVisible(true);
sv.addViewFor(obj);
if(dp!=null){
for(var i = 0;i<objs.length;i++){
obj = objs[i];
if(obj.getObjectTypeName().equals("Table")){
tv = obj.getFirstViewForDPV(sv);
if(tv!=null){
//tv.addTVRelations();
tv.addTVFKRelations();
for(var i = 0;i<objs.length;i++){
obj = objs[i];
if(obj.getObjectTypeName().equals("Table")){
tv = obj.getFirstViewForDPV(sv);
if(tv!=null){
tv.addArcs();
//arrange diagram
sv.rearrangeNewDiagram();
X. Objects in Subview
Subview is instance of Class DesignPartView and its descendants. Each table, view (class TableView), entity, view in
logical model (class EntityView), foreign key (class FKIndexAssociation) and relationship (class Relation) has method
getFirstViewForDPV(dpv)
where dpv is existing subview – here is code that will process only tables in specific subview:
if(dpv!=null){
tables = model.getTableSet().toArray();
table = tables[t];
tv = table.getFirstViewForDPV(dpv);
if(tv!=null){
Again using search functionality this can be done with less coding
Entities and tables has read-only property usedInSubviews – below are pictures showing usage of that property in
Advanced search:
2) Use search result
objs = model.getLastSearchResult().toArray();
for(var i = 0;i<objs.length;i++){
entity = objs[i];
// still can check if it's entity
if(obj.getObjectTypeName().equals("Entity")){
DM comes with transformation script called “Table template” which adds columns from table name
“table_template” to all other tables in the model. Here is script that do the same for logical model and enmities
there using entity named "entity_template" (transformation should be bound to logical model:
var t_name = "entity_template";
template = model.getEntitySet().getByName(t_name);
if(template!=null){
tcolumns = template.getElements();
tables = model.getEntitySet().toArray();
table = tables[t];
if(!table.getName().equalsIgnoreCase(t_name)){
column = tcolumns[i];
col = table.getElementByName(column.getName());
if(col==null){
col = table.createAttribute();
column.copy(col);
table.setDirty(true);
The script can be modified to be used together with search functionality – then different subset of entities can
get different common attribute simply by changing template entity and using different search criteria.
XI.2 Removing columns created with table template and related attributes in logical model
template = model.getTableSet().getByName(t_name);
if(template!=null){
tcolumns = template.getElements();
tables = model.getTableSet().toArray();
table = tables[t];
if(!table.getName().equalsIgnoreCase(t_name)){
column = tcolumns[i];
col = table.getColumnByProperty(p_name,column.getObjectID());
if(col!=null){
attr = col.getEngAttribute();
if(attr!=null){
ent = attr.getEntity();
attr.remove();
if(ent!=null){
ent.setDirty(true);
col.remove();
table.setDirty(true);
}
Though DM store design in set of directories and files, one can use scripting to store the whole design (or one
model) into single file and to restore the status from such file:
- Saving:
model.getAppView().getXMLTransformationManager().saveObjectWithExternals("D:/SVN_Local_files/h
andy_whole_des_big.xml",model.getDesign());
- Loading
Since design will take the status as it’s stored in the file it’s good to be sure design is empty – method
isEmpty() can be used for models (DesignPart class).
model.getAppView().getXMLTransformationManager().loadObjectWithExternals("D:/SVN_Local_files/h
andy_whole_des_big.xml",model.getDesign());
Note about physical models – only Oracle physical models are described in current revision of XML metadata
thus non Oracle physical models cannot be saved into single file.