[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [GNUe] [Bug] gnue-forms / gnue-appserver: OnChange / abort / editabl
Re: [GNUe] [Bug] gnue-forms / gnue-appserver: OnChange / abort / editable="new"
Tue, 06 May 2008 09:55:48 +0200
Am Montag, den 05.05.2008, 19:29 +0200 schrieb David Ayers:
> > Second, I could not reproduce the behaviour with OnChange but only with
> > OnValidate. Could you please double-check?
> Ahm... yes I haven't implemented OnValidate, but actually the check
> I'm making /should/ be implemented in OnValidate... especially if I
> call abort. So unless you want me to debug thism I would 'correct' my
> code and go from there.
abort is valid in both OnChange and OnValidate. However, with abort
running in OnChange, gnue-forms behaves as expected for me.
> > Third, the behaviour is *somewhat* correct for OnValidate: Since
> > OnValidate only runs on commit, the data is already written to Appserver
> > and the object *does* exist, but the transaction is not yet committed.
> > The object is very much in a status like a record in a SQL database is
> > between the INSERT and the COMMIT statements.
> > We might have to think a lot more about exception handling and handling
> > of started but unfinished transactions, but at least I wouldn't consider
> > this a clear but which can be fixed without some deeper thought about
> > the basic concepts.
> Well let's look at this... the reason to implement OnValidate is to
> insure the data is, well, valid and consistent. The purpose is to
> raise an exception when the data is invalid.
> From the documentation:
> `OnValidate' can prevent the commit to happen if it raises an
> exception with `abort' or by other means.
> [Now I'm not sure what the 'other means' refers to wrt the prevention
> but let's ignore that for now.]
It means to raise an exception by other means than "abort".
> In my case it validates that a property contains valid input before it
> is stored and subsequently changed to a non-editable read-only
> So the expectation of a naive application developer like me would be
> that if validation fails as documented (ie an abort), the entire
> transaction from the view of the appserver should be rolled back as if
> it never happened and the client that requested the commit is
> The client should keep it's state as just before the commit was
> requested. Which is why I believe the commit method should return
> return True/False to let the application act accordingly.
I think it is important here to understand that Appserver distinguishes
between storing changes and committing a transaction. In other words,
Appserver knows the concept of uncommitted changes.
A form developer might want to display an updated value of a calculated
property even before the user presses the "save" button. Currently, this
can be achieved by calling the "update" function of the block. This
sends the changes to appserver, but does not yet commit them.
Another use of this concept is when you call a server side function
before the user has hit the "save" button: to run the function properly,
Appserver must receive the latest changes, but they may not yet be
committed because in the end, the user can choose to not "save" his
changes at all.
So basically, there's 2 distinct operations: store and commit.
Pressing the "save" button does both.
Calling any appserver function from the form only does store.
Calling block.update() only does store.
Now for the procedures:
OnChange runs on what we call "store".
OnValidate runs on what we call "commit".
Whenever OnChange raises an exception, the "store" operation for this
record is aborted, and both appserver and the form go back into a state
as if the user hadn't pressed the "save" button at all (at least
regarding the record that caused the exception).
Whenever OnValidate raises an exception, the "store" operation has
already been successful, and the "commit" operation is aborted. So both
appserver and the form are in a state of "uncommitted change". If you
think of SQL databases, an exception in OnValidate means like the
"INSERT INTO" has already run but the "COMMIT" hasn't. So forms has to
be aware that it is not any longer a new object - if there are
subsequent changes to that object, it has to be sent to Appserver as an
update rather than a creation of a new object.
A possible solution might be that the form considers an already inserted
but not yet committed record as a "new" record when it comes to things
like the editable flag.
If all of this wasn't too confusing and you were actually able to follow
this - what do you think about it?
> A have worked with a few persistence frameworks and from my
> experience, contrary to the current gnue-appserver documentation, I
> think it should be considered an error to allow changes during
> validation. Instead an extra pass (let's call it OnChange ;-) )
> should allow all changes and propagation there of... in memory before
> validation. The subsequentOnValidate should only be allowed to verify
> that things are consistent before the state gets stored.
In fact, the possibility to allow changes in OnValidate has made us
quite a headache, especially in making sure that changes that happen in
OnValidate are then subsequently also validated properly.
How do other frameworks handle changes that happen in OnChange? Do these
changes also trigger OnChange again, recursively? How do they avoid
endless recursion loops?
Description: Dies ist ein digital signierter Nachrichtenteil