phisicalinfo.cpp at tip Вы: nobody
Вход

File sqlite1c/SQL_DBF/phisicalinfo.cpp from the latest check-in


// phisicalinfo.cpp
#include "StdAfx.h"
#include "phisicalinfo.h"

phisical_info* phisical_info::buildInfo(CTableEx* pTable)
{
	DWORD nFields = pTable->fieldsCount(),
		nIndexes = pTable->indexesCount();	

	struct field_store
	{
		field_info info;
		CString name;
		
		CDWordArray inIndexesPos;
		void markUseInIndex(DWORD iIdx, DWORD iNumInIdx)
		{
			inIndexesPos.Add(MAKELONG(iIdx, iNumInIdx));
		}
	};
	
	struct index_store
	{
		DWORD keySize;
		CDWordArray includedFields;
		void setUseField(DWORD num, DWORD fldNum, DWORD fldSize)
		{
			includedFields[num] = fldNum;
			keySize += fldSize;
		}
	};

	field_store* pFieldStore = new field_store[nFields];
	index_store* pIndexStore = new index_store[nIndexes];

	CNoCaseMap<DWORD> fieldNames;

	//  .
	DWORD recSize = 0;
	for(DWORD i = 0; i<nFields ; i++)
	{
		CField* pField = pTable->field(i);
		pFieldStore[i].name = pField->szName;
		pFieldStore[i].info.l = pField->sizeCField;
		pFieldStore[i].info.p = pField->precCField;
		pFieldStore[i].info.o = pTable->p_1C->fields[i]->offsetInRec - 1;
		if(2 == pField->TypeCField)	// Numeric
			pFieldStore[i].info.t = field_info::ftNumeric;
		else
			pFieldStore[i].info.t = field_info::ftText;
		recSize += pField->sizeCField;
		
		fieldNames[pField->szName] = i;
	}
	//  .
	DWORD needSize = sizeof(phisical_info) - sizeof(field_info) +
		nFields * sizeof(field_info) +	// field_infos
		nFields * sizeof(DWORD) +		// offsets of fld2idx data
		nIndexes * sizeof(index_info**) +
		nIndexes * (sizeof(index_info) - sizeof(idx_field_info));
	int k = 0;
	for(i = 0; i < nIndexes ; i++)
	{
		CIndexEx* pIdx = pTable->index(i);
		DWORD countFields = pIdx->fieldsCount();
		pIndexStore[i].includedFields.SetSize(countFields);
		pIndexStore[i].keySize = 0;

		CStringArray subExpressions;
		SplitStr2Array(pIdx->p_10->szIdxExpr, subExpressions, '+');
		//      
		needSize += sizeof(idx_field_info) * countFields;	//     
		needSize += sizeof(DWORD) * countFields;		//      

		for(DWORD j = 0; j < countFields ; j++)
		{
			CField* pField = pIdx->field(j);
			DWORD fieldNumInTable = fieldNames[pField->szName];

			pIndexStore[i].setUseField(j, fieldNumInTable, pField->sizeCField);
			pFieldStore[fieldNumInTable].markUseInIndex(i, j);
			//    
			if(3 == pFieldStore[fieldNumInTable].info.t)	//  char
				pFieldStore[fieldNumInTable].info.t = field_info::ftText;
			k++;
		}
	}
	
	//    
	phisical_info* pInfo = (phisical_info*)new BYTE[needSize];
	//    
	pInfo->pTableBuf = pTable->recordBuffer();
	pInfo->recSize = recSize;
	pInfo->fldCount = nFields;
	pInfo->idxCount = nIndexes;

	//  field_info   
	for(i = 0; i < nFields; i++)
		pInfo->m_pFields[i] = pFieldStore[i].info;

	//     .
	pInfo->m_pFields2Index = (DWORD*)(pInfo->m_pFields + nFields);
	DWORD* pWrite = pInfo->m_pFields2Index + nFields;
	DWORD offset = pWrite - (DWORD*)pInfo->m_pFields;
	for(i = 0; i < nFields; i++)
	{
		DWORD size = pFieldStore[i].inIndexesPos.GetSize();
		memcpy(pWrite, pFieldStore[i].inIndexesPos.GetData(), size * sizeof(DWORD));
		pInfo->m_pFields2Index[i] = MAKELONG(offset, size);
		offset += size;
		pWrite += size;
	}

	//     
	pInfo->m_ppIndexes = (index_info**)pWrite;
	index_info* pIdxWrite = (index_info*)(pInfo->m_ppIndexes + nIndexes);
	for(i = 0; i < nIndexes; i++)
	{
		pInfo->m_ppIndexes[i] = pIdxWrite;
		int countFields = pIndexStore[i].includedFields.GetSize();
		pIdxWrite->c = countFields;
		pIdxWrite->s = pIndexStore[i].keySize;
		idx_field_info* pField = pIdxWrite->fi;
		for(DWORD j = 0; j < countFields; j++)
		{
			pField->dwNumInTable = pIndexStore[i].includedFields[j];
			pField->fInfo = pFieldStore[pField->dwNumInTable].info;
			pField++;
		}
		pIdxWrite = (index_info*)pField;
	}
	delete [] pIndexStore;
	delete [] pFieldStore;

	return pInfo;
}