project BLF > class Persistence (Progress) > method LoadInstance

Description

Load instance data from the application database

PreCondition

This method is to be used by instance procedures only.


Parameters


ihClassinputhandle
iiInstanceIDinputintegerinstance ID
ihInstanceDatainputhandledataset with instance data
icClassNameinputcharacter
oiDraftInstanceIdoutputinteger
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


unused


program code (program1/progress.p)

if ihInstanceData:name = "StateData"
then do:
    viFcCount1 = 2.
    if icClassName = "session"
    then do while program-name(viFcCount1) <> ?:
        if program-name(viFcCount1) = "UpdateSessionData program/cacher.p"
        then vlLoadReadonly = yes.
        viFcCount1 = viFcCount1 + 1.
    end.
    
    if ihClass <> ?
    then run GetPublicData in ihClass (input "vlRawTransferSupported", output vcRawTransferSupported, output viFcReturnSuper).
end.
else vlLoadReadonly = yes.

ihInstanceData:empty-dataset().

CREATE tRaw. /* Just need one dummy row to store RAW field in by its handle. */
vhContext = BUFFER tRaw:BUFFER-FIELD("taContext":U):HANDLE.

if vcStateDirectory = "" or ihInstanceData:name <> "StateData"
then do:
    if not (valid-handle(vhInstanceQuery) and
            viInstanceUID = vhInstanceQuery:unique-id)
    then do:
        create buffer vhInstanceBuffer for table "fcInstance":U in widget-pool "persistent".
        create query vhInstanceQuery in widget-pool "persistent".
        vhInstanceQuery:forward-only = yes.
        vhInstanceQuery:set-buffers(vhInstanceBuffer).
        vhInstanceQuery:private-data = "Persistent".    /* do not ever delete this query */
        viInstanceUID = vhInstanceQuery:unique-id.
    end.
    vhInstanceQuery:query-prepare ("for each fcInstance where fcInstance.Instance_ID = ":U + string(iiInstanceId) +
                                   " and fcInstance.InstanceSeq > 0").
    vhInstanceQuery:query-open().

    if vcRawTransferSupported = "false"
    then do:
        vhInstanceQuery:get-first(no-lock).
        do while not vhInstanceQuery:query-off-end:
            if vhInstanceBuffer::InstanceClassName <> icClassName
            then do:
                vhInstanceQuery:query-close().
                assign oiReturnStatus = -3.
                <M-31 run ErrorMessage
                   (input  #T-83'Invalid instance number. Found data for business class '$2', but expected business class '$1'.':255(4394)T-83# (icMessage), 
                    input  icClassName + chr(2) + vhInstanceBuffer::InstanceClassName (icArguments), 
                    input  '' (icFieldName), 
                    input  '' (icFieldValue), 
                    input  '' (icRowid), 
                    input  ? (ihClass)) in Progress>
                return.
            end.
            vlFound = yes.
            vaContext = vhInstanceBuffer::InstanceData.
            viLength = viLength + length(vaContext,"RAW").
            vhInstanceQuery:get-next(no-lock).
        end.
        vhInstanceQuery:query-close().
    
        set-size(vmContext) = viLength.
        viContextPos = 1.
        vhInstanceQuery:query-prepare ("for each fcInstance where fcInstance.Instance_ID = ":U + string(iiInstanceId) +
                                       " and fcInstance.InstanceSeq > 0 by fcInstance.InstanceSeq").
        vhInstanceQuery:query-open().
        
        if vlLoadReadonly
        then do:
            vhInstanceQuery:get-first(no-lock).
            do while not vhInstanceQuery:query-off-end:
                vaContext = vhInstanceBuffer::InstanceData.
                viRawLength = length(vaContext,"RAW").
                put-bytes (vmcontext,viContextPos) = get-bytes (vaContext,1,viRawLength).
                viContextPos = viContextPos + viRawLength.
                vhInstanceQuery:get-next(no-lock).
            end.
        end.
        else do transaction on error undo, throw:
        
            vhInstanceQuery:get-first(no-lock).
            
            viBuffer = 0.
            do while vhInstanceBuffer:available = yes
               and viBuffer < 6
               and (vhInstanceBuffer:locked = yes or vhInstanceBuffer::InstanceIsInUse = yes):
                pause 1 no-message.
                viBuffer = viBuffer + 1.
                vhInstanceQuery:query-prepare ("for each fcInstance where fcInstance.Instance_ID = ":U + string(iiInstanceId) +
                                       " and fcInstance.InstanceSeq > 0").
                vhInstanceQuery:query-open().
                vhInstanceQuery:get-first(no-lock).
            end.
            
            if vhInstanceQuery:query-off-end
            then do:
                vhInstanceQuery:query-close().
                delete tRaw.
                <M-82 run LoadDraftInstance
                   (input  ihClass (ihClass), 
                    input  iiInstanceID (iiInstanceId), 
                    input  ihInstanceData (ihInstanceData), 
                    input  icClassName (icClassName), 
                    output oiDraftInstanceId (oiDraftInstanceId), 
                    output oiReturnStatus (oiReturnStatus)) in Progress>
                return.
            end.

            vhInstanceQuery:get-current(exclusive-lock, no-wait).
        
            do while not vhInstanceQuery:query-off-end:
            
                if vhInstanceBuffer:locked
                then do:
                    vlFound = no.
                    leave.
                end.
                
                if vhInstanceBuffer::InstanceIsInUse = true
                then do:
                    vhInstanceBuffer:buffer-release().
                    assign vlFound = ?.
                    leave.
                end.
                assign vhInstanceBuffer::InstanceIsInUse = true.
        
                vaContext = vhInstanceBuffer::InstanceData.
                viRawLength = length(vaContext,"RAW").
                put-bytes (vmcontext,viContextPos) = get-bytes (vaContext,1,viRawLength).
                viContextPos = viContextPos + viRawLength.
                vhInstanceQuery:get-next(exclusive-lock, no-wait).
            end.
        end.
        
        if vlFound
        then ihInstanceData:read-xml ("memptr",vmContext,"APPEND","",no).    
    end.
    else
    if vlLoadReadonly
    then do:
        vhInstanceQuery:get-first(no-lock).
        
        do while not vhInstanceQuery:query-off-end:
        
            if vhInstanceBuffer::InstanceClassName <> icClassName
            then do:
                vhInstanceQuery:query-close().
                assign oiReturnStatus = -3.
                <M-8 run ErrorMessage
                   (input  #T-9'Invalid instance number. Found data for business class '$2', but expected business class '$1'.':255(4394)T-9# (icMessage), 
                    input  icClassName + chr(2) + vhInstanceBuffer::InstanceClassName (icArguments), 
                    input  '' (icFieldName), 
                    input  '' (icFieldValue), 
                    input  '' (icRowid), 
                    input  ? (ihClass)) in Progress>
                return.
            end.
        
            vlFound = yes.
            viContextPos = 1.
            vaContext = vhInstanceBuffer::InstanceData.
        
            viBuffer = GET-SHORT(vaContext, viContextPos). 
            DO WHILE viBuffer <> 0:
                viBuffer = GET-SHORT(vaContext, viContextPos).
                IF viBuffer <> 0 THEN   /* 0 signals end of data */
                DO:
                    IF viBuffer <> viPrevBuffer 
                    THEN assign vhBuffer = ihInstanceData:GET-BUFFER-HANDLE(viBuffer)
                                viPrevBuffer = viBuffer.
                    viContextPos = viContextPos + 2.    /* Move past the table number. */
                    viRawLength = GET-LONG(vaContext, viContextPos).
                    viContextPos = viContextPos + 4.
                    tRaw.taContext = GET-BYTES(vaContext, viContextPos, viRawLength).
                    viContextPos = viContextPos + viRawLength.
                    vhBuffer:BUFFER-CREATE().
                    vhBuffer:RAW-TRANSFER(FALSE, vhContext).
                END.  /* IF iBuffer <> 0 */
            END.      /* WHILE iBuffer <> 0 */
            
            vhInstanceQuery:get-next(no-lock).
            
        END.          /* FOR EACH matching fcInstance row. */
    end. /* readonly = yes */
    else TRX: do transaction on error undo, throw:
    
        vhInstanceQuery:get-first(no-lock).
        
        viBuffer = 0.
        do while vhInstanceBuffer:available = yes
           and viBuffer < 6
           and (vhInstanceBuffer:locked = yes or vhInstanceBuffer::InstanceIsInUse = yes):
            pause 1 no-message.
            viBuffer = viBuffer + 1.
            vhInstanceQuery:query-prepare ("for each fcInstance where fcInstance.Instance_ID = ":U + string(iiInstanceId) +
                                   " and fcInstance.InstanceSeq > 0").
            vhInstanceQuery:query-open().
            vhInstanceQuery:get-first(no-lock).
        end.
        
        if vhInstanceQuery:query-off-end
        then do:
            vhInstanceQuery:query-close().
            delete tRaw.
            <M-6 run LoadDraftInstance
               (input  ihClass (ihClass), 
                input  iiInstanceID (iiInstanceId), 
                input  ihInstanceData (ihInstanceData), 
                input  icClassName (icClassName), 
                output oiDraftInstanceId (oiDraftInstanceId), 
                output oiReturnStatus (oiReturnStatus)) in Progress>
            return.
        end.
        
        vhInstanceQuery:get-current(exclusive-lock, no-wait).
        
        do while not vhInstanceQuery:query-off-end on error undo TRX, return:
        
            if vhInstanceBuffer:locked
            then do:
                vlFound = no.
                leave.
            end.
        
            if vhInstanceBuffer::InstanceClassName <> icClassName
            then do:
                vhInstanceQuery:query-close().
                assign oiReturnStatus = -3.
                <M-2 run ErrorMessage
                   (input  #T-5'Invalid instance number. Found data for business class '$2', but expected business class '$1'.':255(4394)T-5# (icMessage), 
                    input  icClassName + chr(2) + vhInstanceBuffer::InstanceClassName (icArguments), 
                    input  '' (icFieldName), 
                    input  '' (icFieldValue), 
                    input  '' (icRowid), 
                    input  ? (ihClass)) in Progress>
                return.
            end.
        
            if vhInstanceBuffer::InstanceIsInUse = true
            then do:
                vhInstanceBuffer:buffer-release().
                assign vlFound = ?.
                leave.
            end.
            assign vhInstanceBuffer::InstanceIsInUse = true.
        
            vlFound = yes.    
            viContextPos = 1.
            vaContext = vhInstanceBuffer::InstanceData.
        
            viBuffer = GET-SHORT(vaContext, viContextPos). 
            DO WHILE viBuffer <> 0:
                viBuffer = GET-SHORT(vaContext, viContextPos).
                IF viBuffer <> 0 THEN   /* 0 signals end of data */
                DO:
                    IF viBuffer <> viPrevBuffer 
                    THEN assign vhBuffer = ihInstanceData:GET-BUFFER-HANDLE(viBuffer)
                                viPrevBuffer = viBuffer.
                    viContextPos = viContextPos + 2.    /* Move past the table number. */
                    viRawLength = GET-LONG(vaContext, viContextPos).
                    viContextPos = viContextPos + 4.
                    tRaw.taContext = GET-BYTES(vaContext, viContextPos, viRawLength).
                    viContextPos = viContextPos + viRawLength.
                    vhBuffer:BUFFER-CREATE().
                    vhBuffer:RAW-TRANSFER(FALSE, vhContext).
                END.  /* IF iBuffer <> 0 */
            END.      /* WHILE iBuffer <> 0 */
            
            vhInstanceQuery:get-next(exclusive-lock, no-wait).
            
        END.          /* FOR EACH matching fcInstance row. */
    end.    /* readonly = no */
end.
else do:
    vcFileName = vcStateDirectory + "/" + lc(icClassName) + string(iiInstanceID) + ".lob".
    if search(vcFileName) = ?
    then do:
        delete tRaw.
        <M-7 run LoadDraftInstance
           (input  ihClass (ihClass), 
            input  iiInstanceID (iiInstanceId), 
            input  ihInstanceData (ihInstanceData), 
            input  icClassName (icClassName), 
            output oiDraftInstanceId (oiDraftInstanceId), 
            output oiReturnStatus (oiReturnStatus)) in Progress>
        return.
    end.

    if vcRawTransferSupported = "false"
    then ihInstanceData:read-xml ("file",vcFileName,"APPEND","",no).
    else do:
        copy-lob file vcFileName to vmContext.
        viLength = get-size(vmContext).
        
        DO WHILE viContextPos < viLength - 1:
            viBuffer = GET-SHORT(vmContext, viContextPos).
            IF viBuffer <> viPrevBuffer 
            THEN assign vhBuffer = ihInstanceData:GET-BUFFER-HANDLE(viBuffer)
                        viPrevBuffer = viBuffer.
            viContextPos = viContextPos + 2.    /* Move past the table number. */
            viRawLength = GET-LONG(vmContext, viContextPos).
            viContextPos = viContextPos + 4.
            tRaw.taContext = GET-BYTES(vmContext, viContextPos, viRawLength).
            viContextPos = viContextPos + viRawLength.
            vhBuffer:BUFFER-CREATE().
            vhBuffer:RAW-TRANSFER(FALSE, vhContext).
        END.      /* WHILE iBuffer <> 0 */
    end.
    
    vlFound = yes.
end.

if vlFound = ? or not vlFound
then do:
    assign oiReturnStatus = -3
           vcError        = (if vlFound = no
                             then #T-94'Instance is locked.':255(349881641)T-94#
                             else #T-4'Instance opened twice.':255(92)T-4#)
                          + ' (icClassName= ' + icClassName + ' iiInstanceId= ' + string (iiInstanceId) + ')'.
    <M-1 run ErrorMessage
       (input  vcError (icMessage), 
        input  '' (icArguments), 
        input  '' (icFieldName), 
        input  '' (icFieldValue), 
        input  '' (icRowid), 
        input  ? (ihClass)) in Progress>
end.

finally:
    set-size(vmContext) = 0.
    if available tRaw
    then delete tRaw.
    if vhInstanceQuery <> ?
    then vhInstanceQuery:query-close().
end finally.