Discussion:
[Modeling-users] dirty deeds done dirt cheap
Marcos Dione
2004-03-24 18:21:02 UTC
Permalink
User-Agent: Mutt/1.3.28i


I have the following problem: I have a form where I can edit
Modeling Entities. if you perss a button, it gets saved (the changes, I
mean). but if you press that other button, it should revert any changes
done so far. the Modeling Entities are not saved yet (if you saved
alredy, I'm sorry :)

flipping the docs I see that EditingContext is capable of tell
wether it's dirty or not. but I think it would be better if I could ask
the Entity if it's dirty or not; and, being dirty, ask it to ignore any
changes not saved (which I think will resort to reload from the db)...

note that this seems to have nothing to do with undo/redo, or at
least I think so.
Marcos Dione
2004-03-24 20:38:01 UTC
Permalink
User-Agent: Mutt/1.3.28i
Post by Marcos Dione
flipping the docs I see that EditingContext is capable of tell
wether it's dirty or not. but I think it would be better if I could ask
the Entity if it's dirty or not; and, being dirty, ask it to ignore any
changes not saved (which I think will resort to reload from the db)...
I note two things: first, asking an Entity if it's dirty or not is
impossible w/o an EC, so is unreasonable to ask for it. second, the
answer seems to be to use nested EC's, but if I do it that way, for
reseting I would need to discard the dirty EC, take a new one and
repopulate it with the original values (most probably this two EC's will
be child of one master EC at different times).

what's not clear for me is how to repopulate the second EC.
Sebastien Bigaret
2004-03-24 22:03:07 UTC
Permalink
Post by Marcos Dione
Post by Marcos Dione
flipping the docs I see that EditingContext is capable of tell
wether it's dirty or not. but I think it would be better if I could ask
the Entity if it's dirty or not; and, being dirty, ask it to ignore any
changes not saved (which I think will resort to reload from the db)...
I note two things: first, asking an Entity if it's dirty or not is
impossible w/o an EC, so is unreasonable to ask for it.
Absolutely, the standard way is to ask the ec for that --even if some of
the CustomObject's methods can be relative to the editingContext(), such
as globalID().
Post by Marcos Dione
second, the
answer seems to be to use nested EC's, but if I do it that way, for
reseting I would need to discard the dirty EC, take a new one and
repopulate it with the original values (most probably this two EC's will
be child of one master EC at different times).
what's not clear for me is how to repopulate the second EC.
Repopulating the EC simply consists in fetching the objects, or asking
for a particular object given its globalID (ec.faultForGlobalID()), etc.

Now you may need a simpler way of doing this, esp. if you're dealing
with one object or a few: the nested ECs are very handy when the
modifications of the graph of objects can be very intensive and you do
not want to track which changes occured. But if you know exactly which
object(s) is/are impacted (which is probably the case in any simple
form), you may just ask for forgetting about the changes --what you were
asking for in your 1st post.

I've just submitted patch #922822 with an up-to-date version of one I
posted a year ago (almost: 26 Mar 2003 :/ )
https://sourceforge.net/tracker/index.php?func=detail&aid=922822&group_id=58935&atid=489337

The comments there contain references of the messages talking about
this feature.

It also contains a test case for that. The idea is that you simply
call ec.refaultObject(obj), and the object is reverted back to a fault,
ready to be retrieved from the database next time one of its
properties' value is needed.

It's not been extensively tested, and should be used w/ care for the
moment being; see comments for patch #922822. As noted there, it's
been asked regularly, but even then I've never heard that it has been
really tested. Handle w/ care ;) but hopefully it will be of some
help, and maybe we could finally make it and finally integrate this
into the main trunk some day. So I'll be happy to hear from you if you
find some time to experiment!

-- Sébastien.
Marcos Dione
2004-03-25 19:10:03 UTC
Permalink
User-Agent: Mutt/1.3.28i
Post by Sebastien Bigaret
Repopulating the EC simply consists in fetching the objects, or asking
for a particular object given its globalID (ec.faultForGlobalID()), etc.
well, I was thinking in that yesterday when I left work... is it too
ugly to do it that way? will it mess with something?
Post by Sebastien Bigaret
Now you may need a simpler way of doing this, esp. if you're dealing
with one object or a few: the nested ECs are very handy when the
modifications of the graph of objects can be very intensive and you do
not want to track which changes occured. But if you know exactly which
object(s) is/are impacted (which is probably the case in any simple
form), you may just ask for forgetting about the changes --what you were
asking for in your 1st post.
[snip]
Post by Sebastien Bigaret
It also contains a test case for that. The idea is that you simply
call ec.refaultObject(obj), and the object is reverted back to a fault,
ready to be retrieved from the database next time one of its
properties' value is needed.
It's not been extensively tested, and should be used w/ care for the
moment being; see comments for patch #922822. As noted there, it's
here are those comments:

--- paste ---
I've quickly checked the implementation & at the test I proposed there,
so here is my suggestion: you can use it as-is, given that:

- you're not applying it on deleted, inserted or modified objects, (BTW:
it will become an error to refault a deleted or an inserted object)
[UPDATE: see note, below]

- you stick to EC.refaultObject and do not try to call
DBContext.refaultObject

- you do not use it with a nested ec.

(I'm not saying this won't work, it probably will... but it needs to be
tested before I can say this is supported).
--- paste ---

that last remark applies to the last contition? from the patch, it
seems like the refaultObject is finally done by the 'master' of all the
EC's. do you think the problem would be that the 'reset' is not
'propagated' to children EC's?

the other comment is (I think this is the update you mention above):

--- paste ---
Note: it can be safely applied on modified objects given that no
relationships have been modified (such a situation has not been tested
at all).
--- paste ---

I'll try to make some tests in both cases.

it is interesting to note that most of this patch is already in the
slice_n_sort patch. is that an error? shouldn't this other one depend on
the first one, so applying both doesn't choke?
Sebastien Bigaret
2004-03-25 20:34:02 UTC
Permalink
Post by Marcos Dione
Post by Sebastien Bigaret
Repopulating the EC simply consists in fetching the objects, or asking
for a particular object given its globalID (ec.faultForGlobalID()), etc.
well, I was thinking in that yesterday when I left work... is it too
ugly to do it that way? will it mess with something?
No it's not: GlobalIDs are especially designed to designate a specific
object/row, and using a child EC has several advantages. I was just
saying then that the features it provides [mostly: "OO-transactions" and
inheriting the changes made in the parent EC(s)] may be oversized if all
you need is to forget the state of one or a few objects.

And if you mess with something when doing it this way, that means you've
probably been bitten by a bug.
[...]
Post by Marcos Dione
--- paste ---
I've quickly checked the implementation & at the test I proposed there,
it will become an error to refault a deleted or an inserted object)
[UPDATE: see note, below]
- you stick to EC.refaultObject and do not try to call
DBContext.refaultObject
- you do not use it with a nested ec.
(I'm not saying this won't work, it probably will... but it needs to be
tested before I can say this is supported).
--- paste ---
that last remark applies to the last contition? from the patch, it
seems like the refaultObject is finally done by the 'master' of all the
EC's. do you think the problem would be that the 'reset' is not
'propagated' to children EC's?
- Exactly, it is indeed propagated down the EC hierarchy, then to the
ObjectStoreCoordinator and ultimately to the DatabaseContext
responsible for the object's entity.

- The last remark was targetted to the three conditions. You may
wonder why making this available to non-modified, permanent objects ->
reason is that it was initially designed to make it possible to
"release" objects in ECs, e.g. to keep the number of held objects
under a certain limit: releasing an object also release memory (from
db caches, mostly).

However it's applicable to modified objects, as shown in the test.

- About the propagation of reset up the EC hierarchy: it's not done and
this is a problem. Most probably, the rest of an object wil also reset
it in its parents. But even then, this is only a proposal for the
default behaviour, and one ec should be able to provide its own
response to the refault notification coming from a parent, for example
through a delegate.


NB: however to test it w/ modified objects the following lines in
EC.refaultObject() should be disabled --my fault:

if gid in self._pendingUpdatedObjects+self._updatedObjects:
raise ValueError, 'Cannot refault a modified object'
Post by Marcos Dione
--- paste ---
Note: it can be safely applied on modified objects given that no
relationships have been modified (such a situation has not been tested
at all).
--- paste ---
I'll try to make some tests in both cases.
it is interesting to note that most of this patch is already in the
slice_n_sort patch. is that an error? shouldn't this other one depend on
the first one, so applying both doesn't choke?
You're right! I was not even able to find a difference, it's completely
included in patch #892454... I have several tests configurations here
and it seems that one got integrated in the other. Thanks for noticing,
I'll add a note to the patches'page.

-- Sébastien.

Loading...