Package Gnumed :: Package business :: Module gmDataMining |
[frames] | no frames]

# Source Code for Module Gnumed.business.gmDataMining

      1  """GNUmed data mining middleware."""
      2  #============================================================
      3  __license__ = "GPL v2 or later"
      4  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
      5
      6
      7  import sys
      8  import logging
      9
     10
     11  if __name__ == '__main__':
     12          sys.path.insert(0, '../../')
     13  from Gnumed.pycommon import gmPG2
     14  from Gnumed.pycommon import gmDispatcher
     15  from Gnumed.pycommon import gmI18N
     16
     17  _log = logging.getLogger('gm.reports')
     18
     19  #============================================================
     20 -def report_exists(name=None):
     21          rows, idx = gmPG2.run_ro_queries(queries = [{
     22                  'cmd': 'SELECT EXISTS(SELECT 1 FROM cfg.report_query WHERE label = %(name)s)',
     23                  'args': {'name': name}
     24          }])
     25          return rows[0][0]
     26
     27  #--------------------------------------------------------
     28 -def save_report_definition(name=None, query=None, overwrite=False):
     29          if not overwrite:
     30                  if report_exists(name=name):
     31                          return False
     32
     33          args = {'name': name, 'query': query}
     34          queries = [
     35                  {'cmd': 'DELETE FROM cfg.report_query WHERE label = %(name)s', 'args': args},
     36                  {'cmd': 'INSERT INTO cfg.report_query (label, cmd) VALUES (%(name)s, %(query)s)', 'args': args}
     37          ]
     38          rows, idx = gmPG2.run_rw_queries(queries = queries)
     39          return True
     40
     41  #--------------------------------------------------------
     42 -def delete_report_definition(name=None):
     43          queries = [{
     44                  'cmd': 'DELETE FROM cfg.report_query WHERE label = %(name)s',
     45                  'args': {'name': name}
     46          }]
     47          rows, idx = gmPG2.run_rw_queries(queries=queries)
     48          return True
     49
     50  #--------------------------------------------------------
     51 -def run_report_query(query=None, limit=None, pk_identity=None):
     52          """Returns (status, hint, cols, rows)"""
     53
     54          PATIENT_ID_TOKEN = '$<ID_ACTIVE_PATIENT>$'
     55          if limit is None:
     56                  limit = ''
     57          else:
     58                  limit = 'LIMIT %s' % limit
     59
     60          # does user want to insert current patient ID ?
     61          if query.find(PATIENT_ID_TOKEN) == -1:
     62                  wrapper_query = """
     63                          SELECT * FROM (
     64                                  %%s
     65                          ) AS user_query
     66                          %s
     67                  """ % limit
     68          else:
     69                  # she does, but is it possible ?
     70                  if pk_identity is None:
     71                          gmDispatcher.send('statustext', msg = _('Query needs active patient.'), beep = True)
     72                          cols = [_('Error')]
     73                          rows = [
     74                                  [_('Active patient query')],
     75                                  [''],
     76                                  [_('This query requires a patient to be active in the client.')],
     77                                  [''],
     78                                  [_('Please activate the patient you are interested')],
     79                                  [_('in and re-run the query.')]
     80                          ]
     81                          return (False, 'pk_identity', cols, rows)
     82
     83                  query = query.replace(PATIENT_ID_TOKEN, str(pk_identity))
     84                  wrapper_query = """
     85                          SELECT %s AS pk_patient, * FROM (
     86                                  %%s
     87                          ) AS user_query
     88                          %s
     89                  """ % (pk_identity, limit)
     90
     91          wrapped_query = wrapper_query % query
     92          _log.debug('running report query:')
     93          _log.debug(wrapped_query)
     94
     95          try:
     96                  # read-only for safety reasons
     97                  rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': wrapped_query}], get_col_idx = True)
     98          except Exception:
     99                  _log.exception('report query failed')
    100                  gmDispatcher.send('statustext', msg = _('The query failed.'), beep = True)
    101                  cols = [_('Error')]
    102                  t, v = sys.exc_info()[:2]
    103                  rows = [
    104                          [_('The query failed.')],
    105                          [''],
    106                          [str(t)]
    107                  ]
    108                  for line in str(v).decode(gmI18N.get_encoding()).split('\n'):
    109                          rows.append([line])
    110                  rows.append([''])
    111                  for line in query.split('\n'):
    112                          rows.append([line])
    113                  return (False, 'query failed', cols, rows)
    114
    115          # swap (col_name, col_idx) to (col_idx, col_name)
    116          # and sort them according to position-in-query
    117          cols = [ (value, key) for key, value in idx.items() ]
    118          cols.sort()
    119          cols = [ pair[1] for pair in cols ]
    120
    121          return (True, None, cols, rows)
    122
    123  #============================================================
    124  if __name__ == '__main__':
    125
    126          if len(sys.argv) > 1 and sys.argv[1] == 'test':
    127                  test_report = 'test suite report'
    128                  test_query = 'select 1 as test_suite_report_result'
    129
    130                  print("delete (should work):", delete_report_definition(name = test_report))
    131                  print("check (should return False):", report_exists(name = test_report))
    132                  print("save (should work):", save_report_definition(name = test_report, query = test_query))
    133                  print("save (should fail):", save_report_definition(name = test_report, query = test_query, overwrite = False))
    134                  print("save (should work):", save_report_definition(name = test_report, query = test_query, overwrite = True))
    135                  print("delete (should work):", delete_report_definition(name = test_report))
    136                  print("check (should return False):", report_exists(name = test_report))
    137  #============================================================
    138