unit Aurelius.Commands.MetadataCommandPerformer;

{$I Aurelius.inc}

interface

uses
  Aurelius.Commands.AbstractCommandPerformer,
  Aurelius.Mapping.Metadata,
  Aurelius.Sql.Metadata;

type
  TMetadataCommandPerformer = class(TAbstractCommandPerformer)
  strict protected
    function IsAutoGeneratedColumn(Col: TColumn): boolean;
    procedure MakeEquivalentColumn(Column: TColumnMetadata);
    procedure BuildColumnMetadata(Column: TColumnMetadata; C: TColumn);
  end;

implementation

uses
  DB,
  Aurelius.Sql.Interfaces,
  Aurelius.Sql.Exceptions;

{ TMetadataCommandPerformer }

procedure TMetadataCommandPerformer.BuildColumnMetadata(Column: TColumnMetadata;
  C: TColumn);
begin
  Column.Name := C.Name;
  Column.NotNull := TColumnProp.Required in C.Properties;
  Column.FieldType := C.FieldType;
  Column.Length := C.Length;

  // specific code for memo. When length > 65535, field is considered to be memo, but actually
  // the size doesn't matter. So we must set this to zero otherwise database schema comparison will fail (size mismatch)
  if Column.FieldType in [ftMemo, ftWideMemo] then
    Column.Length := 0;
  Column.Precision := C.Precision;
  Column.Scale := C.Scale;
  Column.AutoGenerated := IsAutoGeneratedColumn(C) and (TDBFeature.AutoGenerated in SQLGenerator.SupportedFeatures);
  MakeEquivalentColumn(Column);
  SQLGenerator.DefineColumnType(Column);
end;

function TMetadataCommandPerformer.IsAutoGeneratedColumn(Col: TColumn): boolean;
begin
  Result := Explorer.GetId(Clazz).IsAutoGenerated and IsIdColumn(Col);
end;

procedure TMetadataCommandPerformer.MakeEquivalentColumn(
  Column: TColumnMetadata);
var
  E: TFieldTypeEquivalence;
begin
  if not (Column.FieldType in SQLGenerator.GetSupportedFieldTypes) then
  begin
    for E in SQLGenerator.GetEquivalentFieldTypes do
      if E.NotSupportedType = Column.FieldType then
      begin
        Column.FieldType := E.EquivalentType;
        Column.Length := E.EquivalentLenth;
        Column.Precision := E.EquivalentPrecision;
        Column.Scale := E.EquivalentScale;
        Exit;
      end;

    raise EUnsupportedFieldType.Create(SQLGenerator, Column.FieldType);
  end;
end;

end.
