[ZODB-Dev] Can I abort part of a transaction setting self._p_changed=0 ?

Michel Pelletier michel@digicool.com
Thu, 28 Jun 2001 13:13:24 -0700 (PDT)


On Thu, 28 Jun 2001, Steve Spicklemire wrote:

> Hmm.. so either this question was:
> 
> 1) Totally unclear and therefore unanswerable
> 
> 2) Totally stupid and therefore not worth the time ... or.. 
> 
> 3) So far out that nobody really knows... 
> 
> In case it's (1) I should clarify that by 'self.CommitObject', I mean
> "export self as a .zexp/.xml to CVS (or something)". 

That was definatly a confusing part.

> does that help? I is (2)? I can't believe it's (3), but if so... I
> should start digging in the code.
> 
> def CommitMetaDataOfObjectManager(self, anObjectManager):
> 
>         holder = anObjectManager._objects
>         delete anObjectManager._objects
>         result = self.CommitObject(anObjectManager)
>         anObjectManager._objects = holder
>         return result
> 
> so that the 'committed' objectManager is stripped of it's objects,
> committed, and then it's objects are restored. (it would be great if
> ObjectManager could present an interface that did that!). The problem is
> that fiddling with _objects will set the _p_changed flag and introduce
> an unwanted side effect of updating ZODB. Can I force _p_changed=0?
> Would that make this a thinkable possibility?

I just looked at cPersistence.c, and it looks like you *can* set
_p_changed to 0.  But I'm not expert, so I'll let *you* make the call
(excerpted from _setattro):

 if(name[3]=='c' && strcmp(name+4,"hanged")==0) 
   {
     if (! v)
       {
         /* delatter is used to invalidate the object
            *even* if it has changed.
          */
         if (self->state != cPersistent_GHOST_STATE)
           self->state = cPersistent_UPTODATE_STATE;
         v=Py_None;
       }
     if (v==Py_None)
       {
         v=PyObject_GetAttr(OBJECT(self), py__p_deactivate);
         if (v) { ASSIGN(v, PyObject_CallObject(v, NULL)); }
         if (v) { Py_DECREF(v); }
         self->state=cPersistent_GHOST_STATE;
         return 0;
       }
     if (PyObject_IsTrue(v)) return changed(self);
     if (self->state >= 0) self->state=cPersistent_UPTODATE_STATE;
     return 0;
   }

It looks to me like the if(!v) clause is checking to see if the value
is 0 and setting the objects state to cPersistent_UPTODATE_STATE.  The
if(PyObject_IsTrue(v)) clause looks like it's calling change().

-Michel