This is a demo of my little TIG (Transparent Interface Gateway) tool.
A brief description of TIG can be found here.
It is basically a tool that expose functionality residing in a VMS shareable image to clients running anywhere without having to manually write too much glue code.
The examples will use managing a very simple customer database (just id, name and address) as problem.
Way more simple than real world code, but sufficient to demonstrate how things work and easier to follow.
On the VMS side we will have business code in Pascal/Basic/Cobol.
On the client side (Windows/Linux/VMS) we will have clients in Java/Groovy/C#/Python/PHP.
Note that these client languages are just those that I have chosen to test with. The Java client can besides Java and Groovy of course also be used from Kotlin and Scala. TIG also support VB.NET, C and C++. The C client can with a little ingenuity be called from many other native languages.
The API exposed will have the methods:
The arguments for the methods in the exposed API will be almost the same for the 3 VMS languages:
Pascal | Basic | Cobol | |
---|---|---|---|
id | integer (32 bit integer) by reference |
integer (32 bit integer) by reference |
pic 9(7) display (string length 7) by reference |
name | varying [255] of char (variable length string) by reference |
string (dynamic fixed length string) by descriptor |
pic x(32) (fixed length string) by reference |
customer | namestr = packed array [1..NAME_LEN] of char; addrstr = packed array [1..ADDR_LEN] of char; customer = record id : [key(0)] integer; name : [key(1)] namestr; address : addrstr; end;by reference |
record customer integer id string xname = 32 string address = 64 end recordby reference |
01 customer-record. 03 customer-id pic 9(7) display. 03 customer-name pic x(32). 03 customer-address pic x(64).by reference |
The types are how I imagine a traditional VMS developer in the respective languages would create the API.
Some caveats:
*) This could be solved by changing the API in a way so that all interactions would be single call, but that is out of scope for this article.
Disclaimer: I have little experience in VMS Basic and Cobol so the Basic and Cobol code may have a few "unusual" ways of of doing things.
As a starting point we have:
We will do the following:
We will only see Java and PHP web applications demoed. I is obvious possible to create web applications in Groovy, C# and Python. But this is about TIG not about writing web applications - and I can easily write Java and PHP web applications in simple year 2000 style. Doing Grails, ASP.NET Core MVC and Django is certainly doable but would add unwanted distractions (so would doing Spring MVC and Larevel).
More info about web applications and modern web frameworks can be found here:
Now it is time to jump to your language of preference:
Setup:
p.inc:
const
NAME_LEN = 32;
ADDR_LEN = 64;
ISQ_FNM = 'p.isq';
type
namestr = packed array [1..NAME_LEN] of char;
addrstr = packed array [1..ADDR_LEN] of char;
customer = record
id : [key(0)] integer;
name : [key(1)] namestr;
address : addrstr;
end;
pload.pas:
program pload(input,output);
%include 'p.inc'
var
cf : file of customer;
c : customer;
begin
open(cf, ISQ_FNM, new, organization := indexed, access_method := keyed);
rewrite(cf);
c.id := 1;
c.name := 'A A';
c.address := 'A road 1';
cf^ := c;
put(cf);
c.id := 2;
c.name := 'B B';
c.address := 'B road 2';
cf^ := c;
put(cf);
c.id := 3;
c.name := 'C C';
c.address := 'C road 3';
cf^ := c;
put(cf);
close(cf);
end.
pmain.pas:
program pmain(input,output);
%include 'p.inc'
var
cf : file of customer;
procedure open_file;
begin
open(cf, ISQ_FNM, old, organization := indexed, access_method := keyed);
reset(cf);
end;
function find_by_id(id : integer; var c : customer) : boolean;
begin
findk(cf, 0, id);
if not ufb(cf) then begin
c := cf^;
find_by_id := true;
end else begin
find_by_id := false;
end;
end;
function find_by_name(name : namestr; var c : customer) : boolean;
begin
findk(cf, 1, name);
if not ufb(cf) then begin
c := cf^;
find_by_name := true;
end else begin
find_by_name := false;
end;
end;
procedure list_start;
begin
reset(cf);
end;
function list_next(var c : customer) : boolean;
begin
if not eof(cf) then begin
c := cf^;
get(cf);
list_next := true;
end else begin
list_next := false;
end;
end;
function add(c : customer) : boolean;
var
c2 : customer;
begin
if (c.id > 0) and (c.name <> '') and not find_by_id(c.id, c2) and not find_by_name(c.name, c2) then begin
cf^ := c;
put(cf);
add := true;
end else begin
add := false;
end;
end;
procedure close_file;
begin
close(cf);
end;
procedure dump(c : customer);
begin
writeln('id=', c.id:1);
writeln('name=', c.name);
writeln('address=', c.address);
end;
var
done : boolean;
sel : char;
id : integer;
name : namestr;
c : customer;
begin
open_file;
done := false;
while not done do begin
writeln('Options:');
writeln(' 1) Lookup by id');
writeln(' 2) Lookup by name');
writeln(' 3) List all');
writeln(' 4) Add');
writeln(' 5) Exit');
write('Choice: ');
readln(sel);
case(sel) of
'1' : begin
write('Enter id: ');
readln(id);
if find_by_id(id, c) then begin
writeln('find by id: ', id:1);
dump(c);
end else begin
writeln('not found: ', id:1);
end;
end;
'2' : begin
write('Enter name: ');
readln(name);
if find_by_name(name, c) then begin
writeln('find by name: ', name);
dump(c);
end else begin
writeln('not found: ', name);
end;
end;
'3' : begin
writeln('list');
list_start;
while list_next(c) do begin
dump(c);
end;
end;
'4' : begin
write('Enter id: ');
readln(c.id);
write('Enter name: ');
readln(c.name);
write('Enter address: ');
readln(c.address);
if add(c) then begin
writeln('add succeeded');
end else begin
writeln('add failed');
end;
end;
'5' : begin
done := true;
end;
otherwise begin
(* nothing *)
end;
end;
end;
close_file;
end.
p.inc:
const
NAME_LEN = 32;
ADDR_LEN = 64;
ISQ_FNM = 'p.isq';
type
varstr = varying [255] of char;
namestr = packed array [1..NAME_LEN] of char;
addrstr = packed array [1..ADDR_LEN] of char;
customer = record
id : [key(0)] integer;
name : [key(1)] namestr;
address : addrstr;
end;
plib.pas:
module pcore(input,output);
%include 'p.inc'
var
cf : file of customer;
procedure open_file;
begin
open(cf, ISQ_FNM, old, organization := indexed, access_method := keyed);
reset(cf);
end;
function find_by_id(id : integer; var c : customer) : boolean;
begin
findk(cf, 0, id);
if not ufb(cf) then begin
c := cf^;
find_by_id := true;
end else begin
find_by_id := false;
end;
end;
function find_by_name(name : namestr; var c : customer) : boolean;
begin
findk(cf, 1, name);
if not ufb(cf) then begin
c := cf^;
find_by_name := true;
end else begin
find_by_name := false;
end;
end;
procedure list_start;
begin
reset(cf);
end;
function list_next(var c : customer) : boolean;
begin
if not eof(cf) then begin
c := cf^;
get(cf);
list_next := true;
end else begin
list_next := false;
end;
end;
function add(c : customer) : boolean;
var
c2 : customer;
begin
if (c.id > 0) and (c.name <> '') and not find_by_id(c.id, c2) and not find_by_name(c.name, c2) then begin
cf^ := c;
put(cf);
add := true;
end else begin
add := false;
end;
end;
procedure close_file;
begin
close(cf);
end;
end.
pmain.pas:
[inherit('plib')]
program pmain(input,output);
procedure dump(c : customer);
begin
writeln('id=', c.id:1);
writeln('name=', c.name);
writeln('address=', c.address);
end;
var
done : boolean;
sel : char;
id : integer;
name : namestr;
c : customer;
begin
open_file;
done := false;
while not done do begin
writeln('Options:');
writeln(' 1) Lookup by id');
writeln(' 2) Lookup by name');
writeln(' 3) List all');
writeln(' 4) Add');
writeln(' 5) Exit');
write('Choice: ');
readln(sel);
case(sel) of
'1' : begin
write('Enter id: ');
readln(id);
if find_by_id(id, c) then begin
writeln('find by id: ', id:1);
dump(c);
end else begin
writeln('not found: ', id:1);
end;
end;
'2' : begin
write('Enter name: ');
readln(name);
if find_by_name(name, c) then begin
writeln('find by name: ', name);
dump(c);
end else begin
writeln('not found: ', name);
end;
end;
'3' : begin
writeln('list');
list_start;
while list_next(c) do begin
dump(c);
end;
end;
'4' : begin
write('Enter id: ');
readln(c.id);
write('Enter name: ');
readln(c.name);
write('Enter address: ');
readln(c.address);
if add(c) then begin
writeln('add succeeded');
end else begin
writeln('add failed');
end;
end;
'5' : begin
done := true;
end;
otherwise begin
(* nothing *)
end;
end;
end;
close_file;
end.
Build:
$ pas/env plib
$ pas pmain
$ link pmain + plib
ptest.pas:
[inherit('plib')]
program pmain(input,output);
procedure dump(c : customer);
begin
writeln('id=', c.id:1);
writeln('name=', c.name);
writeln('address=', c.address);
end;
procedure test_find_by_id(id : integer);
var
c : customer;
begin
if find_by_id(id, c) then begin
writeln('find by id: ', id:1);
dump(c);
end else begin
writeln('not found: ', id:1);
end;
end;
procedure test_find_by_name(name : varstr);
var
c : customer;
begin
if find_by_name(name, c) then begin
writeln('find by name: ', name);
dump(c);
end else begin
writeln('not found: ', name);
end;
end;
procedure test_list;
var
c : customer;
begin
writeln('list');
list_start;
while list_next(c) do begin
dump(c);
end;
end;
procedure test_add(id : integer; name : varstr; addr : varstr);
var
c : customer;
begin
c.id := id;
c.name := name;
c.address := addr;
if add(c) then begin
writeln('add succeeded');
end else begin
writeln('add failed');
end;
end;
begin
open_file;
test_find_by_id(2);
test_find_by_id(5);
test_find_by_name('B B');
test_find_by_name('E E');
test_list;
test_add(5, 'E E', 'E road 5');
test_list;
test_add(0, 'X X', 'X road');
test_list;
close_file;
end.
Build and run:
$ pas ptest
$ link ptest + plib
$ run ptest
pwrap.pas:
[inherit('plib','sys$library:starlet')]
module pwrap(input,output);
[global]
function p_open_file : integer;
begin
open_file;
p_open_file := SS$_NORMAL;
end;
[global]
function p_find_by_id(id : integer; var c : customer) : integer;
begin
if find_by_id(id, c) then begin
p_find_by_id := SS$_NORMAL;
end else begin
p_find_by_id := SS$_ABORT;
end;
end;
[global]
function p_find_by_name(name : varstr; var c : customer) : integer;
begin
if find_by_name(pad(name, ' ', NAME_LEN), c) then begin
p_find_by_name := SS$_NORMAL;
end else begin
p_find_by_name := SS$_ABORT;
end;
end;
[global]
function p_list_start : integer;
begin
list_start;
p_list_start := SS$_NORMAL;
end;
[global]
function p_list_next(var c : customer) : integer;
begin
if list_next(c) then begin
p_list_next := SS$_NORMAL;
end else begin
p_list_next := SS$_ABORT;
end;
end;
[global]
function p_add(c : customer) : integer;
begin
if add(c) then begin
p_add := SS$_NORMAL;
end else begin
p_add := SS$_ABORT;
end;
end;
[global]
function p_close_file : integer;
begin
close_file;
p_close_file := SS$_NORMAL;
end;
end.
Build:
$ pas pwrap
$ link/share=pshr pwrap + plib + sys$input/opt
symbol_vector=(p_open_file=procedure,-
p_find_by_id=procedure,-
p_find_by_name=procedure,-
p_list_start=procedure,-
p_list_next=procedure,-
p_add=procedure,-
p_close_file=procedure)
$
$ define/nolog pshr "''f$parse("pshr.exe")'"
p.xml:
<config>
<image>pshr</image>
<port>30001</port>
<mt>false</mt>
<server>
<language>dk.vajhoej.vms.tig.server.JavaServerGen</language>
</server>
<client>
<language>dk.vajhoej.vms.tig.client.JavaClientGen</language>
<language>dk.vajhoej.vms.tig.client.CSharpClientGen</language>
<language>dk.vajhoej.vms.tig.client.PyClientGen</language>
<language>dk.vajhoej.vms.tig.client.PhpClientGen</language>
</client>
<methods>
<method>
<name>p_open_file</name>
<args/>
</method>
<method>
<name>p_find_by_id</name>
<args>
<arg>
<name>id</name>
<type>LongWord</type>
<pass>Reference</pass>
<use>In</use>
</arg>
<arg>
<name>c</name>
<type>Block</type>
<impl>PCustomer</impl>
<pass>Reference</pass>
<use>InOut</use>
</arg>
</args>
</method>
<method>
<name>p_find_by_name</name>
<args>
<arg>
<name>name</name>
<type>VariableCharacterString</type>
<pass>Reference</pass>
<use>In</use>
</arg>
<arg>
<name>c</name>
<type>Block</type>
<impl>PCustomer</impl>
<pass>Reference</pass>
<use>InOut</use>
</arg>
</args>
</method>
<method>
<name>p_list_start</name>
<args/>
</method>
<method>
<name>p_list_next</name>
<args>
<arg>
<name>c</name>
<type>Block</type>
<impl>PCustomer</impl>
<pass>Reference</pass>
<use>InOut</use>
</arg>
</args>
</method>
<method>
<name>p_add</name>
<args>
<arg>
<name>c</name>
<type>Block</type>
<impl>PCustomer</impl>
<pass>Reference</pass>
<use>In</use>
</arg>
</args>
</method>
<method>
<name>p_close_file</name>
<args/>
</method>
</methods>
</config>
Gen:
java -cp vmstig.jar dk.vajhoej.vms.tig.Gen p.xml server client
Run server:
$ javac -cp vmstig.jar:vmscall.jar:record.jar PshrServer.java
$ java -cp .:vmstig.jar:vmscall.jar:record.jar "PshrServer"
PCustomer.java:
import dk.vajhoej.record.FieldType;
import dk.vajhoej.record.Struct;
import dk.vajhoej.record.StructField;
@Struct
public class PCustomer {
@StructField(n=0,type=FieldType.INT4)
private int id;
@StructField(n=1,type=FieldType.FIXSTR,length=32,pad=true,padchar=' ')
private String name;
@StructField(n=2,type=FieldType.FIXSTR,length=64,pad=true,padchar=' ')
private String address;
public PCustomer() {
this(0, "", "");
}
public PCustomer(int id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
PTest.java:
import java.io.IOException;
import dk.vajhoej.record.RecordException;
public class PTest {
private static void dump(PCustomer c) {
System.out.println("id=" + c.getId());
System.out.println("name=" + c.getName());
System.out.println("address=" + c.getAddress());
}
private static void testFindById(PshrClient cli, int id) throws IOException, RecordException {
PCustomer[] c = new PCustomer[1];
c[0] = new PCustomer();
if(cli.p_find_by_id(id, c) % 2 == 1) {
System.out.println("find by id: " + id);
dump(c[0]);
} else {
System.out.println("not found: " + id);
}
}
private static void testFindByName(PshrClient cli, String name) throws IOException, RecordException {
PCustomer[] c = new PCustomer[1];
c[0] = new PCustomer();
if(cli.p_find_by_name(name, c) % 2 == 1) {
System.out.println("find by name: " + name);
dump(c[0]);
} else {
System.out.println("not found: " + name);
}
}
private static void testList(PshrClient cli) throws IOException, RecordException {
System.out.println("list");
cli.p_list_start();
PCustomer[] c = new PCustomer[1];
c[0] = new PCustomer();
while(cli.p_list_next(c) % 2 == 1) {
dump(c[0]);
}
}
private static void testAdd(PshrClient cli, int id, String name, String address) throws IOException, RecordException {
PCustomer c = new PCustomer(id, name, address);
if(cli.p_add(c) %2 == 1) {
System.out.println("add succeeded");
} else {
System.out.println("add failed");
}
}
public static void main(String[] args) throws IOException, RecordException {
PshrClient cli = new PshrClient("arne4");
cli.p_open_file();
testFindById(cli, 2);
testFindById(cli, 6);
testFindByName(cli, "B B");
testFindByName(cli, "F F");
testList(cli);
testAdd(cli, 6, "F F", "F road 6");
testList(cli);
testAdd(cli, 0, "X X", "X road");
testList(cli);
cli.p_close_file();
}
}
Build and run:
javac -cp record.jar;vmstig.jar PCustomer.java PshrClient.java PTest.java
java -cp .;record.jar;vmstig.jar PTest
PCustomer.java:
import dk.vajhoej.record.FieldType;
import dk.vajhoej.record.Struct;
import dk.vajhoej.record.StructField;
@Struct
public class PCustomer {
@StructField(n=0,type=FieldType.INT4)
private int id;
@StructField(n=1,type=FieldType.FIXSTR,length=32,pad=true,padchar=' ')
private String name;
@StructField(n=2,type=FieldType.FIXSTR,length=64,pad=true,padchar=' ')
private String address;
public PCustomer() {
this(0, "", "");
}
public PCustomer(int id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
PTest.groovy:
def dump(c) {
println("id=" + c.id)
println("name=" + c.name)
println("address=" + c.address)
}
def testFindById(cli, id) {
c = new PCustomer[1]
c[0] = new PCustomer()
if(cli.p_find_by_id(id, c) % 2 == 1) {
println("find by id: " + id)
dump(c[0])
} else {
println("not found: " + id)
}
}
def testFindByName(cli, name) {
c = new PCustomer[1]
c[0] = new PCustomer()
if(cli.p_find_by_name(name, c) % 2 == 1) {
println("find by name: " + name)
dump(c[0])
} else {
println("not found: " + name)
}
}
def testList(cli) {
println("list")
cli.p_list_start()
c = new PCustomer[1]
c[0] = new PCustomer()
while(cli.p_list_next(c) % 2 == 1) {
dump(c[0])
}
}
def testAdd(cli, id, name, address) {
c = new PCustomer(id, name, address)
if(cli.p_add(c) %2 == 1) {
println("add succeeded")
} else {
println("add failed")
}
}
cli = new PshrClient("arne4")
cli.p_open_file()
testFindById(cli, 2)
testFindById(cli, 7)
testFindByName(cli, "B B")
testFindByName(cli, "G G")
testList(cli)
testAdd(cli, 7, "G G", "G road 7")
testList(cli)
testAdd(cli, 0, "X X", "X road")
testList(cli)
cli.p_close_file()
Build and run:
javac -cp record.jar;vmstig.jar PCustomer.java PshrClient.java
set classpath=.;record.jar;vmstig.jar
groovy PTest.groovy
PCustomer.cs:
using Vajhoej.Record;
[Struct]
public class PCustomer
{
[StructField(N=0, Type=FieldType.INT4)]
private int id;
[StructField(N=1, Type=FieldType.FIXSTR, Length=32, Pad=true, PadChar=' ')]
private string name;
[StructField(N=2, Type=FieldType.FIXSTR, Length=64, Pad=true, PadChar=' ')]
private string address;
public PCustomer() : this(0, "", "")
{
}
public PCustomer(int id, string name, string address)
{
this.id = id;
this.name = name;
this.address = address;
}
public int Id
{
get { return id; }
set { id = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
}
PTest.cs:
using System;
public class PTest
{
private static void Dump(PCustomer c)
{
Console.WriteLine("id=" + c.Id);
Console.WriteLine("name=" + c.Name);
Console.WriteLine("address=" + c.Address);
}
private static void TestFindById(PshrClient cli, int id)
{
PCustomer c = new PCustomer();
if(cli.P_find_by_id(id, ref c) % 2 == 1)
{
Console.WriteLine("find by id: " + id);
Dump(c);
}
else
{
Console.WriteLine("not found: " + id);
}
}
private static void TestFindByName(PshrClient cli, string name)
{
PCustomer c = new PCustomer();
if(cli.P_find_by_name(name, ref c) % 2 == 1)
{
Console.WriteLine("find by name: " + name);
Dump(c);
}
else
{
Console.WriteLine("not found: " + name);
}
}
private static void TestList(PshrClient cli)
{
Console.WriteLine("list");
cli.P_list_start();
PCustomer c = new PCustomer();
while(cli.P_list_next(ref c) % 2 == 1)
{
Dump(c);
}
}
private static void TestAdd(PshrClient cli, int id, String name, String address)
{
PCustomer c = new PCustomer(id, name, address);
if(cli.P_add(c) %2 == 1)
{
Console.WriteLine("add succeeded");
}
else
{
Console.WriteLine("add failed");
}
}
public static void Main(string[] args)
{
PshrClient cli = new PshrClient("ARNE4");
cli.P_open_file();
TestFindById(cli, 2);
TestFindById(cli, 8);
TestFindByName(cli, "B B");
TestFindByName(cli, "H H");
TestList(cli);
TestAdd(cli, 8, "H H", "H road 8");
TestList(cli);
TestAdd(cli, 0, "X X", "X road");
TestList(cli);
cli.P_close_file();
}
}
Build and run:
csc /r:tig.dll /r:record.dll PTest.cs PshrClient.cs PCustomer.cs
PTest
PCustomer.py:
import struct
class PCustomer:
def __init__(self, id = 0, name = '', address = ''):
self.id = id
self.name = name
self.address = address
def pack(self):
return struct.pack('<l32s64s', self.id, bytes(self.name.ljust(32,' '), 'iso-8859-1'), bytes(self.address.ljust(64,' '), 'iso-8859-1'))
def unpack(self, blk):
data = struct.unpack('<l32s64s', blk)
self.id = data[0]
self.name = str(data[1], 'iso-8859-1').rstrip(' \0')
self.address = str(data[2], 'iso-8859-1').rstrip(' \0')
ptest.py:
from PshrClient import PshrClient
from PCustomer import PCustomer
def dump(c):
print('id=' + str(c.id))
print('name=' + c.name)
print('address=' + c.address)
def test_find_by_id(cli, id):
c = PCustomer()
stat, c = cli.p_find_by_id(id, c)
if stat % 2 == 1:
print('find by id: ' + str(id))
dump(c)
else:
print('not found: ' + str(id))
def test_find_by_name(cli, name):
c = PCustomer()
stat, c = cli.p_find_by_name(name, c)
if stat % 2 == 1:
print('find by name: ' + name)
dump(c)
else:
print('not found: ' + name)
def test_list(cli):
print('list')
cli.p_list_start()
while True:
c = PCustomer()
stat, c = cli.p_list_next(c)
if stat % 2 != 1: break
dump(c)
def test_add(cli, id, name, address):
c = PCustomer(id, name, address)
if cli.p_add(c) % 2 == 1:
print('add succeded')
else:
print('add failed')
cli = PshrClient('arne4')
cli.p_open_file()
test_find_by_id(cli, 2)
test_find_by_id(cli, 9)
test_find_by_name(cli, 'B B')
test_find_by_name(cli, 'I I')
test_list(cli)
test_add(cli, 9, 'I I', 'I road 9')
test_list(cli)
test_add(cli, 0, 'X X', 'X road')
test_list(cli)
cli.p_close_file()
Run:
python ptest.py
PCustomer.php:
<?php
class PCustomer {
public $id;
public $name;
public $address;
function __construct($id = 0, $name = '', $address = '') {
$this->id = $id;
$this->name = $name;
$this->address = $address;
}
function pack() {
return pack('Va32a64', $this->id, str_pad($this->name, 32, ' '), str_pad($this->address, 64, ' '));
}
function unpack($blk) {
$this->id = unpack('V', $blk, 0)[1];
$this->name = trim(unpack('a32', $blk, 4)[1]);
$this->address = trim(unpack('a64', $blk, 36)[1]);
}
}
?>
ptest.php:
<?php
include 'PCustomer.php';
include 'PshrClient.php';
function dump($c) {
echo 'id=' . $c->id . "\r\n";
echo 'name=' . $c->name . "\r\n";
echo 'address=' . $c->address . "\r\n";
}
function test_find_by_id($cli, $id) {
$c = new PCustomer();
if($cli->p_find_by_id($id, $c) % 2 == 1) {
echo 'find by id: ' . $id . "\r\n";
dump($c);
} else {
echo 'not found: ' . $id . "\r\n";
}
}
function test_find_by_name($cli, $name) {
$c = new PCustomer();
if($cli->p_find_by_name($name, $c) % 2 == 1) {
echo 'find by name: ' . $name . "\r\n";
dump($c);
} else {
echo 'not found: ' . $name . "\r\n";
}
}
function test_list($cli) {
echo "list\r\n";
$cli->p_list_start();
$c = new PCustomer();
while($cli->p_list_next($c) % 2 == 1) {
dump($c);
}
}
function test_add($cli, $id, $name, $address) {
$c = new PCustomer($id, $name, $address);
if($cli->p_add($c) % 2 == 1) {
echo "add succeeded\r\n";
} else {
echo "add failed\r\n";
}
}
$cli = new PshrClient('arne4');
$cli->p_open_file();
test_find_by_id($cli, 2);
test_find_by_id($cli, 10);
test_find_by_name($cli, 'B B');
test_find_by_name($cli, 'J J');
test_list($cli);
test_add($cli, 10, 'J J', 'J road 10');
test_list($cli);
test_add($cli, 0, 'X X', 'X road');
test_list($cli);
$cli->p_close_file()
?>
Run:
php ptest.php
p.jsp:
<html>
<head>
<title>Pshr test</title>
</head>
<body>
<h1>Pshr test</h1>
<h2>Find by id:</h2>
<form method="post" action="p_find_by_id.jsp">
Id: <input type="text" name="id">
<br>
<input type="submit" value="Find">
</form>
<h2>Find by name:</h2>
<form method="post" action="p_find_by_name.jsp">
Name: <input type="text" name="name">
<br>
<input type="submit" value="Find">
</form>
<h2>List all:</h2>
<form method="post" action="p_list.jsp">
<input type="submit" value="List">
</form>
<h2>Add one:</h2>
<form method="post" action="p_add.jsp">
Id: <input type="text" name="id">
<br>
Name: <input type="text" name="name">
<br>
Address: <input type="text" name="address">
<br>
<input type="submit" value="Add">
</form>
</body>
</html>
p_find_by_id.jsp:
<%@ page import="pshr.*" %>
<html>
<head>
<title>Find by id</title>
</head>
<body>
<h1>Find by id</h1>
<h2>Result:</h2>
<%
int id = Integer.parseInt(request.getParameter("id"));
synchronized(PshrClient.class) {
PshrClient cli = new PshrClient("arne4");
cli.p_open_file();
PCustomer[] c = new PCustomer[1];
c[0] = new PCustomer();
if(cli.p_find_by_id(id, c) % 2 == 1) {
out.println("id = " + c[0].getId() + "<br>");
out.println("name = " + c[0].getName() + "<br>");
out.println("address = " + c[0].getAddress());
} else {
out.println("Error: id " + id + " not found");
}
cli.p_close_file();
}
%>
</body>
</html>
p_find_by_name.jsp:
<%@ page import="pshr.*" %>
<html>
<head>
<title>Find by name</title>
</head>
<body>
<h1>Find by name</h1>
<h2>Result:</h2>
<%
String name = request.getParameter("name");
synchronized(PshrClient.class) {
PshrClient cli = new PshrClient("arne4");
cli.p_open_file();
PCustomer[] c = new PCustomer[1];
c[0] = new PCustomer();
if(cli.p_find_by_name(name, c) % 2 == 1) {
out.println("id = " + c[0].getId() + "<br>");
out.println("name = " + c[0].getName() + "<br>");
out.println("address = " + c[0].getAddress());
} else {
out.println("Error: name " + name + " not found");
}
cli.p_close_file();
}
%>
</body>
</html>
p_list.jsp:
<%@ page import="pshr.*" %>
<html>
<head>
<title>List all</title>
</head>
<body>
<h1>List all</h1>
<h2>List:</h2>
<table border="1">
<%
synchronized(PshrClient.class) {
PshrClient cli = new PshrClient("arne4");
cli.p_open_file();
cli.p_list_start();
PCustomer[] c = new PCustomer[1];
c[0] = new PCustomer();
while(cli.p_list_next(c) % 2 == 1) {
out.println("<tr>");
out.println("<td>" + c[0].getId() + "</td>");
out.println("<td>" + c[0].getName() + "</td>");
out.println("<td>" + c[0].getAddress() + "</td>");
out.println("</tr>");
}
cli.p_close_file();
}
%>
</table>
</body>
</html>
p_add.jsp:
<%@ page import="pshr.*" %>
<html>
<head>
<title>Add one</title>
</head>
<body>
<h1>Add one</h1>
<h2>Status:</h2>
<%
int id = Integer.parseInt(request.getParameter("id"));
String name = request.getParameter("name");
String address = request.getParameter("address");
synchronized(PshrClient.class) {
PshrClient cli = new PshrClient("arne4");
cli.p_open_file();
PCustomer c = new PCustomer(id, name, address);
if(cli.p_add(c) % 2 == 1) {
out.println(id + " added");
} else {
out.println(id + " not added");
}
cli.p_close_file();
}
%>
</body>
</html>
p.php:
<html>
<head>
<title>Pshr test</title>
</head>
<body>
<h1>Pshr test</h1>
<h2>Find by id:</h2>
<form method="post" action="p_find_by_id.php">
Id: <input type="text" name="id">
<br>
<input type="submit" value="Find">
</form>
<h2>Find by name:</h2>
<form method="post" action="p_find_by_name.php">
Name: <input type="text" name="name">
<br>
<input type="submit" value="Find">
</form>
<h2>List all:</h2>
<form method="post" action="p_list.php">
<input type="submit" value="List">
</form>
<h2>Add one:</h2>
<form method="post" action="p_add.php">
Id: <input type="text" name="id">
<br>
Name: <input type="text" name="name">
<br>
Address: <input type="text" name="address">
<br>
<input type="submit" value="Add">
</form>
</body>
</html>
p_find_by_id.php:
<html>
<head>
<title>Find by id</title>
</head>
<body>
<h1>Find by id</h1>
<h2>Result:</h2>
<?php
include 'PCustomer.php';
include 'PshrClient.php';
$id = (int)$_POST['id'];
$sem = sem_get(30001);
sem_acquire($sem);
$cli = new PshrClient('arne4');
$cli->p_open_file();
$c = new PCustomer();
if($cli->p_find_by_id($id, $c) % 2 == 1) {
echo 'id = ' . $c->id . "<br>";
echo 'name = ' . $c->name . "<br>";
echo 'address = ' . $c->address . "";
} else {
echo "Error: id $id not found";
}
$cli->p_close_file();
sem_release($sem);
?>
</body>
</html>
p_find_by_name.php:
<html>
<head>
<title>Find by name</title>
</head>
<body>
<h1>Find by name</h1>
<h2>Result:</h2>
<?php
include 'PCustomer.php';
include 'PshrClient.php';
$name = $_POST['name'];
$cli = new PshrClient('arne4');
$sem = sem_get(30001);
sem_acquire($sem);
$cli->p_open_file();
$c = new PCustomer();
if($cli->p_find_by_name($name, $c) % 2 == 1) {
echo 'id = ' . $c->id . "<br>";
echo 'name = ' . $c->name . "<br>";
echo 'address = ' . $c->address . "";
} else {
echo "Error: name $name not found";
}
$cli->p_close_file();
sem_release($sem);
?>
</body>
</html>
p_list.php:
<html>
<head>
<title>List all</title>
</head>
<body>
<h1>List all</h1>
<h2>List:</h2>
<table border="1">
<?php
include 'PCustomer.php';
include 'PshrClient.php';
$sem = sem_get(30001);
sem_acquire($sem);
$cli = new PshrClient('arne4');
$cli->p_open_file();
$cli->p_list_start();
$c = new PCustomer();
while($cli->p_list_next($c) % 2 == 1) {
echo '<tr>';
echo '<td>' . $c->id . '</td>';
echo '<td>' . $c->name . '</td>';
echo '<td>' . $c->address . '</td>';
echo '</tr>';
}
$cli->p_close_file();
sem_release($sem);
?>
</table>
</body>
</html>
p_add.php:
<html>
<head>
<title>Add one</title>
</head>
<body>
<h1>Add one</h1>
<h2>Status:</h2>
<?php
include 'PCustomer.php';
include 'PshrClient.php';
$id = (int)$_POST['id'];
$name = $_POST['name'];
$address = $_POST['address'];
$sem = sem_get(30001);
sem_acquire($sem);
$cli = new PshrClient('arne4');
$cli->p_open_file();
$c = new PCustomer($id, $name, $address);
if($cli->p_add($c) % 2 == 1) {
echo "$id added";
} else {
echo "$id not added";
}
$cli->p_close_file();
sem_release($sem);
?>
</body>
</html>
Setup:
b.inc:
declare integer constant TRUE = -1
declare integer constant FALSE = 0
record customer
integer id
string xname = 32
string address = 64
end record
bload.bas:
program bload
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
open "b.isq" as file #1, indexed fixed, recordtype none, map cmap, primary key cbuf::id, alternate key cbuf::xname
cbuf::id = 1
cbuf::xname = "A A"
cbuf::address = "A road 1"
put #1
cbuf::id = 2
cbuf::xname = "B B"
cbuf::address = "B road 2"
put #1
cbuf::id = 3
cbuf::xname = "C C"
cbuf::address = "C road 3"
put #1
close #1
end program
bmain.bas:
program bmain
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
declare integer done, id
declare string sel, xname
declare customer c
external sub open_file
external integer function find_by_id(integer, customer)
external integer function find_by_name(string, customer)
external sub list_start
external integer function list_next(customer)
external integer function add(customer)
external sub close_file
external sub dump(customer)
call open_file
set no prompt
done = FALSE
while not done
print "Options:"
print " 1) Lookup by id"
print " 2) Lookup by name"
print " 3) List all"
print " 4) Add"
print " 5) Exit"
input "Choice: "; sel
select sel
case = "1"
input "Id: "; id
if find_by_id(id, c) then
print using "find by id: #", id
call dump(c)
else
print using "not found: #", id
end if
case = "2"
input "Name: "; xname
if find_by_name(xname, c) then
print using "find by name: 'E", xname
call dump(c)
else
print using "not found: 'E", xname
end if
case = "3"
print "list"
call list_start
while list_next(c)
call dump(c)
next
case = "4"
input "Enter id: "; c::id
input "Enter name: "; c::xname
input "Enter address: "; c::address
if add(c) then
print "add succeeded"
else
print "add failed"
end if
case = "5"
done = TRUE
case else
! nothing
end select
next
call close_file
end program
!
sub open_file
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
open "b.isq" as file #1, indexed fixed, recordtype none, map cmap, primary key cbuf::id, alternate key cbuf::xname
end sub
!
function integer find_by_id(integer id, customer c)
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
handler notf_handler
find_by_id = FALSE
end handler
when error use notf_handler
get #1, key #0 eq id
c = cbuf
find_by_id = TRUE
end when
end function
!
function integer find_by_name(string xname, customer c)
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
handler notf_handler
find_by_name = FALSE
end handler
when error use notf_handler
get #1, key #1 eq xname
c = cbuf
find_by_name = TRUE
end when
end function
!
sub list_start
reset #1
end sub
!
function integer list_next(customer c)
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
handler eof_handler
list_next = FALSE
end handler
when error use eof_handler
get #1
c = cbuf
list_next = TRUE
end when
end function
!
function integer add(customer c)
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
declare customer c2
external integer function find_by_id(integer, customer)
external integer function find_by_name(string, customer)
if (c::id > 0) and (c::xname <> "") and not find_by_id(c::id, c2) and not find_by_name(c::xname, c2) then
cbuf = c
put #1
add = TRUE
else
add = FALSE
end if
end function
!
sub close_file
option type = explicit
close #1
end sub
!
sub dump(customer c)
option type = explicit
%include "b.inc"
print using "id=#", c::id
print using "name='E", c::xname
print using "address='E", c::address
end sub
b.inc:
declare integer constant TRUE = -1
declare integer constant FALSE = 0
record customer
integer id
string xname = 32
string address = 64
end record
blib.bas:
sub open_file
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
open "b.isq" as file #1, indexed fixed, recordtype none, map cmap, primary key cbuf::id, alternate key cbuf::xname
end sub
!
function integer find_by_id(integer id, customer c)
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
handler notf_handler
find_by_id = FALSE
end handler
when error use notf_handler
get #1, key #0 eq id
c = cbuf
find_by_id = TRUE
end when
end function
!
function integer find_by_name(string xname, customer c)
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
handler notf_handler
find_by_name = FALSE
end handler
when error use notf_handler
get #1, key #1 eq xname
c = cbuf
find_by_name = TRUE
end when
end function
!
sub list_start
reset #1
end sub
!
function integer list_next(customer c)
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
handler eof_handler
list_next = FALSE
end handler
when error use eof_handler
get #1
c = cbuf
list_next = TRUE
end when
end function
!
function integer add(customer c)
option type = explicit
%include "b.inc"
map (cmap) customer cbuf
declare customer c2
external integer function find_by_id(integer, customer)
external integer function find_by_name(string, customer)
if (c::id > 0) and (c::xname <> "") and not find_by_id(c::id, c2) and not find_by_name(c::xname, c2) then
cbuf = c
put #1
add = TRUE
else
add = FALSE
end if
end function
!
sub close_file
option type = explicit
close #1
end sub
bmain.bas:
program bmain
option type = explicit
%include "b.inc"
declare integer done, id
declare string sel, xname
declare customer c
external sub open_file
external integer function find_by_id(integer, customer)
external integer function find_by_name(string, customer)
external sub list_start
external integer function list_next(customer)
external integer function add(customer)
external sub close_file
external sub dump(customer)
call open_file
set no prompt
done = FALSE
while not done
print "Options:"
print " 1) Lookup by id"
print " 2) Lookup by name"
print " 3) List all"
print " 4) Add"
print " 5) Exit"
input "Choice: "; sel
select sel
case = "1"
input "Id: "; id
if find_by_id(id, c) then
print using "find by id: #", id
call dump(c)
else
print using "not found: #", id
end if
case = "2"
input "Name: "; xname
if find_by_name(xname, c) then
print using "find by name: 'E", xname
call dump(c)
else
print using "not found: 'E", xname
end if
case = "3"
print "list"
call list_start
while list_next(c)
call dump(c)
next
case = "4"
input "Enter id: "; c::id
input "Enter name: "; c::xname
input "Enter address: "; c::address
if add(c) then
print "add succeeded"
else
print "add failed"
end if
case = "5"
done = TRUE
case else
! nothing
end select
next
call close_file
end program
!
sub dump(customer c)
option type = explicit
%include "b.inc"
print using "id=#", c::id
print using "name='E", c::xname
print using "address='E", c::address
end sub
Build:
$ bas blib
$ bas bmain
$ link bmain + blib
btest.bas:
program btest
option type = explicit
%include "b.inc"
external sub open_file
external sub test_find_by_id(integer)
external sub test_find_by_name(string)
external sub test_list
external sub test_add(integer, string, string)
external sub close_file
call open_file
call test_find_by_id(2)
call test_find_by_id(5)
call test_find_by_name("B B")
call test_find_by_name("E E")
call test_list
call test_add(5, "E E", "E road 5")
call test_list
call test_add(0, "X X", "X road")
call test_list
call close_file
end program
!
sub test_find_by_id(integer id)
option type = explicit
%include "b.inc"
declare customer c
external integer function find_by_id(integer, customer)
external sub dump(customer)
if find_by_id(id, c) then
print using "find by id: #", id
call dump(c)
else
print using "not found: #", id
end if
end sub
!
sub test_find_by_name(string xname)
option type = explicit
%include "b.inc"
declare customer c
external integer function find_by_name(string, customer)
external sub dump(customer)
if find_by_name(xname, c) then
print using "find by name: 'E", xname
call dump(c)
else
print using "not found: 'E", xname
end if
end sub
!
sub test_list
option type = explicit
%include "b.inc"
declare customer c
external sub list_start
external integer function list_next(customer)
external sub dump(customer)
print "list"
call list_start
while list_next(c)
call dump(c)
next
end sub
!
sub test_add(integer id, string xname, string address)
option type = explicit
%include "b.inc"
declare customer c
external integer function add(customer)
c::id = id
c::xname = xname
c::address = address
if add(c) then
print "add succeeded"
else
print "add failed"
end if
end sub
!
sub dump(customer c)
option type = explicit
%include "b.inc"
print using "id=#", c::id
print using "name='E", c::xname
print using "address='E", c::address
end sub
Build and run:
$ bas btest
$ link btest + blib
$ run btest
bwrap.bas:
function integer b_open_file
option type = explicit
%include "$ssdef" %from %library "sys$library:basic$starlet.tlb"
%include "b.inc"
external sub open_file
call open_file
b_open_file = SS$_NORMAL
end function
!
function integer b_find_by_id(integer id, customer c)
option type = explicit
%include "$ssdef" %from %library "sys$library:basic$starlet.tlb"
%include "b.inc"
external integer function find_by_id(integer, customer)
if find_by_id(id, c) then
b_find_by_id = SS$_NORMAL
else
b_find_by_id = SS$_ABORT
end if
end function
!
function integer b_find_by_name(string xname, customer c)
option type = explicit
%include "$ssdef" %from %library "sys$library:basic$starlet.tlb"
%include "b.inc"
external integer function find_by_name(string, customer)
if find_by_name(xname, c) then
b_find_by_name = SS$_NORMAL
else
b_find_by_name = SS$_ABORT
end if
end function
!
function integer b_list_start
option type = explicit
%include "$ssdef" %from %library "sys$library:basic$starlet.tlb"
external sub list_start
call list_start
b_list_start = SS$_NORMAL
end function
!
function integer b_list_next(customer c)
option type = explicit
%include "$ssdef" %from %library "sys$library:basic$starlet.tlb"
%include "b.inc"
external integer function list_next(customer)
if list_next(c) then
b_list_next = SS$_NORMAL
else
b_list_next = SS$_ABORT
end if
end function
!
function integer b_add(customer c)
option type = explicit
%include "$ssdef" %from %library "sys$library:basic$starlet.tlb"
%include "b.inc"
external integer function add(customer)
if add(c) then
b_add = SS$_NORMAL
else
b_add = SS$_ABORT
end if
end function
!
function integer b_close_file
option type = explicit
%include "$ssdef" %from %library "sys$library:basic$starlet.tlb"
external sub close_file
call close_file
b_close_file = SS$_NORMAL
end function
Build:
$ bas bwrap
$ link/share=bshr bwrap + blib + sys$input/opt
symbol_vector=(b_open_file=procedure,-
b_find_by_id=procedure,-
b_find_by_name=procedure,-
b_list_start=procedure,-
b_list_next=procedure,-
b_add=procedure,-
b_close_file=procedure)
$
$ define/nolog bshr "''f$parse("bshr.exe")'"
b.xml:
<config>
<image>bshr</image>
<port>30002</port>
<mt>false</mt>
<server>
<language>dk.vajhoej.vms.tig.server.JavaServerGen</language>
</server>
<client>
<language>dk.vajhoej.vms.tig.client.JavaClientGen</language>
<language>dk.vajhoej.vms.tig.client.CSharpClientGen</language>
<language>dk.vajhoej.vms.tig.client.PyClientGen</language>
<language>dk.vajhoej.vms.tig.client.PhpClientGen</language>
</client>
<methods>
<method>
<name>b_open_file</name>
<args/>
</method>
<method>
<name>b_find_by_id</name>
<args>
<arg>
<name>id</name>
<type>LongWord</type>
<pass>Reference</pass>
<use>In</use>
</arg>
<arg>
<name>c</name>
<type>Block</type>
<impl>BCustomer</impl>
<pass>Reference</pass>
<use>InOut</use>
</arg>
</args>
</method>
<method>
<name>b_find_by_name</name>
<args>
<arg>
<name>name</name>
<type>FixedCharacterString</type>
<pass>Descriptor</pass>
<use>In</use>
</arg>
<arg>
<name>c</name>
<type>Block</type>
<impl>BCustomer</impl>
<pass>Reference</pass>
<use>InOut</use>
</arg>
</args>
</method>
<method>
<name>b_list_start</name>
<args/>
</method>
<method>
<name>b_list_next</name>
<args>
<arg>
<name>c</name>
<type>Block</type>
<impl>BCustomer</impl>
<pass>Reference</pass>
<use>InOut</use>
</arg>
</args>
</method>
<method>
<name>b_add</name>
<args>
<arg>
<name>c</name>
<type>Block</type>
<impl>BCustomer</impl>
<pass>Reference</pass>
<use>In</use>
</arg>
</args>
</method>
<method>
<name>b_close_file</name>
<args/>
</method>
</methods>
</config>
Gen:
java -cp vmstig.jar dk.vajhoej.vms.tig.Gen b.xml server client
Run server:
$ javac -cp vmstig.jar:vmscall.jar:record.jar BshrServer.java
$ java -cp .:vmstig.jar:vmscall.jar:record.jar "BshrServer"
BCustomer.java:
import dk.vajhoej.record.FieldType;
import dk.vajhoej.record.Struct;
import dk.vajhoej.record.StructField;
@Struct
public class BCustomer {
@StructField(n=0,type=FieldType.INT4)
private int id;
@StructField(n=1,type=FieldType.FIXSTR,length=32,pad=true,padchar=' ')
private String name;
@StructField(n=2,type=FieldType.FIXSTR,length=64,pad=true,padchar=' ')
private String address;
public BCustomer() {
this(0, "", "");
}
public BCustomer(int id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
BTest.java:
import java.io.IOException;
import dk.vajhoej.record.RecordException;
public class BTest {
private static void dump(BCustomer c) {
System.out.println("id=" + c.getId());
System.out.println("name=" + c.getName());
System.out.println("address=" + c.getAddress());
}
private static void testFindById(BshrClient cli, int id) throws IOException, RecordException {
BCustomer[] c = new BCustomer[1];
c[0] = new BCustomer();
if(cli.b_find_by_id(id, c) % 2 == 1) {
System.out.println("find by id: " + id);
dump(c[0]);
} else {
System.out.println("not found: " + id);
}
}
private static void testFindByName(BshrClient cli, String name) throws IOException, RecordException {
BCustomer[] c = new BCustomer[1];
c[0] = new BCustomer();
if(cli.b_find_by_name(name, c) % 2 == 1) {
System.out.println("find by name: " + name);
dump(c[0]);
} else {
System.out.println("not found: " + name);
}
}
private static void testList(BshrClient cli) throws IOException, RecordException {
System.out.println("list");
cli.b_list_start();
BCustomer[] c = new BCustomer[1];
c[0] = new BCustomer();
while(cli.b_list_next(c) % 2 == 1) {
dump(c[0]);
}
}
private static void testAdd(BshrClient cli, int id, String name, String address) throws IOException, RecordException {
BCustomer c = new BCustomer(id, name, address);
if(cli.b_add(c) %2 == 1) {
System.out.println("add succeeded");
} else {
System.out.println("add failed");
}
}
public static void main(String[] args) throws IOException, RecordException {
BshrClient cli = new BshrClient("arne4");
cli.b_open_file();
testFindById(cli, 2);
testFindById(cli, 6);
testFindByName(cli, "B B");
testFindByName(cli, "F F");
testList(cli);
testAdd(cli, 6, "F F", "F road 6");
testList(cli);
testAdd(cli, 0, "X X", "X road");
testList(cli);
cli.b_close_file();
}
}
Build and run:
javac -cp record.jar;vmstig.jar BCustomer.java BshrClient.java BTest.java
java -cp .;record.jar;vmstig.jar BTest
BCustomer.java:
import dk.vajhoej.record.FieldType;
import dk.vajhoej.record.Struct;
import dk.vajhoej.record.StructField;
@Struct
public class BCustomer {
@StructField(n=0,type=FieldType.INT4)
private int id;
@StructField(n=1,type=FieldType.FIXSTR,length=32,pad=true,padchar=' ')
private String name;
@StructField(n=2,type=FieldType.FIXSTR,length=64,pad=true,padchar=' ')
private String address;
public BCustomer() {
this(0, "", "");
}
public BCustomer(int id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
BTest.groovy:
def dump(c) {
println("id=" + c.id)
println("name=" + c.name)
println("address=" + c.address)
}
def testFindById(cli, id) {
c = new BCustomer[1]
c[0] = new BCustomer()
if(cli.b_find_by_id(id, c) % 2 == 1) {
println("find by id: " + id)
dump(c[0])
} else {
println("not found: " + id)
}
}
def testFindByName(cli, name) {
c = new BCustomer[1]
c[0] = new BCustomer()
if(cli.b_find_by_name(name, c) % 2 == 1) {
println("find by name: " + name)
dump(c[0])
} else {
println("not found: " + name)
}
}
def testList(cli) {
println("list")
cli.b_list_start()
c = new BCustomer[1]
c[0] = new BCustomer()
while(cli.b_list_next(c) % 2 == 1) {
dump(c[0])
}
}
def testAdd(cli, id, name, address) {
c = new BCustomer(id, name, address)
if(cli.b_add(c) %2 == 1) {
println("add succeeded")
} else {
println("add failed")
}
}
cli = new BshrClient("arne4")
cli.b_open_file()
testFindById(cli, 2)
testFindById(cli, 7)
testFindByName(cli, "B B")
testFindByName(cli, "G G")
testList(cli)
testAdd(cli, 7, "G G", "G road 7")
testList(cli)
testAdd(cli, 0, "X X", "X road")
testList(cli)
cli.b_close_file()
Test and run:
javac -cp record.jar;vmstig.jar BCustomer.java BshrClient.java
set classpath=.;record.jar;vmstig.jar
groovy BTest.groovy
BCustomer.cs:
using Vajhoej.Record;
[Struct]
public class BCustomer
{
[StructField(N=0, Type=FieldType.INT4)]
private int id;
[StructField(N=1, Type=FieldType.FIXSTR, Length=32, Pad=true, PadChar=' ')]
private string name;
[StructField(N=2, Type=FieldType.FIXSTR, Length=64, Pad=true, PadChar=' ')]
private string address;
public BCustomer() : this(0, "", "")
{
}
public BCustomer(int id, string name, string address)
{
this.id = id;
this.name = name;
this.address = address;
}
public int Id
{
get { return id; }
set { id = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
}
BTest.cs:
using System;
public class BTest
{
private static void Dump(BCustomer c)
{
Console.WriteLine("id=" + c.Id);
Console.WriteLine("name=" + c.Name);
Console.WriteLine("address=" + c.Address);
}
private static void TestFindById(BshrClient cli, int id)
{
BCustomer c = new BCustomer();
if(cli.B_find_by_id(id, ref c) % 2 == 1)
{
Console.WriteLine("find by id: " + id);
Dump(c);
}
else
{
Console.WriteLine("not found: " + id);
}
}
private static void TestFindByName(BshrClient cli, string name)
{
BCustomer c = new BCustomer();
if(cli.B_find_by_name(name, ref c) % 2 == 1)
{
Console.WriteLine("find by name: " + name);
Dump(c);
}
else
{
Console.WriteLine("not found: " + name);
}
}
private static void TestList(BshrClient cli)
{
Console.WriteLine("list");
cli.B_list_start();
BCustomer c = new BCustomer();
while(cli.B_list_next(ref c) % 2 == 1)
{
Dump(c);
}
}
private static void TestAdd(BshrClient cli, int id, String name, String address)
{
BCustomer c = new BCustomer(id, name, address);
if(cli.B_add(c) %2 == 1)
{
Console.WriteLine("add succeeded");
}
else
{
Console.WriteLine("add failed");
}
}
public static void Main(string[] args)
{
BshrClient cli = new BshrClient("ARNE4");
cli.B_open_file();
TestFindById(cli, 2);
TestFindById(cli, 8);
TestFindByName(cli, "B B");
TestFindByName(cli, "H H");
TestList(cli);
TestAdd(cli, 8, "H H", "H road 8");
TestList(cli);
TestAdd(cli, 0, "X X", "X road");
TestList(cli);
cli.B_close_file();
}
}
Test and run:
csc /r:tig.dll /r:record.dll BTest.cs BshrClient.cs BCustomer.cs
BTest
BCustomer.py:
import struct
class BCustomer:
def __init__(self, id = 0, name = '', address = ''):
self.id = id
self.name = name
self.address = address
def pack(self):
return struct.pack('<l32s64s', self.id, bytes(self.name.ljust(32,' '), 'iso-8859-1'), bytes(self.address.ljust(64,' '), 'iso-8859-1'))
def unpack(self, blk):
data = struct.unpack('<l32s64s', blk)
self.id = data[0]
self.name = str(data[1], 'iso-8859-1').rstrip(' \0')
self.address = str(data[2], 'iso-8859-1').rstrip(' \0')
btest.py:
from BshrClient import BshrClient
from BCustomer import BCustomer
def dump(c):
print('id=' + str(c.id))
print('name=' + c.name)
print('address=' + c.address)
def test_find_by_id(cli, id):
c = BCustomer()
stat, c = cli.b_find_by_id(id, c)
if stat % 2 == 1:
print('find by id: ' + str(id))
dump(c)
else:
print('not found: ' + str(id))
def test_find_by_name(cli, name):
c = BCustomer()
stat, c = cli.b_find_by_name(name, c)
if stat % 2 == 1:
print('find by name: ' + name)
dump(c)
else:
print('not found: ' + name)
def test_list(cli):
print('list')
cli.b_list_start()
while True:
c = BCustomer()
stat, c = cli.b_list_next(c)
if stat % 2 != 1: break
dump(c)
def test_add(cli, id, name, address):
c = BCustomer(id, name, address)
if cli.b_add(c) % 2 == 1:
print('add succeded')
else:
print('add failed')
cli = BshrClient('arne4')
cli.b_open_file()
test_find_by_id(cli, 2)
test_find_by_id(cli, 9)
test_find_by_name(cli, 'B B')
test_find_by_name(cli, 'I I')
test_list(cli)
test_add(cli, 9, 'I I', 'I road 9')
test_list(cli)
test_add(cli, 0, 'X X', 'X road')
test_list(cli)
cli.b_close_file()
Run:
python btest.py
BCustomer.php:
<?php
class BCustomer {
public $id;
public $name;
public $address;
function __construct($id = 0, $name = '', $address = '') {
$this->id = $id;
$this->name = $name;
$this->address = $address;
}
function pack() {
return pack('Va32a64', $this->id, str_pad($this->name, 32, ' '), str_pad($this->address, 64, ' '));
}
function unpack($blk) {
$this->id = unpack('V', $blk, 0)[1];
$this->name = trim(unpack('a32', $blk, 4)[1]);
$this->address = trim(unpack('a64', $blk, 36)[1]);
}
}
?>
btest.php:
<?php
include 'BCustomer.php';
include 'BshrClient.php';
function dump($c) {
echo 'id=' . $c->id . "\r\n";
echo 'name=' . $c->name . "\r\n";
echo 'address=' . $c->address . "\r\n";
}
function test_find_by_id($cli, $id) {
$c = new BCustomer();
if($cli->b_find_by_id($id, $c) % 2 == 1) {
echo 'find by id: ' . $id . "\r\n";
dump($c);
} else {
echo 'not found: ' . $id . "\r\n";
}
}
function test_find_by_name($cli, $name) {
$c = new BCustomer();
if($cli->b_find_by_name($name, $c) % 2 == 1) {
echo 'find by name: ' . $name . "\r\n";
dump($c);
} else {
echo 'not found: ' . $name . "\r\n";
}
}
function test_list($cli) {
echo "list\r\n";
$cli->b_list_start();
$c = new BCustomer();
while($cli->b_list_next($c) % 2 == 1) {
dump($c);
}
}
function test_add($cli, $id, $name, $address) {
$c = new BCustomer($id, $name, $address);
if($cli->b_add($c) % 2 == 1) {
echo "add succeeded\r\n";
} else {
echo "add failed\r\n";
}
}
$cli = new BshrClient('arne4');
$cli->b_open_file();
test_find_by_id($cli, 2);
test_find_by_id($cli, 10);
test_find_by_name($cli, 'B B');
test_find_by_name($cli, 'J J');
test_list($cli);
test_add($cli, 10, 'J J', 'J road 10');
test_list($cli);
test_add($cli, 0, 'X X', 'X road');
test_list($cli);
$cli->b_close_file()
?>
Run:
php btest.php
b.jsp:
<html>
<head>
<title>Bshr test</title>
</head>
<body>
<h1>Bshr test</h1>
<h2>Find by id:</h2>
<form method="post" action="b_find_by_id.jsp">
Id: <input type="text" name="id">
<br>
<input type="submit" value="Find">
</form>
<h2>Find by name:</h2>
<form method="post" action="b_find_by_name.jsp">
Name: <input type="text" name="name">
<br>
<input type="submit" value="Find">
</form>
<h2>List all:</h2>
<form method="post" action="b_list.jsp">
<input type="submit" value="List">
</form>
<h2>Add one:</h2>
<form method="post" action="b_add.jsp">
Id: <input type="text" name="id">
<br>
Name: <input type="text" name="name">
<br>
Address: <input type="text" name="address">
<br>
<input type="submit" value="Add">
</form>
</body>
</html>
b_find_by_id.jsp:
<%@ page import="bshr.*" %>
<html>
<head>
<title>Find by id</title>
</head>
<body>
<h1>Find by id</h1>
<h2>Result:</h2>
<%
int id = Integer.parseInt(request.getParameter("id"));
synchronized(BshrClient.class) {
BshrClient cli = new BshrClient("arne4");
cli.b_open_file();
BCustomer[] c = new BCustomer[1];
c[0] = new BCustomer();
if(cli.b_find_by_id(id, c) % 2 == 1) {
out.println("id = " + c[0].getId() + "<br>");
out.println("name = " + c[0].getName() + "<br>");
out.println("address = " + c[0].getAddress());
} else {
out.println("Error: id " + id + " not found");
}
cli.b_close_file();
}
%>
</body>
</html>
b_find_by_name.jsp:
<%@ page import="bshr.*" %>
<html>
<head>
<title>Find by name</title>
</head>
<body>
<h1>Find by name</h1>
<h2>Result:</h2>
<%
String name = request.getParameter("name");
synchronized(BshrClient.class) {
BshrClient cli = new BshrClient("arne4");
cli.b_open_file();
BCustomer[] c = new BCustomer[1];
c[0] = new BCustomer();
if(cli.b_find_by_name(name, c) % 2 == 1) {
out.println("id = " + c[0].getId() + "<br>");
out.println("name = " + c[0].getName() + "<br>");
out.println("address = " + c[0].getAddress());
} else {
out.println("Error: name " + name + " not found");
}
cli.b_close_file();
}
%>
</body>
</html>
b_list.jsp:
<%@ page import="bshr.*" %>
<html>
<head>
<title>List all</title>
</head>
<body>
<h1>List all</h1>
<h2>List:</h2>
<table border="1">
<%
synchronized(BshrClient.class) {
BshrClient cli = new BshrClient("arne4");
cli.b_open_file();
cli.b_list_start();
BCustomer[] c = new BCustomer[1];
c[0] = new BCustomer();
while(cli.b_list_next(c) % 2 == 1) {
out.println("<tr>");
out.println("<td>" + c[0].getId() + "</td>");
out.println("<td>" + c[0].getName() + "</td>");
out.println("<td>" + c[0].getAddress() + "</td>");
out.println("</tr>");
}
cli.b_close_file();
}
%>
</table>
</body>
</html>
b_add.jsp:
<%@ page import="bshr.*" %>
<html>
<head>
<title>Add one</title>
</head>
<body>
<h1>Add one</h1>
<h2>Status:</h2>
<%
int id = Integer.parseInt(request.getParameter("id"));
String name = request.getParameter("name");
String address = request.getParameter("address");
synchronized(BshrClient.class) {
BshrClient cli = new BshrClient("arne4");
cli.b_open_file();
BCustomer c = new BCustomer(id, name, address);
if(cli.b_add(c) % 2 == 1) {
out.println(id + " added");
} else {
out.println(id + " not added");
}
cli.b_close_file();
}
%>
</body>
</html>
b.php:
<html>
<head>
<title>Bshr test</title>
</head>
<body>
<h1>Bshr test</h1>
<h2>Find by id:</h2>
<form method="post" action="b_find_by_id.php">
Id: <input type="text" name="id">
<br>
<input type="submit" value="Find">
</form>
<h2>Find by name:</h2>
<form method="post" action="b_find_by_name.php">
Name: <input type="text" name="name">
<br>
<input type="submit" value="Find">
</form>
<h2>List all:</h2>
<form method="post" action="b_list.php">
<input type="submit" value="List">
</form>
<h2>Add one:</h2>
<form method="post" action="b_add.php">
Id: <input type="text" name="id">
<br>
Name: <input type="text" name="name">
<br>
Address: <input type="text" name="address">
<br>
<input type="submit" value="Add">
</form>
</body>
</html>
b_find_by_id.php:
<html>
<head>
<title>Find by id</title>
</head>
<body>
<h1>Find by id</h1>
<h2>Result:</h2>
<?php
include 'BCustomer.php';
include 'BshrClient.php';
$id = (int)$_POST['id'];
$sem = sem_get(30002);
sem_acquire($sem);
$cli = new BshrClient('arne4');
$cli->b_open_file();
$c = new BCustomer();
if($cli->b_find_by_id($id, $c) % 2 == 1) {
echo 'id = ' . $c->id . "<br>";
echo 'name = ' . $c->name . "<br>";
echo 'address = ' . $c->address . "";
} else {
echo "Error: id $id not found";
}
$cli->b_close_file();
sem_release($sem);
?>
</body>
</html>
b_find_by_name.php:
<html>
<head>
<title>Find by name</title>
</head>
<body>
<h1>Find by name</h1>
<h2>Result:</h2>
<?php
include 'BCustomer.php';
include 'BshrClient.php';
$name = $_POST['name'];
$cli = new BshrClient('arne4');
$sem = sem_get(30002);
sem_acquire($sem);
$cli->b_open_file();
$c = new BCustomer();
if($cli->b_find_by_name($name, $c) % 2 == 1) {
echo 'id = ' . $c->id . "<br>";
echo 'name = ' . $c->name . "<br>";
echo 'address = ' . $c->address . "";
} else {
echo "Error: name $name not found";
}
$cli->b_close_file();
sem_release($sem);
?>
</body>
</html>
b_list.php:
<html>
<head>
<title>List all</title>
</head>
<body>
<h1>List all</h1>
<h2>List:</h2>
<table border="1">
<?php
include 'BCustomer.php';
include 'BshrClient.php';
$sem = sem_get(30001);
sem_acquire($sem);
$cli = new BshrClient('arne4');
$cli->b_open_file();
$cli->b_list_start();
$c = new BCustomer();
while($cli->b_list_next($c) % 2 == 1) {
echo '<tr>';
echo '<td>' . $c->id . '</td>';
echo '<td>' . $c->name . '</td>';
echo '<td>' . $c->address . '</td>';
echo '</tr>';
}
$cli->b_close_file();
sem_release($sem);
?>
</table>
</body>
</html>
b_add.php:
<html>
<head>
<title>Add one</title>
</head>
<body>
<h1>Add one</h1>
<h2>Status:</h2>
<?php
include 'BCustomer.php';
include 'BshrClient.php';
$id = (int)$_POST['id'];
$name = $_POST['name'];
$address = $_POST['address'];
$sem = sem_get(30001);
sem_acquire($sem);
$cli = new BshrClient('arne4');
$cli->b_open_file();
$c = new BCustomer($id, $name, $address);
if($cli->b_add($c) % 2 == 1) {
echo "$id added";
} else {
echo "$id not added";
}
$cli->b_close_file();
sem_release($sem);
?>
</body>
</html>
Setup:
o.inc:
01 customer-record.
03 customer-id pic 9(7) display.
03 customer-name pic x(32).
03 customer-address pic x(64).
oload.cob:
identification division.
program-id.oload.
environment division.
input-output section.
file-control.
select optional customer-file assign to "o.isq"
organization is indexed
access mode is dynamic
record key is customer-id
alternate record key is customer-name.
data division.
file section.
fd customer-file.
copy "o.inc".
working-storage section.
procedure division.
main-paragraph.
open i-o customer-file
move 1 to customer-id
move "A A" to customer-name
move "A road 1" to customer-address
perform insert-paragraph
move 2 to customer-id
move "B B" to customer-name
move "B road 2" to customer-address
perform insert-paragraph
move 3 to customer-id
move "C C" to customer-name
move "C road 3" to customer-address
perform insert-paragraph
close customer-file
stop run.
insert-paragraph.
write customer-record
invalid key display "Error writing customer"
not invalid key continue
end-write.
omain.cob:
identification division.
program-id.omain.
environment division.
input-output section.
file-control.
select optional customer-file assign to "o.isq"
organization is indexed
access mode is dynamic
record key is customer-id
alternate record key is customer-name.
data division.
file section.
fd customer-file.
copy "o.inc".
working-storage section.
01 done pic x.
01 sel pic x.
01 eof pic x.
01 fnd pic x.
01 xid pic 9(7) display.
01 name pic x(32).
01 address pic x(64).
procedure division.
main-paragraph.
perform open-file-paragraph
move "N" to done
perform until done = "Y"
display "Options:"
display " 1) Lookup by id"
display " 2) Lookup by name"
display " 3) List all"
display " 4) Add"
display " 5) Exit"
display "Choice: " with no advancing
accept sel
evaluate sel
when "1"
display "Enter id: " with no advancing
accept xid
perform find-by-id-paragraph
if fnd = "Y"
display "find by id: ", xid
perform dump-paragraph
else
display "not found: ", xid
end-if
when "2"
display "Enter name: " with no advancing
accept name
perform find-by-name-paragraph
if fnd = "Y"
display "find by name: ", name
perform dump-paragraph
else
display "not found: ", name
end-if
when "3"
display "list"
perform list-start-paragraph
move "N" to eof
perform until eof = "Y"
perform list-next-paragraph
if eof not = "Y"
perform dump-paragraph
end-if
end-perform
when "4"
display "Enter id: " with no advancing
accept xid
display "Enter name: " with no advancing
accept name
display "Enter address: " with no advancing
accept address
perform add-paragraph
if fnd = "Y"
display "add succeeded"
else
display "add failed"
end-if
when "5"
move "Y" to done
end-evaluate
end-perform
perform close-file-paragraph
stop run.
open-file-paragraph.
open i-o customer-file.
find-by-id-paragraph.
move xid to customer-id
read customer-file
invalid key move "N" to fnd
not invalid key move "Y" to fnd
end-read.
find-by-name-paragraph.
move name to customer-name
read customer-file key is customer-name
invalid key move "N" to fnd
not invalid key move "Y" to fnd
end-read.
list-start-paragraph.
move 0 to customer-id
start customer-file key is greater than customer-id
invalid key display "error rewinding"
not invalid key continue
end-start.
list-next-paragraph.
read customer-file next
at end move "Y" to eof
not at end continue
end-read.
add-paragraph.
if xid > 0 and name not = ""
perform find-by-id-paragraph
if fnd = "N"
perform find-by-name-paragraph
if fnd = "N"
move xid to customer-id
move name to customer-name
move address to customer-address
write customer-record
invalid key display "error writing"
not invalid key continue
end-write
move "Y" to fnd
else
move "N" to fnd
end-if
else
move "N" to fnd
end-if
else
move "N" to fnd
end-if.
close-file-paragraph.
close customer-file.
dump-paragraph.
display "id=" customer-id
display "name=" customer-name
display "address=" customer-address.
o.inc:
01 customer-record.
03 customer-id pic 9(7) display.
03 customer-name pic x(32).
03 customer-address pic x(64).
o2.inc:
01 c-record.
03 c-id pic 9(7) display.
03 c-name pic x(32).
03 c-address pic x(64).
olib.cob:
identification division.
program-id.open-file.
environment division.
input-output section.
file-control.
select optional customer-file assign to "o.isq"
organization is indexed
access mode is dynamic
record key is customer-id
alternate record key is customer-name.
data division.
file section.
fd customer-file external.
copy "o.inc".
working-storage section.
procedure division.
main-paragraph.
open i-o customer-file.
end program open-file.
****
identification division.
program-id.find-by-id.
environment division.
input-output section.
file-control.
select optional customer-file assign to "o.isq"
organization is indexed
access mode is dynamic
record key is customer-id
alternate record key is customer-name.
data division.
file section.
fd customer-file external.
copy "o.inc".
working-storage section.
linkage section.
01 xid pic 9(7) display.
copy "o2.inc".
01 fnd pic x.
procedure division using xid, c-record, fnd.
main-paragraph.
move xid to customer-id
read customer-file
invalid key move "N" to fnd
not invalid key move "Y" to fnd
end-read
move customer-record to c-record.
end program find-by-id.
****
identification division.
program-id.find-by-name.
environment division.
input-output section.
file-control.
select optional customer-file assign to "o.isq"
organization is indexed
access mode is dynamic
record key is customer-id
alternate record key is customer-name.
data division.
file section.
fd customer-file external.
copy "o.inc".
working-storage section.
linkage section.
01 name pic x(32).
copy "o2.inc".
01 fnd pic x.
procedure division using name, c-record, fnd.
main-paragraph.
move name to customer-name
read customer-file key is customer-name
invalid key move "N" to fnd
not invalid key move "Y" to fnd
end-read
move customer-record to c-record.
end program find-by-name.
****
identification division.
program-id.list-start.
environment division.
input-output section.
file-control.
select optional customer-file assign to "o.isq"
organization is indexed
access mode is dynamic
record key is customer-id
alternate record key is customer-name.
data division.
file section.
fd customer-file external.
copy "o.inc".
working-storage section.
procedure division.
main-paragraph.
move 0 to customer-id
start customer-file key is greater than customer-id
invalid key display "error rewinding"
not invalid key continue
end-start.
end program list-start.
****
identification division.
program-id.list-next.
environment division.
input-output section.
file-control.
select optional customer-file assign to "o.isq"
organization is indexed
access mode is dynamic
record key is customer-id
alternate record key is customer-name.
data division.
file section.
fd customer-file external.
copy "o.inc".
working-storage section.
linkage section.
copy "o2.inc".
01 eof pic x.
procedure division using c-record, eof.
main-paragraph.
read customer-file next
at end move "Y" to eof
not at end
move customer-record to c-record
move "N" to eof
end-read.
end program list-next.
****
identification division.
program-id.xadd.
environment division.
input-output section.
file-control.
select optional customer-file assign to "o.isq"
organization is indexed
access mode is dynamic
record key is customer-id
alternate record key is customer-name.
data division.
file section.
fd customer-file external.
copy "o.inc".
working-storage section.
01 fnd pic x.
01 c2-record.
03 c2-id pic 9(7) display.
03 c2-name pic x(32).
03 c2-address pic x(64).
linkage section.
copy "o2.inc".
01 added pic x.
procedure division using c-record, added.
main-paragraph.
if c-id > 0 and c-name not = ""
call "find-by-id" using c-id, c2-record, fnd end-call
if fnd = "N"
call "find-by-name" using c-name, c2-record, fnd end-call
if fnd = "N"
move c-record to customer-record
write customer-record
invalid key display "error writing"
not invalid key continue
end-write
move "Y" to added
else
move "N" to added
end-if
else
move "N" to added
end-if
else
move "N" to added
end-if.
end program xadd.
****
identification division.
program-id.close-file.
environment division.
input-output section.
file-control.
select optional customer-file assign to "o.isq"
organization is indexed
access mode is dynamic
record key is customer-id
alternate record key is customer-name.
data division.
file section.
fd customer-file external.
copy "o.inc".
working-storage section.
procedure division.
main-paragraph.
close customer-file.
end program close-file.
omain.cob:
identification division.
program-id.omain.
environment division.
input-output section.
data division.
file section.
working-storage section.
copy "o2.inc".
01 done pic x.
01 sel pic x.
01 eof pic x.
01 fnd pic x.
01 xid pic 9(7) display.
01 name pic x(32).
01 temp pic 9(7) display.
procedure division.
main-paragraph.
call "open-file"
move "N" to done
perform until done = "Y"
display "Options:"
display " 1) Lookup by id"
display " 2) Lookup by name"
display " 3) List all"
display " 4) Add"
display " 5) Exit"
display "Choice: " with no advancing
accept sel
evaluate sel
when "1"
display "Enter id: " with no advancing
accept xid
call "find-by-id" using xid, c-record, fnd end-call
if fnd = "Y"
display "find by id: ", xid
perform dump-paragraph
else
display "not found: ", xid
end-if
when "2"
display "Enter name: " with no advancing
accept name
call "find-by-name" using name, c-record, fnd end-call
if fnd = "Y"
display "find by name: ", name
perform dump-paragraph
else
display "not found: ", name
end-if
when "3"
display "list"
call "list-start"
move "N" to eof
perform until eof = "Y"
call "list-next" using c-record, eof end-call
if eof not = "Y"
perform dump-paragraph
end-if
end-perform
when "4"
display "Enter id: " with no advancing
accept temp
move temp to c-id
display "Enter name: " with no advancing
accept c-name
display "Enter address: " with no advancing
accept c-address
call "xadd" using c-record, fnd end-call
if fnd = "Y"
display "add succeeded"
else
display "add failed"
end-if
when "5"
move "Y" to done
end-evaluate
end-perform
call "close-file"
stop run.
dump-paragraph.
display "id=" c-id
display "name=" c-name
display "address=" c-address.
Build:
$ cob olib
$ cob omain
$ link omain + olib
otest.cob:
identification division.
program-id.omain.
environment division.
input-output section.
data division.
file section.
working-storage section.
copy "o2.inc".
01 done pic x.
01 sel pic x.
01 eof pic x.
01 fnd pic x.
01 added pic x.
01 xid pic 9(7) display.
01 name pic x(32).
procedure division.
main-paragraph.
call "open-file"
move 2 to xid
perform test-find-by-id-paragraph
move 5 to xid
perform test-find-by-id-paragraph
move "B B" to name
perform test-find-by-name-paragraph
move "E E" to name
perform test-find-by-name-paragraph
perform test-list-paragraph
move 5 to c-id
move "E E" to c-name
move "E road 5" to c-address
perform test-add-paragraph
move 0 to c-id
move "X X" to c-name
move "X road" to c-address
perform test-add-paragraph
perform test-list-paragraph
call "close-file"
stop run.
test-find-by-id-paragraph.
call "find-by-id" using xid, c-record, fnd end-call
if fnd = "Y"
display "find by id: ", xid
perform dump-paragraph
else
display "not found: ", xid
end-if.
test-find-by-name-paragraph.
call "find-by-name" using name, c-record, fnd end-call
if fnd = "Y"
display "find by name: ", name
perform dump-paragraph
else
display "not found: ", name
end-if.
test-list-paragraph.
display "list"
call "list-start"
move "N" to eof
perform until eof = "Y"
call "list-next" using c-record, eof end-call
if eof not = "Y"
perform dump-paragraph
end-if
end-perform.
test-add-paragraph.
call "xadd" using c-record, added end-call
if added = "Y"
display "add succeeded"
else
display "add failed"
end-if.
dump-paragraph.
display "id=" c-id
display "name=" c-name
display "address=" c-address.
Build and run:
$ cob otest
$ link otest + olib
$ run otest
owrap.cob:
identification division.
program-id.o-open-file.
environment division.
input-output section.
data division.
file section.
working-storage section.
01 stat pic 9(8) comp.
01 SS$_NORMAL pic 9(8) comp value is external SS$_NORMAL.
01 SS$_ABORT pic 9(8) comp value is external SS$_ABORT.
procedure division giving stat.
main-paragraph.
call "open-file"
move SS$_NORMAL to stat.
end program o-open-file.
****
identification division.
program-id.o-find-by-id.
environment division.
input-output section.
data division.
file section.
working-storage section.
01 fnd pic x.
01 stat pic 9(8) comp.
01 SS$_NORMAL pic 9(8) comp value is external SS$_NORMAL.
01 SS$_ABORT pic 9(8) comp value is external SS$_ABORT.
linkage section.
01 xid pic 9(7) display.
copy "o2.inc".
procedure division using xid, c-record giving stat.
main-paragraph.
call "find-by-id" using xid, c-record, fnd end-call
if fnd = "Y"
move SS$_NORMAL to stat
else
move SS$_ABORT to stat
end-if.
end program o-find-by-id.
****
identification division.
program-id.o-find-by-name.
environment division.
input-output section.
data division.
file section.
working-storage section.
01 fnd pic x.
01 stat pic 9(8) comp.
01 SS$_NORMAL pic 9(8) comp value is external SS$_NORMAL.
01 SS$_ABORT pic 9(8) comp value is external SS$_ABORT.
linkage section.
01 name pic x(32).
copy "o2.inc".
procedure division using name, c-record giving stat.
main-paragraph.
call "find-by-name" using name, c-record, fnd end-call
if fnd = "Y"
move SS$_NORMAL to stat
else
move SS$_ABORT to stat
end-if.
end program o-find-by-name.
****
identification division.
program-id.o-list-start.
environment division.
input-output section.
data division.
file section.
working-storage section.
01 stat pic 9(8) comp.
01 SS$_NORMAL pic 9(8) comp value is external SS$_NORMAL.
01 SS$_ABORT pic 9(8) comp value is external SS$_ABORT.
procedure division giving stat.
main-paragraph.
call "list-start"
move SS$_NORMAL to stat.
end program o-list-start.
****
identification division.
program-id.o-list-next.
environment division.
input-output section.
data division.
file section.
working-storage section.
01 eof pic x.
01 stat pic 9(8) comp.
01 SS$_NORMAL pic 9(8) comp value is external SS$_NORMAL.
01 SS$_ABORT pic 9(8) comp value is external SS$_ABORT.
linkage section.
copy "o2.inc".
procedure division using c-record giving stat.
main-paragraph.
call "list-next" using c-record, eof end-call
if eof not = "Y"
move SS$_NORMAL to stat
else
move SS$_ABORT to stat
end-if.
end program o-list-next.
****
identification division.
program-id.o-add.
environment division.
input-output section.
data division.
file section.
working-storage section.
01 added pic x.
01 stat pic 9(8) comp.
01 SS$_NORMAL pic 9(8) comp value is external SS$_NORMAL.
01 SS$_ABORT pic 9(8) comp value is external SS$_ABORT.
linkage section.
copy "o2.inc".
procedure division using c-record giving stat.
main-paragraph.
call "xadd" using c-record, added end-call
if added = "Y"
move SS$_NORMAL to stat
else
move SS$_ABORT to stat
end-if.
end program o-add.
****
identification division.
program-id.o-close-file.
environment division.
input-output section.
data division.
working-storage section.
01 stat pic 9(8) comp.
01 SS$_NORMAL pic 9(8) comp value is external SS$_NORMAL.
01 SS$_ABORT pic 9(8) comp value is external SS$_ABORT.
procedure division giving stat.
main-paragraph.
call "close-file"
move SS$_NORMAL to stat.
end program o-close-file.
Build:
$ cob owrap
$ link/share=oshr owrap + olib + sys$input/opt
symbol_vector=(o_open_file=procedure,-
o_find_by_id=procedure,-
o_find_by_name=procedure,-
o_list_start=procedure,-
o_list_next=procedure,-
o_add=procedure,-
o_close_file=procedure)
$
$ define/nolog oshr "''f$parse("oshr.exe")'"
o.xml:
<config>
<image>oshr</image>
<port>30003</port>
<mt>false</mt>
<server>
<language>dk.vajhoej.vms.tig.server.JavaServerGen</language>
</server>
<client>
<language>dk.vajhoej.vms.tig.client.JavaClientGen</language>
<language>dk.vajhoej.vms.tig.client.CSharpClientGen</language>
<language>dk.vajhoej.vms.tig.client.PyClientGen</language>
<language>dk.vajhoej.vms.tig.client.PhpClientGen</language>
</client>
<methods>
<method>
<name>o_open_file</name>
<args/>
</method>
<method>
<name>o_find_by_id</name>
<args>
<arg>
<name>id</name>
<type>FixedCharacterString</type>
<pass>Reference</pass>
<use>In</use>
</arg>
<arg>
<name>c</name>
<type>Block</type>
<impl>OCustomer</impl>
<pass>Reference</pass>
<use>InOut</use>
</arg>
</args>
</method>
<method>
<name>o_find_by_name</name>
<args>
<arg>
<name>name</name>
<type>FixedCharacterString</type>
<pass>Reference</pass>
<use>In</use>
</arg>
<arg>
<name>c</name>
<type>Block</type>
<impl>OCustomer</impl>
<pass>Reference</pass>
<use>InOut</use>
</arg>
</args>
</method>
<method>
<name>o_list_start</name>
<args/>
</method>
<method>
<name>o_list_next</name>
<args>
<arg>
<name>c</name>
<type>Block</type>
<impl>OCustomer</impl>
<pass>Reference</pass>
<use>InOut</use>
</arg>
</args>
</method>
<method>
<name>o_add</name>
<args>
<arg>
<name>c</name>
<type>Block</type>
<impl>OCustomer</impl>
<pass>Reference</pass>
<use>In</use>
</arg>
</args>
</method>
<method>
<name>o_close_file</name>
<args/>
</method>
</methods>
</config>
Gen:
java -cp vmstig.jar dk.vajhoej.vms.tig.Gen o.xml server client
Run server:
$ javac -cp vmstig.jar:vmscall.jar:record.jar OshrServer.java
$ java -cp .:vmstig.jar:vmscall.jar:record.jar "OshrServer"
OCustomer.java:
import dk.vajhoej.record.FieldType;
import dk.vajhoej.record.Struct;
import dk.vajhoej.record.StructField;
@Struct
public class OCustomer {
public static String format(int id) {
return String.format("%07d", id);
}
public static int parse(String id) {
return Integer.parseInt(id);
}
public static String pad(String name) {
return name + " ".substring(0, 32 - name.length());
}
@StructField(n=0,type=FieldType.FIXSTR,length=7)
private String id;
@StructField(n=1,type=FieldType.FIXSTR,length=32,pad=true,padchar=' ')
private String name;
@StructField(n=2,type=FieldType.FIXSTR,length=64,pad=true,padchar=' ')
private String address;
public OCustomer() {
this(0, "", "");
}
public OCustomer(int id, String name, String address) {
this.id = format(id);
this.name = name;
this.address = address;
}
public int getId() {
return parse(id);
}
public void setId(int id) {
this.id = format(id);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
OTest.java:
import java.io.IOException;
import dk.vajhoej.record.RecordException;
public class OTest {
private static void dump(OCustomer c) {
System.out.println("id=" + c.getId());
System.out.println("name=" + c.getName());
System.out.println("address=" + c.getAddress());
}
private static void testFindById(OshrClient cli, int id) throws IOException, RecordException {
OCustomer[] c = new OCustomer[1];
c[0] = new OCustomer();
if(cli.o_find_by_id(OCustomer.format(id), c) % 2 == 1) {
System.out.println("find by id: " + id);
dump(c[0]);
} else {
System.out.println("not found: " + id);
}
}
private static void testFindByName(OshrClient cli, String name) throws IOException, RecordException {
OCustomer[] c = new OCustomer[1];
c[0] = new OCustomer();
if(cli.o_find_by_name(OCustomer.pad(name), c) % 2 == 1) {
System.out.println("find by name: " + name);
dump(c[0]);
} else {
System.out.println("not found: " + name);
}
}
private static void testList(OshrClient cli) throws IOException, RecordException {
System.out.println("list");
cli.o_list_start();
OCustomer[] c = new OCustomer[1];
c[0] = new OCustomer();
while(cli.o_list_next(c) % 2 == 1) {
dump(c[0]);
}
}
private static void testAdd(OshrClient cli, int id, String name, String address) throws IOException, RecordException {
OCustomer c = new OCustomer(id, name, address);
if(cli.o_add(c) %2 == 1) {
System.out.println("add succeeded");
} else {
System.out.println("add failed");
}
}
public static void main(String[] args) throws IOException, RecordException {
OshrClient cli = new OshrClient("arne4");
cli.o_open_file();
testFindById(cli, 2);
testFindById(cli, 6);
testFindByName(cli, "B B");
testFindByName(cli, "F F");
testList(cli);
testAdd(cli, 6, "F F", "F road 6");
testList(cli);
testAdd(cli, 0, "X X", "X road");
testList(cli);
cli.o_close_file();
}
}
Build and run:
javac -cp record.jar;vmstig.jar OCustomer.java OshrClient.java OTest.java
java -cp .;record.jar;vmstig.jar OTest
OCustomer.java:
import dk.vajhoej.record.FieldType;
import dk.vajhoej.record.Struct;
import dk.vajhoej.record.StructField;
@Struct
public class OCustomer {
public static String format(int id) {
return String.format("%07d", id);
}
public static int parse(String id) {
return Integer.parseInt(id);
}
public static String pad(String name) {
return name + " ".substring(0, 32 - name.length());
}
@StructField(n=0,type=FieldType.FIXSTR,length=7)
private String id;
@StructField(n=1,type=FieldType.FIXSTR,length=32,pad=true,padchar=' ')
private String name;
@StructField(n=2,type=FieldType.FIXSTR,length=64,pad=true,padchar=' ')
private String address;
public OCustomer() {
this(0, "", "");
}
public OCustomer(int id, String name, String address) {
this.id = format(id);
this.name = name;
this.address = address;
}
public int getId() {
return parse(id);
}
public void setId(int id) {
this.id = format(id);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
OTest.groovy:
def dump(c) {
println("id=" + c.id)
println("name=" + c.name)
println("address=" + c.address)
}
def testFindById(cli, id) {
c = new OCustomer[1]
c[0] = new OCustomer()
if(cli.o_find_by_id(OCustomer.format(id), c) % 2 == 1) {
println("find by id: " + id)
dump(c[0])
} else {
println("not found: " + id)
}
}
def testFindByName(cli, name) {
c = new OCustomer[1]
c[0] = new OCustomer()
if(cli.o_find_by_name(OCustomer.pad(name), c) % 2 == 1) {
println("find by name: " + name)
dump(c[0])
} else {
println("not found: " + name)
}
}
def testList(cli) {
println("list")
cli.o_list_start()
c = new OCustomer[1]
c[0] = new OCustomer()
while(cli.o_list_next(c) % 2 == 1) {
dump(c[0])
}
}
def testAdd(cli, id, name, address) {
c = new OCustomer(id, name, address)
if(cli.o_add(c) %2 == 1) {
println("add succeeded")
} else {
println("add failed")
}
}
cli = new OshrClient("arne4")
cli.o_open_file()
testFindById(cli, 2)
testFindById(cli, 7)
testFindByName(cli, "B B")
testFindByName(cli, "G G")
testList(cli)
testAdd(cli, 7, "G G", "G road 7")
testList(cli)
testAdd(cli, 0, "X X", "X road")
testList(cli)
cli.o_close_file()
Build and run:
javac -cp record.jar;vmstig.jar OCustomer.java OshrClient.java
set classpath=.;record.jar;vmstig.jar
groovy OTest.groovy
OCustomer.cs:
using Vajhoej.Record;
[Struct]
public class OCustomer
{
public static string Format(int id)
{
return id.ToString("0000000");
}
public static int Parse(string id)
{
return int.Parse(id);
}
public static string Pad(string name)
{
return name + " ".Substring(0, 32 - name.Length);
}
[StructField(N=0, Type=FieldType.FIXSTR, Length=7)]
private string id;
[StructField(N=1, Type=FieldType.FIXSTR, Length=32, Pad=true, PadChar=' ')]
private string name;
[StructField(N=2, Type=FieldType.FIXSTR, Length=64, Pad=true, PadChar=' ')]
private string address;
public OCustomer() : this(0, "", "")
{
}
public OCustomer(int id, string name, string address)
{
this.id = Format(id);
this.name = name;
this.address = address;
}
public int Id
{
get { return Parse(id); }
set { id = Format(value); }
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
}
OTest.cs:
using System;
public class OTest
{
private static void Dump(OCustomer c)
{
Console.WriteLine("id=" + c.Id);
Console.WriteLine("name=" + c.Name);
Console.WriteLine("address=" + c.Address);
}
private static void TestFindById(OshrClient cli, int id)
{
OCustomer c = new OCustomer();
if(cli.O_find_by_id(OCustomer.Format(id), ref c) % 2 == 1)
{
Console.WriteLine("find by id: " + id);
Dump(c);
}
else
{
Console.WriteLine("not found: " + id);
}
}
private static void TestFindByName(OshrClient cli, string name)
{
OCustomer c = new OCustomer();
if(cli.O_find_by_name(OCustomer.Pad(name), ref c) % 2 == 1)
{
Console.WriteLine("find by name: " + name);
Dump(c);
}
else
{
Console.WriteLine("not found: " + name);
}
}
private static void TestList(OshrClient cli)
{
Console.WriteLine("list");
cli.O_list_start();
OCustomer c = new OCustomer();
while(cli.O_list_next(ref c) % 2 == 1)
{
Dump(c);
}
}
private static void TestAdd(OshrClient cli, int id, String name, String address)
{
OCustomer c = new OCustomer(id, name, address);
if(cli.O_add(c) %2 == 1)
{
Console.WriteLine("add succeeded");
}
else
{
Console.WriteLine("add failed");
}
}
public static void Main(string[] args)
{
OshrClient cli = new OshrClient("ARNE4");
cli.O_open_file();
TestFindById(cli, 2);
TestFindById(cli, 8);
TestFindByName(cli, "B B");
TestFindByName(cli, "H H");
TestList(cli);
TestAdd(cli, 8, "H H", "H road 8");
TestList(cli);
TestAdd(cli, 0, "X X", "X road");
TestList(cli);
cli.O_close_file();
}
}
Build and run:
csc /r:tig.dll /r:record.dll OTest.cs OshrClient.cs OCustomer.cs
OTest
OCustomer.py:
import struct
class OCustomer:
@staticmethod
def format(id):
return '%07d' % (id)
@staticmethod
def parse(id):
return int(id)
@staticmethod
def pad(name):
return name.ljust(32, ' ')
def __init__(self, id = 0, name = '', address = ''):
self.id = id
self.name = name
self.address = address
def pack(self):
return struct.pack('7s32s64s', bytes(OCustomer.format(self.id), 'iso-8859-1'), bytes(self.name.ljust(32,' '), 'iso-8859-1'), bytes(self.address.ljust(64,' '), 'iso-8859-1'))
def unpack(self, blk):
data = struct.unpack('7s32s64s', blk)
self.id = OCustomer.parse(str(data[0], 'iso-8859-1'))
self.name = str(data[1], 'iso-8859-1').rstrip(' \0')
self.address = str(data[2], 'iso-8859-1').rstrip(' \0')
otest.py:
from OshrClient import OshrClient
from OCustomer import OCustomer
def dump(c):
print('id=' + str(c.id))
print('name=' + c.name)
print('address=' + c.address)
def test_find_by_id(cli, id):
c = OCustomer()
stat, c = cli.o_find_by_id(OCustomer.format(id), c)
if stat % 2 == 1:
print('find by id: ' + str(id))
dump(c)
else:
print('not found: ' + str(id))
def test_find_by_name(cli, name):
c = OCustomer()
stat, c = cli.o_find_by_name(OCustomer.pad(name), c)
if stat % 2 == 1:
print('find by name: ' + name)
dump(c)
else:
print('not found: ' + name)
def test_list(cli):
print('list')
cli.o_list_start()
while True:
c = OCustomer()
stat, c = cli.o_list_next(c)
if stat % 2 != 1: break
dump(c)
def test_add(cli, id, name, address):
c = OCustomer(id, name, address)
if cli.o_add(c) % 2 == 1:
print('add succeded')
else:
print('add failed')
cli = OshrClient('arne4')
cli.o_open_file()
test_find_by_id(cli, 2)
test_find_by_id(cli, 9)
test_find_by_name(cli, 'B B')
test_find_by_name(cli, 'I I')
test_list(cli)
test_add(cli, 9, 'I I', 'I road 9')
test_list(cli)
test_add(cli, 0, 'X X', 'X road')
test_list(cli)
cli.o_close_file()
Run:
python otest.py
oCustomer.php:
<?php
class OCustomer {
static function format($id) {
return sprintf('%07d', $id);
}
static function parse($id) {
return sscanf($id, '%07d')[0];
}
static function pad($name) {
return str_pad($name, 32, ' ');
}
public $id;
public $name;
public $address;
function __construct($id = 0, $name = '', $address = '') {
$this->id = $id;
$this->name = $name;
$this->address = $address;
}
function pack() {
return pack('a7a32a64', OCustomer::format($this->id), str_pad($this->name, 32, ' '), str_pad($this->address, 64, ' '));
}
function unpack($blk) {
$this->id = OCustomer::parse(unpack('a7', $blk, 0)[1]);
$this->name = trim(unpack('a32', $blk, 7)[1]);
$this->address = trim(unpack('a64', $blk, 39)[1]);
}
}
?>
otest.php:
<?php
include 'OCustomer.php';
include 'OshrClient.php';
function dump($c) {
echo 'id=' . $c->id . "\r\n";
echo 'name=' . $c->name . "\r\n";
echo 'address=' . $c->address . "\r\n";
}
function test_find_by_id($cli, $id) {
$c = new OCustomer();
if($cli->o_find_by_id(OCustomer::format($id), $c) % 2 == 1) {
echo 'find by id: ' . $id . "\r\n";
dump($c);
} else {
echo 'not found: ' . $id . "\r\n";
}
}
function test_find_by_name($cli, $name) {
$c = new OCustomer();
if($cli->o_find_by_name(OCustomer::pad($name), $c) % 2 == 1) {
echo 'find by name: ' . $name . "\r\n";
dump($c);
} else {
echo 'not found: ' . $name . "\r\n";
}
}
function test_list($cli) {
echo "list\r\n";
$cli->o_list_start();
$c = new OCustomer();
while($cli->o_list_next($c) % 2 == 1) {
dump($c);
}
}
function test_add($cli, $id, $name, $address) {
$c = new OCustomer($id, $name, $address);
if($cli->o_add($c) % 2 == 1) {
echo "add succeeded\r\n";
} else {
echo "add failed\r\n";
}
}
$cli = new OshrClient('arne4');
$cli->o_open_file();
test_find_by_id($cli, 2);
test_find_by_id($cli, 10);
test_find_by_name($cli, 'B B');
test_find_by_name($cli, 'J J');
test_list($cli);
test_add($cli, 10, 'J J', 'J road 10');
test_list($cli);
test_add($cli, 0, 'X X', 'X road');
test_list($cli);
$cli->o_close_file()
?>
Run:
php otest.php
o.jsp:
<html>
<head>
<title>Oshr test</title>
</head>
<body>
<h1>Oshr test</h1>
<h2>Find by id:</h2>
<form method="post" action="o_find_by_id.jsp">
Id: <input type="text" name="id">
<br>
<input type="submit" value="Find">
</form>
<h2>Find by name:</h2>
<form method="post" action="o_find_by_name.jsp">
Name: <input type="text" name="name">
<br>
<input type="submit" value="Find">
</form>
<h2>List all:</h2>
<form method="post" action="o_list.jsp">
<input type="submit" value="List">
</form>
<h2>Add one:</h2>
<form method="post" action="o_add.jsp">
Id: <input type="text" name="id">
<br>
Name: <input type="text" name="name">
<br>
Address: <input type="text" name="address">
<br>
<input type="submit" value="Add">
</form>
</body>
</html>
o_find_by_id.jsp:
<%@ page import="oshr.*" %>
<html>
<head>
<title>Find by id</title>
</head>
<body>
<h1>Find by id</h1>
<h2>Result:</h2>
<%
int id = Integer.parseInt(request.getParameter("id"));
synchronized(OshrClient.class) {
OshrClient cli = new OshrClient("arne4");
cli.o_open_file();
OCustomer[] c = new OCustomer[1];
c[0] = new OCustomer();
if(cli.o_find_by_id(OCustomer.format(id), c) % 2 == 1) {
out.println("id = " + c[0].getId() + "<br>");
out.println("name = " + c[0].getName() + "<br>");
out.println("address = " + c[0].getAddress());
} else {
out.println("Error: id " + id + " not found");
}
cli.o_close_file();
}
%>
</body>
</html>
o_find_by_name.jsp:
<%@ page import="oshr.*" %>
<html>
<head>
<title>Find by name</title>
</head>
<body>
<h1>Find by name</h1>
<h2>Result:</h2>
<%
String name = request.getParameter("name");
synchronized(OshrClient.class) {
OshrClient cli = new OshrClient("arne4");
cli.o_open_file();
OCustomer[] c = new OCustomer[1];
c[0] = new OCustomer();
if(cli.o_find_by_name(OCustomer.pad(name), c) % 2 == 1) {
out.println("id = " + c[0].getId() + "<br>");
out.println("name = " + c[0].getName() + "<br>");
out.println("address = " + c[0].getAddress());
} else {
out.println("Error: name " + name + " not found");
}
cli.o_close_file();
}
%>
</body>
</html>
o_list.jsp:
<%@ page import="oshr.*" %>
<html>
<head>
<title>List all</title>
</head>
<body>
<h1>List all</h1>
<h2>List:</h2>
<table border="1">
<%
synchronized(OshrClient.class) {
OshrClient cli = new OshrClient("arne4");
cli.o_open_file();
cli.o_list_start();
OCustomer[] c = new OCustomer[1];
c[0] = new OCustomer();
while(cli.o_list_next(c) % 2 == 1) {
out.println("<tr>");
out.println("<td>" + c[0].getId() + "</td>");
out.println("<td>" + c[0].getName() + "</td>");
out.println("<td>" + c[0].getAddress() + "</td>");
out.println("</tr>");
}
cli.o_close_file();
}
%>
</table>
</body>
</html>
o_add.jsp:
<%@ page import="oshr.*" %>
<html>
<head>
<title>Add one</title>
</head>
<body>
<h1>Add one</h1>
<h2>Status:</h2>
<%
int id = Integer.parseInt(request.getParameter("id"));
String name = request.getParameter("name");
String address = request.getParameter("address");
synchronized(OshrClient.class) {
OshrClient cli = new OshrClient("arne4");
cli.o_open_file();
OCustomer c = new OCustomer(id, name, address);
if(cli.o_add(c) % 2 == 1) {
out.println(id + " added");
} else {
out.println(id + " not added");
}
cli.o_close_file();
}
%>
</body>
</html>
o.php:
<html>
<head>
<title>Oshr test</title>
</head>
<body>
<h1>Oshr test</h1>
<h2>Find by id:</h2>
<form method="post" action="o_find_by_id.php">
Id: <input type="text" name="id">
<br>
<input type="submit" value="Find">
</form>
<h2>Find by name:</h2>
<form method="post" action="o_find_by_name.php">
Name: <input type="text" name="name">
<br>
<input type="submit" value="Find">
</form>
<h2>List all:</h2>
<form method="post" action="o_list.php">
<input type="submit" value="List">
</form>
<h2>Add one:</h2>
<form method="post" action="o_add.php">
Id: <input type="text" name="id">
<br>
Name: <input type="text" name="name">
<br>
Address: <input type="text" name="address">
<br>
<input type="submit" value="Add">
</form>
</body>
</html>
o_find_by_id.php:
<html>
<head>
<title>Find by id</title>
</head>
<body>
<h1>Find by id</h1>
<h2>Result:</h2>
<?php
include 'OCustomer.php';
include 'OshrClient.php';
$id = (int)$_POST['id'];
$sem = sem_get(30003);
sem_acquire($sem);
$cli = new OshrClient('arne4');
$cli->o_open_file();
$c = new OCustomer();
if($cli->o_find_by_id($id, $c) % 2 == 1) {
echo 'id = ' . $c->id . "<br>";
echo 'name = ' . $c->name . "<br>";
echo 'address = ' . $c->address . "";
} else {
echo "Error: id $id not found";
}
$cli->o_close_file();
sem_release($sem);
?>
</body>
</html>
o_find_by_name.php:
<html>
<head>
<title>Find by name</title>
</head>
<body>
<h1>Find by name</h1>
<h2>Result:</h2>
<?php
include 'OCustomer.php';
include 'OshrClient.php';
$name = $_POST['name'];
$cli = new OshrClient('arne4');
$sem = sem_get(30003);
sem_acquire($sem);
$cli->o_open_file();
$c = new OCustomer();
if($cli->o_find_by_name($name, $c) % 2 == 1) {
echo 'id = ' . $c->id . "<br>";
echo 'name = ' . $c->name . "<br>";
echo 'address = ' . $c->address . "";
} else {
echo "Error: name $name not found";
}
$cli->o_close_file();
sem_release($sem);
?>
</body>
</html>
o_list.php:
<html>
<head>
<title>List all</title>
</head>
<body>
<h1>List all</h1>
<h2>List:</h2>
<table border="1">
<?php
include 'OCustomer.php';
include 'OshrClient.php';
$sem = sem_get(30001);
sem_acquire($sem);
$cli = new OshrClient('arne4');
$cli->o_open_file();
$cli->o_list_start();
$c = new OCustomer();
while($cli->o_list_next($c) % 2 == 1) {
echo '<tr>';
echo '<td>' . $c->id . '</td>';
echo '<td>' . $c->name . '</td>';
echo '<td>' . $c->address . '</td>';
echo '</tr>';
}
$cli->o_close_file();
sem_release($sem);
?>
</table>
</body>
</html>
o_add.php:
<html>
<head>
<title>Add one</title>
</head>
<body>
<h1>Add one</h1>
<h2>Status:</h2>
<?php
include 'OCustomer.php';
include 'OshrClient.php';
$id = (int)$_POST['id'];
$name = $_POST['name'];
$address = $_POST['address'];
$sem = sem_get(30001);
sem_acquire($sem);
$cli = new OshrClient('arne4');
$cli->o_open_file();
$c = new OCustomer($id, $name, $address);
if($cli->o_add($c) % 2 == 1) {
echo "$id added";
} else {
echo "$id not added";
}
$cli->o_close_file();
sem_release($sem);
?>
</body>
</html>
Version | Date | Description |
---|---|---|
1.0 | February 15th 2025 | Initial version |
See list of all articles here
Please send comments to Arne Vajhøj