Skip Project if it is "Locked"

I have some scripts that I'm developing that perform various tasks at the Project level, and I run these as a batch process. I run them at night, when users are (for the most part) not in DOORS. However, on occasion I'll get a message that a Project is locked or that I have an Invalid lock request - data already locked.
What I'd like to do is add some lines to my scripts to catch these issues and move on to the next project - maybe save a list of the projects that "failed" as a text file for review afterwards. I think this begs for a skip list, but I'm having difficulty writing this. Can anyone help?

Thanks,

Chris Annal
SW Test Engineer / DOORS Database Administrator
Sensis Corporation, East Syracuse, New Yor
kchrisa@sensis.com
ChrisAnnal - Wed Jun 08 10:09:16 EDT 2011

Re: Skip Project if it is "Locked"
llandale - Wed Jun 08 14:40:39 EDT 2011

Never figures this out adequately. The "string isLocked(item)" command doesn't seem to work on Projects.

But some years ago I played with the notion that if you was not locked you could rename the project and if it was locked you could not. So I'd try to rename it and if it failed I figured it was locked and I'd bypass it, and it the rename took then I'd rename it back and proceed.

I had some difficulty with the piece of the code that found an error renaming it back ... Ooops, now what? Giving me hackles on the back of my neck and also realizing that DOORS v5.0 left 1000s or residual locks around, I decided my weakly code ..err.. weekly code would just remove all locks Sunday 1am; too bad for folks leaving their module's open for Edit unsaved over the week-end (there's a little Tony in me, after all).

I'm pretty sure you can loop through all locks in the database looking for one that applied to that Project. Perhaps that may look something like this scribbled code:

bool    IsProjectLocked(string NameProj)
{     // Is the project locked?
        // Project name has leading slash e.g. "/MyProject", such as
        //    returned from fullName(Project) <NOT from rootName_(Project)>
        Lock lck
        string NameLock
        
        for lck in lockList do
        {  NameLock = lck.recourceName
           if (matches(NameProj, NameLock)) return(true)
        }
        return(false)
}     // end IsProjectLocked()


Perhaps you could play with that and experiment with two DOORS sessions under what conditions it returns true and let us know. One client has the Project in the RIGHT pane and runs the script, the other project does things like open the project (so its in the left pane) or open a module therein.

 

 

  • Louie

 

 

Re: Skip Project if it is "Locked"
llandale - Wed Jun 08 14:56:34 EDT 2011

llandale - Wed Jun 08 14:40:39 EDT 2011

Never figures this out adequately. The "string isLocked(item)" command doesn't seem to work on Projects.

But some years ago I played with the notion that if you was not locked you could rename the project and if it was locked you could not. So I'd try to rename it and if it failed I figured it was locked and I'd bypass it, and it the rename took then I'd rename it back and proceed.

I had some difficulty with the piece of the code that found an error renaming it back ... Ooops, now what? Giving me hackles on the back of my neck and also realizing that DOORS v5.0 left 1000s or residual locks around, I decided my weakly code ..err.. weekly code would just remove all locks Sunday 1am; too bad for folks leaving their module's open for Edit unsaved over the week-end (there's a little Tony in me, after all).

I'm pretty sure you can loop through all locks in the database looking for one that applied to that Project. Perhaps that may look something like this scribbled code:

bool    IsProjectLocked(string NameProj)
{     // Is the project locked?
        // Project name has leading slash e.g. "/MyProject", such as
        //    returned from fullName(Project) <NOT from rootName_(Project)>
        Lock lck
        string NameLock
        
        for lck in lockList do
        {  NameLock = lck.recourceName
           if (matches(NameProj, NameLock)) return(true)
        }
        return(false)
}     // end IsProjectLocked()


Perhaps you could play with that and experiment with two DOORS sessions under what conditions it returns true and let us know. One client has the Project in the RIGHT pane and runs the script, the other project does things like open the project (so its in the left pane) or open a module therein.

 

 

  • Louie

 

 

so much for scribbling.

bool    IsProjectLocked(string NameProj)
{     // Is the project locked?
        // Project name has leading slash e.g. "/MyProject", such as
        //    returned from fullName(Project) <NOT from rootName_(Project)>
        Lock    lck
        string  NameLock
        LockList        llist = getLocksInDatabase(true)
        bool    Found = false
        Item    itm
        
        for lck in llist do
        {  itm = lck.item
           NameLock = fullName(itm)
           if (matches(NameProj, NameLock)) 
           {  Found = true
              break     // stop looking
           }
        }
        delete(llist)
        return(Found)
}     // end IsProjectLocked()
 
string NameProj = "/LPD26 Interfaces"
print (IsProjectLocked(NameProj)) "\t" NameProj "\n"

 

  • Louie

 

Re: Skip Project if it is "Locked"
ChrisAnnal - Thu Aug 25 10:18:54 EDT 2011

llandale - Wed Jun 08 14:56:34 EDT 2011

so much for scribbling.

bool    IsProjectLocked(string NameProj)
{     // Is the project locked?
        // Project name has leading slash e.g. "/MyProject", such as
        //    returned from fullName(Project) <NOT from rootName_(Project)>
        Lock    lck
        string  NameLock
        LockList        llist = getLocksInDatabase(true)
        bool    Found = false
        Item    itm
        
        for lck in llist do
        {  itm = lck.item
           NameLock = fullName(itm)
           if (matches(NameProj, NameLock)) 
           {  Found = true
              break     // stop looking
           }
        }
        delete(llist)
        return(Found)
}     // end IsProjectLocked()
 
string NameProj = "/LPD26 Interfaces"
print (IsProjectLocked(NameProj)) "\t" NameProj "\n"

 

  • Louie

 

OK. I finally got back to this script and wrote it for archiving projects as part of a batch process. The problem is, if a locked project is found, my script still stops and displays the following in the DOS window:

-I- DXL: Item /<project> locked (shared) by 1 user
user@SENSIS-15246
Failed to lock archive item (/<project>) for inclusion in archive

(Where "<project>" is the actual name of the project that is locked and "user" is the actual name of the user who has it locked).

All I want to do is skip over that project and continue with the archive process, with perhaps the added bonus of logging what projects were skipped over - so they can be addressed later.

Here's the entire existing script:

Lock lockItem 
string uname 
string proj_name 
int pcounter = 0
//Message to user
print "Archiving ...\n"
 
//Iterate through projects in database
Project p
for p in database do{
 
//Extract name of current project
string pname = name p
 
//Get parent project
Project parent = getParentProject(p)
if(null parent && !isDeleted p){
// build the skip list of top level Projects
// pcounter is key, pname is data 
    Skip projList = create 
        int projCount = 0 
    put(projList, pcounter, pname)
    // Get Locks
                LockList lcklist = getLocksInDatabase(true) 
                        for lockItem in lcklist do { 
                    uname = lockItem.user
                    proj_name = lockItem.resourceName 
            }
// for each project in the skip list...
  for pname in projList do {
                         if (proj_name == pname)   //if the project name is one that is "locked"
                           {
                                continue
                                print "User: " uname " has Project resource: " proj_name " locked""\n"
                                }//End if (proj_name == pname)
                                        else  //project isn't locked, so archive it
                                        {
string proj_archive = archive (pname,"c:\\DOORS_Projects\\ATS\\"(pname)".dpa",false,true,allBaselines,false)        
                                                if (!null proj_archive) 
                                                {
                                                        ack proj_archive
                                                        halt
                                                }// End !null proj_archive
                                        }// End else (proj_name != pname)
                        pcounter++
                projCount++
                print pname
                        print " Done!" "\n"
                }// End for pname in projList do 
        }// End if(null parent && !isDeleted p)
}//End for p in database do

 


I thought the "continue" line would allow the process to continue and the "print" would display any of the offenders, but instead I get the message I mentioned above.

Chris Annal
SW Test Engineer / DOORS Database Administrator
Saab Sensis Corporation, East Syracuse, New York
chrisa@saabsensis.com

 

Re: Skip Project if it is "Locked"
llandale - Thu Aug 25 12:07:40 EDT 2011

ChrisAnnal - Thu Aug 25 10:18:54 EDT 2011

OK. I finally got back to this script and wrote it for archiving projects as part of a batch process. The problem is, if a locked project is found, my script still stops and displays the following in the DOS window:

-I- DXL: Item /<project> locked (shared) by 1 user
user@SENSIS-15246
Failed to lock archive item (/<project>) for inclusion in archive

(Where "<project>" is the actual name of the project that is locked and "user" is the actual name of the user who has it locked).

All I want to do is skip over that project and continue with the archive process, with perhaps the added bonus of logging what projects were skipped over - so they can be addressed later.

Here's the entire existing script:

Lock lockItem 
string uname 
string proj_name 
int pcounter = 0
//Message to user
print "Archiving ...\n"
 
//Iterate through projects in database
Project p
for p in database do{
 
//Extract name of current project
string pname = name p
 
//Get parent project
Project parent = getParentProject(p)
if(null parent && !isDeleted p){
// build the skip list of top level Projects
// pcounter is key, pname is data 
    Skip projList = create 
        int projCount = 0 
    put(projList, pcounter, pname)
    // Get Locks
                LockList lcklist = getLocksInDatabase(true) 
                        for lockItem in lcklist do { 
                    uname = lockItem.user
                    proj_name = lockItem.resourceName 
            }
// for each project in the skip list...
  for pname in projList do {
                         if (proj_name == pname)   //if the project name is one that is "locked"
                           {
                                continue
                                print "User: " uname " has Project resource: " proj_name " locked""\n"
                                }//End if (proj_name == pname)
                                        else  //project isn't locked, so archive it
                                        {
string proj_archive = archive (pname,"c:\\DOORS_Projects\\ATS\\"(pname)".dpa",false,true,allBaselines,false)        
                                                if (!null proj_archive) 
                                                {
                                                        ack proj_archive
                                                        halt
                                                }// End !null proj_archive
                                        }// End else (proj_name != pname)
                        pcounter++
                projCount++
                print pname
                        print " Done!" "\n"
                }// End for pname in projList do 
        }// End if(null parent && !isDeleted p)
}//End for p in database do

 


I thought the "continue" line would allow the process to continue and the "print" would display any of the offenders, but instead I get the message I mentioned above.

Chris Annal
SW Test Engineer / DOORS Database Administrator
Saab Sensis Corporation, East Syracuse, New York
chrisa@saabsensis.com

 

That's pretty ugly code; if nothing else fix the indentation. A real editor will let you see tabs and spaces which make formatting far easier.

I think you want code that resembles this:

if the current folder isn't at the database level then warn and halt.
create skpProjectsToArchive
for each project in the database
{  if (project has parent project) then advise and continue
   if (project is currently locked)then warn and continue
   put in skpProjectsToArchive
}
for projects to archive
{  build the project name
   archive the project
   report archive status
}
delete(skpProjectsToArchive)


Some folks will advise to replace
... if (project is currently locked)then warn and continue
with...
while(true)
{ if (project is currently locked)
then delete the lock and warn.
else break // no more locks
}
The "Project Name" could perhaps include today's date in it.

I wonder if the parent project will appear to be "locked" when a subordinate project is actually locked.

 

 

  • Louie

 

 

Re: Skip Project if it is "Locked"
David_G_Bond - Thu Aug 25 13:10:19 EDT 2011

llandale - Thu Aug 25 12:07:40 EDT 2011

That's pretty ugly code; if nothing else fix the indentation. A real editor will let you see tabs and spaces which make formatting far easier.

I think you want code that resembles this:

if the current folder isn't at the database level then warn and halt.
create skpProjectsToArchive
for each project in the database
{  if (project has parent project) then advise and continue
   if (project is currently locked)then warn and continue
   put in skpProjectsToArchive
}
for projects to archive
{  build the project name
   archive the project
   report archive status
}
delete(skpProjectsToArchive)


Some folks will advise to replace
... if (project is currently locked)then warn and continue
with...
while(true)
{ if (project is currently locked)
then delete the lock and warn.
else break // no more locks
}
The "Project Name" could perhaps include today's date in it.

I wonder if the parent project will appear to be "locked" when a subordinate project is actually locked.

 

 

  • Louie

 

 

I'm assuming that use of noError() and lastError() does not work here. Otherwise that would seem to be a simple solution.

Re: Skip Project if it is "Locked"
llandale - Thu Aug 25 17:13:56 EDT 2011

David_G_Bond - Thu Aug 25 13:10:19 EDT 2011
I'm assuming that use of noError() and lastError() does not work here. Otherwise that would seem to be a simple solution.

Actually, the archive command returns an error message and traps lock etc errors, and then continues. Not sure why we want to find out ahead of time of the archive will work, as in both cases you end up with no archive and an Error Message that you want to display.

But, you could find the locks and delete them and thus making the archive work.

  • Louie

Re: Skip Project if it is "Locked"
ChrisAnnal - Fri Aug 26 09:21:55 EDT 2011

llandale - Thu Aug 25 17:13:56 EDT 2011
Actually, the archive command returns an error message and traps lock etc errors, and then continues. Not sure why we want to find out ahead of time of the archive will work, as in both cases you end up with no archive and an Error Message that you want to display.

But, you could find the locks and delete them and thus making the archive work.

  • Louie

I apologize for not being clearer. My basic question was this:
If a locked project is encountered during the running of a batch-process DXL script, how can we avoid the locked project. What I want to do is simply continue with the process and skip over the offending (locked) project. I don't want to unlock it for fear of data corruption. I just want to skip it. This would apply to any DXL script that runs on a batch process using
{Code}
Project p
for p in database do {
string pname = name p // later in the code example, I put these pnames in a Skip List and do something with each...
{Code}
I had thought I needed to build a 2nd list of projects that were locked, using "getLocksInDabase" and comparing the results against the "pname"s in the projList
Again, all of this was in an effort to simply AVOID those projects that are locked when the batch process is running. I know in other threads of the forum various contributers have suggested kicking users out, unlocking, etc when this type of problem arises, but I was looking for a kinder, gentler approach..
:)

Re: Skip Project if it is "Locked"
llandale - Sun Aug 28 17:25:22 EDT 2011

ChrisAnnal - Fri Aug 26 09:21:55 EDT 2011
I apologize for not being clearer. My basic question was this:
If a locked project is encountered during the running of a batch-process DXL script, how can we avoid the locked project. What I want to do is simply continue with the process and skip over the offending (locked) project. I don't want to unlock it for fear of data corruption. I just want to skip it. This would apply to any DXL script that runs on a batch process using
{Code}
Project p
for p in database do {
string pname = name p // later in the code example, I put these pnames in a Skip List and do something with each...
{Code}
I had thought I needed to build a 2nd list of projects that were locked, using "getLocksInDabase" and comparing the results against the "pname"s in the projList
Again, all of this was in an effort to simply AVOID those projects that are locked when the batch process is running. I know in other threads of the forum various contributers have suggested kicking users out, unlocking, etc when this type of problem arises, but I was looking for a kinder, gentler approach..
:)

Way up above I wrote the simple "IsProjectLocked" function which you could use in this sort of loop:

for proejct in database
{  if (IsProjectLocked)
   then print "Ignoring locked project "
   else proceed to archive
}


If you want to save a fraction of a second to avoide repeated calls to "getLocksInDatabase" you could ignore the function, get your locks in database, look througn all locks and get the name, and if its a project(name) then stick it in a skip list of locked projects. Then use the above loop checking the skip instead of the function.

 

 

  • Louie

 

 

Re: Skip Project if it is "Locked"
OurGuest - Mon Aug 29 11:12:46 EDT 2011

ChrisAnnal - Fri Aug 26 09:21:55 EDT 2011
I apologize for not being clearer. My basic question was this:
If a locked project is encountered during the running of a batch-process DXL script, how can we avoid the locked project. What I want to do is simply continue with the process and skip over the offending (locked) project. I don't want to unlock it for fear of data corruption. I just want to skip it. This would apply to any DXL script that runs on a batch process using
{Code}
Project p
for p in database do {
string pname = name p // later in the code example, I put these pnames in a Skip List and do something with each...
{Code}
I had thought I needed to build a 2nd list of projects that were locked, using "getLocksInDabase" and comparing the results against the "pname"s in the projList
Again, all of this was in an effort to simply AVOID those projects that are locked when the batch process is running. I know in other threads of the forum various contributers have suggested kicking users out, unlocking, etc when this type of problem arises, but I was looking for a kinder, gentler approach..
:)

My head began hurting, looking at the code so I simplified. If you have proper permissions the following code should work. Just put your code where script says. "//PUT NORMAL PROCESSING HERE"

I made it about as simple as possible -- you can emblish as you want after you get what you want working.
 

//FindUnlockedProject
/*Demo to find locked projects*/
Lock lockItem 
LockList lcklist
string sProjectName 
Project pX 
Buffer bx1=create, bx2=create
bool bLockedByAnyUser=true
 
for pX in database do  
{  sProjectName = name pX   
   lcklist = getLocksInFolder(pX,true,bLockedByAnyUser) 
   for lockItem in lcklist do {if(matches(sProjectName,bx1 ""))continue;bx1+=sProjectName " locked\n"}
   bx2+= sProjectName " is available for processing\n"
   //PUT NORMAL PROCESSING HERE
} 
print bx1 "\n" bx2""

Re: Skip Project if it is "Locked"
ChrisAnnal - Mon Aug 29 12:25:14 EDT 2011

OurGuest - Mon Aug 29 11:12:46 EDT 2011

My head began hurting, looking at the code so I simplified. If you have proper permissions the following code should work. Just put your code where script says. "//PUT NORMAL PROCESSING HERE"

I made it about as simple as possible -- you can emblish as you want after you get what you want working.
 

//FindUnlockedProject
/*Demo to find locked projects*/
Lock lockItem 
LockList lcklist
string sProjectName 
Project pX 
Buffer bx1=create, bx2=create
bool bLockedByAnyUser=true
 
for pX in database do  
{  sProjectName = name pX   
   lcklist = getLocksInFolder(pX,true,bLockedByAnyUser) 
   for lockItem in lcklist do {if(matches(sProjectName,bx1 ""))continue;bx1+=sProjectName " locked\n"}
   bx2+= sProjectName " is available for processing\n"
   //PUT NORMAL PROCESSING HERE
} 
print bx1 "\n" bx2""

Thank You, OurGuest.
Your simple solution provided the wrapper that I can use to execute my scripts on projects that are not locked, and avoid those that are locked. This allows scripts not only to run as part of a batch process, but (if needed) they can be run during regular hours and not interfere with users who are currently working in DOORS - since the projects they are working in will be avoided. And thanks to Louie, too. Your advice helped me clean up my existing code.

Thanks!

Chris Annal
SW Test Engineer / DOORS Database Administrator
Saab Sensis Corporation, East Syracuse, New York
chrisa@saabsensis.com

Re: Skip Project if it is "Locked"
OurGuest - Mon Aug 29 12:53:42 EDT 2011

OurGuest - Mon Aug 29 11:12:46 EDT 2011

My head began hurting, looking at the code so I simplified. If you have proper permissions the following code should work. Just put your code where script says. "//PUT NORMAL PROCESSING HERE"

I made it about as simple as possible -- you can emblish as you want after you get what you want working.
 

//FindUnlockedProject
/*Demo to find locked projects*/
Lock lockItem 
LockList lcklist
string sProjectName 
Project pX 
Buffer bx1=create, bx2=create
bool bLockedByAnyUser=true
 
for pX in database do  
{  sProjectName = name pX   
   lcklist = getLocksInFolder(pX,true,bLockedByAnyUser) 
   for lockItem in lcklist do {if(matches(sProjectName,bx1 ""))continue;bx1+=sProjectName " locked\n"}
   bx2+= sProjectName " is available for processing\n"
   //PUT NORMAL PROCESSING HERE
} 
print bx1 "\n" bx2""

Simpler and faster -- in previous code after I pasted in the code, I deleted "continue" which was needed. But the following will work faster.
 

//FindUnlockedProject
/*Demo to find locked projects*/
Lock lockItem 
LockList lcklist
string sProjectName 
Project pX 
Buffer bx1=create, bx2=create
bool bLockedByAnyUser=true
 
for pX in database do  
{  sProjectName = name pX   
   lcklist = getLocksInFolder(pX,true,bLockedByAnyUser) 
   for lockItem in lcklist do {bx1+=sProjectName " locked\n";break}
   bx2+= sProjectName " is available for processing\n"
   //PUT NORMAL PROCESSING HERE
} 
print bx1 "\n" bx2""

Re: Skip Project if it is "Locked"
OurGuest - Tue Aug 30 07:10:34 EDT 2011

OurGuest - Mon Aug 29 12:53:42 EDT 2011

Simpler and faster -- in previous code after I pasted in the code, I deleted "continue" which was needed. But the following will work faster.
 

//FindUnlockedProject
/*Demo to find locked projects*/
Lock lockItem 
LockList lcklist
string sProjectName 
Project pX 
Buffer bx1=create, bx2=create
bool bLockedByAnyUser=true
 
for pX in database do  
{  sProjectName = name pX   
   lcklist = getLocksInFolder(pX,true,bLockedByAnyUser) 
   for lockItem in lcklist do {bx1+=sProjectName " locked\n";break}
   bx2+= sProjectName " is available for processing\n"
   //PUT NORMAL PROCESSING HERE
} 
print bx1 "\n" bx2""

To keep from processing locked module need boolean bLocked added
 

//FindUnlockedProject
/*Demo to find locked projects*/
Lock lockItem 
LockList lcklist
string sProjectName 
Project pX 
Buffer bx1=create, bx2=create
bool bLockedByAnyUser=true, bLocked
 
for pX in database do  
{  sProjectName = name pX   
   lcklist = getLocksInFolder(pX,true,bLockedByAnyUser) 
   bLocked=false
   for lockItem in lcklist do {bLocked=true; bx1+=sProjectName " locked\n";break}
   if(bLocked)continue
   bx2+= sProjectName " is available for processing\n"
   //PUT NORMAL PROCESSING HERE
} 
print bx1 "\n" bx2""

Re: Skip Project if it is "Locked"
llandale - Tue Aug 30 14:38:54 EDT 2011

OurGuest - Tue Aug 30 07:10:34 EDT 2011

To keep from processing locked module need boolean bLocked added
 

//FindUnlockedProject
/*Demo to find locked projects*/
Lock lockItem 
LockList lcklist
string sProjectName 
Project pX 
Buffer bx1=create, bx2=create
bool bLockedByAnyUser=true, bLocked
 
for pX in database do  
{  sProjectName = name pX   
   lcklist = getLocksInFolder(pX,true,bLockedByAnyUser) 
   bLocked=false
   for lockItem in lcklist do {bLocked=true; bx1+=sProjectName " locked\n";break}
   if(bLocked)continue
   bx2+= sProjectName " is available for processing\n"
   //PUT NORMAL PROCESSING HERE
} 
print bx1 "\n" bx2""

Never really considered getLocksInFolder() before, am checking old code to see if I should use it.

I see you deleted the "matches" code, which would have failed if Project "ABC" was locked, and then you checked project "AB".

This little code doesn't matter but its good form to delete your structures, delete(lcklist) inside the loop and delete the buffers outside.

  • Louie

Re: Skip Project if it is "Locked"
OurGuest - Tue Aug 30 15:07:58 EDT 2011

llandale - Tue Aug 30 14:38:54 EDT 2011
Never really considered getLocksInFolder() before, am checking old code to see if I should use it.

I see you deleted the "matches" code, which would have failed if Project "ABC" was locked, and then you checked project "AB".

This little code doesn't matter but its good form to delete your structures, delete(lcklist) inside the loop and delete the buffers outside.

  • Louie

The only way it would be good form to delete structures is if there was a standard that a scripter had to comply with. DOORS is suppose to delete the structures when the DXL ends -- so there is no point in deleting the structure if there is no standards established -- which there are non established for this forum or for demo code.