コード例 #1
0
VError DB4DJournalParser::NextOperation( uLONG8 &outOperation, uLONG8 *outGlobalOperation, CDB4DJournalData **outJournalData )
{
	VError error = VE_OK;
	RecordHeader recHeader;
	
	if ( outJournalData )
		*outJournalData = NULL;

	outOperation = fCurrentOperation;
	sLONG8 globaloperation = 0;
	
	if ( fFileStream )
	{
		uLONG operationTag;
		error = fFileStream->GetLong(operationTag);
		if ( error == VE_OK )
		{
			if ( operationTag == kTagLogDB4D )
			{
				sLONG8 contextID;
				DB4D_LogAction logAction;
				sLONG len;
				sLONG8 curpos;
				error = fFileStream->GetLong8(globaloperation);

				if ( error == VE_OK )
				{
					error = fFileStream->GetLong(len);
				}

				if ( !outJournalData )
				{
					error = fFileStream->SetPosByOffset( len - 24 );//- 4 /*Tag*/ - 8 /*Operation#*/- 4 /*len*/ - 4 /*len at the end*/ - 4 /*tag at the end*/
				}
				else
				{

				if ( error == VE_OK )
					error = fFileStream->GetLong((uLONG&)logAction);

				if ( error == VE_OK )
					error = fFileStream->GetLong8(contextID);

				uLONG8 timeStamp;
				if (error == VE_OK)
					error = fFileStream->GetLong8(timeStamp);


				if (error == VE_OK)
				{
					switch (logAction)
					{
						case DB4D_Log_OpenData:
						case DB4D_Log_CloseData:
						case DB4D_Log_StartBackup:
						case DB4D_Log_StartTrans:
						case DB4D_Log_Commit:
						case DB4D_Log_RollBack:
							{
								*outJournalData = new VDB4DJournalData(globaloperation, logAction,contextID, GetContextExtraData( contextID),timeStamp);
							}
							break;

						case DB4D_Log_CloseContext:
							{
								*outJournalData = new VDB4DJournalData(globaloperation, logAction,contextID, GetContextExtraData( contextID),timeStamp);
								fContextExtraByID.erase(contextID);
							}
							break;

						case DB4D_Log_CreateRecord:
						case DB4D_Log_ModifyRecord:
							{
								VUUID xTableID;
								if ( error == VE_OK )
									error = recHeader.ReadFromStream(fFileStream);
								
								if ( error == VE_OK )
									if ( !recHeader.Match(DBOH_Record) )
										error = VE_DB4D_WRONGRECORDHEADER;
								
								if ( error == VE_OK )
									error = xTableID.ReadFromStream(fFileStream);

								curpos = fFileStream->GetPos();
								if ( error == VE_OK )
								{
									sLONG dataSize = recHeader.GetLen() + sizeof(ChampHeader)*(recHeader.GetNbFields());
									error = fFileStream->SetPosByOffset(dataSize);
								}
								if ( error == VE_OK )
									*outJournalData = new VDB4DJournalData(globaloperation, logAction,contextID, GetContextExtraData( contextID),&recHeader,timeStamp, curpos, fFileStream, xTableID);
							}
							break;

						case DB4D_Log_DeleteBlob:
							{
								VString path;
								sLONG blobnumber;
								if ( error == VE_OK )
									error = fFileStream->GetLong(blobnumber);

								if (blobnumber == -2)
								{
									sLONG lenpath = 0;
									error = fFileStream->GetLong(lenpath);
									if (lenpath > 0)
									{
										tempBuffer<256> buff(len);
										error = fFileStream->GetWords((sWORD*)buff.GetPtr(), &lenpath);
										path.FromBlock(buff.GetPtr(), lenpath * sizeof(UniChar), VTC_UTF_16);
									}
								}
								
								VUUID xTableID;
								if ( error == VE_OK )
									error = xTableID.ReadFromStream(fFileStream);

								if ( error == VE_OK )
								{
									VDB4DJournalData* jdata = new VDB4DJournalData(globaloperation, logAction,contextID, GetContextExtraData( contextID),timeStamp, blobnumber ,xTableID);
									*outJournalData = jdata;
									if (!path.IsEmpty())
									{
										jdata->SetPath(path);
									}
								}
							}
							break;

						case DB4D_Log_DeleteRecord:
						case DB4D_Log_TruncateTable:
							{
								sLONG recordNumber;
								if ( error == VE_OK )
									error = fFileStream->GetLong(recordNumber);
								/*
								sLONG tableIndex;
								if ( error == VE_OK )
									error = fFileStream->GetLong(tableIndex);
								*/
								VUUID xTableID;
								if ( error == VE_OK )
									error = xTableID.ReadFromStream(fFileStream);

								if ( error == VE_OK )
									*outJournalData = new VDB4DJournalData(globaloperation, logAction,contextID, GetContextExtraData( contextID),timeStamp,recordNumber,xTableID);
							}
							break;

						case DB4D_Log_CreateContextWithUserUUID:
							{
								VUUID userID;
								error = userID.ReadFromStream(fFileStream);
								if (error == VE_OK)
									*outJournalData = new VDB4DJournalData(globaloperation, logAction,contextID, GetContextExtraData( contextID),timeStamp,userID);
							}
							break;
						
						case DB4D_Log_CreateContextWithExtra:
							{
								VValueBag *bag = new VValueBag;
								if (bag != NULL)
								{
									// the extra data is always stored in little endian
									Boolean oldNeedSwap = fFileStream->NeedSwap();
									fFileStream->SetLittleEndian();
									error = bag->ReadFromStream(fFileStream);
									fFileStream->SetNeedSwap( oldNeedSwap);
									
									if (error == VE_OK)
									{
										try
										{
											fContextExtraByID[contextID] = bag;
										}
										catch(...)
										{
										}
										*outJournalData = new VDB4DJournalData(globaloperation, logAction,contextID, GetContextExtraData( contextID),timeStamp);
									}
								}
								else
								{
									error = memfull;
								}
								ReleaseRefCountable( &bag);
							}
							break;

						case DB4D_Log_CreateBlob:
						case DB4D_Log_ModifyBlob:
							{
								VString path;

								sLONG lenblob = 0;
								sLONG blobNumber;
								if ( error == VE_OK )
									error = fFileStream->GetLong(blobNumber);

								if (blobNumber == -2)
								{
									sLONG lenpath = 0;
									error = fFileStream->GetLong(lenpath);
									if (lenpath > 0)
									{
										tempBuffer<256> buff(len);
										error = fFileStream->GetWords((sWORD*)buff.GetPtr(), &lenpath);
										path.FromBlock(buff.GetPtr(), lenpath * sizeof(UniChar), VTC_UTF_16);
									}
								}


								VUUID xTableID;
								if ( error == VE_OK )
									error = xTableID.ReadFromStream(fFileStream);

								curpos = fFileStream->GetPos();
								if ( error == VE_OK )
								{
									error = fFileStream->GetLong(lenblob);
									error = fFileStream->SetPosByOffset(lenblob);
								}
								if ( error == VE_OK )
								{
									VDB4DJournalData* jdata = new VDB4DJournalData(globaloperation, logAction,contextID, GetContextExtraData( contextID),timeStamp, blobNumber, lenblob, xTableID, curpos, fFileStream);
									*outJournalData = jdata;
									if (!path.IsEmpty())
									{
										jdata->SetPath(path);
									}
								}
							}
							break;

						case DB4D_Log_SaveSeqNum:
							{
								sLONG8 seqnum;
								if ( error == VE_OK )
									error = fFileStream->GetLong8(seqnum);
								/*
								sLONG tableIndex;
								if ( error == VE_OK )
								error = fFileStream->GetLong(tableIndex);
								*/
								VUUID xTableID;
								if ( error == VE_OK )
									error = xTableID.ReadFromStream(fFileStream);

								if ( error == VE_OK )
									*outJournalData = new VDB4DJournalData(globaloperation, logAction,contextID, GetContextExtraData( contextID), timeStamp, seqnum, xTableID, true);
							}
							break;

						default:
							assert(false);
							break;
					}
				}
				}
				sLONG lenEnd;
				if ( error == VE_OK )
				{
					error = fFileStream->GetLong(lenEnd);
					if (len != lenEnd)
						error = VE_UNIMPLEMENTED;
				}

				uLONG operationTagEnd;
				if (error == VE_OK)
				{
					error = fFileStream->GetLong((uLONG&)operationTagEnd);
					if (operationTagEnd != kTagLogDB4DEnd)
						error = VE_UNIMPLEMENTED;
				}
			}
			else
			{
				error = VE_UNIMPLEMENTED; // bad file
			}

			if ( error != VE_OK )
			{
				if ( outJournalData && *outJournalData )
				{
					(*outJournalData)->Release();
					*outJournalData = NULL;
				}
			}
			else
			{
				outOperation = ++fCurrentOperation;
				if ( outJournalData && *outJournalData )
				{
					if ( fCurrentData )
						fCurrentData->Release();
					fCurrentData = *outJournalData;
					fCurrentData->Retain();
				}
			}
		}
	}
	else
	{
		error = VE_UNIMPLEMENTED; // not initialized
	}

	if (outGlobalOperation != NULL)
		*outGlobalOperation = globaloperation;
	
	return error;
}