× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



I believe that we have come up with a solid implementation of a Service program DB abstraction layer in RPG. We have been creating a fairly large new CGI app (over 100 files) from scratch for the past year and decied to create a DB abstraction layer for the entire app. When it was proposed, I thought it was a crazy idea. I thougt all we would be doing was createing DAO's but this is not true. I created a tool that builds a module for each file. We then only have to manually create a routine if we want to get the data in a strange new way, but then I would have had to do it anyway with tradional code and in every program that I wanted to use it. This way I only ever have to code it once and it is hidden. This has saved us 10's of thousands of lines of code.

Some other benefits:
I never have to wory obout coding a F spec, I just prototype in the file or the service program and access the field I want.
I don't have about chains, setll reade or record locking, It just all happens under the covers.
We don't need to create an index before writing a program, since all access is through SQL we just periodically check the index advisor and let it create what it needs.

I don't think I will ever write another RPG app without a DB abstraction layer.

Answeres to Aaron's questions:
1. All files get one.
2. We return a indicator on a record load call, or on any other call we set the SQL CPF Message and use another method (subprocedure) to retrieve it.
3. Each field has a getter that returns it's data.
4. opOrderbyCust(CustId);
dow getNextCustOrder();
// Process the records here.
endDo;
5. We never lock a record. The DAO automaticaly checks for record changes on a update.
6. stCustOrderDesc('this is the order');
insertCustOrder(Custid:OrderId);

If I only need to get one record I would just call the routine for whatever field I need. For example gtCustOrderDesc(CustId:OrderId);

Chris Beck

albartell@xxxxxxxxx 9/25/2007 5:05:12 PM >>>

Couple questions:

1 - What is your criteria as to whether or not a file gets an RPG *SRVPGM IO
layer put in front of it? Or should all files potentially have a wrapper in
your approach?
2 - How do you relay record not found?
3 - How do you return information back to your program?
4 - How would you do a SETLL, READE, DOW not %EOF loop?
5 - How do you do a READ/CHAIN for lock vs. no-lock?
6 - How do you WRITE records to a file?


Some of the above are semi-rhetorical, simply because I have already been
down the road of what you are proposing. But I would be interested to know
if somebody came up with a solid and reasoned implementation of *SRVPGM IO -
I have yet to see one that is well reasoned other than going on a
case-by-case (read file-by-file) basis.

Aaron Bartell
http://mowyourlawn.com


-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx]
On Behalf Of Cassidy, Alan
Sent: Tuesday, September 25, 2007 4:40 PM
To: RPG programming on the AS400 / iSeries
Subject: RE: MVC in RPG?

-----Original Message-----
On Behalf Of albartell
Could you post an sample of your approach for review? I am curious to know
how you address partial key chains/setlls/reades/etc, and how you address
PF's with multiple logicals.


__I didn't do it full-blown but have done a little bit of "offloading"
some I/O to a service program, like for validating screen selections and
other things.

I *think* I like the idea for building new applications or application
"suites" from "scratch", since this would make it easier to do things with
the apps. If not for the limitation of the deadline, for example, it
certainly would have made Y2K a lot easier for a bunch of shops (like mine).

(And the way some shops did it, 2040 will bring Round 2)

For partial key lists to get at a logical, I just used %parms inside the
procedure to count them and do a select list to separate a CHAIN (or
SETLL) for example.

Select
When %parms >= 3 ;
Chain(e) (key1: key2: key3) OrdFile ; When %parms >= 2 ;
Chain(e) (key1: key2 ) OrdFile ;
When %parms >= 1 ;
Chain(e) (key1 ) OrdFile ;
When %parms < 1 ;
Read OrdFile ; // (Didn't use this one, but you could...) EndSL ;

I would suppose you could use %KLST from a DS, and calculate how many fields
from the %parms, but you'd need to load the KLST fields.

You could even set up a STATIC field to track whether it's the first time
in, to determine whether to do a SETLL/READE or just a READE.

I've thought that this might be useful in the stead of using triggers, IF
->ALL<- your DB access to a file was through this method, because among
other things, it would save the maintenance baggage. That's one reason they
haven't used triggers where I work, where it would complicate administration
for HA with journaling, for example. (Don't ask; too many files, libraries,
environments, etc).

--Alan


-------------------------------------------------

This email transmission and any documents, files or previous

email messages attached to it may contain information that is

confidential or legally privileged. If you are not the intended

recipient, you are hereby notified that any disclosure, copying,

printing, distributing or use of this transmission is strictly

prohibited. If you have received this transmission in error,

please immediately notify the sender by telephone or return

email and delete the original transmission and its attachments

without reading or saving in any manner.



The Evangelical Lutheran Good Samaritan Society.

---------------------------------------------------------

As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.