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