コード例 #1
0
ファイル: rel_eq_selection.c プロジェクト: embalint/akdb
/**
 * @author Dino Laktašić.
 * @brief Break conjunctive conditions to individual conditions 
 * (currently not used - commented in main AK_rel_eq_selection function), it can be usefull in some optimization cases
 * <ol>
 * <li>For each delimited item (' AND ') insert item to the struct list_node</li>
 * <li>Remove unused pointers and return the conditions list</li>
 * </ol>
 * @param *cond condition expression
 * @result conditions list
 */
struct list_node *AK_rel_eq_split_condition(char *cond) {
    AK_PRO;
    struct list_node *list_attr = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&list_attr);

    int token_id = 0;
    int attr_address = 0;
    int len_token;
    char *token_cond, *save_token_cond;

    //it's much safe to allocate MAX_VARCHAR_LENGHT, and remove all AK_realloc from function
    char *temp_attr = (char *) AK_calloc(1, sizeof (char));
    //memset(temp_attr, '\0', MAX_VARCHAR_LENGHT);

    char *temp_cond = (char *) AK_calloc(strlen(cond), sizeof (char));
    memcpy(temp_cond, cond, strlen(cond));

    for ((token_cond = strtok_r(temp_cond, " ", &save_token_cond)); token_cond;
            (token_cond = strtok_r(NULL, " ", &save_token_cond)), token_id++) {
        if (token_id < MAX_TOKENS - 1) {
            len_token = strlen(token_cond);

            if (strcmp(token_cond, "AND") == 0) {
            	Ak_InsertAtEnd_L3(TYPE_CONDITION, temp_attr, strlen(temp_attr), list_attr);

                attr_address = 0;
                AK_free(temp_attr);
                temp_attr = (char *) AK_calloc(1, sizeof (char));
            } else {
                if (attr_address > 0) {
                    temp_attr = (char *) AK_realloc(temp_attr, attr_address + len_token + 2);
                    //memcpy(temp_attr + attr_address, " ", 1);
                    strcpy(temp_attr + attr_address, " ");
                    //memcpy(temp_attr + ++attr_address, "\0", 1);
                    attr_address++;
                } else {
                    temp_attr = (char *) AK_realloc(temp_attr, attr_address + len_token + 1);
                }

                strcpy(temp_attr + attr_address, token_cond);
                //memcpy(temp_attr + attr_address, token_cond, len_token);
                attr_address += len_token;
            }
        }
    }

    //memcpy(temp_attr + attr_address, "\0", 1);
    Ak_InsertAtEnd_L3(TYPE_CONDITION, temp_attr, strlen(temp_attr), list_attr);

    AK_free(temp_cond);
    AK_free(temp_attr);
    AK_EPI;
    return list_attr;
}
コード例 #2
0
ファイル: table.c プロジェクト: mschatten/akdb
/**
 * @author Matija Šestak.
 * @brief  Function that fetches all values in some column and put on the list
 * @param num zero-based column index
 * @param  *tblName table name
 * @return column values list
 */
struct list_node *AK_get_column(int num, char *tblName) {
    AK_PRO;
    int num_attr = AK_num_attr(tblName);
    if (num >= num_attr || num < 0){
        AK_EPI;
        return NULL;
    }
    struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&row_root);

    table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName);
    int i, j, k;
    char data[ MAX_VARCHAR_LENGTH ];

    i = 0;
    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 = num; k < DATA_BLOCK_SIZE; k += num_attr) {
                if (temp->block->tuple_dict[k].type != FREE_INT) {
                    int type = temp->block->tuple_dict[k].type;
                    int size = temp->block->tuple_dict[k].size;
                    int address = temp->block->tuple_dict[k].address;
                    memcpy(data, &(temp->block->data[address]), size);
                    data[ size ] = '\0';
                    Ak_InsertAtEnd_L3(type, data, size, row_root);
                }
            }
        }
        i++;
    }
    AK_EPI;
    return row_root;
}
コード例 #3
0
ファイル: selection.c プロジェクト: embalint/akdb
/**
 * @author Krunoslav Bilić
 * @brief  Function for selection operator testing
 *
 */
void AK_op_selection_test2() {
	AK_PRO;
	printf("\n********** SELECTION TEST 2**********\n");
	
	struct list_node *expr = (struct list_node *) AK_malloc(sizeof(struct list_node));
	Ak_Init_L3(&expr);
	
	char *srcTable = "student";
	char *destTable = "selection_test2";
	char num = 23;

	strcpy(expr->table,destTable);

	Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "year", sizeof ("year"), expr);
	Ak_InsertAtEnd_L3(TYPE_INT, &num, sizeof (int), expr);
	Ak_InsertAtEnd_L3(TYPE_OPERATOR, ">", sizeof (">"), expr);
	Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "firstname", sizeof ("firstname"), expr);
	Ak_InsertAtEnd_L3(TYPE_VARCHAR, "Mislav", sizeof ("Mislav"), expr);
	Ak_InsertAtEnd_L3(TYPE_OPERATOR, "=", sizeof ("="), expr);
	Ak_InsertAtEnd_L3(TYPE_OPERATOR, "OR", sizeof ("OR"), expr);

	printf("\nQUERY: SELECT * FROM student WHERE year > 2023 OR firstname = 'Mislav';\n\n");

	AK_selection(srcTable, destTable, expr);
	//AK_print_table("selection_test");

	Ak_DeleteAll_L3(&expr);
	AK_free(expr);
	AK_EPI;
}
コード例 #4
0
ファイル: table.c プロジェクト: mschatten/akdb
/**
 * @author Matija Šestak.
 * @brief Function that fetches a value in some row and column
 * @param row zero-based row index
 * @param column zero-based column index
 * @param *tblName table name
 * @return value in the list
 */
struct list_node *AK_get_tuple(int row, int column, char *tblName) {
    AK_PRO;
    int num_rows = AK_get_num_records(tblName);
    int num_attr = AK_num_attr(tblName);

    if (row >= num_rows || column >= num_attr){
        AK_EPI;
        return NULL;
    }

    table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName);

    struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&row_root);

    int i, j, k, counter;
    char data[ MAX_VARCHAR_LENGTH ];

    i = 0;
    counter = -1;
    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)
                    counter++;
                if (counter == row) 
				{
					struct list_node *next;
                    int type = temp->block->tuple_dict[ k + column ].type;
                    int size = temp->block->tuple_dict[ k + column ].size;
                    int address = temp->block->tuple_dict[ k + column ].address;
                    memcpy(data, &(temp->block->data[address]), size);
                    data[ size ] = '\0';
                    Ak_InsertAtEnd_L3(type, data, size, row_root);
                    AK_free(addresses);
					next = Ak_First_L2(row_root); //store next
					AK_free(row_root); //now we can free base
                    AK_EPI;
					//returns next in row_root leaving base of the list allocated, so we made some corrections
                    //return (struct list_node *) Ak_First_L2(row_root);
					return next; //returns next
                }
            }
        }
        i++;
    }
    AK_free(addresses);
	Ak_DeleteAll_L3(&row_root);
	AK_free(row_root);
    AK_EPI;
    return NULL;
}
コード例 #5
0
ファイル: test.c プロジェクト: mschatten/akdb
/**
 * @author Luka Rajcevic
 * @brief Function for selection operator on one table
 + @param src_table - name of the source table
 + @param dest_table - table in which selection will be stored
 * @param sel_query - array of operators, operands and attributes (postfix query)
 * @param _num - number of attributes
 * @param _type - array of attribute types (eg. TYPE_INT, TYPE_VARCHAR, etc.)
 * @return EXIT_SUCCESS if ok, EXIT_ERROR otherwise
 *
 */
int selection_test(char* src_table, char* dest_table, char** sel_query, int _num, int* _type){
    AK_PRO;
	printf("==================== SELECTION_TEST =====================\n");

    struct list_node *expr = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&expr);

    // TYPE_OPERAND 10
    // TYPE_OPERATOR 11
    // TYPE_ATTRIBS 12

    strcpy(expr->table,dest_table);
    int i;
    for (i = 0; i < _num; i++){
        if (_type[i] == TYPE_INT){
            int val = atoi(sel_query[i]);
            Ak_InsertAtEnd_L3(_type[i], (char*) &val, sizeof(int), expr);    
        }
        if (_type[i] == TYPE_FLOAT){
            float val = atof(sel_query[i]);
            Ak_InsertAtEnd_L3(_type[i], (char *) &val, sizeof(float), expr);
        }
        if (_type[i] == TYPE_OPERATOR || _type[i] == TYPE_ATTRIBS || _type[i] == TYPE_VARCHAR){
            Ak_InsertAtEnd_L3(_type[i], sel_query[i], strlen(sel_query[i]), expr);
        }
    }

    if (AK_selection(src_table, dest_table, expr) == EXIT_SUCCESS){
        Ak_DeleteAll_L3(&expr);
        AK_free(expr); 
        AK_EPI;  
        return 1;
    }
    AK_EPI;
    return 0;

}
コード例 #6
0
ファイル: index.c プロジェクト: embalint/akdb
/**
 * @author Matija Šestak, modified for indexes by Lovro Predovan
 * @brief Function that gets value in some row and column
 * @param row zero-based row index
 * @param column zero-based column index
 * @param *tblName table name
 * @return value in the list
 */
struct list_node *AK_get_index_tuple(int row, int column, char *indexTblName) {
    AK_PRO;

    int num_rows = AK_get_index_num_records(indexTblName);
    int num_attr = AK_num_index_attr(indexTblName);

    if (row >= num_rows || column >= num_attr){
        AK_EPI;
        return NULL;
    }

    table_addresses *addresses = (table_addresses*) AK_get_index_addresses(indexTblName);

    struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&row_root);

    int i, j, k, counter;
    char data[ MAX_VARCHAR_LENGTH ];

    i = 0;
    counter = -1;
    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)
                    counter++;
                if (counter == row) {
                    int type = temp->block->tuple_dict[ k + column ].type;
                    int size = temp->block->tuple_dict[ k + column ].size;
                    int address = temp->block->tuple_dict[ k + column ].address;
                    memcpy(data, &temp->block->data[address], size);
                    data[ size ] = '\0';
                    Ak_InsertAtEnd_L3(type, data, size, row_root);
                    AK_free(addresses);
                    AK_EPI;
                    return (struct list_node *) Ak_First_L2(row_root);
                }
            }
        }
        i++;
    }
    AK_free(addresses);
    AK_EPI;
    return NULL;
}
コード例 #7
0
ファイル: table.c プロジェクト: mschatten/akdb
/**
 * @author Markus Schatten, Matija Šestak.
 * @brief  Function that fetches all values in some row and put on the list
 * @param num zero-based row index
 * @param  * tblName table name
 * @return row values list
 */
struct list_node *AK_get_row(int num, char * tblName) {
    AK_PRO;
    table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName);
    struct list_node *row_root = (struct list_node *)AK_calloc(1, sizeof (struct list_node));
    Ak_Init_L3(&row_root);

    int num_attr = AK_num_attr(tblName);
    int i, j, k, l, counter;
    i = 0;

    char data[MAX_VARCHAR_LENGTH];
    counter = -1;
    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)
                    counter++;
                if (counter == num) {
                    for (l = 0; l < num_attr; l++) {
                        int type = temp->block->tuple_dict[k + l].type;
                        int size = temp->block->tuple_dict[k + l].size;
                        int address = temp->block->tuple_dict[k + l].address;
                        memcpy(data, &(temp->block->data[address]), size);
                        data[size] = '\0';
                        Ak_InsertAtEnd_L3(type, data, size, row_root);
                    }
                    AK_free(addresses);
                    AK_EPI;
                    return row_root;
                }
            }
        }
        i++;
    }
    AK_free(addresses);
	Ak_DeleteAll_L3(&row_root);
	AK_free(row_root);
    AK_EPI;
    return NULL;
}
コード例 #8
0
ファイル: command.c プロジェクト: embalint/akdb
/**
 * @author Unknown, updated by Tomislav Ilisevic
 * @brief  Function for testing commands
 *
 */
void AK_test_command(){
    AK_PRO;
    printf("***Test Command***\n");
    int brojkomandi = 4;
    command *komande = AK_malloc(sizeof(command)*(brojkomandi+1));


	// Test za komandu INSERT

    struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&row_root);
    
    char *tblName = "student";
   
    int mbr, year;
    float weight;
    mbr = 35917;
    year = 2012;
    weight = 82.00;
    Ak_DeleteAll_L3(&row_root);
    Ak_Insert_New_Element(TYPE_INT, &mbr, tblName, "mbr", row_root);
    Ak_Insert_New_Element(TYPE_VARCHAR, "Mario", tblName, "firstname", row_root);
    Ak_Insert_New_Element(TYPE_VARCHAR, "Kolmacic", tblName, "lastname", row_root);
    Ak_Insert_New_Element(TYPE_INT, &year, tblName, "year", row_root);
    Ak_Insert_New_Element(TYPE_FLOAT, &weight, tblName, "weight", row_root);

    komande[0].id_command = INSERT;
    komande[0].tblName = "student";
    komande[0].parameters = row_root;


	// Test za komandu UPDATE

    mbr = 35900;
    
    row_root = (struct list_node *) AK_malloc(sizeof (struct list_node ));
    Ak_Init_L3(&row_root);
    Ak_DeleteAll_L3(&row_root);

    Ak_Insert_New_Element_For_Update(TYPE_INT, &mbr, tblName, "mbr", row_root, 1);
    Ak_Insert_New_Element_For_Update(TYPE_VARCHAR, "FOI", tblName, "firstname", row_root, 0);

    komande[1].id_command = UPDATE;
    komande[1].tblName = "student";
    komande[1].parameters = row_root;


	// Test za komandu DELETE

    int id_prof;
    id_prof = 35893;
    
    row_root = (struct list_node *) AK_malloc(sizeof (struct list_node ));
    Ak_Init_L3(&row_root);
    Ak_DeleteAll_L3(&row_root);

    Ak_Insert_New_Element_For_Update(TYPE_INT, &id_prof, tblName, "id_prof", row_root, 1);
    Ak_Insert_New_Element_For_Update(TYPE_VARCHAR, "FOI", tblName, "firstname", row_root, 0);

    komande[2].id_command = DELETE;
    komande[2].tblName = "professor";
    komande[2].parameters = row_root;


	// Test za komandu SELECT

	row_root = (struct list_node *) AK_malloc(sizeof (struct list_node ));
	Ak_Init_L3(&row_root);
	Ak_DeleteAll_L3(&row_root);

//	printf("\nQUERY: SELECT * FROM student WHERE firstname = 'Robert';\n\n");

	Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "firstname", sizeof ("firstname"), row_root);
	Ak_InsertAtEnd_L3(TYPE_VARCHAR, "Robert", sizeof ("Robert"), row_root);
	Ak_InsertAtEnd_L3(TYPE_OPERATOR, "=", sizeof ("="), row_root);

	komande[3].id_command = SELECT;
	komande[3].tblName = "student";
	komande[3].parameters = row_root;


	// Izvrsi komande
	AK_command(komande, brojkomandi);
	Ak_DeleteAll_L3(&row_root);

	AK_EPI;
}
コード例 #9
0
ファイル: transaction.c プロジェクト: mschatten/akdb
TestResult AK_test_Transaction() {
    AK_PRO;
    printf("***Test Transaction***\n");
    pthread_mutex_lock(&endTransationTestLockMutex);
    pthread_mutex_lock(&newTransactionLockMutex);
    AK_init_observable_transaction();

    // NOTE: This is the way on which we can broadcast notice to all observers
    // observable_transaction->observable->AK_notify_observers(observable_transaction->observable);
    
    memset(LockTable, 0, NUMBER_OF_KEYS * sizeof (struct transaction_list_head));

    /**************** INSERT AND UPDATE COMMAND TEST ******************/
    char *tblName = "student";
    struct list_node *row_root_insert = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&row_root_insert);
    Ak_DeleteAll_L3(&row_root_insert);
    int mbr, year;
    float weight;
    mbr = 38262;
    year = 2012;
    weight = 82.00;
    Ak_DeleteAll_L3(&row_root_insert);
    Ak_Insert_New_Element(TYPE_INT, &mbr, tblName, "mbr", row_root_insert);
    Ak_Insert_New_Element(TYPE_VARCHAR, "Ivan", tblName, "firstname", row_root_insert);
    Ak_Insert_New_Element(TYPE_VARCHAR, "Pusic", tblName, "lastname", row_root_insert);
    Ak_Insert_New_Element(TYPE_INT, &year, tblName, "year", row_root_insert);
    Ak_Insert_New_Element(TYPE_FLOAT, &weight, tblName, "weight", row_root_insert);

    struct list_node *row_root_update = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&row_root_update);
    Ak_DeleteAll_L3(&row_root_update);
    Ak_Update_Existing_Element(TYPE_INT, &mbr, tblName, "mbr", row_root_update);
    Ak_Insert_New_Element(TYPE_VARCHAR, "pppppppppp", tblName, "lastname", row_root_update);

    command* commands_ins_up = AK_malloc(sizeof (command) * 2);
    commands_ins_up[0].tblName = "student";
    commands_ins_up[0].id_command = INSERT;
    commands_ins_up[0].parameters = row_root_insert;

    commands_ins_up[1].tblName = "student";
    commands_ins_up[1].id_command = UPDATE;
    commands_ins_up[1].parameters = row_root_update;

    int id_prof;
    id_prof = 35893;
    struct list_node *row_root_p_update = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&row_root_p_update);
    Ak_DeleteAll_L3(&row_root_p_update);
    
    Ak_Update_Existing_Element(TYPE_INT, &id_prof, "professor", "id_prof", row_root_p_update);
    Ak_Insert_New_Element(TYPE_VARCHAR, "FOI", "professor", "firstname", row_root_p_update);


    /**************** DELETE COMMAND TEST ******************/
    command* commands_delete = AK_malloc(sizeof (command) * 1);
    commands_delete[0].tblName = "professor";
    commands_delete[0].id_command = DELETE;
    commands_delete[0].parameters = row_root_p_update;


    struct list_node *expr = (struct list_node *) AK_malloc(sizeof (struct list_node));
	Ak_Init_L3(&expr);
	int num = 2010;

	Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "year", sizeof ("year"), expr);
	Ak_InsertAtEnd_L3(TYPE_INT, (char*)&num, sizeof (int), expr);
	Ak_InsertAtEnd_L3(TYPE_OPERATOR, "<", sizeof ("<"), expr);
	Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "firstname", sizeof ("firstname"), expr);
	Ak_InsertAtEnd_L3(TYPE_VARCHAR, "Robert", sizeof ("Robert"), expr);
	Ak_InsertAtEnd_L3(TYPE_OPERATOR, "=", sizeof ("="), expr);
	Ak_InsertAtEnd_L3(TYPE_OPERATOR, "OR", sizeof ("OR"), expr);
    
    /**************** SELECT COMMAND TEST ******************/
    command* commands_select = AK_malloc(sizeof(command) * 1);
    commands_select[0].tblName = "student";
    commands_select[0].id_command = SELECT;
    commands_select[0].parameters = expr;

    /**************** EXECUTE TRANSACTIONS ******************/
    AK_transaction_manager(commands_ins_up, 2);
    AK_transaction_manager(commands_ins_up, 2);
    AK_transaction_manager(commands_delete, 1);
    AK_transaction_manager(commands_select, 1);
 
    pthread_mutex_lock(&endTransationTestLockMutex);

    AK_free(expr);
    AK_free(commands_delete);
    AK_free(commands_select);
    AK_free(commands_ins_up);
    AK_free(row_root_insert);
    AK_free(row_root_update);
    AK_free(row_root_p_update);
    AK_free(observable_transaction);

    pthread_mutex_unlock(&endTransationTestLockMutex);
    
    printf("***End test Transaction***\n");
    AK_EPI;

    return TEST_result(0,0);
}
コード例 #10
0
ファイル: table.c プロジェクト: mschatten/akdb
/**
 * @author Dino Laktašić and Mislav Čakarić (replaced old print table function by new one)
 * update by Luka Rajcevic
 * @brief  Function that prints a table
 * @param *tblName table name
 * @return No return value
 * update by Anto Tomaš (corrected the Ak_DeleteAll_L3 function)
 */
void AK_print_table_to_file(char *tblName) {

	char* FILEPATH = "table_test.txt";
	FILE *fp;
    
	AK_PRO;
    fp = fopen(FILEPATH, "a");
    table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName);
    if (addresses->address_from[0] == 0) {
        fprintf(fp, "Table %s does not exist!\n", tblName);

    } 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

        //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;
                }
            }
        }
        //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;

        fprintf(fp, "Table: %s\n", tblName);

        if (num_attr <= 0 || num_rows <= 0) {
            fprintf(fp, "Table is empty.\n");
        } else {
            //print table header
            fclose(fp);
            AK_print_row_spacer_to_file(len, length);
            fp = fopen(FILEPATH, "a");
            fprintf(fp, "\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;
                    fprintf(fp, "%-*s%-*s|", k, " ", k + (int) strlen((head + i)->att_name), (head + i)->att_name);
                } else {
                    k /= 2;
                    fprintf(fp, "%-*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);
            }
            fprintf(fp, "\n");
            fclose(fp);
            AK_print_row_spacer_to_file(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) {
                            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_to_file(len, row_root);
                            AK_print_row_spacer_to_file(len, length);
                            Ak_DeleteAll_L3(&row_root);
                        }
                    }
                }
                i++;
            }
            fp = fopen(FILEPATH, "a");
            fprintf(fp, "\n");
        }
    }
    fclose(fp);
    AK_EPI;
}
コード例 #11
0
ファイル: table.c プロジェクト: mschatten/akdb
/**
 * @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;
}
コード例 #12
0
ファイル: drop.c プロジェクト: mschatten/akdb
/**
 * @author Unknown, Jurica Hlevnjak, updated by Tomislav Ilisevic, Maja Vračan
 * @brief Function for DROP table, index, view, sequence, trigger, function, user, group and constraint.
 * @param type drop type
 * @param drop_arguments arguments of DROP command
 */
int AK_drop(int type, AK_drop_arguments *drop_arguments) {

    char *sys_table;
    char *name;
    int result;
    AK_PRO;
    switch (type) {
        case DROP_TABLE:

            sys_table = "AK_relation";
            name = (char*) drop_arguments->value;

            int status = 0;
            int x = 0;

            if (AK_if_exist(name, sys_table) == 0) {
                printf("Table %s does not exist!\n", name);
            } else {
                for (x = 0; x < NUM_SYS_TABLES; x++) {
                    if (strcmp(name, system_catalog[x]) == 0) {
                        status = 1;
                        printf("Table %s is a System Catalog Table and can't be DROPPED!\n", name);
                        AK_EPI;
                        return EXIT_ERROR;
                        break;
                    }
                }
                if (status != 1) {
                    AK_drop_help_function(name, sys_table);
                    printf("TABLE %s DROPPED!\n", name);
                    AK_EPI;
                    return EXIT_SUCCESS;
                }

            }

            break;

        case DROP_INDEX:

            sys_table = "AK_index";
            name = (char*) drop_arguments->value;

            if (!AK_if_exist(name, sys_table) == 0) {
                AK_drop_help_function(name, sys_table);
                printf("INDEX %s DROPPED!\n", name);
                AK_EPI;
                return EXIT_SUCCESS;
            } else {
                printf("Index %s does not exist!\n", name);
                AK_EPI;
                return EXIT_ERROR;
            }

            break;

        case DROP_VIEW:

            sys_table = "AK_view";
            name = (char*) drop_arguments->value;

            if ((AK_table_empty(sys_table)) || (AK_if_exist(name, sys_table) == 0)) {
                printf("View %s does not exist!\n", name);
                AK_EPI;
                return EXIT_ERROR;
            } else {
                AK_view_remove_by_name(name);
                printf("VIEW %s DROPPED!\n", name);
                AK_EPI;
                return EXIT_SUCCESS;
            }

            break;

        case DROP_SEQUENCE:

            sys_table = "AK_sequence";
            name = (char*) drop_arguments->value;

            if ((AK_table_empty(sys_table)) || (AK_if_exist(name, sys_table) == 0)) {
                printf("Sequence %s does not exist!\n", name);
                AK_EPI;
                return EXIT_ERROR;
            } else {
                AK_sequence_remove(name);
                printf("SEQUENCE %s DROPPED!\n", name);
                AK_EPI;
                return EXIT_SUCCESS;
            }

            break;

        case DROP_TRIGGER:

            sys_table = "AK_trigger";
            char *sys_tbl2 = "AK_relation";

            name = (char*) drop_arguments->value;
            char *tbl = (char*) drop_arguments->next->value;

            if ((AK_table_empty(sys_table)) || (AK_if_exist(name, sys_table) == 0)) {
                printf("Trigger %s does not exist!\n", name);
                AK_EPI;
                return EXIT_ERROR;
            } else if ((AK_table_empty(sys_tbl2)) || (AK_if_exist(tbl, sys_tbl2) == 0)) {
                printf("Table %s does not exist!\n", tbl);
                AK_EPI;
                return EXIT_ERROR;
            } else {
                AK_trigger_remove_by_name(name, tbl);
                printf("TRIGGER %s DROPPED!\n", name);
                AK_EPI;
                return EXIT_SUCCESS;
            }

            break;

        case DROP_FUNCTION:

            sys_table = "AK_function";
            name = (char*) drop_arguments->value;
	    

	    struct list_node *args = (struct list_node *) AK_malloc(sizeof (struct list_node));
            Ak_Init_L3(&args);

            if (drop_arguments != NULL) {
                while (drop_arguments != NULL) {
                    // printf("Argument: %s\n", drop_arguments->value);
                    drop_arguments = drop_arguments->next;
                    if (drop_arguments != NULL) {
                        
			Ak_InsertAtEnd_L3(TYPE_VARCHAR, drop_arguments->value, sizeof (drop_arguments), args);
                    }
                }
            }

            if ((AK_table_empty(sys_table)) || (AK_if_exist(name, sys_table) == 0)) {
                printf("Function %s does not exist!\n", name);
                AK_EPI;
                return EXIT_ERROR;
            } else {
                if (AK_function_remove_by_name(name, args) == EXIT_SUCCESS) {
                    printf("FUNCTION %s DROPPED!\n", name);
                    AK_EPI;
                    return EXIT_SUCCESS;
                } else {
                    printf("Function does not exist!\n"); // returned EXIT_ERROR because the funcion with the given args was not found
                    AK_EPI;
                    return EXIT_ERROR;
                }
            }
            AK_free(args);
            break;

        case DROP_USER:

            sys_table = "AK_user";
            name = (char*) drop_arguments->value;

            int status1 = 0;

            if (strcmp(drop_arguments->next->value, "CASCADE") == 0) {
                status1 = 1;
            }

            if ((AK_table_empty(sys_table)) || (AK_if_exist(name, sys_table) == 0)) {
                printf("User %s does not exist!\n", name);
                AK_EPI;
                return EXIT_ERROR;
            } else {
                // if CASCADE
                if (status1 == 1) {
                    // revokes all user privileges
                    AK_revoke_all_privileges_user(name);
                    // remove user from group(s)
                    AK_remove_user_from_all_groups(name);

                    AK_user_remove_by_name(name);
                    printf("USER %s DROPPED!\n", name);
                    AK_EPI;
                    return EXIT_SUCCESS;

                } else { // if not CASCADE
                    // check if user has any privilege or belong to group
                    if (AK_check_user_privilege(name) == EXIT_SUCCESS) {
                        printf("User %s can not be dropped because it has related objects!\n", name);
                        AK_EPI;
                        return EXIT_ERROR;
                    } else {
                        AK_user_remove_by_name(name);
                        printf("USER %s DROPPED!\n", name);
                        AK_EPI;
                        return EXIT_SUCCESS;
                    }
                }
            }

            break;

        case DROP_GROUP:

            sys_table = "AK_group";
            name = (char*) drop_arguments->value;

            int status2 = 0;

            if (strcmp(drop_arguments->next->value, "CASCADE") == 0) {
                status2 = 1;
            }

            if ((AK_table_empty(sys_table)) || (AK_if_exist(name, sys_table) == 0)) {
                printf("Group %s does not exist!\n", name);
                AK_EPI;
                return EXIT_ERROR;
            } else {
                // if CASCADE
                if (status2 == 1) {
                    // revoke group privileges
                    AK_revoke_all_privileges_group(name);
                    // remove group users
                    AK_remove_all_users_from_group(name);

                    AK_group_remove_by_name(name);
                    printf("GROUP %s DROPPED!\n", name);
                    AK_EPI;
                    return EXIT_SUCCESS;
                } else { // if not CASCADE
                    // check if group has any privilege or have users
                    if (AK_check_group_privilege(name) == EXIT_SUCCESS) {
                        printf("Group %s can not be dropped because it has related objects!\n", name);
                        AK_EPI;
                        return EXIT_ERROR;
                    } else {
                        AK_group_remove_by_name(name);
                        printf("GROUP %s DROPPED!\n", name);
                        AK_EPI;
                        return EXIT_SUCCESS;
                    }
                }
            }

            break;

        case DROP_CONSTRAINT:

            sys_table = (char*) drop_arguments->value; // table
            name = (char*) drop_arguments->next->value; // atribute
            char *constName = (char*) drop_arguments->next->next->value; // constraint name
            char * newValue = drop_arguments->next->next->next->value; //new value
            int deleted = 0;

            if(AK_read_constraint_unique(sys_table, constName, name) == EXIT_SUCCESS){
                result = AK_delete_constraint_unique(sys_table, name, constName);
                if(result == EXIT_SUCCESS) {
                    printf("\nUnique constraint %s dropped", constName);
                    AK_EPI;
                    return EXIT_SUCCESS;
                }
                deleted = 1;
            }
            if(AK_read_constraint_not_null(sys_table, constName, name) == EXIT_SUCCESS){
                result = AK_delete_constraint_not_null(sys_table, name, constName);
                if(result == EXIT_SUCCESS) {
                    printf("\nNot null constraint %s dropped", constName);
                    AK_EPI;
                    return EXIT_SUCCESS;
                }
                
                deleted = 1;
            }
            if(AK_read_constraint_between(sys_table, newValue, name) == EXIT_SUCCESS){
                result = AK_delete_constraint_between(sys_table, constName, name);
                if(result == EXIT_SUCCESS) {
                    printf("\nBetween constraint %s dropped", constName);
                    AK_EPI;
                    return EXIT_SUCCESS;
                }
                deleted = 1;
            }
            AK_EPI;
            return EXIT_ERROR;
            // TODO: delete "check" constraints

            printf("Constraint '%s' in table '%s' %s!\n", (constName==""?name:constName), sys_table,(deleted==0?"does not exist":"DROPPED"));

            break;

        default:
            break;
    }
    
}
コード例 #13
0
ファイル: rel_eq_selection.c プロジェクト: embalint/akdb
/**
 * @author Dino Laktašić.
 * @brief Function for testing rel_eq_selection
 * @return No return value
 */
void AK_rel_eq_selection_test() {
    AK_PRO;
    printf("rel_eq_selection.c: Present!\n");
    printf("\n********** REL_EQ_SELECTION TEST by Dino Laktašić **********\n");

    //create header
    AK_header t_header[MAX_ATTRIBUTES];
    AK_header *temp;

    temp = (AK_header*) AK_create_header("id", TYPE_INT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header, temp, sizeof (AK_header));
    temp = (AK_header*) AK_create_header("firstname", TYPE_VARCHAR, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header + 1, temp, sizeof (AK_header));
    temp = (AK_header*) AK_create_header("job", TYPE_VARCHAR, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header + 2, temp, sizeof (AK_header));
    temp = (AK_header*) AK_create_header("year", TYPE_INT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header + 3, temp, sizeof (AK_header));
    temp = (AK_header*) AK_create_header("tezina", TYPE_FLOAT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header + 4, temp, sizeof (AK_header));
    memset(t_header + 5, '\0', MAX_ATTRIBUTES - 5);

    //create table
    char *tblName = "profesor";

    int startAddress = AK_initialize_new_segment(tblName, SEGMENT_TYPE_TABLE, t_header);

    if (startAddress != EXIT_ERROR)
        printf("\nTABLE %s CREATED!\n", tblName);

    printf("rel_eq_selection_test: After segment initialization: %d\n", AK_num_attr(tblName));

    //create header
    AK_header t_header2[MAX_ATTRIBUTES];
    AK_header *temp2;

    temp2 = (AK_header*) AK_create_header("mbr", TYPE_INT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header2, temp2, sizeof (AK_header));
    temp2 = (AK_header*) AK_create_header("firstname", TYPE_VARCHAR, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header2 + 1, temp2, sizeof (AK_header));
    temp2 = (AK_header*) AK_create_header("lastname", TYPE_VARCHAR, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header2 + 2, temp2, sizeof (AK_header));
    temp2 = (AK_header*) AK_create_header("year", TYPE_INT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header2 + 3, temp2, sizeof (AK_header));
    temp2 = (AK_header*) AK_create_header("weight", TYPE_FLOAT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header2 + 4, temp2, sizeof (AK_header));
    memset(t_header2 + 5, '\0', MAX_ATTRIBUTES - 5);

    //create table
    char *tblName2 = "student";

    int startAddress2 = AK_initialize_new_segment(tblName2, SEGMENT_TYPE_TABLE, t_header2);

    if (startAddress2 != EXIT_ERROR)
        printf("\nTABLE %s CREATED!\n", tblName2);

    printf("rel_eq_selection_test: After segment initialization: %d\n", AK_num_attr(tblName2));
    //-----------------------------------------------------------------------------------------

    //Init list and insert elements (Query parser output)
    struct list_node *expr = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&expr);

    //Commutativity of Selection and Projection
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "s", sizeof ("s"), expr);
    Ak_InsertAtEnd_L3(TYPE_CONDITION, "`L1` 100 >", sizeof ("`L1` 100 >"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "p", sizeof ("p"), expr);
    Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "L1;L2;L3;L4", sizeof ("L1;L2;L3;L4"), expr); //projection attribute
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "p", sizeof ("p"), expr);
    Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "L1;L4;L3;L2;L5", sizeof ("L1;L4;L3;L2;L5"), expr);

    //Cascade of Selection and Commutativity of Selection
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "s", sizeof ("s"), expr);
    Ak_InsertAtEnd_L3(TYPE_CONDITION, "`L1` 100 >", sizeof ("`L1` 100 >"), expr);
    //
    //Commutativity of Selection and set operations (Union, Intersection, and Set difference)
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "s", sizeof ("s"), expr);
    Ak_InsertAtEnd_L3(TYPE_CONDITION, "`L2` 100 > `L3` 50 < OR", sizeof ("`L2` 100 > `L3` 50 < OR"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERAND, "R", sizeof ("R"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERAND, "S", sizeof ("S"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "u", sizeof ("u"), expr); //u, i, e

    //Commutativity of Selection and Theta join (or Cartesian product)
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "s", sizeof ("s"), expr);
    Ak_InsertAtEnd_L3(TYPE_CONDITION, "`job` 'teacher' = `mbr` 50 < AND", sizeof ("`job` 'teacher' = `mbr` 50 < AND"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERAND, "student", sizeof ("student"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERAND, "profesor", sizeof ("profesor"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "t", sizeof ("t"), expr);
    Ak_InsertAtEnd_L3(TYPE_CONDITION, "`mbr` 50 = `job` 'teacher' = AND", sizeof ("`mbr` 50 = `job` 'teacher' = AND"), expr); //theta join attribute

    //printf("\nRA expr. before rel_eq optimization:\n");
    //AK_print_rel_eq_projection(expr);
    AK_print_rel_eq_selection(AK_rel_eq_selection(expr));

    if (DEBUG_ALL) {
        printf("\n------------------> TEST_SELECTION_FUNCTIONS <------------------\n\n");

        char *test_cond1, *test_cond2;
        char *test_table;
        char *cond_attr1, *cond_attr2;

        test_table = "profesor";
        test_cond1 = "`mbr` 100 > `firstname` 50 < AND `id` 'A' > OR";
        test_cond2 = "`id` 100 > `firstname` 50 < AND `job` 'teacher' = AND";

        cond_attr1 = AK_rel_eq_cond_attributes(test_cond1);
        cond_attr2 = AK_rel_eq_cond_attributes(test_cond2);

        printf("IS_SET_SUBSET_OF_LARGER_SET_TEST: (%i)\n\n", AK_rel_eq_is_attr_subset(cond_attr1, cond_attr2));
        printf("GET_ALL_TABLE_ATTRIBUTES_TEST   : (%s)\n\n", AK_rel_eq_get_atrributes_char(test_table));
        printf("GET_CONDITION_ATTRIBUTES_TEST   : (%s)\n\n", AK_rel_eq_cond_attributes(test_cond1));
        printf("COMMUTE_WITH_THETA_JOIN_TEST    : (%s)\n\n", AK_rel_eq_commute_with_theta_join(test_cond1, test_table));
        printf("CONDITION_SHARE_ATTRIBUTES_TEST : (%i)\n", AK_rel_eq_share_attributes(cond_attr1, cond_attr2));
        /**/
    } else {
        printf("...\n");
    }

    Ak_DeleteAll_L3(&expr);
    //dealocate variables ;)
    AK_EPI;
}
コード例 #14
0
ファイル: rel_eq_selection.c プロジェクト: embalint/akdb
/**
 * @author Dino Laktašić.
 * @brief Main function for generating RA expresion according to selection equivalence rules 
 * @param *list_rel_eq RA expresion as the struct list_node
 * @return optimised RA expresion as the struct list_node
 */
struct list_node *AK_rel_eq_selection(struct list_node *list_rel_eq) {
    int step; //, exit_cond[5] = {0};
    AK_PRO;
    //Initialize temporary linked list
    struct list_node *temp = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&temp);

//    struct list_node *list_split_sel;
    struct list_node *tmp, *temp_elem, *temp_elem_prev, *temp_elem_next;
    struct list_node *list_elem_next, *list_elem = (struct list_node *) Ak_First_L2(list_rel_eq);

    //Iterate through all the elements of RA linked list
    while (list_elem != NULL) {

        switch (list_elem->type) {

            case TYPE_OPERATOR:
                Ak_dbg_messg(LOW, REL_EQ, "\nOPERATOR '%c' SELECTED\n", list_elem->data[0]);
                Ak_dbg_messg(LOW, REL_EQ, "----------------------\n");
                temp_elem = (struct list_node *) Ak_End_L2(temp);
                temp_elem_prev = (struct list_node *) Ak_Previous_L2(temp_elem, temp);
                list_elem_next = (struct list_node *) Ak_Next_L2(list_elem);

                switch (list_elem->data[0]) {
                        //Commutativity of Selection and Projection.
                    case RO_PROJECTION:
                        step = -1;

                        if (temp_elem != NULL) {
                            while (temp_elem != NULL) {
                                if (temp_elem->type == TYPE_OPERAND || temp_elem->type == TYPE_CONDITION) {
                                    if (temp_elem->type == TYPE_CONDITION) {
                                        temp_elem_prev = (struct list_node *) Ak_Previous_L2(temp_elem, temp);

                                        if ((AK_rel_eq_can_commute(list_elem_next, temp_elem) == EXIT_FAILURE) &&
                                                (temp_elem_prev->data[0] == RO_SELECTION) && (temp_elem_prev->type == TYPE_OPERATOR)) {
                                        	Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                                            Ak_InsertAtEnd_L3(list_elem_next->type, list_elem_next->data, list_elem_next->size, temp);
                                            Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with condition (%s) in temp list\n", list_elem->data, list_elem_next->data);
                                            step++;
                                            break;
                                        } else if ((AK_rel_eq_can_commute(list_elem_next, temp_elem) == EXIT_SUCCESS) &&
                                                (temp_elem_prev->data[0] == RO_SELECTION) && (temp_elem_prev->type == TYPE_OPERATOR)) {
                                        	Ak_InsertBefore_L2(list_elem->type, list_elem->data, list_elem->size, &temp_elem_prev, &temp);
                                        	Ak_InsertBefore_L2(list_elem_next->type, list_elem_next->data, list_elem_next->size, &temp_elem_prev, &temp);
                                            Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with condition (%s) in temp list\n", list_elem->data, list_elem_next->data);
                                            step++;
                                            break;
                                        }
                                    }
                                }
                                temp_elem = (struct list_node *) Ak_Previous_L2(temp_elem, temp);
                            }
                        }

                        if (temp_elem == NULL || step != 0) {
                        	Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                            Ak_InsertAtEnd_L3(list_elem_next->type, list_elem_next->data, list_elem_next->size, temp);
                            Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with condition (%s) in temp list\n", list_elem->data, list_elem_next->data);
                        }

                        list_elem = list_elem->next;
                        break;

                        //Cascade of Selection and Commutativity of Selection
                    case RO_SELECTION:

                        //Join cascade selection conditions to one
                        if (temp_elem != NULL && temp_elem_prev != NULL && temp_elem->type == TYPE_CONDITION &&
                                temp_elem_prev->data[0] == RO_SELECTION && temp_elem_prev->type == TYPE_OPERATOR) {
                            temp_elem->size = temp_elem->size + list_elem_next->size + strlen(" AND") + 1; //edit to (" AND ")
                            //strcat(temp_elem->data, " AND "); //uncomment for infix use
                            strcat(temp_elem->data, " "); //remove for infix
                            strcat(temp_elem->data, list_elem_next->data);
                            strcat(temp_elem->data, " AND"); //comment if using infix format
                            memcpy(temp_elem->data, temp_elem->data, temp_elem->size);
                            Ak_dbg_messg(MIDDLE, REL_EQ, "::selection cascade - condition changed to (%s) in temp list\n", temp_elem->data);
                        } else {
                        	Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                            Ak_InsertAtEnd_L3(list_elem_next->type, list_elem_next->data, list_elem_next->size, temp);
                            Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with attributes (%s) in temp list\n", list_elem->data, list_elem_next->data);
                        }

                        /*//Divide selection condition (slower than upper solution but can be useful in certain cases)
                        list_split_sel = AK_rel_eq_split_condition(list_elem_next->data);
                        struct list_node *list_elem_split = (struct list_node *)FirstL(list_split_sel);
						
                        if (temp_elem != NULL) {
                                tmp = temp_elem;
						
                                while (list_elem_split != NULL) {
                                        step = 0;
								
                                        while (temp_elem != NULL) {
                                                if (temp_elem->type == TYPE_CONDITION || (temp_elem->data[0] == RO_SELECTION && temp_elem->type == TYPE_OPERATOR)) {
                                                        if (temp_elem->type == TYPE_CONDITION && strcmp(list_elem_next->data, temp_elem->data) == 0) {
                                                                step = 1;
                                                        }
                                                } else if (!step){
                                                        InsertAtEndL(list_elem->type , list_elem->data, list_elem->size, temp);
                                                        InsertAtEndL(list_elem_next->type, list_elem_split->data, list_elem_split->size, temp);
                                                        break;
                                                }
                                                temp_elem = (struct list_node *)PreviousL(temp_elem, temp);
                                        }
								
                                        list_elem_split = list_elem_split->next;
                                        temp_elem = tmp;
                                }
                        } else {
                                while (list_elem_split != NULL) {
                                        InsertAtEndL(list_elem->type , list_elem->data, list_elem->size, temp);
                                        InsertAtEndL(list_elem_next->type, list_elem_split->data, list_elem_split->size, temp);
                                        list_elem_split = list_elem_split->next;
                                }
                        }
                        DeleteAllL(list_split_sel);*/
                        list_elem = list_elem->next;
                        break;

                        //Commutativity of Selection and set operations (Union, Intersection, and Set difference)
                    case RO_UNION:
                    case RO_INTERSECT:
                    case RO_EXCEPT:
                        step = -1;

                        while (temp_elem != NULL) {
                            if (temp_elem->type == TYPE_OPERAND || temp_elem->type == TYPE_CONDITION) {
                                step++;
                                temp_elem_prev = (struct list_node *) Ak_Previous_L2(temp_elem, temp);

                                if (temp_elem_prev->data[0] == RO_SELECTION && temp_elem_prev->type == TYPE_OPERATOR) {
                                    if (step > 1) {
                                        tmp = temp_elem;
                                        while (tmp->type != TYPE_OPERAND) {
                                            tmp = tmp->next;
                                        }
                                        Ak_InsertAfter_L2(temp_elem->type, temp_elem->data, temp_elem->size, &tmp, &temp);
                                        Ak_InsertAfter_L2(temp_elem_prev->type, temp_elem_prev->data, temp_elem_prev->size, &tmp, &temp);
                                        Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with attributes (%s) in temp list\n", temp_elem_prev->data, temp_elem->data);
                                    }
                                    break;
                                }
                            } else {
                                break;
                            }
                            temp_elem = (struct list_node *) Ak_Previous_L2(temp_elem, temp);
                        }
                        Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                        Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted in temp list\n", list_elem->data);
                        break;

                    case RO_NAT_JOIN:
                    	Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                        Ak_InsertAtEnd_L3(list_elem_next->type, list_elem_next->data, list_elem_next->size, temp);
                        Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted in temp list\n", list_elem->data);
                        list_elem = list_elem->next;
                        break;

                        //Commutativity of Selection and Theta join (or Cartesian product)
                    case RO_THETA_JOIN:
                        step = -1;

                        while (temp_elem != NULL) {
                            if (temp_elem->type == TYPE_OPERAND || temp_elem->type == TYPE_CONDITION) {
                                step++;
                                temp_elem_prev = (struct list_node *) Ak_Previous_L2(temp_elem, temp);

                                if (temp_elem_prev->data[0] == RO_SELECTION && temp_elem_prev->type == TYPE_OPERATOR) {
                                    if (step > 1) {
                                        tmp = temp_elem;
                                        temp_elem_next = temp_elem->next;

                                        char *data1, *data2;
                                        char *cond_attr1, *cond_attr2;
                                        char op_selected[2];
                                        memcpy(op_selected, temp_elem_prev->data, 2);

                                        data1 = AK_rel_eq_commute_with_theta_join(temp_elem->data, temp_elem_next->data);
                                        cond_attr1 = AK_rel_eq_cond_attributes(data1);

                                        data2 = AK_rel_eq_commute_with_theta_join(temp_elem->data, (temp_elem_next->next)->data);
                                        cond_attr2 = AK_rel_eq_cond_attributes(data2);

                                        //Debug lines - can be removed later
                                        //printf("CONDITION DATA : data: (%s),(%s), cond: (%s),(%s)\n", data1, data2, cond_attr1, cond_attr2);
                                        //printf("SHARE ATTRIBUTE: (%i)\n", AK_rel_eq_share_attributes(cond_attr1, cond_attr2));

                                        if (AK_rel_eq_share_attributes(cond_attr1, cond_attr2)) {
                                            if (cond_attr1 != NULL) {
                                                //memset(temp_elem->data, '\0', MAX_VARCHAR_LENGHT);
                                                temp_elem->size = strlen(data1) + 1;
                                                memcpy(temp_elem->data, data1, temp_elem->size);
                                                memset(temp_elem->data + temp_elem->size, '\0', MAX_VARCHAR_LENGTH - temp_elem->size);
                                                Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with attributes (%s) in temp list\n", temp_elem_prev->data, temp_elem->data);
                                            } else {
                                                struct list_node *temp_elem_prevprev = (struct list_node *) Ak_Previous_L2(temp_elem_prev, temp);
                                                temp_elem_prevprev->next = temp_elem;
                                                AK_free(temp_elem_prev);
                                                struct list_node *temp_elem_prev = temp_elem_prevprev;

                                                temp_elem_prev->next = temp_elem_next;
                                                AK_free(temp_elem);
                                                struct list_node *temp_elem = temp_elem_next;
                                                temp_elem_next = temp_elem->next;
                                                tmp = temp_elem;
                                            }

                                            while (tmp->type != TYPE_OPERAND) {
                                                tmp = tmp->next;
                                            }

                                            if (cond_attr2 != NULL) {
                                                memset(data2 + strlen(data2), '\0', 1);
                                                Ak_InsertAfter_L2(temp_elem->type, data2, strlen(data2) + 1, &tmp, &temp);
                                                Ak_InsertAfter_L2(TYPE_OPERATOR, op_selected, 2, &tmp, &temp);
                                                Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with attributes (%s) in temp list\n", op_selected, data2);
                                            }
                                        }

                                        AK_free(data1);
                                        AK_free(data2);
                                        AK_free(cond_attr1);
                                        AK_free(cond_attr2);
                                        break;
                                    }
                                }
                            } else {
                                break;
                            }
                            temp_elem = (struct list_node *) Ak_Previous_L2(temp_elem, temp);
                        }

                        Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                        Ak_InsertAtEnd_L3(list_elem_next->type, list_elem_next->data, list_elem_next->size, temp);
                        Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with condition (%s) in temp list\n", list_elem->data, list_elem_next->data);
                        list_elem = list_elem->next;
                        break;

                    case RO_RENAME:
                    	Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                        Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted in temp list\n", list_elem->data);
                        break;

                    default:
                        Ak_dbg_messg(LOW, REL_EQ, "Invalid operator: %s", list_elem->data);
                        break;
                }
                break;

                //additional type definition included to distinguish beetween table name and attribute/s
            case TYPE_ATTRIBS:
                //printf("::attribute '%s' inserted in the temp list\n", list_elem->data);
                break;

                //additional type definition included to distinguish beetween attribute/s and condition
            case TYPE_CONDITION:
                //printf("::condition '%s' inserted in the temp list\n", list_elem->data);
                break;

            case TYPE_OPERAND:
                Ak_dbg_messg(MIDDLE, REL_EQ, "::table_name (%s) inserted in the temp list\n", list_elem->data);
                Ak_InsertAtEnd_L3(TYPE_OPERAND, list_elem->data, list_elem->size, temp);
                break;

            default:
                Ak_dbg_messg(LOW, REL_EQ, "Invalid type: %s", list_elem->data);
                break;
        }

        list_elem = list_elem->next;
    }

    //====================================> IMPROVMENTS <=======================================
    //Recursive RA optimization (need to implement exit condition in place of each operator, ...)
    //If there is no new changes on the list return generated struct list_nodes
    //int iter_cond;
    //for (iter_cond = 0; iter_cond < sizeof(exit_cond); iter_cond++) {
    //	if (exit_cond[iter_cond] == 0) {
    ////	Edit function to return collection of the struct list_nodes
    ////	Generate next RA expr. (new plan)
    ////	temp += remain from the list_rel_eq
    //		AK_rel_eq_selection(temp);
    //	}
    //}

    Ak_DeleteAll_L3(&list_rel_eq);
    AK_EPI;
    return temp;
}
コード例 #15
0
ファイル: index.c プロジェクト: embalint/akdb
/**
 * @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;
}
コード例 #16
0
ファイル: selection.c プロジェクト: embalint/akdb
/**
 * @author Matija Šestak, updated by Dino Laktašić,Nikola Miljancic
 * @brief  Function for selection operator testing
 *
 */
void AK_op_selection_test() {
	AK_PRO;
	printf("\n********** SELECTION TEST **********\n");

	struct list_node *expr = (struct list_node *) AK_malloc(sizeof (struct list_node));
	Ak_Init_L3(&expr);	
	char *srcTable = "student";
	char *destTable = "selection_test";
	int num = 2010;
	strcpy(expr->table,destTable);
	Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "year", sizeof ("year"), expr);
	Ak_InsertAtEnd_L3(TYPE_INT, &num, sizeof (int), expr);
	Ak_InsertAtEnd_L3(TYPE_OPERATOR, ">", sizeof (">"), expr);
	Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "firstname", sizeof ("firstname"), expr);
	Ak_InsertAtEnd_L3(TYPE_VARCHAR, "Robert", sizeof ("Robert"), expr);
	Ak_InsertAtEnd_L3(TYPE_OPERATOR, "=", sizeof ("="), expr);
	//Ak_InsertAtEnd_L3(TYPE_OPERATOR, "OR", sizeof ("OR"), expr);
	Ak_InsertAtEnd_L3( TYPE_OPERATOR, "AND", sizeof("AND"), expr );
	printf("\nQUERY: SELECT * FROM student WHERE year > 2010 AND firstname = 'Robert';\n\n");
	AK_selection(srcTable, destTable, expr);
	Ak_DeleteAll_L3(&expr);
	AK_free(expr);

	struct list_node *expr1 = (struct list_node *) AK_malloc(sizeof (struct list_node));
	Ak_Init_L3(&expr1);
	char *srcTable1 = "student";
        char *destTable1 = "selection_test1";
	float weight = 83.750;
	strcpy(expr1->table,destTable1);
	Ak_InsertAtEnd_L3( TYPE_ATTRIBS, "weight", sizeof("weight"), expr1 );
	Ak_InsertAtEnd_L3( TYPE_FLOAT, &weight, sizeof(float), expr1 );
	Ak_InsertAtEnd_L3( TYPE_OPERATOR, ">", sizeof(">"), expr1 );
	Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "firstname", sizeof ("firstname"), expr1);
	Ak_InsertAtEnd_L3(TYPE_VARCHAR, "Dino", sizeof ("Robert"), expr1);
	Ak_InsertAtEnd_L3(TYPE_OPERATOR, "=", sizeof ("="), expr1);
	Ak_InsertAtEnd_L3(TYPE_OPERATOR, "OR", sizeof ("OR"), expr1);
	printf("\nQUERY: SELECT * FROM student WHERE weight > 83.750 OR firstname = 'Dino';\n\n");
	AK_selection(srcTable1, destTable1, expr1);
	printf("\n Test is successful :) \n");
	Ak_DeleteAll_L3(&expr1);
	AK_free(expr1);
	AK_EPI;
}