Consultor Eletrônico



Kbase P20478: RAW TRANSFER- solution to save data in RAW FIELDS and be able to restore it even if the original DB
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   28/09/2009
Status: Unverified

GOAL:

RAW TRANSFER- solution to save data in RAW FIELDS and be able to restore it even if the original DB structure is changed

FACT(s) (Environment):

OpenEdge Category: Language (4GL/ABL)
Progress 9.x
OpenEdge 10.x
All Supported Operating Systems

FIX:

The idea is to store also the original structure of the database.
The below example show how to store into a temp table a full database record
and also its structure and also how to create a new temp-table with the saved structure and restore there the saved record.

/*
Desc.: RAW TRANSFER- solution to save data in RAW FIELDS and be able to restore it even if the original DB structure is changed
Created: Mihai Cotar
*/

&SCOPED-DEFINE SeparatorRec '#'
&SCOPED-DEFINE SeparatorField '@'
DEF VAR hField AS HANDLE NO-UNDO.
DEF VAR hbtt1 AS HANDLE NO-UNDO.
DEF VAR hbttRaw AS HANDLE NO-UNDO.
DEF VAR httRaw AS HANDLE NO-UNDO.
DEF VAR hb1 AS HANDLE NO-UNDO.
DEF VAR htt1 AS HANDLE NO-UNDO.
DEF VAR hQuery AS HANDLE NO-UNDO.
DEF VAR gctable AS CHAR NO-UNDO INIT "customer".
DEF VAR gcStruct AS CHAR NO-UNDO.
DEF VAR gcTempStruct AS CHAR NO-UNDO.

/*I will use the following TEMP-TABLE to store the records in raw fields*/
DEF TEMP-TABLE ttRaw
FIELD RawField AS RAW
FIELD cStruct AS CHAR.

/* Check if there is any value(gcTable) table in current database */
FIND FIRST _file WHERE _file._FILE-NAME = gcTable NO-ERROR.
IF error-status:ERROR THEN DO:
MESSAGE "Table " gcTable " does't exist in the current database" VIEW-AS ALERT-BOX.
END.

/* Build a dynamic temp-table from gcTable and save the structure in a char variable*/

/* Add fields */
FOR EACH _field OF _file:
/*htt1:ADD-LIKE-FIELD(_field._field-name,string(_file._file-name + '.' + _field._field-name)).*/
gcStruct = gcStruct + (IF gcStruct <> '' THEN {&SeparatorRec} ELSE '') +
_field._field-name
+ {&SeparatorField} + _field._Data-Type
+ {&SeparatorField} + string(_field._Extent)
+ {&SeparatorField} + _field._Format
+ {&SeparatorField} + _field._Initial
+ {&SeparatorField} + (IF _field._Label <> ? THEN _field._Label ELSE '')
+ {&SeparatorField} + (IF _field._Col-Label <> ? THEN _field._Col-Label ELSE '')
.

END.
RUN BuildTT(INPUT-OUTPUT htt1, "MyTT", INPUT gcStruct).


/* get the buffer handle for the temp-table */
hbtt1 = htt1:DEFAULT-BUFFER-HANDLE.
hbtt1:BUFFER-CREATE.

/* Load some data into the temp-table */
IF valid-handle(hQuery) THEN DELETE OBJECT hQuery.
IF valid-handle(hb1) THEN DELETE OBJECT hb1.
CREATE BUFFER hb1 FOR TABLE gcTable.
CREATE QUERY hQuery.
hQuery:SET-BUFFERS(hb1).
hQuery:QUERY-PREPARE(substitute('FOR each &1 exclusive-lock', gcTable)).
hQuery:QUERY-OPEN.

DO TRANSACTION:
hQuery:GET-FIRST.

/* load the current database record to temp-table */
hbtt1:BUFFER-COPY(hb1).

/* delete the original field from the database. Later I intend to restore it from the TTRaw table*/
hb1:DISABLE-LOAD-TRIGGERS(NO).
hb1:BUFFER-DELETE.
END.

/* save this record as raw data in the ttRaw temp table*/
IF valid-handle(hQuery) THEN DELETE OBJECT hQuery.
IF valid-handle(hb1) THEN DELETE OBJECT hb1.
CREATE QUERY hQuery.
CREATE BUFFER hb1 FOR TABLE hbtt1.
hQuery:SET-BUFFERS(hb1).
hQuery:QUERY-PREPARE('FOR each MyTT').
hQuery:QUERY-OPEN.
hQuery:GET-FIRST.

httRaw = TEMP-TABLE ttRaw:HANDLE.
CREATE B.UFFER hbttRaw FOR TABLE "ttRaw".
hbttRaw:BUFFER-CREATE.
hField = hbttRaw:BUFFER-FIELD("cStruct").
hField:BUFFER-VALUE = gcStruct.
hField = hbttRaw:BUFFER-FIELD("RawField").
hb1:RAW-TRANSFER(YES, hField).

/* #################################################################################################################
Now our record TTRaw.RawField, and a description of it it is in TTRaw.cStruct
We want now to build a temp table based on information stored in TTRaw.cStruct, extract
from ttRaw.RawField to the new created temp-table and display the data
*/

DEF VAR hNewTT AS HANDLE NO-UNDO.
DEF VAR hbNewTT AS HANDLE NO-UNDO.
DEF VAR i AS INT NO-UNDO.

hField = hbttRaw:BUFFER-FIELD("cStruct").
RUN BuildTT(INPUT-OUTPUT hNewTT, "MyNewTT", INPUT hField:BUFFER-VALUE).
hbNewTT = hNewTT:DEFAULT-BUFFER-HANDLE.
hField = hbttRaw:BUFFER-FIELD("RawField").
hbNewTT:RAW-TRANSFER(NO, hField).

/*DISPLAY all the fields of the record created MyNewTT*/
DO i = 1 TO hbNewTT:NUM-FIELDS:
hField = hbNewTT:BUFFER-FIELD(i).
MESSAGE hField:BUFFER-VALUE.
END.

/* Now I intend to restore this record in the database table gcTable*/

IF valid-handle(hb1) THEN DELETE OBJECT hb1.
CREATE BUFFER hb1 FOR TABLE gcTable.
DO transaction:
hb1:BUFFER-CREATE. /* Create a new record in database table */
hb1:BUFFER-COPY(hbNewTT).
END.

/* ################################################################################################################# */

PROCEDURE BuildTT:
/*

*/
DEF INPUT-OUTPUT PARAM iphtt AS HANDLE NO-UNDO.
DEF INPUT PARAM ipcTTName AS CHAR NO-UNDO.
DEF INPUT PARAM ipcFieldStruct AS CHAR NO-UNDO.


DEF VAR i AS INT NO-UNDO.
DEF VAR j AS INT NO-UNDO.
DEF VAR cTab AS CHAR NO-UNDO EXTENT 7.


CREATE TEMP-TABLE iphtt.
DO i = 1 TO NUM-ENTRIES(ipcFieldStruct, {&SeparatorRec}):
DO j = 1 TO 7:
cTab[j] = ENTRY(j, ENTRY(i, ipcFieldStruct, {&SeparatorRec}), {&SeparatorField}).

END.

iphtt:ADD-NEW-FIELD(
cTab[1], /* field name */
cTab[2], /* data type */
int(cTab[3]), /* extent */
cTab[4], /* format */
cTab[5], /* init value */
cTab[6], /* label */
cTab[7] /* column label */
).
END.

/* Prepare the temp-table */
iphtt:TEMP-TABLE-PREPARE("MyTT").

END PROCEDURE..