diff --git a/README.md b/README.md index 7f88bca7044d0ca2ae32f35f5ba70ec282c147f3..4d798eed24f259c7da72045092096c2aabd856e2 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,8 @@ make Les tests unitaires sont situées dans le dossier `src/tests`. +Framework de test unitaire utilisé : [Unity Test](https://github.com/ThrowTheSwitch/Unity) + ``` cd src make run_tests -s diff --git a/main.c b/main.c deleted file mode 100644 index 335f9299cca7eb6c3d6052c76afe283b8d1bce47..0000000000000000000000000000000000000000 --- a/main.c +++ /dev/null @@ -1,157 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -#include "Directory.h" -#include "DirectoryRecord.h" - -void clear_buffer() { - int c; - while ((c = getchar()) != '\n' && c != EOF) { - } -} - -void append_record(Directory *directory) { - char phone_number[PHONE_NUMBER_MAXLEN]; - printf("Enter the phone number: "); - scanf("%10s", phone_number); - clear_buffer(); - - char name[NAME_MAXLEN]; - printf("Enter the name: "); - scanf("%20s", name); - clear_buffer(); - - char surname[SURNAME_MAXLEN]; - printf("Enter the surname: "); - scanf("%20s", surname); - clear_buffer(); - - int birth_date_year, birth_date_month, birth_date_day; - do { - printf("Enter the birth date (Y-m-d): "); - } while (scanf("%d-%d-%d", &birth_date_year, &birth_date_month, &birth_date_day) != 3); - - clear_buffer(); - printf("\nIs the information entered correct? (Y/n) "); - - char choice = getchar(); - if (choice != '\n') { - getchar(); - } - - if (choice == 'n') { - printf("\n===>The procedure has been cancelled.\n"); - } else { - DirectoryRecord *record = DirectoryRecord_init(false, phone_number, name, surname, birth_date_year, birth_date_month, birth_date_day); - - if (Directory_append(directory, record)) { - printf("\n===>The record has been saved in the directory.\n"); - } else { - printf("\n===>This phone number is already associated with a record. The record has not been saved.\n"); - } - - DirectoryRecord_destroy(&record); - } -} - -void search_record(Directory *directory) { - printf("Enter the phone number that corresponds to the record you are looking for: "); - char phone_number[PHONE_NUMBER_MAXLEN]; - scanf("%10s", phone_number); - clear_buffer(); - DirectoryRecord *record = Directory_search(directory, phone_number); - printf("\n"); - - if (record == NULL) { - printf("===>No records were found for this phone number.\n"); - } else { - printf("========================\n"); - DirectoryRecord_print(record); - DirectoryRecord_destroy(&record); - printf("========================\n"); - } -} - -void delete_record(Directory *directory) { - printf("Enter the phone number that corresponds to the record you wish to delete: "); - - char phone_number[PHONE_NUMBER_MAXLEN]; - scanf("%10s", phone_number); - clear_buffer(); - DirectoryRecord *record = Directory_search(directory, phone_number); - printf("\n"); - - if (record == NULL) { - printf("===>No records were found for this phone number.\n"); - } else { - printf("========================\n"); - DirectoryRecord_print(record); - DirectoryRecord_destroy(&record); - printf("========================\n"); - - printf("\nAre you sure you want to delete this record? (Y/n) "); - - char choice = getchar(); - if (choice != '\n') { - getchar(); - } - - if (choice == 'n') { - printf("\n===>The procedure has been cancelled.\n"); - } else { - Directory_delete(directory, phone_number); - printf("The record has been deleted from the directory.\n"); - } - } -} - -int main() { - Directory *directory = Directory_init("directory_database"); - - while (true) { - BPTree_print(directory->index, 0); - - printf("Enter 1 to add a member.\n"); - printf("Enter 2 to search for a member via their phone number.\n"); - printf("Enter 3 to delete a member.\n"); - printf("Enter 4 to display all members.\n"); - printf("Enter 5 to exit the program.\n"); - printf("What do you want to do? "); - int action; - scanf("%d", &action); - clear_buffer(); - - if (action < 1 || action > 5) { - system("clear"); - continue; - } - - if (action == 5) { - break; - } - - printf("\n"); - - switch (action) { - case 1: - append_record(directory); - break; - case 2: - search_record(directory); - break; - case 3: - delete_record(directory); - break; - case 4: - Directory_print(directory); - break; - } - - printf("\nPress enter to continue..."); - getchar(); - system("clear"); - } - - Directory_destroy(&directory); - return EXIT_SUCCESS; -} diff --git a/src/Array.c b/src/Array.c index 7cc71bc782cd6a1cad88029f6263eeb20b7130a2..86cd61e0c4098ef4e044c91a32d14954292d7d28 100644 --- a/src/Array.c +++ b/src/Array.c @@ -1,9 +1,8 @@ /** * @file Array.c * @author Florian Burgener (florian.burgener@etu.hesge.ch) - * @brief * @version 1.0 - * @date 2022-06-XX + * @date 2022-06-17 */ #include "Array.h" diff --git a/src/Array.h b/src/Array.h index dd08a7a95d1109d2848fecf7ca4d85314a5f633b..7da6e0000107edbfa3afa51d4cdd1976d561bf45 100644 --- a/src/Array.h +++ b/src/Array.h @@ -1,9 +1,8 @@ /** * @file Array.h * @author Florian Burgener (florian.burgener@etu.hesge.ch) - * @brief Implementation of 3 arrays: IntegerArray, BPTreeNodeArray and ByteArray. * @version 1.0 - * @date 2022-06-XX + * @date 2022-06-17 */ #ifndef ARRAY_H #define ARRAY_H diff --git a/src/BPTree.c b/src/BPTree.c index 52f9a313e8acf85d3c47d6785b24d2022c5474a9..42fc33a0dafeeb8e4c70daac02443c6d328da270 100644 --- a/src/BPTree.c +++ b/src/BPTree.c @@ -1,9 +1,8 @@ /** * @file BPTree.c * @author Florian Burgener (florian.burgener@etu.hesge.ch) - * @brief * @version 1.0 - * @date 2022-06-XX + * @date 2022-06-17 */ #include "BPTree.h" @@ -16,6 +15,13 @@ // BPTreeNode +/** + * @brief Initializes the "BPTreeNode" data structure. + * + * @param order The order of the node. + * @param is_leaf false = the node is not a leaf, true = the node is a leaf. + * @return BPTreeNode* The initialized node. + */ static BPTreeNode *BPTreeNode_init(int order, bool is_leaf) { BPTreeNode *root = (BPTreeNode *)malloc(sizeof(BPTreeNode)); root->order = order; @@ -27,6 +33,11 @@ static BPTreeNode *BPTreeNode_init(int order, bool is_leaf) { return root; } +/** + * @brief Destroys the node and free its memory. + * + * @param node The node to be destroyed. + */ static void BPTreeNode_destroy(BPTreeNode **node) { IntegerArray_destroy(&(*node)->keys); IntegerArray_destroy(&(*node)->data); diff --git a/src/BPTree.h b/src/BPTree.h index 3f5842436050cdfd1e6121167fa69610c8b5501a..77a0daeb9fbe91848d0f8a330f43218bc2f92cb9 100644 --- a/src/BPTree.h +++ b/src/BPTree.h @@ -1,9 +1,8 @@ /** * @file BPTree.h * @author Florian Burgener (florian.burgener@etu.hesge.ch) - * @brief * @version 1.0 - * @date 2022-06-XX + * @date 2022-06-17 */ #ifndef BPTREE_H #define BPTREE_H @@ -13,6 +12,10 @@ #include "Array.h" +/** + * @brief Data structure that represents a B+ Tree. + * + */ typedef struct BPTreeNode { int order; bool is_leaf; @@ -22,12 +25,59 @@ typedef struct BPTreeNode { struct BPTreeNode *next; } BPTreeNode; +/** + * @brief Initializes the B+ Tree data structure. + * + * @param order The order of the B+ Tree. + * @return BPTreeNode* An empty B+ Tree. + */ BPTreeNode *BPTree_init(int order); + +/** + * @brief Destroys the B+ Tree and free its memory. + * + * @param root The root of the B+ Tree. + */ void BPTree_destroy(BPTreeNode **root); +/** + * @brief Displays the B+ Tree. + * + * @param root The root of the B+ Tree. + * @param depth Pass the value 0. + */ void BPTree_print(BPTreeNode *root, int depth); + +/** + * @brief Searches for a key in the B+ Tree. + * + * @param root The root of the B+ Tree. + * @param key The key to search. + * @param data The data found will be assigned to this variable. + * @return true The key exists in the B+ Tree. + * @return false The key does not exist in the B+ Tree. + */ bool BPTree_search(BPTreeNode *root, uint64_t key, uint64_t *data); + +/** + * @brief Inserts a key in the B+ Tree. + * + * @param root The root of the B+ Tree. + * @param key The key to insert. + * @param data The data to be inserted with the key. + * @return true The key could be inserted. + * @return false The key could not be inserted. + */ bool BPTree_insert(BPTreeNode *root, uint64_t key, uint64_t data); + +/** + * @brief Deletes a key from the B+ Tree. + * + * @param root The root of the B+ Tree. + * @param key The key to be deleted. + * @return true The key could be deleted. + * @return false The key could not be deleted. + */ bool BPTree_delete(BPTreeNode *root, uint64_t key); #endif diff --git a/src/Directory.c b/src/Directory.c index f1eef3971da47d6ca8b73c8fd380a268272c316f..3c15e494ded7751b477b67ba54465131e3e35dd8 100644 --- a/src/Directory.c +++ b/src/Directory.c @@ -1,9 +1,8 @@ /** * @file Directory.c * @author Florian Burgener (florian.burgener@etu.hesge.ch) - * @brief * @version 1.0 - * @date 2022-06-XX + * @date 2022-06-17 */ #include "Directory.h" @@ -17,6 +16,12 @@ #include "BPTree.h" #include "DirectoryRecord.h" +/** + * @brief Hashes a string with the SHA-256 algorithm and keeps the first 64 bits. + * + * @param str The string to be hashed. + * @return uint64_t The calculated hash. + */ static uint64_t hash_string(char *str) { SHA256_CTX sha256; SHA256_Init(&sha256); @@ -37,6 +42,12 @@ static uint64_t hash_string(char *str) { return truncated_hash; } +/** + * @brief Gets the size of the file. + * + * @param fp The pointer to the file. + * @return long The size of the file in bytes. + */ static long get_file_size(FILE *fp) { fseek(fp, 0, SEEK_END); long file_size = ftell(fp); @@ -44,6 +55,11 @@ static long get_file_size(FILE *fp) { return file_size; } +/** + * @brief Rebuilds the database index. + * + * @param directory The directory. + */ static void rebuild_index(Directory *directory) { FILE *fp; fp = fopen(directory->database_filename, "rb"); @@ -60,16 +76,21 @@ static void rebuild_index(Directory *directory) { fread(&is_deleted, 1, 1, fp); if ((bool)is_deleted) { - fseek(fp, DirectoryRecord_size_on_disk() - 1, SEEK_CUR); + // This record has been deleted, go to the next one. + fseek(fp, DirectoryRecord_size_on_disk() - IS_DELETED_SIZE_IN_BYTES, SEEK_CUR); } else { + // The record has not been deleted. char phone_number[PHONE_NUMBER_MAXLEN]; phone_number[PHONE_NUMBER_MAXLEN - 1] = '\0'; + // The phone number is read. fread(phone_number, 1, PHONE_NUMBER_MAXLEN_WITHOUT_NULL_CHARACTER, fp); + // The record is indexed. BPTree_insert(directory->index, hash_string(phone_number), data_ptr); - fseek(fp, DirectoryRecord_size_on_disk() - 1 - PHONE_NUMBER_MAXLEN_WITHOUT_NULL_CHARACTER, SEEK_CUR); + fseek(fp, DirectoryRecord_size_on_disk() - IS_DELETED_SIZE_IN_BYTES - PHONE_NUMBER_MAXLEN_WITHOUT_NULL_CHARACTER, SEEK_CUR); } if (ftell(fp) == file_size) { + // The end of the file has been reached. break; } } @@ -105,6 +126,7 @@ void Directory_print(Directory *directory) { int i = 0; while (true) { + // Reads and displays all records. ByteArray *byte_array = ByteArray_init(DirectoryRecord_size_on_disk()); fread(byte_array->items, 1, DirectoryRecord_size_on_disk(), fp); @@ -135,6 +157,7 @@ void Directory_print(Directory *directory) { bool Directory_append(Directory *directory, DirectoryRecord *record) { uint64_t a; if (BPTree_search(directory->index, hash_string(record->phone_number), &a)) { + // The phone number is already used in another record. return false; } @@ -159,46 +182,48 @@ bool Directory_append(Directory *directory, DirectoryRecord *record) { DirectoryRecord *Directory_search(Directory *directory, char phone_number[PHONE_NUMBER_MAXLEN]) { uint64_t data_ptr; - if (BPTree_search(directory->index, hash_string(phone_number), &data_ptr)) { - FILE *fp; - fp = fopen(directory->database_filename, "rb"); - - if (fp == NULL) { - exit(EXIT_FAILURE); - } + if (!BPTree_search(directory->index, hash_string(phone_number), &data_ptr)) { + // The record was not found. + return NULL; + } - fseek(fp, data_ptr, SEEK_SET); - ByteArray *byte_array = ByteArray_init(DirectoryRecord_size_on_disk()); - fread(byte_array->items, 1, DirectoryRecord_size_on_disk(), fp); - byte_array->size = DirectoryRecord_size_on_disk(); - fclose(fp); + FILE *fp; + fp = fopen(directory->database_filename, "rb"); - DirectoryRecord *record = ByteArray_to_DirectoryRecord(byte_array); - ByteArray_destroy(&byte_array); - return record; + if (fp == NULL) { + exit(EXIT_FAILURE); } - return NULL; + fseek(fp, data_ptr, SEEK_SET); + ByteArray *byte_array = ByteArray_init(DirectoryRecord_size_on_disk()); + fread(byte_array->items, 1, DirectoryRecord_size_on_disk(), fp); + byte_array->size = DirectoryRecord_size_on_disk(); + fclose(fp); + + DirectoryRecord *record = ByteArray_to_DirectoryRecord(byte_array); + ByteArray_destroy(&byte_array); + return record; } bool Directory_delete(Directory *directory, char phone_number[PHONE_NUMBER_MAXLEN]) { uint64_t data_ptr; - if (BPTree_search(directory->index, hash_string(phone_number), &data_ptr)) { - FILE *fp; - fp = fopen(directory->database_filename, "r+b"); - - if (fp == NULL) { - exit(EXIT_FAILURE); - } + if (!BPTree_search(directory->index, hash_string(phone_number), &data_ptr)) { + // The record to be deleted does not exist. + return false; + } - fseek(fp, data_ptr, SEEK_SET); - uint8_t is_deleted = (uint8_t) true; - fwrite(&is_deleted, 1, 1, fp); - fclose(fp); + FILE *fp; + fp = fopen(directory->database_filename, "r+b"); - BPTree_delete(directory->index, hash_string(phone_number)); - return true; + if (fp == NULL) { + exit(EXIT_FAILURE); } - return false; + fseek(fp, data_ptr, SEEK_SET); + uint8_t is_deleted = (uint8_t) true; + fwrite(&is_deleted, 1, 1, fp); + fclose(fp); + + BPTree_delete(directory->index, hash_string(phone_number)); + return true; } diff --git a/src/Directory.h b/src/Directory.h index 3ed18780cfa5e723a9cbb7c757359c372716de96..6d46a630dce9fcf3855523efeaf4bc5354477d7c 100644 --- a/src/Directory.h +++ b/src/Directory.h @@ -1,9 +1,8 @@ /** * @file Directory.h * @author Florian Burgener (florian.burgener@etu.hesge.ch) - * @brief * @version 1.0 - * @date 2022-06-XX + * @date 2022-06-17 */ #ifndef DIRECTORY_H #define DIRECTORY_H @@ -16,16 +15,64 @@ #define DEFAULT_ORDER 2 #define FILENAME_MAXLEN 100 +/** + * @brief Data structure that represents a directory database. + * + */ typedef struct Directory { char database_filename[FILENAME_MAXLEN]; BPTreeNode *index; } Directory; +/** + * @brief Initializes the "Directory" data structure. + * + * @param database_filename The name of the database file. + * @return Directory* The initialized directory. + */ Directory *Directory_init(char database_filename[FILENAME_MAXLEN]); + +/** + * @brief Destroys the directory and free its memory. + * + * @param directory The directory to be destroyed. + */ void Directory_destroy(Directory **directory); + +/** + * @brief Displays the directory on the console. + * + * @param directory The directory to be displayed. + */ void Directory_print(Directory *directory); + +/** + * @brief Appends a record to the directory. + * + * @param directory The directory in which the record must be added. + * @param record The record to be added. + * @return true The record could be added. + * @return false The record could not be added. + */ bool Directory_append(Directory *directory, DirectoryRecord *record); + +/** + * @brief Searches for a record in the directory via the phone number. + * + * @param directory The directory in which to search. + * @param phone_number The telephone number of the record. + * @return DirectoryRecord* The corresponding record, NULL if not found. + */ DirectoryRecord *Directory_search(Directory *directory, char phone_number[PHONE_NUMBER_MAXLEN]); + +/** + * @brief Deletes a record from the directory. + * + * @param directory The directory in which the record must be deleted. + * @param phone_number The telephone number of the record. + * @return true The record could be deleted. + * @return false The record could not be deleted. + */ bool Directory_delete(Directory *directory, char phone_number[PHONE_NUMBER_MAXLEN]); #endif diff --git a/src/DirectoryRecord.c b/src/DirectoryRecord.c index 55e4da42492bd54c0e374b99b83b89012d9b2401..bf6be638b8c0852d1c84c1c85b94f0a0aa2ad1d4 100644 --- a/src/DirectoryRecord.c +++ b/src/DirectoryRecord.c @@ -1,9 +1,8 @@ /** * @file DirectoryRecord.c * @author Florian Burgener (florian.burgener@etu.hesge.ch) - * @brief A record that represents a member of the organization. * @version 1.0 - * @date 2022-06-XX + * @date 2022-06-17 */ #include "DirectoryRecord.h" @@ -95,7 +94,7 @@ DirectoryRecord *ByteArray_to_DirectoryRecord(ByteArray *byte_array) { char phone_number[PHONE_NUMBER_MAXLEN]; phone_number[PHONE_NUMBER_MAXLEN - 1] = '\0'; - // Read the bytes of the phone number and reconstruct the string of characters. + // Reconstruct the phone number string with the next 10 bytes. for (int j = 0; j < PHONE_NUMBER_MAXLEN_WITHOUT_NULL_CHARACTER; j++) { phone_number[j] = (char)byte_array->items[i]; i++; @@ -104,7 +103,7 @@ DirectoryRecord *ByteArray_to_DirectoryRecord(ByteArray *byte_array) { char name[NAME_MAXLEN]; name[NAME_MAXLEN - 1] = '\0'; - // Read the bytes of the name and reconstruct the string of characters. + // Reconstruct the name string with the next 20 bytes. for (int j = 0; j < NAME_MAXLEN_WITHOUT_NULL_CHARACTER; j++) { name[j] = (char)byte_array->items[i]; i++; @@ -113,13 +112,13 @@ DirectoryRecord *ByteArray_to_DirectoryRecord(ByteArray *byte_array) { char surname[SURNAME_MAXLEN]; surname[SURNAME_MAXLEN - 1] = '\0'; - // Read the bytes of the surname and reconstruct the string of characters. + // Reconstruct the name string with the next 20 bytes. for (int j = 0; j < SURNAME_MAXLEN_WITHOUT_NULL_CHARACTER; j++) { surname[j] = (char)byte_array->items[i]; i++; } - // Reconstitutes the date of birth from the bytes. + // Reconstitutes the date of birth from the last bytes. int birth_date_year = (int)byte_array->items[i] << 8 | (int)byte_array->items[i + 1]; int birth_date_month = (int)byte_array->items[i + 2]; int birth_date_day = (int)byte_array->items[i + 3]; diff --git a/src/DirectoryRecord.h b/src/DirectoryRecord.h index d14e0e25fcaf3fd9bdddcea2569a9bfd2359b69c..dfef158ca8041238a98fb6f84ca0683e0811d72e 100644 --- a/src/DirectoryRecord.h +++ b/src/DirectoryRecord.h @@ -1,9 +1,8 @@ /** * @file DirectoryRecord.h * @author Florian Burgener (florian.burgener@etu.hesge.ch) - * @brief A record that represents a member of the organization. * @version 1.0 - * @date 2022-06-XX + * @date 2022-06-17 */ #ifndef DIRECTORY_RECORD_H #define DIRECTORY_RECORD_H diff --git a/src/main.c b/src/main.c index c91a7574213172dde93901de36605f21e8ce5b38..0daab04e69c157fbcf29b386741df796c52ebfcf 100644 --- a/src/main.c +++ b/src/main.c @@ -1,63 +1,191 @@ /** * @file main.c * @author Florian Burgener (florian.burgener@etu.hesge.ch) - * @brief * @version 1.0 - * @date 2022-06-XX + * @date 2022-06-17 */ -#include <assert.h> +#include <stdio.h> #include <stdlib.h> -#include "Array.h" -#include "BPTree.h" +#include "Directory.h" +#include "DirectoryRecord.h" -int main() { - BPTreeNode *root = BPTree_init(2); +/** + * @brief Empties the buffer. + * + */ +void clear_buffer() { + int c; + while ((c = getchar()) != '\n' && c != EOF) { + } +} + +/** + * @brief Procedure to append a record to the database. + * + * @param directory The directory. + */ +void append_record(Directory *directory) { + // Reads the user entry for the phone number. + char phone_number[PHONE_NUMBER_MAXLEN]; + printf("Enter the phone number: "); + scanf("%10s", phone_number); + clear_buffer(); + + // Reads the user entry for the name. + char name[NAME_MAXLEN]; + printf("Enter the name: "); + scanf("%20s", name); + clear_buffer(); + + // Reads the user entry for the surname. + char surname[SURNAME_MAXLEN]; + printf("Enter the surname: "); + scanf("%20s", surname); + clear_buffer(); - uint64_t input[] = {8, 12, 11, 47, 22, 95, 86, 40, 33, 78, 28, 5, 75, 88, 21, 56, 82, 51, 93, 66, 48, 70, 57, 65, 35, 4, 60, 41, 49, 55, 68, 72, 23, 31, 30, 42, 18, 87, 24, 58}; - IntegerArray *keys = IntegerArray_init(40); - for (int i = 0; i < 30; i++) { - IntegerArray_append(keys, input[i]); + // Loop until three integers are given. + int birth_date_year, birth_date_month, birth_date_day; + do { + printf("Enter the birth date (Y-m-d): "); + } while (scanf("%d-%d-%d", &birth_date_year, &birth_date_month, &birth_date_day) != 3); + + clear_buffer(); + printf("\nIs the information entered correct? (Y/n) "); + + char choice = getchar(); + if (choice != '\n') { + getchar(); } - IntegerArray_print(keys); + if (choice == 'n') { + // The user has cancelled the procedure. + printf("\n===>The procedure has been cancelled.\n"); + return; + } - for (int i = 0; i < keys->size; i++) { - BPTree_insert(root, keys->items[i], keys->items[i] * 1000); + DirectoryRecord *record = DirectoryRecord_init(false, phone_number, name, surname, birth_date_year, birth_date_month, birth_date_day); + + if (Directory_append(directory, record)) { + printf("\n===>The record has been saved in the directory.\n"); + } else { + printf("\n===>This phone number is already associated with a record. The record has not been saved.\n"); } - for (int i = 0; i < keys->size; i++) { - uint64_t data; - bool found = BPTree_search(root, keys->items[i], &data); + DirectoryRecord_destroy(&record); +} + +/** + * @brief Procedure to search for a record in the database. + * + * @param directory The directory. + */ +void search_record(Directory *directory) { + printf("Enter the phone number that corresponds to the record you are looking for: "); + char phone_number[PHONE_NUMBER_MAXLEN]; + scanf("%10s", phone_number); + clear_buffer(); + DirectoryRecord *record = Directory_search(directory, phone_number); + printf("\n"); - assert(found == true); - assert(data == keys->items[i] * 1000); + if (record == NULL) { + printf("===>No records were found for this phone number.\n"); + } else { + printf("========================\n"); + DirectoryRecord_print(record); + DirectoryRecord_destroy(&record); + printf("========================\n"); } +} - BPTree_delete(root, 65); - BPTree_delete(root, 57); - BPTree_delete(root, 47); - BPTree_delete(root, 28); - BPTree_delete(root, 51); - BPTree_insert(root, 100, 100 * 1000); - BPTree_delete(root, 48); - BPTree_delete(root, 41); - BPTree_delete(root, 60); - BPTree_delete(root, 5); - BPTree_delete(root, 8); - BPTree_delete(root, 21); +/** + * @brief Procedure for deleting a record from the database. + * + * @param directory The directory. + */ +void delete_record(Directory *directory) { + printf("Enter the phone number that corresponds to the record you wish to delete: "); + + char phone_number[PHONE_NUMBER_MAXLEN]; + scanf("%10s", phone_number); + clear_buffer(); + DirectoryRecord *record = Directory_search(directory, phone_number); + printf("\n"); + + if (record == NULL) { + printf("===>No records were found for this phone number.\n"); + return; + } + + printf("========================\n"); + DirectoryRecord_print(record); + DirectoryRecord_destroy(&record); + printf("========================\n"); - BPTree_delete(root, 86); - BPTree_delete(root, 100); - BPTree_delete(root, 88); - BPTree_delete(root, 95); - BPTree_delete(root, 49); - BPTree_delete(root, 56); - BPTree_delete(root, 55); + printf("\nAre you sure you want to delete this record? (Y/n) "); + + char choice = getchar(); + if (choice != '\n') { + getchar(); + } + + if (choice == 'n') { + printf("\n===>The procedure has been cancelled.\n"); + } else { + Directory_delete(directory, phone_number); + printf("The record has been deleted from the directory.\n"); + } +} - BPTree_print(root, 0); +int main() { + Directory *directory = Directory_init("directory_database"); + + while (true) { + BPTree_print(directory->index, 0); + + printf("Enter 1 to add a member.\n"); + printf("Enter 2 to search for a member via their phone number.\n"); + printf("Enter 3 to delete a member.\n"); + printf("Enter 4 to display all members.\n"); + printf("Enter 5 to exit the program.\n"); + printf("What do you want to do? "); + int action; + scanf("%d", &action); + clear_buffer(); + + if (action < 1 || action > 5) { + // The action is invalid. + system("clear"); + continue; + } + + if (action == 5) { + // The program is exited. + break; + } + + printf("\n"); + + switch (action) { + case 1: + append_record(directory); + break; + case 2: + search_record(directory); + break; + case 3: + delete_record(directory); + break; + case 4: + Directory_print(directory); + break; + } + + printf("\nPress enter to continue..."); + getchar(); + system("clear"); + } - IntegerArray_destroy(&keys); - BPTree_destroy(&root); + Directory_destroy(&directory); return EXIT_SUCCESS; } diff --git a/src/tests/BPTreeTests.c b/src/tests/BPTreeTests.c index 18d0026a5be0b6d647a0ab850c457c6b267615f8..9b9618a100b374f999f232f5dd68947f9e04a6e4 100644 --- a/src/tests/BPTreeTests.c +++ b/src/tests/BPTreeTests.c @@ -1,9 +1,8 @@ /** * @file BPTreeTests.c * @author Florian Burgener (florian.burgener@etu.hesge.ch) - * @brief Unit tests of the BPTree data structure. * @version 1.0 - * @date 2022-06-XX + * @date 2022-06-17 */ #include <stdbool.h> #include <stdint.h>