home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-11-28 | 50.8 KB | 1,869 lines |
- #---------------------------------------------------------------------------
- #
- # (c) Cayenne Software Inc. 1997
- #
- # File: @(#)repository.tcl /main/titanic/37
- # Author: <generated>
- # Description:
- #---------------------------------------------------------------------------
- # SccsId = @(#)repository.tcl /main/titanic/37 28 Nov 1997 Copyright 1997 Cayenne Software Inc.
-
- # Start user added include file section
- require repdbms.tcl
- require options.tcl
- require caynutil.tcl
- # End user added include file section
-
-
- Class Repository : {GCObject} {
- constructor
- method destructor
- method msg
- method message
- method warning
- method error
- method execute
- method quickTimeOut
- method resetTimeOut
- method getAvailableRepositories
- method setCurrent
- method currentCorporate
- method checkCorporate
- method currentOwner
- method currentDbServer
- method findDbServer
- method currentRepDir
- method currentObjDir
- method shutdownDbServers
- method getActiveClients
- method getServerById
- method getServerByObject
- method getServerByName
- method changeServerDefinition
- method removeServerDefinition
- method getInfoFromDatabase
- method getInfoFromCmdLine
- method getInfoFromCorporate
- method makeOptions
- method makeDbOptions
- method makeCmdLine
- method makeDbCmdLine
- method makeDbToolCmd
- method runDbScript
- method startDbTool
- method toolFinished
- method checkRepositoryName
- method createRepository
- method changeRepository
- method fixRepositoryDir
- method deleteRepository
- method deleteRepositoryDir
- method deleteRepositoryDb
- method deleteServerEntry
- method optimizeRepository
- method dumpRepository
- method dumpObject
- method restoreRepository
- method restoreObject
- method expandArchiveCommand
- method archiveRepositoryDirectory
- method archiveObjectDirectory
- method unarchiveRepositoryDirectory
- method unarchiveObjectDirectory
- method getExternalFileVersions
- method getLockServer
- method getLocks
- method isHangingLock
- method describeLock
- method setLock
- method removeLock
- method upgradeLocks
- attribute currentName
- attribute lastRepDir
- attribute orbTimeOut
- attribute extFiles
- attribute extFilesLoaded
- attribute extCorp
- attribute extProj
- attribute extConf
- attribute useLockServerId
- attribute toolFinishedScript
- attribute context
- attribute messageHandler
- attribute lockServer
- attribute badServers
- }
-
- constructor Repository {class this} {
- set this [GCObject::constructor $class $this]
- # Start constructor user section
-
- # Make this usable by both otk and otsh.
- #
- catch { OtkRegister::repository }
- catch { OtkRegister::lockServer }
- catch { OtkRegister::reportWriter }
-
- catch { OTShRegister::clientContext }
- catch { OTShRegister::repository }
- catch { OTShRegister::lockServer }
- catch { OTShRegister::reportWriter }
- catch { OTShRegister::semanticModel }
-
- if [catch {$this context [ClientContext::global]} msg] {
- # Do this again, since on error, it returns "",
- # but only the first time.
- #
- $this context [ClientContext::global]
- }
-
- RepositoryDBMS::setCurrent [ORB::nil]
-
- # Determine default corporate from M4_levelpath
- #
- set path [m4_var get M4_levelpath]
- if [regexp {^/([^/]*)} $path dummy corpName] {
- $this currentName $corpName
- }
-
- # Remember original ORB timeout.
- #
- $this orbTimeOut [m4_var get M4_orb_timeout]
-
- $this extFiles [List new]
- $this extFilesLoaded 0
- $this extCorp ""
- $this extProj ""
- $this extConf ""
-
- $this lockServer [ORB::nil]
- $this useLockServerId 0
-
- $this badServers [Dictionary new]
-
- # End constructor user section
- return $this
- }
-
- method Repository::destructor {this} {
- # Start destructor user section
- # End destructor user section
- }
-
-
- # Formats a number of seconds as a string with the
- # format: HH:MM:SS where HH, MM, SS are hours, minutes
- # and seconds respectively. If the number of seconds
- # spans one day or more, the string "D day(s), " is
- # prepended to the time string, where D is the
- # number of days.
- #
- proc Repository::formatSeconds {seconds} {
- set d [expr {$seconds / (24*3600)}]
- set h [expr {($seconds % (24*3600)) / 3600}]
- set m [expr {($seconds % 3600) / 60}]
- set s [expr {$seconds % 60}]
-
- set time [format "%02d:%02.2d:%02d" $h $m $s]
- if {$d == 0} {
- return $time
- }
-
- set s "s"
- if {$d == 1} {
- set s ""
- }
-
- return "$d day$s, $time"
- }
-
-
- # Expands special symbols and variables
- # in the given file name, and returns
- # the new file name. If 'escape' is true,
- # backslashes are escaped as well.
- #
- proc Repository::expandFileName {file {escape 0}} {
-
- # Substitute ~ and ~user. Cannot use glob directory on $file since
- # that returns nothing if the directory/file does not exist.
- #
-
- if [regexp {^~[\\/](.*)} $file dummy path] {
- set file [location [otglob -nocomplain ~] $path]
- } elseif [regexp {^~(.*)} $file dummy path] {
- set expandedDir [path_name directory [otglob -nocomplain ~]]
- set file [location $expandedDir $path]
- }
-
- # Substitute environment variables.
- #
- global env
- while {[regexp -indices {\$([a-zA-Z][a-zA-Z0-9_]*)} $file dummy list]} {
- set var [string range $file [lindex $list 0] [lindex $list 1]]
- regsub "\\\$${var}" $file $env($var) file
- }
-
- if $win95 {
- regsub -all {/} $file {\\} file
- }
-
- # Escape backslashes.
- #
- if $escape {
- regsub -all {\\} $file {\\\\} file
- }
-
- return $file
- }
-
-
- # Does the same as 'expandFileName', but additionally
- # stores the part of the directory that really exists in the
- # file system in the variable named by 'existing'.
- #
- proc Repository::expandDirName {dir {existing ""} {escape 0}} {
- set dir [Repository::expandFileName $dir $escape]
-
- if {$existing != ""} {
- upvar $existing existingPart
- set existingPart $dir
- while {![file exists $existingPart]} {
- set existingPart [file dir $existingPart]
- }
- }
-
- if $win95 {
- regsub -all {/} $dir {\\} dir
- }
-
- return $dir
- }
-
- proc Repository::defaultDumpFile {dumpDir} {
- set repDir [file dir $dumpDir]
- if $win95 {
- regsub -all {/} $repDir {\\} repDir
- }
- set name [file tail $dumpDir]
- return [path_name concat $repDir ${name}_backup]
- }
-
- proc Repository::showDumpInfo {dir} {
- $wmttoolObj startCommand mtool "dbdump -l [quoteIf $dir]" "" \
- "Getting info from dump directory '$dir' ..." {0 0} 1
- return 1
- }
-
- proc Repository::orbOptions {} {
- return {
- M4_brokerport
- M4_dblockmode
- M4_dbms
- M4_dbtracesql
- M4_heartbeat_interval
- M4_imphost
- M4_max_missed_heartbeats
- M4_nameserverhost
- M4_nameserverport
- M4_orb_linger
- M4_orb_maxclients
- M4_orb_maxinstances
- M4_orb_report
- M4_orb_timeout
- M4_parent_pid
- M4_parent_threshold
- M4_probe_control
- M4_probe_maxdelay
- M4_probe_timeout
- M4_protocol
- M4_services
- }
- }
-
- proc Repository::serverOptions {} {
- return {
- M4_dblockmode
- M4_dbtracesql
- M4_heartbeat_interval
- M4_lockfile_update
- M4_max_missed_heartbeats
- M4_orb_linger
- M4_orb_maxclients
- M4_orb_maxinstances
- M4_orb_report
- M4_orb_timeout
- M4_probe_maxdelay
- }
- }
-
- method Repository::msg {this type msg {options ""}} {
- set handler [$this messageHandler]
- if {$handler != ""} {
- eval $handler $type [list $msg] $options
- }
- }
-
- method Repository::message {this msg} {
- $this msg MESSAGE $msg
- }
-
- method Repository::warning {this warning} {
- $this msg WARNING $warning
- }
-
- method Repository::error {this error {options ""}} {
- $this msg ERROR $error $options
- }
-
-
- # Executes the given command line and returns an empty string
- # if it was successful, else it returns an error string.
- #
- method Repository::execute {this cmd} {
- set errFile [BasicFS::tmpFile]
- regsub -all {\\} "$cmd 2>$errFile" {\\\\} cmd
- if [catch {eval "exec $cmd"} execError] {
- set error [BasicFS::readFile $errFile]
- BasicFS::removeFile $errFile
-
- # Check if error occurred while starting command, or because
- # the command exited with status != 0.
- #
- if [string match "*child process exited abnormally*" $execError] {
- # Child exited with status != 0.
- # The reason for this has been read from stderr.
- #
- return $error
- }
-
- # Other exec error.
- #
- return "$execError:\n$error"
- }
-
- set error [BasicFS::readFile $errFile]
- BasicFS::removeFile $errFile
- if {$error != ""} {
- # If successful, no output should be found.
- #
- return $error
- }
-
- # Success.
- return ""
- }
-
-
- # Changes the ORB timeout to a short time, for calls
- # that should take little time.
- #
- method Repository::quickTimeOut {this {smallTimeOut 1000}} {
- # NOTE: does not consider host-context of variable.
- #
- if {[m4_var get M4_orb_timeout] != $smallTimeOut} {
- m4_var set M4_orb_timeout $smallTimeOut
- m4_var saveStatus M4_orb_timeout 0
- }
- }
-
-
- # Resets the ORB timeout to its original value.
- #
- method Repository::resetTimeOut {this} {
- m4_var set M4_orb_timeout [$this orbTimeOut]
- m4_var saveStatus M4_orb_timeout 0
- }
-
-
- # Returns a list with all available repository names.
- #
- method Repository::getAvailableRepositories {this} {
- set names {}
- foreach entry [[ORB::nameServer] serverDefinitions] {
- set id [lindex $entry 2]
- if {$id > 100 && $id < 1000} {
- lappend names [lindex $entry 0]
- }
- }
- return $names
- }
-
-
- # Changes the selected repository to the one with the new name.
- # Use currentCorporate or checkCorporate to find out if the repository
- # could be accessed.
- #
- method Repository::setCurrent {this newName} {
- if {[$this currentName] != ""} {
- set dbserver [$this currentDbServer]
- if ![$dbserver isNil] {
- catch {$dbserver disconnect}
- }
- }
- $this currentName $newName
- [$this context] setLevelPath ""
- if {$newName != ""} {
- [$this context] setLevelPath /$newName
- $this lastRepDir [$this currentRepDir]
- }
-
- RepositoryDBMS::setCurrent [$this currentCorporate]
-
- return 1
- }
-
-
- # Returns the currently selected corporate object. If none
- # is selected or accessible, a nil object is returned.
- #
- method Repository::currentCorporate {this} {
- set name [$this currentName]
- set corp [[$this context] currentCorporate]
- if {$name == "" || [$corp isNil]} {
- return [ORB::nil]
- }
- return $corp
- }
-
-
- # Returns the currently selected corporate object. If none
- # is selected or accessible, an error is returned.
- #
- method Repository::checkCorporate {this} {
- set name [$this currentName]
- if {$name == ""} {
- return -code error "No current repository set."
- }
-
- set corp [[$this context] currentCorporate]
- if {$name == "" || [$corp isNil]} {
- return -code error "Cannot access repository \"$name\"."
- }
-
- return [$this currentCorporate]
- }
-
-
- # Returns the name of the user that owns
- # the currently selected repository.
- # This is determined by examining the
- # owner of the corporate directory.
- #
- method Repository::currentOwner {this} {
- set corp [$this checkCorporate]
- set dir [location [$corp location] [$corp name]]
-
- if [file exists $dir] {
- if ![catch {set owner [BasicFS::owner $dir]} error] {
- if {$owner == "everyone"} {
- set owner ""
- }
- return $owner
- } else {
- $this error $error
- }
- }
-
- return ""
- }
-
-
- # Returns the BrokerImplemServer object
- # that represent the dbserver that is servicing
- # the currently selected corporate. Returns
- # [ORB::nil] if no corporate is selected.
- #
- method Repository::currentDbServer {this} {
- set name [$this currentName]
- if {$name == ""} {
- return [ORB::nil]
- }
-
- set broker [ORB::broker]
- if [$broker isNil] {
- return [ORB::nil]
- }
-
- if ![$this getServerByName $name entry] {
- return [ORB::nil]
- }
-
- set implem [$broker findImplementation $entry(fullId)]
- if [$implem isNil] {
- return [ORB::nil]
- }
-
- foreach server [$implem servers] {
- set me [$server findClient [ORB::currentHost] [ORB::currentProcessId]]
- if ![$me isNil] {
- return $server
- }
- }
-
- return [ORB::nil]
- }
-
- method Repository::findDbServer {this serverId} {
- set broker [ORB::broker]
- if [$broker isNil] {
- return [ORB::nil]
- }
-
- set implem [$broker findImplementation $serverId]
- if [$implem isNil] {
- return [ORB::nil]
- }
-
- foreach server [$implem servers] {
- set me [$server findClient [ORB::currentHost] [ORB::currentProcessId]]
- if ![$me isNil] {
- return $server
- }
- }
-
- return [ORB::nil]
- }
-
- method Repository::currentRepDir {this} {
- set corp [$this checkCorporate]
- set repDir [location [$corp location] [$corp name]]
- if $win95 {
- regsub -all {/} $repDir {\\} repDir
- }
- return $repDir
- }
-
- method Repository::currentObjDir {this obj} {
- set corp [$this checkCorporate]
- set objDir [location [$corp location] [$corp name] \
- [$obj repositoryDirectory]]
- if $win95 {
- regsub -all {/} $objDir {\\} objDir
- }
- return $objDir
- }
-
- method Repository::shutdownDbServers {this name {shutdownRef ""} {delayedRef ""}} {
- if {$delayedRef != ""} {
- upvar $delayedRef delayedCount
- }
- if {$shutdownRef != ""} {
- upvar $shutdownRef shutdownCount
- }
-
- set ns [ORB::nameServer]
-
- if ![$this getServerByName $name serverDef] {
- $this error "Server definition of server '$name' not found."
- return 0
- }
-
- # Disconnect from current dbserver if shutting current.
- #
- if {[$this currentName] == $name} {
- set dbserver [$this currentDbServer]
- if ![$dbserver isNil] {
- catch {$dbserver disconnect}
- }
- }
-
- # Find all current dbservers and shut them down.
- # If any servers are still running, abort name/dir change.
- #
- set delayedCount 0
- set shutdownCount 0
- foreach broker [$ns brokers] {
- set implem [$broker findImplementation $serverDef(fullId)]
- if [$implem isNil] {
- continue
- }
-
- # TODO: tell implementation to shutdown, meaning that it won't
- # start any new servers, because busy clients will try to
- # restart a dbserver.
- # $implem shutdown
-
- foreach server [$implem servers] {
- if [catch {$server shutdown} error] {
- # Server could not be disconnected.
- #
- incr delayedCount
- $this error $error
- } else {
- incr shutdownCount
- }
- }
- }
- if {$delayedCount > 0} {
- if {$delayedCount == 1} {
- set s "is still 1 server"
- } else {
- set s "are still $delayedCount servers"
- }
-
- $this error "There $s of implementation '$name' running.\nQuit all\
- clients and wait for all servers to exit, then retry.\n" -add
-
- return 0
- }
-
- if {$shutdownCount == 0} {
- $this message "No servers of implementation '$name' were found."
- } else {
- if {$shutdownCount == 1} {
- set servers "The only server"
- set have "has"
- } else {
- set servers "All $shutdownCount servers"
- set have "have"
- }
- $this message "$servers of implementation '$name' $have been shutdown."
- }
-
- return 1
- }
-
-
- # Returns the set of active clients. This
- # set contains all clients that are currently
- # connected to an OT server, be it a
- # dbserver or lockserver.
- #
- method Repository::getActiveClients {this clientMapRef} {
- upvar $clientMapRef clientMap
-
- # Build active client map to improve search perforance.
- #
- set ns [ORB::nameServer]
- foreach broker [$ns brokers] {
- if [catch {set implems [$broker implementations]} error] {
- # Skip this broker, but let user know something is wrong
- # with it.
- #
- lappend brokerErrors $error
- continue
- }
- foreach client [query -s servers.clients $implems] {
- set clientKey "[$client host],[$client pid]"
- set clientMap($clientKey) $client
- }
- }
-
- if [info exists brokerErrors] {
- $this warning "Could not consider clients of servers of not-responding\
- broker(s) due to errors:\n\n[join $brokerErrors "\n\n"]"
- }
-
- if ![info exists clientMap] {
- return 0
- }
- return [array size clientMap]
- }
-
- method Repository::getServerById {this implemId serverRef} {
- upvar $serverRef serverDef
-
- set entry [[ORB::nameServer] findServerDefinition $implemId]
- if [lempty $entry] {
- return 0
- }
-
- set serverDef(name) [lindex $entry 0]
- set serverDef(fullId) [lindex $entry 1]
- set serverDef(id) [lindex $entry 2]
- set serverDef(version) [lindex $entry 3]
- set serverDef(policy) [lindex $entry 4]
- set serverDef(protocol) [lindex $entry 5]
- set serverDef(executable) [lindex $entry 6]
- set serverDef(cmdline) [lindex $entry 7]
- set serverDef(host) [lindex $entry 8]
-
- return 1
- }
-
- method Repository::getServerByObject {this objectId serverRef} {
- upvar $serverRef serverDef
-
- set decoded [ORB::decodeObjectId $objectId]
- set implemId [ORB::makeImplemId [lindex $decoded 1] [lindex $decoded 2]]
-
- return [$this getServerById $implemId serverDef]
- }
-
- method Repository::getServerByName {this implemName serverRef} {
- upvar $serverRef serverDef
-
- foreach entry [[ORB::nameServer] serverDefinitions] {
- set name [lindex $entry 0]
- if {$name == $implemName} {
- return [$this getServerById [lindex $entry 1] serverDef]
- }
- }
-
- return 0
- }
-
- method Repository::changeServerDefinition {this id version name policy protocol executable cmdline host} {
- set ns [ORB::nameServer]
- $ns changeServerDefinition \
- $id $version $name $policy $protocol $executable $cmdline $host
- return 0
- }
-
- method Repository::removeServerDefinition {this implemId} {
- set ns [ORB::nameServer]
- $ns removeServerDefinition $implemId
- return 0
- }
-
-
- # Retrieves Corporate object information from the named database.
- # Returns a list with four elements: corporate object id, corporate name,
- # product release string and corporate directory. Uses the dbserver
- # to retrieve the info, therefore only available on Unix and NT.
- #
- method Repository::getInfoFromDatabase {this cmdInfoRef dbName dbInfoRef} {
- upvar $cmdInfoRef cmdInfo
- upvar $dbInfoRef dbInfo
-
- set result [$this runDbScript cmdInfo $dbName dbcorpinfo.tcl]
- if {[lindex $result 0] != "OK"} {
- $this error "Could not retrieve Repository info from database\
- '$dbName':\n[lindex $result 1]" -add
- return 0
- }
-
- set info [lindex $result 1]
-
- set dbInfo(id) [lindex $info 0]
- set dbInfo(name) [lindex $info 1]
- set dbInfo(productRelease) [lindex $info 2]
- set dbInfo(location) [lindex $info 3]
-
- return 1
- }
-
-
- # Retrieves database info from a given
- # dbserver command line as found in the object
- # servers file. The given variable name is used
- # as an associative Tcl variable where its
- # members are the following (if the repository
- # RDBMS supports them): dbname, dbdir, dbuser,
- # dbpassword, dbcryptedpassword, dbhost
- # and dbserver.
- #
- method Repository::getInfoFromCmdLine {this implemId cmdLine cmdInfoRef} {
- upvar $cmdInfoRef cmdInfo
-
- set dbServer 0
- if {$implemId > 100 && $implemId < 1000} {
- set dbServer 1
- }
-
- set tool [lindex $cmdLine 0]
- set argv [lrange $cmdLine 1 end]
- set options(-M4) {m4options noarg {} "M4 options"}
-
- if $dbServer {
- if [RepositoryDBMS::hasDirectory] {
- set options(-d) {dir arg "" "database directory"}
- }
- if [RepositoryDBMS::hasUser] {
- set options(-u) {user arg "" "database user"}
- }
- if [RepositoryDBMS::hasPassword] {
- set options(-p) {cryptedPassword arg "" "crypted password"}
- set options(-P) {plainPassword arg "" "plain password"}
- }
- if [RepositoryDBMS::hasHost] {
- set options(-h) {host arg "" "database host"}
- }
- if [RepositoryDBMS::hasServer] {
- set options(-s) {server arg "" "database server"}
- }
-
- if [catch {Options::parse $tool options argv name} error] {
- $this error "Error parsing command line of server entry:\n\n$error."
- return 0
- }
-
- set cmdInfo(m4options) $m4options
- set cmdInfo(dbname) $name
- set cmdInfo(dbdir) ""
- set cmdInfo(dbuser) ""
- set cmdInfo(dbpassword) ""
- set cmdInfo(dbcryptedpassword) ""
- set cmdInfo(dbhost) ""
- set cmdInfo(dbserver) ""
-
- if [RepositoryDBMS::hasDirectory] {
- set cmdInfo(dbdir) $dir
- }
- if [RepositoryDBMS::hasUser] {
- set cmdInfo(dbuser) $user
- }
- if [RepositoryDBMS::hasPassword] {
- if {$cryptedPassword != ""} {
- set cmdInfo(dbcryptedpassword) $cryptedPassword
- } elseif {$plainPassword != ""} {
- set cmdInfo(dbpassword) $plainPassword
- set cmdInfo(dbcryptedpassword) [ORB::cryptPassword \
- $plainPassword]
- }
- }
- if [RepositoryDBMS::hasHost] {
- set cmdInfo(dbhost) $host
- }
- if [RepositoryDBMS::hasServer] {
- set cmdInfo(dbserver) $server
- }
- } else {
- if [catch {Options::parse $tool options argv} error] {
- $this error "Error parsing command line of server entry:\n\n$error."
- return 0
- }
-
- set cmdInfo(m4options) $m4options
- }
-
- return 1
- }
-
- method Repository::getInfoFromCorporate {this cmdInfoRef} {
- upvar $cmdInfoRef cmdInfo
-
- set corp [$this checkCorporate]
-
- set cmdInfo(dbname) [$corp databaseName]
- set cmdInfo(m4options) {}
- set cmdInfo(dbdir) ""
- set cmdInfo(dbuser) ""
- set cmdInfo(dbpassword) ""
- set cmdInfo(dbcryptedpassword) ""
- set cmdInfo(dbhost) ""
- set cmdInfo(dbserver) ""
-
- if [RepositoryDBMS::hasDirectory] {
- set cmdInfo(dbdir) [$corp databaseDirectory]
- }
- if [RepositoryDBMS::hasUser] {
- set cmdInfo(dbuser) [$corp databaseUser]
- }
- if [RepositoryDBMS::hasPassword] {
- set cmdInfo(dbcryptedpassword) [$corp databasePassword]
- }
- if [RepositoryDBMS::hasHost] {
- set cmdInfo(dbhost) [$corp databaseHost]
- }
- if [RepositoryDBMS::hasServer] {
- set cmdInfo(dbserver) [$corp databaseServer]
- }
-
- return 1
- }
-
- method Repository::makeOptions {this cmdInfoRef} {
- upvar $cmdInfoRef cmdInfo
- set options ""
-
- if [info exists cmdInfo(m4options)] {
- foreach m4option $cmdInfo(m4options) {
- set list [split $m4option "="]
- if {[llength $list] == 1} {
- set option +$m4option
- } else {
- set name [lindex $list 0]
- set value [join [lrange $list 1 end] =]
- if {$value == 0} {
- set option -${name}
- } elseif {$value == 1} {
- set option +${name}
- } else {
- set option -${name}=${value}
- }
- }
- append options " [quoteIf $option]"
- }
- }
-
- return $options
- }
-
- method Repository::makeDbOptions {this cmdInfoRef {plainPassword ""}} {
- upvar $cmdInfoRef cmdInfo
- set options ""
-
- if [RepositoryDBMS::hasUser] {
- if [string length $cmdInfo(dbuser)] {
- append options " -u [quoteIf $cmdInfo(dbuser)]"
- }
- }
- if [RepositoryDBMS::hasPassword] {
- if [string length $plainPassword] {
- append options " -P [quoteIf $plainPassword]"
- } elseif [string length $cmdInfo(dbcryptedpassword)] {
- append options " -p [quoteIf $cmdInfo(dbcryptedpassword)]"
- } elseif [string length $cmdInfo(dbpassword)] {
- append options " -P [quoteIf $cmdInfo(dbpassword)]"
- }
- }
- if [RepositoryDBMS::hasDirectory] {
- if [string length $cmdInfo(dbdir)] {
- append options " -d [quoteIf $cmdInfo(dbdir)]"
- }
- }
- if [RepositoryDBMS::hasServer] {
- if [string length $cmdInfo(dbserver)] {
- append options " -s [quoteIf $cmdInfo(dbserver)]"
- }
- }
- if [RepositoryDBMS::hasHost] {
- if [string length $cmdInfo(dbhost)] {
- append options " -h [quoteIf $cmdInfo(dbhost)]"
- }
- }
-
- set m4options [$this makeOptions cmdInfo]
- if ![lempty $m4options] {
- append options " $m4options"
- }
-
- return $options
- }
-
- method Repository::makeCmdLine {this tool cmdInfoRef} {
- upvar $cmdInfoRef cmdInfo
-
- if [info exists cmdInfo(dbname)] {
- return "$tool[$this makeDbOptions cmdInfo] $cmdInfo(dbname)"
- } else {
- return "$tool[$this makeOptions cmdInfo]"
- }
- }
-
-
- # Creates the command line for a database tool,
- # based on the contents of the assiociative Tcl
- # variable given. The same members as returned
- # by getInfoFromCmdLine must be specified.
- #
- method Repository::makeDbCmdLine {this tool cmdInfoRef} {
- upvar $cmdInfoRef cmdInfo
- return "$tool[$this makeDbOptions cmdInfo] $cmdInfo(dbname)"
- }
-
- method Repository::makeDbToolCmd {this tool cmdInfoRef usePlainPassword argv} {
- upvar $cmdInfoRef cmdInfo
-
- if {[catch {set toolPath [m4_path_name bin $tool$EXE_EXT]}] ||
- ![file exists $toolPath]} {
- $this error "No '$tool' available."
- return {}
- }
-
- # Always require an uncrypted password to be specified (or none).
- #
- if [RepositoryDBMS::hasPassword] {
- if {$usePlainPassword} {
- set cmdInfo(dbcryptedpassword) ""
- } else {
- if [string length $cmdInfo(dbpassword)] {
- set crypted [ORB::cryptPassword $cmdInfo(dbpassword)]
- set cmdInfo(dbcryptedpassword) $crypted
- set cmdInfo(dbpassword) ""
- }
- }
- }
-
- set dbOptions [$this makeDbOptions cmdInfo]
- set cmd "[quoteIf $toolPath] $dbOptions $argv"
-
- # Only need an xtool if the plain password was not specified and the
- # used DBMS needs one, since then the db tool will ask for it.
- #
- set type "mtool"
-
- if [RepositoryDBMS::hasPassword] {
- if {$cmdInfo(dbpassword) == "" && $cmdInfo(dbcryptedpassword) == ""} {
- set type "xtool"
- }
- }
-
- return [list $type $cmd]
- }
-
- method Repository::runDbScript {this cmdInfoRef database script {argv {}}} {
- upvar $cmdInfoRef cmdInfo
-
- # Need uncrypted password if executing a script via -f.
- #
- if {[RepositoryDBMS::hasPassword] && $cmdInfo(dbpassword) == ""} {
- return [list ERROR "No password specified."]
- }
- set cmdInfo(dbcryptedpassword) ""
-
- set script [quoteIf [m4_path_name tcl $script]]
- if {$database == "-"} {
- # Prepend -- to signify end-of-options.
- set database "-- -"
- }
-
- set tmpFile [BasicFS::tmpFile]
- set cmd [lindex [$this makeDbToolCmd dbserver cmdInfo 1 \
- [concat -f $script $database $tmpFile $argv]] 1]
- if {$cmd == ""} {
- BasicFS::removeFile $tmpFile
- return [list ERROR "Error in command line."]
- }
-
- set error [$this execute $cmd]
- if {$error != ""} {
- BasicFS::removeFile $tmpFile
- return [list ERROR $error]
- }
-
- # Parse tmpFile contents: first line is OK or ERROR, further lines
- # contain result or error message(s).
- #
- set f [BasicFS::readFile $tmpFile]
- BasicFS::removeFile $tmpFile
-
- set lines [split $f "\n"]
- if {[lindex $lines 0] == "ERROR"} {
- return [list "ERROR" [join [lrange $lines 1 end] "\n"]]
- }
-
- return [list "OK" [lindex $lines 1]]
- }
-
- method Repository::startDbTool {this tool endScript msg cmdInfoRef argv} {
- upvar $cmdInfoRef cmdInfo
-
- set cmdList [$this makeDbToolCmd $tool cmdInfo 0 $argv]
- set type [lindex $cmdList 0]
- set cmd [lindex $cmdList 1]
-
- if [lempty $cmdList] {
- return 0
- }
-
- $this toolFinishedScript $endScript
- $wmttoolObj startCommand $type $cmd "$this toolFinished" $msg {0 0} 1
- return 1
- }
-
- method Repository::toolFinished {this} {
- set exitCode 0
- foreach exitCode [$wmttoolObj exitStatusList] {
- # Get last status.
- }
- if {$exitCode == ""} {
- set exitCode 0
- }
-
- set endScript [$this toolFinishedScript]
- if {$endScript != ""} {
- if [catch {eval "$endScript $exitCode"} error] {
- $this error $error
- }
- }
- }
-
- proc Repository::goodRepositoryName {name {errorRef ""}} {
- if {$errorRef != ""} {
- upvar $errorRef error
- }
-
- # Detect invalid characters.
- #
- if ![regexp {^[-_a-zA-Z0-9][-_a-zA-Z0-9]*$} $name] {
- set error "Repository name '$name' contains invalid character."
- return 0
- }
-
- # Detect name length overflow.
- #
- if {[string length $name] >= 80} {
- set error "Repository name '$name' is too long.\nAt most 80\
- characters are allowed."
- return 0
- }
-
- return 1
- }
-
- method Repository::checkRepositoryName {this name} {
- if ![Repository::goodRepositoryName $name error] {
- $this error $error -add
- return 0
- }
- return 1
- }
-
- method Repository::createRepository {this endScript cmdInfoRef name dir} {
- upvar $cmdInfoRef cmdInfo
- return [$this startDbTool "dbserver" $endScript \
- "Creating new repository '$name'..." cmdInfo \
- [concat [list -c $name $cmdInfo(dbname)] [quoteIf $dir]]]
- }
-
- method Repository::changeRepository {this cmdInfoRef name dir newName newDir moveDir} {
- upvar $cmdInfoRef cmdInfo
-
- set ns [ORB::nameServer]
-
- if ![$this getServerByName $name serverDef] {
- $this error "Server definition of server '$name' not found."
- return 0
- }
-
- if {$newName != ""} {
- # Strip all spaces: leading, trailing, interior.
- #
- set newName [rmWhiteSpace $newName]
- if ![$this checkRepositoryName $newName] {
- return 0
- }
- }
-
- # Script executed on error to undo previously succeeded actions.
- #
- set undoScript ""
-
- if {$newName == "" && $newDir == ""} {
- $this warning "Nothing to change."
- return 0
- }
-
- if {$newName != "" || $newDir != ""} {
- set argv {}
-
- if {$newName != ""} {
- lappend argv c_name=${newName}
-
- # Change server entry.
- #
- if [catch {$this changeServerDefinition \
- $serverDef(id) \
- $serverDef(version) \
- $newName \
- $serverDef(policy) \
- $serverDef(protocol) \
- $serverDef(executable) \
- $serverDef(cmdline) \
- $serverDef(host)} error] {
- $this error "Failed to change server definition of server\
- '$name':\n\n$error"
- return 0
- }
-
- set undoScript "
- if \[catch {$this changeServerDefinition \
- $serverDef(id) \
- $serverDef(version) \
- [list $serverDef(name)] \
- [list $serverDef(policy)] \
- [list $serverDef(protocol)] \
- [list $serverDef(executable)] \
- [list $serverDef(cmdline)] \
- [list $serverDef(host)]} error] {
- $this error $error
- }
- $undoScript
- "
- }
-
- if {$newDir != ""} {
- lappend argv c_directory=${newDir}
- }
-
- set r [$this runDbScript cmdInfo $cmdInfo(dbname) dbcorpch.tcl $argv]
- if {[lindex $r 0] != "OK"} {
- $this error [lindex $r 1]
- eval $undoScript
- return 0
- }
-
- set undoScript "
- set argv \[list c_name=${name} c_directory=${dir}]
- set r \[$this runDbScript cmdInfo \
- $cmdInfo(dbname) dbcorpch.tcl \$argv]
- if {\[lindex \$r 0] != \"OK\"} {
- $this error \[lindex \$r 1]
- }
- $undoScript
- "
- }
-
- if $moveDir {
- if {$newName != ""} {
- # Move repository directory within old parent directory,
- # or move it into the new parent directory.
- # '$dstDir' is assumed to exist.
- #
- if {$newDir == ""} {
- set dstDir $dir
- } else {
- set dstDir $newDir
- }
-
- set orgRepDir [location $dir $name]
- set newRepDir [location $dstDir $newName]
-
- if [catch {BasicFS::renameDir $orgRepDir $newRepDir} error] {
- $this error "Could not move repository directory:\n\n$error"
- eval $undoScript
- return 0
- }
- } elseif {$newDir != ""} {
- # Move repository directory from old into new parent directory.
- #
- set orgRepDir [location $dir $name]
- set newRepDir [location $newDir $name]
-
- if [catch {BasicFS::renameDir $orgRepDir $newRepDir} error] {
- $this error "Could not move repository directory:\n\n$error"
- eval $undoScript
- return 0
- }
- }
- }
-
- return 1
- }
-
- method Repository::fixRepositoryDir {this cmdInfoRef dir name nameInDb} {
- upvar $cmdInfoRef cmdInfo
-
- # Try to make directory in database correspond with
- # directory in file system.
- #
- set repDir [location $dir $name]
- set repDirInDb [location $dir $nameInDb]
- if {$repDir == $repDirInDb} {
- $this warning "Repository directory '$repDir'\
- corresponds with repository database."
- return 1
- }
-
- # Update database to have the correct name and directory.
- #
- if {$name != $nameInDb} {
- set argv c_name=${name}
- set r [$this runDbScript cmdInfo $cmdInfo(dbname) dbcorpch.tcl $argv]
- if {[lindex $r 0] != "OK"} {
- $this error [lindex $r 1]
- return 0
- }
- }
-
- set repDirExists [file exists $repDir]
- set repDirInDbExists [file exists $repDirInDb]
-
- if {!$repDirExists && $repDirInDbExists} {
- # Move directory to correspond with database.
- #
- if [catch {BasicFS::renameDir $repDirInDb $repDir} error] {
- $this error $error
- return 0
- }
- } elseif {!$repDirExists && !$repDirInDbExists} {
- $this error "Neither one of repository directory \
- '$repDir' not '$repDirInDb' exists."
- return 0
- } elseif {$repDirExists && $repDirInDbExists} {
- $this error "Both of repository directory \
- '$repDir' and '$repDirInDb' exists. Cannot choose."
- return 0
- }
-
- return 1
- }
-
-
- # Deletes the current repository.
- # Database, directory and server entry are all deleted.
- #
- method Repository::deleteRepository {this} {
- $this getInfoFromCorporate cmdInfo
- $this deleteRepositoryDb cmdInfo
- $this deleteRepositoryDir
- $this deleteServerEntry
-
- return 1
- }
-
- method Repository::deleteRepositoryDir {this} {
- set corp [$this checkCorporate]
- set location [location [$corp location] [$corp name]]
- if $win95 {
- regsub -all {/} $location {\\} location
- }
-
- if [catch {BasicFS::removeDirAll $location} error] {
- $this error $error
- return 0
- }
- return 1
- }
-
- method Repository::deleteRepositoryDb {this cmdInfoRef} {
- upvar $cmdInfoRef cmdInfo
-
- set database $cmdInfo(dbname)
-
- set result [$this runDbScript cmdInfo - dbcorpdrop.tcl $database]
- if {[lindex $result 0] != "OK"} {
- $this error [lindex $result 1] -add
- return 0
- }
-
- return 1
- }
-
- method Repository::deleteServerEntry {this} {
- set name [$this currentName]
-
- if [$this getServerByName $name serverDef] {
- set ns [ORB::nameServer]
- if [catch {$this removeServerDefinition $serverDef(fullId)} error] {
- $this error $error
- return 0
- }
- } else {
- $this error "Server entry of repository '$name' not found."
- return 0
- }
- return 1
- }
-
- method Repository::optimizeRepository {this endScript cmdInfoRef options name objects} {
- upvar $cmdInfoRef cmdInfo
-
- if ![lempty objects] {
- if {[lsearch $options -m] == -1} {
- set msg "model(s) '[join $objects "' '"]'"
- } else {
- set msg "projects(s) '[join $objects "' '"]'"
- }
- } else {
- set msg "repository '$name'"
- }
-
- return [$this startDbTool "dboptimize" $endScript \
- "Optimizing $msg ..." cmdInfo \
- [concat $options $cmdInfo(dbname) $objects]]
- }
-
- method Repository::dumpRepository {this endScript cmdInfoRef options name} {
- upvar $cmdInfoRef cmdInfo
-
- set msg "Dumping repository '$name' ..."
- return [$this startDbTool "dbdump" $endScript $msg cmdInfo \
- [concat $options $cmdInfo(dbname)]]
- }
-
- method Repository::dumpObject {this endScript cmdInfoRef options type object} {
- upvar $cmdInfoRef cmdInfo
-
- set msg "Dumping $type '$object' ..."
- if {$type == "model"} {
- append options " -m"
- }
-
- return [$this startDbTool "dbdump" $endScript $msg cmdInfo \
- [concat $options $cmdInfo(dbname) $object]]
- }
-
- method Repository::restoreRepository {this endScript cmdInfoRef options repDir {newName ""}} {
- upvar $cmdInfoRef cmdInfo
-
- set name [file tail $repDir]
- if {$newName == ""} {
- set newMsg ""
- } else {
- set newMsg "under new name '$newName' "
- set newDir [location [file dir $repDir] $newName]
- if $win95 {
- regsub -all {/} $newDir {\\} newDir
- }
-
- $this message "Moving '$repDir' to '$newDir' ..."
- BasicFS::renameDir $repDir $newDir
-
- set repDir $newDir
- }
-
- set msg "Restoring repository '$name' ${newMsg}..."
-
- return [$this startDbTool "dbdump" $endScript $msg cmdInfo \
- [concat -r $options $cmdInfo(dbname) $repDir]]
- }
-
- method Repository::restoreObject {this endScript cmdInfoRef options type objDir {newName ""}} {
- upvar $cmdInfoRef cmdInfo
-
- if {$newName == ""} {
- set newMsg ""
- } else {
- set newMsg "as '$newName' "
- }
-
- set msg "Restoring $type ${newMsg}..."
-
- if {$type == "model"} {
- append options " -m"
- }
-
- return [$this startDbTool "dbdump" $endScript $msg cmdInfo \
- [concat -x $options $cmdInfo(dbname) $objDir $newName]]
- }
-
- method Repository::expandArchiveCommand {this cmd repDir repName objName objDir objType file type} {
- # Check to see if cmd exists in $M4_home/bin using m4_path_name.
- # This will also find it if it's in a bin directory added by a module.
- #
- protect_backslashes {cmd tool} {
- set tool [lindex $cmd 0]
- set toolEnd [string length [quoteIf $tool]]
- incr toolEnd
- catch {set tool [m4_path_name bin $tool]}
- set cmd "[quoteIf $tool] [string range $cmd $toolEnd end]"
- }
-
- # Parent of repository directory. Not quoted since user may want to add
- # something to this string.
- regsub -all %P $cmd $repDir cmd
-
- # Name of repository. Not quoted since user may want to use this
- # string to build another string.
- regsub -all %N $cmd $repName cmd
-
- # Repository subdirectory.
- regsub -all %R $cmd $repName cmd
-
- # Name of the project or model. Not quoted since user may want to use
- # this string to build another string.
- regsub -all %O $cmd $objName cmd
-
- # Name of the project or model subdirectory. Not quoted since user
- # may want to use this string to build another string.
- regsub -all %S $cmd [file tail $objDir] cmd
-
- # Full path to dump file.
- regsub -all %F $cmd [quoteIf $file] cmd
-
- # Directory part of dump file path.
- regsub -all %D $cmd [file dirname $file] cmd
-
- # File name part of dump file path.
- regsub -all %T $cmd [file tail $file] cmd
-
- # Type of command: "archive" or "unarchive"
- regsub -all %W $cmd $type cmd
-
- return $cmd
- }
-
- method Repository::archiveRepositoryDirectory {this endScript dstFile repName repDir} {
- set msg "Archiving repository directory '$repDir' ..."
- set dir [file dir $repDir]
- set cmd [$this expandArchiveCommand \
- [m4_var get M4_archive_cmd -context corporate] \
- $repDir $repName "" "" "" $dstFile "archive"]
-
- $this toolFinishedScript $endScript
- $wmttoolObj startCommand "mtool" $cmd "$this toolFinished" \
- $msg {0 0} 1 [list $dir]
- return 1
- }
-
- method Repository::unarchiveRepositoryDirectory {this endScript srcFile repParentDir} {
- set msg "Unarchiving into repository directory '$repParentDir' ..."
- set dir $repParentDir
- set cmd [$this expandArchiveCommand \
- [m4_var get M4_unarchive_cmd -context corporate] \
- $repParentDir "" "" "" "" $srcFile "unarchive"]
-
- $this toolFinishedScript $endScript
- $wmttoolObj startCommand "mtool" $cmd "$this toolFinished" \
- $msg {0 0} 1 [list $dir]
- return 1
- }
-
- method Repository::archiveObjectDirectory {this endScript dstFile repName repDir objDir objType} {
-
- set msg "Archiving $objType directory '$objDir' ..."
- set dir $repDir
- set cmd [$this expandArchiveCommand \
- [m4_var get M4_archive_cmd -context [string tolower $objType]] \
- $repDir $repName "" $objDir $objType $dstFile "archive"]
-
- $this toolFinishedScript $endScript
- $wmttoolObj startCommand "mtool" $cmd "$this toolFinished" \
- $msg {0 0} 1 [list $dir]
- return 1
- }
-
- method Repository::unarchiveObjectDirectory {this endScript srcFile repName repDir objType} {
-
- set msg "Unarchiving $objType directory into '$repDir' ..."
- set dir $repDir
- set cmd [$this expandArchiveCommand \
- [m4_var get M4_unarchive_cmd -context [string tolower $objType]] \
- $repDir [file tail $repDir] "" "" $objType $srcFile "unarchive"]
-
- $this toolFinishedScript $endScript
- $wmttoolObj startCommand "mtool" $cmd "$this toolFinished" \
- $msg {0 0} 1 [list $dir]
- return 1
- }
-
-
- # Retrieves a list of pairs each containing an ExternalFileVersion and
- # a ConfigVersion in which that file exists. Only those external files are
- # returned for which a file in the client's file system exists.
- # The list of returned files can be restricted by specifying a Project
- # or ConfigVersion. By default, the entire current corporate
- # is searched for external file versions.
- #
- # This action may take a while.
- #
- # Options:
- # -clear: clears the cached list of external file versions; always returns
- # empty list
- # -dirs: only returns objects that represent a directory in the client's
- # files system (i.e. Corporate, Project, ConfigVersion,
- # PhaseVersion or SystemVersion); the returned list now contains
- # pairs with an object (Corporate, Project, ConfigVersion,
- # PhaseVersion or SystemVersion) and a ConfigVersion (if object
- # is not a Project, ConfigVersion or PhaseVersion)
- # -proj: restricts search to the given Project object
- # -conf: restricts search to the given ConfigVersion object
- #
- method Repository::getExternalFileVersions {this args} {
- set corp [$this checkCorporate]
-
- set opts(-dirs) { dirs }
- set opts(-clear) { clear }
- set opts(-proj) " proj arg [ORB::nil] "
- set opts(-conf) " conf arg [ORB::nil] "
- Options::parse getExternalFileVersions opts args
-
- if ![$conf isNil] {
- set proj [$conf project]
- }
-
- if {$clear || ($corp != [$this extCorp] ||
- $proj != [$this extProj] ||
- $conf != [$this extConf])} {
- $this extFilesLoaded 0
- if $clear {
- return {}
- }
- }
-
- $this extCorp $corp
- $this extProj $proj
- $this extConf $conf
-
- if ![$this extFilesLoaded] {
- [$this extFiles] contents {}
-
- if [$conf isNil] {
- if [$proj isNil] {
- set configVersions [query $corp.projects.configVersions]
- } else {
- set configVersions [query $proj.configVersions]
- }
- } else {
- set configVersions [list $conf]
- }
-
- foreach configV $configVersions {
- foreach f [query "file.isExternal == 1" \
- $configV.phaseVersions.systemVersions.localFileVersions] {
-
- [$this extFiles] append [list $f $configV]
- }
- }
-
- $this extFilesLoaded 1
- }
-
- if $dirs {
- [$this extFiles] foreach pair {
- set f [lindex $pair 0]
- set c [lindex $pair 1]
-
- # insert parent objects from corporate to configV
- set dirMap([$f corporate]) [ORB::nil]
- set dirMap([$f project]) [ORB::nil]
- set dirMap($c) [ORB::nil]
-
- # insert phaseV and systemV objects
- set p [$c findPhaseVersion -byPhase [$f phase]]
- set s [$p findSystemVersion -bySystem [$f system]]
- set dirMap($p) $c
- set dirMap($s) $c
- }
- set extDirs {}
- if [info exists dirMap] {
- foreach dir [lsort [flatten [array names dirMap]]] {
- lappend extDirs [list $dir $dirMap($dir)]
- }
- }
- return $extDirs
- }
- return [[$this extFiles] contents]
- }
-
-
- # Retrieves the lockserver object (LockAdmin).
- # If the lockserver is not running, [ORB::nil] is
- # returned unless startIfNotRunning is true, in which
- # case the lockserver is started.
- #
- method Repository::getLockServer {this {startIfNotRunning 1}} {
- if [$this useLockServerId] {
- set lm [ORB::lockManager -nocheck]
- } elseif {[catch {set lm [ORB::lockManager]; $lm isNil} error]} {
- $this useLockServerId 1
- set lm [ORB::lockManager -nocheck]
- }
-
- if {[$lm isNil] && $startIfNotRunning} {
- # Lockserver is not running, cause it to startup.
- #
- $this message "Starting lockserver..."
-
- set lm [ORB::lockManager -nocheck]
- if [catch {$lm pid} startupError] {
- $this warning "Could not start lockserver:\n\n$startupError."
- } else {
- $this message "Lockserver started."
- }
- }
- return $lm
- }
-
-
- # Returns all locks described by the description. If onlyHanging is 1, only
- # the hanging locks in the set are returned.
- #
- method Repository::getLocks {this desc {onlyHangingLocks 0}} {
- set ls [$this getLockServer]
- if [$ls isNil] {
- $this warning "Lockserver is not running."
- return NO_LOCKSERVER
- }
-
- # For now, do pattern matching on reason here, instead of in lockserver.
- #
- set matchReason 0
- if {[lsearch [$desc what] "Reason"] != -1} {
- set reason [$desc reason]
- if {[string first "*" $reason] != -1 ||
- [string first "?" $reason] != -1} {
- set matchReason 1
- $desc setReason "*"
- }
- }
-
- if [catch {set locks [$ls findLocks $desc]} error] {
- $this error $error
- return NO_LOCKSERVER
- }
-
- if $matchReason {
- set matched {}
- foreach lock $locks {
- if [string match $reason [$lock reason]] {
- lappend matched $lock
- }
- }
- set locks $matched
- }
-
- if $onlyHangingLocks {
- set hanging {}
- set desc [LockDescription new]
-
- $this getActiveClients clients
- foreach lock $locks {
- $desc clear
- if { [catch { $ls describeLock $lock $desc }] == 0 } {
- set clientKey "[$desc host],[$desc pid]"
- if ![info exists clients($clientKey)] {
- lappend hanging $lock
- }
- }
- }
- return $hanging
- }
- return $locks
- }
-
-
- # Returns 1 if the given lock is hanging, else 0.
- #
- method Repository::isHangingLock {this lockId} {
- if {[$this getActiveClients clients] == 0} {
- return 1
- }
-
- set desc [LockDescription new]
- set ls [$this getLockServer]
- if [catch {$ls describeLock $lockId $desc} error] {
- return 0
- }
-
- set clientKey "[$desc host],[$desc pid]"
- if [info exists clients($clientKey)] {
- # A client exists with host and pid of the lock,
- # so the lock is not hanging.
- #
- return 0
- }
-
- return 1
- }
-
-
- # Returns a textual description of the given lock.
- #
- method Repository::describeLock {this lockId} {
- set ls [$this getLockServer 0]
- if [$ls isNil] {
- $this warning "Lockserver is not running."
- return 0
- }
- set desc [LockDescription new]
-
- if [catch { $ls describeLock $lockId $desc }] {
- $this error "Lock has been removed already."
- return 0
- }
-
- set objectId [$desc object]
- set lockType [$desc types]
- set text $objectId
-
- set list [ORB::decodeObjectId $objectId]
- set serverId [lindex $list 1].[lindex $list 2]
- set isBadServer 0
- if {[[$this badServers] set $serverId] == "1"} {
- set isBadServer 1
- }
-
- if {!$isBadServer && [catch {
- if {$lockType == "Read" || $lockType == "Write"} {
- # NOTE: This takes a long time if lots of locks are present...
- #
- regexp {^([^:]*):} $objectId dummy className
- set obj [$className new $objectId]
-
- set isVersion [$obj isA Version]
- set isVersionable [$obj isA Versionable]
-
- if {$isVersion || $isVersionable} {
- if $isVersion {
- set versable [$obj object]
- set suffix "([$obj versionName])"
- } else {
- set versable $obj
- set suffix ""
- }
-
- if {[$versable isA Phase] ||
- [$versable isA System] ||
- [$versable isA File]} {
- set text "[$versable name].[$versable type]"
- } else {
- set text "[$versable name]"
- }
- if {$suffix != ""} {
- append text " $suffix"
- }
- }
- }
- }]} {
- # Remember that an error occurred while starting server,
- # so the next time we do not try to start a server again.
- #
- [$this badServers] set $serverId 1
-
- set text $objectId
- }
-
- set dbserver [$this findDbServer \
- [ORB::makeImplemId [lindex $list 1] [lindex $list 2]]]
- if ![$dbserver isNil] {
- catch {$dbserver disconnect}
- }
-
- return $text
- }
-
-
- # Sets a lock based on the given lock description.
- #
- method Repository::setLock {this desc} {
- set ls [$this getLockServer]
- if [$ls isNil] {
- $this error "Lockserver is not running."
- return 0
- }
-
- $ls setLock $desc
- return 1
- }
-
-
- # Removes a lock describes by the given
- # lock description.
- #
- method Repository::removeLock {this lockId {checkHanging 1}} {
- set ls [$this getLockServer 0]
- if [$ls isNil] {
- $this warning "Lockserver is not running."
- return 0
- }
- set desc [LockDescription new]
-
- if [catch { $ls describeLock $lockId $desc }] {
- $this error "Lock has been removed already."
- return 0
- }
-
- if {$checkHanging && ![$this isHangingLock $lockId]} {
- $this error "Lock $lockId is not hanging.\
- Owning process [$desc pid] of '[$desc user]'\
- is still running on host '[$desc host]',\
- or was terminated abnormally, possibly due to a system reboot."
- return 0
- }
-
- set descId [LockDescription new]
- $descId setId $lockId
- return [$ls removeLocks $descId]
- }
-
-
- # Upgrades the given read-locks to write-locks.
- #
- #
- method Repository::upgradeLocks {this lockIds reason} {
- set ls [$this getLockServer 0]
- if [$ls isNil] {
- $this warning "Lockserver is not running."
- return 0
- }
- return [$ls upgrade $lockIds $reason]
- }
-
- # Do not delete this line -- regeneration end marker
-
-