Esempio n. 1
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;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}