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

📄 ljfiledb.cpp

📁 小型文件数据库 一个文件对应一个表 最大只支持65535条记录(可以修改宏) 定长记录 一级索引 支持多关键字索引 不支持sql语句
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "ljfiledb.h"
//#include "afx.h"

using namespace filedbns;

CHead::CHead(){
	_fc = 0;
	_rc = 0;
	db  = NULL;
}

void CHead::Free(){
	_fc = 0;
	_rc = 0;
}

void CHead::attch(THEAD& head){
	_fc = head._fc;
	_rc = head._rc;
}

void CHead::write(){
	fseek(db->file,0,SEEK_SET);
	char buf[3];
	memset(buf,0,3);
	memset(buf,_fc,1);
	int_16 * rc = (int_16*)(buf+1);
	*rc = _rc;
	fwrite(buf,1,3,db->file);
}

void CHead::read(){
	THEAD head;
	memset(&head,0,sizeof(THEAD));
	fseek(db->file,0,SEEK_SET);
	fread(&head,1,3,db->file);
	char* p = (char*)&head;
	int_16* rc = (int_16*)(p+1);
	head._rc = *rc;
	attch(head);
}

CFieldSet::CFieldSet(){
	_ct=0;
}

void CFieldSet::Free(){
	_fields.clear();
}

void CFieldSet::Load(){//Serialize
	TField field;
	for(int i=0;i<_ct;++i){
		memset(&field,0,sizeof(TField));
		fread(&field,1,sizeof(TField),db->file);
		_fields.push_back(field);

		//计算一条索引大小
		if( field._key == 1){
			db->IndexTable._idsz1 += field._fsz;
		}
		
		//计算一条记录的大小
		db->RecordSet._rdsz1+=field._fsz;
	}
}

TField* CFieldSet::Add(char* fn,int_8 fsz,int_8 ft,bool key){
	
	if( db->_stat != ST_CREA)	return NULL;

	TField field;
	memset(field._fn,0,FIELDNAMESZ);
	strcpy(field._fn,fn);
	field._fsz = fsz;
	field._ft = ft;
	field._key = key?1:0;
	field._no = _fields.size();
	if( Write(field) != ER_NOERROR ){
		return NULL;
	}
	_ct++;
	_fields.push_back(field);

	//计算一条索引大小
	if( field._key == 1)
		db->IndexTable._idsz1 += field._fsz;
	//计算一条记录的大小
	db->RecordSet._rdsz1+=field._fsz;

	return &_fields[field._no];
}

int_32 CFieldSet::Write(TField& field){
	if( fseek(db->file,_bp+(field._no*TFIELDSZ),SEEK_SET) !=0 ){
		return ER_FILESEEKER;
	}
	
	char buf[TFIELDSZ];
	memset(buf,0,TFIELDSZ);
	memset(buf,field._no,sizeof(int_8));
	strcpy(buf+sizeof(int_8),field._fn);
	memset(buf+33,field._fsz,sizeof(int_8));
	memset(buf+34,field._ft,sizeof(int_8));
	memset(buf+35,field._key,sizeof(int_8));
	int r = fwrite(buf,1,36,db->file);
	if( r != TFIELDSZ )
		return ER_FILEWRITEER;

	//写文件头
	db->Head._fc++;
	db->Head.write();
	
	return ER_NOERROR;
}

TField* CFieldSet::Fnd(string fn){
	vector<TField>::iterator iter = _fields.begin();
	for(;iter!=_fields.end();++iter){
		if( (*iter)._fn==fn)
			return &(*iter);
	}
	return NULL;
}

TField& CFieldSet::operator[](int i){
	return _fields[i];
}

CRecordSet::CRecordSet(){
	_bp = 0;
	_rdsz1 = 0;
}

void CRecordSet::Free(){
	FreeRecords();
	_bp = 0;
	_rdsz1 = 0;
}

void CRecordSet::FreeRecords(){
	//释放记录集内存
	vector<TRecord>::iterator iter = _records.begin();
	for(;iter!=_records.end();++iter){
		TRecord record = (TRecord)(*iter);
		vector<char*>::iterator iterval = record._values.begin();
		for(;iterval!=record._values.end();++iterval){
			//delete [](*iterval);
            free(*iterval);
        }
		record._values.clear();
	}
	_records.clear();
}

TRecord& CRecordSet::operator[](int i){
	return _records[i];
}

TRecord* CRecordSet::Insert(char* val,...){
	db->_err = ER_NOERROR;
	if( db->_stat != ST_OPEN ){
		db->_err = ER_DBNOTOPEN;
		return NULL;
	}

	FreeRecords();

	TRecord record;
	char* newv;

	va_list vl;
	char *p = val;
	va_start(vl,val);
	while(p) {
		newv = strdup(p);
        record._values.push_back(newv);
		p = va_arg(vl,char *);
	}
	va_end(vl);
	record._no = _records.size();
	if( Write(record) == ER_NOERROR){
		_records.push_back(record);
		return &_records[record._no];
	}
	return NULL;
}

int_32 CRecordSet::Write(TRecord& record){
	db->_err = ER_NOERROR;
	char* buf = new char[_rdsz1];
	memset(buf,0,_rdsz1);

	char* idbuf = new char[db->IndexTable._idsz1-1];
	memset(idbuf,0,db->IndexTable._idsz1-1);

	int prc=0;
	int pid=0;

	for(int i=0;i<db->FieldSet.Count();++i){
		TField field = db->FieldSet[i];
		char*  val = record._values[i];
		if( field._ft == 0){//字符串
			strcpy(buf+prc,val);
			if( field._key == 1){//索引
				strcpy(idbuf+pid,val);
				pid+=field._fsz;
			}
		}else if( field._ft == 1){//4字节整数
			int* p = (int*)(buf+prc);
			*p = atoi(val);
			//*(buf+prc) = atoi(val);
			if( field._key == 1){//索引
				*(idbuf+pid) = atoi(val);
				pid+=field._fsz;
			}
		}
		prc += field._fsz;
	}
	if( db->IndexTable.Find(idbuf) != -1 ){
		return db->_err = ER_KEYCONFICT;
	}
	//登记索引,查找到索引位置后,便可以算出文件位置
	//公式:索引序号*记录长度+记录开始位置
	//从空闲块中取出第一块
	int it = db->IndexTable.GetFrontAvBlock();
	int pos = it*_rdsz1+_bp;
	fseek(db->file,pos,SEEK_SET);
	fwrite(buf,1,_rdsz1,db->file);
	delete []buf;

	//登记索引
	db->IndexTable.AllocBlock(it,idbuf);

	db->Head._rc++;
	db->Head.write();
	return ER_NOERROR;
}

int_16 CRecordSet::Select(TWHEREEXPRESS whereExpress){
	db->_err = ER_NOERROR;

	if( db->_stat != ST_OPEN )
		return db->_err = ER_DBNOTOPEN;
	
	FreeRecords();
	
	char* buf = new char[db->IndexTable._idsz1-1];
	memset(buf,0,db->IndexTable._idsz1-1);
	/*int 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(buf+bufoff,where.val);
				}else if( db->FieldSet[i]._ft == FT_INT4){
					int* p = (int*)(buf+bufoff);
					*p = atoi(where.val);	
				}
				bufoff+=db->FieldSet[i]._fsz;
			}
		}
	}*/

	int buflen = CacKeyv(buf,whereExpress);
	if( buflen != db->IndexTable._idsz1-1 ){
		delete []buf;
		return db->_err = ER_FIELDISNOTEXIST;
	}
	
	int_32 p = db->IndexTable.Find(buf);
	if( p == -1 ){
		delete []buf;
		return db->_err = ER_NORECORD;
	}
	delete []buf;

	//计算位置
	fseek(db->file,_bp+p*_rdsz1,SEEK_SET);
	char* rbuf = new char[_rdsz1];
	memset(rbuf,0,_rdsz1);
	fread(rbuf,1,_rdsz1,db->file);
	TRecord record;
	Structuralize(rbuf,record);
	delete []rbuf;
	record._no = p;
	_records.push_back(record);
	return 1;


}

int_16 CRecordSet::Select(){
	db->_err = ER_NOERROR;
	if( db->_stat != ST_OPEN )
		return db->_err = ER_DBNOTOPEN;
	FreeRecords();
	
	char* buf = new char[_rdsz1];
	map<INDEX,int_16>::iterator iter = db->IndexTable._usedit.begin();
	for(;iter!=db->IndexTable._usedit.end();++iter){
		memset(buf,0,_rdsz1);
		int_16 p = iter->second;
		p--;
		fseek(db->file,_bp+p*_rdsz1,SEEK_SET);
		fread(buf,1,_rdsz1,db->file);
		TRecord record;
		Structuralize(buf,record);
		record._no = p;
		_records.push_back(record);
	}
	delete []buf;
	return Count();
}

int_16 CRecordSet::Delete(TWHEREEXPRESS whereExpress){
	if( db->_stat != ST_OPEN )
		return db->_err = ER_DBNOTOPEN;
	
	FreeRecords();
	
	/*char* buf = new char[db->IndexTable._idsz1-1];
	memset(buf,0,db->IndexTable._idsz1-1);
	TField* field=NULL;
	TWHERE where;
	TWHEREEXPRESS::iterator iter = whereExpress.begin();
	for(;iter!=whereExpress.end();++iter){
		where = *iter;
		field = db->FieldSet.Fnd(where.fn);
		if( field == NULL )
			continue;
		if( field->_key != 1 ){
			delete []buf;
			return db->_err = ER_NONKEYINDEX;
		}else{
			break;
		}
	}
	if( iter == whereExpress.end() ){
		delete []buf;
		return db->_err = ER_FIELDISNOTEXIST;
	}

	if( field->_ft == FT_STR )
		strcpy(buf,where.val);
	else if( field->_ft == FT_INT4){
		int* p = (int*)buf;
		*p = atoi(where.val);
	}*/

	char* buf = new char[db->IndexTable._idsz1-1];
	memset(buf,0,db->IndexTable._idsz1-1);

⌨️ 快捷键说明

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