// This is -*- C++ -*-
/*
* 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 .
*/
/*************************************************************
*
*
* PURPOSE:
*
*
* COMMENTS:
*
************************************************************/
#include "reladminif/oidif.hh"
#include "reladminif/dbref.hh"
#include "reladminif/sqlerror.hh"
#include "reladminif/externs.h"
#include "raslib/rmdebug.hh"
#include "catalogmgr/typefactory.hh"
#include "relcatalogif/mddbasetype.hh"
#include "relcatalogif/basetype.hh"
#include "reladminif/objectbroker.hh"
#include "relcatalogif/dbminterval.hh"
#include "relstorageif/dbstoragelayout.hh"
#include "dbmddobj.hh"
#include "relindexif/indexid.hh"
#include "indexmgr/indexds.hh"
#include "debug-srv.hh"
DBMDDObj::DBMDDObj()
: DBObject(),
myDomain(NULL),
objIxId(),
mddType(NULL),
persistentRefCount(0),
storageLayoutId(new DBStorageLayout())
{
RMDBGENTER(7, RMDebug::module_mddif, "DBMDDObj", "DBMDDObj()");
ENTER( "DBMDDObj::DBMDDObj" );
objecttype = OId::MDDOID;
myDomain = new DBMinterval();
myDomain->setPersistent(true);
storageLayoutId->setPersistent(true);
LEAVE( "DBMDDObj::DBMDDObj" );
RMDBGEXIT(7, RMDebug::module_mddif, "DBMDDObj", "DBMDDObj()");
}
DBMDDObj::DBMDDObj(const OId& id) throw (r_Error)
: DBObject(id),
myDomain(NULL),
objIxId(),
persistentRefCount(0),
mddType(NULL),
storageLayoutId((double)0)
{
RMDBGENTER(7, RMDebug::module_mddif, "DBMDDObj", "DBMDDObj(" << myOId << ")");
ENTER( "DBMDDObj::DBMDDObj, id=" << id );
objecttype = OId::MDDOID;
readFromDb();
LEAVE( "DBMDDObj::DBMDDObj" );
RMDBGEXIT(7, RMDebug::module_mddif, "DBMDDObj", "DBMDDObj(" << myOId << ")");
}
DBMDDObj::DBMDDObj( const MDDBaseType* newMDDType,
const r_Minterval& domain,
const DBObjectId& newObjIx,
const DBStorageLayoutId& newSL,
const OId& newOId) throw (r_Error)
: DBObject(),
objIxId(newObjIx.getOId()),
mddType(newMDDType),
persistentRefCount(0),
storageLayoutId(newSL),
myDomain(NULL)
{
RMDBGENTER(7, RMDebug::module_mddif, "DBMDDObj", "DBMDDObj(" << newMDDType->getName() << ", " << domain << ", Ix " << newObjIx.getOId() << ", Sl " << newSL.getOId() << ", " << newOId << ")");
ENTER( "DBMDDObj::DBMDDObj" );
objecttype = OId::MDDOID;
EXEC SQL BEGIN DECLARE SECTION;
long testoid1;
EXEC SQL END DECLARE SECTION;
testoid1 = newOId.getCounter();
TALK( "EXEC SQL SELECT MDDId INTO :testoid1 FROM RAS_MDDOBJECTS WHERE MDDId = " << testoid1 );
EXEC SQL SELECT
MDDId
INTO
:testoid1
FROM
RAS_MDDOBJECTS
WHERE
MDDId = :testoid1;
if (SQLCODE != SQLNODATAFOUND)
{
((DBObjectId)newObjIx)->setPersistent(false);
((DBObject*)newSL.ptr())->setPersistent(false);
if (SQLCODE == SQLOK)
{
RMDBGMIDDLE(1, RMDebug::module_mddif, "DBMDDObj", "OId is already there");
RMInit::logOut << "DBMDDObj::DBMDDObj(...) OId already exists" << endl;
throw r_Error(r_Error::r_Error_OIdNotUnique);
}
else
{
check("DBMDDObj(type, domain, index, layout, oid)");
generateException();
}
}
if (newMDDType->isPersistent())
mddType = newMDDType;
else
mddType = (const MDDBaseType*)TypeFactory::addMDDType(newMDDType);
myDomain = new DBMinterval(domain);
_isPersistent = true;
_isModified = true;
myOId = newOId;
setPersistent(true);
LEAVE( "DBMDDObj::DBMDDObj, " << newMDDType->getName() << ", " << domain << ", Ix " << newObjIx.getOId() << ", " << myOId << ") " << myOId );
RMDBGEXIT(7, RMDebug::module_mddif, "DBMDDObj", "DBMDDObj(" << newMDDType->getName() << ", " << domain << ", Ix " << newObjIx.getOId() << ", " << myOId << ") " << myOId);
}
DBMDDObj::DBMDDObj(const DBMDDObj& old)
: DBObject(old),
objIxId(),
mddType(NULL),
persistentRefCount(0),
storageLayoutId(),
myDomain(NULL)
{
RMDBGENTER(7, RMDebug::module_mddif, "DBMDDObj", "DBMDDObj(const DBMDDObj&" << old.getOId() << ")");
ENTER( "DBMDDObj::DBMDDObj" );
if (old.myDomain)
{
if (old.myDomain->isPersistent())
{
myDomain = (DBMinterval*)ObjectBroker::getObjectByOId(old.myDomain->getOId());
}
else
{
myDomain = new DBMinterval(*old.myDomain);
myDomain->setPersistent(true);
}
}
else
{
myDomain = NULL;
}
objIxId = old.objIxId;
storageLayoutId = old.storageLayoutId;
persistentRefCount = old.persistentRefCount;
mddType = old.mddType;
LEAVE( "DBMDDObj::DBMDDObj" );
RMDBGEXIT(7, RMDebug::module_mddif, "DBMDDObj", "DBMDDObj(const DBMDDObj& " << old.getOId() << ")");
}
DBMDDObj::DBMDDObj(const MDDBaseType* newMDDType, const r_Minterval& domain, const DBObjectId& newObjIx, const DBStorageLayoutId& newSL)
: DBObject(),
objIxId(newObjIx),
mddType(NULL),
persistentRefCount(0),
storageLayoutId(newSL),
myDomain(NULL)
{
RMDBGENTER(7, RMDebug::module_mddif, "DBMDDObj", "DBMDDObj(" << newMDDType->getName() << ", " << domain << ", Ix " << newObjIx.getOId() << ", Sl " << newSL.getOId() << ")");
ENTER( "DBMDDObj::DBMDDObj" );
objecttype = OId::MDDOID;
myDomain = new DBMinterval(domain);
mddType = newMDDType;
/*only if it is a persistent mdd
if (newMDDType->isPersistent())
mddType = (MDDBaseType*)newMDDType;
else
mddType = (MDDBaseType*)TypeFactory::addMDDType(newMDDType);
setPersistent(true);
*/
LEAVE( "DBMDDObj::DBMDDObj" );
RMDBGEXIT(7, RMDebug::module_mddif, "DBMDDObj", "DBMDDObj(" << newMDDType->getName() << ", " << domain << ", Ix " << newObjIx.getOId() << ") " << myOId);
}
DBMDDObj::~DBMDDObj()
{
RMDBGENTER(7, RMDebug::module_mddif, "DBMDDObj", "~DBMDDObj() " << myOId);
ENTER( "DBMDDObj::~DBMDDObj" );
validate();
if (myDomain)
delete myDomain;
myDomain = NULL;
LEAVE( "DBMDDObj::~DBMDDObj" );
RMDBGEXIT(7, RMDebug::module_mddif, "DBMDDObj", "~DBMDDObj() " << myOId);
}
DBStorageLayoutId
DBMDDObj::getDBStorageLayout() const
{
return storageLayoutId;
}
r_Bytes
DBMDDObj::getMemorySize() const
{
return DBObject::getMemorySize() + sizeof(long) + sizeof(MDDBaseType*) + sizeof(DBMinterval*) + sizeof(OId) + myDomain->getMemorySize() + mddType->getMemorySize() + sizeof(OId);
}
const MDDBaseType*
DBMDDObj::getMDDBaseType() const
{
return mddType;
}
const BaseType*
DBMDDObj::getCellType() const
{
return mddType->getBaseType();
}
r_Dimension
DBMDDObj::dimensionality() const
{
return myDomain->dimension();
}
void
DBMDDObj::setCached(bool ic)
{
DBObject::setCached(ic);
if (myDomain)
myDomain->setCached(ic);
}
//this should only receive an setPersistent(false)
void
DBMDDObj::setPersistent(bool o) throw (r_Error)
{
RMDBGENTER(7, RMDebug::module_mddif, "DBMDDObj", "setPersistent(" << (int)o << ") " << myOId);
ENTER( "DBMDDObj::setPersistent, o=" << o );
DBObject::setPersistent(o);
if (!o)
setCached(false);
if (myDomain)
myDomain->setPersistent(o);
DBObjectId testIx(objIxId);
if (testIx.is_null())
{
RMDBGMIDDLE(0, RMDebug::module_mddif, "DBMDDObj", "index object is not valid " << myOId << " index " << objIxId.getOId());
throw r_Error(INDEX_OF_MDD_IS_NULL);
}
else
{
testIx->setPersistent(o);
if (o)
{
objIxId.release();
}
}
if (storageLayoutId.is_null())
{
RMDBGMIDDLE(0, RMDebug::module_mddif, "DBMDDObj", "layout object is not valid " << myOId << " layout " << storageLayoutId.getOId());
RMInit::logOut << "DBMDDObj::setPersistent() layout object is not valid" << endl;
throw r_Error(STORAGE_OF_MDD_IS_NULL);
}
else
{
storageLayoutId->setPersistent(o);
}
if (o && !mddType->isPersistent())
mddType = (const MDDBaseType*)TypeFactory::addMDDType(mddType);
LEAVE( "DBMDDObj::setPersistent, o=" << o );
RMDBGEXIT(7, RMDebug::module_mddif, "DBMDDObj", "setPersistent(" << (int)o << ") " << myOId);
}
const char*
DBMDDObj::getCellTypeName() const
{
return mddType->getBaseType()->getTypeName();
}
r_Minterval
DBMDDObj::getDefinitionDomain() const
{
return *myDomain;
}
r_Bytes
DBMDDObj::getHeaderSize() const
{
r_Bytes sz = sizeof(MDDBaseType*) + sizeof(r_Minterval*) + sizeof(DBObjectId) + sizeof(DBObject) + sizeof(DBStorageLayoutId);
return sz;
}
void
DBMDDObj::printStatus(unsigned int level, ostream& stream) const
{
DBObject::printStatus(level, stream);
stream << *myDomain << endl;
mddType->printStatus(level + 1, stream);
DBObjectId testIx(objIxId);
if (!testIx.is_null())
testIx->printStatus(level + 1, stream);
else
stream << "index is invalid " << objIxId.getOId();
if (storageLayoutId.is_null())
stream << "storagelayout is invalid " << storageLayoutId.getOId();
else
storageLayoutId->printStatus(level + 1, stream);
}
void
DBMDDObj::setIx(const DBObjectId& newIx)
{
ENTER( "DBMDDObj::setIx" );
if (isPersistent())
{
if (objIxId.getOId() != newIx.getOId())
{
objIxId = newIx.getOId();
setModified();
}
}
else
{
objIxId = newIx;
}
LEAVE( "DBMDDObj::setIx" );
}
void
DBMDDObj::updateInDb() throw (r_Error)
{
RMDBGENTER(7, RMDebug::module_mddif, "DBMDDObj", "updateInDb() " << myOId);
ENTER( "DBMDDObj::updateInDb" );
EXEC SQL BEGIN DECLARE SECTION;
long mddoid3;
double objindex3;
long persRefCount3;
EXEC SQL END DECLARE SECTION;
objindex3 = objIxId.getOId();
mddoid3 = myOId.getCounter();
persRefCount3 = persistentRefCount;
TALK( "EXEC SQL UPDATE RAS_MDDOBJECTS SET PersRefCount = " << persRefCount3 << ", NodeOId = " << objindex3 << " WHERE MDDId = " << mddoid3 );
EXEC SQL UPDATE RAS_MDDOBJECTS SET PersRefCount = :persRefCount3, NodeOId = :objindex3
WHERE MDDId = :mddoid3;
if (SQLCODE != SQLOK)
{
check("DBMDDObj::updateInDb()\0");
generateException();
}
DBObject::updateInDb();
LEAVE( "DBMDDObj::updateInDb" );
RMDBGEXIT(7, RMDebug::module_mddif, "DBMDDObj", "updateInDb() " << myOId);
}
void
DBMDDObj::insertInDb() throw (r_Error)
{
RMDBGENTER(7, RMDebug::module_mddif, "DBMDDObj", "insertInDb() " << myOId);
ENTER( "DBMDDObj::insertInDb" );
EXEC SQL BEGIN DECLARE SECTION;
long mddoid;
double basetypeid;
double storage;
long domainid;
double objindex;
long persRefCount;
EXEC SQL END DECLARE SECTION;
storage = storageLayoutId->getOId();
objindex = objIxId.getOId();
mddoid = myOId.getCounter();
basetypeid = mddType->getOId();
domainid = myDomain->getOId().getCounter();
persRefCount = persistentRefCount;
TALK( "EXEC SQL INSERT INTO RAS_MDDOBJECTS ( MDDId, BaseTypeOId, DomainId, PersRefCount, NodeOId, StorageOId) VALUES ( " << mddoid << "," << basetypeid<< "," << domainid<< "," << persRefCount << "," << objindex << "," << storage << ")" );
EXEC SQL INSERT INTO RAS_MDDOBJECTS ( MDDId, BaseTypeOId, DomainId, PersRefCount, NodeOId, StorageOId)
VALUES ( :mddoid, :basetypeid, :domainid, :persRefCount, :objindex, :storage);
if (SQLCODE != SQLOK)
{
check("DBMDDObj::insertInDb()");
generateException();
}
DBObject::insertInDb();
LEAVE( "DBMDDObj::insertInDb" );
RMDBGEXIT(7, RMDebug::module_mddif, "DBMDDObj", "insertInDb() " << myOId);
}
void
DBMDDObj::deleteFromDb() throw (r_Error)
{
RMDBGENTER(7, RMDebug::module_mddif, "DBMDDObj", "deleteFromDb() " << myOId);
ENTER( "DBMDDObj::deleteFromDb" );
EXEC SQL BEGIN DECLARE SECTION;
long mddoid1;
EXEC SQL END DECLARE SECTION;
mddoid1 = myOId.getCounter();
TALK( "EXEC SQL DELETE FROM RAS_MDDOBJECTS WHERE MDDId = " << mddoid1 );
EXEC SQL DELETE FROM RAS_MDDOBJECTS WHERE MDDId = :mddoid1;
if (SQLCODE != SQLOK)
{
check("DBMDDObj::deleteFromDb()\0");
generateException();
}
DBObject::deleteFromDb();
LEAVE( "DBMDDObj::deleteFromDb" );
RMDBGEXIT(7, RMDebug::module_mddif, "DBMDDObj", "deleteFromDb() " << myOId);
}
void
DBMDDObj::readFromDb() throw (r_Error)
{
RMDBGENTER(7, RMDebug::module_mddif, "DBMDDObj", "readFromDb() " << myOId);
ENTER( "DBMDDObj::readFromDb" );
#ifdef RMANBENCHMARK
DBObject::readTimer.resume();
#endif
EXEC SQL BEGIN DECLARE SECTION;
long mddoid2;
double basetypeid2;
long domainid2;
double objindex2;
long persRefCount2;
double storage2;
EXEC SQL END DECLARE SECTION;
mddoid2 = myOId.getCounter();
TALK( "EXEC SQL SELECT BaseTypeOId, DomainId, PersRefCount, NodeOId, StorageOId INTO :basetypeid2, :domainid2, :persRefCount2, :objindex2, :storage2 FROM RAS_MDDOBJECTS WHERE MDDId = " << mddoid2 );
EXEC SQL SELECT BaseTypeOId, DomainId, PersRefCount, NodeOId, StorageOId
INTO :basetypeid2, :domainid2, :persRefCount2, :objindex2, :storage2
FROM RAS_MDDOBJECTS
WHERE MDDId = :mddoid2;
if (SQLCODE != SQLOK)
{
if (SQLCODE == SQLNODATAFOUND)
{
RMDBGMIDDLE(7, RMDebug::module_mddif, "DBMDDObj", "object not found");
throw r_Error(r_Error::r_Error_ObjectUnknown);
}
else
{
check("DBMDDObj::readFromDb()\0");
generateException();
}
}
objIxId = OId(objindex2);
storageLayoutId = OId(storage2);
persistentRefCount = persRefCount2;
mddType = (MDDBaseType*)ObjectBroker::getObjectByOId(OId(basetypeid2));
myDomain = (DBMinterval*)ObjectBroker::getObjectByOId(OId(domainid2, OId::DBMINTERVALOID));
myDomain->setCached(true);
DBObject::readFromDb();
#ifdef RMANBENCHMARK
DBObject::readTimer.pause();
#endif
LEAVE( "DBMDDObj::readFromDb" );
RMDBGEXIT(7, RMDebug::module_mddif, "DBMDDObj", "readFromDb() " << myOId);
}
DBObjectId
DBMDDObj::getDBIndexDS() const
{
return objIxId;
}
int
DBMDDObj::getPersRefCount() const
{
return persistentRefCount;
}
void
DBMDDObj::incrementPersRefCount()
{
persistentRefCount++;
setModified();
}
void
DBMDDObj::decrementPersRefCount()
{
persistentRefCount--;
if (persistentRefCount == 0)
setPersistent(false);
setModified();
}