sba/database.h
stmctommyau 1e5999a4e5 stock fix,typo fix;
reserve code for admin;
self salse system (in work);
2022-09-01 23:46:16 +08:00

411 lines
12 KiB
C

//include std lib if they havent been included
#ifndef STD_LIB_H
#define STD_LIB_H
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#endif
#ifndef DNT_H
#define DNT_H
#include "dateNtime.h"
#endif // !DNT_H
typedef struct basic_db{
int row_count;
bool init_status;
//array of struct of row
};
//inventory
#define INVENTORY_DB "data_file_inventory.txt"
typedef struct inventory{
struct basic_db db;
struct inventory_row* row;
};
typedef struct inventory_row{
char category[100];
char brand[100];
char product[100];
double price;
int stock;
long barcode;
bool isdeleted;//common for all rows,default is false
};
typedef enum {
category = 1, brand = 2, product = 3, price_inv = 4, stock = 5, barcode_inv = 6
}INVENTORY;
#define ENDOFINVENTORY 6
//transaction
#define TRANSACTION_DB "data_file_transaction.txt"
typedef struct transaction{
struct basic_db db;
struct transaction_row* row;
};
typedef struct transaction_row{
struct date date;
struct time time;
long id;
double price;
int quantity;
long barcode;
bool isdeleted;//common for all rows,default is false
};
typedef enum {
date = 1, time = 2, id_tran = 3, price_tran = 4, quantity = 5, barcode_tran = 6
}TRANSACTION;
#define ENDOFTRANSACTION 6
//user
#define USER_DB "data_file_user.txt"
typedef struct user{
struct basic_db db;
struct user_row* row;
};
typedef struct user_row{
char name[100];
char role[100];
long id;
bool isAdmin;
bool isdeleted;//common for all rows,default is false
};
typedef enum {
name = 1, role = 2, id_user = 3
}USER;
#define ENDOFUSER 3
//list of db func
int basic_get_row_count(int end, FILE *fp){
fseek(fp, 0, SEEK_SET);//prevent pointer on wrong position
//get row count
int row_count = 0;
int colmun_count = 0;
while(!feof(fp)&&!ferror(fp)){
char buffer[100];
fgets(buffer, sizeof(buffer),fp);
if(buffer[0] == '#' || buffer[0] == '\0'){//catch comment line and ignore
continue;
}
colmun_count++;
if(colmun_count == end){
row_count++;
colmun_count = 0;
}
}
return row_count;
}
struct inventory read_db_invt(){//please open file in read mode
FILE* fp = fopen(INVENTORY_DB, "r");
struct inventory db;
//gets the number of rows in the file
int row_count = basic_get_row_count(ENDOFINVENTORY,fp);
db.row = (struct inventory_row*)malloc(row_count * sizeof(struct inventory_row));
db.db.row_count = row_count;
fseek(fp,0,SEEK_SET);//reset fp to the beginning of the file
//read data
for(int i=0;i<row_count;i++){
db.row[i].isdeleted = false;
for(INVENTORY j=category;j<=ENDOFINVENTORY;j++){
char buffer[100];
fgets(buffer, sizeof(buffer),fp);
if(buffer[0] == '#'){//catch comment line and ignore
j--;//decrement j to prevent skipping next column
}else{
switch(j){
case category:
strcpy(db.row[i].category,buffer);
break;
case brand:
strcpy(db.row[i].brand,buffer);
break;
case product:
strcpy(db.row[i].product,buffer);
break;
case price_inv:
db.row[i].price = atof(buffer);
break;
case stock:
db.row[i].stock = atoi(buffer);
break;
case barcode_inv:
db.row[i].barcode = atol(buffer);
break;
}
}
}
}
if(ferror(fp)){
printf("Error in reading file\n");
db.db.init_status = false;
return db;
}
fclose(fp);
db.db.init_status = true;
return db;
}
struct transaction read_db_tran(){
FILE* fp = fopen(TRANSACTION_DB, "r");
struct transaction db;
//gets the number of rows in the file
int row_count = basic_get_row_count(ENDOFTRANSACTION,fp);
db.row = (struct transaction_row*)malloc(row_count * sizeof(struct transaction_row));
db.db.row_count = row_count;
fseek(fp,0,SEEK_SET);//reset fp to the beginning of the file
//read data
for(int i=0;i<row_count;i++){
db.row[i].isdeleted = false;
for(TRANSACTION j=date;j<=ENDOFTRANSACTION;j++){
char buffer[100];
fgets(buffer, sizeof(buffer),fp);
if(buffer[0] == '#'){//catch comment line and ignore
j--;//decrement j to prevent skipping next column
}else{
switch(j){
case date:
db.row[i].date = convert_to_date(buffer);
break;
case time:
db.row[i].time = convert_to_time(buffer);
break;
case id_tran:
db.row[i].id = atol(buffer);
break;
case price_tran:
db.row[i].price = atof(buffer);
break;
case quantity:
db.row[i].quantity = atoi(buffer);
break;
case barcode_tran:
db.row[i].barcode = atol(buffer);
break;
}
}
}
}
if(ferror(fp)){
printf("Error in reading file\n");
db.db.init_status = false;
return db;
}
fclose(fp);
db.db.init_status = true;
return db;
}
struct user read_db_user(){
FILE* fp = fopen(USER_DB,"r");
struct user db;
//gets the number of rows in the file
int row_count = basic_get_row_count(ENDOFUSER,fp);
db.row = (struct user_row*)malloc(row_count * sizeof(struct user_row));
db.db.row_count = row_count;
fseek(fp,0,SEEK_SET);//reset fp to the beginning of the file
//read data
for(int i=0;i<row_count;i++){
db.row[i].isdeleted = false;
for(USER j=name;j<=ENDOFUSER;j++){
char buffer[100];
fgets(buffer, sizeof(buffer),fp);
if(buffer[0] == '#'){//catch comment line and ignore
j--;//decrement j to prevent skipping next column
}else{
switch(j){
case name:
strcpy(db.row[i].name,buffer);
break;
case role:
strcpy(db.row[i].role,buffer);
break;
case id_user:
db.row[i].id = atol(buffer);
break;
}
}
}
}
if(ferror(fp)){
printf("Error in reading file\n");
db.db.init_status = false;
return db;
}
fclose(fp);
db.db.init_status = true;
return db;
}
bool update_db_invt(struct inventory* invt){
FILE* fpR = fopen(INVENTORY_DB,"r");
char temp[30] = INVENTORY_DB;
strcat(temp,".temp");
FILE* fpW = fopen(temp,"w");
if(fpR == NULL || fpW == NULL){
printf("Error in opening file\n");
return false;
}
for(int i=0;i<invt->db.row_count;i++){
if(invt->row[i].isdeleted == true){
continue;
}
for(INVENTORY j=category;j<ENDOFINVENTORY;j++){
char buffer[100];
do{
if(feof(fpR)){
break;
}
fgets(buffer, sizeof(buffer),fpR);
if(buffer[0] == '#'){//catch comment line and print back to new file
fputs(buffer,fpW);
}
}while(buffer[0] == '#');
switch(j){
case category:
fprintf(fpW,"%s",invt->row[i].category);
break;
case brand:
fprintf(fpW,"%s",invt->row[i].brand);
break;
case product:
fprintf(fpW,"%s",invt->row[i].product);
break;
case price_inv:
fprintf(fpW,"%f",invt->row[i].price);
break;
case stock:
fprintf(fpW,"%d",invt->row[i].stock);
break;
case barcode_inv:
fprintf(fpW,"%ld",invt->row[i].barcode);
break;
}
fprintf(fpW,"\n");
}
}
//close file and replace old file with new file
fclose(fpR);
fclose(fpW);
remove(INVENTORY_DB);
rename(temp,INVENTORY_DB);
return true;
}
bool update_db_tran(struct transaction* tran){
FILE* fpR = fopen(TRANSACTION_DB,"r");
char temp[30] = TRANSACTION_DB;
strcat(temp,".temp");
FILE* fpW = fopen(temp,"w");
if(fpR == NULL || fpW == NULL){
printf("Error in opening file\n");
return false;
}
for(int i=0;i<tran->db.row_count;i++){
if(tran->row[i].isdeleted == true){
continue;
}
for(TRANSACTION j=date;j<ENDOFTRANSACTION;j++){
char buffer[100];
do{
if(feof(fpR)){
break;
}
fgets(buffer, sizeof(buffer),fpR);
if(buffer[0] == '#'){//catch comment line and print back to new file
fputs(buffer,fpW);
}
}while(buffer[0] == '#');
switch(j){
case date:
fprintf(fpW,"%d-%d-%d",tran->row[i].date.day,tran->row[i].date.month,tran->row[i].date.year);
break;
case time:
fprintf(fpW,"%d:%d:%d",tran->row[i].time.hour,tran->row[i].time.minute,tran->row[i].time.second);
break;
case id_tran:
fprintf(fpW,"%ld",tran->row[i].id);
break;
case price_tran:
fprintf(fpW,"%f",tran->row[i].price);
break;
case quantity:
fprintf(fpW,"%d",tran->row[i].quantity);
break;
case barcode_tran:
fprintf(fpW,"%ld",tran->row[i].barcode);
break;
}
fprintf(fpW,"\n");
}
}
//close file and replace old file with new file
fclose(fpR);
fclose(fpW);
remove(TRANSACTION_DB);
rename(temp,TRANSACTION_DB);
return true;
}
bool update_db_user(struct user* user){
FILE* fpR = fopen(USER_DB,"r");
char temp[30] = USER_DB;
strcat(temp,".temp");
FILE* fpW = fopen(temp,"w");
if(fpR == NULL || fpW == NULL){
printf("Error in opening file\n");
return false;
}
for(int i=0;i<user->db.row_count;i++){
if(user->row[i].isdeleted == true){
continue;
}
for(USER j=name;j<ENDOFUSER;j++){
char buffer[100];
do{
if(feof(fpR)){
break;
}
fgets(buffer, sizeof(buffer),fpR);
if(buffer[0] == '#'){//catch comment line and print back to new file
fputs(buffer,fpW);
}
}while(buffer[0] == '#');
switch(j){
case name:
fprintf(fpW,"%s",user->row[i].name);
break;
case role:
fprintf(fpW,"%s",user->row[i].role);
break;
case id_user:
fprintf(fpW,"%ld",user->row[i].id);
break;
}
fprintf(fpW,"\n");
}
}
//close file and replace old file with new file
fclose(fpR);
fclose(fpW);
remove(USER_DB);
rename(temp,USER_DB);
return true;
}