Forum OpenACS Development: Re: Joining to acs_objects and package-aware packages

Collapse
Posted by Jim Lynch on
Hi,
The current documentation says:
Try not to write queries in your application that join against acs_objects. This means you should never use the fields in acs_objects for application-specific purposes. This is especially true for the context_id field.
Why not?
One reason to not join with acs_objects that hasn't been mentioned is that it might be a performance hit given so many joins to that table are already going on. So the wisdom here, is "leave it alone if you can".

Also, it's critical to separate the semantics of the core from the semantica of the app, because if you don't, then your application breaks when the core changes. Might that happen anyway? Sure. But you protect yourself better if you apply the software engineering concepts of information hiding and factoring to your code.

If you allow the core to hide its information and redundantly store it yourself, what you get is much more freedom from breakage, because you have separated the issues of your app from being affected by issues of the core.

If you have your app's procs and other entities factored properly, then even if you do experience breakage, you don't have as much work to do to unbreak it, since the breakage is likely factored into only one place.

Collapse
Posted by Joel Aufrecht on
This is something that's causing me some conceptual difficulty. The problem is this: ACS introduces a fair amount of overhead, under the rubric of "doing things right the first time." But then a lot of the core system is incomplete, and so, in the worst-case scenario, you end up spending a lot of time and effort for nothing. A lot of people are doing very good work to finish packages and correct semi-implemented architecture; in the meantime, I'm trying to figure out how to get the best tradeoffs for my own work, and how to document them for others to make informed tradeoffs. And this acs_core stuff is a key point.

Making some of the records in your new package acs_objects takes a lot of effort. A bunch of extra code in the database creation scripts, and then many relational integrity links that can make adding and deleting very frustrating if anything goes wrong. What do you get back in return? Access to a fairly clean, simple, and powerful permissions API. And a consistent way to store and access meta-data. What meta-data? Name, owner, creation and modified date, creation ip.

Okay, now how do you access this meta-data? One way is to join, but there is an argument that joining directly breaks information hiding. Another way is to call a function, but as far as I know a function only exists for name, and I've read posts that say it's to inefficient for big queries.

So my questions are:

What's the best way to get to this meta-data now? If there are several, what's the quick rule of thumb to decide which is appropriate?

What architectural stuff is proposed or already happening to change this?

URL seems like another good piece of data to have universally available. I see another thread about how to build this efficiently. How can we move forward on this?

Collapse
Posted by Jim Lynch on
Part of the answer lies in determining what purpose an individual query has in gaining access to the metadata in acs_objects.

If you are going to assume some non-standard interpretation of an acs_objects field, then don't join, store yourself instead.

On the other hand, if you -strictly- interpret fields in acs_objects according to the original meaning and intent, then a join is ok. This means avoiding application-specific interpretations entirely.

This is going to hold true so long as you believe your interpretation of acs_objects field values will continue to hold over the life of the app.

Many people are advocating quick changes to the data model, a surefire way to keep the core unstable. On top of that, interpretations on fields in acs_objects, once correct assumptions, could become package breakers, as a result of changes in how data in core tables is expected to be interpreted.

Lack of maintained documentation will extend that effect over the entire time docs continue to be ignored: if you can't find out the correct way to interpret fields in tables you don't create, how can you build anything that uses those tables and have a reasonable expectation it will work?

What I've said for the acs_objects table holds true for all other tables in the core kernel, and really for any table that you did not create.