📄 dbf.pas
字号:
unit dbf;
{ design info in dbf_reg.pas }
interface
{$I dbf_common.inc}
uses
Classes,
Db,
dbf_common,
dbf_dbffile,
dbf_parser,
dbf_prsdef,
dbf_cursor,
dbf_fields,
dbf_pgfile,
dbf_idxfile;
// If you got a compilation error here or asking for dsgnintf.pas, then just add
// this file in your project:
// dsgnintf.pas in 'C: \Program Files\Borland\Delphi5\Source\Toolsapi\dsgnintf.pas'
type
//====================================================================
pBookmarkData = ^TBookmarkData;
TBookmarkData = record
PhysicalRecNo: Integer;
end;
pDbfRecord = ^TDbfRecordHeader;
TDbfRecordHeader = record
BookmarkData: TBookmarkData;
BookmarkFlag: TBookmarkFlag;
SequentialRecNo: Integer;
DeletedFlag: Char;
end;
//====================================================================
TDbf = class;
//====================================================================
TDbfStorage = (stoMemory,stoFile);
TDbfOpenMode = (omNormal,omAutoCreate,omTemporary);
TDbfLanguageAction = (laReadOnly, laForceOEM, laForceANSI, laDefault);
TDbfTranslationMode = (tmNoneAvailable, tmNoneNeeded, tmSimple, tmAdvanced);
TDbfFileName = (dfDbf, dfMemo, dfIndex);
//====================================================================
TDbfFileNames = set of TDbfFileName;
//====================================================================
TCompareRecordEvent = procedure(Dbf: TDbf; var Accept: Boolean) of object;
TTranslateEvent = function(Dbf: TDbf; Src, Dest: PChar; ToOem: Boolean): Integer of object;
TLanguageWarningEvent = procedure(Dbf: TDbf; var Action: TDbfLanguageAction) of object;
TConvertFieldEvent = procedure(Dbf: TDbf; DstField, SrcField: TField) of object;
TBeforeAutoCreateEvent = procedure(Dbf: TDbf; var DoCreate: Boolean) of object;
//====================================================================
// TDbfBlobStream keeps a reference count to number of references to
// this instance. Only if FRefCount reaches zero, then the object will be
// destructed. AddReference `clones' a reference.
// This allows the VCL to use Free on the object to `free' that
// particular reference.
TDbfBlobStream = class(TMemoryStream)
private
FBlobField: TBlobField;
FMode: TBlobStreamMode;
FDirty: boolean; { has possibly modified data, needs to be written }
FMemoRecNo: Integer;
{ -1 : invalid contents }
{ 0 : clear, no contents }
{ >0 : data from page x }
FReadSize: Integer;
FRefCount: Integer;
function GetTransliterate: Boolean;
procedure Translate(ToOem: Boolean);
procedure SetMode(NewMode: TBlobStreamMode);
public
constructor Create(FieldVal: TField);
destructor Destroy; override;
function AddReference: TDbfBlobStream;
procedure FreeInstance; override;
procedure Cancel;
procedure Commit;
property Dirty: boolean read FDirty;
property Transliterate: Boolean read GetTransliterate;
property MemoRecNo: Integer read FMemoRecNo write FMemoRecNo;
property ReadSize: Integer read FReadSize write FReadSize;
property Mode: TBlobStreamMode write SetMode;
property BlobField: TBlobField read FBlobField;
end;
//====================================================================
TDbfIndexDefs = class(TCollection)
public
FOwner: TDbf;
private
function GetItem(N: Integer): TDbfIndexDef;
procedure SetItem(N: Integer; Value: TDbfIndexDef);
protected
function GetOwner: TPersistent; override;
public
constructor Create(AOwner: TDbf);
function Add: TDbfIndexDef;
function GetIndexByName(const Name: string): TDbfIndexDef;
function GetIndexByField(const Name: string): TDbfIndexDef;
procedure Update; {$ifdef SUPPORT_REINTRODUCE} reintroduce; {$endif}
property Items[N: Integer]: TDbfIndexDef read GetItem write SetItem; default;
end;
//====================================================================
TDbfMasterLink = class(TDataLink)
private
FDetailDataSet: TDbf;
FParser: TDbfParser;
FFieldNames: string;
FValidExpression: Boolean;
FOnMasterChange: TNotifyEvent;
FOnMasterDisable: TNotifyEvent;
function GetFieldsVal: PChar;
procedure SetFieldNames(const Value: string);
protected
procedure ActiveChanged; override;
procedure CheckBrowseMode; override;
procedure LayoutChanged; override;
procedure RecordChanged(Field: TField); override;
public
constructor Create(ADataSet: TDbf);
destructor Destroy; override;
property FieldNames: string read FFieldNames write SetFieldNames;
property ValidExpression: Boolean read FValidExpression write FValidExpression;
property FieldsVal: PChar read GetFieldsVal;
property Parser: TDbfParser read FParser;
property OnMasterChange: TNotifyEvent read FOnMasterChange write FOnMasterChange;
property OnMasterDisable: TNotifyEvent read FOnMasterDisable write FOnMasterDisable;
end;
//====================================================================
PDbfBlobList = ^TDbfBlobList;
TDbfBlobList = array[0..MaxListSize-1] of TDbfBlobStream;
//====================================================================
TDbf = class(TDataSet)
private
FDbfFile: TDbfFile;
FCursor: TVirtualCursor;
FOpenMode: TDbfOpenMode;
FStorage: TDbfStorage;
FMasterLink: TDbfMasterLink;
FParser: TDbfParser;
FBlobStreams: PDbfBlobList;
FUserStream: TStream; // user stream to open
FTableName: string; // table path and file name
FRelativePath: string;
FAbsolutePath: string;
FIndexName: string;
FReadOnly: Boolean;
FFilterBuffer: PChar;
FTempBuffer: PChar;
FEditingRecNo: Integer;
{$ifdef SUPPORT_VARIANTS}
FLocateRecNo: Integer;
{$endif}
FLanguageID: Byte;
FTableLevel: Integer;
FExclusive: Boolean;
FShowDeleted: Boolean;
FPosting: Boolean;
FDisableResyncOnPost: Boolean;
FTempExclusive: Boolean;
FInCopyFrom: Boolean;
FStoreDefs: Boolean;
FCopyDateTimeAsString: Boolean;
FFindRecordFilter: Boolean;
FIndexFile: TIndexFile;
FDateTimeHandling: TDateTimeHandling;
FTranslationMode: TDbfTranslationMode;
FIndexDefs: TDbfIndexDefs;
FBeforeAutoCreate: TBeforeAutoCreateEvent;
FOnTranslate: TTranslateEvent;
FOnLanguageWarning: TLanguageWarningEvent;
FOnLocaleError: TDbfLocaleErrorEvent;
FOnIndexMissing: TDbfIndexMissingEvent;
FOnCompareRecord: TNotifyEvent;
FOnCopyDateTimeAsString: TConvertFieldEvent;
function GetIndexName: string;
function GetVersion: string;
function GetPhysicalRecNo: Integer;
function GetLanguageStr: string;
function GetCodePage: Cardinal;
function GetExactRecordCount: Integer;
function GetPhysicalRecordCount: Integer;
function GetKeySize: Integer;
function GetMasterFields: string;
function FieldDefsStored: Boolean;
procedure SetIndexName(AIndexName: string);
procedure SetDbfIndexDefs(const Value: TDbfIndexDefs);
procedure SetFilePath(const Value: string);
procedure SetTableName(const S: string);
procedure SetVersion(const S: string);
procedure SetLanguageID(NewID: Byte);
procedure SetDataSource(Value: TDataSource);
procedure SetMasterFields(const Value: string);
procedure SetTableLevel(const NewLevel: Integer);
procedure SetPhysicalRecNo(const NewRecNo: Integer);
procedure MasterChanged(Sender: TObject);
procedure MasterDisabled(Sender: TObject);
procedure DetermineTranslationMode;
procedure UpdateRange;
procedure SetShowDeleted(Value: Boolean);
procedure GetFieldDefsFromDbfFieldDefs;
procedure InitDbfFile(FileOpenMode: TPagedFileMode);
function ParseIndexName(const AIndexName: string): string;
procedure ParseFilter(const AFilter: string);
function GetDbfFieldDefs: TDbfFieldDefs;
function ReadCurrentRecord(Buffer: PChar; var Acceptable: Boolean): TGetResult;
function SearchKeyBuffer(Buffer: PChar; SearchType: TSearchKeyType): Boolean;
procedure SetRangeBuffer(LowRange: PChar; HighRange: PChar);
protected
{ abstract methods }
function AllocRecordBuffer: PChar; override; {virtual abstract}
procedure ClearCalcFields(Buffer: PChar); override;
procedure FreeRecordBuffer(var Buffer: PChar); override; {virtual abstract}
procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override; {virtual abstract}
function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override; {virtual abstract}
function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override; {virtual abstract}
function GetRecordSize: Word; override; {virtual abstract}
procedure InternalAddRecord(Buffer: Pointer; AAppend: Boolean); override; {virtual abstract}
procedure InternalClose; override; {virtual abstract}
procedure InternalDelete; override; {virtual abstract}
procedure InternalFirst; override; {virtual abstract}
procedure InternalGotoBookmark(ABookmark: Pointer); override; {virtual abstract}
procedure InternalHandleException; override; {virtual abstract}
procedure InternalInitFieldDefs; override; {virtual abstract}
procedure InternalInitRecord(Buffer: PChar); override; {virtual abstract}
procedure InternalLast; override; {virtual abstract}
procedure InternalOpen; override; {virtual abstract}
procedure InternalEdit; override; {virtual}
procedure InternalCancel; override; {virtual}
{$ifndef FPC}
{$ifndef DELPHI_3}
procedure InternalInsert; override; {virtual}
{$endif}
{$endif}
procedure InternalPost; override; {virtual abstract}
procedure InternalSetToRecord(Buffer: PChar); override; {virtual abstract}
procedure InitFieldDefs; override;
function IsCursorOpen: Boolean; override; {virtual abstract}
procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override; {virtual abstract}
procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override; {virtual abstract}
procedure SetFieldData(Field: TField; Buffer: Pointer);
{$ifdef SUPPORT_OVERLOAD} overload; {$endif} override; {virtual abstract}
{ virtual methods (mostly optionnal) }
function GetDataSource: TDataSource; {$ifndef VER1_0}override;{$endif}
function GetRecordCount: Integer; override; {virtual}
function GetRecNo: Integer; override; {virtual}
function GetCanModify: Boolean; override; {virtual}
procedure SetRecNo(Value: Integer); override; {virual}
procedure SetFiltered(Value: Boolean); override; {virtual;}
procedure SetFilterText(const Value: String); override; {virtual;}
{$ifdef SUPPORT_DEFCHANGED}
procedure DefChanged(Sender: TObject); override;
{$endif}
function FindRecord(Restart, GoForward: Boolean): Boolean; override;
function GetIndexFieldNames: string; {virtual;}
procedure SetIndexFieldNames(const Value: string); {virtual;}
{$ifdef SUPPORT_VARIANTS}
function LocateRecordLinear(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean;
function LocateRecordIndex(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean;
function LocateRecord(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean;
{$endif}
procedure DoFilterRecord(var Acceptable: Boolean);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
{ abstract methods }
function GetFieldData(Field: TField; Buffer: Pointer): Boolean;
{$ifdef SUPPORT_OVERLOAD} overload; {$endif} override; {virtual abstract}
{ virtual methods (mostly optionnal) }
procedure Resync(Mode: TResyncMode); override;
function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override; {virtual}
{$ifdef SUPPORT_NEW_TRANSLATE}
function Translate(Src, Dest: PChar; ToOem: Boolean): Integer; override; {virtual}
{$else}
procedure Translate(Src, Dest: PChar; ToOem: Boolean); override; {virtual}
{$endif}
{$ifdef SUPPORT_OVERLOAD}
function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; overload;
{$ifdef SUPPORT_BACKWARD_FIELDDATA} override; {$endif}
procedure SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean); overload;
{$ifdef SUPPORT_BACKWARD_FIELDDATA} override; {$endif}
{$endif}
function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer; override;
procedure CheckDbfFieldDefs(ADbfFieldDefs: TDbfFieldDefs);
{$ifdef VER1_0}
procedure DataEvent(Event: TDataEvent; Info: Longint); override;
{$endif}
// my own methods and properties
// most look like ttable functions but they are not tdataset related
// I (try to) use the same syntax to facilitate the conversion between bde and TDbf
// index support (use same syntax as ttable but is not related)
{$ifdef SUPPORT_DEFAULT_PARAMS}
procedure AddIndex(const AIndexName, AFields: String; Options: TIndexOptions; const DescFields: String='');
{$else}
procedure AddIndex(const AIndexName, AFields: String; Options: TIndexOptions);
{$endif}
procedure RegenerateIndexes;
procedure CancelRange;
procedure CheckMasterRange;
{$ifdef SUPPORT_VARIANTS}
function SearchKey(Key: Variant; SearchType: TSearchKeyType; KeyIsANSI: boolean
{$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif}): Boolean;
procedure SetRange(LowRange: Variant; HighRange: Variant; KeyIsANSI: boolean
{$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif});
{$endif}
function PrepareKey(Buffer: Pointer; BufferType: TExpressionType): PChar;
function SearchKeyPChar(Key: PChar; SearchType: TSearchKeyType; KeyIsANSI: boolean
{$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif}): Boolean;
procedure SetRangePChar(LowRange: PChar; HighRange: PChar; KeyIsANSI: boolean
{$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif});
function GetCurrentBuffer: PChar;
procedure ExtractKey(KeyBuffer: PChar);
procedure UpdateIndexDefs; override;
procedure GetFileNames(Strings: TStrings; Files: TDbfFileNames); {$ifdef SUPPORT_DEFAULT_PARAMS} overload; {$endif}
{$ifdef SUPPORT_DEFAULT_PARAMS}
function GetFileNames(Files: TDbfFileNames = [dfDbf] ): string; overload;
{$else}
function GetFileNamesString(Files: TDbfFileNames (* = [dfDbf] *) ): string;
{$endif}
procedure GetIndexNames(Strings: TStrings);
procedure GetAllIndexFiles(Strings: TStrings);
procedure TryExclusive;
procedure EndExclusive;
function LockTable(const Wait: Boolean): Boolean;
procedure UnlockTable;
procedure OpenIndexFile(IndexFile: string);
procedure DeleteIndex(const AIndexName: string);
procedure CloseIndexFile(const AIndexName: string);
procedure RepageIndexFile(const AIndexFile: string);
procedure CompactIndexFile(const AIndexFile: string);
{$ifdef SUPPORT_VARIANTS}
function Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant; override;
function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; override;
{$endif}
function IsDeleted: Boolean;
procedure Undelete;
procedure CreateTable;
procedure CreateTableEx(ADbfFieldDefs: TDbfFieldDefs);
procedure CopyFrom(DataSet: TDataSet; FileName: string; DateTimeAsString: Boolean; Level: Integer);
procedure RestructureTable(ADbfFieldDefs: TDbfFieldDefs; Pack: Boolean);
procedure PackTable;
procedure EmptyTable;
procedure Zap;
{$ifndef SUPPORT_INITDEFSFROMFIELDS}
procedure InitFieldDefsFromFields;
{$endif}
property AbsolutePath: string read FAbsolutePath;
property DbfFieldDefs: TDbfFieldDefs read GetDbfFieldDefs;
property PhysicalRecNo: Integer read GetPhysicalRecNo write SetPhysicalRecNo;
property LanguageID: Byte read FLanguageID write SetLanguageID;
property LanguageStr: String read GetLanguageStr;
property CodePage: Cardinal read GetCodePage;
property ExactRecordCount: Integer read GetExactRecordCount;
property PhysicalRecordCount: Integer read GetPhysicalRecordCount;
property KeySize: Integer read GetKeySize;
property DbfFile: TDbfFile read FDbfFile;
property UserStream: TStream read FUserStream write FUserStream;
property DisableResyncOnPost: Boolean read FDisableResyncOnPost write FDisableResyncOnPost;
published
property DateTimeHandling: TDateTimeHandling
read FDateTimeHandling write FDateTimeHandling default dtBDETimeStamp;
property Exclusive: Boolean read FExclusive write FExclusive default false;
property FilePath: string read FRelativePath write SetFilePath;
property FilePathFull: string read FAbsolutePath write SetFilePath stored false;
property Indexes: TDbfIndexDefs read FIndexDefs write SetDbfIndexDefs stored false;
property IndexDefs: TDbfIndexDefs read FIndexDefs write SetDbfIndexDefs;
property IndexFieldNames: string read GetIndexFieldNames write SetIndexFieldNames stored false;
property IndexName: string read GetIndexName write SetIndexName;
property MasterFields: string read GetMasterFields write SetMasterFields;
property MasterSource: TDataSource read GetDataSource write SetDataSource;
property OpenMode: TDbfOpenMode read FOpenMode write FOpenMode default omNormal;
property ReadOnly: Boolean read FReadOnly write FReadonly default false;
property ShowDeleted: Boolean read FShowDeleted write SetShowDeleted default false;
property Storage: TDbfStorage read FStorage write FStorage default stoFile;
property StoreDefs: Boolean read FStoreDefs write FStoreDefs default False;
property TableName: string read FTableName write SetTableName;
property TableLevel: Integer read FTableLevel write SetTableLevel;
property Version: string read GetVersion write SetVersion stored false;
property BeforeAutoCreate: TBeforeAutoCreateEvent read FBeforeAutoCreate write FBeforeAutoCreate;
property OnCompareRecord: TNotifyEvent read FOnCompareRecord write FOnCompareRecord;
property OnLanguageWarning: TLanguageWarningEvent read FOnLanguageWarning write FOnLanguageWarning;
property OnLocaleError: TDbfLocaleErrorEvent read FOnLocaleError write FOnLocaleError;
property OnIndexMissing: TDbfIndexMissingEvent read FOnIndexMissing write FOnIndexMissing;
property OnCopyDateTimeAsString: TConvertFieldEvent read FOnCopyDateTimeAsString write FOnCopyDateTimeAsString;
property OnTranslate: TTranslateEvent read FOnTranslate write FOnTranslate;
// redeclared data set properties
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -