void DatabaseCreate(struct Connection *conn){ for (int i=0; i < MAX_ROWS; i++){ struct Address addr = {.id = i, .set = 0}; conn->db->rows[i] = addr; } } void DatabaseSet(struct Connection *conn, int id, const char *name, const char *email){ struct Address *addr = &conn->db->rows[id]; if(addr->set) die("Allready set, delete it first"); addr->set = 1; char *res = strncpy(addr->name, name, MAX_DATA); if (!res) die("Name copy fialed"); res = strncpy(addr->email, email, MAX_DATA); if (!res) die("Email copy failed"); } void DatabaseGet(struct Connection *conn, int id){ struct Address *addr = &conn->db->rows[id]; if(addr->set){ AddressPrint(addr); } else { die("ID is not set"); } } void DatabaseDelete(struct Connection *conn, int id){ struct Address addr = {.id = id, .set = 0}; conn->db->rows[id] = addr; } void DatabaseList(struct Connection *conn){ struct Database *db = conn->db; for (int i=0; i<MAX_ROWS; i++){ struct Address *cur = &db->rows[i]; if(cur->set){ AddressPrint(cur); } } } int main(int argc, char *argv[]){ if(argc < 3) die("USAGE: ext17 <dbfile> <action> [action params]"); char *filename = argv[2]; char action = argv[1][0]; struct Connection *conn = DatabaseOpen(filename, action); int id = 0; if(argc > 3) id = atoi(argv[3]); if(id >= MAX_ROWS) die("There is not that many records."); switch(action){ case 'c': DatabaseCreate(conn); DatabaseWrite(conn); break; case 'g': if (argc != 4) die("Need an id to get"); DatabaseGet(conn, id); break; case 's': if(argc != 6) die("Need id, name, email to set."); DatabaseSet(conn, id, argv[4], argv[5]); DatabaseWrite(conn); break; case 'd': if(argc != 4) die("Need id to delete"); DatabaseDelete(conn, id); DatabaseWrite(conn); break; case 'l': DatabaseList(conn); break; default: die("Invalid action:\nc=create\ng=get\ns=set\nd=del\nl=list"); } DatabaseClose(conn); return 0; }
void DatabaseCreate(struct Connection* conn ) { int i = 0; for(i = 0; i < MAX_ROWS; i++) { //make a prototype to initialise it struct Address addr = {.id = i, .set =0}; //then just assign it conn->db->rows[i] = addr; } } void DatabaseSet(struct Connection* conn, int id, const char* name, const char* email) { struct Address* addr = &conn->db->rows[id]; if(addr->set) Die("Already set, deleted it first!", conn); addr->set =1; //WARNING: bug, read the "How to break it" section and fix this char* res = strncpy(addr->name,name,MAX_DATA); //demonstrate the strncpy bug if(!res) Die("Name copy failed", conn); res = strncpy(addr->email,email,MAX_DATA); if(!res) Die("Email copy failed", conn); } void DatabaseGet(struct Connection* conn, int id) { struct Address* addr = &conn->db->rows[id]; if(addr->set) { AddressPrint(addr); } else { Die("Id is not set.", conn); } } void DatabaseDelete(struct Connection* conn, int id) { struct Address addr = {.id = id, .set = 0}; conn->db->rows[id] = addr; } void DatabaseList(struct Connection* conn) { int i = 0; struct Database* db = conn->db; for(i=0;i<MAX_ROWS;i++) { struct Address* cur = &db->rows[i]; if(cur->set) AddressPrint(cur); } } int main(int argc, char* argv[]) { if(argc<3) Die("USAGE: ex17 <dbfile> <action> [action params]", conn); char* filename = argv[1]; char action = argv[2][0]; struct Connection* conn = DatabaseOpen(filename, action); int id =0; if(argc>3) id = atoi(argv[3]); if(id>=MAX_ROWS) Die("There's not that many records.", conn); switch(action) { case 'c': DatabaseCreate(conn); DatabaseWrite(conn); break; case 'g': if(argc != 4) Die("Need an id to get", conn); DatabaseGet(conn, id); break; case 's': if(argc != 6) Die("Need id, name, email to set.", conn); DatabaseSet(conn, id, argv[4], argv[5]); DatabaseWrite(conn); break; case 'd': if(argc != 4) Die("Need id to delete", conn); DatabaseDelete(conn, id); DatabaseWrite(conn); break; case 'l': DatabaseList(conn); break; default: Die("Invalid action, only: c=create, g=get, s=set, d=del, l=list", conn); }//end switch action DatabaseClose(conn); return 0; }//end main