#include "stdafx.h" #include #include #include "TSServer.h" #include "TSField.h" /* * Global Error status functions. */ static int TSErrorCode = TS_OK; void TSSetLastError( int errorCode ) { TSErrorCode = errorCode; } int TSGetLastError() { return TSErrorCode; } void TSClearLastError() { TSSetLastError( TS_OK ); } /* * Methods for the Schema class. */ TSSchema::~TSSchema() { fieldList.EmptyAndDestroyList(); } TSObject* TSSchema::NewObject() { return new TSSchema; } TSObject* TSSchema::Duplicate() { TSSchema* obj = new TSSchema(); obj->tableId = tableId; obj->name = name; obj->userDefinedFields = userDefinedFields; fieldList.Duplicate( &obj->fieldList ); return obj; } // Copy the contents of obj into this. void TSSchema::Copy( TSObject* obj ) { TSSchema* sch = ( TSSchema* ) obj; tableId = sch->tableId; name = sch->name; sch->fieldList.Copy( &fieldList ); } TSString TSSchema::StringDump( int /*recursive*/, TSString indentation ) { char tmp[24]; TSString s = indentation; s += "tableId = "; sprintf( tmp, "%ld", tableId ); s += tmp; s += "\n"; s += indentation; s += "name = "; s += name; s += "\n"; if ( userDefinedFields ) { s += "Has User Defined Fields\n"; } else { s += "Does Not Have User Defined Fields\n"; } return s; } int TSSchema::SocketString( TSString &/*str*/ ) { // Not needed for a schema since it's a client side only // object. return TS_ERROR; } /* * * Methods for the Server class. * */ TSServer::TSServer() : protocolString ( "" ), serverName ( "" ), directoryName ( "" ), dllName ( "" ), portNumber ( 0 ), proxyString ( "" ), authString ( "" ), dllWebAddress ( "" ), errorMsg ( "" ), schemaCache ( ) { } TSServer::~TSServer() { schemaCache.EmptyAndDestroyList(); } const char* TSServer::GetLastErrorMessage() { if ( errorMsg.Length() == 0 ) return NULL; else return errorMsg.GetBuffer(); } int TSServer::Connect( const char* userName, const char* password, const char* serverAddress, const char* proxyAddress /*=NULL*/ ) { int len; char delim; char* host; char* hostptr; const char* from; char szBuffer[1024]; // Some basic error checking if ( userName == NULL || *userName == '\0' ) { errorMsg = "No username specified."; TSSetLastError( TS_INVALID_USER ); return TS_INVALID_USER; } if ( password == NULL ) { errorMsg = "No password specified."; TSSetLastError( TS_INVALID_USER ); return TS_INVALID_USER; } if ( serverAddress == NULL || *serverAddress == '\0' ) { errorMsg = "No server address specified."; TSSetLastError( TS_ERROR ); return TS_ERROR; } // Copy the server address, stripping of leading and trailing spaces // and changing backslashes to forward slashes, uppercase to lowercase host = (char*)malloc( strlen( serverAddress ) + 1 ); from = serverAddress; hostptr = host; while ( *from && iswspace( *from ) ) from++; while ( *from && !iswspace( *from ) ) { if ( *from == '\\' ) { *hostptr++ = '/'; from++; } else { *hostptr++ = tolower( *from++ ); } } *hostptr = '\0'; hostptr = host; // Strip protocol if ( strncmp( hostptr, "http://", 7 ) == 0 ) { protocolString = "http"; portNumber = 80; hostptr += 7; } else if ( strncmp( host, "https://", 8 ) == 0 ) { protocolString = "https"; portNumber = 443; hostptr += 8; } else { protocolString = "http"; portNumber = 80; } // Strip server name len = strcspn( hostptr, ":/" ); if ( len == 0 ) { errorMsg = "No server address specified."; TSSetLastError( TS_ERROR ); return TS_ERROR; } delim = hostptr[len]; hostptr[len] = '\0'; serverName = hostptr; hostptr += len; if ( delim != '\0' ) { hostptr++; } // Strip the port number if ( delim == ':' ) { len = strcspn( hostptr, "/" ); if ( len != 0 ) { delim = hostptr[len]; hostptr[len] = '\0'; int nTmpPort = atol( hostptr ); if ( nTmpPort > 0 ) { portNumber = nTmpPort; } hostptr += len; if ( delim != '\0' ) { hostptr++; } } } directoryName = "tmtrack"; dllName = "tmtrack.dll?"; len = strlen( hostptr ); if ( len > 0 ) { // Get the directory and dll names char* cp; // If the last character is a question mark or slash, strip it off cp = &hostptr[ len - 1 ]; if ( *cp == '?' || *cp == '/' ) { len--; hostptr[ len ] = '\0'; } // if a dll is specified if ( ( len > 4 ) && ( strcmp( &hostptr[ len - 4 ], ".dll" ) == 0 ) ) { // Strip off the dll name cp = strrchr( hostptr, '/' ); if ( cp == NULL ) { // No more slashes, rest of string must be the dll dllName = hostptr; directoryName = ""; } else { dllName = &cp[1]; *cp = '\0'; // rest of string must be directory name directoryName = hostptr; } dllName += "?"; } else { directoryName = hostptr; } } free( host ); if ( proxyAddress != NULL ) { proxyString = proxyAddress; } TSString authentication; authentication = userName; authentication += ":"; authentication += password; authString = "Authorization: Basic "; authString += EncodePassword( authentication.GetBuffer()); sprintf( szBuffer, "%s://%s:%d/%s/%s", protocolString.GetBuffer(), serverName.GetBuffer(), portNumber, directoryName.GetBuffer(), dllName.GetBuffer() ); dllWebAddress = szBuffer; int result = ValidateVersion(); if ( result != TS_OK ) { // 0 is a version failure. if ( result == 0 ) { TSSetLastError( TS_INVALID_VERSION ); return TS_INVALID_VERSION; } else // < 0 is another kind of error; { TSSetLastError( result ); return result; } } return result; } TSSocket* TSServer::OpenSocket() { // Clear out the error message string before we get started errorMsg = ""; TSSocket* socket = new TSSocket; if ( socket == NULL ) { errorMsg = "Error allocating memory for socket."; TSSetLastError( TS_MEMORY_ERROR ); return NULL; } if ( !socket->Create( protocolString.GetBuffer(), directoryName.GetBuffer(), dllName.GetBuffer(), authString.GetBuffer(), proxyString.GetBuffer() ) ) { errorMsg = "Socket Create failed."; TSSetLastError( TS_SOCKET_CREATE_FAILED ); delete socket; return NULL; } if ( !socket->Connect( serverName.GetBuffer(), portNumber )) { errorMsg = "Socket Connect failed."; TSSetLastError( TS_SOCKET_CONNECT_FAILED ); delete socket; return NULL; } return socket; } TSString TSServer::EncodePassword( const char* password ) { TSString out; unsigned char buf[3]; int idx = 0; static char base64Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; while ( *password ) { buf[idx++] = *password++; if ( idx == 3 ) { // Output the 4 encoded bytes out += base64Table[buf[0] >> 2]; // first 6-bits of byte 0 out += base64Table[((( buf[0] & 0x03 ) << 4 )) | ( buf[1] >> 4 )]; // last 2-bits of byte 0 + first 4-bits of byte 1 out += base64Table[((( buf[1] & 0x0f ) << 2 )) | ( buf[2] >> 6 )]; // last 4-bits of byte 1 + first 2-bits of byte 2 out += base64Table[buf[2] & 0x3f]; // last 6-bits of byte 2 idx = 0; } } // Special case handling of last 1 or 2 characters if ( idx == 1 ) { out += base64Table[buf[0] >> 2]; // first 6-bits of byte 0 out += base64Table[(( buf[0] & 0x03 ) << 4 )]; // last 2-bits of byte 0 out += "=="; // == pad } else if ( idx == 2 ) { out += base64Table[buf[0] >> 2]; // first 6-bits of byte 0 out += base64Table[((( buf[0] & 0x03 ) << 4 )) | ( buf[1] >> 4 )]; // last 2-bits of byte 0 + first 4-bits of byte 1 out += base64Table[(( buf[1] & 0x0f ) << 2 )]; // last 4-bits of byte 1 out += "="; // = pad } return out; } int TSServer::BuildFieldList( int tableId, TSFieldList &fieldList ) { TSSchema* schema = GetSchema( tableId ); if ( schema == NULL ) return TS_ERROR; schema->fieldList.Duplicate( &fieldList ); return TS_OK; } TSSchema* TSServer::GetSchema( int tableId ) { TSSchema* schema; TSPosition* pos = schemaCache.GetFirst(); while( pos ) { schema = ( TSSchema* ) schemaCache.GetAt( pos ); if ( schema->tableId == tableId ) { return schema; } pos = schemaCache.GetNext(pos); } // Must not have found the schema for this record type. // Send a message to the server to retrieve it. schema = new TSSchema; schema->tableId = tableId; int result; TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return NULL; } s = "Func=ReadSchema&Params="; TSEncodeInt( tableId, params ); s += params; if ( !Send( socket, s )) return (0); socket->ReceiveInt( &result ); if ( !result ) { delete schema; delete socket; return NULL; } // Receive the id, name and count. int count; int id; TSString name; socket->ReceiveInt( &id ); socket->ReceiveString( &schema->name ); socket->ReceiveInt( &schema->userDefinedFields ); socket->ReceiveInt( &count ); TSField* field; for( int ii = 0; ii < count; ii++ ) { field = new TSField(); field->ReceiveSchema( socket ); schema->fieldList.AddTail( field ); } delete socket; schemaCache.AddHead( schema ); return schema; } int TSServer::Send( TSSocket* socket, const char* str ) { int code; if( socket->Send( str, strlen(str) ) == SOCKET_ERROR ) { TSSetLastError( TS_SOCKET_WRITE_ERROR ); return FALSE; } if ( !socket->GetHttpStatusCode( code ) || code != 200 ) { char errmsg[32]; TSSetLastError( TS_SERVER_ERROR ); sprintf( errmsg, "Server Error: %d", code ); errorMsg = errmsg; return FALSE; } // The stuff coming across the socket looks like: // retCode, "errorMsg", result (s) // We are pulling out the retCode and errorMsg and leaving // the result(s) for the function that called Send. // If Send returns DB_ERRWITHRESULTS ( ==1 ), errorMsg // should be set and can be retrieved with GetLastErrorMessage() int retCode; int nReturn = socket->ReceiveInt( &retCode ); if ( nReturn != TS_OK ) { char errmsg[80]; TSSetLastError( TS_SERVER_ERROR ); sprintf( errmsg, "Failure to receive return code: %d", nReturn ); errorMsg = errmsg; return FALSE; } nReturn = socket->ReceiveString( &errorMsg ); if ( nReturn != TS_OK ) { char errmsg[80]; TSSetLastError( TS_SERVER_ERROR ); sprintf( errmsg, "Failure to receive return message: %d", nReturn ); errorMsg = errmsg; return FALSE; } if ( !retCode ) { TSSetLastError( TS_SERVER_ERROR ); } return retCode; } /******************************************************************** DATA ACCESS FUNCTIONS ********************************************************************/ int TSServer::AddField( TSRecord* field, int tableId, int fieldType, int& fieldId ) { // This function will add a record to the FIELDS table. The // tableId parameter will be used to set the TS_TABLEID field // in the new record. There is no need to set this value before // passing it into this function. // The return value is a TS_xxx error code. // NOTE: A return of TS_OK does not necessarily indicate a success // ALWAYS check the fieldId. // The fieldId will be 0 if failed, otherwise it's the TS_ID // for the new FIELDS table record. int result = 0; fieldId = 0; // Set the tableid in the record result = field->SetInt( "tableid", tableId ); if ( result != TS_OK ) { return result; } TSString s, params; TSSocket* socket = OpenSocket(); if( socket == NULL ) { return TSGetLastError(); } s = "Func=AddField2&Params="; TSEncodeInt( fieldType, params ); s += params; field->SocketString( params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } socket->ReceiveInt( &result ); fieldId = result; delete socket; return TS_OK; } int TSServer::AddRecord( TSRecord* rec, TSRecord* newRecord /*=NULL*/ ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=AddRecord&Params="; TSEncodeInt( rec->tableId, params ); s += params; TSEncodeInt( rec->fieldType, params ); s += params; rec->SocketString( params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int id; socket->ReceiveInt( &id ); if( newRecord != NULL ) { newRecord->Receive( socket ); } else { TSRecord dummy( rec->tableId, this ); dummy.fieldType = rec->fieldType; dummy.Receive( socket ); } delete socket; return TS_OK; } int TSServer::DeleteRecord( int tableId, int id ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=DeleteRecord&Params="; TSEncodeInt( tableId, params ); s += params; TSEncodeInt( id, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); delete socket; if ( !result ) { TSSetLastError( TS_ERROR ); return TS_ERROR; } return TS_OK; } int TSServer::CreateIndex( int tableId, TSList *columnNames, const char *indexName) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } if( columnNames == NULL || indexName == NULL ) { delete socket; return TS_ERROR; } s = "Func=CreateIndex&Params="; TSEncodeInt( tableId, params ); s += params; TSEncodeInt( columnNames->Length(), params); s += params; for( TSPosition *pos = columnNames->GetFirst() ; pos != NULL; pos = columnNames->GetNext( pos ) ) { TSString *columnName = (TSString*)columnNames->GetAt( pos ); if( columnName ) { TSEncodeString( *columnName, params ); s += params; } } TSEncodeString( indexName, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); delete socket; if ( !result ) { TSSetLastError( TS_ERROR ); return TS_ERROR; } return TS_OK; } int TSServer::DeleteIndex( int tableId, const char *indexName) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=DeleteIndex&Params="; TSEncodeInt( tableId, params ); s += params; TSEncodeString( indexName, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); delete socket; if ( !result ) { TSSetLastError( TS_ERROR ); return TS_ERROR; } return TS_OK; } int TSServer::GetConnectionInfo( char** dsn, char** databaseName, char** serverName ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=GetConnectionInfo&Params="; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { TSSetLastError( TS_ERROR ); delete socket; return TS_ERROR; } TSString tmpStr; socket->ReceiveString( &tmpStr ); *dsn = new char[tmpStr.Length()+1]; if ( *dsn == NULL ) { TSSetLastError( TS_MEMORY_ERROR ); return TS_MEMORY_ERROR; } strcpy( *dsn, tmpStr.GetBuffer() ); tmpStr = ""; socket->ReceiveString( &tmpStr ); *databaseName = new char[tmpStr.Length()+1]; if ( *databaseName == NULL ) { TSSetLastError( TS_MEMORY_ERROR ); return TS_MEMORY_ERROR; } strcpy( *databaseName, tmpStr.GetBuffer() ); tmpStr = ""; socket->ReceiveString( &tmpStr ); *serverName = new char[tmpStr.Length()+1]; if ( *serverName == NULL ) { TSSetLastError( TS_MEMORY_ERROR ); return TS_MEMORY_ERROR; } strcpy( *serverName, tmpStr.GetBuffer() ); delete socket; return TS_OK; } int TSServer::GetConnectionInfo( char* dsn, char* databaseName, char* serverName) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=GetConnectionInfo&Params="; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { TSSetLastError( TS_ERROR ); delete socket; return TS_ERROR; } TSString tmpStr; socket->ReceiveString( &tmpStr ); strcpy( dsn, tmpStr.GetBuffer() ); tmpStr = ""; socket->ReceiveString( &tmpStr ); strcpy( databaseName, tmpStr.GetBuffer() ); tmpStr = ""; socket->ReceiveString( &tmpStr ); strcpy( serverName, tmpStr.GetBuffer() ); delete socket; return TS_OK; } int TSServer::GetDbInfo( int infoType, void* out ) { if ( out == NULL ) return TS_ERROR; TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=GetDbInfo&Params="; TSEncodeInt( infoType, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } switch ( infoType ) { case TS_DBINFO_VERSION: case TS_DBINFO_EXPIRATIONDATE: case TS_DBINFO_ROOTPROJECTID: case TS_DBINFO_ROOTFOLDERID: case TS_DBINFO_OBJECTVERSION: case TS_DBINFO_DBMSVER: socket->ReceiveInt(( int * ) out ); break; case TS_DBINFO_EXITURL: case TS_DBINFO_ROOTPROJECTNAME: case TS_DBINFO_DBMSNAME: *(( TSString * ) out ) = ""; socket->ReceiveString(( TSString * ) out ); break; default: break; } delete socket; return TS_OK; } int TSServer::GetInt( int tableId, const char* columnName, int recId, int* result ) { TSString s, params; TSSocket* socket = OpenSocket(); if( socket == NULL ) { return TSGetLastError(); } s = "Func=GetInt&Params="; TSEncodeInt( tableId, params ); s += params; TSEncodeString( columnName, params ); s += params; TSEncodeInt( recId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } socket->ReceiveInt( result ); delete socket; if ( !result ) { TSSetLastError( TS_ERROR ); TSSetLastError( TS_ERROR ); return TS_ERROR; } return TS_OK; } int TSServer::GetString( int tableId, const char* columnName, int recId, char** result ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=GetString&Params="; TSEncodeInt( tableId, params ); s += params; TSEncodeString( columnName, params ); s += params; TSEncodeInt( recId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } TSString tmpStr; socket->ReceiveString( &tmpStr ); if ( tmpStr.Length() > 0 ) { *result = new char[tmpStr.Length() + 1]; if ( *result == NULL ) { TSSetLastError( TS_MEMORY_ERROR ); return TS_MEMORY_ERROR; } strcpy( *result, tmpStr.GetBuffer() ); } else { *result = NULL; } delete socket; return TS_OK; } int TSServer::GetString( int tableId, const char* columnName, int recId, char* result, int size ) { char* tmp; int status = GetString( tableId, columnName, recId, &tmp ); if ( status != TS_OK ) { return status; } strncpy( result, tmp, size ); delete tmp; return TS_OK; } int TSServer::GetSubmitTransition( int projectId, int* id ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=GetSubmitTransition&Params="; TSEncodeInt( projectId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } socket->ReceiveInt( id ); delete socket; return TS_OK; } int TSServer::HasPrivilege( int userId, int projectId, int maskNumber, int mask ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=HasPrivilege&Params="; TSEncodeInt( userId, params ); s += params; TSEncodeInt( projectId, params ); s += params; TSEncodeInt( maskNumber, params ); s += params; TSEncodeInt( mask, params ); s += params; if ( !Send( socket, s )) { delete socket; return FALSE; } int val; socket->ReceiveInt( &val ); delete socket; return val; } int TSServer::HasRecordPrivilege( enum recPriv_e recPriv, int userId, int tableId, int recId ) { TSString s, params; TSSocket* socket = OpenSocket(); if( socket == NULL ) { return TSGetLastError(); } s = "Func=HasRecordPrivilege&Params="; TSEncodeInt( recPriv, params ); s += params; TSEncodeInt( userId, params ); s += params; TSEncodeInt( tableId, params ); s += params; TSEncodeInt( recId, params ); s += params; if ( !Send( socket, s )) { delete socket; return FALSE; } int val; socket->ReceiveInt( &val ); delete socket; return val; } int TSServer::HasValidLicense( const char* solutionIdent ) { TSString s, params; TSSocket* socket = OpenSocket(); if( socket == NULL ) { return TSGetLastError(); } s = "Func=HasValidLicense&Params="; TSEncodeString( solutionIdent, params ); s += params; if ( !Send( socket, s )) { delete socket; return FALSE; } int val; socket->ReceiveInt( &val ); delete socket; return val; } int TSServer::MoveFolder( int folderId, int newParentId, int position ) { TSString s, params; TSSocket* socket = OpenSocket(); if( socket == NULL ) { return TSGetLastError(); } s = "Func=MoveFolder&Params="; TSEncodeInt( folderId, params ); s += params; TSEncodeInt( newParentId, params ); s += params; TSEncodeInt( position, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); delete socket; if ( !result ) { TSSetLastError( TS_ERROR ); return TS_ERROR; } return TS_OK; } int TSServer::MoveProject( int projectId, int newParentId, int position ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=MoveProject&Params="; TSEncodeInt( projectId, params ); s += params; TSEncodeInt( newParentId, params ); s += params; TSEncodeInt( position, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); delete socket; if ( !result ) { TSSetLastError( TS_ERROR ); return TS_ERROR; } return TS_OK; } int TSServer::ReadAllRecords( TSRecordList* list, int tableId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadAllRecords&Params="; TSEncodeInt( tableId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadFieldsByProject( TSRecordList* list, int projectId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadFieldsByProject&Params="; TSEncodeInt( projectId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadAttachmentList( TSRecordList* list, int tableId, int recId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadAttachmentList&Params="; TSEncodeInt( tableId, params ); s += params; TSEncodeInt( recId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadAvailableTransitionList( TSRecordList* list, int tableId, int recId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadAvailableTransitionList&Params="; TSEncodeInt( tableId, params ); s += params; TSEncodeInt( recId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadChangeList( TSRecordList* list, int caseId, BOOL newFirst /*=FALSE*/ ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadChangeList&Params="; TSEncodeInt( caseId, params ); s += params; TSEncodeInt( newFirst, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadFolderItems( TSRecordList* list, int folderId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadFolderItems&Params="; TSEncodeInt( folderId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadFolderList( TSRecordList* list, int owner, int parentId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadFolderList&Params="; TSEncodeInt( owner, params ); s += params; TSEncodeInt( parentId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadProjectSelectionList( TSRecordList* list, int selectid ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadProjectSelectionList&Params="; TSEncodeInt( selectid, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; return TSGetLastError(); } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadProjectTransitionList( TSRecordList* list, int transId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadProjectTransitionList&Params="; TSEncodeInt( transId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadPropertyList( TSRecordList* list, int transId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadPropertyList&Params="; TSEncodeInt( transId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadRecord( TSRecord* rec, int id ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadRecord&Params="; TSEncodeInt( rec->tableId, params ); s += params; TSEncodeInt( rec->fieldType, params ); // This is the type. s += params; TSEncodeInt( id, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } rec->Receive( socket ); delete socket; return result; } int TSServer::ReadRecordWithWhere( TSRecord* record, const char* whereClause ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadRecordWithWhere&Params="; TSEncodeInt( record->tableId, params ); s += params; TSEncodeInt( record->fieldType, params ); // This is the type. s += params; TSEncodeString( whereClause, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } record->Receive( socket ); delete socket; return TS_OK; } /////////////////////////////////////////////////////////////////////// // Reads a record, filtering by the where clause and returning // only the desired fields /////////////////////////////////////////////////////////////////////// int TSServer::ReadRecordWithWhere( TSRecord* record, const char* whereClause, const std::vector& fields ) { TSString s, params; TSSocket* socket = OpenSocket(); if( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadSelectedFieldsWithWhere&Params="; TSEncodeInt( record->tableId, params ); s += params; TSEncodeInt( record->fieldType, params ); // This is the type. s += params; TSEncodeString( whereClause, params ); s += params; // Encode the vector of selected fields TSEncodeInt( fields.size(), params ); s += params; std::vector::const_iterator it = fields.begin(); while ( it != fields.end() ) { TSEncodeInt( *it, params ); s += params; it++; } if( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } record->Receive( socket ); delete socket; return TS_OK; } int TSServer::ReadRecordListWithWhere( TSRecordList* list, int tableId, const char* whereClause ) { TSString s, params; TSSocket* socket = OpenSocket(); if( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadListWithWhere&Params="; TSEncodeInt( tableId, params ); s += params; TSEncodeString( whereClause, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; int nReturn = socket->ReceiveInt( &result ); if ( !result || nReturn != TS_OK ) { delete socket; TSSetLastError( nReturn ); return nReturn; } nReturn = list->Receive( this, socket ); if ( nReturn != TS_OK ) { TSSetLastError( nReturn ); } delete socket; return nReturn; } /////////////////////////////////////////////////////////////////////// // Reads a record, filtering by the where clause and returning // only the desired fields /////////////////////////////////////////////////////////////////////// int TSServer::ReadRecordListWithWhere( TSRecordList *list, int tableId, const char *whereClause, const std::vector& fields ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadListSelectedFieldsWithWhere&Params="; TSEncodeInt( tableId, params ); s += params; TSEncodeString( whereClause, params ); s += params; // Encode the vector of selected fields TSEncodeInt( fields.size(), params ); s += params; std::vector::const_iterator it = fields.begin(); while ( it != fields.end() ) { TSEncodeInt( *it, params ); s += params; it++; } if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadRecordForId( TSRecord* record, const char* searchId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadRecordForItemId&Params="; TSEncodeInt( record->tableId, params ); s += params; TSEncodeInt( record->fieldType, params ); s += params; TSEncodeString( searchId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } record->Receive( socket ); delete socket; return TS_OK; } int TSServer::ReadReport( TSRecord* report, const char* name ) { TSString s, params, modifiedName; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadReport&Params="; TSEncodeInt( TS_TBLID_REPORTS, params ); s += params; TSEncodeInt( 0, params ); // reportType, currently needs to be 0. s += params; // The name needs to be in single quotes since it will be used // in a query. modifiedName = "'"; modifiedName += name; modifiedName += "'"; TSEncodeString( modifiedName, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } report->Receive( socket ); delete socket; return TS_OK; } int TSServer::ReadReportList( TSRecordList* list, long userId, int perm ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadReportList&Params="; TSEncodeInt( userId, params ); s += params; TSEncodeInt( perm, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadSelectionList( TSRecordList* list, int fieldId, int projectId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadSelectionList2&Params="; TSEncodeInt( fieldId, params ); s += params; TSEncodeInt( projectId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadStateList( TSRecordList* list, int workflowId, BOOL incParent /*=FALSE*/ ) { TSString s, params; TSSocket* socket = OpenSocket(); if( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadStateList&Params="; TSEncodeInt( workflowId, params ); s += params; TSEncodeInt( incParent, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadTransitionList( TSRecordList* list, int projectId ) { TSString s, params; TSSocket* socket = OpenSocket(); if( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadTransitionListEx&Params="; TSEncodeInt( projectId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadUserDefinedFields( TSRecordList* list, int tableId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadUserDefinedFields&Params="; TSEncodeInt( tableId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadUserListForPrivilege( TSRecordList* list, int userid, TSRecordList* fieldList, int mask ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadUserListForPrivilege&Params="; TSEncodeInt( userid, params ); s += params; fieldList->SocketString( params ); s += params; TSEncodeInt( mask, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadVCActionsForModule( TSRecordList* list, const char* filename, int userid, int action2 ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadVCActionsForModule&Params="; TSEncodeString( filename, params ); s += params; TSEncodeInt( userid, params ); s += params; TSEncodeInt( action2, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadVCActions( TSRecordList* list, int caseId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadVCActions&Params="; TSEncodeInt( caseId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::ReadUserSelectionList( TSRecordList* list, int fieldId, int projectId, BOOL incDeleted /* = FALSE */ ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ReadUserSelectionList&Params="; TSEncodeInt( fieldId, params ); s += params; TSEncodeInt( projectId, params ); s += params; TSEncodeInt( incDeleted, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::SetExitUrl( const char* exiturl ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=SetExitUrl&Params="; TSEncodeString( exiturl, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } delete socket; return TS_OK; } int TSServer::UpdateList( TSRecordList* list, int tableId, int recid1, int recid2 ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=UpdateList&Params="; TSEncodeInt( tableId, params ); s += params; TSEncodeInt( recid1, params ); s += params; TSEncodeInt( recid2, params ); s += params; list->SocketString( params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } list->Receive( this, socket ); delete socket; return TS_OK; } int TSServer::UpdateRecord( TSRecord* rec, TSRecord* newRecord /*=NULL*/ ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=UpdateRecord&Params="; TSEncodeInt( rec->tableId, params ); s += params; TSEncodeInt( rec->fieldType, params ); s += params; rec->SocketString( params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int id; socket->ReceiveInt( &id ); if( newRecord != NULL ) { newRecord->Receive( socket ); } else { TSRecord dummy( rec->tableId, this ); dummy.fieldType = rec->fieldType; dummy.Receive( socket ); } delete socket; return TS_OK; } int TSServer::ValidateUser( const char* loginid, const char* pwd, BOOL validatePwd/*=TRUE*/, int *userId /*=NULL*/ ) { int result; TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ValidateUser&Params="; TSEncodeString( loginid, params ); s += params; TSEncodeString( pwd, params ); s += params; TSEncodeInt( validatePwd, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } socket->ReceiveInt( &result ); delete socket; if ( !result ) { if ( userId != NULL ) { *userId = 0; } TSSetLastError(TS_INVALID_USER); return TS_INVALID_USER; } else { if( userId != NULL ) { *userId = result; } return TS_OK; } } int TSServer::ValidateVersion() { int result; TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=ValidateAPIVersion¶ms="; TSEncodeInt( TS_APIVERSION, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } socket->ReceiveInt( &result ); delete socket; return result; } int TSServer::Submit( int* nIssueId, TSString& sLoginid, TSRecord* pRec, int nTableId, int nProjectId, int nFolderId, int nType ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } if ( !pRec ) { return TS_ERROR; } s = "Func=Submit&Params="; TSEncodeString( sLoginid, params ); s += params; TSEncodeInt( nProjectId, params ); s += params; TSEncodeInt( nTableId, params ); s += params; TSEncodeInt( nFolderId, params ); s += params; TSEncodeInt( nType, params ); s += params; pRec->SocketString( params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } socket->ReceiveInt( &result ); if ( nIssueId ) { *nIssueId = result; } delete socket; return TS_OK; } int TSServer::Transition( TSString& sLoginid, TSRecord* pRec, int nProjectId, int nTableId, int nRecordId, int nTransition ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } if ( !pRec ) { return TS_ERROR; } s = "Func=Transition&Params="; TSEncodeString( sLoginid, params ); s += params; TSEncodeInt( nProjectId, params ); s += params; TSEncodeInt( nTableId, params ); s += params; TSEncodeInt( nRecordId, params ); s += params; TSEncodeInt( nTransition, params ); s += params; pRec->SocketString( params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } delete socket; return TS_OK; } const char* TSServer::GetDllWebAddress() { return dllWebAddress.GetBuffer(); } int TSServer::RefreshCache( int tableId ) { TSString s, params; TSSocket* socket = OpenSocket(); if ( socket == NULL ) { return TSGetLastError(); } s = "Func=RefreshCache&Params="; TSEncodeInt( tableId, params ); s += params; if ( !Send( socket, s )) { delete socket; return TSGetLastError(); } int result; socket->ReceiveInt( &result ); if ( !result ) { delete socket; TSSetLastError( TS_ERROR ); return TS_ERROR; } delete socket; return TS_OK; }