unit MakhDBCommon;
//(c) 2019 Makhaon Software
interface
uses
Data.DB,
System.Classes,
System.SysUtils,
System.Rtti;
type
DBFieldAttribute = class(TCustomAttribute)
strict private
FFormatParam: string;
FFieldName: string;
public
constructor Create; overload;
constructor Create(const AFieldName: string); overload;
constructor Create(const AFieldName, AFormatParam: string); overload;
property FieldName: string Read FFieldName;
property FormatParam: string Read FFormatParam;
end;
type
TDSHelper<T> = class
class procedure DataSetToVar(DataSet: TDataSet; var Variable: T; ClearRec: boolean = True);
class function DataSetToRecords(DataSet: TDataSet; OnFoundRec: TNotifyEvent = nil): TArray<T>;
end;
implementation
class procedure TDSHelper<T>.DataSetToVar(DataSet: TDataSet; var Variable: T; ClearRec: boolean = True);
var
Context: TRttiContext;
Fields: TRttiType;
Field: TRttiField;
Attr: TCustomAttribute;
AttrAs: DBFieldAttribute;
DBField: TField;
begin
if ClearRec then
Variable := Default(T);
Context := TRttiContext.Create;
try
Fields := Context.GetType(TypeInfo(T));
for Field in Fields.GetFields do
for Attr in Field.GetAttributes do
if Attr is DBFieldAttribute then
begin
AttrAs := DBFieldAttribute(Attr);
DBField := DataSet.FindField(AttrAs.FieldName);
if Assigned(DBField) then
if (Field.FieldType is TRttiStringType) then
if AttrAs.FormatParam.IsEmpty then
Field.SetValue(@Variable, TValue.From(DBField.AsString.TrimRight))
else
Field.SetValue(@Variable, TValue.From(Format(AttrAs.FormatParam, [DBField.AsString.TrimRight])))
else if Field.FieldType.Handle = TypeInfo(boolean) then
Field.SetValue(@Variable, TValue.From(DBField.AsString.StartsWith('+')))
else
Field.SetValue(@Variable, TValue.From(DBField.AsVariant));
end;
finally
Context.Free;
end;
end;
class function TDSHelper<T>.DataSetToRecords(DataSet: TDataSet; OnFoundRec: TNotifyEvent = nil): TArray<T>;
var
i: integer;
begin
with Dataset do
begin
First;
SetLength(Result, RecordCount);
i := 0;
while not Eof do
begin
TDSHelper<T>.DataSetToVar(Dataset, Result[i]);
if Assigned(OnFoundRec) then
OnFoundRec(DataSet);
Inc(i);
Next;
end;
end;
end;
{ DBFieldAttribute }
constructor DBFieldAttribute.Create;
begin
inherited Create;
FFieldName := '';
end;
constructor DBFieldAttribute.Create(const AFieldName: string);
begin
inherited Create;
FFieldName := AFieldName;
FFormatParam := '';
end;
constructor DBFieldAttribute.Create(const AFieldName, AFormatParam: string);
begin
inherited Create;
FFieldName := AFieldName;
FFormatParam := AFormatParam;
end;
end.
|