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

📄 class.cpp

📁 一个功能强大的内存数据库源代码,c++编写,有详细的注释
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    return offs;}void dbTableDescriptor::checkRelationship() {    dbFieldDescriptor* fd;    for (fd = inverseFields; fd != NULL; fd = fd->nextInverseField) { 	dbTableDescriptor* refTable = 	    fd->refTable ? fd->refTable : fd->components->refTable;	fd->inverseRef = refTable->findSymbol(fd->inverseRefName);	assert(fd->inverseRef != NULL 	       && fd->inverseRef->inverseRefName == fd->name);    }}dbFieldDescriptor* dbTableDescriptor::find(char const* name){    char* symnam = (char*)name;    dbSymbolTable::add(symnam, tkn_ident);    return findSymbol(symnam);}dbFieldDescriptor* dbTableDescriptor::findSymbol(const char* name){    dbFieldDescriptor* first = columns;    dbFieldDescriptor* field = first;    do { 	if (field->name == name) { 	    return field;	}    } while ((field = field->next) != first);    return NULL;}dbFieldDescriptor& dbFieldDescriptor::adjustOffsets(long offs){    if (offs != 0) { 	dbFieldDescriptor* fd = this;	do { 	    fd->appOffs += offs;	} while ((fd = fd->next) != this);    }    return *this;}bool dbTableDescriptor::match(dbTable* table, bool confirmDeleteColumns) {    unsigned nFields = table->fields.size;    unsigned nMatches = 0;    bool formatNotChanged = (nFields == this->nFields);    for (dbFieldDescriptor* fd = firstField; fd != NULL; fd = fd->nextField) { 	dbField* field = (dbField*)((char*)table + table->fields.offs);	fd->oldDbsType = dbField::tpUnknown;	for (int n = nFields; --n >= 0; field++) { 	    if (strcmp(fd->longName, (char*)field + field->name.offs) == 0) {		assert(((void)"field can be converted to new format",			(fd->type == dbField::tpReference			 && field->type == dbField::tpReference			 && strcmp((char*)field + field->tableName.offs,				      fd->refTable->name) == 0)			|| (fd->type <= dbField::tpReal8 			    && field->type <= dbField::tpReal8)			|| (fd->type == dbField::tpString			    && field->type == dbField::tpString)			|| (fd->type >= dbField::tpArray			    && fd->type == field->type)));		fd->oldDbsType = field->type;		fd->oldDbsOffs = field->offset;		fd->oldDbsSize = field->size;		if (field->type != fd->type || field->offset != fd->dbsOffs) {		    formatNotChanged = false;		}		nMatches += 1;		//		// Try to reuse indices		//		fd->hashTable = 0;		fd->tTree = 0;		if (field->type == fd->type) { 		    if ((fd->indexType & HASHED) != 0 && field->hashTable != 0) { 			fd->hashTable = field->hashTable; // reuse index			field->hashTable = 0; // prevent index from destruction		    }		    if ((fd->indexType & INDEXED) != 0 && field->tTree != 0) { 			fd->tTree = field->tTree; // reuse index			field->tTree = 0; // prevent index from destruction		    }		}		break;	    }	}    }    if (!confirmDeleteColumns) {                     assert(((void)"field can be removed only from empty table",                nFields==nMatches));    }    return formatNotChanged;}void dbTableDescriptor::setFlags() {     for (dbFieldDescriptor* fd = firstField; fd != NULL; fd = fd->nextField) {	if (fd->tTree != 0) { 	    fd->indexType |= INDEXED;	} else if (fd->hashTable != 0) { 	    fd->indexType |= HASHED;	}    }}bool dbTableDescriptor::equal(dbTable* table) {#ifdef AUTOINCREMENT_SUPPORT    autoincrementCount = table->count;#endif    if (nColumns != table->nColumns || 	nFields != table->fields.size || fixedSize != table->fixedSize)     { 	return false;    }    dbField* field = (dbField*)((char*)table + table->fields.offs);    for (dbFieldDescriptor* fd = firstField; fd != NULL; fd = fd->nextField) { 	if (strcmp(fd->longName, (char*)field + field->name.offs) != 0 	    || (!fd->refTable && *((char*)field+field->tableName.offs) != '\0')	    || (fd->refTable && strcmp((char*)field + field->tableName.offs,				       fd->refTable->name) != 0)	    || (fd->inverseRefName == NULL 		&& *((char*)field + field->inverse.offs) != '\0')	    || (fd->inverseRefName != NULL		&& strcmp((char*)field + field->inverse.offs,			  fd->inverseRefName) != 0)	    || fd->dbsOffs != field->offset	    || fd->type != field->type)	{	    return false;	}	fd->tTree = field->tTree;	fd->hashTable = field->hashTable;	field += 1;    }    return true;}dbTableDescriptor::dbTableDescriptor(dbTable* table){    next = chain;    chain = this;    cloneOf = NULL;    isStatic = false;    name = (char*)table + table->name.offs;    dbSymbolTable::add(name, tkn_ident, true);    nextFieldLink = &firstField;    hashedFields = NULL;    indexedFields = NULL;    inverseFields = NULL;    nFields = 0;    nColumns = 0;    fixedSize = table->fixedSize;    int attr = 0;    appSize = 0;    columns = buildFieldsList(table, "", 0, attr);    *nextFieldLink = NULL;    db = NULL;    tableId = 0;#ifdef AUTOINCREMENT_SUPPORT    autoincrementCount = table->count;#endif}class _AlignArray : public dbAnyArray{  protected:    void*  data;    size_t allocated;};class _AlignReference{  protected:    oid_t       oid;};union _aligns {	struct { char n; bool v; } _abool;	struct { char n; int1 v; } _aint1;	struct { char n; int2 v; } _aint2;	struct { char n; int4 v; } _aint4;	struct { char n; db_int8 v; } _aint8;	struct { char n; real4 v; } _areal4;	struct { char n; real8 v; } _areal8;	struct { char n; char *v; } _astring;	struct { char n; char v[1]; } _arawbinary;	struct { char n; _AlignReference v; } _areference;	struct { char n; _AlignArray v; } _aarray;} __aligns;#define COMPUTE_ALIGNED_SIZE(type) \	(((char *)&(((union _aligns *)0)->_a##type.v)) - ((char *)&(((union _aligns *)0)->_a##type.n)))dbFieldDescriptor* dbTableDescriptor::buildFieldsList(dbTable*    table, 						      char const* prefix,						      int         prefixLen,						      int&        attr){    dbFieldDescriptor* components = NULL;    dbField* field = (dbField*)((char*)table+table->fields.offs) + nFields;	    while (nFields < table->fields.size	   && strncmp((char*)field + field->name.offs, prefix, prefixLen) == 0)    {	char* longName = (char*)field + field->name.offs;	char* name = longName + prefixLen;	if (*name == '.') { 	    name += 1;	} else if (prefixLen != 0 && *name != '[') { 	    break;	}	dbSymbolTable::add(name, tkn_ident, true);		dbFieldDescriptor* fd = new dbFieldDescriptor(name);	fd->dbsOffs = field->offset;	fd->alignment = fd->dbsSize = field->size;	fd->longName = new char[strlen(longName)+1];	strcpy(fd->longName, longName);	fd->type = fd->appType = field->type;	int appFieldSize, appAlignedFieldSize;	 	switch (field->type) {	  case dbField::tpBool:	    appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(bool);	    appFieldSize = sizeof(bool);	    break;          case dbField::tpInt1:	    appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int1);	    appFieldSize = sizeof(int1);	    break;	  case dbField::tpInt2:	    appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int2);	    appFieldSize = sizeof(int2);	    break; 	  case dbField::tpInt4:	    appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int4);	    appFieldSize = sizeof(int4);	    break;	  case dbField::tpInt8:	    appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int8);	    appFieldSize = sizeof(db_int8);	    break;	  case dbField::tpReal4:	    appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(real4);	    appFieldSize = sizeof(real4);	    break;	  case dbField::tpReal8:	    appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(real8);	    appFieldSize = sizeof(real8);	    break;	  case dbField::tpString:	    appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(string);	    appFieldSize = sizeof(char *);	    break;	  case dbField::tpRawBinary:	    appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(rawbinary);	    appFieldSize = field->size;	    break;	  case dbField::tpReference:	    appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(reference);	    appFieldSize = sizeof(dbAnyReference);	    break;	  case dbField::tpArray:	    appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(array);	    appFieldSize = sizeof(_AlignArray);	    break;	  default:	    appAlignedFieldSize = 1;	    appFieldSize = 0;	}	fd->appOffs = appSize = DOALIGN(appSize, appAlignedFieldSize);	appSize += fd->appSize = appFieldSize;	if ((fd->hashTable = field->hashTable) != 0) { 	    fd->nextHashedField = hashedFields;	    hashedFields = fd;	}	if ((fd->tTree = field->tTree) != 0) { 	    fd->nextIndexedField = indexedFields;	    indexedFields = fd;	}	fd->fieldNo = nFields++;	fd->defTable = this;	fd->refTable = NULL;	fd->refTableName = NULL;	if (field->hashTable != 0) { 	    fd->indexType |= HASHED;	}	if (field->tTree != 0) { 	    fd->indexType |= INDEXED;	}	if (field->tableName.size > 1) { 	    fd->refTableName = (char*)field + field->tableName.offs;	    dbSymbolTable::add(fd->refTableName, tkn_ident, true);		}	fd->inverseRefName = NULL;	if (field->inverse.size > 1) { 	    fd->nextInverseField = inverseFields;	    inverseFields = fd; 	    	    fd->inverseRefName = (char*)field + field->inverse.offs;	    dbSymbolTable::add(fd->inverseRefName, tkn_ident, true);		}	fd->attr = (attr & dbFieldDescriptor::ComponentOfArray) | dbFieldDescriptor::OneToOneMapping;	*nextFieldLink = fd;	nextFieldLink = &fd->nextField;	if (prefixLen == 0) { 	    nColumns += 1;	}	if (components == NULL) { 	    components = fd;	} else { 	    fd->next = components;	    fd->prev = components->prev;	    components->prev->next = fd;	    components->prev = fd;	}	if (fd->type == dbField::tpArray || fd->type == dbField::tpString) { 	    attr |= dbFieldDescriptor::HasArrayComponents;	    fd->attr |= dbFieldDescriptor::ComponentOfArray;	    fd->alignment = 4;	}	if (fd->type == dbField::tpArray || fd->type == dbField::tpStructure) {	    int saveAppSize = appSize;	    if (fd->type == dbField::tpArray) { 		appSize = 0;	    }	    fd->components = 		buildFieldsList(table, longName, strlen(longName), fd->attr);	    if (fd->type == dbField::tpArray) { 		appSize = saveAppSize;	    }	    attr |= fd->attr & dbFieldDescriptor::HasArrayComponents;	    field = (dbField*)((char*)table + table->fields.offs) + nFields;	    if (fd->type == dbField::tpStructure) {		size_t alignment = 1;		dbFieldDescriptor* component = fd->components;		do { 		    if (component->alignment > alignment) { 			alignment = component->alignment;		    }		} while ((component = component->next) != fd->components);		fd->alignment = alignment;	    } else { 		if (fd->components->type == dbField::tpString) { 		    fd->arrayAllocator = &dbArray<char*>::arrayAllocator;		    fd->attr &= ~dbFieldDescriptor::OneToOneMapping;		} else { 		    fd->arrayAllocator = &dbAnyArray::arrayAllocator;		}	    }	} else { 	    if (fd->type == dbField::tpString) { 		fd->components = new dbFieldDescriptor("[]");		fd->components->type = fd->components->appType = dbField::tpInt1;		fd->components->dbsSize = fd->components->appSize = 1;		fd->components->alignment = 1; 	    }	    field += 1;	}    }    return components;}size_t dbTableDescriptor::totalNamesLength(){    dbFieldDescriptor* fd;    size_t len = strlen(name) + 1;    for (fd = firstField; fd != NULL; fd = fd->nextField) { 	if (fd->name != NULL) { 	    len += strlen(fd->longName) + 3;	    if (fd->inverseRefName != NULL) { 		len += strlen(fd->inverseRefName);	    }	    if (fd->refTable != NULL) { 		len += strlen(fd->refTable->name);	    }	}    }    return len;}dbTableDescriptor* dbTableDescriptor::clone() {    return new dbTableDescriptor(name,				 DETACHED_TABLE,				 appSize,				 describeComponentsFunc,				 this);}dbTableDescriptor::~dbTableDescriptor(){    if (cloneOf == NULL) {	 dbTableDescriptor **tpp; 	 for (tpp = &chain; *tpp != this; tpp = &(*tpp)->next);	 *tpp = next;    }    dbFieldDescriptor *field, *nextField;    for (field = firstField; field != NULL; field = nextField) { 	nextField = field->nextField;	delete field;    }}void dbTableDescriptor::cleanup(){    dbTableDescriptor* next, *desc;    for (desc = chain; desc != NULL; desc = next) { 	next = desc->next; 	if (!desc->isStatic) { 	    delete desc;	}    }}void dbTableDescriptor::storeInDatabase(dbTable* table){    int offs = sizeof(dbTable) + sizeof(dbField)*nFields;    table->name.offs = offs;    table->name.size = strlen(name)+1;    strcpy((char*)table + offs, name);    offs += table->name.size;    table->fields.offs = sizeof(dbTable);    table->fields.size = nFields;    table->nRows = 0;    table->nColumns = nColumns;    table->fixedSize = fixedSize;    table->firstRow = 0;    table->lastRow = 0;#ifdef AUTOINCREMENT_SUPPORT    table->count = autoincrementCount;#endif    dbFieldDescriptor* fd;    dbField* field = (dbField*)((char*)table + table->fields.offs);    offs -= sizeof(dbTable);    for (fd = firstField; fd != NULL; fd = fd->nextField) { 	field->name.offs = offs;	field->name.size = strlen(fd->longName) + 1;	strcpy((char*)field + offs, fd->longName);	offs += field->name.size;	field->tableName.offs = offs;	if (fd->refTable != NULL) { 	    field->tableName.size = strlen(fd->refTable->name) + 1;	    strcpy((char*)field + offs, fd->refTable->name);	} else { 	    field->tableName.size = 1;	    *((char*)field + offs) = '\0';	}	offs += field->tableName.size;		field->inverse.offs = offs;	if (fd->inverseRefName != NULL) { 	    field->inverse.size = strlen(fd->inverseRefName) + 1;	    strcpy((char*)field + offs, fd->inverseRefName);	} else { 	    field->inverse.size = 1;	    *((char*)field + offs) = '\0';	}	offs += field->inverse.size;		field->tTree = fd->tTree;	field->hashTable = fd->hashTable;	field->type = fd->type;	field->size = fd->dbsSize;	field->offset = fd->dbsOffs;	field += 1;	offs -= sizeof(dbField);    }}	dbAnyMethodTrampoline::~dbAnyMethodTrampoline() {}

⌨️ 快捷键说明

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