[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnumed-devel] Comments on 0.2

From: Ian Haywood
Subject: Re: [Gnumed-devel] Comments on 0.2
Date: Sat, 24 Jun 2006 18:57:12 +1000
User-agent: Thunderbird (X11/20060516)

Karsten Hilbert wrote:

>  pat = gmPerson.gmCurrentPatient()
>  emr = pat.get_emr()
>  allergies = emr.get_allergies()
>  for allergy in allergies:
>    if allergy['substance'] == 'pencilline':
>      allergy['definite'] = True
>        allergy['narrative'] = allergy['narrative'] + '; lab-confirmed'
>      success, data = allergy.save_payload()
>        if not success:
>          print "an error occurred:", data
>          print "what we saw   :", allergy.original_payload()
>          print "our changes   :", allergy.modified_payload()
>          print "database state:", allergy
It's not the API but the highly repetitive surrounding boilerplate
that is required.
I would like to write smart GUI ancestor classes
so all this error boilerplate can be done once
for the 90% case where it's the same
(pretty much 100% from my perspective, I accept you
may have widgets which need to handle errors their own way,
offhand I can't think what these use-cases are)
I can work out how to do it with exceptions, but not
with the current API.

It's possible to write a wrapper function which takes a middleware
result tuple and results either the real data or an exception (having done the 
user interaction)
but this breaks the no-exceptions rule and raises the question (if you're going 
to let me break it)
of why we don't use exceptions to begin with.
> Where in freaking hell is this any more complicated than it
> needs to be ? All the concurrency detection is handled
> behind the back of the user by the base class of cAllergy
> (as returned from get_allergies()).
Also, Richard and I need to be able to crank out lots
of middleware business objects which are all the same
except for the name of the backend table and the fields,
no special behaviour.

IMHO we should assume 1:1 business object and backend
relation (ie. an updateable view most of the time) and have a single
all-purpose generic business class (with optional
subclasses for special functions where required),
taking a single parameter (the name of the backend relation)
This is a good case for metaclasses BYW.

You could use the old 'hand-wrought' classes too, with the
same API, again for that 1% of the time you need it.

Another example.
Here's how I would like gmAllergy.create_allergy () to look

def create_allergy(**kwargs):

        # sanity checks:
        # 1) any of the args being None should fail the SQL code
        # 2) do episode/encounter belong to the same patient ?

        kwargs['patient_id'] = self.check_encounter_sanity 
(kwargs['episode_id'], kwargs['encounter_id'])  # if an error, exception goes 
straight to be caller, we don't need to handle
        if type(allg_type) != types.IntType:
                kwargs['allg_type'] = gmPG.run_ro_query ('select id from 
clin._enum_allergy_type where value=%s', kwargs['allg_type'])[0][0]
        # This below is now done by a backend trigger
        ## set patient has_allergy status
        ## cmd = """delete from clin.allergy_state where fk_patient=%s"""
        ## queries.append((cmd, [pat_id]))
        ## cmd = """insert into clin.allergy_state (fk_patient, has_allergy) 
values (%s, 1)"""
        ## queries.append((cmd, [pat_id]))
        # end triggerwork

        # again errors go straight to the caller, we don't need to check
        allergy = cBusinessClass (table='clin.allergy') (kwargs, new=1) # the 
new flag means create and look in clin.<table>_pk_seq for pk
        return allergy

Again, because we don't need to check for errors at every layer of the stack,
        def add_allergy(self, **kwargs):
                if not kwargs.has_key['encounter_id'] or kwargs['encounter_id'] 
is None:
                        kwargs['encounter_id'] = 
                return gmAllergy.create_allergy (**kwargs) # errors go straight 
to caller

> Sure enough and I really wish people would help find it
> (such as with the recent "select for update" discussion).
Well, I'm trying ;-)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]