| RXDBClient is pretty much similar to RXDbase (although it connects to the RXDBServer database server instead of opening a file locally) but has slightly different constructors, its connect methods are different, and it lacks the create DB / delete DB methods. What if you need to access RXDBServer from machines that don't have a Java Virtual Machine? The source file for RXDBClient is provided in this package (in the maxbase\demo directory), so you can study and port it (you'll see, it's very easy). The default return strings for the following methods are: DBNOTSTARTED: (can't work on nothing) READY: (no errors) SYNTAX ERROR: (go figure) ERROR:FILE ACCESS PROBLEMS (something weird at file level) Unless stated otherwise. More error codes will be introduced as the RXDbase will be enhanced. Use of the RXDBClient class import nrio.RXDBClient Is required in your NetRexx source file. Index of available constructors and methods: RXDbclient() A simple constructor. RXDbclient(Rexx ipaddr, int port, Rexx dbpass) A constructor used to connect to a remote database (with password). RXDbclient(Rexx ipaddr, int port) A constructor used to connect to a remote database (without password). Rexx addfield(Rexx rFieldName, Rexx rFieldLength, Rexx rFieldIndexingMethod) Adds a field to the currently opened database. Rexx connect(Rexx ipaddr, int port, Rexx dbpass) Connects to a remote database (with password). Rexx connect(Rexx ipaddr, int port) Connects to a remote database (without password). Rexx definefilter(Rexx rFilter) Defines a filter to be used in future loadrec calls. Rexx delerec(Rexx[] rToDele, boolean bDelete) Deletes/Undeletes one or more records. Rexx delfield(Rexx rFieldName) Deletes a field of the currently opened database. Rexx disconnect() Disconnects from the currently opened database. Rexx[, ] getdbinfo() Gets information about record structure for the currently opened database. Rexx[] getdbstats() Gets some useful statistics about the database. Rexx[] getdbstatus() Returns the current in use filter and release version for RXDbase. Rexx globalrebuildidx() Rebuilds all of the indexes. Rexx[, ] loadrec(Rexx rIdx, Rexx rHowManyRec, Rexx rStart, boolean bForward) Loads a set of records. Rexx[, ] loadrecwithfilter(Rexx rIdx, Rexx rHowManyRec, Rexx rStart, boolean bForward, Rexx rFilter) Loads a set of records according to a temporary filter. Rexx modfieldidx(Rexx rFieldName, Rexx rFieldIndexingMethod) Modifies (on the fly) indexing strategy for a field. Rexx modfieldlength(Rexx rFieldName, Rexx rNewLength) Modifies (on the fly) the length of a field. Rexx modfieldname(Rexx rOldName, Rexx rNewName) Modifies (on the fly) the name of a field. Rexx modirec(Rexx[, ] rToModi) Modifies one or more records. Rexx pack() Packs the database (physically purge deleted records). Rexx rebuildidx(Rexx rFieldName) Rebuilds the index for a single field. Rexx saverec(Rexx[, ] rToSave, Rexx rMode) Stores one or more records in the database. Rexx status() Returns the current error status of the database. The following constructors are available for RXDBClient: RXDBClient(Rexx ipaddr, int port, Rexx dbpass) Where ipaddr is an IP address, port is a, well, TCP/IP port and dbpass is a password (may be required by the server if running in safe mode). RXDBClient(Rexx ipaddr, int port) This one lacks the password. RXDBClient() A simple constructor. The following methods can be issued on RXDBClient: Rexx addfield(Rexx rFieldName, Rexx rFieldLength, Rexx rFieldIndexingMethod) With this method you can add a field to a database; you can also specify an index, which will be built automatically for you. Notes: Don't use names already in use in the same database, and specify a valid indexing method (currently supported: "ISAMxx" and "NONEx"); The new fields' contents will be blank for all records (of course). See the "connect" method for a listing of valid XX, X values. Rexx connect(Rexx ipaddr, int port) Rexx connect(Rexx ipaddr, int port, Rexx dbpass) These two methods closely mimic the corresponding RXDBClient constructor. Please note that here the returned value is an error message ("READY:" means no errors). Rexx definefilter(Rexx rFilter) By means of this method you can specify a filter with which all subsequent loadrec calls will have to comply. Parameters: rFilter = an expression, which can have nested expressions in parenthesis. Separate filter conditions with | (OR condition) and & (AND condition). Example: name = rob* | surname = kol* will search for every person whose name starts with 'rob' or whose surname starts with 'kol'. Note: Valid filter conditions are: <fieldname> <operator> <value> Where <fieldname> is a valid field name, e.g. 'Name'. <operator> can be one of the following: =,<>,>,>=,<,<= <value> is a valid value for that field, e.g. 'Robert' Wildcards are allowed only for the = and <> operators, and they are represented by the symbol '*', which means "every number of any character". So, Ro* can be Robert, Ronald, etc. *t can be Matt, Robert, etc. M*t can be Matt, mount, etc. (The search is always case-insensitive) You can use only one '*' on a given filter (e.g. you can't query for "Name = *u*i*l*"), with the notable exception of the form *value*, which means "find a substring anywhere that is equal to 'value'". Example: "Telephone = *555*" will search for all phone numbers with a 555 in them. Your filter conditions will not produce anything until the next LOADREC method is issued, from them on all the calls to LOADREC will use your filter. When requesting records, if a filter condition is present, the information about the absolute position on the index of the records will not be meaningful. If you specify a filter condition when another one is in use, the first one will be dropped, and the most recent one will be used. Passing the null string or the "" value will reset the filter conditions. Rexx delerec(Rexx[] rToDele, boolean bDelete) Delerec is used to delete/undelete one or more records. rToDele[0] has to be the total number of records to be (un)deleted, and rToDele[n] is the ACTUAL position of the n-th record to be (un)deleted on the database (NOT A NUMBER RELATIVE TO AN INDEX). The first record on the database is 1 (one). When bDelete = 1, the records are to be deleted, when bDelete = 0, the records are to be undeleted. No errors will come by deleting an already deleted record, or the other way around. Modirec returns one of the standard RXDbase error codes. Rexx delfield(Rexx rFieldName) With this method you can delete a field from a database, including indexes (if any). Note: As ever, rFieldName can be the name of the field (ie, 'name') or the number which references the field (ie, '4', if the 4-th field is 'name'). Warning: The field will disappear *physically* from the archive. No undo, no restore, zippo. Rexx disconnect() Futile, because when you request data from a server you aren't connected full time, but only on request. This method is here only for compatibility. Rexx[, ] getdbinfo() This method returns the database structure (names and field length, along with the number of fields). The returned values are: (let's say we stored the contents in rRec[, ]) rRec[0, 0] --> Number of fields in the database. rRec[n, 0] --> Length (a whole number stored in a Rexx variable) of field 'n'. rRec[n, 1] --> Name of field 'n'. rRec[n, 2] --> Indexing method of the field: it can be any of the following: ISAM00 = ISAM indexing, duplicate and null values are allowed. ISAM11 = ISAM indexing, duplicate and null values are NOT allowed. ISAM10 = ISAM indexing, duplicate values are NOT allowed, null values are. ISAM01 = ISAM indexing, duplicate values are allowed, null values are NOT. B+TREE00 = B+TREE indexing, duplicate and null values are allowed. B+TREE11 = B+TREE indexing, duplicate and null values are NOT allowed. B+TREE10 = B+TREE indexing, duplicate values are NOT allowed, null values are. B+TREE01 = B+TREE indexing, duplicate values are allowed, null values are NOT. NONE0 = No indexing, null values are allowed. NONE1 = No indexing, null values are NOT allowed. As you may have noticed, you cannot specify 'no duplicate values' for the no-index strategy of indexing. Rexx[] getdbstats() This method returns some useful statistics about the database. This function returns an array in which: Element 0 is the db size in bytes. Element 1 is the record size in bytes. Element 2 is the total number of records in the database. Element 3 is the number of active records (not marked with 'N') in the database. Rexx[] getdbstatus() This method lets you retrieve the RXDbase revision and the presence of a filter. Returns: rVar[0] = "No Filter" or "Filter Present" or "No DB loaded" rVar[1] = RXDbase version number (e.g. "RXDbase 1.0 Max Marsiglietti 1997"). Rexx globalrebuildidx() With this method you can rebuild all the indexes of the database currently in use. Useful to correct errors, or to restore all the indexes after a backup+restore. (This way if you need to backup your archives, you can backup only the .dat file, and issueing the globalrebuildidx method after the restore you will get back all of your indexes). Rexx[, ] loadrec(Rexx rIdx, Rexx rHowManyRec, Rexx rStart, boolean bForward) Loadrec loads in memory a number of records from the database. If a filter has been defined with the definefilter method, it will be used; otherwise, no record filtering will occur. rIdx is an EXISTING index to use as a reference. It can be a number (i.e. rIdx = 1 means 'the index on the first field') or a name (that field's EXACT name, i.e. "Name"). rHowManyRec is the number of the records to be loaded, ie '72'. It can also have the value 'ALL', meaning you want all of the records from rStart on. rStart is the starting record. The first record is labeled '1'. A valid value for this variable is also 'LAST', which means 'go to the last record'. bForward If "true", it means take sHowManyRec records starting from rStart on, else it means take them from rStart back. It returns a bidimensional array which is structured this way: rArray[0,0] is the number of records that satisfy the filter condition(s). rArray[0,1] is the number of records which are actually being returned (please use this, and not [0, 0], to know how many records have been returned). rArray[n,m] is the field n of record m (m = 1 to rArray[0,0]). rArray[N+1, m] can be "Y" or "N", depending on the given record: "Y" means active, "N" means deleted (only active records are returned, as of this release). rArray[N+2, m] is the position of the m-th record on the archive (NOT on the index). rArray[N+3, m] is the position of the m-th record on the used index (NOT on the archive); this information is meaningless if a filter is present. Rexx[,] loadrecwithfilter(Rexx rIdx, Rexx rHowManyRec, Rexx rStart, boolean bForward, Rexx rFilter) This method lets you perform a loadrec with a certain filter, then reset the filter to whatever it was before. The parameters exactly match the ones in methods loadrec and definefilter. Rexx modfieldidx(Rexx rFieldName, Rexx rFieldIndexingMethod) Modfieldidx lets you modify the indexing method for a given, existing, field. It automatically rebuilds the index, if passing from no index to some kind of index. It is useful if you decide that you don't need anymore an index, or if you think that you should have put an index on a field at database definion time, but you didn't. Note: rFieldIndexingMethod can be one of the following: ISAM00 = ISAM indexing, duplicate and null values are allowed. ISAM11 = ISAM indexing, duplicate and null values are NOT allowed. ISAM10 = ISAM indexing, duplicate values are NOT allowed, null values are. ISAM01 = ISAM indexing, duplicate values are allowed, null values are NOT. B+TREE00 = B+TREE indexing, duplicate and null values are allowed. B+TREE11 = B+TREE indexing, duplicate and null values are NOT allowed. B+TREE10 = B+TREE indexing, duplicate values are NOT allowed, null values are. B+TREE01 = B+TREE indexing, duplicate values are allowed, null values are NOT. NONE0 = No indexing, null values are allowed. NONE1 = No indexing, null values are NOT allowed. As you may have noticed, you cannot specify 'no duplicate values' for the no-index strategy of indexing. Rexx modfieldlength(Rexx rFieldName, Rexx rNewLength) This method lets you change the length of a field. Note: All the information in excess of the new length will be lost. Note2: As ever, rFieldName can be a number (eg. '4' meaning the 4th field) or a name (eg. "surname"). Rexx modfieldname(Rexx rOldName, Rexx rNewName) This method lets you change the name of a field. The field with name rOldName will get rNewName name. Note: As ever, rOldName can be a number (eg. '4' meaning the 4th field) or a name (eg. "surname"). Rexx modirec(Rexx[, ] rToModi) Modirec is used to modify one or more records in the database. rToModi is to be built this way: rToModi[0, 0] is the total number of records to be modified rToModi[n, m] is field n of the m-th record to be modified. n and m always start from 1 (one). rToModi[0, m] is the ACTUAL number of the record in the database (NOT A NUMBER RELATIVE TO AN INDEX) to be overwritten. This information is the same of the [N+2, m] element in the loadrec method.The first record in the database is marked as '1'. Warning: this method doesn't update single fields, it overwrites whole records. Note: there is not an order on the records to be modified, i.e. you can have: rToModi[0, 1] = 5 rToModi[0, 2] = 3 rToModi[0, 3] = 18 Returns: An appropriate error message is shown in case of errors, else you will be returned a Rexx string, in which every character is either '0' or '1', where '0' means that the specified record was not succesfully saved (a null value where nulls weren't allowed, or a duplicate value where there sholdn't be any) and a '1' means that the record was saved succesfully. Example: If we try to save 3 records and we get '010' back from modirec, this means that only the 2nd record among the ones passed to modirec was succesfully stored in the database: the remaining two were discarded (probably because they had duplicated values for fields in which we specified that no duplicate values should be allowed). Rexx pack() When you delete a record by means of the DELEREC function, that record doesn't physically get deleted from the archive, it is instead marked as 'deleted'. PACK does what the name suggests, it permanently deletes records from the archive, updating automatically all the indexes. Rexx rebuildidx(Rexx rFieldName) This method is similar to globalrebuildidx, but must be invoked explicitly on an index. Note: As ever, rFieldName can be the name of the field (ie, 'name') or the number which references the field (ie, '4', if the 4-th field is 'name'). Rexx saverec(Rexx[, ] rToSave, Rexx rMode) This method lets you write a record on disk. All of the indexes are automatically updated. rMode can only be 'overwrite' or 'append' (case isn't significative). rToSave is to be built this way: rToSave[0,0] --> number of records to be written. rToSave[n,m] --> field n of record m. Warning: both n,m are to start from 1 (one). Warning: When you specify 'overwrite', the whole database will be overwritten (deleted), and the indexes will be resetted. Returns: An appropriate error message is shown in case of errors, else you will be returned a Rexx string, in which every character is either '0' or '1', where '0' means that the specified record was not succesfully saved (a null value where nulls weren't allowed, or a duplicate value where there sholdn't be any) and a '1' means that the record was saved succesfully. Example: If we try to save 3 records and we get '010' back from saverec, this means that only the 2nd record among the ones passed to saverec was succesfully stored in the database: the remaining two were discarded (probably because they had duplicated values for fields in which we specified that no duplicate values should be allowed). Rexx status() With this method, you can query the internal status of the database. Possible return values are: DBNOTSTARTED: (can't work on nothing) READY: (no errors) SYNTAX ERROR: (go figure) ERROR:FILE ACCESS PROBLEMS (something weird at file level)