⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ljfiledb.cpp

📁 小型文件数据库 一个文件对应一个表 最大只支持65535条记录(可以修改宏) 定长记录 一级索引 支持多关键字索引 不支持sql语句
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	int_16 buflen = CacKeyv(buf,whereExpress);
	if( buflen != db->IndexTable._idsz1-1 ){
		delete []buf;
		return db->_err = ER_FIELDISNOTEXIST;
	}

	db->IndexTable.ResetBlock(buf);
	delete []buf;
	db->_err = ER_NOERROR;
	return 1;
}

void CRecordSet::Serialize(char* buf,TRecord& record){
	int p=0;
	memset(buf,0,_rdsz1);
	vector<char*>::iterator iter = record._values.begin();
	for(int i=0;iter!=record._values.end();++iter,++i){
		TField field = db->FieldSet[i];
		char* val = (char*)*iter;
		if( field._ft == 0 ){
			strcpy(buf+p,val);
		}else{
			int* t = (int*)(buf+p);
			*t = atoi(val);
		}
		p+=field._fsz;
	}
}

void CRecordSet::Structuralize(char* buf,TRecord& record){
	int p = 0;
	char* tbuf;
	for(int i=0;i<db->FieldSet.Count();++i){
		if( db->FieldSet[i]._ft == FT_INT4 ){
			int* t = (int*)(buf+p);
			char nbuf[20]={0};
			itoa(*t,nbuf,10);
			tbuf = strdup(nbuf);
		}else{
			//此处进行了优化,按实际的字符串长度分配空间,而不是按照字段长度分配.
			char* sbuf = new char[db->FieldSet[i]._fsz+1];
			memset(sbuf,0,db->FieldSet[i]._fsz+1);
			memcpy(sbuf,buf+p,db->FieldSet[i]._fsz);
			tbuf = strdup(sbuf);
			delete []sbuf;
		}
		record._values.push_back(tbuf);
		p += db->FieldSet[i]._fsz;
	}
}

int_16 CRecordSet::CacKeyv(char* keyv,TWHEREEXPRESS whereExpress){
	int_16 bufoff=0;
	for(int i=0;i<db->FieldSet.Count();++i){
		if( db->FieldSet[i]._key != FT_KEY )
			continue;
		TWHEREEXPRESS::iterator iter = whereExpress.begin();
		for(;iter!=whereExpress.end();++iter){
			TWHERE where = *iter;
			if( strcmp(db->FieldSet[i]._fn,where.fn) == 0 ){
				if( db->FieldSet[i]._ft == 	FT_STR ){
					strcpy(keyv+bufoff,where.val);
				}else if( db->FieldSet[i]._ft == FT_INT4){
					int* p = (int*)(keyv+bufoff);
					*p = atoi(where.val);	
				}
				bufoff+=db->FieldSet[i]._fsz;
			}
		}
	}
	return bufoff;
}

int_16 CRecordSet::Update(TWHEREEXPRESS whereExpress,TWHEREEXPRESS valSet){
	
	Select(whereExpress);
	if( Count() == 0 ){
		return db->_err;
	}
	
	char* okey = new char[db->IndexTable._idsz1-1];
	memset(okey,0,db->IndexTable._idsz1-1);
	CacKeyv(okey,whereExpress);
	char* nkey = new char[db->IndexTable._idsz1-1];
	memcpy(nkey,okey,db->IndexTable._idsz1-1);
	
	char* buf =  new char[_rdsz1];
	Serialize(buf,_records[0]);
	
	int p=0;int idp=0;
	for(int i=0;i<db->FieldSet.Count();++i){
		TWHEREEXPRESS::iterator iter = valSet.begin();
		for(;iter!=valSet.end();++iter){
			if( strcmp( db->FieldSet[i]._fn,(*iter).fn) == 0 ){
				break;
			}
		}
		if( iter!= valSet.end()){//修改
			if( db->FieldSet[i]._ft == FT_STR ){
				strcpy(buf+p,(*iter).val);
			}else{
				int* t = (int*)(buf+p);
				*t = atoi((*iter).val);
			}

			if( db->FieldSet[i]._key == FT_KEY ){//修改索引
				if( db->FieldSet[i]._ft == FT_STR ){
					strcpy(nkey+idp,(*iter).val);
				}else{
					int* t = (int*)(nkey+idp);
					*t = atoi((*iter).val);
				}
			}
		}

		if( db->FieldSet[i]._key == FT_KEY){
			idp += db->FieldSet[i]._fsz;
		}

		p+=db->FieldSet[i]._fsz;
	}

//	TRACE("write record \n");
	fseek(db->file,_bp+_records[0]._no*_rdsz1,SEEK_SET);
	fwrite(buf,1,_rdsz1,db->file);
//	TRACE("write record ok\n");

	//Structuralize(buf,_records[0]);
	db->IndexTable.SetBlock(okey,nkey);
	delete []okey;

	delete []buf;

	return db->_err = ER_NOERROR;
}

CIndexTable::CIndexTable(){
	_idsz1	= 1;	//注意:索引下标从1开始
	_bp		= 0;
}

void CIndexTable::Free(){
	map<INDEX,int_16>::iterator iter = _usedit.begin();
	for(;iter!=_usedit.end();++iter){
		delete []iter->first._val;
	}
	_usedit.clear();

	_unusedit.clear();

	_idsz1	= 1;
}

int CIndexTable::GetFrontAvBlock(){
	return _unusedit.front()-1;
}

void CIndexTable::AllocBlock(int i,char* keyv){

	_unusedit.erase(&_unusedit.front());
	
	fseek(db->file,_bp+i*_idsz1,SEEK_SET);	//写占用位
	char buf[1]={1};
	fwrite(buf,1,1,db->file);

	fwrite(keyv,1,_idsz1-1,db->file);		//写索引值

	INDEX index;
	index._val = keyv;
	index._sz = _idsz1-1;
	_usedit[index] = i+1;
}

void CIndexTable::ResetBlock(char* keyv){
	int_32 p = Find(keyv);
	fseek(db->file,_bp+p*_idsz1,SEEK_SET);
	char buf[1]={0};
	fwrite(buf,1,1,db->file);
	
	_unusedit.push_back(p);
	
	INDEX index;
	index._sz = _idsz1-1;
	index._val=new char[_idsz1-1];
	memset(index._val,0,_idsz1-1);
	memcpy(index._val,keyv,_idsz1-1);
	_usedit.erase(index);
	delete []index._val;
}

void CIndexTable::SetBlock(char* okey,char* nkey){
	int_32 idpos = Find(okey);
	INDEX index;
	index._val = okey;
	index._sz = _idsz1-1;
	
//	TRACE("delete index\n");
	char* t=NULL;
	map<INDEX,int_16>::iterator iter = _usedit.find(index);
    if( iter != _usedit.end() ){
		INDEX oindex = iter->first;
		t = oindex._val;
    }
	_usedit.erase(index);
	if( t )
		delete []t;
	
//	TRACE("delete index ok\n");
	fseek(db->file,_bp+idpos*_idsz1+1,SEEK_SET);
	fwrite(nkey,1,_idsz1-1,db->file);
	index._val = nkey;
	index._sz = _idsz1-1;
	_usedit[index] = idpos+1;
//	TRACE("set index ok\n");
}

void CIndexTable::Load(){
	char* buf = new char[_idsz1];
	fseek(db->file,_bp,SEEK_SET);
	INDEX index;
	index._sz = _idsz1-1;
	for(int i=0;i<MAXRECORDCOUNT;++i){
		memset(buf,0,_idsz1);
		fread(buf,1,_idsz1,db->file);
		if( buf[0] == 1){//占用块
			index._val = new char[_idsz1-1];
			memcpy(index._val,buf+1,_idsz1-1);
			_usedit[index] = i+1;//注意,索引下标从1开始,因为在查map的时候,若没有找到返回的是0,所以不能从0开始
		}else{			//空闲块
			_unusedit.push_back(i+1);
		}
	}
	delete []buf;
}

int_16 CIndexTable::Find(char* key){
	int ret = -1;
	INDEX index;
	index._sz = _idsz1-1;
	index._val=new char[_idsz1-1];
	memset(index._val,0,_idsz1-1);
	memcpy(index._val,key,_idsz1-1);
	
	map<INDEX,int_16>::iterator iter = _usedit.find(index);
    if( iter != _usedit.end() )
         ret = (int)(*iter).second - 1;
	//if( _usedit[index] != NULL )
	//	ret = _usedit[index]-1;
	delete []index._val;
	return ret;
}

CFileDB::CFileDB(){
	Head.db			= this;
	FieldSet.db		= this;
	RecordSet.db	= this;
	IndexTable.db	= this;
	_stat			= ST_CLOS;
}

CFileDB::~CFileDB(){
	if( _stat != ST_CLOS ){
		Clos();
	}
}

int_32 CFileDB::Create(char* fn){
	if( _stat != ST_CLOS)
		return _err = ER_ERROR;
	file = fopen(fn,"wb+");
	if( file == NULL ){
		return _err = ER_FILEOPENER;
	}
	this->fn = strdup(fn);
	Head.write();
	FieldSet._bp = 3;
	_stat = ST_CREA;
	return _err = ER_NOERROR;
}

int_32 CFileDB::Open(char* fn){
	if( _stat != ST_CLOS ){
		return _err = ER_DBOPENED;
	}
	file = fopen(fn,"rb+");
	if( file == NULL ){
		return _err = ER_FILEOPENER;
	}
	this->fn = strdup(fn);
	Head.read();
	
	FieldSet._bp = THEADSIZE;
	FieldSet._ct = Head._fc;
	FieldSet.Load();

	IndexTable._bp = FieldSet._bp+FieldSet.Count()*TFIELDSZ;
	IndexTable.Load();
	
	RecordSet._bp = IndexTable._bp+MAXRECORDCOUNT*IndexTable._idsz1;
	RecordSet._act = Head._rc;

	_stat = ST_OPEN;
	return _err = ER_NOERROR;
}

void CFileDB::Clos(){
	if( _stat == ST_CLOS )
		return;
	Head.Free();
	FieldSet.Free();
	RecordSet.Free();
	IndexTable.Free();
	fclose(file);
	//delete []fn;
    free(fn);
	_stat = ST_CLOS;
}

int_32 CFileDB::Commit(){
	if( _stat != ST_OPEN )
		return _err = ER_DBNOTOPEN;
	fclose(file);
	file = fopen(fn,"rb+");
	if( file == NULL )
		return _err = ER_FILEOPENER;
	return _err = ER_NOERROR;
}

int_32 CFileDB::Open(){
	if( _stat != ST_CREA )
		return _err = ER_ERROR;
	if( FieldSet.Count() == 0 ){
		return _err = ER_EMPTYTABLE;
	}
	//创建索引
	IndexTable._bp = FieldSet.Count()*TFIELDSZ+THEADSIZE;	//计算索引表的位置

	int itsz = MAXRECORDCOUNT*IndexTable._idsz1;	
	if( fseek(CFileDB::file,IndexTable._bp,SEEK_SET) != 0 ){
		return _err = ER_FILESEEKER;
	}
	char *buf = new char[itsz];
	memset(buf,0,itsz);
	int r = fwrite(buf,itsz,1,CFileDB::file);
	delete []buf;

	RecordSet._bp = IndexTable._bp + itsz;

	for(int i=0;i<MAXRECORDCOUNT;++i){
		IndexTable._unusedit.push_back(i+1);
	}

	_stat = ST_OPEN;

	return _err = ER_NOERROR;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -