Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- FlexFile Reference Guide - <b>v_replace() / v_rep()</b> http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 V_REPLACE() / V_REP()
 Replace data stored in a DBV file with new data
-------------------------------------------------------------------------------

 Syntax

    V_REPLACE(   <exp>,
                 <cOldPointer>,
                 [<cAlias> | <nArea>],
                 [<cDataType>])     ->      cNewPointer

 Arguments

    <exp> is any valid clipper variable including single or
    multi-dimensional arrays, Clipper or Class(y) objects, FlexFile arrays,
    MemoEdit() strings, SaveScreen() strings, any binary data stored in a
    Clipper variable, as well as numerics, dates, and logicals, and Proclip
    windows.  They only data type that this function will not store is a
    code block.

    <cOldPointer> is a required six byte pointer-field or variable in
    which you have previously stored a pointer to variable length
    data. Passing six spaces causes FlexFile to assume that there is
    no old data to be released before the new <exp> data is saved.
    Refer to the discussion below for further explanation.

    <cAlias> or <nArea> is a DBV file alias or area specified with
    V_USE() or V_SELECT(). If omitted, the replace will occur in the
    current DBV area.

    <cDataType> is an expression which describes the data type of
    <exp>. FlexFile will assume Clipper's data type if this parameter
    is omitted. Only the first character of <cDataType> is significant
    (e.g. "C" is equivalent to "Character" ).

    This parameter is almost never necessary in this release of FlexFile.
    This is because the type of the data being saved is usually
    non-ambiguous. However, when saving either FlexFile's own strongly
    typed arrays or Proclip(tm) windows, it is necessary to tell FlexFile
    what you are saving.

    This is because FlexFile strongly typed arrays appear to Clipper as
    character data and Proclip window handles appear to Clipper as numeric
    values.  So, for example, if you save a Proclip window handle without
    providing this parameter, FlexFile will save the handle instead of
    the contents of the window.


    Table: V_REPLACE() data type codes

           +----------------------------------------------+
           | Character            Description             |
           |----------------------------------------------|
           |     C          Clipper character data        |
           |     N          Clipper numeric               |
           |     L          Clipper logical               |
           |     D          Clipper date                  |
           |     A          Clipper array                 |
           |     O          Clipper or Class(y) object    |
           |     P          Proclip window handle         |
           |     F          FlexFile strongly typed array |
           +----------------------------------------------+

 Returns

    V_REPLACE() returns a pointer which should be stored in the
    pointer-field with which the variable length data is to be
    associated.

    V_REPLACE() returns (.F.) on error.  This causes the error system
    to be invoked with a "Data Type Mismatch".  Use V_ERROR() to fetch
    the specific error value (see Appendix B for a table of error
    descriptions).

 Description

    V_REPLACE() stores the variable length data defined by <exp> and
    returns a six byte pointer <cNewPointer>. This pointer is the only
    way FlexFile will ever be able to access the <exp> data; if this
    pointer is lost the data in the DBV file will be inaccessible.

    It is highly recommended, therefore, that the V_REPLACE() function
    be imbedded in the same line of code as the Clipper REPLACE
    command (see examples below). <cNewPointer> will then be stored
    directly into a six byte pointer-field in the related DBF file.

    V_REPLACE() first deletes the data associated with <cOldPointer>
    freeing up the space, if any, that it was occupying. V_REPLACE()
    then looks for the smallest available space to put the <exp> new
    data. Finally, it returns <cNewPointer> to be used at any time by
    V_RETRIEVE(), V_REPLACE(), V_LEN(), etc. In most cases, you will
    be storing the <cNewPointer> in a DBF file (highly recommended).

    In designing the associated DBF structure, you will define a
    pseudo memo-field which will be a six byte (or more) character
    type field. FlexFile refers to these fields as pointer-fields.
    When a FlexFile pointer is stored in this field, the field will
    have six bytes of ASCII characters from the "irrational" range
    (128-255). This may appear as "garbage", but is actually a very
    compact encoded structure. It is encoded only to insure that nulls
    are never stored in your DBF file. After creating this field you
    can ignore it exactly as you would a DBT memo-field.  If you need
    to know the offset of the data in the DBV file use the function
    V_PTR().

    The V_REPLACE() function replaces data in the current DBV area or
    the <nArea>/<cAlias> area if specified. Attempting to use
    <cOldPointer> which points into one DBV file to delete/replace
    data in any other DBV file can be dangerous. Although there is a
    degree of protection against this kind of programmer error, it is
    possible that random data will be deleted from the target area
    corrupting that file.


    Incorrect: <fld1> is pointing to data in DBV area 1 but being used
    to refer to data in DBV area 2.

    V_SELECT(1)
    REPLACE fld1 WITH V_REPLACE( "No problem yet", fld1 )
          |
          +-------------------------------------------------+
    V_SELECT(2)                                             |
    REPLACE fld1 WITH V_REPLACE( "File corruption possible", fld1)


    Correct: <fld1> is being used consistently in DBV area 1.

    V_SELECT(1)
    REPLACE fld1 WITH V_REPLACE( "Much better", fld1 )
          +------------------------------+
                                         |
    REPLACE fld1 WITH V_REPLACE( "Best", fld1 )



    +-------------------------- WARNING --------------------------+ 
    | V_REPLACE() deletes the data associated with <cOldPointer>  | 
    | before returning <cNewPointer>.  Attempting to use          | 
    | <cOldPointer> after this function deletes the data that it  | 
    | points to can corrupt the DBV file.                         | 
    +-------------------------------------------------------------+ 

 Notes

  . All file sharing within the DBV file is handled automatically.
    It is the programmers responsibility to handle any one
    pointer-field exactly as you would any DBF field (i.e. use
    Clippers FLOCK()/RLOCK() functions). If a record is successfully
    locked with Clippers RLOCK() function, the pointer-field will be
    inaccessible to other users until the current task releases it.

  . If you use comparison of data in your networking code you are
    guaranteed that the pointer stored in the DBF field will be
    different after a replace even if the <cNewPointer> points to the
    same disk location as <cOldPointer>. It is, therefore, not
    necessary to compare the data itself (to see if it has been
    changed by one user while another user is working with it), but
    rather, it suffices to compare the pointers themselves.

 Examples

    // Example 1: exclusive
    // Assume the DBF file is indexed on the field scr_name
    // Assume the DBF file has a pointer-field scr_vlf.
    LOCAL cScr

    // Open a DBF, an NTX and a related DBV file
    USE dbf_file INDEX dbf_file
    V_USE( "dbv_file" )

    // Save a screen segment to a variable.
    cScr = SAVESCREEN( 5, 5, 10, 50 )

    // Create array of Items on screen.
    aPickList = { "1. Add customer"       ,;
                  "2. Edit customer"      ,;
                  "3. Delete customer"    ,;
                  "4. Quit"                }

    // Make a name for the screen and append the screen and array to
    // the dbv_file.dbv.
    APPEND BLANK
    REPLACE scr_name WITH "main_menu"
    REPLACE scr_vlf  WITH V_REPLACE( cScr, scr_vlf )
    REPLACE picklist WITH V_REPLACE( aPickList, picklist )

    // Later or from a different application, restore
    // the screen segment and array.
    CLEAR
    SEEK "main_menu"
    RESTSCREEN( 5, 5, 10, 50, V_RETRIEVE( scr_vlf ) )
    aPickList = V_RETRIEVE( picklist )


    // Example 2: Network example
    // Assume the file has a pointer-field memo_vlf
    LOCAL ptr, cStr

    // Set exclusive off for Clipper and FlexFile.
    SET EXCLUSIVE OFF
    V_EXCLUSIV( .F. )

    // Open the files
    USE dbf_file INDEX dbf_file
    IF V_USE( "dbv_file" ) == -1
       ? "File not available at this time."
       QUIT
    ENDIF

    // Make up some data; append it to the files.
    APPEND BLANK
    WHILE NETERR()
       APPEND BLANK
    ENDDO

    // Lock the record an put some test data in the vlf.
    WHILE !RLOCK()
    ENDDO
    REPLACE dbf_file->memo_vlf WITH V_REPLACE( "Testing",
                             dbf_file->memo_vlf )
    UNLOCK

    // Remember the pointer for an "updated" test (see below).
    ptr = memo_vlf

    // Edit the existing data.  Note: the file is not locked.
    cStr = MEMOEDIT( V_RETRIEVE( memo_vlf ), 5, 5, 20, 50 )

    // Lock the record before the replace.
    WHILE !RLOCK()
    ENDDO

    // Test for an update between when we assigned memo_vlf to
    // ptr and now.
    IF ptr != dbf_file->memo_vlf
       ? "This memo field has been updated by another user."
       ? "It cannot be saved."
    ELSE
       REPLACE memo_vlf WITH V_REPLACE( cStr, memo_vlf )
    ENDIF

    UNLOCK

    // Close the files.
    USE
    V_USE()

See Also: V_USE() V_RETRIEVE() V_POKE()

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson