Improved handling of case where child is killed by a signal
[tcl-tlc.git] / scripts / hconfig.sql
blob4580cf13cdda56b2e9edb9d27e804c921d786a15
1 -- vim: foldmarker=<<<,>>>
3 drop table hconfig_rel;
4 create table hconfig_rel (
5                 path            text,
6                 attrib          text,
7                 value           text,
8                 primary key(path,attrib)
9 );
10 ---- SQL standard does not require an index on primary key, and later postgres
11 ---- versions do not create one automatically
12 -- create index hconfig_rel_idx on hconfig_rel(path,attrib);
14 drop function get_field(text,text,text);
15 create or replace function get_field(text,text,text) returns text as ' #<<<
16 #       array unset GD plan
17         if {![info exists GD(plan)]} {
18                 set GD(plan)    [spi_prepare "select data,leaf from hconfig where path = \\$1" {text}]
19         }
21         set path        [string trim $1 "/ "]
23         set p           ""
24         set sep         ""
25         set leaf        0
26         array set build {}
27         foreach elem [split $path /] {
28                 append p        $sep $elem
30 #               array unset ::hconfig_cache $p
32                 if {![info exists ::hconfig_cache($p)]} {
33                         set data                ""
34                         set leaf                0
35                         set exists      [spi_execp -count 1 $GD(plan) [list $p]]
36 #                       elog NOTICE "queried ($p), got: ($data) leaf: ($leaf) exists: ($exists)"
37                         set ::hconfig_cache($p) [list $data $leaf]
38                 } else {
39                         set data                [lindex $::hconfig_cache($p) 0]
40                         set leaf                [lindex $::hconfig_cache($p) 1]
41                 }
42                 
43                 array set build $data
44                 set sep         "/"
45                 if {$leaf} break
46         }
48         if {[info exists build($2)]} {
49                 return $build($2)
50         } else {
51                 return $3
52         }
53 ' language 'pltcl';
55 -- >>>
56 drop function examine_cache(text);
57 create or replace function examine_cache(text) returns text as ' #<<<
58         if {[info exists ::hconfig_cache($1)]} {
59                 return $::hconfig_cache($1)
60         } else {
61                 return "undef"
62         }
63 ' language 'pltcl';
65 -- >>>
66 drop trigger invalidate_hconfig_cache_t on hconfig;
67 drop function invalidate_hconfig_cache();
68 create or replace function invalidate_hconfig_cache() returns opaque as ' #<<<
69         if {[info exists OLD(path)]} {
70                 array unset ::hconfig_cache $OLD(path)
71         }
72         if {[info exists NEW(path)]} {
73                 array unset ::hconfig_cache $NEW(path)
74         }
75         return OK
76 ' language 'pltcl';
78 -- >>>
80  create trigger invalidate_hconfig_cache_t
81         after update or delete on hconfig
82         for each row execute procedure invalidate_hconfig_cache();
84 drop trigger update_hconfig_rel_t on hconfig;
85 drop function update_hconfig_rel();
86 create or replace function update_hconfig_rel() returns opaque as ' #<<<
87         if {![info exists GD(dplan)]} {
88                 set GD(dplan)   [spi_prepare "delete from hconfig_rel where path like \\$1" {text}]
89         }
90         if {![info exists GD(iplan)]} {
91                 set GD(iplan)   [spi_prepare "insert into hconfig_rel (path,attrib,value) values (\\$1,\\$2,\\$3)" {text text text}]
92         }
93         if {1 || ![info exists GD(splan)]} {
94                 set GD(splan)   [spi_prepare "select path,data,leaf from hconfig where path like \\$1 order by path asc" {text}]
95         }
96         if {![info exists GD(lplan)]} {
97                 set GD(lplan)   [spi_prepare "select data,leaf from hconfig where path = \\$1" {text}]
98         }
100         proc hconfig_rel_update {spath} {
101                 upvar GD GD
102                 set p           ""
103                 set sep         ""
104                 set leaf        0
105                 array set build {}
106                 foreach elem [split $spath /] {
107                         append p        $sep $elem
109                         set data                ""
110                         set leaf                0
111                         set exists      [spi_execp -count 1 $GD(lplan) [list $p]]
112                         
113                         if {[catch {
114                                 array set build $data
115                         } msg]} {
116                                 elog NOTICE "data: ($data)"
117                                 error $msg
118                         }
119                         set sep         "/"
120                 }
122                 set basic       [array get build]
123                 set pathd       [list $spath]
124                 set datad       [list $basic]
125                 spi_execp $GD(splan) [list "${spath}%"] {
126                         while {![string match "[lindex $pathd end]*" $path] && [llength $pathd] > 1} {
127                                 set pathd       [lrange $pathd 0 end-1]
128                                 set datad       [lrange $datad 0 end-1]
129                         }
130                         
131                         array unset tmp
132                         array set tmp   [lindex $datad end]
133                         array set tmp   $data
135                         set flattened   [array get tmp]
137                         lappend pathd   $path
138                         lappend datad   $flattened
140                         foreach {attrib value} $flattened {
141                                 spi_execp $GD(iplan) [list $path $attrib $value]
142                         }
143                 }
144         }
146         switch -- $TG_op {
147                 "INSERT" {
148                         spi_execp $GD(dplan) [list "${NEW(path)}%"]
149                         hconfig_rel_update $NEW(path)
150                 }
152                 "UPDATE" {
153                         spi_execp $GD(dplan) [list "${OLD(path)}%"]
154                         if {$OLD(path) != $NEW(path)} {
155                                 spi_execp $GD(dplan) [list "${NEW(path)}%"]
156                         }
157                         hconfig_rel_update $NEW(path)
158                 }
160                 "DELETE" {
161                         spi_execp $GD(dplan) [list "${OLD(path)}%"]
162                 }
163         }
165         return OK
166 ' language 'pltcl';
168  create trigger update_hconfig_rel_t
169         after insert or update or delete on hconfig
170         for each row execute procedure update_hconfig_rel();
172 -- Force a complete regeneration of hconfig_rel
173 update hconfig set data = data where path = '';
174 vacuum analyze hconfig_rel;