Exemple #1
0
//遍历初始化,判断一下查询属性类型是否有误等等
int RM_FileScan::OpenScan(RM_FileHandle& fileHandle, AttrType attrType, int attrLength,
                          int attrOffset, int attrCol,CompOp compOp, void* value) {
	if (fileHandle.GetPsum() == 1) {
		cout << "[RM_FileScan]Empty Database" << endl;
		return 1;
	}
	filehandle = &fileHandle;

	/*	if (compOp == NO) {
			type = 18;
		} else {
			if(attrType == NONETYPE) {
				type = 19;
			} else {
				int typevalue = attrType;
				int opvalue = compOp;
				type = (typevalue - 1) * 6 + opvalue;
			}
		}*/
	currentRid = new RID(fileHandle.GetFileid(), 1, 0);
	comparevalue = value;
	attrlength = attrLength;
	attroffset = attrOffset;
	op = compOp;
	type = attrType;
	attrcol = attrCol;
	isclose = false;
	return 0;
}
static RC RollBackDeletion(SM_DbHandle &db, Event &event)
{
    RC rc;
    RID newRid;

    printf("QL: Undoing deletion.\n");

    // Insert the record.
    RM_FileHandle *pTableHandle;
    if ((rc = db.FindTableHandle(event.tableName.c_str(), pTableHandle)))
        return rc;
    if ((rc = pTableHandle->InsertRec(event.record, newRid)))
        return rc;

    // Insert indexes.
    vector<SM_ActiveAttr> *attrs;
    if ((rc = db.AllAttributes(event.tableName.c_str(), attrs)))
        return rc;

    vector<SM_ActiveAttr>::iterator pActiveAttr;
    for (pActiveAttr = attrs->begin(); pActiveAttr != attrs->end(); ++pActiveAttr) {
        if (pActiveAttr->record.hasIndex) {
            IX_IndexHandle *pIndex = &pActiveAttr->indexHandle;
            if ((rc = pIndex->InsertEntry(event.record + pActiveAttr->record.attrOffset, newRid)))
                return rc;
        }
    }

    return 0;
}
static RC RollBackUpdate(SM_DbHandle &db, Event &event, RID &rid)
{
    RC rc;

    printf("QL: Undoing update.\n");
    RM_FileHandle *pTableHandle;
    if ((rc = db.FindTableHandle(event.tableName.c_str(), pTableHandle)))
        return rc;

    RM_Record record;
    if ((rc = pTableHandle->GetRec(rid, record)))
        return rc;

    char *data;
    if ((rc = record.GetData(data)))
        return rc;

    SM_Attribute *pAttr;
    if ((rc = db.FindAttribute(event.tableName.c_str(), event.attrName.c_str(), pAttr)))
        return rc;

    // If indexed, remove the old entry.
    IX_IndexHandle *pIndexHandle;
    if (pAttr->hasIndex) {
        if ((rc = db.FindIndexHandle(event.tableName.c_str(), event.attrName.c_str(), pIndexHandle))) 
            return rc;
        if ((rc = pIndexHandle->DeleteEntry(data + pAttr->attrOffset, rid))) 
            return rc;
    }

    // Restore the record.
    int recordSize = pTableHandle->header.recordSize;
    memcpy(data, event.record, recordSize);

    // Update the record.
    if ((rc = pTableHandle->UpdateRec(record))) 
        return rc;

    // If indexed, insert the new entry.
    if (pAttr->hasIndex) {
        if ((rc = pIndexHandle->InsertEntry(data + pAttr->attrOffset, rid))) 
            return rc;
    }

    return 0;
}
Exemple #4
0
int RM_Manager::CloseFile(RM_FileHandle &fileHandle) {
	fileHandle.close();
	return 0;
}
Exemple #5
0
RC SM_CreateTable(SM_Manager *self, char *relName, AttrInfo *attributes) {
	int recordSize = 0, attrNum = 0, ret;
	AttrInfo *p, *pk = NULL;

	if (self->dbname == NULL) {
		return SM_NODBSELECTED;
	}

	if (checkInViews(self, relName)) {
		return SM_VIEWEXIST;
	}

    for (p = attributes; p; p = p->next) {
    	AttrInfo *p0;
    	for (p0 = p->next; p0; p0 = p0->next) {
    		if (!strcmp(p->name, p0->name))
    			return SM_DUPLICATEATTR;
    	}
    }

	for (p = attributes; p; p = p->next) {
		int j = self->attrCount++;
		attrNum++;
		AttrCat actmp;
		AttrCatSetRelName(&actmp, relName);
		AttrCatSetAttrName(&actmp, p->name);
		actmp.offset = recordSize;
		actmp.attrType = p->type;
		actmp.attrLength = p->size;
		actmp.indexNo = -1;
		if (!checkRelAttr(self, p->foriegnKey)) {
			return SM_NOREL;
		}
		if (p->foriegnKey) {
			MAXSCP(actmp.fkrelName, p->foriegnKey->relName, MAXNAME);
			MAXSCP(actmp.fkattrName, p->foriegnKey->attrName, MAXNAME);

			char *fname = malloc(2*MAXNAME+3);
			strcpy(fname, ".");
			strcat(fname, p->foriegnKey->relName);
			strcat(fname, ".");
			strcat(fname, p->foriegnKey->attrName);
			RM_FileHandle fh;
			initRM_FileHandle(&fh);
			self->rmm->CreateFile(self->rmm, fname, FKINFO_RSIZE);
			self->rmm->OpenFile(self->rmm, fname, &fh);
			fkInfo fki;
			strcpy(fki.relName, p->foriegnKey->relName);
			strcpy(fki.attrName, p->foriegnKey->attrName);
			RID rid;
			fh.InsertRec(&fh, (char *)&fki, &rid);
		} else {
			strcpy(actmp.fkrelName, "");
			strcpy(actmp.fkattrName, "");
		}
		if (p->isPrimaryKey) {
			if (pk) {
				return SM_DUPRIMARYKEY;
			} else {
				pk = p;
			}
		}
		if (p->check) {
			actmp.op = p->check->op;
			memcpy(&actmp.rvalue, p->check->value->data, p->size);
		} else {
			actmp.op = NO_OP;
		}
        self->attrFile.InsertRec(&(self->attrFile), (char *)&actmp,
				&actmp.rid);
        self->attrFile.ForcePages(&(self->attrFile), ALL_PAGES);
		ATTRARRCHECK(self, j);
        memcpy(&(self->attrRecords[j]), &actmp, sizeof(AttrCat));
        recordSize += p->size;
    }

    if ((ret = self->rmm->CreateFile(self->rmm, relName, recordSize))
    		!= NORMAL) {
    	return ret;
    }

    int k = self->relCount++;
    RelCat rctmp;
    RelCatSetRelName(&rctmp, relName);
    rctmp.tupleLength = recordSize;
    rctmp.attrCount = attrNum;
    rctmp.indexCount = 0;
    if (pk) {
    	strcpy(rctmp.primaryKey, pk->name);
    } else {
    	strcpy(rctmp.primaryKey, "");
    }
    self->relFile.InsertRec(&(self->relFile), (char *)&rctmp, &rctmp.rid);
    self->relFile.ForcePages(&(self->relFile), ALL_PAGES);
	RELARRCHECK(self, k);
    memcpy(&(self->relRecords[k]), &rctmp, sizeof(RelCat));
	return NORMAL;
}
Exemple #6
0
RC QL_Manager::FindRecords(const char *relName, vector<RM_Record> &records){

    RC rc;

    RM_FileHandle *rh;
    IX_IndexHandle *ih;
    if (rc = db.FindTableHandle(relName, rh)) 
        return rc;

    RM_FileScan rmscan;
    IX_IndexScan ixscan;

    vector<RM_Record> v_now;
    v_now.clear();
    bool flagAll = true;

    if (rmp.nConditions) {
        for (int i = 0; i < rmp.nConditions; i++) 
            if (rmp.conditions[i].bRhsIsValue) {
                if (strcmp(relName, rmp.conditions[i].lhsAttr.relName) != 0) 
                    continue;
                vector<RM_Record> v_tmp;
                v_tmp.clear();
                char *attrName = rmp.conditions[i].lhsAttr.attrName;
                SM_Attribute *smAttr;
                if (rc = db.FindAttribute(relName, attrName, smAttr))
                    return rc;
                AttrType attrType = smAttr->attrType;
                int attrLength = smAttr->attrLength;
                int attrOffset = smAttr->attrOffset;
                int attrNumber = smAttr->number;
                CompOp op = rmp.conditions[i].op;
                void *data = rmp.conditions[i].rhsValue.data;

                if (smAttr->hasIndex && isCmpOp(op)) {
                    if (rc = db.FindIndexHandle(relName, attrName, ih))
                        return rc;
                    ixscan.OpenScan(*ih, op, data);
                    RID rid;
                    RM_Record rec;
                    v_tmp.clear();
                    while (1) {
                        rc = ixscan.GetNextEntry(rid);
                        if (rc != 0 && rc != IX_EOF)
                            return rc;
                        if (rc == IX_EOF) break;
                        if (rc = rh->GetRec(rid, rec))
                            return rc;
                        v_tmp.push_back(rec);
                    }
                    ixscan.CloseScan();
                }  else {
                    if (op == IS_OP || op == IS_NOT_OP) {
                        int number = smAttr->number;
                        int nullBitmap = rh->header.recordSize - sizeof(int);
                        if ((rc = rmscan.OpenScan(*rh, NOTYPE, 4, nullBitmap, 0, op, &number)))
                            return rc;
                    } else {
                        if (rc = rmscan.OpenScan(*rh, attrType, attrLength, attrOffset, attrNumber, op, data)) 
                            return rc;
                    }
                    v_tmp.clear();
                    RM_Record rec;
                    while (rmscan.GetNextRec(rec) != RM_ERR_EOF) {
                        v_tmp.push_back(rec);
                    }
                    if (rc = rmscan.CloseScan()) 
                        return rc;
                }


                if (rc = MergeAnd(v_now, v_tmp, flagAll))
                    return rc;

                flagAll = false;
            }
        
    }
    //cout << "before flagAll\n";
    if (flagAll) {
        int t = 0;
        if (rc = rmscan.OpenScan(*rh, INT, 4, 0, 0, NO_OP, &t, NO_HINT)) 
            return rc;
        //cout << "after open scan\n";
        RM_Record rec;
        v_now.clear();
        while (rmscan.GetNextRec(rec) != RM_ERR_EOF) 
            v_now.push_back(rec);
        if (rc = rmscan.CloseScan())
            return rc;
    }
    //cout << "after flagAll\n";

    records.clear();
    records.assign(v_now.begin(), v_now.end());

    return 0;
}
RC QL_Manager::Insert()
{
    RC rc;

    const char *tableName = rmp.relName;
    vector<SM_ActiveAttr> *attrs;
    if ((rc = db.AllAttributes(tableName, attrs)))
        return rc;

    if (rmp.nValues != attrs->size()) {
        fprintf(stderr, "QL: Mismatch # of attributes.\n");
        return QL_ERR_INVALID_COMMAND;
    }

    // Fill in the record buffer.
    SM_Attribute *lastAttr = &attrs->at(attrs->size()-1).record;
    int recordSize = lastAttr->attrOffset + lastAttr->attrLength + sizeof(int);

    Event event;
    event.record = new char[recordSize];
    event.type = INSERT;
    event.tableName = rmp.relName;
    memset(event.record, 0, recordSize);

    RM_FileHandle *pTableHandle;
    if ((rc = db.FindTableHandle(rmp.relName, pTableHandle))) {
        delete[] event.record;
        return rc;
    }

    int *pNullBitmap = (int *)(event.record + lastAttr->attrOffset + lastAttr->attrLength);

    for (int i = 0; i < attrs->size(); i++) {
        SM_Attribute *attr = &attrs->at(i).record;
        if (attr->attrType != rmp.values[i].type && rmp.values[i].type != NOTYPE) {
            fprintf(stderr, "QL: Mismatch type for attribute %s\n", attr->attrName);
            delete[] event.record;
            return QL_ERR_INVALID_COMMAND;
        }

        // Check primary key uniqueness.
        if (attr->isPrimary && !attr->hasIndex) {
            RM_FileScan scan;
            if ((rc = scan.OpenScan(*pTableHandle, attr->attrType, 
                                    attr->attrLength, attr->attrOffset,
                                    attr->number,
                                    EQ_OP, rmp.values[i].data)))
                return rc;
            RM_Record rec;
            if (scan.GetNextRec(rec) != RM_ERR_EOF) {
                fprintf(stderr, "QL: Primary key conflicts!\n");
                scan.CloseScan();
                return QL_PRIMARY_KEY;
            }
            if ((rc = scan.CloseScan()))
                return rc;
        }

        // Check foreign key existence.
        if (attr->isForeignKey) {
            RM_FileHandle *pForeign;
            if ((rc = db.FindTableHandle(attr->refTableName, pForeign)))
                return rc;

            SM_Attribute *foreignAttr;
            if ((rc = db.FindAttribute(attr->refTableName, attr->refAttrName, foreignAttr)))
                return rc;

            if (foreignAttr->attrType != attr->attrType) {
                fprintf(stderr, "QL: mismatch attribute type with foreign key.\n");
                return rc;
            }

            RM_FileScan scan;
            if ((rc = scan.OpenScan(*pForeign, foreignAttr->attrType,
                                    foreignAttr->attrLength, foreignAttr->attrOffset,
                                    foreignAttr->number,
                                    EQ_OP, rmp.values[i].data)))
                return rc;

            RM_Record rec;
            if (scan.GetNextRec(rec) != 0) {
                fprintf(stderr, "QL: Foreign key does not exist!\n");
                scan.CloseScan();
                return QL_FOREIGN_KEY;
            }

            if ((rc = scan.CloseScan()))
                return rc;
        }

        if (rmp.values[i].type == NOTYPE) {
            if (attr->hasIndex) {
                fprintf(stderr, "QL: indexed attribute %s cannot be NULL\n", attr->attrName);
                delete[] event.record;
                return QL_ERR_INVALID_COMMAND;
            }
            *pNullBitmap |= 1 << i;
        } else if (rmp.values[i].type == INT || rmp.values[i].type == FLOAT)
            memcpy(event.record + attr->attrOffset, rmp.values[i].data, attr->attrLength);
        else
            strncpy(event.record + attr->attrOffset, (const char *)rmp.values[i].data, attr->attrLength);
    }

    // Insert the record into the database.
    RID rid;
    if ((rc = pTableHandle->InsertRec(event.record, rid))) {
        delete[] event.record;
        return rc;
    }

    transaction.insert(pair<RID, Event>(rid, event));

    // Insert the record into indexes.
    for (int i = 0; i < attrs->size(); i++) {
        SM_Attribute *pAttr = &attrs->at(i).record;
        if (pAttr->hasIndex) {
            IX_IndexHandle *pIndexHandle = &attrs->at(i).indexHandle;
            //cout << "debug:\n";
            if ((rc = pIndexHandle->InsertEntry(event.record + pAttr->attrOffset, rid)))
                return rc;
        }
    }

    return 0;
}
RC QL_Manager::Update()
{
    RC rc;
    vector<RM_Record> chosenRecords;

    RM_FileHandle *pTableHandle;
    if ((rc = db.FindTableHandle(rmp.relName, pTableHandle)))
        return rc;

    SM_Attribute *pAttr;
    if ((rc = db.FindAttribute(rmp.relName, rmp.updAttr.attrName, pAttr)))
        return rc;

    if (rmp.rhsValue.type != pAttr->attrType && rmp.rhsValue.type != NOTYPE) {
        fprintf(stderr, "QL: Update attributes with different type!\n");
        return QL_ERR_INVALID_COMMAND;
    }

    if (rmp.rhsValue.type == NOTYPE && pAttr->notNull) {
        fprintf(stderr, "QL: Update not-null attribute with NULL!\n");
        return QL_ERR_INVALID_COMMAND;
    }

    if ((rc = FindRecords(rmp.relName, chosenRecords)))
        return rc;
    
    vector<RM_Record>::iterator pRecord;
    int recordSize = pTableHandle->header.recordSize;
    for (pRecord = chosenRecords.begin(); pRecord != chosenRecords.end(); pRecord++) {
        RID rid;
        if ((rc = pRecord->GetRid(rid)))
            return rc;
        char *data;
        if ((rc = pRecord->GetData(data)))
            return rc;
        int *pNullBitmap = (int *)(data + recordSize - sizeof(int));

        // Check primary key uniqueness.
        SM_Attribute *attr = pAttr;
        if (attr->isPrimary && !attr->hasIndex) {
            RM_FileScan scan;
            if ((rc = scan.OpenScan(*pTableHandle, attr->attrType, 
                                    attr->attrLength, attr->attrOffset,
                                    attr->number,
                                    EQ_OP, rmp.rhsValue.data)))
                return rc;
            RM_Record rec;
            if (scan.GetNextRec(rec) != RM_ERR_EOF) {
                fprintf(stderr, "QL: Primary key conflicts!\n");
                scan.CloseScan();
                return QL_PRIMARY_KEY;
            }
            if ((rc = scan.CloseScan()))
                return rc;
        }

        // Check foreign key existence.
        if (attr->isForeignKey) {
            RM_FileHandle *pForeign;
            if ((rc = db.FindTableHandle(attr->refTableName, pForeign)))
                return rc;

            SM_Attribute *foreignAttr;
            if ((rc = db.FindAttribute(attr->refTableName, attr->refAttrName, foreignAttr)))
                return rc;

            if (foreignAttr->attrType != attr->attrType) {
                fprintf(stderr, "QL: mismatch attribute type with foreign key.\n");
                return rc;
            }

            RM_FileScan scan;
            if ((rc = scan.OpenScan(*pForeign, foreignAttr->attrType,
                                    foreignAttr->attrLength, foreignAttr->attrOffset,
                                    foreignAttr->number,
                                    EQ_OP, rmp.rhsValue.data)))
                return rc;

            RM_Record rec;
            if (scan.GetNextRec(rec) != 0) {
                fprintf(stderr, "QL: Foreign key does not exist!\n");
                scan.CloseScan();
                return QL_FOREIGN_KEY;
            }

            if ((rc = scan.CloseScan()))
                return rc;
        }

        Event event;
        event.type = UPDATE;
        event.record = new char[recordSize];
        event.tableName = rmp.relName;
        event.attrName = rmp.updAttr.attrName;
        memcpy(event.record, data, recordSize);

        // If indexed, remove the old entry.
        IX_IndexHandle *pIndexHandle;
        if (pAttr->hasIndex) {
            if ((rc = db.FindIndexHandle(rmp.relName, pAttr->attrName, pIndexHandle))) {
                delete[] event.record;
                return rc;
            }
            if ((rc = pIndexHandle->DeleteEntry(data + pAttr->attrOffset, rid))) {
                delete[] event.record;
                return rc;
            }
        }

        map<RID, Event, RID_LessThan>::iterator pPrevEvent = transaction.find(rid);
        if (pPrevEvent == transaction.end()) {
            transaction.insert(pair<RID, Event>(rid, event));
        } else {
            delete[] event.record;
        }

        // Modify the record.
        if (pAttr->attrType == INT || pAttr->attrType == FLOAT) {
            memcpy(data + pAttr->attrOffset, rmp.rhsValue.data, pAttr->attrLength);
            *pNullBitmap &= ~(1 << pAttr->number);
        } else if (pAttr->attrType == NOTYPE) {
            *pNullBitmap |= 1 << pAttr->number;
        } else {
            strncpy(data + pAttr->attrOffset, (const char *)rmp.rhsValue.data, pAttr->attrLength);
            *pNullBitmap &= ~(1 << pAttr->number);
        }

        // Update the record.
        if ((rc = pTableHandle->UpdateRec(*pRecord))) {
            delete[] event.record;
            return rc;
        }

        // If indexed, insert the new entry.
        if (pAttr->hasIndex) {
            if ((rc = pIndexHandle->InsertEntry(data + pAttr->attrOffset, rid))) {
                delete[] event.record;
                return rc;
            }
        }
        
    }

    return 0;
}
RC QL_Manager::Delete()
{
    RC rc;
    vector<RM_Record> chosenRecords;

    vector<SM_ActiveAttr> *attrs;
    if ((rc = db.AllAttributes(rmp.relName, attrs)))
        return rc;

    RM_FileHandle *pTableHandle;
    if ((rc = db.FindTableHandle(rmp.relName, pTableHandle)))
        return rc;

    if ((rc = FindRecords(rmp.relName, chosenRecords)))
        return rc;
    
    vector<RM_Record>::iterator pRecord;
    int recordSize = pTableHandle->header.recordSize;
    for (pRecord = chosenRecords.begin(); pRecord != chosenRecords.end(); ++pRecord) {
        RID rid;
        if ((rc = pRecord->GetRid(rid)))
            return rc;
        char *data;
        if ((rc = pRecord->GetData(data)))
            return rc;

        Event event;
        event.type = DELETE;
        event.record = new char[recordSize];
        event.tableName = rmp.relName;
        memcpy(event.record, data, recordSize);

        if ((rc = pTableHandle->DeleteRec(rid))) {
            delete[] event.record;
            return rc;
        }

        // Delete the record from indexes.
        for (int i = 0; i < attrs->size(); i++) {
            SM_Attribute *pAttr = &attrs->at(i).record;
            if (pAttr->hasIndex) {
                IX_IndexHandle *pIndexHandle = &attrs->at(i).indexHandle;
               
                if ((rc = pIndexHandle->DeleteEntry(event.record + pAttr->attrOffset, rid)))
                    return rc;
            }
        }

        map<RID, Event, RID_LessThan>::iterator pPrevEvent = transaction.find(rid);
        if (pPrevEvent == transaction.end()) {
            transactionDeleted.push_back(event);
        } else {
            if (pPrevEvent->second.type == INSERT) {
                // Previously inserted. Remove it from the transaction.
                delete[] event.record;
                delete[] pPrevEvent->second.record;
                transaction.erase(pPrevEvent);
            } else if (pPrevEvent->second.type == UPDATE) {
                delete[] event.record;
                pPrevEvent->second.type == DELETE;
                transactionDeleted.push_back(pPrevEvent->second);
                transaction.erase(pPrevEvent);
            } 
        }
        
    }

    return 0;
}
Exemple #10
0
RC RM_Manager::CloseFile (RM_FileHandle &fileHandle) {
	return fileHandle.Close ();
}
Exemple #11
0
RC RM_Manager::OpenFile (const char *fileName, RM_FileHandle &fileHandle) {
	return fileHandle.Open (pfm, fileName);
}