1382 lines
43 KiB
ObjectPascal
1382 lines
43 KiB
ObjectPascal
unit Myc.Data.Types;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.Generics.Collections,
|
|
System.SysUtils,
|
|
System.RTTI;
|
|
|
|
type
|
|
TDataKind = (dkOrdinal, dkFloat, dkText, dkTimestamp, dkRecord, dkTuple, dkArray, dkEnum, dkMethod);
|
|
|
|
IDataType = interface
|
|
function GetName: String;
|
|
function GetKind: TDataKind;
|
|
property Name: String read GetName;
|
|
property Kind: TDataKind read GetKind;
|
|
end;
|
|
|
|
IDataValue = interface
|
|
function GetDataType: IDataType;
|
|
function GetAsString: string;
|
|
function AsTValue: TValue;
|
|
property DataType: IDataType read GetDataType;
|
|
property AsString: string read GetAsString;
|
|
end;
|
|
|
|
IDataOrdinalValue = interface(IDataValue)
|
|
function GetValue: Int64;
|
|
property Value: Int64 read GetValue;
|
|
end;
|
|
|
|
// Helper for IDataOrdinalValue
|
|
TDataOrdinalValue = record
|
|
private
|
|
FOrdinalValue: IDataOrdinalValue;
|
|
function GetValue: Int64; inline;
|
|
public
|
|
constructor Create(const AOrdinalValue: IDataOrdinalValue);
|
|
class operator Implicit(const A: IDataOrdinalValue): TDataOrdinalValue; overload;
|
|
class operator Implicit(const A: TDataOrdinalValue): IDataOrdinalValue; overload;
|
|
property Value: Int64 read GetValue;
|
|
end;
|
|
|
|
IDataOrdinalType = interface(IDataType)
|
|
function CreateValue(Init: Int64): IDataOrdinalValue;
|
|
end;
|
|
|
|
// Helper for IDataOrdinalType
|
|
TDataOrdinalType = record
|
|
private
|
|
FOrdinalType: IDataOrdinalType;
|
|
public
|
|
constructor Create(const AOrdinalType: IDataOrdinalType);
|
|
class operator Implicit(const A: IDataOrdinalType): TDataOrdinalType; overload;
|
|
class operator Implicit(const A: TDataOrdinalType): IDataOrdinalType; overload;
|
|
function CreateValue(Init: Int64): TDataOrdinalValue; inline;
|
|
end;
|
|
|
|
IDataFloatValue = interface(IDataValue)
|
|
function GetValue: Double;
|
|
property Value: Double read GetValue;
|
|
end;
|
|
|
|
// Helper for IDataFloatValue
|
|
TDataFloatValue = record
|
|
private
|
|
FFloatValue: IDataFloatValue;
|
|
function GetValue: Double; inline;
|
|
public
|
|
constructor Create(const AFloatValue: IDataFloatValue);
|
|
class operator Implicit(const A: IDataFloatValue): TDataFloatValue; overload;
|
|
class operator Implicit(const A: TDataFloatValue): IDataFloatValue; overload;
|
|
property Value: Double read GetValue;
|
|
end;
|
|
|
|
IDataFloatType = interface(IDataType)
|
|
function CreateValue(Init: Double): IDataFloatValue;
|
|
end;
|
|
|
|
// Helper for IDataFloatType
|
|
TDataFloatType = record
|
|
private
|
|
FFloatType: IDataFloatType;
|
|
public
|
|
constructor Create(const AFloatType: IDataFloatType);
|
|
class operator Implicit(const A: IDataFloatType): TDataFloatType; overload;
|
|
class operator Implicit(const A: TDataFloatType): IDataFloatType; overload;
|
|
function CreateValue(Init: Double): TDataFloatValue; inline;
|
|
end;
|
|
|
|
IDataTextValue = interface(IDataValue)
|
|
function GetValue: string;
|
|
property Value: string read GetValue;
|
|
end;
|
|
|
|
// Helper for IDataTextValue
|
|
TDataTextValue = record
|
|
private
|
|
FTextValue: IDataTextValue;
|
|
function GetValue: string; inline;
|
|
public
|
|
constructor Create(const ATextValue: IDataTextValue);
|
|
class operator Implicit(const A: IDataTextValue): TDataTextValue; overload;
|
|
class operator Implicit(const A: TDataTextValue): IDataTextValue; overload;
|
|
property Value: string read GetValue;
|
|
end;
|
|
|
|
IDataTextType = interface(IDataType)
|
|
function CreateValue(const AValue: string): IDataTextValue;
|
|
end;
|
|
|
|
// Helper for IDataTextType
|
|
TDataTextType = record
|
|
private
|
|
FTextType: IDataTextType;
|
|
public
|
|
constructor Create(const ATextType: IDataTextType);
|
|
class operator Implicit(const A: IDataTextType): TDataTextType; overload;
|
|
class operator Implicit(const A: TDataTextType): IDataTextType; overload;
|
|
function CreateValue(const AValue: string): TDataTextValue; inline;
|
|
end;
|
|
|
|
IDataTimestampValue = interface(IDataValue)
|
|
function GetValue: TDateTime;
|
|
property Value: TDateTime read GetValue;
|
|
end;
|
|
|
|
// Helper for IDataTimestampValue
|
|
TDataTimestampValue = record
|
|
private
|
|
FTimestampValue: IDataTimestampValue;
|
|
function GetValue: TDateTime; inline;
|
|
public
|
|
constructor Create(const ATimestampValue: IDataTimestampValue);
|
|
class operator Implicit(const A: IDataTimestampValue): TDataTimestampValue; overload;
|
|
class operator Implicit(const A: TDataTimestampValue): IDataTimestampValue; overload;
|
|
property Value: TDateTime read GetValue;
|
|
end;
|
|
|
|
IDataTimestampType = interface(IDataType)
|
|
function CreateValue(const AValue: TDateTime): IDataTimestampValue;
|
|
end;
|
|
|
|
// Helper for IDataTimestampType
|
|
TDataTimestampType = record
|
|
private
|
|
FTimestampType: IDataTimestampType;
|
|
public
|
|
constructor Create(const ATimestampType: IDataTimestampType);
|
|
class operator Implicit(const A: IDataTimestampType): TDataTimestampType; overload;
|
|
class operator Implicit(const A: TDataTimestampType): IDataTimestampType; overload;
|
|
function CreateValue(const AValue: TDateTime): TDataTimestampValue; inline;
|
|
end;
|
|
|
|
IDataEnumValue = interface(IDataValue)
|
|
function GetValue: Integer;
|
|
property Value: Integer read GetValue;
|
|
end;
|
|
|
|
// Helper for IDataEnumValue
|
|
TDataEnumValue = record
|
|
private
|
|
FEnumValue: IDataEnumValue;
|
|
function GetValue: Integer; inline;
|
|
public
|
|
constructor Create(const AEnumValue: IDataEnumValue);
|
|
class operator Implicit(const A: IDataEnumValue): TDataEnumValue; overload;
|
|
class operator Implicit(const A: TDataEnumValue): IDataEnumValue; overload;
|
|
property Value: Integer read GetValue;
|
|
end;
|
|
|
|
IDataEnumType = interface(IDataType)
|
|
function GetIdentifier(Idx: Integer): string;
|
|
function GetIdentifierCount: Integer;
|
|
function IndexOf(const AIdentifier: string): Integer;
|
|
function CreateValue(const AValue: Integer): IDataEnumValue; overload;
|
|
function CreateValue(const AIdentifier: string): IDataEnumValue; overload;
|
|
property IdentifierCount: Integer read GetIdentifierCount;
|
|
property Identifiers[Idx: Integer]: string read GetIdentifier; default;
|
|
end;
|
|
|
|
// Helper for IDataEnumType
|
|
TDataEnumType = record
|
|
private
|
|
FEnumType: IDataEnumType;
|
|
function GetIdentifier(Idx: Integer): string; inline;
|
|
function GetIdentifierCount: Integer; inline;
|
|
public
|
|
constructor Create(const AEnumType: IDataEnumType);
|
|
class operator Implicit(const A: IDataEnumType): TDataEnumType; overload;
|
|
class operator Implicit(const A: TDataEnumType): IDataEnumType; overload;
|
|
function IndexOf(const AIdentifier: string): Integer; inline;
|
|
function CreateValue(const AValue: Integer): TDataEnumValue; overload; inline;
|
|
function CreateValue(const AIdentifier: string): TDataEnumValue; overload; inline;
|
|
property IdentifierCount: Integer read GetIdentifierCount;
|
|
property Identifiers[Idx: Integer]: string read GetIdentifier; default;
|
|
end;
|
|
|
|
// A method that transforms one data value into another.
|
|
TDataMethodProc = reference to function(const AValue: IDataValue): IDataValue;
|
|
|
|
// Represents an executable method data value.
|
|
IDataMethodValue = interface(IDataValue)
|
|
{$region 'private'}
|
|
function GetValue: TDataMethodProc;
|
|
{$endregion}
|
|
property Value: TDataMethodProc read GetValue;
|
|
end;
|
|
|
|
// Helper for IDataMethodValue
|
|
TDataMethodValue = record
|
|
private
|
|
FMethodValue: IDataMethodValue;
|
|
function GetValue: TDataMethodProc; inline;
|
|
public
|
|
constructor Create(const AMethodValue: IDataMethodValue);
|
|
class operator Implicit(const A: IDataMethodValue): TDataMethodValue; overload;
|
|
class operator Implicit(const A: TDataMethodValue): IDataMethodValue; overload;
|
|
property Value: TDataMethodProc read GetValue;
|
|
end;
|
|
|
|
// Represents the type of a method data value, including its signature.
|
|
IDataMethodType = interface(IDataType)
|
|
{$region 'private'}
|
|
function GetArgType: IDataType;
|
|
function GetResultType: IDataType;
|
|
{$endregion}
|
|
property ArgType: IDataType read GetArgType;
|
|
property ResultType: IDataType read GetResultType;
|
|
function CreateValue(const AValue: TDataMethodProc): IDataMethodValue;
|
|
end;
|
|
|
|
// Helper for IDataMethodType
|
|
TDataMethodType = record
|
|
private
|
|
FMethodType: IDataMethodType;
|
|
function GetArgType: IDataType; inline;
|
|
function GetResultType: IDataType; inline;
|
|
public
|
|
constructor Create(const AMethodType: IDataMethodType);
|
|
class operator Implicit(const A: IDataMethodType): TDataMethodType; overload;
|
|
class operator Implicit(const A: TDataMethodType): IDataMethodType; overload;
|
|
property ArgType: IDataType read GetArgType;
|
|
property ResultType: IDataType read GetResultType;
|
|
function CreateValue(const AValue: TDataMethodProc): TDataMethodValue; inline;
|
|
end;
|
|
|
|
IDataRecordValue = interface(IDataValue)
|
|
function GetItem(Idx: Integer): IDataValue;
|
|
property Items[Idx: Integer]: IDataValue read GetItem; default;
|
|
end;
|
|
|
|
// Helper for IDataRecordValue
|
|
TDataRecordValue = record
|
|
private
|
|
FRecordValue: IDataRecordValue;
|
|
function GetItem(Idx: Integer): IDataValue; inline;
|
|
public
|
|
constructor Create(const ARecordValue: IDataRecordValue);
|
|
class operator Implicit(const A: IDataRecordValue): TDataRecordValue; overload;
|
|
class operator Implicit(const A: TDataRecordValue): IDataRecordValue; overload;
|
|
property Items[Idx: Integer]: IDataValue read GetItem; default;
|
|
end;
|
|
|
|
TRecordField = record
|
|
Name: string;
|
|
DataType: IDataType;
|
|
constructor Create(const AName: string; const ADataType: IDataType);
|
|
end;
|
|
|
|
IDataRecordType = interface(IDataType)
|
|
function GetFieldCount: Integer;
|
|
function GetField(Idx: Integer): TRecordField;
|
|
function IndexOf(const AName: string): Integer;
|
|
function CreateValue(const AItems: array of IDataValue): IDataRecordValue;
|
|
property FieldCount: Integer read GetFieldCount;
|
|
property Fields[Idx: Integer]: TRecordField read GetField; default;
|
|
end;
|
|
|
|
// Helper for IDataRecordType
|
|
TDataRecordType = record
|
|
private
|
|
FRecordType: IDataRecordType;
|
|
function GetFieldCount: Integer; inline;
|
|
function GetField(Idx: Integer): TRecordField; inline;
|
|
public
|
|
constructor Create(const ARecordType: IDataRecordType);
|
|
class operator Implicit(const A: IDataRecordType): TDataRecordType; overload;
|
|
class operator Implicit(const A: TDataRecordType): IDataRecordType; overload;
|
|
function IndexOf(const AName: string): Integer; inline;
|
|
function CreateValue(const AItems: array of IDataValue): TDataRecordValue;
|
|
property FieldCount: Integer read GetFieldCount;
|
|
property Fields[Idx: Integer]: TRecordField read GetField; default;
|
|
end;
|
|
|
|
IDataTupleValue = interface(IDataValue)
|
|
function GetItemCount: Integer;
|
|
function GetItem(Idx: Integer): IDataValue;
|
|
property ItemCount: Integer read GetItemCount;
|
|
property Items[Idx: Integer]: IDataValue read GetItem; default;
|
|
end;
|
|
|
|
// Helper for IDataTupleValue
|
|
TDataTupleValue = record
|
|
private
|
|
FTupleValue: IDataTupleValue;
|
|
function GetItemCount: Integer; inline;
|
|
function GetItem(Idx: Integer): IDataValue; inline;
|
|
public
|
|
constructor Create(const ATupleValue: IDataTupleValue);
|
|
class operator Implicit(const A: IDataTupleValue): TDataTupleValue; overload;
|
|
class operator Implicit(const A: TDataTupleValue): IDataTupleValue; overload;
|
|
property ItemCount: Integer read GetItemCount;
|
|
property Items[Idx: Integer]: IDataValue read GetItem; default;
|
|
end;
|
|
|
|
IDataTupleType = interface(IDataType)
|
|
function CreateValue(const AItems: array of IDataValue): IDataTupleValue;
|
|
end;
|
|
|
|
// Helper for IDataTupleType
|
|
TDataTupleType = record
|
|
private
|
|
FTupleType: IDataTupleType;
|
|
public
|
|
constructor Create(const ATupleType: IDataTupleType);
|
|
class operator Implicit(const A: IDataTupleType): TDataTupleType; overload;
|
|
class operator Implicit(const A: TDataTupleType): IDataTupleType; overload;
|
|
function CreateValue(const AItems: array of IDataValue): TDataTupleValue;
|
|
end;
|
|
|
|
IDataArrayValue = interface(IDataValue)
|
|
function GetElementCount: Integer;
|
|
function GetItem(Idx: Integer): IDataValue;
|
|
property ElementCount: Integer read GetElementCount;
|
|
property Items[Idx: Integer]: IDataValue read GetItem; default;
|
|
end;
|
|
|
|
// Helper for IDataArrayValue
|
|
TDataArrayValue = record
|
|
private
|
|
FArrayValue: IDataArrayValue;
|
|
function GetElementCount: Integer; inline;
|
|
function GetItem(Idx: Integer): IDataValue; inline;
|
|
public
|
|
constructor Create(const AArrayValue: IDataArrayValue);
|
|
class operator Implicit(const A: IDataArrayValue): TDataArrayValue; overload;
|
|
class operator Implicit(const A: TDataArrayValue): IDataArrayValue; overload;
|
|
property ElementCount: Integer read GetElementCount;
|
|
property Items[Idx: Integer]: IDataValue read GetItem; default;
|
|
end;
|
|
|
|
IDataArrayType = interface(IDataType)
|
|
function GetElementType: IDataType;
|
|
function CreateValue(const AItems: array of IDataValue): IDataArrayValue;
|
|
property ElementType: IDataType read GetElementType;
|
|
end;
|
|
|
|
// Helper for IDataArrayType
|
|
TDataArrayType = record
|
|
private
|
|
FArrayType: IDataArrayType;
|
|
function GetElementType: IDataType; inline;
|
|
public
|
|
constructor Create(const AArrayType: IDataArrayType);
|
|
class operator Implicit(const A: IDataArrayType): TDataArrayType; overload;
|
|
class operator Implicit(const A: TDataArrayType): IDataArrayType; overload;
|
|
function CreateValue(const AItems: array of IDataValue): TDataArrayValue;
|
|
property ElementType: IDataType read GetElementType;
|
|
end;
|
|
|
|
TDataType = record
|
|
strict private
|
|
FDataType: IDataType;
|
|
function GetName: String; inline;
|
|
function GetKind: TDataKind; inline;
|
|
class var
|
|
FArrayTypeRegistry: TDictionary<IDataType, IDataArrayType>;
|
|
FRecordTypeRegistry: TDictionary<TArray<TRecordField>, IDataRecordType>;
|
|
FMethodTypeRegistry: TDictionary<TPair<IDataType, IDataType>, IDataMethodType>;
|
|
class constructor CreateClass;
|
|
class destructor DestroyClass;
|
|
public
|
|
constructor Create(const ADataType: IDataType);
|
|
|
|
class operator Implicit(const A: IDataType): TDataType; overload;
|
|
class operator Implicit(const A: TDataType): IDataType; overload;
|
|
class operator Implicit(const A: TDataOrdinalType): TDataType; overload;
|
|
class operator Implicit(const A: TDataFloatType): TDataType; overload;
|
|
class operator Implicit(const A: TDataTextType): TDataType; overload;
|
|
class operator Implicit(const A: TDataTimestampType): TDataType; overload;
|
|
class operator Implicit(const A: TDataEnumType): TDataType; overload;
|
|
class operator Implicit(const A: TDataMethodType): TDataType; overload;
|
|
class operator Implicit(const A: TDataRecordType): TDataType; overload;
|
|
class operator Implicit(const A: TDataTupleType): TDataType; overload;
|
|
class operator Implicit(const A: TDataArrayType): TDataType; overload;
|
|
|
|
// Type factories
|
|
class function Ordinal: TDataOrdinalType; static;
|
|
class function Float: TDataFloatType; static;
|
|
class function Text: TDataTextType; static;
|
|
class function Timestamp: TDataTimestampType; static;
|
|
class function Tuple: TDataTupleType; static;
|
|
class function MethodOf(const AArgType, AResultType: IDataType): TDataMethodType; static;
|
|
class function ArrayOf(const AElementType: IDataType): TDataArrayType; static;
|
|
class function RecordOf(const Fields: TArray<TRecordField>): TDataRecordType; overload; static;
|
|
class function RecordOf(const Fields: array of TRecordField): TDataRecordType; overload; static;
|
|
class function EnumOf(const AName: string; const AIdentifiers: array of string): TDataEnumType; static;
|
|
|
|
// Casting
|
|
function AsOrdinal: TDataOrdinalType;
|
|
function AsFloat: TDataFloatType;
|
|
function AsText: TDataTextType;
|
|
function AsTimestamp: TDataTimestampType;
|
|
function AsRecord: TDataRecordType;
|
|
function AsTuple: TDataTupleType;
|
|
function AsArray: TDataArrayType;
|
|
function AsEnum: TDataEnumType;
|
|
function AsMethod: TDataMethodType;
|
|
|
|
property DataType: IDataType read FDataType;
|
|
property Name: String read GetName;
|
|
property Kind: TDataKind read GetKind;
|
|
end;
|
|
|
|
TDataValue = record
|
|
private
|
|
FDataValue: IDataValue;
|
|
function GetDataType: IDataType; inline;
|
|
public
|
|
constructor Create(const ADataValue: IDataValue);
|
|
|
|
// Casting
|
|
function AsOrdinal: TDataOrdinalValue;
|
|
function AsFloat: TDataFloatValue;
|
|
function AsText: TDataTextValue;
|
|
function AsTimestamp: TDataTimestampValue;
|
|
function AsRecord: TDataRecordValue;
|
|
function AsTuple: TDataTupleValue;
|
|
function AsArray: TDataArrayValue;
|
|
function AsEnum: TDataEnumValue;
|
|
function AsMethod: TDataMethodValue;
|
|
|
|
class operator Implicit(const A: IDataValue): TDataValue; overload;
|
|
class operator Implicit(const A: TDataValue): IDataValue; overload;
|
|
class operator Implicit(const A: TDataOrdinalValue): TDataValue; overload;
|
|
class operator Implicit(const A: TDataFloatValue): TDataValue; overload;
|
|
class operator Implicit(const A: TDataTextValue): TDataValue; overload;
|
|
class operator Implicit(const A: TDataTimestampValue): TDataValue; overload;
|
|
class operator Implicit(const A: TDataEnumValue): TDataValue; overload;
|
|
class operator Implicit(const A: TDataMethodValue): TDataValue; overload;
|
|
class operator Implicit(const A: TDataRecordValue): TDataValue; overload;
|
|
class operator Implicit(const A: TDataTupleValue): TDataValue; overload;
|
|
class operator Implicit(const A: TDataArrayValue): TDataValue; overload;
|
|
|
|
// Value factories
|
|
class function FromOrdinal(const AValue: Int64): TDataOrdinalValue; static;
|
|
class function FromFloat(const AValue: Double): TDataFloatValue; static;
|
|
class function FromText(const AValue: string): TDataTextValue; static;
|
|
class function FromTimestamp(const AValue: TDateTime): TDataTimestampValue; static;
|
|
class function FromTuple(const AItems: array of IDataValue): TDataTupleValue; static;
|
|
class function FromMethod(const AMethodType: TDataMethodType; const AValue: TDataMethodProc): TDataMethodValue; static;
|
|
|
|
property DataValue: IDataValue read FDataValue;
|
|
property DataType: IDataType read GetDataType;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.SyncObjs,
|
|
System.Generics.Defaults,
|
|
Myc.Data.Types.Ordinal,
|
|
Myc.Data.Types.Float,
|
|
Myc.Data.Types.Text,
|
|
Myc.Data.Types.Timestamp,
|
|
Myc.Data.Types.Arrays,
|
|
Myc.Data.Types.Records,
|
|
Myc.Data.Types.Tuple,
|
|
Myc.Data.Types.Enum,
|
|
Myc.Data.Types.Method;
|
|
|
|
{ TRecordField }
|
|
|
|
constructor TRecordField.Create(const AName: string; const ADataType: IDataType);
|
|
begin
|
|
Name := AName;
|
|
DataType := ADataType;
|
|
end;
|
|
|
|
{ TDataOrdinalValue }
|
|
|
|
constructor TDataOrdinalValue.Create(const AOrdinalValue: IDataOrdinalValue);
|
|
begin
|
|
FOrdinalValue := AOrdinalValue;
|
|
end;
|
|
|
|
function TDataOrdinalValue.GetValue: Int64;
|
|
begin
|
|
Result := FOrdinalValue.Value;
|
|
end;
|
|
|
|
class operator TDataOrdinalValue.Implicit(const A: TDataOrdinalValue): IDataOrdinalValue;
|
|
begin
|
|
Result := A.FOrdinalValue;
|
|
end;
|
|
|
|
class operator TDataOrdinalValue.Implicit(const A: IDataOrdinalValue): TDataOrdinalValue;
|
|
begin
|
|
Result.FOrdinalValue := A;
|
|
end;
|
|
|
|
{ TDataOrdinalType }
|
|
|
|
constructor TDataOrdinalType.Create(const AOrdinalType: IDataOrdinalType);
|
|
begin
|
|
FOrdinalType := AOrdinalType;
|
|
end;
|
|
|
|
function TDataOrdinalType.CreateValue(Init: Int64): TDataOrdinalValue;
|
|
begin
|
|
Result := FOrdinalType.CreateValue(Init);
|
|
end;
|
|
|
|
class operator TDataOrdinalType.Implicit(const A: TDataOrdinalType): IDataOrdinalType;
|
|
begin
|
|
Result := A.FOrdinalType;
|
|
end;
|
|
|
|
class operator TDataOrdinalType.Implicit(const A: IDataOrdinalType): TDataOrdinalType;
|
|
begin
|
|
Result.FOrdinalType := A;
|
|
end;
|
|
|
|
{ TDataFloatValue }
|
|
|
|
constructor TDataFloatValue.Create(const AFloatValue: IDataFloatValue);
|
|
begin
|
|
FFloatValue := AFloatValue;
|
|
end;
|
|
|
|
function TDataFloatValue.GetValue: Double;
|
|
begin
|
|
Result := FFloatValue.Value;
|
|
end;
|
|
|
|
class operator TDataFloatValue.Implicit(const A: IDataFloatValue): TDataFloatValue;
|
|
begin
|
|
Result.FFloatValue := A;
|
|
end;
|
|
|
|
class operator TDataFloatValue.Implicit(const A: TDataFloatValue): IDataFloatValue;
|
|
begin
|
|
Result := A.FFloatValue;
|
|
end;
|
|
|
|
{ TDataFloatType }
|
|
|
|
constructor TDataFloatType.Create(const AFloatType: IDataFloatType);
|
|
begin
|
|
FFloatType := AFloatType;
|
|
end;
|
|
|
|
function TDataFloatType.CreateValue(Init: Double): TDataFloatValue;
|
|
begin
|
|
Result := FFloatType.CreateValue(Init);
|
|
end;
|
|
|
|
class operator TDataFloatType.Implicit(const A: IDataFloatType): TDataFloatType;
|
|
begin
|
|
Result.FFloatType := A;
|
|
end;
|
|
|
|
class operator TDataFloatType.Implicit(const A: TDataFloatType): IDataFloatType;
|
|
begin
|
|
Result := A.FFloatType;
|
|
end;
|
|
|
|
{ TDataTextValue }
|
|
|
|
constructor TDataTextValue.Create(const ATextValue: IDataTextValue);
|
|
begin
|
|
FTextValue := ATextValue;
|
|
end;
|
|
|
|
function TDataTextValue.GetValue: string;
|
|
begin
|
|
Result := FTextValue.Value;
|
|
end;
|
|
|
|
class operator TDataTextValue.Implicit(const A: IDataTextValue): TDataTextValue;
|
|
begin
|
|
Result.FTextValue := A;
|
|
end;
|
|
|
|
class operator TDataTextValue.Implicit(const A: TDataTextValue): IDataTextValue;
|
|
begin
|
|
Result := A.FTextValue;
|
|
end;
|
|
|
|
{ TDataTextType }
|
|
|
|
constructor TDataTextType.Create(const ATextType: IDataTextType);
|
|
begin
|
|
FTextType := ATextType;
|
|
end;
|
|
|
|
function TDataTextType.CreateValue(const AValue: string): TDataTextValue;
|
|
begin
|
|
Result := FTextType.CreateValue(AValue);
|
|
end;
|
|
|
|
class operator TDataTextType.Implicit(const A: IDataTextType): TDataTextType;
|
|
begin
|
|
Result.FTextType := A;
|
|
end;
|
|
|
|
class operator TDataTextType.Implicit(const A: TDataTextType): IDataTextType;
|
|
begin
|
|
Result := A.FTextType;
|
|
end;
|
|
|
|
{ TDataTimestampValue }
|
|
|
|
constructor TDataTimestampValue.Create(const ATimestampValue: IDataTimestampValue);
|
|
begin
|
|
FTimestampValue := ATimestampValue;
|
|
end;
|
|
|
|
function TDataTimestampValue.GetValue: TDateTime;
|
|
begin
|
|
Result := FTimestampValue.Value;
|
|
end;
|
|
|
|
class operator TDataTimestampValue.Implicit(const A: IDataTimestampValue): TDataTimestampValue;
|
|
begin
|
|
Result.FTimestampValue := A;
|
|
end;
|
|
|
|
class operator TDataTimestampValue.Implicit(const A: TDataTimestampValue): IDataTimestampValue;
|
|
begin
|
|
Result := A.FTimestampValue;
|
|
end;
|
|
|
|
{ TDataTimestampType }
|
|
|
|
constructor TDataTimestampType.Create(const ATimestampType: IDataTimestampType);
|
|
begin
|
|
FTimestampType := ATimestampType;
|
|
end;
|
|
|
|
function TDataTimestampType.CreateValue(const AValue: TDateTime): TDataTimestampValue;
|
|
begin
|
|
Result := FTimestampType.CreateValue(AValue);
|
|
end;
|
|
|
|
class operator TDataTimestampType.Implicit(const A: IDataTimestampType): TDataTimestampType;
|
|
begin
|
|
Result.FTimestampType := A;
|
|
end;
|
|
|
|
class operator TDataTimestampType.Implicit(const A: TDataTimestampType): IDataTimestampType;
|
|
begin
|
|
Result := A.FTimestampType;
|
|
end;
|
|
|
|
{ TDataEnumValue }
|
|
|
|
constructor TDataEnumValue.Create(const AEnumValue: IDataEnumValue);
|
|
begin
|
|
FEnumValue := AEnumValue;
|
|
end;
|
|
|
|
function TDataEnumValue.GetValue: Integer;
|
|
begin
|
|
Result := FEnumValue.Value;
|
|
end;
|
|
|
|
class operator TDataEnumValue.Implicit(const A: IDataEnumValue): TDataEnumValue;
|
|
begin
|
|
Result.FEnumValue := A;
|
|
end;
|
|
|
|
class operator TDataEnumValue.Implicit(const A: TDataEnumValue): IDataEnumValue;
|
|
begin
|
|
Result := A.FEnumValue;
|
|
end;
|
|
|
|
{ TDataEnumType }
|
|
|
|
constructor TDataEnumType.Create(const AEnumType: IDataEnumType);
|
|
begin
|
|
FEnumType := AEnumType;
|
|
end;
|
|
|
|
function TDataEnumType.CreateValue(const AValue: Integer): TDataEnumValue;
|
|
begin
|
|
Result := FEnumType.CreateValue(AValue);
|
|
end;
|
|
|
|
function TDataEnumType.CreateValue(const AIdentifier: string): TDataEnumValue;
|
|
begin
|
|
Result := FEnumType.CreateValue(AIdentifier);
|
|
end;
|
|
|
|
function TDataEnumType.GetIdentifier(Idx: Integer): string;
|
|
begin
|
|
Result := FEnumType.GetIdentifier(Idx);
|
|
end;
|
|
|
|
function TDataEnumType.GetIdentifierCount: Integer;
|
|
begin
|
|
Result := FEnumType.IdentifierCount;
|
|
end;
|
|
|
|
function TDataEnumType.IndexOf(const AIdentifier: string): Integer;
|
|
begin
|
|
Result := FEnumType.IndexOf(AIdentifier);
|
|
end;
|
|
|
|
class operator TDataEnumType.Implicit(const A: IDataEnumType): TDataEnumType;
|
|
begin
|
|
Result.FEnumType := A;
|
|
end;
|
|
|
|
class operator TDataEnumType.Implicit(const A: TDataEnumType): IDataEnumType;
|
|
begin
|
|
Result := A.FEnumType;
|
|
end;
|
|
|
|
{ TDataMethodValue }
|
|
|
|
constructor TDataMethodValue.Create(const AMethodValue: IDataMethodValue);
|
|
begin
|
|
FMethodValue := AMethodValue;
|
|
end;
|
|
|
|
function TDataMethodValue.GetValue: TDataMethodProc;
|
|
begin
|
|
Result := FMethodValue.Value;
|
|
end;
|
|
|
|
class operator TDataMethodValue.Implicit(const A: IDataMethodValue): TDataMethodValue;
|
|
begin
|
|
Result.FMethodValue := A;
|
|
end;
|
|
|
|
class operator TDataMethodValue.Implicit(const A: TDataMethodValue): IDataMethodValue;
|
|
begin
|
|
Result := A.FMethodValue;
|
|
end;
|
|
|
|
{ TDataMethodType }
|
|
|
|
constructor TDataMethodType.Create(const AMethodType: IDataMethodType);
|
|
begin
|
|
FMethodType := AMethodType;
|
|
end;
|
|
|
|
function TDataMethodType.CreateValue(const AValue: TDataMethodProc): TDataMethodValue;
|
|
begin
|
|
Result := FMethodType.CreateValue(AValue);
|
|
end;
|
|
|
|
function TDataMethodType.GetArgType: IDataType;
|
|
begin
|
|
Result := FMethodType.ArgType;
|
|
end;
|
|
|
|
function TDataMethodType.GetResultType: IDataType;
|
|
begin
|
|
Result := FMethodType.ResultType;
|
|
end;
|
|
|
|
class operator TDataMethodType.Implicit(const A: IDataMethodType): TDataMethodType;
|
|
begin
|
|
Result.FMethodType := A;
|
|
end;
|
|
|
|
class operator TDataMethodType.Implicit(const A: TDataMethodType): IDataMethodType;
|
|
begin
|
|
Result := A.FMethodType;
|
|
end;
|
|
|
|
{ TDataRecordValue }
|
|
|
|
constructor TDataRecordValue.Create(const ARecordValue: IDataRecordValue);
|
|
begin
|
|
FRecordValue := ARecordValue;
|
|
end;
|
|
|
|
function TDataRecordValue.GetItem(Idx: Integer): IDataValue;
|
|
begin
|
|
Result := FRecordValue.GetItem(Idx);
|
|
end;
|
|
|
|
class operator TDataRecordValue.Implicit(const A: IDataRecordValue): TDataRecordValue;
|
|
begin
|
|
Result.FRecordValue := A;
|
|
end;
|
|
|
|
class operator TDataRecordValue.Implicit(const A: TDataRecordValue): IDataRecordValue;
|
|
begin
|
|
Result := A.FRecordValue;
|
|
end;
|
|
|
|
{ TDataRecordType }
|
|
|
|
constructor TDataRecordType.Create(const ARecordType: IDataRecordType);
|
|
begin
|
|
FRecordType := ARecordType;
|
|
end;
|
|
|
|
function TDataRecordType.CreateValue(const AItems: array of IDataValue): TDataRecordValue;
|
|
begin
|
|
Result := FRecordType.CreateValue(AItems);
|
|
end;
|
|
|
|
function TDataRecordType.GetField(Idx: Integer): TRecordField;
|
|
begin
|
|
Result := FRecordType.GetField(Idx);
|
|
end;
|
|
|
|
function TDataRecordType.GetFieldCount: Integer;
|
|
begin
|
|
Result := FRecordType.FieldCount;
|
|
end;
|
|
|
|
function TDataRecordType.IndexOf(const AName: string): Integer;
|
|
begin
|
|
Result := FRecordType.IndexOf(AName);
|
|
end;
|
|
|
|
class operator TDataRecordType.Implicit(const A: IDataRecordType): TDataRecordType;
|
|
begin
|
|
Result.FRecordType := A;
|
|
end;
|
|
|
|
class operator TDataRecordType.Implicit(const A: TDataRecordType): IDataRecordType;
|
|
begin
|
|
Result := A.FRecordType;
|
|
end;
|
|
|
|
{ TDataTupleValue }
|
|
|
|
constructor TDataTupleValue.Create(const ATupleValue: IDataTupleValue);
|
|
begin
|
|
FTupleValue := ATupleValue;
|
|
end;
|
|
|
|
function TDataTupleValue.GetItem(Idx: Integer): IDataValue;
|
|
begin
|
|
Result := FTupleValue.GetItem(Idx);
|
|
end;
|
|
|
|
function TDataTupleValue.GetItemCount: Integer;
|
|
begin
|
|
Result := FTupleValue.ItemCount;
|
|
end;
|
|
|
|
class operator TDataTupleValue.Implicit(const A: IDataTupleValue): TDataTupleValue;
|
|
begin
|
|
Result.FTupleValue := A;
|
|
end;
|
|
|
|
class operator TDataTupleValue.Implicit(const A: TDataTupleValue): IDataTupleValue;
|
|
begin
|
|
Result := A.FTupleValue;
|
|
end;
|
|
|
|
{ TDataTupleType }
|
|
|
|
constructor TDataTupleType.Create(const ATupleType: IDataTupleType);
|
|
begin
|
|
FTupleType := ATupleType;
|
|
end;
|
|
|
|
function TDataTupleType.CreateValue(const AItems: array of IDataValue): TDataTupleValue;
|
|
begin
|
|
Result := FTupleType.CreateValue(AItems);
|
|
end;
|
|
|
|
class operator TDataTupleType.Implicit(const A: IDataTupleType): TDataTupleType;
|
|
begin
|
|
Result.FTupleType := A;
|
|
end;
|
|
|
|
class operator TDataTupleType.Implicit(const A: TDataTupleType): IDataTupleType;
|
|
begin
|
|
Result := A.FTupleType;
|
|
end;
|
|
|
|
{ TDataArrayValue }
|
|
|
|
constructor TDataArrayValue.Create(const AArrayValue: IDataArrayValue);
|
|
begin
|
|
FArrayValue := AArrayValue;
|
|
end;
|
|
|
|
function TDataArrayValue.GetElementCount: Integer;
|
|
begin
|
|
Result := FArrayValue.ElementCount;
|
|
end;
|
|
|
|
function TDataArrayValue.GetItem(Idx: Integer): IDataValue;
|
|
begin
|
|
Result := FArrayValue.GetItem(Idx);
|
|
end;
|
|
|
|
class operator TDataArrayValue.Implicit(const A: IDataArrayValue): TDataArrayValue;
|
|
begin
|
|
Result.FArrayValue := A;
|
|
end;
|
|
|
|
class operator TDataArrayValue.Implicit(const A: TDataArrayValue): IDataArrayValue;
|
|
begin
|
|
Result := A.FArrayValue;
|
|
end;
|
|
|
|
{ TDataArrayType }
|
|
|
|
constructor TDataArrayType.Create(const AArrayType: IDataArrayType);
|
|
begin
|
|
FArrayType := AArrayType;
|
|
end;
|
|
|
|
function TDataArrayType.CreateValue(const AItems: array of IDataValue): TDataArrayValue;
|
|
begin
|
|
Result := FArrayType.CreateValue(AItems);
|
|
end;
|
|
|
|
function TDataArrayType.GetElementType: IDataType;
|
|
begin
|
|
Result := FArrayType.ElementType;
|
|
end;
|
|
|
|
class operator TDataArrayType.Implicit(const A: IDataArrayType): TDataArrayType;
|
|
begin
|
|
Result.FArrayType := A;
|
|
end;
|
|
|
|
class operator TDataArrayType.Implicit(const A: TDataArrayType): IDataArrayType;
|
|
begin
|
|
Result := A.FArrayType;
|
|
end;
|
|
|
|
{ TDataType }
|
|
|
|
constructor TDataType.Create(const ADataType: IDataType);
|
|
begin
|
|
Assert(Assigned(ADataType));
|
|
FDataType := ADataType;
|
|
end;
|
|
|
|
class constructor TDataType.CreateClass;
|
|
begin
|
|
FArrayTypeRegistry := TDictionary<IDataType, IDataArrayType>.Create;
|
|
FRecordTypeRegistry := TDictionary<TArray<TRecordField>, IDataRecordType>.Create(TRecordFieldComparer.Create);
|
|
FMethodTypeRegistry :=
|
|
TDictionary<TPair<IDataType, IDataType>, IDataMethodType>.Create(
|
|
TEqualityComparer<TPair<IDataType, IDataType>>.Construct(
|
|
function(const Left, Right: TPair<IDataType, IDataType>): Boolean
|
|
begin
|
|
Result := (Left.Key = Right.Key) and (Left.Value = Right.Value);
|
|
end,
|
|
function(const Value: TPair<IDataType, IDataType>): Integer
|
|
var
|
|
hash1, hash2: NativeInt;
|
|
begin
|
|
hash1 := NativeInt(Value.Key);
|
|
hash2 := NativeInt(Value.Value);
|
|
// Simple XOR combination for pointer hashes
|
|
Result := Integer(hash1 xor hash2);
|
|
end
|
|
)
|
|
);
|
|
end;
|
|
|
|
class destructor TDataType.DestroyClass;
|
|
begin
|
|
FArrayTypeRegistry.Free;
|
|
FRecordTypeRegistry.Free;
|
|
FMethodTypeRegistry.Free;
|
|
end;
|
|
|
|
class function TDataType.ArrayOf(const AElementType: IDataType): TDataArrayType;
|
|
var
|
|
res: IDataArrayType;
|
|
begin
|
|
if not Assigned(AElementType) then
|
|
raise EArgumentException.Create('Cannot create an array type with a nil element type.');
|
|
|
|
TMonitor.Enter(FArrayTypeRegistry);
|
|
try
|
|
if not FArrayTypeRegistry.TryGetValue(AElementType, res) then
|
|
begin
|
|
res := TImplDataArrayType.Create(AElementType);
|
|
FArrayTypeRegistry.Add(AElementType, res);
|
|
end;
|
|
finally
|
|
TMonitor.Exit(FArrayTypeRegistry);
|
|
end;
|
|
Result.Create(res);
|
|
end;
|
|
|
|
function TDataType.AsArray: TDataArrayType;
|
|
begin
|
|
if (FDataType.Kind <> dkArray) then
|
|
raise EInvalidCast.Create('Array expected');
|
|
Result.Create(IDataArrayType(FDataType));
|
|
end;
|
|
|
|
function TDataType.AsEnum: TDataEnumType;
|
|
begin
|
|
if (FDataType.Kind <> dkEnum) then
|
|
raise EInvalidCast.Create('Enum expected');
|
|
Result.Create(IDataEnumType(FDataType));
|
|
end;
|
|
|
|
function TDataType.AsFloat: TDataFloatType;
|
|
begin
|
|
if (FDataType.Kind <> dkFloat) then
|
|
raise EInvalidCast.Create('Float expected');
|
|
Result.Create(IDataFloatType(FDataType));
|
|
end;
|
|
|
|
function TDataType.AsMethod: TDataMethodType;
|
|
begin
|
|
if (FDataType.Kind <> dkMethod) then
|
|
raise EInvalidCast.Create('Method expected');
|
|
Result.Create(IDataMethodType(FDataType));
|
|
end;
|
|
|
|
function TDataType.AsOrdinal: TDataOrdinalType;
|
|
begin
|
|
if (FDataType.Kind <> dkOrdinal) then
|
|
raise EInvalidCast.Create('Ordinal expected');
|
|
Result.Create(IDataOrdinalType(FDataType));
|
|
end;
|
|
|
|
function TDataType.AsRecord: TDataRecordType;
|
|
begin
|
|
if (FDataType.Kind <> dkRecord) then
|
|
raise EInvalidCast.Create('Record expected');
|
|
Result.Create(IDataRecordType(FDataType));
|
|
end;
|
|
|
|
function TDataType.AsText: TDataTextType;
|
|
begin
|
|
if (FDataType.Kind <> dkText) then
|
|
raise EInvalidCast.Create('Text expected');
|
|
Result.Create(IDataTextType(FDataType));
|
|
end;
|
|
|
|
function TDataType.AsTimestamp: TDataTimestampType;
|
|
begin
|
|
if (FDataType.Kind <> dkTimestamp) then
|
|
raise EInvalidCast.Create('Timestamp expected');
|
|
Result.Create(IDataTimestampType(FDataType));
|
|
end;
|
|
|
|
function TDataType.AsTuple: TDataTupleType;
|
|
begin
|
|
if (FDataType.Kind <> dkTuple) then
|
|
raise EInvalidCast.Create('Tuple expected');
|
|
Result.Create(IDataTupleType(FDataType));
|
|
end;
|
|
|
|
class function TDataType.Float: TDataFloatType;
|
|
begin
|
|
Result.Create(TImplDataFloatType.Singleton);
|
|
end;
|
|
|
|
function TDataType.GetName: String;
|
|
begin
|
|
if Assigned(FDataType) then
|
|
Result := FDataType.Name
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
class function TDataType.MethodOf(const AArgType, AResultType: IDataType): TDataMethodType;
|
|
var
|
|
key: TPair<IDataType, IDataType>;
|
|
res: IDataMethodType;
|
|
begin
|
|
key := TPair<IDataType, IDataType>.Create(AArgType, AResultType);
|
|
TMonitor.Enter(FMethodTypeRegistry);
|
|
try
|
|
if not FMethodTypeRegistry.TryGetValue(key, res) then
|
|
begin
|
|
res := TImplDataMethodType.Create(AArgType, AResultType);
|
|
FMethodTypeRegistry.Add(key, res);
|
|
end;
|
|
finally
|
|
TMonitor.Exit(FMethodTypeRegistry);
|
|
end;
|
|
Result.Create(res);
|
|
end;
|
|
|
|
class function TDataType.Ordinal: TDataOrdinalType;
|
|
begin
|
|
Result.Create(TImplDataOrdinalType.Singleton);
|
|
end;
|
|
|
|
class function TDataType.RecordOf(const Fields: TArray<TRecordField>): TDataRecordType;
|
|
var
|
|
res: IDataRecordType;
|
|
begin
|
|
TMonitor.Enter(FRecordTypeRegistry);
|
|
try
|
|
if not FRecordTypeRegistry.TryGetValue(Fields, res) then
|
|
begin
|
|
res := TImplDataRecordType.Create(Fields);
|
|
FRecordTypeRegistry.Add(Fields, res);
|
|
end;
|
|
finally
|
|
TMonitor.Exit(FRecordTypeRegistry);
|
|
end;
|
|
Result.Create(res);
|
|
end;
|
|
|
|
class function TDataType.RecordOf(const Fields: array of TRecordField): TDataRecordType;
|
|
var
|
|
tFields: TArray<TRecordField>;
|
|
i: Integer;
|
|
begin
|
|
SetLength(tFields, Length(Fields));
|
|
for i := 0 to High(Fields) do
|
|
tFields[i] := Fields[i];
|
|
Result := RecordOf(tFields);
|
|
end;
|
|
|
|
class function TDataType.EnumOf(const AName: string; const AIdentifiers: array of string): TDataEnumType;
|
|
begin
|
|
Result.Create(TImplDataEnumType.Create(AName, AIdentifiers));
|
|
end;
|
|
|
|
function TDataType.GetKind: TDataKind;
|
|
begin
|
|
Result := FDataType.Kind;
|
|
end;
|
|
|
|
class function TDataType.Text: TDataTextType;
|
|
begin
|
|
Result.Create(TImplDataTextType.Singleton);
|
|
end;
|
|
|
|
class function TDataType.Timestamp: TDataTimestampType;
|
|
begin
|
|
Result.Create(TImplDataTimestampType.Singleton);
|
|
end;
|
|
|
|
class function TDataType.Tuple: TDataTupleType;
|
|
begin
|
|
Result.Create(TImplDataTupleType.Singleton);
|
|
end;
|
|
|
|
class operator TDataType.Implicit(const A: TDataType): IDataType;
|
|
begin
|
|
Result := A.FDataType;
|
|
end;
|
|
|
|
class operator TDataType.Implicit(const A: IDataType): TDataType;
|
|
begin
|
|
Result.FDataType := A;
|
|
end;
|
|
|
|
class operator TDataType.Implicit(const A: TDataOrdinalType): TDataType;
|
|
begin
|
|
Result.FDataType := A.FOrdinalType;
|
|
end;
|
|
|
|
class operator TDataType.Implicit(const A: TDataFloatType): TDataType;
|
|
begin
|
|
Result.FDataType := A.FFloatType;
|
|
end;
|
|
|
|
class operator TDataType.Implicit(const A: TDataTextType): TDataType;
|
|
begin
|
|
Result.FDataType := A.FTextType;
|
|
end;
|
|
|
|
class operator TDataType.Implicit(const A: TDataTimestampType): TDataType;
|
|
begin
|
|
Result.FDataType := A.FTimestampType;
|
|
end;
|
|
|
|
class operator TDataType.Implicit(const A: TDataEnumType): TDataType;
|
|
begin
|
|
Result.FDataType := A.FEnumType;
|
|
end;
|
|
|
|
class operator TDataType.Implicit(const A: TDataMethodType): TDataType;
|
|
begin
|
|
Result.FDataType := A.FMethodType;
|
|
end;
|
|
|
|
class operator TDataType.Implicit(const A: TDataRecordType): TDataType;
|
|
begin
|
|
Result.FDataType := A.FRecordType;
|
|
end;
|
|
|
|
class operator TDataType.Implicit(const A: TDataTupleType): TDataType;
|
|
begin
|
|
Result.FDataType := A.FTupleType;
|
|
end;
|
|
|
|
class operator TDataType.Implicit(const A: TDataArrayType): TDataType;
|
|
begin
|
|
Result.FDataType := A.FArrayType;
|
|
end;
|
|
|
|
{ TDataValue }
|
|
|
|
constructor TDataValue.Create(const ADataValue: IDataValue);
|
|
begin
|
|
Assert(Assigned(ADataValue));
|
|
FDataValue := ADataValue;
|
|
end;
|
|
|
|
function TDataValue.AsArray: TDataArrayValue;
|
|
begin
|
|
if (FDataValue.DataType.Kind <> dkArray) then
|
|
raise EInvalidCast.Create('Array expected');
|
|
Result.Create(IDataArrayValue(FDataValue));
|
|
end;
|
|
|
|
function TDataValue.AsFloat: TDataFloatValue;
|
|
begin
|
|
if (FDataValue.DataType.Kind <> dkFloat) then
|
|
raise EInvalidCast.Create('Float expected');
|
|
Result.Create(IDataFloatValue(FDataValue));
|
|
end;
|
|
|
|
function TDataValue.AsMethod: TDataMethodValue;
|
|
begin
|
|
if (FDataValue.DataType.Kind <> dkMethod) then
|
|
raise EInvalidCast.Create('Method expected');
|
|
Result.Create(IDataMethodValue(FDataValue));
|
|
end;
|
|
|
|
function TDataValue.AsText: TDataTextValue;
|
|
begin
|
|
if (FDataValue.DataType.Kind <> dkText) then
|
|
raise EInvalidCast.Create('Text expected');
|
|
Result.Create(IDataTextValue(FDataValue));
|
|
end;
|
|
|
|
function TDataValue.AsTimestamp: TDataTimestampValue;
|
|
begin
|
|
if (FDataValue.DataType.Kind <> dkTimestamp) then
|
|
raise EInvalidCast.Create('Timestamp expected');
|
|
Result.Create(IDataTimestampValue(FDataValue));
|
|
end;
|
|
|
|
function TDataValue.AsOrdinal: TDataOrdinalValue;
|
|
begin
|
|
if (FDataValue.DataType.Kind <> dkOrdinal) then
|
|
raise EInvalidCast.Create('Ordinal expected');
|
|
Result.Create(IDataOrdinalValue(FDataValue));
|
|
end;
|
|
|
|
function TDataValue.AsRecord: TDataRecordValue;
|
|
begin
|
|
if (FDataValue.DataType.Kind <> dkRecord) then
|
|
raise EInvalidCast.Create('Record expected');
|
|
Result.Create(IDataRecordValue(FDataValue));
|
|
end;
|
|
|
|
function TDataValue.AsTuple: TDataTupleValue;
|
|
begin
|
|
if (FDataValue.DataType.Kind <> dkTuple) then
|
|
raise EInvalidCast.Create('Tuple expected');
|
|
Result.Create(IDataTupleValue(FDataValue));
|
|
end;
|
|
|
|
function TDataValue.AsEnum: TDataEnumValue;
|
|
begin
|
|
if (FDataValue.DataType.Kind <> dkEnum) then
|
|
raise EInvalidCast.Create('Enum expected');
|
|
Result.Create(IDataEnumValue(FDataValue));
|
|
end;
|
|
|
|
class function TDataValue.FromOrdinal(const AValue: Int64): TDataOrdinalValue;
|
|
begin
|
|
Result := TDataType.Ordinal.CreateValue(AValue);
|
|
end;
|
|
|
|
class function TDataValue.FromFloat(const AValue: Double): TDataFloatValue;
|
|
begin
|
|
Result := TDataType.Float.CreateValue(AValue);
|
|
end;
|
|
|
|
class function TDataValue.FromMethod(const AMethodType: TDataMethodType; const AValue: TDataMethodProc): TDataMethodValue;
|
|
begin
|
|
if not Assigned(AMethodType.FMethodType) then // Check underlying interface
|
|
raise EArgumentException.Create('AMethodType');
|
|
Result := AMethodType.CreateValue(AValue);
|
|
end;
|
|
|
|
class function TDataValue.FromText(const AValue: string): TDataTextValue;
|
|
begin
|
|
Result := TDataType.Text.CreateValue(AValue);
|
|
end;
|
|
|
|
class function TDataValue.FromTimestamp(const AValue: TDateTime): TDataTimestampValue;
|
|
begin
|
|
Result := TDataType.Timestamp.CreateValue(AValue);
|
|
end;
|
|
|
|
class function TDataValue.FromTuple(const AItems: array of IDataValue): TDataTupleValue;
|
|
begin
|
|
Result := TDataType.Tuple.CreateValue(AItems);
|
|
end;
|
|
|
|
function TDataValue.GetDataType: IDataType;
|
|
begin
|
|
if Assigned(FDataValue) then
|
|
Result := FDataValue.DataType
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
class operator TDataValue.Implicit(const A: TDataValue): IDataValue;
|
|
begin
|
|
Result := A.FDataValue;
|
|
end;
|
|
|
|
class operator TDataValue.Implicit(const A: IDataValue): TDataValue;
|
|
begin
|
|
Result.FDataValue := A;
|
|
end;
|
|
|
|
class operator TDataValue.Implicit(const A: TDataOrdinalValue): TDataValue;
|
|
begin
|
|
Result.FDataValue := A.FOrdinalValue;
|
|
end;
|
|
|
|
class operator TDataValue.Implicit(const A: TDataFloatValue): TDataValue;
|
|
begin
|
|
Result.FDataValue := A.FFloatValue;
|
|
end;
|
|
|
|
class operator TDataValue.Implicit(const A: TDataTextValue): TDataValue;
|
|
begin
|
|
Result.FDataValue := A.FTextValue;
|
|
end;
|
|
|
|
class operator TDataValue.Implicit(const A: TDataTimestampValue): TDataValue;
|
|
begin
|
|
Result.FDataValue := A.FTimestampValue;
|
|
end;
|
|
|
|
class operator TDataValue.Implicit(const A: TDataEnumValue): TDataValue;
|
|
begin
|
|
Result.FDataValue := A.FEnumValue;
|
|
end;
|
|
|
|
class operator TDataValue.Implicit(const A: TDataMethodValue): TDataValue;
|
|
begin
|
|
Result.FDataValue := A.FMethodValue;
|
|
end;
|
|
|
|
class operator TDataValue.Implicit(const A: TDataRecordValue): TDataValue;
|
|
begin
|
|
Result.FDataValue := A.FRecordValue;
|
|
end;
|
|
|
|
class operator TDataValue.Implicit(const A: TDataTupleValue): TDataValue;
|
|
begin
|
|
Result.FDataValue := A.FTupleValue;
|
|
end;
|
|
|
|
class operator TDataValue.Implicit(const A: TDataArrayValue): TDataValue;
|
|
begin
|
|
Result.FDataValue := A.FArrayValue;
|
|
end;
|
|
|
|
end.
|