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