Jump to content
Sign in to follow this  
Alberto Fornés

Persist data in a stream

Recommended Posts

     Hello, in a data exchange between vcl clients and a REST server, I have implemented a method to save the data in a stream, that stream I send to the client and it loads the data in a reverse process. I do this to reduce the information to be sent as much as possible and I do not directly use a SaveToStream of the table, query or stored procedure. The information of the fields I read from the IFDDataSetReference interface, and I have a problem when saving the blob fields, the procedure worked with Delphi 10.3 but with Delphi 10.4 there is something different that I cannot guess (I have a professional version and I do not have access to the FireDac code ) . The abbreviated code for the procedure is: 

 

//iData = IFDDataSetReference
//FieldData = array of Fields
ab: TArray<Byte>;
bd: AnsiString;
nl: Int64;

var ADest:= TMemoryStream.Create;
var wr:= TBinaryWriter.Create(ADest,TEncoding.UTF8,false);
 for i:= 0 to iData.DataView.Rows.Count - 1 do
  begin
   for c:= Low(FieldData) to High(FieldData) do
    begin
     //when blob field I do this
      begin
       //ValueI is a variant
       bd:= iData.DataView.Rows[i].ValueI[c]; //bd value is not the same in Delphi 10.3 as in Delphi 10.4
       ab:= TEncoding.ANSI.GetBytes(bd);
       nl:= Length(ab);
       wr.Write(nl);
       wr.Write(ab);
      end;
    end;  
  end;

 

In client side I can read de stream with:

 

ADest: TFDMemTable;

nl:= sR.ReadInt64;
if (nl = 0) then
 begin
  ADest.Fields[c].AsBytes:= nil;
 end else
 begin
  ADest.Fields[c].AsBytes:= sR.ReadBytes(nl);
 end; 

 

Edited by Alberto Fornés
Added more info

Share this post


Link to post

    I expand the information, doing more tests I have verified that it is not a problem associated with Delphi 10.3 vs Delphi 10.4, I made that statement because I have two computers, one with Delphi Rio and the other with Delphi Sydney, but installing Delphi 10.3 on the other computer I have verified that the problem is due to the computer (Windows 10 in both cases). Any suggestions on any pc configuration that might motivate this? 

Share this post


Link to post
Guest

Don't have an answer, but some thoughts here

 

1) You control these two devices, so why not log the problem input then compare, just log i,c and bd , this should give you a great insight.

2) Where did the data come from ? is it same DB or by mistake you have two different DB, compare the source.

3) "bd value is not the same in Delphi 10.3 as in Delphi 10.4" is not enough, does bd have meaningful data or something unreadable ? are bd value is from different fields ?

 

Hope that helps.

Share this post


Link to post
8 hours ago, Kas Ob. said:

Don't have an answer, but some thoughts here

 

1) You control these two devices, so why not log the problem input then compare, just log i,c and bd , this should give you a great insight.

2) Where did the data come from ? is it same DB or by mistake you have two different DB, compare the source.

3) "bd value is not the same in Delphi 10.3 as in Delphi 10.4" is not enough, does bd have meaningful data or something unreadable ? are bd value is from different fields ?

 

Hope that helps.

 

 Hello Kas Ob, thanks for you reply. As I said in second message the problem is not related to Delphi version, is related to computer where I execute the program. The DB is the same, I attach a small demo with the esential part of code where I can verify the error. When I open the program a TFDMemTable with different fields defined is open, I add a record with some values and use the add image button to load a blob field (in this case bitmap image included in sample code, that you can see on picture) :

 

create_table.thumb.png.c3759d8bc686b15e7d3df47807d20af0.png

 

 When Save Table button is pushed the data and some table metadata is used to fill a stream that can be saved in a file, although you can use de load table button to fill a second TFDMemTable with this stream, and assign the dataource to this dataset, in this case and in a certain computer the image is not readed correctly (in other blob cases this is an error):

 

load_table.thumb.png.551b33e5fed7ab2f54a29e2da0119a06.png

 

 If you want to load the stream from saved file, push load stream button and then load table). The same program in other computer (it doesn't matter Delphi 10.3 or Delphi 10.4) works well, so I think it's a pc configuration that I can't guess.

 

Stream_Sample_2.zip

Edited by Alberto Fornés
Sample code was incorrect

Share this post


Link to post
Guest

Well, now we need someone has the tools to help !

 

I don't have the latest versions of Delphi, and never used i used FireDac, so i am sorry i am not a help here, but i can un-notice this this in the code which looks wrong, (still i might be wrong)

....
      dtAnsiString,
      dtWideString:begin
                    ns:= 3;
                    wr.Write(ns);
                    ns:= iData.DataView.Table.Columns[c].Size; //  <-   This is is undefied value for Tipo
                    wr.Write(ns);
                   end;
           dtBlob :begin
                    ns:= 4;
                    wr.Write(ns);
                   end;
...
     end;
     FieldData[c].Tipo:= ns;  // <- !!!??

 

Share this post


Link to post

Finally I found how to solve the problem on the computer that was failing (only 24 days have passed!). Unchecking this option (in beta) from the regional settings. Does anyone know how the system identifies that a program is unicode or not? 

 

 

check_utf8_beta_3.png

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×