Forum OpenACS Development: Chicken and egg problem with content_item__delete

content_item__delete calls plain content_item__del which then goes through a row of different deletions for objects related to the given item. One of these points is to delete all associated revisions. However, this bombs when the live revision is being deleted, because it's referenced by the cr_items.live_revision field of the original item. So what I end up with is an error like:

ERROR:  Referential Integrity: attempting to delete live_revision: 937

The problem is that we can't delete the revision because it's the live revision and we can't delete the item because it still has revisions associated with it.

So how should this be solved? Should the live_revision and latest_revision of the item be nullified before trying to delete it? It should probably be inside the delete procedure, tho.

Posted by Jarkko Laine on
Oh, and the codebase is 5.1 from CVS.
Posted by Jarkko Laine on
OK, tracked this down to trigger cr_revision_del_ri_trg(). Is it a design choice that an item can't be deleted if it has a live or latest revision set or is this a bug? If former, how should a cr item be deleted with a single command whether or not it still has those revisions set? It seems to me a bit counter-intuitive since if an item has any revisions at all, it also has latest_revision. So what phase 3 of content_item__del tries to do is totally pointless since it will raise the abovementioned error always when there's any revisions. And if there aren't, well, there's no need to iterate over related revisions and try to delete them.
Posted by Jun Yamog on
Hi Jarkko,

This is the expected behaviour from what I know. I believe the tcl cr api should be able to handle this. Normally its up to the developer to either unpublish the items first and delete it, or the UI will inform the user that its not able to delete since other users are still using, viewing, etc..

If you are talking about the associated items, I think the relationship must be removed first before deleting the items.

Posted by Jarkko Laine on
Hi Jun,

I was talking about content revisions, not associated objects per se.

If that's the expected behaviour, then why is this in content_item__del:

  raise NOTICE ''Deleting associated revisions...'';
  -- 3) delete all revisions of this item
  delete from cr_item_publish_audit
    where item_id = delete__item_id;

  for v_revision_val in select
                          item_id = delete__item_id
    PERFORM acs_object__delete(v_revision_val.revision_id);
  end loop;

...because there's no idea to delete revisions if the assumption is that there can be no revisions left before calling content_item__delete. From what I found, you can unset the live revision with CR TCL API but not the latest revision (which would not make any sense anyway). Having the latest_revision set will pull the abovementioned trigger as well.

So I don't really see why I would need to delete the revisions by hand before trying to delete the item. I'm working on Simulation which uses bcms and calls bcms::item::delete_item to delete items. bcms::item::delete_item then calls content_item__delete to do the dirty work. I don't think simulation package is the right place to put in code that essentially unsets the live and latest revisions of a cr item and then deletes them. I really think content_item__del should at least be able to delete the revisions (it is after all trying to do it already, with no success) even if it weren't the default behaviour.

Posted by Dave Bauer on
I posted a detailed report in the bug for this:

Basically, content_item__delete works fine for plain content_revision types.

So the error message is not correct. Something else is causing a RI error, and the pl/sql proc is returning that message although its not the actual error.

More debugging is needed. Any details you can give would be really helpful.