gnumed-devel
[Top][All Lists]
Advanced

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

Re: [Gnumed-devel] Specs (was: Gnumed brochures)


From: Karsten Hilbert
Subject: Re: [Gnumed-devel] Specs (was: Gnumed brochures)
Date: Sun, 18 Dec 2005 23:48:19 +0100
User-agent: Mutt/1.5.11

On Sun, Dec 18, 2005 at 12:36:19PM +1100, Ian Haywood wrote:

> Before specification & design comes an even eariler phase: requirements.
...
> And it's here problems arise. Obviously in Australia we
> have different, much broader requirements.
...
> Do we have such a community?: yes, in potential, but the
> core "kernel" must exist, being much bigger than Linus'
> first release of his kernel, local teams can then add on
> modules to suit local requirements, which is of course what
> we've spent six years trying to build.
> It's just really hard.
Ian, thanks for this insightful post. I am glad good things
arise even from heated argument in this community.

> On the whole, I'm happy with the backend too. SQL is so
> high-level it's practically like UML anyway.
Nevertheless, visualization is good. Especially for those
starting to get into things. In fact, I was darn surprised
when I first looked at the ER diagrams generated from our
schema since a) they matched my internal diagram and b) they
actually made sense (to me).

> It is sometimes a struggle to get Karsten to accept our
> required changes, but he does eventually and I can hardly
> argue that his contemplations acts as some sort of
> bottleneck.
Please do struggle on with me ! :-)  Much good has come from
it so far.

> The only way it can work is if the frontend adheres to a
> unifying philosophy/paradigm/whatever where there is a
> common system across all modules.
I won't argue with that as I lack the experience.

> So, Richard and I need to write our own frontend, (which
> we are quietly doing already)
This is excellent. What sort of backend does it use ?

> Gnumed already supports completely different pluggable UI
> "personalities", no-one has ever had a problem with that.
Even more so, the backend is intended and designed to
support completely different user interfaces entirely.

> So where's the problem? I have to say it's the business
> layer. Personally I find coding it causes serious posterior
> pain. I find it overly complex,
This is due to two things:

1) I lack(ed) the skill and/or experience to write a better one.
2) Despite of that I felt the need to write middleware that
   is true to the principle of NO DATA LOSS/CORRUPTION.

> I'm (still) really frustrated and confused by the prohibition
> on python exceptions,
There is a fundamental misunderstanding here: I am not
opposed to using Python exceptions at all. I did not like
the way they were used in some of the code that was
proposed, yes. The reason being that they were used to
propagate information between *threads*.

> It's also slows the client down to an unusable speed.
I haven't observed that. Once the clinical record object is
initialized for a given patient everything else pretty much
happens instantaneously on my machine ?

Nevertheless, there is very likely conceptual possibilities
here to gain quite some speedups.

> This is something where I would vote for a putting a bomb
> under it and starting afresh, problem is that means
> blowing up the GUI layer too, (although some large fragments
> could be re-used)
Well, writing a new middleware shouldn't concern the
existing frontend at all, should it. By definition the
middleware should be independant, agnostic even, of the
frontend that might use it. Hence the big throwup will only
happen once the *then existing* new middleware will have
gained enough code, features, unit tests and thereby
credibility to replace the old middleware... Yes, that'd be
painful, but it'd work.

> Our current middleware comes unstuck because it does
> everything twice: middleware objects need to be manually
> defined even though 90% they correspond to stuff in the
> backend.
OK, I see your point.

> They don't do error-handling well
AFAICT they do quite extensive error handling. It may not be
convenient for your style of coding, yes, that's possible.

> (I want to be able to write error-handling *once* and
> never worry about it again,
I don't think you seriously think this is possible ?

> I don't want to check for errors *every* *single* *time* I
> call the middleware layer!),
Why of course you have to !?!

Please show me sample code that alleviates the need for
checking errors every time they could come up and not miss
any !!

> and inserting new rows is harder then it should be.
It's cumbersome in some ways but it's got method (as in
design principles) to it. Those are:

create_<object>() only does the minimum necessary to return
a valid object in the database. From then on the
cBusinessDbObject is used to manipulate it's fields. Hence
creation of a new object is a two-step process in most cases:

- set up a new instance of the class by create_*()
- fill that class with data by object['*'] = * and object.save_payload()

> Working with 'advanced' postgres features like stored
> procedures is harder than it should be, and so under-utilised.
It is under-utilized because no one wrote more stored
procedures than we have now. Using them is no different from
any other database manipulation.

> example.
> 
> l = sql.find_patient ("Smith") # runs the backend prepared query 
> find_patient, returning row instances
Very hard or impossible to do sanely because find_patient()
requires extensive and intricate munging of input which
PostgreSQL *does not even support properly yet* !

> p = l[0]
> a = p.allergies # runs select * from allergies where fk_patient = <pk of 
> patient>, which is cached

*** How do you evict the cache when the backend changes state ? ***
 
> del a[0] # runs delete from allergies where pk = <the pk of that row>
> 
> a.new (reaction="rash", drug="penicillin") # insert into allergies (reaction, 
> drug, fk_patient) values ("rash", "penicillin", <pk of patient>)
> a.do_something (foo) # calls the prepared query do_something (<pk of 
> allergy>, foo)
> p.update () # commits the above changes in a single transaction by traversing 
> the local object tree.

Let me restate your sequence in our current middleware:

l = gmPerson.gmPatientSearcher_SQL().get_persons(search_term=smith)
emr = l[0].get_emr()
a = emr.get_allergies()
emr.remove_allergy(pk=a[0]['pk_allergy'])
a_new = emr.add_allergy(...)
a_new[...] = ...
a_new.save_payload()
a.do_something(foo)

p.update() isn't needed as the current middleware persists
data when something() is called.

> all this without defined specific "allergy" and "patient" classes,
What *are* they, then ? Lists of lists of lists with some
special magic added (*.new()) ?

> however such classes can be defined and will be used automatically if you
> want some client-side functionality.
Should we try to write a class which inherits from
business/gmClinItem.cClinItem() or even
pycommon/gmBusinessDbObject.cBusinessDBObject() but
generically provides your proposed interface ?

> In many ways this is the culmination of what the current business layer has 
> been evolving towards for some time,
Aha, I see. How about the above suggestion ?

> the biggest difference this that it throws error exceptions, which simplifies 
> things a lot.
I don't believe throwing exceptions simplifies things until
I see it.

> the code is in gnumed/test-area/ian/purepg.py
Please do separate your middleware interface from the DB API
layer. That's two different ideas. Don't make a middleware
change be the trojan for your desire of having "our own"
DB-API adapter, however attractive the latter may seem. It
doesn't make sense to implement/maintain another DB API
adapter.

> What am I proposing? To use this or something like it instead? Of course 
> that's what I'd like
> but I'm realistic, that the other coders seem happy with the status quo and 
> aren't facing the
> same tasks Richard and I are.
I will definitely take a look at what you come up with and
tell you what I think.

I am definitely willing to make your's and Richard's (and
mine !) life easier in that respect.

Karsten
-- 
GPG key ID E4071346 @ wwwkeys.pgp.net
E167 67FD A291 2BEA 73BD  4537 78B9 A9F9 E407 1346
 




reply via email to

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