You must implement this function, even if there is no such processing to perform.
Example
// You must implement ostcDisconnect, even if as a no-op
void ostcDisconnect(void)
{
}
examples/ostc/quickstart contains these two subdirectories:
This thin client uses one header file, quickstartclient.h, which declares the following classes:
All thin clients must include ostc.h:
#include <ostc.h>
The thin client uses two .cpp files:
// Main program for the client
// Must specify router host:port pair as argument
#include <stdio.h>
#include "quickstartclient.h"
int main(int argc, char ** argv)
{
...
// Set the router
ostc::addRouter(argv[1]);
...
}
#include <stdio.h>
#include "quickstartclient.h"
// Construction/Destruction
QuickStartClient::QuickStartClient()
{
// Connect to the server
_session = ostc::connect("quickstart");
}
QuickStartClient::~QuickStartClient()
{
// Disconnect from the server
ostc::disconnect(_session);
}
void QuickStartDisplay::transfer()
{
// Input from_name, to_name, and amount
...
// Call QuickStartClient::transfer()
ostc_ObjectList * result =
_client->transfer(from_name, to_name, amount);
...
// Extract the results
ostc_Object * account = 0;
account = result->first();
printf(
"%-20.15s%15f\n",
account->getStringValue("name"),
account->getFloatValue("val")
);
account = result->next();
printf(
"%-20.15s%15f\n",
account->getStringValue("name"),
account->getFloatValue("val")
);
...
}
The function returns the result in the form of a list of ostc_Objects.
ostc_ObjectList * QuickStartClient::transfer(
char * from_name,
char * to_name,
float amount
)
{
// Get the transfer operation
ostc_Operation * transfer = _session->getOperation("transfer");
if ( !transfer )
return 0;
// Set up the arguments
transfer->setArgument("from_acct_name", from_name);
transfer->setArgument("to_acct_name", to_name);
transfer->setArgument("amount", amount);
// Execute the operation without using the cache
ostc_ObjectList * result = _session->doOperation(transfer,0);
if (!result) {
return 0;
}
else {
return result;
}
}
The Server plug-in uses the following header files:
The plug-in header should include ostcsrvr.h:
#include <osctsrvr.h>
You must declare three global functions:
// Forward declarations
class ostc_ServerSession;
extern "C" {
#ifdef WIN32
__declspec( dllexport ) void ostcInitialize();
__declspec( dllexport ) void ostcConnect(ostc_ServerSession *);
__declspec( dllexport ) void ostcDisconnect(void);
#else
void ostcInitialize();
void ostcConnect(ostc_ServerSession *);
void ostcDisconnect(void);
#endif
}
This use of _declspec is required for Windows platforms.
ostcoperations.h
The Server plug-in defines one subtype of ostc_ServerOperation for each operation it supports. Here is the one corresponding to the transfer operation:
class txfer_operation : public ostc_ServerOperation
{
public:
txfer_operation(QuickStart*);
~txfer_operation() {}
void execute(ostc_Object * Arguments, ostc_OperationResult*);
void format(
const void*,
ostc_ObjectList*,
ostc_OperationResult*
);
private:
QuickStart * _app;
};
The plug-in uses the following .cpp files:
ostcInitialize() instantiates QuickStart, which instantiates the operation subtypes, opens or creates a database, and retrieves a root:
// This function is called once at server start-up
void ostcInitialize()
{
// Generate an instance of the app
if (!QuickStart::theServer)
QuickStart::theServer = new QuickStart();
}
ostcConnect() registers the operation objects with the session:
// This function is also called once at start-up.
void ostcConnect(ostc_ServerSession * session)
{
// Add the QuickStart operations to the server
QuickStart::theServer->addOperations(session);
}
ostcDisconect() performs cleanup:
// This function is called once when the server is being shut down
void ostcDisconnect(void)
{
// If we have no more connections then delete the QuickStart
if (QuickStart::theServer)
delete QuickStart::theServer;
}
This is called by ostcInitialize():
QuickStart::QuickStart()
{
// The member initialize() opens or creates db and gets root
initialize(example_db_name);
// Create all of the server operations
_addAccount = new AddAccount(this);
_withdraw = new withdraw(this);
_deposit = new deposit(this);
_balance = new balance(this);
_transfer = new txfer_operation(this);
}
This is called by ostcConnect():
// Adds Server operations to the session
void QuickStart::addOperations(ostc_ServerSession * session)
{
// Add all the operations to all servers for this service
session->addOperation(_addAccount);
session->addOperation(_withdraw);
session->addOperation(_deposit);
session->addOperation(_transfer);
session->addOperation(_balance);
}
The operation subtype constructor specifies the operation name, transaction type, and formal parameters:
txfer_operation::txfer_operation(QuickStart * app) :
ostc_ServerOperation("transfer", ostc::isolated_update)
{
// initialize
_app = app;
addArgument("from_acct_name", ostc::ostc_string);
addArgument("to_acct_name", ostc::ostc_string);
addArgument("amount", ostc::ostc_float);
addReturnSetAttribute("val", ostc::ostc_float);
addReturnSetAttribute("name", ostc::ostc_string);
}
execute() performs the operation:
void txfer_operation::execute(
ostc_Object * Arguments,
ostc_OperationResult* result
)
{
const char* from_acct_name =
Arguments->getStringValue("from_acct_name");
const char* to_acct_name =
Arguments->getStringValue("to_acct_name");
float amount =
Arguments->getFloatValue("amount");
Account * from_account = _app->getAccount(from_acct_name);
Account * to_account = _app->getAccount(to_acct_name);
_app->transfer(from_account, to_account, amount);
os_collection *new_balances =
&os_collection::create(
os_segment::get_transient_segment()
);
new_balances->insert( from_account );
new_balances->insert( to_account );
result->setReturnValue(new_balances);
}
format() formats the operation results as Ostc_Objects:
void txfer_operation::format(
const void * OSobj,
ostc_ObjectList * ostcList,
ostc_OperationResult*)
{
Account * acct = (Account*)OSobj;
ostc_Object * obj = ostcList->addObject();
obj->setValue("name", acct->getName());
obj->setValue("val", acct->getBalance());
}
The thin client in this application allows the end user to perform the following actions:
There are also administrative actions for adding and removing shows, performances, and theaters.
Then the client redisplays the menu of actions.