unit uDataTableUtils;

interface

uses
  uDACDSDataTable, uDADataTable, uDAInterfaces;


procedure CloneDataTable(const ASource : TDACDSDataTable;
                         var ATarget : TDACDSDataTable;
                         RemoteUpdate: Boolean = True); 

procedure CopyDataTable(ASource : IDADataset; ATarget : TDADataTable;
  const OnlySelectedRows : Boolean = False);
procedure DeleteAllTable(const ADataTable : TDADataTable);
function DeltaValuesAreDifferent(const aDelta : IDADelta): boolean;

implementation

uses
  uDAClasses, SysUtils, uDABINAdapter, uROTypes, uDBSelectionList, cxControls,
  Dialogs, Variants;


{procedure EliminarNoSeleccionados(const ASource : IDADataset;
  var ATarget : TDADataTable);
var
  AObj : ISelectedRowList;
  i : Integer;
begin
  if not Supports(ASource, ISelectedRowList, aObj) then
    Exit;

//  ATarget.DisableControls;
//  ATarget.DisableEventHandlers;
  ShowHourglassCursor;
  try
    ATarget.Open;
    ATarget.Last;
    while ATarget.RecordCount > AObj.SelectedRows.Count do
    begin
      if AObj.SelectedRows.IndexOf(ATarget.RecIDValue) < 0 then
        ATarget.Delete
      else
        ATarget.Prior;
    end;
  finally
//    ATarget.EnableControls;
//    ATarget.EnableControls;
    HideHourglassCursor;
  end;
end;}


procedure DeleteAllTable(const ADataTable : TDADataTable);
begin
  ADataTable.ClearRows;
end;

procedure CloneDataTable(const ASource : TDACDSDataTable;
  var ATarget : TDACDSDataTable; RemoteUpdate: Boolean);
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);

    if Assigned(ASource.LocalSchema) then
      LocalSchema := ASource.LocalSchema
    else begin
      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.Fields.AssignFieldCollection(ASource.Fields);   // o también ATarget.LoadSchema;
    end;
    
    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;

  if not RemoteUpdate then
  begin
    ATarget.LogChanges := False;
    ATarget.RemoteFetchEnabled := False;
  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;


procedure CopyDataTable(ASource : IDADataset; ATarget : TDADataTable;
  const OnlySelectedRows : Boolean = False);
var
  DABin: Binary;
  DAAdapter : TDABINAdapter;
  AFilter : String;
  AFiltered : Boolean;
  AObj : ISelectedRowList;
  i : Integer;
begin
  DABin := Binary.Create;
  DAAdapter := TDABINAdapter.Create(nil);
  AFilter := '';

  if OnlySelectedRows then
  begin
    if not Supports(ASource, ISelectedRowList, aObj) then
      raise Exception.Create('El origen de datos no soporta la interfaz ISelectedRowList (CopyDataTable)');

    if ASource.Dataset.Filtered then
    begin
      AFiltered := True;
      AFilter := ASource.Dataset.Filter;
      ASource.Dataset.Filtered := False;
    end;

    ASource.Dataset.Filter := '';    
    for i := 0 to AObj.SelectedRows.Count - 1 do
    begin
      if (i > 0) then
        ASource.Dataset.Filter := ASource.Dataset.Filter + ' or ';
      ASource.Dataset.Filter := ASource.Dataset.Filter + '(RecID = ' + IntToStr(AObj.SelectedRows.Items[i]) + ')';
    end;

    ASource.Dataset.Filtered := True;
  end;

  try
    ATarget.LogicalName := ASource.LogicalName;  // We need to specify new dataset LogicalName

    if not ASource.Active then
      ASource.Open;
    ASource.Dataset.First;

    DAAdapter.WriteDataset(DABin, ASource, [woRows, woSchema], -1);
    DAAdapter.Initialize(DABin, aiReadFromBeginning);
    DAAdapter.ReadDataset(ATarget.LogicalName, ATarget, True, True);
    DAAdapter.Finalize;

    if OnlySelectedRows then
    begin
      ASource.Dataset.Filtered := False;
      ASource.Dataset.Filter := AFilter;
      if AFiltered then
        ASource.Dataset.Filtered := True;
    end;

  finally
    FreeAndNil(DABin);
    FreeAndNil(DAAdapter);
  end;
end;


end.
