Creating a Rich-Client Interface (InterBase Tutorial)
Go Up to Tutorial: Using an InterBase Database in a Delphi or C++ Application
Now we create a client that uses the server. The client exercises both functions of the server:
- Call a stored procedure and return a value.
- Display and update data in a database table.
Here is a view of the client application's form with the components we will be adding:
The visual components that you interact with are on the left side of the form. The nonvisual components you use to access the database are on the right side.
Follow these steps to create the client application.
- To create the client application in the same project group as the server application, right-click the name of the project group in the Project Manager and select Add New Project or choose Project > Add New Project.
- The New Items dialog box appears.
- For Delphi, select the Delphi category, then select Windows VCL Application.
- For C++Builder, select the C++Builder category, then select Windows VCL Application.
- Click OK. Select the new form and set its Caption property to "Client demo" in the Object Inspector. Choose File > Save All to save the files:
- For Delphi, save the unit as Un_client_main.pas. Save the project as ClientDemo.dproj.
- For C++, save the unit as Un_client_main.cpp. Save the project as ClientDemo.cbproj.
- Now run the server that you built in the previous section. Double-click ServerDemo.exe in the Project Manager. Choose Run > Run Without Debugging to run it. You can minimize the ServerForm dialog that appears.
- Place a TSQLConnection component on the new form and set its properties:
- Set the Driver property to "DataSnap". In Object Inspector, click on the
+
on the left of the Driver property to display additional properties:- Set Port to "211" (default).
- Set HostName to "localhost" (default).
- These properties can also be set by changing the Params property. Click on the ellipsis (...) button in the Params property to display the Value List Editor. You can enter property values in this dialog, then click OK to set the values.
- Set LoginPrompt to false to prevent the user name and password dialog appearing every time the client connects to the server
- Set Connected true
- While the server is running, right-mouse click on the TSQLConnection and select Generate DataSnap Client classes from the context menu. This action creates a new unit. Save the newly generated unit, which contains the client classes.
- For Delphi, save the unit as Un_client_classes.pas.
- For C++, save the unit as Un_client_classes.cpp.
- Save the changes to Un_client_main.
- Link the Un_client_classes unit to Un_client_main.
- For Delphi, click on the Un_client_main tab, click its Code tab, then add Un_client_classes to Un_client_main's
uses
clause. - For C++, click on the Un_client_main.cpp tab at the top of the Code Editor, then click on the Un_client_main.cpp tab at the bottom of the Code Editor. Add the following include after the other includes in Un_client_main.cpp:
- Now start building the interface described in the figure above. In the Un_client_main client, click the Design tab and drag components from the Tool Palette onto the form to the positions indicated in the figure above:
- A TDBNavigator control to navigate through the database.
- A TDBGrid control to view a database table.
- Three TButtons to load the database table, update database data and call the stored procedure. Set the corresponding TButton's Captions to "Load R/W", "Apply updates" and "Get project" as shown in the figure.
- A TEdit control for the employee number. Change its Text property to blank.
- A TLabel control to show the project ID.
- Add the database components that access the database's stored procedure and connect these components to each other.
- Place a TSqlServerMethod component on the form.
- Set the SQLConnection property to "SQLConnection1" from the drop-down menu.
- Set the ServerMethodName property. When the server is running, you can use the property's drop-down menu to see all the server methods available. Select "TDSServerModule1.callStoredProcedure", which is the function in the server that calls the stored procedure.
- Do not set Active to true. If you do, you get an error message, because the stored procedure does not return a dataset.
- Drag a TDataSetProvider onto the form.
- Set the DataSet property to "SQLServerMethod1" from the drop-down menu.
- Place a TClientDataSet on the form.
- Set the ProviderName property to "DataSetProvider1" from the drop-down menu.
- Drag a TDataSource onto the form.
- Set its DataSet property to "ClientDataSet1" from the drop-down menu.
- Add the database components for read/write access to the dataset.
- Drag a TDSProviderConnection onto the form. This provider component gives us the ability to freely navigate through and resolve database updates.
- Set the SQLConnection property to "SQLConnection1" from the drop-down menu.
- Set the ServerClassName property to "TDSServerModule1".
- Place another TClientDataSet on the form.
- Set the RemoteServer property to "DSProviderConnection1" from the drop-down menu.
- Set the ProviderName property to "ServerDataSetProvider1" from the drop-down menu.
- Drag another TDataSource onto the form.
- Set its DataSet property to "ClientDataSet2" from the drop-down menu.
- Connect the TDBGrid and TDBNavigator to the data source by setting both components' DataSource property to "DataSource2".
- Test the connections.
- Set the ClientDataSet2 TClientDataSet's Active property to true. The TDBGrid component should become active, displaying the database's EMPLOYEE table's data.
- Set ClientDataSet2's Active property back to false. The client application will set ClientDataSet2 true to activate the database connection in the event handler we add next.
- Add the click event for the "Load R/W" TButton. Select this TButton. In the Events tab of the Object Inspector, double-click the
OnClick
event to generate skeleton code. Add one line to activate the TClientDataSet in the event handler: - Similarly, add the
OnClick
event handler for the "Apply updates" TButton. Create the skeleton for the event handler as above and add this code: - The parameter for
ApplyUpdates
is the number of errors to tolerate, zero in this case. - Set up for calling the stored procedure.
- Create an event handler skeleton for the "Get project" TButton's
OnClick
event. Clicking this TButton results in calling the method we defined on the server. Since the stored procedure takes an integer value, we need to convert the text in the employee number TEdit to an integer. Here is the event handler code that does this: - Notice that the preceding code sets the Caption of the TLabel to the value returned from calling the stored procedure: the project ID.
- Select File > Save All to save all the files.
- Get database information from the EMPLOYEE_PROJECT table.
- Build and run the client side of the project.
- Build the client project by right-clicking ClientDemo in the Project Manager and selecting Build. Fix any errors.
- Run the client application. The following dialog appears:
- Click the "Load R/W" TButton, which activates the "ClientDataSet2" TClientDataSet. The TDBGrid gets populated with entries from the EMPLOYEE table. The TDBNavigator control is also active, allowing you to navigate through the table entries.
- You can select a cell in the TDBGrid and change its value. Clicking the "Apply updates" TButton would update the database table with the change.
- Finally, test the stored procedure. Enter one of the valid employee numbers in the TEdit control and click the "Get project" TButton. The caption of the label below the TButton should change to the appropriate project ID from the EMPLOYEE_PROJECT table:
#include "Un_client_classes.h"
After you have placed the components, move and resize them as needed.
Delphi
procedure TForm2.Button3Click(Sender: TObject);
begin
ClientDataSet2.Active := true;
end;
C++
void __fastcall TForm2::Button1Click(TObject *Sender)
{
ClientDataSet2->Active = true;
}
Delphi
procedure TForm2.Button4Click(Sender: TObject);
begin
ClientDataSet2.ApplyUpdates(0);
end;
C++
void __fastcall TForm2::Button2Click(TObject *Sender)
{
ClientDataSet2->ApplyUpdates(0);
}
Delphi
procedure TForm2.Button1Click(Sender: TObject);
var
mykey : Integer; //variable to hold text from edit box
myServer : TDSServerModule1Client; //server proxy we will call
begin
mykey := StrToInt(Edit1.Text); //conversion to integer
SQLConnection1.Open;
// Server creation using the SQLConnection for communication
myServer := TDSServerModule1Client.Create(SQLConnection1.DBXConnection);
try
// Calling method that calls the stored procedure with the key.
// Set label to value returned from stored procedure.
Label1.Caption := myServer.callStoredProcedure(mykey);
finally
if SQLConnection1.Connected then
SQLConnection1.Close;
myServer.Free; //free up the server
end;
end;
C++
void __fastcall TForm2::Button3Click(TObject *Sender)
{
int mykey; //variable to hold text from edit box
TDSServerModule1Client *myServer; //server proxy we will call
mykey = StrToInt(Edit1->Text); //conversion to integer
SQLConnection1->Open();
// Server creation using the SQLConnection for communication
myServer = new TDSServerModule1Client(SQLConnection1->DBXConnection);
try
{
// Calling method that calls the stored procedure with the key.
// Set label to value returned from stored procedure.
Label1->Caption = myServer->callStoredProcedure(mykey);
}
__finally
{
if (SQLConnection1->Connected)
SQLConnection1->Close();
delete myServer; //free up the server
}
}
Before running the client application, we need to get information from a database table. In Data Explorer, open the INTERBASE connection entry, then open the EMPLOYEE connection under it. Under this connection, open Tables. Right-click EMPLOYEE_PROJECT and select View to display that table's data:
Make note of some of the values listed in the EMP_NO column. The stored procedure we are using, GET_EMP_PROJ, accesses the EMPLOYEE_PROJECT table. We need to know some valid employee numbers to retrieve data from this table using that stored procedure.
This completes the client running as an application.