User’s Guide¶
Read and Update Example¶
The following program inserts a record into the Employees demo file, reads and backs it out:
adapya/adabas/scripts/n1_acbx.py
"""Store and Read record then backout and close session"""
from __future__ import print_function # PY3
from adapya.base.defs import log, LOGBEFORE, LOGCMD, LOGCB, LOGRB, LOGRSP, LOGFB
from adapya.adabas.api import Adabasx, DatabaseError, UPD
from adapya.base.dump import dump
FNR=11;DBID=8 # Employees file 11 in database 8
FB=b'AA,8,A.' # String for format buffer with field AA (personnel-id)
c1=Adabasx(fbl=64,rbl=64) # allocate set of buffers ACBX,
# abd+format and record buffer
log(LOGCMD|LOGCB|LOGRB|LOGFB) # switch on printing of Adabas commands
try:
# print Adabas buffers after Adabas call
c1.cb.dbid=DBID # for ACBX; c1.dbid=DBID for ACB
c1.cb.fnr=FNR # set control block fields
c1.open(mode=UPD) # issue OP
c1.cb.cid=b'abcd' # command id
c1.cb.isn=0 # no record number yet
c1.fb.value=FB # put data into format buffer
c1.rb.value=b'ABCDEFGH' # .. record buffer
c1.rabd.send=8 # set send size for record buffer
c1.store() # issue N1
c1.rb.value=b' '*8 # reset record buffer
c1.get() # issue L1
print( repr(c1.rb.value), 'returned size', c1.rabd.recv)
except DatabaseError as e:
print('DatabaseError exception:\n%s\n' % e.value)
dump(e.apa.acbx, header='Control Block Extended')
raise
finally:
log(LOGCMD|LOGRSP)
c1.bt() # issue backout
c1.close()
Some explanations in the following sections. You may also look into source adapya/adabas/api.py
Adabasx Objects¶
Adabas database requests use a control block and a number of data buffers. In Python such a request can be set up with an Adabasx object
c1=Adabasx(fbl=64,rbl=64)
c1 is an instance of the Adabasx class with an Adabas control block (ACBX) and a format buffer of and record buffer of 64 bytes length each.
The Adabasx and Acbx classes are defined in adapya/adabas/api.py.
When creating the Adabasx object Python calls the __init__() method defined in the Adabas class. Behind the scenes, this method does the following
create a buffer with Abuf() of length ACBXLEN and assign it to the attribute acbx of the Adabasx. Create format and record buffers:
import from adapya.base.defs Abuf self.acbx=Abuf(ACBXLEN) self.fb=Abuf(fbl) self.rb=Abuf(rbl)
define a mapping of Acbx fields to the buffer:
self.cb=Acbx(buffer=self.acbx)
Abuf()¶
adapya.base.defs defines the buffer class Abuf(size) which is backed by the ctypes character buffer.
Abuf() defines slice and file I/O operations and is used as read/write buffer in the foreign function call to the Adabas database.
Datamap()¶
Internally, Python has no concept to store data of different variables physically together as in a C struct or assembler DSECT. Yet with pack() and unpack() functions from the Python struct module variables can be mapped to a buffer (or string).
With the datamap.py module from the adapya.base package such a mapping can be defined similar to C structs.
Opening a session with the database¶
The following statement sets the database id in the Adabas control block in c1 to select the database:
c1.cb.dbid=8
c1.open(mode=UPD) # issue OP
Then the open() method of the Adabasx class issues an Adabas OP command.
Storing a Record¶
Preparation to store a new record:
c1.cb.cid=b'abcd'
c1.fb.value=FB # put data into format buffer
c1.rb.value=b'ABCDEFGH' # .. record buffer
c1.rabd.send=8 # set send size for record buffer
c1.store() # issue N1
In detail: set Command id is set with a 4 byte string:
c1.cb.cid=b'abcd'
Assign data to the record buffer:
c1.rb.value=b'ABCDEFGH'
c1.rb is the record buffer. Make sure that you assign a value with c1.rb.value or with the slice operator:
c1.rb[0:8]=b'ABCDEFGE'
With ACBX the size of the buffers to send must be set. c1.rabd is the record buffer ABD:
c1.rabd.send=8 # set send size for record buffer
The store() function is used to insert a new record. It issues the N1 command and is equivalent to:
c1.call(cmd='N1', isn=0, op1=' ', op2=' ')
Reading a Record¶
c1.rb.value=b' '*8 # reset record buffer
c1.get() # issue L1
print( repr(c1.rb.value), 'returned size', c1.rabd.recv)
Backing-out the Transaction¶
At the end of the program we back out the transaction which removes the new record from the database.
c1.bt() # issue backout
Closing the User session¶
c1.close() # issue close
Response Code Checking vs. Exception Handling¶
try:
....
except DatabaseError as e:
print('DatabaseError exception:\n%s\n' % e.value)
dump(apa.acbx, header='Control Block')
raise
The block within try:
and except:
contains some Adabas calls.
Any Adabas response code will interupt the program sequence
and raise a DatabaseError exception. This is caught in with the except:
statement and handled by printing diagnostic information.