HP3000-L Archives

November 2012, Week 1

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Denys Beauchemin <[log in to unmask]>
Reply To:
Date:
Tue, 6 Nov 2012 09:53:14 -0600
Content-Type:
text/plain
Parts/Attachments:
text/plain (110 lines)
Strangely enough, I received several private messages asking for details on
what I found wrong in the manual.  So, instead of responding separately, I
thought I would post here and have the answer stored in the archives as one
person suggested.

We developed a transpiler that takes BASIC code from MPE and spits out C
code that runs on Unix/Linux.  We migrated a huge application with this
transpiler and the customer elected to continue to maintain the existing
code in BASIC and just retranspile it every time as it only takes a second
or so.  It's also easier for their BASIC developpers to support the
application.

However, now that they are using Oracle as their database they want to use
more features of it from the program itself, yet still maintain the
immediacy of BASIC transpile.  For example, I replaced the use of message
files in the BASIC code with calls to Oracle's Advanced Queueing  (AQ).  The
code had ancient routines to help with open and close of message files and
so on.  I commented all that stuff out and made use of the BASIC INVOKE
feature.  I created a segment in proC (pre-processed C) that communicates
with the pure BASIC programs using the COM variables.   So, if PROGA wants
to get a message from the MSG_IN AQ, it puts the name of the queue in a
common variable, and invokes the proC segment PROGQ with the proper line
number; 5640 INVOKE "PROGQ",2000.    The segment PROGQ will get the common
variable's content and switch to the line2000 label and start executing
there.  The code calls a stored procedure I wrote and placed in Oracle.
This procedure will receive the queue name and will perform an Oracle
dbms_aq.dequeue on the selected queue.  The content of the dequeued message
is then placed in another common variable and the status of the call is
stored in a third variable.  The PROGQ segment then exits and control
returns to the BASIC program that INVOKEd the proC segment, PROGA.  The
BASIC code then checks the contents of the common variable used for status
report and continues executing from there.

In the proC segment, I coded several areas so the BASIC code only needs to
INVOKE using a line number.  So, 1000 is used to log into Oracle; 2000 is
used to dequeue messages; 3000 is used to enqueue messages; 4000 is used to
disconnect from Oracle; and so on.  The BASIC code just loads the common
variable appropriately and then INVOKEs the proC code with the proper line
number as listed above.  When the INVOKE finishes, BASIC has its data in the
common variables.

I also use this technique to access Unix sockets and I have BASIC programs
(well, really C programs transpiled from BASIC code) accessing sockets on
other servers and exchanging messages.

This brings us to today's find.  Right now, I am designing the replacement
of KSAM and its set of BK intrinsics with direct Oracle access, using the
INVOKE technique I described above.

While researching the constructs of various BK intrinsics, I needed to read
about the one called BKWRITE to verify the use of the various parameters.
One must remember that BASIC had its own interface to KSAM and IMAGE which
allowed it to use varying numbers of parameters for the data portion of the
calls.  This was required because of two reasons:  BASIC has no pointers or
redefines and BASIC strings had a maximum of 255 bytes, (I'm ignoring arrays
here.)  So, if you wanted to retrieve a KSAM or IMAGE record that was 4000
bytes long and was made up of various types of data, you could use a number
of variables to make up the data area.  Astute BASIC programmers would
compile the IMAGE DB lists in such a way as to get the various data bits
together in arrays, but I digress again.

So for BKWRITE, I was looking for the calling sequence and the example to
make sure I understood it right.  In the pdf manual Using KSAM XL and KSAM
64 (32650-90886)  E0300, March 2000, I found what I was looking for in
Appendix B, BASIC/V Intrinsics.  In the BKWRITE description, the manual has
an example called figure B-13.  It has the lines:
.
.
50 DIM B$[12]
.
.
.
520 RS="123"
530 REM
540 REM F IS THE FILE NUMBER OF A KSAM FILE
550 REM OPENED BY A CALL TO BKOPEN
560 REM
570 REM NOTE THAT ONLY THREE BYTES "123" ARE WRITTEN FROM B$
580 REM WHEREAS TEN WORDS ARE WRITTEN FROM NUMERIC ARRAY A.
620 REM
630 REM THREE IDENTICAL RECORDS ARE BEING OUTPUT SO THAT
640 REM SUBSEQUENT EXAMPLES OF THIS PROGRAM WILL EXECUTE
650 REM .
660 FOR I=1 TO 3
670 CALL BKWRITE(F,S$,BS,A[*])
680 REM

Now, isn't that the funniest thing you have ever seen?  I sprayed my screen
with some hot coffee. 

Could this be due to bad scanning and imperfect character recognition?

I'm thinking that "RS" is quite close to "B$", which would explain line 520.
And "BS" is also close to "B$" in line 670, but why did "S$" not get mangled
also?

At any rate, the thread on manuals was just irresistible.  

So, now I am going to replace BKSTART with an Oracle CREATE CURSOR, BKREAD
with Oracle FETCH, BKREWRITE with Oracle UPDATE CURRENT OF, BKDELETE with
Oracle DELETE CURRENT OF, BKWRITE with Oracle INSERT and BKREADBYKEY with
Oracle SELECT.  Note to self, make sure to close cursors.

Who says you can teach an old code new tricks?

Denys

* To join/leave the list, search archives, change list settings, *
* etc., please visit http://raven.utc.edu/archives/hp3000-l.html *

ATOM RSS1 RSS2