Componentes.Terceros.RemObj.../official/5.0.24.615/Data Abstract for Delphi/Source/uDAInterfaces.pas

6169 lines
187 KiB
ObjectPascal

unit uDAInterfaces;
{----------------------------------------------------------------------------}
{ Data Abstract Library - Core Library }
{ }
{ compiler: Delphi 6 and up, Kylix 3 and up }
{ platform: Win32, Linux }
{ }
{ (c)opyright RemObjects Software. all rights reserved. }
{ }
{ Using this code requires a valid license of the Data Abstract }
{ which can be obtained at http://www.remobjects.com. }
{----------------------------------------------------------------------------}
{$I DataAbstract.inc}
interface
uses
Classes, DB, uROClasses, SysUtils, uDASupportClasses,
DataAbstract3_Intf, DataAbstract4_Intf, uROXmlIntf, FMTBcd;
const
func_GetDriverObject = 'GetDriverObject';
ClientFieldPrefix = '##';
type
TDAObjecttype = (dotTable,dotProcedure, dotView);
TDAChangeType = (ctInsert, ctUpdate, ctDelete);
TDAChangeTypes = set of TDAChangeType;
TDAChangeStatus = (csPending, csResolved, csFailed);
TDASQLCondition = (cEqual,
cDifferent,
cMajor,
cLess,
cMajorOrEqual,
cLessOrEqual,
cLike,
cIn,
cContaining,
cIsNull,
cIsNotNull);
TDASQLOperator = (opAND,
opOR,
opNOT);
TDADefaultOperator = (doNone, doAnd, doOr);
TDABlobType = (dabtUnknown, dabtBlob, dabtMemo, dabtOraBlob, dabtOraClob, dabtGraphic, dabtTypedBinary);
TDAJoinType = (jtInner, jtLeftOuter, jtRightOuter, jtFullOuter, jtCross);
TDARelationshipType = (rtForeignKey, rtMasterDetail);
const
StrSQLCondition: array[TDASQLCondition] of string = (
'=', '<>', '>', '<', '>=', '<=', 'LIKE', 'IN', 'CONTAINING', 'IS NULL', 'IS NOT NULL');
StrSQLOperator: array[TDASQLOperator] of string = (
'AND', 'OR', 'NOT');
BlobTypeMappings : array[TDABlobType] of TFieldType =
(ftBlob, ftBlob, ftMemo, ftOraBlob, ftOraClob, ftGraphic,ftTypedBinary);
type
{ Forwards }
IDADriver = interface;
IDAStoredProcedure = interface;
IDADataset = interface;
IDAConnection = interface;
IDASQLCommand = interface;
IDADataDictionary = interface;
IDATestableObject = interface;
IDAConnectionPool = interface;
IDAConnectionManager = interface;
TDACustomField = class;
TDADataset = class;
{ Driver access }
TDAGetDriverObject = function: IDADriver; stdcall;
//TDriverErrorEvent = procedure(anErrorCode : integer; const anErrorMessage : string) of object;
EDADriverLoadException = class(Exception)
private
fErrorCode: integer;
public
constructor Create(anErrorCode: integer; const anErrorMessage: string);
property ErrorCode: integer read fErrorCode;
end;
EDADriverLoadExceptionClass = class of EDADriverLoadException;
TDADataAbstractException = EDADriverLoadException;
TDADataAbstractExceptionClass = class of TDADataAbstractException;
{ Misc. types }
TDASQLStatementType = (stSQL, stStoredProcedure, stAutoSQL);
TDACommandType = (cmdInsert, cmdDelete, cmdUpdate);
TDACommandTypes = set of TDACommandType;
TDAPersistFormat = (pfBinary, pfXML);
TDAParamType = (daptUnknown, daptInput, daptOutput, daptInputOutput, daptResult);
TDADataType = (datUnknown,
datString,
datDateTime,
datFloat,
datCurrency,
datAutoInc,
datInteger,
datLargeInt,
datBoolean,
datMemo,
datBlob,
datWideString,
datWideMemo,
datLargeAutoInc,
datByte,
datShortInt,
datWord,
datSmallInt,
datCardinal,
datLargeUInt,
datGuid,
datXml,
datDecimal,
datSingleFloat);
{ Forwards }
TDASQLCommand = class;
TDAStatementCollection = class;
TDASQLCommandCollection = class;
TDAParamCollection = class;
TDAJoinConditionCollection = class;
TDAUnionSourceTableCollection = class;
{ TDAColumnMapping }
TDAColumnMapping = class(TInterfacedCollectionItem)
private
fDatasetField: string;
fTableField: string;
fSQLOrigin: string;
function GetSQLOrigin: string;
function StoreSQLOrigin: Boolean;
procedure SetDatasetField(const Value: string);
procedure SetSQLOrigin(const Value: string);
procedure SetTableField(const Value: string);
public
procedure Assign(aSource: TPersistent); override;
procedure AssignFieldMapping(aSource: TPersistent);
published
property DatasetField: string read fDatasetField write SetDatasetField;
property TableField: string read fTableField write SetTableField;
property SQLOrigin: string read GetSQLOrigin write SetSQLOrigin stored StoreSQLOrigin;
end;
{ TDAColumnMappingCollection }
TDAColumnMappingCollection = class(TSearcheableCollection)
private
function GetColumnMappings(Index: integer): TDAColumnMapping;
procedure SetColumnMappings(Index: integer;
const Value: TDAColumnMapping);
protected
function SetItemName(anItem: TCollectionItem; const aName: string): string; override;
function GetItemName(anItem: TCollectionItem): string; override;
public
constructor Create(aOwner: TPersistent);
procedure AssignColumnMapping(aSource: TPersistent);
function Add: TDAColumnMapping; reintroduce;
function FindMappingByDatasetField(const aDatasetField: string): TDAColumnMapping;
function MappingByDatasetField(const aDatasetField: string): TDAColumnMapping;
function MappingByTableField(const aTableField: string): TDAColumnMapping;
property ColumnMappings[Index: integer]: TDAColumnMapping read GetColumnMappings write SetColumnMappings; default;
end;
{ TDAStatement }
TDAStatement = class(TCollectionItem)
private
fSQL: string;
fStatementType: TDASQLStatementType;
fConnection: string;
fColumnMappings: TDAColumnMappingCollection;
fTargetTable: string;
fName: string;
fConnectionType: string;
fDefault: boolean;
procedure SetColumnMappings(const Value: TDAColumnMappingCollection);
function GetStatementCollection: TDAStatementCollection;
procedure SetSQL(const Value: string);
function GetNeedsParams: boolean;
function StoreSQL: Boolean;
protected
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
procedure Assign(aSource: TPersistent); override;
property StatementCollection: TDAStatementCollection read GetStatementCollection;
property NeedsParams: boolean read GetNeedsParams;
published
property Connection: string read fConnection write fConnection;
property ConnectionType: string read fConnectionType write fConnectionType;
property Default: boolean read fDefault write fDefault default false;
property TargetTable: string read fTargetTable write fTargetTable;
property Name: string read fName write fName;
property SQL: string read fSQL write SetSQL stored StoreSQL;
property StatementType: TDASQLStatementType read fStatementType write fStatementType;
property ColumnMappings: TDAColumnMappingCollection read fColumnMappings write SetColumnMappings;
end;
{ TDAStatementCollection }
TDAStatementCollection = class(TSearcheableCollection)
private
fSQLCommand: TDASQLCommand;
function GetStatements(Index: integer): TDAStatement;
procedure SetStatements(Index: integer; const Value: TDAStatement);
protected
function SetItemName(anItem: TCollectionItem; const aName: string): string; override;
function GetItemName(anItem: TCollectionItem): string; override;
public
constructor Create(aOwner: TPersistent; aSQLCommand: TDASQLCommand);
function Add: TDAStatement; reintroduce;
function FindItem(const aName: string; const aStatementName: string=''; const aConnectionType: string = ''; aReturnDefault: Boolean = false): TDAStatement; reintroduce;
function StatementByName(const aName: string): TDAStatement;
property SQLCommand: TDASQLCommand read fSQLCommand;
property Statements[Index: integer]: TDAStatement read GetStatements write SetStatements; default;
end;
{ TDAUpdateRule }
TDAUpdateFailureBehavior = (fbRaiseException, fbLogAndContinue, fbIgnoreAndContinue);
TDAUpdateRule = class(TCollectionItem)
private
fDatasetName: string;
fName: string;
fFailureBehavior: TDAUpdateFailureBehavior;
fDoInsert: boolean;
fDoUpdate: boolean;
fDoDelete: boolean;
function GetChangeTypes: TDAChangeTypes;
protected
function GetDisplayName : string; override;
public
constructor Create(aCollection : TCollection); override;
procedure Assign(aSource: TPersistent); override;
property ChangeTypes: TDAChangeTypes read GetChangeTypes;
published
property Name : string read fName write fName;
property DoUpdate : boolean read fDoUpdate write fDoUpdate default True;
property DoInsert : boolean read fDoInsert write fDoInsert default True;
property DoDelete : boolean read fDoDelete write fDoDelete default True;
property DatasetName : string read fDatasetName write fDatasetName;
property FailureBehavior : TDAUpdateFailureBehavior read fFailureBehavior write fFailureBehavior;
end;
{ TDAUpdateRuleCollection }
TDAUpdateRuleCollection = class(TSearcheableCollection)
private
function GetUpdateRules(Index: integer): TDAUpdateRule;
protected
public
constructor Create(aOwner : TComponent);
function Add: TDAUpdateRule; reintroduce;
function UpdateRuleByName(const aName : string) : TDAUpdateRule;
property UpdateRules[Index : integer] : TDAUpdateRule read GetUpdateRules; default;
end;
{ TDABaseField }
TDABaseField = class(TInterfacedCollectionItem)
private
fDictionaryEntry: string;
fSize: integer;
fDescription,
fName: string;
fDataType: TDADataType;
fValue: Variant;
fBlobType: TDABlobType;
fGeneratorName : string;
FDecimalPrecision: Integer;
FDecimalScale: Integer;
//procedure FixSize;
protected
function MergeDatadictionaries: Boolean;
function GetBlobSize: Integer; virtual;
function GetName: string; virtual;
procedure SetName(const Value: string); virtual;
function GetDataType: TDADataType;
procedure SetDataType(Value: TDADataType);
function GetSize: integer;
procedure SetSize(Value: integer);
function GetValue: Variant; virtual;
procedure SetValue(const aValue: Variant); virtual;
function GetDescription: string;
procedure SetDescription(const Value: string);
function StoreBlobType : boolean;
function GetBlobType: TDABlobType;
procedure SetBlobType(const Value: TDABlobType); virtual;
function GetGeneratorName: string;
procedure SetGeneratorName(const aValue: string);
function GetAsBoolean: boolean; virtual;
function GetAsCurrency: currency; virtual;
function GetAsDateTime: TDateTime; virtual;
function GetAsFloat: double; virtual;
function GetAsInteger: integer; virtual;
function GetAsString: string; virtual;
function GetAsVariant: variant; virtual;
function GetAsLargeInt: int64; virtual;
function GetAsWideString: Widestring; virtual;
function GetAsByte: Byte; virtual;
function GetAsCardinal: Cardinal; virtual;
function GetAsDecimal: TBcd; virtual;
function GetAsGuid: TGUID; virtual;
function GetAsLargeUInt: Int64; virtual;
function GetAsShortInt: ShortInt; virtual;
function GetAsSingle: Single; virtual;
function GetAsSmallInt: SmallInt; virtual;
function GetAsWord: Word; virtual;
function GetAsXml: IXMLNode; virtual;
procedure SetAsByte(const Value: Byte); virtual;
procedure SetAsCardinal(const Value: Cardinal); virtual;
procedure SetAsDecimal(const Value: TBcd); virtual;
procedure SetAsGuid(const Value: TGUID); virtual;
procedure SetAsLargeUInt(const Value: Int64); virtual;
procedure SetAsShortInt(const Value: ShortInt); virtual;
procedure SetAsSingle(const Value: Single); virtual;
procedure SetAsSmallInt(const Value: SmallInt); virtual;
procedure SetAsWord(const Value: Word); virtual;
procedure SetAsXml(const Value: IXMLNode); virtual;
procedure SetAsBoolean(const aValue: boolean); virtual;
procedure SetAsCurrency(const aValue: currency); virtual;
procedure SetAsDateTime(const aValue: TDateTime); virtual;
procedure SetAsString(const aValue: string); virtual;
procedure SetAsVariant(const aValue: variant); virtual;
procedure SetAsFloat(const aValue: double); virtual;
procedure SetAsInteger(const aValue: integer); virtual;
procedure SetAsLargeInt(const aValue: Int64); virtual;
procedure SetAsWideString(const aValue: Widestring); virtual;
function GetIsNull: boolean; virtual;
function StoreDataType: Boolean;
function StoreDescription: Boolean;
function StoreGeneratorName: Boolean;
function StoreSize: Boolean;
function StoreDecimalPrecision: Boolean;
function StoreDecimalScale: Boolean;
function GetDictionaryEntry: string;
procedure SetDictionaryEntry(const Value: string);
function FindDictionaryField: TDACustomField;
function GetDictionaryField: TDACustomField;
// Internal
function GetDisplayName: string; override;
procedure SetDisplayName(const Value: string); override;
function GetDecimalPrecision: Integer; virtual;
procedure SetDecimalPrecision(const Value: Integer);virtual;
function GetDecimalScale: Integer;virtual;
procedure SetDecimalScale(const Value: Integer);virtual;
function IsCompatibleV4: boolean; virtual;
public
property Value: Variant read GetValue write SetValue;
procedure Assign(Source: TPersistent); override;
procedure AssignField(Source: TDABaseField); virtual;
function HasValidDictionaryField: Boolean;
procedure Clear;
function GetNamePath: string; override;
property AsBoolean: boolean read GetAsBoolean write SetAsBoolean;
property AsCurrency: currency read GetAsCurrency write SetAsCurrency;
property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime; //null->0
property AsFloat: double read GetAsFloat write SetAsFloat; //null->0
property AsInteger: integer read GetAsInteger write SetAsInteger; //null->0
property AsString: string read GetAsString write SetAsString; //null->''
property AsVariant: variant read GetAsVariant write SetAsVariant;
property AsLargeInt: Int64 read GetAsLargeInt write SetAsLargeInt;
property AsWideString: WideString read GetAsWideString write SetAsWideString;
property BlobSize: Integer read GetBlobSize;
property IsNull: boolean read GetIsNull;
property AsByte: Byte read GetAsByte write SetAsByte;
property AsShortInt: ShortInt read GetAsShortInt write SetAsShortInt;
property AsWord: Word read GetAsWord write SetAsWord;
property AsSmallInt: SmallInt read GetAsSmallInt write SetAsSmallInt;
property AsCardinal: Cardinal read GetAsCardinal write SetAsCardinal;
property AsLargeUInt: Int64 read GetAsLargeUInt write SetAsLargeUInt;
property AsGuid: TGUID read GetAsGuid write SetAsGuid;
property AsDecimal: TBcd read GetAsDecimal write SetAsDecimal;
property AsXml: IXMLNode read GetAsXml write SetAsXml;
property AsSingle: Single read GetAsSingle write SetAsSingle;
property DictionaryEntry: string read GetDictionaryEntry write SetDictionaryEntry;
published
property Name: string read GetName write SetName;
property DataType: TDADataType read GetDataType write SetDataType default datUnknown;
property Size: integer read GetSize write SetSize default 0;
property Description: string read GetDescription write SetDescription;
property BlobType: TDABlobType read GetBlobType write SetBlobType default dabtUnknown;
property GeneratorName : string read GetGeneratorName write SetGeneratorName;
property DecimalPrecision: Integer read GetDecimalPrecision write SetDecimalPrecision stored StoreDecimalPrecision;
property DecimalScale: Integer read GetDecimalScale write SetDecimalScale stored StoreDecimalScale;
end;
{ TDACustomField }
TDAFieldNotifyEvent = procedure(Sender: TDACustomField) of object;
TDAFieldGetTextEvent = procedure(Sender: TDACustomField; var Text: string; DisplayText: boolean) of object;
TDAFieldSetTextEvent = procedure(Sender: TDACustomField; const Text: string) of object;
TDACustomFieldCollection = class;
TDACustomField = class(TDABaseField)
private
fField: TField;
fTableField: string;
fCustomAttributes: TStringList;
fRequired: boolean;
fInPrimaryKey: boolean;
fRegExpression: string;
fDefaultValue: string;
fDisplayWidth: integer;
fDisplayLabel: string;
fReadOnly: boolean;
fVisible: boolean;
fEditMask: string;
fLogChanges: boolean;
fCalculated: boolean;
fOnChange: TDAFieldNotifyEvent;
fOnValidate: TDAFieldNotifyEvent;
fDisplayFormat: string;
fBusinessClassID: string;
fAlignment : TAlignment;
fEditFormat : string;
fLookupCache: boolean;
fLookupKeyFields: string;
fLookupResultField: string;
fKeyFields: string;
fLookupSource: TDataSource;
fLookup: boolean;
fServerAutoRefresh: boolean;
fSQLOrigin: string;
fServerCalculated: Boolean;
fExpression: string;
function GetDisplayLabel: string;
function StoreDisplayLabel: Boolean;
function StoreProperties : boolean;
function GetDefaultValue: string;
function GetDisplayWidth: integer;
function GetEditMask: string;
function GetReadOnly: boolean;
function GetVisible: boolean;
//procedure SetBusinessRulesID(const Value: string);
//function GetBusinessRulesID: string;
function GetDisplayFormat: string;
function GetAlignment: TAlignment;
function GetEditFormat: string;
procedure SetAlignment(const Value: TAlignment);
procedure SetEditFormat(const Value: string);
procedure SetKeyFields(const Value: string);
procedure SetLookupCache(const Value: boolean);
procedure SetLookupKeyFields(const Value: string);
procedure SetLookupResultField(const Value: string);
procedure SetLookupSource(const Value: TDataSource);
procedure SetCalculated(const Value: boolean);
procedure SetLookup(const Value: boolean);
function GetFieldCollection: TDACustomFieldCollection;
{function GetNotNull: boolean;
procedure SetNotNull(const Value: boolean);}
function GetServerAutoRefresh: boolean;
procedure SetServerAutoRefresh(const Value: boolean);
function GetLogChanges: boolean;
function GetOldValue: Variant;
function GetSQLOrigin: string;
function GetBusinessClassID: string;
procedure SetBusinessClassID(const Value: string);
procedure SetServerCalculated(const Value: Boolean);
procedure SetExpression(const Value: string);
function StoredServerCalculated: Boolean;
function StoredExpression: Boolean;
protected
function GetOwner: TPersistent; override;
procedure SetName(const Value: string); override;
function GetInPrimaryKey: boolean;
function GetRegExpression: string;
function GetRequired: boolean;
procedure SetInPrimaryKey(const Value: boolean);
procedure SetRegExpression(const Value: string);
function GetBlobSize: Integer; override;
function GetValue: Variant; override;
procedure SetValue(const Value: Variant); override;
function GetTableField: string;
procedure SetTableField(const Value: string);
function GetCustomAttributes: TStrings;
procedure SetCustomAttributes(const Value: TStrings);
procedure SetDisplayFormat(const Value: string);
procedure SetBlobType(const Value: TDABlobType); override;
procedure SetRequired(const aValue: boolean);
procedure SetDisplayLabel(const aValue: string);
procedure SetVisible(const aValue: boolean);
procedure SetDisplayWidth(const aValue: integer);
procedure SetEditMask(const aValue: string);
procedure SetReadOnly(const aValue: boolean);
// Event hooks
procedure InternalOnChange(Sender: TField);
procedure InternalOnValidate(Sender: TField);
function GetAsBoolean: boolean; override;
function GetAsCurrency: currency; override;
function GetAsDateTime: TDateTime; override;
function GetAsFloat: double; override;
function GetAsInteger: integer; override;
function GetAsString: string; override;
function GetAsVariant: variant; override;
function GetAsLargeInt: int64; override;
function GetAsWideString: Widestring; override;
function GetAsByte: Byte; override;
function GetAsCardinal: Cardinal; override;
function GetAsDecimal: TBcd; override;
function GetAsGuid: TGUID; override;
function GetAsLargeUInt: Int64; override;
function GetAsShortInt: ShortInt; override;
function GetAsSingle: Single; override;
function GetAsSmallInt: SmallInt; override;
function GetAsWord: Word; override;
function GetAsXml: IXMLNode; override;
procedure SetAsByte(const Value: Byte); override;
procedure SetAsCardinal(const Value: Cardinal); override;
procedure SetAsDecimal(const Value: TBcd); override;
procedure SetAsGuid(const Value: TGUID); override;
procedure SetAsLargeUInt(const Value: Int64); override;
procedure SetAsShortInt(const Value: ShortInt); override;
procedure SetAsSingle(const Value: Single); override;
procedure SetAsSmallInt(const Value: SmallInt); override;
procedure SetAsWord(const Value: Word); override;
procedure SetAsXml(const Value: IXMLNode); override;
procedure SetAsBoolean(const aValue: boolean); override;
procedure SetAsCurrency(const aValue: currency); override;
procedure SetAsDateTime(const aValue: TDateTime); override;
procedure SetAsString(const aValue: string); override;
procedure SetAsVariant(const aValue: variant); override;
procedure SetAsFloat(const aValue: double); override;
procedure SetAsInteger(const aValue: integer); override;
procedure SetAsLargeInt(const aValue: Int64); override;
procedure SetAsWideString(const aValue: Widestring); override;
function GetIsNull: boolean; override;
function GetDecimalPrecision: Integer; override;
procedure SetDecimalPrecision(const Value: Integer);override;
function GetDecimalScale: Integer;override;
procedure SetDecimalScale(const Value: Integer);override;
function IsCompatibleV4: boolean; override;
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
function GetNamePath: string; override;
procedure Bind(aField: TField);
procedure Unbind;
procedure SaveToStream(const aStream: IROStream); overload;
procedure LoadFromStream(const aStream: IROStream); overload;
procedure SaveToStream(const aStream: TStream); overload;
procedure LoadFromStream(const aStream: TStream); overload;
procedure SaveToFile(const aFileName: string);
procedure LoadFromFile(const aFileName: string);
property FieldCollection : TDACustomFieldCollection read GetFieldCollection;
procedure FocusControl;
property TableField: string read GetTableField write SetTableField;
property SQLOrigin: string read GetSQLOrigin write fSQLOrigin;
procedure Assign(Source: TPersistent); override;
procedure AssignField(Source: TDABaseField); override;
property OldValue : Variant read GetOldValue;
property BindedField: TField read FField;
public
property OnChange: TDAFieldNotifyEvent read fOnChange write fOnChange;
property OnValidate: TDAFieldNotifyEvent read fOnValidate write fOnValidate;
property InPrimaryKey: boolean read GetInPrimaryKey write SetInPrimaryKey default False;
property Calculated: boolean read fCalculated write SetCalculated default False;
property Expression: string read fExpression write SetExpression stored StoredExpression;
property ServerCalculated: Boolean read fServerCalculated write SetServerCalculated stored StoredServerCalculated default False;
property Lookup : boolean read fLookup write SetLookup default False;
property LookupSource : TDataSource read fLookupSource write SetLookupSource;
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;
published
property LogChanges: boolean read GetLogChanges write fLogChanges stored StoreProperties default true;
property RegExpression: string read GetRegExpression write SetRegExpression stored StoreProperties;
property DefaultValue: string read GetDefaultValue write fDefaultValue stored StoreProperties;
property Required: boolean read GetRequired write SetRequired stored StoreProperties default FALSE;
property DisplayWidth: integer read GetDisplayWidth write SetDisplayWidth stored StoreProperties default 0;
property DisplayLabel: string read GetDisplayLabel write SetDisplayLabel stored StoreDisplayLabel;
property EditMask: string read GetEditMask write SetEditMask stored StoreProperties;
property Visible: boolean read GetVisible write SetVisible stored StoreProperties default TRUE;
property ReadOnly: boolean read GetReadOnly write SetReadOnly stored StoreProperties default FALSE;
property CustomAttributes: TStrings read GetCustomAttributes write SetCustomAttributes stored StoreProperties;
property DisplayFormat: string read GetDisplayFormat write SetDisplayFormat stored StoreProperties;
//property BusinessRulesID : string read GetBusinessRulesID write SetBusinessRulesID stored StoreProperties;
property BusinessClassID : string read GetBusinessClassID write SetBusinessClassID stored StoreProperties;
property EditFormat : string read GetEditFormat write SetEditFormat stored StoreProperties;
property Alignment : TAlignment read GetAlignment write SetAlignment stored StoreProperties default taLeftJustify;
property ServerAutoRefresh : boolean read GetServerAutoRefresh write SetServerAutoRefresh default FALSE;
end;
TDAField = class(TDACustomField)
protected
function GetDisplayName: string; override;
published
property DictionaryEntry;
property InPrimaryKey;
property Calculated;
property Expression;
property ServerCalculated;
property OnChange;
property OnValidate;
property Lookup;
property LookupSource;
property LookupKeyFields;
property LookupResultField;
property KeyFields;
property LookupCache;
end;
TDADataDictionaryField = class(TDACustomField)
end;
TDAFieldClass = class of TDACustomField;
{ TDACustomFieldCollection }
TDACustomFieldCollection = class(TSearcheableInterfacedCollection)
private
fDataDictionary: IDADataDictionary;
fFieldEventsDisabled: boolean;
fFieldBeforeUpdate,
fFieldAfterUpdate: TDAFieldNotifyEvent;
fIsCompatibleV4: boolean;
function GetFields(Index: integer): TDACustomField;
procedure SetFields(Index: integer; const Value: TDACustomField);
public
constructor Create(aOwner: TPersistent; aFieldClass: TDAFieldClass);
procedure Bind(aDataset: TDataset);
procedure Unbind;
property FieldEventsDisabled:boolean read fFieldEventsDisabled write fFieldEventsDisabled default false;
function Add: TDAField; reintroduce; overload;
function Add(const aName: string; aType: TDADataType; aSize: integer = 0): TDACustomField; overload;
procedure Assign(Source: TPersistent); override;
procedure AssignFieldCollection(Source: TDACustomFieldCollection);
function FieldByName(const aName: string): TDACustomField;
function FindField(const aName: string): TDACustomField;
property DataDictionary: IDADataDictionary read fDataDictionary write fDataDictionary;
property Fields[Index: integer]: TDACustomField read GetFields write SetFields; default;
property OnFieldBeforeUpdate: TDAFieldNotifyEvent read fFieldBeforeUpdate write fFieldBeforeUpdate;
property OnFieldAfterUpdate: TDAFieldNotifyEvent read fFieldAfterUpdate write fFieldAfterUpdate;
property IsCompatibleV4: boolean read fIsCompatibleV4 write fIsCompatibleV4;
end;
TDAFieldCollection = class(TDACustomFieldCollection)
private
function GetFields(Index: integer): TDAField;
procedure SetFields(Index: integer; const Value: TDAField);
public
constructor Create(aOwner: TPersistent);
function FieldByName(const aName: string): TDAField; reintroduce;
function FindField(const aName: string): TDAField;
property Fields[Index: integer]: TDAField read GetFields write SetFields; default;
end;
TDADriverForeignKey = class(TInterfacedCollectionItem)
private
fValues:array[0..3] of string;
fName: string;
function GetValue(const Index: Integer): string;
procedure SetValue(const Index: Integer; const Value: string);
published
property Name: string read fName write fName;
property FKTable: string index 0 read GetValue write SetValue;
property PKTable: string index 1 read GetValue write SetValue;
property FKField: string index 2 read GetValue write SetValue;
property PKField: string index 3 read GetValue write SetValue;
end;
TDADriverForeignKeyCollection = class(TInterfacedCollection)
private
function GetForeignKeys(Index: integer): TDADriverForeignKey;
procedure SetForeignKeys(Index: integer; const Value: TDADriverForeignKey);
public
constructor Create(aOwner: TPersistent);
function Add: TDADriverForeignKey; reintroduce; overload;
//procedure Assign(Source: TPersistent); override;
//procedure AssignFieldCollection(Source: TDACustomFieldCollection);
property ForeignKeys[Index: integer]: TDADriverForeignKey read GetForeignKeys write SetForeignKeys; default;
end;
TDADataDictionaryFieldCollection = class(TDACustomFieldCollection)
end;
{ TDAParam }
TDAParam = class(TDABaseField)
private
fParamType: TDAParamType;
function GetParamType: TDAParamType;
procedure SetParamType(Value: TDAParamType);
public
procedure SaveToStream(const aStream: IROStream);
procedure LoadFromStream(const aStream: IROStream);
procedure SaveToFile(const aFileName: string);
procedure LoadFromFile(const aFileName: string);
procedure AssignField(Source: TDABaseField); override;
published
property Value stored true;
property AsString stored false;
property ParamType: TDAParamType read GetParamType write SetParamType default daptUnknown;
end;
{ TDAParamCollection }
TDAParamCollection = class(TSearcheableInterfacedCollection) // They are used also by the driver commands/datasets
private
function GetParams(Index: integer): TDAParam;
procedure SetParams(Index: integer; const Value: TDAParam);
function GetHasInputParams: boolean;
protected
public
constructor Create(aOwner: TPersistent);
procedure WriteValues(OutputParams: TParams);
procedure ReadValues(InputParams: TParams);
function Add: TDAParam; reintroduce;
function ParamByName(const aName: string): TDAParam;
function FindParam(const aParamName: string): TDAParam;
procedure Assign(Source: TPersistent); override;
procedure AssignParamCollection(Source: TDAParamCollection);
property Params[Index: integer]: TDAParam read GetParams write SetParams; default;
property HasInputParams:boolean read GetHasInputParams;
end;
{ TDASQLCommand }
TDASQLCommand = class(TCollectionItem)
private
fName: string;
fDescription: string;
fStatements: TDAStatementCollection;
fParams: TDAParamCollection;
fCustomAttributes: TStrings;
fIsPublic: Boolean;
procedure SetName(const Value: string);
procedure SetCustomAttributes(const Value: TStrings);
protected
function GetDisplayName: string; override;
procedure SetDisplayName(const Value: string); override;
function GetParams: TDAParamCollection; virtual;
procedure SetParams(const Value: TDAParamCollection); virtual;
function GetStatements(): TDAStatementCollection; virtual;
procedure SetStatements(const Value: TDAStatementCollection); virtual;
function GetSQLCommandCollection: TDASQLCommandCollection; virtual;
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
function ParamByName(const aName: string): TDAParam;
procedure Assign(aSource: TPersistent); override;
property SQLCommandCollection: TDASQLCommandCollection read GetSQLCommandCollection;
published
property IsPublic: Boolean read fIsPublic write fIsPublic default True;
property Params: TDAParamCollection read GetParams write SetParams;
property Statements: TDAStatementCollection read GetStatements write SetStatements;
property Name: string read fName write SetName;
property Description: string read fDescription write fDescription;
property CustomAttributes: TStrings read fCustomAttributes write SetCustomAttributes;
end;
TDASQLCommandClass = class of TDASQLCommand;
{ TDASQLCommandCollection }
TDASQLCommandCollection = class(TSearcheableCollection)
private
function GetSQLCommands(Index: integer): TDASQLCommand;
procedure SetSQLCommands(Index: integer; const Value: TDASQLCommand);
protected
function GetItemClass: TDASQLCommandClass; virtual;
public
constructor Create(aOwner: TComponent);
function Add: TDASQLCommand; reintroduce;
function SQLCommandByName(const aName: string): TDASQLCommand;
property SQLCommands[Index: integer]: TDASQLCommand read GetSQLCommands write SetSQLCommands; default;
end;
TROSEScriptLanguage = (rslPascalScript);
TDABusinessRuleScript = class(TPersistent)
private
fScriptLanguage: TROSEScriptLanguage;
fScript: string;
fDescription: string;
published
property Script: string read fScript write fScript;
property ScriptLanguage: TROSEScriptLanguage read fScriptLanguage write fScriptLanguage default rslPascalScript;
property Description: string read fDescription write fDescription;
end;
TDAClientBusinessRuleScript = class(TDABusinessRuleScript)
private
fRunOnClientAndServer: boolean;
fCompileOnServer: boolean;
published
constructor Create();
property CompileOnServer: boolean read fCompileOnServer write fCompileOnServer default true;
property RunOnClientAndServer: boolean read fRunOnClientAndServer write fRunOnClientAndServer default true;
end;
{ TDADatasetRelationship }
TDADatasetRelationship = class(TCollectionItem)
private
fDetailFields: string;
fMasterFields: string;
fDetailDatasetName: string;
fMasterDatasetName: string;
fName: string;
fDescription: string;
fRelationshipType: TDARelationshipType;
protected
function GetDisplayName : string; override;
public
constructor Create(Collection: TCollection); override;
published
procedure Assign(Source : TPersistent); override;
property Name : string read fName write fName;
property MasterDatasetName : string read fMasterDatasetName write fMasterDatasetName;
property MasterFields : string read fMasterFields write fMasterFields;
property DetailDatasetName : string read fDetailDatasetName write fDetailDatasetName;
property DetailFields : string read fDetailFields write fDetailFields;
property Description: string read fDescription write fDescription;
property RelationshipType: TDARelationshipType read fRelationshipType write fRelationshipType;
end;
{ TDADatasetRelationshipList }
TDADatasetRelationshipList = class(TList)
private
function GetItems(Index: integer): TDADatasetRelationship;
protected
public
function Add(aRelationship : TDADatasetRelationship) : integer; reintroduce;
property Items[Index : integer] : TDADatasetRelationship read GetItems; default;
end;
{ TDADatasetRelationshipCollection }
TDADatasetRelationshipCollection = class(TSearcheableCollection)
private
function GetRelationShips(Index: integer): TDADatasetRelationship;
protected
public
constructor Create(aOwner : TComponent);
procedure GetDetails(const aMasterDatasetName: string; aList: TDADatasetRelationshipList);
function Add: TDADatasetRelationship; overload;
function RelationShipByName(const aName : string) : TDADatasetRelationship;
property RelationShips[Index : integer] : TDADatasetRelationship read GetRelationShips; default;
end;
{ TDADataset }
TDADataset = class(TDASQLCommand)
private
fFields: TDAFieldCollection;
fBusinessClassID: string;
fBusinessRulesServer: TDABusinessRuleScript;
fBusinessRulesClient: TDAClientBusinessRuleScript;
fReadOnly: Boolean;
procedure SetFields(const Value: TDAFieldCollection);
procedure SetBusinessRulesClient(const Value: TDAClientBusinessRuleScript);
procedure SetBusinessRulesServer(const Value: TDABusinessRuleScript);
protected
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
procedure Assign(aSource: TPersistent); override;
function FieldByName(const aName: string): TDAField;
function FindField(const aName: string): TDAField;
published
property Fields: TDAFieldCollection read fFields write SetFields;
property BusinessClassID : string read fBusinessClassID write fBusinessClassID;
property ReadOnly: Boolean read fReadOnly write fReadOnly default False;
property BusinessRulesClient: TDAClientBusinessRuleScript read fBusinessRulesClient write SetBusinessRulesClient;
property BusinessRulesServer: TDABusinessRuleScript read fBusinessRulesServer write SetBusinessRulesServer;
end;
{ TDADatasetCollection }
TDADatasetCollection = class(TDASQLCommandCollection)
private
function GetDatasets(Index: integer): TDADataset;
procedure SetDatasets(Index: integer; const Value: TDADataset);
protected
function GetItemClass: TDASQLCommandClass; override;
public
function Add: TDADataset; reintroduce;
function DatasetByName(const aName: string): TDADataset;
function FindDatasetByName(const aName: string): TDADataset;
property Datasets[Index: integer]: TDADataset read GetDatasets write SetDatasets; default;
end;
{ TDAJoinSourceTable }
TDAJoinSourceTable = class(TCollectionItem)
private
fName: String;
fJoinType: TDAJoinType;
fJoinConditions: TDAJoinConditionCollection;
protected
function GetDisplayName : string; override;
procedure SetName(const Value: string);
public
constructor Create(Collection: TCollection); override;
procedure Assign(aSource: TPersistent); override;
published
property Name: string read fName write SetName;
property JoinType: TDAJoinType read fJoinType write fJoinType;
property JoinConditions: TDAJoinConditionCollection read fJoinConditions;
end;
{ TDAJoinSourceTableCollection }
TDAJoinSourceTableCollection = class(TSearcheableCollection)
private
function GetJoinSourceTables(Index: integer): TDAJoinSourceTable;
procedure SetJoinSourceTables(Index: integer; const Value: TDAJoinSourceTable);
public
constructor Create(aOwner: TPersistent);
function Add: TDAJoinSourceTable; reintroduce;
function JoinSourceTableByName(const aName: string): TDAJoinSourceTable;
property JoinSourceTables[Index:Integer]: TDAJoinSourceTable read GetJoinSourceTables write SetJoinSourceTables;
end;
{ TDAJoinCondition }
TDAJoinCondition = class(TCollectionItem)
private
fFromTableName: String;
fFromFieldName: String;
fToTableName: String;
fToFieldName: String;
published
property FromTableName: String read fFromTableName write fFromTableName;
property FromFieldName: String read fFromFieldName write fFromFieldName;
property ToTableName: String read fToTableName write fToTableName;
property ToFieldName: String read fToFieldName write fToFieldName;
end;
{ TDAJoinConditionCollection }
TDAJoinConditionCollection = class(TOwnedCollection)
private
public
constructor Create(aOwner: TPersistent);
function Add: TDAJoinCondition; reintroduce;
end;
{ TDAJoinDataTable }
TDAJoinDataTable = class(TDADataset)
private
fMasterTable: String;
fJoinSourceTables: TDAJoinSourceTableCollection;
procedure SetJoinSourceTables(const Value: TDAJoinSourceTableCollection);
protected
function GetParams: TDAParamCollection; override;
procedure SetParams(const Value: TDAParamCollection); override;
function GetStatements(): TDAStatementCollection; override;
procedure SetStatements(const Value: TDAStatementCollection); override;
function GetSQLCommandCollection: TDASQLCommandCollection; override;
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
procedure Assign(aSource: TPersistent); override;
property Params;
property Statements;
published
property JoinSourceTables: TDAJoinSourceTableCollection read fJoinSourceTables write SetJoinSourceTables;
property MasterTable: String read fMasterTable write fMasterTable;
end;
TDAJoinDataTableClass = class of TDAJoinDataTable;
{ TDAJoinedTableCollection }
TDAJoinDataTableCollection = class(TSearcheableCollection)
private
function GetJoinDataTables(Index: integer): TDAJoinDataTable;
procedure SetJoinDataTables(Index: integer; const Value: TDAJoinDataTable);
protected
//function GetItemClass: TDAJoinedTableClass; override;
public
constructor Create(aOwner : TComponent);
function Add: TDAJoinDataTable; reintroduce;
function JoinTableByName(const aName: string): TDAJoinDataTable;
function FindJoinTableByName(const aName: string): TDAJoinDataTable;
property JoinTables[Index: integer]: TDAJoinDataTable read GetJoinDataTables write SetJoinDataTables; default;
end;
{TDAUnionSourceTable}
TDAUnionSourceTable = class(TCollectionItem)
private
fName: string;
fColumnMappings: TDAColumnMappingCollection;
fReadOnly: Boolean;
procedure SetColumnMappings(const Value: TDAColumnMappingCollection);
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
published
property Name: string read fName write fName;
property ColumnMappings: TDAColumnMappingCollection read fColumnMappings write SetColumnMappings;
property IsReadOnly: Boolean read fReadOnly write fReadOnly;
end;
{TDAUnionSourceTableCollection}
TDAUnionSourceTableCollection = class(TSearcheableCollection)
private
function GetUnionSourceTables(Index: integer): TDAUnionSourceTable;
protected
public
constructor Create(aOwner : TPersistent);
function Add: TDAUnionSourceTable; reintroduce;
function UnionSourceTableByName(const aName : string) : TDAUnionSourceTable;
property UnionSourceTables[Index : integer] : TDAUnionSourceTable read GetUnionSourceTables; default;
end;
{TDAUnionDataTable}
TDAUnionDataTable = class(TDADataset)
private
fDefaultSourceTable: string;
fSourceTables: TDAUnionSourceTableCollection;
procedure SetSourceTables(Value: TDAUnionSourceTableCollection);
protected
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
property Params;
property Statements;
published
property SourceTables: TDAUnionSourceTableCollection read fSourceTables write SetSourceTables;
property DefaultSourceTable: String read fDefaultSourceTable write fDefaultSourceTable;
end;
{ TDAUnionDataTableCollection }
TDAUnionDataTableCollection = class(TSearcheableCollection)
private
function GetUnionDataTables(Index: integer): TDAUnionDataTable;
procedure SetUnionDataTables(Index: integer; const Value: TDAUnionDataTable);
protected
//function GetItemClass: TDAJoinedTableClass; override;
public
constructor Create(aOwner : TComponent);
function Add: TDAUnionDataTable; reintroduce;
function UnionDataTableByName(const aName: string): TDAUnionDataTable;
function FindUnionDataTableByName(const aName: string): TDAUnionDataTable;
property UnionDataTables[Index: integer]: TDAUnionDataTable read GetUnionDataTables write SetUnionDataTables; default;
end;
{ TDAConnection }
TDAConnection = class(TCollectionItem)
private
fDescription: string;
fConnectionString: string;
fConnectionType: string;
fName: string;
fDefault: boolean;
fTag: integer;
procedure SetDefault(const Value: boolean);
procedure SetName(const Value: string);
protected
function GetDisplayName: string; override;
procedure SetDisplayName(const Value: string); override;
function GetConnectionString: string; virtual;
procedure SetConnectionString(const aValue: string); virtual;
public
procedure Assign(aSource: TPersistent); override;
published
property Name: string read fName write SetName;
property ConnectionString: string read GetConnectionString write SetConnectionString;
property Description: string read fDescription write fDescription;
property ConnectionType: string read fConnectionType write fConnectionType;
property Default: boolean read fDefault write SetDefault default False;
property Tag: integer read fTag write fTag default 0;
end;
{ TDAConnectionCollection }
TDAConnectionCollection = class(TSearcheableCollection)
private
function GetConnections(Index: integer): TDAConnection;
procedure SetConnections(Index: integer; const Value: TDAConnection);
procedure ClearDefaults(iExceptFor: TDAConnection);
protected
function ItemName: string; override;
public
constructor Create(aOwner: TPersistent);
function Add: TDAConnection; reintroduce;
function ConnectionByName(const aName: string): TDAConnection;
function FindConnection(const aName: string; const aType: string): TDAConnection;
function GetDefaultConnection : TDAConnection;
property Connections[Index: integer]: TDAConnection read GetConnections write SetConnections; default;
property OnItemRenamed;
property OnItemRemoved;
end;
EDADriverAlreadyLoaded = class(EDADriverLoadException);
EDASchemaModelerOnly = class(EDADriverLoadException);
IDADataDictionary = interface
['{34078D79-6310-494C-BA92-0FC187B275BE}']
procedure SetFields(const Value: TDADataDictionaryFieldCollection);
function GetFields: TDADataDictionaryFieldCollection;
property Fields: TDADataDictionaryFieldCollection read GetFields write SetFields;
end;
IDAHasDataDictionary = interface
['{A25ADACE-BBD7-4A04-84A9-B9B699389E3D}']
function GetDataDictionary: IDADataDictionary;
property DataDictionary: IDADataDictionary read GetDataDictionary;
end;
{ IDADriverManager
Provides access to all the functionality needed to load, unload and verify drivers.
Access to this interface is obtained using a TDADriverManager component.
There can only be one driver manager loaded at any give time in one application. }
IDADriverManager = interface
['{5B6B8C91-F91A-4A25-8B6F-CF7959275682}']
// Properties readers/writers
function GetDrivers(Index: integer): IDADriver;
function GetDriverCount: integer;
// Methods
procedure LoadDriver(const aFileName: string);
procedure UnloadDriver(anIndex: integer);
procedure LoadDrivers;overload;
procedure LoadDrivers(const aDriverList: IROStrings; aIgnoreDuplicates: boolean = false; aIgnoreErrors: boolean = false);overload;
procedure UnloadAllDrivers;
function ListDrivers(const aDirectory: string; out FileNames: IROStrings): integer;
function FindDriver(const aDriverID: string; out Driver: IDADriver): boolean;
function DriverByDriverID(const aDriverID: string): IDADriver;
// Properties
property Drivers[Index: integer]: IDADriver read GetDrivers; default;
property DriverCount: integer read GetDriverCount;
end;
TDAAvailableDriverOption = (doAuxDriver, doServerName, doDatabaseName, doLogin, doCustom);
TDAAvailableDriverOptions = set of TDAAvailableDriverOption;
TDADriverHelpType = (dhConnectionWizard);
{ IDADriver
An object implementing this interface is returned by the Data Abstract drivers. You get a reference to
it by calling the DLL's exported function GetDriverObject. If the DLL doesn't support this method, it is
not a Data Abstract driver. Once you retrieve a reference to this object you can query it for additional
interfaces such as IDAConnectionPool and obtain access to additional functionality. Not all drivers implement
the same number of interfaces. }
TDATraceSource = (tsUnknown, tsConnection, tsDataset, tsCommand);
TDATraceOption = (toPrepare,
toExecute,
toFetch,
toError,
toStmt,
toConnect,
toTransact,
toBlob,
toService,
toMisc,
toParams);
TDATraceOptions = set of TDATraceOption;
TDALogTraceEvent = procedure(Sender: TObject; const Text: string; Tag: integer) of object;
IDADriver = interface
['{1829ABED-299B-4698-9803-DBABCF5443FA}']
// Properties readers/writers
function GetDriverID: string; safecall;
function GetDescription: string; safecall;
function GetMajVersion: byte; safecall;
function GetMinVersion: byte; safecall;
// Methods
procedure Initialize; safecall;
procedure Finalize; safecall;
function NewConnection(const aName: string = '';const aConnectionType: string = ''): IDAConnection; safecall; overload; {deprecated;}
function NewConnection(const aConnectionManager: IDAConnectionManager; aConnectionDefinition: TDAConnection): IDAConnection; safecall; overload;
procedure SetTraceOptions(TraceActive: boolean; TraceOptions: TDATraceOptions; Callback: TDALogTraceEvent); safecall;
function GetAvailableDriverOptions: TDAAvailableDriverOptions; safecall;
function GetDefaultCustomParameters: string; safecall;
// Properties
property DriverID: string read GetDriverID;
property Description: string read GetDescription;
property MajVersion: byte read GetMajVersion;
property MinVersion: byte read GetMinVersion;
procedure GetAuxDrivers(out List: IROStrings); safecall;
procedure GetAuxParams(const AuxDriver: string; out List: IROStrings); safecall;
function GetDefaultConnectionType(const AuxDriver: string): string; safecall;
end;
IDADriver30 = interface(IDADriver)
['{F14A6526-CE1F-4A6B-BC4D-3892BA712FE2}']
function GetDriverHelp(aType: TDADriverHelpType): string;
end;
IDADriver40 = interface(IDADriver30)
['{82903957-974A-4E1F-B91C-C07F608A96A9}']
function GetProviderDefaultCustomParameters(Provider: string): string; safecall;
end;
IDACanQueryDatabaseNames = interface
['{67870220-37E2-4510-BD6A-627EADED75ED}']
function GetDatabaseNames: IROStrings;
end;
IDAFileBasedDatabase = interface
['{C37EA8EE-9AC7-44F3-863C-EFB1581D4D57}']
function GetFileExtensions: IROStrings;
end;
IDADirectoryBasedDatabase = interface
['{40C102F0-B86E-4CD6-AB3D-4B0903723A5D}']
end;
{ IDAConnectionObjectAccess
Provides access to the internal connection component and facilitates access to its
properties in form of a collection of properties. This interface is useful when you want
to complete control of the internal object. In order to use this interface you need
to use ShareMem or FastShareMem. }
IDAConnectionObjectAccess = interface
['{FF8F2319-4EAE-4A2B-8713-A6E6B3F5E48A}']
// Properties readers/writers
function GetConnectionObject: TObject; safecall;
function GetConnectionProperties(const aPropertyName: string): Variant; safecall;
procedure SetConnectionProperties(const aPropertyName: string; const aValue: Variant); safecall;
// Properties
property ConnectionObject: TObject read GetConnectionObject;
property ConnectionProperties[const aPropertyName: string]: Variant read GetConnectionProperties write SetConnectionProperties;
end;
TDAQuoteCharArray = array[0..1] of char;
TDABeforeOpenDatasetEvent = procedure(const Sender: IDADataset) of object;
TDAAfterOpenDatasetEvent = procedure(const Sender: IDADataset; ActualSQL: string; ElapsedMilliseconds: Cardinal) of object;
TDAOpenDatasetErrorEvent = procedure(const Sender: IDADataset; ActualSQL: string; Error: Exception) of object;
TDABeforeExecuteCommandEvent = procedure(const Sender: IDASQLCommand) of object;
TDAAfterExecuteCommandEvent = procedure(const Sender: IDASQLCommand; ActualSQL: string; ElapsedMilliseconds: Cardinal) of object;
TDAExecuteCommandErrorEvent = procedure(const Sender: IDASQLCommand; ActualSQL: string; Error: Exception) of object;
{ TDAWhereBuilder }
TDAWhereBuilder = class;
TDAWhereExpression = class(TObject)
private
fOwner: TDAWhereBuilder;
public
constructor Create(anOwner: TDAWhereBuilder);
property Owner: TDAWhereBuilder read fOwner;
class function ParseExpression(aOwner: TDAWhereBuilder; xr: IXmlNode): TDAWhereExpression;
procedure ReadFromXml(xr: IXmlNode); virtual; abstract;
procedure WriteToXml(sw: IXmlNode); virtual; abstract;
end;
TDABinaryOperator = (dboAnd, dboOr, dboXor, dboLess, dboLessOrEqual, dboGreater,
dboGreaterOrEqual, dboNotEqual, dboEqual, dboLike, dboIn, dboAddition, dboSubtraction,
dboMultiply, dboDivide);
TDAUnaryOperator = (duoNot, duoMinus);
TDAWhereBuilder = class
private
fExpression: TDAWhereExpression;
FColumnMapping: TDAColumnMappingCollection;// for TDAESQLCommand
fParams: TDAParamCollection;
function getXml: WideString;
procedure setXml(const aValue: WideString);
procedure SetColumnMapping(const Value: TDAColumnMappingCollection);
procedure SetParams(const Value: TDAParamCollection);
protected
function ReadFromXml(xr: IXmlNode): TDAWhereExpression; virtual;
procedure WriteToXml(sw: IXmlNode; const aExpression: TDAWhereExpression); virtual;
public
constructor Create;
destructor Destroy; override;
property Expression: TDAWhereExpression read fExpression write FExpression;
property Xml: WideString read GetXml write SetXml;
function NewBinaryExpression(aLeft, aRight: TDAWhereExpression; anOp: TDABinaryOperator): TDAWhereExpression;
function NewUnaryExpression(anExpression: TDAWhereExpression; anOp: TDAUnaryOperator): TDAWhereExpression;
function NewConstant(const aValue: Variant; aType: TDADataType): TDAWhereExpression;
function NewList(const aValues: array of TDAWhereExpression): TDAWhereExpression;
function NewParameter(const aParameterName: string): TDAWhereExpression;
function NewField(const aTableName,aFieldName: string): TDAWhereExpression;
function NewNull: TDAWhereExpression;
function NewMacro(const aName: string): TDAWhereExpression; overload;
function NewMacro(const aName: string; const aValues: array of TDAWhereExpression): TDAWhereExpression; overload;
procedure Clear;
function IsEmpty:Boolean;
property ColumnMapping: TDAColumnMappingCollection read FColumnMapping write SetColumnMapping;
property Params: TDAParamCollection read fParams write SetParams;
function ExpressionToXmlNode(const aExpression: TDAWhereExpression): IXMLNode;
function XMLToExpression(const aXML: widestring):TDAWhereExpression;
end;
TDAQueryBuilder = class;
TDASQLWhereBuilder = class(TDAWhereBuilder)
private
FId: Integer;
FConnection: IDAConnection;
FQueryBuilder: TDAQueryBuilder;
function GenerateParamName: String;
function GenerateParameter(const aParameterName: string):string;
function GetMappingTableField(const aDataSetField: string): string;
protected
function GenerateFieldName(aTablename, aFieldName: string):string; virtual;
function ProcessExpression(AExpression: TDAWhereExpression): string;
function ProcessBinaryExpression(AExpression: TDAWhereExpression): string; virtual; abstract;
function ProcessUnaryExpression(AExpression: TDAWhereExpression): string; virtual; abstract;
function ProcessConstantExpression(AExpression: TDAWhereExpression): string; virtual;
function ProcessListExpression(AExpression: TDAWhereExpression): string; virtual;
function ProcessParameterExpression(AExpression: TDAWhereExpression): string; virtual;
function ProcessFieldExpression(AExpression: TDAWhereExpression): string; virtual;
function ProcessNullExpression(AExpression: TDAWhereExpression): string; virtual; abstract;
function ProcessMacroExpression(AExpression: TDAWhereExpression): string; virtual;
public
constructor Create(AConnection: IDAConnection); overload;
constructor Create(AQueryBuilder: TDAQueryBuilder); overload;
function CreateWhereClause: string;
property Connection: IDAConnection read FConnection;
property QueryBuilder: TDAQueryBuilder read FQueryBuilder;
end;
{ TDAQueryBuilder }
TDATableFieldCollectionItem = class(TCollectionItem)
private
FFieldName: string;
FTableName: string;
public
procedure Assign(Source: TPersistent); override;
property TableName: string read FTableName write FTableName;
property FieldName: string read FFieldName write FFieldName;
end;
TDASelectItem = TDATableFieldCollectionItem;
TDASelectCollection = TCollection;
TDAGroupByItem = TDATableFieldCollectionItem;
TDAGroupByCollection = TCollection;
TDAOrderByItem = TDATableFieldCollectionItem;
TDAOrderByCollection = TCollection;
TDAQueryBuilderOption = (qboSelectDistinct, qboGenerateSimpleSelect, qboGenerateDynamicWhereStatement);
TDAQueryBuilderOptions = set of TDAQueryBuilderOption;
TDAQueryBuilder = class(TPersistent)
private
// IDAConnection
FMainTable: TDAJoinDataTable;
FSelectCollection: TDASelectCollection;
FGroupByCollection: TDAGroupByCollection;
FOrderByCollection: TDAOrderByCollection;
FWhere: TDASQLWhereBuilder;
FOptions: TDAQueryBuilderOptions;
FConnection: IDAConnection;
FColumnMapping: TDAColumnMappingCollection;
procedure SetColumnMapping(const Value: TDAColumnMappingCollection);
function GetWhereBuilder: TDASQLWhereBuilder;
protected
function GetMappingTableField(const aDataSetField: string): string;
procedure Validate; virtual;
function CreateWhereBuilder: TDASQLWhereBuilder; virtual; abstract;
function CreateSelectClause: string; virtual;
function CreateTableClause: string; virtual;abstract;
function CreateGroupByClause: string; virtual;
function CreateOrderByClause: string; virtual;
function GenerateFieldName(aTablename, aFieldName: string; aProcessMapping: Boolean = True):string; virtual;
function QuoteFieldNameIfNeeded(const aTableName, aFieldName: string): string; virtual;
function QuoteIdentifierIfNeeded(const iIdentifier: string): string; virtual;
function QuoteIdentifier(const iIdentifier: string): string; virtual;
function IdentifierNeedsQuoting(const iIdentifier: string):boolean;virtual;
public
constructor Create;
destructor Destroy; override;
function GenerateSelectSQL: string; virtual;
function CreateWhereClause: string; virtual;
procedure Assign(Source: TPersistent); override;
procedure Clear;
procedure AddSelect(ATable, AField: string);
procedure AddGroupBy(ATable, AField: string);
procedure AddOrderBy(ATable, AField: string);
procedure AddJoin(AJoinTable, AJoinFieldName, AJoinToTableName, AJoinToFieldName: string; AJoinType: TDAJoinType = jtInner); overload;
procedure AddJoin(AJoinTable: string; AJoinFieldNames: array of string; AJoinToTableName: string; AJoinToFieldNames: array of string; AJoinType: TDAJoinType = jtInner); overload;
procedure AddCrossJoin(ATable: string);
property Select: TDASelectCollection read FSelectCollection;
property MainTable: TDAJoinDataTable read FMainTable;
property Where: TDASQLWhereBuilder read GetWhereBuilder;
property GroupBy: TDAGroupByCollection read FGroupByCollection;
property OrderBy: TDAOrderByCollection read FOrderByCollection;
property Options: TDAQueryBuilderOptions read FOptions write FOptions;
property Connection: IDAConnection read FConnection write FConnection;
property ColumnMapping: TDAColumnMappingCollection read FColumnMapping write SetColumnMapping;
end;
IDABaseConnection = interface
['{B96CFC5B-CE8A-4B6F-994E-2A82509B0F18}']
end;
{ IDAConnection
Provides access to a connection object in a database and vendor independent manner.
Objects implementing IDAConnection are returned by the driver.
Each connection object might also implement additional interfaces that are specific to the
underlying database or the data-access framework. These additional interfaces are defined in
separate units. To find out what interfaces a connection implements you can check the source code
of the relative uDAxxxDriver.pas unit. }
IDAConnection = interface(IDABaseConnection)
['{6D9C806F-65A5-43B3-8F07-4ED782A13A0A}']
// Properties readers/writers
function GetConnectionPool: IDAConnectionPool; safecall;
procedure SetConnectionPool(const Value: IDAConnectionPool); safecall;
function GetConnectionString: string; safecall;
procedure SetConnectionString(Value: string); safecall;
function GetConnected: boolean; safecall;
procedure SetConnected(Value: boolean); safecall;
function GetName: string; safecall;
function GetOnAfterExecuteCommand: TDAAfterExecuteCommandEvent; safecall;
function GetOnAfterOpenDataset: TDAAfterOpenDatasetEvent; safecall;
function GetOnBeforeExecuteCommand: TDABeforeExecuteCommandEvent; safecall;
function GetOnBeforeOpenDataset: TDABeforeOpenDatasetEvent; safecall;
function GetOnExecuteCommandError: TDAExecuteCommandErrorEvent; safecall;
function GetOnOpenDatasetError: TDAOpenDatasetErrorEvent; safecall;
procedure SetOnAfterExecuteCommand(const Value: TDAAfterExecuteCommandEvent); safecall;
procedure SetOnAfterOpenDataset(const Value: TDAAfterOpenDatasetEvent); safecall;
procedure SetOnBeforeExecuteCommand(const Value: TDABeforeExecuteCommandEvent); safecall;
procedure SetOnBeforeOpenDataset(const Value: TDABeforeOpenDatasetEvent); safecall;
procedure SetOnExecuteCommandError(const Value: TDAExecuteCommandErrorEvent); safecall;
procedure SetOnOpenDatasetError(const Value: TDAOpenDatasetErrorEvent); safecall;
function GetConnectionType: string; safecall;
// Transaction support
function BeginTransaction: integer; safecall;
procedure CommitTransaction; safecall;
procedure RollbackTransaction; safecall;
function GetInTransaction: boolean; safecall;
// UserID/Password
function GetUserID: string; safecall;
procedure SetUserID(const Value: string); safecall;
function GetPassword: string; safecall;
procedure SetPassword(const Value: string); safecall;
// Connection
procedure Open(const aUserID: string = ''; const aPassword: string = ''); safecall;
procedure Close; safecall;
// Metadata
procedure GetTableNames(out List: IROStrings); safecall;
procedure GetViewNames(out List: IROStrings); safecall;
procedure GetStoredProcedureNames(out List: IROStrings); safecall;
procedure GetTableFields(const aTableName: string; out Fields: TDAFieldCollection); safecall;
procedure GetQueryFields(const aSQL: string; aParamsIfNeeded: TDAParamCollection; out Fields: TDAFieldCollection); safecall;
procedure GetViewFields(const aViewName: string; out Fields: TDAFieldCollection); safecall;
procedure GetStoredProcedureParams(const aStoredProcedureName: string; out Params: TDAParamCollection); safecall;
procedure GetForeignKeys(out ForeignKeys: TDADriverForeignKeyCollection); safecall;
function GetQuoteChars: TDAQuoteCharArray; safecall;
function IdentifierNeedsQuoting(const iIdentifier: string): boolean; safecall;
function QuoteIdentifierIfNeeded(const iIdentifier: string): string; safecall;
function QuoteIdentifier(const iIdentifier: string): string; safecall;
function QuoteFieldNameIfNeeded(const aTableName, aFieldName: string): string; safecall;
function QuoteFieldName(const aTableName, aFieldName: string): string; safecall;
function GetSPSelectSyntax(HasArguments: Boolean): string; safecall;
// Commands and datasets
function NewCommand(const Text: string; CommandType: TDASQLStatementType; const aCommandName: string = ''): IDASQLCommand; safecall;
function NewDataset(const SQL: string; const aDatasetName: string = ''): IDADataset; safecall;
function GetLastAutoInc(const GeneratorName: string = ''): integer; safecall;
function isAlive: Boolean; safecall;
// Properties
property ConnectionString: string read GetConnectionString write SetConnectionString;
property Connected: boolean read GetConnected write SetConnected;
property Name: string read GetName;
property InTransaction: boolean read GetInTransaction;
property UserID: string read GetUserID write SetUserID;
property Password: string read GetPassword write SetPassword;
property ConnectionPool: IDAConnectionPool read GetConnectionPool write SetConnectionPool;
property ConnectionType: string read GetConnectionType;
property OnBeforeOpenDataset: TDABeforeOpenDatasetEvent read GetOnBeforeOpenDataset write SetOnBeforeOpenDataset;
property OnAfterOpenDataset: TDAAfterOpenDatasetEvent read GetOnAfterOpenDataset write SetOnAfterOpenDataset;
property OnOpenDatasetError: TDAOpenDatasetErrorEvent read GetOnOpenDatasetError write SetOnOpenDatasetError;
property OnBeforeExecuteCommand: TDABeforeExecuteCommandEvent read GetOnBeforeExecuteCommand write SetOnBeforeExecuteCommand;
property OnAfterExecuteCommand: TDAAfterExecuteCommandEvent read GetOnAfterExecuteCommand write SetOnAfterExecuteCommand;
property OnExecuteCommandError: TDAExecuteCommandErrorEvent read GetOnExecuteCommandError write SetOnExecuteCommandError;
// QueryBuilder
function GetQueryBuilder: TDAQueryBuilder; safecall;
function GetWhereBuilder: TDASQLWhereBuilder; safecall;
function GetUseMacroProcessor: Boolean; safecall;
procedure SetUseMacroProcessor(Value:Boolean); safecall;
property UseMacroProcessor: Boolean read GetUseMacroProcessor write SetUseMacroProcessor;
end;
IDAHETConnection = interface(IDABaseConnection)
['{9471FB7A-F5C6-4420-A2E6-F2DD7C6535A7}']
function GetConnectionForObject(const aObjectName: string; aOpenConnection: boolean = false): IDAConnection;
end;
{ IDATestableObject }
IDATestableObject = interface
['{DC2C3CD1-9031-4B0A-97B9-563580611C25}']
procedure Test; safecall;
end;
{ IDAUseGenerators }
IDAUseGenerators = interface
['{7963D550-361E-486A-AAD6-EFD12896F719}']
function GetNextAutoinc(const GeneratorName: string): integer; safecall;
end;
IDACanQueryGeneratorsNames = interface
['{E7C4A441-16B2-42BA-92DD-BD0F3EC39250}']
function GetGeneratorNames: IROStrings;
end;
{ IDAConnectionManager }
IDAConnectionManager = interface
['{C2C2B1DB-7D0A-4772-8DDF-5E5150A84827}']
function GetDefaultConnectionName: string;
function NewConnection(const aConnectionName: string;
OpenConnection: boolean = TRUE;
const UserID: string = '';
const Password: string = ''): IDAConnection;
procedure Clear;
end;
IDAConnectionPool = interface
['{6E132C7B-A6AD-4ECB-B901-80000AC4B912}']
procedure ReleaseConnection(const Conn: IDAConnection);
end;
{ IDASchema }
IDASchema = interface
['{19C63BF1-9CAA-43B7-B49C-E3FE82F5A02E}']
function GetDatasetText(const aConnection: IDAConnection; const aName: string): string;
function GetCommandText(const aConnection: IDAConnection; const aName: string): string;
function NewDataset(const aConnection: IDAConnection; const aName: string;
aStatementName: string='';
OpenIt: boolean = false): IDADataset; overload;
function NewDataset(const aConnection: IDAConnection; const aName: string;
const ParamNames: array of string;
const ParamValues: array of Variant;
OpenIt: boolean = TRUE;
aStatementName: string=''): IDADataset; overload;
function NewDataset(const aConnection: IDAConnection; const aName: string;
aDynSelectFields: array of string;
aWhereClause: WideString;
aStatementName: string='';
OpenIt: boolean = false; AlwaysGenerateDynamicWhereStatement: Boolean=False): IDADataset; overload;
function NewDataset(const aConnection: IDAConnection; const aName: string;
const ParamNames: array of string;
const ParamValues: array of Variant;
aDynSelectFields: array of string;
aWhereClause: WideString;
OpenIt: boolean = TRUE;
aStatementName: string=''): IDADataset; overload;
function NewCommand(const aConnection: IDAConnection; const aName: string;
aStatementName: string=''): IDASQLCommand; overload;
function NewCommand(const aConnection: IDAConnection; const aName: string;
const ParamNames: array of string;
const ParamValues: array of Variant;
ExecuteIt: boolean = TRUE;
aStatementName: string=''): IDASQLCommand; overload;
procedure Clear;
function MergeDataDictionaries: Boolean;
end;
{ TDAWhere
Represents an abstraction of the WHERE condition of a SQL statement in an IDADataset. }
TDAWhere = class
private
fFields: TDAFieldCollection;
fClause: string;
fOnChange: TNotifyEvent;
fChanged,
fClientFields: boolean;
fLastWasCondition: Boolean;
fDefaultOperator: TDADefaultOperator;
function GetEmpty: boolean;
function GetNotEmpty: boolean;
function GetProperName(aField: TDACustomField) : string;
protected
public
constructor Create(const aFields: TDAFieldCollection; aClientFields : boolean);
procedure Clear;
procedure AddOperator(aOperator: TDASQLOperator);
function AddCondition(const FieldName: string;
Condition: TDASQLCondition;
const Value: Variant;
SkipIfEmptyValue: boolean = TRUE): boolean;overload;
function AddCondition(const FieldName: string;
Condition: TDASQLCondition): boolean;overload;
procedure AddValueGroup(const FieldName: string;
const Values: array of Variant);
procedure AddSpaces(Count: integer = 1);
procedure AddText(const someText: string; MapClientFields : boolean = TRUE);
procedure OpenBraket; deprecated;
procedure CloseBraket; deprecated;
procedure OpenBracket;
procedure CloseBracket;
function AddConditions(const FieldNames : array of string;
const Conditions : array of TDASQLCondition;
const Values: array of Variant;
const Operator: TDASQLOperator) : integer;
property OnChange: TNotifyEvent read fOnChange write fOnChange;
property Clause: string read fClause;
property Fields: TDAFieldCollection read fFields write fFields;
property Empty : boolean read GetEmpty;
property NotEmpty : boolean read GetNotEmpty;
property ClientFields : boolean read fClientFields;
property DefaultOperator: TDADefaultOperator read fDefaultOperator write fDefaultOperator;
property LastWasCondition: Boolean read fLastWasCondition write fLastWasCondition;
property Changed: Boolean read fChanged write fChanged;
end;
{ IDASQLCommand
Base interface for SQL commands. It defines the common functionality shared by queries and stored procedures
that is providing access to a parameter list and being able to execute a statement which affects a certain
number of records. }
IDASQLCommand = interface
['{F57D2647-2DDE-4F69-86C5-CFACD6AC601F}']
// Properties readers/writers
function GetParams: TDAParamCollection; safecall;
function GetPrepared: boolean; safecall;
procedure SetPrepared(Value: boolean); safecall;
function GetWhere: TDAWhere; safecall; deprecated;
function GetDynamicWhere: TDAWhereBuilder; safecall;
procedure SetDynamicWhere(const Value: TDAWhereBuilder);safecall;
function SQLContainsDynamicWhere:boolean; safecall;
function GetSQL: string; safecall;
procedure SetSQL(const Value: string); safecall;
function GetDataset: TDataset; safecall;
function GetName: string; safecall;
function GetOnAfterExecute: TDAAfterExecuteCommandEvent; safecall;
function GetOnBeforeExecute: TDABeforeExecuteCommandEvent; safecall;
procedure SetOnAfterExecute(const Value: TDAAfterExecuteCommandEvent); safecall;
procedure SetOnBeforeExecute(const Value: TDABeforeExecuteCommandEvent); safecall;
function GetOnExecuteError: TDAExecuteCommandErrorEvent; safecall;
procedure SetOnExecuteError(const Value: TDAExecuteCommandErrorEvent); safecall;
// Methods
procedure RefreshParams; safecall;
function Execute: integer; safecall;
function ParamByName(const aName: string): TDAParam; safecall;
// Properties
property Name: string read GetName;
property Dataset: TDataSet read GetDataset;
property SQL: string read GetSQL write SetSQL;
property Params: TDAParamCollection read GetParams;
property Prepared: boolean read GetPrepared write SetPrepared;
{$WARN SYMBOL_DEPRECATED OFF}
property Where: TDAWhere read GetWhere;
{$WARN SYMBOL_DEPRECATED ON}
property DynamicWhere: TDAWhereBuilder read GetDynamicWhere write SetDynamicWhere;
property OnBeforeExecute: TDABeforeExecuteCommandEvent read GetOnBeforeExecute write SetOnBeforeExecute;
property OnAfterExecute: TDAAfterExecuteCommandEvent read GetOnAfterExecute write SetOnAfterExecute;
property OnExecuteError: TDAExecuteCommandErrorEvent read GetOnExecuteError write SetOnExecuteError;
end;
{ IDAMustSetParams
Implemented only by few SQL commands when we need to call PSSetParams after the parameter values
are written. For internal use only. See TDAEDataset.DoSetActive }
IDAMustSetParams = interface
['{575A8055-0200-44F1-AC5A-EF8604CBB489}']
procedure SetParamValues(Params: TDAParamCollection); safecall;
procedure GetParamValues(Params: TDAParamCollection); safecall;
end;
{ IDADataset
Provides access to a row set generated from a SQL select or a call to a stored procedure which
returns rows. IDADataset objects are created using the method IDAConnection.NewDataset.
Objects implementing this interface are equivalent to TDataset and in most cases simply wrap one. }
IDADataset = interface(IDASQLCommand)
['{8A3E5056-A8B9-4455-B82C-67E48CC39EA5}']
// Properties readers/writers
function GetRecordCount: integer; safecall;
function GetFieldCount: integer; safecall;
function GetFields: TDAFieldCollection; safecall;
function GetActive: boolean; safecall;
procedure SetActive(Value: boolean); safecall;
function GetEOF: boolean; safecall;
function GetFieldValues(Index: integer): Variant; safecall;
function GetNames(Index: integer): string; safecall;
function GetIsEmpty : boolean; safecall;
function GetLogicalName : string; safecall;
procedure SetLogicalName(aName : string); safecall;
function GetOnAfterOpen: TDAAfterOpenDatasetEvent; safecall;
function GetOnBeforeOpen: TDABeforeOpenDatasetEvent; safecall;
procedure SetOnAfterOpen(const Value: TDAAfterOpenDatasetEvent); safecall;
procedure SetOnBeforeOpen(const Value: TDABeforeOpenDatasetEvent); safecall;
function GetOnOpenError: TDAOpenDatasetErrorEvent; safecall;
procedure SetOnOpenError(const Value: TDAOpenDatasetErrorEvent); safecall;
// Methods
procedure Open; safecall;
procedure Close; safecall;
procedure EnableControls; safecall;
procedure DisableControls; safecall;
procedure Next; safecall;
function FieldByName(const aName: string): TDAField; safecall;
function FindField(const aName: string): TDAField; safecall;
function GetCurrentRecIdValue: integer;
procedure SetCurrentRecIdValue(Value: integer);
function GetRowRecIDValue: integer;
procedure EnableConstraints; safecall;
procedure DisableConstraints; safecall;
function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; safecall;
function Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant; safecall;
property RowRecIdValue: integer read GetRowRecIdValue;
property CurrentRecIdValue: integer read GetCurrentRecIdValue write SetCurrentRecIdValue;
// Properties
property IsEmpty : boolean read GetIsEmpty;
(* property BOF: boolean read GetBOF;*)
property EOF: boolean read GetEOF;
property RecordCount: integer read GetRecordCount;
property Fields: TDAFieldCollection read GetFields;
property Active: boolean read GetActive write SetActive;
property FieldCount: integer read GetFieldCount;
property FieldValues[Index: integer]: Variant read GetFieldValues;
property Names[Index: integer]: string read GetNames;
property LogicalName : string read GetLogicalName write SetLogicalName;
property OnBeforeOpen: TDABeforeOpenDatasetEvent read GetOnBeforeOpen write SetOnBeforeOpen;
property OnAfterOpen: TDAAfterOpenDatasetEvent read GetOnAfterOpen write SetOnAfterOpen;
property OnOpenError: TDAOpenDatasetErrorEvent read GetOnOpenError write SetOnOpenError;
end;
IDADatasetEx = interface(IDADataset)
['{BB588B03-620E-43AD-B77E-EFD35F303112}']
function GetBOF: boolean; safecall;
procedure Refresh; safecall;
function GetBookMark: pointer; safecall;
procedure GotoBookmark(Bookmark: TBookmark); safecall;
procedure FreeBookmark(Bookmark: TBookmark); safecall;
function GetState : TDatasetState; safecall;
property State : TDatasetState read GetState;
end;
{ IDAEditableDataset }
IDAEditableDataset = interface(IDADatasetEx)
['{D3E2147F-65B3-4D9D-8614-7270011FA7D5}']
procedure Edit; safecall;
procedure Insert; safecall;
procedure Post; safecall;
procedure Cancel; safecall;
procedure Append; safecall;
procedure Delete; safecall;
procedure Prior; safecall;
procedure First; safecall;
procedure Last; safecall;
procedure AddRecord(const FieldNames : array of string; const FieldValues : array of Variant); safecall;
procedure EnableEventHandlers; safecall;
procedure DisableEventHandlers; safecall;
end;
{ IDAStoredProcedure
Provides access to stored database procedures.
IDAStoredProcedure objects are created using the method IDAConnection.NewStoredProcedure.}
IDAStoredProcedure = interface(IDASQLCommand)
['{6D9C806F-65A5-43B3-8F07-4ED782A13A0A}']
// Properties readers/writers
function GetStoredProcedureName: string; safecall;
procedure SetStoredProcedureName(const Name: string); safecall;
// Methods
function Execute: integer; safecall;
// Properties
property StoredProcedureName: string read GetStoredProcedureName write SetStoredProcedureName;
end;
{ IDADatasetPersist }
IDADatasetPersist = interface
['{D6F850CD-9204-4953-A54F-1E622AA993B6}']
function Persist(const aQuery: IDADataset; MaxRecords: integer; out Data: IROStream): integer;
end;
{ IDADatasetResolver }
IDADatasetResolver = interface
['{D6F850CD-9204-4953-A54F-1E622AA993B6}']
procedure Resolve(const Data: IROStream; const aQuery: IDADataset; MaxErrors: integer);
end;
{ IDALoginInfoAware }
IDALoginInfoAware = interface
['{755615F0-4208-459A-B1C4-97EA5A3DB346}']
function GetLoginInfo : TDALoginInfo;
procedure SetLoginInfo(aValue : TDALoginInfo);
property LoginInfo : TDALoginInfo read GetLoginInfo write SetLoginInfo;
end;
{ TDALoginInfoAware }
TDALoginInfoAware = class(TInterfacedObject, IDALoginInfoAware)
private
fLoginInfo : TDALoginInfo;
protected
{ IDALoginInfoAware }
function GetLoginInfo : TDALoginInfo;
procedure SetLoginInfo(aValue : TDALoginInfo);
{ IInterface }
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
{ IDASimpleClonedCursorsSupport }
IDASimpleClonedCursorsSupport = interface
['{39D05665-5B13-4EC3-B31E-D39CBEA52AC6}']
function GetSimpleCloneSource : TObject;
end;
IDAMemDatasetBatchAdding = interface
['{73A4A297-2938-46EB-8D0C-2F8FB58046E2}']
function AllocRecordBuffer: PChar;
procedure FreeRecordBuffer(var Buffer: PChar);
function GetFieldNativeBuffer(Buffer: PChar; Field: TField): Pointer;
function MakeBlobFromString(Blob:String): pointer;
procedure AppendBuffer(Buffer: Pchar);
procedure SetNullMask(Buffer: PChar; Field: TField; const Value: boolean);
procedure SetAnsiString(NativeBuf: Pointer; Field: TField; const Value: Ansistring);
procedure SetWideString(NativeBuf: Pointer; Field: TField; const Value: Widestring);
procedure FinalizeBatchAdding;
end;
{ TDADataSource }
TDABaseDataSource = class(TDataSource)
end;
const
DADataTypeNames: array[Low(TDADataType)..High(TDADataType)] of string = ('Unknown',
'String',
'DateTime',
'Float',
'Currency',
'AutoInc',
'Integer',
'LargeInt',
'Boolean',
'Memo',
'Blob',
'WideString',
'WideMemo',
'LargeAutoInc',
'Byte',
'ShortInt',
'Word',
'SmallInt',
'Cardinal',
'LargeUInt',
'Guid',
'Xml',
'Decimal',
'SingleFloat');
DADataTypesMappings: array[TDADataType] of TFieldType = (
ftUnknown, ftString, ftDateTime, ftFloat, ftCurrency, ftAutoInc, ftInteger,
ftLargeInt, ftBoolean, ftMemo, ftBlob, ftWideString,
{$IFNDEF DELPHI10UP}ftMemo{$ELSE}ftWideMemo{$ENDIF DELPHI10UP},
ftLargeInt, ftSmallint, ftSmallint, ftWord, ftSmallint, ftInteger, ftLargeint,
ftGuid, ftWideString, ftFMTBcd, ftFloat);
function VCLTypeToDAType(aFieldType: TFieldType): TDADataType;
function DATypeToVCLType(aDAType: TDADataType): TFieldType;
{ Cross-platform GetTickCount }
function ROGetTickCount: Cardinal;
{ Variant converters }
function GetVarBoolean(const Value: Variant): boolean;
function GetVarCurrency(const Value: Variant): currency;
function GetVarDateTime(const Value: Variant): TDateTime;
function GetVarFloat(const Value: Variant): double;
function GetVarInteger(const Value: Variant): integer;
function GetVarString(const Value: Variant): string;
function GetVarInt64(const Value: Variant): Int64;
function GetVarWideString(const Value: Variant): WideString;
function GetVarByte(const Value: Variant): Byte;
function GetVarShortInt(const Value: Variant): ShortInt;
function GetVarWord(const Value: Variant): Word;
function GetVarSmallInt(const Value: Variant): SmallInt;
function GetVarCardinal(const Value: Variant): Cardinal;
function GetVarLargeUInt(const Value: Variant): Int64;
function GetVarGuid(const Value: Variant): TGuid;
function GetVarXml(const Value: Variant): IXMLNode;
function GetVarDecimal(const Value: Variant): TBCD;
function GetVarSingleFloat(const Value: Variant): Single;
function TestDefaultValue(const DefaultValue: string; DataType: TDADataType): Boolean;
{ Misc }
function NewDatasetParam(anArray : TDADatasetParamArray; Name : string; Value : Variant) : TDADatasetParam;
function NewDatasetRequestInfo(anArray : TDADatasetRequestInfoArray;
DatasetName : string;
ParamNames : array of string;
ParamValues : array of variant;
IncludeSchema : boolean = FALSE;
MaxRecords : integer = -1) : TDADatasetRequestInfo;
implementation
uses
{$IFDEF DataAbstract_Trial}
Forms, Dialogs, //Windows,
{$ENDIF DataAbstract_Trial}
TypInfo, Variants,
uDARes, uROBinaryHelpers, {uDAClasses, uDADataTable,} uDAWhere
{$IFDEF MSWINDOWS}
,Windows
{$ENDIF}
{$IFDEF LINUX}
,Libc
{$ENDIF LINUX};
{ Cross-platform GetTickCount }
{$IFDEF LINUX}
// This has been grabbed from IdGlobal.pas. Needs to be tested under Kylix just in case
function ROGetTickCount: Cardinal;
var
tv: timeval;
begin
gettimeofday(tv, nil);
{$RANGECHECKS OFF}
Result := int64(tv.tv_sec) * 1000 + tv.tv_usec div 1000;
{$RANGECHECKS ON}
end;
{$ENDIF}
{$IFDEF MSWINDOWS}
function ROGetTickCount: Cardinal;
begin
result := Windows.GetTickCount;
end;
{$ENDIF}
{ Variant converters }
function GetVarBoolean(const Value: Variant): boolean;
begin
if VarIsNull(Value) then
result := FALSE
else
result := Value;
end;
function GetVarCurrency(const Value: Variant): currency;
begin
if VarIsNull(Value) then
result := 0
else
result := Value;
end;
function GetVarDateTime(const Value: Variant): TDateTime;
begin
if VarIsNull(Value) then
result := 0
else
result := Value;
end;
function GetVarFloat(const Value: Variant): double;
begin
if VarIsNull(Value) then
result := 0
else
result := Value;
end;
function GetVarInteger(const Value: Variant): integer;
begin
if VarIsNull(Value) then
result := 0
else
result := Value;
end;
function GetVarString(const Value: Variant): string;
begin
if VarIsNull(Value) then
result := ''
else
result := Value;
end;
function GetVarInt64(const Value: Variant): Int64;
begin
if VarIsNull(Value) then
result := 0
else
result := Value;
end;
function GetVarWideString(const Value: Variant): WideString;
begin
if VarIsnull(Value) then
Result := ''
else
Result := Value;
end;
function GetVarByte(const Value: Variant): Byte;
begin
if VarIsnull(Value) then
Result := 0
else
Result := Value;
end;
function GetVarShortInt(const Value: Variant): ShortInt;
begin
if VarIsnull(Value) then
Result := 0
else
Result := Value;
end;
function GetVarWord(const Value: Variant): Word;
begin
if VarIsnull(Value) then
Result := 0
else
Result := Value;
end;
function GetVarSmallInt(const Value: Variant): SmallInt;
begin
if VarIsnull(Value) then
Result := 0
else
Result := Value;
end;
function GetVarCardinal(const Value: Variant): Cardinal;
begin
if VarIsnull(Value) then
Result := 0
else
Result := Value;
end;
function GetVarLargeUInt(const Value: Variant): Int64;
begin
if VarIsnull(Value) then
Result := 0
else
Result := Value;
end;
function GetVarGuid(const Value: Variant): TGuid;
begin
if VarIsnull(Value) then
FillChar(Result, sizeof(Result), 0)
else
Result := StringToGuid(Value);
end;
function GetVarXml(const Value: Variant): IXMLNode;
var
lDoc: IXMLDocument;
begin
if VarIsnull(Value) then
Result := nil
else begin
lDoc := NewROXmlDocument;
lDoc.New;
lDoc.XML := Value;
Result := lDoc.DocumentNode;
end;
end;
function GetVarDecimal(const Value: Variant): TBCD;
begin
Result := VariantToBCD(Value);
end;
function GetVarSingleFloat(const Value: Variant): Single;
begin
if VarIsnull(Value) then
Result := 0
else
Result := Value;
end;
function TestDefaultValue(const DefaultValue: string; DataType: TDADataType): Boolean;
var
aDecimal: TDecimal;
begin
try
case DataType of
datString: ;
datDateTime: VarAsType(DefaultValue, varDate);
datFloat: VarAsType(DefaultValue, varDouble);
datDecimal: if not VarByteArrayToDecimal(DefaultValue,aDecimal) then VarAsType(DefaultValue, VarFMTBcd);
datCurrency: VarAsType(DefaultValue, varCurrency);
datAutoInc,
datInteger: VarAsType(DefaultValue, varInteger);
datLargeInt: VarAsType(DefaultValue, varInt64);
datBoolean: VarAsType(DefaultValue, varBoolean);
datMemo: VarAsType(DefaultValue, varString);
datBlob: begin Result := False; exit; end;
datWideString: VarAsType(DefaultValue, varOleStr);
datWideMemo: VarAsType(DefaultValue, varOleStr);
else
begin
result := false;
exit;
end;
end;
result := true;
except
result := false;
end;
end;
{ EDADriverLoadException }
constructor EDADriverLoadException.Create(anErrorCode: integer;
const anErrorMessage: string);
begin
inherited Create(anErrorMessage);
fErrorCode := anErrorCode;
end;
function VCLTypeToDAType(aFieldType: TFieldType): TDADataType;
begin
result := datUnknown;
case aFieldType of
ftUnknown: result := datUnknown;
ftAutoInc: result := datAutoInc;
ftGuid: Result:= datGuid;
ftFixedChar,
ftString: result := datString;
ftLargeint: result := datLargeInt;
ftSmallint: Result := datSmallInt;
ftWord: Result:= datWord;
ftInteger: result := datInteger;
ftFloat: result := datFloat;
ftBCD,
ftFMTBcd: Result := datDecimal;
ftCurrency: result := datCurrency;
ftTimeStamp,
ftDate,
ftTime,
ftDateTime: result := datDateTime;
ftMemo,
ftFmtMemo: result := datMemo;
ftBytes, ftTypedBinary,
ftVarBytes,
ftBlob,
ftGraphic,
ftOraBlob,
ftOraClob: result := datBlob;
ftBoolean: result := datBoolean;
ftWideString: Result := datWideString;
{$IFDEF DELPHI10UP}
ftWideMemo: Result:= datWideMemo;
{$ENDIF DELPHI10UP}
else
RaiseError(err_FieldTypeNotSupported, [GetEnumName(TypeInfo(TFieldType), Ord(aFieldType)), Ord(aFieldType)]);
end;
end;
function DATypeToVCLType(aDAType: TDADataType): TFieldType;
begin
result := DADataTypesMappings[aDAType];
end;
{ Misc }
function NewDatasetParam(anArray : TDADatasetParamArray; Name : string; Value : Variant) : TDADatasetParam;
begin
result := anArray.Add;
result.Name := Name;
result.Value := Value;
end;
function NewDatasetRequestInfo(anArray : TDADatasetRequestInfoArray;
DatasetName : string;
ParamNames : array of string;
ParamValues : array of variant;
IncludeSchema : boolean = FALSE;
MaxRecords : integer = -1) : TDADatasetRequestInfo;
var i : integer;
begin
if (Length(ParamNames)<>Length(ParamValues))
then raise EROUserError.Create('ParamNames and ParamValues arrays don''t contain the same number of items');
result := anArray.Add;
result.DatasetName := DatasetName;
result.MaxRecords := MaxRecords;
result.IncludeSchema := IncludeSchema;
if (Length(ParamNames)>0) then begin
result.Params := TDADatasetParamArray.Create;
for i := 0 to (Length(ParamNames)-1) do
NewDatasetParam(result.Params, ParamNames[i], ParamValues[i]);
end
else result.Params := NIL;
end;
{ TDAStatementCollection }
function TDAStatementCollection.Add: TDAStatement;
begin
result := TDAStatement(inherited Add);
end;
function TDAStatementCollection.FindItem(const aName: string; const aStatementName: string=''; const aConnectionType: string = ''; aReturnDefault: Boolean = false): TDAStatement;
var
i: integer;
lDef, lStatement:TDAStatement;
begin
result := nil;
lDef := nil;
for i := 0 to (Count - 1) do begin
lStatement := Items[i] as TDAStatement;
if lStatement.Default then lDef := lStatement;
if
((aConnectionType <> '') and (SameText(lStatement.ConnectionType, aConnectionType))) or
SameText(lStatement.Connection, aName) and
((aStatementName = '') or SameText(lStatement.Name, aStatementName)) then begin
result := lStatement;
exit;
end;
end;
if aReturnDefault then result := lDef;
end;
constructor TDAStatementCollection.Create(aOwner: TPersistent; aSQLCommand: TDASQLCommand);
begin
inherited Create(aOwner, TDAStatement);
FAllowEmptyName := True;
fSQLCommand := aSQLCommand;
end;
function TDAStatementCollection.GetItemName(
anItem: TCollectionItem): string;
begin
result := GetPropValue(anItem, 'Connection', TRUE);
end;
function TDAStatementCollection.GetStatements(
Index: integer): TDAStatement;
begin
result := TDAStatement(inherited Items[Index])
end;
function TDAStatementCollection.SetItemName(anItem: TCollectionItem;
const aName: string): string;
begin
SetPropValue(anItem, 'Connection', aName);
end;
procedure TDAStatementCollection.SetStatements(Index: integer;
const Value: TDAStatement);
begin
Statements[Index].Assign(Value);
end;
function TDAStatementCollection.StatementByName(
const aName: string): TDAStatement;
begin
result := TDAStatement(inherited ItemByName(aName));
end;
{ TDABaseField }
procedure TDABaseField.Assign(Source: TPersistent);
begin
if (Source is TDABaseField) then begin
AssignField(TDABaseField(Source));
end
else begin
inherited;
end;
end;
procedure TDABaseField.AssignField(Source: TDABaseField);
begin
fSize := Source.fSize;
fDescription := Source.fDescription;
fName := Source.fName;
fDataType := Source.fDataType;
fValue := Source.fValue;
fBlobType := Source.fBlobType;
fGeneratorName := Source.GeneratorName;
FDecimalPrecision := Source.FDecimalPrecision;
FDecimalScale := Source.FDecimalScale;
end;
{procedure TDABaseField.FixSize;
begin
if (fDataType <> datString) then fSize := 0;
end;}
function TDABaseField.GetDataType: TDADataType;
begin
if not HasValidDictionaryField then begin
result := fDataType
end
else begin
result := GetDictionaryField().DataType;
end;
end;
function TDABaseField.GetDescription: string;
begin
if not HasValidDictionaryField then begin
result := fDescription;
end
else begin
result := GetDictionaryField().Description;
end;
end;
function TDABaseField.GetName: string;
begin
result := fName
end;
function TDABaseField.GetSize: integer;
begin
if (DataType <> datString) and (DataType <> datWideString) then begin
result := 0;
end
else begin
if not HasValidDictionaryField then begin
result := fSize
end
else begin
result := GetDictionaryField().Size;
end;
end;
end;
function TDABaseField.GetValue: Variant;
begin
result := fValue
end;
procedure TDABaseField.SetDataType(Value: TDADataType);
begin
fDataType := Value;
//FixSize();
end;
procedure TDABaseField.SetDescription(const Value: string);
begin
fDescription := Value;
end;
procedure TDABaseField.SetName(const Value: string);
var
lOldName: string;
begin
lOldName := fName;
fName := Value;
if lOldName <> '' then
(Collection as TSearcheableCollection).TriggerOnItemRenamed(lOldName, fName);
end;
procedure TDABaseField.SetSize(Value: integer);
begin
fSize := Value;
//FixSize();
end;
procedure TDABaseField.SetValue(const aValue: Variant);
begin
fValue := aValue
end;
function TDABaseField.GetAsBoolean: boolean;
begin
result := GetVarBoolean(Value);
//if VarIsNull(Value) then result := FALSE else result := Value;
end;
function TDABaseField.GetAsCurrency: currency;
begin
result := GetVarCurrency(Value);
//if VarIsNull(Value) then result := 0 else result := Value;
end;
function TDABaseField.GetAsDateTime: TDateTime;
begin
result := GetVarDateTime(Value);
//if VarIsNull(Value) then result := 0 else result := Value;
end;
function TDABaseField.GetAsFloat: double;
begin
result := GetVarFloat(Value);
//if VarIsNull(Value) then result := 0 else result := Value;
end;
function TDABaseField.GetAsInteger: integer;
begin
result := GetVarInteger(Value);
//if VarIsNull(Value) then result := 0 else result := Value;
end;
function TDABaseField.GetAsString: string;
begin
result := GetVarString(Value);
//if VarIsNull(Value) then result := '' else result := Value;
end;
function TDABaseField.GetAsVariant: variant;
begin
result := Value
end;
procedure TDABaseField.SetAsBoolean(const aValue: boolean);
begin
Value := aValue;
end;
procedure TDABaseField.SetAsCurrency(const aValue: currency);
begin
Value := aValue;
end;
procedure TDABaseField.SetAsDateTime(const aValue: TDateTime);
begin
Value := aValue;
end;
procedure TDABaseField.SetAsFloat(const aValue: double);
begin
Value := aValue;
end;
procedure TDABaseField.SetAsString(const aValue: string);
begin
Value := aValue;
end;
procedure TDABaseField.SetAsVariant(const aValue: variant);
begin
Value := aValue;
end;
procedure TDABaseField.SetAsInteger(const aValue: integer);
begin
Value := aValue;
end;
function TDABaseField.GetDisplayName: string;
begin
//result := Format('%s %-20s [%s, %d]', [GetName, '', GetEnumName(TypeInfo(TDADataType), Ord(DataType)), Size]);
result := GetName;
end;
function TDABaseField.GetNamePath: string;
begin
if (Collection <> nil) then
result := Collection.GetNamePath + Name
else
result := inherited GetNamePath;
result := inherited GetNamePath;
end;
function TDABaseField.GetDictionaryEntry: string;
begin
result := fDictionaryEntry
end;
procedure TDABaseField.SetDictionaryEntry(const Value: string);
begin
fDictionaryEntry := Value
end;
function TDABaseField.FindDictionaryField: TDACustomField;
var
lOwner: TObject;
lHasDict: IDAHasDataDictionary;
lDictionary: IDADataDictionary;
begin
result := nil;
if DictionaryEntry = '' then exit;
lDictionary := TDACustomFieldCollection(Collection).DataDictionary;
{ No Dictionary assigned? then try getting dictionary from owning Schema }
if not Assigned(lDictionary) then begin
lOwner := TDACustomFieldCollection(Collection).Owner;
if not (lOwner is TDADataSet) then exit;
lOwner := TDADatasetCollection(TDADataSet(lOwner).Collection).Owner;
// if not (lOwner is TDASchema) then exit;
// lDictionary := TDASchema(lOwner).DataDictionary;
if Supports(lOwner, IDAHasDataDictionary, lHasDict) then
lDictionary := lHasDict.DataDictionary;
end;
if Assigned(lDictionary) then
result := lDictionary.Fields.FindField(DictionaryEntry);
end;
function TDABaseField.GetDictionaryField: TDACustomField;
begin
result := FindDictionaryField();
if not Assigned(result) then
RaiseError('Dictionary entry %s not found for field %s', [DictionaryEntry, Name])
end;
function TDABaseField.HasValidDictionaryField: Boolean;
begin
result := (DictionaryEntry <> '') and
Assigned(FindDictionaryField());
end;
function TDABaseField.IsCompatibleV4: boolean;
begin
Result:=False;
end;
function TDABaseField.StoreDataType: Boolean;
begin
result := MergeDatadictionaries or not HasValidDictionaryField();
end;
function TDABaseField.StoreDecimalPrecision: Boolean;
begin
Result:= (MergeDatadictionaries or (FDecimalPrecision <>0)) and not IsCompatibleV4;
end;
function TDABaseField.StoreDecimalScale: Boolean;
begin
Result:= (MergeDatadictionaries or (FDecimalScale <>0)) and not IsCompatibleV4;
end;
function TDABaseField.StoreGeneratorName: Boolean;
begin
result := MergeDatadictionaries or not HasValidDictionaryField();
end;
function TDABaseField.StoreDescription: Boolean;
begin
result := MergeDatadictionaries or not HasValidDictionaryField();
end;
function TDABaseField.StoreSize: Boolean;
begin
result := MergeDatadictionaries or (((DataType = datString) or (DataType = datWideString)) and (not HasValidDictionaryField()));
end;
function TDABaseField.GetBlobType: TDABlobType;
begin
if HasValidDictionaryField
then result := GetDictionaryField().BlobType
else result := fBlobType
end;
function TDABaseField.GetGeneratorName: string;
begin
if not HasValidDictionaryField then begin
result := fGeneratorName
end
else begin
result := GetDictionaryField().GeneratorName;
end;
end;
procedure TDABaseField.SetBlobType(const Value: TDABlobType);
begin
fBlobType := Value;
end;
function TDABaseField.StoreBlobType: boolean;
begin
result := HasValidDictionaryField;
end;
procedure TDABaseField.Clear;
begin
Value := Null;
end;
procedure TDABaseField.SetGeneratorName(const aValue: string);
begin
fGeneratorName := aValue
end;
procedure TDABaseField.SetDisplayName(const Value: string);
begin
inherited;
fName := Value;
end;
function TDABaseField.GetAsLargeInt: int64;
begin
Result := GetVarInt64(Value);
end;
procedure TDABaseField.SetAsLargeInt(const aValue: Int64);
begin
Value := aValue;
end;
function TDABaseField.GetAsWideString: Widestring;
begin
Result := GetVarWideString(Value);
end;
procedure TDABaseField.SetAsWideString(const aValue: Widestring);
begin
Value := aValue;
end;
function TDABaseField.GetIsNull: boolean;
begin
result := VarIsNull(Value);
end;
function TDABaseField.GetBlobSize: Integer;
var
v: Variant;
begin
v := GetValue;
if VarIsArray(v) then result := VarArrayHighBound(V, 1) - VarArrayLowBound(V, 1) + 1
else if VarIsStr(v) then result := Length(v) else
Result := 0;
end;
function TDABaseField.GetAsByte: Byte;
begin
result := GetVarByte(Value);
end;
function TDABaseField.GetAsCardinal: Cardinal;
begin
result := GetVarCardinal(Value);
end;
function TDABaseField.GetAsDecimal: TBcd;
begin
result := GetVarDecimal(Value);
end;
function TDABaseField.GetAsGuid: TGUID;
begin
result := GetVarGuid(Value);
end;
function TDABaseField.GetAsLargeUInt: Int64;
begin
Result := GetVarInt64(Value);
end;
function TDABaseField.GetAsShortInt: ShortInt;
begin
result := GetVarShortInt(Value);
end;
function TDABaseField.GetAsSingle: Single;
begin
result := GetVarSingleFloat(Value);
end;
function TDABaseField.GetAsSmallInt: SmallInt;
begin
result := GetVarSmallInt(Value);
end;
function TDABaseField.GetAsWord: Word;
begin
result := GetVarWord(Value);
end;
function TDABaseField.GetAsXml: IXMLNode;
begin
result := GetVarXml(Value);
end;
procedure TDABaseField.SetAsByte(const Value: Byte);
begin
self.Value := Value;
end;
procedure TDABaseField.SetAsCardinal(const Value: Cardinal);
begin
self.Value := Value;
end;
procedure TDABaseField.SetAsDecimal(const Value: TBcd);
begin
self.Value := BCDToVariant(Value);
end;
procedure TDABaseField.SetAsGuid(const Value: TGUID);
begin
self.Value := GuidToString(Value);
end;
procedure TDABaseField.SetAsLargeUInt(const Value: Int64);
begin
self.Value := Value;
end;
procedure TDABaseField.SetAsShortInt(const Value: ShortInt);
begin
self.Value := Value;
end;
procedure TDABaseField.SetAsSingle(const Value: Single);
begin
self.Value := Value;
end;
procedure TDABaseField.SetAsSmallInt(const Value: SmallInt);
begin
self.Value := Value;
end;
procedure TDABaseField.SetAsWord(const Value: Word);
begin
self.Value := Value;
end;
procedure TDABaseField.SetAsXml(const Value: IXMLNode);
begin
if Value = nil then
Self.Value := null
else
self.Value := Value.XML;
end;
procedure TDABaseField.SetDecimalPrecision(const Value: Integer);
begin
FDecimalPrecision := Value;
end;
function TDABaseField.GetDecimalPrecision: Integer;
begin
if not HasValidDictionaryField then begin
result := FDecimalPrecision
end
else begin
result := GetDictionaryField().DecimalPrecision;
end;
end;
function TDABaseField.GetDecimalScale: Integer;
begin
if not HasValidDictionaryField then begin
result := FDecimalScale
end
else begin
result := GetDictionaryField().DecimalScale;
end;
end;
procedure TDABaseField.SetDecimalScale(const Value: Integer);
begin
FDecimalScale := Value;
end;
function TDABaseField.MergeDatadictionaries: Boolean;
var
lOwner: TObject;
lSchema: IDASchema;
begin
result := false;
if DictionaryEntry = '' then exit;
lOwner := TDACustomFieldCollection(Collection).Owner;
if not (lOwner is TDADataSet) then exit;
lOwner := TDADatasetCollection(TDADataSet(lOwner).Collection).Owner;
if Supports(lOwner, IDASchema, lSchema) then
result := lSchema.MergeDataDictionaries;
end;
{ TDACustomField }
constructor TDACustomField.Create(Collection: TCollection);
begin
inherited;
fServerAutoRefresh := FALSE;
fCustomAttributes := TStringList.Create;
fVisible := TRUE;
fLogChanges := TRUE;
end;
destructor TDACustomField.Destroy;
begin
fCustomAttributes.Free;
inherited;
end;
function TDACustomField.GetInPrimaryKey: boolean;
begin
result := fInPrimaryKey
end;
function TDACustomField.GetRegExpression: string;
begin
if not HasValidDictionaryField
then result := fRegExpression
else result := GetDictionaryField().RegExpression;
end;
function TDACustomField.GetDefaultValue: string;
begin
if not HasValidDictionaryField
then result := fDefaultValue
else result := GetDictionaryField().DefaultValue;
end;
function TDACustomField.GetRequired: boolean;
begin
if not HasValidDictionaryField
then result := fRequired
else result := GetDictionaryField().Required;
end;
function TDACustomField.GetDisplayLabel: string;
begin
if not HasValidDictionaryField
then result := fDisplayLabel
else result := GetDictionaryField().DisplayLabel;
if (result='') then result := Name;
end;
function TDACustomField.GetDisplayWidth: integer;
begin
if not HasValidDictionaryField
then result := fDisplayWidth
else result := GetDictionaryField().DisplayWidth;
end;
function TDACustomField.GetEditMask: string;
begin
if not HasValidDictionaryField
then result := fEditMask
else result := GetDictionaryField().EditMask;
end;
function TDACustomField.GetReadOnly: boolean;
begin
if not HasValidDictionaryField
then result := fReadOnly
else result := GetDictionaryField().ReadOnly;
end;
function TDACustomField.GetVisible: boolean;
begin
if not HasValidDictionaryField
then result := fVisible
else result := GetDictionaryField().Visible;
end;
function TDACustomField.GetDisplayFormat: string;
begin
if not HasValidDictionaryField
then result := fDisplayFormat
else result := GetDictionaryField().DisplayFormat;
end;
function TDACustomField.GetAlignment: TAlignment;
begin
if not HasValidDictionaryField
then result := fAlignment
else result := GetDictionaryField().Alignment;
end;
function TDACustomField.GetEditFormat: string;
begin
if not HasValidDictionaryField
then result := fEditFormat
else result := GetDictionaryField().EditFormat;
end;
procedure TDACustomField.SetInPrimaryKey(const Value: boolean);
begin
fInPrimaryKey := Value
end;
procedure TDACustomField.SetRegExpression(const Value: string);
begin
fRegExpression := Value
end;
procedure TDACustomField.LoadFromFile(const aFileName: string);
begin
if (fField<>nil) then begin
if (fField is TBlobField) then TBlobField(fField).LoadFromFile(aFileName)
end
else RaiseError(err_FieldIsNotBound);
end;
procedure TDACustomField.SaveToFile(const aFileName: string);
begin
if (fField<>nil) then begin
if (fField is TBlobField) then TBlobField(fField).SaveToFile(aFileName)
end
else RaiseError(err_FieldIsNotBound);
end;
procedure TDACustomField.LoadFromStream(const aStream: IROStream);
begin
LoadFromStream(aStream.Stream);
end;
procedure TDACustomField.SaveToStream(const aStream: IROStream);
begin
SaveToStream(aStream.Stream);
end;
function TDACustomField.GetValue: Variant;
begin
if Assigned(fField) then begin
if fField.IsNull then Result := Null else
{$IFNDEF FPC}
if fField is TWideStringField then result := TWideStringField(fField).Value else
{$ENDIF}
{$IFDEF DELPHI10UP}
if fField is TWideMemoField then result := TWideMemoField(fField).Value else
{$ENDIF DELPHI10UP}
result := fField.Value;
end
else result := Null;
end;
procedure TDACustomField.SetValue(const Value: Variant);
var
aDecimal: TDecimal;
begin
if Assigned(fField) then begin
{$IFNDEF FPC}
if (fField is TWideStringField) and not VarIsNull( Value ) then
TWideStringField(fField).Value := Value else
{$ENDIF}
{$IFDEF DELPHI10UP}
if (fField is TWideMemoField) and not VarIsNull( Value ) then
fField.AsWideString := Value else
{$ENDIF DELPHI10UP}
if (fField is TLargeintField) and not VarIsNull( Value ) then
TLargeintField(fField).Value := Value else
if VarByteArrayToDecimal(Value,aDecimal) then
SetAsDecimal(DecimalToBCD(aDecimal)) else
fField.Value := Value
end
else RaiseError(err_FieldIsNotBound);
end;
procedure TDACustomField.Bind(aField: TField);
begin
fField := aField;
if Assigned(fField) then begin
fField.DisplayLabel := DisplayLabel;
fField.DisplayWidth := DisplayWidth;
{$IFNDEF FPC}
fField.EditMask := EditMask;
{$ENDIF FPC}
fField.ReadOnly := ReadOnly;
fField.Required := Required;
fField.Visible := Visible;
fField.Alignment := Alignment;
if (fField is TNumericField) then begin
TNumericField(fField).DisplayFormat := DisplayFormat;
TNumericField(fField).EditFormat := EditFormat;
end
else if (fField is TDateTimeField) then begin
TDateTimeField(fField).DisplayFormat := DisplayFormat
end
{$IFNDEF FPC}
else if (fField is TFMTBCDField) then begin
TFMTBCDField(fField).Precision := DecimalPrecision;
TFMTBCDField(fField).Size := DecimalScale;
end
else if (fField is TBCDField) then begin
TBCDField(fField).Precision := DecimalPrecision;
TBCDField(fField).Size := DecimalScale;
end
{$ENDIF FPC}
else if (fField is TBlobField) then begin
{$IFDEF DELPHI10UP}
if TBlobField(fField).BlobType <> ftWideMemo then
{$ENDIF}
TBlobField(fField).BlobType := BlobTypeMappings[BlobType];
end;
fField.OnValidate := InternalOnValidate;
fField.OnChange := InternalOnChange;
{fField.Lookup := Lookup;
if (LookupSource<>NIL) then
with TDADataSource(LookupSource) do
if Assigned(DataTable)
then fField.LookupDataSet := DataTable.Dataset;
fField.LookupKeyFields := LookupKeyFields;
fField.LookupCache := LookupCache;
fField.LookupResultField := LookupResultField;
fField.KeyFields := KeyFields;}
end;
end;
procedure TDACustomField.Unbind;
begin
if (fField=NIL) then Exit;
fField.OnChange := nil;
fField.OnSetText := nil;
fField.OnGetText := nil;
fField.OnValidate := nil;
fField := nil;
end;
function TDACustomField.GetTableField: string;
begin
result := fTableField
end;
procedure TDACustomField.SetTableField(const Value: string);
begin
fTableField := Value;
end;
procedure TDACustomField.SetName(const Value: string);
var
updatesc: boolean;
begin
updatesc := (fTableField = '') or (fTableField = Name);
inherited;
if updatesc then fTableField := Value;
end;
function TDACustomField.GetCustomAttributes: TStrings;
begin
result := fCustomAttributes
end;
procedure TDACustomField.SetCustomAttributes(const Value: TStrings);
begin
fCustomAttributes.Assign(Value);
end;
procedure TDACustomField.Assign(Source: TPersistent);
begin
if (Source is TDACustomField) then begin
AssignField(TDACustomField(Source));
end
else begin
inherited;
end;
end;
procedure TDACustomField.AssignField(Source: TDABaseField);
var
lSource: TDACustomField;
begin
inherited;
lSource := TDACustomField(Source);
fField := nil; { Assigned DAField will always be unbound }
fTableField := lSource.fTableField;
fRequired := lSource.fRequired;
fInPrimaryKey := lSource.fInPrimaryKey;
fRegExpression := lSource.fRegExpression;
fDefaultValue := lSource.fDefaultValue;
fDictionaryEntry := lSource.fDictionaryEntry;
fDisplayWidth := lSource.fDisplayWidth;
fDisplayLabel := lSource.fDisplayLabel;
fDisplayFormat := lSource.DisplayFormat;
fReadOnly := lSource.fReadOnly;
fVisible := lSource.fVisible;
fEditMask := lSource.fEditMask;
fLogChanges := lSource.fLogChanges;
fCalculated := lSource.fCalculated;
fServerCalculated := lSource.fServerCalculated;
fEditFormat := lSource.EditFormat;
fAlignment := lSource.Alignment;
fOnChange := lSource.OnChange;
{fOnGetText := lSource.OnGetText;
fOnSetText := lSource.OnSetText;}
fOnValidate := lSource.OnValidate;
fLookupCache := lSource.LookupCache;
fLookupKeyFields := lSource.LookupKeyFields;
fLookupResultField := lSource.LookupResultField;
fKeyFields := lSource.KeyFields;
fLookupSource := lSource.LookupSource;
fLookup := lSource.Lookup;
//fCustomAttributes.Assign(lSource.fCustomAttributes);
fCustomAttributes.Text := lSource.fCustomAttributes.Text;
fServerAutoRefresh := lSource.ServerAutoRefresh;
fGeneratorName := lSource.GeneratorName;
fBusinessClassID := lSource.BusinessClassID;
end;
procedure TDACustomField.InternalOnChange(Sender: TField);
begin
if not (Collection as TDACustomFieldCollection).FieldEventsDisabled then
begin
if assigned(TDACustomFieldCollection(Collection).OnFieldAfterUpdate) then
TDACustomFieldCollection(Collection).OnFieldAfterUpdate(Self);
if Assigned(fOnChange) then
fOnChange(Self);
end;
end;
procedure TDACustomField.InternalOnValidate(Sender: TField);
begin
if not (Collection as TDACustomFieldCollection).FieldEventsDisabled then
begin
if assigned(TDACustomFieldCollection(Collection).OnFieldBeforeUpdate) then
TDACustomFieldCollection(Collection).OnFieldBeforeUpdate(Self);
if Assigned(fOnValidate) then
fOnValidate(Self);
end;
end;
function TDACustomField.IsCompatibleV4: boolean;
begin
if Assigned(FieldCollection) then
Result := FieldCollection.IsCompatibleV4
else
Result := inherited IsCompatibleV4;
end;
procedure TDACustomField.SetDisplayLabel(const aValue: string);
begin
fDisplayLabel := aValue;
if Assigned(fField) then fField.DisplayLabel := aValue;
end;
procedure TDACustomField.SetRequired(const aValue: boolean);
begin
fRequired := aValue;
if Assigned(fField) then fField.Required := aValue;
end;
procedure TDACustomField.SetVisible(const aValue: boolean);
begin
fVisible := aValue;
if Assigned(fField) then fField.Visible := aValue;
end;
procedure TDACustomField.SetDisplayWidth(const aValue: integer);
begin
fDisplayWidth := aValue;
if Assigned(fField) then fField.DisplayWidth := aValue;
end;
procedure TDACustomField.SetEditMask(const aValue: string);
begin
fEditMask := aValue;
{$IFNDEF FPC}
if Assigned(fField) then fField.EditMask := aValue;
{$ENDIF}
end;
procedure TDACustomField.SetReadOnly(const aValue: boolean);
begin
fReadOnly := aValue;
if Assigned(fField) then fField.ReadOnly := aValue;
end;
procedure TDACustomField.SetDisplayFormat(const Value: string);
begin
fDisplayFormat := Value;
if Assigned(fField) then begin
if (fField is TNumericField) then
TNumericField(fField).DisplayFormat := Value
else if (fField is TDateTimeField) then
TDateTimeField(fField).DisplayFormat := Value;
end;
end;
function TDACustomField.StoredExpression: Boolean;
begin
Result:= not IsCompatibleV4;
end;
function TDACustomField.StoreDisplayLabel: Boolean;
begin
result := MergeDatadictionaries or (not HasValidDictionaryField()) and (fDisplayLabel <> '') and (fDisplayLabel <> Name);
end;
function TDACustomField.StoredServerCalculated: Boolean;
begin
Result:= not IsCompatibleV4;
end;
function TDAField.GetDisplayName: string;
begin
result := Format('%s [%s, %d', [fName, GetEnumName(TypeInfo(TDADataType), Ord(DataType)), Size]);
if Required then
result := result+', REQUIRED';
result := result+']'
end;
function TDACustomField.GetOwner: TPersistent;
begin
result := Collection;
end;
function TDACustomField.GetNamePath: string;
begin
if (Collection <> nil) and (Collection.Owner <> nil) and (Collection.Owner is TComponent) then
result := TComponent(Collection.Owner).Name + '.' + FName
else
result := FName;
end;
procedure TDACustomField.SetAlignment(const Value: TAlignment);
begin
fAlignment := Value;
if Assigned(fField) then fField.Alignment := Value;
end;
procedure TDACustomField.SetEditFormat(const Value: string);
begin
fEditFormat := Value;
if Assigned(fField) then begin
if (fField is TNumericField) then TNumericField(fField).EditFormat := Value
end;
end;
procedure TDACustomField.SetKeyFields(const Value: string);
begin
fKeyFields := Value;
if Assigned(fField)
then fField.KeyFields := Value;
end;
procedure TDACustomField.SetLookupCache(const Value: boolean);
begin
fLookupCache := Value;
if Assigned(fField)
then fField.LookupCache := Value;
end;
procedure TDACustomField.SetLookupKeyFields(const Value: string);
begin
fLookupKeyFields := Value;
if Assigned(fField)
then fField.LookupKeyFields := Value;
end;
procedure TDACustomField.SetLookupResultField(const Value: string);
begin
fLookupResultField := Value;
if Assigned(fField)
then fField.LookupResultField := Value;
end;
procedure TDACustomField.SetLookupSource(const Value: TDataSource);
begin
if Assigned(Value) and not (Value is TDABaseDataSource) then raise Exception.Create('LookupSource must be a TDADataSource');
fLookupSource := Value;
if Assigned(fField) then
if Assigned(Value)
then fField.LookupDataSet := Value.DataSet
else fField.LookupDataSet := nil;
end;
procedure TDACustomField.SetCalculated(const Value: boolean);
begin
fCalculated := Value;
if Value then begin
fLookup := FALSE;
fServerCalculated := false;
end;
end;
procedure TDACustomField.SetLookup(const Value: boolean);
begin
fLookup := Value;
if Value then begin
fCalculated := FALSE;
end;
end;
function TDACustomField.GetFieldCollection: TDACustomFieldCollection;
begin
result := TDACustomFieldCollection(Collection);
end;
procedure TDACustomField.SetBlobType(const Value: TDABlobType);
begin
inherited;
if Assigned(fField) and (fField is TBlobField)
then TBlobField(fField).BlobType := BlobTypeMappings[Value];
end;
function TDACustomField.GetServerAutoRefresh: boolean;
begin
result := fServerAutoRefresh
end;
procedure TDACustomField.SetServerAutoRefresh(const Value: boolean);
begin
fServerAutoRefresh := Value;
end;
function TDACustomField.GetLogChanges: boolean;
begin
if not HasValidDictionaryField
then result := fLogChanges
else result := GetDictionaryField().fLogChanges;
result := Result and not (fCalculated or fLookup)
end;
function TDACustomField.StoreProperties: boolean;
begin
result := MergeDatadictionaries or not HasValidDictionaryField();
end;
function TDACustomField.GetOldValue: Variant;
begin
if Assigned(fField)
then result := fField.OldValue
else result := Unassigned;
end;
function TDACustomField.GetSQLOrigin: string;
begin
if fSQLOrigin=''
then result := TableField
else result := fSQLOrigin;
end;
procedure TDACustomField.FocusControl;
begin
if Assigned(fField)
then fField.FocusControl;
end;
{procedure TDACustomField.SetBusinessRulesID(const Value: string);
begin
BusinessClassID := Value;
end;
function TDACustomField.GetBusinessRulesID: string;
begin
result := BusinessClassID;
end;}
function TDACustomField.GetBusinessClassID: string;
begin
if not HasValidDictionaryField
then result := fBusinessClassID
else result := GetDictionaryField().BusinessClassID;
end;
procedure TDACustomField.SetBusinessClassID(const Value: string);
begin
fBusinessClassID := Value;
end;
procedure TDACustomField.LoadFromStream(const aStream: TStream);
begin
if (fField<>nil) then begin
if (fField is TBlobField) then TBlobField(fField).LoadFromStream(aStream)
end
else RaiseError(err_FieldIsNotBound);
end;
procedure TDACustomField.SaveToStream(const aStream: TStream);
begin
if (fField<>nil) then begin
if (fField is TBlobField) then TBlobField(fField).SaveToStream(aStream)
end
else RaiseError(err_FieldIsNotBound);
end;
function TDACustomField.GetBlobSize: Integer;
begin
if fField is TBlobField then
result := TBlobField(fField).BlobSize
else
Result := 0;
end;
procedure TDACustomField.SetServerCalculated(const Value: Boolean);
begin
fServerCalculated := Value;
if Value then begin
Readonly := True;
LogChanges := False;
Calculated := False;
InPrimaryKey := False;
end;
end;
procedure TDACustomField.SetExpression(const Value: string);
begin
fExpression := Value;
if value <> '' then
Calculated := true; // will unset lookup & server calculated
end;
function TDACustomField.GetAsBoolean: boolean;
begin
if Assigned(fField) then
Result:= fField.AsBoolean
else
Result:= inherited GetAsBoolean;
end;
function TDACustomField.GetAsCurrency: currency;
begin
if Assigned(fField) then
Result:= fField.AsCurrency
else
Result:= inherited GetAsCurrency;
end;
function TDACustomField.GetAsDateTime: TDateTime;
begin
if Assigned(fField) then
Result:= fField.AsDateTime
else
Result:= inherited GetAsDateTime;
end;
function TDACustomField.GetAsFloat: double;
begin
if Assigned(fField) then
Result:= fField.AsFloat
else
Result:= inherited GetAsFloat;
end;
function TDACustomField.GetAsInteger: integer;
begin
if Assigned(fField) then
Result:= fField.AsInteger
else
Result:= inherited GetAsInteger;
end;
function TDACustomField.GetAsLargeInt: int64;
begin
if Assigned(fField) and (fField.DataType = ftLargeInt) then
Result:= TLargeintField(fField).AsLargeint
else
result:= inherited GetAsLargeInt;
end;
function TDACustomField.GetAsString: string;
begin
if Assigned(fField) then
Result:= fField.AsString
else
Result:= inherited GetAsString;
end;
function TDACustomField.GetAsVariant: variant;
begin
if Assigned(fField) then
Result:= fField.AsVariant
else
Result:= inherited GetAsVariant;
end;
function TDACustomField.GetAsWideString: Widestring;
begin
if Assigned(fField) and (fField.DataType = ftWideString) then begin
if GetIsNull then
Result:=''
else
{$IFNDEF FPC}
Result := TWideStringField(fField).Value;
{$ELSE}
REsult:= inherited GetAsWideString;
{$ENDIF}
end
{$IFDEF DELPHI10UP}
else if Assigned(fField) and (fField.DataType = ftWideMemo) then
Result := TWideMemoField(fField).Value
{$ENDIF}
else
Result := inherited GetAsWideString;
end;
function TDACustomField.GetIsNull: boolean;
begin
if Assigned(fField) then
Result:= fField.IsNull
else
Result:= inherited GetIsNull;
end;
procedure TDACustomField.SetAsBoolean(const aValue: boolean);
begin
if Assigned(fField) then
fField.AsBoolean := aValue
else
inherited SetAsBoolean(aValue);
end;
procedure TDACustomField.SetAsCurrency(const aValue: currency);
begin
if Assigned(fField) then
fField.AsCurrency := aValue
else
inherited SetAsCurrency(aValue);
end;
procedure TDACustomField.SetAsDateTime(const aValue: TDateTime);
begin
if Assigned(fField) then
fField.AsDateTime := aValue
else
inherited SetAsDateTime(aValue);
end;
procedure TDACustomField.SetAsFloat(const aValue: double);
begin
if Assigned(fField) then
fField.AsFloat := aValue
else
inherited SetAsFloat(aValue);
end;
procedure TDACustomField.SetAsInteger(const aValue: integer);
begin
if Assigned(fField) then
fField.AsInteger := aValue
else
inherited SetAsInteger(aValue);
end;
procedure TDACustomField.SetAsLargeInt(const aValue: Int64);
begin
if Assigned(fField) and (fField.DataType = ftLargeInt) then
TLargeintField(fField).AsLargeInt := aValue
else
inherited SetAsLargeInt(aValue);
end;
procedure TDACustomField.SetAsString(const aValue: string);
begin
if Assigned(fField) then
fField.AsString := aValue
else
inherited SetAsString(aValue);
end;
procedure TDACustomField.SetAsVariant(const aValue: variant);
begin
if Assigned(fField) then
fField.AsVariant := aValue
else
inherited SetAsVariant(aValue);
end;
procedure TDACustomField.SetAsWideString(const aValue: Widestring);
begin
{$IFNDEF FPC}
if (fField<>nil) and (fField.DataType = ftWideString) then TWideStringField(fField).Value := aValue else
{$ENDIF}
{$IFDEF DELPHI10UP}
if (fField<>nil) and (fField.DataType = ftWideMemo) then TWideMemoField(fField).Value := aValue else
{$ENDIF}
inherited SetAsWideString(aValue);
end;
function TDACustomField.GetAsByte: Byte;
begin
Result := GetAsSmallInt;
end;
function TDACustomField.GetAsCardinal: Cardinal;
begin
Result := GetAsInteger;
end;
function TDACustomField.GetAsDecimal: TBcd;
begin
{$IFNDEF FPC}
if Assigned(fField) and (fField.DataType = ftFmtBcd) then
result := TFMTBCDField(fField).AsBCD
else
{$ENDIF}
result := inherited GetAsDecimal;
end;
function TDACustomField.GetAsGuid: TGUID;
begin
{$IFNDEF FPC}
if Assigned(fField) and (fField.DataType = ftGuid) then
result := TGuidField(fField).AsGuid
else
{$ENDIF}
result := inherited GetAsGuid;
end;
function TDACustomField.GetAsLargeUInt: Int64;
begin
result := GetAsLargeInt;
end;
function TDACustomField.GetAsShortInt: ShortInt;
begin
Result := GetAsSmallInt;
end;
function TDACustomField.GetAsSingle: Single;
begin
if Assigned(fField) then
result := fField.AsFloat
else
Result := inherited GetAsSingle;
end;
function TDACustomField.GetAsSmallInt: SmallInt;
begin
if Assigned(fField) and (fField.DataType = ftSmallint) then
result := TSmallintField(fField).Value
else
result := inherited GetAsSmallInt;
end;
function TDACustomField.GetAsWord: Word;
begin
if Assigned(fField) and (fField.DataType = ftWord) then
result := TWordField(fField).AsInteger
else
result := inherited GetAsWord;
end;
function TDACustomField.GetAsXml: IXMLNode;
var
s: string;
lDoc: IXMLDocument;
begin
s := GetAsWideString;
if s = '' then result := nil else begin
lDoc := NewROXmlDocument;
lDoc.New;
lDoc.XML := s;
Result := lDoc.DocumentNode;
end;
end;
procedure TDACustomField.SetAsByte(const Value: Byte);
begin
SetAsSmallInt(Value);
end;
procedure TDACustomField.SetAsCardinal(const Value: Cardinal);
begin
SetAsInteger(Value);
end;
procedure TDACustomField.SetAsDecimal(const Value: TBcd);
begin
{$IFNDEF FPC}
if (fField<>nil) and (fField.DataType = ftFMTBcd) then
TFMTBCDField(fField).Value := Value
else
{$ENDIF}
inherited SetAsDecimal(Value);
end;
procedure TDACustomField.SetAsGuid(const Value: TGUID);
begin
{$IFNDEF FPC}
if (fField<>nil) and (fField.DataType = ftGuid) then
TGuidField(fField).AsGuid := Value
else
{$ENDIF}
inherited SetAsGuid(Value);
end;
procedure TDACustomField.SetAsLargeUInt(const Value: Int64);
begin
SetAsLargeInt(Value);
end;
procedure TDACustomField.SetAsShortInt(const Value: ShortInt);
begin
SetAsSmallInt(Value);
end;
procedure TDACustomField.SetAsSingle(const Value: Single);
begin
if Assigned(fField) then
SetAsFloat(Value)
else
inherited SetAsSingle(Value);
end;
procedure TDACustomField.SetAsSmallInt(const Value: SmallInt);
begin
if Assigned(fField) and (fField.DataType = ftSmallint) then
TSmallintField(fField).Value := Value
else
inherited SetAsSmallInt(Value);
end;
procedure TDACustomField.SetAsWord(const Value: Word);
begin
if Assigned(fField) and (fField.DataType = ftWord) then
TWordField(fField).AsInteger := Value
else
inherited SetAsWord(Value);
end;
procedure TDACustomField.SetAsXml(const Value: IXMLNode);
begin
if (Value = nil) then
AsVariant := Null
else begin
SetAsWideString(Value.Xml);
end;
end;
procedure TDACustomField.SetDecimalPrecision(const Value: Integer);
begin
inherited;
if Assigned(fField) then begin
{$IFNDEF FPC}
if fField is TFMTBCDField then TFMTBCDField(fField).Precision:=Value
else if fField is TBCDField then TBCDField(fField).Precision:=Value;
{$ENDIF FPC}
end;
end;
function TDACustomField.GetDecimalPrecision: Integer;
begin
Result:=inherited GetDecimalPrecision;
if Assigned(fField) then begin
{$IFNDEF FPC}
if fField is TFMTBCDField then Result := TFMTBCDField(fField).Precision
else if fField is TBCDField then Result := TBCDField(fField).Precision;
{$ENDIF FPC}
end;
end;
function TDACustomField.GetDecimalScale: Integer;
begin
Result:=inherited GetDecimalScale;
if Assigned(fField) then begin
{$IFNDEF FPC}
if fField is TFMTBCDField then Result := TFMTBCDField(fField).Size
else if fField is TBCDField then Result := TBCDField(fField).Size;
{$ENDIF FPC}
end;
end;
procedure TDACustomField.SetDecimalScale(const Value: Integer);
begin
inherited;
if Assigned(fField) then begin
{$IFNDEF FPC}
if fField is TFMTBCDField then TFMTBCDField(fField).Size:=Value
else if fField is TBCDField then TBCDField(fField).Size:=Value;
{$ENDIF FPC}
end;
end;
{ TDACustomFieldCollection }
constructor TDACustomFieldCollection.Create(aOwner: TPersistent; aFieldClass: TDAFieldClass);
begin
inherited Create(aOwner, aFieldClass);
end;
function TDACustomFieldCollection.Add: TDAField;
begin
result := TDAField(inherited Add);
end;
function TDACustomFieldCollection.Add(const aName: string; aType: TDADataType; aSize: integer): TDACustomField;
begin
result := Add;
result.Name := aName;
result.DataType := aType;
result.Size := aSize;
end;
procedure TDACustomFieldCollection.Bind(aDataset: TDataset);
var
i: integer;
lDAField: TDACustomField;
lField: TField;
begin
Check(aDataset = nil, err_InvalidDataset);
try
for i := 0 to (Count - 1) do begin
lDAField := Fields[i];
lField := aDataset.FindField(lDAField.SQLOrigin);
if (not Assigned(lField)) and (not lDAField.Calculated) and not (lDAField.ServerCalculated) and not (lDAField.Lookup) then
RaiseError(err_CannotFindField, [lDAField.SQLOrigin])
else
lDAField.Bind(lField);
end;
except
Unbind;
raise;
end;
end;
procedure TDACustomFieldCollection.Assign(Source: TPersistent);
begin
if (Source is TDACustomFieldCollection) then begin
AssignFieldCollection(TDACustomFieldCollection(Source));
end
else
inherited;
end;
procedure TDACustomFieldCollection.AssignFieldCollection(Source: TDACustomFieldCollection);
var
i: integer;
src: TDACustomFieldCollection;
fld: TDAField;
begin
src := TDACustomFieldCollection(Source);
Clear;
if not Assigned(Source) then Exit;
for i := 0 to (src.Count - 1) do begin
fld := Add;
fld.AssignField(src[i]);
end;
end;
function TDACustomFieldCollection.FieldByName(const aName: string): TDACustomField;
begin
result := TDACustomField(inherited ItemByName(aName))
end;
function TDACustomFieldCollection.FindField(const aName: string): TDACustomField;
begin
result := TDACustomField(inherited FindItem(aName))
end;
function TDACustomFieldCollection.GetFields(Index: integer): TDACustomField;
begin
result := TDACustomField(inherited Items[Index])
end;
procedure TDACustomFieldCollection.SetFields(Index: integer; const Value: TDACustomField);
begin
Fields[Index].Assign(Value);
end;
procedure TDACustomFieldCollection.Unbind;
var
i: integer;
begin
for i := 0 to (Count - 1) do
Fields[i].Unbind;
end;
{ TDAFieldCollection }
constructor TDAFieldCollection.Create(aOwner: TPersistent);
begin
inherited Create(aOwner, TDAField);
end;
function TDAFieldCollection.FieldByName(const aName: string): TDAField;
begin
result := TDAField(inherited ItemByName(aName))
end;
function TDAFieldCollection.FindField(const aName: string): TDAField;
begin
result := TDAField(inherited FindItem(aName))
end;
function TDAFieldCollection.GetFields(Index: integer): TDAField;
begin
result := TDAField(inherited Items[Index])
end;
procedure TDAFieldCollection.SetFields(Index: integer; const Value: TDAField);
begin
Fields[Index].Assign(Value);
end;
{ TDAParam }
function TDAParam.GetParamType: TDAParamType;
begin
result := fParamType;
end;
procedure TDAParam.LoadFromFile(const aFileName: string);
begin
LoadFromStream(NewROStream(TFileStream.Create(aFileName, fmOpenRead), TRUE));
end;
procedure TDAParam.SaveToFile(const aFileName: string);
begin
SaveToStream(NewROStream(TFileStream.Create(aFileName, fmCreate), TRUE));
end;
procedure TDAParam.LoadFromStream(const aStream: IROStream);
begin
Value := VariantBinaryFromRawBinary(aStream.Stream);
end;
procedure TDAParam.SaveToStream(const aStream: IROStream);
begin
VariantBinaryToRawBinary(Value, aStream.Stream);
end;
procedure TDAParam.SetParamType(Value: TDAParamType);
begin
fParamType := Value;
end;
procedure TDAParam.AssignField(Source: TDABaseField);
begin
inherited;
if Source is TDAParam then
ParamType := TDAParam(Source).ParamType;
end;
{ TDAParamCollection }
function TDAParamCollection.Add: TDAParam;
begin
result := TDAParam(inherited Add)
end;
constructor TDAParamCollection.Create(aOwner: TPersistent);
begin
inherited Create(aOwner, TDAParam);
end;
function TDAParamCollection.FindParam(
const aParamName: string): TDAParam;
begin
result := TDAParam(inherited FindItem(aParamName));
end;
function TDAParamCollection.GetParams(Index: integer): TDAParam;
begin
result := TDAParam(inherited Items[Index])
end;
function TDAParamCollection.ParamByName(const aName: string): TDAParam;
begin
result := TDAParam(inherited ItembyName(aName))
end;
procedure TDAParamCollection.ReadValues(InputParams: TParams);
var
i: integer;
par: TDAParam;
begin
for i := 0 to (Count - 1) do begin
par := Params[i];
par.Value := InputParams.ParamByName(par.Name).Value;
end;
end;
procedure TDAParamCollection.SetParams(Index: integer; const Value: TDAParam);
begin
Params[Index].Assign(Value);
end;
procedure TDAParamCollection.WriteValues(OutputParams: TParams);
var
i: integer;
par: TDAParam;
outpar: TParam;
begin
for i := 0 to (Count - 1) do begin
par := Params[i];
outpar := OutputParams.ParamByName(par.Name);
if par.DataType = datBlob then begin
outpar.DataType := ftBlob;
outpar.Value := VariantBinaryToString(par.Value);
{ ToDo: make sure this is valid for ALL Data Drivers, only tested with IBX so far. mh. }
end
else begin
outpar.Value := par.Value;
end;
//outpar.Size := par.Size; // Seems to fix an ADO problem with size of parameters with SDAC
end;
end;
procedure TDAParamCollection.Assign(Source: TPersistent);
begin
if (Source is TDAParamCollection) then begin
AssignParamCollection(TDAParamCollection(Source))
end
else
inherited;
end;
procedure TDAParamCollection.AssignParamCollection(Source: TDAParamCollection);
var
i: integer;
begin
Clear;
for i := 0 to (Source.Count - 1) do
Add.AssignField(Source[i]);
end;
function TDAParamCollection.GetHasInputParams: boolean;
var
i: Integer;
begin
result := false;
for i := 0 to Count-1 do begin
if Params[i].ParamType in [daptUnknown, daptInput, daptInputOutput] then begin
result := true;
exit;
end;
end; { for }
end;
{ TDASQLCommand }
procedure TDASQLCommand.Assign(aSource: TPersistent);
var
lSource: TDASQLCommand;
begin
if (aSource is TDASQLCommand) then begin
lSource := TDASQLCommand(aSource);
fName := lSource.fName;
fDescription := lSource.fDescription;
fStatements.Assign(lSource.fStatements);
fParams.Assign(lSource.fParams);
fCustomAttributes.Assign(lSource.CustomAttributes);
end
else begin
inherited;
end;
end;
constructor TDASQLCommand.Create(Collection: TCollection);
begin
inherited;
fIsPublic := true;
fStatements := TDAStatementCollection.Create(nil, Self);
fParams := TDAParamCollection.Create(nil);
fCustomAttributes := TStringList.Create;
end;
destructor TDASQLCommand.Destroy;
begin
fCustomAttributes.Free;
fStatements.Free;
fParams.Free;
inherited;
end;
function TDASQLCommand.GetDisplayName: string;
begin
result := Name;
end;
function TDASQLCommand.GetParams: TDAParamCollection;
begin
result := fParams;
end;
function TDASQLCommand.GetSQLCommandCollection: TDASQLCommandCollection;
begin
result := TDASQLCommandCollection(Collection);
end;
function TDASQLCommand.ParamByName(const aName: string): TDAParam;
begin
result := fParams.ParamByName(aName)
end;
procedure TDASQLCommand.SetCustomAttributes(const Value: TStrings);
begin
fCustomAttributes.Assign(Value);
end;
procedure TDASQLCommand.SetDisplayName(const Value: string);
begin
inherited;
SetName(Value);
end;
procedure TDASQLCommand.SetName(const Value: string);
var
lOldName: string;
begin
lOldName := fName;
fName := Value;
if lOldName <> '' then
(Collection as TSearcheableCollection).TriggerOnItemRenamed(lOldName, fName);
end;
procedure TDASQLCommand.SetParams(const Value: TDAParamCollection);
begin
fParams.Assign(Value);
end;
procedure TDASQLCommand.SetStatements(const Value: TDAStatementCollection);
begin
fStatements.Assign(Value);
end;
function TDASQLCommand.GetStatements(): TDAStatementCollection;
begin
result := fStatements;
end;
{ TDADataset }
procedure TDADataset.Assign(aSource: TPersistent);
var
lSource: TDADataset;
begin
if (aSource is TDADataset) then begin
inherited; { Need to work the TDASQLCommand, too}
lSource := TDADataset(aSource);
fFields.Assign(lSource.Fields);
end
else begin
inherited;
end;
end;
constructor TDADataset.Create(Collection: TCollection);
begin
inherited;
fFields := TDAFieldCollection.Create(self);
fBusinessRulesServer := TDABusinessRuleScript.Create();
fBusinessRulesClient := TDAClientBusinessRuleScript.Create();
end;
destructor TDADataset.Destroy;
begin
FreeAndNil(fFields);
FreeAndNil(fBusinessRulesServer);
FreeAndNil(fBusinessRulesClient);
inherited;
end;
function TDADataset.FieldByName(const aName: string): TDAField;
begin
result := Fields.FieldByName(aName)
end;
function TDADataset.FindField(const aName: string): TDAField;
begin
result := Fields.FindField(aName)
end;
procedure TDADataset.SetBusinessRulesClient(const Value: TDAClientBusinessRuleScript);
begin
fBusinessRulesClient.Assign(Value);
end;
procedure TDADataset.SetBusinessRulesServer(const Value: TDABusinessRuleScript);
begin
fBusinessRulesServer.Assign(Value);
end;
procedure TDADataset.SetFields(const Value: TDAFieldCollection);
begin
fFields.Assign(Value);
end;
{ TDASQLCommandCollection }
function TDASQLCommandCollection.Add: TDASQLCommand;
begin
result := TDASQLCommand(inherited Add)
end;
constructor TDASQLCommandCollection.Create(aOwner: TComponent);
begin
inherited Create(aOwner, GetItemClass);
end;
function TDASQLCommandCollection.GetItemClass: TDASQLCommandClass;
begin
result := TDASQLCommand;
end;
function TDASQLCommandCollection.GetSQLCommands(
Index: integer): TDASQLCommand;
begin
result := TDASQLCommand(inherited Items[Index]);
end;
procedure TDASQLCommandCollection.SetSQLCommands(Index: integer;
const Value: TDASQLCommand);
begin
SQLCommands[Index].Assign(Value);
end;
function TDASQLCommandCollection.SQLCommandByName(
const aName: string): TDASQLCommand;
begin
result := TDASQLCommand(inherited ItemByName(aName));
end;
{ TDADatasetCollection }
function TDADatasetCollection.Add: TDADataset;
begin
result := TDADataset(inherited Add);
end;
function TDADatasetCollection.DatasetByName(const aName: string): TDADataset;
begin
result := TDADataset(inherited ItemByName(aName));
end;
function TDADatasetCollection.FindDatasetByName(const aName: string): TDADataset;
begin
result := TDADataset(inherited FindItem(aName));
end;
function TDADatasetCollection.GetDatasets(Index: integer): TDADataset;
begin
result := TDADataset(inherited Items[Index]);
end;
function TDADatasetCollection.GetItemClass: TDASQLCommandClass;
begin
result := TDADataset;
end;
procedure TDADatasetCollection.SetDatasets(Index: integer;
const Value: TDADataset);
begin
Datasets[Index].Assign(Value);
end;
{ TDAConnectionCollection }
function TDAConnectionCollection.Add: TDAConnection;
begin
result := TDAConnection(inherited Add);
end;
procedure TDAConnectionCollection.ClearDefaults(iExceptFor: TDAConnection);
var
i: integer;
begin
for i := 0 to Count - 1 do begin
if (Connections[i] <> iExceptFor) then Connections[i].Default := false;
end;
end;
function TDAConnectionCollection.ConnectionByName(
const aName: string): TDAConnection;
begin
result := TDAConnection(inherited ItemByName(aName));
end;
constructor TDAConnectionCollection.Create(aOwner: TPersistent);
begin
inherited Create(aOwner, TDAConnection);
end;
function TDAConnectionCollection.FindConnection(const aName,
aType: string): TDAConnection;
var
i: Integer;
begin
if aName <> '' then begin
for i := 0 to Count -1 do begin
if GetConnections(i).Name = aName then begin
Result := GetConnections(i);
exit;
end;
end;
end;
if aType <> '' then begin
for i := 0 to Count -1 do begin
if GetConnections(i).ConnectionType = aType then begin
Result := GetConnections(i);
exit;
end;
end;
end;
result := nil;
end;
function TDAConnectionCollection.GetConnections(
Index: integer): TDAConnection;
begin
result := TDAConnection(inherited Items[Index]);
end;
function TDAConnectionCollection.GetDefaultConnection: TDAConnection;
begin
result := inherited GetDefaultItem as TDAConnection;
end;
function TDAConnectionCollection.ItemName: string;
begin
result := 'connection';
end;
procedure TDAConnectionCollection.SetConnections(Index: integer;
const Value: TDAConnection);
begin
Connections[Index].Assign(Value);
end;
{ TDAConnection }
procedure TDAConnection.Assign(aSource: TPersistent);
var
lSource: TDAConnection;
begin
if (aSource is TDAConnection) then begin
lSource := TDAConnection(aSource);
fDescription := lSource.fDescription;
ConnectionString := lSource.ConnectionString;
ConnectionType := lSource.ConnectionType;
fName := '_____' + lSource.fName;
fDefault := false;
end
else begin
inherited;
end;
end;
function TDAConnection.GetConnectionString: string;
begin
result := fConnectionString;
end;
function TDAConnection.GetDisplayName: string;
begin
if (Trim(Name) = '') then
result := '<Noname>'
else
result := Name;
//if Default then result := result+' - [Default]';
end;
procedure TDAConnection.SetConnectionString(const aValue: string);
begin
if fConnectionString <> aValue then
fConnectionString := aValue;
end;
procedure TDAConnection.SetDefault(const Value: boolean);
begin
if (fDefault <> Value) then begin
fDefault := Value;
if Default then begin
(Collection as TDAConnectionCollection).ClearDefaults(self);
end;
end;
end;
procedure TDAConnection.SetDisplayName(const Value: string);
begin
inherited;
SetName(Value);
end;
procedure TDAConnection.SetName(const Value: string);
var
lOldName: string;
begin
if (Value <> fName) then begin
lOldName := fName;
fName := Value;
if lOldName <> '' then
(Collection as TDAConnectionCollection).TriggerOnItemRenamed(lOldName, fName);
end;
end;
{ TDAStatement }
procedure TDAStatement.Assign(aSource: TPersistent);
var
lSource: TDAStatement;
begin
if (aSource is TDAStatement) then begin
lSource := TDAStatement(aSource);
fSQL := lSource.fSQL;
fStatementType := lSource.fStatementType;
fConnection := lSource.fConnection;
fColumnMappings.Assign(lSource.fColumnMappings);
fTargetTable := lSource.fTargetTable;
end
else begin
inherited;
end;
end;
constructor TDAStatement.Create(Collection: TCollection);
begin
inherited;
fColumnMappings := TDAColumnMappingCollection.Create(Self);
end;
destructor TDAStatement.Destroy;
begin
fColumnMappings.Free;
inherited;
end;
function TDAStatement.GetNeedsParams: boolean;
var
lParams: TParams;
lSQL: string;
begin
lParams := TParams.Create;
try
{ Bug in ParseSQL modified passed in string; use UniqueString to prevent
corrupting the original! }
lSQL := SQL;
UniqueString(lSQL);
lParams.ParseSQL(lSQL, TRUE);
result := (lParams.Count > 0);
finally
lParams.Free;
end;
end;
function TDAStatement.GetStatementCollection: TDAStatementCollection;
begin
result := TDAStatementCollection(Collection);
end;
procedure TDAStatement.SetColumnMappings(
const Value: TDAColumnMappingCollection);
begin
fColumnMappings.Assign(Value);
end;
procedure TDAStatement.SetSQL(const Value: string);
begin
fSQL := Value;
end;
function TDAStatement.StoreSQL: Boolean;
begin
Result := fStatementType <> stAutoSQL;
end;
{ TDAColumnMappingCollection }
function TDAColumnMappingCollection.Add: TDAColumnMapping;
begin
result := TDAColumnMapping(inherited Add);
end;
procedure TDAColumnMappingCollection.AssignColumnMapping(aSource: TPersistent);
var
i: Integer;
begin
Clear;
for i := 0 to TDAColumnMappingCollection(aSource).Count -1 do begin
Add.AssignFieldMapping(TDAColumnMappingCollection(aSource)[i]);
end;
end;
constructor TDAColumnMappingCollection.Create(aOwner: TPersistent);
begin
inherited Create(aOwner, TDAColumnMapping);
end;
function TDAColumnMappingCollection.FindMappingByDatasetField(
const aDatasetField: string): TDAColumnMapping;
var
i: integer;
begin
result := nil;
for i := 0 to (Count - 1) do
if SameText(ColumnMappings[i].DatasetField, aDatasetField) then begin
result := ColumnMappings[i];
Exit;
end;
end;
function TDAColumnMappingCollection.GetColumnMappings(
Index: integer): TDAColumnMapping;
begin
result := TDAColumnMapping(inherited Items[Index])
end;
function TDAColumnMappingCollection.GetItemName(
anItem: TCollectionItem): string;
begin
result := TDAColumnMapping(anItem).DatasetField;
end;
function TDAColumnMappingCollection.MappingByDatasetField(
const aDatasetField: string): TDAColumnMapping;
begin
result := TDAColumnMapping(inherited ItemByName(aDatasetField))
end;
function TDAColumnMappingCollection.MappingByTableField(
const aTableField: string): TDAColumnMapping;
var
i: integer;
begin
result := nil;
for i := 0 to (Count - 1) do
if SameText(ColumnMappings[i].TableField, aTableField) then begin
result := ColumnMappings[i];
Exit;
end;
RaiseError('Cannot find mapping for table field %s', [aTableField]);
end;
procedure TDAColumnMappingCollection.SetColumnMappings(Index: integer;
const Value: TDAColumnMapping);
begin
TDAColumnMapping(inherited Items[Index]).AssignTo(Value);
end;
function TDAColumnMappingCollection.SetItemName(anItem: TCollectionItem;
const aName: string): string;
begin
TDAColumnMapping(anItem).DatasetField := aName;
end;
{ TDAWhere }
function TDAWhere.GetProperName(aField: TDACustomField) : string;
begin
if fClientFields
then result := ClientFieldPrefix+aField.Name
else result := aField.TableField
end;
function TDAWhere.AddCondition(const FieldName: string;
Condition: TDASQLCondition; const Value: Variant; SkipIfEmptyValue: boolean = TRUE): boolean;
var
isstr, isnull, isfloat, isCurr: boolean;
fld: TDACustomField;
fieldnametouse : string;
str: string;
oldDecimalSeparator: Char;
begin
result := FALSE;
fld := fFields.FindField(FieldName);
isnull := VarIsNull(Value) or (VarIsType(Value, [varString, varOleStr]) and (Value = ''))
or (VarIsType(Value, [varDate]) and (Value = 0));
if isnull and SkipIfEmptyValue then Exit;
if fLastWasCondition then
begin
case fDefaultOperator of
doAnd: AddOperator(opAND);
doOr: AddOperator(opOR);
end;
end;
fLastWasCondition := True;
if fld <> nil then
fieldnametouse := GetProperName(fld) // Changed by AleF: WHERE clauses cannot work with field aliases like "FieldA as XYZ"
else
fieldnametouse := FieldName;
fClause := fClause + '(' + fieldnametouse + ' ' + StrSQLCondition[Condition] + ' ';
isstr := (fld <> nil) and (fld.DataType in [datWideString, datWideMemo, datString, datDateTime, datMemo]);
isfloat := (fld <> nil) and (fld.DataType in [datFloat, datSingleFloat]);
isCurr :=(fld <> nil) and (fld.DataType in [datCurrency]);
case Condition of
cIsNull, cIsNotNull:begin
fClause := TrimRight(fClause) + ')';
end;
else begin
if isstr then begin
str:=VarToStr(Value);
if Condition = cIn then
fClause := fClause + '(' + str + '))'
else
fClause := fClause + '''' + str + ''')'
end
else begin
if isfloat or isCurr then begin
oldDecimalSeparator := DecimalSeparator;
DecimalSeparator := '.';
try
if isfloat then str:= FloatToStr(Value)
else str:=CurrToStrF(Value,ffGeneral,4);
finally
DecimalSeparator := oldDecimalSeparator;
end;
end
else
str:=VarToStr(Value);
if Condition = cIn then
fClause := fClause + '(' + str + '))'
else
fClause := fClause + str + ')';
end;
end;
end;
result := TRUE;
Changed := True;
if Assigned(OnChange) then OnChange(Self);
end;
procedure TDAWhere.AddValueGroup(const FieldName: string;
const Values: array of Variant);
var
fld: TDAField;
isstr: boolean;
cnt, i: integer;
fieldnametouse : string;
begin
fld := fFields.FieldByName(FieldName);
if fLastWasCondition then
begin
case fDefaultOperator of
doAnd: AddOperator(opAND);
doOr: AddOperator(opOR);
end;
end;
fLastWasCondition := True;
fieldnametouse := GetProperName(fld); // Changed by AleF: WHERE clauses cannot work with field aliases like "FieldA as XYZ"
if (Length(Values) > 0) then begin
isstr := (fld.DataType in [datWideString, datWideMemo, datString, datDateTime, datMemo]);
fClause := fClause + '(' + fieldnametouse + ' ' + StrSQLCondition[cIn] + ' (';
cnt := High(Values);
for i := 0 to cnt do begin
if isstr then
fClause := fClause + '''' + VarToStr(Values[i]) + ''''
else
fClause := fClause + VarToStr(Values[i]) + '';
if (i < cnt) then fClause := fClause + ', ';
end;
fClause := fClause + '))';
end;
Changed := True;
if Assigned(OnChange) then OnChange(Self);
end;
constructor TDAWhere.Create(const aFields: TDAFieldCollection; aClientFields : boolean);
begin
inherited Create;
fDefaultOperator := doAnd;
fFields := aFields;
fClientFields := aClientFields;
end;
{$WARN SYMBOL_DEPRECATED OFF} // Delphi warns you about implementing a method that's deprecated in the interface.
procedure TDAWhere.OpenBraket;
begin
OpenBracket();
end;
procedure TDAWhere.CloseBraket;
begin
CloseBracket();
end;
{$WARN SYMBOL_DEPRECATED ON}
procedure TDAWhere.OpenBracket;
begin
fClause := fClause + '(';
Changed := True;
if Assigned(OnChange) then OnChange(Self);
end;
procedure TDAWhere.CloseBracket;
begin
fClause := fClause + ')';
Changed := True;
if Assigned(OnChange) then OnChange(Self);
end;
procedure TDAWhere.AddOperator(aOperator: TDASQLOperator);
begin
fClause := fClause + ' ' + StrSQLOperator[aOperator] + ' ';
Changed := True;
fLastWasCondition := False;
if Assigned(OnChange) then OnChange(Self);
end;
procedure TDAWhere.Clear;
begin
fClause := '';
fLastWasCondition := false;
Changed := True;
if Assigned(OnChange) then OnChange(Self);
end;
procedure TDAWhere.AddText(const someText: string; MapClientFields : boolean = TRUE);
var s : string;
i : integer;
begin
s := someText;
if MapClientFields then begin
for i := 0 to (Fields.Count-1) do
s := StringReplace(s, ClientFieldPrefix+Fields[i].Name, Fields[i].TableField, [rfReplaceAll, rfIgnoreCase]);
end;
fClause := fClause + s;
Changed := True;
if Assigned(OnChange) then OnChange(Self);
end;
procedure TDAWhere.AddSpaces(Count: integer = 1);
var
i: integer;
begin
for i := 1 to Count do
fClause := fClause + ' ';
Changed := True;
if Assigned(OnChange) then OnChange(Self);
end;
function TDAWhere.GetEmpty: boolean;
begin
result := Trim(fClause)=''
end;
function TDAWhere.GetNotEmpty: boolean;
begin
result := not Empty
end;
function TDAWhere.AddConditions(const FieldNames: array of string;
const Conditions: array of TDASQLCondition;
const Values: array of Variant;
const Operator: TDASQLOperator): integer;
var i : integer;
isnull : boolean;
oldclause : string;
oldonchange : TNotifyEvent;
begin
result := 0;
oldclause := fClause;
oldonchange := OnChange;
OnChange := NIL;
try
for i := 0 to Length(FieldNames)-1 do begin
isnull := VarIsNull(Values[i]) or (VarIsType(Values[i], [varString, varOleStr]) and (Values[i] = ''));
if isnull then Continue;
if NotEmpty then AddOperator(Operator);
AddCondition(FieldNames[i], Conditions[i], Values[i], TRUE);
Inc(result);
end;
finally
// This is to avoid OnChange fireing for each condition in the loop above
OnChange := oldonchange;
Changed := True;
if Assigned(OnChange) then OnChange(Self);
end;
end;
function TDAWhere.AddCondition(const FieldName: string;
Condition: TDASQLCondition): boolean;
begin
Result:=AddCondition(FieldName,Condition,0);
end;
{ TDAColumnMapping }
procedure TDAColumnMapping.Assign(aSource: TPersistent);
var
lSource: TDAColumnMapping;
begin
if (aSource is TDAColumnMapping) then begin
lSource := TDAColumnMapping(aSource);
fDatasetField := lSource.fDatasetField;
fTableField := lSource.fTableField;
end
else begin
inherited;
end;
end;
procedure TDAColumnMapping.AssignFieldMapping(aSource: TPersistent);
var
lSource: TDAColumnMapping;
begin
lSource := TDAColumnMapping(aSource);
fDatasetField := lSource.fDatasetField;
fTableField := lSource.fTableField;
fSQLOrigin := lSource.fSQLOrigin;
end;
function TDAColumnMapping.GetSQLOrigin: string;
begin
if (fSQLOrigin='')
then result := TableField
else result := fSQLOrigin
end;
procedure TDAColumnMapping.SetDatasetField(const Value: string);
begin
fDatasetField := Trim(Value);
end;
procedure TDAColumnMapping.SetSQLOrigin(const Value: string);
begin
fSQLOrigin:= Trim(Value)
end;
procedure TDAColumnMapping.SetTableField(const Value: string);
begin
fTableField := Trim(Value);
end;
function TDAColumnMapping.StoreSQLOrigin: Boolean;
begin
result := (fSQLOrigin <> fTableField) and (Trim(fSQLOrigin)<>'')
end;
{ TDAClientBusinessRuleScript }
constructor TDAClientBusinessRuleScript.Create;
begin
inherited;
fRunOnClientAndServer := true;
fCompileOnServer := true;
end;
{ TDADriverForeignKey }
function TDADriverForeignKey.GetValue(const Index: Integer): string;
begin
result := fValues[Index];
end;
procedure TDADriverForeignKey.SetValue(const Index: Integer; const Value: string);
begin
fValues[Index] := Value;
end;
{ TDADriverForeignKeyCollection }
constructor TDADriverForeignKeyCollection.Create(aOwner: TPersistent);
begin
inherited Create(aOwner, TDADriverForeignKey);
end;
function TDADriverForeignKeyCollection.Add: TDADriverForeignKey;
begin
result := TDADriverForeignKey(inherited Add());
end;
function TDADriverForeignKeyCollection.GetForeignKeys(Index: integer): TDADriverForeignKey;
begin
result := TDADriverForeignKey(inherited Items[Index]);
end;
procedure TDADriverForeignKeyCollection.SetForeignKeys(Index: integer; const Value: TDADriverForeignKey);
begin
inherited Items[Index].Assign(Value);
end;
{ TDAUpdateRuleCollection }
function TDAUpdateRuleCollection.Add: TDAUpdateRule;
begin
result := inherited Add() as TDAUpdateRule;
end;
constructor TDAUpdateRuleCollection.Create(aOwner : TComponent);
begin
inherited Create(aOwner, TDAUpdateRule);
end;
function TDAUpdateRuleCollection.GetUpdateRules(
Index: integer): TDAUpdateRule;
begin
result := TDAUpdateRule(inherited Items[Index]);
end;
function TDAUpdateRuleCollection.UpdateRuleByName(
const aName: string): TDAUpdateRule;
begin
result := ItemByName(aName) as TDAUpdateRule
end;
{ TDAUpdateRule }
procedure TDAUpdateRule.Assign(aSource: TPersistent);
var
lSource: TDAUpdateRule;
begin
lSource := aSource as TDAUpdateRule;
fDatasetName := lSource.fDatasetName;
fName := lSource.fName;
fDoUpdate := lSource.fDoUpdate;
fDoInsert := lSource.fDoInsert;
fDoDelete := lSource.fDoDelete;
fFailureBehavior := lSource.fFailureBehavior;
end;
constructor TDAUpdateRule.Create(aCollection: TCollection);
begin
inherited;
fDoUpdate := true;
fDoInsert := true;
fDoDelete := true;
fFailureBehavior := fbRaiseException;
end;
function TDAUpdateRule.GetChangeTypes: TDAChangeTypes;
begin
result := [];
if DoUpdate then Include(result,ctUpdate);
if DoInsert then Include(result,ctInsert);
if DoDelete then Include(result,ctDelete);
end;
function TDAUpdateRule.GetDisplayName: string;
begin
result := Name;
if (result='') then result := '<Unknown>';
end;
{ TDADatasetRelationshipCollection }
function TDADatasetRelationshipCollection.Add: TDADatasetRelationship;
begin
result := inherited Add() as TDADatasetRelationship;
end;
constructor TDADatasetRelationshipCollection.Create(aOwner: TComponent);
begin
inherited Create(aOwner, TDADatasetRelationship);
end;
procedure TDADatasetRelationshipCollection.GetDetails(const aMasterDatasetName: string; aList: TDADatasetRelationshipList);
var i : integer;
begin
aList.Clear;
for i := 0 to (Count-1) do begin
if SameText(aMasterDatasetName, RelationShips[i].MasterDatasetName) then begin
aList.Add(RelationShips[i]);
end;
end;
end;
function TDADatasetRelationshipCollection.GetRelationShips(
Index: integer): TDADatasetRelationship;
begin
result := TDADatasetRelationship(inherited Items[Index]);
end;
function TDADatasetRelationshipCollection.RelationShipByName(
const aName: string): TDADatasetRelationship;
begin
result := ItemByName(aName) as TDADatasetRelationship;
end;
{ TDADatasetRelationship }
procedure TDADatasetRelationship.Assign(Source: TPersistent);
var src : TDADatasetRelationship;
begin
if (Source is TDADatasetRelationship) then begin
src := TDADatasetRelationship(Source);
Name := src.Name;
MasterDatasetName := src.MasterDatasetName;
MasterFields := src.MasterFields;
DetailDatasetName := src.DetailDatasetName;
DetailFields := src.DetailFields;
end
else inherited;
end;
function TDADatasetRelationship.GetDisplayName: string;
begin
result := Format('%s: %s (%s) --> %s (%s)', [fName, fDetailDatasetName, fDetailFields, fMasterDatasetName, fMasterFields]);
end;
{ TDADatasetRelationshipList }
function TDADatasetRelationshipList.Add(
aRelationship: TDADatasetRelationship): integer;
begin
result := inherited Add(aRelationship)
end;
function TDADatasetRelationshipList.GetItems(
Index: integer): TDADatasetRelationship;
begin
result := TDADatasetRelationship(inherited Items[Index]);
end;
{ TDALoginInfoAware }
function TDALoginInfoAware._AddRef: Integer;
begin
result := -1;
end;
function TDALoginInfoAware._Release: Integer;
begin
result := -1;
end;
function TDALoginInfoAware.GetLoginInfo: TDALoginInfo;
begin
result := fLoginInfo
end;
procedure TDALoginInfoAware.SetLoginInfo(aValue: TDALoginInfo);
begin
fLoginInfo := aValue;
end;
{ TDAJoinDataTableCollection }
constructor TDAJoinDataTableCollection.Create(aOwner : TComponent);
begin
inherited Create(aOwner, TDAJoinDataTable);
end;
function TDAJoinDataTableCollection.GetJoinDataTables(Index: integer): TDAJoinDataTable;
begin
result := TDAJoinDataTable(inherited Items[Index]);
end;
procedure TDAJoinDataTableCollection.SetJoinDataTables(Index: integer; const Value: TDAJoinDataTable);
begin
JoinTables[Index].Assign(Value);
end;
{
function TDAJoinedTableCollection.GetItemClass: TDASQLCommandClass;
begin
result := TDAJoinedTable;
end;
}
function TDAJoinDataTableCollection.Add: TDAJoinDataTable;
begin
result := TDAJoinDataTable(inherited Add);
end;
function TDAJoinDataTableCollection.JoinTableByName(const aName: string): TDAJoinDataTable;
begin
result := TDAJoinDataTable(inherited ItemByName(aName));
end;
function TDAJoinDataTableCollection.FindJoinTableByName(const aName: string): TDAJoinDataTable;
begin
result := TDAJoinDataTable(inherited FindItem(aName));
end;
{ TDAJoinSourceTableCollection }
function TDAJoinSourceTableCollection.GetJoinSourceTables(Index: integer): TDAJoinSourceTable;
begin
result := TDAJoinSourceTable(inherited Items[Index])
end;
procedure TDAJoinSourceTableCollection.SetJoinSourceTables(Index: integer; const Value: TDAJoinSourceTable);
begin
TDAJoinSourceTable(inherited Items[Index]).AssignTo(Value);
end;
constructor TDAJoinSourceTableCollection.Create(aOwner: TPersistent);
begin
inherited Create(aOwner, TDAJoinSourceTable);
end;
function TDAJoinSourceTableCollection.Add: TDAJoinSourceTable;
begin
result := TDAJoinSourceTable(inherited Add);
end;
function TDAJoinSourceTableCollection.JoinSourceTableByName(const aName: string): TDAJoinSourceTable;
begin
result := TDAJoinSourceTable(inherited ItemByName(aName));
end;
{
function TDAJoinedTableItemCollection.GetItemClass: TDAJoinedTableItem;
begin
result := TDAJoinedTableItem;
end;
}
{ TDAJoinDataTable }
constructor TDAJoinDataTable.Create(Collection: TCollection);
begin
inherited;
fJoinSourceTables := TDAJoinSourceTableCollection.Create(self);
end;
destructor TDAJoinDataTable.Destroy;
begin
FreeAndNil(fJoinSourceTables);
inherited;
end;
procedure TDAJoinDataTable.Assign(aSource: TPersistent);
var
lSource: TDAJoinDataTable;
begin
if (aSource is TDAJoinDataTable) then begin
inherited; { Need to work the TDASQLCommand, too}
lSource := TDAJoinDataTable(aSource);
fJoinSourceTables.Assign(lSource.fJoinSourceTables);
fMasterTable:= lSource.fMasterTable;
end
else begin
inherited;
end;
end;
procedure TDAJoinDataTable.SetJoinSourceTables(const Value: TDAJoinSourceTableCollection);
begin
fJoinSourceTables.Assign(Value);
end;
function TDAJoinDataTable.GetParams: TDAParamCollection;
begin
result := nil;
end;
procedure TDAJoinDataTable.SetParams(const Value: TDAParamCollection);
begin
// Do Nothing
end;
function TDAJoinDataTable.GetStatements(): TDAStatementCollection;
begin
result := nil;
end;
procedure TDAJoinDataTable.SetStatements(const Value: TDAStatementCollection);
begin
// Do Nothing
end;
function TDAJoinDataTable.GetSQLCommandCollection: TDASQLCommandCollection;
begin
result := nil;
end;
{ TDAJoinSourceTable }
constructor TDAJoinSourceTable.Create(Collection: TCollection);
begin
inherited;
fJoinConditions := TDAJoinConditionCollection.Create(Self);
end;
function TDAJoinSourceTable.GetDisplayName: string;
begin
if (Trim(Name) = '') then
result := '<Noname>'
else
result := Name;
end;
procedure TDAJoinSourceTable.SetName(const Value: string);
var
lOldName: string;
begin
lOldName := fName;
fName := Value;
if lOldName <> '' then
(Collection as TSearcheableCollection).TriggerOnItemRenamed(lOldName, fName);
end;
procedure TDAJoinSourceTable.Assign(aSource: TPersistent);
var
lSource: TDAJoinSourceTable;
begin
if (aSource is TDAJoinSourceTable) then begin
lSource := TDAJoinSourceTable(aSource);
fName:= lSource.fName;
fJoinType:= lSource.fJoinType;
fJoinConditions.Assign(lSource.fJoinConditions);
end
else begin
inherited;
end;
end;
{ TDAJoinConditionCollection }
constructor TDAJoinConditionCollection.Create(aOwner: TPersistent);
begin
inherited Create(aOwner, TDAJoinCondition);
end;
function TDAJoinConditionCollection.Add: TDAJoinCondition;
begin
result := TDAJoinCondition(inherited Add);
end;
constructor TDADatasetRelationship.Create(Collection: TCollection);
begin
inherited Create(Collection);
fRelationshipType := rtForeignKey;
end;
{ TDATableFieldCollectionItem }
procedure TDATableFieldCollectionItem.Assign(Source: TPersistent);
begin
inherited;
if Source is TDATableFieldCollectionItem then begin
self.FFieldName := TDATableFieldCollectionItem(Source).FieldName;
self.FTableName := TDATableFieldCollectionItem(Source).TableName;
end;
end;
{ TDAQueryBuilder }
procedure TDAQueryBuilder.AddCrossJoin(ATable: string);
begin
with FMainTable.JoinSourceTables.Add do begin
JoinType := jtCross;
Name := ATable;
end;
end;
procedure TDAQueryBuilder.AddGroupBy(ATable, AField: string);
begin
with TDAGroupByItem(FGroupByCollection.Add) do begin
TableName := aTable;
FieldName := AField;
end;
end;
procedure TDAQueryBuilder.AddJoin(AJoinTable, AJoinFieldName,
AJoinToTableName, AJoinToFieldName: string; AJoinType: TDAJoinType);
begin
with FMainTable.JoinSourceTables.Add do begin
JoinType := AJoinType;
Name := AJoinTable;
with JoinConditions.Add do begin
FromTableName := AJoinTable;
FromFieldName := AJoinFieldName;
ToTableName := AJoinToTableName;
ToFieldName := AJoinToFieldName;
end;
end;
end;
procedure TDAQueryBuilder.AddJoin(AJoinTable: string;
AJoinFieldNames: array of string; AJoinToTableName: string;
AJoinToFieldNames: array of string; AJoinType: TDAJoinType);
var
i: integer;
begin
if High(AJoinToFieldNames) <> High(AJoinFieldNames) then raise Exception.Create('Can''t create join: AJoinFieldNames and AJoinToFieldNames should contain equal members count');
with FMainTable.JoinSourceTables.Add do begin
JoinType := AJoinType;
Name := AJoinTable;
For i:=0 to High(AJoinToFieldNames) do
with JoinConditions.Add do begin
FromTableName := AJoinTable;
FromFieldName := AJoinFieldNames[i];
ToTableName := AJoinToTableName;
ToFieldName := AJoinToFieldNames[i];
end;
end;
end;
procedure TDAQueryBuilder.AddOrderBy(ATable, AField: string);
begin
with TDAOrderByItem(FOrderByCollection.Add) do begin
TableName := aTable;
FieldName := AField;
end;
end;
procedure TDAQueryBuilder.AddSelect(ATable, AField: string);
begin
with TDASelectItem(FSelectCollection.Add) do begin
TableName := aTable;
FieldName := AField;
end;
end;
procedure TDAQueryBuilder.Assign(Source: TPersistent);
begin
inherited;
if Source is TDAQueryBuilder then begin
FMainTable.Assign(TDAQueryBuilder(Source).MainTable);
FSelectCollection.Assign(TDAQueryBuilder(Source).Select);
FGroupByCollection.Assign(TDAQueryBuilder(Source).GroupBy);
FOrderByCollection.Assign(TDAQueryBuilder(Source).OrderBy);
FOptions:=TDAQueryBuilder(Source).FOptions;
FConnection:=TDAQueryBuilder(Source).Connection;
if (TDAQueryBuilder(Source).FWhere <> nil) or (FWhere <> nil) then
Where.Xml:=TDAQueryBuilder(Source).Where.Xml;
end;
end;
procedure TDAQueryBuilder.Clear;
begin
FMainTable.MasterTable := '';
FMainTable.JoinSourceTables.Clear;
FSelectCollection.Clear;
if FWhere <> nil then FWhere.Clear;
FGroupByCollection.Clear;
FOrderByCollection.Clear;
end;
constructor TDAQueryBuilder.Create;
begin
inherited Create;
FSelectCollection := TDASelectCollection.Create(TDASelectItem);
FMainTable := TDAJoinDataTable.Create(nil);
FGroupByCollection := TDAGroupByCollection.Create(TDAGroupByItem);
FOrderByCollection := TDAOrderByCollection.Create(TDAOrderByItem);
FColumnMapping := TDAColumnMappingCollection.Create(Self);
FWhere := nil;
FOptions := [];
Clear;
end;
function TDAQueryBuilder.CreateGroupByClause: string;
var
i: integer;
begin
Result := '';
for i := 0 to GroupBy.Count - 1 do begin
if i <> 0 then Result := Result + ', ';
with TDAGroupByItem(GroupBy.Items[i]) do
Result := Result + GenerateFieldName(TableName, FieldName);
end;
end;
function TDAQueryBuilder.CreateOrderByClause: string;
var
i: integer;
begin
Result := '';
for i := 0 to OrderBy.Count - 1 do begin
if i <> 0 then Result := Result + ', ';
with TDAOrderByItem(OrderBy.Items[i]) do
Result := Result + GenerateFieldName(TableName, FieldName);
end;
end;
function TDAQueryBuilder.CreateSelectClause: string;
var
i,j: integer;
lflds: TDAFieldCollection;
lquotedtablename: string;
begin
Result := '';
if Select.Count = 0 then begin
if not (qboGenerateSimpleSelect in FOptions) and Assigned(FConnection) then begin
FConnection.GetTableFields(MainTable.MasterTable, lflds);
if Assigned(lflds) then try
if MainTable.JoinSourceTables.Count =0 then
lquotedtablename := ''
else
lquotedtablename:=QuoteIdentifierIfNeeded(MainTable.MasterTable)+'.';
For i:= 0 to lflds.Count -1 do
Result := Result + lquotedtablename+QuoteFieldNameIfNeeded(MainTable.MasterTable, lflds.Fields[i].Name)+', '
finally
lFlds.Free;
end;
For j:= 0 to MainTable.JoinSourceTables.Count - 1 do
with TDAJoinSourceTable(MainTable.JoinSourceTables.Items[j]) do begin
lquotedtablename:=QuoteIdentifierIfNeeded(Name)+'.';
FConnection.GetTableFields(name, lflds);
if Assigned(lflds) then try
For i:= 0 to lflds.Count -1 do
Result := Result + lquotedtablename+QuoteFieldNameIfNeeded(Name, lflds.Fields[i].Name)+', '
finally
lFlds.Free;
end;
end;
end;
end else begin
for i := 0 to Select.Count - 1 do begin
with TDASelectItem(Select.Items[i]) do
Result := Result + GenerateFieldName(TableName, FieldName)+', ';
end;
end;
if Length(Result) > 2 then SetLength(Result, Length(Result)-2);
if Result = '' then Result:='*';
end;
function TDAQueryBuilder.CreateWhereClause: string;
begin
if FWhere = nil then
Result := ''
else
Result := FWhere.CreateWhereClause;
end;
destructor TDAQueryBuilder.Destroy;
begin
FColumnMapping.Free;
FWhere.Free;
FOrderByCollection.Free;
FGroupByCollection.Free;
FSelectCollection.Free;
FMainTable.Free;
inherited;
end;
function TDAQueryBuilder.GenerateFieldName(aTablename,
aFieldName: string; aProcessMapping: Boolean): string;
begin
if aProcessMapping then aFieldName:= GetMappingTableField(aFieldName);
if aTableName <> '' then
Result := QuoteIdentifierIfNeeded(aTableName) + '.' + QuoteFieldNameIfNeeded(aTableName, aFieldName)
else
Result := QuoteFieldNameIfNeeded(aTableName, aFieldName);
end;
function TDAQueryBuilder.GenerateSelectSQL: string;
const
c_Indent = ' ';
c_Lenght = 47;
function CompactString(AStr: String): string;
var
p,p1: Pchar;
s: string;
begin
Result:='';
p:=Pchar(AStr);
repeat
p1:=p;
repeat
p1:=StrPos(p1, ',');
if p1 <> nil then inc(p1);
until (p1 = nil) or (p1-p > c_lenght);
if p1 = nil then begin
s:=p;
end else begin
inc(p1);
SetString(s,p, p1-p);
end;
p:=p1;
Result:=Result+sLineBreak +c_Indent+ s;
until p = nil;
end;
var
lSelect, lTable, lWhere, lGroupBy, lOrderBy: string;
begin
Validate;
lSelect := CompactString(CreateSelectClause);
lTable := CreateTableClause;
lWhere := CreateWhereClause;
lGroupBy := CreateGroupByClause;
lOrderBy := CreateOrderByClause;
Result :=
'SELECT' + lSelect + sLinebreak +
'FROM' + sLineBreak + c_Indent + lTable;
if (qboGenerateDynamicWhereStatement in Options) and (lWhere = '') then lWhere := '{WHERE}';
if lWhere <> '' then Result := Result + sLineBreak + 'WHERE' + sLineBreak + c_Indent + lWhere;
if lGroupBy <> '' then Result := Result + sLineBreak + 'GROUP BY' + sLineBreak + c_Indent + lGroupBy;
if lOrderBy <> '' then Result := Result + sLineBreak + 'ORDER BY' + sLineBreak + c_Indent + lOrderBy;
end;
function TDAQueryBuilder.GetMappingTableField(
const aDataSetField: string): string;
var
lColumnMapping: TDAColumnMapping;
begin
lColumnMapping := FColumnMapping.FindMappingByDatasetField(aDataSetField);
if Assigned(lColumnMapping) then
Result := lColumnMapping.TableField
else
Result := aDataSetField;
end;
function TDAQueryBuilder.GetWhereBuilder: TDASQLWhereBuilder;
begin
if FWhere = nil then FWhere := CreateWhereBuilder;
Result:= FWhere;
end;
function TDAQueryBuilder.IdentifierNeedsQuoting(
const iIdentifier: string): boolean;
var
i: integer;
begin
if Assigned(Connection) then
Result := Connection.IdentifierNeedsQuoting(iIdentifier)
else begin
Result := False;
for i := 1 to Length(iIdentifier) do begin
Result := not (iIdentifier[i] in ['a'..'z', 'A'..'Z', '0'..'9', '_', '.']);
if Result then Break;
end;
end;
end;
function TDAQueryBuilder.QuoteFieldNameIfNeeded(const aTableName,
aFieldName: string): string;
begin
if Assigned(Connection) then
Result := Connection.QuoteFieldNameIfNeeded(aTableName, aFieldName)
else
Result := {aTableName + '.' +} QuoteIdentifierIfNeeded(aFieldName);
end;
function TDAQueryBuilder.QuoteIdentifier(
const iIdentifier: string): string;
begin
if Assigned(Connection) then
Result := Connection.QuoteIdentifier(iIdentifier)
else
Result := '''' + iIdentifier + '''';
end;
function TDAQueryBuilder.QuoteIdentifierIfNeeded(
const iIdentifier: string): string;
begin
if Assigned(Connection) then
Result := Connection.QuoteIdentifierIfNeeded(iIdentifier)
else if IdentifierNeedsQuoting(iIdentifier) then
Result := QuoteIdentifier(iIdentifier)
else
Result := iIdentifier;
end;
procedure TDAQueryBuilder.SetColumnMapping(
const Value: TDAColumnMappingCollection);
begin
FColumnMapping.AssignColumnMapping(Value);
end;
procedure TDAQueryBuilder.Validate;
begin
if FMainTable.MasterTable = '' then raise Exception.Create('Please specify MainTable.MasterTable');
end;
{ TDAWhereBuilder }
const
c_DAWhereBuilderLocalName = 'query';
c_DAWhereBuilderNamespaceURI = 'http://www.remobjects.com/schemas/dataabstract/queries/5.0';
c_DAWhereBuilderwhere = 'where';
procedure TDAWhereBuilder.Clear;
begin
FreeAndNil(FExpression);
FColumnMapping.Clear;
fParams.Clear;
end;
constructor TDAWhereBuilder.Create;
begin
inherited Create;
FColumnMapping := TDAColumnMappingCollection.Create(nil);
fParams := TDAParamCollection.Create(nil);
end;
destructor TDAWhereBuilder.Destroy;
begin
Clear;
fParams.Free;
FColumnMapping.Free;
inherited Destroy;
end;
function TDAWhereBuilder.ExpressionToXmlNode(
const aExpression: TDAWhereExpression): IXMLNode;
var
doc: IXMLDocument;
el: IXMLNode;
begin
doc := NewROXmlDocument;
doc.New(c_DAWhereBuilderLocalName);
el := doc.DocumentNode;
el.AddAttribute('xmlns', c_DAWhereBuilderNamespaceURI);
el.AddAttribute('version', '5.0');
WriteToXml(el,aExpression);
result := doc.DocumentNode;
end;
function TDAWhereBuilder.getXml: WideString;
begin
Result:= ExpressionToXmlNode(fExpression).Document.XML;
end;
function TDAWhereBuilder.IsEmpty: Boolean;
begin
Result:= fExpression = nil;
end;
function TDAWhereBuilder.NewBinaryExpression(aLeft,
aRight: TDAWhereExpression; anOp: TDABinaryOperator): TDAWhereExpression;
begin
Result := TDABinaryExpression.Create(Self, aLeft, aRight, anOp);
end;
function TDAWhereBuilder.NewConstant(const aValue: Variant;
aType: TDADataType): TDAWhereExpression;
begin
Result := TDAConstantExpression.Create(Self, aValue, aType);
end;
function TDAWhereBuilder.NewField(
const aTableName,aFieldName: string): TDAWhereExpression;
begin
Result := TDAFieldExpression.Create(Self, aTableName,aFieldName);
end;
function TDAWhereBuilder.NewList(
const aValues: array of TDAWhereExpression): TDAWhereExpression;
begin
result := TDAListExpression.Create(Self, aValues);
end;
function TDAWhereBuilder.NewMacro(const aName: string;
const aValues: array of TDAWhereExpression): TDAWhereExpression;
begin
Result := TDAMacroExpression.Create(Self, aName, aValues);
end;
function TDAWhereBuilder.NewMacro(const aName: string): TDAWhereExpression;
begin
Result := TDAMacroExpression.Create(Self, aName);
end;
function TDAWhereBuilder.NewNull: TDAWhereExpression;
begin
Result := TDANullExpression.Create(Self);
end;
function TDAWhereBuilder.NewParameter(
const aParameterName: string): TDAWhereExpression;
begin
Result := TDAParameterExpression.Create(Self, aParameterName);
end;
function TDAWhereBuilder.NewUnaryExpression(
anExpression: TDAWhereExpression;
anOp: TDAUnaryOperator): TDAWhereExpression;
begin
Result := TDAUnaryExpression.Create(Self, anExpression, anOp);
end;
function TDAWhereBuilder.ReadFromXml(xr: IXmlNode): TDAWhereExpression;
begin
xr := SelectNodeLocal(xr, c_DAWhereBuilderwhere);
if (xr = nil) then raise Exception.Create('"'+c_DAWhereBuilderwhere+'" tag expected');
if xr.ChildrenCount > 0 then
Result := TDAWhereExpression.ParseExpression(self, xr.FirstChild)
else
Result := nil;
end;
procedure TDAWhereBuilder.SetColumnMapping(
const Value: TDAColumnMappingCollection);
begin
FColumnMapping.Assign(Value);
end;
procedure TDAWhereBuilder.SetParams(const Value: TDAParamCollection);
begin
fParams.Assign(Value);
end;
procedure TDAWhereBuilder.setXml(const aValue: WideString);
begin
Clear;
fExpression:=XMLToExpression(aValue);
end;
procedure TDAWhereBuilder.WriteToXml(sw: IXmlNode; const aExpression: TDAWhereExpression);
begin
sw := sw.Add(c_DAWhereBuilderwhere);
if aExpression <> nil then
aExpression.WriteToXml(sw);
end;
function TDAWhereBuilder.XMLToExpression(
const aXML: widestring): TDAWhereExpression;
var
doc: IXMLDocument;
el: IXMLNode;
begin
doc := NewROXmlDocument;
doc.New();
doc.XML := aXML;
el := doc.DocumentNode;
if (el.LocalName <> c_DAWhereBuilderLocalName) or (el.NamespaceURI <> c_DAWhereBuilderNamespaceURI) then raise Exception.Create('Not a DataAbstract query xml');
Result:= ReadFromXml(el);
end;
{ TDAWhereExpression }
constructor TDAWhereExpression.Create(anOwner: TDAWhereBuilder);
begin
inherited Create;
fOwner := anOwner;
end;
class function TDAWhereExpression.ParseExpression(aOwner: TDAWhereBuilder;
xr: IXmlNode): TDAWhereExpression;
begin
Result := CreateWhereExpression(aOwner, xr.LocalName);
Result.ReadFromXml(xr);
end;
{ TDAUnionDataTable }
constructor TDAUnionDataTable.Create(Collection: TCollection);
begin
inherited;
fSourceTables := TDAUnionSourceTableCollection.Create(Self);
end;
destructor TDAUnionDataTable.Destroy;
begin
FreeAndNil(fSourceTables);
inherited;
end;
procedure TDAUnionDataTable.SetSourceTables(Value: TDAUnionSourceTableCollection);
begin
fSourceTables.Assign(Value);
end;
{ TDAUnionSourceTableCollection }
function TDAUnionSourceTableCollection.Add: TDAUnionSourceTable;
begin
result := inherited Add() as TDAUnionSourceTable;
end;
constructor TDAUnionSourceTableCollection.Create(aOwner : TPersistent);
begin
inherited Create(aOwner, TDAUnionSourceTable);
end;
function TDAUnionSourceTableCollection.GetUnionSourceTables(
Index: integer): TDAUnionSourceTable;
begin
result := TDAUnionSourceTable(inherited Items[Index]);
end;
function TDAUnionSourceTableCollection.UnionSourceTableByName(
const aName: string): TDAUnionSourceTable;
begin
result := ItemByName(aName) as TDAUnionSourceTable
end;
{ TDAUnionSourceTable }
procedure TDAUnionSourceTable.Assign(Source: TPersistent);
begin
if Source is TDAUnionSourceTable then begin
Name := TDAUnionSourceTable(Source).Name;
IsReadonly := TDAUnionSourceTable(Source).IsReadOnly;
ColumnMappings.Assign(TDAUnionSourceTable(Source).ColumnMappings);
end;
end;
constructor TDAUnionSourceTable.Create(Collection: TCollection);
begin
inherited;
fColumnMappings := TDAColumnMappingCollection.Create(Self);
end;
destructor TDAUnionSourceTable.Destroy;
begin
FreeAndNil(fColumnMappings);
inherited;
end;
procedure TDAUnionSourceTable.SetColumnMappings(const Value: TDAColumnMappingCollection);
begin
fColumnMappings.Assign(Value);
end;
{ TDAUnionDataTableCollection }
constructor TDAUnionDataTableCollection.Create(aOwner : TComponent);
begin
inherited Create(aOwner, TDAUnionDataTable);
end;
function TDAUnionDataTableCollection.GetUnionDataTables(Index: integer): TDAUnionDataTable;
begin
result := TDAUnionDataTable(inherited Items[Index]);
end;
procedure TDAUnionDataTableCollection.SetUnionDataTables(Index: integer; const Value: TDAUnionDataTable);
begin
UnionDataTables[Index].Assign(Value);
end;
function TDAUnionDataTableCollection.Add: TDAUnionDataTable;
begin
result := TDAUnionDataTable(inherited Add);
end;
function TDAUnionDataTableCollection.UnionDataTableByName(const aName: string): TDAUnionDataTable;
begin
result := TDAUnionDataTable(inherited ItemByName(aName));
end;
function TDAUnionDataTableCollection.FindUnionDataTableByName(const aName: string): TDAUnionDataTable;
begin
result := TDAUnionDataTable(inherited FindItem(aName));
end;
{ TDASQLWhereBuilder }
constructor TDASQLWhereBuilder.Create(AConnection: IDAConnection);
begin
inherited Create;
FConnection:= AConnection;
end;
constructor TDASQLWhereBuilder.Create(AQueryBuilder: TDAQueryBuilder);
begin
inherited Create;
FQueryBuilder:= AQueryBuilder;
end;
function TDASQLWhereBuilder.CreateWhereClause: string;
begin
FId:=0;
Params.Clear;
Result:= ProcessExpression(Expression);
end;
function TDASQLWhereBuilder.GenerateFieldName(aTablename,
aFieldName: string): string;
begin
aFieldName:= GetMappingTableField(aFieldName);
if FQueryBuilder <> nil then
Result := FQueryBuilder.GenerateFieldName(aTablename,aFieldName,False)
else
if FConnection <> nil then begin
if aTableName <> '' then
Result := FConnection.QuoteIdentifierIfNeeded(aTableName) + '.' + FConnection.QuoteFieldNameIfNeeded(aTableName, aFieldName)
else
Result := FConnection.QuoteFieldNameIfNeeded(aTableName, aFieldName);
end;
end;
function TDASQLWhereBuilder.GenerateParameter(
const aParameterName: string): string;
begin
Result:= ':'+aParameterName;
end;
function TDASQLWhereBuilder.GenerateParamName: String;
begin
fId := fId + 1;
result := Format('P%d', [fId]);
end;
function TDASQLWhereBuilder.GetMappingTableField(
const aDataSetField: string): string;
var
lColumnMapping: TDAColumnMapping;
begin
lColumnMapping := FColumnMapping.FindMappingByDatasetField(aDataSetField);
if Assigned(lColumnMapping) then
Result := lColumnMapping.TableField
else
Result := aDataSetField;
end;
function TDASQLWhereBuilder.ProcessConstantExpression(
AExpression: TDAWhereExpression): string;
const
const_prefix = 'DACONST_';
begin
With Params.Add do begin
ParamType := daptInput;
Value := TDAConstantExpression(AExpression).Value;
DataType := TDAConstantExpression(AExpression).aType;
Name := GenerateParamName();
Result:= GenerateParameter(Name);
end;
end;
function TDASQLWhereBuilder.ProcessExpression(
AExpression: TDAWhereExpression): string;
begin
Result := '';
if AExpression = nil then Exit;
if AExpression is TDABinaryExpression then Result := ProcessBinaryExpression(TDABinaryExpression(AExpression))
else if AExpression is TDAUnaryExpression then Result := ProcessUnaryExpression(TDAUnaryExpression(AExpression))
else if AExpression is TDAConstantExpression then Result := ProcessConstantExpression(TDAConstantExpression(AExpression))
else if AExpression is TDAListExpression then Result := ProcessListExpression(TDAListExpression(AExpression))
else if AExpression is TDAParameterExpression then Result := ProcessParameterExpression(TDAParameterExpression(AExpression))
else if AExpression is TDAFieldExpression then Result := ProcessFieldExpression(TDAFieldExpression(AExpression))
else if AExpression is TDANullExpression then Result := ProcessNullExpression(TDANullExpression(AExpression))
else if AExpression is TDAMacroExpression then Result := ProcessMacroExpression(TDAMacroExpression(AExpression))
else ;
end;
function TDASQLWhereBuilder.ProcessFieldExpression(
AExpression: TDAWhereExpression): string;
begin
with TDAFieldExpression(AExpression) do
Result:= GenerateFieldName(TableName, FieldName);
end;
function TDASQLWhereBuilder.ProcessListExpression(
AExpression: TDAWhereExpression): string;
var
i: integer;
begin
Result := '';
with TDAListExpression(AExpression) do
for i := 0 to Count - 1 do begin
if i > 0 then Result := Result + ', ';
Result := Result + ProcessExpression(Item[i]);
end;
end;
function TDASQLWhereBuilder.ProcessMacroExpression(
AExpression: TDAWhereExpression): string;
var
s1: string;
i: integer;
begin
with TDAMacroExpression(AExpression) do begin
Result := '{' + Name;
s1 := '}';
if Count > 0 then begin
Result := Result + '(';
for i := 0 to Count - 1 do begin
if i > 0 then Result := Result + ', ';
Result := Result + ProcessExpression(Item[i]);
end;
Result := Result + ')';
end;
end;
Result := Result + s1;
end;
function TDASQLWhereBuilder.ProcessParameterExpression(
AExpression: TDAWhereExpression): string;
begin
with TDAParameterExpression(AExpression) do
Result := GenerateParameter(ParameterName);
end;
{$IFDEF DataAbstract_Trial}
{$INCLUDE DataAbstract_Trial.inc}
{$ENDIF DataAbstract_Trial}
end.