gpt4 book ai didi

delphi - 将数据库复制到受限客户端

转载 作者:行者123 更新时间:2023-12-01 18:39:44 26 4
gpt4 key购买 nike

我创建了一个绑定(bind)应用程序。服务器需要复制一个Sqlite db并将其流式传输到客户端。

我使用以下代码获取数据库:

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;

我捕获流并使用以下代码编写数据库:

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;

所以我的问题是,如何将数据库复制到客户端然后在客户端使用它?

更好的是,如何使用内存数据库而不是磁盘数据库?我尝试将 FDConnection 文件名设置为 :memory: 但那没有工作。

德尔福CE Rio 10.3.2

谢谢...丹'l'+

最佳答案

我不认为有一种方法可以将 Sqlite 数据库完整复制到系留数据库客户端无法将整个数据库文件复制到客户端,因为它可能包含许多表和其他资源,如 View 、存储过程等。

但是,将整个数据库复制为文件实际上相当简单简单易做。在客户端中,您可以使用本地FDConnection打开其中的表和 FDQuery。

服务器代码:

procedure TApp1Form.SendDBAsStream;
var
StreamToSend : TMemoryStream;

const
DBName = 'D:\Delphi\Code\Sqlite\DB1.Sqlite';

begin
StreamToSend := TMemoryStream.Create;
try
StreamToSend.LoadFromFile(DBName);
StreamToSend.Position := 0;
TetheringAppProfile1.Resources.FindByName('SqliteDB').Value := StreamToSend;
finally
// Don't free StreamToSend ?
end;
end;

客户端代码

procedure TApp2Form.TetheringAppProfile1Resources0ResourceReceived(const Sender:
TObject; const AResource: TRemoteResource);
var
ReceivedStream : TStream;
FileStream : TFileStream;
begin
FileName := ExtractFilePath(Application.ExeName) + 'Temp.Sqlite';
AResource.Value.AsStream.Position := 0;

FileStream := TFileStream.Create(FileName, fmCreate);
ReceivedStream := AResource.Value.AsStream;
try
ReceivedStream.Position := 0;
FileStream.CopyFrom(ReceivedStream, ReceivedStream.Size);
finally
FileStream.Free;
// ReceivedStream.Free; No! The tethering framework frees the stream
end;
OpenTable;
end;

procedure TApp2Form.OpenTable;
begin
if FDConnection1.Connected then
FDConnection1.Connected := False;
FDConnection1.Params.Clear;
FDConnection1.Params.Add('Database=' + FileName);
FDConnection1.DriverName := 'Sqlite';

try
FDConnection1.Connected := True;
FDQuery1.Open('select * from mytable');
except
ShowMessage(Exception(ExceptObject).Message + ' ' + FileName);
end;
end;

我在 Win10 64 位上的 Delphi 10.2.3 中测试了上述内容,它对我来说工作得很好。

如果你只想复制几个表给客户端,我会做的是

  • 在服务器中,打开 FDQuery 中的一个表,然后将其数据分配给FDMemtable by FDMemTable1.Data := FDQ​​uery1.Data

  • 在 FDMemTable1 上调用 SaveToStream 并将流作为流资源发送到客户端

  • 在客户端,调用FDMemTable.LoadFromStream加载接收到的流。我认为,因为我还没有尝试过客户端需要包含 TFDPhysSQLiteDriverLink支持从流加载。

关于delphi - 将数据库复制到受限客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55455875/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com