Repository URL to install this package:
|
Version:
9.6.1-1PGDG.el7 ▾
|
#! /bin/sh
# Start tclsh \
exec /usr/bin/tclsh "$0" "$@"
#
# Code still has to be documented
#
#load /usr/local/pgsql/lib/libpgtcl.so
package require Pgtcl
#
# Check for minimum arguments
#
if {$argc < 2} {
puts stderr ""
puts stderr "usage: pltcl_loadmod dbname \[options\] file \[...\]"
puts stderr ""
puts stderr "options:"
puts stderr " -host hostname"
puts stderr " -port portnumber"
puts stderr ""
exit 1
}
#
# Remember database name and initialize options
#
set dbname [lindex $argv 0]
set options ""
set errors 0
set opt ""
set val ""
set i 1
while {$i < $argc} {
if {[string compare [string index [lindex $argv $i] 0] "-"] != 0} {
break;
}
set opt [lindex $argv $i]
incr i
if {$i >= $argc} {
puts stderr "no value given for option $opt"
incr errors
continue
}
set val [lindex $argv $i]
incr i
switch -- $opt {
-host {
append options "-host \"$val\" "
}
-port {
append options "-port $val "
}
default {
puts stderr "unknown option '$opt'"
incr errors
}
}
}
#
# Final syntax check
#
if {$i >= $argc || $errors > 0} {
puts stderr ""
puts stderr "usage: pltcl_loadmod dbname \[options\] file \[...\]"
puts stderr ""
puts stderr "options:"
puts stderr " -host hostname"
puts stderr " -port portnumber"
puts stderr ""
exit 1
}
proc __PLTcl_loadmod_check_table {conn tabname expnames exptypes} {
set attrs [expr [llength $expnames] - 1]
set error 0
set found 0
pg_select $conn "select C.relname, A.attname, A.attnum, T.typname \
from pg_catalog.pg_class C, pg_catalog.pg_attribute A, pg_catalog.pg_type T \
where C.relname = '$tabname' \
and A.attrelid = C.oid \
and A.attnum > 0 \
and T.oid = A.atttypid \
order by attnum" tup {
incr found
set i $tup(attnum)
if {$i > $attrs} {
puts stderr "Table $tabname has extra field '$tup(attname)'"
incr error
continue
}
set xname [lindex $expnames $i]
set xtype [lindex $exptypes $i]
if {[string compare $tup(attname) $xname] != 0} {
puts stderr "Attribute $i of $tabname has wrong name"
puts stderr " got '$tup(attname)' expected '$xname'"
incr error
}
if {[string compare $tup(typname) $xtype] != 0} {
puts stderr "Attribute $i of $tabname has wrong type"
puts stderr " got '$tup(typname)' expected '$xtype'"
incr error
}
}
if {$found == 0} {
return 0
}
if {$found < $attrs} {
incr found
set miss [lrange $expnames $found end]
puts "Table $tabname doesn't have field(s) $miss"
incr error
}
if {$error > 0} {
return 2
}
return 1
}
proc __PLTcl_loadmod_check_tables {conn} {
upvar #0 __PLTcl_loadmod_status status
set error 0
set names {{} modname modseq modsrc}
set types {{} name int2 text}
switch [__PLTcl_loadmod_check_table $conn pltcl_modules $names $types] {
0 {
set status(create_table_modules) 1
}
1 {
set status(create_table_modules) 0
}
2 {
puts "Error(s) in table pltcl_modules"
incr error
}
}
set names {{} funcname modname}
set types {{} name name}
switch [__PLTcl_loadmod_check_table $conn pltcl_modfuncs $names $types] {
0 {
set status(create_table_modfuncs) 1
}
1 {
set status(create_table_modfuncs) 0
}
2 {
puts "Error(s) in table pltcl_modfuncs"
incr error
}
}
if {$status(create_table_modfuncs) && !$status(create_table_modules)} {
puts stderr "Table pltcl_modfuncs doesn't exist but pltcl_modules does"
puts stderr "Either both tables must be present or none."
incr error
}
if {$status(create_table_modules) && !$status(create_table_modfuncs)} {
puts stderr "Table pltcl_modules doesn't exist but pltcl_modfuncs does"
puts stderr "Either both tables must be present or none."
incr error
}
if {$error} {
puts stderr ""
puts stderr "Abort"
exit 1
}
if {!$status(create_table_modules)} {
__PLTcl_loadmod_read_current $conn
}
}
proc __PLTcl_loadmod_read_current {conn} {
upvar #0 __PLTcl_loadmod_status status
upvar #0 __PLTcl_loadmod_modsrc modsrc
upvar #0 __PLTcl_loadmod_funclist funcs
upvar #0 __PLTcl_loadmod_globlist globs
set errors 0
set curmodlist ""
pg_select $conn "select distinct modname from pltcl_modules" mtup {
set mname $mtup(modname);
lappend curmodlist $mname
}
foreach mname $curmodlist {
set srctext ""
pg_select $conn "select * from pltcl_modules \
where modname = '$mname' \
order by modseq" tup {
append srctext $tup(modsrc)
}
if {[catch {
__PLTcl_loadmod_analyze \
"Current $mname" \
$mname \
$srctext new_globals new_functions
}]} {
incr errors
}
set modsrc($mname) $srctext
set funcs($mname) $new_functions
set globs($mname) $new_globals
}
if {$errors} {
puts stderr ""
puts stderr "Abort"
exit 1
}
}
proc __PLTcl_loadmod_analyze {modinfo modname srctext v_globals v_functions} {
upvar 1 $v_globals new_g
upvar 1 $v_functions new_f
upvar #0 __PLTcl_loadmod_allfuncs allfuncs
upvar #0 __PLTcl_loadmod_allglobs allglobs
set errors 0
set old_g [info globals]
set old_f [info procs]
set new_g ""
set new_f ""
if {[catch {
uplevel #0 "$srctext"
} msg]} {
puts "$modinfo: $msg"
incr errors
}
set cur_g [info globals]
set cur_f [info procs]
foreach glob $cur_g {
if {[lsearch -exact $old_g $glob] >= 0} {
continue
}
if {[info exists allglobs($glob)]} {
puts stderr "$modinfo: Global $glob previously used in module $allglobs($glob)"
incr errors
} else {
set allglobs($glob) $modname
}
lappend new_g $glob
uplevel #0 unset $glob
}
foreach func $cur_f {
if {[lsearch -exact $old_f $func] >= 0} {
continue
}
if {[info exists allfuncs($func)]} {
puts stderr "$modinfo: Function $func previously defined in module $allfuncs($func)"
incr errors
} else {
set allfuncs($func) $modname
}
lappend new_f $func
rename $func {}
}
if {$errors} {
return -code error
}
#puts "globs in $modname: $new_g"
#puts "funcs in $modname: $new_f"
}
proc __PLTcl_loadmod_create_tables {conn} {
upvar #0 __PLTcl_loadmod_status status
if {$status(create_table_modules)} {
if {[catch {
set res [pg_exec $conn \
"create table pltcl_modules ( \
modname name, \
modseq int2, \
modsrc text);"]
} msg]} {
puts stderr "Error creating table pltcl_modules"
puts stderr " $msg"
exit 1
}
if {[catch {
set res [pg_exec $conn \
"create index pltcl_modules_i \
on pltcl_modules using btree \
(modname name_ops);"]
} msg]} {
puts stderr "Error creating index pltcl_modules_i"
puts stderr " $msg"
exit 1
}
puts "Table pltcl_modules created"
pg_result $res -clear
}
if {$status(create_table_modfuncs)} {
if {[catch {
set res [pg_exec $conn \
"create table pltcl_modfuncs ( \
funcname name, \
modname name);"]
} msg]} {
puts stderr "Error creating table pltcl_modfuncs"
puts stderr " $msg"
exit 1
}
if {[catch {
set res [pg_exec $conn \
"create index pltcl_modfuncs_i \
on pltcl_modfuncs using hash \
(funcname name_ops);"]
} msg]} {
puts stderr "Error creating index pltcl_modfuncs_i"
puts stderr " $msg"
exit 1
}
puts "Table pltcl_modfuncs created"
pg_result $res -clear
}
}
proc __PLTcl_loadmod_read_new {conn} {
upvar #0 __PLTcl_loadmod_status status
upvar #0 __PLTcl_loadmod_modsrc modsrc
upvar #0 __PLTcl_loadmod_funclist funcs
upvar #0 __PLTcl_loadmod_globlist globs
upvar #0 __PLTcl_loadmod_allfuncs allfuncs
upvar #0 __PLTcl_loadmod_allglobs allglobs
upvar #0 __PLTcl_loadmod_modlist modlist
set errors 0
set new_modlist ""
foreach modfile $modlist {
set modname [file rootname [file tail $modfile]]
if {[catch {
set fid [open $modfile "r"]
} msg]} {
puts stderr $msg
incr errors
continue
}
set srctext [read $fid]
close $fid
if {[info exists modsrc($modname)]} {
if {[string compare $modsrc($modname) $srctext] == 0} {
puts "Module $modname unchanged - ignored"
continue
}
foreach func $funcs($modname) {
unset allfuncs($func)
}
foreach glob $globs($modname) {
unset allglobs($glob)
}
unset funcs($modname)
unset globs($modname)
set modsrc($modname) $srctext
lappend new_modlist $modname
} else {
set modsrc($modname) $srctext
lappend new_modlist $modname
}
if {[catch {
__PLTcl_loadmod_analyze "New/updated $modname" \
$modname $srctext new_globals new_funcs
}]} {
incr errors
}
set funcs($modname) $new_funcs
set globs($modname) $new_globals
}
if {$errors} {
puts stderr ""
puts stderr "Abort"
exit 1
}
set modlist $new_modlist
}
proc __PLTcl_loadmod_load_modules {conn} {
upvar #0 __PLTcl_loadmod_modsrc modsrc
upvar #0 __PLTcl_loadmod_funclist funcs
upvar #0 __PLTcl_loadmod_modlist modlist
set errors 0
foreach modname $modlist {
set xname [__PLTcl_loadmod_quote $modname]
pg_result [pg_exec $conn "begin;"] -clear
pg_result [pg_exec $conn \
"delete from pltcl_modules where modname = '$xname'"] -clear
pg_result [pg_exec $conn \
"delete from pltcl_modfuncs where modname = '$xname'"] -clear
foreach func $funcs($modname) {
set xfunc [__PLTcl_loadmod_quote $func]
pg_result [ \
pg_exec $conn "insert into pltcl_modfuncs values ( \
'$xfunc', '$xname')" \
] -clear
}
set i 0
set srctext $modsrc($modname)
while {[string compare $srctext ""] != 0} {
set xpart [string range $srctext 0 3999]
set xpart [__PLTcl_loadmod_quote $xpart]
set srctext [string range $srctext 4000 end]
pg_result [ \
pg_exec $conn "insert into pltcl_modules values ( \
'$xname', $i, '$xpart')" \
] -clear
incr i
}
pg_result [pg_exec $conn "commit;"] -clear
puts "Successfully loaded/updated module $modname"
}
}
proc __PLTcl_loadmod_quote {s} {
regsub -all {\\} $s {\\\\} s
regsub -all {'} $s {''} s
return $s
}
set __PLTcl_loadmod_modlist [lrange $argv $i end]
set __PLTcl_loadmod_modsrc(dummy) ""
set __PLTcl_loadmod_funclist(dummy) ""
set __PLTcl_loadmod_globlist(dummy) ""
set __PLTcl_loadmod_allfuncs(dummy) ""
set __PLTcl_loadmod_allglobs(dummy) ""
unset __PLTcl_loadmod_modsrc(dummy)
unset __PLTcl_loadmod_funclist(dummy)
unset __PLTcl_loadmod_globlist(dummy)
unset __PLTcl_loadmod_allfuncs(dummy)
unset __PLTcl_loadmod_allglobs(dummy)
puts ""
set __PLTcl_loadmod_conn [eval pg_connect $dbname $options]
unset i dbname options errors opt val
__PLTcl_loadmod_check_tables $__PLTcl_loadmod_conn
__PLTcl_loadmod_read_new $__PLTcl_loadmod_conn
__PLTcl_loadmod_create_tables $__PLTcl_loadmod_conn
__PLTcl_loadmod_load_modules $__PLTcl_loadmod_conn
pg_disconnect $__PLTcl_loadmod_conn
puts ""