Jump to content
GreatDayDan

Copy Sqlite DB to tethered app

Recommended Posts

I have created a tethered app. The server needs to copy a Sqlite db and stream it to the client.

I get the db with this code:

procedure TfmxServer.actStreamTheDbExecute(Sender: TObject);
var
  ms: TMemoryStream;
begin
  ms := tmemorystream.Create;
  ms := dmplanner.GetDbAsStream;  // get it from the datamodule
  ms.Position := 0;
  thrprofServer.SendStream(thrmanServer.RemoteProfiles.First,
          'Stream_TheDB', ms);  // send it to the client
end;


function TdmPlanner.GetDbAsStream: TMemoryStream;  // datamodule
var
  fs: TFilestream;
  ms: TMemoryStream;
begin
  fs := tfilestream.Create(consqlite.Params.Values['Database'] , fmOpenRead);
  ms := tmemorystream.Create;
  try
   ms.loadfromstream(fs); // ms.size = 315392, file size = (315,392 bytes
   result := ms;               // so I am getting the full db3 file.
   result.Position := 0;
  finally
   freeandnil(fs);
   freeandnil(ms); // does this kill the result?
  end;
end;

I catch the stream and to write the db with this code:

procedure TfrmMobile_Client_Main.DoStreamTheDb(
  const Aresource: TremoteResource);
var
  fs: TFilestream;
  ms: TMemoryStream;
begin
  fs := tfilestream.Create
    (dmplannerclient.consqlite.Params.Values['Database'] ,
    fmopenreadwrite or fmCreate);
  try
   ms := TMemoryStream.Create;
   ms := TMemoryStream(AResource.Value.AsStream);
   ms.Position := 0;    // ms.size = 315392, so I got the whole file.
   ms.SaveToStream(fs);
  dmPlannerClient.FillLbx(lbxRecipeNames);
  // now fill a listbox, but when I open a query, I get
  //  [FireDAC][Phys][SQLite] ERROR: unable to open database file.
  finally
   freeandnil(fs);
   freeandnil(ms);
  end;
end;

So my question is, How do I copy the db to the client and then use it on the client?

Better yet, How do I an in-memory db instead of an on-disk db? I have tried setting the FDConnection filename to :memory: but that did not work.

Delphi CE Rio 10.3.2

Thanks...Dan'l' +

Share this post


Link to post

Sorry, TLDR.

 

These lines are a little doubtful to me.

ms := TMemoryStream.Create;

//<-- This is overwriting the formerly created TMemoryStream.
ms := dmplanner.GetDbAsStream;  

I would expect some kind of CopyStream here.

Share this post


Link to post
Quote

These lines are a little doubtful to me.

Seems to be taken from:

https://stackoverflow.com/questions/55455875/copy-database-to-tethered-client

 

The manual creation of the Stream leads to a memory leak.

 

I would prefer the stream as inputvar.

Quote

How do I copy the db to the client and then use it on the client?

 ms.SaveToStream(fs);

Should write it to the client.

Share this post


Link to post
On 4/1/2019 at 2:11 PM, GreatDayDan said:

Better yet, How do I an in-memory db instead of an on-disk db? I have tried setting the FDConnection filename to :memory: but that did not work.

You can use FDMemTables, they can load and save from streams, files and other datasets. 

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

×