home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / blt2_214.zip / src / bd_join.c < prev    next >
C/C++ Source or Header  |  1996-10-16  |  18KB  |  593 lines

  1.  
  2. /* bd_join.c -  2-Oct-1996 Cornel Huth
  3.  * This module is called by bd_main.c
  4.  * multiple table view, join
  5.  */
  6.  
  7. #include "platform.h"
  8.  
  9. // external to this module
  10.  
  11. void PutMsg(CHAR *strg);
  12. void GetMsg(CHAR *strg);
  13.  
  14. extern CHAR *collateTable;
  15. extern CHAR gCLS[6];
  16.  
  17. // public in this module
  18.  
  19. int bd_join(void);
  20.  
  21.  
  22. // GO
  23.  
  24. int bd_join(void) {
  25.  
  26.  void BuildEmpFieldList(FIELDDESCTYPE fieldList[]);
  27.  void BuildDptFieldList(FIELDDESCTYPE fieldList[]);
  28.  
  29.  // structures below are byte-aligned by virtue of being of all char type
  30.  typedef struct _EmpRecType {
  31.  CHAR tag;               // record tag, init to SPACE, * means deleted
  32.  CHAR empID[9];          // SSN (not 0T string)
  33.  CHAR empLN[16];         // last name
  34.  CHAR empFN[16];         // first name
  35.  CHAR empHire[8];        // "YYYYMMDD" (not 0T string)
  36.  CHAR empDept[6];        // department assigned
  37.  } EmpRecType; // 56 bytes
  38.  
  39.  typedef struct _DptRecType {
  40.  CHAR tag;               // record tag, init to SPACE, * means deleted
  41.  CHAR dptID[6];          // department (same format as empDept)
  42.  CHAR dptName[16];       // department name
  43.  CHAR dptMgrID[9];       // manager of (same format as empID)
  44.  CHAR dptNumber[4];      // number of employees assigned to department
  45.  } DptRecType; // 36 bytes
  46.  
  47.  // Sample data records for the database EMP-DEPT
  48.  // C++ probably doesn't like these exact-fit, non-zero-terminating strings
  49.  
  50.  EmpRecType empSampleRecords[] = {
  51.  //   123456789   1234567890123456   1234567890123456   12345678   123456
  52.  ' ',"465309999","Que",             "Barbie",          "19900131","BOSS",
  53.  ' ',"445038888","Stewart",         "Jackie",          "19910228","ACC",
  54.  ' ',"760443232","Whitman",         "Kelly",           "19920414","HUM",
  55.  ' ',"845309944","Beatty",          "Leslie",          "19940122","PRG",
  56.  ' ',"555033388","Jasper",          "Amy",             "19930230","PRG",
  57.  ' ',"430443222","Hauntos",         "Poco",            "19920414","PRG",
  58.  ' ',"365502949","Hopkins",         "Lisa",            "19910121","PRG",
  59.  ' ',"685733868","Leonard",         "Rosina",          "19850218","PRG",
  60.  ' ',"500945242","Morton",          "Holly",           "19950406","PSY",
  61.  ' ',"335209939","Buckly",          "Lois",            "19930715","GO4",
  62.  ' ',"745338218","Parker",          "Angie",           "19940412","MKT",
  63.  ' ',"860461892","Sosa",            "Rhoda",           "19940623","R&D",
  64.  ' ',"225374865","Jefferson",       "Weezie",          "19941106","R&D",
  65.  ' ',"115036578","Chung",           "Connie",          "19941205","PRG",
  66.  ' ',"240443355","Baker",           "Rosinda",         "19940304","PRG",
  67.  };
  68.  
  69.  DptRecType dptSampleRecords[] = {
  70.  //   123456   1234567890123456   123456789   1234
  71.  ' ',"BOSS",  "40th Floor",      "465309999","   1",
  72.  ' ',"GO4",   "Secretarial",     "335209939","   1",
  73.  ' ',"PRG",   "Programming",     "845309944","   7",
  74.  ' ',"R&D",   "Research & Dev",  "860461892","   2",
  75.  ' ',"MKT",   "Marketing",       "745338218","   1",
  76.  ' ',"ACC",   "Accounting",      "445038888","   1",
  77.  ' ',"PSY",   "Psycho Healers",  "500945242","   1",
  78.  ' ',"HUM",   "Human Resources", "760443232","   1",
  79.  };
  80.  
  81.  
  82. #pragma pack(1)         // recommended around Bullet-accessed data
  83.  
  84.  ACCESSPACK AP[3];
  85.  DOSFILEPACK DFP;
  86.  CREATEDATAPACK CDP;
  87.  CREATEINDEXPACK CIP;
  88.  HANDLEPACK HP;
  89.  OPENPACK OP;
  90.  
  91.  CHAR *indexFilename[] = {
  92.  ".\\$bd_jnss.ix3",        // employee SSN index
  93.  ".\\$bd_jnns.ix3",        // employee Last name and SSN last-four index
  94.  ".\\$bd_jnid.ix3"         // department ID index
  95.  };
  96.  
  97.  ULONG indexID[] ={0,0,0};
  98.  
  99.  CHAR *keyExpression[] = {
  100.  "SSN",
  101.  "SUBSTR(LNAME,1,4)+SUBSTR(SSN,6,4)",
  102.  "DEPT_ID"
  103.  };
  104.  
  105.  // The max key length Bullet uses is 64 bytes (this is a big key)
  106.  // I've sized the arrays at 68 bytes so that I can append a 0T
  107.  // if I want to make the key (if it ever were exactly 64 bytes)
  108.  // a C string (by appending a 0T, of course).
  109.  
  110.  CHAR *keyBuffer[3][68];
  111.  
  112.  CHAR *dataFilename[] = {
  113.  ".\\$bd_jnem.dbf",        // employee data
  114.  ".\\$bd_jndp.dbf"         // department data
  115.  };
  116.  
  117.  ULONG dataID[] ={0,0};
  118.  
  119.  FIELDDESCTYPE empFieldList[5];  // 5 fields used in Employee data record
  120.  EmpRecType empRec;
  121.  
  122.  FIELDDESCTYPE dptFieldList[4];  // 4 fields used in Department data record
  123.  DptRecType dptRec;
  124.  
  125. #pragma pack()
  126.  
  127.  LONG rez;               // return value from Bullet
  128.  LONG i;                 // counter
  129.  CHAR tmpStr[128];       // misc stuff, non-Bullet related
  130.  CHAR putStr[128];
  131.  
  132.  LONG empRecs2Add = sizeof(empSampleRecords) / sizeof(empRec);
  133.  LONG dptRecs2Add = sizeof(dptSampleRecords) / sizeof(dptRec);
  134.  
  135.  // Clap for the Wolfman
  136.  
  137.  PutMsg(gCLS);
  138.  PutMsg("Employee-Department database using two data files & three index files\n\n");
  139.  
  140.  // Assign fieldlist members (after first zeroing)
  141.  
  142.  memset(empFieldList,0,sizeof(empFieldList));
  143.  BuildEmpFieldList(empFieldList);
  144.  memset(dptFieldList,0,sizeof(dptFieldList));
  145.  BuildDptFieldList(dptFieldList);
  146.  
  147.  // Delete previous files from any previous run (disregard any error return)
  148.  
  149.  DFP.func = DELETE_FILE_DOS;
  150.  DFP.filenamePtr = dataFilename[0];
  151.  rez = BULLET(&DFP);
  152.  DFP.filenamePtr = dataFilename[1];
  153.  rez = BULLET(&DFP);
  154.  
  155.  for (i=0;i<3;i++) {
  156.     DFP.filenamePtr = indexFilename[i];
  157.     rez = BULLET(&DFP);
  158.  }
  159.  
  160.  // Create the data files
  161.  
  162.  CDP.func = CREATE_DATA_XB;
  163.  CDP.filenamePtr = dataFilename[0];
  164.  CDP.noFields = 5;
  165.  CDP.fieldListPtr = empFieldList;
  166.  CDP.fileID = 0x03;
  167.  rez = BULLET(&CDP);
  168.  if (rez) {
  169.     sprintf(putStr,"Failed EMP data file create.  Err: %d\n",rez);
  170.     PutMsg(putStr);
  171.     goto Abend;
  172.  }
  173.  
  174.  CDP.filenamePtr = dataFilename[1];
  175.  CDP.noFields = 4;
  176.  CDP.fieldListPtr = dptFieldList;
  177.  rez = BULLET(&CDP);
  178.  if (rez) {
  179.     sprintf(putStr,"Failed DPT data file create.  Err: %d\n",rez);
  180.     PutMsg(putStr);
  181.     goto Abend;
  182.  }
  183.  
  184.  // Open the data files
  185.  
  186.  OP.func = OPEN_DATA_XB;
  187.  OP.filenamePtr = dataFilename[0];
  188.  OP.asMode = READWRITE | DENYNONE;
  189.  rez = BULLET(&OP);
  190.  if (rez) {
  191.     sprintf(putStr,"Failed EMP data file open.  Err: %d\n",rez);
  192.     PutMsg(putStr);
  193.     goto Abend;
  194.  }
  195.  dataID[0] = OP.handle;
  196.  
  197.  OP.filenamePtr = dataFilename[1];
  198.  rez = BULLET(&OP);
  199.  if (rez) {
  200.     sprintf(putStr,"Failed DPT data file open.  Err: %d\n",rez);
  201.     PutMsg(putStr);
  202.     goto Abend;
  203.  }
  204.  dataID[1] = OP.handle;
  205.  
  206.  // Create index files
  207.  // First two index EMP data file, third indexes DPT data file
  208.  
  209.  CIP.func = CREATE_INDEX_XB;
  210.  CIP.filenamePtr = indexFilename[0];
  211.  CIP.keyExpPtr = keyExpression[0];
  212.  CIP.xbLink = dataID[0];
  213.  CIP.sortFunction = ASCII_SORT;
  214.  CIP.codePage = CODEPAGE;
  215.  CIP.countryCode = CTRYCODE;
  216.  CIP.collatePtr = NULL;
  217.  CIP.nodeSize = 512;
  218.  rez = BULLET(&CIP);
  219.  if (rez) {
  220.     sprintf(putStr,"Failed EMP SSN index file create.  Err: %d\n",rez);
  221.     PutMsg(putStr);
  222.     goto Abend;
  223.  }
  224.  
  225.  CIP.filenamePtr = indexFilename[1];
  226.  CIP.keyExpPtr = keyExpression[1];
  227.  CIP.xbLink = dataID[0];
  228.  CIP.sortFunction = NLS_SORT | SORT_SET;
  229.  CIP.codePage = CODEPAGE;
  230.  CIP.countryCode = CTRYCODE;
  231.  CIP.collatePtr = collateTable;
  232.  CIP.nodeSize = 512;
  233.  rez = BULLET(&CIP);
  234.  if (rez) {
  235.     sprintf(putStr,"Failed EMP NAME index file create.  Err: %d\n",rez);
  236.     PutMsg(putStr);
  237.     goto Abend;
  238.  }
  239.  
  240.  CIP.filenamePtr = indexFilename[2];
  241.  CIP.keyExpPtr = keyExpression[2];
  242.  CIP.xbLink = dataID[1];
  243.  CIP.sortFunction = ASCII_SORT;
  244.  CIP.codePage = CODEPAGE;
  245.  CIP.countryCode = CTRYCODE;
  246.  CIP.collatePtr = NULL;
  247.  CIP.nodeSize = 512;
  248.  rez = BULLET(&CIP);
  249.  if (rez) {
  250.     sprintf(putStr,"Failed DPT index file create.  Err: %d\n",rez);
  251.     PutMsg(putStr);
  252.     goto Abend;
  253.  }
  254.  
  255.  // Open the index files
  256.  
  257.  OP.func = OPEN_INDEX_XB;
  258.  OP.filenamePtr = indexFilename[0];
  259.  OP.asMode = READWRITE | DENYNONE;
  260.  OP.xbLink = dataID[0];
  261.  rez = BULLET(&OP);
  262.  if (rez) {
  263.     sprintf(putStr,"Failed SSN index file open.  Err: %d\n",rez);
  264.     PutMsg(putStr);
  265.     goto Abend;
  266.  }
  267.  indexID[0] = OP.handle;
  268.  
  269.  OP.filenamePtr = indexFilename[1];
  270.  OP.xbLink = dataID[0];
  271.  rez = BULLET(&OP);
  272.  if (rez) {
  273.     sprintf(putStr,"Failed EMP NAME index file open.  Err: %d\n",rez);
  274.     PutMsg(putStr);
  275.     goto Abend;
  276.  }
  277.  indexID[1] = OP.handle;
  278.  
  279.  OP.filenamePtr = indexFilename[2];
  280.  OP.asMode = READWRITE | DENYNONE;
  281.  OP.xbLink = dataID[1];
  282.  rez = BULLET(&OP);
  283.  if (rez) {
  284.     sprintf(putStr,"Failed DPT index file open.  Err: %d\n",rez);
  285.     PutMsg(putStr);
  286.     goto Abend;
  287.  }
  288.  indexID[2] = OP.handle;
  289.  
  290.  // Insert into the database.  This example has separate inserts for the
  291.  // employee file and the department file.  These could be done together,
  292.  // with just the single call, however, since this is done in a loop, for
  293.  // the number of sample records of each (different counts), and since an
  294.  // insert into EMP is distinct from an insert into DPT (not dependent on
  295.  // each other), it does not matter that they are done separately -- and
  296.  // actually, makes more sense to do so, considering that they are distinct.
  297.  
  298.  // Insert into the EMP data file (two index, one data)
  299.  
  300.  AP[0].func = INSERT_XB;
  301.  AP[0].handle = indexID[0];
  302.  AP[0].keyPtr = keyBuffer[0];
  303.  AP[0].nextPtr = &AP[1];
  304.  AP[1].func = INSERT_XB;
  305.  AP[1].handle = indexID[1];
  306.  AP[1].keyPtr = keyBuffer[1];
  307.  AP[1].nextPtr = NULL;
  308.  
  309.  for (i=0;i < empRecs2Add;i++) {
  310.     AP[0].recNo = 0;
  311.     AP[0].recPtr = &empSampleRecords[i];
  312.     AP[1].recNo = 0x80000000;
  313.     AP[1].recPtr = &empSampleRecords[i];
  314.     rez = BULLET(&AP[0]);
  315.     if (rez!=0) break;
  316.  }
  317.  if (rez) {
  318.     if (rez < 0) {
  319.        rez = abs(rez);
  320.        sprintf(putStr,"INSERT_XB #%d failed, data pack# %d, err: %d\n",i,rez,AP[rez-1].stat);
  321.        PutMsg(putStr);
  322.     }
  323.     else {
  324.        sprintf(putStr,"INSERT_XB #%d failed, index pack# %d, err: %d\n",i,rez,AP[rez-1].stat);
  325.        PutMsg(putStr);
  326.     }
  327.     goto Abend;
  328.  }
  329.  
  330.  // Insert into the DPT data file (one index, one data)
  331.  
  332.  AP[2].func = INSERT_XB;         // invariants out of loop
  333.  AP[2].handle = indexID[2];
  334.  AP[2].keyPtr = keyBuffer[2];
  335.  AP[2].nextPtr = NULL;
  336.  
  337.  for (i=0;i < dptRecs2Add;i++) {
  338.     AP[2].recNo = 0;
  339.     AP[2].recPtr = &dptSampleRecords[i];
  340.     rez = BULLET(&AP[2]);
  341.     if (rez!=0) break;
  342.  }
  343.  if (rez) {
  344.     if (rez < 0) {
  345.        sprintf(putStr,"INSERT_XB #%d failed, data pack# %d, err: %d\n",i,rez,AP[2].stat);
  346.        PutMsg(putStr);
  347.     }
  348.     else {
  349.        sprintf(putStr,"INSERT_XB #%d failed, index pack# %d, err: %d\n",i,rez,AP[2].stat);
  350.        PutMsg(putStr);
  351.     }
  352.     goto Abend;
  353.  }
  354.  
  355.  // Shows a view on the two tables, EMP-DPT, so that all employee info is
  356.  // shown, along with the department info that that employee is assigned.
  357.  // EMP.DEPT_ID (datafile.fieldname) is a foreign key into DPT.DEPT_ID, and
  358.  // so EMP.DEPT_ID for each EMP record is joined with the DPT info for that
  359.  // department.  First in SSN order, then in LNAME+last-4 order.  After this,
  360.  // a view on DPT-EMP is shown, listing the managers of each department, and
  361.  // their EMP info.
  362.  
  363.  AP[0].func = GET_FIRST_XB;      // using AP[0] since it's convenient to do so
  364.  AP[0].handle = indexID[0];
  365.  AP[0].recPtr = &empRec;
  366.  AP[0].keyPtr = keyBuffer[0];
  367.  
  368.  AP[2].func = GET_EQUAL_XB;      // accessing DPT by foreign key (exact) first
  369.  AP[2].handle = indexID[2];
  370.  AP[2].recPtr = &dptRec;
  371.  AP[2].keyPtr = keyBuffer[2];
  372.  
  373.  i=0;
  374.  //       123456789 1234567890123456 1234567890123456 12345678 1234567890123456
  375.  PutMsg(" EMP.SSN   LNAME            FNAME            HIRED    DEPARTMENT\n");
  376.  rez=BULLET(&AP[0]);
  377.  while (rez==0) {
  378.     memcpy(keyBuffer[2],empRec.empDept,6);       // foreign key to key buffer
  379.     rez=BULLET(&AP[2]);                          // and get it to dptRec
  380.     if (rez!=0) strcpy(dptRec.dptName,"Error!");
  381.  
  382.     sprintf(putStr," %9.9s %-16.16s %-16.16s %8.8s %-16.16s\n",
  383.             empRec.empID,
  384.             empRec.empLN,
  385.             empRec.empFN,
  386.             empRec.empHire,
  387.             dptRec.dptName);
  388.     PutMsg(putStr);
  389.  
  390.     if (rez==0) {
  391.        i++;
  392.        AP[0].func = GET_NEXT_XB;
  393.        rez=BULLET(&AP[0]);
  394.     }
  395.  }
  396.  if (rez == EXB_END_OF_FILE) rez=0; // expected is ERR_END_OF_FILE
  397.  if (rez) {
  398.     sprintf(putStr,"(SSN) Failed EMP-DPT view #%d, err: %d\n",i,rez);
  399.     PutMsg(putStr);
  400.     goto Abend;
  401.  }
  402.  
  403.  PutMsg("\nThat was in SSN order.  Press <Enter> for LNAME+last-4 order... ");
  404.  GetMsg(tmpStr);
  405.  PutMsg(gCLS);
  406.  
  407.  // now the same thing, but in LNAME+last-4 order
  408.  
  409.  AP[1].func = GET_FIRST_XB;      // using AP[1] since it's convenient to do so
  410.  AP[1].handle = indexID[1];
  411.  AP[1].recPtr = &empRec;
  412.  AP[1].keyPtr = keyBuffer[1];
  413.  
  414.  AP[2].func = GET_EQUAL_XB;      // accessing DPT by foreign key (exact) first
  415.  AP[2].handle = indexID[2];
  416.  AP[2].recPtr = &dptRec;
  417.  AP[2].keyPtr = keyBuffer[2];
  418.  
  419.  i=0;
  420.  //       123456789 1234567890123456 1234567890123456 12345678 1234567890123456
  421.  PutMsg(" EMP.SSN   LNAME            FNAME            HIRED    DEPARTMENT\n");
  422.  rez=BULLET(&AP[1]);
  423.  while (rez==0) {
  424.     memcpy(keyBuffer[2],empRec.empDept,6);       // foreign key to key buffer
  425.     rez=BULLET(&AP[2]);                          // and get it to dptRec
  426.     if (rez!=0) strcpy(dptRec.dptName,"Error!");
  427.  
  428.     sprintf(putStr," %9.9s %-16.16s %-16.16s %8.8s %-16.16s\n",
  429.             empRec.empID,
  430.             empRec.empLN,
  431.             empRec.empFN,
  432.             empRec.empHire,
  433.             dptRec.dptName);
  434.     PutMsg(putStr);
  435.  
  436.     if (rez==0) {
  437.        i++;
  438.        AP[1].func = GET_NEXT_XB;
  439.        rez=BULLET(&AP[1]);
  440.     }
  441.  }
  442.  if (rez == EXB_END_OF_FILE) rez=0; // expected is ERR_END_OF_FILE
  443.  if (rez) {
  444.     sprintf(putStr,"(LNAME) Failed EMP-DPT view #%d, err: %d\n",i,rez);
  445.     PutMsg(putStr);
  446.     goto Abend;
  447.  }
  448.  
  449.  // now for something a little different... the managers' info
  450.  
  451.  PutMsg("\nThose were EMP-DPT views.  Press <Enter> for DPT-EMP view (DEPT_ID order)...");
  452.  GetMsg(tmpStr);
  453.  PutMsg(gCLS);
  454.  
  455.  AP[2].func = GET_FIRST_XB;
  456.  AP[2].handle = indexID[2];
  457.  AP[2].recPtr = &dptRec;
  458.  AP[2].keyPtr = keyBuffer[2];
  459.  
  460.  AP[0].func = GET_EQUAL_XB;      // accessing EMP by foreign key (exact) first
  461.  AP[0].handle = indexID[0];      // indexID[0] is the SSN (aka MGR_ID)
  462.  AP[0].recPtr = &empRec;
  463.  AP[0].keyPtr = keyBuffer[0];
  464.  
  465.  i=0;
  466.  //       1234567890123456 123456- 1234---8 1234567890123456 1234567890123456
  467.  PutMsg(" DEPARTMENT       DEPT_ID ASSIGNED MANAGER\n");
  468.  rez=BULLET(&AP[2]);
  469.  while (rez==0) {
  470.     memcpy(keyBuffer[0],dptRec.dptMgrID,9);      // foreign key to key buffer
  471.     rez=BULLET(&AP[0]);                          // and get it to empRec
  472.     if (rez!=0) strcpy(empRec.empLN,"Error!");
  473.  
  474.     sprintf(putStr," %-16.16s %7.6s %4.4s     %s %s\n",
  475.             dptRec.dptName,
  476.             dptRec.dptID,
  477.             dptRec.dptNumber,
  478.             empRec.empFN,
  479.             empRec.empLN);
  480.     PutMsg(putStr);
  481.  
  482.     if (rez==0) {
  483.        i++;
  484.        AP[2].func = GET_NEXT_XB;
  485.        rez=BULLET(&AP[2]);
  486.     }
  487.  }
  488.  if (rez == EXB_END_OF_FILE) rez=0; // expected is ERR_END_OF_FILE
  489.  if (rez) {
  490.     sprintf(putStr,"(DEPT_ID) Failed DPT-EMP view #%d, err: %d\n",i,rez);
  491.     PutMsg(putStr);
  492.     goto Abend;
  493.  }
  494.  
  495.  // Fatal errors above come straight to here
  496.  Abend:
  497.  
  498.  // Close files (index files first then data (recommended but not required))
  499.  
  500.  HP.func = CLOSE_INDEX_XB;
  501.  for (i=2;i >= 0;i--) {
  502.     if (indexID[i]) {
  503.        HP.handle = indexID[i];
  504.        rez = BULLET(&HP);
  505.        if (rez) {
  506.           sprintf(putStr,"Failed index #%d file close.  Err: %d\n",i,rez);
  507.           PutMsg(putStr);
  508.        }
  509.     }
  510.  }
  511.  
  512.  HP.func = CLOSE_DATA_XB;
  513.  for (i=1;i >= 0;i--) {
  514.     if (dataID[i]) {
  515.        HP.handle = dataID[i];
  516.        rez = BULLET(&HP);
  517.        if (rez) {
  518.           sprintf(putStr,"Failed data #%d file close.  Err: %d\n",i,rez);
  519.           PutMsg(putStr);
  520.        }
  521.     }
  522.  }
  523.  
  524.  return rez;
  525. }
  526.  
  527. // field list assigns moved down here to just get them the heck out of the way!
  528. // -- actually, all these rez=BULLET() sections would be, should be,
  529. // wrapped up into generic routines (e.g., InitDatabase(xyz),
  530. // CreateDatabase(abc), GetEqualOrGreater(), and so on -- all the building
  531. // blocks are already done, you just need to put them together the way you
  532. // want them.
  533.  
  534. //---------------------------------------------
  535. // Init field list items for employee data file
  536.  
  537. void BuildEmpFieldList(FIELDDESCTYPE fieldList[]) {
  538.  
  539.  strcpy(fieldList[0].fieldName, "SSN");
  540.  fieldList[0].fieldType = 'C';
  541.  fieldList[0].fieldLen = 9;
  542.  fieldList[0].fieldDC = 0;
  543.  
  544.  strcpy(fieldList[1].fieldName, "LNAME");
  545.  fieldList[1].fieldType = 'C';
  546.  fieldList[1].fieldLen = 16;
  547.  fieldList[1].fieldDC = 0;
  548.  
  549.  strcpy(fieldList[2].fieldName, "FNAME");
  550.  fieldList[2].fieldType = 'C';
  551.  fieldList[2].fieldLen = 16;
  552.  fieldList[2].fieldDC = 0;
  553.  
  554.  strcpy(fieldList[3].fieldName, "HIRED");
  555.  fieldList[3].fieldType = 'D';
  556.  fieldList[3].fieldLen = 8;
  557.  fieldList[3].fieldDC = 0;
  558.  
  559.  strcpy(fieldList[4].fieldName, "DEPT_ID");
  560.  fieldList[4].fieldType = 'C';
  561.  fieldList[4].fieldLen = 6;
  562.  fieldList[4].fieldDC = 0;
  563.  return;
  564. }
  565.  
  566.  
  567. //-----------------------------------------------
  568. // Init field list items for department data file
  569.  
  570. void BuildDptFieldList(FIELDDESCTYPE fieldList[]) {
  571.  
  572.  strcpy(fieldList[0].fieldName, "DEPT_ID");
  573.  fieldList[0].fieldType = 'C';
  574.  fieldList[0].fieldLen = 6;
  575.  fieldList[0].fieldDC = 0;
  576.  
  577.  strcpy(fieldList[1].fieldName, "NAME");
  578.  fieldList[1].fieldType = 'C';
  579.  fieldList[1].fieldLen = 16;
  580.  fieldList[1].fieldDC = 0;
  581.  
  582.  strcpy(fieldList[2].fieldName, "MGR_ID");
  583.  fieldList[2].fieldType = 'C';
  584.  fieldList[2].fieldLen = 9;
  585.  fieldList[2].fieldDC = 0;
  586.  
  587.  strcpy(fieldList[3].fieldName, "ASSIGNED");
  588.  fieldList[3].fieldType = 'N';
  589.  fieldList[3].fieldLen = 4;
  590.  fieldList[3].fieldDC = 0;
  591.  return;
  592. }
  593.