pltcl_loadmod
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:11k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. #!/bin/sh
  2. # Start tclsh 
  3. exec tclsh "$0" $@
  4. #
  5. # Code still has to be documented
  6. #
  7. #load /usr/local/pgsql/lib/libpgtcl.so
  8. package require Pgtcl
  9. #
  10. # Check for minimum arguments
  11. #
  12. if {$argc < 2} {
  13.     puts stderr ""
  14.     puts stderr "usage: pltcl_loadmod dbname [options] file [...]"
  15.     puts stderr ""
  16.     puts stderr "options:"
  17.     puts stderr "    -host hostname"
  18.     puts stderr "    -port portnumber"
  19.     puts stderr ""
  20.     exit 1
  21. }
  22. #
  23. # Remember database name and initialize options
  24. #
  25. set dbname [lindex $argv 0]
  26. set options ""
  27. set errors 0
  28. set opt ""
  29. set val ""
  30. set i 1
  31. while {$i < $argc} {
  32.     if {[string compare [string index [lindex $argv $i] 0] "-"] != 0} {
  33.         break;
  34.     }
  35.     set opt [lindex $argv $i]
  36.     incr i
  37.     if {$i >= $argc} {
  38.         puts stderr "no value given for option $opt"
  39. incr errors
  40. continue
  41.     }
  42.     set val [lindex $argv $i]
  43.     incr i
  44.     switch -- $opt {
  45.         -host {
  46.     append options "-host "$val" "
  47. }
  48. -port {
  49.     append options "-port $val "
  50. }
  51. default {
  52.     puts stderr "unknown option '$opt'"
  53.     incr errors
  54. }
  55.     }
  56. }
  57. #
  58. # Final syntax check
  59. #
  60. if {$i >= $argc || $errors > 0} {
  61.     puts stderr ""
  62.     puts stderr "usage: pltcl_loadmod dbname [options] file [...]"
  63.     puts stderr ""
  64.     puts stderr "options:"
  65.     puts stderr "    -host hostname"
  66.     puts stderr "    -port portnumber"
  67.     puts stderr ""
  68.     exit 1
  69. }
  70. proc __PLTcl_loadmod_check_table {conn tabname expnames exptypes} {
  71.     set attrs [expr [llength $expnames] - 1]
  72.     set error 0
  73.     set found 0
  74.     pg_select $conn "select C.relname, A.attname, A.attnum, T.typname 
  75.      from pg_class C, pg_attribute A, pg_type T
  76. where C.relname = '$tabname'
  77.   and A.attrelid = C.oid
  78.   and A.attnum > 0
  79.   and T.oid = A.atttypid
  80. order by attnum" tup {
  81. incr found
  82. set i $tup(attnum)
  83. if {$i > $attrs} {
  84.     puts stderr "Table $tabname has extra field '$tup(attname)'"
  85.     incr error
  86.     continue
  87. }
  88. set xname [lindex $expnames $i]
  89. set xtype [lindex $exptypes $i]
  90. if {[string compare $tup(attname) $xname] != 0} {
  91.     puts stderr "Attribute $i of $tabname has wrong name"
  92.     puts stderr "    got '$tup(attname)' expected '$xname'"
  93.     incr error
  94. }
  95. if {[string compare $tup(typname) $xtype] != 0} {
  96.     puts stderr "Attribute $i of $tabname has wrong type"
  97.     puts stderr "    got '$tup(typname)' expected '$xtype'"
  98.     incr error
  99. }
  100.     }
  101.     if {$found == 0} {
  102.         return 0
  103.     }
  104.     if {$found < $attrs} {
  105. incr found
  106. set miss [lrange $expnames $found end]
  107.         puts "Table $tabname doesn't have field(s) $miss"
  108. incr error
  109.     }
  110.     if {$error > 0} {
  111.         return 2
  112.     }
  113.     return 1
  114. }
  115. proc __PLTcl_loadmod_check_tables {conn} {
  116.     upvar #0 __PLTcl_loadmod_status status
  117.     set error 0
  118.     set names {{} modname modseq modsrc}
  119.     set types {{} name int2 text}
  120.     switch [__PLTcl_loadmod_check_table $conn pltcl_modules $names $types] {
  121.         0 {
  122.     set status(create_table_modules) 1
  123. }
  124. 1 {
  125.     set status(create_table_modules) 0
  126. }
  127. 2 {
  128.     puts "Error(s) in table pltcl_modules"
  129.     incr error
  130. }
  131.     }
  132.     set names {{} funcname modname}
  133.     set types {{} name name}
  134.     switch [__PLTcl_loadmod_check_table $conn pltcl_modfuncs $names $types] {
  135.         0 {
  136.     set status(create_table_modfuncs) 1
  137. }
  138. 1 {
  139.     set status(create_table_modfuncs) 0
  140. }
  141. 2 {
  142.     puts "Error(s) in table pltcl_modfuncs"
  143.     incr error
  144. }
  145.     }
  146.     if {$status(create_table_modfuncs) && !$status(create_table_modules)} {
  147.         puts stderr "Table pltcl_modfuncs doesn't exist but pltcl_modules does"
  148. puts stderr "Either both tables must be present or none."
  149. incr error
  150.     }
  151.     if {$status(create_table_modules) && !$status(create_table_modfuncs)} {
  152.         puts stderr "Table pltcl_modules doesn't exist but pltcl_modfuncs does"
  153. puts stderr "Either both tables must be present or none."
  154. incr error
  155.     }
  156.     if {$error} {
  157.         puts stderr ""
  158. puts stderr "Abort"
  159. exit 1
  160.     }
  161.     if {!$status(create_table_modules)} {
  162.         __PLTcl_loadmod_read_current $conn
  163.     }
  164. }
  165. proc __PLTcl_loadmod_read_current {conn} {
  166.     upvar #0 __PLTcl_loadmod_status status
  167.     upvar #0 __PLTcl_loadmod_modsrc modsrc
  168.     upvar #0 __PLTcl_loadmod_funclist funcs
  169.     upvar #0 __PLTcl_loadmod_globlist globs
  170.     set errors 0
  171.     set curmodlist ""
  172.     pg_select $conn "select distinct modname from pltcl_modules" mtup {
  173. set mname $mtup(modname);
  174.         lappend curmodlist $mname
  175.     }
  176.     foreach mname $curmodlist {
  177. set srctext ""
  178.         pg_select $conn "select * from pltcl_modules
  179. where modname = '$mname'
  180. order by modseq" tup {
  181.     append srctext $tup(modsrc)
  182.         }
  183. if {[catch {
  184.         __PLTcl_loadmod_analyze 
  185. "Current $mname"
  186. $mname
  187. $srctext new_globals new_functions
  188.     }]} {
  189.     incr errors
  190.         }
  191. set modsrc($mname) $srctext
  192. set funcs($mname) $new_functions
  193. set globs($mname) $new_globals
  194.     }
  195.     if {$errors} {
  196.         puts stderr ""
  197.         puts stderr "Abort"
  198. exit 1
  199.     }
  200. }
  201. proc __PLTcl_loadmod_analyze {modinfo modname srctext v_globals v_functions} {
  202.     upvar 1 $v_globals new_g
  203.     upvar 1 $v_functions new_f
  204.     upvar #0 __PLTcl_loadmod_allfuncs allfuncs
  205.     upvar #0 __PLTcl_loadmod_allglobs allglobs
  206.     set errors 0
  207.     set old_g [info globals]
  208.     set old_f [info procs]
  209.     set new_g ""
  210.     set new_f ""
  211.     if {[catch {
  212.     uplevel #0 "$srctext"
  213.         } msg]} {
  214.         puts "$modinfo: $msg"
  215. incr errors
  216.     }
  217.     set cur_g [info globals]
  218.     set cur_f [info procs]
  219.     foreach glob $cur_g {
  220.         if {[lsearch -exact $old_g $glob] >= 0} {
  221.     continue
  222. }
  223. if {[info exists allglobs($glob)]} {
  224.     puts stderr "$modinfo: Global $glob previously used in module $allglobs($glob)"
  225.     incr errors
  226. } else {
  227.     set allglobs($glob) $modname
  228. }
  229. lappend new_g $glob
  230. uplevel #0 unset $glob
  231.     }
  232.     foreach func $cur_f {
  233.         if {[lsearch -exact $old_f $func] >= 0} {
  234.     continue
  235. }
  236. if {[info exists allfuncs($func)]} {
  237.     puts stderr "$modinfo: Function $func previously defined in module $allfuncs($func)"
  238.     incr errors
  239. } else {
  240.     set allfuncs($func) $modname
  241. }
  242. lappend new_f $func
  243. rename $func {}
  244.     }
  245.     if {$errors} {
  246.         return -code error
  247.     }
  248.     #puts "globs in $modname: $new_g"
  249.     #puts "funcs in $modname: $new_f"
  250. }
  251. proc __PLTcl_loadmod_create_tables {conn} {
  252.     upvar #0 __PLTcl_loadmod_status status
  253.     if {$status(create_table_modules)} {
  254.         if {[catch {
  255.         set res [pg_exec $conn
  256.     "create table pltcl_modules (
  257.         modname name,
  258. modseq int2,
  259. modsrc text);"]
  260.     } msg]} {
  261.     puts stderr "Error creating table pltcl_modules"
  262.     puts stderr "    $msg"
  263.     exit 1
  264. }
  265.         if {[catch {
  266.         set res [pg_exec $conn
  267.     "create index pltcl_modules_i 
  268.         on pltcl_modules using btree
  269. (modname name_ops);"]
  270.     } msg]} {
  271.     puts stderr "Error creating index pltcl_modules_i"
  272.     puts stderr "    $msg"
  273.     exit 1
  274. }
  275. puts "Table pltcl_modules created"
  276. pg_result $res -clear
  277.     }
  278.     if {$status(create_table_modfuncs)} {
  279.         if {[catch {
  280.         set res [pg_exec $conn
  281.     "create table pltcl_modfuncs (
  282.         funcname name,
  283. modname  name);"]
  284.     } msg]} {
  285.     puts stderr "Error creating table pltcl_modfuncs"
  286.     puts stderr "    $msg"
  287.     exit 1
  288. }
  289.         if {[catch {
  290.         set res [pg_exec $conn
  291.     "create index pltcl_modfuncs_i 
  292.         on pltcl_modfuncs using hash
  293. (funcname name_ops);"]
  294.     } msg]} {
  295.     puts stderr "Error creating index pltcl_modfuncs_i"
  296.     puts stderr "    $msg"
  297.     exit 1
  298. }
  299. puts "Table pltcl_modfuncs created"
  300. pg_result $res -clear
  301.     }
  302. }
  303. proc __PLTcl_loadmod_read_new {conn} {
  304.     upvar #0 __PLTcl_loadmod_status status
  305.     upvar #0 __PLTcl_loadmod_modsrc modsrc
  306.     upvar #0 __PLTcl_loadmod_funclist funcs
  307.     upvar #0 __PLTcl_loadmod_globlist globs
  308.     upvar #0 __PLTcl_loadmod_allfuncs allfuncs
  309.     upvar #0 __PLTcl_loadmod_allglobs allglobs
  310.     upvar #0 __PLTcl_loadmod_modlist modlist
  311.     set errors 0
  312.     set new_modlist ""
  313.     foreach modfile $modlist {
  314.         set modname [file rootname [file tail $modfile]]
  315. if {[catch {
  316.         set fid [open $modfile "r"]
  317.     } msg]} {
  318.     puts stderr $msg
  319.     incr errors
  320.     continue
  321.         }
  322. set srctext [read $fid]
  323. close $fid
  324. if {[info exists modsrc($modname)]} {
  325.     if {[string compare $modsrc($modname) $srctext] == 0} {
  326.         puts "Module $modname unchanged - ignored"
  327. continue
  328.     }
  329.     foreach func $funcs($modname) {
  330.         unset allfuncs($func)
  331.     }
  332.     foreach glob $globs($modname) {
  333.         unset allglobs($glob)
  334.     }
  335.     unset funcs($modname)
  336.     unset globs($modname)
  337.     set modsrc($modname) $srctext
  338.     lappend new_modlist $modname
  339. } else {
  340.     set modsrc($modname) $srctext
  341.     lappend new_modlist $modname
  342. }
  343. if {[catch {
  344.         __PLTcl_loadmod_analyze "New/updated $modname"
  345. $modname $srctext new_globals new_funcs
  346.     }]} {
  347.     incr errors
  348. }
  349. set funcs($modname) $new_funcs
  350. set globs($modname) $new_globals
  351.     }
  352.     if {$errors} {
  353.         puts stderr ""
  354.         puts stderr "Abort"
  355. exit 1
  356.     }
  357.     set modlist $new_modlist
  358. }
  359. proc __PLTcl_loadmod_load_modules {conn} {
  360.     upvar #0 __PLTcl_loadmod_modsrc modsrc
  361.     upvar #0 __PLTcl_loadmod_funclist funcs
  362.     upvar #0 __PLTcl_loadmod_modlist modlist
  363.     set errors 0
  364.     foreach modname $modlist {
  365. set xname [__PLTcl_loadmod_quote $modname]
  366.         pg_result [pg_exec $conn "begin;"] -clear
  367. pg_result [pg_exec $conn 
  368. "delete from pltcl_modules where modname = '$xname'"] -clear
  369. pg_result [pg_exec $conn 
  370. "delete from pltcl_modfuncs where modname = '$xname'"] -clear
  371. foreach func $funcs($modname) {
  372.     set xfunc [__PLTcl_loadmod_quote $func]
  373.     pg_result [
  374.         pg_exec $conn "insert into pltcl_modfuncs values (
  375. '$xfunc', '$xname')"
  376.     ] -clear
  377. }
  378. set i 0
  379. set srctext $modsrc($modname)
  380. while {[string compare $srctext ""] != 0} {
  381.     set xpart [string range $srctext 0 3999]
  382.     set xpart [__PLTcl_loadmod_quote $xpart]
  383.     set srctext [string range $srctext 4000 end]
  384.     pg_result [
  385.      pg_exec $conn "insert into pltcl_modules values (
  386. '$xname', $i, '$xpart')"
  387.     ] -clear
  388. }
  389.         pg_result [pg_exec $conn "commit;"] -clear
  390. puts "Successfully loaded/updated module $modname"
  391.     }
  392. }
  393. proc __PLTcl_loadmod_quote {s} {
  394.     regsub -all {\} $s {\\} s
  395.     regsub -all {'}  $s {''} s
  396.     return $s
  397. }
  398. set __PLTcl_loadmod_modlist [lrange $argv $i end]
  399. set __PLTcl_loadmod_modsrc(dummy) ""
  400. set __PLTcl_loadmod_funclist(dummy) ""
  401. set __PLTcl_loadmod_globlist(dummy) ""
  402. set __PLTcl_loadmod_allfuncs(dummy) ""
  403. set __PLTcl_loadmod_allglobs(dummy) ""
  404. unset __PLTcl_loadmod_modsrc(dummy)
  405. unset __PLTcl_loadmod_funclist(dummy)
  406. unset __PLTcl_loadmod_globlist(dummy)
  407. unset __PLTcl_loadmod_allfuncs(dummy)
  408. unset __PLTcl_loadmod_allglobs(dummy)
  409. puts ""
  410. set __PLTcl_loadmod_conn [eval pg_connect $dbname $options]
  411. unset i dbname options errors opt val
  412. __PLTcl_loadmod_check_tables $__PLTcl_loadmod_conn
  413. __PLTcl_loadmod_read_new $__PLTcl_loadmod_conn
  414. __PLTcl_loadmod_create_tables $__PLTcl_loadmod_conn
  415. __PLTcl_loadmod_load_modules $__PLTcl_loadmod_conn
  416. pg_disconnect $__PLTcl_loadmod_conn
  417. puts ""