From 18b2e7ba8a255cfe7e87c52c38c73ee3b647b316 Mon Sep 17 00:00:00 2001
From: Andrew To <andrewto.307@gmail.com>
Date: Sun, 2 Feb 2025 23:39:09 -0500
Subject: [PATCH] Assignment 2
---
assn2/a2-questions.md | 122 +++
assn2/starter/README.md | 5 +
assn2/starter/db.h | 35 +
assn2/starter/dblayout.png | Bin 0 -> 56255 bytes
assn2/starter/makefile | 29 +
assn2/starter/sdbsc.c | 698 ++++++++++++++++++
assn2/starter/sdbsc.dSYM/Contents/Info.plist | 20 +
.../sdbsc.dSYM/Contents/Resources/DWARF/sdbsc | Bin 0 -> 14308 bytes
assn2/starter/sdbsc.h | 64 ++
assn2/starter/test.sh | 194 +++++
assn2/starter/testload.sh | 6 +
11 files changed, 1173 insertions(+)
create mode 100644 assn2/a2-questions.md
create mode 100644 assn2/starter/README.md
create mode 100644 assn2/starter/db.h
create mode 100644 assn2/starter/dblayout.png
create mode 100644 assn2/starter/makefile
create mode 100644 assn2/starter/sdbsc.c
create mode 100644 assn2/starter/sdbsc.dSYM/Contents/Info.plist
create mode 100644 assn2/starter/sdbsc.dSYM/Contents/Resources/DWARF/sdbsc
create mode 100644 assn2/starter/sdbsc.h
create mode 100755 assn2/starter/test.sh
create mode 100755 assn2/starter/testload.sh
diff --git a/assn2/a2-questions.md b/assn2/a2-questions.md
new file mode 100644
index 0000000..169aab5
--- /dev/null
+++ b/assn2/a2-questions.md
@@ -0,0 +1,122 @@
+## Assignment 2 Questions
+
+#### Directions
+Please answer the following questions and submit in your repo for the second assignment. Please keep the answers as short and concise as possible.
+
+1. In this assignment I asked you provide an implementation for the `get_student(...)` function because I think it improves the overall design of the database application. After you implemented your solution do you agree that externalizing `get_student(...)` into it's own function is a good design strategy? Briefly describe why or why not.
+
+ > **Answer**: I believe it's a good design to include the get_student() function since whenever we want to get a student, we need to move to this position. And we need to do this process in several functions like del_student() or count_db_records(). Also, this design helps our code be readable when choosing the option 'f', so that we can print different outputs, static or from print_student(), based on the return of the get_student() function.
+
+2. Another interesting aspect of the `get_student(...)` function is how its function prototype requires the caller to provide the storage for the `student_t` structure:
+
+ ```c
+ int get_student(int fd, int id, student_t *s);
+ ```
+
+ Notice that the last parameter is a pointer to storage **provided by the caller** to be used by this function to populate information about the desired student that is queried from the database file. This is a common convention (called pass-by-reference) in the `C` programming language.
+
+ In other programming languages an approach like the one shown below would be more idiomatic for creating a function like `get_student()` (specifically the storage is provided by the `get_student(...)` function itself):
+
+ ```c
+ //Lookup student from the database
+ // IF FOUND: return pointer to student data
+ // IF NOT FOUND: return NULL
+ student_t *get_student(int fd, int id){
+ student_t student;
+ bool student_found = false;
+
+ //code that looks for the student and if
+ //found populates the student structure
+ //The found_student variable will be set
+ //to true if the student is in the database
+ //or false otherwise.
+
+ if (student_found)
+ return &student;
+ else
+ return NULL;
+ }
+ ```
+ Can you think of any reason why the above implementation would be a **very bad idea** using the C programming language? Specifically, address why the above code introduces a subtle bug that could be hard to identify at runtime?
+
+ > **ANSWER:** If we return the pointer which is created inside the function to the main, it will cause some bug like segmentation faults since this memory is valid only inside the function and cannot be accessed outside this function. Therefore, if in any line of code outside this function we refer this return, it will cause segmentation error
+
+3. Another way the `get_student(...)` function could be implemented is as follows:
+
+ ```c
+ //Lookup student from the database
+ // IF FOUND: return pointer to student data
+ // IF NOT FOUND or memory allocation error: return NULL
+ student_t *get_student(int fd, int id){
+ student_t *pstudent;
+ bool student_found = false;
+
+ pstudent = malloc(sizeof(student_t));
+ if (pstudent == NULL)
+ return NULL;
+
+ //code that looks for the student and if
+ //found populates the student structure
+ //The found_student variable will be set
+ //to true if the student is in the database
+ //or false otherwise.
+
+ if (student_found){
+ return pstudent;
+ }
+ else {
+ free(pstudent);
+ return NULL;
+ }
+ }
+ ```
+ In this implementation the storage for the student record is allocated on the heap using `malloc()` and passed back to the caller when the function returns. What do you think about this alternative implementation of `get_student(...)`? Address in your answer why it work work, but also think about any potential problems it could cause.
+
+ > **ANSWER:** This works since we dynamically allocate the storage of the student record on the heap. However, this design is not optional since sometimes it will be confused to determine where we should free this memory(if we free this memory inside the function, we can't use it outside. If we don't, we will need to free it in other place in the main function. But it may cause some potential problem about memory leak)
+
+4. Lets take a look at how storage is managed for our simple database. Recall that all student records are stored on disk using the layout of the `student_t` structure (which has a size of 64 bytes). Lets start with a fresh database by deleting the `student.db` file using the command `rm ./student.db`. Now that we have an empty database lets add a few students and see what is happening under the covers. Consider the following sequence of commands:
+
+ ```bash
+ > ./sdbsc -a 1 john doe 345
+ > ls -l ./student.db
+ -rw-r----- 1 bsm23 bsm23 128 Jan 17 10:01 ./student.db
+ > du -h ./student.db
+ 4.0K ./student.db
+ > ./sdbsc -a 3 jane doe 390
+ > ls -l ./student.db
+ -rw-r----- 1 bsm23 bsm23 256 Jan 17 10:02 ./student.db
+ > du -h ./student.db
+ 4.0K ./student.db
+ > ./sdbsc -a 63 jim doe 285
+ > du -h ./student.db
+ 4.0K ./student.db
+ > ./sdbsc -a 64 janet doe 310
+ > du -h ./student.db
+ 8.0K ./student.db
+ > ls -l ./student.db
+ -rw-r----- 1 bsm23 bsm23 4160 Jan 17 10:03 ./student.db
+ ```
+
+ For this question I am asking you to perform some online research to investigate why there is a difference between the size of the file reported by the `ls` command and the actual storage used on the disk reported by the `du` command. Understanding why this happens by design is important since all good systems programmers need to understand things like how linux creates sparse files, and how linux physically stores data on disk using fixed block sizes. Some good google searches to get you started: _"lseek syscall holes and sparse files"_, and _"linux file system blocks"_. After you do some research please answer the following:
+
+ - Please explain why the file size reported by the `ls` command was 128 bytes after adding student with ID=1, 256 after adding student with ID=3, and 4160 after adding the student with ID=64?
+
+ > **ANSWER:** Student with id=x is located starting at byte x * sizeof(student_t), with student_t = 64 bytes. So with any ID=x, it starts at byte 64, and the student data's size is x*64 bytes, so the total is 64*(x+1). Therefore, with x=1, the file size using 'ls' is 128, and 256 and 4160 for ID=3 and ID=64, respectively.
+
+ - Why did the total storage used on the disk remain unchanged when we added the student with ID=1, ID=3, and ID=63, but increased from 4K to 8K when we added the student with ID=64?
+
+ > **ANSWER:** Since the block 4KB is large enough for storing data of student with ID=1, ID=3 or ID=63, since the max size is 64 * 64 = 4096, which is exactly equal to 4KB. With ID=64, the size now is 4160.
+
+ - Now lets add one more student with a large student ID number and see what happens:
+
+ ```bash
+ > ./sdbsc -a 99999 big dude 205
+ > ls -l ./student.db
+ -rw-r----- 1 bsm23 bsm23 6400000 Jan 17 10:28 ./student.db
+ > du -h ./student.db
+ 12K ./student.db
+ ```
+ We see from above adding a student with a very large student ID (ID=99999) increased the file size to 6400000 as shown by `ls` but the raw storage only increased to 12K as reported by `du`. Can provide some insight into why this happened?
+
+ > **ANSWER:** In our code, we are using lseek to move to the position with equivalent ID and store data here. Therefore, our db file is a sparse file, which has "holes", where bytes are all zeros, between real data in the file. Therefore, with ID=99999, we need a file with size 6400000 (since 99999*64 = 6399936). The du command measures the disk space occupied by files or directories. Regarding data storage in disk, it doesn't physically store blocks of zeroes, so we don't need that big space for these "holes"
+
diff --git a/assn2/starter/README.md b/assn2/starter/README.md
new file mode 100644
index 0000000..071387f
--- /dev/null
+++ b/assn2/starter/README.md
@@ -0,0 +1,5 @@
+Name: Andrew To
+ID: dt686
+
+I did the extra credit implementation
+I added the command rm -f .tmp_student.db in Makefile to make it possible to delete the compressed database when we use make test.
\ No newline at end of file
diff --git a/assn2/starter/db.h b/assn2/starter/db.h
new file mode 100644
index 0000000..ac7e122
--- /dev/null
+++ b/assn2/starter/db.h
@@ -0,0 +1,35 @@
+#ifndef __DB_H__
+ #define __DB_H__
+
+// Basic student database record. Note:
+// 1. id must be > 0. A student id==0 means the record has been deleted
+// 2. gpa is an int, should be between 0<=gpa<=500, real gpa is gpa/100.0 this
+// simplifies dealing with floating point types
+// 3. Notice that the student struct was engineered to have a size of
+// 64 bytes. There are reasons for using such a number
+typedef struct student{
+ int id;
+ char fname[24];
+ char lname[32];
+ int gpa;
+} student_t;
+
+//Define limits for sudent ids and allowable GPA ranges. Note GPA values will
+//be stored as integers but printed as floats. For example a GPA of 450 is really
+//that value divided by 100.0 or 4.50.
+#define MIN_STD_ID 1
+#define MAX_STD_ID 100000
+#define MIN_STD_GPA 0
+#define MAX_STD_GPA 500
+
+//some useful constants you should consider using versus hard coding
+//in your program.
+static const student_t EMPTY_STUDENT_RECORD = {0};
+static const int STUDENT_RECORD_SIZE = sizeof(struct student);
+static const int DELETED_STUDENT_ID = 0;
+
+
+#define DB_FILE "student.db" //name of database file
+#define TMP_DB_FILE ".tmp_student.db" //for extra credit
+
+#endif
\ No newline at end of file
diff --git a/assn2/starter/dblayout.png b/assn2/starter/dblayout.png
new file mode 100644
index 0000000000000000000000000000000000000000..0aa1ba5aedd5556d13736f0836a36a9ba492626a
GIT binary patch
literal 56255
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
literal 0
HcmV?d00001
diff --git a/assn2/starter/makefile b/assn2/starter/makefile
new file mode 100644
index 0000000..69c0492
--- /dev/null
+++ b/assn2/starter/makefile
@@ -0,0 +1,29 @@
+# Compiler settings
+CC = gcc
+CFLAGS = -Wall -Wextra -g
+
+# Target executable name
+TARGET = sdbsc
+
+# Find all source and header files
+SRCS = $(wildcard *.c)
+HDRS = $(wildcard *.h)
+
+# Default target
+all: $(TARGET)
+
+# Compile source to executable
+$(TARGET): $(SRCS) $(HDRS)
+ $(CC) $(CFLAGS) -o $(TARGET) $(SRCS)
+
+# Clean up build files
+clean:
+ rm -f $(TARGET)
+ rm -f student.db
+ rm -f .tmp_student.db
+
+test:
+ ./test.sh
+
+# Phony targets
+.PHONY: all clean
\ No newline at end of file
diff --git a/assn2/starter/sdbsc.c b/assn2/starter/sdbsc.c
new file mode 100644
index 0000000..7943b08
--- /dev/null
+++ b/assn2/starter/sdbsc.c
@@ -0,0 +1,698 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h> //c library for system call file routines
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+// database include files
+#include "db.h"
+#include "sdbsc.h"
+
+/*
+ * open_db
+ * dbFile: name of the database file
+ * should_truncate: indicates if opening the file also empties it
+ *
+ * returns: File descriptor on success, or ERR_DB_FILE on failure
+ *
+ * console: Does not produce any console I/O on success
+ * M_ERR_DB_OPEN on error
+ *
+ */
+int open_db(char *dbFile, bool should_truncate)
+{
+ // Set permissions: rw-rw----
+ // see sys/stat.h for constants
+ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
+
+ // open the file if it exists for Read and Write,
+ // create it if it does not exist
+ int flags = O_RDWR | O_CREAT;
+
+ if (should_truncate)
+ flags += O_TRUNC;
+
+ // Now open file
+ int fd = open(dbFile, flags, mode);
+
+ if (fd == -1)
+ {
+ // Handle the error
+ printf(M_ERR_DB_OPEN);
+ return ERR_DB_FILE;
+ }
+
+ return fd;
+}
+
+/*
+ * get_student
+ * fd: linux file descriptor
+ * id: the student id we are looking forname of the
+ * *s: a pointer where the located (if found) student data will be
+ * copied
+ *
+ * returns: NO_ERROR student located and copied into *s
+ * ERR_DB_FILE database file I/O issue
+ * SRCH_NOT_FOUND student was not located in the database
+ *
+ * console: Does not produce any console I/O used by other functions
+ */
+int get_student(int fd, int id, student_t *s)
+{
+ // TODO
+ int offset = id * sizeof(student_t);
+
+ lseek(fd, offset, SEEK_SET);
+
+ student_t curr;
+ int read_byte = read(fd, &curr, sizeof(student_t));
+ student_t check = {0};
+
+ if (read_byte == -1){
+ printf(M_ERR_DB_READ);
+ return ERR_DB_FILE;
+ }
+
+ if (memcmp(&curr, &check, read_byte) == 0 || read_byte != sizeof(student_t)){
+ return SRCH_NOT_FOUND;
+ }
+
+ *s = curr;
+
+ return NO_ERROR;
+}
+
+/*
+ * add_student
+ * fd: linux file descriptor
+ * id: student id (range is defined in db.h )
+ * fname: student first name
+ * lname: student last name
+ * gpa: GPA as an integer (range defined in db.h)
+ *
+ * Adds a new student to the database. After calculating the index for the
+ * student, check if there is another student already at that location. A good
+ * way is to use something like memcmp() to ensure that the location for this
+ * student contains all zero byes indicating the space is empty.
+ *
+ * returns: NO_ERROR student added to database
+ * ERR_DB_FILE database file I/O issue
+ * ERR_DB_OP database operation logically failed (aka student
+ * already exists)
+ *
+ *
+ * console: M_STD_ADDED on success
+ * M_ERR_DB_ADD_DUP student already exists
+ * M_ERR_DB_READ error reading or seeking the database file
+ * M_ERR_DB_WRITE error writing to db file (adding student)
+ *
+ */
+int add_student(int fd, int id, char *fname, char *lname, int gpa)
+{
+ // TODO
+ student_t new_student;
+ strcpy(new_student.fname, fname);
+ strcpy(new_student.lname, lname);
+ new_student.id = id;
+ new_student.gpa = gpa;
+
+ int offset = id * sizeof(student_t);
+
+ if (lseek(fd, offset, SEEK_SET) == -1){
+ printf(M_ERR_DB_READ);
+ return ERR_DB_FILE;
+ }
+
+ student_t curr;
+ int read_byte = read(fd, &curr, sizeof(curr));
+ student_t check = {0};
+
+ if (read_byte == -1){
+ printf(M_ERR_DB_READ);
+ return ERR_DB_FILE;
+ }
+
+ if (memcmp(&curr, &check, read_byte) != 0 && read_byte != 0){
+ printf(M_ERR_DB_ADD_DUP, new_student.id);
+ return ERR_DB_OP;
+ }
+
+ lseek(fd, offset, SEEK_SET);
+
+ if (write(fd, &new_student, sizeof(new_student)) == -1){
+ printf(M_ERR_DB_WRITE);
+ return ERR_DB_FILE;
+ }
+
+ printf(M_STD_ADDED, new_student.id);
+
+ return NO_ERROR;
+
+}
+
+/*
+ * del_student
+ * fd: linux file descriptor
+ * id: student id to be deleted
+ *
+ * Removes a student to the database. Use the get_student() function to
+ * locate the student to be deleted. If there is a student at that location
+ * write an empty student record - see EMPTY_STUDENT_RECORD from db.h at
+ * that location.
+ *
+ * returns: NO_ERROR student deleted from database
+ * ERR_DB_FILE database file I/O issue
+ * ERR_DB_OP database operation logically failed (aka student
+ * not in database)
+ *
+ *
+ * console: M_STD_DEL_MSG on success
+ * M_STD_NOT_FND_MSG student not in database, cant be deleted
+ * M_ERR_DB_READ error reading or seeking the database file
+ * M_ERR_DB_WRITE error writing to db file (adding student)
+ *
+ */
+int del_student(int fd, int id)
+{
+ // TODO
+ student_t *s = malloc(sizeof(student_t));
+
+ int i = get_student(fd, id, s);
+
+ int offset = id * sizeof(student_t);
+ int l = lseek(fd, offset, SEEK_SET);
+ if (l == -1){
+ printf(M_ERR_DB_READ);
+ return ERR_DB_FILE;
+ }
+
+ if (i==0){
+ if (write(fd, &EMPTY_STUDENT_RECORD, sizeof(student_t)) < 0){
+ printf(M_ERR_DB_WRITE);
+ return ERR_DB_FILE;
+ }
+ printf(M_STD_DEL_MSG, id);
+ return NO_ERROR;
+ }
+
+ printf(M_STD_NOT_FND_MSG, id);
+
+ free(s);
+ return ERR_DB_OP;
+}
+
+/*
+ * count_db_records
+ * fd: linux file descriptor
+ *
+ * Counts the number of records in the database. Start by reading the
+ * database at the beginning, and continue reading individual records
+ * until you it EOF. EOF is when the read() syscall returns 0. Check
+ * if a slot is empty or previously deleted by investigating if all of
+ * the bytes in the record read are zeros - I would suggest using memory
+ * compare memcmp() for this. Create a counter variable and initialize it
+ * to zero, every time a non-zero record is read increment the counter.
+ *
+ * returns: <number> returns the number of records in db on success
+ * ERR_DB_FILE database file I/O issue
+ * ERR_DB_OP database operation logically failed (aka student
+ * not in database)
+ *
+ *
+ * console: M_DB_RECORD_CNT on success, to report the number of students in db
+ * M_DB_EMPTY on success if the record count in db is zero
+ * M_ERR_DB_READ error reading or seeking the database file
+ * M_ERR_DB_WRITE error writing to db file (adding student)
+ *
+ */
+int count_db_records(int fd)
+{
+ // TODO
+ int record_count = 0;
+ if (lseek(fd, 0, SEEK_SET) == -1){
+ printf(M_ERR_DB_READ);
+ return ERR_DB_FILE;
+ }
+
+ student_t curr;
+ student_t check = {0};
+ int i;
+ while ((i = read(fd, &curr, sizeof(curr))) != 0){
+ if (i == -1){
+ printf(M_ERR_DB_READ);
+ return ERR_DB_FILE;
+ }
+ if (memcmp(&curr, &check, sizeof(check)) != 0){
+ record_count++;
+ }
+ }
+ if(record_count == 0){
+ printf(M_DB_EMPTY);
+ } else {
+ printf(M_DB_RECORD_CNT, record_count);
+ }
+
+ return record_count;
+}
+
+/*
+ * print_db
+ * fd: linux file descriptor
+ *
+ * Prints all records in the database. Start by reading the
+ * database at the beginning, and continue reading individual records
+ * until you it EOF. EOF is when the read() syscall returns 0. Check
+ * if a slot is empty or previously deleted by investigating if all of
+ * the bytes in the record read are zeros - I would suggest using memory
+ * compare memcmp() for this. Be careful as the database might be empty.
+ * on the first real row encountered print the header for the required output:
+ *
+ * printf(STUDENT_PRINT_HDR_STRING, "ID",
+ * "FIRST_NAME", "LAST_NAME", "GPA");
+ *
+ * then for each valid record encountered print the required output:
+ *
+ * printf(STUDENT_PRINT_FMT_STRING, student.id, student.fname,
+ * student.lname, calculated_gpa_from_student);
+ *
+ * The code above assumes you are reading student records into a local
+ * variable named student that is of type student_t. Also dont forget that
+ * the GPA in the student structure is an int, to convert it into a real
+ * gpa divide by 100.0 and store in a float variable.
+ *
+ * returns: NO_ERROR on success
+ * ERR_DB_FILE database file I/O issue
+ *
+ *
+ * console: <see above> on success, print table or database empty
+ * M_ERR_DB_READ error reading or seeking the database file
+ *
+ */
+int print_db(int fd)
+{
+ // TODO
+ student_t student;
+ student_t check = {0};
+ if (read(fd, &student, sizeof(student)) == 0){
+ printf(M_DB_EMPTY);
+ return NO_ERROR;
+ }
+
+ if (lseek(fd, 0, SEEK_SET) == -1){
+ printf(M_ERR_DB_READ);
+ return ERR_DB_FILE;
+ }
+ printf(STUDENT_PRINT_HDR_STRING, "ID", "FIRST_NAME", "LAST_NAME", "GPA");
+ int i;
+ while ((i = read(fd, &student, sizeof(student))) != 0){
+ if (i == -1){
+ printf(M_ERR_DB_READ);
+ return ERR_DB_FILE;
+ }
+ if (memcmp(&student, &check, sizeof(check)) != 0){
+ if (student.id != 0){
+ double calculated_gpa_from_student = (double)student.gpa / 100;
+ printf(STUDENT_PRINT_FMT_STRING, student.id, student.fname, student.lname, calculated_gpa_from_student);
+ }
+ }
+ }
+ return NO_ERROR;
+}
+
+/*
+ * print_student
+ * *s: a pointer to a student_t structure that should
+ * contain a valid student to be printed
+ *
+ * Start by ensuring that provided student pointer is valid. To do this
+ * make sure it is not NULL and that s->id is not zero. After ensuring
+ * that the student is valid, print it the exact way that is described
+ * in the print_db() function by first printing the header then the
+ * student data:
+ *
+ * printf(STUDENT_PRINT_HDR_STRING, "ID",
+ * "FIRST NAME", "LAST_NAME", "GPA");
+ *
+ * printf(STUDENT_PRINT_FMT_STRING, s->id, s->fname,
+ * student.lname, calculated_gpa_from_s);
+ *
+ * Dont forget that the GPA in the student structure is an int, to convert
+ * it into a real gpa divide by 100.0 and store in a float variable.
+ *
+ * returns: nothing, this is a void function
+ *
+ *
+ * console: <see above> on success, print table or database empty
+ * M_ERR_STD_PRINT if the function argument s is NULL or if
+ * s->id is zero
+ *
+ */
+void print_student(student_t *s)
+{
+ // TODO
+ if (s == NULL || s-> id == 0){
+ printf(M_ERR_STD_PRINT);
+ return;
+ }
+ printf(STUDENT_PRINT_HDR_STRING, "ID", "FIRST_NAME", "LAST_NAME", "GPA");
+ if (s->id != 0){
+ double calculated_gpa_from_s = (double)s->gpa / 100;
+ printf(STUDENT_PRINT_FMT_STRING, s->id, s->fname, s->lname, calculated_gpa_from_s);
+ }
+ return;
+}
+
+/*
+ * NOTE IMPLEMENTING THIS FUNCTION IS EXTRA CREDIT
+ *
+ * compress_db
+ * fd: linux file descriptor
+ *
+ * This assignment takes advantage of the way Linux handles sparse files
+ * on disk. Thus if there is a large hole between student records, Linux
+ * will not use any physical storage. However, when a database record is
+ * deleted storage is used to write a blank - see EMPTY_STUDENT_RECORD from
+ * db.h - record.
+ *
+ * Since Linux provides no way to delete data in the middle of a file, and
+ * deleted records take up physical storage, this function will compress the
+ * database by rewriting a new database file that only includes valid student
+ * records. There are a number of ways to do this, but since this is extra credit
+ * you need to figure this out on your own.
+ *
+ * At a high level create a temporary database file then copy all valid students from
+ * the active database (passed in via fd) to the temporary file. When this is done
+ * rename the temporary database file to the name of the real database file. See
+ * the constants in db.h for required file names:
+ *
+ * #define DB_FILE "student.db" //name of database file
+ * #define TMP_DB_FILE ".tmp_student.db" //for extra credit
+ *
+ * Note that you are passed in the fd of the database file to be compressed,
+ * it is very likely you will need to close it to overwrite it with the
+ * compressed version of the file. To ensure the caller can work with the
+ * compressed file after you create it, it is a good design to return the fd
+ * of the new compressed file from this function
+ *
+ * returns: <number> returns the fd of the compressed database file
+ * ERR_DB_FILE database file I/O issue
+ *
+ *
+ * console: M_DB_COMPRESSED_OK on success, the db was successfully compressed.
+ * M_ERR_DB_OPEN error when opening/creating temporary database file.
+ * this error should also be returned after you
+ * compressed the database file and if you are unable
+ * to open it to pass the fd back to the caller
+ * M_ERR_DB_CREATE error creating the db file. For instance the
+ * inability to copy the temporary file back as
+ * the primary database file.
+ * M_ERR_DB_READ error reading or seeking the the db or tempdb file
+ * M_ERR_DB_WRITE error writing to db or tempdb file (adding student)
+ *
+ */
+int compress_db(int fd)
+{
+ // TODO
+
+ int new_fd = open_db(TMP_DB_FILE, false);
+ if (lseek(fd, 0, SEEK_SET) == -1){
+ printf(M_ERR_DB_READ);
+ return ERR_DB_FILE;
+ }
+ student_t student;
+ student_t check = {0};
+ if (read(fd, &student, sizeof(student)) == 0){
+ return fd;
+ }
+
+ int i;
+ while ((i = read(fd, &student, sizeof(student))) != 0){
+ if (i == -1){
+ printf(M_ERR_DB_READ);
+ return ERR_DB_FILE;
+ }
+ if (memcmp(&student, &check, sizeof(check)) != 0){
+
+ if (memcmp(&student, &check, sizeof(check)) != 0 &&
+ student.id != 0){
+
+ int offset = student.id * sizeof(student_t);
+ if (lseek(new_fd, offset, SEEK_SET) == -1){
+ printf(M_ERR_DB_READ);
+ return ERR_DB_FILE;
+ }
+ if (write(new_fd, &student, sizeof(student_t)) == -1){
+ printf(M_ERR_DB_WRITE);
+ return ERR_DB_FILE;
+ }
+ }
+ }
+
+ }
+ printf(M_DB_COMPRESSED_OK);
+ close(new_fd);
+ return new_fd;
+}
+
+/*
+ * validate_range
+ * id: proposed student id
+ * gpa: proposed gpa
+ *
+ * This function validates that the id and gpa are in the allowable ranges
+ * as per the specifications. It checks if the values are within the
+ * inclusive range using constents in db.h
+ *
+ * returns: NO_ERROR on success, both ID and GPA are in range
+ * EXIT_FAIL_ARGS if either ID or GPA is out of range
+ *
+ * console: This function does not produce any output
+ *
+ */
+int validate_range(int id, int gpa)
+{
+
+ if ((id < MIN_STD_ID) || (id > MAX_STD_ID))
+ return EXIT_FAIL_ARGS;
+
+ if ((gpa < MIN_STD_GPA) || (gpa > MAX_STD_GPA))
+ return EXIT_FAIL_ARGS;
+
+ return NO_ERROR;
+}
+
+/*
+ * usage
+ * exename: the name of the executable from argv[0]
+ *
+ * Prints this programs expected usage
+ *
+ * returns: nothing, this is a void function
+ *
+ * console: This function prints the usage information
+ *
+ */
+void usage(char *exename)
+{
+ printf("usage: %s -[h|a|c|d|f|p|z] options. Where:\n", exename);
+ printf("\t-h: prints help\n");
+ printf("\t-a id first_name last_name gpa(as 3 digit int): adds a student\n");
+ printf("\t-c: counts the records in the database\n");
+ printf("\t-d id: deletes a student\n");
+ printf("\t-f id: finds and prints a student in the database\n");
+ printf("\t-p: prints all records in the student database\n");
+ printf("\t-x: compress the database file [EXTRA CREDIT]\n");
+ printf("\t-z: zero db file (remove all records)\n");
+}
+
+// Welcome to main()
+int main(int argc, char *argv[])
+{
+ char opt; // user selected option
+ int fd; // file descriptor of database files
+ int rc; // return code from various operations
+ int exit_code; // exit code to shell
+ int id; // userid from argv[2]
+ int gpa; // gpa from argv[5]
+
+ // space for a student structure which we will get back from
+ // some of the functions we will be writing such as get_student(),
+ // and print_student().
+ student_t student = {0};
+
+ // This function must have at least one arg, and the arg must start
+ // with a dash
+ if ((argc < 2) || (*argv[1] != '-'))
+ {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ // The option is the first character after the dash for example
+ //-h -a -c -d -f -p -x -z
+ opt = (char)*(argv[1] + 1); // get the option flag
+
+ // handle the help flag and then exit normally
+ if (opt == 'h')
+ {
+ usage(argv[0]);
+ exit(EXIT_OK);
+ }
+
+ // now lets open the file and continue if there is no error
+ // note we are not truncating the file using the second
+ // parameter
+ fd = open_db(DB_FILE, false);
+ if (fd < 0)
+ {
+ exit(EXIT_FAIL_DB);
+ }
+
+ // set rc to the return code of the operation to ensure the program
+ // use that to determine the proper exit_code. Look at the header
+ // sdbsc.h for expected values.
+
+ exit_code = EXIT_OK;
+ switch (opt)
+ {
+ case 'a':
+ // arv[0] arv[1] arv[2] arv[3] arv[4] arv[5]
+ // prog_name -a id first_name last_name gpa
+ //-------------------------------------------------------
+ // example: prog_name -a 1 John Doe 341
+ if (argc != 6)
+ {
+ usage(argv[0]);
+ exit_code = EXIT_FAIL_ARGS;
+ break;
+ }
+
+ // convert id and gpa to ints from argv. For this assignment assume
+ // they are valid numbers
+ id = atoi(argv[2]);
+ gpa = atoi(argv[5]);
+
+ exit_code = validate_range(id, gpa);
+ if (exit_code == EXIT_FAIL_ARGS)
+ {
+ printf(M_ERR_STD_RNG);
+ break;
+ }
+
+ rc = add_student(fd, id, argv[3], argv[4], gpa);
+ if (rc < 0)
+ exit_code = EXIT_FAIL_DB;
+
+ break;
+
+ case 'c':
+ // arv[0] arv[1]
+ // prog_name -c
+ //-----------------
+ // example: prog_name -c
+ rc = count_db_records(fd);
+ if (rc < 0)
+ exit_code = EXIT_FAIL_DB;
+ break;
+
+ case 'd':
+ // arv[0] arv[1] arv[2]
+ // prog_name -d id
+ //-------------------------
+ // example: prog_name -d 100
+ if (argc != 3)
+ {
+ usage(argv[0]);
+ exit_code = EXIT_FAIL_ARGS;
+ break;
+ }
+ id = atoi(argv[2]);
+ rc = del_student(fd, id);
+ if (rc < 0)
+ exit_code = EXIT_FAIL_DB;
+
+ break;
+
+ case 'f':
+ // arv[0] arv[1] arv[2]
+ // prog_name -f id
+ //-------------------------
+ // example: prog_name -f 100
+ if (argc != 3)
+ {
+ usage(argv[0]);
+ exit_code = EXIT_FAIL_ARGS;
+ break;
+ }
+ id = atoi(argv[2]);
+ rc = get_student(fd, id, &student);
+
+ switch (rc)
+ {
+ case NO_ERROR:
+ print_student(&student);
+ break;
+ case SRCH_NOT_FOUND:
+ printf(M_STD_NOT_FND_MSG, id);
+ exit_code = EXIT_FAIL_DB;
+ break;
+ default:
+ printf(M_ERR_DB_READ);
+ exit_code = EXIT_FAIL_DB;
+ break;
+ }
+ break;
+
+ case 'p':
+ // arv[0] arv[1]
+ // prog_name -p
+ //-----------------
+ // example: prog_name -p
+ rc = print_db(fd);
+ if (rc < 0)
+ exit_code = EXIT_FAIL_DB;
+ break;
+
+ case 'x':
+ // arv[0] arv[1]
+ // prog_name -x
+ //-----------------
+ // example: prog_name -x
+
+ // remember compress_db returns a fd of the compressed database.
+ // we close it after this switch statement
+ fd = compress_db(fd);
+ if (fd < 0)
+ exit_code = EXIT_FAIL_DB;
+ break;
+
+ case 'z':
+ // arv[0] arv[1]
+ // prog_name -x
+ //-----------------
+ // example: prog_name -x
+ // HINT: close the db file, we already have fd
+ // and reopen db indicating truncate=true
+ close(fd);
+ fd = open_db(DB_FILE, true);
+ if (fd < 0)
+ {
+ exit_code = EXIT_FAIL_DB;
+ break;
+ }
+ printf(M_DB_ZERO_OK);
+ exit_code = EXIT_OK;
+ break;
+ default:
+ usage(argv[0]);
+ exit_code = EXIT_FAIL_ARGS;
+ }
+
+ // dont forget to close the file before exiting, and setting the
+ // proper exit code - see the header file for expected values
+ close(fd);
+ exit(exit_code);
+}
diff --git a/assn2/starter/sdbsc.dSYM/Contents/Info.plist b/assn2/starter/sdbsc.dSYM/Contents/Info.plist
new file mode 100644
index 0000000..b0e4048
--- /dev/null
+++ b/assn2/starter/sdbsc.dSYM/Contents/Info.plist
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.xcode.dsym.sdbsc</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>dSYM</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ </dict>
+</plist>
diff --git a/assn2/starter/sdbsc.dSYM/Contents/Resources/DWARF/sdbsc b/assn2/starter/sdbsc.dSYM/Contents/Resources/DWARF/sdbsc
new file mode 100644
index 0000000000000000000000000000000000000000..5dd64c9ed75e2a118f73ecdf762fb4153bc11dd0
GIT binary patch
literal 14308
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
literal 0
HcmV?d00001
diff --git a/assn2/starter/sdbsc.h b/assn2/starter/sdbsc.h
new file mode 100644
index 0000000..79b08e7
--- /dev/null
+++ b/assn2/starter/sdbsc.h
@@ -0,0 +1,64 @@
+#ifndef __SDB_H__
+
+#include "db.h" //get student record type
+
+//prototypes for functions go below for this assignment
+int open_db(char *dbFile, bool should_truncate);
+int add_student(int fd, int id, char *fname, char *lname, int gpa);
+int get_student(int fd, int id, student_t *s);
+int del_student(int fd, int id);
+int compress_db(int fd);
+void print_student(student_t *s);
+int validate_range(int id, int gpa);
+int count_db_records(int fd);
+int print_db(int fd);
+void usage(char *);
+
+//error codes to be returned from individual functions
+// NO_ERROR is returned if there are no errors
+// ERR_DB_FILE is returned if there is are any issues with the database file itself
+// ERR_DB_OP is returned if an operation did not work aka add or delete a student
+// SRCH_NOT_FOUND is returned if the student is not found (get_student, and del_student)
+#define NO_ERROR 0
+#define ERR_DB_FILE -1
+#define ERR_DB_OP -2
+#define SRCH_NOT_FOUND -3
+#define NOT_IMPLEMENTED_YET 0
+
+
+//error codes to be returned to the shell
+// EXIT_OK program executed without error
+// EXIT_FAIL_DB a database operation failed
+// EXIT_FAIL_ARGS one or more arguments to program were not valid
+// EXIT_NOT_IMPL the operation has not been implemented yet
+#define EXIT_OK 0
+#define EXIT_FAIL_DB 1
+#define EXIT_FAIL_ARGS 2
+#define EXIT_NOT_IMPL 3
+
+//Output messages
+#define M_ERR_STD_RNG "Cant add student, either ID or GPA out of allowable range!\n"
+#define M_ERR_DB_CREATE "Error creating DB file, exiting!\n"
+#define M_ERR_DB_OPEN "Error opening DB file, exiting!\n"
+#define M_ERR_DB_READ "Error reading DB file, exiting!\n"
+#define M_ERR_DB_WRITE "Error writing DB file, exiting!\n"
+#define M_ERR_DB_ADD_DUP "Cant add student with ID=%d, already exists in db.\n"
+#define M_ERR_STD_PRINT "Cant print student. Student is NULL or ID is zero\n"
+
+#define M_STD_ADDED "Student %d added to database.\n"
+#define M_STD_DEL_MSG "Student %d was deleted from database.\n"
+#define M_STD_NOT_FND_MSG "Student %d was not found in database.\n"
+#define M_DB_COMPRESSED_OK "Database successfully compressed!\n"
+#define M_DB_ZERO_OK "All database records removed!\n"
+#define M_DB_EMPTY "Database contains no student records.\n"
+#define M_DB_RECORD_CNT "Database contains %d student record(s).\n"
+#define M_NOT_IMPL "The requested operation is not implemented yet!\n"
+
+//useful format strings for print students
+//For example to print the header in the required output:
+// printf(STUDENT_PRINT_HDR_STRING, "ID","FIRST NAME",
+// "LAST_NAME", "GPA");
+#define STUDENT_PRINT_HDR_STRING "%-6s %-24s %-32s %-3s\n"
+#define STUDENT_PRINT_FMT_STRING "%-6d %-24.24s %-32.32s %-3.2f\n"
+
+#endif
\ No newline at end of file
diff --git a/assn2/starter/test.sh b/assn2/starter/test.sh
new file mode 100755
index 0000000..19f7d3d
--- /dev/null
+++ b/assn2/starter/test.sh
@@ -0,0 +1,194 @@
+#!/usr/bin/env bats
+
+# The setup function runs before every test
+setup_file() {
+ # Delete the student.db file if it exists
+ if [ -f "student.db" ]; then
+ rm "student.db"
+ fi
+}
+
+@test "Check if database is empty to start" {
+ run ./sdbsc -p
+ [ "$status" -eq 0 ]
+ [ "$output" = "Database contains no student records." ]
+}
+
+@test "Add a student 1 to db" {
+ run ./sdbsc -a 1 john doe 345
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "Student 1 added to database." ]
+}
+
+@test "Add more students to db" {
+ run ./sdbsc -a 3 jane doe 390
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "Student 3 added to database." ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+
+ run ./sdbsc -a 63 jim doe 285
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "Student 63 added to database." ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+
+ run ./sdbsc -a 64 janet doe 310
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "Student 64 added to database." ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+
+ run ./sdbsc -a 99999 big dude 205
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "Student 99999 added to database." ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+}
+
+@test "Check student count" {
+ run ./sdbsc -c
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "Database contains 5 student record(s)." ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+}
+
+@test "Make sure adding duplicate student fails" {
+ run ./sdbsc -a 63 dup student 300
+ [ "$status" -eq 1 ] || {
+ echo "Expecting status of 1, got: $status"
+ return 1
+ }
+ [ "${lines[0]}" = "Cant add student with ID=63, already exists in db." ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+}
+
+@test "Make sure the file size is correct at this time" {
+ run stat --format="%s" ./student.db
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "6400000" ] || {
+ echo "Failed Output: $output"
+ echo "Expected: 64000000"
+ return 1
+ }
+}
+
+@test "Find student 3 in db" {
+ run ./sdbsc -f 3
+
+ # Ensure the command ran successfully
+ [ "$status" -eq 0 ]
+
+ # Use echo with -n to avoid adding extra newline and normalize spaces
+ normalized_output=$(echo -n "${lines[1]}" | tr -s '[:space:]' ' ')
+
+ # Define the expected output
+ expected_output="3 jane doe 3.90"
+
+ # Compare the normalized output with the expected output
+ [ "$normalized_output" = "$expected_output" ] || {
+ echo "Failed Output: $normalized_output"
+ echo "Expected: $expected_output"
+ return 1
+ }
+}
+
+@test "Try looking up non-existent student" {
+ run ./sdbsc -f 4
+ [ "$status" -eq 1 ] || {
+ echo "Expecting status of 1, got: $status"
+ return 1
+ }
+ [ "${lines[0]}" = "Student 4 was not found in database." ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+}
+
+@test "Delete student 64 in db" {
+ run ./sdbsc -d 64
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "Student 64 was deleted from database." ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+}
+
+@test "Try deleting non-existent student" {
+ run ./sdbsc -d 65
+ [ "$status" -eq 1 ] || {
+ echo "Expecting status of 1, got: $status"
+ return 1
+ }
+ [ "${lines[0]}" = "Student 65 was not found in database." ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+}
+
+@test "Check student count again, should be 4 now" {
+ run ./sdbsc -c
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "Database contains 4 student record(s)." ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+}
+
+@test "Print student records" {
+ # Run the command
+ run ./sdbsc -p
+
+ # Ensure the command ran successfully
+ [ "$status" -eq 0 ]
+
+ # Normalize the output by replacing multiple spaces with a single space
+ normalized_output=$(echo -n "$output" | tr -s '[:space:]' ' ')
+
+ # Define the expected output (normalized)
+ expected_output="ID FIRST_NAME LAST_NAME GPA 1 john doe 3.45 3 jane doe 3.90 63 jim doe 2.85 99999 big dude 2.05"
+
+ # Compare the normalized output
+ [ "$normalized_output" = "$expected_output" ] || {
+ echo "Failed Output: $normalized_output"
+ echo "Expected Output: $expected_output"
+ return 1
+ }
+}
+
+
+@test "Compress db - try 1" {
+ run ./sdbsc -x
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "Database successfully compressed!" ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+}
+
+
+@test "Delete student 99999 in db" {
+ run ./sdbsc -d 99999
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "Student 99999 was deleted from database." ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+}
+
+@test "Compress db again - try 2" {
+ run ./sdbsc -x
+ [ "$status" -eq 0 ]
+ [ "${lines[0]}" = "Database successfully compressed!" ] || {
+ echo "Failed Output: $output"
+ return 1
+ }
+}
\ No newline at end of file
diff --git a/assn2/starter/testload.sh b/assn2/starter/testload.sh
new file mode 100755
index 0000000..2f36a92
--- /dev/null
+++ b/assn2/starter/testload.sh
@@ -0,0 +1,6 @@
+#! /bin/bash
+./sdbsc -a 1 john doe 3.45
+./sdbsc -a 3 jane doe 3.90
+./sdbsc -a 63 jim doe 2.85
+./sdbsc -a 64 janet doe 3.10
+./sdbsc -a 99999 big dude 2.05
\ No newline at end of file
--
GitLab