Jim Tierney

DataSnap Server Methods Parameters

Delphi 2009 introduced support for DataSnap server methods. If you are not familiar with this feature, here are two articles that describe server methods: DataSnap 2009 Overview , Getting Started with Delphi DataSnap 2009.

DataSnap server methods support a variety of parameter and return types. The following list shows the types grouped into my own categories. 

This post is about "Basic" types.  The sample client and server projects that go with this post can be downloaded here: http://cc.codegear.com/item/26702

Basic DBXValue Collection Connection
  • AnsiString
  • Boolean
  • Currency
  • TDateTime
  • TDBXDate
  • TDBXTime
  • Double
  • Int64
  • Integer
  • LongInt
  • OleVariant
  • Single
  • SmallInt
  • WideString
  • TDBXAnsiStringValue
  • TDBXAnsiCharsValue
  • TDBXBcdValue
  • TDBXBooleanValue
  • TDBXConnectionValue
  • TDBXDateValue
  • TDBXDoubleValue
  • TDBXInt16Value
  • TDBXInt32Value
  • TDBXInt64Value
  • TDBXReaderValue
  • TDBXSingleValue
  • TDBXStreamValue
  • TDBXStringValue
  • TDBXTimeStampValue
  • TDBXTimeValue
  • TDBXWideCharsValue
  • TDBXWideStringValue
  • TDBXReader
  • TDataSet
  • TParams
  • TStream
  • TDBXConnection

Getting Started with Delphi DataSnap 2009 uses the following function as an example of a server method:

function TDSServerModule1.Echo(s: string): string;
begin
 Result := 'Delphi DataSnap 2009 is echoing ' + s + ' ....' + s;
end;

The proxy generator generates the following code to call this method:

function TDSServerModule1Client.Echo(s: string): string;
begin
  if FEchoCommand = nil then
   begin
     FEchoCommand := FDBXConnection.CreateCommand;
     FEchoCommand.CommandType := TDBXCommandTypes.DSServerMethod;
     FEchoCommand.Text := 'TDSServerModule1.Echo';
     FEchoCommand.Prepare;
   end;
   FEchoCommand.Parameters[0].Value.SetWideString(s);
   FEchoCommand.ExecuteUpdate;
   Result := FEchoCommand.Parameters[1].Value.GetWideString;
end;

I wanted my sample server and client to work like the sample in the article, with simple server methods and  generated proxy in the client.  In addition, I wanted to support various types so started with this generic server method implementation:

{$METHODINFO ON}
 TTestBasicType = class(TComponent)
     function Echo(I: T): T;
 end;
{$METHODINFO OFF}

 function TTestBasicType.Echo(I: T): T;
 begin
   Result := I;
 end;

The I used TTestBasicType used to declare and implement "Echo" methods for a variety of types, such as string, boolean, and double:

TTestString = class(TTestBasicType<string>))
end;

TTestBoolean = class(TTestBasicType<Boolean>)
end; 

TTestDouble = class(TTestBasicType<Double>))
end;

To test parameters directions, I expanded the generic class with var and out parmeters:

{$METHODINFO ON}
TTestBasicType = class(TComponent)
  function Echo(I: T): T;
  procedure Copy(I: T; out J: T);
  procedure Swap(var I: T; var J: T);
end;
{$METHODINFO OFF}

Consult the sample server to see how I’ve implemented the "plumbing" to make these classes callable by a DataSnap client. The implementation is unconventional because the TDSServerClass component is not used.

The sample VCL client is built starting with a TSQLConnection component. After setting the port and host name, I right clicked on the TSQLConnection and selected "Generate DataSnap client classes" to generate a client proxy:

In the generated code, there is a "Client" class for every one of the server classes. For example, TTestBooleanClient calls the TTestBoolean class on the server:

TTestBooleanClient = class
private
  FDBXConnection: TDBXConnection;
  FInstanceOwner: Boolean;
  FEchoCommand: TDBXCommand;
  FCopyCommand: TDBXCommand;
  FSwapCommand: TDBXCommand;
public
  constructor Create(ADBXConnection: TDBXConnection);overload;
  constructor Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean); overload;
  destructor Destroy; override;
  function Echo(I: Boolean): Boolean;
  procedure Copy(I: Boolean; out J: Boolean);
  procedure Swap(var I: Boolean; var J: Boolean);
end;

Here is the implementation of TTestBooleanClient.Echo.  Consult the sample code to see the complete proxy implementation.  

function TTestBooleanClient.Echo(I: Boolean): Boolean;
begin
 if FEchoCommand = nil then
 begin FEchoCommand := FDBXConnection.CreateCommand;
   FEchoCommand.CommandType := TDBXCommandTypes.DSServerMethod;
   FEchoCommand.Text := 'TTestBoolean.Echo';
   FEchoCommand.Prepare;
 end; FEchoCommand.Parameters[0].Value.SetBoolean(I);
 FEchoCommand.ExecuteUpdate;
 Result := FEchoCommand.Parameters[1].Value.GetBoolean;
end;

The sample client tests the generated methods by calling them with sample values and verifying the results. Consult the sample for implementation details.

Here is screen shot of the running server and client:

 

The following table shows the parameter types and return types demonstrated in the sample client and server:

Type (in) var out Result
AnsiString X     X
Boolean X X X X
Currency X X X X
TDateTime X X X X
DBXDate X X X X
DBXTime X X X X
Double X X X X
Int64 X X X X
Integer X X X X
LongInt X X X X
OleVariant X X X  
Single X X X X
SmallInt X X X X
String X     X
WideString X     X

There are some Delphi types that you might expect to see in this list such as Byte and Cardinal. DataSnap currently doesn’t support these two nor LongWord, ShortInt, Word, TSQLTimeStamp, and TBcd. Support for var and out strings is coming (a workaround/alternative is to use TDBXStringValue in place of var String and TDBXAnsiStringValue in place of var AnsiString).

Thats all for now. I plan to cover more types in the future.

Posted by Jim Tierney on February 13th, 2009 under DataSnap, Delphi |



6 Responses to “DataSnap Server Methods Parameters”

  1. Robert H Says:

    Jim, most interesting and very valuable post.

    Many thanks

    Robert

  2. Paweł Głowacki : Delphi Workshop in Belgium Last Week Says:

    [...] applications. In fact: any client/server applications in Delphi 2009 that communicate over TCP/IP. DataSnap 2009 extends capabilities of DBX4 framework introduced in Delphi 2007. The last demo was to create a [...]

  3. jz labour Says:

    Dear Sir.

    When I run the application on my machine,there is an error messagebox on the client side,whitch tells me that : ”1/1/2000 12:01:01” is not a valid date and time.

    Why……..?

  4. Jim Tierney Says:

    jz,

    The string passed to StrToDateTime doesn’t match your locale.

    Change these lines:

    LValue1 := StrToDateTime(’1/1/2000 12:01:01′);
    LValue2 := StrToDateTime(’12/31/1999 11:02:02′);

    To

    LValue1 := EncodeDateTime(2000, 1, 1, 12, 1, 1, 0);
    LValue2 := EncodeDateTime(1999, 12, 31, 11, 2, 2, 0);

  5. Jim Tierney » DataSnap Server Method DBXValue Parameters Says:

    [...] server method parameters and return types. This is my second post on this subject, following DataSnap Server Method Parameters. The previous post was about "Basic" types. This post is about "Basic DBXValue" types.  The sample [...]

  6. Jim Tierney » Call DataSnap Server Methods with Delphi Prism Says:

    [...] This client has nearly the same functionality as the Delphi client described in this post: DataSnap Server Methods Parameters.  The difference is that the Delphi Prism client isn’t able to call server methods with [...]

Leave a Comment



Server Response from: blog2.codegear.com