## Dbase for LANs by P.L. Olympia and Kathy Cea, page 40


Listing 1


 Function CHANGE  
   SCATTER TO HoldRec
     GOTO RECNO()
     set CntInRec to the _DBASELOCK Count value in database
     set CntInArr to the _DBASELOCK Count value in array
     IF CntInRec <> CntInArr
        GATHER FROM HoldRec
        RETURN .T.
     ELSE
        RETURN .F.
     ENDIF



Listing 2


/**************************************************************
*
* LogicLok.C is a sample program to demonstrate the use of
*  Logical Record Locking facilities provided by the NetWare
*  Synchronization Services.  It demonstrates a series of function
*  calls to log two sample database records into the Log Table,
*  lock the records in the table, unlock the records, and
*  clear the Log Table.
*
*  Compiled in Turbo C 2.0
*
*  The Include files NIT.H and NITERROR.H are header files
*   provided with the Novell API's, not Turbo C.
****************************************************************/

#include <stdio.h>
#include <string.h>
#include <nit.h>
#include <niterror.h>

int AddRectoLog (char *RecName);
int lockLog ();
void unlockLog ();
void clearLog ();

main()
{
    char RecName1[100],
         RecName2[100];
    char test;
    int returncode;
    BYTE lockMode;

/************************************************************************
 * For test purposes, we'll define two sample database records by
 * assigning a logical record name consisting of the .dbf name plus the
 * primary key field value, separated with a dash (-).  In this example,
 * we lock a record in the Employee.Dbf with a primary key of
 * "123-45-6789" and a record in the Dept.Dbf with a primary key of
 * "SALES".
 ***********************************************************************/

    strcpy (RecName1, "Employee-123-45-6789");
    strcpy (RecName2, "Dept-SALES");

/**************************************************************
*
* SetLockMode is a NetWare function call that sets the network
*  locking mode based on the parameter passed as follows:
*
*   0 - Compatibility Lock mode (NetWare 4.6 and earlier)
*   1 - Extended Lock mode (Advanced NetWare)
*
*  The default is 0.
****************************************************************/

    lockMode = 1;     /* We're using Advanced NetWare 286 here */
    SetLockMode(lockMode);

    returncode = AddRectoLog(RecName1);
    if (!returncode)
        printf("Record 1 Added to Log Table\n");
    else
        printf("Record 1 Could not be added to Log Table\n");

    returncode = AddRectoLog(RecName2);
    if (!returncode)
        printf("Record 2 Added to Log Table\n");
    else
        printf("Record 2 Could not be added to Log Table\n");

    returncode = lockLog();
    if (!returncode) {
        printf("Logged records are now locked\n");
        test = getche();   /* Wait until a key is pressed to unlock records */
        unlockLog();
    }
    else
        printf("Logged records could not be locked\n");

    clearLog();
}

int AddRectoLog (char *RecName)
/**************************************************************
*
* AddRectoLog adds the record passed in RecName to the
*  Log Table.  Does not attempt to lock the record.
*  Returns 0 if record is successfully logged, 1 otherwise.
*
****************************************************************/

{
    int returncode;
    BYTE lockDir;
    WORD timeout;

/*************************************************************************
 *  The lockDir parameter specifies whether the record should be locked.
 *    lockDir may take the following values:
 *
 *       0x00 Log record
 *       0x01 Log record and lock exclusively
 *       0x03 Log record and lock with shareable, read-only lock
 *************************************************************************/
    lockDir = 0;

/* timeout is ignored if lockDir is 0  */

    timeout = 0;
    returncode = LogLogicalRecord (RecName, lockDir, timeout);
    return(returncode ? 1 : 0);
}


int lockLog ()

/**************************************************************
*
* lockLog attempts to lock all records in the Log Table.
*  Timeout Limit in this example is set to 36 (2 seconds).
*  Returns 0 if lock is successfully, 1 otherwise.
*
****************************************************************/

{
    int returncode;
    WORD timeout;
/*********************************************************************
 *    timeout specifies the maximum time limit to wait for record(s)
 *     in Log Table to become available.  Value is specified in units
 *     of 1/18 of a second
 **********************************************************************/
    timeout = 36;

    returncode = LockLogicalRecordSet (timeout);
    return(returncode ? 1 : 0);
}

void unlockLog ()
/**************************************************************
*
* unlockLog unlocks all logical records in the Log Table,
*  but leaves the records in the table.  If there are no locked
*  records, the function is ignored.
*
****************************************************************/

{
    ReleaseLogicalRecordSet();
}

void clearLog ()
/**************************************************************
*
* clearLog unlocks all logical records in the Log Table,
*  and removes them from the table.  If there are no logical
*  records logged, the function is ignored.
*
****************************************************************/

{
    ClearLogicalRecordSet();
}



Listing 3A and B


Listing 3A

GO BOTTOM
SKIP                  && move pointer to phantom record
SCATTER TO BlankArr   && create a blank array from phantom record
GOTO Record 5
GATHER FROM BlankArr  && blank current record (record 5)


Listing 3B

Alternative 1

SCATTER TO x BLANK   && x will be an array with empty elements
GATHER FROM x        && blanks the current record


Alternative 2

SCATTER MEMVAR BLANK   && Creates set of empty memory variables
GATHER MEMVAR          && blanks the current record
