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

📄 kbmmemcsvstreamformat.pas

📁 内存数据库控件源代码
💻 PAS
📖 第 1 页 / 共 4 页
字号:
end;

procedure TkbmCustomCSVStreamFormat.DetermineLoadFieldIDs(ADataset:TkbmCustomMemTable; AList:TStringList; Situation:TkbmDetermineLoadFieldsSituation);
var
   s:string;
   null:boolean;
begin
     // Dont try to get fields display names if def not yet loaded.
     if (Situation<>dlfAfterLoadDef) or (Line='') or (sfLoadNoHeader in sfNoHeader) then
     begin
          inherited;
          exit;
     end;

     // Determine which fields is present in the stream.
     // Line has already been populated by LoadDef.
     with TkbmProtCustomMemTable(ADataSet) do
     begin
          AList.Clear;
          lptr:=PChar(Line);
          while (lptr<elptr) do
          begin
               // Get DisplayName for field.
               s:=GetWord(null);
               AList.Add(s);
          end;
     end;
end;

procedure TkbmCUstomCSVStreamFormat.DetermineLoadFieldIndex(ADataset:TkbmCustomMemTable; ID:string; FieldCount:integer; OrigIndex:integer; var NewIndex:integer; Situation:TkbmDetermineLoadFieldsSituation);
var
   i:integer;
   s:string;
begin
     // If determined not to load field, dont.
     if (Situation<>dlfAfterLoadDef) then exit;

     // Dont want to worry about case.
     s:=UpperCase(ID);

     // Find Field index in dataset
     for i:=0 to ADataset.FieldCount-1 do
     begin
          if (UpperCase(ADataset.Fields[i].DisplayName)=s) then
          begin
               NewIndex:=i;
               exit;
          end;
     end;

     NewIndex:=-1;
end;

procedure TkbmCustomCSVStreamFormat.LoadDef(ADataset:TkbmCustomMemTable);
var
   ld:boolean;
   i:integer;
   slist:TStringList;
   DuringTableDef,DuringIndexDef:boolean;
   null:boolean;
   FName,KName,TName,DName,EMask,DExpr:string;
   FSize,DSize:integer;
   REQ,RO,INV,CASEIN,{$IFNDEF LEVEL3}NONMT,{$ENDIF}DESC,UNIQ:boolean;
   FT:TFieldType;
   FK:TFieldKind;
   FFields:string;
   ioptions:TIndexOptions;
begin
     if (StreamSize = 0) then exit;
     ld:=sfLoadDef in sfDef;

     with TkbmProtCustomMemTable(ADataSet) do
     begin
          // Read all definition lines in CSV format.
          slist:=TStringList.Create;
          DuringTableDef:=false;
          DuringIndexDef:=false;
          try
             while true do
             begin
                  GetLine;
                  if Line='' then break;

                  // Read magic words if any.
                  Word:=GetWord(null);

{$IFNDEF CSV_FILE_1XX_COMPATIBILITY}
                  if Word=kbmFileVersionMagic then
                  begin
                       Word:=GetWord(null);
//                     FileVersion:=StrToInt(Word);
                       continue;
                  end
                  else
{$ENDIF}

                  if Word=kbmTableDefMagicStart then
                  begin
                       DuringTableDef:=true;
                       if ld then
                       begin
                            Close;
                            FieldDefs.clear;
                            DeleteTable;
                       end;
                       continue;
                  end

                  // End of table definition?
                  else if Word=kbmTableDefMagicEnd then
                  begin
                       DuringTableDef:=false;
                       Open;
                       continue;
                  end

                  // Start of index definitions?
                  else if Word=kbmIndexDefMagicStart then
                  begin
                       if ld then
                       begin
                            DestroyIndexes;
                            IndexDefs.Clear;
                       end;
                       DuringIndexDef:=true;
                       continue;
                  end

                  // End of index definitions?
                  else if Word=kbmIndexDefMagicEnd then
                  begin
                       DuringIndexDef:=false;
                       if ld then CreateIndexes;
                       continue;
                  end;

                  // If not during table definitions then its the header. Break.
                  if not DuringTableDef then break;

                  // If its an index definition.
                  if DuringIndexDef then
                  begin
                       if ld then
                       begin
                            Line:=ExtractQuoteString(Line,FCSVQuote);
                            i:=pos('=',Line);
                            slist.CommaText:=copy(Line,i+1,length(Line));
                            FName:=copy(Line,1,i-1);
                            FFields:=slist.Strings[0];
                            DName:=slist.Strings[1];
                            CASEIN:=pos(',CASE',Line)<>0;
{$IFNDEF LEVEL3}
                            NONMT:=pos(',NONMT',Line)<>0;
{$ENDIF}
                            DESC:=pos(',DESC',Line)<>0;
                            UNIQ:=pos(',UNIQ',Line)<>0;

                            // Add field definition.
                            ioptions:=[];
                            if CASEIN then ioptions:=ioptions+[ixCaseInSensitive];
                            if DESC then ioptions:=ioptions+[ixDescending];
                            if UNIQ then ioptions:=ioptions+[ixUnique];
{$IFNDEF LEVEL3}
                            if NONMT then ioptions:=ioptions+[ixNonMaintained];
                            with IndexDefs.AddIndexDef do
                            begin
                                 Name:=FName;
                                 Fields:=FFields;
                                 Options:=ioptions;
                                 DisplayName:=DName;
                            end;
{$ELSE}
                            IndexDefs.Add(FName,FFields,ioptions);
{$ENDIF}
                       end;
                       continue;
                  end;

                  // Otherwise its a field definition. Break the line apart.
                  if ld then
                  begin
                       Line:=ExtractQuoteString(Line,FCSVQuote);
                       i:=pos('=',Line);
                       slist.CommaText:=copy(Line,i+1,length(Line));
                       FName:=copy(Line,1,i-1);
                       TName:=slist.Strings[0];
                       FSize:=strtoint(slist.Strings[1]);
                       DName:=slist.Strings[2];
                       EMask:=slist.Strings[3];
                       DSize:=strtoint(slist.Strings[4]);
                       REQ:=pos(',REQ',Line)<>0;
                       RO:=pos(',RO',Line)<>0;
                       INV:=pos(',INV',Line)<>0;
                       i:=slist.Count;
                       DExpr:='';
                       if i>6 then
                       begin
                            DExpr:=slist.Strings[i-1];
                            dec(i);
                       end;
                       if i>5 then
                          KName:=slist.Strings[i-1]
                       else
                           KName:=FieldKindNames[0]; // fkData.

                       // 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+kbmUnknownFieldErr2,[TName,Word]));

                       // Check if autoinc field in stream, use data from stream.
                       if FT=ftAutoInc then
                          SetIgnoreAutoIncPopulation(ADataset,true);

                       // If fieldkind specified, find fieldkind.
                       FK:=fkData;
                       for i:=0 to ord(High(FieldKindNames)) do
                           if FieldKindNames[i]=KName then
                           begin
                                FK:=TFieldKind(i);
                                break;
                           end;

                       // Add field definition.
                       FieldDefs.Add(FName,FT,FSize,REQ);

                       // Setup other properties.
                       i:=FieldDefs.IndexOf(FName);
                       with FieldDefs.Items[i].CreateField(ADataset) do
                       begin
                            FieldKind:=FK;
                            DisplayLabel:=DName;
                            EditMask:=EMask;
                            ReadOnly:=RO;
                            DisplayWidth:=DSize;
{$IFDEF LEVEL4}
                            DefaultExpression:=DExpr;
{$ENDIF}
                            Visible:=not INV;
                       end;
                  end;
             end;
          finally
             slist.free;
          end;
     end;
     FDefLoaded:=true;
end;

procedure TkbmCustomCSVStreamFormat.LoadData(ADataset:TkbmCustomMemTable);
var
   i,j:integer;
   nf:integer;
   null:boolean;
   s:string;
   Accept:boolean;
   LoadLine:boolean;
begin
     if (StreamSize = 0) then exit;
     if not (sfLoadData in sfData) then exit;

     // Check if data line already loaded.
     LoadLine:=not (sfLoadNoHeader in sfNoHeader);
     lptr:=PChar(Line);            // Make sure word pointer is at start of line.

     with TkbmProtCustomMemTable(ADataSet) do
     begin
          ResetAutoInc;

          // Read all lines in CSV format.
          FLoadCount:=0;
          FLoadedCompletely:=true;
          while true do
          begin
               if (FLoadLimit>0) and (FLoadCount>=FLoadLimit) then
               begin
                    FLoadedCompletely:=false;
                    break;
               end;

               if LoadLine then GetLine;
               LoadLine:=true;
               if Line='' then break;

               append;

               i:=0;
{$IFDEF LEVEL4}
               nf:=length(LoadFields);
{$ELSE}
               nf:=LoadFieldsCount;
{$ENDIF}
               while (lptr<elptr) and (i<nf) do
               begin
                    j:=LoadFields[i];
                    s:=GetWord(null);
                    if j>=0 then
                    begin
                         if not (sfLoadFieldKind in sfFieldKind) then
                         begin
                              if Fields[j].FieldKind<>fkData then
                              begin
                                   inc(i);
                                   continue;
                              end;
                         end;

                         if assigned(FOnFormatLoadField) then
                            FOnFormatLoadField(self,Fields[j],null,s);

                         if null then
                             Fields[j].Clear
                         else if Fields[j].DataType in kbmStringTypes then
                             Fields[j].AsString:=CodedStringToString(s)
                         else if Fields[j].DataType in kbmBinaryTypes then
                             Fields[j].AsString:=Base64ToString(s)
                         else if Fields[j].DataType = ftBoolean then
                              with TBooleanField(Fields[j]) do
                              begin
                                   if s=FCSVTrueString then
                                      Value:=true
                                   else
                                       Value:=false;
                              end
                         else
                             Fields[j].AsString:=s;

                         if Assigned(OnLoadField) then OnLoadField(ADataSet,j,Fields[j]);
                    end;
                    inc(i);
               end;

               Accept:=true;
               if Assigned(OnLoadRecord) then OnLoadRecord(ADataset,Accept);
               if Accept then
               begin
                    Post;
                    inc(FLoadCount);
               end
               else
                    Cancel;
          end;
     end;
end;

// -----------------------------------------------------------------------------------
// Registration for Delphi 3 / C++ Builder 3
// -----------------------------------------------------------------------------------

{$ifdef LEVEL3}
procedure Register;
begin
     RegisterComponents('kbmMemTable', [TkbmCSVStreamFormat]);
end;
{$endif}

end.

⌨️ 快捷键说明

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