Description
Write the data to the database.
This takes care of the transfer of data from the class temp-tables to the real database tables.
It also takes care of the optimistic locking checkings (using t_i<table>).
Parameters
tDynRel | input | temp-table | Description of the data to write. |
ihClass | input | handle | Handle to the class that is using the persistence layer. In most of the cases, this handle will be available in the preprocessor {&TARGETPROCEDURE}. |
ihRowidConvert | input | handle | Handle to the temp-table tFcRowidConvert. |
icUserLogin | input | character | |
oiReturnStatus | output | integer | |
Internal usage
unused
program code (program1/other.p)
assign oiReturnStatus = -98
vhOldRowid = ihRowidConvert:buffer-field("tcFcOldRowid":U)
vhNewRowid = ihRowidConvert:buffer-field("tcFcNewRowid":U).
&if defined(DEBUGSQL) > 0 &then
run SqlDebugWrite in {&TARGETPROCEDURE} ("* ":U + program-name(1), 1).
&endif
/* Clean up the garbage */
for each tBufferFields where
not valid-handle(tBufferFields.thTempBuffer):
delete tBufferFields.
end.
/* copy tDynRel into method data items that cannot be changed by other
instances of this method (as started by ref.integrity programs. */
for each tDynRel on error undo, throw:
assign viDynrelNum = viDynrelNum + 1
vcDynrelTo[viDynrelNum] = tDynRel.tcFcTo
vhDynrelBuffer[viDynrelNum] = tDynRel.thFcBuffer
vhDynrelIbuffer[viDynrelNum] = tDynRel.thFcIBuffer.
end.
do viDynrelCount = 1 to viDynrelNum:
/* ================================================================= */
/* Create recordsets for original and changed data */
/* ================================================================= */
<M-1 run UpdateBufferInfo (input vhDynrelBuffer[viDynrelCount] (ihDestinationBuffer),
input vhDynrelIBuffer[viDynrelCount] (ihIDestinationBuffer),
output viFcReturnSuper (oiReturnStatus)) in other>
if viFcReturnSuper <> 0
then do:
assign oiReturnStatus = viFcReturnSuper.
return.
end.
assign vhPdatabaseInst = ihClass.
<M-16 run GetKeyFields (input-output vcDynrelTo[viDynrelCount] (bcTableName),
output vcPkey (ocPrimaryKey),
output vcDummy (ocAlternateKey),
output vcDummy (ocObjectID),
output vcDummy (ocObjectStatus),
output viFcReturnSuper (oiReturnStatus)) in database>
run SqlBufCreate in {&TARGETPROCEDURE}
(input vcDynrelTo[viDynrelCount],
output viBufferId,
output viFcReturnSuper).
if viFcReturnSuper <> 0
then do:
assign oiReturnStatus = viFcReturnSuper.
return.
end.
for each tBufferFields where
tBufferFields.thTempBuffer = vhDynrelBuffer[viDynrelCount] and
tBufferFields.tcFieldName <> "tc_ParentRowid":U and
tBufferFields.tcFieldName <> "tc_Rowid":U and
tBufferFields.tcFieldName <> "tc_Status":U:
run SqlBufAddField in {&TARGETPROCEDURE}
(input viBufferId,
input tBufferFields.tcFieldName,
input tBufferFields.thDestinationField:data-type,
input (if can-do(vcPKey, tBufferFields.tcFieldName) then 1 else 0),
output viFieldId,
output viFcReturnSuper).
if viFcReturnSuper <> 0
then do:
assign oiReturnStatus = viFcReturnSuper.
return.
end.
end.
/* ================================================================= */
/* Fill recordset with changed data. */
/* ================================================================= */
create query vhCQuery.
vhCQuery:set-buffers(vhDynrelBuffer[viDynrelCount]).
create query vhOQuery.
vhOQuery:set-buffers(vhDynrelIbuffer[viDynrelCount]).
vhCQuery:query-prepare
("for each ":U + vhDynrelBuffer[viDynrelCount]:name +
" where ":U + vhDynrelBuffer[viDynrelCount]:name + ".tc_status <> ''":U).
vhCQuery:query-open().
vhCQuery:get-first().
assign vhStatusField = vhDynrelBuffer[viDynrelCount]:buffer-field("tc_Status":U)
vhRowidField = vhDynrelBuffer[viDynrelCount]:buffer-field("tc_Rowid":U)
vhRefInt = ?.
do while not vhCQuery:query-off-end :
vhOQuery:query-prepare(
"for each ":U + vhDynrelIbuffer[viDynrelCount]:name +
" where tc_Rowid = '":U + vhRowidField:buffer-value + "'":U).
vhOQuery:query-open().
vhOQuery:get-first().
if vhOQuery:query-off-end
then do:
vhOQuery:query-close().
vhCQuery:get-next().
next.
end.
if vhStatusField:buffer-value = "D":U
then do:
if vhRefInt = ?
then run value ("ref_int/dc_":U + vcDynrelTo[viDynrelCount] + ".p":U)
persistent set vhRefInt.
run gipr_RefInt in vhRefInt
(input vhDynrelBuffer[viDynrelCount],
input ihClass,
input {&TARGETPROCEDURE},
input icUserLogin,
output viFcReturnSuper).
if viFcReturnSuper < 0
then do:
assign oiReturnStatus = viFcReturnSuper.
if vhRefInt <> ?
then do:
delete procedure vhRefInt.
assign vhRefInt = ?.
end.
vhOQuery:query-close().
delete object vhOQuery.
vhCQuery:query-close().
delete object vhCQuery.
run SqlBufDestroy in {&TARGETPROCEDURE}
(input viBufferId,
output viFcReturnSuper).
return.
end.
end.
/* set UPDATED values */
assign viFieldId = 0.
for each tBufferFields where
tBufferFields.thTempBuffer = vhDynrelBuffer[viDynrelCount] and
tBufferFields.tcFieldName <> "tc_ParentRowid":U and
tBufferFields.tcFieldName <> "tc_Rowid":U and
tBufferFields.tcFieldName <> "tc_Status":U :
if tBufferFields.thDestinationField:buffer-value = ?
then run SqlFldSetNull in {&TARGETPROCEDURE}
(input viBufferId,
input viFieldId,
input 1,
output viLocalReturn).
else if tBufferFields.thDestinationField:data-type = "CHARACTER":U
or tBufferFields.thDestinationField:data-type = "DECIMAL":U
then run SqlFldSetString in {&TARGETPROCEDURE}
(input viBufferId,
input viFieldId,
input 1,
input string (tBufferFields.thDestinationField:buffer-value),
output viLocalReturn).
else run SqlFldSetInteger in {&TARGETPROCEDURE}
(input viBufferId,
input viFieldId,
input 1,
input integer(tBufferFields.thDestinationField:buffer-value),
output viLocalReturn).
if viLocalReturn <> 0 then leave.
assign viFieldId = viFieldId + 1.
end.
if viLocalReturn <> 0 then leave.
/* set ORIGINAL values */
assign viFieldId = 0.
for each tBufferFields where
tBufferFields.thTempBuffer = vhDynrelBuffer[viDynrelCount] and
tBufferFields.tcFieldName <> "tc_ParentRowid":U and
tBufferFields.tcFieldName <> "tc_Rowid":U and
tBufferFields.tcFieldName <> "tc_Status":U :
if tBufferFields.thIDestinationField:buffer-value = ?
then run SqlFldSetNull in {&TARGETPROCEDURE}
(input viBufferId,
input viFieldId,
input 0,
output viLocalReturn).
else if tBufferFields.thDestinationField:data-type = "CHARACTER":U
or tBufferFields.thDestinationField:data-type = "DECIMAL":U
then run SqlFldSetString in {&TARGETPROCEDURE}
(input viBufferId,
input viFieldId,
input 0,
input string (tBufferFields.thIDestinationField:buffer-value),
output viLocalReturn).
else run SqlFldSetInteger in {&TARGETPROCEDURE}
(input viBufferId,
input viFieldId,
input 0,
input integer(tBufferFields.thIDestinationField:buffer-value),
output viLocalReturn).
if viLocalReturn <> 0 then leave.
assign viFieldId = viFieldId + 1.
end.
if viLocalReturn <> 0 then leave.
vcRowid = vhRowidField:buffer-value.
run SqlBufWriteData in {&TARGETPROCEDURE}
(input viBufferId,
input vhStatusField:buffer-value,
input vcRowid,
output viLocalReturn).
if viLocalReturn = -2
then do:
run SqlGetError in {&TARGETPROCEDURE} (output viErrAddr, output viErrCode).
if viErrAddr > 0
then assign vcOptLock = <M-14 getString (input viErrAddr (iiAddr)) in other>.
end.
if viLocalReturn <> 0 then leave.
run SqlBufGetRowid in {&TARGETPROCEDURE}
(input viBufferId,
output viCnt,
output viLocalReturn).
if viLocalReturn <> 0 then leave.
ihRowidConvert:buffer-create().
assign vhOldRowid:buffer-value = vhRowidField:buffer-value
vhNewRowid:buffer-value = string(viCnt).
ihRowidConvert:buffer-release().
vhOQuery:query-close().
vhCQuery:get-next().
end.
vhOQuery:query-close().
delete widget vhOQuery.
vhCQuery:query-close().
delete widget vhCQuery.
if vhRefInt <> ?
then do:
delete procedure vhRefInt.
assign vhRefInt = ?.
end.
run SqlBufDestroy in {&TARGETPROCEDURE}
(input viBufferId,
output viFcReturnSuper).
if viLocalReturn < 0
then do:
assign viCnt = 0.
if vcOptLock = ""
then do:
<M-10 run SqlErrorMessage (input ihClass (ihClass),
output viFcReturnSuper (oiReturnStatus)) in other>
end.
else do while true:
assign viCnt = viCnt + 1.
if viCnt > num-entries(vcOptLock,chr(2))
then leave.
assign viNum = integer(entry(viCnt,vcOptLock,chr(2)))
vhPDatabaseInst = ihClass.
if viNum = 1
then do:
<M-7 run SetMessage
(input #T-1'This field was changed from $1 to $2 by another user.':255(82)T-1# (icMessage),
input entry(viCnt + 2,vcOptLock,chr(2)) + chr(2) + entry(viCnt + 3,vcOptLock,chr(2)) (icArguments),
input 't':U + vcDynrelTo[viDynrelCount] + '.':U + entry(viCnt + 1,vcOptLock,chr(2)) (icFieldName),
input entry(viCnt + 4,vcOptLock,chr(2)) (icFieldValue),
input 'D':U (icType),
input integer(entry(viCnt + 6,vcOptLock,chr(2))) (iiSeverity),
input entry(viCnt + 5,vcOptLock,chr(2)) (icRowid),
input 'BLF-367':U (icFcMsgNumber),
input '' (icFcExplanation),
input '' (icFcIdentification),
input '' (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in database>
assign viCnt = viCnt + 6.
end.
else do:
if viNum = 4
then vcError = #T-17'A detail line you tried to create was already created by another user.':255(85)T-17#.
else if viNum = 3
then vcError = #T-18'A detail line you tried to delete was already deleted by another user.':255(84)T-18#.
else vcError = #T-19'A detail line you tried to change was deleted by another user.':255(83)T-19#.
<M-8 run SetMessage
(input vcError (icMessage),
input '' (icArguments),
input 't':U + vcDynrelTo[viDynrelCount] (icFieldName),
input '' (icFieldValue),
input 'D':U (icType),
input 2 (iiSeverity),
input entry(viCnt + 1,vcOptLock,chr(2)) (icRowid),
input 'BLF-368':U (icFcMsgNumber),
input '' (icFcExplanation),
input '' (icFcIdentification),
input '' (icFcContext),
output viFcReturnSuper (oiReturnStatus)) in database>
assign viCnt = viCnt + 1.
end.
end.
return.
end.
end.
assign oiReturnStatus = viLocalReturn.