eb656de7d9 2007-10-05 aku: ## -*- tcl -*- eb656de7d9 2007-10-05 aku: # # ## ### ##### ######## ############# ##################### eb656de7d9 2007-10-05 aku: ## Copyright (c) 2007 Andreas Kupries. eb656de7d9 2007-10-05 aku: # eb656de7d9 2007-10-05 aku: # This software is licensed as described in the file LICENSE, which eb656de7d9 2007-10-05 aku: # you should have received as part of this distribution. eb656de7d9 2007-10-05 aku: # eb656de7d9 2007-10-05 aku: # This software consists of voluntary contributions made by many eb656de7d9 2007-10-05 aku: # individuals. For exact contribution history, see the revision eb656de7d9 2007-10-05 aku: # history and logs, available at http://fossil-scm.hwaci.com/fossil eb656de7d9 2007-10-05 aku: # # ## ### ##### ######## ############# ##################### eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: ## State manager. Maintains the sqlite database used by all the other eb656de7d9 2007-10-05 aku: ## parts of the system, especially the passes and their support code, eb656de7d9 2007-10-05 aku: ## to persist and restore their state across invokations. eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: # # ## ### ##### ######## ############# ##################### eb656de7d9 2007-10-05 aku: ## Requirements eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: package require Tcl 8.4 ; # Required runtime. eb656de7d9 2007-10-05 aku: package require snit ; # OO system. eb656de7d9 2007-10-05 aku: package require fileutil ; # File operations. eb656de7d9 2007-10-05 aku: package require sqlite3 ; # Database access. eb656de7d9 2007-10-05 aku: package require vc::tools::trouble ; # Error reporting. eb656de7d9 2007-10-05 aku: package require vc::tools::log ; # User feedback. eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: # # ## ### ##### ######## ############# ##################### eb656de7d9 2007-10-05 aku: ## eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: snit::type ::vc::fossil::import::cvs::state { eb656de7d9 2007-10-05 aku: # # ## ### ##### ######## ############# eb656de7d9 2007-10-05 aku: ## Public API eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: typemethod use {path} { eb656de7d9 2007-10-05 aku: # Immediate validation. There are are two possibilities to eb656de7d9 2007-10-05 aku: # consider. The path exists or it doesn't. eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: # In the first case it has to be a readable and writable file, eb656de7d9 2007-10-05 aku: # and it has to be a proper sqlite database. Further checks eb656de7d9 2007-10-05 aku: # regarding the required tables will be done later, by the eb656de7d9 2007-10-05 aku: # passes, during their setup. eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: # In the second case we have to be able to create the file, eb656de7d9 2007-10-05 aku: # and check that. This is done by opening it, sqlite will then eb656de7d9 2007-10-05 aku: # try to create it, and may fail. eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: if {[file exists $path]} { eb656de7d9 2007-10-05 aku: if {![fileutil::test $path frw msg {cvs2fossil state}]} { eb656de7d9 2007-10-05 aku: trouble fatal $msg eb656de7d9 2007-10-05 aku: return eb656de7d9 2007-10-05 aku: } eb656de7d9 2007-10-05 aku: } eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: if {[catch { eb656de7d9 2007-10-05 aku: sqlite3 ${type}::TEMP $path eb656de7d9 2007-10-05 aku: } res]} { eb656de7d9 2007-10-05 aku: trouble fatal $res eb656de7d9 2007-10-05 aku: return eb656de7d9 2007-10-05 aku: } eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: # A previously defined state database is closed before eb656de7d9 2007-10-05 aku: # committing to the new definition. We do not store the path eb656de7d9 2007-10-05 aku: # itself, this ensures that the file is _not_ cleaned up after eb656de7d9 2007-10-05 aku: # a run. eb656de7d9 2007-10-05 aku: fb1e36d290 2007-10-05 aku: set mystate ${type}::STATE fb1e36d290 2007-10-05 aku: set mypath {} fb1e36d290 2007-10-05 aku: fb1e36d290 2007-10-05 aku: catch { $mystate close } fb1e36d290 2007-10-05 aku: rename ${type}::TEMP $mystate fb1e36d290 2007-10-05 aku: fb1e36d290 2007-10-05 aku: log write 2 state "is $path" eb656de7d9 2007-10-05 aku: return eb656de7d9 2007-10-05 aku: } eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: typemethod setup {} { eb656de7d9 2007-10-05 aku: # If, and only if no state database was defined by the user eb656de7d9 2007-10-05 aku: # then it is now the time to create our own using a tempfile. eb656de7d9 2007-10-05 aku: fb1e36d290 2007-10-05 aku: if {$mystate ne ""} return eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: set mypath [fileutil::tempfile cvs2fossil_state_] fb1e36d290 2007-10-05 aku: set mystate ${type}::STATE fb1e36d290 2007-10-05 aku: sqlite3 $mystate $mypath eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: log write 2 state "using $mypath" eb656de7d9 2007-10-05 aku: return eb656de7d9 2007-10-05 aku: } eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: typemethod release {} { eb656de7d9 2007-10-05 aku: log write 2 state release eb656de7d9 2007-10-05 aku: ${type}::STATE close eb656de7d9 2007-10-05 aku: if {$mypath eq ""} return eb656de7d9 2007-10-05 aku: file delete $mypath eb656de7d9 2007-10-05 aku: return fb1e36d290 2007-10-05 aku: } fb1e36d290 2007-10-05 aku: fb1e36d290 2007-10-05 aku: typemethod writing {name definition} { fb1e36d290 2007-10-05 aku: # Method for a user to declare a table its needs for storing fb1e36d290 2007-10-05 aku: # persistent state, and the expected structure. A possibly fb1e36d290 2007-10-05 aku: # previously existing definition is dropped. fb1e36d290 2007-10-05 aku: fb1e36d290 2007-10-05 aku: $mystate transaction { fb1e36d290 2007-10-05 aku: catch { $mystate eval "DROP TABLE $name" } fb1e36d290 2007-10-05 aku: $mystate eval "CREATE TABLE $name ( $definition )" fb1e36d290 2007-10-05 aku: } fb1e36d290 2007-10-05 aku: return fb1e36d290 2007-10-05 aku: } fb1e36d290 2007-10-05 aku: fb1e36d290 2007-10-05 aku: typemethod reading {name} { fb1e36d290 2007-10-05 aku: # Method for a user to declare a table it wishes to read fb1e36d290 2007-10-05 aku: # from. A missing table is an internal error causing an fb1e36d290 2007-10-05 aku: # immediate exit. fb1e36d290 2007-10-05 aku: fb1e36d290 2007-10-05 aku: set found [llength [$mystate eval { fb1e36d290 2007-10-05 aku: SELECT name fb1e36d290 2007-10-05 aku: FROM sqlite_master fb1e36d290 2007-10-05 aku: WHERE type = 'table' fb1e36d290 2007-10-05 aku: AND name = $name fb1e36d290 2007-10-05 aku: ; fb1e36d290 2007-10-05 aku: }]] fb1e36d290 2007-10-05 aku: fb1e36d290 2007-10-05 aku: if {$found} return fb1e36d290 2007-10-05 aku: fb1e36d290 2007-10-05 aku: trouble internal "The required table \"$name\" is not defined." fb1e36d290 2007-10-05 aku: # Not reached fb1e36d290 2007-10-05 aku: return fb1e36d290 2007-10-05 aku: } fb1e36d290 2007-10-05 aku: fb1e36d290 2007-10-05 aku: typemethod run {args} { fb1e36d290 2007-10-05 aku: return [uplevel 1 [linsert $args 0 $mystate eval]] 042d54bae5 2007-10-05 aku: } 042d54bae5 2007-10-05 aku: 042d54bae5 2007-10-05 aku: typemethod transaction {script} { 042d54bae5 2007-10-05 aku: return [uplevel 1 [list $mystate transaction $script]] 042d54bae5 2007-10-05 aku: } 042d54bae5 2007-10-05 aku: 042d54bae5 2007-10-05 aku: typemethod id {} { 042d54bae5 2007-10-05 aku: return [$mystate last_insert_rowid] eb656de7d9 2007-10-05 aku: } eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: # # ## ### ##### ######## ############# eb656de7d9 2007-10-05 aku: ## State eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: typevariable mystate {} ; # Sqlite database (command) holding the converter state. eb656de7d9 2007-10-05 aku: typevariable mypath {} ; # Path to the database, for cleanup of a temp database. eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: # # ## ### ##### ######## ############# eb656de7d9 2007-10-05 aku: ## Internal methods eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: # # ## ### ##### ######## ############# eb656de7d9 2007-10-05 aku: ## Configuration eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: pragma -hasinstances no ; # singleton eb656de7d9 2007-10-05 aku: pragma -hastypeinfo no ; # no introspection eb656de7d9 2007-10-05 aku: pragma -hastypedestroy no ; # immortal eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: # # ## ### ##### ######## ############# eb656de7d9 2007-10-05 aku: } eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: namespace eval ::vc::fossil::import::cvs { eb656de7d9 2007-10-05 aku: namespace export state eb656de7d9 2007-10-05 aku: namespace eval state { eb656de7d9 2007-10-05 aku: namespace import ::vc::tools::trouble eb656de7d9 2007-10-05 aku: namespace import ::vc::tools::log eb656de7d9 2007-10-05 aku: log register state eb656de7d9 2007-10-05 aku: } eb656de7d9 2007-10-05 aku: } eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: # # ## ### ##### ######## ############# ##################### eb656de7d9 2007-10-05 aku: ## Ready eb656de7d9 2007-10-05 aku: eb656de7d9 2007-10-05 aku: package provide vc::fossil::import::cvs::state 1.0 eb656de7d9 2007-10-05 aku: return