RSS订阅 | 匿名投稿
您的位置:网站首页 > 数据库 > 正文

delphi KBMMW SampleService/SampleClient方式传输数据集

作者:admin 来源: 日期:2018/1/16 7:36:30 人气: 标签:KBMMW

马上周末了,趁着下午这会儿回顾一下这几天对旧项目的升级过程,一些重要但不常用的东西记录下来是很有必要的。其中一个项目中对KBMMW的远程数据通讯方式做了改进,利用SampleService/SampleClient方式传输数据集,以增加对底层数据通讯的可控性。

服务端代码示例:


type
  TkbmMWSimpleService1 = class(TkbmMWSimpleService)
  private
     { Private declarations }
  protected
     { Protected declarations }
     function ProcessRequest(const Func:string; const ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant; override;
     function PerformOpenSQL(ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant; virtual;
 
  public
     { Public declarations }
{$IFNDEF CPP}class{$ENDIF} function GetFlags:TkbmMWServiceFlags; override;
  end;
 
//...省略
 
function TkbmMWSimpleService1.ProcessRequest(const Func:string; const ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant;
var
   AFunc:string;
begin
     AFunc:=UpperCase(Func);
     if AFunc='OPENSQL' then
        Result:=PerformOpenSQL(ClientIdent,Args)
     else Result:=inherited ProcessRequest(Func,ClientIdent,Args);
end;
 
function TkbmMWSimpleService1.PerformOpenSQL(ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant;
var
  sqlStr: string;
  aQuery: TUniQuery;
  aconn: TkbmMWUNIDACConnection;
  memTable: TkbmMemTable;
  aStreamFormat: TkbmBinaryStreamFormat;
begin
  Result := 0;
  sqlStr:=args[0];
  aQuery := TUniQuery.Create(nil);//uniquery,和两层的用法一样
  aQuery.Options.QueryRecCount := True;
  aconn := TkbmMWUNIDACConnection(DMunt.kbmMWUNIDACConnectionPool1.GetBestConnection(True,0,nil,10000));//取连接池中的连接
  if aconn = nil then
  begin
    kbmMWRaiseServerException('无可用的数据库连接');
    Exit;
  end;
  aQuery.Connection := aconn.Database;
  aQuery.SQL.Text := sqlStr;
  if (mainform.PAL_mode_01.Visible) then
    LogIOer.AddShow(ClientIdent.Username+'执行SQL查询:'+aQuery.SQL.Text,0);
  memTable := TkbmMemTable.Create(nil);
  aStreamFormat := TkbmBinaryStreamFormat.Create(nil);
  memTable.DefaultFormat := aStreamFormat;
  memTable.IndexFieldNames := '';
  memTable.SortFields := '';
  memTable.MasterSource := nil;
  try
    try
      aQuery.Open;//查询
      Result := aQuery.RecordCount;//返回记录条数
    except
      on E:Exception do
      begin
        kbmMWRaiseServerException(E.Message+',异常语句:'+aQuery.SQL.Text);//抛异常到客户端
        Exit;
      end;
    end;
    memTable.LoadFromDataSet(aQuery,[mtcpoStructure,mtcpoProperties]); //复制数据集进KbMemTable
    memTable.SaveToStreamViaFormat(ResultStream,aStreamFormat); //按照指定流格式存入结果流ResultStream
  finally
    aconn.UnlockConnection;
    aQuery.Free;
    memTable.Free;
    aStreamFormat.Free;
  end;
end;
客户端代码:


function openSql(Sqlstr:string;var Ds:TDataSet;var Rs:string):integer;stdcall;
  var
    args: array[0..1] of Variant;
  begin
    Result := 0;
    Rs := '执行成功';
    if assigned(kbmMWSimpleClient1) then
    begin
      try
        args[0]:= Sqlstr;//SQL语句
        Result := kbmMWSimpleClient1.Request('TkbmMWSimpleService1','','openSql',args);//SimpleClient执行请求
        kbmMemTable.EmptyTable;//清空内存表
        kbmMemTable.LoadFromStreamViaFormat(kbmMWSimpleClient1.ResultStream,aStreamFormat);//将结果流复制进内存表
        ds := kbmMemTable;//返回dataset(kbmMemTable继承自Tdataset)
      except
        on E:Exception do
        begin
          Result := -1;
          rs := errorInfo(E.Message);
          if FIsLog then Writelog(rs);
        end;
      end;
    end
    else
    begin
      Result := -1;//未执行初始化操作
      Rs := '远程数据通讯接口未执行初始化操作'
    end;
  end;
核心代码就这些,相信用到的人能够看明白。同理,可以利用这种方式实现二进制文件流(如:图像等)的传输,不再赘述。
另外,有一个小问题折磨了我一下午,提醒大家一下,希望大家不要像我一样粗心:
有两个类:TkbmBinaryStreamFormat(kbmMemBinaryStreamFormat.pas)、TkbmMWBinaryStreamFormat(kbmMWBinaryStreamFormat.pas)很容易混淆(正确用法见上述代码),而且一旦混淆,会造成KbmMeMTable在流的处理过程中出错。

来源:http://www.pfeng.org/archives/385

读完这篇文章后,您心情如何?
0
0
0
0
0
0
0
0
本文网址:
下一篇:没有资料