[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Proposal for LedgerSMB 1.5: Refactor and move some utility functionality to CPAN

On Tue, May 28, 2013 at 12:37 AM, Kaare Rasmussen <..hidden..> wrote:
Hi Chris

Thanks for releasing the code. Some initial feedback, based on the description. I haven't tried the module(s) yet.

Name. Why not Pg::Object and Pg::Object::Simple.
The description leads me to believe that PGObject would be better as a Moose role. Especially "Most developers will want to use more functional modules which add to these functions." and the note about state handling.

I thought about it, but there is already a Pg.pm which is  not officially maintained, but fills a very different role.  I figured might not be great to send mixed messages there.

The idea is that the PGObject namespace would be a set of related systems of integrating stored procedures into object-oriented Perl programming.  The docs might not be as clear as I would like so I will probably see what I can do to make them clearer.  You aren't entirely off-base, but hopefully this will make things clearer.

PGObject interface systems can be thought of as consisting of a top half and a bottom half.  The bottom-half is db-facing and provides interfaces which interface systems use to interact with the database.  The top-half consist of developer API's  for integrating these into objects.   So PGObject and PGObject::Simple actually serve different functions.

PGObject::Simple looks like a class consuming that role.

Not quite (I can see how it looks that way though).    PGObject itself is essentially a singleton which glues three things together:

1.  the database
2.  "top-half" modules like PGObject::Simple.
3.  PGObject-aware types.  This support is getting stronger for 1.1, and requires storage in the module of some global state (state intended to be more or less run-time configuration parameters instructed by other modules).

The interfaces provided are therefore essentially to allow the top half modules to talk to the database, and for PGObject-aware types to plug themselves into the process.  Top half object systems and roles then use these services to fill their needs.  PGObject::Simple for example has no function_info function exposed to the world even though it uses this as an integral part of its own operation (there really wouldn't be a point).

The reason to release PGObject::Simple is that it is almost compatible with what we did with LedgerSMB::DBObject in LedgerSMB 1.3.  It is a complete class in itself that can be used as a base class relatively easily with a great deal of transparency and very little abstraction except when it comes to stored procedures.  It is sort of the quick and dirty approach.  It would not take much effort to either wrap our existing call structure around what is in PGObject::Simple, or just port to it.  In general it has some very good things about it along with the bad, and it makes it very easy to build Perl scripts which interact with PostgreSQL databases.

Obviously this isn't really that great in some cases.  So in 1.4 we wrapped this in LedgerSMB::DBObject_Moose which is a role.  I am looking at replacing this with PGObject::Simple::Role, which wraps PGObject::Simple functionality in a Moo role so it can be incorporated in Moose and non-Moose applications with a minimum of dependencies.

So what I am getting at is that PGObject and PGObject::Simple encapsulate different functionality with different audiences in mind.  There is some overlap in terms of calling stored procedures, but the overlap there somewhat deceptive.  PGObject encapsulates the lower-level database operations for developer-facing models and integrated types.  Developer-facing models encapsulate stored procedure conventions.  Integrated types allow you to say "I want this class to be instantiated on every date value retrieved from the database."

Does this help make things clearer?  Or is it still confusing?

Best Wishes,
Chris Travers