Get Enum size and name passed as generic parameter
delphi, enums, generics, orm
Solution
You can use the new System.RTTI unit:
function TBaseTable<TableType>.Select: string;
var
EnumIndex: Byte;
Context: TRttiContext;
TableTypeRtti: TRttiEnumerationType;
begin
Context := TRttiContext.Create;
try
TableTypeRtti := Context.GetType(TypeInfo(TableType)) as TRttiEnumerationType;
Result := 'SELECT ';
for EnumIndex := TableTypeRtti.MinValue to TableTypeRtti.MaxValue do begin
Result := Result + GetEnumName(TypeInfo(TableType), EnumIndex) + ',';
end;
Result := Copy(Result, 0, Length(Result) - 1);
Result := Result + ' FROM ' + TableTypeRtti.Name;
finally
Context.Free;
end;
end;
Problem
Take a look the following code : ``` uses TypInfo, Dialogs, Classes, Generics.Collections, ADODB, DB, SysUtils; type TTable_1 = (ID, FName, LName, FatherName); type TBaseTable<TableType> = class(TADOQuery) public constructor Create(AOwner: TComponent); Override; procedure Select(DS: TDataSource); end; implementation { TBaseTable<TableType> } constructor TBaseTable<TableType>.Create(AOwner: TComponent); begin inherited; Self.Connection := DataModule3.ADOConnection1; Self.Connection.Connected := True; end; procedure TBaseTable<TableType>.Select(DS: TDataSource); var Query: string; EnumIndex: Byte; begin EnumIndex := 0; Query := 'SELECT '; while (GetEnumName(TypeInfo(TableType), EnumIndex) <> UnitName) do begin Query := Query + GetEnumName(TypeInfo(TableType), EnumIndex) + ','; Inc(EnumIndex); end; Query := Copy(Query, 0, Length(Query) - 1); Query := Query + ' FROM Table_1'; Close; SQL.Text := Query; Open; DS.DataSet := Self; end; ``` I use it like : ``` var Test: TBaseTable<TTable_1>; begin Test := TBaseTable<TTable_1>.Create(Self); Test.Select(DataSource1); end; ``` As you can see, I write the name of the table in the query as static string ( 'Table_1' ), I want to get the enum name and pass it to select statement as table name to make code more usable. Another question is how to get the passed enum size to get the field names, as you can see currently I compare the current enum name with Unit name, it's bad idea, anyone can help me? At least I want to develop a class, write an Enum for each table in my database and pass it to my class and my class's methods use it to Select, Insert, Edit and etc. I want to write a micro ORM for my personal use. Thanks.