project BLF > class Database Component > method MaintainByDatasetWithOutput

Description

This method uses contents of the input class temp-tables (prefix t_s) to perform the action specified in icAction. (if icAction is empty, it gets the default value of "SAVE")
SAVE : validate contents and write to database if correct
SAVEDRAFT : validate contents, write to database if correct, copy the data to the class tables (prefix t_o) and create draft instance if incorrect
DRAFT : copy data to the class tables (prefix t_o) and create draft instance
VALIDATE : only validate data

It returns the object dataset if required (if ilProvideOutput = true).


Parameters


icActioninputcharacterSAVE
SAVEDRAFT
DRAFT
VALIDATE
ilReturnDatasetinputlogicalIndication whether the logic should return the official dataset of the object that has just been created/modified.
ilPartialUpdateinputlogicalIndication whether the input dataset is a full object or only a partial one.
icPartialUpdateExceptionListinputcharacterComma separated list with fields that need to be skipped in the test logic for partial update.
Fields in the list are specified as t<table>.<field>.
opPrimaryKeyoutputlongchar
opRowidoutputlongchar
oiDraftInstanceoutputinteger
ocPrimaryKeyNameoutputcharacterThe name of the field(s) in the primary key of the object. Normally this is the name of the object ID of the main table. (like creditor_ID)
ozObjectRepresentationoutputdataset-handleThe dataset containing the official representation of the object dataset. It should always be passed by-reference, meaning, the dataset handle should be created before the call.
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


BLF
method database.MaintainByDataset
method BUDCConfiguration.AdditionalUpdates
method BXmlDaemonProcessor.LoadXmlDocument
method RPCRequestService.ProcessDS


program code (program1/database.p)

if icAction = "" or icAction = ?
then assign icAction = {&DAEMONACTION-SAVE}.

if  icAction <> {&DAEMONACTION-SAVE}
and icAction <> {&DAEMONACTION-SAVESTORE}
and icAction <> {&DAEMONACTION-STORE}
and icAction <> {&DAEMONACTION-VALIDATE}
then do:
    <M-17 run SetMessage
          (input  'Invalid action ($1).':U (icMessage), 
           input  icAction (icArguments), 
           input  '' (icFieldName), 
           input  '' (icFieldValue), 
           input  'S':U (icType), 
           input  3 (iiSeverity), 
           input  '' (icRowid), 
           input  'BLF-215':U (icFcMsgNumber), 
           input  '' (icFcExplanation), 
           input  '' (icFcIdentification), 
           input  '' (icFcContext), 
           output viFcReturnSuper (oiReturnStatus)) in database>
    assign oiReturnStatus = -3.
    return.
end.

<M-18 run DataDescription
   (input  '' (icRowids), 
    input  '' (icPkey), 
    input  '' (icObjectIds), 
    input  no (ilAllTables), 
    output viFcReturnSuper (oiReturnStatus)) in database>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.

/* =================================================================== */
/* Saving drafts requires that input tables contain exactly one object */
/* =================================================================== */
if icAction = {&DAEMONACTION-SAVESTORE}
or icAction = {&DAEMONACTION-STORE}
then do:
    find first tFcDynRel where tFcDynRel.tcFcFrom = "" no-error.
    if available tFcDynRel
    then do:
        tFcDynRel.thFcSBuffer:find-unique ("where true") no-error.
        if not tFcDynRel.thFcSBuffer:available
        then do:
            <M-20 run SetMessage
               (input  (if tFcDynRel.thFcSBuffer:ambiguous then 'Input dataset has more than one object.':U else 'Input dataset is empty.':U) (icMessage), 
                input  '' (icArguments), 
                input  '' (icFieldName), 
                input  '' (icFieldValue), 
                input  'S':U (icType), 
                input  3 (iiSeverity), 
                input  '' (icRowid), 
                input  'BLF-217':U (icFcMsgNumber), 
                input  '' (icFcExplanation), 
                input  '' (icFcIdentification), 
                input  '' (icFcContext), 
                output viFcReturnSuper (oiReturnStatus)) in database>
            assign oiReturnStatus = -3.
            return.
        end.
    end.
end.

<M-90 run ClearData  (output viFcReturnSuper (oiReturnStatus)) in database>

if viFcReturnSuper <> 0
then assign oiReturnStatus = viFcReturnSuper.

if viFcReturnSuper < 0
then return.

/* ================================================================= */
/* Load database records (for update)                                */
/* ================================================================= */
vlInitializeTranslations = no.

<M-13 run DataLoadByInput
   (output opPrimaryKey (opPrimeKey), 
    output viFcReturnSuper (oiReturnStatus)) in database>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.

/* ================ */
/* Allow defaulting */
/* ================ */
<M-91 run MaintainByDatasetDefaulting  (output viFcReturnSuper (oiReturnStatus)) in database>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.

<I-27 {bFcRun
     &PROCEDURE            = "gipr_CompleteSTables"}>

if vcActivityCode = "Delete":U
then do:
    /* ================================================================= */
    /* On delete activity ignore input data and set loaded records to    */
    /* delete.                                                           */
    /* ================================================================= */
    <M-22 run DataDelete  (output viFcReturnSuper (oiReturnStatus)) in database>
    if viFcReturnSuper <> 0
    then oiReturnStatus = viFcReturnSuper.
    if viFcReturnSuper < 0
    then return.

    /* Before data is deleted, we can lookup rowid */
    find first tFcDynRel where tFcDynRel.tcFcFrom = "" no-error.
    if available tFcDynRel
    then do:
        create query vhRowidQuery in widget-pool "non-persistent".
        vhRowidQuery:forward-only = yes.
        vhRowidQuery:set-buffers(tFcDynRel.thFcBuffer).
        vhRowidQuery:query-prepare("for each t_o":U + tFcDynRel.tcFcTo).
        vhRowidQuery:query-open().
        vhRowidQuery:get-first().

        do while not vhRowidQuery:query-off-end:
            if opRowid <> ""
            then assign opRowid = opRowid + ",".

            assign opRowid = opRowid + tFcDynRel.thFcBuffer::tc_Rowid.
            vhRowidQuery:get-next().
        end.

        vhRowidQuery:query-close().
        delete object vhRowidQuery.
    end.
end.
else do:
    /* ================================================================= */
    /* When in partial update mode, make sure the S buffers are updated  */
    /* correctly.                                                        */
    /* ================================================================= */
    if ilPartialUpdate
    then do:
        <M-26 run CorrectionForPartialUpdate
           (input  icPartialUpdateExceptionList (icPartialUpdateExceptionList), 
            output viFcReturnSuper (oiReturnStatus)) in database>
        if viFcReturnSuper <> 0
        then oiReturnStatus = viFcReturnSuper.
        if viFcReturnSuper < 0
        then return.
    end.

    /* ================================================================= */
    /* On all other activities, validate contents (and copy to t_o***)   */
    /* ================================================================= */
    if icAction <> {&DAEMONACTION-STORE}
    then do:
        <M-14 run ValidateUI  (output viFcReturnSuper (oiReturnStatus)) in database>
        if viFcReturnSuper <> 0
        then oiReturnStatus = viFcReturnSuper.
    end.

    if icAction = {&DAEMONACTION-STORE}
    or (icAction = {&DAEMONACTION-SAVESTORE} and oiReturnStatus < 0)
    then do:
        /* copy input tables without validation so a draft instance can be made */
        <I-23 {bFcRun
            &PARAMETERS = "output viFcReturnSuper"
            &PROCEDURE  = "gipr_SetTables"}>
    end.

    if oiReturnStatus >= 0
    and (icAction = {&DAEMONACTION-SAVE} or
         icAction = {&DAEMONACTION-SAVESTORE})
    then do:
        <M-15 run AdditionalUpdates (output viFcReturnSuper (oiReturnStatus)) in database>
        if viFcReturnSuper <> 0
        then oiReturnStatus = viFcReturnSuper.
    end.
end.

/* ================================================================= */
/* Database update                                                   */
/* ================================================================= */
if oiReturnStatus >= 0
and (icAction = {&DAEMONACTION-SAVE} or
     icAction = {&DAEMONACTION-SAVESTORE})
then do:
    if ilReturnDataset
    then do:
        create dataset vhTempDS in widget-pool "non-persistent".
        <M-24 run GetXmlRepresentationDataset
           (input  '' (icObjectRowId), 
            input  false (ilHeaderOnly), 
            input  0 (iiPriority), 
            output vhTempDS by-reference (ozXMLDataset), 
            output viFcReturnSuper (oiReturnStatus)) in database>
        if viFcReturnSuper <> 0
        then oiReturnStatus = viFcReturnSuper.

        if viFcReturnSuper >= 0
        then do:
            /* Make a deep-copy of the dataset to prevent any further updates in the class tables from being reflected
               into the published dataset.
            */
            ozObjectRepresentation:copy-dataset (vhTempDS,true,false,false,"",false,"").

            assign vcTableName = "".

            <M-25 run GetKeyFields
               (input-output vcTableName (bcTableName), 
                output ocPrimaryKeyName (ocPrimaryKey), 
                output vcDummy (ocAlternateKey), 
                output vcDummy (ocObjectID), 
                output vcDummy (ocObjectStatus), 
                output viFcReturnSuper (oiReturnStatus)) in database>
            if viFcReturnSuper <> 0
            then assign oiReturnStatus = viFcReturnSuper.
        end.
        
        delete object vhTempDS.
    end.

    if oiReturnStatus >= 0
    then do:
        <M-16 run DataSave (output viFcReturnSuper (oiReturnStatus)) in database>
        if viFcReturnSuper <> 0
        then oiReturnStatus = viFcReturnSuper.
    end.
    
    if vcActivityCode <> "Delete":U
    and oiReturnStatus >= 0
    then do:
        /* After data has been saved, we can lookup rowid */
        find first tFcDynRel where tFcDynRel.tcFcFrom = "" no-error.
        if available tFcDynRel
        then do:
            create query vhRowidQuery in widget-pool "non-persistent".
            vhRowidQuery:forward-only = yes.
            vhRowidQuery:set-buffers(tFcDynRel.thFcBuffer).
            vhRowidQuery:query-prepare("for each t_o":U + tFcDynRel.tcFcTo).
            vhRowidQuery:query-open().
            vhRowidQuery:get-first().

            do while not vhRowidQuery:query-off-end:
                if opRowid <> ""
                then assign opRowid = opRowid + ",".

                assign opRowid = opRowid + tFcDynRel.thFcBuffer::tc_Rowid.
                vhRowidQuery:get-next().
            end.

            vhRowidQuery:query-close().
            delete object vhRowidQuery.
        end.
    end.
end.

/* ================================================================= */
/* Create draft instance                                             */
/* ================================================================= */
if icAction = {&DAEMONACTION-STORE}
or (icAction = {&DAEMONACTION-SAVESTORE} and oiReturnStatus < 0)
then do:
    assign oiDraftInstance = viFcCurrentInstanceId
           vcDummy         = substring(ocPrimaryKeyName,1,255,"CHARACTER").
    <M-21 run StoreState
       (input  vcFcComponentName + ' (':U + vcDummy + ')':U (icDescription), 
        input  '' (icUIClass), 
        output oiReturnStatus (oiReturnStatus)) in database>
end.