NAME MPE::IMAGE - Access MPEs TurboIMAGE/XL databases from within Perl SYNOPSIS use MPE::IMAGE ':all'; my $db = DbOpen('Dbase.Group.Account','Password',5); die "DbOpen Error: $DbError" unless $DbStatus[0] == 0; my %record = DbGet($db,2,'dataset','items'); DbExplain unless $DbStatus[0] == 0; $db->DbClose(1); DbExplain unless $DbStatus[0] == 0; DESCRIPTION MPE::IMAGE is designed to make access to TurboIMAGE/XL databases fairly comfortable to the Perl programmer. Please note that the calls differ in certain ways from the native intrinsic calls. In specific: * Anywhere a "number of elements" was given, it is no longer necessary. Perl knows how many elements are in an array and passes that information to the appropriate intrinsic. An example of this is in passing an item-number list to `DbGet'. * The status array is a globally defined perl array and so does not get passed to any of the routines. * The data returned from `DbGet' and passed to `DbPut' and `DbUpdate' can be either a single scalar value containing the entire buffer exactly as it is gotten or put, or a hash mapping item names to their values. * MPE::IMAGE will handle all the translation to and from the various IMAGE datatypes transparently. * `DbGet', `DbPut' and `DbUpdate' can each take a schema hash, allowing fields to be redefined. * Dataset and item names can be given in any case. They will be passed to the intrinsics uppercase. The following are provided by MPE::IMAGE. Note that for each call which expects a database argument, that argument should be a database object as returned by `DbOpen'. `@DbStatus' The array `@DbStatus' contains the status values from the most recent intrinsic call. `$DbError' `DBERROR' is implemented as a readonly variable called `$DbError'. When used in a string context, `$DbError' gives the text returned by a call to `DBERROR'. When used in a numeric context, it contains the same value as `$DbStatus[0]'. However, it is somewhat more expensive to use than `$DbStatus[0]' as using it includes the overhead of using a tied variable and, possibly, a call to `DBERROR'. In any of the following usages, the overhead should be negligible die "DbOpen Error: $DbError" unless $DbStatus[0] == 0; die "DbOpen Error: $DbError" if $DbError; dbfail($DbError) if $DbError != 0 and $DbError != 15; I would be much less likely to use it in this fashion: while ($DbError == 0) { %data = DbGet($db,5,'dataset'); . . . } because it makes a "method" call on every iteration and in the final pass, when the status comes up 15, it performs a `DBERROR' call to get an explanation for an expected condition, both problems which are avoided by using $DbStatus[0] instead: while ($DbStatus[0] == 0) { %data = DbGet($db,5,'dataset'); . . . } `DbBegin' DbBegin(Database,1); DbBegin(Database,1,text); $transid = DbBegin(Array of bases,3 or 4); $transid = DbBegin(Array of bases,3 or 4,text); Note that the $transid is more than just a number. It is the array, in binary form, containing not only the transaction id but all the base ids as well. Its only intended purpose is for passing to DbEnd. `DbClose' DbClose(Database); DbClose(Database,mode); DbClose(Database,mode,dataset); If mode is omitted, it defaults to 1. `DbControl' DbControl(Database,mode); $status = DbControl(Database,13,0); $status = DbControl(Database,13,function,set); $status = DbControl(Database,13,function,set,flags); $status = DbControl(Database,14,function); $status = DbControl(Database,14,7,wildcard); DbControl(Database,15); DbControl(Database,15,wildcard); DbControl(Database,16); `DbDelete' DbDelete(Database,Dataset); `DbEnd' DbEnd(Database,1 or 2); DbEnd(Database,1 or 2,text); DbEnd(Array of bases,3 or 4); DbEnd(Array of bases,3 or 4,text); DbEnd($transid,3 or 4); DbEnd($transid,3 or 4,text); `DbExplain' DbExplain; `DbFind' DbFind(Database,dataset,argument); # Assumed find mode 1 on key item DbFind(Database,dataset,item,argument); # Assumed mode 1 DbFind(Database,dataset,mode,item,argument); DbFind(Database,dataset,argument,type); # Assumed find mode 1 on key item DbFind(Database,dataset,item,argument,type); # Assumed mode 1 DbFind(Database,dataset,mode,item,argument,type); `type' is a string containing an IMAGE type (such as "2X10") and is necessary only when searching on a TPI index (for which MPE::IMAGE cannot look up the type). `DbGet' DbGet(Database,mode,dataset); DbGet(Database,mode,dataset,list); DbGet(Database,mode,dataset,undef,undef,schema); DbGet(Database,mode,dataset,list,undef,schema); If mode is 4, 7 or 8: DbGet(Database,mode,dataset,argument); DbGet(Database,mode,dataset,list,argument); DbGet(Database,mode,dataset,undef,argument,schema); DbGet(Database,mode,dataset,list,argument,schema); `list' can be either an array of or a comma-separated list of item names or numbers (or a mixture of both). It can also be "0", "*" or "@" and can be semicolon/space-terminated or not as preferred. If `list' is omitted, it is assumed to be "*;" if the dataset has previously be used and "@;" if not. `schema' is the description of the fields and must describe a space of exactly the same size as the fields in `list'. There will be a helper function to allow a schema to be checked prior to use and this is highly recommended. If the schema is omitted, a schema derived from the IMAGE item descriptions is used instead. See the section on schemata for more information. When used in scalar context, DbGet returns the retrieved values as a single block. Otherwise it returns a hash where the keys are the item names (or the fields described in the schema) and the values are the values of those items/fields. `DbInfo' Since the return values from DbInfo must be parsed, and since the necessary buffer size varies widely depending on the mode, only the modes listed in the August 1997 (sixth) edition of the Image manual are supported (third-party indexing modes are not currently supported). $item_num = DbInfo(Database,101,item name or number); %item_info = DbInfo(Database,102,item name or number); `%item_info' will have elements with the following keys: "name", "type", "length", "count". @item_nums = DbInfo(Database,103); `@item_nums' will contain the item numbers (positive and negative). As with other modes which return arrays, the first element is *not* the number of items. Rather, the number of items is reflected in the size of the array. @item_nums = DbInfo(Database,104,set name or number); @btree_info = DbInfo(Database,113); `@btree_info' will be a six-element array, the 2nd and 6th elements of which contain the respective wild-card characters (see Image documentation). $set_num = DbInfo(Database,201,set name or number); %set_info = DbInfo(Database,202,set name or number); `%set_info' will have elements with the following keys: "name", "type", "length", "block fact", "entries", "capacity". @set_nums = DbInfo(Database,203); @set_nums = DbInfo(Database,204,item name or number); %set_info = DbInfo(Database,205,set name or number); `%set_info' will have elements with the following keys: "name", "type", "length", "block fact", "entries", "capacity", "hwm", "max cap", "init cap", "increment", "inc percent", "dynamic cap". $num_chunks = DbInfo(Database,206,set name or number); @chunk_sizes = DbInfo(Database,207,set name or number); @set_info = DbInfo(Database,208,set name or number); `@set_info' will be a seven-element array. @btree_info = DbInfo(Database,209,set name or number); `@btree_info' will be a two-element array. @path_array = DbInfo(Database,301,set name or number); `@path_array' will be an n-element array, where n is the number of paths for the specified dataset. Each element will be a reference to a hash containing elements with the following keys: "set", "search", and "sort". To report which sets are connected by paths to MYDETAIL, you could do something like this: my @path_array = DbInfo($db,301,'MYDETAIL'); foreach (@path_array) { print $_->{'set'},"\n"; } # end of example @key_array = DbInfo(Database,302,set name or number); `@key_array' will be a two-element array. %log_info = DbInfo(Database,401); `%log_info' will have elements with the following keys: "logid", "base log flag", "user log flag", "trans flag", "user trans num". %ILR_info = DbInfo(Database,402); `%ILR_info' will have elements with the following keys: "ILR log flag", "ILR date", "ILR time". %log_info = DbInfo(Database,403); `%log_info' will have elements with the following keys: "logid", "base log flag", "user log flag", "trans flag", "user trans num", "log set size", "log set type", "base attached", "dynamic trans", "log set name". %log_info = DbInfo(Database,404); `%log_info' will have elements with the following keys: "base log flag", "user log flag", "rollback flag", "ILR log flag", "mustrecover", "base remote", "trans flag", "logid", "log index", "trans id", "trans bases", "base ids". "base ids" will be a reference to an array containing the ids of the bases being used in a multiple-base transaction. %db_info = DbInfo(Database,406); `%db_info' will have elements with the following keys: "name", "mode", "version" $subsys_access = DbInfo(Database,501); @ci_update = DbInfo(Database,502); `@ci_update' will be a two-element array. $language_id = DbInfo(Database,901); `DbLock' DbLock(Database,1 or 2); DbLock(Database,3 or 4,Dataset); DbLock(Database,5 or 6,Desc1,Desc2,...); The Descriptors are either hashes or arrays. If they are hashes, they must contain a 'set' key and may optionally contain a 'cond' key. The value for the 'set' key should be the dataset, either numeric or alphabetic. The condition should be given as item, relop and value value in a single string. For example, 'ID=12345' would be a valid condition. If the descriptor is an array, it should contain the dataset in slot 0 and the conditional, if any, in slot 1. `DbMemo' DbMemo(Database); DbMemo(Database,text); `DbOpen' $db = DbOpen(BaseName,Password,Mode); DbOpen returns a database object which can be passed to the other calls. `DbPut' DbPut(Database,Dataset,Data); DbPut(Database,Dataset,List,Data); Data may either be a hash or a scalar. If it is a hash, the keys of the hash will be used to construct the list. If it is a scalar and no list is specified, the current list will be used. `DbUnlock' DbUnlock(Database); `DbUpdate' DbUpdate(Database,Dataset,Data); DbUpdate(Database,Dataset,List,Data); Data may either be a hash or a scalar. If it is a hash, the keys of the hash will be used to construct the list. If it is a scalar and no list is specified, the current list will be used. `DbXBegin' DbXBegin(Database,1); DbXBegin(Database,1,text); $transid = DbXBegin(Array of bases,3); $transid = DbXBegin(Array of bases,3,text); Note that the $transid is more than just a number. It is the array, in binary form, containing not only the transaction id but all the base ids as well. Its only intended purpose is for passing to DbXEnd or DbXUndo. `DbXEnd' DbXEnd(Database,1 or 2); DbXEnd(Database,1 or 2,text); DbXEnd($transid,3); DbXEnd($transid,3,text); `DbXUndo' DbXUndo(Database,1); DbXUndo(Database,1,text); DbXUndo($transid,3); DbXUndo($transid,3,text); HELPER FUNCTIONS MPE::IMAGE also provides a set of helper functions * dset_info(Database,Dataset Num) * dset_name(Database,Dataset) * dset_num(Database,Dataset) * item_info(Database,Item Num) * item_name(Database,Item) * item_num(Database,Item) These functions return information about datasets or items either by making the necessary DbInfo calls or from cache, so they can be considerably faster that making a DbInfo call. `dset_info' returns all of the mode 205 information except number of entries, capacity and high-water mark--those things which cannot be safely cached. `item_info' returns the mode 102 information. The *_name and *_num calls can take either a dataset/item name or number. That way, one can use, for example, `item_num' passing it whatever item identification one currently has and receive back an item number. SCHEMAS Yet to be written. Note that schemas do NOT yet work for DbPut or DbUpdate, only DbGet (and in a small way for DbFind). NOTES * ONLY those calls/modes which are in the test suite are guaranteed to be tested. There are some things, such as Priv Mode DbControl calls and things relating to B-Trees and Jumbo sets which I couldn't very well test. * MPE::IMAGE can handle packed-decimal fields of any length, but as a P28, for example, can hold a larger number than a 64-bit integer, P fields are always translated into strings. If the number is within range, Perl will translate it into binary format when necessary. * IMAGE allows the definition of I, J and K types greater than 64 bits. MPE::IMAGE, however, gets very confused by such things. AUTHOR Ted Ashton, ashted@southern.edu SEE ALSO perl(1).