clientdataset server.api.pas

clientdataset server.api.pas

复制代码
unit server.api;

/// <author>cxg 2024-12-6</author>
/// This unit surport clientdataset in client
interface

uses
  dbclient, System.IniFiles,
  SysUtils, FireDAC.Stan.StorageBin, DB, keyValue.serialize, classes, Dialogs,
  FireDAC.Comp.Client, FireDAC.Stan.Intf, IdHTTP;

var
  url: string;
  // 查询
  // dbid: 数据库帐套号
procedure qry(const dbid: string; const sqls: array of string;
  const dss: array of tdataset);
// 保存
// noSaveFields: 不要保存的字段列表,逗号分隔
procedure save(const dbid: string; const tblNames, noSaveFlds: array of string;
  const dss: array of tdataset);
// 存储过程查询
procedure spopen(const dbid, spname, params: string; ds: tdataset);
// 上传
procedure upload(const filename: string);
// 执行事务性SQL: insert,update,delete
procedure execsql(const dbid, sql: string);
// 下载
procedure download(const filename: string);
// 验证码
procedure verifyCode(var code: string; image: tstream);
// 雪花id
// datacenterid: 数据中心id
// workerid: 机器id
procedure snowflakeID(var id: int64; const datacenterid, workerid: byte);

implementation

procedure snowflakeID(var id: int64; const datacenterid, workerid: byte);
var
  s: tserialize;
  req, res: tstream;
  http: tidhttp;
begin
  s := tserialize.Create;
  req := TMemoryStream.Create;
  res := TMemoryStream.Create;
  http := tidhttp.Create(nil);
  s.asbyte['datacenterid'] := datacenterid;
  s.asbyte['workerid'] := workerid;
  s.marshal(req);
  http.Post(url + '/bin/snowflakeid', req, res);
  s.Clear;
  s.unMarshal(res);
  if s.asInt['status'] <> 200 then
    ShowMessage('fail ' + s.asStr['exception'])
  else
  begin
    id := s.asInt64['snowflakeid'];
  end;
  s.Free;
  req.Free;
  res.Free;
  http.Free;
end;

procedure verifyCode(var code: string; image: tstream);
var
  s: tserialize;
  req, res: tstream;
  http: tidhttp;
begin
  s := tserialize.Create;
  req := TMemoryStream.Create;
  res := TMemoryStream.Create;
  http := tidhttp.Create(nil);
  http.Post(url + '/bin/verifycode', req, res);
  s.unMarshal(res);
  if s.asInt['status'] <> 200 then
    ShowMessage('fail ' + s.asStr['exception'])
  else
  begin
    code := s.asStr['code'];
    image.CopyFrom(s.asStream['image']);
  end;
  req.Free;
  res.Free;
  http.Free;
end;

procedure execsql(const dbid, sql: string);
var
  s: tserialize;
  req, res: tstream;
  http: tidhttp;
begin
  s := tserialize.Create;
  req := TMemoryStream.Create;
  res := TMemoryStream.Create;
  http := tidhttp.Create(nil);
  s.asStr['dbid'] := dbid;
  s.asStr['sql'] := sql;
  s.marshal(req);
  http.Post(url + '/cds/execsql', req, res);
  s.Clear;
  s.unMarshal(res);
  if not s.asBool['ok'] then
    ShowMessage('fail ' + s.asStr['message'])
  else
    ShowMessage('ok');
  s.Free;
  req.Free;
  res.Free;
  http.Free;
end;

procedure download(const filename: string);
var
  s: tserialize;
  req, res, ms: tstream;
  http: tidhttp;
begin
  s := tserialize.Create;
  req := TMemoryStream.Create;
  res := TMemoryStream.Create;
  http := tidhttp.Create(nil);
  s.asbyte['cnt'] := 1;
  s.asStr['filename1'] := filename;
  http.Post(url + '/bin/upload', req, res);
  s.Clear;
  s.unMarshal(res);
  if s.asInt['status'] <> 200 then
    ShowMessage('fail ' + s.asStr['exception'])
  else
  begin
    ms := s.asStream['file1'];
    // 处理下载的文件
  end;
  s.Free;
  req.Free;
  res.Free;
  ms.Free;
  http.Free;
end;

procedure upload(const filename: string);
var
  s: tserialize;
  req, res, ms: tstream;
  http: tidhttp;
begin
  s := tserialize.Create;
  req := TMemoryStream.Create;
  res := TMemoryStream.Create;
  ms := TFileStream.Create(filename, fmOpenRead);
  http := tidhttp.Create(nil);
  s.asbyte['cnt'] := 1;
  s.asStr['filename1'] := extractfilename(filename);
  s.asStream['file1'] := ms;
  s.marshal(req);
  http.Post(url + '/bin/upload', req, res);
  s.Clear;
  s.unMarshal(res);
  if s.asInt['status'] <> 200 then
    ShowMessage('upload fail ' + s.asStr['exception'])
  else
    ShowMessage('upload ok');
  s.Free;
  req.Free;
  res.Free;
  ms.Free;
  http.Free;
end;

procedure spopen(const dbid, spname, params: string; ds: tdataset);
var
  s: tserialize;
  req, res, ms: tstream;
  http: tidhttp;
begin
  s := tserialize.Create;
  req := TMemoryStream.Create;
  res := TMemoryStream.Create;
  http := tidhttp.Create(nil);
  s.asStr['dbid'] := dbid;
  s.asStr['spname'] := spname;
  s.asStr['params'] := params;
  s.marshal(req);
  http.Post(url + '/bin/spopen', req, res);
  s.Clear;
  s.unMarshal(res);
  if s.asInt['status'] <> 200 then
    ShowMessage('fail ' + s.asStr['exception'])
  else
  begin
    ms := s.asStream['ds'];
    ds.DisableControls;
    TFDMemTable(ds).LoadFromStream(ms, sfBinary);
    ds.EnableControls;
  end;
  s.Free;
  req.Free;
  res.Free;
  ms.Free;
  http.Free;
end;

procedure save(const dbid: string; const tblNames, noSaveFlds: array of string;
  const dss: array of tdataset);
var
  ser: tserialize;
  req, res: tstream;
  http: tidhttp;
  i: Integer;
begin
  for i := Low(dss) to High(dss) do
  begin
    if tdataset(dss[i]).State in dsEditModes then
      tdataset(dss[i]).Post;
    if TClientDataSet(dss[i]).ChangeCount = 0 then
      Exit;
  end;
  ser := tserialize.Create;
  req := TMemoryStream.Create;
  res := TMemoryStream.Create;
  http := tidhttp.Create(nil);
  ser.asStr['dbid'] := dbid;
  ser.asbyte['count'] := High(tblNames) + 1;
  for i := 0 to High(tblNames) do
  begin
    ser.asStr['tablename' + (i + 1).ToString] := tblNames[i];
    ser.asvariant['delta' + (i + 1).ToString] := TClientDataSet(dss[i]).delta;
    ser.asStr['nonfields' + (i + 1).ToString] := noSaveFlds[i];
  end;
  ser.marshal(req);
  http.Post(url + '/cds/save', req, res);
  ser.Clear;
  ser.unMarshal(res);
  if not ser.asBool['ok'] then
  begin
    for i := 0 to High(tblNames) do
      TClientDataSet(dss[i]).CancelUpdates;
    ShowMessage('Save fail ' + ser.asStr['message']);
  end
  else
  begin
    for i := 0 to High(tblNames) do
      TClientDataSet(dss[i]).MergeChangeLog;
    ShowMessage('Save ok');
  end;
  ser.Free;
  req.Free;
  res.Free;
  http.Free;
end;

procedure qry(const dbid: string; const sqls: array of string;
  const dss: array of tdataset);
var
  ser: tserialize;
  req, res: tstream;
  http: tidhttp;
  i: Integer;
begin
  ser := tserialize.Create;
  req := TMemoryStream.Create;
  res := TMemoryStream.Create;
  http := tidhttp.Create(nil);
  ser.asbyte['count'] := High(sqls) + 1;
  ser.asStr['dbid'] := dbid;
  for i := 0 to High(sqls) do
    ser.asStr['sql' + (i + 1).ToString] := sqls[i];
  ser.marshal(req);
  http.Post(url + '/cds/select', req, res);
  ser.Clear;
  ser.unMarshal(res);
  if not ser.asBool['ok'] then
  begin
    ShowMessage('Query fail ' + ser.asStr['message']);
    Exit;
  end;
  for i := 0 to High(dss) do
  begin
    dss[i].DisableControls;
    TClientDataSet(dss[i]).Data := ser.asvariant['ds' + (i + 1).ToString];
    dss[i].EnableControls;
  end;
  ser.Free;
  req.Free;
  res.Free;
  http.Free;
end;

procedure ReadConf;
begin
  var
    ini: TIniFile := TIniFile.Create(ExtractFilePath(ParamStr(0)) +
      'client.ini');
  url := ini.ReadString('config', 'url', '');
  ini.Free;
end;

initialization

ReadConf;

end.
复制代码

 

posted @   delphi中间件  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2018-12-07 mormot事务控制
2017-12-07 非正常情况下的移动加权平均算法
2017-12-07 unigui在阿里云服务器上部署
点击右上角即可分享
微信分享提示