Hello,
few minutes ago I tried to create datatables from scratch, by reading stored content from stream, using handy function uDADataTable.DatatableFromStream, and I discovered a problem… function always fails during processing subsequent calls, exactly inside of TDADelta.Create constructor, see call stack:
:757c1d4d KERNELBASE.RaiseException + 0x48
uDADelta.TDADelta.Create('',False)
uDADelta.TDADelta.Create($2C979F0)
uDADataTable.TDADataTable.InitializeDataTable
uDADataTable.TDADataTable.DoOpen(???)
uDAMemDataTable.TDAMemDataTable.DoOpen(???)
uDADataTable.TDADataTable.Open
uDADataTable.TDADataTable.Dataset_Open
uDABin2DataStreamer.TDABin2DataStreamer.DoReadDataset('TEST_DATA',TDAMemDataTable($2C97C70) as IDADataset,???,False)
uDADataStreamer.TDADataStreamer.ReadDataset('TEST_DATA',TDAMemDataTable($2C97C70) as IDADataset,True,True,False)
uDADataStreamer.TDADataStreamer.ReadDataset(???,TDAMemDataTable($2C97C70) as IDADataset,True,'TEST_DATA',True,True,False)
uDADataTable.DatatableFromStream($2D239E0,???,$2C890B0,'TEST_DATA')
fmSample.TfrmSample.Button1Click($2CA0140)
The reason is clear… new instance of TDADataTable, created on-fly at begin of DatatableFromStream method has no LogicalName assigned…
There are two usable solutions:
1/ modify code of DatatableFromStream method, in this way:
function DatatableFromStream(aStream : TStream;
aDataTableClass : TDADataTableClass;
anAdapter : TDADataAdapter;
const aDatasetName : string = '') : TDADataTable;
begin
result := aDataTableClass.Create(nil);
result.RemoteFetchEnabled := False;
// >> set LogicalName before reading data from stream
result.LogicalName := aDataSetName;
anAdapter.ReadDataset(aStream, result, True, aDatasetName);
result.First;
end;
…this solutions works only if aDataSetName parameter has value, in other cases… the problem remains.
2/ modify code of TDADataStreamer.ReadDataSet mehod, something like this:
procedure TDADataStreamer.ReadDataset(Stream: TStream;
const Destination: IDADataset;
ApplySchema: boolean = FALSE;
DatasetName: string = '';
LoadRecords: boolean = TRUE;
ReadFromBeginning: boolean = TRUE;
AppendMode: Boolean = False);
var
nme: string;
begin
if ReadFromBeginning then
Initialize(Stream, aiReadFromBeginning)
else
Initialize(Stream, aiRead);
try
if (DatasetName = '') then
nme := DatasetNames[0]
else
nme := DatasetName;
// >> ensure that Destination dataset has non-empty LogicalName
if Destination.LogicalName='' then
Destination.LogicalName := nme;
ReadDataset(nme, Destination, ApplySchema, LoadRecords,AppendMode);
finally
Finalize;
end;
end;
I attached small testcase, where mentioned poblem can be raised, observed, traced…
Greetings from Prague,
Jaroslav
daSample.zip (80.9 KB)