void project(char *rel_name, char *attr_name){
	char filename[FILENAME_SIZE]; //Declares a char variable that will be used to store the name of the binary file.
	char filename_two[FILENAME_SIZE]; //Declares a char variable that will be used to store the name of the schema file.
	int schema_len, boolean_value=0, tuple_count, tuple_size, total_length; //Integer variables used to store certain data about the relation
	int totcr, i=0, byte_len, x=0; //Other variables used to store data being read in, as well as max size.
	char *buffer; //Declares a char variable that will be used to read in the contents of the binary file.
	FILE *file, *file_two;  //FILE variable that will point to the file of the relation specified by the parameter.
	char first_attr[ATTRIBUTE_SIZE], second_attr[ATTRIBUTE_SIZE]; //Variables holding the name and type of certain attributes.
	
	strcpy(filename, rel_name);  //Copies the name of the relation onto the filename variable.
	strcat(filename, ".dat"); //Copies the .dat extension onto the filename variable.
	
	strcpy(filename_two, rel_name); //Copies the name of the relation onto the filename_two variable.
	strcat(filename_two, ".sch"); //Copies the .sch extension onto the filename_two variable.
	
	/* This IF statement tests wether the file exists in the current directory or not, if it does, the function moves onto
	the else part, if it doesn't exists, it prints out an error message specifying an invalid relation. */

	if (fileExist(filename)==0){
		fprintf(stderr, "Error: Invalid relation -- %s\n\n", rel_name);
	}
	
		//If the file exists, do the following.
	else{
		
		/* Checks to see if the relation file can be opened for reading, if not prints out an
		error message and exits the program.
		*/
		if((file = fopen(filename, "rb"))==NULL){
		fprintf(stderr, "Could not open the %s binary file for reading.\n", rel_name);
		exit(1);
		}
		
		tuple_size = tuplen(rel_name); //Stores the length of each tuple of the relation into tuple_size
		tuple_count = count(rel_name); //Stores the number of tuples into tuple_count
		file_two = fopen(filename_two, "r"); //Opens the schema file for reading.
		total_length = tuple_size * tuple_count; //Stores the total relation size in bytes into total_length
		buffer = (char *)malloc(sizeof(char)*total_length); //Allocates space for the buffer with the total relation size.
		
		
		
		for(x=0; x<tuple_count; x++){ //This loops until the number of tuples or rows has been reached.
			fscanf(file_two, "%d", &schema_len); //Scans the first digit of the schema file.
			
				while (i<schema_len){ //Loops for each category or attribute that the relation has.
					fscanf(file_two, "%s%s%d", first_attr, second_attr, &byte_len); //Scans the attribute name, type and length
				   
					if(strcmp(second_attr, "S")==0){ //If the attribute type is of String, goes into the statement.
						fread((void *) buffer, sizeof(char), byte_len, file); //Reads x amount of data into the buffer, depending on the byte_len
							if (strcmp(attr_name, first_attr)==0){ //If the attribute inputted matches the current attribute, enter.
								boolean_value = 1; //Sets the boolean value to 1, or true.
								printf("%s\n", buffer); //Prints the buffer, since match was found.
							}
						}
						
					if(strcmp(second_attr, "I")==0){ //If the attribute type is of Integer, goes into the statement.
						fread((void *) &totcr, sizeof(int), 1, file); //Reads one integer into totcr.
							if (strcmp(attr_name, first_attr)==0){ //If the attribute inputted matches the current attribute, enter.
								boolean_value = 1; //Sets the boolean value to 1, or true.
								printf("%d\n", totcr); //Prints totcr, since match was found
						}
					}
						memset(buffer, 0, BUFFER_SIZE); //Resets the buffer in order to get rid of corrupted data.
					 	i++; //Increments the counter in the while loop.
				}
			i=0; //After the while loop goes through entire schema and a tuple in the binary file, resets the counter for a new tuple.
			rewind(file_two); //Resets the position of the schema file for a new read.
		}
		
		printf("\n"); //Prints a newline character.
		
		if (boolean_value == 0 ){ //If boolean value is still 0 at this point, then no attribute of that name was found in the schema file.
				printf("Error: Invalid attribute -- %s\n\n", attr_name); //Prints error message.
			}
		
		/* Attempts to close the binary file, if it is unable to close it prints out an error message.
		*/
		if (fclose(file)==EOF){
			fprintf(stderr, "Could not close the file: %s.\n", filename);
			exit(1);
		}
	}
}
Exemple #2
0
void project( char *relName, char *attrName){

	FILE *schemaFile;  /*Ptr to schema file*/
	FILE *dataFile;  /*Ptr to data file*/
	int numAttr;  /*Stores number of attributes in schema file*/
	char name[MAX_STRING];  /*Temp for attribute name*/
	char type[CHAR_LENGTH];  /*Temp for attr type*/
	int bytes;  /*Temp for num of bytes in attribute*/
	int bytesToAttr;  /*Num of bytes from begin of tuple to attr*/
	int flag;  /*Flag to tell if attr found in relation*/
	char strings[MAX_TUPLES][MAX_TUPLES];  /*Array of strings (type S)*/
	int numbers[MAX_TUPLES];  /*Array of ints (type I)*/
	int tempInt;  /*Int for storing attribute values*/
	int arrayCounter;  /*Keeps track of current array index*/
	int tupleLen;  /*Length of a tuple for this attribute*/
	char *temp;  /*Temp array for fread junk*/
	int counter;  /*Loop counter for array*/

	/*Create an array large enough for a string that is the attribute
	name plus ".sch\0". This will be the name of the schema file. 
	*/
	char fileName[ strlen( relName) + strlen( ".sch\0")];
	strcpy( fileName, relName);
	strcat( fileName, ".sch\0");

	/*Open the schema file for reading. If unable to open, print an
	error message and exit.
	*/
	if( (schemaFile = ( fopen( fileName, "r"))) == NULL ){
		printf("There was an error trying to open schema file.\n");
		exit(1);
	}

	tupleLen = tuplen( relName, 0);  /*Get length of tuple for this rel'n*/
	/*Set temp array to length of a tuple, for use in a bit*/
	if( (temp = ((char *)malloc( tupleLen))) == NULL){
		printf("Space allocation failed.\n");
		exit(1);
	}

	fscanf( schemaFile, "%d", &numAttr);  /*Get first int in schema file*/
	flag = 0;  /*Initialize flag to attribute not found*/
	bytes = bytesToAttr = 0;  /*Initialize num bytes to 0*/

	/*Check all attributes in schema file for attrName. If found, set 
	flag to found(1), and stop looking. Keep track of number of bytes 
	in schema before the attribute we want.
	*/
	while( numAttr > 0){
		fscanf( schemaFile, "%s%s%d", name, type, &bytes);
		if( strcmp( attrName, name) == 0){
			flag = 1;
			break;
		}
		numAttr--;
		bytesToAttr = bytesToAttr + bytes;
	}

	/*If the attribute was not found for this relation, print a message
	*/
	if( flag == 0){
		printf(" Error: %s attribute is not part of %s relation.\n\n", 
				attrName, relName);
		fflush( stdout);
		return;
	}

	/////////////////BEGIN WORKING WITH DATA FILE///////////////////

	/*Copy attribute name plus ".dat\0" into fileName string. This will 
	now be the name of the data file. 
	*/
	strcpy( fileName, relName);
	strcat( fileName, ".dat\0");

	/*Open the data file for reading. If unable to open, print an
	error message and exit.
	*/
	if( (dataFile = ( fopen( fileName, "r"))) == NULL ){
		printf("There was an error trying to open data file.\n");
		exit(1);
	}

	arrayCounter = 0;  /*Initialize array counter*/
	tempInt = 0;  /*Initialize temporary int to 0*/
	flag = 0;  /*Initialize flag to no duplicate value found*/

	/*If the attribute type int or string, then check whether it is the first 
	attribute in a tuple or not.  If it is the first attribute in a tuple,
	look through the array of values already come across and see if there is 
	a duplicate. If it is a duplicate, do not add it to the array. If it isn't
	a dup, add it to the next open array space in the correct array (numbers
	if an int, strings if a string). Read through all tuples in the data file.
	Then print all the values for the attribute.
	*/
	if( strcmp( type, "I") == 0){  /*Attribute type == INT*/
		if( bytesToAttr == 0){  
		/*First attribute in a tuple, read the attr and store the value*/
			while( (fread( (void *) &tempInt, sizeof(int), 1, dataFile)) == 1){
				counter = 0;
				flag = 0;
				while( counter < arrayCounter){  /*Look for dup value*/
					if( tempInt == numbers[counter] ){
						flag = 1;  /*Duplicate value found in array*/
					}
					counter++;
				}
				if( flag == 0){  /*If not a duplicate value*/
					numbers[arrayCounter] = tempInt;  /*Add value to array*/
					arrayCounter++;
				}
			/*Continue reading data file
			*/
			fread( (void *) temp, (tupleLen - bytes), 1, dataFile);  
			}
		
		}///////////////////IF NOT FIRST ATTRIBUTE IN TUPLE///////////////////

		else if( bytesToAttr != 0){  /*Not first attribute in tuple*/
			while( (fread( (void *) temp, bytesToAttr, 1, dataFile)) == 1){
				/*Read until beginning of the attribute, then read space
				of desired attribute and store value*/
				fread( (void *) &tempInt, sizeof(int), 1, dataFile);
				counter = 0;
				flag = 0;
				while( counter < arrayCounter){  /*Look for dup value*/
					if( tempInt == numbers[counter] ){
						flag = 1;  /*Duplicate value found in array*/
					}
					counter++;
				}
				if( flag == 0){  /*If not a duplicate value*/
					numbers[arrayCounter] = tempInt;  /*Add to array*/
					arrayCounter++;
				}
				fread( (void *) temp, (tupleLen - bytesToAttr - bytes),
						 1, dataFile);  /*Continue reading data file*/
			}
		}
		
		counter = 0;  /*Init loop counter*/
		/*Look at each spot in the numbers array, print the value stored 
		there to stdout
		*/
		while( counter < arrayCounter){  
			printf("%d\n", numbers[counter]);
			fflush( stdout);  /*Flush the buffer*/
			counter++;
		}
		printf("\n");  /*Leave space between query results*/
		fflush( stdout);

	}////////////END TYPE 'I'/////////////

	else{  /*If attribute is of type 'S'*/
		if( bytesToAttr == 0){  
		/*Attr is first in tuple, read the tuple and store the string*/
			while( (fread( (void *) temp, bytes, 1, dataFile)) == 1){
				counter = 0;
				flag = 0;
				while( counter < arrayCounter){  /*Look for dup string*/
					if( strcmp( temp, strings[counter]) == 0 ){
						flag = 1;  /*Dup string in array*/
					}
					counter++;
				}
				if( flag == 0){  /*If not a duplicate value*/
					strcpy( strings[arrayCounter], temp);  /*Add to array*/
					arrayCounter++;
				}
			/*Continue reading data file
			*/
			fread( (void *) temp, (tupleLen - bytes), 1, dataFile);
			}
		
		}/////////////////IF NOT FIRST ATTRIBUTE IN TUPLE////////////////////
		
		else if( bytesToAttr != 0){  
		/*Not first attr in a tuple, read before the attribute, then read the
		attribute and store the string
		*/
			while( (fread( (void *) temp, bytesToAttr, 1, dataFile)) == 1){
				fread( (void *) temp, bytes, 1, dataFile);
				counter = 0;
				flag = 0;
				while( counter < arrayCounter){  /*Look for dup string*/
					if( strcmp( temp, strings[counter]) == 0 ){
						flag = 1;  /*Dup string in array*/
					}
					counter++;
				}
				if( flag == 0){  /*If not a duplicate value*/
					strcpy( strings[arrayCounter], temp);  /*Add to array*/
					arrayCounter++;
				}
				/*Continue reading data file
				*/
				fread( (void *) temp, (tupleLen - bytesToAttr - bytes),
						 1, dataFile);
			}
		}

		counter = 0;
		/*Look at each spot in the string array, and print the string at
		each location to stdout.
		*/
		while( counter < arrayCounter){
			printf("%s\n", strings[counter]);
			fflush( stdout);  /*Flush buffer*/
			counter++;
		}
		printf("\n");  /*Leave space between query results*/
		fflush( stdout);

	}/////////END TYPE 'S'///////



	/*Close schema file
	*/
	if( fclose( schemaFile) == EOF){
		fprintf( stderr, "Error closing schema file.\n");
		exit(1);
	}

	/*Close data file
	*/
	if( fclose( dataFile) == EOF){
		fprintf( stderr, "Error closing data file.\n");
		exit(1);
	}

}
Exemple #3
0
int main( int argc, char const *argv[] ){

	FILE *configFile;  /*Pointer to config file*/
	FILE *queryFile;  /*Poiner to query file*/
	char command[COMMAND_LENGTH];  /*A temp string for the query command*/
	char relName[MAX_STRING];  /*A temp string for the relation name*/
	char attrName[MAX_STRING];  /*A temp string for attribute name*/
	char relop[RELOP_LENGTH];  /*Array to hold relational operator*/
	char value[MAX_STRING];  /*Array to hold string to compare*/
	int numericValue;  /*Int to hold integer value to compare*/


	/*If the wrong number of arguments is given, print an error message and 
	exit.
	*/
	if( argc != NUM_ARGS){
		fprintf( stderr, "Incorrect number of arguments\n" );
		exit(1);
	}

	/*If the config file cannot be opened for reading, print an error message 
	and exit.
	*/
	if( (configFile = ( fopen( argv[CONFIG_FILE_ARG], "r"))) == NULL){
		fprintf( stderr, "There was an error trying to open config file %s\n",
				argv[CONFIG_FILE_ARG]);
		exit(1);
	}

	/*If the query file cannot be opened for reading, print an error message 
	and exit.
	*/
	if( (queryFile = ( fopen( argv[QUERY_FILE_ARG], "r"))) == NULL){
		fprintf( stderr, "There was an error trying to open query file %s\n",
				argv[QUERY_FILE_ARG]);
		exit(1);
	}


	/*Keep checking query file for another command
	*/
	while( fscanf( queryFile, "%s", command) == 1){

		/*If command entered is "nattr", get the relation name after the cmd, 
		and check to see if it is in the db. If so, call function to get the
		number of attributes for the specified relation. If not, print an 
		error message and move to the next query.
		*/
		if( strcmp( command, "nattr") == 0){
			fscanf( queryFile, "%s", relName);
			if( checkRelation( configFile, relName) == 1){
				nattr( relName);
			}
			else{
				printf(" Error: %s relation is not in the database.\n\n", 
						relName);
				fflush( stdout);
				continue;
			}
		}

		/*If command entered is "tuplen", get the relation name after the 
		cmd and check to see if it is in the db. If so, call the function to
		get the length of each tuple in this relation. If the relation is 
		not in the db, print an error message and move to the next query.
		*/
		else if( strcmp( command, "tuplen") == 0){
			fscanf( queryFile, "%s", relName);
			if( checkRelation( configFile, relName) == 1){
				tuplen( relName, 1);
			}
			else{
				printf(" Error: %s relation is not in the database.\n\n", 
						relName);
				fflush( stdout);
				continue;
			}

		}

		/*If command entered is "infattr", get the relation and attribute
		names after the cmd.  Check if the relation is in the database. If
		it is, call the function to check if the attribute is in that 
		relation (and if it is, print the type and number of bytes of the 
		attribute). If the relation is not in the db, print an error message
		and move to the next query.
		*/
		else if( strcmp( command, "infattr") == 0){
			fscanf( queryFile, "%s", relName);
			fscanf( queryFile, "%s", attrName);
			if( checkRelation( configFile, relName) == 1){
				infattr( relName, attrName, 1);
			}
			else{
				printf(" Error: %s relation is not in the database.\n\n", 
						relName);
				fflush( stdout);
				continue;
			}
		}

		/*If the command entered is "count", get the relation name after
		the cmd and check that it is a relation in the db. If so, call the
		function which prints the number of tuples in this relation. If the 
		relation is not in the db, print an error message and move to the 
		next query in the query file.
		*/
		else if( strcmp( command, "count") == 0){
			fscanf( queryFile, "%s", relName);
			if( checkRelation( configFile, relName) == 1){
				count( relName, 1);
			}
			else{
				printf(" Error: %s relation is not in the database.\n\n", 
						relName);
				fflush( stdout);
				continue;
			}
		}

		/*If command entered is "project", get the relation name and 
		attribute name after the cmd. Check that the relation is indeed
		a relation in the database. If so, call the function which prints
		all non duplicate values for this relation in the database. If this
		is not a relation in the database, print an error message and move
		on to the next query.
		*/
		else if( strcmp( command, "project") == 0){
			fscanf( queryFile, "%s", relName);
			fscanf( queryFile, "%s", attrName);
			if( checkRelation( configFile, relName) == 1){
				project( relName, attrName);
			}
			else{
				printf(" Error: %s relation is not in the database.\n\n", 
						relName);
				fflush( stdout);
				continue;
			}
		}

		/*If command entered is "select", get the relation name, attribute
		name, and relational operator that follow, and store their values.
		Check if relation is in db, then check that the attribute belongs
		to the relation. Then get the type. If the type is INT, then get
		the int from the next position in the query file, and set the string
		to "". If the type is STRING, then get the string from the next 
		position in the query file, and set the int to -1. In either case
		("I" or "S") call the function which prints out all tuples who
		satisfy the condition in the query. If this is not a relation in the 
		db, print an error message and go on to the next query.
		*/
		else if( strcmp( command, "select") == 0){
			fscanf( queryFile, "%s", relName);
			fscanf( queryFile, "%s", attrName);
			fscanf( queryFile, "%s", relop);
			/*If the relation is in db
			*/
			if( checkRelation( configFile, relName) == 1){
				/*If the attribute belongs to the relation
				*/
				if( (infattr( relName, attrName, 0)) == 1){
					/*If the relation type is "I"
					*/
					if( whatType( relName, attrName, 0) == 1){  /*INT type*/
						fscanf( queryFile, "%d", &numericValue); /*Store int*/
						/*Dummy value used to determine if we are trying to 
						compare an int and a string, later on in select 
						function
						*/
						strcpy( value, "\0");  
						select( relName, attrName, relop, numericValue, 
									value, "I");
					}
					/*If the relation type is "S"
					*/
					else{
						fscanf( queryFile, "%s", value);  /*Store string*/
						/*Dummy value used to determine if we are trying to 
						compare a string and an int, later on in select 
						function
						*/
						numericValue = -1;  
						select( relName, attrName, relop, numericValue, 
									value, "S");
					}
				}
			}
			/*If the relation is not in db, print an error message and go to 
			next query
			*/
			else{  
				printf(" Error: %s relation is not in the database.\n\n", 
						relName);
				fflush( stdout);
				continue;
			}
		}

		/*If the command entered is "quit", then close the files and exit the
		program.
		*/
		else if( strcmp( command, "quit") == 0){
			/*Close query file*/
			if( fclose( queryFile) == EOF){
				fprintf( stderr, "Error closing query file.\n");
				exit(1);
			}
			/*Close config file*/
			if( fclose( configFile) == EOF){
				fprintf( stderr, "Error closing config file.\n");
				exit(1);
			}
			exit(1);
		}
	}
	return 0;
}