struct Connection *Database_open(const char *filename, char mode) { struct Connection *conn = malloc(sizeof(struct Connection)); if (!conn) die("Memory Error"); conn->db = malloc(sizeof(struct Database)); if (!conn->db) die("Memory Error"); if (mode == 'c') { conn->file = fopen(filename, "w"); } else { conn->file = fopen(filename, "r+"); if (conn->file) { Database_load(conn); } } if (!conn->file) die("Failed to open the file"); return conn; };
void Database_open(const char *filename, char mode) { int i; conn = malloc(sizeof(struct Connection)); if(!conn) die("Memory error."); conn->db = malloc(sizeof(struct Database)); if(!conn->db) die("Memory error."); if(mode == 'c') { conn->file = fopen(filename, "w"); } else { conn->file = fopen(filename, "r+"); fread(&max_rows, sizeof(int), 1, conn->file); fread(&max_data, sizeof(int), 1, conn->file); } if(!conn->file) die("Failed to open the file"); conn->db->rows = malloc(sizeof(struct Address) * max_rows); if(!conn->db->rows) die("Memory error."); for (i = 0; i < max_rows; i++) { conn->db->rows[i].id = i; conn->db->rows[i].set = 0; conn->db->rows[i].name = calloc(1, sizeof(char) * max_data); if (!conn->db->rows[i].name) die("Memory error"); conn->db->rows[i].email = calloc(1, sizeof(char) * max_data); if (!conn->db->rows[i].email) die("Memory error"); conn->db->rows[i].name[max_data - 1] = '\0'; conn->db->rows[i].email[max_data - 1] = '\0'; } if (mode != 'c') { if(conn->file) { Database_load(); } } }
struct Connection *Database_open(const char *filename, char mode) //allocates memory to the database { struct Connection *conn = malloc(sizeof(struct Connection)); if(!conn) die("Memory error"); conn->db = malloc(sizeof(struct Database)); //block of memory size equaling the size of the database if(!conn->db) die("Memory error"); if(mode == 'c') { conn->file = fopen(filename, "w"); //if we want to create a database... } else { conn->file = fopen(filename, "r+"); if(conn->file){ Database_load(conn); } } if(!conn->file) die("Failed to open the file"); return conn; }
void Database_delete(int id) { struct Address addr = {.id = id, .set = 0} ; // Yep, need to allocate the memory for these strings here too; // just like we did when we first initialized all the Addresses. addr.name = malloc(sizeof(char) * conn->db->max_data); addr.email = malloc(sizeof(char) * conn->db->max_data); conn->db->rows[id] = addr; } void Database_list() { struct Database *db = conn->db; printf("MAX_DATA: %d\n", db->max_data); printf("MAX_ROWS: %d\n", db->max_rows); int i = 0; for (i = 0; i < db->max_rows; i++) { struct Address *cur = &db->rows[i]; if (cur->set) Address_print(cur); } } void Database_open(const char *filename, char mode) { // Initialize the global connection conn = malloc(sizeof(struct Connection)); if (!conn) die("Memory error."); conn->db = malloc(sizeof(struct Database)); if (!conn->db) die("Memory error"); if (mode == 'c') { conn->file = fopen(filename, "w"); } else { conn->file = fopen(filename, "r+"); if (conn->file) Database_load(); } if (!conn->file) die("Failed to open file."); }
struct Connection *Database_open(const char *filename, char mode) { struct Connection *conn = malloc(sizeof(struct Connection)); if(!conn) die("Memory error"); // This could happen when memory in your computer is exhausted. conn->db = malloc(sizeof(struct Database)); if(!conn->db) die("Memory error"); if(mode == 'c') { conn->file = fopen(filename, "w"); } else { conn->file = fopen(filename, "r+"); if(conn->file) { Database_load(conn); } } if(!conn->file) die("Failed to open the file"); return conn; }
struct Connection *Database_open(const char *filename, char mode) { //printf("Allocated memory for connection\n"); struct Connection *conn = malloc(sizeof(struct Connection)); if(!conn) die("Memory error.", conn); //printf("Allocated memory for database\n"); conn->db = malloc(sizeof(struct Database)); if(!conn->db) die("Memory error.", conn); if(mode == 'c') { conn->file = fopen(filename, "w"); } else { conn->file = fopen(filename, "r+"); if(conn->file) { Database_load(conn); } } if(!conn->file) die("Failed to open the file.", conn); return conn; }
struct Connection* Database_open(const char *filename, char mode, int max_rows, int max_data) { struct Connection *conn = malloc(sizeof(struct Connection)); if(!conn) die("Memory Error"); // conn->db = malloc(sizeof(struct Database)); long size = sizeof(struct Database) + ((sizeof(struct Address) + (max_data * 2)) * max_rows); conn->db = malloc(size); if(!conn->db) die ("Memory Error"); if(mode == 'c') { conn->file = fopen(filename, "w"); } else { conn->file = fopen(filename, "r+"); if(conn->file) { Database_load(conn, size); printf("loaded db with max rows %d and max data %d\n", conn->db->max_rows, conn->db->max_data); } } if(!conn->file) die("Failed to open the file"); return conn; }
void Database_create(struct Connection *conn, int max_rows, int max_data) { conn->db->max_rows = max_rows; conn->db->max_data = max_data; Database_alloc_rows(conn); int i = 0; for(i = 0; i < max_rows; i++) { struct Address addr = { .id = i, .set = 0}; addr.email = malloc(sizeof(char) * conn->db->max_data); addr.name = malloc(sizeof(char) * conn->db->max_data); conn->db->rows[i] = addr; } } struct Connection *Database_open(const char *filename, char mode) { struct Connection *conn = malloc(sizeof(struct Connection)); if(!conn) die("Memory error", conn); conn->db = malloc(sizeof(struct Database)); if(!conn->db) die("Memory error", conn); if(mode == 'c') { conn->file = fopen(filename, "w"); } else { conn->file = fopen(filename, "r+"); if(conn->file) { Database_load(conn); } } if(!conn->file) die("Failed to open the file", conn); return conn; } void Database_close(struct Connection *conn) { if(conn) { if(conn->file) fclose(conn->file); if(conn->db->rows) free(conn->db->rows); if(conn->db) free(conn->db); free(conn); } } void Database_set(struct Connection *conn, int id, const char *name, const char *email) { struct Address *addr = &conn->db->rows[id]; if(addr->set) die("Already set, delete it first", conn); addr->set = 1; //WARNING: bug, read the "How to break it" and fix this char *res = strncpy(addr->name, name, conn->db->max_data); //demonstrate the strncpy bug if(!res) die("Name copy failed", conn); res = strncpy(addr->email, email, conn->db->max_data); if(!res) die("Email copy failed", conn); } void Database_get(struct Connection *conn, int id) { if(id > conn->db->max_rows) { die("There's not that many rows", conn); } struct Address *addr = &conn->db->rows[id]; if(addr->set) { Address_print(addr); } else { die("ID not set", conn); } } void Database_delete(struct Connection *conn, int id) { struct Address addr = {.id = id, .set = 0}; addr.email = malloc(sizeof(char) * conn->db->max_data); addr.name = malloc(sizeof(char) * conn->db->max_data); conn->db->rows[id] = addr; } void Database_list(struct Connection *conn) { int i = 0; for(i=0; i< conn->db->max_rows; i++) { struct Address *cur = &(conn->db->rows[i]); if(cur->set) { Address_print(cur); } } } int main(int argc, char *argv[]) { if(argc < 3) die("USAGE: ex17 <dbfile> <action> [action params]", NULL); char *filename = argv[1]; char action = argv[2][0]; struct Connection *conn = Database_open(filename, action); int param1 = 0; int param2 = 0; int max_rows = 100; int max_data = 512; if(argc > 3) { param1 = atoi(argv[3]); } if(argc > 4) { param2 = atoi(argv[4]); } switch(action) { case 'c': if(argc > 3) { max_rows = param1; } if(argc > 4) { max_data = param2; } Database_create(conn, max_rows, max_data); Database_write(conn); break; case 'g': if(argc != 4) die("Need an id to get", conn); Database_get(conn, param1); break; case 's': if(argc != 6) die("Need id, name, email to set", conn); Database_set(conn, param1, argv[4], argv[5]); Database_write(conn); break; case 'd': if(argc != 4) die("Need an id to delete", conn); Database_delete(conn, param1); Database_write(conn); break; case 'l': Database_list(conn); break; default: die("Invalid action, only: c=create, g-get, s=set, d=del, l=list", conn); } Database_close(conn); return 0; }