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.

Original source