예제 #1
0
//Παιρνει τα στοιχεια της στηλης attrName του πινακα tableName και τα βαζει στο attr 
t_rc SSQLM::getAttr(const char* tableName, const char* attrName, struct relAttr &attr)
{
	char* NameString = (char*)tableName;
	//Παιρνω το χειριστη του attr.met
	REM_RecordFileHandle* rfh_rel = sysm->getAttrMet();
	REM_RecordFileScan rfs;
	//ανοιγω fileScan για το πρωτο πεδιο (το ονομα του πινακα)
	t_rc rc = rfs.OpenRecordScan(*rfh_rel,TYPE_STRING,30*sizeof(char),0,EQ_OP,NameString);
	if(rc!=OK) return rc;
	REM_RecordHandle rh;
	//Για ολα τα records (αντικειμενα relAttr) που ανηκουν στον πινακα tableName
	do
	{
		//Ψαχνω αν καποιο αντικειμενο εχει το δωθεν ονομα στηλης
		rc = rfs.GetNextRecord(rh);
		if(rc==OK)
		{
			//Αν δε διαβαστηκαν ολα τα αντικειμενα, αρχικοποιησε τα επομενα δεδομενα
			//σε αντικειμενο relAttr
			char* data;
			t_rc rc2 = rh.GetData(data);
			if(rc2!=OK) return rc;
			int thesize=sizeof(struct relAttr);
			struct relAttr* pointermet = &attr;
			memcpy(pointermet,data,thesize);
		}
	}
	//Μεχρι να βρεθει το αντικειμενο με τα ζητουμενα χαρακτηριστικα
	//Ή μεχρι να εχαντληθουν ολα τα δεδομενα του αρχειου
	while(strcmp(attr.attr_name,attrName) && rc==OK);

	rc = rfs.CloseRecordScan();
	return rc;
}
예제 #2
0
//Υποπεριπτωση της εκτελεσης WHERE οπου το attr2 χαρακτηριστικο υποδεικνυει τιμη συγκρισης
t_rc SSQLM::whereValueCase(REM_RecordFileHandle &rfh, queue<REM_RecordID> &ridQ, struct relAttr RAttr, t_compOp compOp, string value)
{
	t_rc rc;
	int theSize = value.length();
	void* thisvalue;

	//αρχικοποιηση σε καταλληλο τυπο δεδομενων το thisvalue
	writeToVoid(thisvalue,value,RAttr.type);
	REM_RecordFileScan rfs;

	//Ανοιγμα fileScan για την τιμη αυτη
	rc = rfs.OpenRecordScan(rfh,RAttr.type,RAttr.attr_Length,RAttr.offset, compOp, thisvalue);
	if(rc!=OK) return rc;
	REM_RecordHandle rh;

	//Οσο υπαρχουν records που την ικανοποιουν
	while(rfs.GetNextRecord(rh)==OK)
	{
		REM_RecordID rid;
		rc = rh.GetRecordID(rid);
		if(rc!=OK) return rc;
		ridQ.push(rid); //προστεσε τα στην ουρα
	}

	rc = rfs.CloseRecordScan();
	return rc;
	
}
예제 #3
0
//Παιρνει τα στοιχεια του πινακα tableName απο το rel.met και τα βαζει στο rm
t_rc SSQLM::getTable(const char* tableName, struct relMet &rm)
{
	char* tName = (char*)tableName;
	//Παρε το χειριστη του rel.met
	REM_RecordFileHandle* rfh_rel = sysm->getRelMet();
	REM_RecordFileScan rfs;
	//Ανοιγω fileScan και ψαχνω αντιστοιχια με το ονομα στο ορισμα μεσα στο αρχειο rel.met
	//το ονομα εχει μηκος char[30] και ειναι το πρωτο πεδιο στο record.
	t_rc rc = rfs.OpenRecordScan(*rfh_rel,TYPE_STRING,30*sizeof(char),0,EQ_OP,tName);
	if(rc!=OK) return rc;
	REM_RecordHandle rh;
	//Θεωρουμε πως δε γινεται να υπαρχουν δυο πινακες με το ιδιο ονομα
	//Επομενως μια κληση της GetNextRecord μου δινει τον πινακα που θελω
	rc = rfs.GetNextRecord(rh);
	if(rc!=OK) return rc;
	char* data;
	rc = rh.GetData(data);
	//τα data ειναι χαρακτηρες που αντιστοιχουν στην περιγραφη μιας δομης relMet
	if(rc!=OK) return rc;
	int thesize=sizeof(struct relMet);
	//Διαβαζω τα data και αρχικοποιω το relMet
	memcpy(&rm,data,thesize);
	rc = rfs.CloseRecordScan();
	return rc;
}
t_rc SSQLM_DML_Manager::FindAttributeInAttrmet(const char *tName, char *attributeName, int &offset, char *&type, int &size, int &indexID){

	int attributeLength = strlen(attributeName);
	int tableLength = strlen(tName);
	int tableNattributeLength = attributeLength + tableLength + 1;

	char *tableANDattribute = (char *)malloc(tableNattributeLength);
	strcpy(tableANDattribute,tName);
	strcat(tableANDattribute,";");
	strcat(tableANDattribute,attributeName);

	REM_RecordFileScan *rfs = new REM_RecordFileScan();
	REM_RecordHandle rh;
	char *pData;

	t_rc rc = rfs->OpenRecordScan(*attrmet,TYPE_STRING,tableNattributeLength, 0, EQ_OP, tableANDattribute);	//	kai psakse mesa sto attrmet to record gia to sygkekrimeno attribute tou sygkekrimenou table
	if (rc != OK) {return rc; }

	rc = rfs->GetNextRecord(rh);
	if (rc != OK) {return rc; }
	
	rc = rh.GetData(pData);
	if (rc != OK) {return rc; }
	
	rc = GetAttrInfo(pData,offset,type,size,indexID);												//	Pare tis plhrofories gia to attribute.
	if (rc != OK) {return rc; }

	rc = rfs->CloseRecordScan();
	if (rc != OK) {return rc; }

	return OK;
}
예제 #5
0
//Υποπεριπτωση της εκτελεσης WHERE οπου το attr2 χαρακτηριστικο υποδεικνυει ονομα στηλης
t_rc SSQLM::whereAttrCase(REM_RecordFileHandle &rfh, queue<REM_RecordID> &ridQ, struct relAttr RAttr1, t_compOp compOp, struct relAttr RAttr2)
{
	t_rc rc;
	REM_RecordFileScan rfs;

	//Ανοιξε scan για τις δυο στηλες
	rc = rfs.OpenRecordScan(rfh, RAttr1.type, RAttr1.attr_Length, RAttr1.offset, NO_OP, NULL);
	if(rc != OK) return rc;
	REM_RecordHandle rh;
	//Για καθε γραμμη στον πινακα
	//Παρε τον χειριστη
	while(rfs.GetNextRecord(rh)==OK)
	{
		//Παρε τα δεδομενα της καθε στηλης απο τους χειριστες
		char* data;
		rc = rh.GetData(data);
		if(rc!=OK) return rc;
		
		//Ελεγξε αν ικανοποιουν τις συνθηκες και αν ναι βαλτα στην ουρα
		if(makeComp(data + RAttr1.offset,RAttr1,compOp,data + RAttr2.offset,true))
		{
			REM_RecordID rid;
			rh.GetRecordID(rid);
			ridQ.push(rid);
		}
	}
	rc = rfs.CloseRecordScan();
	return rc;
}
예제 #6
0
//Παιρνει ολες τις στηλες του πινακα tableName και τις προσθετει στην ουρα attrQ
t_rc SSQLM::getAllAttrs(char* tableName, queue<struct relAttr> &attrQ)
{
	//Η συναρτηση διαβαζει ολα τα records απο το attr.met και για τον δωθεν πινακα
	//αρχικοποιει και ενημερωνει μια ουρα με ολες τις στηλες που περιλαμβανει ο πινακας

	//Παρε το χειριστη του attr.met
	REM_RecordFileHandle* rfh_attr = sysm->getAttrMet();
	REM_RecordFileScan rfs;

	//Ανοιξε fileScan για τα records που ανηκουν στο συγκεκριμενο πινακα
	t_rc rc = rfs.OpenRecordScan(*rfh_attr,TYPE_STRING,30*sizeof(char),0,NO_OP,tableName);
	if(rc!=OK) return rc;
	REM_RecordHandle rh;

	//Για καθε record που ανηκει στον πινακα
	while(rfs.GetNextRecord(rh) == OK)
	{
		//Παρε τα δεδομενα του
		char* data;
		rc = rh.GetData(data);
		if(rc!=OK) return rc;
		relAttr temp;
		//και αρχικοποιησε τα σε αντικειμενο στηλης
		memcpy(&temp,data,sizeof(struct relAttr));

		//Αν οντως το αντικειμενο ανηκει στον πινακα, προστεσε το στην ουρα.
		if(strcmp(temp.name,tableName) == 0)
		{
			attrQ.push(temp);
		}
	}

	rc = rfs.CloseRecordScan();
	return rc;
}
예제 #7
0
t_rc SYSM_UserManager::DeleteUser(char * username, char * password) {
	t_rc rc;

	if (!this->isLoggedIn) return (SYSM_NOTLOGGEDIN);
	if (this->CheckPrivilege("all") != OK) return (SYSM_NOTALLOWEDUSER);

	std::string t_path(this->path);
	t_path.append("users");

	AttrMet u_meta;
	rc = this->smm->GetAttributeMetadata("users", "username", u_meta);
	if (rc != OK) return rc;

	AttrMet p_meta;
	rc = this->smm->GetAttributeMetadata("users", "password", p_meta);
	if (rc != OK) return rc;

	REM_RecordFileHandle rfh;
	rc = this->rfm->OpenRecordFile((char *) t_path.c_str(),rfh);
	if (rc != OK) return rc;

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,u_meta.type,u_meta.length,u_meta.offset,EQ_OP,username);
	if (rc != OK) return rc;

	REM_RecordHandle rh;
	while ((rc = rfs.GetNextRecord(rh)) == OK) {
		char * pData;
		rc = rh.GetData(pData);
		if (rc != OK) return rc;

		char * aData = new char[p_meta.length];
		memcpy(aData,&pData[p_meta.offset],p_meta.length);

		if (strcmp(aData,password) == 0) {
			REM_RecordID rid;
			rc = rh.GetRecordID(rid);
			if (rc != OK) return rc;

			rc = rfh.DeleteRecord(rid);
			if (rc != OK) return rc;
		}
	}

	rc = rfs.CloseRecordScan();
	if (rc != OK) return rc;

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	rc = this->RemoveAllPrivileges(username);
	if (rc != OK) return rc;

	return (OK);
}
예제 #8
0
t_rc SYSM_UserManager::InsertUser(char * username, char * password) {
	t_rc rc;

	if (!this->isLoggedIn) return (SYSM_NOTLOGGEDIN);
	if (this->CheckPrivilege("all") != OK) return (SYSM_NOTALLOWEDUSER);

	std::string t_path(this->path);
	t_path.append("users");

	AttrMet u_meta;
	rc = this->smm->GetAttributeMetadata("users", "username", u_meta);
	if (rc != OK) return rc;

	AttrMet p_meta;
	rc = this->smm->GetAttributeMetadata("users", "password", p_meta);
	if (rc != OK) return rc;

	REM_RecordFileHandle rfh;
	rc = this->rfm->OpenRecordFile((char *) t_path.c_str(),rfh);
	if (rc != OK) return rc;

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,u_meta.type,u_meta.length,u_meta.offset,EQ_OP,username);
	if (rc != OK) return rc;

	REM_RecordHandle rh;
	if (rfs.GetNextRecord(rh) == OK) return (SYSM_USEREXISTS);
	
	RelMet r_meta;
	rc = this->smm->GetRelationMetadata("users",r_meta);
	if (rc != OK) return rc;

	rc = rfs.CloseRecordScan();
	if (rc != OK) return rc;

	char * pData = new char[r_meta.rs];
	memcpy(&pData[u_meta.offset],username,u_meta.length);
	memcpy(&pData[p_meta.offset],password,p_meta.length);

	REM_RecordID rid;
	rc = rfh.InsertRecord(pData,rid);
	if (rc != OK) return rc;

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	return (OK);
}
예제 #9
0
t_rc SYSM_MetaManager::GetRelationMetadata(char * relName, RelMet &relMeta) {

	if (!this->sysm->isOpen) return (SYSM_NOTOPENEDDATABASE);
	t_rc rc;
	REM_RecordFileHandle rfh;
	std::string relPath(this->sysm->path + this->sysm->openedDBName + "\\rel.met");

	rc = this->rfm->OpenRecordFile(relPath.c_str(), rfh);
	if (rc != OK) return rc;

	bool exists = true;
	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,TYPE_STRING,REL_NAME_SIZE,REL_NAME_OFFSET,EQ_OP,relName);
	if (rc == OK) {
	
		REM_RecordHandle rh;
		if (rfs.GetNextRecord(rh) != OK) {
			rc = this->rfm->CloseRecordFile(rfh);
			if (rc != OK) return rc;
			
			return (SYSM_RELATIONDOESNOTEXISTS);
		}

		char * pData;
		rc = rh.GetData(pData);
		if (rc != OK) return rc;
	
		relMeta.name = new char[255];

		memcpy(relMeta.name,&pData[REL_NAME_OFFSET],REL_NAME_SIZE);
		memcpy(&relMeta.rs,&pData[REL_REC_SIZE_OFFSET],sizeof(int));
		memcpy(&relMeta.numAttrs,&pData[REL_ATTR_NUM_OFFSET],sizeof(int));
		memcpy(&relMeta.numOfIndexes,&pData[REL_INX_NUM_OFFSET],sizeof(int));

		rc = rfs.CloseRecordScan();
		if (rc != OK) return rc;

		rc = this->rfm->CloseRecordFile(rfh);
		if (rc != OK) return rc;
		
		return (OK);
	} else {
		rc = this->rfm->CloseRecordFile(rfh);
		if (rc != OK) return rc;
		
		return (SYSM_RELATIONDOESNOTEXISTS);
	}
}
예제 #10
0
//Παιρνει τα στοιχεια της στηλης attrName απο τον καταλληλο πινακα μεταξυ των tableName και τα βαζει στο attr
t_rc SSQLM::getSimpleAttr(string* tableName, int tableSize, const char* attrName, struct relAttr &attr)
{
	//Η συναρτηση εχει διαφορετικη στρατηγικη αρχικοποιησης.
	//Ουσιατικα ελεγχει και αρχικοποιει μια στηλη η οποια δεν ξερουμε σε ποιο πινακα ανηκει.
	//Γενικα καλειται σε περιπτωσεις που το ονομα στηλης ειναι μοναδικο σε ολη τη βαση.
	REM_RecordFileHandle* rfh_rel = sysm->getAttrMet(); //παιρνω το χειριστη του attr.met
	REM_RecordFileScan rfs;
	//Ανοιγω fileScan για ΟΛΑ τα records ανεξαρτητως (ολες οι υπαρχουσες στηλες της βασης)
	t_rc rc = rfs.OpenRecordScan(*rfh_rel,TYPE_STRING,30*sizeof(char),30*sizeof(char),NO_OP,NULL);
	if(rc!=OK) return rc;
	REM_RecordHandle rh;
	
	bool flag = false; //Υποδηλωνει αν βρεθηκε η στηλη που ψαχνουμε
	while((rfs.GetNextRecord(rh) == OK)&&(!flag)) //Για καθε επομενο record που υπαρχει στο αρχειο
	{
		char* data;
		//Διαβαζει τα δεδομενα του
		rc = rh.GetData(data);
		if(rc!=OK) return rc;
		struct relAttr temp;
		//και αρχικοποιει ενα βοηθητικο αντικειμενο relAttr
		memcpy(&temp,data,sizeof(struct relAttr));
		for(int i=0; i<tableSize; i++)
		{
			//Αν το βοηθητικο αντικειμενο ανηκει σε εναν απο τους πινακες στο ορισμα
			//και αντιστοιχει στο ονομα στηλης που ψαχνουμε
			if((!tableName[i].compare(temp.name)) && (!strcmp(attrName,temp.attr_name)) )
			{
				//τοτε, ενημερωσε πως βρηκαμε τη στηλη
				flag = true;
				//και αρχικοποιησε την
				memcpy(&attr, data, sizeof(struct relAttr));
				break;
			}
		}
	}
	rc = rfs.CloseRecordScan();
	if(rc!=OK) return rc;

	if(flag) //αν βρεθηκε η στηλη, ΟΚ
	{
		return OK;
	}
	else //αν οχι, εξαντληθηκαν ολα τα δεδομενα και εχουμε προβλημα
	{
		return REM_NO_MORE_RECORDS;
	}
}
예제 #11
0
t_rc SYSM_UserManager::CheckPrivilege(char * dbname) {
	t_rc rc;

	if (!this->isLoggedIn) return (SYSM_NOTLOGGEDIN);

	std::string t_path(this->path);
	t_path.append("privileges");

	AttrMet u_meta;
	rc = this->smm->GetAttributeMetadata("privileges","username",u_meta);
	if (rc != OK) return rc;

	AttrMet db_meta;
	rc = this->smm->GetAttributeMetadata("privileges","dbname",db_meta);
	if (rc != OK) return rc;

	REM_RecordFileHandle rfh;
	rc = this->rfm->OpenRecordFile((char *) t_path.c_str(), rfh);
	if (rc != OK) return rc;

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,u_meta.type,u_meta.length,u_meta.offset,EQ_OP,this->user);
	if (rc != OK) return rc;

	REM_RecordHandle rh;
	while ((rc = rfs.GetNextRecord(rh)) == OK) {
		char * pData;
		rc = rh.GetData(pData);
		if (rc != OK) return rc;

		char * priv = new char[db_meta.length];
		memcpy(priv,&pData[db_meta.offset],db_meta.length);

		if (strcmp(priv,"all") == 0 || strcmp(priv,dbname) == 0) return (OK);
	}

	rc = rfs.CloseRecordScan();
	if (rc != OK) return rc;

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	return (SYSM_PRIVNOTFOUND);
}
예제 #12
0
t_rc SSQLM_DDL_Manager::DropTable(char * t_Name) {

	t_rc rc;

	std::string a_path = this->path + "attr.met";
	REM_RecordFileHandle rfh;
	rc = this->rfm->OpenRecordFile(a_path.c_str(), rfh);
	if (rc != OK) return rc;
	
	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,TYPE_STRING,REL_NAME_SIZE,ATTR_REL_NAME_OFFSET,EQ_OP,t_Name);
	if (rc != OK) return rc;

	REM_RecordHandle rh;
	while ((rc = rfs.GetNextRecord(rh)) == OK) {
		char * pData;
		rc = rh.GetData(pData);
		if (rc != OK) return rc;

		int indexNo;
		memcpy(&indexNo,&pData[ATTR_INX_NO_OFFSET],sizeof(int));

		if (indexNo >= 0) {
			char * attrName = new char[ATTR_NAME_SIZE];
			memcpy(attrName,&pData[ATTR_NAME_OFFSET],ATTR_NAME_SIZE);

			rc = this->DropIndex(t_Name, attrName);
			if (rc != OK) return rc;
		}
	}

	rc = smm->DeleteRelationMetadata(t_Name);
	if (rc != OK) return rc;

	std::string dbname(this->openedDatabaseName);
	std::string path("C:\\sirenbase\\data\\" + dbname + "\\" + t_Name);
	rc = this->rfm->DestroyRecordFile(path.c_str());
	if (rc != OK) return rc;

	
	return (OK);
}
예제 #13
0
t_rc SYSM_UserManager::RemoveAllPrivileges (char * username) {
	t_rc rc;

	if (!this->isLoggedIn) return (SYSM_NOTLOGGEDIN);
	if (this->CheckPrivilege("all") != OK) return (SYSM_NOTALLOWEDUSER);

	std::string t_path(this->path);
	t_path.append("privileges");

	AttrMet u_meta;
	rc = this->smm->GetAttributeMetadata("privileges", "username", u_meta);
	if (rc != OK) return rc;

	REM_RecordFileHandle rfh;
	rc = this->rfm->OpenRecordFile((char *) t_path.c_str(),rfh);
	if (rc != OK) return rc;

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,u_meta.type,u_meta.length,u_meta.offset,EQ_OP,username);
	if (rc != OK) return rc;

	REM_RecordHandle rh;
	while ((rc = rfs.GetNextRecord(rh)) == OK) {
		
		REM_RecordID rid;
		rc = rh.GetRecordID(rid);
		if (rc != OK) return rc;

		rc = rfh.DeleteRecord(rid);
		if (rc != OK) return rc;
	}

	rc = rfs.CloseRecordScan();
	if (rc != OK) return rc;

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	return (OK);
}
t_rc SSQLM_DML_Manager::CheckIfTableHasIndexes(const char *tName, bool &hasIndexes){

	char *tokens;
	char *nextToken;
	REM_RecordFileScan *rfs = new REM_RecordFileScan();				//	psaxnoume sto relmet arxeio na vroume thn eggrafh
	int tNameLength = strlen(tName);								//	pou anaferete sto diko mas table kai na elegksoume
	REM_RecordHandle rh;											//	ean o ari8mos twn indexes einai diaforos tou 0.
	char *pData;

	// Find the record with table name "tName"
	t_rc rc = rfs->OpenRecordScan(*relmet,TYPE_STRING,tNameLength, 0, EQ_OP, (char*)tName);
	if (rc != OK) {return rc; }

	rc = rfs->GetNextRecord(rh);
	if (rc != OK) {return rc; }

	rc = rh.GetData(pData);
	if (rc != OK) {return rc; }

	// Check if the indexes field is not 0
	tokens = strtok_s (pData,";", &nextToken);
	int i = 1;
	hasIndexes = false;

	while (tokens != NULL){
		if( i == 4 ){
			if( strcmp(tokens,"0") != 0 )
				hasIndexes = true;
			break;
		}
		i++;
		tokens = strtok_s (NULL, ";", &nextToken);
	}

	rc = rfs->CloseRecordScan();

	return OK;
}
t_rc SSQLM_DML_Manager::GetTableRecordSize(char *tName, int &recordSize){

	char *tokens;
	char *nextToken;
	int i = 1;

	REM_RecordFileScan *rfs = new REM_RecordFileScan();
	REM_RecordHandle rh;
	char *pData;

	t_rc rc = rfs->OpenRecordScan(*relmet,TYPE_STRING,strlen(tName), 0, EQ_OP, tName);	//	kai psakse mesa sto attrmet to record gia to sygkekrimeno attribute tou sygkekrimenou table
	if (rc != OK) {return rc; }

	rc = rfs->GetNextRecord(rh);
	if (rc != OK) {return rc; }
	
	rc = rh.GetData(pData);
	if (rc != OK) {return rc; }

	char *rec = (char *)malloc(strlen(pData));
	strcpy(rec,pData);
	
	tokens = strtok_s (rec,";", &nextToken);					

	while (tokens != NULL){
		if( i == 2 )
			recordSize = atoi(tokens);
		i++;
		tokens = strtok_s (NULL, ";", &nextToken);
	}

	rc = rfs->CloseRecordScan();
	if (rc != OK) {return rc; }

	return OK;
}
t_rc SSQLM_Manager::CompareValue(t_attrInfo comparisonAttribute, char *convertion, t_compOp compOp, vector<char *> &pData) {
	t_rc rc;
	if(comparisonAttribute.indexNo != -1) {
		/*INXM_IndexHandle indesHandle;
		INXM_IndexScan indexScan;
		

		std::stringstream ss;
		ss << comparisonAttribute.relName << "." << comparisonAttribute.indexNo;
		
		rc = inxm.OpenIndex(ss.str(), comparisonAttribute.indexNo, indexHandle);
		if(rc != OK)
			return rc;

		rc = indexScan.OpenIndexScan(indexHandle, compOp, convertion);
		if(rc != OK)
			return rc;

		char *data;
		while(GetNextEntry(rid) == OK) {
			rc = rfh.ReadRecord(rid, rh);
			if(rc != OK)
				return rc;

			rc = rh.GetData(data);
			if(rc != OK)
				return rc;

			pData.push_back(data);
		}
		rc = fileScan.CloseIndexScan();
		if(rc != OK)
			return rc;

		rc = inxm.CloseIndex(indexHandle);
		if(rc != OK)
			return rc;*/
	}else{
		REM_RecordFileHandle rfh;
		REM_RecordHandle rh;
		REM_RecordID rid;
		rc = rfm.OpenRecordFile(comparisonAttribute.relName, rfh);
		if(rc != OK)
			return rc;

		//void *value;
		double doubleNum;
		int intNum;
		float floatNum;
		REM_RecordFileScan fileScan;

		switch(comparisonAttribute.attrType) {
		case TYPE_DOUBLE :
			doubleNum = strtod(convertion,NULL);
			rc = fileScan.OpenRecordScan(rfh, comparisonAttribute.attrType, comparisonAttribute.attrLength, comparisonAttribute.offset, compOp, &doubleNum);
			if(rc != OK)
				return rc;
			break;
		case TYPE_INT :
			intNum = atoi(convertion);
			rc = fileScan.OpenRecordScan(rfh, comparisonAttribute.attrType, comparisonAttribute.attrLength, comparisonAttribute.offset, compOp, &intNum);
			if(rc != OK)
				return rc;
			break;
		case TYPE_FLOAT :
			floatNum = atof(convertion);
			rc = fileScan.OpenRecordScan(rfh, comparisonAttribute.attrType, comparisonAttribute.attrLength, comparisonAttribute.offset, compOp, &floatNum);
			if(rc != OK)
				return rc;
			break;
		case TYPE_STRING:
			rc = fileScan.OpenRecordScan(rfh, comparisonAttribute.attrType, comparisonAttribute.attrLength, comparisonAttribute.offset, compOp, convertion);
			if(rc != OK)
				return rc;
			break;
		}


		char *data;
		while(fileScan.GetNextRecord(rh) == OK) {
			rc = rh.GetData(data);
			if(rc != OK)
				return rc;

			pData.push_back(data);
		}

		rc = fileScan.CloseRecordScan();
		if(rc != OK)
			return rc;
		rc = rfm.CloseRecordFile(rfh);
		if(rc != OK)
			return rc;
	}

	return OK;
}
t_rc SSQLM_Manager::CompareAttributes(t_attrInfo comparisonAttribute, t_attrInfo convertionAttribute, t_compOp compOp, vector<char *> &pData) {
	t_rc rc;
	REM_RecordFileHandle rfhCompare;
	REM_RecordFileHandle rfhConvertion;
	REM_RecordHandle rhCompare;
	REM_RecordHandle rhConvertion;
	REM_RecordID ridCompare;
	REM_RecordID ridConvertion;
	if(comparisonAttribute.indexNo != -1) {
		/*INXM_IndexHandle indesHandle;
		INXM_IndexScan indexScan;
		

		std::stringstream ss;
		ss << comparisonAttribute.relName << "." << comparisonAttribute.indexNo;
		
		rc = inxm.OpenIndex(ss.str(), comparisonAttribute.indexNo, indexHandle);
		if(rc != OK)
			return rc;

		rc = indexScan.OpenIndexScan(indexHandle, compOp, 

*/

	}else {
		if(comparisonAttribute.relName != convertionAttribute.relName) {
			rc = rfm.OpenRecordFile(comparisonAttribute.relName, rfhCompare);
			if(rc != OK)
				return rc;
			rc = rfm.OpenRecordFile(convertionAttribute.relName, rfhConvertion);
			if(rc != OK)
				return rc;

			REM_RecordFileScan fileScan;
		
			int slotCompare = 0;
			int pageIDCompare = 2;
			int slotConvertion = 0;
			int pageIDConvertion = 2;

			for( ;pageIDCompare <= rfhCompare.sfh.GetNumReservedPages(); pageIDCompare++) {
				for( ;slotCompare <= rfhCompare.rfsh.nrecords; slotCompare++) {
					rc = ridCompare.SetPageID(pageIDCompare);
					if(rc != OK)
						return rc;
					
					rc = ridCompare.SetSlot(slotCompare);
					if(rc != OK)
						return rc;

					rc = rfhCompare.ReadRecord(ridCompare, rhCompare);
					if(rc != OK)
						return rc;

					char *dataCompare;
					rc = rhCompare.GetData(dataCompare);
					if(rc != OK)
						return rc;

					rc = fileScan.OpenRecordScan(rfhConvertion, convertionAttribute.attrType, convertionAttribute.attrLength, convertionAttribute.offset, compOp, dataCompare);
					if(rc != OK)
						return rc;

					char *dataConvertion;
					while(fileScan.GetNextRecord(rhConvertion) == OK){
						rc = rhConvertion.GetData(dataConvertion);
						if(rc != OK)
							return rc;

						pData.push_back(dataCompare);
						pData.push_back(dataConvertion);
					}
					fileScan.CloseRecordScan();
				}
			}
		}
	}
	return OK;
}
예제 #18
0
t_rc SSQLM_DDL_Manager::CreateIndex(char * t_Name, char * a_Name) {
	
	t_rc rc;

	AttrMet a_meta;
	rc = this->smm->GetAttributeMetadata(t_Name, a_Name, a_meta);
	if (rc != OK) return rc;
	
	RelMet r_meta;
	rc = this->smm->GetRelationMetadata(t_Name, r_meta);
	if (rc != OK) return rc;

	if (a_meta.indexNo >= 0) return (SSQLM_DDL_INDEXEXISTS);

	int indexNo = 0;
	while (this->im->CreateIndex((path + t_Name).c_str(),indexNo,a_meta.type,a_meta.length) != OK) indexNo++;

	a_meta.indexNo = indexNo;
	r_meta.numOfIndexes++;

	rc = this->smm->UpdateAttributeMetadata(t_Name, a_Name, a_meta.relName, a_meta.attrName, a_meta.offset, a_meta.type, a_meta.length, a_meta.indexNo);
	if (rc != OK) return rc;

	rc = this->smm->UpdateRelationMetadata(t_Name, r_meta.name, r_meta.rs, r_meta.numAttrs, r_meta.numOfIndexes);
	if (rc != OK) return rc;

	REM_RecordFileHandle rfh;
	rc = this->rfm->OpenRecordFile((path + t_Name).c_str(),rfh);
	if (rc != OK) return rc;

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,TYPE_INT,0,0,NO_OP,0);
	if (rc != OK) return rc;
	
	INXM_IndexHandle ih;
	rc = this->im->OpenIndex((path + t_Name).c_str(),indexNo,ih);
	if (rc != OK) return rc;

	REM_RecordHandle rh;
	REM_RecordID rid;
	char * rData;

	while ((rc = rfs.GetNextRecord(rh)) == OK) {

		rc = rh.GetData(rData);
		if (rc != OK) return rc;

		rc = rh.GetRecordID(rid);
		if (rc != OK) return rc;

		char * aData = new char[a_meta.length];
		memcpy(aData,&rData[a_meta.offset],a_meta.length);

		rc = ih.InsertEntry(aData, rid);
		if (rc != OK) return rc;
	}

	rc = rfs.CloseRecordScan();
	if (rc != OK) return rc;

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	rc = this->im->CloseIndex(ih);
	if (rc != OK) return rc;
	

	return (OK);
}
예제 #19
0
void testREM() {
	STORM_StorageManager mgr;
	STORM_FileHandle fh;
	t_rc rc;
	STORM_PageHandle ph;

	
	
	
	REM_RecordFileManager *rmgr = new REM_RecordFileManager(&mgr);
	
	REM_RecordFileHandle rfh;
	
	rc = rmgr->CreateRecordFile("test.dat", 40);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rc = rmgr->OpenRecordFile("test.dat", rfh);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	REM_RecordID rid1, rid2, rid3;
	int pageID, slot;
	
	//================================================================================	
	rc = rfh.InsertRecord("check my list yo", rid1);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rc = rid1.GetPageID(pageID);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rc = rid1.GetSlot(slot);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	printf("Page ID = %d,  Slot = %d\n", pageID, slot);
	
	rc = rfh.InsertRecord("check my list yo 2", rid2);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
		
	rc = rid2.GetPageID(pageID);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rc = rid2.GetSlot(slot);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	printf("Page ID = %d,  Slot = %d\n", pageID, slot);

	rc = rfh.InsertRecord("check my list yo 3", rid3);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
		
	rc = rid3.GetPageID(pageID);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rc = rid3.GetSlot(slot);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	printf("Page ID = %d,  Slot = %d\n", pageID, slot);
	//================================================================================	
	//================================================================================	
	REM_RecordHandle rh;
	char *pData;
	
	rc = rfh.ReadRecord(rid1, rh);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rh.GetData(pData);
	printf("This is data : %s ||| from rid %d\n", pData, 1);

	rc = rfh.ReadRecord(rid2, rh);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rh.GetData(pData);
	printf("This is data : %s ||| from rid %d\n", pData, 2);

	rc = rfh.ReadRecord(rid3, rh);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rh.GetData(pData);
	printf("This is data : %s ||| from rid %d\n", pData, 3);	
	
	//================================================================================	
	//================================================================================	
	
	REM_RecordFileScan fs;
	
	
	rc = fs.OpenRecordScan(rfh, TYPE_STRING, 18, 0, EQ_OP, (char*)"check my list yo 2");
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rc = fs.GetNextRecord(rh);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rh.GetData(pData);
	printf("This is data : %s ||| from File Scan \n", pData);
	
	rc = fs.GetNextRecord(rh);
	if (rc != OK) {DisplayReturnCode(rc);}

	rh.GetData(pData);
	printf("This is data : %s ||| from File Scan 2\n", pData);

	
	//================================================================================	
	//================================================================================	
	
	rfh.DeleteRecord(rid1);
	
	rc = rfh.ReadRecord(rid1, rh);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rh.GetData(pData);
	printf("This is data : %s ||| from rid %d\n", pData, 1);
	//================================================================================	
	//================================================================================	
	memcpy(pData, "koka kolas!", 40);
	
	rfh.UpdateRecord(rh);
	
	rc = rfh.ReadRecord(rid1, rh);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rh.GetData(pData);
	printf("This is data : %s ||| from rid %d\n", pData, 1);	
	//================================================================================	
	
	rc = rmgr->CloseRecordFile(rfh);
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
	rc = rmgr->DestroyRecordFile("test.dat");
	if (rc != OK) {DisplayReturnCode(rc);exit(-1);}	
	
}
예제 #20
0
t_rc SYSM_MetaManager::UpdateRelationMetadata(char * p_Rel_Name, char * n_Rel_Name, int n_Rec_Size, int n_Num_Of_Attributes, int numOfIndexes) {

	if (!this->sysm->isOpen) return (SYSM_NOTOPENEDDATABASE);

	t_rc rc;
	REM_RecordFileHandle rfh;
	std::string relPath(this->sysm->path + this->sysm->openedDBName + "\\rel.met");

	rc = this->rfm->OpenRecordFile(relPath.c_str(), rfh);
	if (rc != OK) {
		rc = this->rfm->CloseRecordFile(rfh);
		if (rc != OK) return rc;
		
		return (SYSM_RELATIONDOESNOTEXISTS);
	}

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,TYPE_STRING,REL_NAME_SIZE,REL_NAME_OFFSET,EQ_OP,p_Rel_Name);
	if (rc != OK) return rc;

	REM_RecordHandle rh;
	if (rfs.GetNextRecord(rh) != OK) return (SYSM_RELATIONDOESNOTEXISTS);
	
	char * pData;
	REM_RecordID rid;

	rc = rh.GetData(pData);
	if (rc != OK) return rc;

	memcpy(&pData[REL_NAME_OFFSET],n_Rel_Name,REL_NAME_SIZE);
	memcpy(&pData[REL_REC_SIZE_OFFSET],&n_Rec_Size,sizeof(int));
	memcpy(&pData[REL_ATTR_NUM_OFFSET],&n_Num_Of_Attributes,sizeof(int));
	memcpy(&pData[REL_INX_NUM_OFFSET],&numOfIndexes,sizeof(int));

	rc = rfh.UpdateRecord(rh);
	if (rc != OK) return rc;

	rc = rfs.CloseRecordScan();
	if (rc != OK) return rc;

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	if (strcmp(p_Rel_Name,n_Rel_Name) != 0) {
		std::string attrPath(this->sysm->path + this->sysm->openedDBName + "\\attr.met");
		rc = this->rfm->OpenRecordFile(attrPath.c_str(),rfh);
		if (rc != OK) return rc;

		rfs.OpenRecordScan(rfh,TYPE_STRING,REL_NAME_SIZE,ATTR_REL_NAME_OFFSET,EQ_OP,p_Rel_Name);
		if (rc != OK) {
			rc = this->rfm->CloseRecordFile(rfh);
			if (rc != OK) return rc;

			return (OK);
		}

		while (rfs.GetNextRecord(rh) == OK) {
			char * pData;
			rc = rh.GetData(pData);
			if (rc != OK) return rc;

			memcpy(&pData[ATTR_REL_NAME_OFFSET],n_Rel_Name,REL_NAME_SIZE);

			rc = rfh.UpdateRecord(rh);
			if (rc != OK) return rc;
		}

		rc = rfs.CloseRecordScan();
		if (rc != OK) return rc;

		rc = this->rfm->CloseRecordFile(rfh);
		if (rc != OK) return rc;
	}

	return (OK);
}
예제 #21
0
t_rc SYSM_MetaManager::DeleteAttributeMetadata(char * relName, char * attrName) {

	if (!this->sysm->isOpen) return (SYSM_NOTOPENEDDATABASE);

	t_rc rc;
	REM_RecordFileHandle rfh;
	std::string attrPath(this->sysm->path + this->sysm->openedDBName + "\\attr.met");

	rc = this->rfm->OpenRecordFile(attrPath.c_str(), rfh);
	if (rc != OK) return rc;

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,TYPE_STRING,ATTR_NAME_SIZE,ATTR_NAME_OFFSET,EQ_OP,attrName);
	if (rc != OK) {
		rc = this->rfm->CloseRecordFile(rfh);
		if (rc != OK) return rc;

		return (SYSM_ATTRIBUTEDOESNOTEXISTS);
	}

	bool done = false;
	REM_RecordHandle rh;
	while (rfs.GetNextRecord(rh) == OK) {
		
		REM_RecordFileScan temp_rfs;
		rc = temp_rfs.OpenRecordScan(rfh,TYPE_STRING,REL_NAME_SIZE,ATTR_REL_NAME_OFFSET,EQ_OP,relName);
		if (rc != OK) return rc;

		REM_RecordHandle temp_rh;
		while (temp_rfs.GetNextRecord(temp_rh) == OK) {
			
			REM_RecordID rid, temp_rid;
			rc = rh.GetRecordID(rid);
			if (rc != OK) return rc;

			rc = temp_rh.GetRecordID(temp_rid);
			if (rc != OK) return rc;

			int pageID, temp_pageID;
			rc = rid.GetPageID(pageID);
			if (rc != OK) return rc;

			rc = temp_rid.GetPageID(temp_pageID);
			if (rc != OK) return rc;

			int slot, temp_slot;
			rc = rid.GetSlot(slot);
			if (rc != OK) return rc;

			rc = temp_rid.GetSlot(temp_slot);
			if (rc != OK) return rc;

			if ((pageID == temp_pageID) && (slot == temp_slot)) {
				rc = rfh.DeleteRecord(rid);
				if (rc != OK) return rc;

				done = true;
				break;
			}
		}

		rc = temp_rfs.CloseRecordScan();
		if (rc != OK) return rc;

		if (done) break;
	}

	rc = rfs.CloseRecordScan();
	if (rc != OK) return rc;

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	if (!done) return (SYSM_ATTRIBUTEDOESNOTEXISTS);
	return (OK);
}
예제 #22
0
t_rc SYSM_UserManager::AddPrivilege (char * username, char * dbname) {
	t_rc rc;

	if (!this->isLoggedIn) return (SYSM_NOTLOGGEDIN);
	if (this->CheckPrivilege("all") != OK) return (SYSM_NOTALLOWEDUSER);

	std::string t_path(this->path);
	t_path.append("privileges");

	AttrMet u_meta;
	rc = this->smm->GetAttributeMetadata("privileges", "username", u_meta);
	if (rc != OK) return rc;

	AttrMet db_meta;
	rc = this->smm->GetAttributeMetadata("privileges", "dbname", db_meta);
	if (rc != OK) return rc;

	REM_RecordFileHandle rfh;
	rc = this->rfm->OpenRecordFile((char *) t_path.c_str(),rfh);
	if (rc != OK) return rc;

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,u_meta.type,u_meta.length,u_meta.offset,EQ_OP,username);
	if (rc != OK) return rc;

	REM_RecordHandle rh;
	while ((rc = rfs.GetNextRecord(rh)) == OK) {
		
		if (strcmp(dbname,"grand") == 0) {
			REM_RecordID rid;
			rc = rh.GetRecordID(rid);
			if (rc != OK) return rc;

			rc = rfh.DeleteRecord(rid);
			if (rc != OK) return rc;

		} else {
			char * pData;
			rc = rh.GetData(pData);
			if (rc != OK) return rc;

			char * aData = new char[db_meta.length];
			memcpy(aData,&pData[db_meta.offset],db_meta.length);

			if (strcmp(aData,dbname) == 0) return (SYSM_PRIVEXISTS);
		}
	}
	
	RelMet r_meta;
	rc = this->smm->GetRelationMetadata("privileges",r_meta);
	if (rc != OK) return rc;

	rc = rfs.CloseRecordScan();
	if (rc != OK) return rc;

	char * pData = new char[r_meta.rs];
	memcpy(&pData[u_meta.offset],username,u_meta.length);
	memcpy(&pData[db_meta.offset],dbname,db_meta.length);

	REM_RecordID rid;
	rc = rfh.InsertRecord(pData,rid);
	if (rc != OK) return rc;

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	return (OK);
}
예제 #23
0
t_rc SYSM_MetaManager::UpdateAttributeMetadata(char * p_RelName, char * p_AttrName, 
	char * n_RelName, char * n_AttrName, int n_AttrOffset, t_attrType n_AttrType, int n_AttrLength, int indexNum) {

	if (!this->sysm->isOpen) return (SYSM_NOTOPENEDDATABASE);

	t_rc rc;
	REM_RecordFileHandle rfh;
	std::string attrPath(this->sysm->path + this->sysm->openedDBName + "\\attr.met");

	rc = this->rfm->OpenRecordFile(attrPath.c_str(), rfh);
	if (rc != OK) return rc;

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,TYPE_STRING,ATTR_NAME_SIZE,ATTR_NAME_OFFSET,EQ_OP,p_AttrName);
	if (rc != OK) {
		rc = this->rfm->CloseRecordFile(rfh);
		if (rc != OK) return rc;
		
		return (SYSM_ATTRIBUTEDOESNOTEXISTS);
	}

	bool done = false;
	REM_RecordHandle rh;
	while (rfs.GetNextRecord(rh) == OK) {
		
		REM_RecordFileScan temp_rfs;
		rc = temp_rfs.OpenRecordScan(rfh,TYPE_STRING,REL_NAME_SIZE,ATTR_REL_NAME_OFFSET,EQ_OP,p_RelName);
		if (rc != OK) return rc;

		REM_RecordHandle temp_rh;
		while (temp_rfs.GetNextRecord(temp_rh) == OK) {
			
			REM_RecordID rid, temp_rid;
			rc = rh.GetRecordID(rid);
			if (rc != OK) return rc;

			rc = temp_rh.GetRecordID(temp_rid);
			if (rc != OK) return rc;

			int pageID, temp_pageID;
			rc = rid.GetPageID(pageID);
			if (rc != OK) return rc;

			rc = temp_rid.GetPageID(temp_pageID);
			if (rc != OK) return rc;

			int slot, temp_slot;
			rc = rid.GetSlot(slot);
			if (rc != OK) return rc;

			rc = temp_rid.GetSlot(temp_slot);
			if (rc != OK) return rc;

			if ((pageID == temp_pageID) && (slot == temp_slot)) {
				char * pData;
				rc = rh.GetData(pData);
				if (rc != OK) return rc;

				memcpy(&pData[ATTR_REL_NAME_OFFSET],n_RelName,REL_NAME_SIZE);
				memcpy(&pData[ATTR_NAME_OFFSET],n_AttrName,ATTR_NAME_SIZE);
				memcpy(&pData[ATTR_OFFSET_OFFSET],&n_AttrOffset,sizeof(int));
				memcpy(&pData[ATTR_TYPE_OFFSET],&n_AttrType,sizeof(t_attrType));
				memcpy(&pData[ATTR_LENGTH_OFFSET],&n_AttrLength,sizeof(int));
				memcpy(&pData[ATTR_INX_NO_OFFSET],&indexNum,sizeof(int));

				rc = rfh.UpdateRecord(rh);
				if (rc != OK) return rc;

				done = true;
				break;
			}
		}

		rc = temp_rfs.CloseRecordScan();
		if (rc != OK) return rc;

		if (done) break;
	}

	rc = rfs.CloseRecordScan();
	if (rc != OK) return rc;

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	if (done) return (OK);
	return (SYSM_ATTRIBUTEDOESNOTEXISTS);

}
예제 #24
0
t_rc SYSM_MetaManager::DeleteRelationMetadata(char * rel_Name) {

	if (!this->sysm->isOpen) return (SYSM_NOTOPENEDDATABASE);

	t_rc rc;
	REM_RecordFileHandle rfh;
	std::string relPath(this->sysm->path + this->sysm->openedDBName + "\\rel.met");

	rc = this->rfm->OpenRecordFile(relPath.c_str(), rfh);
	if (rc != OK) return rc;

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,TYPE_STRING,REL_NAME_SIZE,REL_NAME_OFFSET,EQ_OP,rel_Name);
	if (rc != OK) {
		rc = this->rfm->CloseRecordFile(rfh);
		if (rc != OK) return rc;
		
		return (SYSM_RELATIONDOESNOTEXISTS);
	}

	REM_RecordHandle rh;
	if (rfs.GetNextRecord(rh) != OK) return (SYSM_RELATIONDOESNOTEXISTS);

	REM_RecordID rid;
	rc = rh.GetRecordID(rid);
	if (rc != OK) return rc;

	rc = rfh.DeleteRecord(rid);
	if (rc != OK) return rc;

	rc = rfs.CloseRecordScan();
	if (rc != OK) return rc;

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	std::string attrPath(this->sysm->path + this->sysm->openedDBName + "\\attr.met");
	rc = this->rfm->OpenRecordFile(attrPath.c_str(),rfh);
	if (rc != OK) return rc;

	rc = rfs.OpenRecordScan(rfh,TYPE_STRING,REL_NAME_SIZE,ATTR_REL_NAME_OFFSET,EQ_OP,rel_Name);
	if (rc != OK) {
		rc = this->rfm->CloseRecordFile(rfh);
		if (rc != OK) return rc;
		
		return (OK);
	}

	while (rfs.GetNextRecord(rh) == OK) {
		rc = rh.GetRecordID(rid);
		if (rc != OK) return rc;

		rc = rfh.DeleteRecord(rid);
		if (rc != OK) return rc;
	}

	rc = rfs.CloseRecordScan();
	if (rc != OK) return rc;

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	return (OK);
}
예제 #25
0
t_rc SYSM_MetaManager::GetAttributeMetadata(char * relName, char * attrName, AttrMet &attrMeta) {
	
	if (!this->sysm->isOpen) return (SYSM_NOTOPENEDDATABASE);

	t_rc rc;
	REM_RecordID rid;
	REM_RecordFileHandle rfh;
	std::string attrPath;
	attrPath.append(this->sysm->path.c_str());
	attrPath.append(this->sysm->openedDBName.c_str());
	attrPath.append("\\attr.met");

	rc = this->rfm->OpenRecordFile(attrPath.c_str(), rfh);
	if (rc != OK) return rc;

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(rfh,TYPE_STRING,ATTR_NAME_SIZE,ATTR_NAME_OFFSET,EQ_OP,attrName);
	if (rc == OK) {
		REM_RecordHandle rh;
		while (rfs.GetNextRecord(rh) == OK) {
			rc = rh.GetRecordID(rid);
			if (rc != OK) return rc;

			char * n_relName = new char[REL_NAME_SIZE];
			char * pData = new char[ATTR_SIZE];

			rc = rh.GetData(pData);
			if (rc != OK) return rc;

			memcpy(n_relName,&pData[ATTR_REL_NAME_OFFSET],REL_NAME_SIZE);

			if (strcmp(relName,n_relName) == 0) {
				
				attrMeta.relName = new char[255];
				attrMeta.attrName = new char[255];

				memcpy(attrMeta.relName,&pData[ATTR_REL_NAME_OFFSET],REL_NAME_SIZE);
				memcpy(attrMeta.attrName,&pData[ATTR_NAME_OFFSET],ATTR_NAME_SIZE);
				memcpy(&attrMeta.offset,&pData[ATTR_OFFSET_OFFSET],sizeof(int));
				memcpy(&attrMeta.type,&pData[ATTR_TYPE_OFFSET],sizeof(t_attrType));
				memcpy(&attrMeta.length,&pData[ATTR_LENGTH_OFFSET],sizeof(int));
				memcpy(&attrMeta.indexNo,&pData[ATTR_INX_NO_OFFSET],sizeof(int));

				rc = rfs.CloseRecordScan();
				if (rc != OK) return rc;

				rc = this->rfm->CloseRecordFile(rfh);
				if (rc != OK) return rc;

				return (OK);
			}
		}

		rc = rfs.CloseRecordScan();
		if (rc != OK) return rc;
	}

	rc = this->rfm->CloseRecordFile(rfh);
	if (rc != OK) return rc;

	return (SYSM_ATTRIBUTEDOESNOTEXISTS);
}
예제 #26
0
//Εκτελει την εντολη insert into tableName του DML
t_rc SSQLM::runInsert(char name[30], char values[30][256]){

	std::string path = "data/";
	char* curDbName = sysm->getCurdbName();
	path += curDbName;
	path = path + "/" + name;
	struct stat st; //για να δούμε εάν υπάρχει ο πίνακας ή όχι
	if(stat(path.c_str(),&st) != 0) //εάν δεν υπάρχει ο πίνακας
		return SSQLM_TABLE_DOESNT_EXIST;

	//υπάρχει  ο πίνακας ας γίνει η εισαγωγή.
	
	//πρέπει να πάρω τις πληροφορίες για τις δομές rel.met και attr.met
	
	REM_RecordFileScan rfs;
	t_rc rc = rfs.OpenRecordScan(sysm->relMet,TYPE_STRING,30,0,EQ_OP,name);
	if(rc!=OK) return rc;
	REM_RecordHandle rh;
	rc = rfs.GetNextRecord(rh); //αρκεί μία φορά....
	if(rc!=OK) return rc;
	relMet relRec;
	char *data = new char[sizeof(relMet)];
	rc = rh.GetData(data);
	if(rc!=OK) return rc;
	memcpy(&relRec,data,sizeof(relMet));
	
	rc = rfs.CloseRecordScan();
	if(rc!=OK) return rc;

	int recordLength = relRec.record_Length;
	int attrCount = relRec.num_Columns;
	
	/*
		
		Σε περίπτωση που γεμίσουν οι σελίδες δεν ξανα μπαίνουν τα δεδομένα από την πρώτη σελίδα
		και πέρα εγγράφοντας ό,τι δεδομένα υπήρχαν προηγουμένως(ακόμα και αυτά που δεν έχουν
		διαγραφεί). Οι εγγραφές για τα attributes μπαίνουν σειριακά στο attr.met. Δηλαδή
		το δεύτερο attribute δεν μπορεί να βρίσκεται σε recordID που είναι μικρότερο(πιο αριστερά)
		από το recordID του πρώτου attribute.

	*/

	rc = rfs.OpenRecordScan(sysm->attrMet,TYPE_STRING,30,0,EQ_OP,name);
	if(rc!=OK) return rc;
	int i;
	char *recordData = new char[recordLength]; //εδώ θα μπουν τα δεδομένα του record
	for(i=0;i<attrCount;i++){
		
		SYSM::relAttrStr attrRec;
		rc = rfs.GetNextRecord(rh); //αρκεί μία φορά....
		if(rc!=OK) return rc;
		char *data;
		rc = rh.GetData(data);
		if(rc!=OK) return rc;
		memcpy(&attrRec,data,sizeof(attrRec));
		//πήραμε το struct για το (i+1)-oστό attribute
		if(attrRec.type == TYPE_STRING)
			memcpy(recordData + attrRec.offset, values[i], attrRec.attr_Length);
		else if(attrRec.type == TYPE_INT){
			int intData = atoi(values[i]);
			memcpy(recordData + attrRec.offset, &intData, attrRec.attr_Length);
		}
		//ενημερώσαμε το recordData.
	}
	rc = rfs.CloseRecordScan();
	if(rc!=OK) return rc;

	//έχουμε το recordData, ας το εισάγουμε.

	STORM_StorageManager *sm = new STORM_StorageManager();
	REM_RecordFileManager rfm(sm);
	REM_RecordFileHandle rfh;
	REM_RecordID rid;

    rc = rfm.OpenRecordFile(path.c_str(),rfh);
	if(rc!=OK) return rc;

	rc = rfh.InsertRecord(recordData,rid);
	if(rc!=OK) return rc;

	rc = rfm.CloseRecordFile(rfh);
	if(rc!=OK) return rc;
	delete[] recordData;
	return OK;
}
예제 #27
0
t_rc SSQLM::dropTable(char name[30]){

	/*
		διαγραφή table σημαίνει
		1. διαγραφή από τον δίσκο
		2. διαγραφή εγγραφών από rel.met
		3. διαγραφή εγγραφών από attr.met
	*/

	//έλεγχος για το εάν υπάρχει ή όχι ο πίνακας.

	std::string path = "data/";
	char* curDbName = sysm->getCurdbName();
	path += curDbName;
	path = path + "/" + name;
	struct stat st; //για να δούμε εάν υπάρχει ο πίνακας ή όχι
	if(stat(path.c_str(),&st) != 0) //εάν δεν υπάρχει ο πίνακας
		return SSQLM_TABLE_DOESNT_EXIST;
	
	//υπάρχει το table. Ας γίνει η διαγραφή.

	STORM_StorageManager *sm = new STORM_StorageManager();
	REM_RecordFileManager rfm(sm);
	t_rc rc = rfm.DestroyRecordFile(path.c_str());

	//rel.met
	//πρέπει να βρώ το rid του record μέσω του filescan και μετά να καλέσω την delete record.

	REM_RecordFileScan rfs;
	rc = rfs.OpenRecordScan(sysm->relMet,TYPE_STRING,30,0,EQ_OP,name);
	if(rc!=OK) return rc;
	REM_RecordHandle rh;
	rc = rfs.GetNextRecord(rh); //αρκεί μία φορά....

	SYSM::relMetStr relRec;
	char *data = new char[sizeof(SYSM::relMetStr)];
	rc = rh.GetData(data);
	if(rc!=OK) return rc;
	memcpy(&relRec,data,sizeof(SYSM::relMetStr));
	
	rc = rfs.CloseRecordScan();
	if(rc!=OK) return rc;

	REM_RecordID rid;
	rc = rh.GetRecordID(rid); 
	if(rc!=OK) return rc;

	//πήραμε το record id

	rc = sysm->relMet.DeleteRecord(rid); //κάνουμε την διαγραφή.
	if(rc!=OK) return rc;

	//ας κάνουμε την αντίστοιχη διαδικασία για κάθε εγγραφή στο attr.met που αφορά τον πίνακα
	//με όνομα name

	//ουσιαστικά βρίσκουμε το attrCount από το relMet και το RecordHandle πρώτα.


	int attrCount = relRec.num_Columns;

	int i;

	rc = rfs.OpenRecordScan(sysm->attrMet,TYPE_STRING,30,0,EQ_OP,name);
	if(rc!=OK) return rc;
	for(i=0;i<attrCount;i++){
	
		rc = rfs.GetNextRecord(rh); //αρκεί μία φορά....
		if(rc!=OK) return rc;
		rc = rh.GetRecordID(rid);
		if(rc!=OK) return rc;
		rc = sysm->attrMet.DeleteRecord(rid);
		if(rc!=OK) return rc;
	
	}
	rc = rfs.CloseRecordScan();
	if(rc!=OK) return rc;
	//delete[] data;
	return OK;
}
예제 #28
0
t_rc SSQLM::createTable(int attrCount, char tName[30], 
			char attrNames[30][30], char attrTypes[30][10]){

	if(!sysm->isOpen) return SYSM_DB_IS_NOT_OPEN;
	//πρέπει να σιγουρευτούμε πως ο πίνακας με όνομα tName δεν υπάρχει ήδη.
	
	REM_RecordFileScan rfs;
	
	t_rc rc = rfs.OpenRecordScan(sysm->relMet,TYPE_STRING,30,0,EQ_OP,tName);
	if(rc!=OK) return rc;
	REM_RecordHandle rh;
	if(rfs.GetNextRecord(rh) != REM_NO_MORE_RECORDS){
		//υπάρχει ο πίνακας επέστρεψε σφάλμα
		return SSQLM_TABLE_ALREADY_EXISTS;
	}

	rc = rfs.CloseRecordScan();
	if(rc!=OK) return rc;

	//ο πίνακας δεν υπάρχει. 
	
	//δημιουργία πίνακα.

	int recordSize = 0;
	int i;
	
	for(i=0;i<attrCount;i++){
		if(strcmp(attrTypes[i],"INT") == 0){
				recordSize+=sizeof(int);
		}
		else{
			//θα είναι της μορφής CHAR(N), πρέπει να βρώ το Ν.
			char *num = new char[10-6+1]; //CHAR + 2 παρενθέσεις και το '\0'
			int j;
			for(j=5;j<strlen(attrTypes[i]) - 1;j++){
				num[j - 5] = attrTypes[i][j];
			}
			num[j-5] = '\0';
			//ας πάρουμε τον αριθμό.
			int temp = atoi(num);
			recordSize+=temp;
			delete[] num;
			if(temp>256) return SSQLM_STRING_TOO_BIG;
		}
	}

	STORM_StorageManager *sm = new STORM_StorageManager();
	REM_RecordFileManager rfm(sm);

	std::string path = "data/";
	char* curDbName = sysm->getCurdbName();
	path += curDbName;
	path = path + "/" + tName;

	rc = rfm.CreateRecordFile(path.c_str(),recordSize);
	if(rc!=OK) return rc;
	//κάναμε CreateRecordFile
	//πρέπει να ενημερώσουμε τα αρχεία rel.met και attr.met
	//έχουμε τις πληροφορίες για τα attributes και γενικά το είδος τους.
	//έχουμε το όνομα του πίνακα και άρα η ενημέρωση δεν είναι τίποτα.
	
	SYSM::relMetStr relRec;
	
	strcpy(relRec.name,tName);
	relRec.num_Columns = attrCount;
	relRec.num_Indexes = 0;
	relRec.record_Length = recordSize;

	//έχουμε μία εγγραφή, ας την βάλουμε στο rel.met

	char *data = new char[sizeof(relRec)];
	memcpy(data,&relRec,sizeof(relRec));

	REM_RecordID rid;

	rc = sysm->relMet.InsertRecord(data,rid);
	if(rc!=OK) return rc;
	delete data;

	//κάναμε ενημέρωση το rel.met, πάμε στο attr.met

	SYSM::relAttrStr attrRec;
/*
	char name[10]; //όνομα πίνακα
		char attr_name[10]; //όνομα πεδίου
		int offset; //offset όπου αρχίζει το πεδίο μέσα στην εγγραφή
		t_attrType type; //τύπος του πεδίου
		int attr_Length; //μήκος του πεδίου
		int cat_ID; //id του καταλόγου αν υπάρχει(-1 αν δεν υπάρχει).
		*/

	int prevTypesSize = 0;
	for(i=0;i<attrCount;i++){

		strcpy(attrRec.name,tName);
		strcpy(attrRec.attr_name,attrNames[i]);
		if(strcmp(attrTypes[i],"INT") == 0){
				
			attrRec.offset = prevTypesSize;
			attrRec.type = TYPE_INT;
			attrRec.attr_Length = sizeof(int);
			attrRec.cat_ID = -1;
			prevTypesSize += sizeof(int);

		}
		else{
			//θα είναι της μορφής CHAR(N), πρέπει να βρώ το Ν.
			char *num = new char[10-6+1]; //CHAR + 2 παρενθέσεις και το '\0'
			int j;
			for(j=5;j<strlen(attrTypes[i]) - 1;j++){
				num[j - 5] = attrTypes[i][j];
			}
			num[j-5] = '\0';
			//ας πάρουμε τον αριθμό.
			int attrSize=atoi(num);
			delete[] num;
			attrRec.offset = prevTypesSize;
			attrRec.type = TYPE_STRING;
			attrRec.attr_Length = attrSize;
			attrRec.cat_ID = -1;
			prevTypesSize += attrSize;
		}
		
		//ας κάνουμε την εισαγωγή στο attr.met
		data = new char[sizeof(attrRec)];
		memcpy(data,&attrRec,sizeof(attrRec));
		rc = sysm->attrMet.InsertRecord(data,rid);
		if(rc!=OK) return rc;
		delete data;
		//έγινε η εισαγωγή!
	}

	//έγινε η δημιουργία του πίνακα και ενημερώσαμε τα αρχεία rel και attr! 
	
	return OK;
}
예제 #29
0
//Εκτελει υπο-εντολη του DML που ελεγχει τις συνθηκες στο κομματι WHERE
t_rc SSQLM::executeWhere(string tableName, queue<string> comp, queue<REM_RecordID> &ridQ)
{
	//Ουρα με τα rids που ικανοποιουν τουλαχιστον μια συνθηκη
	queue<REM_RecordID> ridQcheck;
	
	t_rc rc;
	
	//Δηλωση χειριστων
	STORM_StorageManager *sm = new STORM_StorageManager();
	REM_RecordFileManager rm(sm);
	REM_RecordFileHandle rfh;
	
	//Υποδεικνυει το πληθος των τριαδων-συνθηκων που υπαρχουν
	//Μια τριαδα ειναι της μορφης attr1 comp attr2 και ολες συνδεονται με τελεστη AND
	int ANDcounter = 0;
	
	//Παρε το directory του πινακα μεσα στη βαση
	string path="data/";
	path.append(sysm->getCurdbName());
	path.append("/");
	path.append(tableName);
	//και ανοιξε fileScan για το συγκεκριμενο πινακα
	rc = rm.OpenRecordFile(path.c_str(),rfh);
	if(rc!=OK) return rc;


	//Αν δεν εχουμε καποια συνθηκη
	if(comp.empty())
	{
		REM_RecordFileScan rfs;
		REM_RecordHandle rh;

		//Ανοιξε το χειριστη του πινακα χωρις συνθηκη
		rc = rfs.OpenRecordScan(rfh,TYPE_STRING,0,0,NO_OP,NULL);
		if(rc!=OK) return rc;
		
		//Για ολα τα records που υπαρχουν στον πινακα
		while(rfs.GetNextRecord(rh)==OK)
		{
			//Παρε το επομενο recordID
			REM_RecordID rid;
			rc = rh.GetRecordID(rid);
			if(rc!=OK) return rc;
			
			//και προσθεσε το στην τελικη ουρα απευθειας
			ridQ.push(rid);
		}
		rc = rfs.CloseRecordScan();
		
	}
	else
	{
		//Μεχρι να εχουν ελεγχθει ολες οι τριαδες συνθηκης
		while(!comp.empty())
		{
			//Διαβασε την επομενη τριαδα
			string attr1, compOp, attr2;
			attr1 = comp.front();
			comp.pop();
			compOp = comp.front();
			comp.pop();
			attr2 = comp.front();
			comp.pop();
			//Μορφης attr1 compOp attr2

			//παρε τον τελεστη REM απο το compOp το οποιο ειναι μορφης τελεστη SirenBase
			t_compOp OrCompOp = getCompOp(compOp);

			struct relAttr RAttr, RAttr2;
			string* tablePoint = &tableName;

			//Αρχικοποιησε τη στηλη attr1
			rc = initializeAttr(tablePoint, 1, attr1, RAttr);
			if(rc!=OK) return rc;
			
			//Προσπαθησε να αρχικοποιησεις τη στηλη attr2
			rc = initializeAttr(tablePoint, 1, attr2, RAttr2);
			if((rc!=OK)||(RAttr2.type!=RAttr.type)) //Αν η προσπαθεια αποτυχει ή οι δυο στηλες δεν ειναι ομοιες
			{
				//το RAttr2 δεν ειναι στηλη, αρα, αναφερεται σε τιμη
				rc = whereValueCase(rfh,ridQcheck,RAttr,OrCompOp,attr2);
				if(rc!=OK) return rc;
			}
			else //αλλιως, αν η αρχικοποιηση ηταν επιτυχης
			{
				//το RAttr2 αναφερεται σε στηλη

				rc = whereAttrCase(rfh, ridQcheck, RAttr,OrCompOp,RAttr2);
				if(rc!=OK) return rc;
			}
			if(!comp.empty()) comp.pop(); //Πεταμα του "AND", αν υπαρχει
			ANDcounter++; //Ενημερωσε το μετρητη ζευγων που εχουμε
		}
		int qSize = ridQcheck.size(); //το πληθος των πολλαπλοεμφανιζομενων rids (ικανοποιουν τουλαχιστον μια συνθηκη)
		
		//Δομη για καθε rid που ικανοποιει μια τουλαχιστον συνθηκη
		//Περιλαμβανει, το rid και τον αριθμο συνθηκων που ικανοποιει
		struct RIDdata* tAND = new RIDdata[qSize];
		int m=0; //ο Μετρητης αυτου του πινακα απο structs
		
		//Για καθε rid που ικανοποιει μια τουλαχιστον συνθηκη
		for(int i=0;i<qSize;i++)
		{
			//παρε το επομενο rid
			REM_RecordID temp = ridQcheck.front();
			ridQcheck.pop();

			bool flaggy=true; //δειχνει αν το τρεχων rid (temp) εχει ξαναεμφανιστει πριν στην ουρα
			int pID, sID, pIDs, sIDs;
			
			//Παρε τις ιδιοτητες του temp
			rc = temp.GetPageID(pID);
			if(rc!=OK) return rc;
			rc = temp.GetSlot(sID);
			if(rc!=OK) return rc;

			//Για καθε rid που διαβαστηκε προηγουμενως
			for(int j=0;j<m;j++)
			{
				//παρε τις ιδιοτητες του
				rc = tAND[j].rid.GetPageID(pIDs);
				if(rc!=OK) return rc;
				rc = tAND[j].rid.GetSlot(sIDs);
				if(rc!=OK) return rc;

				//και συγκρινε τες
				if((pID-pIDs) || (sID-sIDs)) //Αν δεν ταυτιζεται με το τρεχων rid
				{
					//nothing
				}
				else //αλλιως, αν ταυτιζεται
				{
					flaggy=false; //το rid temp δεν ειναι πρωτοεμφανιζομενο
					tAND[j].times++; //αυξησε το πληθος συνθηκων που ικανοποιει
				}
			}
			if(flaggy) //αν δεν ταυτιστηκε με κανενα απο τα προηγουμενα rids
			{
				//πρωτοεμφανιζομενο rid
				//αρχικοποιησε ενα νεο tAND
				tAND[m].rid = temp;
				tAND[m].times = 1;
				m++;
			}
		}
		
		//Για καθε δομη tAND
		for(int i=0;i<m;i++)
		{
			//Αν το συγκεκριμενο tAND ικανοποιει ολες τις συνθηκες
			if(tAND[i].times==ANDcounter)
			{
				ridQ.push(tAND[i].rid); //προστεσε το rid του στην τελικη ουρα
			}
		}
	}
	rc = rm.CloseRecordFile(rfh);
	return rc;
}
t_rc SSQLM_DML_Manager::Join(char *table1, char* table2, char *connectionAttribute){

	//	Gia na kanoume to JOIN, anoigoume to table1 kai pairnoume seiriaka ena-ena ta records tou.
	//	Apo ka8e record, kratame thn timh pou 8a ginei h syndesh, kai me authn psaxnoume sto
	//	table2 na vroume poia records exoun thn timh auth sto column ths syndeshs. H anazhthsh 
	//	pragmatopoieitai eite me index( ean to table2 exei index gia to column ths syndeshs)
	//	eite se periptwsh pou den exei index, anoigontas to arxeio tou table table2.
	//	Gia ka8e record pou vre8hke sto table2, dhmiourgeitai to neo record pou perilamvanei
	//	ta attributes kai apo ta 2 tables ths syndeshs ( fysika to attribute ths syndeshs 
	//	emfanizetai 1 mono fora ).
	//	Afou dhmiourgh8oun ta nea records (ta opoia apoteloun ousiastika to join twn 2 pinakwn),
	//	anadhmiourgoume ta string gia thn kataskeyh twn 2 tables (px: id INT, name CHAR(15), age INT...)
	//	Auto to kanoume gia na ftiaksoume to neo string gia thn kataskeuh tou tempTableForIndex,
	//	ston opoio me mia epanalhpsh, kanoume insert ta nea records ths syndeshs.
	//	H synarthsh auth mporei na klei8ei anadromika wste na ginoun join apeirwn pinakwn.

	STORM_StorageManager *stormgr = new STORM_StorageManager();				
	REM_RecordFileManager *remrfm = new REM_RecordFileManager(stormgr);	
	REM_RecordFileHandle *remrfh = new REM_RecordFileHandle();
	REM_RecordFileScan *remrfs = new REM_RecordFileScan();
	REM_RecordHandle *remrh = new REM_RecordHandle;

	STORM_StorageManager *stormgr2 = new STORM_StorageManager();				
	REM_RecordFileManager *remrfm2 = new REM_RecordFileManager(stormgr2);	
	REM_RecordFileHandle *remrfh2 = new REM_RecordFileHandle();
	REM_RecordFileScan *remrfs2 = new REM_RecordFileScan();
	REM_RecordHandle *remrh2 = new REM_RecordHandle;

	STORM_StorageManager *mgrTemp = new STORM_StorageManager();
	REM_RecordFileManager *rfmTemp = new REM_RecordFileManager(mgrTemp);
	INXM_IndexManager *imTemp = new INXM_IndexManager(mgrTemp);
	SSQLM_DDL_Manager *ddlmTemp = new SSQLM_DDL_Manager(rfm,im,"testingDB");

	char pathname[50];
	int offset,
		offset2,
		size,
		size2,
		indexID,
		indexID2,
		recordSize1,
		recordSize2;
	char *typeString,
		*typeString2,
		*pData1;
	t_attrType type1,
		type2;
	REM_RecordID rid;
	vector<char *> newTableRecords; 

	_snprintf_s(pathname,sizeof(pathname),"%s/%s",dbName,table1);
	t_rc rc = remrfm->OpenRecordFile(pathname,*remrfh);
	if (rc != OK) { return rc; }

	_snprintf_s(pathname,sizeof(pathname),"%s/%s",dbName,table2);
	rc = remrfm2->OpenRecordFile(pathname,*remrfh2);
	if (rc != OK) { return rc; }

	rc = FindAttributeInAttrmet(table1,connectionAttribute,offset,typeString,size,indexID);
	if (rc != OK) { return rc; }

	if(strcmp(typeString,"TYPE_INT") == 0)
		type1 = TYPE_INT;
	else
		type1 = TYPE_STRING;

	rc = FindAttributeInAttrmet(table2,connectionAttribute,offset2,typeString2,size2,indexID2);
	if (rc != OK) { return rc; }

	if(strcmp(typeString2,"TYPE_INT") == 0)
		type2 = TYPE_INT;
	else
		type2 = TYPE_STRING;

	rc = GetTableRecordSize(table1,recordSize1);
	if (rc != OK) { return rc; }

	rc = GetTableRecordSize(table2,recordSize2);
	if (rc != OK) { return rc; }

	rc = remrfs->OpenRecordScan(*remrfh,type1,0,0,NO_OP,NULL);
	if (rc != OK) { return rc; }
	
	char *connectionValue = (char *)malloc(size);

	while( remrfs->GetNextRecord(*remrh) != REM_FSEOF ){

		rc = remrh->GetData(pData1);
		if (rc != OK) { return rc; }

		int i;

		for(i=0; i<size; i++){
			connectionValue[i] = pData1[i+offset];
		}
		connectionValue[i] = '\0';

		char *firstRecord = (char *)malloc(strlen(pData1));
		strcpy(firstRecord,pData1);
		firstRecord[recordSize1] = '\0';
		char *newRecord;

		if( indexID2 != -1 ){	//	CASE INDEX

			INXM_IndexHandle ih;
			INXM_IndexScan *is = new INXM_IndexScan();
			char pathname[50];

			_snprintf_s(pathname,sizeof(pathname),"%s/%s",dbName,table2);								
			rc = im->OpenIndex(pathname,indexID2,ih);					
			if (rc != OK) { return rc; }									
																		
			if(strcmp(typeString,"TYPE_INT") == 0){	// case of Integer								
					int cndV = atoi(connectionValue);						
					int *key1 = new int(cndV);							
					rc = is->OpenIndexScan(ih, EQ_OP, key1);								
					if (rc != OK) { return rc; }							
				}																
			else{		//case of string									
				rc = is->OpenIndexScan(ih, EQ_OP, connectionValue);			
				if (rc != OK) { return rc; }										
			}

			while( is->GetNextEntry(rid) != INXM_FSEOF){
				
				rc = ConCatRecords(rid,remrfh2,remrh2,offset2,size2,recordSize2,firstRecord,newRecord);
				if (rc != OK) { return rc; }
			}
		}
		else{	// CASE NO INDEX
				if(strcmp(typeString,"TYPE_INT") == 0){	// case of Integer								
					int cndV = atoi(connectionValue);						
					int *key1 = new int(cndV);							
					rc = remrfs2->OpenRecordScan(*remrfh2,type2,size2,offset2,EQ_OP,key1);								
					if (rc != OK) { return rc; }							
				}	
				else{
					rc = remrfs2->OpenRecordScan(*remrfh2,type2,size2,offset2,EQ_OP,connectionValue);								
					if (rc != OK) { return rc; }
				}

				while( remrfs2->GetNextRecord(*remrh2) != REM_FSEOF ){
					remrh2->GetRecordID(rid);
					rc = ConCatRecords(rid,remrfh2,remrh2,offset2,size2,recordSize2,firstRecord,newRecord);
					if (rc != OK) { return rc; }
				}
		}
		cout<<newRecord<<endl;
		newTableRecords.push_back(newRecord);
	}

	// Find all the records in attr.met about table1
	char *tableDefinition;
	rc = RebuildTableDefinition(table1,tableDefinition);
	if (rc != OK) { return rc; }
	
	char *tableDefinition2;
	rc = RebuildTableDefinitionChopped(table2,tableDefinition2,connectionAttribute);
	if (rc != OK) { return rc; }

	char *newTableDefinition = (char *)malloc(strlen(tableDefinition)+strlen(tableDefinition2) + 2);

	strcpy(newTableDefinition,tableDefinition);
	strcat(newTableDefinition,", ");
	strcat(newTableDefinition,tableDefinition2);
	
	if( strcmp(table1,"tempTableForJoin") == 0 ){
		rc = ddlmTemp->DropTable("tempTableForJoin");
		if (rc != OK) { return rc; }
	}

	rc = ddlmTemp->CreateTable("tempTableForJoin",newTableDefinition);
	if (rc != OK) { return rc; }
	
	SSQLM_DML_Manager *dmlmTemp = new SSQLM_DML_Manager(rfmTemp,imTemp,"testingDB");

	for( int t = 0; t < (int) newTableRecords.size(); t++ ){
		rc = dmlmTemp->Insert("tempTableForJoin",newTableRecords[t]);
		if (rc != OK) { return rc; }
	}



	rc = remrfm->CloseRecordFile(*remrfh);
	if (rc != OK) { return rc; }

	rc = remrfm2->CloseRecordFile(*remrfh2);
	if (rc != OK) { return rc; }

	delete stormgr, stormgr2, mgrTemp,
		remrfm,	remrfm2, rfmTemp,
		remrfh, remrfh2,
		remrfs, remrfs2,
		remrh,remrh2,
		imTemp,ddlmTemp,dmlmTemp;




	return OK;
}