Package Gnumed :: Package pycommon :: Module gmDrugObject
[frames] | no frames]

Source Code for Module Gnumed.pycommon.gmDrugObject

  1   
  2  print "this is currently not used" 
  3   
  4  import sys 
  5  sys.exit() 
  6   
  7  ############################################################################# 
  8  # 
  9  # gmDrugObject - Object hiding all drug related backend communication 
 10  # --------------------------------------------------------------------------- 
 11  # 
 12  # @author: Hilmar Berger 
 13  # @copyright: author 
 14  # @license: GPL v2 or later (details at http://www.gnu.org) 
 15  # 
 16  ############################################################################ 
 17   
 18  # FIXME: likely, this should be in client/business/ 
 19   
 20  #==================================================================              
 21  # $Source: /home/ncq/Projekte/cvs2git/vcs-mirror/gnumed/gnumed/client/pycommon/gmDrugObject.py,v $       
 22  # $Id: gmDrugObject.py,v 1.4 2008-04-13 14:41:40 ncq Exp $ 
 23  __version__ = "$Revision: 1.4 $" 
 24  __author__ = "Hilmar Berger <Hilmar.Berger@gmx.net>" 
 25   
 26  import sys, string, types, os.path 
 27   
 28  _log = gmLog.gmDefLog 
 29  if __name__ == "__main__": 
 30          # running standalone means diagnostics by definition, hehe 
 31          _log.SetAllLogLevels(gmLog.lData) 
 32  _log.Log(gmLog.lData, __version__) 
 33   
 34  from gmExceptions import * 
 35   
 36  #-------------------------------------------------------------------------- 
37 -class cQueryGroup:
38 """Object holding query strings and associated variable lists grouped together. 39 40 - Every query has to be identified by a unique identifier (string or number). 41 - mQueryStrings holds the query strings returning one or more parameters. 42 - mVarNames holds a list of variables that are to be filled by the query, 43 for this the order of the returned column names map 1:1 onto the 44 variable names 45 - mMappings holds the variables that should be mapped to the query. 46 - mInfos holds arbitrary infos (in a single string) about the query. 47 This can be used for format strings and so on. 48 - These three dictionaries are accessible from other objects. 49 - You must use addEntry to add entries to the dictionaries, though, 50 else the data will be written to the class as static variables. 51 """ 52
53 - def __init__(self):
54 self.mVarNames = {} 55 self.mQueryStrings = {} 56 self.mMappings = {}
57
58 - def addEntry(self, aEntry = None):
59 if aEntry != None: 60 self.mVarNames[aEntry] = None 61 self.mQueryStrings[aEntry] = None 62 self.mMappings[aEntry] = None
63 64 #--------------------------------------------------------------------------
65 -class cDrug:
66 """High level API to access drug data 67 68 FIXME: should class Drug not, perhaps, be derived from gmBusinessDBObject ? 69 """ 70 _db = None 71 #--------------------------------------------------------------------------
72 - def __init__(self, fastInit=0, queryCfgSource = None):
73 """initialize static variables""" 74 75 self.mVars = {} # variables usable for mapping 76 self.__mQueryGroups = {} 77 self.__mQueryGroupHandlers = {} 78 self.__fastInit=0 79 80 # get queries from configuration source (currently only files are supported) 81 if queryCfgSource is None: 82 _log.Log(gmLog.lWarn, "No query configuration source specified") 83 # we want to return an error here 84 # in that case we'll have to raise an exception... can't return 85 # anything else than None from an __init__ method 86 raise TypeError, "No query configuration source specified" 87 else: 88 self.__mQueryCfgSource = queryCfgSource 89 if not self.__getQueries(): 90 raise IOError, "cannot load queries" 91 92 # try to fetch all data at once if fastInit is true 93 self.__fastInit = fastInit 94 if fastInit: 95 self.getAllData()
96 #--------------------------------------------------------------------------
97 - def GetData(self, groupName = None, refresh=0):
98 """Get data of QueryGroupHandlers identified by groupName. 99 100 Returns None if the group does not exist or if the query was not 101 successful. Else it returns a dictionary containing all the variables 102 defined for this query. 103 If the query should be repeated instead of the cached data used, you will 104 have to set refresh to 1 (you should do this if some mapped variable was 105 changed). 106 """ 107 # return None if no sub object was named 108 if groupName is None: 109 return None 110 111 if self.__mQueryGroupHandlers.has_key(groupName): 112 # get query group data 113 result = self.__mQueryGroupHandlers[groupName].getData(refresh) 114 return result 115 else: 116 return None
117 #--------------------------------------------------------------------------
118 - def GetAllData(self):
119 """fetch data of all standard sub objects""" 120 for s in self.__QueryGroupHandlers.keys(): 121 self.GetData(s)
122 123 #--------------------------------------------------------------------------
124 - def __getQueries(self):
125 """get query strings and initialize query group objects""" 126 127 # open configuration source 128 try: 129 cfgSource = gmCfg.cCfgFile(aFile = self.__mQueryCfgSource, \ 130 flags=gmCfg.cfg_SEARCH_STD_DIRS | gmCfg.cfg_IGNORE_CMD_LINE) 131 # handle all exceptions including 'config file not found' 132 except: 133 exc = sys.exc_info() 134 _log.LogException("Unhandled exception while opening config file [%s]" % self.__mQueryCfgSource, exc, verbose = 0) 135 return None 136 137 cfgData = cfgSource.getCfg() 138 groups = cfgSource.getGroups() 139 140 # every group holds one query consisting of three items: variables, the 141 # query itself and the mappings 142 # queries are identified by the item 'type=query' 143 for entry_group in groups: 144 gtype = cfgSource.get(entry_group, "type") 145 # groups not containing queries are silently ignored 146 if gtype != 'query': 147 continue 148 149 qname = cfgSource.get(entry_group, "querygroup") 150 if qname is None: 151 _log.Log(gmLog.lWarn,"query definition invalid in entry_group %s." % entry_group) 152 continue 153 154 qvars = cfgSource.get(entry_group, "variables") 155 if qvars is None: 156 _log.Log(gmLog.lWarn,"query definition invalid in entry_group %s." % entry_group) 157 continue 158 159 # query is gonna be a list because of issues 160 # with special characters in simple string items 161 query = cfgSource.get(entry_group, "query") 162 if query is None or not type(query) == types.ListType: 163 _log.Log(gmLog.lWarn,"query definition invalid in entry_group %s." % entry_group) 164 continue 165 166 qstring = query[0] 167 168 qmappings = cfgSource.get(entry_group, "mappings") 169 if qmappings is None: 170 _log.Log(gmLog.lWarn,"query definition invalid in entry_group %s." % entry_group) 171 continue 172 173 # add new query group to QueryGroups dictionary 174 if not self.__mQueryGroups.has_key(qname): 175 self.__mQueryGroups[qname] = cQueryGroup() 176 self.__mQueryGroups[qname].addEntry(entry_group) 177 178 # set the parameters read from config file 179 self.__mQueryGroups[qname].mVarNames[entry_group] = string.split(qvars, ',') 180 self.__mQueryGroups[qname].mMappings[entry_group] = string.split(qmappings, ',') 181 self.__mQueryGroups[qname].mQueryStrings[entry_group] = qstring 182 183 # inititalize variables used for mapping 184 for v in string.split(qmappings, ','): 185 # print "var %s" % v 186 if v != '': 187 self.mVars[v] = None 188 189 # initialize new QueryGroupHandler objects using configuration data 190 for so in self.__mQueryGroups.keys(): 191 self.__mQueryGroupHandlers[so] = cQueryGroupHandler(self, so, self.__mQueryGroups[so]) 192 193 return 1
194 #--------------------------------------------------------------------------
195 -class cQueryGroupHandler:
196 """Object covering groups of related items. 197 198 used to access the backend to fetch all those items at once 199 200 """ 201 #--------------------------------------------------------------------------
202 - def __init__(self, aParent=None, aName=None, aQueryGroup=None):
203 self.__mParent = None # points to the parent Drug object, used to access mVars 204 self.__mDBObject = None # reference to DBObject 205 self.__mObjectName = None # this DrugQueryGroupHandler's name 206 self.__mQueries = cQueryGroup() # a QueryGroup holding queries to get the data for this QueryGroupHandlers. 207 self.__mData = {} # a dictionary holding all items belonging to this QueryGroupHandler 208 209 if aParent != None: 210 self.__mParent = aParent 211 if aQueryGroup != None: 212 self.__mQueries = aQueryGroup 213 if aName != None: 214 self.__mObjectName = aName
215 #--------------------------------------------------------------------------
216 - def getData(self,refresh=0):
217 """returns a dictionary of entry names and its values""" 218 219 # if data must be refreshed, clear data cache 220 if refresh == 1: 221 self.__mData = {} 222 223 if len(self.__mData) == 0: 224 # if data has not been fetched until now, get the data from backend 225 if self.__fetchBackendData(): 226 return self.__mData 227 else: 228 return None 229 else: 230 # else return the data already available 231 return self.__mData
232 233 #--------------------------------------------------------------------------
234 - def __fetchBackendData(self):
235 """try to fetch data from backend""" 236 237 # cycle through query strings and get data 238 for queryName in self.__mQueries.mQueryStrings.keys(): 239 # get variable mappings 240 mappings = self.__mQueries.mMappings[queryName] 241 allVars = [] 242 for var in mappings: 243 # get variables from parent 244 if var != '': 245 allVars.append(self.__mParent.mVars[var]) 246 247 # print "QUERY ", self.__mQueries.mQueryStrings[queryName] % tuple(allVars) 248 # set query string 249 if len(allVars) > 0: 250 querystring = self.__mQueries.mQueryStrings[queryName] % tuple(allVars) 251 else: 252 querystring = self.__mQueries.mQueryStrings[queryName] 253 254 # _log.Log(gmLog.lInfo, "Running query: %s" % querystring) 255 try: 256 result = gmPG.run_ro_query('pharmaceutica',querystring) 257 except: 258 _log.Log(gmLog.lWarn, "Query failed.") 259 260 # maybe we should raise an exception here 261 if result is None: 262 return None 263 264 # get results 265 VarNames = self.__mQueries.mVarNames[queryName] 266 VarNumMax = len(VarNames) 267 # init missing vars (keys) in data cache dict 268 for vn in VarNames: 269 if not self.__mData.has_key(vn): 270 self.__mData[vn] = [] 271 272 # if we got just one row in the result 273 if len(result) == 1: 274 row = result[0] # the row we fetched 275 col_idx = 0 # column counter 276 cols_avail = len(row) # number of available columns in row 277 for col_val in row: # loop through all columns 278 # don't try to map more columns than we have variable name mappings for 279 if col_idx > VarNumMax: 280 break 281 # map column (field) name to variable name in cache object 282 VarName = VarNames[col_idx] 283 # and cache the value 284 self.__mData[VarName] = col_val 285 # increase column count 286 col_idx = col_idx + 1 287 288 else: 289 # if multiple rows in result 290 for row in result[:]: 291 col_idx = 0 292 cols_avail = len(row) 293 for col_val in row: 294 if col_idx > VarNumMax: 295 break 296 VarName = VarNames[col_idx] 297 self.__mData[VarName].append(col_val) 298 col_idx = col_idx + 1 299 300 # return TRUE if everything went right 301 return 1
302 #==================================================================================== 303 # MAIN 304 #==================================================================================== 305 306 if __name__ == "__main__": 307 import os.path 308 tmp = os.path.join(os.path.expanduser("~"), ".gnumed", "amis.conf") 309 a = cDrug(0, tmp) 310 x = a.GetData('brand') 311 if x: 312 print x 313 else: 314 print "Query wasn't successful." 315 316 print "-----------------------------------------------------" 317 a.mVars['ID']="3337631600" 318 y=a.GetData('product_info') 319 print y 320 # y = a.GetData('brand_all') 321 # print y 322 # print len(x['brandname']) 323 #==================================================================================== 324 # $Log: gmDrugObject.py,v $ 325 # Revision 1.4 2008-04-13 14:41:40 ncq 326 # - old style logging is out 327 # 328 # Revision 1.3 2005/03/17 20:32:14 hinnef 329 # -fixed module dependencies 330 # 331 # Revision 1.2 2005/01/19 11:15:41 ncq 332 # - lots of FIXME stuff and some cleanup 333 # 334 # Revision 1.1 2004/02/25 09:30:13 ncq 335 # - moved here from python-common 336 # 337 # Revision 1.2 2003/11/17 10:56:36 sjtan 338 # 339 # synced and commiting. 340 # 341 # Revision 1.1 2003/10/23 06:02:39 sjtan 342 # 343 # manual edit areas modelled after r.terry's specs. 344 # 345 # Revision 1.1 2003/08/24 13:38:24 hinnef 346 # moved to main-tree, some bug fixes 347 # 348 # Revision 1.7 2002/11/17 16:44:23 hinnef 349 # fixed some bugs regarding display of non-string items and list entries in PI 350 # 351 # Revision 1.6 2002/10/29 15:40:48 ncq 352 # - first try at making this runnable standalone 353 # 354 # Revision 1.5 2002/10/28 23:26:02 hinnef 355 # first partially functional DrugReferenceBrowser version 356 # 357 # Revision 1.4 2002/10/24 13:04:18 ncq 358 # - just add two silly comments 359 # 360 # Revision 1.3 2002/10/23 22:41:54 hinnef 361 # more cleanup, fixed some bugs regarding variable mapping 362 # 363 # Revision 1.2 2002/10/22 21:18:11 ncq 364 # - fixed massive whitespace lossage 365 # - sprinkled some comments throughout 366 # - killed a few levels of indentation 367 # - tried to rename a few variable to be more self-documenting 368 # 369