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.