/** * @author Unknown * @brief Function for testing table abstraction * @return No return value @update by Ana-Marija Balen - added getRow function to the test */ TestResult AK_table_test() { AK_PRO; printf("table.c: Present!\n"); printf("\n********** TABLE ABSTRACTION TEST by Matija Šestak **********\n\n"); printf("Table \"student\":AK_print_table\n"); AK_print_table("student"); printf("\n"); printf("Table \"student\": AK_table_empty: "); if (AK_table_empty("student")) printf("true\n"); else printf("false\n"); printf("\n"); printf("Table \"student\": AK_num_attr: "); printf("%d\n", AK_num_attr("student")); printf("\n"); int get_num_records; printf("Table \"student\": AK_get_num_records: "); printf("%d\n", get_num_records = AK_get_num_records("student")); printf("\n"); printf("Table \"student\": AK_get_row: "); int i; AK_header *head = AK_get_header("student"); int num_attr = AK_num_attr("student"); int len[num_attr]; for (i = 0; i < num_attr; i++) { len[i] = strlen((head + i)->att_name); } AK_print_row(len, AK_get_row(0,"student")); printf("\n"); printf("Table \"student\": AK_get_attr_name for index 3: "); int get_attr_name; printf("%s\n", get_attr_name = AK_get_attr_name("student", 3)); printf("\n"); int get_attr_index; printf("Table \"student\": AK_get_attr_index of \"year\": "); printf("%d\n", get_attr_index = AK_get_attr_index("student", "year")); printf("\n"); int tuple_to_string; printf("Table \"student\": AK_get_tuple for row=0, column=1:"); printf("%s\n", tuple_to_string = AK_tuple_to_string(AK_get_tuple(0, 1, "student"))); if (get_num_records != EXIT_WARNING & get_attr_name != NULL & get_attr_index != EXIT_WARNING & tuple_to_string != NULL) { printf("\nTest succeeded!\n"); } else{ printf("\nTest failed!\n"); } AK_EPI; return TEST_result(0,0); }
/** * @author Dino Laktašić and Mislav Čakarić (replaced old print table function by new one) * @brief Function for printing table * @param *tblName table name * @return No return value */ void AK_print_table(char *tblName) { AK_PRO; table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName); // || (AK_table_exist(tblName) == 0) if ((addresses->address_from[0] == 0) || (AK_table_exist(tblName) == 0)) { printf("Table %s does not exist!\n", tblName); AK_free(addresses); } else { AK_header *head = AK_get_header(tblName); int i, j, k, l; int num_attr = AK_num_attr(tblName); int num_rows = AK_get_num_records(tblName); int len[num_attr]; //max length for each attribute in row int length = 0; //length of spacer clock_t t; //store lengths of header attributes for (i = 0; i < num_attr; i++) { len[i] = strlen((head + i)->att_name); } //for each header attribute iterate through all table rows and check if //there is longer element than previously longest and store it in array for (i = 0; i < num_attr; i++) { for (j = 0; j < num_rows; j++) { struct list_node *el = AK_get_tuple(j, i, tblName); switch (el->type) { case TYPE_INT: length = AK_chars_num_from_number(*((int *) (el)->data), 10); if (len[i] < length) { len[i] = length; } break; case TYPE_FLOAT: length = AK_chars_num_from_number(*((float *) (el)->data), 10); if (len[i] < length) { len[i] = length; } break; case TYPE_VARCHAR: default: if (len[i] < el->size) { len[i] = el->size; } break; } //we don't need this linked list anymore (starting from tupple first to the end //see comment above in function AK_get_tuple - Elvis Popovic Ak_DeleteAll_L3(&el); AK_free(el); } } //num_attr is number of char | + space in printf //set offset to change the box size length = 0; for (i = 0; i < num_attr; length += len[i++]); length += num_attr * TBL_BOX_OFFSET + 2 * num_attr + 1; //start measuring time t = clock(); printf("Table: %s\n", tblName); if (num_attr <= 0 || num_rows <= 0) { printf("Table is empty.\n"); } else { //print table header AK_print_row_spacer(len, length); printf("\n|"); for (i = 0; i < num_attr; i++) { //print attributes center aligned inside box k = (len[i] - (int) strlen((head + i)->att_name) + TBL_BOX_OFFSET + 1); if (k % 2 == 0) { k /= 2; printf("%-*s%-*s|", k, " ", k + (int) strlen((head + i)->att_name), (head + i)->att_name); } else { k /= 2; printf("%-*s%-*s|", k, " ", k + (int) strlen((head + i)->att_name) + 1, (head + i)->att_name); } //print attributes left aligned inside box //printf(" %-*s|", len[i] + MAX_TABLE_BOX_OFFSET, (head + i)->att_name); } AK_free(head); printf("\n"); AK_print_row_spacer(len, length); struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node)); Ak_Init_L3(&row_root); i = 0; int type, size, address; while (addresses->address_from[i] != 0) { for (j = addresses->address_from[i]; j < addresses->address_to[i]; j++) { AK_mem_block *temp = (AK_mem_block*) AK_get_block(j); if (temp->block->last_tuple_dict_id == 0) break; for (k = 0; k < DATA_BLOCK_SIZE; k += num_attr) { if (temp->block->tuple_dict[k].size > 0 /*&& k / num_attr < num_rows*/) { for (l = 0; l < num_attr; l++) { type = temp->block->tuple_dict[k + l].type; size = temp->block->tuple_dict[k + l].size; address = temp->block->tuple_dict[k + l].address; Ak_InsertAtEnd_L3(type, &temp->block->data[address], size, row_root); } AK_print_row(len, row_root); AK_print_row_spacer(len, length); Ak_DeleteAll_L3(&row_root); } } } i++; } printf("\n"); t = clock() - t; if ((((double) t) / CLOCKS_PER_SEC) < 0.1) { printf("%i rows found, duration: %f μs\n", num_rows, ((double) t) / CLOCKS_PER_SEC * 1000); } else { printf("%i rows found, duration: %f s\n", num_rows, ((double) t) / CLOCKS_PER_SEC); } AK_free(row_root); } AK_free(addresses); } AK_EPI; }
/** * @author Matija Šestak, modified for indexes by Lovro Predovan * @brief Function for printing index table * @param *tblName table name * @return No return value */ void AK_print_index_table(char *indexTblName) { AK_PRO; table_addresses *addresses = (table_addresses*) AK_get_index_addresses(indexTblName); char *index_table = "AK_index"; if ((addresses->address_from[0] == 0) || (AK_index_table_exist(indexTblName) == 0)) { printf("Table %s does not exist!\n", indexTblName); AK_EPI; } else { AK_header *head = AK_get_index_header(indexTblName); int i, j, k, l; int num_attr = AK_num_index_attr(indexTblName); int num_rows = AK_get_index_num_records(indexTblName); int len[num_attr]; //max length for each attribute in row int length = 0; //length of spacer clock_t t; //printf("BROJ ATTR %i ; BROJ REDOVA %i U TABLICI %s",num_attr,num_rows,indexTblName); //store lengths of header attributes for (i = 0; i < num_attr; i++) { len[i] = strlen((head + i)->att_name); } //for each header attribute iterate through all table rows and check if //there is longer element than previously longest and store it in array for (i = 0; i < num_attr; i++) { for (j = 0; j < num_rows; j++) { struct list_node *el = AK_get_index_tuple(j, i, indexTblName); switch (el->type) { case TYPE_INT: length = AK_chars_num_from_number(*((int *) (el)->data), 10); if (len[i] < length) { len[i] = length; } break; case TYPE_FLOAT: length = AK_chars_num_from_number(*((float *) (el)->data), 10); if (len[i] < length) { len[i] = length; } break; case TYPE_VARCHAR: default: if (len[i] < el->size) { len[i] = el->size; } break; } } } //num_attr is number of char | + space in printf //set offset to change the box size length = 0; for (i = 0; i < num_attr; length += len[i++]); length += num_attr * TBL_BOX_OFFSET + 2 * num_attr + 1; //start measuring time t = clock(); if (num_attr <= 0 || num_rows <= 0) { printf("Table is empty.\n"); AK_EPI; } else { AK_print_row_spacer(len, length); printf("\n|"); //HEADER for (i = 0; i < num_attr; i++) { //PRINTING HEADER ELEMENTS CENTERED k = (len[i] - (int) strlen((head + i)->att_name) + TBL_BOX_OFFSET + 1); if (k % 2 == 0) { k /= 2; printf("%-*s%-*s|", k, " ", k + (int) strlen((head + i)->att_name), (head + i)->att_name); } else { k /= 2; printf("%-*s%-*s|", k, " ", k + (int) strlen((head + i)->att_name) + 1, (head + i)->att_name); } } printf("\n"); AK_print_row_spacer(len, length); //END HEADER struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node)); Ak_Init_L3(&row_root); int type, size, address,last_addres_value; i = 0; if(addresses->address_to[i] != 0){ last_addres_value = addresses->address_to[i]; } while (addresses->address_from[i] != 0) { for (j = addresses->address_from[i]; j < addresses->address_to[i]; j++) { AK_mem_block *temp = (AK_mem_block*) AK_get_block(j); //THIS IS KINDA HACK, THIS PROBABLY SHOULD BE CHANGED SO MAIN INDEX TABLE ARE NOT INCLUDED if ((temp->block->last_tuple_dict_id == 0) && (last_addres_value == addresses->address_to[i])){ printf("\nIndex: %s\n", indexTblName); //PRINTING OUT TIME STATS t = clock() - t; if ((((double) t) / CLOCKS_PER_SEC) < 0.1) { printf("%i rows found, duration: %f μs\n", num_rows, ((double) t) / CLOCKS_PER_SEC * 1000); } else { printf("%i rows found, duration: %f s\n", num_rows, ((double) t) / CLOCKS_PER_SEC); } AK_free(row_root); AK_free(addresses); AK_EPI; //break; return 1; } //PRINTING VALUES IN INDEX TABLE for (k = 0; k < DATA_BLOCK_SIZE; k += num_attr) { if (temp->block->tuple_dict[k].size > 0) { for (l = 0; l < num_attr; l++) { type = temp->block->tuple_dict[k + l].type; size = temp->block->tuple_dict[k + l].size; address = temp->block->tuple_dict[k + l].address; Ak_InsertAtEnd_L3(type, &temp->block->data[address], size, row_root); } AK_print_row(len, row_root); AK_print_row_spacer(len, length); Ak_DeleteAll_L3(&row_root); } } } i++; } AK_free(row_root); } } AK_free(addresses); AK_EPI; }