Tag Archives: ctags

Python and D-ISAM

D-ISAM is fully supported in Python by way of the ctypes library.

This is documented at The Python Software Foundation as A foreign function library for Python.

D-ISAM is easily imported as a shared library (or apple dylib, or windows dll) as follows:

from ctypes import CDLL
d7 = CDLL( "libdisam72.so" )

In addition to importing the library, you will also (most probably) wish to add the standard ISAM constants, and at least an instance of the ISAM key description structure, and deploy the results as a module.

An example module is available here.

A simple demonstration is available here.

D-ISAM Python module

This Python module imports D-ISAM as a shared library, and exports three classes.

d7 class exports the D-ISAM library itself, and adds “constant” values for the standard ISAM defines – for example d7.isOpen( "myfile", d7.ISINOUT + d7.ISAUTOLOCK )

d7error is a python Exception class, for example raise d7error( isam, "message text" )

d7key is a ctypes Structure class, and provides an instance of an ISAM key descriptor.

An example of usage can be found here

An overview is available here

Download the module here

#!/bin/python

from ctypes import CDLL, Structure, c_void_p, c_char_p, c_int, c_short, c_uint

d7 = CDLL( "libdisam72.so" )

# disam 'constant' values

d7.ISMAXPARTS = 20
d7.ISINPUT = 0x00
d7.ISOUTPUT = 0x01
d7.ISINOUT = 0x02
d7.ISTRANS = 0x04
d7.ISNOLOG = 0x08
d7.ISFIXLEN = 0x00
d7.ISVARLEN = 0x10
d7.ISVARCMP = 0x30
d7.ISSYNCWR = 0x40
d7.ISMASKED = 0x80
d7.ISNOCARE = 0x8000
d7.ISRDONLY = 0x100
d7.ISAUTOLOCK = 0x200
d7.ISMANULOCK = 0x400
d7.ISEXCLLOCK = 0x800
d7.ISSEMILOCK = 0x1000
d7.ISFIRST = 0
d7.ISLAST = 1
d7.ISNEXT = 2
d7.ISPREV = 3
d7.ISCURR = 4
d7.ISEQUAL = 5
d7.ISGREAT = 6
d7.ISGTEQ = 7
d7.CHARTYPE = 0
d7.DECIMALTYPE = 0
d7.INTTYPE = 1
d7.LONGTYPE = 2
d7.DOUBLETYPE = 3
d7.FLOATTYPE = 4
d7.MINTTYPE = 5
d7.MLONGTYPE = 6
d7.STRINGTYPE = 7
d7.ISDESC = 0x80
d7.CHARSIZE = 1
d7.INTSIZE = 2
d7.LONGSIZE = 4
d7.DOUBLESIZE = 8
d7.FLOATSIZE = 4
d7.MINTSIZE = 2
d7.MLONGSIZE = 4
d7.STRINGSIZE = 1
d7.ISNODUPS = 0x00
d7.ISDUPS = 0x01
d7.DCOMPRESS = 0x02
d7.LCOMPRESS = 0x04
d7.TCOMPRESS = 0x08
d7.COMPRESS = 0x0E
d7.TNULL = 0x10
d7.NULLKEY = 0x20
d7.ISLOCK = 0x100
d7.ISSKIPLOCK = 0x200
d7.ISWAIT = 0x400
d7.ISLCKW = 0x500
d7.ISKEEPLOCK = 0x800
d7.AUDSETNAME = 0
d7.AUDGETNAME = 1
d7.AUDSTART = 2
d7.AUDSTOP = 3
d7.AUDINFO = 4
d7.USERINFOSIZE = 10

# disam functions return and argument definitions

d7.isIndexInfo.restype = c_int
d7.isIndexInfo.argtypes = [ c_void_p, c_void_p, c_int ]

d7.isIsamInfo.restype = c_int
d7.isIsamInfo.argtypes = [ c_void_p, c_void_p ]

d7.isErase.restype = c_int
d7.isErase.argtypes = [ c_char_p ]

d7.isRename.restype = c_int
d7.isRename.argtypes = [ c_char_p, c_char_p ]

d7.isCluster.restype = c_void_p
d7.isCluster.argtypes = [ c_void_p, c_void_p ]

d7.isClone.restype = c_void_p
d7.isClone.argtypes = [ c_void_p, c_char_p ]

d7.isCopy.restype = c_int
d7.isCopy.argtypes = [ c_void_p, c_void_p, c_void_p ]

d7.isBuild.restype = c_void_p
d7.isBuild.argtypes = [ c_char_p, c_int, c_int, c_void_p, c_int ]

d7.isPrecious.restype = c_int
d7.isPrecious.argtypes = [ c_void_p, c_int ]

d7.isAddIndex.restype = c_int
d7.isAddIndex.argtypes = [ c_void_p, c_void_p ]

d7.isDelIndex.restype = c_int
d7.isDelIndex.argtypes = [ c_void_p, c_void_p ]

d7.isUserInfo.restype = c_int
d7.isUserInfo.argtypes = [ c_void_p, c_int, c_char_p ]

d7.isOpen.restype = c_void_p
d7.isOpen.argtypes = [ c_char_p, c_int ]

d7.isClose.restype = c_int
d7.isClose.argtypes = [ c_void_p ]

d7.isLockCheck.restype = c_int
d7.isLockCheck.argtypes = [ c_void_p, c_int ]

d7.isSetMode.restype = c_int
d7.isSetMode.argtypes = [ c_void_p, c_int ]

d7.isWrite.restype = c_int
d7.isWrite.argtypes = [ c_void_p, c_void_p ]

d7.isWrLock.restype = c_int
d7.isWrLock.argtypes = [ c_void_p, c_void_p ]

d7.isWrCurr.restype = c_int
d7.isWrCurr.argtypes = [ c_void_p, c_void_p ]

d7.isRewrite.restype = c_int
d7.isRewrite.argtypes = [ c_void_p, c_void_p ]

d7.isRewCurr.restype = c_int
d7.isRewCurr.argtypes = [ c_void_p, c_void_p ]

d7.isRewRec.restype = c_int
d7.isRewRec.argtypes = [ c_void_p, c_uint, c_void_p ]

d7.isRewNxt.restype = c_int
d7.isRewNxt.argtypes = [ c_void_p, c_void_p ]

d7.isRead.restype = c_int
d7.isRead.argtypes = [ c_void_p, c_void_p, c_int ]

d7.isStart.restype = c_int
d7.isStart.argtypes = [ c_void_p, c_void_p, c_int, c_void_p, c_int ]

d7.isIndex.restype = c_int
d7.isIndex.argtypes = [ c_void_p, c_int ]

d7.isGoto.restype = c_int
d7.isGoto.argtypes = [ c_void_p, c_uint ]

d7.isPush.restype = c_int
d7.isPush.argtypes = [ c_void_p, c_void_p, c_void_p ]

d7.isPop.restype = c_int
d7.isPop.argtypes = [ c_void_p, c_int, c_uint ]

d7.isData.restype = c_int
d7.isData.argtypes = [ c_void_p, c_void_p, c_uint ]

d7.isLock.restype = c_int
d7.isLock.argtypes = [ c_void_p ]

d7.isUnLock.restype = c_int
d7.isUnLock.argtypes = [ c_void_p ]

d7.isRelease.restype = c_int
d7.isRelease.argtypes = [ c_void_p ]

d7.isRelRec.restype = c_int
d7.isRelRec.argtypes = [ c_void_p, c_uint ]

d7.isRelCurr.restype = c_int
d7.isRelCurr.argtypes = [ c_void_p ]

d7.isDelete.restype = c_int
d7.isDelete.argtypes = [ c_void_p, c_void_p ]

d7.isDelCurr.restype = c_int
d7.isDelCurr.argtypes = [ c_void_p ]

d7.isDelRec.restype = c_int
d7.isDelRec.argtypes = [ c_void_p, c_uint ]

d7.isErrno.restype = c_int
d7.isErrno.argtypes = [ c_void_p ]

d7.isErrio.restype = c_int
d7.isErrio.argtypes = [ c_void_p ]

d7.isCount.restype = c_int
d7.isCount.argtypes = [ c_void_p ]

d7.isRecnum.restype = c_int
d7.isRecnum.argtypes = [ c_void_p ]

d7.isReclen.restype = c_int
d7.isReclen.argtypes = [ c_void_p ]

d7.isSetrec.restype = c_int
d7.isSetrec.argtypes = [ c_void_p, c_uint ]

d7.isSetlen.restype = c_int
d7.isSetlen.argtypes = [ c_void_p, c_short ]

d7.isLdSchema.restype = c_int
d7.isLdSchema.argtypes = [ c_void_p, c_char_p ]

d7.isDpSchema.restype = c_int
d7.isDpSchema.argtypes = [ c_void_p ]

d7.isStSchema.restype = c_int
d7.isStSchema.argtypes = [ c_void_p, c_char_p ]

d7.isRmSchema.restype = c_int
d7.isRmSchema.argtypes = [ c_void_p ]

d7.isSetUnique.restype = c_int
d7.isSetUnique.argtypes = [ c_void_p, c_uint ]

d7.isUniqueId.restype = c_int
d7.isUniqueId.argtypes = [ c_void_p, c_void_p ]

d7.isGetLastRec.restype = c_int
d7.isGetLastRec.argtypes = [ c_void_p, c_void_p ]

d7.isSetLastRec.restype = c_int
d7.isSetLastRec.argtypes = [ c_void_p, c_uint ]

d7.isLastRec.restype = c_int
d7.isLastRec.argtypes = [ c_void_p, c_void_p ]

d7.isAmSane.restype = c_int
d7.isAmSane.argtypes = [ ]

d7.isCheckData.restype = c_int
d7.isCheckData.argtypes = [ c_void_p ]

d7.isCheckIndex.restype = c_int
d7.isCheckIndex.argtypes = [ c_void_p, c_int ]

d7.isRebuildFree.restype = c_int
d7.isRebuildFree.argtypes = [ c_void_p, c_int ]

d7.isRebuildIdx.restype = c_int
d7.isRebuildIdx.argtypes = [ c_void_p, c_int ]

d7.isCheckVarlen.restype = c_int
d7.isCheckVarlen.argtypes = [ c_void_p, c_void_p ]

class d7error(Exception):

  def __init__ ( self, isam, string ):
    self.value = d7.isErrno( isam ) 
    self.string = string;

  def __str__ ( self ):
    return repr( "[%s] %s" % ( self.value, self.string ) )


class _d7_key_part(Structure):
  _fields_ = [ ("kp_start", c_short),
               ("kp_leng", c_short),
               ("kp_type", c_short) ]

class d7key(Structure):
  _fields_ = [ ("k_flags", c_short),
               ("k_nparts", c_short),
               ("k_part", _d7_key_part * d7.ISMAXPARTS) ]

D-ISAM example in Python

The following example code demonstrates the basic principles of using D-ISAM in Python, by means of the standard ctypes library.

The required disam72 class module is here

An overview is available here

Download the example here

#!/usr/bin/python

from ctypes import *
from disam72 import d7, d7key, d7error

name = "example_isam_file"

class RECORD(Structure):
  _fields_ = [ ( "code", c_int ),
               ( "name", c_char * 31 ) ]

key1 = d7key( d7.ISNODUPS, 1, ( ( 0, 4, d7.LONGTYPE ), ) )

key2 = d7key( d7.COMPRESS + d7.TNULL, 1, ( ( 4, 31, d7.STRINGTYPE ), ) )

d7.iserase( name )

isam = d7.isBuild( name, 35, 0, byref(key1), d7.ISINOUT + d7.ISMANULOCK )
if isam is None:
  raise d7error( None, "build %s failed" % name )

if d7.isAddIndex( isam, byref(key2) ) == 0:
  raise d7error( isam, "add second index failed" );

pad = RECORD( 0, "" )

pad.code = 1
pad.name = "banana, junior"
if d7.isWrite( isam, byref(pad) ) == 0:
  raise d7error( isam, "add %d %s failed" % ( pad.code, pad.name ) )

pad.code = 2
pad.name = "apple, macintosh"
if d7.isWrite( isam, byref(pad) ) == 0:
  raise d7error( isam, "add %d %s failed" % ( pad.code, pad.name ) )

pad.code = 999
pad.name = "error, read failed"

if d7.isRead( isam, byref(pad), d7.ISFIRST ) == 0:
  raise d7error( isam, "read first on primary index failed" )
else:
  print "%d: %s" % ( pad.code, pad.name )

if d7.isStart( isam, byref(key2), 1, isam, d7.ISFIRST ) == 0:
  raise d7error( isam, "switch to secondary index failed" );

if d7.isRead( isam, byref(pad), d7.ISFIRST ) == 0:
  raise d7error( isam, "read first on secondary index failed" )
else:
  print "%d: %s" % ( pad.code, pad.name )

result:

1: banana, junior
2: apple, macintosh