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



Hi Rick,

<snip>
Maybe I'm missing the boat here, but why couldn't you use the native I/O to
read data into a data structure and then pass the data structure, or
pointer, to the procedure? IIRC, your C example is basically passing a
pointer to the file information into your frobozz function. Unless you need
something other than the data the data structure approach would do the same
think I think.

Something like this (syntax not verified):

D FileDS eds ExternalName(InputFile)

/Free

Read InputFile FileDS;

frobozz(FileDS);

/End-Free

</snip>

Yes, I think you may be missing the boat. :-)

The code in the C example is not passing file information as you see it.
Your code is passing a data-structure containing the information retrieved
from a single read of an already open file. The C example code is using
Ropen() to open a database file and return a file pointer to that open file.
This is very similar in concept to opening a streamfile and passing a file
descriptor. Once you have the file pointer you can pass it to a subprocedure
so it can use it to randomly or sequentially access data from that file.

Consider the following code from my toy db2_utils service program:

d db2_chain pi n
d file 10i 0 value
d key 255a
d recordBuffer * value
d lock n options(*omit:*nopass)

d lw_lock s 10i 0 inz(NO_LOCK)
d lw_recordFound s n inz(*off)

/free

// If lock option not passed - default to no lock...
if %parms >= 4 and %addr(lock) <> null;
lw_lock = lock;
endif;

// If we do not have a valid file - return false...
if file <= 0;
return *off;
elseif openFiles(file) = null;
return *off;
endif;

// Chain...
pRIOFB_T = Rreadk(openFiles(file)
:%addr(stringBuffer)
:%size(stringBuffer)
:KEY_EQ + lw_lock
:%addr(key)
:%len(%trimR(key)));

// If data retrieved - copy to the output buffer...
if num_bytes > 0;
recordbuffer = %subst(stringBuffer:1:num_bytes);
lw_recordFound = *on;
endif;

return lw_recordFound;

/end-free

p db2_chain e


This code should successfully locate a record in the file described by the
file descriptor held in array element openFiles(file), using the key in
variable (er...) key, and load the record format data into variable
stringBuffer (assuming the chain was successful). This code has no knowledge
of the open file described by openFiles(file), or the DS ultimately mapped
over recordBuffer, or the key fields forming the composite key used to
locate the record.

This code would be called after calling subprocedure db2_open() to open the
file. The db2_open() subprocedure returns an integer representing the
element in array openFiles which holds the associated file pointer (which it
stores globally after successfully opening the file). This integer would be
passed to all subprocedures which work on the file (such as db2_close()).
You don't NEED to know what the file pointer is to use it. You just need to
store it somewhere (I use the array openFiles to hold all of my open files)
and pass it to the C apis when required.


James,

You can't get the functionality you request in native RPG file I/O code. But
do you really need to? After all, we now code in ILE not RPG. :-)
You can write a service program to wrap the apis in subprocedures which
presents a more comfortable interface. I'll give you my code to start
playing with if you want it. But I believe you can code in C so you probably
already have your own examples. Also, some things are a pain when working
this way, such as emulating reade with these apis.

If you really, really need to soft-code your database file access then this
is ONE way to go. But there are other ways - consider embedded sql or the
QSQPRCED api. They are both very useful tools. I have a service program in
production for many years which uses QSQPRCED to dynamically create xml data
from database data using nested sql prepared statements. If you want to look
at it you can have the code (I have an agreement with my company that allows
me to provide it free as open source :-) ). It was originally based on a
really cool SQL2XML command written by Beppe Costagliola. But I had to go
back to basics and created a new service program which extended it for my
own specific requirements and it now uses xml templates and multiple nested
prepared statements to build the xml directly from the database.

Pick your toy carefully, but have fun!

Larry Ducie

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.