1 &ANALYZE-SUSPEND _VERSION-NUMBER UIB_v8r12
3 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _DEFINITIONS Procedure
4 /*--------------------------------------------------------------------------
6 Purpose
: Replication Load process
15 ------------------------------------------------------------------------*/
17 DEF TEMP-TABLE LogEntry
LIKE ReplLog.
18 DEF TEMP-TABLE CollLog
NO-UNDO LIKE ReplCollisionlog.
19 DEF VAR load-program
AS CHAR NO-UNDO.
20 DEF VAR log-file-name
AS CHAR NO-UNDO.
21 DEF VAR last-repl-date
LIKE ReplLog.ReplDate
NO-UNDO INITIAL ?.
22 DEF VAR last-repl-time
LIKE ReplLog.ReplTime
NO-UNDO INITIAL ?.
24 DEF VAR file-list
AS CHAR NO-UNDO.
25 DEF VAR i
AS INT NO-UNDO.
26 DEF VAR file-name
AS CHAR NO-UNDO.
27 DEF VAR full-path
AS CHAR NO-UNDO.
28 DEF VAR file-type
AS CHAR NO-UNDO.
29 DEF VAR previous-file
AS CHAR NO-UNDO.
30 DEF VAR last-file-loaded
AS CHAR NO-UNDO.
32 DEF VAR load-directory
AS CHAR NO-UNDO.
33 load-directory
= "rplctn\dump\toload".
35 DEF TEMP-TABLE replication-list
36 FIELD file-name
AS CHAR
37 FIELD full-path
AS CHAR
38 FIELD file-type
AS CHAR
39 INDEX file-name
IS UNIQUE PRIMARY file-name
ASCENDING.
41 /* _UIB-CODE-BLOCK-END
*/
45 &ANALYZE-SUSPEND _UIB-PREPROCESSOR-BLOCK
47 /* ******************** Preprocessor Definitions
******************** */
49 &Scoped-define PROCEDURE-TYPE Procedure
53 /* _UIB-PREPROCESSOR-BLOCK-END
*/
57 /* ************************ Function Prototypes
********************** */
59 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION-FORWARD get-load-program Procedure
60 FUNCTION get-load-program
RETURNS CHARACTER
61 ( INPUT table-name
AS CHAR ) FORWARD.
63 /* _UIB-CODE-BLOCK-END
*/
67 /* *********************** Procedure Settings
************************ */
69 &ANALYZE-SUSPEND _PROCEDURE-SETTINGS
70 /* Settings for
THIS-PROCEDURE
74 Add Fields to
: Neither
75 Other Settings
: CODE-ONLY
COMPILE
77 &ANALYZE-RESUME _END-PROCEDURE-SETTINGS
79 /* ************************* Create Window
************************** */
81 &ANALYZE-SUSPEND _CREATE-WINDOW
82 /* DESIGN Window definition
(used by the UIB
)
83 CREATE WINDOW Procedure
ASSIGN
86 /* END WINDOW DEFINITION
*/
92 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _INCLUDED-LIB Procedure
93 /* ************************* Included-Libraries
*********************** */
95 {inc
/method
/m-txtrep.i
}
98 /* _UIB-CODE-BLOCK-END
*/
103 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _MAIN-BLOCK Procedure
106 /* *************************** Main Block
*************************** */
109 OS-CREATE-DIR "rplctn\dump".
110 OS-CREATE-DIR "rplctn\dump\log".
111 log-file-name
= "rplctn\dump\log\" +
112 STRING( YEAR( TODAY ), "9999" ) +
113 STRING( MONTH( TODAY ), "99" ) +
114 STRING( DAY( TODAY ), "99" ) + ".log".
116 INPUT FROM OS-DIR( load-directory
) .
119 CREATE replication-list
NO-ERROR.
120 IMPORT replication-list
NO-ERROR.
122 FOR EACH replication-list
:
123 IF replication-list.file-type
<> "F" OR TRIM(replication-list.full-path
) = "" THEN
124 DELETE replication-list.
129 OUTPUT TO VALUE( log-file-name
) KEEP-MESSAGES APPEND.
130 DO WHILE CAN-FIND( FIRST replication-list
):
131 FIND FIRST replication-list .
132 RUN load-log-file
( replication-list.full-path
).
134 IF ERROR-STATUS:ERROR THEN DO:
135 MESSAGE "Error processing replication file >>" + replication-list.full-path
+ "<<".
136 DELETE replication-list.
139 IF last-repl-date
<> ?
AND last-repl-time
<> ?
THEN DO TRANSACTION:
141 FIND OfficeSetting
OF Office
WHERE OfficeSetting.SetName
= "Last-Replicate-Data" EXCLUSIVE-LOCK NO-ERROR.
142 IF NOT AVAILABLE(OfficeSetting
) THEN DO:
143 CREATE OfficeSetting.
144 OfficeSetting.OfficeCode
= Office.OfficeCode.
145 OfficeSetting.SetName
= "Last-Replicate-Data".
147 OfficeSetting.SetValue
= STRING(last-repl-time
,"HH:MM") + " on " + STRING(last-repl-date
,"99/99/9999").
149 FIND OfficeSetting
OF Office
WHERE OfficeSetting.SetName
= "Last-Replicate-Run" EXCLUSIVE-LOCK NO-ERROR.
150 IF NOT AVAILABLE(OfficeSetting
) THEN DO:
151 CREATE OfficeSetting.
152 OfficeSetting.OfficeCode
= Office.OfficeCode.
153 OfficeSetting.SetName
= "Last-Replicate-Run".
155 OfficeSetting.SetValue
= STRING(TIME,"HH:MM") + " on " + STRING(TODAY,"99/99/9999").
162 /* _UIB-CODE-BLOCK-END
*/
166 /* ********************** Internal Procedures
*********************** */
168 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE create-collisions Procedure
169 PROCEDURE create-collisions
:
170 /*------------------------------------------------------------------------------
171 Purpose
: Create collision log entries for all entries in
172 the given transaction ID
175 ------------------------------------------------------------------------------*/
177 DEF INPUT PARAMETER transact-id
LIKE ReplLog.TransActID
NO-UNDO.
178 DEF INPUT PARAMETER collision-list
AS CHAR NO-UNDO.
179 DEF INPUT PARAMETER log-file
AS CHAR NO-UNDO.
181 FOR EACH LogEntry
WHERE LogEntry.TransactID
= transact-id
:
183 BUFFER-COPY LogEntry
TO CollLog
185 CollLog.Collided
= LOOKUP( STRING( LogEntry.ReplID
), collision-list
) <> 0
186 CollLog.LoadFile
= log-file
187 CollLog.CollisionID
= NEXT-VALUE( CollisionID
).
192 /* _UIB-CODE-BLOCK-END
*/
196 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE load-log-file Procedure
197 PROCEDURE load-log-file
:
198 /*------------------------------------------------------------------------------
199 Purpose
: Load in a replication change log from file
201 Parameters
: log-file
- The name of the file to load in
203 Notes
: Each entry in the replication log is ordered by
204 transaction id and a sequence number. If any collision
205 occurs for a particular transaction id
, no changes
206 within that particular transaction will be applied.
207 ------------------------------------------------------------------------------*/
208 DEF INPUT PARAMETER log-file
AS CHAR NO-UNDO.
210 DEF VAR transact-id
LIKE ReplLog.TransactId
INIT ?
NO-UNDO.
211 DEF VAR need-to-rollback
AS LOGI
NO-UNDO.
212 DEF VAR report-collisions
AS LOGI
NO-UNDO.
213 DEF VAR collision-list
AS CHAR NO-UNDO.
214 DEF VAR repl-source
AS CHAR NO-UNDO.
216 DEF VAR first-line
AS CHAR NO-UNDO.
217 DEF VAR current-rowid
AS ROWID NO-UNDO.
218 DEF VAR current-pos
AS INT NO-UNDO.
220 current-rowid
= ROWID(replication-list
).
222 /* Load in the log entries
*/
223 /* NOTE
: Must maintain the on error clause
! */
224 FOR EACH LogEntry
: DELETE LogEntry.
END.
225 MESSAGE "Loading replication from file:" log-file.
226 INPUT FROM VALUE( log-file
).
227 IMPORT UNFORMATTED first-line.
228 current-pos
= SEEK( INPUT ).
230 IF SUBSTRING( first-line
, 1 , 12) = ">>>Previous=" THEN DO:
231 /* ensure that the
"previous" file has been loaded
*/
232 previous-file
= SUBSTRING( first-line
, 13).
233 repl-source
= SUBSTRING( previous-file
, 1, 4).
234 FIND replication-list
WHERE replication-list.file-name
= previous-file
NO-LOCK NO-ERROR.
235 IF AVAILABLE(replication-list
) THEN DO:
236 MESSAGE "Previous file" previous-file
"not loaded, but now available.".
237 /* not processed yet
, but it is in our list so we'll do it before this one
*/
238 RUN load-log-file
( replication-list.full-path
).
240 /* re-create where we were.
*/
241 FIND replication-list
WHERE ROWID(replication-list
) = current-rowid.
244 FIND replication-list
WHERE ROWID(replication-list
) = current-rowid.
245 FIND RP
WHERE RP.UserName
= "Replication-" + repl-source
246 AND RP.ReportID
= "Last Replication File" NO-LOCK NO-ERROR.
247 IF AVAILABLE(RP
) THEN DO:
248 last-file-loaded
= RP.Char1.
249 IF last-file-loaded
<> previous-file
THEN DO:
250 MESSAGE "Previous file" previous-file
"was not loaded!!!".
251 RUN sequence-error
( previous-file
).
252 /* which quits the whole thing
! */
255 MESSAGE "Previous file" previous-file
"was loaded OK.".
258 MESSAGE "No record of loading previous file from" repl-source
"which should have been '" + previous-file
+ "'".
264 INPUT FROM VALUE( log-file
).
265 SEEK INPUT TO current-pos.
266 REPEAT TRANSACTION ON ERROR UNDO, LEAVE:
275 need-to-rollback
= No.
276 report-collisions
= No.
278 RUN next-transact-id
( INPUT-OUTPUT transact-id
).
279 IF transact-id
= ?
THEN LEAVE iterate-transaction.
281 replication-transaction
:
284 FOR EACH LogEntry
WHERE LogEntry.TransActID
= transact-id
:
286 last-repl-date
= LogEntry.ReplDate.
287 last-repl-time
= LogEntry.ReplTime.
289 repl-source
= LogEntry.Office.
290 FIND FIRST ReplLoadRule
WHERE ReplLoadRule.SourceSystem
= LogEntry.OfficeCode
291 AND ReplLoadRule.TableToLoad
= LogEntry.TableToRepl
NO-LOCK NO-ERROR.
293 IF AVAILABLE ReplLoadRule
THEN DO:
294 IF INDEX( ReplLoadRule.Activity
, LogEntry.ReplEvent
) <> 0 THEN DO:
295 load-program
= get-load-program
( LogEntry.TableToRepl
).
296 RUN VALUE( load-program
) ( LogEntry.ReplBI
, LogEntry.ReplAI
, LogEntry.ReplEvent
).
297 IF RETURN-VALUE <> "" THEN DO:
298 add-to-list
( collision-list
, STRING( LogEntry.ReplID
) ).
299 need-to-rollback
= need-to-rollback
OR ReplLoadRule.CollisionDetect .
300 report-collisions
= Yes.
302 RUN log
( "(Trans: " + STRING( transact-id
)
303 + ", ID: " + STRING( LogEntry.ReplID
) + ") " + RETURN-VALUE
304 + " error: Source - " + LogEntry.OfficeCode
+ ", "
305 + "Table - " + LogEntry.TabletoRepl
+ ", "
306 + "Event - " + LogEntry.ReplEvent
).
311 RUN log
( "(Trans: " + STRING( transact-id
) + ", ID: " + STRING( LogEntry.ReplID
) + ") " +
312 "No load rule for: Source - " + LogEntry.OfficeCode
+ ", " +
313 "Table - " + LogEntry.TabletoRepl
+ ", " +
314 "Event - " + LogEntry.ReplEvent
).
315 need-to-rollback
= Yes.
320 /* Create collision records for all other entries in the transaction
*/
321 IF report-collisions
THEN
322 RUN create-collisions
( transact-id
, collision-list
, log-file
).
324 IF need-to-rollback
THEN DO:
325 RUN log
( "Rolling Back Transaction: Source - " + repl-source
+ ", Trans - " + STRING( transact-id
) +
326 IF collision-list
= "" THEN ", Missing Load Rules!" ELSE ( ", Collisions on " + collision-list
) ).
327 UNDO replication-transaction
, LEAVE replication-transaction.
330 END.
/* Replication transaction
*/
334 /* Update the collision log
*/
336 CREATE ReplCollisionLog.
337 BUFFER-COPY CollLog
TO ReplCollisionLog.
342 FIND RP
WHERE RP.UserName
= "Replication-" + repl-source
343 AND RP.ReportID
= "Last Replication File" EXCLUSIVE-LOCK NO-ERROR.
344 IF NOT AVAILABLE(RP
) THEN CREATE RP.
345 RP.UserName
= "Replication-" + repl-source.
346 RP.ReportID
= "Last Replication File".
347 RP.Char1
= replication-list.file-name.
348 DOS SILENT VALUE( "move " + log-file
+ " " + REPLACE( log-file
, "toload", "loaded" ) ).
349 FIND replication-list
WHERE ROWID(replication-list
) = current-rowid
NO-ERROR.
350 DELETE replication-list
NO-ERROR.
355 /* _UIB-CODE-BLOCK-END
*/
359 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE log Procedure
361 /*------------------------------------------------------------------------------
363 ------------------------------------------------------------------------------*/
364 DEF INPUT PARAMETER entry-text
AS CHAR NO-UNDO.
366 PUT UNFORMATTED STRING( TIME, "HH:MM:SS" ) + " " + entry-text
SKIP.
370 /* _UIB-CODE-BLOCK-END
*/
374 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE next-transact-id Procedure
375 PROCEDURE next-transact-id
:
376 /*------------------------------------------------------------------------------
378 ------------------------------------------------------------------------------*/
379 DEF INPUT-OUTPUT PARAMETER transact-id
LIKE ReplLog.TransActID
NO-UNDO.
381 DEF BUFFER LE FOR LogEntry.
383 IF transact-id
= ?
THEN
384 FIND FIRST LE NO-ERROR.
386 FIND FIRST LE WHERE LE.TransActID
> transact-id
NO-ERROR.
388 transact-id
= IF AVAILABLE LE THEN LE.TransActID
ELSE ?.
392 /* _UIB-CODE-BLOCK-END
*/
396 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE sequence-error Procedure
397 PROCEDURE sequence-error
:
398 /*------------------------------------------------------------------------------
399 Purpose
: A sequence error is one where we can't process this file because
400 an earlier hasn't been processed yet
, and isn't available.
401 ------------------------------------------------------------------------------*/
402 DEF INPUT PARAMETER previous-file
AS CHAR NO-UNDO.
404 RUN log
( "File Sequence Error processing: " + replication-list.full-path
).
405 RUN log
( "Previous file has not beenprocessed: " + previous-file
).
408 log-file-name
= "rplctn\dump\log\seq-err.log".
409 OUTPUT TO VALUE( log-file-name
) KEEP-MESSAGES APPEND.
410 RUN log
( "File Sequence Error processing: " + replication-list.full-path
).
411 RUN log
( "Previous file has not been processed: " + previous-file
).
412 RUN log
( "The last file processed was: " + last-file-loaded
).
414 RUN log
( "The " + previous-file
+ " file needs to be moved back into the").
415 RUN log
( "rplctn/dump/tosend directory for re-sending (it should be in" ).
416 RUN log
( "the rplctn/dump/sent directory at the moment)." ).
419 /* we can't really continue past this point
*/
424 /* _UIB-CODE-BLOCK-END
*/
428 /* ************************ Function Implementations
***************** */
430 &ANALYZE-SUSPEND _UIB-CODE-BLOCK _FUNCTION get-load-program Procedure
431 FUNCTION get-load-program
RETURNS CHARACTER
432 ( INPUT table-name
AS CHAR ) :
433 /*------------------------------------------------------------------------------
434 Purpose
: Get the name of the generic replication load program for the
435 given table. If it does not exist then generate the code for the
436 program and compile it.
438 ------------------------------------------------------------------------------*/
440 DEF VAR load-program
AS CHAR NO-UNDO.
442 FIND _File
WHERE _File._File-Name
= table-name
NO-LOCK.
444 load-program
= "rplctn/load/" + _File._Dump-Name
+ ".p".
446 IF SEARCH( load-program
) = ?
THEN DO:
447 RUN rplctn
/mkload.p
( table-name
, load-program
).
448 IF RETURN-VALUE = "FAIL" THEN RETURN RETURN-VALUE.
455 /* _UIB-CODE-BLOCK-END
*/