/* * 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: * Code with embedded SQL for PostgreSQL DBMS * * * COMMENTS: * none * ***********************************************************************/ #include "reladminif/sqlerror.hh" #include "reladminif/externs.h" #include "dbminterval.hh" #include "raslib/rmdebug.hh" EXEC SQL include "../reladminif/sqlglobals.h"; DBMinterval::DBMinterval() : r_Minterval(), DBObject() { objecttype = OId::DBMINTERVALOID; } DBMinterval::DBMinterval(const OId& id) throw (r_Error) : r_Minterval(), DBObject(id) { objecttype = OId::DBMINTERVALOID; readFromDb(); } DBMinterval::DBMinterval(r_Dimension dim) : r_Minterval(dim), DBObject() { objecttype = OId::DBMINTERVALOID; } DBMinterval::DBMinterval(const char* dom) : r_Minterval((char*)dom), DBObject() { objecttype = OId::DBMINTERVALOID; } DBMinterval::DBMinterval(const DBMinterval& old) : r_Minterval(old), DBObject(old) { objecttype = OId::DBMINTERVALOID; } DBMinterval::DBMinterval(const r_Minterval& old) : r_Minterval(old), DBObject() { objecttype = OId::DBMINTERVALOID; } DBMinterval::~DBMinterval() { RMDBGENTER(4, RMDebug::module_catalogif, "DBMinterval", "~DBMinterval() " << myOId); validate(); RMDBGEXIT(4, RMDebug::module_catalogif, "DBMinterval", "~DBMinterval() " << myOId); } DBMinterval& DBMinterval::operator=(const DBMinterval& old) { RMDBGENTER(11, RMDebug::module_catalogif, "DBMinterval", "operator=(" << old.getOId() << ") with me " << myOId); if (this == &old) return *this; r_Minterval::operator=(old); setModified(); RMDBGEXIT(11, RMDebug::module_catalogif, "DBMinterval", "operator=(" << old.getOId() << ") with me " << myOId); return *this; } DBMinterval& DBMinterval::operator=(const r_Minterval& old) { if (this == &old) return *this; r_Minterval::operator=(old); setModified(); return *this; } r_Bytes DBMinterval::getMemorySize() const { return DBObject::getMemorySize() + sizeof(r_Minterval) + dimensionality * (4 + 4 + 1 + 1); } void DBMinterval::insertInDb() throw (r_Error) { EXEC SQL BEGIN DECLARE SECTION; long domainid; long count; long low; short lowind; long high; short highind; long dimension; EXEC SQL END DECLARE SECTION; domainid = myOId.getCounter(); dimension = dimensionality; EXEC SQL INSERT INTO RAS_DOMAINS ( DomainId, Dimension) VALUES ( :domainid, :dimension); if (SQLCODE != SQLOK) { check("DBMinterval::insertInDb() INSERT INTO RAS_DOMAINS"); generateException(); } for (count = 0; count < dimensionality; count++) { if (intervals[count].is_low_fixed()) { low = intervals[count].low(); lowind = 0; } else { lowind = -1; } if (intervals[count].is_high_fixed()) { high = intervals[count].high(); highind = 0; } else { highind = -1; } EXEC SQL INSERT INTO RAS_DOMAINVALUES ( DomainId, DimensionCount, Low, High) VALUES ( :domainid, :count, :low INDICATOR :lowind, :high INDICATOR :highind); if (SQLCODE != SQLOK) { check("DBMinterval::insertInDb() INSERT INTO RAS_DOMAINVALUES"); generateException(); } } DBObject::insertInDb(); } void DBMinterval::updateInDb() throw (r_Error) { EXEC SQL BEGIN DECLARE SECTION; long domainid1; long count1; long low1; short lowind1; long high1; short highind1; long dimension1; EXEC SQL END DECLARE SECTION; domainid1 = myOId.getCounter(); EXEC SQL SELECT Dimension INTO :dimension1 FROM RAS_DOMAINS WHERE DomainId = :domainid1; if (dimension1 < dimensionality) { //insert more rows in RAS_DOMAINVALUES for (count1 = dimension1; count1 < dimensionality; count1++) { EXEC SQL INSERT INTO RAS_DOMAINVALUES ( DomainId, DimensionCount) VALUES ( :domainid1, :count1); if (SQLCODE != SQLOK) { check("DBMinterval::updateInDb() INSERT INTO RAS_DOMAINVALUES"); generateException(); } } dimension1 = dimensionality; EXEC SQL UPDATE RAS_DOMAINS SET Dimension = :dimension1 WHERE DomainId = :domainid1; if (check("DBMinterval::updateInDb() UPDATE RAS_DOMAINS")) generateException(); } else { if (dimension1 > dimensionality) { //delete superfluous dimensions for (count1 = dimension1; count1 > dimensionality; count1--) { EXEC SQL DELETE FROM RAS_DOMAINVALUES WHERE DomainId = :domainid1 AND DimensionCount = :count1; if (SQLCODE != SQLOK) { check("DBMinterval::updateInDb() DELETE FROM RAS_DOMAINVALUES"); generateException(); } } dimension1 = dimensionality; EXEC SQL UPDATE RAS_DOMAINS SET Dimension = :dimension1 WHERE DomainId = :domainid1; if (SQLCODE != SQLOK) { check("DBMinterval::updateInDb() UPDATE RAS_DOMAINS"); generateException(); } } else { //only update dimension boundaries } } for (count1 = 0; count1 < dimensionality; count1++) { if (intervals[count1].is_low_fixed()) { low1 = intervals[count1].low(); lowind1 = 0; } else { lowind1 = -1; } if (intervals[count1].is_high_fixed()) { high1 = intervals[count1].high(); highind1 = 0; } else { highind1 = -1; } EXEC SQL UPDATE RAS_DOMAINVALUES SET Low = :low1 INDICATOR :lowind1, High = :high1 INDICATOR :highind1 WHERE DomainId = :domainid1 AND DimensionCount = :count1; if (SQLCODE != SQLOK) { check("DBMinterval::updateInDb() UPDATE RAS_DOMAINVALUES"); generateException(); } } DBObject::updateInDb(); } void DBMinterval::deleteFromDb() throw (r_Error) { EXEC SQL BEGIN DECLARE SECTION; long domainid2; EXEC SQL END DECLARE SECTION; domainid2 = myOId.getCounter(); EXEC SQL DELETE FROM RAS_DOMAINS WHERE DomainId = :domainid2; if (SQLCODE != SQLOK) { check("DBMinterval::deleteFromDb() DELETE FROM RAS_DOMAINS"); generateException(); } EXEC SQL DELETE FROM RAS_DOMAINVALUES WHERE DomainId = :domainid2; if (SQLCODE != SQLOK) { check("DBMinterval::deleteFromDb() DELETE FROM RAS_DOMAINVALUES"); generateException(); } DBObject::deleteFromDb(); } void DBMinterval::readFromDb() throw (r_Error) { char undefined = '*'; EXEC SQL BEGIN DECLARE SECTION; long domainid3; long count3; long low3; short lowind3; long high3; short highind3; long dimension3; EXEC SQL END DECLARE SECTION; domainid3 = myOId.getCounter(); EXEC SQL SELECT Dimension INTO :dimension3 FROM RAS_DOMAINS WHERE DomainId = :domainid3; if (SQLCODE != SQLOK) { check("DBMinterval::readFromDb() SELECT FROM RAS_DOMAINS"); if (SQLCODE == 100) { throw r_Error(r_Error::r_Error_ObjectUnknown); } else { generateException(); } } dimensionality = dimension3; delete[] intervals; intervals = new r_Sinterval[dimensionality]; streamInitCnt = 0; for (count3 = 0; count3 < dimension3; count3++) { EXEC SQL SELECT Low, High INTO :low3 INDICATOR :lowind3, :high3 INDICATOR :highind3 FROM RAS_DOMAINVALUES WHERE DimensionCount = :count3 AND DomainId = :domainid3; if (SQLCODE != SQLOK) { check("DBMinterval::readFromDb() SELECT FROM RAS_DOMAINVALUES"); generateException(); } if (!lowind3) { intervals[count3].set_low((r_Range)low3); } else { intervals[count3].set_low(undefined); } if (!highind3) { intervals[count3].set_high((r_Range)high3); } else { intervals[count3].set_high(undefined); } streamInitCnt++; } DBObject::readFromDb(); }