*****Listing 1*****


  1: /*
  2:  *  MDBEDIT.C
  3:  *
  4:  *  Program:  Mini-Database
  5:  *  Written by: Leor Zolman
  6:  *  Module:   Edit the Current Database
  7:  */
  8: 
  9: #include <stdio.h>
 10: #include <stdlib.h>
 11: #include <string.h>
 12: #include <ctype.h>
 13: 
 14: #include "mdb.h"
 15: 
 16: static void fix_db(void);
 17: 
 18: #define LIST_RECS 1   /* Edit menu action codes */
 19: #define NEXT      2
 20: #define PREVIOUS  3
 21: #define MODIFY    4
 22: #define NEW       5
 23: #define DELETE    6
 24: #define UNDELETE  7 
 25: #define QUIT      8
 26: #define SELECT    9
 27: #define FIX       10
 28: 
 29: static struct menu_item edit_menu[] =
 30: {
 31:   {LIST_RECS, "List Records"},
 32:   {NEXT, "Go to Next Record"},
 33:   {PREVIOUS, "Go to Previous Record"},
 34:   {MODIFY, "Modify Current Record"},
 35:   {NEW, "Add New Record"},
 36:   {DELETE, "Delete Current Record"},
 37:   {UNDELETE, "Un-Delete Current Record"},
 38:   {SELECT, "Select Record (by Record Number)"},
 39:   {FIX, "Fix Up Database"},
 40:   {QUIT, "Return to Main Menu"},
 41:   {NULL}
 42: };
 43: 
 44: /*
 45:  * Function:    edit_db
 46:  * Purpose:     Perform operations on current Database
 47:  * Parameter:   Database Name
 48:  * Return Value:  None
 49:  */
 50: 
 51: void edit_db(char *db_name)
 52: {
 53:   int cur_rec = 0;  /* current record number */
 54:   struct record *rp;  /* ptr to current record */
 55:   char buf[150];
 56:   int i;
 57:   
 58:   while (1)
 59:   {
 60:     rp = RECS[cur_rec];
 61:     printf("\nDatabase: %s\n", db_name);
 62:     if (n_recs)
 63:     {
 64:       printf("Current Record is #%d", cur_rec);
 65:       if (!rp->active)
 66:         printf(" (Deleted)");
 67:       printf(":\n");
 68: 
 69:       printf("Name:   %s %s\n", rp->first, rp->last);
 70:       printf("ID#:    %ld\n", rp->id);
 71:       printf("Age:    %d\n", rp->age);
 72:       printf("Gender: %c\n", rp->gender);
 73:       printf("Salary: $%.2f\n", rp->salary);
 74:     }
 75:     
 76:     switch(do_menu(edit_menu, "Edit Menu"))
 77:     {
 78:       case LIST_RECS:
 79:         for (i = 0; i < n_recs; i++)
 80:           printf("%4d: %s%s\n", i, RECS[i]->last,
 81:             RECS[i]->active ? "" : " (Deleted)");
 82:         printf("Press RETURN to continue:");
 83:         gets(buf);
 84:         break;
 85:           
 86:       case NEXT:      /* find next active record: */
 87:         for (i = cur_rec + 1; i < n_recs; i++)
 88:           if (RECS[i]->active) /* skip inactives */
 89:             break;
 90:         if (i == n_recs)       /* over the top? */
 91:         {
 92:           printf("\aAt end of file.\n");
 93:           break;
 94:         }
 95:         cur_rec = i;
 96:         break;
 97:         
 98:       case PREVIOUS:  /* find previous active record: */
 99:         for (i = cur_rec - 1; i >= 0; i--)
100:           if (RECS[i]->active) /* skip inactives */
101:             break;
102:         if (i < 0)       /* "under the bottom"? */
103:         {
104:           printf("\aAt beginning of file.\n");
105:           break;
106:         }
107:         cur_rec = i;
108:         break;
109:                 
110:       case NEW:
111:         if (n_recs+1 > max_recs)
112:         {
113:           printf("Maximum # of records ");
114:           printf("(%d) reached.\n", max_recs);
115:           break;
116:         }
117: 
118:         if ((rp = alloc_rec()) == NULL)
119:         {
120:           printf("Out of memory. Try Fixing ");
121:           printf("Database first...\n");
122:           break;
123:         }
124:                    /* make new record current:  */
125:         cur_rec = n_recs++;
126:         RECS[cur_rec] = rp;
127:         rp->active = TRUE;
128: 
129:         strcpy(rp->last,""); /* initialize the record */
130:         strcpy(rp->first,"");
131:         rp->id = 0;
132:         rp->age = 0;
133:         rp->gender = ' ';
134:         rp->salary = 0.;  /*  fall through to MODIFY  */
135:         
136:       case MODIFY:
137:         printf("Last Name [%s]: ", rp->last);
138:         if (strlen(gets(buf)) > 0)
139:           strcpy(rp->last, buf);
140:           
141:         printf("First Name [%s]: ", rp->first);
142:         if (strlen(gets(buf)) > 0)
143:           strcpy(rp->first, buf);
144: 
145:         printf("ID# [%ld]: ", rp->id);
146:         if (strlen(gets(buf)) > 0)
147:           rp->id = atol(buf);
148:         
149:         printf("Age [%d] ", rp->age);
150:         if (strlen(gets(buf)) > 0)
151:           rp->age = atoi(buf);
152:         
153:         printf("Gender [%c]: ", rp->gender);
154:         if (strlen(gets(buf)) > 0)
155:           rp->gender = toupper(*buf);
156:         
157:         printf("Salary [%.2f]: ", rp->salary);
158:         if (strlen(gets(buf)) > 0)
159:           rp->salary = (float) atof(buf);
160:         break;
161:       
162:       case DELETE:
163:         if (!rp->active)
164:         {
165:           printf("Record is already deleted.\n");
166:           break;
167:         }
168:         printf("Press 'y' to delete record,\n");
169:         printf("anything else to abort: ");
170:         gets(buf);
171:         if (tolower(*buf) == 'y')
172:           rp->active = FALSE;
173:         break;
174:         
175:       case UNDELETE:
176:         if (rp->active)
177:         {
178:           printf("Record is not deleted.\n");
179:           break;
180:         }
181:         rp->active = TRUE;
182:         printf("Record restored.\n");
183:         break;
184: 
185:       case SELECT:
186:         printf("Enter new record number: ");
187:         i = atoi(gets(buf));
188:         if (i < 0 || i > n_recs)
189:         {
190:           printf("Record # out of range.\n");
191:           break;
192:         }
193:         cur_rec = i;
194:         break;
195:         
196:       case FIX:
197:         fix_db();   /* clean up database  */
198:         break;
199:             
200:       case QUIT:
201:         return;
202:     }
203:   }
204: }
205:   
206: /*
207:  * Function:     fix_db
208:  * Purpose:      Purge deleted records, sort Database
209:  * Parameters:   None
210:  * Return Value: None
211:  */
212: 
213: static  int compar( struct record **p1,
214: 					struct record **p2);
215: 
216: static void fix_db()    /* File Fix module */
217: {
218:   int i, new_n_recs;
219:   
220:   for (i = 0, new_n_recs = 0; i < n_recs; i++)
221:   {
222:     RECS[new_n_recs] = RECS[i];
223:     if (RECS[i]->active)
224:       new_n_recs++;
225:     else
226:       free(RECS[i]);
227:   }
228: 
229:   n_recs = new_n_recs;
230:   qsort(RECS, new_n_recs,
231: 		  sizeof(struct record *), compar);
232: }
233: 
234: /*
235:  * Function:	compar
236:  * Purpose:     Comparison function for qsort(), 
237:  *				sorting simply on last name
238:  * Parameters:  Two pointers to record pointers
239:  * Return Value:  As per strcmp()
240:  */
241: 
242: static int compar(struct record **p1,
243: 				  struct record **p2)
244: {
245:   return strcmp((*p1)->last, (*p2)->last);
246: }
