splitting database fxn
[monitor.git] / monitor / database / pickle.py
1 import os
2 import sys
3 import pickle
4 noserial=False
5 try:
6         from util.PHPSerialize import *
7         from util.PHPUnserialize import *
8 except:
9         #print >>sys.stderr, "PHPSerial db type not allowed."
10         noserial=True
11
12 import inspect
13 import shutil
14 import config
15 import config as monitorconfig
16
17 DEBUG= 0
18 PICKLE_PATH=config.MONITOR_DATA_ROOT
19
20
21 def dbLoad(name, type=None):
22         return SPickle().load(name, type)
23
24 def dbExists(name, type=None):
25         #if self.config.debug:
26         #       name = "debug.%s" % name
27         return SPickle().exists(name, type)
28
29 def dbDump(name, obj=None, type=None):
30         # depth of the dump is 2 now, since we're redirecting to '.dump'
31         return SPickle().dump(name, obj, type, 2)
32
33 def if_cached_else_refresh(cond, refresh, name, function, type=None):
34         s = SPickle()
35         if refresh:
36                 if not config.debug and s.exists("production.%s" % name, type):
37                         s.remove("production.%s" % name, type)
38                 if config.debug and s.exists("debug.%s" % name, type):
39                         s.remove("debug.%s" % name, type)
40
41         return if_cached_else(cond, name, function, type)
42
43 def if_cached_else(cond, name, function, type=None):
44         s = SPickle()
45         if (cond and s.exists("production.%s" % name, type)) or \
46            (cond and config.debug and s.exists("debug.%s" % name, type)):
47                 o = s.load(name, type)
48         else:
49                 o = function()
50                 if cond:
51                         s.dump(name, o, type)   # cache the object using 'name'
52                         o = s.load(name, type)
53                 # TODO: what if 'o' hasn't been converted...
54         return o
55
56 class SPickle:
57         def __init__(self, path=PICKLE_PATH):
58                 self.path = path
59
60         def if_cached_else(self, cond, name, function, type=None):
61                 if cond and self.exists("production.%s" % name, type):
62                         o = self.load(name, type)
63                 else:
64                         o = function()
65                         if cond:
66                                 self.dump(name, o, type)        # cache the object using 'name'
67                 return o
68
69         def __file(self, name, type=None):
70                 if type == None:
71                         return "%s/%s.pkl" % (self.path, name)
72                 else:
73                         if noserial:
74                                 raise Exception("No PHPSerializer module available")
75
76                         return "%s/%s.phpserial" % (self.path, name)
77                 
78         def exists(self, name, type=None):
79                 return os.path.exists(self.__file(name, type))
80
81         def remove(self, name, type=None):
82                 return os.remove(self.__file(name, type))
83
84         def load(self, name, type=None):
85                 """ 
86                 In debug mode, we should fail if neither file exists.
87                         if the debug file exists, reset name
88                         elif the original file exists, make a copy, reset name
89                         else neither exist, raise an error
90                 Otherwise, it's normal mode, if the file doesn't exist, raise error
91                 Load the file
92                 """
93                 print "loading %s" % name
94
95                 if config.debug:
96                         if self.exists("debug.%s" % name, type):
97                                 name = "debug.%s" % name
98                         elif self.exists("production.%s" % name, type):
99                                 debugname = "debug.%s" % name
100                                 if not self.exists(debugname, type):
101                                         name = "production.%s" % name
102                                         shutil.copyfile(self.__file(name, type), self.__file(debugname, type))
103                                 name = debugname
104                         else:   # neither exist
105                                 raise Exception, "No such pickle based on %s" % self.__file("debug.%s" % name, type)
106                 else:
107                         if   self.exists("production.%s" % name, type):
108                                 name = "production.%s" % name
109                         elif self.exists(name, type):
110                                 name = name
111                         else:
112                                 raise Exception, "No such file %s" % name
113                                 
114
115                 #import traceback
116                 #print traceback.print_stack()
117                 #print "loading %s" % self.__file(name, type)
118                 #sys.stderr.write("-----------------------------\n")
119                 f = open(self.__file(name, type), 'r')
120                 if type == None:
121                         o = pickle.load(f)
122                 else:
123                         if noserial:
124                                 raise Exception("No PHPSerializer module available")
125                         s = PHPUnserialize()
126                         o = s.unserialize(f.read())
127                 f.close()
128                 return o
129                         
130         
131         # use the environment to extract the data associated with the local
132         # variable 'name'
133         def dump(self, name, obj=None, type=None, depth=1):
134                 if obj == None:
135                         o = inspect.getouterframes(inspect.currentframe())
136                         up1 = o[depth][0] # get the frame one prior to (up from) this frame
137                         argvals = inspect.getargvalues(up1)
138                         # TODO: check that 'name' is a local variable; otherwise this would fail.
139                         obj = argvals[3][name] # extract the local variable name 'name'
140                 if not os.path.isdir("%s/" % self.path):
141                         os.mkdir("%s" % self.path)
142                 if config.debug:
143                         name = "debug.%s" % name
144                 else:
145                         name = "production.%s" % name
146                 f = open(self.__file(name, type), 'w')
147                 if type == None:
148                         pickle.dump(obj, f)
149                 else:
150                         if noserial:
151                                 raise Exception("No PHPSerializer module available")
152                         s = PHPSerialize()
153                         f.write(s.serialize(obj))
154                 f.close()
155                 return