/* crcdf4.p (V0.4) 26th Mar 2001 */ /* Creates two .df files that can be used to build a CRC */ /* compatible DB in Progress version 8.1/8.2/8.3 (V7 ???) */ /* Note - doesn't seem to work with V9 dict, but in theory it */ /* shouldn't be necessary with V9 ??? */ /* Copyright (C) Kean Maizels & Grant Maizels 13th Oct 1999 */ /* http://www.maizels.nu/progress */ /* V0.1 initial public release */ /* V0.2 includes changes suggested by Steve.Brown@dana.com */ /* - create initial df by _file-num, and include DUMP-NAME */ /* to avoid non-unique dump names for long table names */ /* V0.3 includes additional changes by Grant Maizels */ /* - includes sequences (and dummies) to get same _seq-num */ /* (not a CRC issue - just the schema) */ /* - field case-sensitive flag affects CRCs but not fixed by */ /* applying a delta */ /* - format case is not picked up by delta eg "Yes/No" */ /* - order by _file-num and gap filling with dummies */ /* - order by _idx-num and gap filling with dummies */ /* **see known problems below** */ /* V0.4 includes additional changes by Grant Maizels */ /* - fix bug where there are no sequences in source db */ /* - fix bug where dummy sequences are not correctly named */ /* Known Problems */ /* 1. _idx-num order is not guaranteed to be the same as the */ /* source database. This is because adding tables creates a */ /* default index which uses _idx-num positions. This could be */ /* fixed by merging the two loops, possibly requiring more */ /* two DFs. Still thinking about this. Doesn't affect CRC */ /* after V6 - but low level schema may not not identical. */ /* 2. RECIDs will never be guaranteed to be the same! */ /* calls crccmp.p (or use crccmp2.p for more detail) */ /* needs prodict includes, so $DLC/src should be in propath */ /* Thanks to Steve Brown for example of loading incremental df */ /* Thanks to Peter van Dam for previous work on crccopy */ /* procedure used is :- */ /* 1: create simple df containing all user tables, and fields */ /* including dummy placeholder fields for rpos gaps */ /* also include primary indexes, as this speeds up creation */ /* of delta df - no prompts re deactivating indexes */ /* 2: create a new DB */ /* 3: load the simple df */ /* 4: create a delta df between original and new DBs */ /* 5: apply delta df to newdb to get all other field/index */ /* attributes, sequence etc. this will also drop the dummy */ /* fields */ /* 6: compare the CRCs */ {prodict/dictvar.i new} {prodict/user/uservar.i new} {prodict/user/userhue.i new} {prodict/user/userpik.i new} def var db as char init "" no-undo. def var odb as char no-undo. def var fldnum as int no-undo. def var fldmax as int no-undo. def var tblnum as int no-undo. def var tblmax as int no-undo. def var idxnum as int no-undo. def var idxmax as int no-undo. def var seqnum as int no-undo. def var seqmax as int no-undo. if connected(db) then disconnect value(db). odb = ldbname("dictdb"). display "CRC compatible df file generator V0.3" skip "by Kean Maizels & Grant Maizels 20th Jan 2000" skip(1). display odb format "x(40)" label "Current DB" with side-labels. update db format "x(40)" label "New DB name" help "DB name without extension - WARNING: will overwrite exisitng DB". if db = ? or db = "" then return. message "1: Creating simple .df". output to value(db + "_1.df"). put unformatted "UPDATE DATABASE ""?""" skip(1). seqmax = 0. for each dictdb._sequence no-lock: seqmax = max(seqmax, _seq-num). end. do seqnum = 0 to seqmax: find dictdb._sequence no-lock where _seq-num = seqnum no-error. if not available dictdb._sequence then do: if seqnum <> 0 then put unformatted "ADD SEQUENCE ""dummy_seq" string(seqnum) """" skip(1). end. else do: put unformatted "ADD SEQUENCE """ _seq-name """" skip " INITIAL " _seq-init skip " INCREMENT " _seq-incr skip " CYCLE-ON-LIMIT " _cycle-ok skip " MIN-VAL " _seq-min skip " MAX-VAL " _seq-max skip skip(1). end. end. tblmax = 0. for each dictdb._file no-lock: tblmax = max(tblmax, _file-num). end. repeat tblnum = 1 to tblmax: find dictdb._file no-lock where _file-num = tblnum no-error. if not available dictdb._file then do: put unformatted "ADD TABLE ""dummy_" string(tblnum) """" skip " DUMP-NAME ""d%_" string(tblnum) """" skip(1). next. end. put unformatted "ADD TABLE """ _file-name """" skip " DUMP-NAME """ _Dump-name """" skip(1). fldmax = 1. for each dictdb._field of _file no-lock: fldmax = max(fldmax, _field-rpos). end. do fldnum = 2 to fldmax: find dictdb._field of _file no-lock where _field-rpos = fldnum no-error. if not available dictdb._field then do: put unformatted "ADD FIELD ""dummy_rpos" string(fldnum) """ OF """ _file-name """ AS char" skip. end. else do: put unformatted "ADD FIELD """ _field-name """ OF """ _file-name """ AS " _data-type skip " ORDER " _order skip. if _extent <> 0 then put unformatted " EXTENT " _extent skip. if _data-type = "decimal" then put unformatted " DECIMALS " _decimals skip. if _fld-case then put unformatted " CASE-SENSITIVE" skip. put unformatted " FORMAT """ _format """" skip. end. put unformatted skip(1). end. end. idxmax = 0. for each dictdb._index no-lock, first _file of _index where _file-num > 0: idxmax = max(idxmax, _idx-num). end. repeat idxnum = 1 to idxmax: find dictdb._index no-lock where _idx-num = idxnum no-error. if not available _index then do: find first dictdb._file where _file-num > 0 and _numfld > 0. find first dictdb._field of _file. put unformatted "ADD INDEX ""dummy" idxnum """ ON """ _file-name """" skip " INDEX-FIELD " _field-name " ASCENDING" skip(1). next. end. find dictdb._file no-lock of dictdb._index. if _file._file-num < 0 then next. /* this is a metaschema index */ if _index-name = "default" then next. /* created by dictionary */ put unformatted "ADD INDEX """ _index-name """ ON """ _file-name """" skip. if _unique then put unformatted " UNIQUE" skip. if recid(_index) = _file._prime-index then put unformatted " PRIMARY" skip. for each dictdb._index-field of _index no-lock: find dictdb._field of _index-field. put unformatted " INDEX-FIELD " _field-name " " trim(string(_asc, "ASCENDING/DESCENDING")) " " trim(string(_abbrev, " ABBREVIATED/")) skip. end. put unformatted skip(1). end. output close. message "2: Creating new DB". create database db replace. connect value(db) -1 -ld newdb. create alias dictdb for database newdb. pause 0. message "3: Loading simple .df". run prodict/load_df.p (db + "_1.df"). message "4: Creating delta .df". create alias dictdb for database value(odb). create alias dictdb2 for database newdb. assign user_dbtype = "PROGRESS" cache_db# = 1 cache_db_t[1] = "PROGRESS" cache_db_l[1] = "newdb" user_env[2] = db + "_2.df" user_env[5] = "" . find first _file no-lock no-error. if available _file then do: drec_db = _file._db-recid. run prodict/dump/_dmpincr.p. end. message "5: Loading delta .df". create alias dictdb for database newdb. run prodict/load_df.p (db + "_2.df"). message "6: Comparing CRCs". create alias dictdb for database value(odb). create alias dictdb2 for database newdb. run crccmp.p. disconnect newdb.