As I mentioned somewhere else on this forum, I have to move objects between packages to improve user experience while working with database models. EA's DB RE imports all objects of the same type to single package regardless schema. And this location is mandatory for further work with RE. However for daily usage, we have to have split those objects into schema-based packages.
In result, every time I need to update EA model based on existing database, I have to move objects back and forth. With number of objects (thousands) it takes a lot of time (recently it took almost and hour, while running outside of working hours). Maybe worth to mention we are using central repository.
I'm moving the objects using scripting, in particular creating needed packages and changing packageID of each element.
Is there any way to speed this operation up, considering production model so any risky moves have to be limited. A few come to my mind:
- updating model using SQL queries against repo
- performing complete RE outside production model, then import via XMI
Both ways do look to me kinda dirty.
Maybe it's possible to speed up existing script, ie by some bulk update/refresh instead of doing it for single object separately. But I'm not sure what is allowed to do in this matter.
Here is a code I'm using for moving objects from original EA structure into Schemas/<schema_name>/<object_type>/<object> sctructure
!INC Local Scripts.EAConstants-JScript
!INC MichalK Scripts.Shared-Lib-JScript
/*
* Script Name: DbObjects_ReorganizeIntoSchemasTypes
* Author: Michal Kozusznik
* Purpose: Move db objects located in object type packages (functions,tables and so on) into Schemas/schemaname/objecttype
* Date: 2017-11-28
*/
function main()
{
Repository.EnsureOutputVisible( "Script" );
Session.Output( "Move tables to schemas-packages" );
Session.Output( "=======================================" );
var err;
MeasureTime();
try
{
var pck as EA.Package;
var RootSchemaPackageName = 'Schemas';
oType = Repository.GetTreeSelectedItemType();
if (oType != 5 /* package */) throw new Error("No package selected. Exiting.");
pck = Repository.GetTreeSelectedObject();
if (pck.StereotypeEx != 'Database') throw new Error("It is no root database package. Exiting.");
schemapackage = CreatePackageIfMissing(pck, RootSchemaPackageName);
for ( var i = 0 ; i < pck.Packages.Count ; i++)
{
if (pck.Packages.GetAt(i).Name == RootSchemaPackageName) continue;
Session.Output( "Processing: " + pck.Packages.GetAt(i).Name);
ProcessObjects(pck.Packages.GetAt(i), schemapackage);
}
Session.Output( "Finished" );
}
catch (err)
{
Session.Prompt(err.message, 0);
return;
}
Session.Output('Finished in: ' + MeasureTime() + 's');
}
/**********
* Iterate through all elements found in <srcPck> package and move them into <schemaPck>
* Inside of <schemaPck> subpackages representing db schemas will be created.
* And inside of the latter, subpackages for object types (Functions, Tables etc)
*
* <schemaPck>
* schema1
* Functinos
* Sequences
* Tables
* Views
* schema2
* Functinos
* Sequences
* Tables
* Vies
* etc
*
***********/
function ProcessObjects(srcPck, schemaPck)
{
var sourcePackage as EA.Package;
sourcePackage = srcPck;
var schema as EA.Package;
var currPackage as EA.Package;
var obj as EA.Element;
for ( var i = 0 ; i < sourcePackage.Elements.Count ; i++)
{
obj = sourcePackage.Elements.GetAt(i);
Session.Output( obj.Name);
schema = CreatePackageIfMissing(schemaPck, GetSchemaFromTaggedValue(obj));
currPackage = CreatePackageIfMissing(schema, sourcePackage.Name);
obj.PackageID = currPackage.PackageID;
obj.Update();
}
sourcePackage.Update();
schemaPck.Update();
}
/*
* Find a <schemaname> package collection of <pck>, or create one if not existist.
*/
function CreatePackageIfMissing(pck, schemaname)
{
var currentObj as EA.Package;
var currentPackage as EA.Package;
currentPackage = pck;
currentObj = null;
try
{
currentObj = currentPackage.Packages.GetByName(schemaname);
}
catch (err)
{
// do nothing
}
if (currentObj == null)
{
currentObj = currentPackage.Packages.AddNew(schemaname, "Class");
currentObj.Update();
currentPackage.Packages.Refresh();
}
return currentObj;
}
/******
* Get Schema name from 'Owner' TaggedValue of given <obj>
******/
function GetSchemaFromTaggedValue(obj)
{
var element as EA.Element;
var retval;
element = obj;
if (element.TaggedValues.GetByName('Owner') != null) retval = element.TaggedValues.GetByName('Owner').Value;
else if (element.TaggedValues.GetByName('OWNER') != null) retval = element.TaggedValues.GetByName('OWNER').Value;
if (retval == null)
{
throw new Error('Element ' + element.Name + ' has no tagged value Owner');
}
return retval;
}
main();
Don't bother of included script. It provides MeasureTime() to measure script execution time. Nothing critical.
With regards