/usr/share/tcltk/xotcl1.6.7-store/Persistence.xotcl is in xotcl 1.6.7-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | # $Id: Persistence.xotcl,v 1.6 2006/09/27 08:12:40 neumann Exp $
package provide xotcl::store::persistence 0.8
package require xotcl::trace
package require xotcl::package
package require xotcl::mixinStrategy
package require xotcl::store
package require XOTcl
namespace eval ::xotcl::store::persistence {
namespace import ::xotcl::*
@ @File {
description {
Persistent store for XOTcl objects with Eager and Lazy persistence.
Take a look at "persistenceExample.xotcl" for exmaple of usage.
}
}
@ Class PersistenceMgr {
description {
A persistent store requires a persistent manager. The persistent
manager implements the Storage interface via storage mixin. With
the parameter "dbPackage" we can specify which storage will be used.
The persistent manager than tries to load the package
"xotcl::${dbPackage}Storage". Default is Sdbm.
Example:
<@pre>
PersistenceMgr pmgr -persistenceDir . -persistenceFile example-db
</@pre>
}
}
#
# base class for persistent managers -- just register corresponding
# storage mixin and open DB
#
Class PersistenceMgr -parameter {
{fileName {[string trimleft [self] :]}}
{dbPackage Sdbm}
trace
dirName
}
PersistenceMgr instproc init args {
my instvar dbPackage
package require xotcl::store::[string tolower $dbPackage]
Storage=$dbPackage [self]::store $args
foreach v {dirName fileName} {
if {[my exists $v]} {
[self]::store $v [my set $v]
}
}
if {[my exists trace]} {
[self]::store filter traceFilter
}
my array set persistentObjs {}
next
}
# delegate methods to the store object
PersistenceMgr instproc store args {
eval [self]::store $args
}
PersistenceMgr instproc destroy args {
foreach obj [my array names persistentObjs] {
$obj storeall
$obj persistenceMgr ""
}
[self]::store close
next
}
PersistenceMgr instproc assureOpenDb {} {
if {![my exists dbOpen]} {
[self]::store dbOpen
my set dbOpen 1
}
}
PersistenceMgr instproc addPersistentObj {obj} {
my set persistentObjs($obj) ""
}
PersistenceMgr instproc removePersistentObj {obj} {
if {[my exists persistentObjs($obj)]} {
my unset persistentObjs($obj)
}
}
@ Class Persistent {
description {
Superclass or mixin class for all persistent objects. Normally
subclasses are used as mixins or instmixins on object, like:
<@pre>
o mixin Persistent=Eager
p mixin Persistent=Lazy
</@pre>
}
}
#
# Persistence (mixin) classes#
Class Persistent -parameter {
persistenceMgr
}
# can be overloaded by subclasses, that need a cleanup on
# persistenceMgr->destroy (like Lazy)
Persistent instproc storeall {} {;}
@ Persistent instproc persistenceMgr {args "persistent manager name"} {
description {
Specify which persistence manager to use for [self] object, like:
<@pre>
o persistenceMgr pmgr
</@pre>
Each persistent object must have a persistence manager specified,
before vars can be made persistent.
}
}
#
# turn off persistence with ... persistenceMgr "", but
# persistent vars stay persistent
#
Persistent instproc persistenceMgr args {
if {[llength $args] == 0} {
return [my set [self proc]]
} elseif {[llength $args] == 1} {
set pmgr [lindex $args 0]
if {$pmgr eq "" && [my exists persistenceMgr]} {
[my set persistenceMgr] removePersistentObj [self]
my unset persistenceMgr
return ""
}
$pmgr addPersistentObj [self]
return [my set [self proc] $pmgr]
} else {
error "wrong # args: [self] [self proc] ?value?"
}
}
@ Persistent instproc persistentVars {} {
description {
Returns list of persistent vars.
}
}
Persistent instproc persistentVars {} {
if {[my exists __persistentVars]} {
return [my set __persistentVars]
}
return ""
}
@ Persistent instproc persistent {list "persistent variables" } {
description {
Make a list of object variables persistent. If a persistent
DB exists, the values are read from this DB, overwriting the current value.
E.g.:
<@pre>
o persistent {x y}
</@pre>
}
}
Persistent instproc persistent {list} {
my instvar persistenceMgr
if {![info exists persistenceMgr]} {return}
set store ${persistenceMgr}::store
$persistenceMgr assureOpenDb
foreach var $list {
my lappend __persistentVars $var
# try to refetch vars from db
if {[$store exists [self]::${var}(_____arraynames)]} {
#puts stderr array=[self]::${var}
foreach i [$store set [self]::${var}(_____arraynames)] {
my set ${var}($i) [$store set [self]::${var}($i)]
}
} elseif {[$store exists [self]::$var]} {
#puts stderr "---store=$store exists [self]::$var"
#puts stderr "---set [self]::$var <[$store set [self]::$var]>"
my instvar $var
#set name [$store set [self]::$var]
#puts ***name*[set name]--$var
set $var [$store set [self]::$var]
} elseif {[my exists $var]} {
#
# first store of the variable in persistent store
if {[my array exists $var]} {
# this variable is an array
#puts stderr array=[self]::$var
set anames [my array names $var]
foreach n $anames {
$store set [self]::${var}($n) [my set ${var}($n)]
}
$store set [self]::${var}(_____arraynames) $anames
} else {
#puts stderr "+++set [self]::$var [$store set [self]::$var]"
$store set [self]::$var [my set $var]
}
} else {
error "persistent: $var is not a variable on [self]"
}
}
}
@ Persistent instproc persistent+init {list "persistent variables" } {
description {
Initialize all data in the list as empty strings,
if they do not exist yet, and then make them persistent
using the 'persistent' method
}
}
Persistent instproc persistent+init {list} {
foreach pd $list {
if {![my exists $pd]} {
my set $pd ""
}
}
my persistent $list
}
@ Persistent instproc unPersistent {list "persistent variables" } {
description {
Make a list of object variables not persistent.
}
}
Persistent instproc unPersistent {list} {
my instvar __persistentVars
set pMgr [my set persistenceMgr]
foreach v $list {
set i [lsearch -exact $__persistentVars $v]
catch {
set __persistentVars [lreplace $__persistentVars $i $i]
${pMgr}::store unset [self]::$v
}
}
}
@ Persistent instproc makeVarScript {} {
description {
Build a Tcl script of "set ..." statements reflecting the current situation in the database.
}
}
Persistent instproc makeVarScript {} {
set script ""
foreach v [my persistentVars] {
set vt [namespace tail $v]
append script [list my set $vt [my set $vt]]\n
}
#set script [concat [next] $script]
return $script
}
Persistent instproc destroy args {
if {[my exists persistenceMgr]} {
[my set persistenceMgr] removePersistentObj [self]
my unset persistenceMgr
}
next
#my showMsg "Persistent object [self] destroyed."
}
@ Class Persistent=Eager {
description {
Eager persistence strategy. Store everything at the same moment to the database
}
}
Class Persistent=Eager -superclass Persistent
#
# we use 'strange' argument names to avoid name clashes with given
# variable names, when we have to instvar "[self] instvar $nametail"
#
Persistent=Eager instproc vartrace {__name_vartrace __sub_vartrace __op_vartrace} {
#my showCall
if {$__op_vartrace eq "w"} {
my instvar persistenceMgr
if {![info exists persistenceMgr]} {return}
set store ${persistenceMgr}::store
set nametail [namespace tail $__name_vartrace]
set key [self]::$nametail
if {$__sub_vartrace eq ""} {
my instvar $nametail
#puts stderr "+++VT: $store set $key [set $nametail]"
$store set $key [set $nametail]
} else {
if {$__sub_vartrace ne "_____arraynames"} {
my instvar "${nametail}($__sub_vartrace) subname"
$store set ${key}($__sub_vartrace) $subname
$store set ${key}(_____arraynames) [my array names $nametail]
} else {
error "With persistent arrays you may not use '_____arraynames' as index"
}
}
}
}
Persistent=Eager instproc persistent {list} {
#my showCall
next
foreach v $list {
#puts stderr "***trace variable [self]::$v w [list my vartrace]"
my trace variable $v w [list [self] vartrace]
}
}
Persistent=Eager instproc unPersistent {list} {
foreach v $list {
my trace vdelete $v w [list [self] vartrace]
}
next
}
@ Class Persistent=Lazy {
description {
Lazy persistence strategy. Store everything on object destroy (or program termination).
}
}
Class Persistent=Lazy -superclass Persistent
Persistent=Lazy instproc storeall {} {
my instvar persistenceMgr
if {![info exists persistenceMgr]} {return}
set store ${persistenceMgr}::store
foreach v [my persistentVars] {
if {[my array exists $v]} {
set anames ""
foreach sub [my array names $v] {
if {[my exists ${v}($sub)]} {
set key [self]::${v}($sub)
$store set $key [my set ${v}($sub)]
lappend anames $sub
}
}
$store set [self]::${v}(_____arraynames) $anames
} else {
if {[my exists $v]} {
set key [self]::$v
$store set $key [my set $v]
}
}
}
}
Persistent=Lazy instproc destroy args {
my storeall
next
}
namespace export PersistenceMgr Persistent Persistent=Eager Persistent=Lazy
}
namespace import ::xotcl::store::persistence::*
|