Commands sample (console) (Delphi)
The Commands sample demonstrates executing remote schema commands from a client application that will insert, update and delete a record from a table in an instance of Relativity Server. The sample also demonstrates using DA SQL to selectively retrieve data from the schema table.
Getting Started
The sample is located in C:\Users\Public\Documents\RemObjects Samples\Data Abstract for Delphi\Commands (Console)
.
To build it, you will need Delphi Rad Studio, and like all the samples provided with Data Abstract for Delphi you will need to be running Relativity Server with the DASamples
Domain and the Simple
Schema available.
Included with the sample is a uLogSupport
class which has a LogTable
procedure that takes an instance of TDADataTable and creates a nicely formatted string representation of the table that it then prints to the Console which can be useful for debugging purposes. (An example of its output can be seen at the end of this document)
Running the Sample
When run the sample sets up a connection to an instance of Relativity Server and logs in (Step 1). It then creates a collection of DataParameter
s that are passed to the server along with the command name to execute to insert a new row into the table, after printing the result of the command a DA SQL statement is used to retrieve the new row from the Clients
table (Step 2). The values in a number of the DataParameter
s are updated and passed to the server to update the values there using the update command (Step 3). Finally the Id
value from the new row is used to delete the new row from the table using the delete command (Step 4).
Examining the Code
All of the code can be found in the uCommands
source file. The "Clients
" schema table used in this sample is comprised of 10 fields, which this sample will limit to just 4 using DA SQL when it retrieves the new row from the server.
Looking at the Commands
Before stepping through the code, we shall take a detour and use Schema Modeler to examine that commands that are used in the following sections. If you open Relativity Admin Tool, navigate to the Simple
schema and press the "Open in Schema Modeler" button. This opens Schema Modeler with the selected schema. There you can see a folder titled "Commands" which contains all of the commands that are available in this schema.
Each command's name describes the table it affects and what the action is to ensure that is no confusion. Clicking the disclosure triangle beside the command name allows you to drill down into the details of the command; including the parameters that the command takes and the statement object that defines the mapping between the schema table and the database table.
In the figure below you can see that the Clients_DELETE
command takes a single parameter OLD_ClientId
and uses a custom SQL statement that uses that parameter to try and match against the table's Id
field and then delete that table from the Agents
table (The Clients
schema table is mapped to the Agents
database table)
Next we shall look at using the commands.
Using the INSERT command
Before we can execute the Clients_INSERT
command, we need to create an array of DataParameter objects that match the parameters defined for the command in the schema. Each DataParameter is comprised of a Name
that must match one of the parameter names, and a Value
object that we want to set the data to. If you fail to provide one of the parameters defined in the schema then a null
value will instead be inserted for that parameter in the database table.
The array of parameters is passed to the Execute function of TDARemoteCommand, along with the name of the command we want to execute as a string; here "Clients_INSERT
". The Execute function will return an integer value which indicates if the command was successfully executed (It returns a 1) or if it failed (It returns a 0).
Note that if you supply an invalid command name or parameter name then an exception will be thrown and should be handled as appropriate.
Having executed the command, the sample then uses DA SQL to retrieve the newly added row, passing in a pre-created SQL
select statement along with some of the values assigned to the newly created row to the FillWithDASql function of TDARemoteDataAdapter. The ClientId
of the newly created row is extracted from the table and stored for later use.
Lastly the newly retrieved table is printed to the console so you can see that the command was successfully executed.
daSQL = 'SELECT ClientId, ClientName, ClientPhone, ClientNotes FROM Clients '+
'WHERE ClientName = ''%s'' AND ClientEmail = ''%s'' AND ClientPassword = ''%s''';
... snipped code ...
Log('STEP 2. Call command for adding a new client row ...');
ldp:= DataParameterArray.Create;
{0}lp := ldp.Add; lp.Name := UTF8Encode('ClientName');lp.Value := 'Jane C.';
{1}lp := ldp.Add; lp.Name := UTF8Encode('ClientDiscount');lp.Value := 0.01;
{2}lp := ldp.Add; lp.Name := UTF8Encode('ClientEmail');lp.Value := 'test@gmail.com';
{3}lp := ldp.Add; lp.Name := UTF8Encode('ClientPassword');lp.Value := 'temp';
{4}lp := ldp.Add; lp.Name := UTF8Encode('ClientBirthdate');lp.Value := EncodeDate(1973,6,1);
{5}lp := ldp.Add; lp.Name := UTF8Encode('ClientPhone');lp.Value := 'Unknown yet';
{6}lp := ldp.Add; lp.Name := UTF8Encode('ClientPostalCode');lp.Value := '???';
{7}lp := ldp.Add; lp.Name := UTF8Encode('ClientAddress');lp.Value := 'Somewhere in Texas...';
{8}lp := ldp.Add; lp.Name := UTF8Encode('ClientNotes');lp.Value := 'Added by command';
lResultExCommand := lCommand.Execute('Clients_INSERT',ldp);
Log('Done with result: '+IntToStr(lResultExCommand));
lRemoteDataAdapter.FillWithDASql(lTable,Format(daSQL,[
ldp[0].Value, //ClientName
ldp[2].Value, //
ldp[3].Value]),
nil);
lClientID :=lTable.FieldByName('ClientId').asInteger;
LogTable(ltable);
Using the UPDATE command
In this step a number of the fields in the previously created DataParameterArray
are updated with new values, two of the parameters are deleted, and an additional one is added which is the ClientID
we retrieved at the end of the previous step.
As before the array of parameters is passed to the Execute function of the TDARemoteCommand, this time with the command name Clients_UPDATE
. A result of 1 is returned if the command was successful and a 0 if it failed.
Note that if you supply an invalid command name or parameter name then an exception will be thrown and should be handled as appropriate.
To show the record was correctly updated, we again use FillWithDASql of TDARemoteDataAdapter to retrieve a table with only the specific record. The SQL SELECT
statement is slightly different this time around, using the lClientId
we retrieved at the end of Step 2.
daSQL1 = 'SELECT ClientId, ClientName, ClientPhone, ClientNotes FROM clients WHERE clientid = %d';
... snipped code ...
Log('STEP 3. Call command for modification client row ...');
ldp[0].Value := 'Jane Colins'; // ClientName
ldp[1].Value := 0.05; //ClientDiscount
ldp[2].Value := 'janec@gmail.com'; //ClientEmail
ldp[3].Value := 'djCkU'; //ClientPassword
ldp[5].Value := '(095) 636-19-63'; //ClientPhone
ldp[7].Value := '4935 Oliver Street Weatherford, TX 76086'; //ClientAddress
ldp[8].Value := 'Updated by command'; //ClientNotes
// remove unneeded parameters
ldp.Delete(6);//ClientPostalCode
ldp.Delete(4);//ClientBirthdate
lp := ldp.Add; lp.Name := UTF8Encode('OLD_ClientId');lp.Value := lClientID;
lResultExCommand := lCommand.Execute('Clients_UPDATE',ldp);
Log('Done with result: '+IntToStr(lResultExCommand));
lRemoteDataAdapter.FillWithDASql(lTable,Format(daSQL1,[lClientID]),nil);
LogTable(ltable);
Using the DELETE command
To delete a record from the Clients
table, the sample uses the Execute function passing the name of the delete command (Clients_DELETE
) as well as an array that contains only the previously retrieved ClientID
value. The DataParameterArray
from earlier is reused, however its contents are first cleared before adding a single DataParameter that is required as an argument by the schema's Clients_DELETE
command.
This time, when FillWithDASql is called, the table returned will be empty as the row has been deleted.
daSQL1 = 'SELECT ClientId, ClientName, ClientPhone, ClientNotes FROM clients WHERE clientid = %d';
... snipped code ...
Log('STEP 4. Call command for removing client row ...');
ldp.Clear;
lp := ldp.Add; lp.Name := UTF8Encode('OLD_ClientId');lp.Value := lClientID;
lResultExCommand := lCommand.Execute('Clients_DELETE',ldp);
Log('Done with result: '+IntToStr(lResultExCommand));
lRemoteDataAdapter.FillWithDASql(lTable,Format(daSQL1,[lClientID]),nil);
LogTable(ltable);
Log('Done!');
Using DA SQL to retrieve data
Data Abstract provides a technology called DA SQL that allows you to execute an SQL
statement against the schema data rather than directly against the backend table.
To use it create a string that contains the SQL
clause you wish to use. Then call the FillWithDASql function passing in the TDADataTable that will contain the table data as the first argument, then the DA SQL statement as the second argument, and finally an optional array of DataParameter objects that would be needed for arguments to the DA SQL
statement.
This sample uses DA SQL 3 times to (try and) retrieve the newly added record from the Clients
table.
daSQL1 = 'SELECT ClientId, ClientName, ClientPhone, ClientNotes FROM clients WHERE clientid = %d';
... snipped code ...
lRemoteDataAdapter.FillWithDASql(lTable,Format(daSQL1,[lClientID]),nil);
Example Output
This is an example of the output you will see when the sample is run. You can see in Step 2 the table contains only the newly added row (thanks to using DA SQL to selectively retrieve data). Then in Step 3 that the values for the ClientName
, ClientPhone
and ClientNotes
fields have been updated. Finally as the row is deleted in Step 4, the DA SQL statement fails to find a matching row, so the resultant table is empty.
Commands
:Commands sample has been started.
Target URL is http://localhost:7099/bin
RO SDK layer is configured.
RO DataAbstract layer is configured.
STEP 1: Login to DataService
Connecting to Relativity server: http://localhost:7099/bin
Login string is :
User Id="simple";Password="simple";Domain="DASamples";Schema="Simple"
Login has been successfull. Going further...
STEP 2. Call command for adding a new client row ...
Done with result: 1
Table: Data (1 rows from 1)
--------------------------------------------------------------------------
| ClientId | ClientName | ClientPhone | ClientNotes |
--------------------------------------------------------------------------
| 26 | Jane C. | Unknown yet | Added by command |
--------------------------------------------------------------------------
STEP 3. Call command for modification client row ...
Done with result: 1
Table: Data (1 rows from 1)
--------------------------------------------------------------------------
| ClientId | ClientName | ClientPhone | ClientNotes |
--------------------------------------------------------------------------
| 26 | Jane Colins | (095) 636-19-63 | Updated by command |
--------------------------------------------------------------------------
STEP 4. Call command for removing client row ...
Done with result: 1
Table: Data (0 rows from 0)
--------------------------------------------------------------------------
| ClientId | ClientName | ClientPhone | ClientNotes |
--------------------------------------------------------------------------
--------------------------------------------------------------------------
Done!
Cleanup!
Press ENTER to continue...