and here is BBS for tyserv. use it in a carefree :-)
If you like old but simple database programming environments like COBOL+VSAM(KSDS) or C+C-ISAM, you will like tyserv too ;-)
ex. (/etc/rc.d/rc.local etc)
if [ -x /etc/rc.d/rc.tyserv ]; then
. /etc/rc.d/rc.tyserv -d /home/tyserv/rundir1
fi
chmod 600 /home/tyserv/tyserv/etc/passwd
(*) access_control
access library(tyserv/sample/perl/tyserv.pl) is ready for perl.
c interface(tyserv/sample/open-cobol/tycob.c) is ready for OpenCOBOL.
see tyserv/sample/perl/*, tyserv/sample/open-cobol/* to use tyserv.pl or
tycob.c.
command token is separated by TAB(0x09).
status1 status2 name1=value1 name2=value2 ... nameX valueX
separeter is TAB(0x09).
CONDITION is
see tyserv/doc/*, tyserv/sample/perl/*.pl to get more information.
$ telnet localhost 20000 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. start_tran user user <-Input OK TRANSACTION START <-Response put smp1 id=1111 name=Taro salary=150000 <-Input OK INSERTED <-Response put smp1 id=2222 name=Jiro salary=200000 <-Input OK INSERTED <-Response put smp1 id=3333 name=Goro salary=250000 <-Input OK INSERTED <-Response commit <-Input OK COMMITED <-Response get smp1 pkey eq 1111 <-Input OK FOUND id=1111 name=Taro salary=150000 <-Response getnext smp1 pkey <-Input OK FOUND id=2222 name=Jiro salary=200000 <-Response getnext smp1 pkey <-Input OK FOUND id=3333 name=Goro salary=250000 <-Response update smp1 2222 name=Jirorin <-Input OK UPDATED <-Response get smp1 pkey eq 2222 <-Input OK FOUND id=2222 name=Jirorin salary=200000 <-Response delete smp1 2222 <-Input OK DELETED <-Response get smp1 pkey eq 2222 <-Input NG NOTFOUND <-Response rollback <-Input OK ROLLBACKED <-Response get smp1 pkey eq 2222 <-Input OK FOUND id=2222 name=Jiro salary=200000 <-Response end_tran <-Input OK TRANSACTION END <-Response Connection closed by foreign host.
#! /usr/bin/perl
#---------------------------------------------------------
# socket communication library
use IO::Socket;
#
# tyserv access library
require 'tyserv.pl';
#---------------------------------------------------------
# user name
$user = "manager";
#
# password
$passwd = "manager";
#
# host name
$host = "localhost";
#
# port number
$port = 20000;
#---------------------------------------------------------
# get socket handle
$handle = IO::Socket::INET->new(Proto => "tcp",
PeerAddr => $host,
PeerPort => $port);
#
# set autoflush socket
$handle->autoflush(1); # so output gets there right away
#---------------------------------------------------------
# update transaction start
($sts1, $sts2) = &ty_start_tran($handle, $user, $passwd);
#---------------------------------------------------------
# initialize record
%rec = ();
#
# set record
$rec{id} = "9999";
$rec{name} = "Mr. X";
$rec{salary} = 900000;
#
# insert record
($sts1, $sts2) = &ty_put($handle, "smp1", \%rec);
#---------------------------------------------------------
# initialize record
%rec = ();
#
# get record
($sts1, $sts2, %rec) = &ty_get($handle, "smp1", "pkey", "eq", ["9999"]);
#---------------------------------------------------------
# update salary B-)
$rec{salary} *= 10;
#
# update record
($sts1, $sts2) = &ty_update($handle, "smp1", ["9999"], \%rec);
#---------------------------------------------------------
# delete recoed
($sts1, $sts2) = &ty_delete($handle, "smp1", ["9999"]);
#---------------------------------------------------------
# terminate transaction
($sts1, $sts2) = &ty_end_tran($handle);
#---------------------------------------------------------
#
exit 0;
IDENTIFICATION DIVISION.
PROGRAM-ID. sample1.
ENVIRONMENT DIVISION.
*------------------------------------------
* work definition
*------------------------------------------
WORKING-STORAGE SECTION.
*------------------------------------------
* constant value
*------------------------------------------
01 C-NULL PIC X(1) VALUE LOW-VALUE.
01 C-TAB PIC X(1) VALUE X'09'.
*------------------------------------------
* work variable
*------------------------------------------
*
* sock_* interface
*
01 HOST.
02 FILLER PIC X(9) VALUE 'localhost'.
02 FILLER PIC X(1) VALUE LOW-VALUE.
01 PORT.
02 FILLER PIC X(5) VALUE '20000'.
02 FILLER PIC X(1) VALUE LOW-VALUE.
01 FD-SOCK.
02 FILLER PIC X(5) VALUE SPACE.
02 FILLER PIC X(1) VALUE LOW-VALUE.
01 SEND-DATA.
02 FILLER PIC X(1024) VALUE SPACE.
02 FILLER PIC X(1) VALUE LOW-VALUE.
01 RECV-DATA.
02 FILLER PIC X(1024) VALUE SPACE.
02 FILLER PIC X(1) VALUE LOW-VALUE.
*
* get_* interface
*
01 STAT1 PIC X(2) VALUE SPACE.
01 STAT2 PIC X(1024) VALUE SPACE.
01 G-ID PIC X(4).
01 G-NAME PIC X(20).
01 G-SALARY PIC 9(7).
*------------------------------------------
* procedure start
*------------------------------------------
PROCEDURE DIVISION.
*
MAIN-EN.
*
* socket open
*
CALL 'sock_open' USING HOST PORT FD-SOCK.
*
* start update transaction
*
INITIALIZE SEND-DATA RECV-DATA STAT1 STAT2.
STRING 'start_tran' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'user' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'user' DELIMITED BY SIZE
C-NULL DELIMITED BY SIZE
INTO SEND-DATA.
CALL 'sock_send_recv' USING FD-SOCK SEND-DATA RECV-DATA.
CALL 'get_status' USING RECV-DATA STAT1 STAT2.
*
* insert record
*
INITIALIZE SEND-DATA RECV-DATA STAT1 STAT2.
STRING 'put' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'smp1' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'id=9999' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'name=Mr. X' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'salary=0900000' DELIMITED BY SIZE
C-NULL DELIMITED BY SIZE
INTO SEND-DATA.
CALL 'sock_send_recv' USING FD-SOCK SEND-DATA RECV-DATA.
CALL 'get_status' USING RECV-DATA STAT1 STAT2.
*
* get record
*
INITIALIZE SEND-DATA RECV-DATA STAT1 STAT2.
STRING 'get' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'smp1' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'pkey' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'eq' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'9999' DELIMITED BY SIZE
C-NULL DELIMITED BY SIZE
INTO SEND-DATA.
CALL 'sock_send_recv' USING FD-SOCK SEND-DATA RECV-DATA.
CALL 'get_status' USING RECV-DATA STAT1 STAT2.
*
* update salary B-)
*
INITIALIZE G-ID G-NAME G-SALARY.
CALL 'get_value' USING RECV-DATA 'id' G-ID.
CALL 'get_value' USING RECV-DATA 'name' G-NAME.
CALL 'get_value' USING RECV-DATA 'salary' G-SALARY.
COMPUTE G-SALARY = G-SALARY * 10.
*
* update record
*
INITIALIZE SEND-DATA RECV-DATA STAT1 STAT2.
STRING 'update' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'smp1' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
G-ID DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'salary=' DELIMITED BY SIZE
G-SALARY DELIMITED BY SIZE
C-NULL DELIMITED BY SIZE
INTO SEND-DATA.
CALL 'sock_send_recv' USING FD-SOCK SEND-DATA RECV-DATA.
CALL 'get_status' USING RECV-DATA STAT1 STAT2.
*
* delete record
*
INITIALIZE SEND-DATA RECV-DATA STAT1 STAT2.
STRING 'delete' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'smp1' DELIMITED BY SIZE
C-TAB DELIMITED BY SIZE
'9999' DELIMITED BY SIZE
C-NULL DELIMITED BY SIZE
INTO SEND-DATA.
CALL 'sock_send_recv' USING FD-SOCK SEND-DATA RECV-DATA.
CALL 'get_status' USING RECV-DATA STAT1 STAT2.
*
* terminate transaction
*
INITIALIZE SEND-DATA RECV-DATA STAT1 STAT2.
STRING 'end_tran' DELIMITED BY SIZE
INTO SEND-DATA.
CALL 'sock_send_recv' USING FD-SOCK SEND-DATA RECV-DATA.
CALL 'get_status' USING RECV-DATA STAT1 STAT2.
*
* socket close
*
CALL 'sock_close' USING FD-SOCK.
MAIN-EX.
STOP RUN.
*------------------------------------------
* all terminate
*------------------------------------------
if program terminate without END_TRAN, ABORT_TRAN, ABORT_TRAN is assumed.
| STS1 | STS2 |
|---|---|
| OK | COMMITED |
| OK | COMMITED BUT RECOVERY JOURNAL OVERFLOW |
| OK | DELETED |
| OK | FOUND |
| OK | INSERTED |
| OK | NORMAL SHUTDOWN |
| OK | ROLLBACKED |
| OK | SWAPRVJ TO full_path_of_recovery_journal |
| OK | TRANSACTION ABORT, ROLLBACKED |
| OK | TRANSACTION END |
| OK | TRANSACTION END BUT RECOVERY JOURNAL OVERFLOW |
| OK | TRANSACTION START |
| OK | UPDATED |
| NG | ACCESS DENIED(ip address) |
| NG | CAN NOT OPEN DATABASE db_status=xxxx |
| NG | CAN NOT READ SOCKET |
| NG | DUPLICATE |
| NG | NO RECOVERY JOURNAL |
| NG | NO ROLLBACK JOURNAL |
| NG | NOT GRANTED |
| NG | NOTFOUND |
| NG | RECOVERY JOURNAL OVERFLOW |
| NG | REQUIRE START_TRAN OR START_TRAN_NJ OR START_TRANM |
| NG | ROLLBACK JOURNAL OVERFLOW |
| NG | SOCKET READ ERROR |
| NG | SOCKET READ ERROR, ROLLBACKED |
| NG | STATUS=xxxx |
| NG | UNKNOWN CONDITION |
| NG | UNKNOWN FUNCTION |
| NG | UNKNOWN ITEM |
| NG | UNKNOWN KEY |
| NG | UNKNOWN RECORD |
1 database typhoondb {
2 data file "smp1.dat" contains smp1;
3 key file "smp1.pk" contains smp1.smp1_pkey;
4 key file "smp1.s1" contains smp1.smp1_skey1;
5 record smp1 {
6 char id[4 + 1];
7 char name[20 + 1];
8 char salary[7 + 1];
9 primary key smp1_pkey { id asc };
10 alternate key smp1_skey1 { name asc, id asc };
11 }
12 }
1 start database definition
database database_name {
o database_name must be `typhoondb'.
2 base data file definition
data file "file_name" contains table_name;
o file_name must be `table_name' + `.dat'
3 primary key data file definition
key file "file_name" contains table_name.table_name_pkey;
o primary key must be unique in table
o file_name must be `table_name.pk'
4 alternate key data file definition
key file "file_name" contains table_name.table_name_skey(seq number);
o alternate key can be multiple
o file_name must be `table_name' + `.s' + `seq number'
o seq number must be from 1 by 1 at each alternate key
5 start table definition
record table_name {
6 column definition
7 column definition
8 column definition
char column_name[length + 1];
o only `char' can be specified
9 primary key definition
primary key table_name_pkey { colmun_name sequence[, colmun_name sequence] ... };
o primary key must be unique in table
o primary key must point a record uniquely
o sequence must be `asc' or `desc'
10 alternate key definition
alternate key table_name_skey(seq number) { colmun_name sequence[, colmun_name sequence] ... };
o alternate key can be multiple
o alternate key can point multiple records
o seq number must be from 1 by 1 at each alternate key
11 end of table definition
}
12 end of database definition
}
tyimport(in typhoon-1.11.0) generate typhoondb.imp. typhoondb.imp include import definition for all table.
copy typhoondb.imp to typhoondb.table_name.imp, and edit typhoondb.table_name.imp to leave about table_name.
data load from foo.txt into table
foo.txt : CSV file separeted by TAB.
foo.txt must include same number colmun in typhoondb.smp1.imp.
tyexport(in typhoon-1.11.0) generate typhoondb.exp. typhoondb.exp include export definition for all table.
copy typhoondb.exp to typhoondb.table_name.exp, and edit typhoondb.table_name.exp to leave about table_name.
data output from table into foo.txt
ex. if table `smp1' exists in typhoondb.ddl, OBJS is defined following
OBJS = tyserv_smp1.o
and then you want to add table `smp2', OBJS must be following
OBJS = tyserv_smp1.o \
tyserv_smp2.o
object name must be `tyserv_' + `table_name' + `.o'
tyserv is executed in background automatically
and `SOCKET_PORT=port_number' must be unique in each tyserv.conf.
$ tysearch -h <-- show help usage : tysearch table start_count rec_count key_name key_value ... environment value : TYPHOON_DIR $ tysearch smp1 1 3 pkey 0003 OK FOUND id=0003 name=Kiyoshi Sakamoto salary=0510000 OK FOUND id=0004 name=Masaharu Sawada salary=0470000 OK FOUND id=0005 name=Masahiko Ito salary=0300000 $
$ tytran.sh -h <-- show help
usage : tytran.sh [-s server|--server server] [-p port|--port port] [-n|--ngexit] [-v|--verbose]
execute transaction in batch mode
option : -s server connect to server. default localhost.
-p port connect to port. default 20000.
-n, --ngexit exit when NG status
-v, --verbose verbose mode
$ vi trancmd.txt
#
# comment here
#
START_TRAN USER USER
GET smp1 pkey eq 0001
UPDATE smp1 0001 salary=9999999
COMMIT
END_TRAN
$ tytran.sh <trancmd.txt