123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- import labkeyInterface
- import labkeyInterface
- import labkeyDatabaseBrowser
- # interact with the database (connect, get handle, getRows, uploadRows)
- def connectDB(server):
- net=labkeyInterface.labkeyInterface()
- fconfig=os.path.join(os.path.expanduser('~'),'.labkey',f'{server}.json')
- net.init(fconfig)
- return net,labkeyDatabaseBrowser.labkeyDB(net)
- def getDB(pars):
- try:
- return pars['db']
- except KeyError:
- pass
- pars['net'],pars['db']=connectDB(pars['server'])
- return pars['db']
- def getRows(pars):
- db=getDB(pars)
- qFilter=pars.get('qFilter',[])
- return db.selectRows(pars['project'],pars['schema'],
- pars['query'],qFilter)['rows']
- def modifyRows(pars,mode,rows):
- db=getDB(pars)
- return db.modifyRows(mode,pars['project'],pars['schema'],pars['query'],rows)
- # helper function
- #very generic variable splitting routine
- def parseVariables(q):
- if q==None:
- return []
- arr=q.split(';')
- v=[x.split('=') for x in arr]
- return [{'varName':x[0],'varValue':x[1]} for x in v]
- # get snapshot of the data layout
- #this should really look at FormStatus on layout and do the conversion
- def toStatus(x):
- if x=='Submitted':
- return 2
- if x=='InProgress':
- return 1
- if x=='Approved':
- return 5
- #get dataset names
- def getInputLists(pars):
- try:
- return pars['inputLists']
- except KeyError:
- pass
- parServerLayout={'db':pars['db'],'project':'crfLayout/hypoAfrica'}
- parInputLists={'schema':'lists','query':'inputLists'}
- rows=getRows(parServerLayout|parInputLists)
- pars['inputLists']={r['Key']:r['queryName'] for r in rows}
- return pars['inputLists']
- #get datasets for form
- def getDatasets(pars,form):
- try:
- return pars['datasets'][form]
- except KeyError:
- pass
- parServerLayout={'db':pars['db'],'project':'crfLayout/hypoAfrica'}
- # set datasets for forms
- formFilter={'variable':'formName','value':f'{form}','oper':'eq'}
- parFormSetup={'schema':'lists','query':'FormSetup'}
- parFilter={'qFilter':[formFilter]}
- rows=getRows(parServerLayout|parFormSetup|parFilter)
- #ignore show query since 15 has all set to NONE
- #keep variable definition
- inputLists=getInputLists(pars)
- datasets={r['Key']:r|{'query':inputLists[r['queryName']]} for r in rows}
- try:
- pars['datasets'][form]=datasets
- except KeyError:
- pars['datasets']={form:datasets}
- return datasets
-
- #manager CRF master entries (get, modify, upload)
- def getCrfEntry(pars,crf):
- crfFilter={'variable':'entryId','value':crf,'oper':'eq'}
- parFilter={'qFilter':[crfFilter]}
- parCrf={'schema':'lists','query':'crfEntry'}
- rows=getRows(pars|parCrf|parFilter)
- if len(rows)!=1:
- print('Fail crfEntry')
- return None
- return rows[0]
- def changeFormStatus(pars,crfEntry,targetStatus):
- crfEntry['FormStatus']=toStatus(targetStatus)
- uploadCrfEntry(pars,crfEntry)
-
- def uploadCrfEntry(pars,crfEntry):
- parCrf={'schema':'lists','query':'crfEntry'}
- outcome=modifyRows(pars|parCrf,'update',[crfEntry])
- try:
- print(outcome['exception'])
- except KeyError:
- pass
- #manage DATA (set, verify, upload)
- def setData(pars,crfEntry,schema):
- datasets=getDatasets(pars,crfEntry['Form'])
- for k in datasets:
- d=datasets[k]
- crf=crfEntry['entryId']
- #print('Setting [{}:{}/{}]'.format(schema,d['query'],d['variableDefinition']))
- crfFilter={'variable':'crfRef','value':crf,'oper':'eq'}
- qFilter=[crfFilter]
- qvar=parseVariables(d['variableDefinition'])
- qvarFilter=[{'variable':x['varName'],'value':x['varValue'],'oper':'eq'} for x in qvar]
- qFilter.extend(qvarFilter)
- parD={'schema':schema,'query':d['query'],'qFilter':qFilter}
- rows=getRows(pars|parD)
- try:
- pars['data'][schema][k]=rows
- except KeyError:
- try:
- pars['data'][schema]={k:rows}
- except KeyError:
- pars['data']={schema:{k:rows}}
-
- def verifyData(pars,crfEntry,schema):
- ok=True
- datasets=getDatasets(pars,crfEntry['Form'])
- for k in datasets:
- d=datasets[k]
- rows=pars['data'][schema][k]
- testFailed={'lists':len(rows)!=1,'study':len(rows)>1}
- if testFailed[schema]:
- print('[{} {}/{}]: {}'.format(schema,d['query'],
- d['variableDefinition'],len(rows)))
- #at least one fail
- ok=False
- continue
- return ok
-
- def uploadData(pars,crfEntry):
- status=True
- datasets=getDatasets(pars,crfEntry['Form'])
- for k in datasets:
- listRow=pars['data']['lists'][k][0]
- studyRows=pars['data']['study'][k]
- try:
- outRow=studyRows[0]
- outRow.update(listRow)
- mode='update'
- except IndexError:
- outRow={x:listRow[x] for x in listRow}
- mode='insert'
- outRow['ParticipantId']=crfEntry['participantStudyId']
- outRow['SequenceNum']=(int(crfEntry['entryId']) % 1000000000 )
-
-
- d=datasets[k]
- parD={'schema':'study','query':d['query']}
- outcome=modifyRows(pars|parD,mode,[outRow])
- try:
- print(outcome['exception'])
- status=False
- except KeyError:
- pass
- return status
- ## mimic CRF actions
- def onSubmitedToInProgress(pars,crf):
- crfEntry=getCrfEntry(pars,crf)
- statusIn=crfEntry['FormStatus']
- if statusIn!=toStatus('Submitted'):
- print(f'[{crf}]: Inappropriate status({statusIn})')
- return
- changeFormStatus(pars,crfEntry,'InProgress')
- def onApprovedToSubmited(pars,crf):
- crfEntry=getCrfEntry(pars,crf)
- statusIn=crfEntry['FormStatus']
- if statusIn!=toStatus('Approved'):
- print(f'[{crf}]: Inappropriate status({statusIn})')
- return
- changeFormStatus(pars,crfEntry,'Submitted')
-
- def onSubmit(pars,crf):
- crfEntry=getCrfEntry(pars,crf)
- statusIn=crfEntry['FormStatus']
- if statusIn!=toStatus('InProgress'):
- print(f'[{crf}]: Inappropriate status({statusIn})')
- return
-
- form=crfEntry['Form']
- setData(pars,crfEntry,'lists')
- status=verifyData(pars,crfEntry,'lists')
- crf=crfEntry['entryId']
- if not status:
- print(f'[{crf}/{form}] verification failed')
- return
- changeFormStatus(pars,crfEntry,'Submitted')
- def onDatabaseUpload(pars,crf):
- crfEntry=getCrfEntry(pars,crf)
- statusIn=crfEntry['FormStatus']
- if statusIn!=toStatus('Submitted'):
- print(f'[{crf}]: Inappropriate status({statusIn})')
- return
-
- form=crfEntry['Form']
- setData(pars,crfEntry,'lists')
- setData(pars,crfEntry,'study')
- dataOK=verifyData(pars,crfEntry,'study')
- if not dataOK:
- print(f'[{crf}]: verification failed')
- return
- print(f'[{crf}]: verification OK')
-
- uploadOK=uploadData(pars,crfEntry)
- if not uploadOK:
- print(f'[{crf}]: upload failed')
- return
- print(f'[{crf}]: upload OK')
- changeFormStatus(pars,crfEntry,'Approved')
|