diff --git a/BuildDataBase.c b/BuildDataBase.c index c18da7aaa8ef4b3b98b5426841743611361a3081..8d75e78fb854125bc090516fcadb6870ec883730 100644 --- a/BuildDataBase.c +++ b/BuildDataBase.c @@ -60,6 +60,9 @@ char* remove_quotes(); // Removes quotes from string value. void print_all_songs(); // Prints info for all songs in array. void print_song_info(); // Prints all info for provided song. void sort_array(); // Sorts array by song name. +void save_array(); // Saves entire array to file(s). +void save_line(); // Creates/saves single line of song data. +void write_song_field(); // Writes a single song_filed to file. void exit_program(); // Frees memory and closes program. @@ -69,14 +72,15 @@ void exit_program(); // Frees memory and closes program. */ int main(int argc, char* argv[]) { songs_array = calloc(songs_array_max, sizeof(songs_struct *)); - int file_descriptor = open_file(); + int file_descriptor = open_file("Data/SongCSV_Small.csv", O_RDONLY); read_file(file_descriptor); - write(1, "\n\n\n\n\n", 10); - print_all_songs(); - write(1, "\nSorting...\n\n\n", 15); - sort_array(); - print_all_songs(); - + write(1, "\n\n\n\n\n", 6); + //print_all_songs(); + //write(1, "\nSorting...\n\n\n", 15); + //sort_array(); + //print_all_songs(); + save_array(); + close(file_descriptor); exit_program(); } @@ -84,10 +88,24 @@ int main(int argc, char* argv[]) { /** * Opens file. */ -int open_file() { - int file_descriptor = open("Data/SongCSV_Small.csv", O_RDONLY); - if (file_descriptor < 0) { - err_sys("Failed to open file."); +int open_file(char* file_location, int operator_flags) { + int file_descriptor; + if ((operator_flags == (O_CREAT | O_APPEND | O_WRONLY)) || + (operator_flags == (O_CREAT | O_TRUNC | O_WRONLY))) { + // Handle for creating file. + // Umask for issues with other_write privledges not assigning. + mode_t oldval = umask(0); + file_descriptor = open(file_location, operator_flags, 0777); + //S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH); + umask(oldval); + if (file_descriptor < 0) { + err_sys("Failed to open file."); + } + } else { // Handle for all else. + file_descriptor = open(file_location, operator_flags); + if (file_descriptor < 0) { + err_sys("Failed to open file."); + } } return file_descriptor; } @@ -243,7 +261,7 @@ void populate_array(int field_number, char *field_buffer) { temp_float_ptr = &temp_float; songs_array[song_index]->duration = copy_float(temp_float_ptr); break; - case 14: // Hotttness. + case 14: // Hotttnesss. temp_double = atof(field_buffer); // Check if NAN. if (temp_double != temp_double) { @@ -336,18 +354,117 @@ void print_all_songs() { void print_song_info(songs_struct* song) { float duration = *song->duration; int year = *song->year; - double hotness = *song->hotttnesss; + double hotttnesss = *song->hotttnesss; printf("Song Name: %s\n", song->song_name); printf("Album Name: %s\n", song->album_name); printf("Artist Name: %s\n", song->artist); printf("Duration: %.2f\n", duration); - printf("year: %d\n", year); - printf("Hotttnesss: %f\n", hotness); + printf("Year: %d\n", year); + printf("Hotttnesss: %f\n", hotttnesss); printf("\n"); } +/** + * Saves array to file. Supposed to act as a permanent "database" of sorts. + */ +void save_array() { + //int file_descriptor = open_file("Data/SongCSV_Small.csv", O_RDONLY); + int song_directory_descriptor = open_file("Data/Song_Directory_Small", O_CREAT | O_TRUNC | O_WRONLY); + int song_binary_descriptor = open_file("Data/BinarySongData_Small", O_CREAT | O_TRUNC | O_WRONLY); + song_index = 0; + + while (songs_array[song_index] != NULL) { + save_line(song_directory_descriptor, song_binary_descriptor); + song_index++; + } + + close(song_directory_descriptor); + close(song_binary_descriptor); +} + + +/** + * Takes a single song from the songs arary and creates buffer to save. + */ +void save_line(int directory_descriptor, int binary_descriptor) { + int current_line_size = 0; + int name_size = ((strlen(songs_array[song_index]->song_name) * sizeof(char)) + 1); + int album_size = ((strlen(songs_array[song_index]->album_name) * sizeof(char)) + 1); + int artist_size = ((strlen(songs_array[song_index]->artist) * sizeof(char)) + 1); + int duration_size = (sizeof(float)); + int hotttnesss_size = (sizeof(double)); + int year_size = (sizeof(int)); + int* current_line_size_ptr = ¤t_line_size; + + printf("SongName: %s\n", songs_array[song_index]->song_name); + printf("Size of SongName: %ld\n", (strlen(songs_array[song_index]->song_name)) * sizeof(char)); + printf("AlbumName: %s\n", songs_array[song_index]->album_name); + printf("Size of AlbumName: %ld\n", (strlen(songs_array[song_index]->album_name)) * sizeof(char)); + printf("Artist: %s\n", songs_array[song_index]->artist); + printf("Size of Artist: %ld\n", (strlen(songs_array[song_index]->artist)) * sizeof(char)); + printf("Duration: %.2f\n", *songs_array[song_index]->duration); + printf("Size of Duration: %ld\n", sizeof(float)); + printf("Hotttnesss: %f\n", *songs_array[song_index]->hotttnesss); + printf("Size of Hotttnesss: %ld\n", sizeof(double)); + printf("Year: %d\n", *songs_array[song_index]->year); + printf("Size of Year: %ld\n", sizeof(int)); + + // Get total song value size by adding field memory together. + current_line_size += name_size; + current_line_size += album_size; + current_line_size += artist_size; + current_line_size += duration_size; + current_line_size += hotttnesss_size; + current_line_size += year_size; + + printf("%d\n", current_line_size); + printf("\n\n"); + + // Save directory values to file. + ssize_t write_size = write(directory_descriptor, current_line_size_ptr, sizeof(int) + 1); + if (write_size < sizeof(int) + 1) { + err_sys("Failed to write to song_directory file."); + } + + off_t offset_size = lseek(directory_descriptor, sizeof(int), SEEK_CUR); + if (offset_size < 0) { + err_sys("Failed to update song_directory write pointer."); + } + + // Create song buffer to save values to file. + // Song Name. + write_song_field(binary_descriptor, songs_array[song_index]->song_name, name_size); + // Album Name. + write_song_field(binary_descriptor, songs_array[song_index]->album_name, album_size); + // Artist Name. + write_song_field(binary_descriptor, songs_array[song_index]->artist, artist_size); + // Duration. + write_song_field(binary_descriptor, songs_array[song_index]->duration, duration_size); + // Hotttnesss. + write_song_field(binary_descriptor, songs_array[song_index]->hotttnesss, hotttnesss_size); + // Year. + write_song_field(binary_descriptor, songs_array[song_index]->year, year_size); +} + + +/** + * Writes single field to file. + */ +void write_song_field(int binary_descriptor, void* field, int field_size) { + ssize_t write_size = write(binary_descriptor, field, field_size); + if (write_size < field_size) { + err_sys("Failed to write to song_directory file."); + } + + off_t offset_size = lseek(binary_descriptor, field_size, SEEK_CUR); + if (offset_size < 0) { + err_sys("Failed to update song_directory write pointer."); + } +} + + /** * Frees remaining memory and so program can close cleanly. */