unit uDataTableUtils;

interface

uses
  uDACDSDataTable, uDADataTable, Classes;


procedure CloneDataTable(const ASource : TDACDSDataTable;
                         var ATarget : TDACDSDataTable);

procedure GetKeyListAndValueList (const ASource : TDADataTable;
                                  var KeysList: TStringList; var ValuesList: TStringList);

procedure DeleteAllTable(const ADataTable : TDADataTable);

function DeltaValuesAreDifferent(const aDelta : IDADelta): boolean;


implementation

uses
  uDAClasses, uDAInterfaces, SysUtils, Variants;


procedure DeleteAllTable(const ADataTable : TDADataTable);
begin
  ADataTable.ClearRows;
 {  if ADataTable.RecordCount > 0 then
  begin
    ADataTable.DisableControls;
    //ADataTable.DisableEventHandlers;  <- No descomentar
    try
      repeat begin
        ADataTable.Last;
        ADataTable.Delete;
      end
      until ADataTable.BOF;
    finally
      ADataTable.EnableControls;
      //ADataTable.EnableEventHandlers;  <- No descomentar
    end;
  end;}
end;


procedure CloneDataTable(const ASource : TDACDSDataTable;
  var ATarget : TDACDSDataTable);
var
  i : Integer;
begin
  with ATarget do
  begin
    RemoteService := ASource.GetRemoteService;
    Adapter := ASource.GetAdapter;

    BusinessRulesID := ASource.BusinessRulesID;
    Randomize;
    Name := ASource.Name + '_' + IntToStr(Random(MAXINT));
    LogicalName := ASource.LogicalName;

    Params.AssignParamCollection(ASource.Params);

    with SchemaCall do
    begin
      MethodName := ASource.SchemaCall.MethodName;
      for i := 0 to ASource.SchemaCall.Params.Count - 1 do
      begin
        with Params.Add do begin
          Name := ASource.SchemaCall.Params[i].Name;
          ParamType := ASource.SchemaCall.Params[i].ParamType;
          DataType := ASource.SchemaCall.Params[i].DataType;
          Value := ASource.SchemaCall.Params[i].Value;
          UserClassName := ASource.SchemaCall.Params[i].UserClassName;
        end;
      end;
    end;
    ATarget.LoadSchema;  // o también ATarget.Fields.AssignFieldCollection(ASource.Fields);

    with DataUpdateCall do
    begin
      MethodName := ASource.DataUpdateCall.MethodName;
      for i := 0 to ASource.DataUpdateCall.Params.Count - 1 do
      begin
        with Params.Add do begin
          Name := ASource.DataUpdateCall.Params[i].Name;
          ParamType := ASource.DataUpdateCall.Params[i].ParamType;
          DataType := ASource.DataUpdateCall.Params[i].DataType;
          Value := ASource.DataUpdateCall.Params[i].Value;
          UserClassName := ASource.DataUpdateCall.Params[i].UserClassName;
        end;
      end;
    end;

    with ScriptCall do
    begin
      MethodName := ASource.ScriptCall.MethodName;
      for i := 0 to ASource.ScriptCall.Params.Count - 1 do
      begin
        with Params.Add do begin
          Name := ASource.ScriptCall.Params[i].Name;
          ParamType := ASource.ScriptCall.Params[i].ParamType;
          DataType := ASource.ScriptCall.Params[i].DataType;
          Value := ASource.ScriptCall.Params[i].Value;
          UserClassName := ASource.ScriptCall.Params[i].UserClassName;
        end;
      end;
    end;

    with DataRequestCall do
    begin
      MethodName := ASource.DataRequestCall.MethodName;
      for i := 0 to ASource.DataRequestCall.Params.Count - 1 do
      begin
        with Params.Add do begin
          begin
            Name := ASource.DataRequestCall.Params[i].Name;
            ParamType := ASource.DataRequestCall.Params[i].ParamType;
            DataType := ASource.DataRequestCall.Params[i].DataType;
            Value := ASource.DataRequestCall.Params[i].Value;
            UserClassName := ASource.DataRequestCall.Params[i].UserClassName;
          end;
        end;
      end;
    end;

    with MasterParamsMappings do
      for i := 0 to ASource.MasterParamsMappings.Count - 1 do
        Add(ASource.MasterParamsMappings.Strings[i]);

    with MasterRequestMappings do
      for i := 0 to ASource.MasterRequestMappings.Count - 1 do
        Add(ASource.MasterRequestMappings.Strings[i]);

    MasterMappingMode := ASource.MasterMappingMode;

    MasterFields := ASource.MasterFields;
    MasterOptions := ASource.MasterOptions;

    DetailFields := ASource.DetailFields;
    DetailOptions := ASource.DetailOptions;

    RemoteUpdatesOptions := ASource.RemoteUpdatesOptions;
    StreamingOptions := ASource.StreamingOptions;
    RemoteFetchEnabled := ASource.RemoteFetchEnabled;
  end;
end;

procedure getKeyListAndValueList (const ASource : TDADataTable;
                                  var KeysList: TStringList; var ValuesList: TStringList);
var
  i: Integer;
begin
  if not Assigned(KeysList) or not Assigned(ValuesList) then
     raise Exception.Create('Las listas están vacias');

  KeysList.Clear;
  ValuesList.Clear;

  for i:=0 to (ASource.Fields.Count-1) do
      if ASource.Fields.Fields[i].InPrimaryKey then
      begin
         KeysList.Add(Copy(ASource.Fields.Fields[i].Name, 0, Length(ASource.Fields.Fields[i].Name)));
         ValuesList.Add(Copy(VarToStr(ASource.Fields.Fields[i].Value), 0, Length(VarToStr(ASource.Fields.Fields[i].Value))));
      end;
end;

function DeltaValuesAreDifferent(const aDelta : IDADelta): boolean;
var
  i, x : integer;
  OldNewAreDifferent: boolean;
begin
  OldNewAreDifferent := FALSE;
  for i := 0 to (aDelta.Count-1) do
  begin
    for x := 0 to (aDelta.LoggedFieldCount-1) do
    begin
      OldNewAreDifferent := (aDelta.Changes[i].OldValues[x] <> aDelta.Changes[i].NewValues[x]);

      if OldNewAreDifferent then
        Break;    // Abandon iteration at the first difference between old and new.
    end;

    if OldNewAreDifferent then
      Break;    // Abandon iteration at the first difference between old and new.
  end;
  result := OldNewAreDifferent;
end;


end.
