/*********************************************************** * Calendar database rutines. * ************************************************************ * Description: * * * * Created by: Avrami Tzur * * At: Sat Nov 7 20:52:24 1992 * ***********************************************************/ /* INCLUDES */ # include # include /* for printing error messages */ # include # include /* for stat() ** needs types.h ***/ # include # include # include # include "AOPcalendar.h" /* DECLARATIONS */ int apiDbInitilizeDb(char *file_name); int apiDbInsertAppointment(dayAppP rec, int year, int month, int day); dayAppP apiDbGetDateAppointments(int year, int month, int day, int *counter); dayAppP apiDbGetAppointment(int year, int month, int day, int start_time); int apiDbDeleteAppointment(int year, int month, int day, int start_time); int apiDbUpdateAppointment(int year, int month, int day, int start_time, dayAppP rec); static int calOpenFile(char *file_name, char *status); static int calCloseFile(); static void calFreeStruct(); static int calLoadApp(calListP day_rec); static int calStoreInfo(char *file_name); static appListP calGetAppointment(long date, int start_time); static calListP calGetDateRecord(long date, int create_new); static appListP calInsertAppRecord(calListP day_rec, dayAppP app_rec); static void calDeleteAppRecord(appListP app_rec); static void calDeleteDayRecord(calListP day_rec); static int calDateCmp(long date1, long date2); static void calSysError(char *message); static long intToDate(int year, int month, int day); static void dateToInt(long date, int *year, int *month, int *day); static FILE *db_file = NULL ; static calListP cal_list = NULL; static char *db_name ; /* ============================================================ | apiDbInitilizeDb() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 12:35:50 1992 | |==========================================================| */ int apiDbInitilizeDb(char *file_name) { int ret; int i ; calListP temp_list = NULL; char buffer[sizeof(struct dayStruct)]; /* Store the file name. */ /* You might want to play with directory and stuff ... */ if(file_name == NULL) { file_name = ".AOPcal"; } db_name = (char *)malloc(strlen(file_name)+1); strcpy(db_name, file_name); /* Open the file */ if((ret = calOpenFile(db_name, CAL_READ)) == CAL_ERROR) return(ret); if(cal_list != NULL) { /* Free the previus read list */ calFreeStruct(); } /* Load the table. The file format is Date year + month + day + Number of appointment records Record 1 + Record2 + ... Record The days are sorted and the appointment records are sorted by the appointment start time. */ while(!feof(db_file)) { /* Get the date */ if(fread(buffer,sizeof(struct dayStruct),1,db_file) != 1) { if(!feof(db_file)){ calSysError("Error in reading"); return(CAL_ERROR); } else break; } /* Store in record */ if(temp_list == NULL) { /* First element */ cal_list = (calListP)malloc(sizeof(struct calList)); temp_list = cal_list; temp_list->previous = NULL; } else { temp_list->next = (calListP)malloc(sizeof(struct calList)); temp_list->next->previous = temp_list; temp_list = temp_list->next; } temp_list->next = NULL; /* Strore the day structure. */ memcpy((char *)&(temp_list->day_struct),buffer, sizeof(struct dayStruct)); /* Store the appointment records. */ if((ret = calLoadApp(temp_list)) == CAL_ERROR) return(ret); } /* Close the file. */ if((ret = calCloseFile()) == CAL_ERROR) return(ret); return(CAL_OK); } /* ============================================================ | apiDbInsertAppointment() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 17:15:41 1992 | |==========================================================| */ int apiDbInsertAppointment(dayAppP rec, int year, int month, int day) { int found = 0; calListP day_rec; appListP app_rec; long date = intToDate(year, month, day); /* Find the day record. */ day_rec = calGetDateRecord(date, CAL_CREATE); /* Increase the appointmnt counter. */ (day_rec->day_struct.app_counter)++; /* Add the appointment to the appointment list */ app_rec = calInsertAppRecord(day_rec,rec); /* Update the file on disk. */ return(calStoreInfo(NULL)); } /* ============================================================ | apiDbGetDateAppointments() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Tue Nov 10 10:41:16 1992 | |==========================================================| */ dayAppP apiDbGetDateAppointments(int year, int month, int day, int *counter) { long date = intToDate(year, month, day); calListP day_rec = calGetDateRecord(date, CAL_CHECK ); dayAppP app_array; appListP temp; int i; if(day_rec == NULL) { *counter = 0; return(NULL); } else { *counter = day_rec->day_struct.app_counter; app_array = (dayAppP)malloc(sizeof(struct dayApp)*day_rec->day_struct.app_counter); temp = day_rec->app_list; for(i=0; i< *counter; i++) { memcpy((char *)&(app_array[i]), (char *)&(temp->app), sizeof(struct dayApp)); temp = temp->next; } return(app_array); } } /* ============================================================ | apiDbGetAppointment() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Tue Nov 17 13:03:44 1992 | |==========================================================| */ dayAppP apiDbGetAppointment(int year, int month, int day, int start_time) { long date = intToDate(year, month, day); appListP temp = calGetAppointment(date, start_time); dayAppP app; if(temp == NULL) return(NULL); else { app = (dayAppP)malloc(sizeof(struct dayApp)); memcpy((char *)app, (char *)&(temp->app), sizeof(struct dayApp)); return(app); } } /* ============================================================ | apiDbDeleteAppointment() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 17:07:25 1992 | |==========================================================| */ int apiDbDeleteAppointment(int year, int month, int day, int start_time) { long date = intToDate(year, month, day); appListP app_rec = calGetAppointment(date, start_time); if(app_rec == NULL) return(CAL_ERROR); else { /* Delete the record. */ calDeleteAppRecord(app_rec); /* Decrement the appointment counter. */ (app_rec->day_rec->day_struct.app_counter)--; if(app_rec->day_rec->day_struct.app_counter == 0) { /* The last appointment. Delete the day record*/ calDeleteDayRecord(app_rec->day_rec); } /* Update the file on disk. */ return(calStoreInfo(NULL)); } } /* ============================================================ | apiDbUpdateAppointment() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 17:17:08 1992 | |==========================================================| */ int apiDbUpdateAppointment(int year, int month, int day, int start_time, dayAppP rec) { long date = intToDate(year, month, day); appListP app_rec = calGetAppointment(date, start_time); calListP day_rec; if(app_rec == NULL) return(CAL_ERROR); else { day_rec = app_rec->day_rec; /* Delete the old record. */ calDeleteAppRecord(app_rec); /* Insert the new record. */ calInsertAppRecord(day_rec, rec); /* Update the file on disk. */ return(calStoreInfo(NULL)); } } /* ============================================================ | calOpenFile() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : Open the db file. | | | | Returns: | | Created by: Avrami Tzur | | At: Sat Nov 7 22:35:07 1992 | |==========================================================| */ static int calOpenFile(char *file_name, char *status) { db_file = fopen(file_name,status); if(db_file == NULL) { calSysError("Can not open db file"); return(CAL_ERROR); } else return(CAL_OK); } /* ============================================================ | calCloseFile() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Sun Nov 8 00:14:11 1992 | |==========================================================| */ static int calCloseFile() { /* Check that the file is open. */ if(db_file == NULL) { calSysError("db file not open"); return(CAL_ERROR); } fclose(db_file); return(CAL_OK); } /* ============================================================ | calFreeStruct() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 17:52:51 1992 | |==========================================================| */ static void calFreeStruct() { calListP temp12, temp11 = cal_list; appListP temp21, temp22; /* Go over all the days. */ while(temp11 != NULL) { temp21 = temp11->app_list; /* Go over all the appointments. */ while(temp21 != NULL){ temp22 = temp21->next; free(temp21); temp21 = temp22; } temp12 = temp11->next; free(temp11); temp11 = temp12; } cal_list = NULL; } /* ============================================================ | calLoadApp() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 13:22:55 1992 | |==========================================================| */ static int calLoadApp(calListP day_rec) { appListP temp = NULL; int i; for(i=0; iday_struct.app_counter; i++) { /* Allocate a record */ if(temp == NULL) { /* First record. */ day_rec->app_list = (appListP)malloc(sizeof(struct appList)); temp = day_rec->app_list; temp->previous = NULL; } else { temp->next = (appListP)malloc(sizeof(struct appList)); temp->next->previous = temp; temp = temp->next; } temp->day_rec = day_rec; temp->next = NULL; /* Read a record */ if(fread((char *)&(temp->app),sizeof(struct dayApp),1,db_file) != 1) { calSysError("Error in reading"); return(CAL_ERROR); } } return(CAL_OK); } /* ============================================================ | calStoreInfo() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 13:35:16 1992 | |==========================================================| */ static int calStoreInfo(char *file_name) { int ret, i, items; calListP temp_list = NULL; appListP app_list; /* Open the file */ if(file_name == NULL) file_name = db_name; if((ret = calOpenFile(file_name, CAL_WRITE)) == CAL_ERROR) return(ret); /* Store the info */ temp_list = cal_list; while(temp_list != NULL) { if(temp_list->day_struct.app_counter != 0) { /* Write the day record. */ if((items = fwrite((char *)&(temp_list->day_struct), sizeof(struct dayStruct), 1, db_file)) != 1) { calSysError("Unable to write to db file"); return(CAL_ERROR); } /* Write the appointments. */ app_list = temp_list->app_list; for(i=0; iday_struct.app_counter; i++) { if((items = fwrite((char *)&(app_list->app), sizeof(struct dayApp), 1, db_file)) != 1) { calSysError("Unable to write to db file"); return(CAL_ERROR); } app_list = app_list->next; } } temp_list = temp_list->next; } /* Close the file. */ if((ret = calCloseFile()) == CAL_ERROR) return(ret); return(CAL_OK); } /* ============================================================ | calGetAppointment() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Tue Nov 17 13:58:53 1992 | |==========================================================| */ static appListP calGetAppointment(long date, int start_time) { calListP day_rec = calGetDateRecord(date, CAL_CHECK ); appListP temp; int i; if(day_rec == NULL) { return(NULL); } else { temp = day_rec->app_list; for(i=0; iday_struct.app_counter; i++) { if(temp->app.start >= start_time) break; else temp = temp->next; } if(temp == NULL) return(NULL); else { if(temp->app.start == start_time) return(temp); else return(NULL); } } } /* ============================================================ | calGetDateRecord() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 16:12:35 1992 | |==========================================================| */ static calListP calGetDateRecord(long date, int create_new) { int found = 0; calListP day_nex, day_pre, day_rec; appListP app_list; int day_comp; /* Find the date. */ day_pre = NULL; day_nex = cal_list; while(day_nex != NULL) { day_comp = calDateCmp(day_nex->day_struct.date,date); if(day_comp != DAY_COMPARE_BEFORE) { found = (day_comp == DAY_COMPARE_EQUAL); break; } else { day_pre = day_nex; day_nex = day_nex->next; } } if(!create_new) return((found) ? day_nex: NULL); if(!found) { /* Date record not found. Create a new one. */ day_rec = (calListP)malloc(sizeof(struct calList)); day_rec->day_struct.date = date; day_rec->day_struct.app_counter = 0; day_rec->app_list = NULL; /* Conect the new record to the previous record */ day_rec->previous = day_pre; if(day_pre == NULL) { /* The new is the first. */ cal_list = day_rec; } else { day_pre->next = day_rec; } /* Conect the new record to the next record. */ day_rec->next = day_nex; if(day_nex != NULL) { /* Conect the next backwards. */ day_nex->previous = day_rec; } } else day_rec = day_nex; return(day_rec); } /* ============================================================ | calInsertAppRecord() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 16:22:26 1992 | |==========================================================| */ static appListP calInsertAppRecord(calListP day_rec, dayAppP app_rec) { appListP nex_rec, new_rec, pre_rec; /* Find the insertion point. */ pre_rec = NULL; nex_rec = day_rec->app_list; while(nex_rec != NULL) { if(nex_rec->app.start <= app_rec->start) { pre_rec = nex_rec; nex_rec = nex_rec->next; } else break; } /* Create a new record. */ new_rec = (appListP)malloc(sizeof(struct appList)); memcpy((char *)&(new_rec->app), (char *)app_rec, sizeof(struct dayApp)); new_rec->day_rec = day_rec; /* Connect backwards. */ new_rec->previous = pre_rec; if(pre_rec == NULL) { /* The first in the list. */ day_rec->app_list = new_rec; } else { pre_rec->next = new_rec; } /* Conect forward. */ new_rec->next = nex_rec; if(nex_rec != NULL) nex_rec->previous = new_rec; return(new_rec); } /* ============================================================ | calDeleteAppRecord() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 17:08:06 1992 | |==========================================================| */ static void calDeleteAppRecord(appListP app_rec) { if(app_rec->previous == NULL) { /* It was the first one. */ app_rec->day_rec->app_list = app_rec->next; } else app_rec->previous->next = app_rec->next; if(app_rec->next != NULL) { app_rec->next->previous = app_rec->previous; } /* Free the memory. */ free(app_rec); } /* ============================================================ | calDeleteDayRecord() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 17:22:38 1992 | |==========================================================| */ static void calDeleteDayRecord(calListP day_rec) { if(day_rec->previous == NULL) { /* It was the first one. */ cal_list = day_rec->next; } else day_rec->previous->next = day_rec->next; if(day_rec->next != NULL) { day_rec->next->previous = day_rec->previous; } /* Free the memory. */ free(day_rec); } /* ============================================================ | calDateComp() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Mon Nov 9 17:57:51 1992 | |==========================================================| */ static int calDateCmp(long date1, long date2) { return((date1 == date2)? DAY_COMPARE_EQUAL : ((date1 > date2)?DAY_COMPARE_BEFORE : DAY_COMPARE_AFTER)); } /* ============================================================ | calSysError() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Sun Nov 8 00:12:30 1992 | |==========================================================| */ static void calSysError(char *message) { printf("\n\n\nERROR\n%s\n\n\n",message); } /* ============================================================ | intToDate() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Tue Nov 17 13:25:59 1992 | |==========================================================| */ static long intToDate(int year, int month, int day) { return(year*10000 + month*100 + day); } /* ============================================================ | dateToInt() | |----------------------------------------------------------| | Params : 1) | | 2) | | 3) | | Desc : | | | | Returns: | | Created by: Avrami Tzur | | At: Tue Nov 17 13:27:56 1992 | |==========================================================| */ static void dateToInt(long date, int *year, int *month, int *day) { *year = date / 10000; date = date % 10000; *month = date / 100; *day = date % 100; }