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

  1.  
  2. /* bd_memo.c -  2-Oct-1996 Cornel Huth
  3.  * This module is called by bd_main.c
  4.  * memo fields
  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.  
  16.  
  17. // public in this module
  18.  
  19. int bd_memo(void);
  20.  
  21.  
  22. // GO
  23.  
  24. int bd_memo(void) {
  25.  
  26.  void BuildEmpFieldListMemo(FIELDDESCTYPE fieldList[]);
  27.  
  28.  typedef struct _EmpRecType {
  29.  CHAR tag;               // record tag, init to SPACE, * means deleted
  30.  CHAR empID[9];          // SSN (not 0T string)
  31.  CHAR empLN[16];         // last name
  32.  CHAR empFN[16];         // first name
  33.  CHAR empHire[8];        // "YYYYMMDD" (not 0T string)
  34.  CHAR empNotes[10];      // a memo field, called Notes
  35.  } EmpRecType; // 60 bytes
  36.  
  37.  // Sample data records for the database EMP
  38.  // 10-space data at end is the blank memo field value (means no memo yet)
  39.  // C++ probably doesn't like these exact-fit, non-zero-terminating strings
  40.  
  41.  EmpRecType empSampleRecords2[] = {
  42.  //   123456789   1234567890123456   1234567890123456   12345678   123456
  43.  ' ',"465309999","Que",             "Barbie",          "19900131","          ",
  44.  ' ',"445038888","Stewart",         "Jackie",          "19910228","          ",
  45.  ' ',"760443232","Whitman",         "Kelly",           "19920414","          ",
  46.  ' ',"845309944","Beatty",          "Leslie",          "19940122","          ",
  47.  ' ',"555033388","Jasper",          "Amy",             "19930230","          ",
  48.  ' ',"430443222","Hauntos",         "Poco",            "19920414","          ",
  49.  ' ',"365502949","Hopkins",         "Lisa",            "19910121","          ",
  50.  ' ',"685733868","Leonard",         "Rosina",          "19850218","          ",
  51.  ' ',"500945242","Morton",          "Holly",           "19950406","          ",
  52.  ' ',"335209939","Buckly",          "Lois",            "19930715","          ",
  53.  ' ',"745338218","Parker",          "Angie",           "19940412","          ",
  54.  ' ',"860461892","Sosa",            "Rhoda",           "19940623","          ",
  55.  ' ',"225374865","Jefferson",       "Weezie",          "19941106","          ",
  56.  ' ',"115036578","Chung",           "Connie",          "19941205","          ",
  57.  ' ',"240443355","Baker",           "Rosinda",         "19940304","          ",
  58.  };
  59.  
  60.  // Sample memos for the database EMP.dbt
  61.  // Anything goes
  62.  
  63.  CHAR *empSampleMemos[] = {
  64.  "This is memo sample number uno",
  65.  "This would then be number two",
  66.  "And number three",
  67.  "Number four, too",
  68.  "Don't forget memo number five!",
  69.  "Then comes memo six",
  70.  "And since seven follows six, memo seven",
  71.  "Eight is close to the last memo",
  72.  "But nine is even close to the last memo",
  73.  "Ten, now this is the last memo",
  74.  "Well, no, that wasn't -- this is eleven",
  75.  "Memo twelve is this",
  76.  "Thirteen here, or is this unlucky?",
  77.  "Memo Fourteen, now we're getting some where",
  78.  "Memo Fifteen, this is the last (one for each employee record)",
  79.  };
  80.  
  81. #pragma pack(1)
  82.  
  83.  ACCESSPACK AP;
  84.  DOSFILEPACK DFP;
  85.  CREATEDATAPACK CDP;
  86.  CREATEINDEXPACK CIP;
  87.  HANDLEPACK HP;
  88.  MEMODATAPACK MDP;
  89.  OPENPACK OP;
  90.  
  91.  CHAR indexFilename[] = ".\\$bd_memo.ix3";
  92.  ULONG indexID=0;
  93.  
  94.  CHAR keyExpression[] = "SSN";
  95.  CHAR keyBuffer[68];
  96.  
  97.  CHAR dataFilename[] = ".\\$bd_memo.dbf";
  98.  ULONG dataID=0;
  99.  
  100.  // the memo file is created implicitly when the DBF is, but to ease deleting
  101.  // the memo file at program startup, the DBT (as it would be by default)
  102.  // is set here
  103.  
  104.  CHAR memoFilename[] = ".\\$bd_memo.dbt";
  105.  
  106.  FIELDDESCTYPE empFieldList[5];  // 5 fields used in Employee data record
  107.  EmpRecType empRec;
  108.  
  109. #pragma pack()
  110.  
  111.  LONG rez;               // return value from Bullet
  112.  LONG i;                 // counter
  113.  CHAR tmpStr[256];       // misc stuff, non-Bullet related (so far as not needing pack() goes)
  114.  CHAR putStr[128];
  115.  
  116.  LONG empRecs2Add = sizeof(empSampleRecords2) / sizeof(empRec);
  117.  
  118.  PutMsg("Memo file example (sort order is by SSN, not in memo number order)\n\n");
  119.  
  120.  // Assign fieldlist members (after first zeroing)
  121.  
  122.  memset(empFieldList,0,sizeof(empFieldList));
  123.  BuildEmpFieldListMemo(empFieldList);
  124.  
  125.  // Delete previous files from any previous run (disregard any error return)
  126.  
  127.  DFP.func = DELETE_FILE_DOS;
  128.  DFP.filenamePtr = dataFilename;
  129.  rez = BULLET(&DFP);
  130.  DFP.filenamePtr = memoFilename;
  131.  rez = BULLET(&DFP);
  132.  DFP.filenamePtr = indexFilename;
  133.  rez = BULLET(&DFP);
  134.  
  135.  // Create the data files
  136.  
  137.  CDP.func = CREATE_DATA_XB;
  138.  CDP.filenamePtr = dataFilename;
  139.  CDP.noFields = 5;
  140.  CDP.fieldListPtr = empFieldList;
  141.  CDP.fileID = 0x8B;              // bit7&3=1 then also create memo file
  142.  rez = BULLET(&CDP);
  143.  if (rez) {
  144.     sprintf(putStr,"Failed EMP data file create.  Err: %d\n",rez);
  145.     PutMsg(putStr);
  146.     goto Abend;
  147.  }
  148.  
  149.  // Open the data file
  150.  
  151.  OP.func = OPEN_DATA_XB;
  152.  OP.filenamePtr = dataFilename;
  153.  OP.asMode = READWRITE | DENYNONE;
  154.  rez = BULLET(&OP);
  155.  if (rez) {
  156.     sprintf(putStr,"Failed EMP data file open.  Err: %d\n",rez);
  157.     PutMsg(putStr);
  158.     goto Abend;
  159.  }
  160.  dataID = OP.handle;
  161.  
  162.  // Create index file
  163.  
  164.  CIP.func = CREATE_INDEX_XB;
  165.  CIP.filenamePtr = indexFilename;
  166.  CIP.keyExpPtr = keyExpression;
  167.  CIP.xbLink = dataID;
  168.  CIP.sortFunction = ASCII_SORT;
  169.  CIP.codePage = CODEPAGE;
  170.  CIP.countryCode = CTRYCODE;
  171.  CIP.collatePtr = NULL;
  172.  CIP.nodeSize = 512;
  173.  rez = BULLET(&CIP);
  174.  if (rez) {
  175.     sprintf(putStr,"Failed EMP SSN index file create.  Err: %d\n",rez);
  176.     PutMsg(putStr);
  177.     goto Abend;
  178.  }
  179.  
  180.  // Open the index file
  181.  
  182.  OP.func = OPEN_INDEX_XB;
  183.  OP.filenamePtr = indexFilename;
  184.  OP.asMode = READWRITE | DENYNONE;
  185.  OP.xbLink = dataID;
  186.  rez = BULLET(&OP);
  187.  if (rez) {
  188.     sprintf(putStr,"Failed SSN index file open.  Err: %d\n",rez);
  189.     PutMsg(putStr);
  190.     goto Abend;
  191.  }
  192.  indexID = OP.handle;
  193.  
  194.  // Insert into the EMP data file, adding the memo record in the process
  195.  
  196.  AP.func = INSERT_XB;
  197.  AP.handle = indexID;
  198.  AP.keyPtr = keyBuffer;
  199.  AP.nextPtr = NULL;
  200.  
  201.  MDP.func = ADD_MEMO_XB;
  202.  MDP.dbfHandle = dataID;   // this remains the same, as does the song
  203.  
  204.  for (i=0;i < empRecs2Add;i++) {
  205.  
  206.     // it may seem odd to add a memo before its DBF record exists, but
  207.     // this is not so odd -- if you were adding a new employee record,
  208.     // say, you'd enter the info via some form of dialog, getting the
  209.     // standard record info (DBF field data) and also any memo data
  210.     // (comments, other non-field data), and then post that data to the
  211.     // database.  Since the DBF record's memo field needs the memo number
  212.     // (which is returned from the ADD_MEMO_XB call), it only makes sense
  213.     // to first add the memo, then fill in the DBF field's memo number
  214.     // and then INSERT_XB the employee record (DBF, the DBT having already
  215.     // been written to disk) -- and that is what this does
  216.  
  217.     MDP.memoPtr = empSampleMemos[i];
  218.     MDP.memoBytes = strlen(empSampleMemos[i])+1;  // +1 so it stores \0, too
  219.     rez = BULLET(&MDP);
  220.  
  221.     if (rez!=0) {
  222.        sprintf(putStr,"ADD_MEMO_XB #%d failed, err: %d\n",i,MDP.stat);
  223.        PutMsg(putStr);
  224.        goto Abend;
  225.     }
  226.  
  227.     sprintf(tmpStr,"%10.10u",MDP.memoNo);  // "0000000001" is first memo...
  228.     strncpy(empSampleRecords2[i].empNotes,tmpStr,10);  // put memo number in
  229.  
  230.     AP.recNo = 0;
  231.     AP.recPtr = &empSampleRecords2[i];
  232.  
  233.     rez = BULLET(&AP);
  234.     if (rez!=0) {
  235.        if (rez < 0) {
  236.           rez = abs(rez);
  237.           sprintf(putStr,"INSERT_XB #%d failed, data pack# %d, err: %d\n",i,rez,AP.stat);
  238.           PutMsg(putStr);
  239.        }
  240.        else {
  241.           sprintf(putStr,"INSERT_XB #%d failed, index pack# %d, err: %d\n",i,rez,AP.stat);
  242.           PutMsg(putStr);
  243.        }
  244.        goto Abend;
  245.     }
  246.  }
  247.  
  248.  // Shows a view on the EMP table, along with memo notes (first 30 or so bytes)
  249.  // This is just a crude output method -- the memo routines do return the
  250.  // size of each memo data, and so on -- enough info to manage them quite well,
  251.  // much better than can be done in dBASE
  252.  
  253.  AP.func = GET_FIRST_XB;
  254.  AP.handle = indexID;
  255.  AP.recPtr = &empRec;
  256.  AP.keyPtr = keyBuffer;
  257.  
  258.  
  259.  // for demo use, get bytes of memo data
  260.  // ====================================
  261.  // ===========================
  262.  
  263.  
  264.  //MDP.func = GET_MEMO_XB; // no real point setting this now, since it's changed in the loop
  265.  MDP.memoPtr = tmpStr;     // read memo into this (other MDP. parms already set)
  266.  MDP.memoOffset = 0;       // starting at first byte of memo
  267.  
  268.  i=0;
  269.  //       123456789 1234567890123456 1234567890123456 12345678 123456789012345...
  270.  PutMsg(" EMP.SSN   LNAME            FNAME            HIRED    NOTES (memo, '>' added)\n");
  271.  rez=BULLET(&AP);
  272.  while (rez==0) {
  273.  
  274.     // don't want to use atol(empRec.empNotes) since this field is not zero-terminated
  275.     // and fills the 10 bytes completely -- use sscanf(), or atol() on left 10 bytes
  276.     // MDP.memoNo = atol(empRec.empNotes); // scratch this
  277.  
  278.     sscanf(empRec.empNotes,"%10u",&MDP.memoNo);
  279.  
  280.     // MDP.memoNo set from above, get number of bytes of real data of this memo record
  281.     // this size returned INCLUDES the 0T since that's the way it was written above
  282.     // as:  MDP.memoBytes = strlen(empSampleMemos[i])+1;  // +1 so it stores \0, too
  283.  
  284.     MDP.func = GET_MEMO_SIZE_XB;
  285.     rez = BULLET(&MDP);
  286.     if (rez!=0) {
  287.        sprintf(putStr,"GET_MEMO_SIZE_XB #%d failed, err: %d\n",i,MDP.stat);
  288.        PutMsg(putStr);
  289.        goto Abend;
  290.     }
  291.  
  292.     // MDP.memoBytes set from above, .memoPtr/Offset from several lines up
  293.  
  294.     MDP.func = GET_MEMO_XB;
  295.     // other members already setup
  296.     rez = BULLET(&MDP);
  297.     if (rez!=0) {
  298.        sprintf(putStr,"GET_MEMO_XB #%d failed, err: %d\n",MDP.memoNo,MDP.stat);
  299.        PutMsg(putStr);
  300.        goto Abend;
  301.     }
  302.  
  303.     // tmpStr has the memo record, including the 0T that was written originally
  304.     // only the first 24 characters of the memo record are printed (with an
  305.     // added > to show that more follow, and to mark the end of shorter ones)
  306.  
  307.     sprintf(putStr," %9.9s %-16.16s %-16.16s %8.8s %-.24s>\n",
  308.             empRec.empID,
  309.             empRec.empLN,
  310.             empRec.empFN,
  311.             empRec.empHire,
  312.             tmpStr);
  313.     PutMsg(putStr);
  314.  
  315.     if (rez==0) {
  316.        i++;
  317.        AP.func = GET_NEXT_XB;
  318.        rez=BULLET(&AP);
  319.     }
  320.     
  321.  }
  322.  if (rez == EXB_END_OF_FILE) rez=0; // expected is EXB_END_OF_FILE
  323.  if (rez) {
  324.     sprintf(putStr,"(SSN) Failed EMP view #%d, err: %d\n",i,rez);
  325.     PutMsg(putStr);
  326.     goto Abend;
  327.  }
  328.  
  329.  // Fatal errors above come straight to here
  330.  Abend:
  331.  
  332.  // Close files
  333.  // closing the data file closes its memo file
  334.  
  335.  HP.func = CLOSE_INDEX_XB;
  336.  if (indexID) {
  337.     HP.handle = indexID;
  338.     rez = BULLET(&HP);
  339.     if (rez) {
  340.        sprintf(putStr,"Failed index #%d file close.  Err: %d\n",i,rez);
  341.        PutMsg(putStr);
  342.     }
  343.  }
  344.  
  345.  HP.func = CLOSE_DATA_XB;
  346.  if (dataID) {
  347.     HP.handle = dataID;
  348.     rez = BULLET(&HP);
  349.     if (rez) {
  350.        sprintf(putStr,"Failed data #%d file close.  Err: %d\n",i,rez);
  351.        PutMsg(putStr);
  352.     }
  353.  }
  354.  
  355.  return rez;
  356. }
  357.  
  358.  
  359. //---------------------------------------------
  360. // Init field list items for employee data file
  361.  
  362. void BuildEmpFieldListMemo(FIELDDESCTYPE fieldList[]) {
  363.  
  364.  strcpy(fieldList[0].fieldName, "SSN");
  365.  fieldList[0].fieldType = 'C';
  366.  fieldList[0].fieldLen = 9;
  367.  fieldList[0].fieldDC = 0;
  368.  
  369.  strcpy(fieldList[1].fieldName, "LNAME");
  370.  fieldList[1].fieldType = 'C';
  371.  fieldList[1].fieldLen = 16;
  372.  fieldList[1].fieldDC = 0;
  373.  
  374.  strcpy(fieldList[2].fieldName, "FNAME");
  375.  fieldList[2].fieldType = 'C';
  376.  fieldList[2].fieldLen = 16;
  377.  fieldList[2].fieldDC = 0;
  378.  
  379.  strcpy(fieldList[3].fieldName, "HIRED");
  380.  fieldList[3].fieldType = 'D';
  381.  fieldList[3].fieldLen = 8;
  382.  fieldList[3].fieldDC = 0;
  383.  
  384.  strcpy(fieldList[4].fieldName, "NOTES");
  385.  fieldList[4].fieldType = 'M';
  386.  fieldList[4].fieldLen = 10;
  387.  fieldList[4].fieldDC = 0;
  388.  return;
  389. }
  390.