mOrmot 服务端 方法 代码载录

/// some common definitions shared by both client and server side

unit ServerIntf;

interface

uses
  SynCommons, mORMot;


type
  TRemoteSQLEngine = (rseOleDB, rseODBC, rseOracle, rseSQlite3, rseJet, rseMSSQL, resMySQL);
  IRemoteSQL = interface(IInvokable)
   ['{051C8EC8-921D-4248-88E8-489E3B869F50}']
    function Execute(const aSQL: RawUTF8; aExpectResults, aExpanded: Boolean): RawJSON;
    //执行多条语句
    function MulExecute(const QSQL: TRawUTF8DynArray; aExpectResults: Boolean): Boolean;
  end;
  ICalculator = interface(IInvokable)
    ['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}']
    function Add(a, b: integer): integer;
    function GetQuery(vData :RawUTF8): RawUTF8;
  end;
  IQueryData = interface(IInvokable)
   ['{B1793EB7-764D-4B8E-8012-BA13D188493A}']
    function GetQueryReslt(vData: RawUTF8): RawUTF8;
    //function ExecSql(SqlStr: string): RawUTF8;
  end;
const
  ROOT_NAME = 'root';
  PORT_NAME = '888';
  APPLICATION_NAME = 'RestService';

implementation

initialization
  // so that we could use directly ICalculator instead of TypeInfo(ICalculator)
  TInterfaceFactory.RegisterInterfaces([TypeInfo(ICalculator)]);
  TInterfaceFactory.RegisterInterfaces([TypeInfo(IQueryData)]);
  TInterfaceFactory.RegisterInterfaces([TypeInfo(IRemoteSQL)]);
end.






unit ServerMethod;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, ServerIntf, Dialogs,
  SynCommons, SynLog, mORMot, mORMotDB, mORMotHttpServer, SynDB,
  SynDBZeos, DB;    

type       

  TServiceCalculator = class(TInterfacedObject, ICalculator)
  public
    function Add(a, b: integer): integer;
    function GetQuery(vData: RawUTF8): RawUTF8;
  end;


  TServiceQueryData = class(TInterfacedObject, IQueryData)
  public
    function GetQueryReslt(vData: RawUTF8): RawUTF8;
  end;


  TServiceRemoteSQL = class(TInterfacedObject, IRemoteSQL)
  public
    // constructor Create;
    destructor Destroy; override;
    function GetTableNames: TRawUTF8DynArray;
    function Execute(const aSQL: RawUTF8; aExpectResults, aExpanded: Boolean): RawJSON;
    //执行多条语句
    function MulExecute(const QSQL: TRawUTF8DynArray; aExpectResults: Boolean): Boolean;
    function DataSetToJSON(Data: TDataSet; const RecNo:Integer=0): RawUTF8;
  end;


  TConnDataSQL = class
  protected
    fProps: TSQLDBConnectionProperties;
    // fServer: TSQLDBServerSockets;
  public
    constructor Create;
    destructor Destroy; override;
    function GetDBConnectionProperties: TSQLDBConnectionProperties;
  end;


var
  Pub_ConnDataSQL: TConnDataSQL;


implementation

uses uSysCFG;



function TConnDataSQL.GetDBConnectionProperties: TSQLDBConnectionProperties;
begin
  Result := fProps;
end;


destructor TConnDataSQL.Destroy;
begin
  FreeAndNil(fProps);
  inherited;
end;


constructor TConnDataSQL.Create;
const
  MYSQL_CONSTR = 'zdbc:mysql://%s:%d/%s?username=%s;password=%s;LibLocation=ht.dll';
var
  constr, dbserver, dbdatabase, dbusername, dbpassword: string;
  dbport: Integer;
begin
  // 连接数据库
  dbserver := IniOptions.dbServer;
  dbdatabase := IniOptions.dbDatabase;
  dbusername := IniOptions.dbUserName;
  dbpassword := IniOptions.dbPassword;
  dbport := IniOptions.dbPort;
  constr := Format(MYSQL_CONSTR, [dbserver, dbport, dbdatabase, dbusername, dbpassword]);
  try
    fProps := TSQLDBZEOSConnectionProperties.Create(constr, '', '', '');
  except
    raise Exception.Create('数据连接失败,请检数据库查配置参数!');
  end;
  // fServer := TSQLDBServerSockets.Create(fProps, 'myserver', '8192', 'user', 'psw');
  // Connect(rseODBC,'127.0.0.1:3306','mysql5.6','root','1234567');
  // Connect(rseMSSQL,'zhy\sql2008','jxtestdataytnew','sa','sql');
end;

function TServiceCalculator.Add(a, b: integer): integer;
begin
  result := a + b;
end;


function TServiceCalculator.GetQuery(vData: RawUTF8): RawUTF8;
begin
  result := StringToUTF8(vData + '<錦------------錦>' + vData);
end;


function TServiceQueryData.GetQueryReslt(vData: RawUTF8): RawUTF8;
begin
  result := vData + '--錦--' + vData;
end;


function TServiceRemoteSQL.DataSetToJSON(Data: TDataSet; const RecNo:Integer=0): RawUTF8;
var
  W: TJSONWriter;
  f: integer;
  blob: TRawByteStringStream;
begin
  result := 'null';
  if Data = nil then
    exit;
  if (RecNo = 0) then
    Data.First;
  if Data.Eof then
    exit;
  W := TJSONWriter.Create(nil, true, false);
  try
    // get col names and types
    SetLength(W.ColNames, Data.FieldCount);
    for f := 0 to high(W.ColNames) do
      StringToUTF8(Data.FieldDefs[f].Name, W.ColNames[f]);
    W.AddColumns;
    if (RecNo=0) then
      W.Add('[');
    repeat
      W.Add('{');
      for f := 0 to Data.FieldCount-1 do begin
        W.AddString(W.ColNames[f]);
        with Data.Fields[f] do
        if IsNull then
          W.AddShort('null') else

        case DataType of
        ftBoolean:
          W.Add(AsBoolean);
        ftSmallint, ftInteger, ftWord, ftAutoInc:
          W.Add(AsInteger);
        ftLargeint:
          W.Add(TLargeintField(Data.Fields[f]).AsLargeInt);
        ftFloat, ftCurrency: // TCurrencyField is sadly a TFloatField
          W.Add(AsFloat,TFloatField(Data.Fields[f]).Precision);
        ftBCD:
          W.AddCurr64(AsCurrency);
        //ftFMTBcd:
          //AddBcd(W,AsBCD);
        ftTimeStamp, ftDate, ftTime, ftDateTime: begin
          W.Add('"');
          W.AddDateTime(AsDateTime);
          W.Add('"');
        end;
        ftString, ftFixedChar, ftMemo: begin
          W.Add('"');
          W.AddAnsiString({$ifdef UNICODE}AsAnsiString{$else}AsString{$endif},
            twJSONEscape);
          W.Add('"');
        end;
        ftWideString: begin
          W.Add('"');
          W.AddJSONEscapeW(pointer(TWideStringField(Data.Fields[f]).Value));
          W.Add('"');
        end;
        ftVariant:
          W.AddVariant(AsVariant);
        ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob: begin
          blob := TRawByteStringStream.Create;
          try
            (Data.Fields[f] as TBlobField).SaveToStream(blob);
            W.WrBase64(pointer(blob.DataString),length(blob.DataString),true);
          finally
            blob.Free;
          end;
        end;
        {$ifdef ISDELPHI2007ANDUP}
        ftWideMemo, ftFixedWideChar: begin
          W.Add('"');
          W.AddJSONEscapeW(pointer(AsWideString));
          W.Add('"');
        end;
        {$endif}
        {$ifdef UNICODE}
        ftShortint, ftByte:
          W.Add(AsInteger);
        ftLongWord:
          W.AddU(TLongWordField(Data.Fields[f]).Value);
        ftExtended:
          W.Add(AsFloat,DOUBLE_PRECISION);
        ftSingle:
          W.Add(AsFloat,SINGLE_PRECISION);
        {$endif}
        else W.AddShort('null'); // unhandled field type
        end;  // case
        W.Add(',');
      end;  // for

      W.CancelLastComma;
      W.Add('}',',');
      if (RecNo=0) then Data.Next else break;
    until (Data.Eof);
    
    W.CancelLastComma;
    if (RecNo=0) then
      W.Add(']');
    W.SetText(result);
  finally
    W.Free;
  end;
end;


function TServiceRemoteSQL.Execute(const aSQL: RawUTF8; aExpectResults,
  aExpanded: Boolean): RawJSON;
var
  res: ISQLDBRows;
  fProps: TSQLDBConnectionProperties;
begin
    fProps := Pub_ConnDataSQL.GetDBConnectionProperties;
    if fProps=nil then
    begin
      raise Exception.Create('Connect call required before Execute');
    end;
    res := fProps.ExecuteInlined(aSQL, aExpectResults);
    if res=nil then
      result := ''
    else
      result := res.FetchAllAsJSON(aExpanded);
end;


function TServiceRemoteSQL.GetTableNames: TRawUTF8DynArray;
var
  fProps: TSQLDBConnectionProperties;
begin   
    fProps := Pub_ConnDataSQL.GetDBConnectionProperties;
    if fProps=nil then
      raise Exception.Create('Connect call required before GetTableNames');
    fProps.GetTableNames(result);   
end;


destructor TServiceRemoteSQL.Destroy;
begin
  inherited;
end;


function  TServiceRemoteSQL.MulExecute(const QSQL: TRawUTF8DynArray;
  aExpectResults: Boolean): Boolean;
var
  i: Integer;
  newCon: TSQLDBConnection;
  fProps: TSQLDBConnectionProperties;
  query: TQuery;
begin
   Result := True;
  try  
    fProps := Pub_ConnDataSQL.GetDBConnectionProperties;
    if fProps = nil then
      raise Exception.Create('Connect call required before Execute');
    newCon := fProps.ThreadSafeConnection;
    if not newCon.Connected then  newCon.Connect;
    query := TQuery.Create(newCon);
    try
      newCon.StartTransaction;
      for I := Low(QSQL) to High(QSQL) do
      begin
        with query do
        begin
          Close;
          SQL.Clear;
          SQL.Add(QSQL[i]);
          Open;
        end;
      end;
      newCon.Commit;
    except
      newCon.Rollback;
      Result := False;
    end;
  finally
    FreeAndNil(query);
  end;
end;


end.

转载于:https://my.oschina.net/u/582827/blog/1619981

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值