From 8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 Mon Sep 17 00:00:00 2001 From: Constantin Jucovschi Date: Fri, 24 Apr 2009 07:20:22 -0400 Subject: Initial commit --- rasodmg/database.cc | 475 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 475 insertions(+) create mode 100644 rasodmg/database.cc (limited to 'rasodmg/database.cc') diff --git a/rasodmg/database.cc b/rasodmg/database.cc new file mode 100644 index 0000000..bdf11b0 --- /dev/null +++ b/rasodmg/database.cc @@ -0,0 +1,475 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +/ +/** + * SOURCE: database.cc + * + * MODULE: rasodmg + * CLASS: r_Database + * + * COMMENTS: + * None +*/ + +static const char rcsid[] = "@(#)rasodmg, r_Database: $Id: database.cc,v 1.47 2005/09/03 20:39:35 rasdev Exp $"; + +#ifdef __VISUALC__ +#ifndef __EXECUTABLE__ +#define __EXECUTABLE__ +#define DATABASE_NOT_SET +#endif +#endif + +#include "rasodmg/database.hh" +#include "rasodmg/transaction.hh" +#include "clientcomm/clientcomm.hh" + +#ifdef DATABASE_NOT_SET +#undef __EXECUTABLE__ +#endif + +#include + +// At the beginning, no database is actually opened. +r_Database* r_Database::actual_database = 0; + + +r_Database::r_Database() + : db_status( not_open ), + rasmgrName(0), + userName(0), + plainPass(0), + communication(0) +{ +} + +r_Database::r_Database( const char* name ) throw(r_Error) + : db_status( not_open ), + userName(0), + plainPass(0), + communication(0) +{ + if(!name) + { + RMInit::logOut << "Error: null database name." << std::endl; + throw r_Error(r_Error::r_Error_NameInvalid); + } + this->rasmgrName = strdup( name ); +} + +r_Type* +r_Database::get_type_schema(const char* typeName, type_schema typeType) throw (r_Error) +{ + r_Type* retval = 0; + + if ((typeName == NULL) || (strlen(typeName) == 0)) + throw r_Error(r_Error::r_Error_NameInvalid); + else if ((typeType != COLLECTION ) && (typeType != MARRAY)) + throw r_Error(r_Error::r_Error_TypeInvalid); + else if (r_Database::actual_database != NULL) + throw r_Error(r_Error::r_Error_DatabaseClosed); + else if (r_Database::actual_database->get_status() != r_Database::not_open) + throw r_Error(r_Error::r_Error_DatabaseClosed); + else if (r_Transaction::actual_transaction != NULL) + throw r_Error(r_Error::r_Error_TransactionNotOpen); + else if (r_Transaction::actual_transaction->get_status() == r_Transaction::active) + throw r_Error(r_Error::r_Error_TransactionNotOpen); + else + { + ClientComm::r_Type_Type type; + if (typeType == COLLECTION) + type = ClientComm::r_SetType_Type; + else + type = ClientComm::r_MDDType_Type; + char* temp = r_Database::actual_database->communication->getTypeStructure( typeName, type ); + retval = r_Type::get_any_type(temp); + delete [] temp; + temp = 0; + } + return retval; +} + +r_Database::~r_Database() +{ + if( db_status != not_open ) + close(); + + if( rasmgrName ) + free( rasmgrName ); + if( userName ) + free( userName ); + if( plainPass ) + free( plainPass ); +} + +void +r_Database::open( const char* database_name, access_status new_status ) + throw( r_Error ) +{ + if( db_status != not_open || actual_database ) + { + r_Error err = r_Error(r_Error::r_Error_DatabaseOpen); + throw err; + } + + if(!database_name) + { + RMInit::logOut << "r_Database::open(name, new_status) name is null" << std::endl; + throw r_Error(r_Error::r_Error_NameInvalid); + } + + // While instantiating the communication object, the first connection to + // the server is established. Any exception is given through to the caller + // of open(...). + try + { + communication = ClientComm::createObject( rasmgrName, rasmgrPort ); + if( userName && plainPass ) + communication->setUserIdentification( userName, plainPass ); + } + catch( ... ) + { + if(communication) + delete communication; + throw; // re-throw the exception (r_Error_HostInvalid, r_Error_ServerInvalid) + } + + // open database + unsigned int status=0; + try + { + status = communication->openDB( (char*)database_name ); + } + catch( ... ) + { + if(communication) + delete communication; + throw; + } + + if( status ) + { + // translate error values into exceptions + r_Error err; + + switch( status ) + { + case 1: + err = r_Error( r_Error::r_Error_ClientUnknown ); + break; + + case 2: + err = r_Error( r_Error::r_Error_DatabaseUnknown ); + break; + + case 3: + err = r_Error( r_Error::r_Error_DatabaseOpen ); + break; + + case 4: + err = r_Error( r_Error::r_Error_RpcInterfaceIncompatible ); + break; + case CONNECTIONCLOSED: + err = r_Error(CONNECTIONCLOSED); + break; + default: + err = r_Error( r_Error::r_Error_General ); + } + + if(communication) + delete communication; + + throw err; + } + + actual_database = this; + db_status = new_status; +} + +void +r_Database::close() +{ + if( db_status != not_open ) + { + // if a communication object exists, close and delete it + if( communication ) + { + // abort any open TA -- PB 2005-sep-02 + // This is quite a hack (borrowed from fastscale.cc): + // Actual transaction is a pointer to this in a TA. + // Since the TA was allocated by the application program + // it should be save to use it like this. + if (r_Transaction::actual_transaction != 0) + { // make _very_ sure we have sequential evaluation -> nested ifs + if (r_Transaction::actual_transaction->get_status() == r_Transaction::active) + r_Transaction::actual_transaction->abort(); + } + + communication->closeDB(); + delete communication; + communication = 0; + } + + db_status = not_open; + actual_database = 0; + } +} + +void +r_Database::create( const char* name ) throw( r_Error ) +{ + // this operation is not supported through this interface; use rasdl + throw( r_Error(803)); // Access denied, no permission +} + +void +r_Database::destroy( const char* name ) throw( r_Error ) +{ + // this operation is not supported through this interface; use rasdl + throw( r_Error(803)); // Access denied, no permission +} + + +void +r_Database::set_servername( const char* name, int port ) throw (r_Error) +{ + //We let the name of the function as it is, but it's about the rasmgr name + + if(!name) + { + RMInit::logOut << "r_Database::set_servername(name, port) name is null" << std::endl; + throw r_Error(r_Error::r_Error_NameInvalid); + } + + if( rasmgrName) + free( rasmgrName ); + + rasmgrName = strdup( name ); + rasmgrPort = port; +} +void +r_Database::set_useridentification( const char* name, const char *plain_pass ) throw(r_Error) +{ + if(!name) + { + RMInit::logOut << "r_Database::set_useridentification(name, plain_pass) name is null" << std::endl; + throw r_Error(r_Error::r_Error_NameInvalid); + } + if(!plain_pass) + { + RMInit::logOut << "r_Database::set_useridentification(name, plain_pass) plain_pass is null" << std::endl; + throw r_Error(r_Error::r_Error_NameInvalid); + } + + if (userName) + free(userName); + if (plainPass) + free(plainPass); + userName = strdup( name ); + plainPass = strdup( plain_pass ); +} + +void +r_Database::set_object_name( r_Object &obj, const char* name ) throw(r_Error) +{ + obj.set_object_name( name ); +} + +r_Ref_Any +r_Database::lookup_object( const char* name ) const throw( r_Error ) +{ + r_Ref_Any returnValue; + + if( db_status == not_open ) + { + r_Error err = r_Error( r_Error::r_Error_DatabaseClosed ); + throw err; + } + + if(!name) + { + RMInit::logOut << "r_Database::lookup_object(name) name is null" << std::endl; + throw r_Error(r_Error::r_Error_NameInvalid); + } + + if( !r_Transaction::actual_transaction + || r_Transaction::actual_transaction->get_status() != r_Transaction::active ) + { + r_Error err = r_Error( r_Error::r_Error_TransactionNotOpen ); + throw err; + } + + try + { + // get collection + returnValue = communication->getCollOIdsByName( name ); + } + catch( ... ) + { + throw; // re-throw the exception + } + + return returnValue; +} + + + +r_Ref_Any +r_Database::lookup_object( const r_OId& oid ) const throw( r_Error ) +{ + r_Ref_Any returnValue; + + if( db_status == not_open ) + { + r_Error err = r_Error( r_Error::r_Error_DatabaseClosed ); + throw err; + } + + if( !r_Transaction::actual_transaction + || r_Transaction::actual_transaction->get_status() != r_Transaction::active ) + { + r_Error err = r_Error( r_Error::r_Error_TransactionNotOpen ); + throw err; + } + + try + { + // determine type of object and get it + if( communication->getObjectType( oid ) == 1 ) + returnValue = communication->getMDDByOId( oid ); + else + returnValue = communication->getCollOIdsByOId( oid ); + } + catch( ... ) + { + throw; // re-throw the exception + } + + return returnValue; +} + + +void +r_Database::set_transfer_format( r_Data_Format format, const char *formatParams ) throw( r_Error ) +{ + unsigned short result; + + if ( db_status == not_open ) + { + r_Error err = r_Error( r_Error::r_Error_DatabaseClosed ); + throw (err); + } + //keeps from crashing in rpc on linux + if (formatParams == 0) + formatParams = ""; + result = communication->setTransferFormat(format, formatParams); + + switch (result) + { + case 1: + { + r_Error err = r_Error( r_Error::r_Error_ClientUnknown ); + throw(err); + } + break; + case 2: + { + r_Error err = r_Error( r_Error::r_Error_FeatureNotSupported ); + throw(err); + } + break; + default: + break; + } +} + +void +r_Database::set_storage_format( r_Data_Format format, const char *formatParams ) throw( r_Error ) +{ + unsigned short result; + + if ( db_status == not_open ) + { + r_Error err( r_Error::r_Error_DatabaseClosed ); + throw(err); + } + + //keeps from crashing in rpc on linux + if (formatParams == 0) + formatParams = ""; + + result = communication->setStorageFormat(format, formatParams); + + switch (result) + { + case 1: + { + r_Error err( r_Error::r_Error_ClientUnknown ); + throw(err); + } + break; + case 2: + { + r_Error err( r_Error::r_Error_FeatureNotSupported ); + throw(err); + } + break; + default: + break; + } +} + + + +const r_OId +r_Database::get_new_oid( unsigned short objType ) const throw(r_Error) +{ + return communication->getNewOId( objType ); +} + + +void r_Database::insertColl( const char* collName, const char* typeName, const r_OId& oid ) throw( r_Error ) +{ + communication->insertColl(collName,typeName,oid ); +} + +void r_Database::removeObjFromColl( const char* name, const r_OId& oid ) throw ( r_Error ) +{ + communication->removeObjFromColl(name,oid); +} + +ClientComm* r_Database::getComm() +{ + return communication; +} + + + + + + + + + + + + -- cgit