/*
* 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 .
*/
// This is -*- C++ -*-
/*************************************************************************
*
*
* PURPOSE:
* Contains all code that is shared by the database interface implementations
*
*
* COMMENTS:
* - schema version depending on release doesn't make sense; rather change
* it when the schema _really_ changes!
*
***********************************************************************/
#include
#include
#include "globals.hh" // DEFAULT_DBNAME
#include "databaseif.hh"
#include "adminif.hh"
#include "raslib/rminit.hh"
#include "raslib/rmdebug.hh"
#include "externs.h"
#include "sqlerror.hh"
#include "raslib/error.hh"
#include "relcatalogif/alltypes.hh"
// defined in rasserver.cc
extern char globalConnectId[256];
const char* DatabaseIf::DefaultDatabaseName = DEFAULT_DBNAME;
DatabaseIf::~DatabaseIf()
{
RMDBGENTER(4, RMDebug::module_adminif, "DatabaseIf", "~DatabaseIf()");
if (isConnected())
{
baseDBMSClose();
}
if (myName)
{
free(myName);
myName = NULL;
}
connected = false;
opened = false;
RMDBGEXIT(4, RMDebug::module_adminif, "DatabaseIf", "~DatabaseIf()");
}
bool
DatabaseIf::isConnected() const
{
RMDBGONCE(4, RMDebug::module_adminif, "DatabaseIf", "isConnected() " << connected);
return connected;
}
bool
DatabaseIf::isOpen() const
{
RMDBGONCE(4, RMDebug::module_adminif, "DatabaseIf", "isOpen() " << opened);
return opened;
}
void
DatabaseIf::open(const char* dbName) throw(r_Error)
{
RMDBGENTER(4, RMDebug::module_adminif, "DatabaseIf", "open(" << dbName << ")");
if (opened)
{
RMDBGMIDDLE(4, RMDebug::module_adminif, "DatabaseIf", "another database is already open");
throw r_Error(r_Error::r_Error_DatabaseOpen);
}
else
{
//cannot do any further error checking
if ( 0 ) // we allow any other database name -- strcmp(dbName, DefaultDatabaseName))
{
RMDBGMIDDLE(4, RMDebug::module_adminif, "DatabaseIf", "database name unknown");
RMInit::logOut << "b_DatabaseIf::open(" << dbName << ") dbName=" << dbName << std::endl;
throw r_Error(r_Error::r_Error_DatabaseUnknown);
}
else
{
opened = true;
myName = strdup(dbName);
}
}
RMDBGEXIT(4, RMDebug::module_adminif, "DatabaseIf", "open(" << dbName << ")");
}
void
DatabaseIf::baseDBMSOpen() throw (r_Error)
{
RMDBGENTER(4, RMDebug::module_adminif, "DatabaseIf", "baseDBMSOpen() " << ((myName)? myName:"NULL"));
if (connected)
{
RMDBGMIDDLE(4, RMDebug::module_adminif, "DatabaseIf", "databasename is already connected");
throw r_Error(r_Error::r_Error_TransactionOpen);
}
#ifdef RMANDEBUG
if (AdminIf::getCurrentDatabaseIf())
{
RMDBGMIDDLE(0, RMDebug::module_adminif, "DatabaseIf", "baseDBMSOpen() CurrentDatabaseIf != 0");
RMInit::logOut << "Transaction begin:" << std::endl \
<< "There seems to be another database connection active (Internal State 1)." << std::endl \
<< "Please contact Customer support." << std::endl;
throw r_Error(DATABASE_OPEN);
}
#endif
AdminIf::setCurrentDatabaseIf(this);
connect();
connected = true;
#ifdef DBMS_PGSQL // cannot have this check in PostgreSQL -- PB 2005-jan-09
if (!databaseExists(myName))
{
RMInit::logOut << "Database " << ((myName)? myName: "NULL") << " unknown" << std::endl;
throw r_Error(r_Error::r_Error_DatabaseUnknown);
}
#endif // DBMS_PGSQL
#ifndef FASTCONNECT
checkCompatibility();
if (!isConsistent())
{
RMInit::logOut << "Database " << ((myName)? myName: "NULL") << " inconsistent" << std::endl;
throw r_Error(DATABASE_INCONSISTENT);
}
#endif
RMDBGEXIT(4, RMDebug::module_adminif, "DatabaseIf", "baseDBMSOpen()");
}
void
DatabaseIf::close()
{
RMDBGENTER(4, RMDebug::module_adminif, "DatabaseIf", "close()");
opened = false;
if (myName)
{
free(myName);
myName = NULL;
}
if (connected)
{
disconnect();
connected = false;
}
RMDBGEXIT(4, RMDebug::module_adminif, "DatabaseIf", "close()");
}
void
DatabaseIf::baseDBMSClose()
{
RMDBGENTER(4, RMDebug::module_adminif, "DatabaseIf", "baseDBMSClose()");
#ifdef RMANDEBUG
if (AdminIf::getCurrentDatabaseIf() == this)
{
#endif
AdminIf::setCurrentDatabaseIf(0);
#ifdef RMANDEBUG
}
else
{
//this happens when a transaction is killed by the server
RMDBGONCE(0, RMDebug::module_adminif, "DatabaseIf", "baseDBMSClose() current DatabaseIf != this");
}
#endif
disconnect();
connected = false;
RMDBGEXIT(4, RMDebug::module_adminif, "DatabaseIf", "baseDBMSClose()");
}
DatabaseIf::DatabaseIf()
: opened(false),
connected(false),
myName(NULL)
{
RMDBGONCE(4, RMDebug::module_adminif, "DatabaseIf", "DatabaseIf()");
}
const char*
DatabaseIf::getName() const
{
RMDBGONCE(4, RMDebug::module_adminif, "DatabaseIf", "getName() " << ((myName)? myName:"NULL"));
return myName;
}
ostream&
operator << (ostream& stream, DatabaseIf& db)
{
stream << "DatabaseIf" << std::endl;
stream << "\tConnected To\t: " << ((db.getName())? db.getName():" ") << std::endl;
if (db.opened)
{
if (db.connected)
{
stream << "\tDatabase is really ONLINE" << std::endl;
}
else
{
stream << "\tDatabase is only FAKE ONLINE" << std::endl;
}
}
else
{
stream << "\tDatabase is OFFLINE" << std::endl;
}
return stream;
}
void
DatabaseIf::garbage( )
{
RMDBGONCE(0, RMDebug::module_adminif, "DatabaseIf", "garbage() NOT IMPLEMENTED");
}