Files
MycLib/Src/Data/Myc.Data.Types.Decimal.pas
T
2025-08-26 13:47:38 +02:00

128 lines
2.7 KiB
ObjectPascal

unit Myc.Data.Types.Decimal;
interface
uses
Myc.Data.Types;
type
// Concrete implementation of the IDataDecimalType interface.
TImplDataDecimalType = class(TInterfacedObject, IDataDecimalType)
private
FScale: Integer;
public
constructor Create(const AScale: Integer);
// IDataType
function GetName: String;
function GetKind: TDataKind;
// IDataDecimalType
function GetScale: Integer;
function CreateValue(const AValue: Int64): IDataDecimalValue;
end;
implementation
uses
System.SysUtils,
System.Rtti,
System.Math;
type
TDataDecimalValue = class(TInterfacedObject, IDataDecimalValue)
private
FDataType: IDataDecimalType;
FValue: Int64;
public
constructor Create(const AValue: Int64; const ADataType: IDataDecimalType);
// IDataValue
function GetDataType: IDataType;
function GetAsString: string;
function AsTValue: TValue;
// IDataDecimalValue
function GetValue: Int64;
end;
{ TImplDataDecimalType }
constructor TImplDataDecimalType.Create(const AScale: Integer);
begin
inherited Create;
FScale := AScale;
end;
function TImplDataDecimalType.CreateValue(const AValue: Int64): IDataDecimalValue;
begin
Result := TDataDecimalValue.Create(AValue, Self);
end;
function TImplDataDecimalType.GetKind: TDataKind;
begin
Result := dkDecimal;
end;
function TImplDataDecimalType.GetName: String;
begin
Result := Format('Decimal(18, %d)', [FScale]);
end;
function TImplDataDecimalType.GetScale: Integer;
begin
Result := FScale;
end;
{ TDataDecimalValue }
constructor TDataDecimalValue.Create(const AValue: Int64; const ADataType: IDataDecimalType);
begin
inherited Create;
FValue := AValue;
FDataType := ADataType;
end;
function TDataDecimalValue.AsTValue: TValue;
begin
Result := TValue.From<Int64>(FValue);
end;
function TDataDecimalValue.GetAsString: string;
var
s: string;
scale: Integer;
insertPos: Integer;
begin
s := IntToStr(abs(FValue));
scale := FDataType.Scale;
if scale > 0 then
begin
if Length(s) <= scale then
s := StringOfChar('0', scale - Length(s) + 1) + s;
insertPos := Length(s) - scale;
Result := Copy(s, 1, insertPos) + '.' + Copy(s, insertPos + 1, MaxInt);
end
else
begin
Result := s;
end;
if FValue < 0 then
Result := '-' + Result;
end;
function TDataDecimalValue.GetDataType: IDataType;
begin
Result := FDataType;
end;
function TDataDecimalValue.GetValue: Int64;
begin
Result := FValue;
end;
end.