Forum OpenACS Development: Clean delete of packages

Collapse
Posted by Jon Griffin on
Right now to delete a package you must remember to call many functions in your -drop scripts.

  • delete plsql functions
  • delete from acs_permissions
  • delete custom permissions
  • acs_object_delete
  • acs_object_type__drop_type - this doesn't need the boolean

Should there be a way to just call one proc and have most of this done automatically? It seems a lot less error prone

Collapse
Posted by Tom Jackson on

When we find out, I'll be happy to add it to my query-writer package. It currently drops most stuff (it writes the package-drop.sql file).

Collapse
Posted by Tilmann Singer on
The custom permission deletion has been added recently to acs_object.delete in the oacs-4-6 branch. There is no upgrade script for that, but dropping and recreating the pl/sql package should do it - I guess with Don's new permission stuff there will be an upgrade script that drops and recreates the package anyway.

And I don't see the difference between these two:

delete from acs_permissions
delete custom permissions

Did you mean: delete from acs_privileges for the first one?

Collapse
Posted by Peter Marklund on
Jon,
I am changing the package delete page in the APM UI so that it unmounts and deletes all instances before deleting the package. That way, by using APM Tcl callbacks we are able to cleanly delete workflow and bug tracker from the APM UI.

IMHO permissions should cascade, or if we don't want to cascade, why don't we delete them in acs_object__delete? Analogously I just set up lang_message_keys to cascade from package_key.

I think non-cascading constraints are a major headache and I also think they can cause serious problems. What if package A sets a constraint on an object in package B. When package B tries to delete its object it fails because package A (that package B has no knowledge of) has it referenced. Isn't this just plain wrong? I think all composite relationships should be cascading constraints (permissions are a perfect example, they can't exist without the party, privilege, or object that they are made up of).

The only thing that could convince me that cascading is bad is the warning I got from Jeff Davis that cascading can cause locking issues or other problems. I don't understand yet why that would happen but if somebody can explain it to me or even better show how it happens in OpenACS in practice I would be more than willing to change my mind.

Collapse
Posted by Tilmann Singer on
Peter,

<blockquote> why don't we delete them in acs_object__delete?
</blockquote>

That's exactly what's happening now. The reason not to use cascade in this case was just that it was simpler because it doesn't require complicated upgrade scripts, just reloading the pl/sql (plpgsql) code.

The reason not to use cascade in many other cases is one most strongly made by Dirk (on irc, maybe also somewhere in this forum), that deletion of data in general is a bad idea, and there is no need to jump trough loops to enable it everywhere in the toolkit. The foreign key constraints are thus a good thing, because they prevent you from deleting data that is referenced from somewhere else. A good example for this is the user object - you almost certainly wouldn't want a system that deletes on cascade all objects a user has references to, directly because he created them or somehow indirectly. We might just have to accept that in a highly referenced data like in OpenACS things like users are just not deletable.

Collapse
Posted by Peter Marklund on
Tilmann,
of course instead of deleting a user you can flag him as deleted or nuked if you want the data to be archived. However, that issue is hardly relevant to the on delete cascade discussion. In the event that you really want to delete the user you must delete all his data if you use cascading or not. That task is just made all the more easier if you have cascades.

My point is that it's wrong to create an application or service that references objects so that the kernel and/or other applications can't delete their objects anymore. There might be a better way than cascading to make sure things are deleted, maybe by using triggers? There certainly isn't an easier way though than using on delete cascade.

Collapse
Posted by Jeff Davis on
I don't know Peter, if I were writing an ecommerce package and
had unpaid invoices that referenced users I don't think
I would want on delete cascade on the invoice table.
Of course, you may be much more forgiving of people who owe
you money than I am :)
Collapse
Posted by Don Baccus on
You wouldn't want to use ON DELETE CASCADE blindly, of course.  Judicious use would really simplify a lot of code, though.  I had this argument with Richard Li and others three years ago and lost, though.

The unpaid invoices problem can be solved a couple of different ways ... don't use ON DELETE CASCADE for this particular case or use it but define a BEFORE trigger on the users table and block the deletion of a user if there's an unpaid invoice, while allowing it to go through if there's not.

I'd rather deal with special cases like this than the current mess we have where a bunch of different packages won't let you delete things.

For instance my last round of commits involved fixing the notifications package so you can delete a notification request if there are still unsent notifications pending.  Rather than bomb, which is what it did until I fixed it.

Whether you disagree or not, though, don't worry ... writing upgrade scripts to add the constraints and modify the various delete procs would be a extremely painful process, particularly in current versions of PG with its rather weak ALTER command.

Collapse
Posted by Paul Huibers on
I have been dropping packages as part of an upgrade from ACS 4.2 to OpenACS 4.6.  It is easy to drop the Oracle objects created in the package-create scripts, but so far I have ignored the metadata in ACS.

Has anyone written a script to check the database for orphaned  ACS objects?  It would be useful to check for permissions, objects and object types that are not referenced anywhere.