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