Author: Jim T1392
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 |
---|
|
|
|
|
Getting Started with Delphi DataSnap 2009 uses the following function as an example of a server method:
1 2 3 4 |
function TDSServerModule1.Echo(s: string): string;<br> begin<br> Result := 'Delphi DataSnap 2009 is echoing ' + s + ' ....' + s;<br> end; |
The proxy generator generates the following code to call this method:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function TDSServerModule1Client.Echo(s: string): string;<br> begin<br> if FEchoCommand = nil then<br> begin<br> FEchoCommand := FDBXConnection.CreateCommand;<br> FEchoCommand.CommandType := TDBXCommandTypes.DSServerMethod;<br> FEchoCommand.Text := 'TDSServerModule1.Echo';<br> FEchoCommand.Prepare;<br> end;<br> FEchoCommand.Parameters[0].Value.SetWideString(s);<br> FEchoCommand.ExecuteUpdate;<br> Result := FEchoCommand.Parameters[1].Value.GetWideString;<br> 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:
1 2 3 4 5 6 7 8 9 10 |
{$METHODINFO ON}<br> TTestBasicType = class(TComponent)<br> function Echo(I: T): T;<br> end;<br> {$METHODINFO OFF}<br> <br> function TTestBasicType.Echo(I: T): T;<br> begin<br> Result := I;<br> end; |
The I used TTestBasicType used to declare and implement “Echo” methods for a variety of types, such as string, boolean, and double:
1 2 3 4 5 6 7 8 |
TTestString = class(TTestBasicType<string>))<br> end;<br> <br> TTestBoolean = class(TTestBasicType<Boolean>)<br> end; <br> <br> TTestDouble = class(TTestBasicType<Double>))<br> end; |
To test parameters directions, I expanded the generic class with var and out parmeters:
1 2 3 4 5 6 7 |
{$METHODINFO ON}<br> TTestBasicType = class(TComponent)<br> function Echo(I: T): T;<br> procedure Copy(I: T; out J: T);<br> procedure Swap(var I: T; var J: T);<br> end;<br> {$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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
TTestBooleanClient = class<br> private<br> FDBXConnection: TDBXConnection;<br> FInstanceOwner: Boolean;<br> FEchoCommand: TDBXCommand;<br> FCopyCommand: TDBXCommand;<br> FSwapCommand: TDBXCommand;<br> public<br> constructor Create(ADBXConnection: TDBXConnection);overload;<br> constructor Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean); overload;<br> destructor Destroy; override;<br> function Echo(I: Boolean): Boolean;<br> procedure Copy(I: Boolean; out J: Boolean);<br> procedure Swap(var I: Boolean; var J: Boolean);<br> end; |
Here is the implementation of TTestBooleanClient.Echo. Consult the sample code to see the complete proxy implementation.
1 2 3 4 5 6 7 8 9 10 11 |
function TTestBooleanClient.Echo(I: Boolean): Boolean;<br> begin<br> if FEchoCommand = nil then<br> begin FEchoCommand := FDBXConnection.CreateCommand;<br> FEchoCommand.CommandType := TDBXCommandTypes.DSServerMethod;<br> FEchoCommand.Text := 'TTestBoolean.Echo';<br> FEchoCommand.Prepare;<br> end; FEchoCommand.Parameters[0].Value.SetBoolean(I);<br> FEchoCommand.ExecuteUpdate;<br> Result := FEchoCommand.Parameters[1].Value.GetBoolean;<br> 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.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition