project BLF > class Persistence (other) > method ReadDataRecursive

Description

ReadDataRecursive


Parameters


icTableNameinputcharacterTableName
ihDestinationBufferinputhandleDestinationBuffer
ihIDestinationBufferinputhandleIDestinationBuffer
icPrepareinputcharacterPrepare
icParentRowidinputcharactericParentRowid
ilTopLevelinputlogicalilTopLevel
ihClassinputhandleClass
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


BLF
method other.ReadData
method other.ReadDataRecursive


program code (program1/other.p)

assign oiReturnStatus      = -98
       vhParentRowidField  = ihDestinationBuffer:buffer-field("tc_ParentRowid":U)
       vhStatusField       = ihDestinationBuffer:buffer-field("tc_status":U)
       vhIParentRowidField = ihIDestinationBuffer:buffer-field("tc_ParentRowid":U) no-error.

/* must exist */
assign vhRowidField        = ihDestinationBuffer:buffer-field("tc_rowid":U).

<M-1 run UpdateBufferInfo (input  ihDestinationBuffer (ihDestinationBuffer), 
                           input  ihIDestinationBuffer (ihIDestinationBuffer), 
                           output viFcReturnSuper (oiReturnStatus)) in other>
if viFcReturnSuper < 0
then do:
    assign oiReturnStatus = viFcReturnSuper.
    return.
end.

&if defined(DEBUGSQL) > 0 &then
run SqlDebugWrite in {&TARGETPROCEDURE} ("* ":U + program-name(1), 1).
&endif

/* ================================================================= */
/* Fill the recordset                                                */
/* ================================================================= */
assign viQryid = -1.
run SqlQryOpenTable in {&TARGETPROCEDURE}
   (icTableName, icPrepare, "", output viQryid, output oiReturnStatus).
if oiReturnStatus = 0
then run SqlQryExecute in {&TARGETPROCEDURE}
        (viQryId, output viCols, output oiReturnStatus).
if oiReturnStatus = 0
then run SqlQryMoveNext in {&TARGETPROCEDURE}
        (viQryId, output viRows, output oiReturnStatus).

if oiReturnStatus < 0
then do:
    <M-3 run SqlErrorMessage (input  ihClass (ihClass), 
                          output viFcReturnSuper (oiReturnStatus)) in other>
    if viQryid >= 0
    then run SqlQryDestroy in {&TARGETPROCEDURE} (viQryId, output oiReturnStatus).
    return.
end.


if viRows = 0
then do:
    if ilTopLevel
    then do:
        run SqlCleanup in {&TARGETPROCEDURE}.
        assign oiReturnStatus = -4.
        return.
    end.
end.

/* ================================================================= */
/*  Now, create the queries for looking for existing t and t_i data  */
/* ================================================================= */
create query vhTIQuery.
vhTIQuery:set-buffers(ihIDestinationBuffer).
create query vhTQuery.
vhTQuery:set-buffers(ihDestinationBuffer).

/* ================================================================= */
/*  Go over all records, and create the corresponding t en t_i       */
/*  records if they do not already exist.                            */
/*  Call the iReadDataRecursive for related tables.                  */
/* ================================================================= */
do while viRows = 1:

    vcRowid = <M-5 getColumnValue (input  viQryid (iiCmd), 
                     input  viCols - 1 (iiCol)) in other>.
    vhTQuery:query-prepare
        ("for each ":U + ihDestinationBuffer:name +
         " where ":U + ihDestinationBuffer:name + ".tc_rowid = '":U +
         vcRowid + "'":U).
    vhTQuery:query-open().
    vhTQuery:get-first().
    
    if vhTQuery:query-off-end
    then do:
        ihDestinationBuffer:buffer-create.
        ihIDestinationBuffer:buffer-create.
    end.
    else do:
        vhTIQuery:query-prepare
            ("for each ":U + ihIDestinationBuffer:name +
             " where ":U + ihIDestinationBuffer:name + ".tc_rowid = '":U +
             vcRowid + "'":U).
        vhTIQuery:query-open().
        vhTIQuery:get-first().
        if vhTIQuery:query-off-end
        then do:
            run SqlCleanup in {&TARGETPROCEDURE}.
            assign oiReturnStatus = -4.
            return.
        end.
    end.
    
    do viColIdx = 0 to viCols - 1:
    
        vcColName = <M-6 getColumnName (input  viQryid (iiCmd), 
                    input  viColIdx (iiCol)) in other>.
        
        if vcColName = "tc_Status":U
        then next.
        
        find tBufferFields where
             tBufferFields.thTempBuffer = ihDestinationBuffer and
             tBufferFields.tcFieldName = vcColName no-error.
        if not available tBufferFields
        then next.
        
        if vcColName = "tc_ParentRowid":U
        then do:
            assign tBufferFields.thDestinationField:buffer-value  = icParentRowid
                   tBufferFields.thIDestinationField:buffer-value = icParentRowid.
            next.
        end.

        run SqlColGetAsString in {&TARGETPROCEDURE}
           (viQryId, viColIdx, output viAddr, output oiReturnStatus).
        if viAddr = 0 
        then vcColValue = ?.
        else vcColValue = <M-7 getString (input  viAddr (iiAddr)) in other>.
        
        if vhTQuery:query-off-end
        or tBufferFields.thIDestinationField:buffer-value =
             tBufferFields.thDestinationField:buffer-value
        then assign tBufferFields.thDestinationField:buffer-value = vcColValue.
        
        assign tBufferFields.thIDestinationField:buffer-value = vcColValue.
    end.
    
    if  vhStatusField <> ?
    and vhStatusField:buffer-value = "D":U
    then assign vhStatusField:buffer-value = "".
    
    if vhParentRowidField <> ?
    then assign vhParentRowidField:buffer-value  = icParentRowid
                vhIParentRowidField:buffer-value = icParentRowid.

    create tRowidList.
    assign tRowidList.tcRowid = vcRowid.
    
    for each bDynRel where
             bDynRel.tcFcFrom = icTableName
             on error undo, throw:
        
        if bDynRel.tcFcTo matches "*":U + icTableName
        then assign vcPrepare = replace (bDynRel.tcFcRel,bDynRel.tcFcTo,chr(2)).
        else assign vcPrepare = bDynRel.tcFcRel.

        
        do viColIdx = 0 to viCols - 1:
            
            vcColName = <M-8 getColumnName (input  viQryid (iiCmd), 
                    input  viColIdx (iiCol)) in other>.
        
            if index(bDynRel.tcFcRel, icTableName + ".":U + vcColName) = 0
            then next.

            find tBufferFields where
                 tBufferFields.thTempBuffer = ihDestinationBuffer and
                 tBufferFields.tcFieldName = vcColName no-error.
            if not available tBufferFields
            then next.

            run SqlColGetAsString in {&TARGETPROCEDURE}
               (viQryId, viColIdx, output viAddr, output oiReturnStatus).
            if viAddr = 0 
            then vcValue = "?".
            else do:
                vcColValue = <M-9 getString (input  viAddr (iiAddr)) in other>.
                
                case tBufferFields.thDestinationField:type:
                when "character":U
                then assign vcValue = "'":U
                                    + replace(vcColValue, "'":U, "''":U)
                                    + "'":U.
                when "LOGICAL":U
                then assign vcValue = vcColValue.
                when "DATE":U
                then assign vtWork = date(vcValue)
                            vcValue = (if vtWork = ?
                                        then "?":U
                                        else "date(":U + string(month(vtWork),"99":U) + ",":U
                                              + string(day(vtWork),"99":U) + ",":U
                                              + string(year(vtWork),"99":U) + ")":U).
                otherwise assign vcValue = vcColValue.
                end case.
            end.

            assign vcPrepare = replace(vcPrepare,
                                       icTableName + ".":U +
                                      (if bDynRel.tcFcTo matches "*":U + icTableName
                                       then replace (tBufferFields.tcFieldName,bDynRel.tcFcTo,chr(2))
                                       else tBufferFields.tcFieldName),
                                       vcValue).
        end.
        
        if bDynRel.tcFcTo matches "*":U + icTableName
        then assign vcPrepare = replace (vcPrepare,chr(2),bDynRel.tcFcTo).

        <M-10 run ReadDataRecursive (input  bDynRel.tcFcTo (icTableName), 
                             input  bDynRel.thFcBuffer (ihDestinationBuffer), 
                             input  bDynRel.thFcIBuffer (ihIDestinationBuffer), 
                             input  vcPrepare (icPrepare), 
                             input  vcRowid (icParentRowid), 
                             input  false (ilTopLevel), 
                             input  ihClass (ihClass), 
                             output viFcReturnSuper (oiReturnStatus)) in other>
        if viFcReturnSuper <> 0
        then do :
            assign oiReturnStatus = viFcReturnSuper.
            run SqlCleanup in {&TARGETPROCEDURE}.
            return.
        end.
    end.
    
    vhTQuery:query-close().
    vhTIQuery:query-close().
    
    assign viReadCount = viReadCount + 1.
    
    run SqlQryMoveNext in {&TARGETPROCEDURE}
       (viQryId, output viRows, output oiReturnStatus).
end.

/* ================================================================= */
/* Update the records that have not been reloaded                    */
/* (because deleted in the database)                                 */
/* ================================================================= */
if icParentRowid  <> ""
and vhStatusField <> ?
then do:
    vhTQuery:query-prepare
        ("for each ":U + ihDestinationBuffer:name +
         " where ":U + ihDestinationBuffer:name + 
         ".tc_ParentRowid = '":U + icParentRowid +
         "' and ":U + ihDestinationBuffer:name +
         ".tc_status <> 'N'":U).
    vhTQuery:query-open().
    vhTQuery:get-first().

    do while not vhTQuery:query-off-end :
    
        if not can-find (first tRowidList where
                               tRowidList.tcRowid = string(vhRowidField:buffer-value))
        then do:
            assign vlTFound = (vhStatusField:buffer-value = "C":U).
            
            if vhStatusField:buffer-value = ""
            then for each bDynRel where
                          bDynRel.tcFcFrom = icTableName:
                <M-18 run CheckChanges (input  bDynRel.tcFcTo (icTableName), 
                        input  bDynRel.thFcBuffer (ihDestinationBuffer), 
                        input  vhRowidField:buffer-value (icParentRowid), 
                        output vlTFound (olFound), 
                        output viFcReturnSuper (oiReturnStatus)) in other>
                if vlTFound then leave.
            end.

            if vlTFound
            then do:
                /* If a record that is deleted in the database, is changed by the user
                   give it status 'N', including it's detail. */
                assign vhPdatabaseInst = ihClass
                       vcTRowid        = <M-12 GetNumberForNew () in database>.

                for each bDynRel where
                         bDynRel.tcFcFrom = icTableName:
                    <M-19 run UpdateChanges (input  bDynRel.tcFcTo (icTableName), 
                         input  bDynRel.thFcBuffer (ihDestinationBuffer), 
                         input  vhRowidField:buffer-value (icOldRowid), 
                         input  vcTRowid (icNewRowid), 
                         input  ihClass (ihClass), 
                         output viFcReturnSuper (oiReturnStatus)) in other>
                    if viFcReturnSuper <> 0
                    then do :
                        run SqlQryDestroy in {&TARGETPROCEDURE}
                           (viQryId, output oiReturnStatus).
                        assign oiReturnStatus = viFcReturnSuper.
                        return.
                    end.
                end.
                assign vhRowidField:buffer-value  = vcTrowid
                       vhStatusField:buffer-value = "N":U.
            end.
            else do:
                /* If a record that is deleted in the database, is not changed by the user
                   delete it, including it's detail. */
                for each bDynRel where
                         bDynRel.tcFcFrom = icTableName:
                    <M-20 run UpdateChanges (input  bDynRel.tcFcTo (icTableName), 
                         input  bDynRel.thFcBuffer (ihDestinationBuffer), 
                         input  vhRowidField:buffer-value (icOldRowid), 
                         input  '' (icNewRowid), 
                         input  ihClass (ihClass), 
                         output viFcReturnSuper (oiReturnStatus)) in other>
                end.
                ihDestinationBuffer:buffer-delete().
            end.
        end.
        
        vhTQuery:get-next().
    end.
    
    vhTQuery:query-close().
end.

run SqlQryDestroy in {&TARGETPROCEDURE}
   (viQryId, output oiReturnStatus).
delete object vhTQuery.
delete object vhTIQuery.

assign oiReturnStatus = 0.