home *** CD-ROM | disk | FTP | other *** search
-
- {*******************************************************}
- { }
- { Delphi Visual Component Library }
- { Core Database }
- { }
- { Copyright (c) 1995,97 Borland International }
- { }
- {*******************************************************}
-
- unit Db;
-
- {$R-}
-
- interface
-
- uses Windows, SysUtils, Classes, Graphics;
-
- const
-
- { TDataSet maximum number of record buffers }
-
- dsMaxBufferCount = MAXINT div 8;
-
- { Maximum string field size }
-
- dsMaxStringSize = 8192;
-
- type
-
- { Misc Dataset types }
-
- TDataSetState = (dsInactive, dsBrowse, dsEdit, dsInsert, dsSetKey,
- dsCalcFields, dsFilter, dsNewValue, dsOldValue, dsCurValue);
-
- TDataEvent = (deFieldChange, deRecordChange, deDataSetChange,
- deDataSetScroll, deLayoutChange, deUpdateRecord, deUpdateState,
- deCheckBrowseMode, dePropertyChange, deFieldListChange, deFocusControl);
-
- TUpdateStatus = (usUnmodified, usModified, usInserted, usDeleted);
-
- { Forward declarations }
-
- TFieldDef = class;
- TFieldDefs = class;
- TField = class;
- TDataLink = class;
- TDataSource = class;
- TDataSet = class;
-
- { Exception classes }
-
- EDatabaseError = class(Exception);
-
- { TFieldDef }
-
- TFieldClass = class of TField;
-
- TFieldType = (ftUnknown, ftString, ftSmallint, ftInteger, ftWord,
- ftBoolean, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime,
- ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic,
- ftFmtMemo, ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor);
-
- TFieldDef = class
- private
- FOwner: TFieldDefs;
- FName: string;
- FFieldNo: Integer;
- FDataType: TFieldType;
- FPrecision: Integer;
- FSize: Word;
- FRequired: Boolean;
- FInternalCalcField: Boolean;
- function GetFieldClass: TFieldClass;
- public
- constructor Create(Owner: TFieldDefs; const Name: string;
- DataType: TFieldType; Size: Word; Required: Boolean; FieldNo: Integer);
- destructor Destroy; override;
- function CreateField(Owner: TComponent): TField;
- property InternalCalcField: Boolean read FInternalCalcField write FInternalCalcField;
- property DataType: TFieldType read FDataType;
- property FieldClass: TFieldClass read GetFieldClass;
- property FieldNo: Integer read FFieldNo;
- property Name: string read FName;
- property Precision: Integer read FPrecision write FPrecision;
- property Required: Boolean read FRequired;
- property Size: Word read FSize;
- end;
-
- { TFieldDefs }
-
- TFieldDefs = class
- private
- FDataSet: TDataSet;
- FItems: TList;
- FUpdated: Boolean;
- function GetCount: Integer;
- function GetItem(Index: Integer): TFieldDef;
- public
- constructor Create(DataSet: TDataSet);
- destructor Destroy; override;
- procedure Add(const Name: string; DataType: TFieldType; Size: Word;
- Required: Boolean);
- procedure Assign(FieldDefs: TFieldDefs);
- procedure Clear;
- function Find(const Name: string): TFieldDef;
- function IndexOf(const Name: string): Integer;
- procedure Update;
- property Count: Integer read GetCount;
- property Items[Index: Integer]: TFieldDef read GetItem; default;
- end;
-
- { TField }
-
- TFieldKind = (fkData, fkCalculated, fkLookup, fkInternalCalc);
-
- TFieldNotifyEvent = procedure(Sender: TField) of object;
- TFieldGetTextEvent = procedure(Sender: TField; var Text: string;
- DisplayText: Boolean) of object;
- TFieldSetTextEvent = procedure(Sender: TField; const Text: string) of object;
- TFieldRef = ^TField;
- TFieldChars = set of Char;
-
- PLookupListEntry = ^TLookupListEntry;
- TLookupListEntry = record
- Key: Variant;
- Value: Variant;
- end;
-
- TLookupList = class(TObject)
- private
- FList: TList;
- public
- constructor Create;
- destructor Destroy; override;
- procedure Add(const AKey, AValue: Variant);
- procedure Clear;
- function ValueOfKey(const AKey: Variant): Variant;
- end;
-
- TField = class(TComponent)
- private
- FDataSet: TDataSet;
- FFieldName: string;
- FDataType: TFieldType;
- FReadOnly: Boolean;
- FFieldKind: TFieldKind;
- FAlignment: TAlignment;
- FVisible: Boolean;
- FRequired: Boolean;
- FValidating: Boolean;
- FSize: Word;
- FOffset: Word;
- FFieldNo: Integer;
- FDisplayWidth: Integer;
- FDisplayLabel: string;
- FEditMask: string;
- FValueBuffer: Pointer;
- FLookupDataSet: TDataSet;
- FKeyFields: string;
- FLookupKeyFields: string;
- FLookupResultField: string;
- FLookupCache: Boolean;
- FLookupList: TLookupList;
- FAttributeSet: string;
- FCustomConstraint: string;
- FImportedConstraint: string;
- FConstraintErrorMessage: string;
- FDefaultExpression: string;
- FOrigin: string;
- FValidChars: TFieldChars;
- FOnChange: TFieldNotifyEvent;
- FOnValidate: TFieldNotifyEvent;
- FOnGetText: TFieldGetTextEvent;
- FOnSetText: TFieldSetTextEvent;
- procedure Bind(Binding: Boolean);
- procedure CalcLookupValue;
- function FieldKindStored: Boolean;
- function GetCalculated: Boolean;
- function GetDisplayLabel: string;
- function GetDisplayName: string;
- function GetDisplayText: string;
- function GetDisplayWidth: Integer;
- function GetEditText: string;
- function GetHasConstraints: Boolean;
- function GetIndex: Integer;
- function GetIsIndexField: Boolean;
- function GetLookup: Boolean;
- function GetLookupList: TLookupList;
- function GetCurValue: Variant;
- function GetNewValue: Variant;
- function GetOldValue: Variant;
- function IsDisplayLabelStored: Boolean;
- function IsDisplayWidthStored: Boolean;
- procedure ReadAttributeSet(Reader: TReader);
- procedure ReadCalculated(Reader: TReader);
- procedure ReadLookup(Reader: TReader);
- procedure SetAlignment(Value: TAlignment);
- procedure SetCalculated(Value: Boolean);
- procedure SetDataSet(ADataSet: TDataSet);
- procedure SetDisplayLabel(Value: string);
- procedure SetDisplayWidth(Value: Integer);
- procedure SetEditMask(const Value: string);
- procedure SetEditText(const Value: string);
- procedure SetFieldKind(Value: TFieldKind);
- procedure SetFieldName(const Value: string);
- procedure SetIndex(Value: Integer);
- procedure SetLookup(Value: Boolean);
- procedure SetLookupDataSet(Value: TDataSet);
- procedure SetLookupKeyFields(const Value: string);
- procedure SetLookupResultField(const Value: string);
- procedure SetKeyFields(const Value: string);
- procedure SetLookupCache(const Value: Boolean);
- procedure SetNewValue(const Value: Variant);
- procedure SetReadOnly(const Value: Boolean);
- procedure SetVisible(Value: Boolean);
- procedure ValidateLookupInfo(All: Boolean);
- procedure WriteAttributeSet(Writer: TWriter);
- procedure WriteCalculated(Writer: TWriter);
- procedure WriteLookup(Writer: TWriter);
- protected
- function AccessError(const TypeName: string): EDatabaseError; dynamic;
- procedure CheckInactive;
- class procedure CheckTypeSize(Value: Integer); virtual;
- procedure Change; virtual;
- procedure DataChanged;
- procedure DefineProperties(Filer: TFiler); override;
- procedure FreeBuffers; virtual;
- function GetAsBoolean: Boolean; virtual;
- function GetAsCurrency: Currency; virtual;
- function GetAsDateTime: TDateTime; virtual;
- function GetAsFloat: Double; virtual;
- function GetAsInteger: Longint; virtual;
- function GetAsString: string; virtual;
- function GetAsVariant: Variant; virtual;
- function GetCanModify: Boolean; virtual;
- function GetDataSize: Word; virtual;
- function GetDefaultWidth: Integer; virtual;
- function GetIsNull: Boolean; virtual;
- function GetParentComponent: TComponent; override;
- procedure GetText(var Text: string; DisplayText: Boolean); virtual;
- function HasParent: Boolean; override;
- procedure Notification(AComponent: TComponent;
- Operation: TOperation); override;
- procedure PropertyChanged(LayoutAffected: Boolean);
- procedure ReadState(Reader: TReader); override;
- procedure SetAsBoolean(Value: Boolean); virtual;
- procedure SetAsCurrency(Value: Currency); virtual;
- procedure SetAsDateTime(Value: TDateTime); virtual;
- procedure SetAsFloat(Value: Double); virtual;
- procedure SetAsInteger(Value: Longint); virtual;
- procedure SetAsString(const Value: string); virtual;
- procedure SetAsVariant(const Value: Variant); virtual;
- procedure SetDataType(Value: TFieldType);
- procedure SetSize(Value: Word); virtual;
- procedure SetParentComponent(AParent: TComponent); override;
- procedure SetText(const Value: string); virtual;
- procedure SetVarValue(const Value: Variant); virtual;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure Assign(Source: TPersistent); override;
- procedure AssignValue(const Value: TVarRec);
- procedure Clear; virtual;
- procedure FocusControl;
- function GetData(Buffer: Pointer): Boolean;
- class function IsBlob: Boolean; virtual;
- function IsValidChar(InputChar: Char): Boolean; virtual;
- procedure RefreshLookupList;
- procedure SetData(Buffer: Pointer);
- procedure SetFieldType(Value: TFieldType); virtual;
- procedure Validate(Buffer: Pointer);
- property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean;
- property AsCurrency: Currency read GetAsCurrency write SetAsCurrency;
- property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime;
- property AsFloat: Double read GetAsFloat write SetAsFloat;
- property AsInteger: Longint read GetAsInteger write SetAsInteger;
- property AsString: string read GetAsString write SetAsString;
- property AsVariant: Variant read GetAsVariant write SetAsVariant;
- property AttributeSet: string read FAttributeSet write FAttributeSet;
- property Calculated: Boolean read GetCalculated write SetCalculated default False;
- property CanModify: Boolean read GetCanModify;
- property CurValue: Variant read GetCurValue;
- property DataSet: TDataSet read FDataSet write SetDataSet stored False;
- property DataSize: Word read GetDataSize;
- property DataType: TFieldType read FDataType;
- property DisplayName: string read GetDisplayName;
- property DisplayText: string read GetDisplayText;
- property EditMask: string read FEditMask write SetEditMask;
- property EditMaskPtr: string read FEditMask;
- property FieldNo: Integer read FFieldNo;
- property IsIndexField: Boolean read GetIsIndexField;
- property IsNull: Boolean read GetIsNull;
- property Lookup: Boolean read GetLookup write SetLookup;
- property LookupList: TLookupList read GetLookupList;
- property NewValue: Variant read GetNewValue write SetNewValue;
- property Offset: word read FOffset;
- property OldValue: Variant read GetOldValue;
- property Size: Word read FSize write SetSize;
- property Text: string read GetEditText write SetEditText;
- property ValidChars: TFieldChars read FValidChars write FValidChars;
- property Value: Variant read GetAsVariant write SetAsVariant;
- published
- property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
- property CustomConstraint: string read FCustomConstraint write FCustomConstraint;
- property ConstraintErrorMessage: string read FConstraintErrorMessage write FConstraintErrorMessage;
- property DefaultExpression: string read FDefaultExpression write FDefaultExpression;
- property DisplayLabel: string read GetDisplayLabel write SetDisplayLabel
- stored IsDisplayLabelStored;
- property DisplayWidth: Integer read GetDisplayWidth write SetDisplayWidth
- stored IsDisplayWidthStored;
- property FieldKind: TFieldKind read FFieldKind write SetFieldKind stored FieldKindStored;
- property FieldName: string read FFieldName write SetFieldName;
- property HasConstraints: Boolean read GetHasConstraints;
- property Index: Integer read GetIndex write SetIndex stored False;
- property ImportedConstraint: string read FImportedConstraint write FImportedConstraint;
- property LookupDataSet: TDataSet read FLookupDataSet write SetLookupDataSet;
- property LookupKeyFields: string read FLookupKeyFields write SetLookupKeyFields;
- property LookupResultField: string read FLookupResultField write SetLookupResultField;
- property KeyFields: string read FKeyFields write SetKeyFields;
- property LookupCache: Boolean read FLookupCache write SetLookupCache default False;
- property Origin: string read FOrigin write FOrigin;
- property ReadOnly: Boolean read FReadOnly write SetReadOnly default False;
- property Required: Boolean read FRequired write FRequired default False;
- property Visible: Boolean read FVisible write SetVisible default True;
- property OnChange: TFieldNotifyEvent read FOnChange write FOnChange;
- property OnGetText: TFieldGetTextEvent read FOnGetText write FOnGetText;
- property OnSetText: TFieldSetTextEvent read FOnSetText write FOnSetText;
- property OnValidate: TFieldNotifyEvent read FOnValidate write FOnValidate;
- end;
-
- { TStringField }
-
- TStringField = class(TField)
- private
- FTransliterate: Boolean;
- protected
- class procedure CheckTypeSize(Value: Integer); override;
- function GetAsBoolean: Boolean; override;
- function GetAsDateTime: TDateTime; override;
- function GetAsFloat: Double; override;
- function GetAsInteger: Longint; override;
- function GetAsString: string; override;
- function GetAsVariant: Variant; override;
- function GetDataSize: Word; override;
- function GetDefaultWidth: Integer; override;
- procedure GetText(var Text: string; DisplayText: Boolean); override;
- function GetValue(var Value: string): Boolean;
- procedure SetAsBoolean(Value: Boolean); override;
- procedure SetAsDateTime(Value: TDateTime); override;
- procedure SetAsFloat(Value: Double); override;
- procedure SetAsInteger(Value: Longint); override;
- procedure SetAsString(const Value: string); override;
- procedure SetVarValue(const Value: Variant); override;
- public
- constructor Create(AOwner: TComponent); override;
- property Value: string read GetAsString write SetAsString;
- published
- property EditMask;
- property Size default 20;
- property Transliterate: Boolean read FTransliterate write FTransliterate default True;
- end;
-
- { TNumericField }
-
- TNumericField = class(TField)
- private
- FDisplayFormat: string;
- FEditFormat: string;
- protected
- procedure RangeError(Value, Min, Max: Extended);
- procedure SetDisplayFormat(const Value: string);
- procedure SetEditFormat(const Value: string);
- public
- constructor Create(AOwner: TComponent); override;
- published
- property Alignment default taRightJustify;
- property DisplayFormat: string read FDisplayFormat write SetDisplayFormat;
- property EditFormat: string read FEditFormat write SetEditFormat;
- end;
-
- { TIntegerField }
-
- TIntegerField = class(TNumericField)
- private
- FMinRange: Longint;
- FMaxRange: Longint;
- FMinValue: Longint;
- FMaxValue: Longint;
- procedure CheckRange(Value, Min, Max: Longint);
- procedure SetMaxValue(Value: Longint);
- procedure SetMinValue(Value: Longint);
- protected
- function GetAsFloat: Double; override;
- function GetAsInteger: Longint; override;
- function GetAsString: string; override;
- function GetAsVariant: Variant; override;
- function GetDataSize: Word; override;
- procedure GetText(var Text: string; DisplayText: Boolean); override;
- function GetValue(var Value: Longint): Boolean;
- procedure SetAsFloat(Value: Double); override;
- procedure SetAsInteger(Value: Longint); override;
- procedure SetAsString(const Value: string); override;
- procedure SetVarValue(const Value: Variant); override;
- public
- constructor Create(AOwner: TComponent); override;
- property Value: Longint read GetAsInteger write SetAsInteger;
- published
- property MaxValue: Longint read FMaxValue write SetMaxValue default 0;
- property MinValue: Longint read FMinValue write SetMinValue default 0;
- end;
-
- { TSmallintField }
-
- TSmallintField = class(TIntegerField)
- protected
- function GetDataSize: Word; override;
- public
- constructor Create(AOwner: TComponent); override;
- end;
-
- { TWordField }
-
- TWordField = class(TIntegerField)
- protected
- function GetDataSize: Word; override;
- public
- constructor Create(AOwner: TComponent); override;
- end;
-
- { TAutoIncField }
-
- TAutoIncField = class(TIntegerField)
- public
- constructor Create(AOwner: TComponent); override;
- end;
-
- { TFloatField }
-
- TFloatField = class(TNumericField)
- private
- FCurrency: Boolean;
- FCheckRange: Boolean;
- FPrecision: Integer;
- FMinValue: Double;
- FMaxValue: Double;
- procedure SetCurrency(Value: Boolean);
- procedure SetMaxValue(Value: Double);
- procedure SetMinValue(Value: Double);
- procedure SetPrecision(Value: Integer);
- procedure UpdateCheckRange;
- protected
- function GetAsFloat: Double; override;
- function GetAsInteger: Longint; override;
- function GetAsString: string; override;
- function GetAsVariant: Variant; override;
- function GetDataSize: Word; override;
- procedure GetText(var Text: string; DisplayText: Boolean); override;
- procedure SetAsFloat(Value: Double); override;
- procedure SetAsInteger(Value: Longint); override;
- procedure SetAsString(const Value: string); override;
- procedure SetVarValue(const Value: Variant); override;
- public
- constructor Create(AOwner: TComponent); override;
- property Value: Double read GetAsFloat write SetAsFloat;
- published
- property Currency: Boolean read FCurrency write SetCurrency default False;
- property MaxValue: Double read FMaxValue write SetMaxValue;
- property MinValue: Double read FMinValue write SetMinValue;
- property Precision: Integer read FPrecision write SetPrecision default 15;
- end;
-
- { TCurrencyField }
-
- TCurrencyField = class(TFloatField)
- public
- constructor Create(AOwner: TComponent); override;
- published
- property Currency default True;
- end;
-
- { TBooleanField }
-
- TBooleanField = class(TField)
- private
- FDisplayValues: string;
- FTextValues: array[Boolean] of string;
- procedure LoadTextValues;
- procedure SetDisplayValues(const Value: string);
- protected
- function GetAsBoolean: Boolean; override;
- function GetAsString: string; override;
- function GetAsVariant: Variant; override;
- function GetDataSize: Word; override;
- function GetDefaultWidth: Integer; override;
- procedure SetAsBoolean(Value: Boolean); override;
- procedure SetAsString(const Value: string); override;
- procedure SetVarValue(const Value: Variant); override;
- public
- constructor Create(AOwner: TComponent); override;
- property Value: Boolean read GetAsBoolean write SetAsBoolean;
- published
- property DisplayValues: string read FDisplayValues write SetDisplayValues;
- end;
-
- { TDateTimeField }
-
- TDateTimeField = class(TField)
- private
- FDisplayFormat: string;
- function GetValue(var Value: TDateTime): Boolean;
- procedure SetDisplayFormat(const Value: string);
- protected
- function GetAsDateTime: TDateTime; override;
- function GetAsFloat: Double; override;
- function GetAsString: string; override;
- function GetAsVariant: Variant; override;
- function GetDataSize: Word; override;
- procedure GetText(var Text: string; DisplayText: Boolean); override;
- procedure SetAsDateTime(Value: TDateTime); override;
- procedure SetAsFloat(Value: Double); override;
- procedure SetAsString(const Value: string); override;
- procedure SetVarValue(const Value: Variant); override;
- public
- constructor Create(AOwner: TComponent); override;
- property Value: TDateTime read GetAsDateTime write SetAsDateTime;
- published
- property DisplayFormat: string read FDisplayFormat write SetDisplayFormat;
- property EditMask;
- end;
-
- { TDateField }
-
- TDateField = class(TDateTimeField)
- protected
- function GetDataSize: Word; override;
- public
- constructor Create(AOwner: TComponent); override;
- end;
-
- { TTimeField }
-
- TTimeField = class(TDateTimeField)
- protected
- function GetDataSize: Word; override;
- public
- constructor Create(AOwner: TComponent); override;
- end;
-
- { TBinaryField }
-
- TBinaryField = class(TField)
- protected
- class procedure CheckTypeSize(Value: Integer); override;
- function GetAsString: string; override;
- procedure GetText(var Text: string; DisplayText: Boolean); override;
- function GetAsVariant: Variant; override;
- procedure SetAsString(const Value: string); override;
- procedure SetText(const Value: string); override;
- procedure SetVarValue(const Value: Variant); override;
- public
- constructor Create(AOwner: TComponent); override;
- published
- property Size default 16;
- end;
-
- { TBytesField }
-
- TBytesField = class(TBinaryField)
- protected
- function GetDataSize: Word; override;
- public
- constructor Create(AOwner: TComponent); override;
- end;
-
- { TVarBytesField }
-
- TVarBytesField = class(TBytesField)
- protected
- function GetDataSize: Word; override;
- public
- constructor Create(AOwner: TComponent); override;
- end;
-
- { TBCDField }
-
- TBCDField = class(TNumericField)
- private
- FCurrency: Boolean;
- FCheckRange: Boolean;
- FMinValue: Currency;
- FMaxValue: Currency;
- FPrecision: Integer;
- procedure SetCurrency(Value: Boolean);
- procedure SetMaxValue(Value: Currency);
- procedure SetMinValue(Value: Currency);
- procedure UpdateCheckRange;
- protected
- class procedure CheckTypeSize(Value: Integer); override;
- function GetAsCurrency: Currency; override;
- function GetAsFloat: Double; override;
- function GetAsInteger: Longint; override;
- function GetAsString: string; override;
- function GetAsVariant: Variant; override;
- function GetDataSize: Word; override;
- function GetDefaultWidth: Integer; override;
- procedure GetText(var Text: string; DisplayText: Boolean); override;
- function GetValue(var Value: Currency): Boolean;
- procedure SetAsCurrency(Value: Currency); override;
- procedure SetAsFloat(Value: Double); override;
- procedure SetAsInteger(Value: Longint); override;
- procedure SetAsString(const Value: string); override;
- procedure SetVarValue(const Value: Variant); override;
- public
- constructor Create(AOwner: TComponent); override;
- property Value: Currency read GetAsCurrency write SetAsCurrency;
- published
- property Currency: Boolean read FCurrency write SetCurrency default False;
- property MaxValue: Currency read FMaxValue write SetMaxValue;
- property MinValue: Currency read FMinValue write SetMinValue;
- property Size default 4;
- end;
-
- { TBlobField }
-
- TBlobType = ftBlob..ftTypedBinary;
-
- TBlobField = class(TField)
- private
- FModified: Boolean;
- FModifiedRecord: Integer;
- FTransliterate: Boolean;
- function GetBlobType: TBlobType;
- function GetModified: Boolean;
- procedure LoadFromBlob(Blob: TBlobField);
- procedure LoadFromBitmap(Bitmap: TBitmap);
- procedure LoadFromStrings(Strings: TStrings);
- procedure SaveToBitmap(Bitmap: TBitmap);
- procedure SaveToStrings(Strings: TStrings);
- procedure SetBlobType(Value: TBlobType);
- procedure SetModified(Value: Boolean);
- protected
- procedure AssignTo(Dest: TPersistent); override;
- procedure FreeBuffers; override;
- function GetAsString: string; override;
- function GetAsVariant: Variant; override;
- function GetBlobSize: Integer; virtual;
- function GetIsNull: Boolean; override;
- procedure GetText(var Text: string; DisplayText: Boolean); override;
- procedure SetAsString(const Value: string); override;
- procedure SetText(const Value: string); override;
- procedure SetVarValue(const Value: Variant); override;
- public
- constructor Create(AOwner: TComponent); override;
- procedure Assign(Source: TPersistent); override;
- procedure Clear; override;
- class function IsBlob: Boolean; override;
- procedure LoadFromFile(const FileName: string);
- procedure LoadFromStream(Stream: TStream);
- procedure SaveToFile(const FileName: string);
- procedure SaveToStream(Stream: TStream);
- procedure SetFieldType(Value: TFieldType); override;
- property BlobSize: Integer read GetBlobSize;
- property Modified: Boolean read GetModified write SetModified;
- property Value: string read GetAsString write SetAsString;
- property Transliterate: Boolean read FTransliterate write FTransliterate;
- published
- property BlobType: TBlobType read GetBlobType write SetBlobType;
- property Size default 0;
- end;
-
- { TMemoField }
-
- TMemoField = class(TBlobField)
- public
- constructor Create(AOwner: TComponent); override;
- published
- property Transliterate default True;
- end;
-
- { TGraphicField }
-
- TGraphicField = class(TBlobField)
- public
- constructor Create(AOwner: TComponent); override;
- end;
-
- { TIndexDef }
-
- TIndexDefs = class;
-
- TIndexOptions = set of (ixPrimary, ixUnique, ixDescending,
- ixCaseInsensitive, ixExpression);
-
- TIndexDef = class
- private
- FOwner: TIndexDefs;
- FSource: string;
- FName: string;
- FFields: string;
- FOptions: TIndexOptions;
- function GetExpression: string;
- function GetFields: string;
- public
- constructor Create(Owner: TIndexDefs; const Name, Fields: string;
- Options: TIndexOptions);
- destructor Destroy; override;
- property Expression: string read GetExpression;
- property Fields: string read GetFields;
- property Name: string read FName;
- property Options: TIndexOptions read FOptions;
- property Source: string read FSource write FSource;
- end;
-
- { TIndexDefs }
-
- TIndexDefs = class
- private
- FDataSet: TDataSet;
- FItems: TList;
- FUpdated: Boolean;
- function GetCount: Integer;
- function GetItem(Index: Integer): TIndexDef;
- public
- constructor Create(DataSet: TDataSet);
- destructor Destroy; override;
- procedure Add(const Name, Fields: string; Options: TIndexOptions);
- procedure Assign(IndexDefs: TIndexDefs);
- procedure Clear;
- function FindIndexForFields(const Fields: string): TIndexDef;
- function GetIndexForFields(const Fields: string;
- CaseInsensitive: Boolean): TIndexDef;
- function IndexOf(const Name: string): Integer;
- procedure Update;
- property Count: Integer read GetCount;
- property Items[Index: Integer]: TIndexDef read GetItem; default;
- property Updated: Boolean read FUpdated write FUpdated;
- end;
-
- { TDataLink }
-
- TDataLink = class(TPersistent)
- private
- FDataSource: TDataSource;
- FNext: TDataLink;
- FBufferCount: Integer;
- FFirstRecord: Integer;
- FReadOnly: Boolean;
- FActive: Boolean;
- FEditing: Boolean;
- FUpdating: Boolean;
- FDataSourceFixed: Boolean;
- procedure DataEvent(Event: TDataEvent; Info: Longint);
- function GetActiveRecord: Integer;
- function GetDataSet: TDataSet;
- function GetRecordCount: Integer;
- procedure SetActive(Value: Boolean);
- procedure SetActiveRecord(Value: Integer);
- procedure SetBufferCount(Value: Integer);
- procedure SetDataSource(ADataSource: TDataSource);
- procedure SetEditing(Value: Boolean);
- procedure SetReadOnly(Value: Boolean);
- procedure UpdateRange;
- procedure UpdateState;
- protected
- procedure ActiveChanged; virtual;
- procedure CheckBrowseMode; virtual;
- procedure DataSetChanged; virtual;
- procedure DataSetScrolled(Distance: Integer); virtual;
- procedure FocusControl(Field: TFieldRef); virtual;
- procedure EditingChanged; virtual;
- procedure LayoutChanged; virtual;
- procedure RecordChanged(Field: TField); virtual;
- procedure UpdateData; virtual;
- public
- constructor Create;
- destructor Destroy; override;
- function Edit: Boolean;
- procedure UpdateRecord;
- property Active: Boolean read FActive;
- property ActiveRecord: Integer read GetActiveRecord write SetActiveRecord;
- property BufferCount: Integer read FBufferCount write SetBufferCount;
- property DataSet: TDataSet read GetDataSet;
- property DataSource: TDataSource read FDataSource write SetDataSource;
- property DataSourceFixed: Boolean read FDataSourceFixed write FDataSourceFixed;
- property Editing: Boolean read FEditing;
- property ReadOnly: Boolean read FReadOnly write SetReadOnly;
- property RecordCount: Integer read GetRecordCount;
- end;
-
- { TDataSource }
-
- TDataChangeEvent = procedure(Sender: TObject; Field: TField) of object;
-
- TDataSource = class(TComponent)
- private
- FDataSet: TDataSet;
- FDataLinks: TList;
- FEnabled: Boolean;
- FAutoEdit: Boolean;
- FState: TDataSetState;
- FOnStateChange: TNotifyEvent;
- FOnDataChange: TDataChangeEvent;
- FOnUpdateData: TNotifyEvent;
- procedure AddDataLink(DataLink: TDataLink);
- procedure DataEvent(Event: TDataEvent; Info: Longint);
- procedure NotifyDataLinks(Event: TDataEvent; Info: Longint);
- procedure RemoveDataLink(DataLink: TDataLink);
- procedure SetDataSet(ADataSet: TDataSet);
- procedure SetEnabled(Value: Boolean);
- procedure SetState(Value: TDataSetState);
- procedure UpdateState;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure Edit;
- function IsLinkedTo(DataSet: TDataSet): Boolean;
- property State: TDataSetState read FState;
- published
- property AutoEdit: Boolean read FAutoEdit write FAutoEdit default True;
- property DataSet: TDataSet read FDataSet write SetDataSet;
- property Enabled: Boolean read FEnabled write SetEnabled default True;
- property OnStateChange: TNotifyEvent read FOnStateChange write FOnStateChange;
- property OnDataChange: TDataChangeEvent read FOnDataChange write FOnDataChange;
- property OnUpdateData: TNotifyEvent read FOnUpdateData write FOnUpdateData;
- end;
-
- { TDataSetDesigner }
-
- TDataSetDesigner = class(TObject)
- private
- FDataSet: TDataSet;
- FSaveActive: Boolean;
- public
- constructor Create(DataSet: TDataSet);
- destructor Destroy; override;
- procedure BeginDesign;
- procedure DataEvent(Event: TDataEvent; Info: Longint); virtual;
- procedure EndDesign;
- property DataSet: TDataSet read FDataSet;
- end;
-
- { TCheckConstraint }
-
- TCheckConstraint = class(TCollectionItem)
- private
- FImportedConstraint: string;
- FCustomConstraint: string;
- FErrorMessage: string;
- FFromDictionary: Boolean;
- procedure SetImportedConstraint(const Value: string);
- procedure SetCustomConstraint(const Value: string);
- procedure SetErrorMessage(const Value: string);
- public
- procedure Assign(Source: TPersistent); override;
- function GetDisplayName: string; override;
- published
- property CustomConstraint: string read FCustomConstraint write SetCustomConstraint;
- property ErrorMessage: string read FErrorMessage write SetErrorMessage;
- property FromDictionary: Boolean read FFromDictionary write FFromDictionary;
- property ImportedConstraint: string read FImportedConstraint write SetImportedConstraint;
- end;
-
- { TCheckConstraints }
-
- TCheckConstraints = class(TCollection)
- private
- FOwner: TPersistent;
- function GetItem(Index: Integer): TCheckConstraint;
- procedure SetItem(Index: Integer; Value: TCheckConstraint);
- protected
- function GetOwner: TPersistent; override;
- public
- constructor Create(Owner: TPersistent);
- function Add: TCheckConstraint;
- property Items[Index: Integer]: TCheckConstraint read GetItem write SetItem; default;
- end;
-
- { TDataSet }
-
- TBookmark = Pointer;
- TBookmarkStr = string;
-
- PBookmarkFlag = ^TBookmarkFlag;
- TBookmarkFlag = (bfCurrent, bfBOF, bfEOF, bfInserted);
-
- PBufferList = ^TBufferList;
- TBufferList = array[0..dsMaxBufferCount - 1] of PChar;
-
- TGetMode = (gmCurrent, gmNext, gmPrior);
-
- TGetResult = (grOK, grBOF, grEOF, grError);
-
- TResyncMode = set of (rmExact, rmCenter);
-
- TDataAction = (daFail, daAbort, daRetry);
-
- TUpdateKind = (ukModify, ukInsert, ukDelete);
-
- TBlobStreamMode = (bmRead, bmWrite, bmReadWrite);
-
- TLocateOption = (loCaseInsensitive, loPartialKey);
- TLocateOptions = set of TLocateOption;
-
- TDataOperation = procedure of object;
-
- TDataSetNotifyEvent = procedure(DataSet: TDataSet) of object;
- TDataSetErrorEvent = procedure(DataSet: TDataSet; E: EDatabaseError;
- var Action: TDataAction) of object;
-
- TFilterOption = (foCaseInsensitive, foNoPartialCompare);
- TFilterOptions = set of TFilterOption;
-
- TFilterRecordEvent = procedure(DataSet: TDataSet;
- var Accept: Boolean) of object;
-
- TDataSet = class(TComponent)
- private
- FFields: TList;
- FFieldDefs: TFieldDefs;
- FDataSources: TList;
- FFirstDataLink: TDataLink;
- FBufferCount: Integer;
- FRecordCount: Integer;
- FActiveRecord: Integer;
- FCurrentRecord: Integer;
- FBuffers: PBufferList;
- FCalcBuffer: PChar;
- FBufListSize: Integer;
- FBookmarkSize: Integer;
- FCalcFieldsSize: Integer;
- FBOF: Boolean;
- FEOF: Boolean;
- FModified: Boolean;
- FStreamedActive: Boolean;
- FInternalCalcFields: Boolean;
- FState: TDataSetState;
- FEnableEvent: TDataEvent;
- FDisableState: TDataSetState;
- FDesigner: TDataSetDesigner;
- FDisableCount: Integer;
- FFound: Boolean;
- FDefaultFields: Boolean;
- FAutoCalcFields: Boolean;
- FFiltered: Boolean;
- FBlobFieldCount: Integer;
- FFilterText: string;
- FFilterOptions: TFilterOptions;
- FConstraints: TCheckConstraints;
- FBeforeOpen: TDataSetNotifyEvent;
- FAfterOpen: TDataSetNotifyEvent;
- FBeforeClose: TDataSetNotifyEvent;
- FAfterClose: TDataSetNotifyEvent;
- FBeforeInsert: TDataSetNotifyEvent;
- FAfterInsert: TDataSetNotifyEvent;
- FBeforeEdit: TDataSetNotifyEvent;
- FAfterEdit: TDataSetNotifyEvent;
- FBeforePost: TDataSetNotifyEvent;
- FAfterPost: TDataSetNotifyEvent;
- FBeforeCancel: TDataSetNotifyEvent;
- FAfterCancel: TDataSetNotifyEvent;
- FBeforeDelete: TDataSetNotifyEvent;
- FAfterDelete: TDataSetNotifyEvent;
- FBeforeScroll: TDataSetNotifyEvent;
- FAfterScroll: TDataSetNotifyEvent;
- FOnNewRecord: TDataSetNotifyEvent;
- FOnCalcFields: TDataSetNotifyEvent;
- FOnEditError: TDataSetErrorEvent;
- FOnPostError: TDataSetErrorEvent;
- FOnDeleteError: TDataSetErrorEvent;
- FOnFilterRecord: TFilterRecordEvent;
- procedure AddDataSource(DataSource: TDataSource);
- procedure AddField(Field: TField);
- procedure AddRecord(const Values: array of const; Append: Boolean);
- procedure BeginInsertAppend;
- procedure CheckCanModify;
- procedure CheckFieldName(const FieldName: string);
- procedure CheckFieldNames(const FieldNames: string);
- procedure CheckOperation(Operation: TDataOperation;
- ErrorEvent: TDataSetErrorEvent);
- procedure CheckRequiredFields;
- procedure DoInternalOpen;
- procedure DoInternalClose;
- procedure EndInsertAppend;
- function GetActive: Boolean;
- function GetBuffer(Index: Integer): PChar;
- function GetField(Index: Integer): TField;
- function GetFieldCount: Integer;
- function GetFieldValue(const FieldName: string): Variant;
- function GetFound: Boolean;
- procedure MoveBuffer(CurIndex, NewIndex: Integer);
- procedure RemoveDataSource(DataSource: TDataSource);
- procedure RemoveField(Field: TField);
- procedure SetActive(Value: Boolean);
- procedure SetBufferCount(Value: Integer);
- procedure SetField(Index: Integer; Value: TField);
- procedure SetFieldDefs(Value: TFieldDefs);
- procedure SetFieldValue(const FieldName: string; const Value: Variant);
- procedure SetConstraints(const Value: TCheckConstraints);
- procedure UpdateBufferCount;
- procedure UpdateFieldDefs;
- protected
- procedure ActivateBuffers; virtual;
- procedure BindFields(Binding: Boolean);
- function BookmarkAvailable: Boolean;
- function BCDToCurr(BCD: Pointer; var Curr: Currency): Boolean; virtual;
- function CurrToBCD(const Curr: Currency; BCD: Pointer; Precision,
- Decimals: Integer): Boolean; virtual;
- procedure CalculateFields(Buffer: PChar); virtual;
- procedure CheckActive; virtual;
- procedure CheckInactive; virtual;
- procedure ClearBuffers; virtual;
- procedure ClearCalcFields(Buffer: PChar); virtual;
- procedure CloseBlob(Field: TField); virtual;
- procedure CloseCursor; virtual;
- procedure CreateFields;
- procedure DataEvent(Event: TDataEvent; Info: Longint); virtual;
- procedure DestroyFields; virtual;
- procedure DoAfterCancel; virtual;
- procedure DoAfterClose; virtual;
- procedure DoAfterDelete; virtual;
- procedure DoAfterEdit; virtual;
- procedure DoAfterInsert; virtual;
- procedure DoAfterOpen; virtual;
- procedure DoAfterPost; virtual;
- procedure DoAfterScroll; virtual;
- procedure DoBeforeCancel; virtual;
- procedure DoBeforeClose; virtual;
- procedure DoBeforeDelete; virtual;
- procedure DoBeforeEdit; virtual;
- procedure DoBeforeInsert; virtual;
- procedure DoBeforeOpen; virtual;
- procedure DoBeforePost; virtual;
- procedure DoBeforeScroll; virtual;
- procedure DoOnCalcFields; virtual;
- procedure DoOnNewRecord; virtual;
- function FieldByNumber(FieldNo: Integer): TField;
- function FindRecord(Restart, GoForward: Boolean): Boolean; virtual;
- procedure FreeFieldBuffers; virtual;
- function GetBookmarkStr: TBookmarkStr; virtual;
- procedure GetCalcFields(Buffer: PChar); virtual;
- function GetCanModify: Boolean; virtual;
- procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
- function GetDataSource: TDataSource; virtual;
- function GetFieldClass(FieldType: TFieldType): TFieldClass; virtual;
- function GetStateFieldValue(State: TDataSetState; Field: TField): Variant; virtual;
- function GetIsIndexField(Field: TField): Boolean; virtual;
- function GetNextRecords: Integer; virtual;
- function GetNextRecord: Boolean; virtual;
- function GetPriorRecords: Integer; virtual;
- function GetPriorRecord: Boolean; virtual;
- function GetRecordCount: Integer; virtual;
- function GetRecNo: Integer; virtual;
- procedure InitFieldDefs; virtual;
- procedure InitRecord(Buffer: PChar); virtual;
- procedure InternalCancel; virtual;
- procedure InternalEdit; virtual;
- procedure InternalRefresh; virtual;
- procedure Loaded; override;
- procedure OpenCursor(InfoQuery: Boolean); virtual;
- procedure RefreshInternalCalcFields(Buffer: PChar); virtual;
- procedure RestoreState(const Value: TDataSetState);
- procedure SetBookmarkStr(const Value: TBookmarkStr); virtual;
- procedure SetBufListSize(Value: Integer);
- procedure SetChildOrder(Component: TComponent; Order: Integer); override;
- procedure SetCurrentRecord(Index: Integer); virtual;
- procedure SetFiltered(Value: Boolean); virtual;
- procedure SetFilterOptions(Value: TFilterOptions); virtual;
- procedure SetFilterText(const Value: string); virtual;
- procedure SetFound(const Value: Boolean);
- procedure SetModified(Value: Boolean);
- procedure SetName(const Value: TComponentName); override;
- procedure SetStateFieldValue(State: TDataSetState; Field: TField; Value: Variant); virtual;
- procedure SetOnFilterRecord(const Value: TFilterRecordEvent); virtual;
- procedure SetRecNo(Value: Integer); virtual;
- procedure SetState(Value: TDataSetState);
- function SetTempState(const Value: TDataSetState): TDataSetState;
- function TempBuffer: PChar;
- procedure UpdateIndexDefs; virtual;
- property ActiveRecord: Integer read FActiveRecord;
- property CurrentRecord: Integer read FCurrentRecord;
- property BlobFieldCount: Integer read FBlobFieldCount;
- property BookmarkSize: Integer read FBookmarkSize write FBookmarkSize;
- property Buffers[Index: Integer]: PChar read GetBuffer;
- property BufferCount: Integer read FBufferCount;
- property CalcBuffer: PChar read FCalcBuffer;
- property CalcFieldsSize: Integer read FCalcFieldsSize;
- property InternalCalcFields: Boolean read FInternalCalcFields;
- property Constraints: TCheckConstraints read FConstraints write SetConstraints;
- protected { abstract methods }
- function AllocRecordBuffer: PChar; virtual; abstract;
- procedure FreeRecordBuffer(var Buffer: PChar); virtual; abstract;
- procedure GetBookmarkData(Buffer: PChar; Data: Pointer); virtual; abstract;
- function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; virtual; abstract;
- function GetFieldData(Field: TField; Buffer: Pointer): Boolean; virtual; abstract;
- function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult; virtual; abstract;
- function GetRecordSize: Word; virtual; abstract;
- procedure InternalAddRecord(Buffer: Pointer; Append: Boolean); virtual; abstract;
- procedure InternalClose; virtual; abstract;
- procedure InternalDelete; virtual; abstract;
- procedure InternalFirst; virtual; abstract;
- procedure InternalGotoBookmark(Bookmark: Pointer); virtual; abstract;
- procedure InternalHandleException; virtual; abstract;
- procedure InternalInitFieldDefs; virtual; abstract;
- procedure InternalInitRecord(Buffer: PChar); virtual; abstract;
- procedure InternalLast; virtual; abstract;
- procedure InternalOpen; virtual; abstract;
- procedure InternalPost; virtual; abstract;
- procedure InternalSetToRecord(Buffer: PChar); virtual; abstract;
- function IsCursorOpen: Boolean; virtual; abstract;
- procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); virtual; abstract;
- procedure SetBookmarkData(Buffer: PChar; Data: Pointer); virtual; abstract;
- procedure SetFieldData(Field: TField; Buffer: Pointer); virtual; abstract;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- function ActiveBuffer: PChar;
- procedure Append;
- procedure AppendRecord(const Values: array of const);
- function BookmarkValid(Bookmark: TBookmark): Boolean; virtual;
- procedure Cancel; virtual;
- procedure CheckBrowseMode;
- procedure ClearFields;
- procedure Close;
- function ControlsDisabled: Boolean;
- function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer; virtual;
- function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; virtual;
- procedure CursorPosChanged;
- procedure Delete;
- procedure DisableControls;
- procedure Edit;
- procedure EnableControls;
- function FieldByName(const FieldName: string): TField;
- function FindField(const FieldName: string): TField;
- function FindFirst: Boolean;
- function FindLast: Boolean;
- function FindNext: Boolean;
- function FindPrior: Boolean;
- procedure First;
- procedure FreeBookmark(Bookmark: TBookmark); virtual;
- function GetBookmark: TBookmark; virtual;
- function GetCurrentRecord(Buffer: PChar): Boolean; virtual;
- procedure GetFieldList(List: TList; const FieldNames: string);
- procedure GetFieldNames(List: TStrings);
- procedure GotoBookmark(Bookmark: TBookmark);
- procedure Insert;
- procedure InsertRecord(const Values: array of const);
- function IsEmpty: Boolean;
- function IsLinkedTo(DataSource: TDataSource): Boolean;
- function IsSequenced: Boolean; virtual;
- procedure Last;
- function Locate(const KeyFields: string; const KeyValues: Variant;
- Options: TLocateOptions): Boolean; virtual;
- function Lookup(const KeyFields: string; const KeyValues: Variant;
- const ResultFields: string): Variant; virtual;
- function MoveBy(Distance: Integer): Integer;
- procedure Next;
- procedure Open;
- procedure Post; virtual;
- procedure Prior;
- procedure Refresh;
- procedure Resync(Mode: TResyncMode); virtual;
- procedure SetFields(const Values: array of const);
- procedure Translate(Src, Dest: PChar; ToOem: Boolean); virtual;
- procedure UpdateCursorPos;
- procedure UpdateRecord;
- property BOF: Boolean read FBOF;
- property Bookmark: TBookmarkStr read GetBookmarkStr write SetBookmarkStr;
- property CanModify: Boolean read GetCanModify;
- property DataSource: TDataSource read GetDataSource;
- property DefaultFields: Boolean read FDefaultFields;
- property Designer: TDataSetDesigner read FDesigner;
- property EOF: Boolean read FEOF;
- property FieldCount: Integer read GetFieldCount;
- property FieldDefs: TFieldDefs read FFieldDefs write SetFieldDefs;
- property Fields[Index: Integer]: TField read GetField write SetField;
- property FieldValues[const FieldName: string]: Variant read GetFieldValue write SetFieldValue; default;
- property Found: Boolean read GetFound;
- property Modified: Boolean read FModified;
- property RecordCount: Integer read GetRecordCount;
- property RecNo: Integer read GetRecNo write SetRecNo;
- property RecordSize: Word read GetRecordSize;
- property State: TDataSetState read FState;
- property Filter: string read FFilterText write SetFilterText;
- property Filtered: Boolean read FFiltered write SetFiltered default False;
- property FilterOptions: TFilterOptions read FFilterOptions write SetFilterOptions default [];
- property Active: Boolean read GetActive write SetActive default False;
- property AutoCalcFields: Boolean read FAutoCalcFields write FAutoCalcFields default True;
- property BeforeOpen: TDataSetNotifyEvent read FBeforeOpen write FBeforeOpen;
- property AfterOpen: TDataSetNotifyEvent read FAfterOpen write FAfterOpen;
- property BeforeClose: TDataSetNotifyEvent read FBeforeClose write FBeforeClose;
- property AfterClose: TDataSetNotifyEvent read FAfterClose write FAfterClose;
- property BeforeInsert: TDataSetNotifyEvent read FBeforeInsert write FBeforeInsert;
- property AfterInsert: TDataSetNotifyEvent read FAfterInsert write FAfterInsert;
- property BeforeEdit: TDataSetNotifyEvent read FBeforeEdit write FBeforeEdit;
- property AfterEdit: TDataSetNotifyEvent read FAfterEdit write FAfterEdit;
- property BeforePost: TDataSetNotifyEvent read FBeforePost write FBeforePost;
- property AfterPost: TDataSetNotifyEvent read FAfterPost write FAfterPost;
- property BeforeCancel: TDataSetNotifyEvent read FBeforeCancel write FBeforeCancel;
- property AfterCancel: TDataSetNotifyEvent read FAfterCancel write FAfterCancel;
- property BeforeDelete: TDataSetNotifyEvent read FBeforeDelete write FBeforeDelete;
- property AfterDelete: TDataSetNotifyEvent read FAfterDelete write FAfterDelete;
- property BeforeScroll: TDataSetNotifyEvent read FBeforeScroll write FBeforeScroll;
- property AfterScroll: TDataSetNotifyEvent read FAfterScroll write FAfterScroll;
- property OnCalcFields: TDataSetNotifyEvent read FOnCalcFields write FOnCalcFields;
- property OnDeleteError: TDataSetErrorEvent read FOnDeleteError write FOnDeleteError;
- property OnEditError: TDataSetErrorEvent read FOnEditError write FOnEditError;
- property OnFilterRecord: TFilterRecordEvent read FOnFilterRecord write SetOnFilterRecord;
- property OnNewRecord: TDataSetNotifyEvent read FOnNewRecord write FOnNewRecord;
- property OnPostError: TDataSetErrorEvent read FOnPostError write FOnPostError;
- end;
-
- { TDateTimeRec }
-
- type
- TDateTimeRec = record
- case TFieldType of
- ftDate: (Date: Longint);
- ftTime: (Time: Longint);
- ftDateTime: (DateTime: TDateTime);
- end;
-
- const
- dsEditModes = [dsEdit, dsInsert, dsSetKey];
- dsWriteModes = [dsEdit, dsInsert, dsSetKey, dsCalcFields, dsFilter, dsNewValue];
-
- DefaultFieldClasses: array[ftUnknown..ftTypedBinary] of TFieldClass = (
- nil, { ftUnknown }
- TStringField, { ftString }
- TSmallintField, { ftSmallint }
- TIntegerField, { ftInteger }
- TWordField, { ftWord }
- TBooleanField, { ftBoolean }
- TFloatField, { ftFloat }
- TCurrencyField, { ftCurrency }
- TBCDField, { ftBCD }
- TDateField, { ftDate }
- TTimeField, { ftTime }
- TDateTimeField, { ftDateTime }
- TBytesField, { ftBytes }
- TVarBytesField, { ftVarBytes }
- TAutoIncField, { ftAutoInc }
- TBlobField, { ftBlob }
- TMemoField, { ftMemo }
- TGraphicField, { ftGraphic }
- TBlobField, { ftFmtMemo }
- TBlobField, { ftParadoxOle }
- TBlobField, { ftDBaseOle }
- TBlobField); { ftTypedBinary }
-
- function ExtractFieldName(const Fields: string; var Pos: Integer): string;
- procedure RegisterFields(const FieldClasses: array of TFieldClass);
-
- procedure DatabaseError(const Message: string);
- procedure DatabaseErrorFmt(const Message: string; const Args: array of const);
- procedure DBError(Ident: Word);
- procedure DBErrorFmt(Ident: Word; const Args: array of const);
-
- procedure DisposeMem(var Buffer; Size: Integer);
- function BuffersEqual(Buf1, Buf2: Pointer; Size: Integer): Boolean;
-
- function GetFieldProperty(DataSet: TDataSet; Control: TComponent;
- const FieldName: string): TField;
-
- const
- RegisterFieldsProc: procedure(const FieldClassess: array of TFieldClass) = nil;
-
- implementation
-
- uses DBConsts, Mask;
-
- { Paradox graphic BLOB header }
-
- type
- TGraphicHeader = record
- Count: Word; { Fixed at 1 }
- HType: Word; { Fixed at $0100 }
- Size: Longint; { Size not including header }
- end;
-
- { Error and exception handling routines }
-
- procedure DatabaseError(const Message: string);
- begin
- raise EDatabaseError.Create(Message);
- end;
-
- procedure DatabaseErrorFmt(const Message: string; const Args: array of const);
- begin
- raise EDatabaseError.CreateFmt(Message, Args);
- end;
-
- procedure DBError(Ident: Word);
- begin
- DatabaseError(LoadStr(Ident));
- end;
-
- procedure DBErrorFmt(Ident: Word; const Args: array of const);
- begin
- DatabaseError(FmtLoadStr(Ident, Args));
- end;
-
- function GetFieldProperty(DataSet: TDataSet; Control: TComponent;
- const FieldName: string): TField;
- begin
- Result := DataSet.FindField(FieldName);
- if Result = nil then
- DatabaseErrorFmt(SFieldNotFound, [Control.Name, FieldName]);
- end;
-
- { Utility routines }
-
- procedure DisposeMem(var Buffer; Size: Integer);
- begin
- if Pointer(Buffer) <> nil then
- begin
- FreeMem(Pointer(Buffer), Size);
- Pointer(Buffer) := nil;
- end;
- end;
-
- function BuffersEqual(Buf1, Buf2: Pointer; Size: Integer): Boolean; assembler;
- asm
- PUSH EDI
- PUSH ESI
- MOV ESI,Buf1
- MOV EDI,Buf2
- XOR EAX,EAX
- JECXZ @@1
- CLD
- REPE CMPSB
- JNE @@1
- INC EAX
- @@1: POP ESI
- POP EDI
- end;
-
- function ExtractFieldName(const Fields: string; var Pos: Integer): string;
- var
- I: Integer;
- begin
- I := Pos;
- while (I <= Length(Fields)) and (Fields[I] <> ';') do Inc(I);
- Result := Trim(Copy(Fields, Pos, I - Pos));
- if (I <= Length(Fields)) and (Fields[I] = ';') then Inc(I);
- Pos := I;
- end;
-
- procedure RegisterFields(const FieldClasses: array of TFieldClass);
- begin
- if Assigned(RegisterFieldsProc) then
- RegisterFieldsProc(FieldClasses) else
- DatabaseError(SInvalidFieldRegistration);
- end;
-
- { TDataSetDesigner }
-
- constructor TDataSetDesigner.Create(DataSet: TDataSet);
- begin
- FDataSet := DataSet;
- FDataSet.FDesigner := Self;
- end;
-
- destructor TDataSetDesigner.Destroy;
- begin
- FDataSet.FDesigner := nil;
- end;
-
- procedure TDataSetDesigner.BeginDesign;
- begin
- FSaveActive := FDataSet.Active;
- if FSaveActive then
- begin
- FDataSet.DoInternalClose;
- FDataSet.SetState(dsInactive);
- end;
- FDataSet.DisableControls;
- end;
-
- procedure TDataSetDesigner.DataEvent(Event: TDataEvent; Info: Longint);
- begin
- end;
-
- procedure TDataSetDesigner.EndDesign;
- begin
- FDataSet.EnableControls;
- if FSaveActive then
- begin
- try
- FDataSet.DoInternalOpen;
- FDataSet.SetState(dsBrowse);
- except
- FDataSet.SetState(dsInactive);
- FDataSet.CloseCursor;
- raise;
- end;
- end;
- end;
-
- { TFieldDef }
-
- constructor TFieldDef.Create(Owner: TFieldDefs; const Name: string;
- DataType: TFieldType; Size: Word; Required: Boolean; FieldNo: Integer);
- var
- FieldClass: TFieldClass;
- begin
- FieldClass := Owner.FDataSet.GetFieldClass(DataType);
- if Assigned(FieldClass) then
- FieldClass.CheckTypeSize(Size);
- if Owner <> nil then
- begin
- Owner.FItems.Add(Self);
- Owner.FUpdated := False;
- FOwner := Owner;
- end;
- FName := Name;
- FDataType := DataType;
- FSize := Size;
- FRequired := Required;
- FFieldNo := FieldNo;
- end;
-
- destructor TFieldDef.Destroy;
- begin
- if FOwner <> nil then
- begin
- FOwner.FItems.Remove(Self);
- FOwner.FUpdated := False;
- end;
- end;
-
- function TFieldDef.CreateField(Owner: TComponent): TField;
- var
- FieldClass: TFieldClass;
- begin
- FieldClass := GetFieldClass;
- if FieldClass = nil then DatabaseErrorFmt(SUnknownFieldType, [Name]);
- Result := FieldClass.Create(Owner);
- try
- Result.FieldName := Name;
- Result.Size := FSize;
- Result.Required := FRequired;
- Result.SetFieldType(FDataType);
- if Result is TBCDField then
- TBCDField(Result).FPrecision := Precision;
- if FOwner <> nil then Result.DataSet := FOwner.FDataSet;
- except
- Result.Free;
- raise;
- end;
- end;
-
- function TFieldDef.GetFieldClass: TFieldClass;
- begin
- Result := FOwner.FDataSet.GetFieldClass(FDataType);
- end;
-
- { TFieldDefs }
-
- constructor TFieldDefs.Create(DataSet: TDataSet);
- begin
- FDataSet := DataSet;
- FItems := TList.Create;
- end;
-
- destructor TFieldDefs.Destroy;
- begin
- if FItems <> nil then Clear;
- FItems.Free;
- end;
-
- procedure TFieldDefs.Add(const Name: string; DataType: TFieldType;
- Size: Word; Required: Boolean);
- begin
- if Name = '' then DatabaseError(SFieldNameMissing);
- if IndexOf(Name) >= 0 then DatabaseErrorFmt(SDuplicateFieldName, [Name]);
- TFieldDef.Create(Self, Name, DataType, Size, Required, FItems.Count + 1);
- end;
-
- procedure TFieldDefs.Assign(FieldDefs: TFieldDefs);
- var
- I: Integer;
- begin
- Clear;
- for I := 0 to FieldDefs.Count - 1 do
- with FieldDefs[I] do Add(Name, DataType, Size, Required);
- end;
-
- procedure TFieldDefs.Clear;
- begin
- while FItems.Count > 0 do TFieldDef(FItems.Last).Free;
- end;
-
- function TFieldDefs.Find(const Name: string): TFieldDef;
- var
- I: Integer;
- begin
- I := IndexOf(Name);
- if I < 0 then DatabaseErrorFmt(SFieldNotFound, [FDataset.Name, Name]);
- Result := FItems[I];
- end;
-
- function TFieldDefs.GetCount: Integer;
- begin
- Result := FItems.Count;
- end;
-
- function TFieldDefs.GetItem(Index: Integer): TFieldDef;
- begin
- Result := FItems[Index];
- end;
-
- function TFieldDefs.IndexOf(const Name: string): Integer;
- begin
- for Result := 0 to FItems.Count - 1 do
- if AnsiCompareText(TFieldDef(FItems[Result]).Name, Name) = 0 then Exit;
- Result := -1;
- end;
-
- procedure TFieldDefs.Update;
- begin
- FDataSet.UpdateFieldDefs;
- end;
-
- { TLookupList }
-
- constructor TLookupList.Create;
- begin
- FList := TList.Create;
- end;
-
- destructor TLookupList.Destroy;
- begin
- if Assigned(FList) then Clear;
- FList.Free;
- end;
-
- procedure TLookupList.Add(const AKey, AValue: Variant);
- var
- ListEntry: PLookupListEntry;
- begin
- New(ListEntry);
- ListEntry.Key := AKey;
- ListEntry.Value := AValue;
- FList.Add(ListEntry);
- end;
-
- procedure TLookupList.Clear;
- var
- I: Integer;
- begin
- for I := 0 to FList.Count - 1 do
- Dispose(PLookupListEntry(FList.Items[I]));
- FList.Clear;
- end;
-
- function TLookupList.ValueOfKey(const AKey: Variant): Variant;
- var
- I: Integer;
- begin
- Result := Null;
- if not VarIsNull(AKey) then
- for I := 0 to FList.Count - 1 do
- if PLookupListEntry(FList.Items[I]).Key = AKey then
- begin
- Result := PLookupListEntry(FList.Items[I]).Value;
- Break;
- end;
- end;
-
- { TField }
-
- constructor TField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FVisible := True;
- FValidChars := [#0..#255];
- end;
-
- destructor TField.Destroy;
- begin
- if FDataSet <> nil then
- begin
- FDataSet.Close;
- FDataSet.RemoveField(Self);
- end;
- FLookupList.Free;
- inherited Destroy;
- end;
-
- function TField.AccessError(const TypeName: string): EDatabaseError;
- begin
- Result := EDatabaseError.Create(Format(SFieldAccessError,
- [DisplayName, TypeName]));
- end;
-
- procedure TField.Assign(Source: TPersistent);
- begin
- if Source = nil then
- begin
- Clear;
- Exit;
- end;
- if Source is TField then
- begin
- Value := TField(Source).Value;
- Exit;
- end;
- inherited Assign(Source);
- end;
-
- procedure TField.AssignValue(const Value: TVarRec);
-
- procedure Error;
- begin
- DatabaseErrorFmt(SFieldValueError, [DisplayName]);
- end;
-
- begin
- with Value do
- case VType of
- vtInteger:
- AsInteger := VInteger;
- vtBoolean:
- AsBoolean := VBoolean;
- vtChar:
- AsString := VChar;
- vtExtended:
- AsFloat := VExtended^;
- vtString:
- AsString := VString^;
- vtPointer:
- if VPointer <> nil then Error;
- vtPChar:
- AsString := VPChar;
- vtObject:
- if (VObject = nil) or (VObject is TPersistent) then
- Assign(TPersistent(VObject))
- else
- Error;
- vtAnsiString:
- AsString := string(VAnsiString);
- vtCurrency:
- AsCurrency := VCurrency^;
- vtVariant:
- if not VarIsEmpty(VVariant^) then AsVariant := VVariant^;
- else
- Error;
- end;
- end;
-
- procedure TField.Bind(Binding: Boolean);
- begin
- if FFieldKind = fkLookup then
- if Binding then
- begin
- if FLookupCache then
- RefreshLookupList
- else
- ValidateLookupInfo(True);
- end;
- end;
-
- procedure TField.CalcLookupValue;
- begin
- if FLookupCache then
- Value := LookupList.ValueOfKey(FDataSet.FieldValues[FKeyFields])
- else if (FLookupDataSet <> nil) and FLookupDataSet.Active then
- Value := FLookupDataSet.Lookup(FLookupKeyFields,
- FDataSet.FieldValues[FKeyFields], FLookupResultField);
- end;
-
- procedure TField.Change;
- begin
- if Assigned(FOnChange) then FOnChange(Self);
- end;
-
- procedure TField.CheckInactive;
- begin
- if FDataSet <> nil then FDataSet.CheckInactive;
- end;
-
- procedure TField.Clear;
- begin
- SetData(nil);
- end;
-
- procedure TField.DataChanged;
- begin
- FDataSet.DataEvent(deFieldChange, Longint(Self));
- end;
-
- procedure TField.DefineProperties(Filer: TFiler);
-
- function AttributeSetStored: Boolean;
- begin
- if Assigned(Filer.Ancestor) then
- Result := CompareText(FAttributeSet, TField(Filer.Ancestor).FAttributeSet) <> 0
- else
- Result := FAttributeSet <> '';
- end;
-
- function CalculatedStored: Boolean;
- begin
- if Assigned(Filer.Ancestor) then
- Result := Calculated <> TField(Filer.Ancestor).Calculated else
- Result := Calculated;
- end;
-
- function LookupStored: Boolean;
- begin
- if Assigned(Filer.Ancestor) then
- Result := Lookup <> TField(Filer.Ancestor).Lookup else
- Result := Lookup;
- end;
-
- begin
- Filer.DefineProperty('AttributeSet', ReadAttributeSet, WriteAttributeSet,
- AttributeSetStored);
- { For backwards compatibility }
- Filer.DefineProperty('Calculated', ReadCalculated, WriteCalculated,
- CalculatedStored);
- Filer.DefineProperty('Lookup', ReadLookup, WriteLookup, LookupStored);
- end;
-
- function TField.FieldKindStored: Boolean;
- begin
- Result := (FieldKind = fkInternalCalc);
- end;
-
- procedure TField.FocusControl;
- var
- Field: TField;
- begin
- if (FDataSet <> nil) and FDataSet.Active then
- begin
- Field := Self;
- FDataSet.DataEvent(deFocusControl, Longint(@Field));
- end;
- end;
-
- procedure TField.FreeBuffers;
- begin
- end;
-
- function TField.GetAsBoolean: Boolean;
- begin
- raise AccessError('Boolean'); { Do not localize }
- end;
-
- function TField.GetAsCurrency: Currency;
- begin
- Result := GetAsFloat;
- end;
-
- function TField.GetAsDateTime: TDateTime;
- begin
- raise AccessError('DateTime'); { Do not localize }
- end;
-
- function TField.GetAsFloat: Double;
- begin
- raise AccessError('Float'); { Do not localize }
- end;
-
- function TField.GetAsInteger: Longint;
- begin
- raise AccessError('Integer'); { Do not localize }
- end;
-
- function TField.GetAsString: string;
- var
- I, L: Integer;
- S: string[63];
- begin
- S := ClassName;
- I := 1;
- L := Length(S);
- if S[1] = 'T' then I := 2;
- if (L >= 5) and (CompareText(Copy(S, L - 4, 5), 'FIELD') = 0) then Dec(L, 5);
- FmtStr(Result, '(%s)', [Copy(S, I, L + 1 - I)]);
- if not IsNull then Result := AnsiUpperCase(Result);
- end;
-
- function TField.GetAsVariant: Variant;
- begin
- raise AccessError('Variant'); { Do not localize }
- end;
-
- function TField.GetCalculated: Boolean;
- begin
- Result := FFieldKind = fkCalculated;
- end;
-
- function TField.GetCanModify: Boolean;
- begin
- if FieldNo > 0 then
- if DataSet.State <> dsSetKey then
- Result := not ReadOnly and DataSet.CanModify else
- Result := IsIndexField
- else
- Result := False;
- end;
-
- function TField.GetData(Buffer: Pointer): Boolean;
- begin
- if FDataSet = nil then DatabaseErrorFmt(SDataSetMissing, [DisplayName]);
- if FValidating then
- begin
- Result := LongBool(FValueBuffer);
- if Result and (Buffer <> nil) then
- Move(FValueBuffer^, Buffer^, DataSize);
- end else
- Result := FDataSet.GetFieldData(Self, Buffer);
- end;
-
- function TField.GetDataSize: Word;
- begin
- Result := 0;
- end;
-
- function TField.GetDefaultWidth: Integer;
- begin
- Result := 10;
- end;
-
- function TField.GetDisplayLabel: string;
- begin
- Result := GetDisplayName;
- end;
-
- function TField.GetDisplayName: string;
- begin
- if FDisplayLabel <> '' then
- Result := FDisplayLabel else
- Result := FFieldName;
- end;
-
- function TField.GetDisplayText: string;
- begin
- Result := '';
- if Assigned(FOnGetText) then
- FOnGetText(Self, Result, True) else
- GetText(Result, True);
- end;
-
- function TField.GetDisplayWidth: Integer;
- begin
- if FDisplayWidth > 0 then
- Result := FDisplayWidth else
- Result := GetDefaultWidth;
- end;
-
- function TField.GetEditText: string;
- begin
- Result := '';
- if Assigned(FOnGetText) then
- FOnGetText(Self, Result, False) else
- GetText(Result, False);
- end;
-
- function TField.GetHasConstraints: Boolean;
- begin
- Result := (CustomConstraint <> '') or (ImportedConstraint <> '') or
- (DefaultExpression <> '');
- end;
-
- function TField.GetIndex: Integer;
- begin
- if FDataSet <> nil then
- Result := FDataSet.FFields.IndexOf(Self) else
- Result := -1;
- end;
-
- function TField.GetIsIndexField: Boolean;
- begin
- if FDataSet <> nil then
- Result := DataSet.GetIsIndexField(Self) else
- Result := False;
- end;
-
- class function TField.IsBlob: Boolean;
- begin
- Result := False;
- end;
-
- function TField.GetIsNull: Boolean;
- begin
- Result := not GetData(nil);
- end;
-
- function TField.GetLookup: Boolean;
- begin
- Result := FFieldKind = fkLookup;
- end;
-
- function TField.GetLookupList: TLookupList;
- begin
- if not Assigned(FLookupList) then
- FLookupList := TLookupList.Create;
- Result := FLookupList;
- end;
-
- procedure TField.GetText(var Text: string; DisplayText: Boolean);
- begin
- Text := GetAsString;
- end;
-
- function TField.HasParent: Boolean;
- begin
- HasParent := True;
- end;
-
- function TField.GetNewValue: Variant;
- begin
- Result := DataSet.GetStateFieldValue(dsNewValue, Self);
- end;
-
- function TField.GetOldValue: Variant;
- begin
- Result := DataSet.GetStateFieldValue(dsOldValue, Self);
- end;
-
- function TField.GetCurValue: Variant;
- begin
- Result := DataSet.GetStateFieldValue(dsCurValue, Self);
- end;
-
- function TField.GetParentComponent: TComponent;
- begin
- Result := DataSet;
- end;
-
- procedure TField.SetParentComponent(AParent: TComponent);
- begin
- if not (csLoading in ComponentState) then DataSet := AParent as TDataSet;
- end;
-
- function TField.IsValidChar(InputChar: Char): Boolean;
- begin
- Result := InputChar in ValidChars;
- end;
-
- function TField.IsDisplayLabelStored: Boolean;
- begin
- Result := FDisplayLabel <> '';
- end;
-
- function TField.IsDisplayWidthStored: Boolean;
- begin
- Result := FDisplayWidth > 0;
- end;
-
- procedure TField.Notification(AComponent: TComponent;
- Operation: TOperation);
- begin
- inherited Notification(AComponent, Operation);
- if (Operation = opRemove) and (AComponent = FLookupDataSet) then
- FLookupDataSet := nil;
- end;
-
- procedure TField.PropertyChanged(LayoutAffected: Boolean);
- const
- Events: array[Boolean] of TDataEvent = (deDataSetChange, deLayoutChange);
- begin
- if (FDataSet <> nil) and FDataSet.Active then
- FDataSet.DataEvent(Events[LayoutAffected], 0);
- end;
-
- procedure TField.ReadAttributeSet(Reader: TReader);
- begin
- FAttributeSet := Reader.ReadString;
- end;
-
- procedure TField.ReadCalculated(Reader: TReader);
- begin
- if Reader.ReadBoolean then
- FFieldKind := fkCalculated;
- end;
-
- procedure TField.ReadLookup(Reader: TReader);
- begin
- if Reader.ReadBoolean then
- FFieldKind := fkLookup;
- end;
-
- procedure TField.ReadState(Reader: TReader);
- begin
- inherited ReadState(Reader);
- if Reader.Parent is TDataSet then DataSet := TDataSet(Reader.Parent);
- end;
-
- procedure TField.RefreshLookupList;
- var
- WasActive: Boolean;
- begin
- if Assigned(FLookupDataSet) then
- begin
- WasActive := FLookupDataSet.Active;
- ValidateLookupInfo(True);
- with FLookupDataSet do
- try
- LookupList.Clear;
- DisableControls;
- try
- First;
- while not EOF do
- begin
- FLookupList.Add(FieldValues[FLookupKeyFields],
- FieldValues[FLookupResultField]);
- Next;
- end;
- finally
- EnableControls;
- end;
- finally
- Active := WasActive;
- end;
- end
- else
- ValidateLookupInfo(False);
- end;
-
- procedure TField.SetAsBoolean(Value: Boolean);
- begin
- raise AccessError('Boolean'); { Do not localize }
- end;
-
- procedure TField.SetAsCurrency(Value: Currency);
- begin
- SetAsFloat(Value);
- end;
-
- procedure TField.SetAsDateTime(Value: TDateTime);
- begin
- raise AccessError('DateTime'); { Do not localize }
- end;
-
- procedure TField.SetAsFloat(Value: Double);
- begin
- raise AccessError('Float'); { Do not localize }
- end;
-
- procedure TField.SetAsInteger(Value: Longint);
- begin
- raise AccessError('Integer'); { Do not localize }
- end;
-
- procedure TField.SetAsString(const Value: string);
- begin
- raise AccessError('String'); { Do not localize }
- end;
-
- procedure TField.SetAsVariant(const Value: Variant);
- begin
- if VarIsNull(Value) then
- Clear
- else
- try
- SetVarValue(Value);
- except
- on EVariantError do DatabaseErrorFmt(SFieldValueError, [DisplayName]);
- end;
- end;
-
- procedure TField.SetAlignment(Value: TAlignment);
- begin
- if FAlignment <> Value then
- begin
- FAlignment := Value;
- PropertyChanged(False);
- end;
- end;
-
- procedure TField.SetCalculated(Value: Boolean);
- begin
- if Value then
- FieldKind := fkCalculated
- else if FieldKind = fkCalculated then
- FieldKind := fkData;
- end;
-
- procedure TField.SetData(Buffer: Pointer);
- begin
- if FDataSet = nil then DatabaseErrorFmt(SDataSetMissing, [DisplayName]);
- FDataSet.SetFieldData(Self, Buffer);
- end;
-
- procedure TField.SetDataSet(ADataSet: TDataSet);
- begin
- if ADataset <> FDataset then
- begin
- if FDataSet <> nil then FDataSet.CheckInactive;
- if ADataSet <> nil then
- begin
- ADataSet.CheckInactive;
- ADataSet.CheckFieldName(FFieldName);
- end;
- if FDataSet <> nil then FDataSet.RemoveField(Self);
- if ADataSet <> nil then ADataSet.AddField(Self);
- end;
- end;
-
- procedure TField.SetDataType(Value: TFieldType);
- begin
- FDataType := Value;
- end;
-
- procedure TField.SetDisplayLabel(Value: string);
- begin
- if Value = FFieldName then Value := '';
- if FDisplayLabel <> Value then
- begin
- FDisplaylabel := Value;
- PropertyChanged(True);
- end;
- end;
-
- procedure TField.SetDisplayWidth(Value: Integer);
- begin
- if FDisplayWidth <> Value then
- begin
- FDisplayWidth := Value;
- PropertyChanged(True);
- end;
- end;
-
- procedure TField.SetEditMask(const Value: string);
- begin
- FEditMask := Value;
- PropertyChanged(False);
- end;
-
- procedure TField.SetEditText(const Value: string);
- begin
- if Assigned(FOnSetText) then FOnSetText(Self, Value) else SetText(Value);
- end;
-
- procedure TField.SetFieldKind(Value: TFieldKind);
- begin
- if FFieldKind <> Value then
- begin
- if Assigned(DataSet) and Assigned(DataSet.FDesigner) then
- with DataSet.Designer do
- begin
- BeginDesign;
- try
- FFieldKind := Value;
- finally
- EndDesign;
- end;
- end else
- begin
- CheckInactive;
- FFieldKind := Value;
- end;
- end;
- end;
-
- procedure TField.SetFieldName(const Value: string);
- begin
- CheckInactive;
- if FDataSet <> nil then FDataSet.CheckFieldName(Value);
- FFieldName := Value;
- if FDisplayLabel = Value then FDisplayLabel := '';
- if FDataSet <> nil then FDataSet.DataEvent(deFieldListChange, 0);
- end;
-
- procedure TField.SetFieldType(Value: TFieldType);
- begin
- end;
-
- procedure TField.SetIndex(Value: Integer);
- var
- CurIndex, Count: Integer;
- begin
- CurIndex := GetIndex;
- if CurIndex >= 0 then
- begin
- Count := FDataSet.FFields.Count;
- if Value < 0 then Value := 0;
- if Value >= Count then Value := Count - 1;
- if Value <> CurIndex then
- begin
- FDataSet.FFields.Delete(CurIndex);
- FDataSet.FFields.Insert(Value, Self);
- PropertyChanged(True);
- FDataSet.DataEvent(deFieldListChange, 0);
- end;
- end;
- end;
-
- procedure TField.SetLookup(Value: Boolean);
- begin
- if Value then
- FieldKind := fkLookup
- else if FieldKind = fkLookup then
- FieldKind := fkData;
- end;
-
- procedure TField.SetLookupDataSet(Value: TDataSet);
- begin
- CheckInactive;
- if (Value <> nil) and (Value = FDataSet) then DatabaseError(SCircularDataLink);
- FLookupDataSet := Value;
- end;
-
- procedure TField.SetLookupKeyFields(const Value: string);
- begin
- CheckInactive;
- FLookupKeyFields := Value;
- end;
-
- procedure TField.SetLookupResultField(const Value: string);
- begin
- CheckInactive;
- FLookupResultField := Value;
- end;
-
- procedure TField.SetKeyFields(const Value: string);
- begin
- CheckInactive;
- FKeyFields := Value;
- end;
-
- procedure TField.SetNewValue(const Value: Variant);
- begin
- DataSet.SetStateFieldValue(dsNewValue, Self, Value);
- end;
-
- procedure TField.SetLookupCache(const Value: Boolean);
- begin
- CheckInactive;
- FLookupCache := Value;
- end;
-
- class procedure TField.CheckTypeSize(Value: Integer);
- begin
- if (Value <> 0) and not IsBlob then DatabaseError(SInvalidFieldSize);
- end;
-
- procedure TField.SetSize(Value: Word);
- begin
- CheckInactive;
- CheckTypeSize(Value);
- FSize := Value;
- end;
-
- procedure TField.SetText(const Value: string);
- begin
- SetAsString(Value);
- end;
-
- procedure TField.SetReadOnly(const Value: Boolean);
- begin
- if FReadOnly <> Value then
- begin
- FReadOnly := Value;
- PropertyChanged(True);
- end;
- end;
-
- procedure TField.SetVarValue(const Value: Variant);
- begin
- raise AccessError('Variant'); { Do not localize }
- end;
-
- procedure TField.SetVisible(Value: Boolean);
- begin
- if FVisible <> Value then
- begin
- FVisible := Value;
- PropertyChanged(True);
- end;
- end;
-
- procedure TField.Validate(Buffer: Pointer);
- begin
- if Assigned(OnValidate) then
- begin
- FValueBuffer := Buffer;
- FValidating := True;
- try
- OnValidate(Self);
- finally
- FValidating := False;
- end;
- end;
- end;
-
- procedure TField.ValidateLookupInfo(All: Boolean);
- begin
- if (All and ((FLookupDataSet = nil) or (FLookupKeyFields = '') or
- (FLookupResultField = ''))) or (FKeyFields = '') then
- DatabaseErrorFmt(SLookupInfoError, [DisplayName]);
- FDataSet.CheckFieldNames(FKeyFields);
- if All then
- begin
- FLookupDataSet.Open;
- FLookupDataSet.CheckFieldNames(FLookupKeyFields);
- FLookupDataSet.FieldByName(FLookupResultField);
- end;
- end;
-
- procedure TField.WriteAttributeSet(Writer: TWriter);
- begin
- Writer.WriteString(FAttributeSet);
- end;
-
- procedure TField.WriteCalculated(Writer: TWriter);
- begin
- Writer.WriteBoolean(True);
- end;
-
- procedure TField.WriteLookup(Writer: TWriter);
- begin
- Writer.WriteBoolean(True);
- end;
-
- { TStringField }
-
- constructor TStringField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftString);
- Size := 20;
- Transliterate := True;
- end;
-
- class procedure TStringField.CheckTypeSize(Value: Integer);
- begin
- if (Value < 1) or (Value > dsMaxStringSize) then DatabaseError(SInvalidFieldSize);
- end;
-
- function TStringField.GetAsBoolean: Boolean;
- var
- S: string;
- begin
- S := GetAsString;
- Result := (Length(S) > 0) and (S[1] in ['T', 't', 'Y', 'y']);
- end;
-
- function TStringField.GetAsDateTime: TDateTime;
- begin
- Result := StrToDateTime(GetAsString);
- end;
-
- function TStringField.GetAsFloat: Double;
- begin
- Result := StrToFloat(GetAsString);
- end;
-
- function TStringField.GetAsInteger: Longint;
- begin
- Result := StrToInt(GetAsString);
- end;
-
- function TStringField.GetAsString: string;
- begin
- if not GetValue(Result) then Result := '';
- end;
-
- function TStringField.GetAsVariant: Variant;
- var
- S: string;
- begin
- if GetValue(S) then Result := S else Result := Null;
- end;
-
- function TStringField.GetDataSize: Word;
- begin
- Result := Size + 1;
- end;
-
- function TStringField.GetDefaultWidth: Integer;
- begin
- Result := Size;
- end;
-
- procedure TStringField.GetText(var Text: string; DisplayText: Boolean);
- begin
- if DisplayText and (EditMaskPtr <> '') then
- Text := FormatMaskText(EditMaskPtr, GetAsString) else
- Text := GetAsString;
- end;
-
- function TStringField.GetValue(var Value: string): Boolean;
- var
- Buffer: array[0..dsMaxStringSize] of Char;
- begin
- Result := GetData(@Buffer);
- if Result then
- begin
- Value := Buffer;
- if Transliterate and (Value <> '') then
- DataSet.Translate(PChar(Value), PChar(Value), False);
- end;
- end;
-
- procedure TStringField.SetAsBoolean(Value: Boolean);
- const
- Values: array[Boolean] of string[1] = ('F', 'T');
- begin
- SetAsString(Values[Value]);
- end;
-
- procedure TStringField.SetAsDateTime(Value: TDateTime);
- begin
- SetAsString(DateTimeToStr(Value));
- end;
-
- procedure TStringField.SetAsFloat(Value: Double);
- begin
- SetAsString(FloatToStr(Value));
- end;
-
- procedure TStringField.SetAsInteger(Value: Longint);
- begin
- SetAsString(IntToStr(Value));
- end;
-
- procedure TStringField.SetAsString(const Value: string);
- var
- Buffer: array[0..dsMaxStringSize] of Char;
- begin
- StrLCopy(Buffer, PChar(Value), Size);
- if Transliterate then
- DataSet.Translate(Buffer, Buffer, True);
- SetData(@Buffer);
- end;
-
- procedure TStringField.SetVarValue(const Value: Variant);
- begin
- SetAsString(Value);
- end;
-
- { TNumericField }
-
- constructor TNumericField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- Alignment := taRightJustify;
- end;
-
- procedure TNumericField.RangeError(Value, Min, Max: Extended);
- begin
- DatabaseErrorFmt(SFieldRangeError, [Value, DisplayName, Min, Max]);
- end;
-
- procedure TNumericField.SetDisplayFormat(const Value: string);
- begin
- if FDisplayFormat <> Value then
- begin
- FDisplayFormat := Value;
- PropertyChanged(False);
- end;
- end;
-
- procedure TNumericField.SetEditFormat(const Value: string);
- begin
- if FEditFormat <> Value then
- begin
- FEditFormat := Value;
- PropertyChanged(False);
- end;
- end;
-
- { TIntegerField }
-
- constructor TIntegerField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftInteger);
- FMinRange := Low(Longint);
- FMaxRange := High(Longint);
- ValidChars := ['+', '-', '0'..'9'];
- end;
-
- procedure TIntegerField.CheckRange(Value, Min, Max: Longint);
- begin
- if (Value < Min) or (Value > Max) then RangeError(Value, Min, Max);
- end;
-
- function TIntegerField.GetAsFloat: Double;
- begin
- Result := GetAsInteger;
- end;
-
- function TIntegerField.GetAsInteger: Longint;
- begin
- if not GetValue(Result) then Result := 0;
- end;
-
- function TIntegerField.GetAsString: string;
- var
- L: Longint;
- begin
- if GetValue(L) then Str(L, Result) else Result := '';
- end;
-
- function TIntegerField.GetAsVariant: Variant;
- var
- L: Longint;
- begin
- if GetValue(L) then Result := L else Result := Null;
- end;
-
- function TIntegerField.GetDataSize: Word;
- begin
- Result := SizeOf(Integer);
- end;
-
- procedure TIntegerField.GetText(var Text: string; DisplayText: Boolean);
- var
- L: Longint;
- FmtStr: string;
- begin
- if GetValue(L) then
- begin
- if DisplayText or (FEditFormat = '') then
- FmtStr := FDisplayFormat else
- FmtStr := FEditFormat;
- if FmtStr = '' then Str(L, Text) else Text := FormatFloat(FmtStr, L);
- end else
- Text := '';
- end;
-
- function TIntegerField.GetValue(var Value: Longint): Boolean;
- var
- Data: record
- case Integer of
- 0: (I: Smallint);
- 1: (W: Word);
- 2: (L: Longint);
- end;
- begin
- Result := GetData(@Data);
- if Result then
- case DataType of
- ftSmallint: Value := Data.I;
- ftWord: Value := Data.W;
- else
- Value := Data.L;
- end;
- end;
-
- procedure TIntegerField.SetAsFloat(Value: Double);
- begin
- SetAsInteger(Round(Value));
- end;
-
- procedure TIntegerField.SetAsInteger(Value: Longint);
- begin
- if (FMinValue <> 0) or (FMaxValue <> 0) then
- CheckRange(Value, FMinValue, FMaxValue) else
- CheckRange(Value, FMinRange, FMaxRange);
- SetData(@Value);
- end;
-
- procedure TIntegerField.SetAsString(const Value: string);
- var
- E: Integer;
- L: Longint;
- begin
- if Value = '' then Clear else
- begin
- Val(Value, L, E);
- if E <> 0 then DatabaseErrorFmt(SInvalidIntegerValue, [Value, DisplayName]);
- SetAsInteger(L);
- end;
- end;
-
- procedure TIntegerField.SetMaxValue(Value: Longint);
- begin
- CheckRange(Value, FMinRange, FMaxRange);
- FMaxValue := Value;
- end;
-
- procedure TIntegerField.SetMinValue(Value: Longint);
- begin
- CheckRange(Value, FMinRange, FMaxRange);
- FMinValue := Value;
- end;
-
- procedure TIntegerField.SetVarValue(const Value: Variant);
- begin
- SetAsInteger(Value);
- end;
-
- { TSmallintField }
-
- constructor TSmallintField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftSmallint);
- FMinRange := Low(Smallint);
- FMaxRange := High(Smallint);
- end;
-
- function TSmallintField.GetDataSize: Word;
- begin
- Result := SizeOf(SmallInt);
- end;
-
- { TWordField }
-
- constructor TWordField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftWord);
- FMinRange := Low(Word);
- FMaxRange := High(Word);
- end;
-
- function TWordField.GetDataSize: Word;
- begin
- Result := SizeOf(Word);
- end;
-
- { TAutoIncField }
-
- constructor TAutoIncField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftAutoInc);
- end;
-
- { TFloatField }
-
- constructor TFloatField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftFloat);
- FPrecision := 15;
- ValidChars := [DecimalSeparator, '+', '-', '0'..'9', 'E', 'e'];
- end;
-
- function TFloatField.GetAsFloat: Double;
- begin
- if not GetData(@Result) then Result := 0;
- end;
-
- function TFloatField.GetAsInteger: Longint;
- begin
- Result := Round(GetAsFloat);
- end;
-
- function TFloatField.GetAsString: string;
- var
- F: Double;
- begin
- if GetData(@F) then Result := FloatToStr(F) else Result := '';
- end;
-
- function TFloatField.GetAsVariant: Variant;
- var
- F: Double;
- begin
- if GetData(@F) then Result := F else Result := Null;
- end;
-
- function TFloatField.GetDataSize: Word;
- begin
- Result := SizeOf(Double);
- end;
-
- procedure TFloatField.GetText(var Text: string; DisplayText: Boolean);
- var
- Format: TFloatFormat;
- FmtStr: string;
- Digits: Integer;
- F: Double;
- begin
- if GetData(@F) then
- begin
- if DisplayText or (FEditFormat = '') then
- FmtStr := FDisplayFormat else
- FmtStr := FEditFormat;
- if FmtStr = '' then
- begin
- if FCurrency then
- begin
- if DisplayText then Format := ffCurrency else Format := ffFixed;
- Digits := CurrencyDecimals;
- end
- else begin
- Format := ffGeneral;
- Digits := 0;
- end;
- Text := FloatToStrF(F, Format, FPrecision, Digits);
- end else
- Text := FormatFloat(FmtStr, F);
- end else
- Text := '';
- end;
-
- procedure TFloatField.SetAsFloat(Value: Double);
- begin
- if FCheckRange and ((Value < FMinValue) or (Value > FMaxValue)) then
- RangeError(Value, FMinValue, FMaxValue);
- SetData(@Value);
- end;
-
- procedure TFloatField.SetAsInteger(Value: Longint);
- begin
- SetAsFloat(Value);
- end;
-
- procedure TFloatField.SetAsString(const Value: string);
- var
- F: Extended;
- begin
- if Value = '' then Clear else
- begin
- if not TextToFloat(PChar(Value), F, fvExtended) then
- DatabaseErrorFmt(SInvalidFloatValue, [Value, DisplayName]);
- SetAsFloat(F);
- end;
- end;
-
- procedure TFloatField.SetCurrency(Value: Boolean);
- begin
- if FCurrency <> Value then
- begin
- FCurrency := Value;
- PropertyChanged(False);
- end;
- end;
-
- procedure TFloatField.SetMaxValue(Value: Double);
- begin
- FMaxValue := Value;
- UpdateCheckRange;
- end;
-
- procedure TFloatField.SetMinValue(Value: Double);
- begin
- FMinValue := Value;
- UpdateCheckRange;
- end;
-
- procedure TFloatField.SetPrecision(Value: Integer);
- begin
- if Value < 2 then Value := 2;
- if Value > 15 then Value := 15;
- if FPrecision <> Value then
- begin
- FPrecision := Value;
- PropertyChanged(False);
- end;
- end;
-
- procedure TFloatField.SetVarValue(const Value: Variant);
- begin
- SetAsFloat(Value);
- end;
-
- procedure TFloatField.UpdateCheckRange;
- begin
- FCheckRange := (FMinValue <> 0) or (FMaxValue <> 0);
- end;
-
- { TCurrencyField }
-
- constructor TCurrencyField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftCurrency);
- FCurrency := True;
- end;
-
- { TBooleanField }
-
- constructor TBooleanField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftBoolean);
- LoadTextValues;
- end;
-
- function TBooleanField.GetAsBoolean: Boolean;
- var
- B: WordBool;
- begin
- if GetData(@B) then Result := B else Result := False;
- end;
-
- function TBooleanField.GetAsString: string;
- var
- B: WordBool;
- begin
- if GetData(@B) then Result := FTextValues[B] else Result := '';
- end;
-
- function TBooleanField.GetAsVariant: Variant;
- var
- B: WordBool;
- begin
- if GetData(@B) then Result := B else Result := Null;
- end;
-
- function TBooleanField.GetDataSize: Word;
- begin
- Result := SizeOf(WordBool);
- end;
-
- function TBooleanField.GetDefaultWidth: Integer;
- begin
- if Length(FTextValues[False]) > Length(FTextValues[True]) then
- Result := Length(FTextValues[False]) else
- Result := Length(FTextValues[True]);
- end;
-
- procedure TBooleanField.LoadTextValues;
- begin
- FTextValues[False] := STextFalse;
- FTextValues[True] := STextTrue;
- end;
-
- procedure TBooleanField.SetAsBoolean(Value: Boolean);
- var
- B: WordBool;
- begin
- if Value then Word(B) := 1 else Word(B) := 0;
- SetData(@B);
- end;
-
- procedure TBooleanField.SetAsString(const Value: string);
- var
- L: Integer;
- begin
- L := Length(Value);
- if L = 0 then
- begin
- if Length(FTextValues[False]) = 0 then SetAsBoolean(False) else
- if Length(FTextValues[True]) = 0 then SetAsBoolean(True) else
- Clear;
- end else
- begin
- if AnsiCompareText(Value, Copy(FTextValues[False], 1, L)) = 0 then
- SetAsBoolean(False)
- else
- if AnsiCompareText(Value, Copy(FTextValues[True], 1, L)) = 0 then
- SetAsBoolean(True)
- else
- DatabaseErrorFmt(SInvalidBoolValue, [Value, DisplayName]);
- end;
- end;
-
- procedure TBooleanField.SetDisplayValues(const Value: string);
- var
- P: Integer;
- begin
- if FDisplayValues <> Value then
- begin
- FDisplayValues := Value;
- if Value = '' then LoadTextValues else
- begin
- P := Pos(';', Value);
- if P = 0 then P := 256;
- FTextValues[False] := Copy(Value, P + 1, 255);
- FTextValues[True] := Copy(Value, 1, P - 1);
- end;
- PropertyChanged(True);
- end;
- end;
-
- procedure TBooleanField.SetVarValue(const Value: Variant);
- begin
- SetAsBoolean(Value);
- end;
-
- { TDateTimeField }
-
- constructor TDateTimeField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftDateTime);
- end;
-
- function TDateTimeField.GetAsDateTime: TDateTime;
- begin
- if not GetValue(Result) then Result := 0;
- end;
-
- function TDateTimeField.GetAsFloat: Double;
- begin
- Result := GetAsDateTime;
- end;
-
- function TDateTimeField.GetAsString: string;
- begin
- GetText(Result, False);
- end;
-
- function TDateTimeField.GetAsVariant: Variant;
- var
- D: TDateTime;
- begin
- if GetValue(D) then Result := VarFromDateTime(D) else Result := Null;
- end;
-
- function TDateTimeField.GetDataSize: Word;
- begin
- Result := SizeOf(TDateTime);
- end;
-
- procedure TDateTimeField.GetText(var Text: string; DisplayText: Boolean);
- var
- F: string;
- D: TDateTime;
- begin
- if GetValue(D) then
- begin
- if DisplayText and (FDisplayFormat <> '') then
- F := FDisplayFormat
- else
- case DataType of
- ftDate: F := ShortDateFormat;
- ftTime: F := LongTimeFormat;
- end;
- DateTimeToString(Text, F, D);
- end else
- Text := '';
- end;
-
- function TDateTimeField.GetValue(var Value: TDateTime): Boolean;
- var
- TimeStamp: TTimeStamp;
- Data: TDateTimeRec;
- begin
- Result := GetData(@Data);
- if Result then
- begin
- case DataType of
- ftDate:
- begin
- TimeStamp.Time := 0;
- TimeStamp.Date := Data.Date;
- end;
- ftTime:
- begin
- TimeStamp.Time := Data.Time;
- TimeStamp.Date := DateDelta;
- end;
- else
- try
- TimeStamp := MSecsToTimeStamp(Data.DateTime);
- except
- TimeStamp.Time := 0;
- TimeStamp.Date := 0;
- end;
- end;
- Value := TimeStampToDateTime(TimeStamp);
- end;
- end;
-
- procedure TDateTimeField.SetAsDateTime(Value: TDateTime);
- var
- TimeStamp: TTimeStamp;
- Data: TDateTimeRec;
- begin
- TimeStamp := DateTimeToTimeStamp(Value);
- case DataType of
- ftDate: Data.Date := TimeStamp.Date;
- ftTime: Data.Time := TimeStamp.Time;
- else
- Data.DateTime := TimeStampToMSecs(TimeStamp);
- end;
- SetData(@Data);
- end;
-
- procedure TDateTimeField.SetAsFloat(Value: Double);
- begin
- SetAsDateTime(Value);
- end;
-
- procedure TDateTimeField.SetAsString(const Value: string);
- var
- DateTime: TDateTime;
- begin
- if Value = '' then Clear else
- begin
- case DataType of
- ftDate: DateTime := StrToDate(Value);
- ftTime: DateTime := StrToTime(Value);
- else
- DateTime := StrToDateTime(Value);
- end;
- SetAsDateTime(DateTime);
- end;
- end;
-
- procedure TDateTimeField.SetDisplayFormat(const Value: string);
- begin
- if FDisplayFormat <> Value then
- begin
- FDisplayFormat := Value;
- PropertyChanged(False);
- end;
- end;
-
- procedure TDateTimeField.SetVarValue(const Value: Variant);
- begin
- SetAsDateTime(VarToDateTime(Value));
- end;
-
- { TDateField }
-
- constructor TDateField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftDate);
- end;
-
- function TDateField.GetDataSize: Word;
- begin
- Result := SizeOf(Integer);
- end;
-
- { TTimeField }
-
- constructor TTimeField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftTime);
- end;
-
- function TTimeField.GetDataSize: Word;
- begin
- Result := SizeOf(Integer);
- end;
-
- { TBinaryField }
-
- constructor TBinaryField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- end;
-
- class procedure TBinaryField.CheckTypeSize(Value: Integer);
- begin
- if (Value = 0) then DatabaseError(SInvalidFieldSize);
- end;
-
- function TBinaryField.GetAsString: string;
- begin
- SetLength(Result, DataSize);
- GetData(PChar(Result));
- end;
-
- procedure TBinaryField.SetAsString(const Value: string);
- var
- Data: string;
- Count: Integer;
- begin
- if Length(Value) = DataSize then
- Data := Value
- else
- begin
- SetLength(Data, DataSize);
- FillChar(PChar(Data)^, DataSize, #0);
- if Length(Value) > DataSize then
- Count := DataSize else
- Count := Length(Value);
- Move(PChar(Value)^, PChar(Data)^, Count);
- end;
- SetData(PChar(Data));
- end;
-
- function TBinaryField.GetAsVariant: Variant;
- var
- Data: Pointer;
- HasData: Boolean;
- begin
- Result := VarArrayCreate([0, DataSize - 1], varByte);
- Data := VarArrayLock(Result);
- try
- HasData := GetData(Data);
- finally
- VarArrayUnlock(Result);
- end;
- if not HasData then Result := Null;
- end;
-
- procedure TBinaryField.SetVarValue(const Value: Variant);
- var
- Data: Pointer;
- begin
- if not (VarIsArray(Value) and (VarArrayDimCount(Value) = 1) and
- ((VarType(Value) and VarTypeMask) = varByte) and
- ((VarArrayHighBound(Value, 1) - VarArrayLowBound(Value, 1) + 1) = DataSize)) then
- DatabaseError(SInvalidVarByteArray);
- Data := VarArrayLock(Value);
- try
- SetData(Data);
- finally
- VarArrayUnlock(Value);
- end;
- end;
-
- procedure TBinaryField.GetText(var Text: string; DisplayText: Boolean);
- begin
- Text := inherited GetAsString;
- end;
-
- procedure TBinaryField.SetText(const Value: string);
- begin
- raise AccessError('Text');
- end;
-
- { TBytesField }
-
- constructor TBytesField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftBytes);
- Size := 16;
- end;
-
- function TBytesField.GetDataSize: Word;
- begin
- Result := Size;
- end;
-
- { TVarBytesField }
-
- constructor TVarBytesField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftVarBytes);
- Size := 16;
- end;
-
- function TVarBytesField.GetDataSize: Word;
- begin
- Result := Size + 2;
- end;
-
- { TBCDField }
-
- constructor TBCDField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftBCD);
- Size := 4;
- ValidChars := [DecimalSeparator, '+', '-', '0'..'9'];
- end;
-
- class procedure TBCDField.CheckTypeSize(Value: Integer);
- begin
- if Value > 32 then DatabaseError(SInvalidFieldSize);
- end;
-
- function TBCDField.GetAsCurrency: Currency;
- begin
- if not GetValue(Result) then Result := 0;
- end;
-
- function TBCDField.GetAsFloat: Double;
- begin
- Result := GetAsCurrency;
- end;
-
- function TBCDField.GetAsInteger: Longint;
- begin
- Result := Round(GetAsCurrency);
- end;
-
- function TBCDField.GetAsString: string;
- var
- C: System.Currency;
- begin
- if GetValue(C) then Result := CurrToStr(C) else Result := '';
- end;
-
- function TBCDField.GetAsVariant: Variant;
- var
- C: System.Currency;
- begin
- if GetValue(C) then Result := C else Result := Null;
- end;
-
- function TBCDField.GetDataSize: Word;
- begin
- Result := 34; { sizeof FMTBCD (BDE) }
- end;
-
- function TBCDField.GetDefaultWidth: Integer;
- begin
- if FPrecision > 0 then
- Result := FPrecision + 1 else
- Result := inherited GetDefaultWidth;
- end;
-
- procedure TBCDField.GetText(var Text: string; DisplayText: Boolean);
- var
- Format: TFloatFormat;
- Digits: Integer;
- FmtStr: string;
- BCD: array[0..255] of Byte;
- C: System.Currency;
- begin
- if GetData(@BCD) then
- if DataSet.BCDToCurr(@BCD, C) then
- begin
- if DisplayText or (EditFormat = '') then
- FmtStr := DisplayFormat else
- FmtStr := EditFormat;
- if FmtStr = '' then
- begin
- if FCurrency then
- begin
- if DisplayText then Format := ffCurrency else Format := ffFixed;
- Digits := CurrencyDecimals;
- end
- else begin
- Format := ffGeneral;
- Digits := 0;
- end;
- Text := CurrToStrF(C, Format, Digits);
- end else
- Text := FormatCurr(FmtStr, C);
- end else
- Text := SBCDOverflow
- else
- Text := '';
- end;
-
- function TBCDField.GetValue(var Value: Currency): Boolean;
- var
- BCD: array[0..255] of Byte;
- begin
- Result := GetData(@BCD);
- if Result then
- if not FDataSet.BCDToCurr(@BCD, Value) then
- DatabaseErrorFmt(SFieldOutOfRange, [DisplayName]);
- end;
-
- procedure TBCDField.SetAsCurrency(Value: Currency);
- var
- BCD: array[0..255] of Byte;
- begin
- if FCheckRange and ((Value < FMinValue) or (Value > FMaxValue)) then
- RangeError(Value, FMinValue, FMaxValue);
- FDataSet.CurrToBCD(Value, @BCD, FPrecision, Size);
- SetData(@BCD);
- end;
-
- procedure TBCDField.SetAsFloat(Value: Double);
- begin
- SetAsCurrency(Value);
- end;
-
- procedure TBCDField.SetAsInteger(Value: Longint);
- begin
- SetAsCurrency(Value);
- end;
-
- procedure TBCDField.SetAsString(const Value: string);
- var
- C: System.Currency;
- begin
- if Value = '' then Clear else
- begin
- if not TextToFloat(PChar(Value), C, fvCurrency) then
- DatabaseErrorFmt(SInvalidFloatValue, [Value, DisplayName]);
- SetAsCurrency(C);
- end;
- end;
-
- procedure TBCDField.SetCurrency(Value: Boolean);
- begin
- if FCurrency <> Value then
- begin
- FCurrency := Value;
- PropertyChanged(False);
- end;
- end;
-
- procedure TBCDField.SetMaxValue(Value: Currency);
- begin
- FMaxValue := Value;
- UpdateCheckRange;
- end;
-
- procedure TBCDField.SetMinValue(Value: Currency);
- begin
- FMinValue := Value;
- UpdateCheckRange;
- end;
-
- procedure TBCDField.SetVarValue(const Value: Variant);
- begin
- SetAsCurrency(Value);
- end;
-
- procedure TBCDField.UpdateCheckRange;
- begin
- FCheckRange := (FMinValue <> 0) or (FMaxValue <> 0);
- end;
-
- { TBlobField }
-
- constructor TBlobField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftBlob);
- end;
-
- procedure TBlobField.Assign(Source: TPersistent);
- begin
- if Source is TBlobField then
- begin
- LoadFromBlob(TBlobField(Source));
- Exit;
- end;
- if Source is TStrings then
- begin
- LoadFromStrings(TStrings(Source));
- Exit;
- end;
- if Source is TBitmap then
- begin
- LoadFromBitmap(TBitmap(Source));
- Exit;
- end;
- if (Source is TPicture) and (TPicture(Source).Graphic is TBitmap) then
- begin
- LoadFromBitmap(TBitmap(TPicture(Source).Graphic));
- Exit;
- end;
- inherited Assign(Source);
- end;
-
- procedure TBlobField.AssignTo(Dest: TPersistent);
- begin
- if Dest is TStrings then
- begin
- SaveToStrings(TStrings(Dest));
- Exit;
- end;
- if Dest is TBitmap then
- begin
- SaveToBitmap(TBitmap(Dest));
- Exit;
- end;
- if Dest is TPicture then
- begin
- SaveToBitmap(TPicture(Dest).Bitmap);
- Exit;
- end;
- inherited AssignTo(Dest);
- end;
-
- procedure TBlobField.Clear;
- begin
- DataSet.CreateBlobStream(Self, bmWrite).Free;
- end;
-
- procedure TBlobField.FreeBuffers;
- begin
- if FModified then
- begin
- Dataset.CloseBlob(Self);
- FModified := False;
- end;
- end;
-
- function TBlobField.GetAsString: string;
- var
- Len: Integer;
- begin
- with DataSet.CreateBlobStream(Self, bmRead) do
- try
- Len := Size;
- SetString(Result, nil, Len);
- ReadBuffer(Pointer(Result)^, Len);
- finally
- Free;
- end;
- end;
-
- function TBlobField.GetAsVariant: Variant;
- begin
- Result := GetAsString;
- end;
-
- function TBlobField.GetBlobSize: Integer;
- begin
- with DataSet.CreateBlobStream(Self, bmRead) do
- try
- Result := Size;
- finally
- Free;
- end;
- end;
-
- function TBlobField.GetBlobType: TBlobType;
- begin
- Result := TBlobType(DataType);
- end;
-
- function TBlobField.GetIsNull: Boolean;
- begin
- if Modified then
- begin
- with DataSet.CreateBlobStream(Self, bmRead) do
- try
- Result := (Size = 0);
- finally
- Free;
- end;
- end else
- Result := inherited GetIsNull;
- end;
-
- function TBlobField.GetModified: Boolean;
- begin
- Result := FModified and (FModifiedRecord = DataSet.ActiveRecord);
- end;
-
- procedure TBlobField.GetText(var Text: string; DisplayText: Boolean);
- begin
- Text := inherited GetAsString;
- end;
-
- class function TBlobField.IsBlob: Boolean;
- begin
- Result := True;
- end;
-
- procedure TBlobField.LoadFromBitmap(Bitmap: TBitmap);
- var
- BlobStream: TStream;
- Header: TGraphicHeader;
- begin
- BlobStream := DataSet.CreateBlobStream(Self, bmWrite);
- try
- if (DataType = ftGraphic) or (DataType = ftTypedBinary) then
- begin
- Header.Count := 1;
- Header.HType := $0100;
- Header.Size := 0;
- BlobStream.Write(Header, SizeOf(Header));
- Bitmap.SaveToStream(BlobStream);
- Header.Size := BlobStream.Position - SizeOf(Header);
- BlobStream.Position := 0;
- BlobStream.Write(Header, SizeOf(Header));
- end else
- Bitmap.SaveToStream(BlobStream);
- finally
- BlobStream.Free;
- end;
- end;
-
- procedure TBlobField.LoadFromBlob(Blob: TBlobField);
- var
- BlobStream: TStream;
- begin
- BlobStream := DataSet.CreateBlobStream(Self, bmWrite);
- try
- Blob.SaveToStream(BlobStream);
- finally
- BlobStream.Free;
- end;
- end;
-
- procedure TBlobField.LoadFromFile(const FileName: string);
- var
- Stream: TStream;
- begin
- Stream := TFileStream.Create(FileName, fmOpenRead);
- try
- LoadFromStream(Stream);
- finally
- Stream.Free;
- end;
- end;
-
- procedure TBlobField.LoadFromStream(Stream: TStream);
- begin
- with DataSet.CreateBlobStream(Self, bmWrite) do
- try
- CopyFrom(Stream, 0);
- finally
- Free;
- end;
- end;
-
- procedure TBlobField.LoadFromStrings(Strings: TStrings);
- var
- BlobStream: TStream;
- begin
- BlobStream := DataSet.CreateBlobStream(Self, bmWrite);
- try
- Strings.SaveToStream(BlobStream);
- finally
- BlobStream.Free;
- end;
- end;
-
- procedure TBlobField.SaveToBitmap(Bitmap: TBitmap);
- var
- BlobStream: TStream;
- Size: Longint;
- Header: TGraphicHeader;
- begin
- BlobStream := DataSet.CreateBlobStream(Self, bmRead);
- try
- Size := BlobStream.Size;
- if Size >= SizeOf(TGraphicHeader) then
- begin
- BlobStream.Read(Header, SizeOf(Header));
- if (Header.Count <> 1) or (Header.HType <> $0100) or
- (Header.Size <> Size - SizeOf(Header)) then
- BlobStream.Position := 0;
- end;
- Bitmap.LoadFromStream(BlobStream);
- finally
- BlobStream.Free;
- end;
- end;
-
- procedure TBlobField.SaveToFile(const FileName: string);
- var
- Stream: TStream;
- begin
- Stream := TFileStream.Create(FileName, fmCreate);
- try
- SaveToStream(Stream);
- finally
- Stream.Free;
- end;
- end;
-
- procedure TBlobField.SaveToStream(Stream: TStream);
- var
- BlobStream: TStream;
- begin
- BlobStream := DataSet.CreateBlobStream(Self, bmRead);
- try
- Stream.CopyFrom(BlobStream, 0);
- finally
- BlobStream.Free;
- end;
- end;
-
- procedure TBlobField.SaveToStrings(Strings: TStrings);
- var
- BlobStream: TStream;
- begin
- BlobStream := DataSet.CreateBlobStream(Self, bmRead);
- try
- Strings.LoadFromStream(BlobStream);
- finally
- BlobStream.Free;
- end;
- end;
-
- procedure TBlobField.SetAsString(const Value: string);
- begin
- with DataSet.CreateBlobStream(Self, bmWrite) do
- try
- WriteBuffer(Pointer(Value)^, Length(Value));
- finally
- Free;
- end;
- end;
-
- procedure TBlobField.SetBlobType(Value: TBlobType);
- begin
- SetFieldType(Value);
- end;
-
- procedure TBlobField.SetFieldType(Value: TFieldType);
- begin
- if Value in [Low(TBlobType)..High(TBlobType)] then SetDataType(Value);
- end;
-
- procedure TBlobField.SetModified(Value: Boolean);
- begin
- FModified := Value;
- if FModified then
- FModifiedRecord := DataSet.ActiveRecord;
- end;
-
- procedure TBlobField.SetText(const Value: string);
- begin
- raise AccessError('Text');
- end;
-
- procedure TBlobField.SetVarValue(const Value: Variant);
- begin
- SetAsString(Value);
- end;
-
- { TMemoField }
-
- constructor TMemoField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftMemo);
- Transliterate := True;
- end;
-
- { TGraphicField }
-
- constructor TGraphicField.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- SetDataType(ftGraphic);
- end;
-
- { TIndexDef }
-
- constructor TIndexDef.Create(Owner: TIndexDefs; const Name, Fields: string;
- Options: TIndexOptions);
- begin
- if Owner <> nil then
- begin
- Owner.FItems.Add(Self);
- Owner.FUpdated := False;
- FOwner := Owner;
- end;
- FName := Name;
- FFields := Fields;
- FOptions := Options;
- end;
-
- destructor TIndexDef.Destroy;
- begin
- if FOwner <> nil then
- begin
- FOwner.FItems.Remove(Self);
- FOwner.FUpdated := False;
- end;
- end;
-
- function TIndexDef.GetExpression: string;
- begin
- if ixExpression in Options then Result := FFields else Result := '';
- end;
-
- function TIndexDef.GetFields: string;
- begin
- if ixExpression in Options then Result := '' else Result := FFields;
- end;
-
- { TIndexDefs }
-
- constructor TIndexDefs.Create(DataSet: TDataSet);
- begin
- FDataSet := DataSet;
- FItems := TList.Create;
- end;
-
- destructor TIndexDefs.Destroy;
- begin
- if FItems <> nil then Clear;
- FItems.Free;
- end;
-
- procedure TIndexDefs.Add(const Name, Fields: string;
- Options: TIndexOptions);
- begin
- if IndexOf(Name) >= 0 then DatabaseErrorFmt(SDuplicateIndexName, [Name]);
- TIndexDef.Create(Self, Name, Fields, Options);
- end;
-
- procedure TIndexDefs.Assign(IndexDefs: TIndexDefs);
- var
- I: Integer;
- begin
- Clear;
- for I := 0 to IndexDefs.Count - 1 do
- with IndexDefs[I] do Add(Name, Fields, Options);
- end;
-
- procedure TIndexDefs.Clear;
- begin
- while FItems.Count > 0 do TIndexDef(FItems.Last).Free;
- end;
-
- function TIndexDefs.FindIndexForFields(const Fields: string): TIndexDef;
- begin
- Result := GetIndexForFields(Fields, False);
- if Result = nil then
- DatabaseErrorFmt(SNoIndexForFields, [FDataSet.Name, Fields]);
- end;
-
- function TIndexDefs.GetCount: Integer;
- begin
- Result := FItems.Count;
- end;
-
- function TIndexDefs.GetIndexForFields(const Fields: string;
- CaseInsensitive: Boolean): TIndexDef;
- var
- Exact: Boolean;
- I, L: Integer;
- begin
- Update;
- L := Length(Fields);
- Exact := True;
- while True do
- begin
- for I := 0 to FItems.Count - 1 do
- begin
- Result := FItems[I];
- if (Result.FOptions * [ixDescending, ixExpression] = []) and
- (not CaseInsensitive or (ixCaseInsensitive in Result.FOptions)) then
- if Exact then
- begin
- if AnsiCompareText(Fields, Result.Fields) = 0 then Exit;
- end
- else begin
- if (AnsiCompareText(Fields, Copy(Result.Fields, 1, L)) = 0) and
- ((Length(Result.FFields) = L) or
- (Result.FFields[L + 1] = ';')) then Exit;
- end;
- end;
- if not Exact then Break;
- Exact := False;
- end;
- Result := nil;
- end;
-
- function TIndexDefs.GetItem(Index: Integer): TIndexDef;
- begin
- Result := FItems[Index];
- end;
-
- function TIndexDefs.IndexOf(const Name: string): Integer;
- begin
- for Result := 0 to FItems.Count - 1 do
- if AnsiCompareText(TIndexDef(FItems[Result]).FName, Name) = 0 then Exit;
- Result := -1;
- end;
-
- procedure TIndexDefs.Update;
- begin
- FDataSet.UpdateIndexDefs;
- end;
-
- { TDataLink }
-
- constructor TDataLink.Create;
- begin
- inherited Create;
- FBufferCount := 1;
- end;
-
- destructor TDataLink.Destroy;
- begin
- FActive := False;
- FEditing := False;
- FDataSourceFixed := False;
- SetDataSource(nil);
- inherited Destroy;
- end;
-
- procedure TDataLink.UpdateRange;
- var
- Min, Max: Integer;
- begin
- Min := DataSet.FActiveRecord - FBufferCount + 1;
- if Min < 0 then Min := 0;
- Max := DataSet.FBufferCount - FBufferCount;
- if Max < 0 then Max := 0;
- if Max > DataSet.FActiveRecord then Max := DataSet.FActiveRecord;
- if FFirstRecord < Min then FFirstRecord := Min;
- if FFirstRecord > Max then FFirstRecord := Max;
- end;
-
- function TDataLink.GetDataSet: TDataSet;
- begin
- if DataSource <> nil then Result := DataSource.DataSet else Result := nil;
- end;
-
- procedure TDataLink.SetDataSource(ADataSource: TDataSource);
- begin
- if FDataSource <> ADataSource then
- begin
- if FDataSourceFixed then DatabaseError(SDataSourceChange);
- if FDataSource <> nil then FDataSource.RemoveDataLink(Self);
- if ADataSource <> nil then ADataSource.AddDataLink(Self);
- end;
- end;
-
- procedure TDataLink.SetReadOnly(Value: Boolean);
- begin
- if FReadOnly <> Value then
- begin
- FReadOnly := Value;
- UpdateState;
- end;
- end;
-
- procedure TDataLink.SetActive(Value: Boolean);
- begin
- if FActive <> Value then
- begin
- FActive := Value;
- if Value then UpdateRange else FFirstRecord := 0;
- ActiveChanged;
- end;
- end;
-
- procedure TDataLink.SetEditing(Value: Boolean);
- begin
- if FEditing <> Value then
- begin
- FEditing := Value;
- EditingChanged;
- end;
- end;
-
- procedure TDataLink.UpdateState;
- begin
- SetActive((DataSource <> nil) and (DataSource.State <> dsInactive));
- SetEditing((DataSource <> nil) and (DataSource.State in dsEditModes) and
- not FReadOnly);
- end;
-
- procedure TDataLink.UpdateRecord;
- begin
- FUpdating := True;
- try
- UpdateData;
- finally
- FUpdating := False;
- end;
- end;
-
- function TDataLink.Edit: Boolean;
- begin
- if not FReadOnly and (DataSource <> nil) then DataSource.Edit;
- Result := FEditing;
- end;
-
- function TDataLink.GetActiveRecord: Integer;
- begin
- if DataSource.State = dsSetKey then
- Result := 0 else
- Result := DataSource.DataSet.FActiveRecord - FFirstRecord;
- end;
-
- procedure TDataLink.SetActiveRecord(Value: Integer);
- begin
- if DataSource.State <> dsSetKey then
- DataSource.DataSet.FActiveRecord := Value + FFirstRecord;
- end;
-
- procedure TDataLink.SetBufferCount(Value: Integer);
- begin
- if FBufferCount <> Value then
- begin
- FBufferCount := Value;
- if Active then
- begin
- UpdateRange;
- DataSet.UpdateBufferCount;
- UpdateRange;
- end;
- end;
- end;
-
- function TDataLink.GetRecordCount: Integer;
- begin
- if DataSource.State = dsSetKey then Result := 1 else
- begin
- Result := DataSource.DataSet.FRecordCount;
- if Result > FBufferCount then Result := FBufferCount;
- end;
- end;
-
- procedure TDataLink.DataEvent(Event: TDataEvent; Info: Longint);
- var
- Active, First, Last, Count: Integer;
- begin
- if Event = deUpdateState then UpdateState else
- if FActive then
- case Event of
- deFieldChange, deRecordChange:
- if not FUpdating then RecordChanged(TField(Info));
- deDataSetChange, deDataSetScroll, deLayoutChange:
- begin
- Count := 0;
- if DataSource.State <> dsSetKey then
- begin
- Active := DataSource.DataSet.FActiveRecord;
- First := FFirstRecord + Info;
- Last := First + FBufferCount - 1;
- if Active > Last then Count := Active - Last else
- if Active < First then Count := Active - First;
- FFirstRecord := First + Count;
- end;
- case Event of
- deDataSetChange: DataSetChanged;
- deDataSetScroll: DataSetScrolled(Count);
- deLayoutChange: LayoutChanged;
- end;
- end;
- deUpdateRecord:
- UpdateRecord;
- deCheckBrowseMode:
- CheckBrowseMode;
- deFocusControl:
- FocusControl(TFieldRef(Info));
- end;
- end;
-
- procedure TDataLink.ActiveChanged;
- begin
- end;
-
- procedure TDataLink.CheckBrowseMode;
- begin
- end;
-
- procedure TDataLink.DataSetChanged;
- begin
- RecordChanged(nil);
- end;
-
- procedure TDataLink.DataSetScrolled(Distance: Integer);
- begin
- DataSetChanged;
- end;
-
- procedure TDataLink.EditingChanged;
- begin
- end;
-
- procedure TDataLink.FocusControl(Field: TFieldRef);
- begin
- end;
-
- procedure TDataLink.LayoutChanged;
- begin
- DataSetChanged;
- end;
-
- procedure TDataLink.RecordChanged(Field: TField);
- begin
- end;
-
- procedure TDataLink.UpdateData;
- begin
- end;
-
- { TDataSource }
-
- constructor TDataSource.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FDataLinks := TList.Create;
- FEnabled := True;
- FAutoEdit := True;
- end;
-
- destructor TDataSource.Destroy;
- begin
- FOnStateChange := nil;
- SetDataSet(nil);
- while FDataLinks.Count > 0 do RemoveDataLink(FDataLinks.Last);
- FDataLinks.Free;
- inherited Destroy;
- end;
-
- procedure TDataSource.Edit;
- begin
- if AutoEdit and (State = dsBrowse) then DataSet.Edit;
- end;
-
- procedure TDataSource.SetState(Value: TDataSetState);
- var
- PriorState: TDataSetState;
- begin
- if FState <> Value then
- begin
- PriorState := FState;
- FState := Value;
- NotifyDataLinks(deUpdateState, 0);
- if not (csDestroying in ComponentState) then
- begin
- if Assigned(FOnStateChange) then FOnStateChange(Self);
- if PriorState = dsInactive then
- if Assigned(FOnDataChange) then FOnDataChange(Self, nil);
- end;
- end;
- end;
-
- procedure TDataSource.UpdateState;
- begin
- if Enabled and (DataSet <> nil) then
- SetState(DataSet.State) else
- SetState(dsInactive);
- end;
-
- function TDataSource.IsLinkedTo(DataSet: TDataSet): Boolean;
- var
- DataSource: TDataSource;
- begin
- Result := True;
- while DataSet <> nil do
- begin
- DataSource := DataSet.GetDataSource;
- if DataSource = nil then Break;
- if DataSource = Self then Exit;
- DataSet := DataSource.DataSet;
- end;
- Result := False;
- end;
-
- procedure TDataSource.SetDataSet(ADataSet: TDataSet);
- begin
- if IsLinkedTo(ADataSet) then DatabaseError(SCircularDataLink);
- if FDataSet <> nil then FDataSet.RemoveDataSource(Self);
- if ADataSet <> nil then ADataSet.AddDataSource(Self);
- end;
-
- procedure TDataSource.SetEnabled(Value: Boolean);
- begin
- FEnabled := Value;
- UpdateState;
- end;
-
- procedure TDataSource.AddDataLink(DataLink: TDataLink);
- begin
- FDataLinks.Add(DataLink);
- DataLink.FDataSource := Self;
- if DataSet <> nil then DataSet.UpdateBufferCount;
- DataLink.UpdateState;
- end;
-
- procedure TDataSource.RemoveDataLink(DataLink: TDataLink);
- begin
- DataLink.FDataSource := nil;
- FDataLinks.Remove(DataLink);
- DataLink.UpdateState;
- if DataSet <> nil then DataSet.UpdateBufferCount;
- end;
-
- procedure TDataSource.NotifyDataLinks(Event: TDataEvent; Info: Longint);
- var
- I: Integer;
- begin
- for I := 0 to FDataLinks.Count - 1 do
- with TDataLink(FDataLinks[I]) do
- if FBufferCount = 1 then DataEvent(Event, Info);
- for I := 0 to FDataLinks.Count - 1 do
- with TDataLink(FDataLinks[I]) do
- if FBufferCount > 1 then DataEvent(Event, Info);
- end;
-
- procedure TDataSource.DataEvent(Event: TDataEvent; Info: Longint);
- begin
- if Event = deUpdateState then UpdateState else
- if FState <> dsInactive then
- begin
- NotifyDataLinks(Event, Info);
- case Event of
- deFieldChange:
- if Assigned(FOnDataChange) then FOnDataChange(Self, TField(Info));
- deRecordChange, deDataSetChange, deDataSetScroll, deLayoutChange:
- if Assigned(FOnDataChange) then FOnDataChange(Self, nil);
- deUpdateRecord:
- if Assigned(FOnUpdateData) then FOnUpdateData(Self);
- end;
- end;
- end;
-
- { TCheckConstraint }
-
- procedure TCheckConstraint.Assign(Source: TPersistent);
- begin
- if Source is TCheckConstraint then
- begin
- ImportedConstraint := TCheckConstraint(Source).ImportedConstraint;
- CustomConstraint := TCheckConstraint(Source).CustomConstraint;
- ErrorMessage := TCheckConstraint(Source).ErrorMessage;
- end
- else inherited Assign(Source);
- end;
-
- function TCheckConstraint.GetDisplayName: string;
- begin
- Result := ImportedConstraint;
- if Result = '' then Result := CustomConstraint;
- if Result = '' then Result := inherited GetDisplayName;
- end;
-
- procedure TCheckConstraint.SetImportedConstraint(const Value: string);
- begin
- if ImportedConstraint <> Value then
- begin
- FImportedConstraint := Value;
- Changed(True);
- end;
- end;
-
- procedure TCheckConstraint.SetCustomConstraint(const Value: string);
- begin
- if CustomConstraint <> Value then
- begin
- FCustomConstraint := Value;
- Changed(True);
- end;
- end;
-
- procedure TCheckConstraint.SetErrorMessage(const Value: string);
- begin
- if ErrorMessage <> Value then
- begin
- FErrorMessage := Value;
- Changed(True);
- end;
- end;
-
- { TCheckConstraints }
-
- constructor TCheckConstraints.Create(Owner: TPersistent);
- begin
- inherited Create(TCheckConstraint);
- FOwner := Owner;
- end;
-
- function TCheckConstraints.Add: TCheckConstraint;
- begin
- Result := TCheckConstraint(inherited Add);
- end;
-
- function TCheckConstraints.GetOwner: TPersistent;
- begin
- Result := FOwner;
- end;
-
- function TCheckConstraints.GetItem(Index: Integer): TCheckConstraint;
- begin
- Result := TCheckConstraint(inherited GetItem(Index));
- end;
-
- procedure TCheckConstraints.SetItem(Index: Integer; Value: TCheckConstraint);
- begin
- inherited SetItem(Index, Value);
- end;
-
- { TDataSet }
-
- constructor TDataSet.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FFieldDefs := TFieldDefs.Create(Self);
- FFields := TList.Create;
- FDataSources := TList.Create;
- FAutoCalcFields := True;
- FConstraints := TCheckConstraints.Create(Self);
- ClearBuffers;
- end;
-
- destructor TDataSet.Destroy;
- begin
- Destroying;
- Close;
- FDesigner.Free;
- if Assigned(FDataSources) then
- while FDataSources.Count > 0 do
- RemoveDataSource(FDataSources.Last);
- FDataSources.Free;
- if Assigned(FFields) then
- DestroyFields;
- FFields.Free;
- FFieldDefs.Free;
- FConstraints.Free;
- inherited Destroy;
- end;
-
- procedure TDataSet.SetName(const Value: TComponentName);
- var
- I: Integer;
- OldName, FieldName, NamePrefix: TComponentName;
- Field: TField;
- begin
- OldName := Name;
- inherited SetName(Value);
- if (csDesigning in ComponentState) and (Name <> OldName) then
- { In design mode the name of the fields should track the data set name }
- for I := 0 to FFields.Count - 1 do
- begin
- Field := FFields[I];
- if Field.Owner = Owner then
- begin
- FieldName := Field.Name;
- NamePrefix := FieldName;
- if Length(NamePrefix) > Length(OldName) then
- begin
- SetLength(NamePrefix, Length(OldName));
- if CompareText(OldName, NamePrefix) = 0 then
- begin
- System.Delete(FieldName, 1, Length(OldName));
- System.Insert(Value, FieldName, 1);
- try
- Field.Name := FieldName;
- except
- on EComponentError do {Ignore rename errors };
- end;
- end;
- end;
- end;
- end;
- end;
-
- procedure TDataSet.GetChildren(Proc: TGetChildProc; Root: TComponent);
- var
- I: Integer;
- Field: TField;
- begin
- for I := 0 to FFields.Count - 1 do
- begin
- Field := FFields[I];
- if Field.Owner = Root then Proc(Field);
- end;
- end;
-
- procedure TDataSet.SetChildOrder(Component: TComponent; Order: Integer);
- begin
- if FFields.IndexOf(Component) >= 0 then
- (Component as TField).Index := Order;
- end;
-
- procedure TDataSet.Loaded;
- begin
- inherited Loaded;
- try
- if FStreamedActive then Active := True;
- except
- if csDesigning in ComponentState then
- InternalHandleException else
- raise;
- end;
- end;
-
- procedure TDataSet.SetState(Value: TDataSetState);
- begin
- if FState <> Value then
- begin
- FState := Value;
- FModified := False;
- DataEvent(deUpdateState, 0);
- end;
- end;
-
- procedure TDataSet.SetModified(Value: Boolean);
- begin
- FModified := Value;
- end;
-
- function TDataSet.GetFound: Boolean;
- begin
- Result := FFound;
- end;
-
- procedure TDataSet.SetFound(const Value: Boolean);
- begin
- FFound := Value;
- end;
-
- function TDataSet.SetTempState(const Value: TDataSetState): TDataSetState;
- begin
- Result := FState;
- FState := Value;
- Inc(FDisableCount);
- FModified := False;
- end;
-
- procedure TDataSet.RestoreState(const Value: TDataSetState);
- begin
- FState := Value;
- Dec(FDisableCount);
- FModified := False;
- end;
-
- procedure TDataSet.Open;
- begin
- Active := True;
- end;
-
- procedure TDataSet.Close;
- begin
- Active := False;
- end;
-
- procedure TDataSet.CheckInactive;
- begin
- if Active then
- if csUpdating in ComponentState then
- Close else
- DatabaseError(SDataSetOpen);
- end;
-
- procedure TDataSet.CheckActive;
- begin
- if State = dsInactive then DatabaseError(SDataSetClosed);
- end;
-
- function TDataSet.GetActive: Boolean;
- begin
- Result := State <> dsInactive;
- end;
-
- procedure TDataSet.SetActive(Value: Boolean);
- begin
- if (csReading in ComponentState) then
- begin
- if Value then FStreamedActive := True;
- end
- else
- if Active <> Value then
- begin
- if Value then
- begin
- DoBeforeOpen;
- try
- OpenCursor(False);
- SetState(dsBrowse);
- except
- SetState(dsInactive);
- CloseCursor;
- raise;
- end;
- DoAfterOpen;
- DoAfterScroll;
- end else
- begin
- if not (csDestroying in ComponentState) then DoBeforeClose;
- SetState(dsInactive);
- CloseCursor;
- if not (csDestroying in ComponentState) then DoAfterClose;
- end;
- end;
- end;
-
- procedure TDataSet.DoInternalOpen;
- begin
- FDefaultFields := FieldCount = 0;
- InternalOpen;
- UpdateBufferCount;
- FBOF := True;
- end;
-
- procedure TDataSet.DoInternalClose;
- begin
- FreeFieldBuffers;
- ClearBuffers;
- SetBufListSize(0);
- InternalClose;
- FBufferCount := 0;
- FDefaultFields := False;
- end;
-
- procedure TDataSet.OpenCursor(InfoQuery: Boolean);
- begin
- if InfoQuery then
- InternalInitFieldDefs else
- DoInternalOpen;
- end;
-
- procedure TDataSet.CloseCursor;
- begin
- DoInternalClose;
- end;
-
- procedure TDataSet.InitFieldDefs;
- begin
- if not Active then
- try
- OpenCursor(True);
- finally
- CloseCursor;
- end;
- end;
-
- { Field Management }
-
- function TDataSet.GetFieldClass(FieldType: TFieldType): TFieldClass;
- begin
- Result := DefaultFieldClasses[FieldType];
- end;
-
- procedure TDataSet.CreateFields;
- var
- I: Integer;
- begin
- for I := 0 to FFieldDefs.Count - 1 do
- with FFieldDefs[I] do
- if DataType <> ftUnknown then CreateField(Self);
- end;
-
- procedure TDataSet.DestroyFields;
- var
- Field: TField;
- begin
- while FFields.Count > 0 do
- begin
- Field := FFields.Last;
- RemoveField(Field);
- Field.Free;
- end;
- end;
-
- procedure TDataSet.BindFields(Binding: Boolean);
- const
- CalcFieldTypes = [ftString, ftSmallint, ftInteger, ftWord, ftBoolean,
- ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime];
- BaseTypes: array[TFieldType] of TFieldType = (
- ftUnknown, ftString, ftSmallint, ftInteger, ftWord,
- ftBoolean, ftFloat, ftFloat, ftBCD, ftDate, ftTime, ftDateTime,
- ftBytes, ftVarBytes, ftInteger, ftBlob, ftBlob, ftBlob,
- ftBlob, ftBlob, ftBlob, ftBlob, ftUnknown);
- var
- I: Integer;
- FieldDef: TFieldDef;
- begin
- FCalcFieldsSize := 0;
- FBlobFieldCount := 0;
- FInternalCalcFields := False;
- for I := 0 to FFields.Count - 1 do
- with TField(FFields[I]) do
- if Binding then
- begin
- if FieldKind in [fkCalculated, fkLookup] then
- begin
- if not (DataType in CalcFieldTypes) then
- DatabaseErrorFmt(SInvalidCalcType, [DisplayName]);
- FFieldNo := -1;
- FOffset := FCalcFieldsSize;
- Inc(FCalcFieldsSize, DataSize + 1);
- end else
- begin
- FieldDef := FieldDefs.Find(FFieldName);
- if (BaseTypes[DataType] <> BaseTypes[FieldDef.DataType]) or
- (Size <> FieldDef.Size) then
- begin
- { Ignore size check for blob field types (BDE 3.5->4.0 comp issue) }
- if (BaseTypes[DataType] = ftBlob) then
- FSize := FieldDef.Size else
- DatabaseErrorFmt(SFieldTypeMismatch, [DisplayName]);
- end;
- FFieldNo := FieldDef.FieldNo;
- if FieldDef.InternalCalcField then
- FInternalCalcFields := True;
- if BaseTypes[FieldDef.DataType] = ftBlob then
- begin
- FOffset := FBlobFieldCount;
- Inc(FBlobFieldCount);
- end;
- end;
- Bind(True);
- end else
- begin
- Bind(False);
- FFieldNo := 0;
- end;
- end;
-
- procedure TDataSet.AddField(Field: TField);
- begin
- FFields.Add(Field);
- Field.FDataSet := Self;
- DataEvent(deFieldListChange, 0)
- end;
-
- procedure TDataSet.RemoveField(Field: TField);
- begin
- Field.FDataSet := nil;
- FFields.Remove(Field);
- if not (csDestroying in ComponentState) then
- DataEvent(deFieldListChange, 0)
- end;
-
- procedure TDataSet.FreeFieldBuffers;
- var
- I: Integer;
- begin
- for I := 0 to FFields.Count - 1 do TField(FFields[I]).FreeBuffers;
- end;
-
- procedure TDataSet.SetFieldDefs(Value: TFieldDefs);
- begin
- FFieldDefs.Assign(Value);
- end;
-
- procedure TDataSet.UpdateFieldDefs;
- begin
- if not FFieldDefs.FUpdated then
- begin
- InitFieldDefs;
- FFieldDefs.FUpdated := True;
- end;
- end;
-
- function TDataSet.GetFieldCount: Integer;
- begin
- Result := FFields.Count;
- end;
-
- function TDataSet.GetField(Index: Integer): TField;
- begin
- Result := FFields[Index];
- end;
-
- procedure TDataSet.SetField(Index: Integer; Value: TField);
- begin
- TField(FFields[Index]).Assign(Value);
- end;
-
- function TDataSet.GetFieldValue(const FieldName: string): Variant;
- var
- I: Integer;
- Fields: TList;
- begin
- if Pos(';', FieldName) <> 0 then
- begin
- Fields := TList.Create;
- try
- GetFieldList(Fields, FieldName);
- Result := VarArrayCreate([0, Fields.Count - 1], varVariant);
- for I := 0 to Fields.Count - 1 do
- Result[I] := TField(Fields[I]).Value;
- finally
- Fields.Free;
- end;
- end else
- Result := FieldByName(FieldName).Value
- end;
-
- procedure TDataSet.SetFieldValue(const FieldName: string;
- const Value: Variant);
- var
- I: Integer;
- Fields: TList;
- begin
- if Pos(';', FieldName) <> 0 then
- begin
- Fields := TList.Create;
- try
- GetFieldList(Fields, FieldName);
- for I := 0 to Fields.Count - 1 do
- TField(Fields[I]).Value := Value[I];
- finally
- Fields.Free;
- end;
- end else
- FieldByName(FieldName).Value := Value;
- end;
-
- function TDataSet.FieldByName(const FieldName: string): TField;
- begin
- Result := FindField(FieldName);
- if Result = nil then DatabaseErrorFmt(SFieldNotFound, [Name, FieldName]);
- end;
-
- function TDataSet.FieldByNumber(FieldNo: Integer): TField;
- var
- I: Integer;
- begin
- for I := 0 to FFields.Count - 1 do
- begin
- Result := Fields[I];
- if Result.FieldNo = FieldNo then Exit;
- end;
- Result := nil;
- end;
-
- function TDataSet.FindField(const FieldName: string): TField;
- var
- I: Integer;
- begin
- for I := 0 to FFields.Count - 1 do
- begin
- Result := FFields[I];
- if AnsiCompareText(Result.FFieldName, FieldName) = 0 then Exit;
- end;
- Result := nil;
- end;
-
- procedure TDataSet.SetConstraints(const Value: TCheckConstraints);
- begin
- FConstraints.Assign(Value);
- end;
-
- procedure TDataSet.CheckFieldName(const FieldName: string);
- begin
- if FieldName = '' then DatabaseError(SFieldNameMissing);
- if FindField(FieldName) <> nil then
- DatabaseErrorFmt(SDuplicateFieldName, [FieldName]);
- end;
-
- procedure TDataSet.CheckFieldNames(const FieldNames: string);
- var
- Pos: Integer;
- begin
- Pos := 1;
- while Pos <= Length(FieldNames) do
- FieldByName(ExtractFieldName(FieldNames, Pos));
- end;
-
- procedure TDataSet.GetFieldNames(List: TStrings);
- var
- I: Integer;
- begin
- List.BeginUpdate;
- try
- List.Clear;
- if FFields.Count > 0 then
- for I := 0 to FFields.Count - 1 do
- List.Add(TField(FFields[I]).FFieldName)
- else
- begin
- UpdateFieldDefs;
- for I := 0 to FFieldDefs.Count - 1 do
- List.Add(FFieldDefs[I].Name);
- end;
- finally
- List.EndUpdate;
- end;
- end;
-
- function TDataSet.GetStateFieldValue(State: TDataSetState; Field: TField): Variant;
- var
- SaveState: TDataSetState;
- begin
- if Field.FieldKind in [fkData, fkInternalCalc] then
- begin
- SaveState := FState;
- FState := State;
- try
- Result := Field.AsVariant;
- finally
- FState := SaveState;
- end;
- end else
- Result := NULL;
- end;
-
- procedure TDataSet.SetStateFieldValue(State: TDataSetState; Field: TField; Value: Variant);
- var
- SaveState: TDataSetState;
- begin
- if Field.FieldKind <> fkData then Exit;
- SaveState := FState;
- FState := State;
- try
- Field.AsVariant := Value;
- finally
- FState := SaveState;
- end;
- end;
-
- procedure TDataSet.CloseBlob(Field: TField);
- begin
- end;
-
- function TDataSet.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream;
- begin
- Result := nil;
- end;
-
- function TDataSet.BCDToCurr(BCD: Pointer; var Curr: Currency): Boolean;
- begin
- Result := False;
- end;
-
- function TDataSet.CurrToBCD(const Curr: Currency; BCD: Pointer; Precision,
- Decimals: Integer): Boolean;
- begin
- Result := False;
- end;
-
- { Index Related }
-
- function TDataSet.GetIsIndexField(Field: TField): Boolean;
- begin
- Result := False;
- end;
-
- procedure TDataSet.UpdateIndexDefs;
- begin
- end;
-
- { Datasource/Datalink Interaction }
-
- function TDataSet.GetDataSource: TDataSource;
- begin
- Result := nil;
- end;
-
- function TDataSet.IsLinkedTo(DataSource: TDataSource): Boolean;
- var
- DataSet: TDataSet;
- begin
- Result := True;
- while DataSource <> nil do
- begin
- DataSet := DataSource.DataSet;
- if DataSet = nil then Break;
- if DataSet = Self then Exit;
- DataSource := DataSet.DataSource;
- end;
- Result := False;
- end;
-
- procedure TDataSet.AddDataSource(DataSource: TDataSource);
- begin
- FDataSources.Add(DataSource);
- DataSource.FDataSet := Self;
- UpdateBufferCount;
- DataSource.UpdateState;
- end;
-
- procedure TDataSet.RemoveDataSource(DataSource: TDataSource);
- begin
- DataSource.FDataSet := nil;
- FDataSources.Remove(DataSource);
- DataSource.UpdateState;
- UpdateBufferCount;
- end;
-
- procedure TDataSet.DataEvent(Event: TDataEvent; Info: Longint);
- var
- I: Integer;
- begin
- case Event of
- deFieldChange:
- begin
- if TField(Info).FieldKind in [fkData, fkInternalCalc] then
- FModified := True;
- if State <> dsSetKey then
- begin
- if FInternalCalcFields and (TField(Info).FieldKind = fkData) then
- RefreshInternalCalcFields(ActiveBuffer)
- else if (FCalcFieldsSize <> 0) and FAutoCalcFields and
- (TField(Info).FieldKind = fkData) then
- CalculateFields(ActiveBuffer);
- TField(Info).Change;
- end;
- end;
- dePropertyChange:
- FFieldDefs.FUpdated := False;
- end;
- if FDisableCount = 0 then
- begin
- for I := 0 to FDataSources.Count - 1 do
- TDataSource(FDataSources[I]).DataEvent(Event, Info);
- if FDesigner <> nil then FDesigner.DataEvent(Event, Info);
- end else
- if (Event = deUpdateState) and (State = dsInactive) or
- (Event = deLayoutChange) then FEnableEvent := deLayoutChange;
- end;
-
- function TDataset.ControlsDisabled: Boolean;
- begin
- Result := FDisableCount <> 0;
- end;
-
- procedure TDataSet.DisableControls;
- begin
- if FDisableCount = 0 then
- begin
- FDisableState := FState;
- FEnableEvent := deDataSetChange;
- end;
- Inc(FDisableCount);
- end;
-
- procedure TDataSet.EnableControls;
- begin
- if FDisableCount <> 0 then
- begin
- Dec(FDisableCount);
- if FDisableCount = 0 then
- begin
- if FDisableState <> FState then DataEvent(deUpdateState, 0);
- if (FDisableState <> dsInactive) and (FState <> dsInactive) then
- DataEvent(FEnableEvent, 0);
- end;
- end;
- end;
-
- procedure TDataSet.UpdateRecord;
- begin
- if not (State in dsEditModes) then DatabaseError(SNotEditing);
- DataEvent(deUpdateRecord, 0);
- end;
-
- { Buffer Management }
-
- procedure TDataSet.SetBufListSize(Value: Integer);
- var
- I: Integer;
- NewList: PBufferList;
- begin
- if FBufListSize <> Value then
- begin
- if Value > 0 then
- GetMem(NewList, Value * SizeOf(Pointer)) else
- NewList := nil;
- if FBufListSize > Value then
- begin
- if Value <> 0 then
- Move(FBuffers^, NewList^, Value * SizeOf(Pointer));
- for I := Value to FBufListSize - 1 do
- FreeRecordBuffer(FBuffers^[I]);
- end else
- begin
- if FBufListSize <> 0 then
- Move(FBuffers^, NewList^, FBufListSize * SizeOf(Pointer));
- I := FBufListSize;
- try
- while I < Value do
- begin
- NewList^[I] := AllocRecordBuffer;
- Inc(I);
- end;
- except
- while I > FBufListSize do
- begin
- FreeRecordBuffer(NewList^[I]);
- Dec(I);
- end;
- FreeMem(NewList, Value * SizeOf(Pointer));
- raise;
- end;
- end;
- FreeMem(FBuffers, FBufListSize * SizeOf(Pointer));
- FBuffers := NewList;
- FBufListSize := Value;
- end;
- end;
-
- procedure TDataSet.SetBufferCount(Value: Integer);
- var
- I, Delta: Integer;
- DataLink: TDataLink;
-
- procedure AdjustFirstRecord(Delta: Integer);
- var
- DataLink: TDataLink;
- begin
- if Delta <> 0 then
- begin
- DataLink := FFirstDataLink;
- while DataLink <> nil do
- begin
- if DataLink.Active then Inc(DataLink.FFirstRecord, Delta);
- DataLink := DataLink.FNext;
- end;
- end;
- end;
-
- begin
- if FBufferCount <> Value then
- begin
- if (FBufferCount > Value) and (FRecordCount > 0) then
- begin
- Delta := FActiveRecord;
- DataLink := FFirstDataLink;
- while DataLink <> nil do
- begin
- if DataLink.Active and (DataLink.FFirstRecord < Delta) then
- Delta := DataLink.FFirstRecord;
- DataLink := DataLink.FNext;
- end;
- for I := 0 to Value - 1 do MoveBuffer(I + Delta, I);
- Dec(FActiveRecord, Delta);
- if FCurrentRecord <> -1 then Dec(FCurrentRecord, Delta);
- if FRecordCount > Value then FRecordCount := Value;
- AdjustFirstRecord(-Delta);
- end;
- SetBufListSize(Value + 1);
- FBufferCount := Value;
- GetNextRecords;
- AdjustFirstRecord(GetPriorRecords);
- end;
- end;
-
- procedure TDataSet.UpdateBufferCount;
- var
- I, J, MaxBufferCount: Integer;
- DataLink: TDataLink;
- begin
- if IsCursorOpen then
- begin
- MaxBufferCount := 1;
- FFirstDataLink := nil;
- for I := FDataSources.Count - 1 downto 0 do
- with TDataSource(FDataSources[I]) do
- for J := FDataLinks.Count - 1 downto 0 do
- begin
- DataLink := FDataLinks[J];
- DataLink.FNext := FFirstDataLink;
- FFirstDataLink := DataLink;
- if DataLink.FBufferCount > MaxBufferCount then
- MaxBufferCount := DataLink.FBufferCount;
- end;
- SetBufferCount(MaxBufferCount);
- end;
- end;
-
- procedure TDataSet.SetCurrentRecord(Index: Integer);
- var
- Buffer: PChar;
- begin
- if FCurrentRecord <> Index then
- begin
- Buffer := FBuffers[Index];
- case GetBookmarkFlag(Buffer) of
- bfCurrent,
- bfInserted: InternalSetToRecord(Buffer);
- bfBOF: InternalFirst;
- bfEOF: InternalLast;
- end;
- FCurrentRecord := Index;
- end;
- end;
-
- function TDataSet.GetBuffer(Index: Integer): PChar;
- begin
- Result := FBuffers[Index];
- end;
-
- function TDataSet.GetNextRecord: Boolean;
- var
- GetMode: TGetMode;
- begin
- GetMode := gmNext;
- if FRecordCount > 0 then
- begin
- SetCurrentRecord(FRecordCount - 1);
- if (State = dsInsert) and (FCurrentRecord = FActiveRecord) and
- (GetBookmarkFlag(ActiveBuffer) = bfCurrent) then GetMode := gmCurrent;
- end;
- Result := (GetRecord(FBuffers[FRecordCount], GetMode, True) = grOK);
- if Result then
- begin
- if FRecordCount = 0 then
- ActivateBuffers
- else
- if FRecordCount < FBufferCount then
- Inc(FRecordCount) else
- MoveBuffer(0, FRecordCount);
- FCurrentRecord := FRecordCount - 1;
- Result := True;
- end else
- CursorPosChanged;
- end;
-
- function TDataSet.GetPriorRecord: Boolean;
- begin
- if FRecordCount > 0 then SetCurrentRecord(0);
- Result := (GetRecord(FBuffers[FRecordCount], gmPrior, True) = grOK);
- if Result then
- begin
- if FRecordCount = 0 then
- ActivateBuffers else
- begin
- MoveBuffer(FRecordCount, 0);
- if FRecordCount < FBufferCount then
- begin
- Inc(FRecordCount);
- Inc(FActiveRecord);
- end;
- end;
- FCurrentRecord := 0;
- end else
- CursorPosChanged;
- end;
-
- procedure TDataSet.Resync(Mode: TResyncMode);
- var
- Count: Integer;
- begin
- if rmExact in Mode then
- begin
- CursorPosChanged;
- if GetRecord(FBuffers[FRecordCount], gmCurrent, True) <> grOK then
- DatabaseError(SRecordNotFound);
- end else
- if (GetRecord(FBuffers[FRecordCount], gmCurrent, False) <> grOK) and
- (GetRecord(FBuffers[FRecordCount], gmNext, False) <> grOK) and
- (GetRecord(FBuffers[FRecordCount], gmPrior, False) <> grOK) then
- begin
- ClearBuffers;
- DataEvent(deDataSetChange, 0);
- Exit;
- end;
- if rmCenter in Mode then
- Count := (FBufferCount - 1) div 2 else
- Count := FActiveRecord;
- MoveBuffer(FRecordCount, 0);
- ActivateBuffers;
- try
- while (Count > 0) and GetPriorRecord do Dec(Count);
- GetNextRecords;
- GetPriorRecords;
- except
- end;
- DataEvent(deDataSetChange, 0);
- end;
-
- procedure TDataSet.MoveBuffer(CurIndex, NewIndex: Integer);
- var
- Buffer: PChar;
- begin
- if CurIndex <> NewIndex then
- begin
- Buffer := FBuffers[CurIndex];
- if CurIndex < NewIndex then
- Move(FBuffers[CurIndex + 1], FBuffers[CurIndex],
- (NewIndex - CurIndex) * SizeOf(Pointer))
- else
- Move(FBuffers[NewIndex], FBuffers[NewIndex + 1],
- (CurIndex - NewIndex) * SizeOf(Pointer));
- FBuffers[NewIndex] := Buffer;
- end;
- end;
-
- function TDataSet.ActiveBuffer: PChar;
- begin
- Result := FBuffers[FActiveRecord];
- end;
-
- function TDataSet.TempBuffer: PChar;
- begin
- Result := FBuffers[FRecordCount];
- end;
-
- procedure TDataSet.ClearBuffers;
- begin
- FRecordCount := 0;
- FActiveRecord := 0;
- FCurrentRecord := -1;
- FBOF := True;
- FEOF := True;
- end;
-
- procedure TDataSet.ActivateBuffers;
- begin
- FRecordCount := 1;
- FActiveRecord := 0;
- FCurrentRecord := 0;
- FBOF := False;
- FEOF := False;
- end;
-
- procedure TDataSet.UpdateCursorPos;
- begin
- if FRecordCount > 0 then SetCurrentRecord(FActiveRecord);
- end;
-
- procedure TDataSet.CursorPosChanged;
- begin
- FCurrentRecord := -1;
- end;
-
- function TDataSet.GetCurrentRecord(Buffer: PChar): Boolean;
- begin
- Result := False;
- end;
-
- function TDataSet.GetNextRecords: Integer;
- begin
- Result := 0;
- try
- while (FRecordCount < FBufferCount) and GetNextRecord do Inc(Result);
- except
- end;
- end;
-
- function TDataSet.GetPriorRecords: Integer;
- begin
- Result := 0;
- try
- while (FRecordCount < FBufferCount) and GetPriorRecord do Inc(Result);
- except
- end;
- end;
-
- procedure TDataSet.InitRecord(Buffer: PChar);
- begin
- InternalInitRecord(Buffer);
- ClearCalcFields(Buffer);
- SetBookmarkFlag(Buffer, bfInserted);
- end;
-
- function TDataSet.IsEmpty: Boolean;
- begin
- Result := FActiveRecord >= FRecordCount;
- end;
-
- procedure TDataSet.GetCalcFields(Buffer: PChar);
- var
- SaveState: TDataSetState;
- begin
- if (FCalcFieldsSize > 0) or FInternalCalcFields then
- begin
- SaveState := FState;
- FState := dsCalcFields;
- try
- CalculateFields(Buffer);
- finally
- FState := SaveState;
- end;
- end;
- end;
-
- procedure TDataSet.CalculateFields(Buffer: PChar);
- var
- I: Integer;
- begin
- FCalcBuffer := Buffer;
- ClearCalcFields(CalcBuffer);
- for I := 0 to FFields.Count - 1 do
- with TField(FFields[I]) do
- if FieldKind = fkLookup then CalcLookupValue;
- DoOnCalcFields;
- end;
-
- procedure TDataSet.ClearCalcFields(Buffer: PChar);
- begin
- end;
-
- procedure TDataSet.RefreshInternalCalcFields(Buffer: PChar);
- var
- I: Integer;
- begin
- for I := 0 to FieldCount - 1 do
- with Fields[I] do
- if (FieldKind = fkInternalCalc) then Value := Value;
- end;
-
- { Navigation }
-
- procedure TDataSet.First;
- begin
- CheckBrowseMode;
- DoBeforeScroll;
- ClearBuffers;
- try
- InternalFirst;
- GetNextRecord;
- GetNextRecords;
- finally
- FBOF := True;
- DataEvent(deDataSetChange, 0);
- DoAfterScroll;
- end;
- end;
-
- procedure TDataSet.Last;
- begin
- CheckBrowseMode;
- DoBeforeScroll;
- ClearBuffers;
- try
- InternalLast;
- GetPriorRecord;
- GetPriorRecords;
- finally
- FEOF := True;
- DataEvent(deDataSetChange, 0);
- DoAfterScroll;
- end;
- end;
-
- function TDataSet.MoveBy(Distance: Integer): Integer;
- var
- OldRecordCount, ScrollCount, I: Integer;
- begin
- CheckBrowseMode;
- Result := 0;
- DoBeforeScroll;
- if ((Distance > 0) and not FEOF) or ((Distance < 0) and not FBOF) then
- begin
- FBOF := False;
- FEOF := False;
- OldRecordCount := FRecordCount;
- ScrollCount := 0;
- try
- while Distance > 0 do
- begin
- if FActiveRecord < FRecordCount - 1 then Inc(FActiveRecord) else
- begin
- if FRecordCount < FBufferCount then I := 0 else I := 1;
- if GetNextRecord then
- begin
- Dec(ScrollCount, I);
- if FActiveRecord < FRecordCount - 1 then Inc(FActiveRecord);
- end else
- begin
- FEOF := True;
- Break;
- end;
- end;
- Dec(Distance);
- Inc(Result);
- end;
- while Distance < 0 do
- begin
- if FActiveRecord > 0 then Dec(FActiveRecord) else
- begin
- if FRecordCount < FBufferCount then I := 0 else I := 1;
- if GetPriorRecord then
- begin
- Inc(ScrollCount, I);
- if FActiveRecord > 0 then Dec(FActiveRecord);
- end else
- begin
- FBOF := True;
- Break;
- end;
- end;
- Inc(Distance);
- Dec(Result);
- end;
- finally
- if FRecordCount <> OldRecordCount then
- DataEvent(deDataSetChange, 0) else
- DataEvent(deDataSetScroll, ScrollCount);
- DoAfterScroll;
- end;
- end;
- end;
-
- procedure TDataSet.Next;
- begin
- MoveBy(1);
- end;
-
- procedure TDataSet.Prior;
- begin
- MoveBy(-1);
- end;
-
- procedure TDataSet.Refresh;
- begin
- CheckBrowseMode;
- UpdateCursorPos;
- InternalRefresh;
- Resync([]);
- end;
-
- { Editing }
-
- procedure TDataSet.Edit;
- begin
- if not (State in [dsEdit, dsInsert]) then
- if FRecordCount = 0 then Insert else
- begin
- CheckBrowseMode;
- CheckCanModify;
- DoBeforeEdit;
- CheckOperation(InternalEdit, FOnEditError);
- GetCalcFields(ActiveBuffer);
- SetState(dsEdit);
- DataEvent(deRecordChange, 0);
- DoAfterEdit;
- end;
- end;
-
- procedure TDataSet.Insert;
- var
- Buffer: PChar;
- OldCurrent: TBookmarkStr;
- begin
- BeginInsertAppend;
- OldCurrent := Bookmark;
- MoveBuffer(FRecordCount, FActiveRecord);
- Buffer := ActiveBuffer;
- InitRecord(Buffer);
- if FRecordCount = 0 then
- SetBookmarkFlag(Buffer, bfBOF) else
- SetBookmarkData(Buffer, Pointer(OldCurrent));
- if FRecordCount < FBufferCount then Inc(FRecordCount);
- EndInsertAppend;
- end;
-
- procedure TDataSet.Append;
- var
- Buffer: PChar;
- begin
- BeginInsertAppend;
- ClearBuffers;
- Buffer := FBuffers[0];
- InitRecord(Buffer);
- SetBookmarkFlag(Buffer, bfEOF);
- FRecordCount := 1;
- FBOF := False;
- GetPriorRecords;
- EndInsertAppend;
- end;
-
- procedure TDataSet.Post;
- begin
- UpdateRecord;
- case State of
- dsEdit, dsInsert:
- begin
- DataEvent(deCheckBrowseMode, 0);
- CheckRequiredFields;
- DoBeforePost;
- CheckOperation(InternalPost, FOnPostError);
- FreeFieldBuffers;
- SetState(dsBrowse);
- Resync([]);
- DoAfterPost;
- end;
- end;
- end;
-
- procedure TDataSet.Cancel;
- begin
- case State of
- dsEdit, dsInsert:
- begin
- DataEvent(deCheckBrowseMode, 0);
- DoBeforeCancel;
- UpdateCursorPos;
- if State = dsEdit then InternalCancel;
- FreeFieldBuffers;
- SetState(dsBrowse);
- Resync([]);
- DoAfterCancel;
- end;
- end;
- end;
-
- procedure TDataSet.Delete;
- begin
- CheckActive;
- if State in [dsInsert, dsSetKey] then Cancel else
- begin
- if FRecordCount = 0 then DatabaseError(SDataSetEmpty);
- DataEvent(deCheckBrowseMode, 0);
- DoBeforeDelete;
- DoBeforeScroll;
- CheckOperation(InternalDelete, FOnDeleteError);
- FreeFieldBuffers;
- SetState(dsBrowse);
- Resync([]);
- DoAfterDelete;
- DoAfterScroll;
- end;
- end;
-
- procedure TDataSet.BeginInsertAppend;
- begin
- CheckBrowseMode;
- CheckCanModify;
- DoBeforeInsert;
- DoBeforeScroll;
- end;
-
- procedure TDataSet.EndInsertAppend;
- begin
- SetState(dsInsert);
- try
- DoOnNewRecord;
- except
- UpdateCursorPos;
- FreeFieldBuffers;
- SetState(dsBrowse);
- Resync([]);
- raise;
- end;
- FModified := False;
- DataEvent(deDataSetChange, 0);
- DoAfterInsert;
- DoAfterScroll;
- end;
-
- procedure TDataSet.AddRecord(const Values: array of const; Append: Boolean);
- var
- Buffer: PChar;
- begin
- BeginInsertAppend;
- if not Append then UpdateCursorPos;
- DisableControls;
- try
- MoveBuffer(FRecordCount, FActiveRecord);
- try
- Buffer := ActiveBuffer;
- InitRecord(Buffer);
- FState := dsInsert;
- try
- DoOnNewRecord;
- DoAfterInsert;
- SetFields(Values);
- DoBeforePost;
- InternalAddRecord(Buffer, Append);
- finally
- FreeFieldBuffers;
- FState := dsBrowse;
- FModified := False;
- end;
- except
- MoveBuffer(FActiveRecord, FRecordCount);
- raise;
- end;
- Resync([]);
- DoAfterPost;
- finally
- EnableControls;
- end;
- end;
-
- procedure TDataSet.InsertRecord(const Values: array of const);
- begin
- AddRecord(Values, False);
- end;
-
- procedure TDataSet.AppendRecord(const Values: array of const);
- begin
- AddRecord(Values, True);
- end;
-
- procedure TDataSet.CheckOperation(Operation: TDataOperation;
- ErrorEvent: TDataSetErrorEvent);
- var
- Done: Boolean;
- Action: TDataAction;
- begin
- Done := False;
- repeat
- try
- UpdateCursorPos;
- Operation;
- Done := True;
- except
- on E: EDatabaseError do
- begin
- Action := daFail;
- if Assigned(ErrorEvent) then ErrorEvent(Self, E, Action);
- if Action = daFail then raise;
- if Action = daAbort then SysUtils.Abort;
- end;
- end;
- until Done;
- end;
-
- procedure TDataSet.SetFields(const Values: array of const);
- var
- I: Integer;
- begin
- for I := 0 to High(Values) do Fields[I].AssignValue(Values[I]);
- end;
-
- procedure TDataSet.ClearFields;
- begin
- if not (State in dsEditModes) then DatabaseError(SNotEditing);
- DataEvent(deCheckBrowseMode, 0);
- InternalInitRecord(ActiveBuffer);
- if State <> dsSetKey then GetCalcFields(ActiveBuffer);
- DataEvent(deRecordChange, 0);
- end;
-
- procedure TDataSet.CheckRequiredFields;
- var
- I: Integer;
- begin
- for I := 0 to FFields.Count - 1 do
- with TField(FFields[I]) do
- if Required and not ReadOnly and (FieldKind = fkData) and IsNull then
- begin
- FocusControl;
- DatabaseErrorFmt(SFieldRequired, [DisplayName]);
- end;
- end;
-
- { Bookmarks }
-
- function TDataset.BookmarkAvailable: Boolean;
- begin
- Result := (State in [dsBrowse, dsEdit, dsInsert]) and not IsEmpty
- and (GetBookmarkFlag(ActiveBuffer) = bfCurrent);
- end;
-
- function TDataSet.GetBookmark: TBookmark;
- begin
- if BookmarkAvailable then
- begin
- Result := StrAlloc(FBookmarkSize);
- GetBookmarkData(ActiveBuffer, Result);
- end else
- Result := nil;
- end;
-
- function TDataset.GetBookmarkStr: TBookmarkStr;
- begin
- if BookmarkAvailable then
- begin
- SetLength(Result, BookmarkSize);
- GetBookmarkData(ActiveBuffer, Pointer(Result));
- end else
- Result := '';
- end;
-
- procedure TDataSet.GotoBookmark(Bookmark: TBookmark);
- begin
- if Bookmark <> nil then
- begin
- CheckBrowseMode;
- DoBeforeScroll;
- InternalGotoBookmark(Bookmark);
- Resync([rmExact, rmCenter]);
- DoAfterScroll;
- end;
- end;
-
- procedure TDataset.SetBookmarkStr(const Value: TBookmarkStr);
- begin
- GotoBookmark(Pointer(Value));
- end;
-
- function TDataSet.BookmarkValid(Bookmark: TBookmark): Boolean;
- begin
- Result := False;
- end;
-
- function TDataSet.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer;
- begin
- Result := 0;
- end;
-
- procedure TDataSet.FreeBookmark(Bookmark: TBookmark);
- begin
- StrDispose(Bookmark);
- end;
-
- procedure TDataSet.InternalCancel;
- begin
- end;
-
- procedure TDataSet.InternalEdit;
- begin
- end;
-
- procedure TDataSet.InternalRefresh;
- begin
- end;
-
- procedure TDataSet.Translate(Src, Dest: PChar; ToOem: Boolean);
- begin
- if (Src <> nil) and (Src <> Dest) then
- StrCopy(Dest, Src);
- end;
-
- { Filter / Locate / Find }
-
- function TDataSet.FindRecord(Restart, GoForward: Boolean): Boolean;
- begin
- Result := False;
- end;
-
- function TDataSet.FindFirst: Boolean;
- begin
- Result := FindRecord(True, True);
- end;
-
- function TDataSet.FindLast: Boolean;
- begin
- Result := FindRecord(True, False);
- end;
-
- function TDataSet.FindNext: Boolean;
- begin
- Result := FindRecord(False, True);
- end;
-
- function TDataSet.FindPrior: Boolean;
- begin
- Result := FindRecord(False, False);
- end;
-
- procedure TDataSet.SetFiltered(Value: Boolean);
- begin
- FFiltered := Value;
- end;
-
- procedure TDataSet.SetFilterOptions(Value: TFilterOptions);
- begin
- FFilterOptions := Value;
- end;
-
- procedure TDataSet.SetFilterText(const Value: string);
- begin
- FFilterText := Value;
- end;
-
- procedure TDataSet.SetOnFilterRecord(const Value: TFilterRecordEvent);
- begin
- FOnFilterRecord := Value;
- end;
-
- function TDataSet.Locate(const KeyFields: string; const KeyValues: Variant;
- Options: TLocateOptions): Boolean;
- begin
- Result := False;
- end;
-
- function TDataSet.Lookup(const KeyFields: string; const KeyValues: Variant;
- const ResultFields: string): Variant;
- begin
- Result := False;
- end;
-
- { Informational }
-
- procedure TDataSet.CheckBrowseMode;
- begin
- CheckActive;
- DataEvent(deCheckBrowseMode, 0);
- case State of
- dsEdit, dsInsert:
- begin
- UpdateRecord;
- if Modified then Post else Cancel;
- end;
- dsSetKey:
- Post;
- end;
- end;
-
- function TDataSet.GetCanModify: Boolean;
- begin
- Result := True;
- end;
-
- procedure TDataSet.CheckCanModify;
- begin
- if not CanModify then DatabaseError(SDataSetReadOnly);
- end;
-
- procedure TDataSet.GetFieldList(List: TList; const FieldNames: string);
- var
- Pos: Integer;
- begin
- Pos := 1;
- while Pos <= Length(FieldNames) do
- List.Add(FieldByName(ExtractFieldName(FieldNames, Pos)));
- end;
-
- function TDataSet.GetRecordCount: Longint;
- begin
- Result := -1;
- end;
-
- function TDataSet.GetRecNo: Integer;
- begin
- Result := -1;
- end;
-
- procedure TDataSet.SetRecNo(Value: Integer);
- begin
- end;
-
- function TDataSet.IsSequenced: Boolean;
- begin
- Result := True;
- end;
-
- { Event Handler Helpers }
-
- procedure TDataSet.DoAfterCancel;
- begin
- if Assigned(FAfterCancel) then FAfterCancel(Self);
- end;
-
- procedure TDataSet.DoAfterClose;
- begin
- if Assigned(FAfterClose) then FAfterClose(Self);
- end;
-
- procedure TDataSet.DoAfterDelete;
- begin
- if Assigned(FAfterDelete) then FAfterDelete(Self);
- end;
-
- procedure TDataSet.DoAfterEdit;
- begin
- if Assigned(FAfterEdit) then FAfterEdit(Self);
- end;
-
- procedure TDataSet.DoAfterInsert;
- begin
- if Assigned(FAfterInsert) then FAfterInsert(Self);
- end;
-
- procedure TDataSet.DoAfterOpen;
- begin
- if Assigned(FAfterOpen) then FAfterOpen(Self);
- end;
-
- procedure TDataSet.DoAfterPost;
- begin
- if Assigned(FAfterPost) then FAfterPost(Self);
- end;
-
- procedure TDataSet.DoAfterScroll;
- begin
- if Assigned(FAfterScroll) then FAfterScroll(Self);
- end;
-
- procedure TDataSet.DoBeforeCancel;
- begin
- if Assigned(FBeforeCancel) then FBeforeCancel(Self);
- end;
-
- procedure TDataSet.DoBeforeClose;
- begin
- if Assigned(FBeforeClose) then FBeforeClose(Self);
- end;
-
- procedure TDataSet.DoBeforeDelete;
- begin
- if Assigned(FBeforeDelete) then FBeforeDelete(Self);
- end;
-
- procedure TDataSet.DoBeforeEdit;
- begin
- if Assigned(FBeforeEdit) then FBeforeEdit(Self);
- end;
-
- procedure TDataSet.DoBeforeInsert;
- begin
- if Assigned(FBeforeInsert) then FBeforeInsert(Self);
- end;
-
- procedure TDataSet.DoBeforeOpen;
- begin
- if Assigned(FBeforeOpen) then FBeforeOpen(Self);
- end;
-
- procedure TDataSet.DoBeforePost;
- begin
- if Assigned(FBeforePost) then FBeforePost(Self);
- end;
-
- procedure TDataSet.DoBeforeScroll;
- begin
- if Assigned(FBeforeScroll) then FBeforeScroll(Self);
- end;
-
- procedure TDataSet.DoOnCalcFields;
- begin
- if Assigned(FOnCalcFields) then FOnCalcFields(Self);
- end;
-
- procedure TDataSet.DoOnNewRecord;
- begin
- if Assigned(FOnNewRecord) then FOnNewRecord(Self);
- end;
-
- end.
-