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

📄 kbmmembinarystreamformat.pas

📁 kbmMemTable v5.50 (Dec. 12 2005)内存表控件
💻 PAS
📖 第 1 页 / 共 3 页
字号:
          // Count number of fields actually saved.
          j:=0;
          for i:=0 to nf-1 do
              if SaveFields[i]>=0 then inc(j);

          // Start writing header.
          Writer.WriteListBegin;
          Writer.WriteInteger(j);
          for i:=0 to nf-1 do
          begin
               if SaveFields[i]>=0 then
                  Writer.WriteInteger(ord(ADataSet.Fields[i].DataType));
          end;
          Writer.WriteListEnd;
     end;

     // Write all records
     ADataSet.SaveCount := 0;
     ADataSet.SavedCompletely:=true;
     Writer.WriteListBegin;

     // Check if to write according to current index or not.
     UsingIndex:=sfSaveUsingIndex in FUsingIndex;
     if UsingIndex then
        cnt:=ADataSet.CurIndex.References.Count
     else
         cnt:=TkbmProtCommon(ADataSet.Common).FRecords.Count;

     for j:=0 to cnt-1 do
     begin
          // Check if to save more.
          if (ADataSet.SaveLimit>0) and (ADataSet.SaveCount>=ADataSet.SaveLimit) then
          begin
               ADataSet.SavedCompletely:=false;
               break;
          end;

          // Check if to invoke progress event if any.
          if (j mod 100)=0 then ADataSet.Progress(trunc((j/cnt)*100),mtpcSave);

          // Setup which record to look at.
          if UsingIndex then
             ADataSet.OverrideActiveRecordBuffer:=PkbmRecord(ADataSet.CurIndex.References.Items[j])
          else
             ADataSet.OverrideActiveRecordBuffer:=PkbmRecord(TkbmProtCommon(ADataSet.Common).FRecords.Items[j]);
          if (ADataSet.OverrideActiveRecordBuffer=nil) then continue;

          // Calculate fields.
          ADataSet.__ClearCalcFields({$IFNDEF DOTNET}PChar(ADataSet.OverrideActiveRecordBuffer){$ELSE}ADataSet.OverrideActiveRecordBuffer{$ENDIF});
          ADataSet.__GetCalcFields({$IFNDEF DOTNET}PChar(ADataSet.OverrideActiveRecordBuffer){$ELSE}ADataSet.OverrideActiveRecordBuffer{$ENDIF});

          // Check filter of record.
          Accept:=ADataSet.FilterRecord(ADataSet.OverrideActiveRecordBuffer,false);
          if not Accept then continue;

          // Check accept of saving this record.
          Accept:=true;
          if Assigned(ADataSet.OnSaveRecord) then ADataSet.OnSaveRecord(ADataset,Accept);
          if not Accept then continue;

          // Write current record.
          NewestVersion:=true;
{$IFNDEF BINARY_FILE_1XX_COMPATIBILITY}
 {$IFNDEF BINARY_FILE_200_COMPATIBILITY}
          // New for v. 2.24.

  {$IFDEF DOTNET}
          ARec := TKbmRecord (Marshal.PtrToStructure(ADataSet.OverrideActiveRecordBuffer,TypeOf(TKbmRecord) ));

          if (not (sfSaveData in sfData)) and (ARec.UpdateStatus=usUnmodified) then continue;

          // New for v. 2.30b
          if (not (sfSaveDontFilterDeltas in sfDontFilterDeltas)) and (ARec.UpdateStatus=usDeleted) then
          begin
               // Make sure record has not been inserted and deleted again.
               pRec:=ARec.PrevRecordVersion;
               Rec := TKbmRecord (Marshal.PtrToStructure(pRec,TypeOf(TKbmRecord)));
               while Rec.PrevRecordVersion<>nil do
               begin
                  pRec:=Rec.PrevRecordVersion;
                  Rec := TKbmRecord (Marshal.PtrToStructure(pRec,TypeOf(TKbmRecord)));
               end;
               if Rec.UpdateStatus=usInserted then continue;
          end;
  {$ELSE}
          if (not (sfSaveData in sfData)) and (ADataSet.OverrideActiveRecordBuffer^.UpdateStatus=usUnmodified) then continue;

          // New for v. 2.30b
          if (not (sfSaveDontFilterDeltas in sfDontFilterDeltas)) and (ADataSet.OverrideActiveRecordBuffer^.UpdateStatus=usDeleted) then
          begin
               // Make sure record has not been inserted and deleted again.
               pRec:=ADataSet.OverrideActiveRecordBuffer^.PrevRecordVersion;
               while pRec^.PrevRecordVersion<>nil do pRec:=pRec^.PrevRecordVersion;
               if pRec^.UpdateStatus=usInserted then continue;
          end;
  {$ENDIF}

          // Write record versions in a list starting with Updatestatus.
          Writer.WriteListBegin;
          while ADataSet.OverrideActiveRecordBuffer<>nil do
          begin
  {$IFDEF DOTNET}
               ARec:=TKbmRecord (Marshal.PtrToStructure(ADataSet.OverrideActiveRecordBuffer,TypeOf(TKbmRecord) ));
               Writer.WriteInteger(ord(ARec.UpdateStatus));
  {$ELSE}
               Writer.WriteInteger(ord(ADataSet.OverrideActiveRecordBuffer^.UpdateStatus));
  {$ENDIF}
 {$ENDIF}
{$ENDIF}
               for i:=0 to nf-1 do
               begin
                    if SaveFields[i]>=0 then
                    begin
                         if NewestVersion and Assigned(ADataSet.OnSaveField) then ADataSet.OnSaveField(ADataset,i,ADataSet.Fields[i]);

{$IFNDEF BINARY_FILE_1XX_COMPATIBILITY}
 {$IFNDEF BINARY_FILE_200_COMPATIBILITY}
  {$IFNDEF BINARY_FILE_230_COMPATIBILITY}
                         Writer.WriteBoolean(ADataSet.Fields[i].IsNull);
                         if not ADataSet.Fields[i].IsNull then
                         begin
  {$ENDIF}
 {$ENDIF}
{$ENDIF}
                              case ADataSet.Fields[i].DataType of
                                   ftBoolean : Writer.WriteBoolean(ADataSet.Fields[i].AsBoolean);

{$IFNDEF LEVEL3}
                                   ftLargeInt: Writer.WriteFloat(ADataSet.Fields[i].AsFloat);
 {$IFDEF DOTNET}
                                   ftWideString: Writer.WriteString(ADataSet.Fields[i].AsString);
 {$ELSE}
                                   ftWideString: Writer.WriteString({$IFDEF LEVEL6}UTF8Encode(ADataSet.Fields[i].Value){$ELSE}ADataSet.Fields[i].AsString{$ENDIF});
 {$ENDIF}
{$ENDIF}

                                   ftSmallInt,
                                   ftInteger,
                                   ftWord,
                                   ftAutoInc : Writer.WriteInteger(ADataSet.Fields[i].AsInteger);

                                   ftFloat : Writer.WriteFloat(ADataSet.Fields[i].AsFloat);

                                   ftBCD,
                                   ftCurrency : Writer.WriteFloat(ADataSet.Fields[i].AsCurrency);

                                   ftDate,
                                   ftTime,ftDateTime: Writer.WriteFloat(ADataSet.Fields[i].AsFloat);
                              else
                                  Writer.WriteString(ADataSet.Fields[i].AsString);
                              end;
{$IFNDEF BINARY_FILE_1XX_COMPATIBILITY}
 {$IFNDEF BINARY_FILE_200_COMPATIBILITY}
  {$IFNDEF BINARY_FILE_230_COMPATIBILITY}
                         end;
  {$ENDIF}
 {$ENDIF}
{$ENDIF}
                    end;
               end;
{$IFNDEF BINARY_FILE_1XX_COMPATIBILITY}
 {$IFNDEF BINARY_FILE_200_COMPATIBILITY}                         // New for v. 2.24.

               // Only write newest version (current data).
               if not (sfSaveDeltas in sfDeltas) then break;

               // Prepare writing next older version of record.
  {$IFDEF DOTNET}
               ARec:=TKbmRecord(Marshal.PtrToStructure(ADataSet.OverrideActiveRecordBuffer,TypeOf(TKbmRecord)));
               ADataSet.OverrideActiveRecordBuffer:=ARec.PrevRecordVersion;
  {$ELSE}
               ADataSet.OverrideActiveRecordBuffer:=ADataSet.OverrideActiveRecordBuffer^.PrevRecordVersion;
  {$ENDIF}
               NewestVersion:=false;
          end;
          Writer.WriteListEnd;
 {$ENDIF}
{$ENDIF}

          // Increment save count.
          ADataSet.SaveCount:=ADataSet.SaveCount + 1;
     end;
     Writer.WriteListEnd;
end;

procedure TkbmCustomBinaryStreamFormat.BeforeLoad(ADataset:TkbmCustomMemTable);
begin
     inherited;

     StreamSize:=WorkStream.Size;
     ProgressCnt:=0;

     Reader:=TReader.Create(WorkStream,FBuffSize);
     Reader.ReadSignature;

     InitIndexDef:=false;

{$IFNDEF BINARY_FILE_1XX_COMPATIBILITY}
     if Reader.NextValue = vaList then       // A hack since vaList only exists in >= v. 2.xx.
       FileVersion := 100
     else
       FileVersion:=Reader.ReadInteger;
{$ELSE}
     FileVersion:=0;
{$ENDIF}
end;

procedure TkbmCustomBinaryStreamFormat.AfterLoad(ADataset:TkbmCustomMemTable);
begin
     Reader.Free;

     // Now create indexes as defined.
     if InitIndexDef then ADataset.CreateIndexes;
     ADataset.OverrideActiveRecordBuffer:=nil;
     inherited;
end;

procedure TkbmCustomBinaryStreamFormat.DetermineLoadFieldIndex(ADataset:TkbmCustomMemTable; ID:string; FieldCount:integer; OrigIndex:integer; var NewIndex:integer; Situation:TkbmDetermineLoadFieldsSituation);
begin
     NewIndex:=OrigIndex;
end;

procedure TkbmCustomBinaryStreamFormat.LoadDef(ADataset:TkbmCustomMemTable);
var
   i:integer;
   FName,KName,TName,DName,EMask,DExpr:string;
   FSize,DSize:integer;
   REQ,RO:boolean;
   FT:TFieldType;
   FK:TFieldKind;
   InitTableDef:boolean;
   ld,ldidx:boolean;
{$IFNDEF BINARY_FILE_1XX_COMPATIBILITY}
   ioptions:TIndexOptions;
   FFields:string;
{$ENDIF}
  aField:TField;
  aIndexDef:TIndexDef;
begin
     if (StreamSize = 0) then exit;
     ld:=sfLoadDef in sfDef;
     ldidx:=sfLoadIndexDef in sfIndexDef;

     // Read all definitions if any saved.
     InitTableDef:=false;
     InitIndexDef:=false;
     try
        Reader.ReadListBegin;

        while not(Reader.EndofList) do
        begin
             // Clear previous setup if not cleared yet.
             if not InitTableDef then
             begin
                  if ld then
                  begin
                       ADataSet.Close;
                       ADataSet.FieldDefs.clear;
                       ADataSet.DeleteTable;
                  end;
                  InitTableDef:=true;
             end;

             // read field definition.
             FName := Reader.ReadString;
             TName := Reader.ReadString;
             FSize := Reader.ReadInteger;
             DName := Reader.ReadString;
             EMask := Reader.ReadString;
             DSize := Reader.ReadInteger;
             REQ := Reader.ReadBoolean;
             RO := Reader.ReadBoolean;
             if FileVersion>=250 then KName:=Reader.ReadString
             else KName:=FieldKindNames[0]; // fkData
             if FileVersion>=251 then DExpr:=Reader.ReadString
             else DExpr:='';

             // Find fieldtype from fieldtypename.
             for i:=0 to ord(High(FieldTypeNames)) do
                 if FieldTypeNames[TFieldType(i)]=TName then break;
             FT:=TFieldType(i);
             if not (FT in kbmSupportedFieldTypes) then
                raise EMemTableError.Create(Format(kbmUnknownFieldErr1,[TName]));

             // Find fieldkind from fieldkindname.
             FK:=fkData;
             for i:=0 to ord(High(FieldKindNames)) do
                 if FieldKindNames[i]=KName then
                 begin
                      FK:=TFieldKind(i);
                      break;
                 end;

            if ld then
            begin
                 // Add field definition.
                 ADataSet.FieldDefs.Add(FName,FT,FSize,REQ);

                 // Setup other properties.
                 i:=ADataSet.FieldDefs.IndexOf(FName);

                 AField := ADataSet.FieldDefs.Items[i].CreateField(ADataset);
                 AField.FieldKind:=FK;
                 AField.DisplayLabel:=DName;
                 AField.EditMask:=EMask;
                 AField.ReadOnly:=RO;
                 AField.DisplayWidth:=DSize;
{$IFDEF LEVEL4}
                 AField.DefaultExpression:=DExpr;
{$ENDIF}
             end;
        end;
        Reader.ReadListEnd;

        // Indexes introduced in file version 2.00
        if FileVersion>=200 then
        begin
             // Read all index definitions if any saved.
             Reader.ReadListBegin;

⌨️ 快捷键说明

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