I agree with Eric.
I would add that "encapsulating" the database (in the manner that Kurt
has demonstrated) doesn't provide much encapsulation. The caller still
has to know which tables (PFs) he's accessing, and what the keys are to
that table, etc. If you changed the underlying storage method, the
caller would need to be changed to reflect that. Where's the
encapsulation?!
So you're doing your "chain" in a SRVPGM instead of the same source
member. So what? You still need to understand the tables and their
relationships, you still need to code all that into your program. you
still need to code the record retrieval methods (such as "chain") into
your program.
What on earth is this gaining you other than added complexity? How will
this save development time, ease development efforts, support efforts,
or improve the user experience?
Code your logic based on the business transactions you need to perform,
not the underlying method that you're using to perform them! That's how
you encapsulate things.
A routine, for example, to retrieve inventory for a given SKU might look
like this:
if item_getInventory( sku : InvArray ) = FAIL;
errMsg = item_getLastError();
// log error
endif;
Here you are working with business objects. You sell items, so you need
to know what's in inventory. You identify your items with a sku, so you
pass that sku as a parameter. InvArray is returned and is an array
containing a list of inventory locations, quantities, etc.
All the business logic needed to retrieve inventory for a SKU is
encapsulated into the item_getInventory() routine. The caller doesn't
need to know which database table(s) the data is stored in. It doesn't
need to know what gyrations you have to go through to look up the
inventory values. In fact, the data might not be in a databaase at
all... maybe it's in an XML file in the IFS, or maybe it's accessed
through a web service from some remote location... all of that will work
fine because the caller makes no attempt to know how that data is stored.
Compare that to Kurt's approach:
$declareItemMast( *off: sku );
$chainItemMast();
$closeItemMast();
// no idea how I'm supposed to get fields.
$declareInventory( *off : sku: itemstgcode );
$setllInventory();
dow $readeInventory() = SUCCESS;
// combine fields from both ITemMast and Inventory
// tables to get needed inventory data.
enddo;
$closeInventory();
Now your caller needs to know that part of the needed data is in the
"itemmast" table, and part is in the "inventory" table (and who knows
what else would be required in a "real world" application instead of
this simple example I threw together)
It has to know which fields are in which table, etc. It has to
understand that these are database tables that are keyed in a particular
way. If you want to change any of that, you have to rewrite both the
caller and the database "encapsulation" *srvpgm, because they are
inextricably linked.
What's the point? If you're going to take Kurt's approach, why not
simply do the SETLL/READE or CHAIN in the RPG program to begin with?
you haven't gained anything over and above that approach.
In my (and, presumably, Eric's) approach, you achieve some layer of
independence from the database itself. In Kurt's, you really don't.
That's my thought, anyway.
On 4/4/2012 11:13 AM, DeLong, Eric wrote:
Which is really not of much value when writing RPG applications... I'm just saying, it never made much sense to me... RPG is inextricably tied to DB2i, and given the simplicity and power of database I/O within RPG, why try to achieve database independence.
To me, for business development, the transaction is everything... You "do stuff" with "things". Your "things" are business-centric concepts, like Customer, Product, Address, Invoice, A/R Account, etc. "things" are described as data structures, which can be used by your procs to pass metadata, not record formats...
Oh well, we know all about opinions, right? ;-)
-Eric DeLong
As an Amazon Associate we earn from qualifying purchases.