Go Back

User login

Frontpage Sponsor


For ERP LN feature pack upgrade, what method of install are you using?
Installation Wizard into existing VRC
Installation Wizard into new VRC
Manual into existing VRC
Manual into new VRC
Total votes: 31

Baanboard at LinkedIn

Reference Content

gcommand tool
By patvdv at 23 Feb 2008 - 21:06


A tool called gcommand is used for testing Triton database drivers. This tool is extremely useful and can be used for testing drivers at any stage e.g during initial development, enhancements, simulating a bug etc.

This document describes the usage of gcommand. It is assumed that the reader is familiar with Triton database drivers and various database actions described in this document.


Running gcommand.

Gcommand is a executable, $BSE/bin/gcommand6.1 It reads the database actions to be executed from a text file.

Syntax of using gcommand is as follows


gcommand6.1 [ Test File ] [ Company Number ]


  • Test File : name of the text file containing the database actions can be specified. If no file is specified, by default, gcommand reads from file commands
  • Company : if company number is specified, all commands in the tests are executed in that company. If no company number is specified, company 000 is default.

As gcommand executes each database action, it writes information about it on stderr. The detail results of the test are written in a file named commlog, which is created in the directory from where gcommand is run. This file should be viewed later to see if any actions failed. A simple way to do that is to search for pattern !!! ( three ! characters ) in commlog files. Presence of it at any position indicates an error on that command.


Command Line Options

  • Command line option -P can be used to print the domain file e.g. daa.pd for the table.
  • Command line option -D can be used to print the DD of a table.

Note that the domain and dictionary information is hardcoded in the program and it will not generate various types of DD files.

  • Command line option -u or -U can be used to print the usage.
  • Command line option -v or -V can be used to print the compilation information about the gcommand binary.


Format of test file

The test file a ASCII text file, containing the database actions to be executed and parameters for these actions, if any. The format of specifying a database command is:


[ Session ] <Table> <Action> <Argument> [ Options ]



Session is a optional parameter. If no session is specified, all commands are executed in one session. A session can be specified as #n e.g


with n between 1 to 16.

For each session in the test file, corresponding session is created in database driver. All commands specified in same session are executed in corresponding session. E.g all commands starting with #1 are executed in one session, those with #2 in another session etc.



This is mandatory parameter, specifying table on which database action will be done. The format is:


<package> <table name>


e.g ttadv999, tiitm001 etc.



This a mandatory parameter, specifying the database action to be performed. This is a string. Actions are described below, grouped by their nature for better understanding.


Transaction Level Actions

These actions are the transaction control actions in session. They start with D

  • DCOM : commit transaction
  • DABORT : abort transaction

An example would be:


#1 aabdb000 DABORT 0


Table Level Actions

These actions start with T.

  • TCRTBL : create table
  • TDRTBL : drop table
  • TCRI : create index
  • TDRI : drop Index
  • TCLTBL : clear table
  • TCLREF : clear reference counters
  • TLOCK : lock table
  • TNRROW : count rows in table
  • TCHORD : change current index.


Row Level Actions

These actions start with R. Most of the row level actions are relative to the current index.


Read without lock

Following reads do not put any locks on rows read.

  • RFIRST : read first row
  • RLAST : read last row
  • RNEXT : read next row
  • RPREV : read previous row
  • RCURR : read current row
  • RGREAT : read greater than
  • RGTEQ : read greater than or equal
  • RLESS : read less than
  • REQLE : read less than or equal
  • REQUAL : read equal


Read with lock

Following commands read a row with lock. The lock is maintained till end of transaction. Note that all these commands have a ending '*'.

  • RFIRST* : read first row with lock
  • RLAST* : read last row with lock
  • RNEXT* : read next row with lock
  • RPREV* : read previous row with lock
  • RCURR* : read current row with lock
  • RGREAT* : read greater than with lock
  • RGTEQ* : read greater than or equal with lock
  • RLESS* : read less than with lock
  • REQLE* : read less than or equal with lock
  • REQUAL* : read equal with lock


Read with delayed lock

Following commands read a row with delayed lock. Note that all delayed lock commands have a ending '#'.

  • RFIRST# : read first row with delayed lock
  • RLAST# : read last row with delayed lock
  • RNEXT# : read next row with delayed lock
  • RPREV# : read previous row with delayed lock
  • RCURR# : read current row with delayed lock
  • RGREAT# : read greater than with delayed lock
  • RGTEQ# : read greater than or equal with delayed lock
  • RLESS# : read less than with delayed lock
  • REQLE# : read less than or equal with delayed lock
  • REQUAL# : read equal with delayed lock


Read with _51
  • RLAST% : DB_LAST_51
  • RNEXT% : DB_NEXT_51
  • RPREV% : DB_PREV_51
  • RGREAT% : DB_GT_51
  • RGTEQ% : DB_GE_51
  • RLESS% : DB_LESS_51
  • REQLE% : DB_EQLE_51
  • REQUAL% : DB_EQ_51


  • RINS : insert a row
  • RINS% : n/a


  • RUPD : update the row. The row must be locked before, using one of the eads with lock.
  • RUPD# : update the row. The row must be delay-locked before, using one of the reads with delay-lock.
  • RUPD% : n/a


  • RDEL : delete the row. The row must be locked before, using one of the reads with lock.
  • RDEL# : delete the row. The row must be delay-locked before, using one of the reads with delay-lock.
  • RDEL% : n/a


Delayed Lock Check
  • RROWCH : check if row changed.

Now, we will talk about updates. Say, we make an insert with the insert command. Now, before we do a commit if we want to update it. The thing about updates and delete are you need to do a locking of the record before you do that. The three kinds of updates are:

  • * physical lock
  • # delayed lock
  • % n/a

It is useful to use delayed lock, because it locks up record only when you perform an update. Physical lock once applied just locks the record. Delayed lock escalates to physical lock only when doing an update. If two sessions have delayed lock only for the purpose of reading, both will be able to access the sessions. If they have physical locks, then the second session won't even be able to read the record. So, in the same file where we inserted a record, the next line would b

#1 aabdb000 REQUAL* 0 -i
= aabdb000.byte = 11
#1 aabdb000 RUPD 0 -i
= aabdb000.byte = 22


Set transaction read only

This is not really a row level action but a transaction level action.


  • RRX : set transaction read-only.


Terminate test

This is not a database action but is used to stop a test in middle of a test file.


  • QUIT : the test will be terminated at this action.



This is a mandatory parameter, and must be specified, even if unused in most of the cases. This should be a integer. This has different meanings for different database actions, which is explained below.


  • TCRTBL :
    • 0 : create table with indexes
    • 1 : create table indexes
  • TDRTBL :
    • 0 : normal drop table
    • 1 : drop with backup
  • TCRI :
    • 9999 : create all indexes on the table
    • 1-64 : create specified index.
  • TDRI :
    • 2-64 Drop specified index
  • TCLTBL :
    • 0 : clear table with rollback
    • 1 : clear table without rollback
  • TCHORD :
    • 1-64 : change current index to the specified index.
  • TLOCK :
    • 0 : sser lock
    • 1 : lock for drop table
    • 2 : lock for clear table
    • 0 : normal action
    • 1 : buffered action



Various options can be specified.

String values can be specified as a character string e.g ONE or as hex values e.g <0x41><0x42><0x43> The hex format is useful for specifying multi-byte strings.

#1 aabdb000 RINS 0 -p -i
= aabdb000.byte = 11
= = 11
= aabdb000.double = 1.11
= aabdb000.float = 1.11
= = 11
= aabdb000.long = 11
= aabdb000.string = string 10
#1 aabdb000 DCOM 0


Array column values can also be specified using subscript e.g:


#1 aabdb000 RINS 0 -i
= aabdb000.byte[0] = 1
= aabdb000.byte[1] = 2


Specify input values

Option -i is used to specify input row value for insert, key values for selects and new values for update. The input values are specified on separate line(s), format of which is:


= <column name> = <value>


The column name should be qualified by the table name. E.g

#1 aabdb000 REQUAL 0 -i
= aabdb000.byte = 11
= aabdb000.float = 1.1
= aabdb000.string = itm001


Check output row

Option -c is used to check the result of a select. The actual row data can be compared with expected values. Any column(s) can be specified for this option. The expected values are specified on separate line(s), format of which is:


c <column name> = <value>



#1 aabdb000 RFIRST 0
c aabdb000.byte = 99
c aabdb000.float = 9.9
c aabdb000.string = Ninetynine


For any column, if actual value does not matches with expected values, an error will be flagged.


Print output

Option -p is used to print the entire row for selects. For TNRROW option, it will print number of rows found in table. If row contains long string columns, not entire column may be printed.


#1 aabdb000 TNRR 0 -p


Specify expected error

Option -E can be used to check error conditions. E.g if a action is supposed to generate an error, this option can be used to specify expected bdb_errno. It can be specified either as a number e.g -E100, -E506 or as text. Option -E0 means no error. Upto 8 expected errors can be specified for one action. E.g:


#1 aabdb000 TDRTBL 0 -E0 -E506


In above case, if error is either 0 ( i.e no error ) or 506, the action is successful. Otherwise the test has failed.

Note that if a action, which is supposed to generate a error, does not generates one, then this test is assumed to be failed. E.g in case of:


#1 aabdb000 TDRTBL 0 -E506

if the drop table does not fails with error 506, this test has failed.

For convenience, some errors can also be specified as text. E.g duplicate error can be specified either as -E100 or as -EDUPL.


#1 aabdb000 RINS 0 -p -i -EDUPL
= aabdb000.byte = 11
= = 11
= aabdb000.double = 1.11
= aabdb000.float = 1.11
= = 11
= aabdb000.long = 11
= aabdb000.string = string 10

The text for these errors are listed below.


DUPL Duplicate record
BADARG Bad argument
BADKEY Bad key
NOTEXCL Not exclusive owner
LOCKED Record is locked
KEXISTS Index already exists
ENDFILE End of file
NOREC No record found
NOCURR No current record
FLOCKED Table is locked
ROW_CHANGED Row has changed
TRANSACTION_IS_ON This action is not allowed in transaction
READONLY Not allowed in readonly transaction
NOT_IN_RANGE Column value is out of range
NOT_LOCKED Row is not locked
AUDIT Error from audit server
ABORT Transaction is aborted
MIRROR Problem in mirror
MLOCKED Mirror is locked
NO_TABLE Table does not exists
TABLE_EXIST Table already exists
DB_NOT_ON Database not up
WRONG_VERSION Mismatched versions of client and database drivers
DD_CORRUPT Table & DD do not match
NO_DD DD not found
SECURITY Database security violation
LICENCE_ERROR Triton licence problem
REF_LOCKED Reference is locked
UNDEF_REF Undefined reference
REF_EXISTS Reference to this record exists
NO_REFTBL Reference table not found


Save current record

Option -s is used to save the current record in internal buffer.


Load saved record

Option -l can be used to load record value saved with -s option. These two options can be used e.g to delete a exisiting record and re-insert it later on.

#1 aabdb000 RFIRST 0
#2 aabdb000 RFIRST 0
#2 aabdb000 RNEXT* 0 -p -s
#2 aabdb000 RDEL 0
#2 aabdb000 DCOM 0
#1 aabdb000 RNEXT 0 -c
c aabdb000.byte = 13
#2 aabdb000 RINS 0 -p -l
#2 aabdb000 DCOM 0


Pause test

Option -t is used to pause the test. When gcommand encounters this option, it waits for the user to hit return key, before proceeding further. This is mainly used for attaching a debugger to gcommand after a certain command has been executed.


Specify company number for main cursor

Option -C is used to specify a different company number for main cursor.


Specify company number for internal cursor

Option -I is used to specify a different company number for a internal cursor, same as filling the field _compnr.

#1 aabdb000 RFIRST 0 -p -C100
#1 aabdb000 RLAST 0 -p -I200

What you will find from the dbs.log, is that it will open a new cursor for executing company 100 query whereas for company 200, it will use the existing cursor.


Specify a cursor

Option -N is used to specify a cursor to be used for the action. This option can be used to create multiple cursors in the client.

#1 aabdb000 RFIRST 0 -p -N1
#1 aabdb000 RLAST 0 -p -N2
#1 aabdb000 RNEXT 0 -p -N1
#1 aabdb000 RPREV 0 -p -N2


Schedule a session

Option -S is used to specify the number of scheduling ticks on the session.

#1 aabdb000 REQUAL 0 -i
= aabdb000.byte = 11
#2 aabdb000 REQUAL 0 -i -x -S1
= aabdb000.byte = 11
#1 aabdb000 REQUAL 0 -i
= aabdb000.byte = 11

You will find that -x closes the cursor after the command. Run it with BDB_DEBUG option and check your commlog file. It should describe that your cursor is closed.


Close Cursor

Option -x will close the cursor used for the action, after the action is done


Close session

Option -X will close the session after performing the action.


Setting a stripped Environment

  • Setting up a stripped environment for the purpose of gcommand is really a good idea. It is really easy to set up and doesn't involve time.
  • Make sure you link your binaries to an existing environment. Other than that you basically would have same directory structure as your other environment. The only places where you need stuff is for the lib files and the data dictionary should have the package combination.


Things to try

  • Try to update records. Don't commit them. Try this with bisam and oracle. You should see a difference when you try to make use of second session to read the record. This is because oracle doesn't allow dirty reads.
  • A lot of things can be tried with trying to do cascade delete, restricted lookup etc. Try to do cascade delete and see what happens. This should allow you to delete record from child whereas the same is not possible with restricted lookup as it will complain about references. Try doing this for level 1 and level 2 drivers. To make the dbslog of average size, use DBSLOG=0560 when using level 2 and DBSLOG =0470 on level 1. See the way SQL gets generated. Make use of the explode6.1 function to look into data dictionary and use it in conjunction with vi to make changes. A list of what cascade, lookup means is also attached at the end.
  • One thing you should observe is whether there is a full table scan or index scan . When there are indices defined, you will find that there is a index scan. While trying to do just an delete of a record, level 1 did a full table scan on the child table whereas level 2 generated an query with just the condition.
  • Try doing gcommand with BDB_DEBUG=02 option. See how the client communicates with the driver.
  • Let session 1 have physical lock and session 2 have delayed lock. Try to see if you can read data. The next thing to do would be to update session 2 and see if it complains. If it does, is there a way you can set up, so that it will ignore the error message.

Average: 5 (1 vote)

All times are GMT +2. The time now is 22:56.

©2001-2017 - -