project BLF > class Persistence (Progress) > method CreateDraftInstance

Description

Add all instance data into the fcDraftInstance table.


Parameters


iiTransactionIdinputintegerInstance ID of transaction (optional)
iiInstanceIdinputintegerinstance ID of the draft instance
icBusinessinputcharacterBusiness class shortname of the draft instance
icActivityinputcharacterActivity Code
icReferenceinputcharacterReference to identify the draft instance with
icCreatedByinputcharacterCreatedBy
icFormNameinputcharacterUI form name
ilDraftIsSharedinputlogical
iiCompanyIDinputinteger
ihInstanceDatainputhandle
iiOldInstanceIdinputinteger
ihClassinputhandle
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


unused


program code (program1/progress.p)

do transaction on error undo, throw:
    
    if ihClass <> ?
    then run GetPublicData in ihClass (input "vlRawTransferSupported", output vcRawTransferSupported, output viFcReturnSuper).

    if not (valid-handle(vhDraftQuery) and
            viDraftUID = vhDraftQuery:unique-id)
    then do:
        create buffer vhDraftBuffer for table "fcDraftInstance":U in widget-pool "persistent".
        create query vhDraftQuery in widget-pool "persistent".
        vhDraftQuery:forward-only = yes.
        vhDraftQuery:set-buffers(vhDraftBuffer).
        vhDraftQuery:private-data = "Persistent".    /* do not ever delete this query */        
        viDraftUID = vhDraftQuery:unique-id.
        
        create buffer vhDraftDataBuffer for table "fcDraftInstanceData":U in widget-pool "persistent".
        create query vhDraftDataQuery in widget-pool "persistent".
        vhDraftDataQuery:forward-only = yes.
        vhDraftDataQuery:set-buffers(vhDraftDataBuffer).
        vhDraftDataQuery:private-data = "Persistent".    /* do not ever delete this query */
    end.

    if iiOldInstanceId = 0
    then vhDraftBuffer:buffer-create().
    else do:
        vhDraftQuery:query-prepare
             ("for each fcDraftInstance where fcDraftInstance.DraftInstance_ID = ":U +
              string(iiOldInstanceId)).
        vhDraftQuery:query-open().
        vhDraftQuery:get-first(exclusive-lock, no-wait).
        if vhDraftBuffer:available and vhDraftBuffer:locked
        then do:
            vhDraftQuery:query-close().
            assign oiReturnStatus = -3.
            return.
        end.
        if not vhDraftBuffer:available
        then vhDraftBuffer:buffer-create().
    end.

    assign vhDraftBuffer::DraftInstance_ID = iiInstanceId
           vhDraftBuffer::TransactionId    = iiTransactionId
           vhDraftBuffer::BusinessClass    = icBusiness
           vhDraftBuffer::Activity         = icActivity
           vhDraftBuffer::FormName         = icFormName
           vhDraftBuffer::Reference        = icReference
           vhDraftBuffer::IsShared         = ilDraftIsShared
           vhDraftBuffer::Company_ID       = iiCompanyID
           vhDraftBuffer::Owner            = icCreatedBy
           vhDraftBuffer::CreationUser     = icCreatedBy
           vhDraftBuffer::CreationDate     = today
           vhDraftBuffer::CreationTime     = time
           vhDraftBuffer::IsInUse          = false.
    vhDraftBuffer:buffer-release().

    if iiOldInstanceId <> 0
    then do:
        vhDraftDataQuery:query-prepare
         ("for each fcDraftInstanceData where fcDraftInstanceData.DraftInstance_ID = ":U + string(iiOldInstanceId)).
        vhDraftDataQuery:query-open().
        vleoq = no.
    end.
    
    if vcRawTransferSupported = "false"
    then do:
        ihInstanceData:write-xml ("memptr",vmContext,false,?,?,false,false,false,true).
        viMaxLength = get-size(vmcontext).
        viContextPos = 1.
        
        do while viContextPos <= viMaxLength:
        
            viRawLength = minimum (viMaxLength - viContextPos + 1, 31000).
            vacontext = get-bytes (vmcontext,viContextPos,viRawLength).
            viContextPos = viContextPos + viRawLength.

            if iiOldInstanceId <> 0
            and vleoq = no
            then do:
                vhDraftDataQuery:get-next(exclusive-lock, no-wait).
                if vhDraftDataBuffer:available and vhDraftDataBuffer:locked
                then do:
                    vhDraftDataQuery:query-close().
                    assign oiReturnStatus = -3.
                    return.
                end.
                vleoq = vhDraftDataQuery:query-off-end.
            end.
        
            if iiOldInstanceId <> 0
            and vleoq = no
            then assign viContextSeq = vhDraftDataBuffer::DraftInstanceSeq.
            else do:
                vhDraftDataBuffer:buffer-create().
                viContextSeq = viContextSeq + 1.
            end.
        
            assign vhDraftDataBuffer::DraftInstance_ID = iiInstanceId
                   vhDraftDataBuffer::DraftInstanceSeq = viContextSeq
                   vhDraftDataBuffer::DraftInstanceData = vaContext.
        end.
    end.
    else do:
        /* maximum number of bytes to store in a RAW field */
        if <M-33 DataServerActive  () in Progress>
        then viMaxLength = 26000.
        else viMaxLength = 31900.

        if iiOldInstanceId <> 0
        then do:
            vhDraftDataQuery:get-first(exclusive-lock, no-wait).
            if vhDraftDataBuffer:available and vhDraftDataBuffer:locked
            then do:
                vhDraftDataQuery:query-close().
                assign oiReturnStatus = -3.
                return.
            end.
        end.
    
        if iiOldInstanceId <> 0
        and vhDraftDataBuffer:available
        then assign viContextSeq = vhDraftDataBuffer::DraftInstanceSeq.
        else vhDraftDataBuffer:buffer-create().
    
        assign vhDraftDataBuffer::DraftInstance_ID = iiInstanceId
               vhDraftDataBuffer::DraftInstanceSeq = viContextSeq.

        CREATE QUERY vhQuery in widget-pool "non-persistent".
        CREATE tRaw. /* Just need one dummy row to store RAW field in by its handle. */
        vhContext = BUFFER tRaw:BUFFER-FIELD("taContext":U):HANDLE.
        
        SET-SIZE(vmContext) = viMaxLength.
        DO viBuffer = 1 TO ihInstanceData:NUM-BUFFERS:
        
            vhBuffer = ihInstanceData:GET-BUFFER-HANDLE(viBuffer).
            vhQuery:SET-BUFFERS(vhBuffer).
            vhQuery:QUERY-PREPARE("FOR EACH ":U + vhBuffer:NAME).
            vhQuery:QUERY-OPEN().
            vhQuery:GET-FIRST().
        
            DO WHILE NOT vhQuery:QUERY-OFF-END:
        
                vhBuffer:RAW-TRANSFER(TRUE, vhContext).
                viRawLength = LENGTH(tRaw.taContext, "RAW":U).
                IF viContextPos + viRawLength + 8 > viMaxLength THEN
                DO:
                    /* The data won't fit in a single BLOB, so create another row. */
                    PUT-SHORT(vmContext, viContextPos) = 0. /* Signal end of this row. */
                    viContextPos = viContextPos + 2.
                    vaContext = get-bytes(vmContext,1,viContextPos).
                    vhDraftDataBuffer::DraftInstanceData = vaContext.
                    if iiOldInstanceId <> 0
                    and vhDraftDataQuery:query-off-end = no
                    then vhDraftDataQuery:get-next(exclusive-lock).
                    if iiOldInstanceId = 0
                    or vhDraftDataQuery:query-off-end = yes
                    then do:
                        viContextSeq = viContextSeq + 1.
                        vhDraftDataBuffer:buffer-create().
                        assign vhDraftDataBuffer::DraftInstance_ID = iiInstanceId
                               vhDraftDataBuffer::DraftInstanceSeq = viContextSeq.
                    end.
                    else assign viContextSeq = vhDraftDataBuffer::DraftInstanceSeq.
                    viContextPos = 1.
                END.
                PUT-SHORT(vmContext, viContextPos) = viBuffer. 
                viContextPos = viContextPos + 2.    /* Move past the table number. */
                PUT-LONG(vmContext, viContextPos) = viRawLength.
                viContextPos = viContextPos + 4.   /* Move past the buffer length. */
                PUT-BYTES(vmContext, viContextPos) = tRaw.taContext.
                viContextPos = viContextPos + viRawLength.
                vhQuery:GET-NEXT().
            END.
        
            vhQuery:QUERY-CLOSE().
        
            IF viBuffer = ihInstanceData:NUM-BUFFERS
            THEN DO:
                PUT-SHORT(vmContext, viContextPos) = 0.  /* Mark the end of the data. */
                viContextPos = viContextPos + 2.
            END.
        END.
        vaContext = get-bytes(vmContext,1,viContextPos).
        vhDraftDataBuffer::DraftInstanceData = vaContext.
    end.
    
    if iiOldInstanceId <> 0
    then do while not vhDraftDataQuery:query-off-end:
        vhDraftDataQuery:get-next(exclusive-lock).
        if vhDraftDataQuery:query-off-end then leave.
        vhDraftDataBuffer:buffer-delete().
    end.

    if vcStateDirectory = ""
    then do:
        <M-1 run WriteDirect
           (input  'fcInstance':U (icTableName), 
            input  'for each fcInstance where fcInstance.Instance_ID = ':U + string(iiInstanceId) (icPrepare), 
            input  '' (icFieldList), 
            input  '' (icFieldListDataTypes), 
            input  '' (icAbsolute), 
            input  '' (icIncremental), 
            input  ihClass (ihClass), 
            input  icCreatedBy (icUserLogin), 
            output viFcReturnSuper (oiReturnStatus)) in Progress>
    end.
    else if iiTransactionId = iiInstanceId
    then os-delete value(vcStateDirectory + "/transaction"       + string(iiInstanceId) + ".lob").
    else os-delete value(vcStateDirectory + "/" + lc(icBusiness) + string(iiInstanceId) + ".lob").
end.

finally:
    if vhDraftQuery <> ?
    then vhDraftQuery:query-close().
    if vhDraftDataBuffer <> ?
    then vhDraftDataBuffer:buffer-release().
    if vhDraftDataQuery <> ?
    then vhDraftDataQuery:query-close().
    if available tRaw
    then delete tRaw.
    if vhQuery <> ?
    then delete object vhQuery.
    SET-SIZE(vmContext) = 0.
end finally.