PrePAN

Sign in to PrePAN

PGObject Toolkit for integrating PostgreSQL stored procedures into objects

Author
einhverfr@github
Date
URL
Status
Shipped
Good

Synopsis

To get basic info from a function

  my $f_info = PGObject->function_info(
      dbh        =>  $dbh,
      funcname   =>  $funcname,
      funcschema =>  'public',
  );

To get info about a function, filtered by first argument type

  my $f_info = PGObject->function_info(
      dbh        =>  $dbh,
      funcname   =>  $funcname,
      funcschema =>  'public',
      objtype    =>  'invoice',
      objschema  =>  'public',
  );

To call a function with enumerated arguments

  my @results = PGObject->call_procedure(
      dbh          =>  $dbh,
      funcname     => $funcname,
      funcschema   => $funcname,
      args         => [$arg1, $arg2, $arg3],
  );

To do the same with a running total

  my @results = PGObject->call_procedure(
      dbh           =>  $dbh,
      funcname      => $funcname,
      funcschema    => $funcname,
      args          => [$arg1, $arg2, $arg3],
      running_funcs => [{agg => 'sum(amount)', alias => 'running_total'}],
  );

Description

PGObject contains the base routines for object management using discoverable stored procedures in PostgreSQL databases. This module contains only common functionality and support structures, and low-level API's. Most developers will want to use more functional modules which add to these functions.

The overall approach here is to provide the basics for a toolkit that other modules can extend. This is thus intended to be a component for building integration between PostgreSQL user defined functions and Perl objects.

Because decisions such as state handling are largely outside of the scope of this module, this module itself does not do any significant state handling.
Database handles (using DBD::Pg 2.0 or later) must be passed in on every call. This decision was made in order to allow for diversity in this area, with the idea that wrapper classes would be written to implement this.

This module provides what are essentially bottom-half services for other modules which create developer-friendly API's. One would do well to see this as the "database-facing" piece of a framework for integrating stored procedures in a flexible and yet robust manner.

Comments

As a note, this is intended to be the first of five related modules which create a toolkit for incorporating stored procedures and udf's into objects seemlessly and quickly. The others are:

- PGObject::Simple, which implements a simple object property to argument name mapping interface with overrides
- PGObject::Simple::Role, a Moose role which wraps PGObject::Simple in an antlered interface
- PGObject::DateTime, a DateTime wrapper class with PGObject and user localization support
- PGObject::Numeric, an arbitrary precision arithmetic wrapper class with PGObject and user localization support
1) Namespace. You're trying to use a new root namespace, why not try DBIx::Pg:: or something? DBIx::Pg already exists, and that is where I would search for a module like yours.

2) I would suggest considering OO-style interface, like

my $pgo = PGObject->new(dbh => $dbh);
$pgo->function_info(...);

Most people only need one database handle, and providing it every time could be an annoyance.
Hi dallaylaen, just a couple clarifications.

First, PGObject is intended to be a db-facing side of a framework. It isn't really intended to be application facing. This is why the problems are generalized. If you are using calls to this module in a lot of places, you are using this far differently than imagined. In short this is a framework framework, not an application framework.

Secondly (and why the namespace decision), this is put where it is because it is intended to be the db-facing side of a family of database-centric object frameworks. Right now I am working on two of these object frameworks (with and without Moo role wrappers), namely "PGObject::Simple" and "PGObject::CompositeType." For example if you use the Moo role PGObject::Simple::Role, your class gets to specify a way to retrieve the database handle (which could be done in a wrapper for your application, removing the need to pass it from your application code at all).

Because the emphasis on the family is on an object model rather than on db access, I am not sure that putting it under DBIx would do anything other than lead to very long namespace names, and the wrong emphasis.

I recognize my above could have been clearer. I am hoping to get DBObject::CompositeType out some time in the next few months. But before then I have paying work to do :-)

Please sign up to post a review.