× 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.



Quite the contrary I believe that they can actually make life easier for the new comer. For example we have a purchased app with over 1200 files, and the database design absolutely sucks it has over 8 master files with names in it. We can take and generate the DB code then tweak it so that it reads the correct master file in the correct situation. This way as a consumer of the procedures when I want a Resident name, I don't have to hunt around and decide what file to use all I have to do is say getResName(resAcctNum) and not worry about it.

3. When a work variable is needed, it is declared with a Like() this way on a field change we would only need a recompile, and our CM software handles all that. We have found that we actually need very few work fields since you can just call the getter when you need to value.

4. The DB layer would signal and error. This also comes down to your idea of a good design. I would not call a routine that loops through the file that you are already processing.


Lim.Hock-Chai@xxxxxxxxxxxxxxx 9/28/2007 1:45:43 PM >>>

Sorry, I've to disagree.

It would be critical and beneficial for programming language that does
not auto generate file DS during compilation or language that does not
support EXTNAME/LIKEREC keyword. However, I don't see much benefit of
create you own DB layer in RPG apps. RPG has such a robust file IO
functions that create you own IO would probably just confuse the new
comer.

Just curious as how do you normally handle situation below:
3. Each field has a getter that returns it's data.
How do you normally declare the variable in the program that uses the
getter method? What happen if a field in the file needs to be changed.

4. opOrderbyCust(CustId);
dow getNextCustOrder();
// Process the records here.
endDo;
If you happen to need to call an existing procedure within the DOW and
this procedure accept CustID as parm, how can you be sure that this
existing procedure does not call getNextCustOrder and mess up you loop?





-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx
[mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of chris beck
Sent: Friday, September 28, 2007 9:07 AM
To: rpg400-l@xxxxxxxxxxxx
Subject: RE: MVC in RPG?

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 is the RPG programming on the AS400 / iSeries (RPG400-L) mailing
list To post a message email: RPG400-L@xxxxxxxxxxxx To subscribe,
unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives at
http://archive.midrange.com/rpg400-l.




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

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.