Description
Load instance data from the application database
PreCondition
This method is to be used by instance procedures only.
Parameters
ihClass | input | handle | |
iiInstanceID | input | integer | instance ID |
ihInstanceData | input | handle | dataset with instance data |
icClassName | input | character | |
oiDraftInstanceId | output | integer | |
oiReturnStatus | output | integer | Return 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.