/* 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] = "<internal defaults apply>"
  .

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.
