Delete Objects with child Objects

Hello Forum,
I'm despaired with a problem. Maybe it is easy to solve, but...
I want to softDelete some object within some formal modules by a DXL-Script(DOORS 8.3)
Some have incoming links but I can take care of that.
Now, when running the script I will get a warning when object have (a)child(s)
I thought I could write a function that will delete the childs (and links) backwards, but I can not find the right way. :(
 

void recurseObjects(Object currObj)
{
    if(last(currObj) != null)
        {
                Object lastObj = last(currObj)
                softDelete(lastObj)
                recurseObjects(currObj)
        }
}
 
for obj in mod do
{
        if(!leaf(obj))
        {
                recurseObjects(obj)
                softDelete(obj)
        }
}

 


Is there an easier way to do so?
I give up. :)

Greets
Chris

 


SystemAdmin - Wed Jun 02 10:34:01 EDT 2010

Re: Delete Objects with child Objects
llandale - Wed Jun 02 11:21:41 EDT 2010

I'm just scribbling this down, you'll need to debug it yourself:

void  SoftDeleteObject(Object obj)
{     // delete the object recursively deleting its children first
 
   if (null obj) return
   Object  oChild
   for oChild in obj do
   {  SoftDeleteObject(oChild)  // ** RECURSION HERE **
   }
 
   DeleteIncomingLinks(obj)   // you can write these two
   DeleteOutgoingLinks(obj)
   flushDeletions()
 
   if (!isDeleted(obj)) softDelete(obj)
}  // end SoftDeleteObject()
 
SoftDeleteObject(current Object)


It may seem silly to ignore the deleted status when recursing its children, but it is indeed possible to create a situation where an object is deleted, but one of its children is NOT deleted.

I don't know what happens should the current user lack any Read rights to a child object.

 

 

  • Louie

 

 

Re: Delete Objects with child Objects
llandale - Wed Jun 02 11:25:27 EDT 2010

llandale - Wed Jun 02 11:21:41 EDT 2010

I'm just scribbling this down, you'll need to debug it yourself:

void  SoftDeleteObject(Object obj)
{     // delete the object recursively deleting its children first
 
   if (null obj) return
   Object  oChild
   for oChild in obj do
   {  SoftDeleteObject(oChild)  // ** RECURSION HERE **
   }
 
   DeleteIncomingLinks(obj)   // you can write these two
   DeleteOutgoingLinks(obj)
   flushDeletions()
 
   if (!isDeleted(obj)) softDelete(obj)
}  // end SoftDeleteObject()
 
SoftDeleteObject(current Object)


It may seem silly to ignore the deleted status when recursing its children, but it is indeed possible to create a situation where an object is deleted, but one of its children is NOT deleted.

I don't know what happens should the current user lack any Read rights to a child object.

 

 

  • Louie

 

 

Oh yes. I doubt you should actually delete objects in the middle of a standard object loop.

Skip  skpDeletes = create()
for obj in entire (current Module) do
{  if(I want to delete this object) put(skpDeletes, obj, obj)
}
 
for obj in skpDeletes do SoftDeleteObject(obj)
delete(skpDeletes)


Perhaps modify SoftDeleteObject() such that it stores the Objects it has deleted, so you don't thrash around re-deleting the same objects over and over, due to the Hierarchy.

 

 

  • Louie

 

 

Re: Delete Objects with child Objects
Mathias Mamsch - Wed Jun 02 11:32:57 EDT 2010

When I ignore the incoming links problem and any "can not delete object because some weird condition" problem (which are not easy to solve, since you need to take care of a lot of special cases: source modules being locked, only available in shared edit or you have no access, etc.). You can code it as follows:
 

void deleteObject(Object currObj)
{
      Object childObj
 
        // delete outlinks
        Skip sk = create(); Link L; for L in all currObj->"*" do put(sk, L,L); 
        for L in sk do delete L 
 
        refresh module currObj
 
        for childObj in all currObj do {
            if (cell childObj || row childObj || isDeleted childObj) 
                continue
 
            deleteObject childObj 
        }
 
        // delete the object
        softDelete currObj
}
 
deleteObject current

 


Regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Re: Delete Objects with child Objects
llandale - Wed Jun 02 11:52:56 EDT 2010

Mathias Mamsch - Wed Jun 02 11:32:57 EDT 2010

When I ignore the incoming links problem and any "can not delete object because some weird condition" problem (which are not easy to solve, since you need to take care of a lot of special cases: source modules being locked, only available in shared edit or you have no access, etc.). You can code it as follows:
 

void deleteObject(Object currObj)
{
      Object childObj
 
        // delete outlinks
        Skip sk = create(); Link L; for L in all currObj->"*" do put(sk, L,L); 
        for L in sk do delete L 
 
        refresh module currObj
 
        for childObj in all currObj do {
            if (cell childObj || row childObj || isDeleted childObj) 
                continue
 
            deleteObject childObj 
        }
 
        // delete the object
        softDelete currObj
}
 
deleteObject current

 


Regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Even if you let deleting the Table object also delete the rows and the cells, you still need to remove any links from the cells (and I guess the rows). So yes recurse cells and rows but move that check down to before the softDelete command.

Re: Delete Objects with child Objects
Mathias Mamsch - Wed Jun 02 15:33:44 EDT 2010

llandale - Wed Jun 02 11:52:56 EDT 2010
Even if you let deleting the Table object also delete the rows and the cells, you still need to remove any links from the cells (and I guess the rows). So yes recurse cells and rows but move that check down to before the softDelete command.

Did not think about that one ... Well spotted! Regards, Mathias

Re: Delete Objects with child Objects
SystemAdmin - Tue Jun 08 05:04:49 EDT 2010

Thank you for your thoughts.
This will help me to create a script that will fit my intension.
Regards Chris

Re: Delete Objects with child Objects
Tekka - Mon Nov 08 10:26:59 EST 2010

llandale - Wed Jun 02 11:21:41 EDT 2010

I'm just scribbling this down, you'll need to debug it yourself:

void  SoftDeleteObject(Object obj)
{     // delete the object recursively deleting its children first
 
   if (null obj) return
   Object  oChild
   for oChild in obj do
   {  SoftDeleteObject(oChild)  // ** RECURSION HERE **
   }
 
   DeleteIncomingLinks(obj)   // you can write these two
   DeleteOutgoingLinks(obj)
   flushDeletions()
 
   if (!isDeleted(obj)) softDelete(obj)
}  // end SoftDeleteObject()
 
SoftDeleteObject(current Object)


It may seem silly to ignore the deleted status when recursing its children, but it is indeed possible to create a situation where an object is deleted, but one of its children is NOT deleted.

I don't know what happens should the current user lack any Read rights to a child object.

 

 

  • Louie

 

 

Hello,

I have the same problem. I tried to delete Objects and their child's, which have a special Attribute value.
In reference to your solution I tried to fix my problem, but now I'm on a point I really don't know where my mistake is.
 

void deleteObjects(Object obj){
                Object objChild
        if (null obj) return
                if(obj."Variabilitaet" "" == "variabel"){
                        if(last obj != null)
                                for objChild in obj do
                                        deleteObjects objChild
                        delete obj
                }
        }
                        
        Object obj;
        for obj in current module do
                deleteObjects obj;


The loop go to the first parent Object and then runs throw the first child Objects and delete them, but when it go to the second parent Object the program fails.
(Error: Cannot delete Object: object has descendants)
Does somebody see why it runs throw the first loop and then failed in the second loop…?

Thanks

Re: Delete Objects with child Objects
llandale - Mon Nov 08 14:53:30 EST 2010

Tekka - Mon Nov 08 10:26:59 EST 2010

Hello,

I have the same problem. I tried to delete Objects and their child's, which have a special Attribute value.
In reference to your solution I tried to fix my problem, but now I'm on a point I really don't know where my mistake is.
 

void deleteObjects(Object obj){
                Object objChild
        if (null obj) return
                if(obj."Variabilitaet" "" == "variabel"){
                        if(last obj != null)
                                for objChild in obj do
                                        deleteObjects objChild
                        delete obj
                }
        }
                        
        Object obj;
        for obj in current module do
                deleteObjects obj;


The loop go to the first parent Object and then runs throw the first child Objects and delete them, but when it go to the second parent Object the program fails.
(Error: Cannot delete Object: object has descendants)
Does somebody see why it runs throw the first loop and then failed in the second loop…?

Thanks

No doubt your 2nd parent object has children objects whose attr value is not "variabel". Your code will not delete those, and when recursion unwinds back to the top then the top object still has undeleted children.

Is it your intention to set that attribute "Variabilitaet" to "variabel" for an object, and have your code delete that object and all descendants, without bothering to set the value for each descendant? If so, you need a top level loop that looks at each object and its attribute value, and if it indicates 'delete', then call the recursive function that deletes that object, first recursively deleting all child objects, second deleting all in-links, and lastly deleting the object. that loop should, BTW, check if the objet is already deleted, and if so will indeed recurse child objects and dlete any inlinks, but won't try to actually delete it again.

  • Louie

Re: Delete Objects with child Objects
Tekka - Thu Nov 11 04:25:58 EST 2010

llandale - Mon Nov 08 14:53:30 EST 2010
No doubt your 2nd parent object has children objects whose attr value is not "variabel". Your code will not delete those, and when recursion unwinds back to the top then the top object still has undeleted children.

Is it your intention to set that attribute "Variabilitaet" to "variabel" for an object, and have your code delete that object and all descendants, without bothering to set the value for each descendant? If so, you need a top level loop that looks at each object and its attribute value, and if it indicates 'delete', then call the recursive function that deletes that object, first recursively deleting all child objects, second deleting all in-links, and lastly deleting the object. that loop should, BTW, check if the objet is already deleted, and if so will indeed recurse child objects and dlete any inlinks, but won't try to actually delete it again.

  • Louie

Thanks Louie,

I replaced

delete obj

with

softdelete obj

and also check if the object is already deleted. Now it works fine :)

Re: Delete Objects with child Objects
senthilsubbu2020 - Wed Nov 22 02:03:56 EST 2017

Tekka - Thu Nov 11 04:25:58 EST 2010

Thanks Louie,

I replaced

delete obj

with

softdelete obj

and also check if the object is already deleted. Now it works fine :)

Hello All

    Greetings

whatever proposed solution and code didnot work and getting the error of: cannot delete Object: object has descendants. Based on my understanding, DXL will mark the object has to be deleted,but delete operation will be executed once DXL execution complete. Script is marking all child object has to delete, when parent comes it says object has descendants, but all child are deleted at end of the execution

any help will be very useful.

Re: Delete Objects with child Objects
EHcnck - Wed Nov 22 13:55:45 EST 2017

senthilsubbu2020 - Wed Nov 22 02:03:56 EST 2017

Hello All

    Greetings

whatever proposed solution and code didnot work and getting the error of: cannot delete Object: object has descendants. Based on my understanding, DXL will mark the object has to be deleted,but delete operation will be executed once DXL execution complete. Script is marking all child object has to delete, when parent comes it says object has descendants, but all child are deleted at end of the execution

any help will be very useful.

pragma encoding, "UTF-8"
pragma runLim, 0

Module m = current
Object startObj, endObj, o = current(m)
 
getSelection(m, startObj, endObj)
Skip skChildCache = create();

Object deleteInLinks(Object o) {
        Link l             = null
        LinkRef lr         = null
    ModName_ otherMod  = null
    Object othero      = null
        Skip deleteLinks   = create

        for lr in all(o<-"*") do {
                ModuleVersion otherVersion = sourceVersion lr
                otherMod = module (otherVersion)
                
                edit(rootName_(otherMod), true, true, true)
                
                if ( !null otherMod ) {
                        if ( (!isDeleted otherMod) && (null data(otherVersion)) ) {
                                edit(rootName_(otherMod), true, true, true)
                        }
                }
                delete otherVersion
        }
        
    for l in all(o<-"*") do {
        ModuleVersion otherVersion = sourceVersion l
        otherMod = module(otherVersion)
                delete otherVersion
        if (null otherMod || isDeleted otherMod) continue
        othero = source l
        if (null othero) {edit(rootName_(otherMod), true, true, true)}
        othero = source l
        if (null othero) continue
                
                put(deleteLinks, l, l, true) //overwrite if already exists.
    }
        
        for l in deleteLinks do {
                delete(l)
        }
        
        delete deleteLinks
        
        flushDeletions()
        return(o)
}

Object deleteOutLink (Object o) {
        Skip deleteLinks = create
        bool ret = false
        Link L
        
        for L in o->"*" do {
                put(deleteLinks, L, L, true) //overwrite if already exists.
        }
        
        for L in deleteLinks do {
                delete(L)
        }
        
        delete deleteLinks
        
        flushDeletions()
        return(o)
}

void recursiveAddChilds (Skip sk, Object oParent) {
    put(sk, oParent, oParent, true); //overwrite if already exists.
    Object oChild; 
        for oChild in all oParent do {
        recursiveAddChilds(sk, oChild); // Cleanup current delete Object(s) too.
    }
}
 
if ( !null(startObj) ) {  //if range has been selected, otherwise do nothing
        while ( !null(startObj) && isSelected(startObj) ) {
                recursiveAddChilds(skChildCache, startObj); 
                startObj = next(startObj) 
        }
} else {
        if ( !null(o) ) {
                recursiveAddChilds(skChildCache, o);
        }
}

{
        //Clean up linkage even if already deleted
        for o in skChildCache do {
                deleteInLinks(deleteOutLink(o))
        }

        for o in skChildCache do {
                //print (o."Absolute Number") "\n"
                if ( isDeleted(o) ) continue; 
                softDelete(o, false)
        }    
}

delete skChildCache
bringToFront(m)

 

Re: Delete Objects with child Objects
senthilsubbu2020 - Tue Nov 28 05:10:54 EST 2017

EHcnck - Wed Nov 22 13:55:45 EST 2017

pragma encoding, "UTF-8"
pragma runLim, 0

Module m = current
Object startObj, endObj, o = current(m)
 
getSelection(m, startObj, endObj)
Skip skChildCache = create();

Object deleteInLinks(Object o) {
        Link l             = null
        LinkRef lr         = null
    ModName_ otherMod  = null
    Object othero      = null
        Skip deleteLinks   = create

        for lr in all(o<-"*") do {
                ModuleVersion otherVersion = sourceVersion lr
                otherMod = module (otherVersion)
                
                edit(rootName_(otherMod), true, true, true)
                
                if ( !null otherMod ) {
                        if ( (!isDeleted otherMod) && (null data(otherVersion)) ) {
                                edit(rootName_(otherMod), true, true, true)
                        }
                }
                delete otherVersion
        }
        
    for l in all(o<-"*") do {
        ModuleVersion otherVersion = sourceVersion l
        otherMod = module(otherVersion)
                delete otherVersion
        if (null otherMod || isDeleted otherMod) continue
        othero = source l
        if (null othero) {edit(rootName_(otherMod), true, true, true)}
        othero = source l
        if (null othero) continue
                
                put(deleteLinks, l, l, true) //overwrite if already exists.
    }
        
        for l in deleteLinks do {
                delete(l)
        }
        
        delete deleteLinks
        
        flushDeletions()
        return(o)
}

Object deleteOutLink (Object o) {
        Skip deleteLinks = create
        bool ret = false
        Link L
        
        for L in o->"*" do {
                put(deleteLinks, L, L, true) //overwrite if already exists.
        }
        
        for L in deleteLinks do {
                delete(L)
        }
        
        delete deleteLinks
        
        flushDeletions()
        return(o)
}

void recursiveAddChilds (Skip sk, Object oParent) {
    put(sk, oParent, oParent, true); //overwrite if already exists.
    Object oChild; 
        for oChild in all oParent do {
        recursiveAddChilds(sk, oChild); // Cleanup current delete Object(s) too.
    }
}
 
if ( !null(startObj) ) {  //if range has been selected, otherwise do nothing
        while ( !null(startObj) && isSelected(startObj) ) {
                recursiveAddChilds(skChildCache, startObj); 
                startObj = next(startObj) 
        }
} else {
        if ( !null(o) ) {
                recursiveAddChilds(skChildCache, o);
        }
}

{
        //Clean up linkage even if already deleted
        for o in skChildCache do {
                deleteInLinks(deleteOutLink(o))
        }

        for o in skChildCache do {
                //print (o."Absolute Number") "\n"
                if ( isDeleted(o) ) continue; 
                softDelete(o, false)
        }    
}

delete skChildCache
bringToFront(m)

 

Thank you so much EHcnck.

 your code worked perfectly. This is my first post and response. I am very much impressed.