home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / CONTRIB / MBASE / MBASE50.TAR / mbase / sample / sample.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-22  |  14.9 KB  |  475 lines

  1. /*
  2.  * METALBASE 5.0
  3.  *
  4.  * Released October 1st, 1992 by Huan-Ti [ richid@owlnet.rice.edu ]
  5.  *                                       [ t-richj@microsoft.com ]
  6.  */
  7.  
  8. #undef MODULE
  9.  
  10. /*
  11.  * Lemme explain the above line--it's not necessary 'cause MODULE isn't
  12.  * defined anywhere else, but I put it in so I could put in this comment.
  13.  * The headers created by "build" and "form" include actual data, that should
  14.  * be local to only one module of a multiple .c-program executable; all the
  15.  * others should have the headers' variables declared as external.  So the
  16.  * headers use #ifdefs and check for the definition of MODULE--if it's there,
  17.  * variables are declared external, if not, they're declared local.  That way,
  18.  * variables always go in this one piece of .c code; if you were to link this
  19.  * with any others, add "#define MODULE" to 'em and the headers will tell the
  20.  * program that the variables therein are actually local to another C program.
  21.  * Works rather well.
  22.  *
  23.  */
  24.  
  25. #include <mbase.h>
  26.  
  27. #include "sample.h"     /* Created during "% build sample.s"  */
  28. #include "sampl_fm.h"  /* Created during "% form sample.frm" */
  29.  
  30. #ifdef LONGARGS
  31.    void  main      (void);
  32.    void  add_cust  (void);
  33.    int   validate  (de_form *);
  34.    void  do_datent (void);
  35.    void  do_error  (char *);
  36.    int   verify    (char *);
  37. #else
  38.    void  main();
  39.    void  add_cust();
  40.    int   validate();
  41.    void  do_datent();
  42.    void  do_error();
  43.    int   verify();
  44. #endif
  45.  
  46. #ifdef MSDOS
  47. #define Standout()   /* For some reason, the MSDOS curses package I use   */
  48. #define Standend()   /* craps out with standout and standend.  Try yours. */
  49. #else
  50. #define Standout() standout()
  51. #define Standend() standend()
  52. #endif
  53.  
  54. static sample_str arr[] =
  55.  { { "Johnson Bill", 0L, 123.4567, 0L, 0L, "N", (ushort)15, "494-0220" },
  56.    { "Calvin John",  0L,  23.00,   0L, 0L, "N", (ushort)3,  "216-881-2624"  },
  57.    { "Moore Bob",    0L, 456.1234, 0L, 0L, "Y", (ushort)45, "882-8080x14651" },
  58.    { "",             0L,   0.0,    0L, 0L, "",  (ushort)0,  ""  } };
  59.  
  60. relation   *samp;
  61. int         iserr;
  62. sample_str  rec;
  63.  
  64. void
  65. main ()
  66. {
  67.    int       i;
  68.    long      l;
  69.    char      temp[80];
  70.  
  71. /*
  72.  * First, if we need one, we've gotta get an encryption key for sample.rel:
  73.  *
  74.  */
  75.  
  76. #ifdef NOENCRYPT
  77.    temp[0] = 0;
  78. #else
  79.    printf ("%s%s%sMetalBase 5.0 Sample________________________________%s",
  80.             SNGCR, CLS, SNGCR, SNGCR);
  81.    printf ("%sEncryption password : ", DUBCR);
  82.    gets   (temp);
  83.    printf (SNGCR);
  84. #endif
  85.  
  86.    if ((samp = mb_inc ("sample", strtokey (temp))) == RNULL)
  87.     { fprintf (stderr, "Database could not be opened (%s).%s", mb_error,SNGCR);
  88.       mb_exit (1);
  89.     }
  90.  
  91.    for (;;)
  92.     { if ((l = mb_num(samp)) == 1L)
  93.          printf ("%s%sThere is currently 1 customer in the database.%s",
  94.                       CLS, SNGCR, DUBCR);
  95.       else
  96.          printf ("%s%sThere are currently %ld customers in the database.%s",
  97.                  CLS, SNGCR, l, DUBCR);
  98.       printf ("It is currently %s %s%s",
  99.                 fmt_time(curtime(),0), fmt_date(curdate(),0), SNGCR);
  100.  
  101.       printf (SNGCR);
  102.       printf (" [D] - Add demonstration customers%s", SNGCR);
  103.       printf (" [F] - Use data-entry form%s", SNGCR);
  104.       printf (" [Q] - Quit%s", SNGCR);
  105.       printf ("%sOption : ", SNGCR);
  106.       gets (temp);  if ((i = tolower (temp[0])) == 'q')  break;
  107.  
  108.       switch (i)
  109.        { case 'd':  add_cust  ();      gets(temp);  break;
  110.          case 'f':  do_datent ();                   break;
  111.          default:                                   break;
  112.        }
  113.     }
  114.  
  115.    printf ("%s%s%s", SNGCR, CLS, SNGCR);
  116.    if (mb_rmv (samp))
  117.     { fprintf (stderr, "Database could not be closed (%s).%s", mb_error,SNGCR);
  118.       mb_exit (1);
  119.     }
  120.    mb_exit (0);
  121. }
  122.  
  123. /*
  124.  * Here, we add three customers to the relation.  Basically so you can have
  125.  * some test data to play with, without thinking of anyone's names or
  126.  * whatever; also helps demonstrate mb_add().
  127.  *
  128.  */
  129.  
  130. void
  131. add_cust ()
  132. {
  133.    int  i, n;
  134.  
  135.    printf (SNGCR);
  136.    for (n=0; ; n++)
  137.       if (arr[n].custname[0] == 0)  break;
  138.    for (i=0; i<n; i++)
  139.     { printf ("Adding customer #%d/%d...", i+1, n);
  140.       arr[i].date_en = curdate();
  141.       arr[i].time_en = curtime();
  142.  
  143. /*
  144.  * Note that the serial number is not set by us--it's assigned automatically
  145.  * by the system.  We just send in 0L, or whatever happens to be there--
  146.  * its value when passed is discarded.
  147.  *
  148.  */
  149.  
  150.       if (mb_add (samp, &arr[i]) == MB_OKAY)
  151.          printf ("Successfully added%s", SNGCR);
  152.       else
  153.          printf ("%s%s", mb_error, SNGCR);
  154.  
  155. /*
  156.  * Note that after a successful mb_add() call, the record's serial number
  157.  * has been filled in automatically; if you looked in arr[i].custnum, the
  158.  * number is now set.  Most engines require you to look up the record before
  159.  * you can find out what number it was assigned; likewise, money values have
  160.  * been truncated appropriately.  Nya nya nya, Informix.  :)
  161.  *
  162.  */
  163.  
  164.     }
  165.    printf ("%sPress RETURN :", SNGCR);
  166. }
  167.  
  168. /*
  169.  * Here's the code for the data-entry stuff.  I'm including my notes
  170.  * for when I first designed this, to press a point--data-entry is SIMPLE
  171.  * if you're positive of what exactly you want BEFORE you start to code.
  172.  * I suggest you do something exactly like what I've got here, and DE will
  173.  * completely cease to be a problem for you.  :)  Likely, anyway...
  174.  *
  175.  * We've got:
  176.  *
  177.  *       +--------------------------------------------+
  178.  *       |                                            |
  179.  *       |  Customer Number...[custnum  ]             |
  180.  *       |  Customer Name.....[custname  ]            |
  181.  *       |                                            |
  182.  *       |  Current Balance...${balance  }            |
  183.  *       |  Accept Credit.....[A]..[B  ]              |
  184.  *       |                                            |
  185.  *       |  Date Entered......[date_en  ][time_en  ]  |
  186.  *       |                                            |
  187.  *       +--------------------------------------------+
  188.  *
  189.  * We want a menu that sez:
  190.  *  Add  Find  Change  Delete
  191.  *
  192.  * Where
  193.  * Add     == Mode 1 (everything inout, save date/time and custnum--
  194.  *                 they're set by the system)
  195.  * Find    == Mode 2 (only number and name inout, everything else out)
  196.  * Change  == Mode 1 (same stuff as for Add, above)
  197.  * Delete  == No mode--just a yes/no question.
  198.  *
  199.  * On second thought, let's not make it a menu.  Let's put 'em in the data-
  200.  * entry form... since there's no data, we'll start with Find == mode 2.  When
  201.  * they've entered something valid, we'll go on to Mode 1/Change; if they enter
  202.  * something invalid, we'll go to Mode 1/Add.  If they're in Mode 1/Change..
  203.  * hell, let's make it a mode 3.. If they're in Mode 3, and they hit
  204.  * EOF==Ctrl-D, we'll delete the record if they want to--and they'll go back
  205.  * to Mode 2 with no data.
  206.  * Let's also let 'em move around.  Ctrl-N and Ctrl-P will select the Next
  207.  * and previous records if they're in custnum or custname fields... if they're
  208.  * not, print an error.  Those two keys will work in.. hummm.  If they're
  209.  * in find mode, -N will do a FIRST, and -P will do a LAST; after any -N/-P,
  210.  * it'll pull up the record & put 'em in change mode, same field.  From change
  211.  * mode, they'll do NEXT and PREVIOUS, respectively... if you've updated the
  212.  * data, it'll ask you if you wanna save it.
  213.  *
  214.  * So:
  215.  *      Set Mode 2
  216.  *      Set Field Custnum
  217.  *      Go
  218.  *       : If (selected Previous or Next)
  219.  *       :  : if (! in custnum or custname)
  220.  *       :  :  : error--can't search on any other fields (nya nya)
  221.  *       :  : if (in mode 1 ("Add"))
  222.  *       :  :  : error--can't search during add
  223.  *       :  : if (in mode 2 ("Find"))
  224.  *       :  :  : make 'em do FIRST and LAST
  225.  *       :  :  : pull up record go to mode 3 ("Change")
  226.  *       :  : if (in mode 3 ("Change"))
  227.  *       :  :  : if they've updated the record, don't ask to save it  :)
  228.  *       :  :  : pull up record
  229.  *       :  : don't change fields
  230.  *       :  : return 0 (okay)
  231.  *       : If (mode 2 ("Find"))
  232.  *       :  : If (Abort DE)
  233.  *       :  :  : return -1 --abort
  234.  *       :  : If (valid custnum or valid custname)
  235.  *       :  :  : load information
  236.  *       :  :  : change to mode 3 ("Change")
  237.  *       :  : If (invalid custnum or invalid custname)
  238.  *       :  :  : error--cannot find record (stay in field)
  239.  *       :  : If (custname == "new")
  240.  *       :  :  : clear the form and go to mode 1
  241.  *       : If (mode 1 ("Add"))
  242.  *       :  : If (EOF)
  243.  *       :  :  : clear data--change to mode 2
  244.  *       :  : If (Accept DE)
  245.  *       :  :  : add new record
  246.  *       :  :  : change to mode 3 ("Change")
  247.  *       :  : If (Abort DE)
  248.  *       :  :  : clear data--change to mode 2
  249.  *       : If (mode 3 ("Change"))
  250.  *       :  : If (EOF)
  251.  *       :  :  : ask to delete--if so, clear data and change to mode 2 ("Find")
  252.  *       :  : If (Accept DE)
  253.  *       :  :  : add new record
  254.  *       :  : If (Abort DE)
  255.  *       :  :  : clear data--change to mode 2
  256.  *      Done
  257.  *
  258.  */
  259.  
  260. void
  261. do_datent ()
  262. {
  263.    de_form *form = &sample_fm; /* Shorthand, basically. */
  264.  
  265.    sprintf (quit_chars, "%c%c%c", CTRL_D, CTRL_P, CTRL_N);
  266.  
  267.    form->curmode  = 2;
  268.    form->curfield = fm_fldnum (form, "custnum");
  269.    form->valid_fn = validate;
  270.  
  271. /*
  272.  * Oh yeah.  If we left looking at a record, let's pull it up and start in
  273.  * Change mode:
  274.  *
  275.  */
  276.  
  277. /* (naw)
  278.  *
  279.  * if (mb_sel (samp, 0, &rec, CURRENT, NULL) == MB_OKAY)
  280.  *  { form->curmode = 3;
  281.  *    reltoform (samp, form, &rec);
  282.  *  }
  283.  *
  284.  */
  285.  
  286.    do_form (form);
  287. }
  288.  
  289. int
  290. validate (form)
  291. de_form  *form;
  292. {
  293.    int   idx, n;
  294.  
  295.    if (iserr)  do_error("");  /* Get rid of any old message */
  296.  
  297.    if (form->key == CTRL_P || form->key == CTRL_N)
  298.     { idx = -1;
  299.       if (form->curfield == fm_fldnum (form, "custnum"))
  300.          idx = idxnum (samp, "ix_number");
  301.       if (form->curfield == fm_fldnum (form, "custname"))
  302.          idx = idxnum (samp, "ix_name");
  303.       if (idx == -1)
  304.        { do_error ("Ctrl-N and Ctrl-P only work on CustNum / CustName");
  305.          form->nextfield = form->curfield;
  306.          return 0;
  307.        }
  308.       if (form->curmode == 1)
  309.        { do_error ("you may not search during an add operation");
  310.          form->nextfield = form->curfield;
  311.          return 0;
  312.        }
  313.       do_error ("wait...");
  314.       if (form->curmode == 3)
  315.        { if (mb_sel (samp, idx, &rec, (form->key==CTRL_P) ?PREV:NEXT, NULL))
  316.           { do_error ("no more records in that direction");
  317.             form->nextfield = form->curfield;
  318.             return 0;
  319.           }
  320.        }
  321.       if (form->curmode == 2)
  322.        { if (mb_sel (samp, idx, &rec, (form->key==CTRL_P) ?LAST:FIRST, NULL))
  323.           { do_error ("no more records in that direction");
  324.             form->nextfield = form->curfield;
  325.             return 0;
  326.           }
  327.          fm_mode (form, 3);
  328.        }
  329.       form->nextfield = form->curfield;
  330.       reltoform  (samp, form, &rec);
  331.       fm_refrall (form);
  332.       do_error ("record found successfully");
  333.       return 0;
  334.     }
  335.  
  336.    switch (form->curmode)
  337.     {
  338.       case 2:  formtorel (form, samp, &rec);
  339.                if (form->key == -1)
  340.                   return -1;
  341.  
  342.                if (rec.custname[0] != 0)
  343.                 { idx = idxnum (samp, "ix_name");
  344.  
  345.                   if (! strcmp (rec.custname, "new"))
  346.                    { fm_mode (form, 1);
  347.                      form->nextfield = form->curfield;  /* Don't move */
  348.                      fm_zero (form);
  349.                      if ((n = fm_fldnum (form, "custname")) >= 0)
  350.                         fm_refrnum (form, n);
  351.                      do_error ("enter new record");
  352.                      break;
  353.                    }
  354.                 }
  355.                else
  356.                   if (rec.custnum != 0L)
  357.                      idx = idxnum (samp, "ix_number");
  358.                   else
  359.                      break;
  360.  
  361.                do_error ("wait...");
  362.                if (mb_sel (samp, idx, &rec, GTEQ, NULL) == MB_OKAY)
  363.                 { reltoform  (samp, form, &rec);
  364.                   fm_refrall (form);
  365.                   fm_mode (form, 3);
  366.                   do_error ("record found successfully");
  367.                   break;
  368.                 }
  369.                do_error ("the specified record cannot be found.");
  370.                form->nextfield = form->curfield;
  371.               break;
  372.  
  373.       case 1:  if (form->key == 4)
  374.                 { fm_zero    (form);
  375.                   fm_refrall (form);
  376.                   fm_mode (form, 2);
  377.                   do_error ("add aborted");
  378.                   break;
  379.                 }
  380.                if (form->key == 1)
  381.                 { formtorel (form, samp, &rec);
  382.                   do_error ("wait...");
  383.                   rec.date_en = curdate();
  384.                   rec.time_en = curtime();
  385.                   if (mb_add (samp, &rec) != MB_OKAY)
  386.                      do_error (mb_error);
  387.                   else
  388.                    { do_error   ("record added successfully");
  389.                      fm_mode    (form, 3);
  390.                      reltoform  (samp, form, &rec);
  391.                      fm_refrall (form);
  392.                    }
  393.                   break;
  394.                 }
  395.                if (form->key == -1)
  396.                 { do_error   ("add aborted");
  397.                   fm_mode    (form, 2);
  398.                   fm_zero    (form);
  399.                   fm_refrall (form);
  400.                   formtorel  (form, samp, &rec);
  401.                   break;
  402.                 }
  403.               break;
  404.  
  405.       case 3:  if (form->key == 4)
  406.                 { if (! verify ("delete this record ? [yN] "))
  407.                    { do_error ("delete aborted");
  408.                      break;
  409.                    }
  410.                   do_error ("wait...");
  411.                   if (mb_del (samp) != MB_OKAY)
  412.                    { do_error (mb_error);
  413.                      break;
  414.                    }
  415.                   fm_zero    (form);
  416.                   formtorel  (form, samp, &rec);
  417.                   fm_refrall (form);
  418.                   do_error ("record deleted");
  419.                   break;
  420.                 }
  421.                if (form->key == 1)
  422.                 { formtorel (form, samp, &rec);
  423.                   do_error ("wait...");
  424.                   if (mb_upd (samp, &rec) != MB_OKAY)
  425.                      do_error (mb_error);
  426.                   else
  427.                      do_error ("record updated successfully");
  428.                   break;
  429.                 }
  430.                if (form->key == -1)
  431.                 { do_error   ("change aborted");
  432.                   fm_mode    (form, 2);
  433.                   fm_zero    (form);
  434.                   fm_refrall (form);
  435.                   formtorel  (form, samp, &rec);
  436.                   break;
  437.                 }
  438.              break;
  439.     }
  440.  
  441.    return 0;
  442. }
  443.  
  444. /*
  445.  * Stuff copied from vr.c to make life a little easier and a little prettier:
  446.  *
  447.  */
  448.  
  449. void
  450. do_error (line)
  451. char     *line;
  452. {
  453.    move (23, 0);   clrtoeol();  iserr = 0;
  454.    if (! *line)  { refresh(); return; }
  455.    Standout();     addstr (line);
  456.    Standend();     refresh();   iserr = 1;
  457. }
  458.  
  459. int
  460. verify (str)
  461. char   *str;
  462. {
  463.    char  c;
  464.    do_error (str);
  465.    for (;;)
  466.     { c = getarr();
  467.       switch (tolower(c))
  468.        { case 'q': case 'n':  case ' ':   do_error (""); return 0; break;
  469.          case  27: case '\r': case '\n':  do_error (""); return 0; break;
  470.          case 'y':                        do_error (""); return 1; break;
  471.        }
  472.     }
  473. }
  474.  
  475.