Sparx Systems Forum

Enterprise Architect => Automation Interface, Add-Ins and Tools => Topic started by: ja1234 on August 24, 2016, 10:59:31 pm

Title: Function to delete packages from model given packagename
Post by: ja1234 on August 24, 2016, 10:59:31 pm
Hello,

I have a very simple function to delete packages from a parent package, given the name of the package I want to delete, however, it does not work at all times (eg it does not delete the folders given as name ).  Any ideas why?

Example:

Input

-parent
--mypackage
--mypackage
----subpackge_of_my_package
--another subpackage

Output (expected)
-parent
--another subpackage

This is the function:

Code: [Select]
parent = parent folder ( given )
packageName = package name of the folders to be deleted (given)

Code: [Select]
//deletes a package with the reference to the package given
function deleteFolderIfExists( parent, packageName) {
var pkgList as EA.Collection;
pkgList = parent.Packages;

for (var i = 0; i < pkgList.Count; i++) {
var p as EA.Package;
p = pkgList.GetAt(i);

if (p.Name == packageName) {
pkgList.Delete(i);
pkgList.Refresh();
parent.Update();
}
}
}
Title: Re: Function to delete packages from model given packagename
Post by: qwerty on August 24, 2016, 11:53:59 pm
Have your deletion loop run backwards. If you delete the first element, now the 2nd is the first. Also your update() call is pointless.

q.
Title: Re: Function to delete packages from model given packagename
Post by: Eve on August 25, 2016, 08:30:02 am
Have your deletion loop run backwards. If you delete the first element, now the 2nd is the first.
Removing the refresh will also do the same thing, but also save reloading the collection after every delete.
Title: Re: Function to delete packages from model given packagename
Post by: qwerty on August 25, 2016, 04:10:50 pm
Oh yes. I  forgot to point out to remove the refresh as well. Though the removed refresh would simply solve the issue I'd always run deletions from collections downwards, simply as a good practice. There might be collections that behave different and re-index immediately.
q.
Title: Re: Function to delete packages from model given packagename
Post by: ja1234 on August 26, 2016, 02:02:09 am
Thanks, I have used the suggestions, but the package is still not deleted. Could the problem be that I create and delete the package in the same run of the script? (JScript)

I might simply use the SQL solution where I delete the package by name, can I safely do this?
Title: Re: Function to delete packages from model given packagename
Post by: qwerty on August 26, 2016, 02:22:39 am
No. If you just delete the package by SQL you will miss its elements. Only delete a package via API.

You can create and delete a package in the same run. So probably you're doing something wrong somewhere :-\

q.
Title: Re: Function to delete packages from model given packagename
Post by: ja1234 on August 30, 2016, 08:56:03 am
No. If you just delete the package by SQL you will miss its elements. Only delete a package via API.

You can create and delete a package in the same run. So probably you're doing something wrong somewhere :-\

q.

The package that I am deleting is not empty (has some other packages inside it), though that should not be a problem..

I have tried over the weekend to see what could be the problem, sure that using the API to delete a package is the best way, but looping through all packages/elements of the model to find a package with a specific name can and will take a lot of time.  Maybe it would be an option to delete all the packages that have ParentID the package that I want to delete?

I initially thought that the fact that I had set:
Code: [Select]
  Repository.EnableUIUpdates = false;
was the problem, but it seems not.

Will keep digging, thanks.
Title: Re: Function to delete packages from model given packagename
Post by: qwerty on August 30, 2016, 07:26:10 pm
You can use
Code: [Select]
Repository.SQLQuery ("SELECT FROM t_package WHERE name=<the name>") to quickly locate packages with a certain name.

If you delete a package via API it will also delete everything inside recursively.

q.
Title: Re: Function to delete packages from model given packagename
Post by: ja1234 on August 31, 2016, 10:40:29 pm
Thanks, q, starting from your pointers, I managed to get it to work. Writing the solution here, maybe it will  help other people.

Code: [Select]
var query = "SELECT Package_ID FROM t_package WHERE name LIKE '"+ packageName +"'";
var queryResult = Repository.SQLQuery (query);
var columnName = "Package_ID";
var stringValue;

if ( queryResult.length > 0 )
{
var resultDOM = XMLParseXML( queryResult );
if ( resultDOM )
stringValue = XMLGetNodeText( resultDOM, "//EADATA//Dataset_0//Data//Row//" + columnName + "[0]" );
}

if (stringValue)
{
var deleteQuery = "DELETE FROM t_package WHERE Package_ID ="+stringValue;

try { Repository.Execute(deleteQuery); }
catch(ex){};
}
Title: Re: Function to delete packages from model given packagename
Post by: qwerty on August 31, 2016, 11:17:13 pm
This will work, but in general it should not be done this way, since it will orphan anything that might be in the package. Better do do a GetPackageByID and delete that from its parent's Packages. If you run a consistency check on your model EA will probably croak about those orphans and move them to a dummy package it creates.

q.
Title: Re: Function to delete packages from model given packagename
Post by: Eve on September 01, 2016, 08:15:57 am
Additionally, even if the package appears completely empty it will leave a t_object row representing that package.
Title: Re: Function to delete packages from model given packagename
Post by: Paolo F Cantoni on September 01, 2016, 09:58:14 am
This will work, but in general it should not be done this way, since it will orphan anything that might be in the package. Better do do a GetPackageByID and delete that from its parent's Packages. If you run a consistency check on your model EA will probably croak about those orphans and move them to a dummy package it creates.

q.
As qwerty implies, it's MOST important to run the Integrity Checker after you run your developing code.  Run before you run your code to ensure there are no issues and then after you run the code - to check you didn't introduce any.  If none, then your code is "safe".  It may not be correct, but at least it's safe.

Paolo