Arreglado un error que se producía al comprobar si un DataTable sin deltas preparados ha sido modificado.

git-svn-id: https://192.168.0.254/svn/Proyectos.LuisLeon_FactuGES/trunk@199 c93665c3-c93d-084d-9b98-7d5f4a9c3376
This commit is contained in:
roberto 2007-12-12 20:09:20 +00:00
parent 72510f75e7
commit e6e810c371

View File

@ -3,7 +3,7 @@ unit uDataTableUtils;
interface
uses
uDACDSDataTable, uDADataTable, uDAInterfaces;
uDACDSDataTable, uDADataTable, uDAInterfaces, uDADelta, uDAMemDataTable;
const
ID_NULO = -9000;
@ -19,9 +19,19 @@ function SetFieldNull(ATarget: TDADataTable; const FieldName: String): Boolean;
procedure ConectarTabla (ATarget: TDADataTable);
procedure DesconectarTabla (ATarget: TDADataTable);
procedure CopyDataTableDA5(ASource : TDADataTable; ATarget: TDADataTable;
const OnlySelectedRows : Boolean = False);
procedure CopyDataTableDA3(ASource : TDADataTable; ATarget : TDADataTable;
const OnlySelectedRows : Boolean = False);
procedure CloneDataTable(const ASource : TDACDSDataTable;
var ATarget : TDACDSDataTable;
RemoteUpdate: Boolean = True);
RemoteUpdate: Boolean = True); overload;
function CloneDataTable(const ASource : TDAMemDataTable;
RemoteUpdate: Boolean = True): TDAMemDataTable; overload;
procedure DuplicarRegistro(ASource : TDADataTable; ATarget : TDADataTable;
Const WithKey: Boolean = False);
@ -29,9 +39,6 @@ procedure DuplicarRegistros(ASource : TDADataTable; ATarget : TDADataTable;
AModo : TModoDuplicarRegistros; APermitirRepetidos: Boolean = True;
Const WithDeltas: Boolean = True; Const WithKey: Boolean = False);
procedure CopyDataTable(ASource : TDADataTable; ATarget : TDADataTable;
const OnlySelectedRows : Boolean = False);
procedure DeleteAllTable(const ADataTable : TDADataTable);
function DeltaValuesAreDifferent(const aDelta : IDADelta): boolean;
@ -48,7 +55,84 @@ implementation
uses
Classes, DB, uDAClasses, SysUtils, uDABINAdapter, uROTypes, cxControls,
Dialogs, Variants, uDBSelectionListUtils, uROClasses;
Dialogs, Variants, uDBSelectionListUtils, uROClasses, uDADataStreamer, uDABin2DataStreamer;
procedure CopyDataTableDA5(ASource : TDADataTable;
ATarget: TDADataTable;
const OnlySelectedRows : Boolean);
var
AStream : Binary;
AStream2 : Binary;
AFilter : String;
AFiltered : Boolean;
AObj : ISeleccionable;
i : Integer;
begin
AFilter := '';
AFiltered := False;
if not Assigned(ASource) then
raise Exception.Create ('No se ha asignado la tabla de origen (CopyDataTable)');
if not Assigned(ATarget) then
raise Exception.Create ('No se ha asignado la tabla de destino (CopyDataTable)');
if not ATarget.Active then
ATarget.Active := True;
if OnlySelectedRows then
begin
if not Supports(ASource, ISeleccionable, aObj) then
raise Exception.Create('El origen de datos no soporta la interfaz ISeleccionable (CopyDataTable)');
if ASource.Filtered then
begin
AFiltered := True;
AFilter := ASource.Filter;
ASource.Filtered := False;
end;
ASource.Filter := '';
if ASource.Active then
ASource.Close;
for i := 0 to AObj.SelectedRecords.Count - 1 do
begin
if (i > 0) then
ASource.Filter := ASource.Filter + ' or ';
ASource.Filter := ASource.Filter + '(ID = ' + IntToStr(AObj.SelectedRecords.Items[i]) + ')';
end;
ASource.Filtered := True;
end;
if not ASource.Active then
ASource.Open;
AStream := Binary.Create;
DesconectarTabla(ATarget);
try
ASource.SaveToStream(AStream);
AStream2 := AStream.Clone;
// ShowMessage(AStream.ToReadableString);
ATarget.LoadFromStream(AStream2); ///->>>>>>>>>>>>>>>>>>>>>>>>>>ERRORRRR
finally
FreeAndNil(AStream);
ConectarTabla(ATarget);
// Dejar el filtro de la tabla origen como estaba
if OnlySelectedRows then
begin
ASource.Filtered := False;
ASource.Filter := AFilter;
if AFiltered then
ASource.Filtered := True;
end;
end;
end;
function SetFieldNull(ATarget: TDADataTable; const FieldName: String): Boolean;
begin
@ -101,10 +185,11 @@ var
i : integer;
begin
bCambiado := False;
if Assigned(ADataTable) and (ADataTable.Active) then
begin
bCambiado := (ADataTable.State = dsEdit) or
DeltaValuesAreDifferent(ADataTable.Delta);
bCambiado :=(ADataTable.State = dsEdit) or
(ADataTable.HasDelta and DeltaValuesAreDifferent(ADataTable.Delta));
if (not bCambiado) then
begin
@ -113,7 +198,8 @@ begin
begin
bCambiado := bCambiado or
((TDADataTable(dtDetails.Items[i])).State in dsEditModes) or
DeltaValuesAreDifferent((TDADataTable(dtDetails.Items[i])).Delta);
((TDADataTable(dtDetails.Items[i])).HasDelta and
DeltaValuesAreDifferent((TDADataTable(dtDetails.Items[i])).Delta));
if bCambiado then
Break;
end;
@ -128,6 +214,81 @@ begin
ADataTable.ClearRows;
end;
function CloneDataTable(const ASource : TDAMemDataTable;
RemoteUpdate: Boolean = True): TDAMemDataTable;
var
i : Integer;
ATarget : TDAMemDataTable;
begin
if not Assigned(ASource) then
raise Exception.Create ('No se ha asignado la tabla de origen (CloneDataTable)');
ATarget := TDAMemDataTable.Create(NIL);
with ATarget do
begin
{ ATENCIÓN !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
--------------------------------------------------------------------
DA5 tiene un fallo en el cual las tablas definidas como detalle no
tienen asociados los eventos internos before... y after... por lo
que los campos AutoInc no funcionan (no pone el -1, -2...).
La forma de arreglarlo es llamar a DisableEventHandlers/EnableEventHandlers
que realiza la asociación de los eventos.
}
ATarget.DisableEventHandlers; // <--- INDISPENSABLE!!!!!!!!!!!!!!!!!!!!
try
if not Assigned(ASource.RemoteDataAdapter) then
raise Exception.Create('No está asignado RemoteDataAdapter (' + ASource.Name + ')');
LogicalName := ASource.LogicalName;
CustomAttributes.Assign(ASource.CustomAttributes);
Fields.AssignFieldCollection(ASource.Fields); // o también ATarget.LoadSchema;
Params.AssignParamCollection(ASource.Params);
RemoteDataAdapter := ASource.RemoteDataAdapter;
Randomize;
Name := ASource.Name + '_' + IntToStr(Random(MAXINT));
BusinessRulesID := ASource.BusinessRulesID;
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;
finally
ATarget.EnableEventHandlers; // <--- INDISPENSABLE!!!!!!!!!!!!!!!!!!!!!!!!!
end;
end;
if not RemoteUpdate then
begin
ATarget.LogChanges := False;
ATarget.RemoteFetchEnabled := False;
end;
Result := ATarget;
end;
procedure CloneDataTable(const ASource : TDACDSDataTable;
var ATarget : TDACDSDataTable; RemoteUpdate: Boolean);
var
@ -135,10 +296,17 @@ var
begin
with ATarget do
begin
RemoteService := ASource.GetRemoteService;
Adapter := ASource.GetAdapter;
// ****** Inicio migración DA 5
{RemoteService := ASource.GetRemoteService;
Adapter := ASource.GetAdapter;}
//BusinessRulesID := ASource.BusinessRulesID;
if not Assigned(ASource.RemoteDataAdapter) then
raise Exception.Create('No está asignado RemoteDataAdapter (' + ASource.Name + ')');
RemoteDataAdapter.Assign(ASource.RemoteDataAdapter);
// ****** Fin migración DA 5
BusinessRulesID := ASource.BusinessRulesID;
Randomize;
Name := ASource.Name + '_' + IntToStr(Random(MAXINT));
LogicalName := ASource.LogicalName;
@ -148,6 +316,8 @@ begin
if Assigned(ASource.LocalSchema) then
LocalSchema := ASource.LocalSchema
else begin
// ****** Inicio migración DA 5
{
with SchemaCall do
begin
MethodName := ASource.SchemaCall.MethodName;
@ -162,9 +332,13 @@ begin
end;
end;
end;
}
// ****** Fin migración DA 5
ATarget.Fields.AssignFieldCollection(ASource.Fields); // o también ATarget.LoadSchema;
end;
// ****** Inicio migración DA 5
{
with DataUpdateCall do
begin
MethodName := ASource.DataUpdateCall.MethodName;
@ -211,6 +385,8 @@ begin
end;
end;
end;
}
// ****** Fin migración DA 5
with MasterParamsMappings do
for i := 0 to ASource.MasterParamsMappings.Count - 1 do
@ -239,7 +415,6 @@ begin
ATarget.RemoteFetchEnabled := False;
end;
end;
function DeltaValuesAreDifferent(const aDelta : IDADelta): boolean;
var
@ -251,16 +426,7 @@ begin
begin
for x := 0 to (aDelta.LoggedFieldCount-1) do
begin
if aDelta.LoggedFieldTypes[x] <> datBlob then
begin
try
OldNewAreDifferent := (aDelta.Changes[i].OldValues[x] <> aDelta.Changes[i].NewValues[x]);
except
// Capturar cualquier tipo de excepción de conversión de tipos
on E: EVariantTypeCastError do
OldNewAreDifferent := True;
end;
end;
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.
@ -273,7 +439,7 @@ begin
end;
procedure CopyDataTable(ASource : TDADataTable; ATarget : TDADataTable;
procedure CopyDataTableDA3(ASource : TDADataTable; ATarget : TDADataTable;
const OnlySelectedRows : Boolean = False);
var
DABin: Binary;
@ -314,6 +480,7 @@ begin
DABin := Binary.Create;
DAAdapter := TDABINAdapter.Create(nil);
try
ATarget.LogicalName := ASource.LogicalName; // We need to specify new dataset LogicalName
ATarget.RemoteFetchEnabled := False; // "Desconectamos" la tabla destino del servidor
@ -322,12 +489,11 @@ begin
ASource.Open;
ASource.First;
DAAdapter.Initialize(DABin, aiWrite);
DAAdapter.WriteDataset(DABin, ASource, [woRows]);
DAAdapter.Initialize(DABin, aiReadFromBeginning);
DAAdapter.ReadDataset(DABin, ATarget);
DAAdapter.Finalize;
ATarget.RemoteFetchEnabled := True; // "Conectamos" la tabla del servidor otra vez
// Dejar el filtro de la tabla origen como estaba
@ -461,14 +627,14 @@ begin
if Assigned(ADetail) then
begin
// ¡¡¡¡¡ MUY IMPORTANTE !!!!!!!!!!!!!!!!!!
ADetail.DataTable.DisableEventHandlers;
//ADetail.DataTable.DisableEventHandlers;
try
ADetail.DataTable.MasterSource := AMasterDataSource;
finally
{ Hay que activar los eventos porque dejan de funcionar
las reglas de negocio al establecer la relación
maestro-detalle. (Fallo de Data Abstract 3) }
ADetail.DataTable.EnableEventHandlers;
//ADetail.DataTable.EnableEventHandlers;
end;
end;
end;
@ -501,5 +667,4 @@ begin
end;
end;
end.