Commit 0a8516b3 by shtaya

HW 3(Database) is done.

parent 7494d9a9
#ifndef DATABASE_H
#define DATABASE_H
#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>
void checkConnectionError(PGconn *conn);
void checkInqueryError(PGresult *res);
void checkConnectionError(PGconn *conn)
{
if (PQstatus(conn) == CONNECTION_BAD)
{
printf("We're unable to connect to the database\n");
PQfinish(conn);
exit(-1);
}
return;
}
void checkInqueryError(PGresult *res)
{
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
printf("We did not get any data!\n");
PQclear(res);
exit(-1);
}
return;
}
void dispResult(PGresult *res)
{
int numTuple = PQntuples(res);
int numField = PQnfields(res);
int i,j;
printf("%5s\t", "No.");
for (i = 0; i < numField; i++)
{
printf("%15s\t", PQfname(res,i));
}
printf("\n");
for (j = 0; j < numTuple; j++)
{
printf("%5d\t", j+1);
for (i = 0; i < numField; i++)
{
printf("%15s\t", PQgetvalue(res,j,i));
}
printf("\n");
}
return;
}
#endif
#ifndef DATABASE_H
#define DATABASE_H
#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>
void checkConnectionError(PGconn *conn);
void checkUnvoidInqueryError(PGresult *res);
void checkVoidInqueryError(PGresult *res);
void dispTable(PGresult *res);
void checkConnectionError(PGconn *conn)
{
if (PQstatus(conn) == CONNECTION_BAD)
{
printf("We're unable to connect to the database\n");
PQfinish(conn);
exit(-1);
}
return;
}
void checkUnvoidInqueryError(PGresult *res)
{
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
printf("We did not get any data!\n");
PQclear(res);
exit(-1);
}
return;
}
void checkVoidInqueryError(PGresult *res)
{
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
printf("SQL command failed.\n");
PQclear(res);
exit(-1);
}
return;
}
void dispTable(PGresult *res)
{
int numTuple = PQntuples(res);
int numField = PQnfields(res);
int i,j;
printf("%5s\t", "No.");
for (i = 0; i < numField; i++)
{
printf("%15s\t", PQfname(res,i));
}
printf("\n");
for (j = 0; j < numTuple; j++)
{
printf("%5d\t", j+1);
for (i = 0; i < numField; i++)
{
printf("%15s\t", PQgetvalue(res,j,i));
}
printf("\n");
}
return;
}
#endif
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
#include <stdio.h>
#include <stdlib.h>
#include "database.h"
#include "ui.h"
typedef struct student {
int student_code;
char first_name[34];
char last_name[34];
char birthdate[11];
double average_grade;
} student_t;
typedef struct subject {
int id_subject;
int credits;
char subject_code[12];
char name[256];
char teacher[64];
} subject_t;
typedef struct grade {
int id_grade;
int id_subject;
int student_code;
int grade;
} grade_t;
void insertStudentRecord(PGconn *conn);
student_t inputStudentData(void);
int genUniqueStudentCode(PGconn *conn);
void modifyStudentRecord(PGconn *conn);
char *getIdtoEdit(PGconn *conn, const char filedName[], const char database[]);
void deleteStudentRecord(PGconn *conn);
void insertSubjectRecord(PGconn *conn);
subject_t inputSubjectData(void);
void modifySubjectRecord(PGconn *conn);
char *subjectChoice(PGconn *conn);
void deleteSubjectRecord(PGconn *conn);
void GradeRecord(PGconn *conn);
void dispStudentTableByGrade(PGconn *conn);
void insertStudentRecord(PGconn *conn)
{
PGresult *res;
char query[128];
student_t addedData = inputStudentData();
addedData.student_code = genUniqueStudentCode(conn);
sprintf(query, "insert into student values ('%d','%s','%s','%s','%lf')", addedData.student_code, addedData.first_name, addedData.last_name, addedData.birthdate, 0.00);
res = PQexec(conn, query);
checkVoidInqueryError(res);
PQclear(res);
return;
}
student_t inputStudentData(void)
{
student_t data;
printf("Please insert student's first name.\n>>");
scanf("%s",data.first_name);
printf("Please insert student's last name.\n>>");
scanf("%s",data.last_name);
sprintf(data.birthdate, "%04d-%02d-%02d", getInt(1900,2100,"Please insert student's birth year.\n"),
getInt(1,12,"Please insert student's birth month in digit\n"),
getInt(1,31,"Please insert student's birth day.\n"));
return data;
}
int genUniqueStudentCode(PGconn *conn)
{
int generatedStudentCode;
PGresult *res;
res = PQexec(conn, "select max(student_code) from student");
checkUnvoidInqueryError(res);
generatedStudentCode = atoi(PQgetvalue(res, 0, 0));
PQclear(res);
return generatedStudentCode+1;
}
void modifyStudentRecord(PGconn *conn)
{
char *studentCode;
PGresult *res;
char query[128];
student_t modifiedData;
studentCode = getIdtoEdit(conn, "first_name", "student");
if (studentCode != NULL)
{
printf("Modifying student %s.\n", studentCode);
modifiedData = inputStudentData();
sprintf(query, "update student set first_name = '%s', last_name = '%s', birthdate = '%s' where student_code = '%s'", modifiedData.first_name, modifiedData.last_name, modifiedData.birthdate, studentCode);
res = PQexec(conn, query);
checkVoidInqueryError(res);
PQclear(res);
}
return;
}
char *getIdtoEdit(PGconn *conn, const char fieldName[], const char database[])
{
char *id;
PGresult *res;
char query[128];
char fieldData[32];
int numChosen;
printf("Please insert %s.\n>>", fieldName);
scanf("%s", fieldData);
sprintf(query, "select * from %s where %s = '%s'", database, fieldName, fieldData);
res = PQexec(conn, query);
checkUnvoidInqueryError(res);
printf("Chooes the one to edit or exit with 0.\n");
dispTable(res);
numChosen = getInt(0,PQntuples(res),"");
id = PQgetvalue(res, numChosen-1, 0);
PQclear(res);
return id;
}
void deleteStudentRecord(PGconn *conn)
{
char *studentCode;
PGresult *res;
char query[128];
student_t modifiedData;
studentCode = getIdtoEdit(conn, "first_name", "student");
printf("Student %s was deleted.\n", studentCode);
sprintf(query, "delete from student where student_code = '%s'", studentCode);
res = PQexec(conn, query);
checkVoidInqueryError(res);
PQclear(res);
return;
}
void insertSubjectRecord(PGconn *conn)
{
PGresult *res;
char query[128];
subject_t addedSubject = inputSubjectData();
sprintf(query, "insert into subject (credits, subject_code, name, teacher) values ('%d','%s','%s','%s')", addedSubject.credits, addedSubject.subject_code, addedSubject.name, addedSubject.teacher);
res = PQexec(conn, query);
checkVoidInqueryError(res);
PQclear(res);
return;
}
subject_t inputSubjectData(void)
{
subject_t data;
printf("Please insert subject's name.\n>>");
scanf("%s",data.name);
data.credits = getInt(1,30,"Please insert subject's credit point.\n");
printf("Please insert subject's code.(ie. AAA0000)\n>>");
scanf("%s",data.subject_code);
printf("Please insert teacher's name.\n>>");
scanf("%s",data.teacher);
return data;
}
void modifySubjectRecord(PGconn *conn)
{
char *subjectId;
PGresult *res;
char query[128];
subject_t modifiedData;
subjectId = subjectChoice(conn);
printf("Modifying subject record %s.\n", subjectId);
modifiedData = inputSubjectData();
sprintf(query, "update subject set credits = '%d', subject_code = '%s', name = '%s', teacher = '%s' where id_subject = '%s'", modifiedData.credits, modifiedData.subject_code, modifiedData.name, modifiedData.teacher, subjectId);
res = PQexec(conn, query);
checkVoidInqueryError(res);
PQclear(res);
return;
}
char *subjectChoice(PGconn *conn)
{
char *id;
PGresult *res;
char query[128];
int numChosen;
sprintf(query, "select * from subject");
res = PQexec(conn, query);
checkUnvoidInqueryError(res);
printf("Chooes the a subject.\n");
dispTable(res);
numChosen = getInt(1,PQntuples(res),"");
id = PQgetvalue(res, numChosen-1, 0);
PQclear(res);
return id;
}
void deleteSubjectRecord(PGconn *conn)
{
char *subjectId;
PGresult *res;
char query[128];
subject_t modifiedData;
subjectId = subjectChoice(conn);
printf("Deleting subject record %s.\n", subjectId);
sprintf(query, "delete from subject where id_subject = '%s'", subjectId);
res = PQexec(conn, query);
checkVoidInqueryError(res);
PQclear(res);
return;
}
void GradeRecord(PGconn *conn)
{
char *subjectId;
char *studentCode;
char mess[128];
int newGrade;
PGresult *res;
char query[128];
subjectId = subjectChoice(conn);
studentCode = getIdtoEdit(conn, "first_name", "student");
sprintf(mess, "Please insert new grade for student %s in subject %s\n", studentCode, subjectId);
newGrade = getInt(0, 5, mess);
sprintf(query, "select * from grade where id_subject = '%s' and student_code = '%s'", subjectId,studentCode);
res = PQexec(conn, query);
checkUnvoidInqueryError(res);
if (PQgetisnull(res,0,0) == 1)
{
sprintf(query, "insert into grade (id_subject, student_code, grade) values ('%s', '%s', '%d')", subjectId, studentCode, newGrade);
res = PQexec(conn, query);
checkVoidInqueryError(res);
printf("Grade data was inserted.\n");
}
else
{
sprintf(query, "update grade set grade = '%d' where id_subject = '%s' and student_code = '%s'", newGrade, subjectId, studentCode);
res = PQexec(conn, query);
checkVoidInqueryError(res);
printf("Grade data was updated.\n");
}
sprintf(query, "select cast(sum(grade*credits) as float)/sum(credits) from grade join subject on student_code=student_code where student_code = '%s'", studentCode);
res = PQexec(conn, query);
checkUnvoidInqueryError(res);
;
sprintf(query, "update student set average_grade = '%s' where student_code = '%s'", PQgetvalue(res,0,0), studentCode);
res = PQexec(conn, query);
checkVoidInqueryError(res);
PQclear(res);
return;
}
void dispStudentTableByGrade(PGconn *conn)
{
PGresult *res;
char query[128];
double lowLimit = getDouble(0, 5, "Please input lower limit of grade.\n");
double upLimit = getDouble(lowLimit, 5, "Please input upper limit of grade.\n");
sprintf(query, "select * from student where average_grade >= %lf and average_grade <= %lf order by average_grade desc", lowLimit, upLimit);
res = PQexec(conn, query);
checkUnvoidInqueryError(res);
dispTable(res);
PQclear(res);
return;
}
#endif
//gcc main.c -L/Library/PostgreSQL/9.6/lib -I/Library/PostgreSQL/9.6/include -lpq
#include <stdio.h>
#include "functions.h"
#include "database.h"
#include "ui.h"
#define LOGIN_INFO "dbname=mveb165842 host=ewis.pld.ttu.ee port=5432 user=mveb165842 password=7ez6d0mu"
#define WELCOME_MES "Welcome. This program accesses database mveb165842 at ewis.pld.ttu.ee.\n"
#define MAIN_MENU "Main menu\n1: Edit student record\n2: Edit subject record\n3: Edit grade record\n4: Display students table \n5: Exit\n"
#define EDIT_MENU "1: Insert\n2: Modify\n3: Delete\n"
#define YES_NO "1: Yes\n2: No\n"
int editStudentRecord(PGconn *conn);
int editSubjectRecord(PGconn *conn);
int editGradeRecord(PGconn *conn);
int dispStudentTable(PGconn *conn);
int normalExit(PGconn *conn);
int main()
{
PGconn *conn;
int (*func[5])() = {editStudentRecord, editSubjectRecord, editGradeRecord, dispStudentTable, normalExit};
int exitFlag = 0;
checkConnectionError(conn = PQconnectdb(LOGIN_INFO));
printf(WELCOME_MES);
while ((*func[getInt(1,5,MAIN_MENU)-1])(conn) == 0);
PQfinish(conn);
return 0;
}
int editStudentRecord(PGconn *conn)
{
void (*func[3])() = {insertStudentRecord, modifyStudentRecord, deleteStudentRecord};
do
{
(*func[getInt(1,3,"Editing student record\n" EDIT_MENU)-1])(conn);
} while(getInt(1, 2, "Edit more student record?\n" YES_NO) == 1);
return 0;
}
int editSubjectRecord(PGconn *conn)
{
void (*func[3])() = {insertSubjectRecord, modifySubjectRecord, deleteSubjectRecord};
do
{
(*func[getInt(1,3,"Editing subject record\n" EDIT_MENU)-1])(conn);
} while(getInt(1, 2, "Edit more subject record?\n" YES_NO) == 1);
return 0;
}
int editGradeRecord(PGconn *conn)
{
do
{
GradeRecord(conn);
} while(getInt(1, 2, "Add more grade record?\n" YES_NO) == 1);
return 0;
}
int dispStudentTable(PGconn *conn)
{
do
{
dispStudentTableByGrade(conn);
} while(getInt(1, 2, "Display another table?\n" YES_NO) == 1);
return 0;
}
int normalExit(PGconn *conn)
{
return -1;
}
#ifndef UI_H
#define UI_H
#include <stdio.h>
#include <stdlib.h>
#include "database.h"
#define INV_INPUT "Invailed input was inserted.\n"
double getDouble(double min, double max, const char mess[]);
int getInt(int min, int max, const char mess[]);
double getDouble(double min, double max, const char mess[])
{
double num;
printf("%s", mess);
while(1)
{
printf(">>");
scanf("%lf", &num);
if (min <= num && num <= max)
{
break;
}
else
{
printf(INV_INPUT);
}
}
return num;
}
int getInt(int min, int max, const char mess[])
{
int num;
printf("%s", mess);
while(1)
{
printf(">>");
scanf("%d", &num);
if (min <= num && num <= max)
{
break;
}
else
{
printf(INV_INPUT);
}
}
return num;
}
#endif
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include "database.h"
#include "ui.h"
#define LOW_GRADE_LIMIT "Please input lower limit of grade.\n"
#define UP_GRADE_LIMIT "Please input upper limit of grade.\n"
#define STUDENT_EDIT_FUNC_LIST "What do you want to do?\n1: insert\n2: modify\n3: select\n"
typedef struct date {
int day;
int month;
int year;
} date_t;
typedef struct student {
char first_name[32];
char last_name[32];
date_t date;
} student_t;
void editStudent(PGconn *conn);
void insertStudentData(PGconn *conn);
void modifyStudentData(PGconn *conn);
void deleteStudentData(PGconn *conn);
void editSubject(PGconn *conn);
void addGrade(PGconn *conn);
void dispStudentByGrade(PGconn *conn);
void editStudent(PGconn *conn)
{
void (*func[5])() = {insertStudentData, modifyStudentData, deleteStudentData};
while (1)
{
(*func[getInt(1,5,STUDENT_EDIT_FUNC_LIST)-1])(conn);
if (getInt(1,2,"Edit more data?\n1: Yes\n2: No\n") == 2)
{
break;
}
}
return;
}
void insertStudentData(PGconn *conn)
{
char query[128];
student_t addedStudentRecord;
printf("Insert student's first name.\n>>");
scanf("%s", addedStudentRecord.first_name);
printf("Insert student's last name.\n>>");
scanf("%s", addedStudentRecord.last_name);
printf("Insert student's birthdate. (i.e. YYYYMMDD)\n>>");
scanf("%4d%2d%2d", &addedStudentRecord.date.year, &addedStudentRecord.date.month, &addedStudentRecord.date.day);
//error check is needed!!
sprintf(query, "insert into student (first_name,last_name,date) values (%s,%s,%d%d%d)", addedStudentRecord.first_name, addedStudentRecord.last_name, addedStudentRecord.date.year, addedStudentRecord.date.month, addedStudentRecord.date.day);
printf("%s\n" , query);
return;
}
void modifyStudentData(PGconn *conn)
{
return;
}
void deleteStudentData(PGconn *conn)
{
return;
}
void editSubject(PGconn *conn)
{
return;
}
void addGrade(PGconn *conn)
{
return;
}
void dispStudentByGrade(PGconn *conn)
{
PGresult *res;
double lowLimit;
double upLimit;
char query[128];
while (1)
{
lowLimit = getDouble(0, 5, LOW_GRADE_LIMIT);
upLimit = getDouble(lowLimit, 5, UP_GRADE_LIMIT);
sprintf(query, "select * from student where average_grade > %lf and average_grade < %lf order by average_grade desc", lowLimit, upLimit);
res = PQexec(conn, query);
checkInqueryError(res);
dispResult(res);
if (getInt(1,2,"Add more data?\n1: Yes\n2: No\n") == 2)
{
break;
}
}
PQclear(res);
return;
}
#endif
//gcc main.c -L/Library/PostgreSQL/9.6/lib -I/Library/PostgreSQL/9.6/include -lpq
#include <stdio.h>
#include "database.h"
#include "ui.h"
#include "functions.c"
#define WELCOME_MES "Welcome. This program accesses database mveb165842 at ewis.pld.ttu.ee.\n"
#define SERVICE_LIST "Choose a service from the list given below.\n1: Edit student data\n2: Edit subject data\n3: Add grade\n4: Display students' grades\n5: Exit\n"
#define LOGIN_INFO "dbname=mveb165842 host=ewis.pld.ttu.ee port=5432 user=mveb165842 password=7ez6d0mu"
void doExit(PGconn *conn);
int main(void)
{
PGconn *conn;
PGresult *res;
void (*func[5])() = {editStudent, editSubject, addGrade, dispStudentByGrade, doExit};
printf(WELCOME_MES);
checkConnectionError(conn = PQconnectdb(LOGIN_INFO));
while (1)
{
(*func[getInt(1,5,SERVICE_LIST)-1])(conn) < 0)
}
return 0;
}
void doExit(PGconn *conn)
{
PQfinish(conn);
exit(1);
return;
}
#ifndef UI_H
#define UI_H
#include <stdio.h>
#include <stdlib.h>
#define INV_INPUT "Invailed input was inserted.\n"
double getDouble(double min, double max, const char mess[]);
int getInt(int min, int max, const char mess[]);
double getDouble(double min, double max, const char mess[])
{
double num;
printf("%s", mess);
while(1)
{
printf(">>");
scanf("%lf", &num);
if (min <= num && num <= max)
{
break;
}
else
{
printf(INV_INPUT);
}
}
return num;
}
int getInt(int min, int max, const char mess[])
{
int num;
printf("%s", mess);
while(1)
{
printf(">>");
scanf("%d", &num);
if (min <= num && num <= max)
{
break;
}
else
{
printf(INV_INPUT);
}
}
return num;
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment