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

📄 class.cpp

📁 fastdb-241源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			offsElem -= sizeElem;
			dstElem += sizeElem;
			srcElem += sizeElem;
		    }
		    offs += offsElem;
		} else { 
		    memcpy(dstElem, srcElem, offsElem);
		} 
	    } else if (fd->attr & HasArrayComponents) { 
		offs = fd->components->copyRecordExceptOneField(field, dst, 
								src, offs);
	    } else {
		memcpy(dst+fd->dbsOffs, src+fd->dbsOffs, fd->dbsSize);
	    }
	}
    } while ((fd = fd->next) != this);

    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->find(fd->inverseRefName);
	assert(fd->inverseRef != NULL 
	       && fd->inverseRef->inverseRefName == fd->name);
    }
}

dbFieldDescriptor* dbTableDescriptor::find(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) 
{
    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;
	    }
	}
    }
    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; 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(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->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;

	*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) {
	    fd->components = 
		buildFieldsList(table, longName, strlen(longName), fd->attr);
	    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->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 + -