/* * 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: * - need connection via ECPG and libqg, use non-public interface to * obtain libpq style connection ptr from ECPG structure * - global variable globalConnectId used for DB server identification, maybe better as constructor parameter * - dbName parameter not evaluated * - PG: no CLUSTER index available * - PG: index always in same schema as table * - replaced "if ((SQLCODE != SQLOK) && (SQLCODE != SQLNULLFETCHED))" * by "if (SQLCODE < 0 || SQLCODE == SQLNODATAFOUND)" * - databaseExists() not used * - attribute name 'OId' -> 'UOId' (for UDFs), 'OId' -> 'Id' (for IXs) * to avoid PG name clash with attr type * - except for RAS_COUNTERS, "no data" means no error, but that we need to initialize the empty table * ***********************************************************************/ static const char rcsid[] = "@(#)reladminif,DatabaseIf: $Id: databaseif.ec,v 1.9 2003/12/27 23:11:43 rasdev Exp $"; #include "debug/debug.hh" // general embedded SQL related definitions EXEC SQL include sqlglobals.h; // SQL error codes: EXEC SQL include "externs.h" // PG stuff #include "libpq-fe.h" // C interface to PgSQL // libq-style connection ptr taken from ECPG connect (needed for libq functions): // (currently used by relblobif/blobtile.pgc) PGconn *pgConn = NULL; #include "databaseif.hh" #include "raslib/rmdebug.hh" #include "sqlerror.hh" #include "oidif.hh" #include "adminif.hh" extern char globalConnectId[256]; // size of ARCHITECTURE attribute in RAS_ADMIN: #define SIZE_ARCH_RASADMIN 20 void DatabaseIf::disconnect() throw (r_Error) { RMDBGENTER(4, RMDebug::module_adminif, "DatabaseIf", "disconnect()"); ENTER( "DatabaseIf::disconnect" ); TALK( "EXEC SQL ROLLBACK WORK" ); EXEC SQL ROLLBACK WORK; // 'ok' or 'no begin work issued' (which happens at a close database) if (SQLCODE != SQLOK && SQLCODE != -255) { check("DatabaseIf::disconnect() ROLLBACK\0"); TALK( "Error while issuing ROLLBACK"); RMDBGMIDDLE(4, RMDebug::module_adminif, "DatabaseIf", "error occured while issuing a ROLLBACK"); } TALK( "EXEC SQL DISCONNECT CURRENT" ); EXEC SQL DISCONNECT CURRENT; if (SQLCODE != SQLOK) { check("DatabaseIf::disconnect() DISCONNECT\0"); TALK( "Error while issuing DISCONNECT"); RMDBGMIDDLE(4, RMDebug::module_adminif, "DatabaseIf", "error occured while issuing a DISCONNECT"); } TALK( "PQfinish..." ); PQfinish(pgConn); pgConn = NULL; TALK( "pgConn NULL now, status: PQstatus(pgConn)=" + PQstatus(pgConn) ); LEAVE( "DatabaseIf::disconnect, SQLCODE=" << SQLCODE ); RMDBGEXIT(4, RMDebug::module_adminif, "DatabaseIf", "disconnect() SQLCODE=" << SQLCODE); } void DatabaseIf::connect() throw (r_Error) { RMDBGENTER(4, RMDebug::module_adminif, "DatabaseIf", "connect()"); ENTER( "DatabaseIf::connect" ); EXEC SQL BEGIN DECLARE SECTION; char id[STRING_MAXLEN]; EXEC SQL END DECLARE SECTION; strcpy((char *)&id, globalConnectId); TALK( "EXEC SQL CONNECT TO " << id ); EXEC SQL CONNECT TO :id AS rasdaConn; // "AS" param must be same as down in ECPGget_connection() if (SQLCODE != SQLOK) { check("DatabaseIf::connect() CONNECT"); RMDBGMIDDLE(4, RMDebug::module_adminif, "DatabaseIf", "connect() SQLCODE=" << SQLCODE); TALK( "error in connect, SQLCODE=" << SQLCODE ); generateException(); } pgConn = PQsetdb(NULL,NULL,NULL,NULL,globalConnectId); if (pgConn == NULL || PQstatus(pgConn) == CONNECTION_BAD) { RMDBGMIDDLE(4, RMDebug::module_adminif, "DatabaseIf", "Error: cannot obtain libpq connection" ); TALK( "Error: cannot obtain libpq connection" ); generateException(); } LEAVE( "DatabaseIf::connect, SQLCODE=" << SQLCODE << ", PQstatus=" << PQstatus(pgConn) ); RMDBGEXIT(4, RMDebug::module_adminif, "DatabaseIf", "connect()"); } void DatabaseIf::checkCompatibility() throw (r_Error) { RMDBGENTER(4, RMDebug::module_adminif, "DatabaseIf", "checkCompatibility()"); ENTER( "DatabaseIf::checkCompatibility" ); EXEC SQL BEGIN DECLARE SECTION; long rasver1; // rasdaman version as stored in db long schemaver1; // schema version as stored in db char* arch1[SIZE_ARCH_RASADMIN]; // used for reading architecture from db char *myArchitecture = RASARCHITECTURE; // used for architecture selection EXEC SQL END DECLARE SECTION; TALK( "EXEC SQL SELECT ServerVersion, IFVersion INTO :rasver1, :schemaver1 FROM RAS_ADMIN WHERE Architecture = " << myArchitecture ); EXEC SQL SELECT ServerVersion, IFVersion INTO :rasver1, :schemaver1 FROM RAS_ADMIN WHERE Architecture = :myArchitecture; TALK( "-> rasver1=" << rasver1 << ", schemaver1=" << schemaver1 ); if (SQLCODE != SQLOK) { check("DatabaseIf::baseDBMSOpen() check schema\0"); // this error is not supported by PG -- PB 2005-jan-07 // if (SQLCODE == SQLTABLEUNKNOWN)... if (SQLCODE == SQLNODATAFOUND) { RMInit::logOut << "The Database is incompatible with the current RasServer." << std::endl \ << "Database has no entry for the current platform." << std::endl \ << "You are using rasserver:" << std::endl \ << "\tversion " << RMANVERSION << std::endl \ << "\tschema " << RASSCHEMAVERSION << std::endl \ << "\tplatform " << RASARCHITECTURE << std::endl; EXEC SQL DECLARE admincursor CURSOR FOR SELECT ServerVersion, IFVersion, Architecture FROM RAS_ADMIN; EXEC SQL OPEN admincursor; do { (void) memset( arch1, '\0', (size_t) sizeof(arch1) ); // just to make sure string is terminated EXEC SQL FETCH admincursor INTO :rasver1, :schemaver1, :arch1; if (SQLCODE != SQLOK) { if (SQLCODE != SQLNODATAFOUND) { check("DatabaseIf::checkCompatibility()\0"); RMInit::logOut << "DBMS Error occured during compatibility check." << std::endl \ << "Please see Debug Log for additional information." << std::endl; EXEC SQL CLOSE admincursor; generateException(); } break; } RMInit::logOut << "Found database entries for rasserver:" << std::endl \ << "\tversion " << rasver1 << std::endl \ << "\tschema " << schemaver1 << std::endl \ << "\tplatform " << arch1 << std::endl << std::endl \ << "Please see Migration Documentation." << std::endl; } while (true); EXEC SQL CLOSE admincursor; throw r_Error(DATABASE_INCOMPATIBLE); } else { RMInit::logOut << "DBMS Error occured during compatibility check." << std::endl \ << "Please see Debug Log for additional information." << std::endl; generateException(); } } else { if (schemaver1 != RASSCHEMAVERSION) { RMInit::logOut << "The Database is incompatible with the current RasServer." << std::endl \ << "The database was generated with:" << std::endl \ << "\tversion " << rasver1 << std::endl \ << "\tschema " << schemaver1 << std::endl \ << "\tplatform " << arch1 << std::endl << std::endl \ << "You are using rasserver:" << std::endl \ << "\tversion " << RMANVERSION << std::endl \ << "\tschema " << RASSCHEMAVERSION << std::endl \ << "\tplatform " << RASARCHITECTURE << std::endl \ << "Please see Migration Documentation." << std::endl; throw r_Error(DATABASE_INCOMPATIBLE); } #if 0 // do not check against release, v6 has same schema as v5! -- PB 2005-sep-18 // check only against major release number -- PB 2003-sep-08 if (rasver1/1000 != RMANVERSION/1000) { RMInit::logOut << "The Database is incompatible with the current RasServer." << std::endl \ << "The database was generated with:" << std::endl \ << "\tversion " << rasver1 << std::endl \ << "\tschema " << schemaver1 << std::endl \ << "\tplatform " << arch1 << std::endl << std::endl \ << "You are using rasserver:" << std::endl \ << "\tversion " << RMANVERSION << std::endl \ << "\tschema " << RASSCHEMAVERSION << std::endl \ << "\tplatform " << RASARCHITECTURE << std::endl \ << "Please see Migration Documentation." << std::endl; throw r_Error(DATABASE_INCOMPATIBLE); } #endif // 0 } LEAVE( "DatabaseIf::checkCompatibility" ); RMDBGEXIT(4, RMDebug::module_adminif, "DatabaseIf", "checkComptatibility()"); } bool DatabaseIf::isConsistent() throw (r_Error) { RMDBGENTER(4, RMDebug::module_adminif, "DatabaseIf", "isConsistent()"); ENTER( "DatabaseIf::isConsistent" ); bool retval=true; EXEC SQL BEGIN DECLARE SECTION; long nextoid; long checkoid; // was: double -- PB 2005-jul-12 short oidind; char name2[255]; // must be able to hold counterNames elements, see oidif.cc EXEC SQL END DECLARE SECTION; nextoid = 0; checkoid = 0; oidind = 0; (void) strncpy( name2, (char*) OId::counterNames[OId::DBMINTERVALOID], (size_t) sizeof(name2) ); TALK( "EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = " << name2 ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; TALK( "-> nextoid=" << nextoid ); if (check("DatabaseIf::isConsistent() SELECT DBMINTERVALOID")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(DomainId) INTO :checkoid INDICATOR :oidind // FROM RAS_DOMAINS; checkoid = 0; TALK( "SELECT DomainId..." ); EXEC SQL SELECT DomainId INTO :checkoid INDICATOR :oidind FROM RAS_DOMAINS ORDER BY DomainId DESC LIMIT 1; TALK( "-> SQLCODE=" << SQLCODE ); // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(DomainId)"); generateException(); } if ((checkoid > nextoid) && (oidind == 0)) { RMInit::logOut << "The administrative tables for Domain Data is inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_DOMAINS : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << std::endl; retval=false; } checkoid = 0; nextoid=0; oidind=0; if(retval) { (void) strncpy( name2, (char*) OId::counterNames[OId::MDDOID], (size_t) sizeof(name2) ); TALK( "SELECT NextValue FROM RAS_COUNTERS..." ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; if (check("DatabaseIf::isConsistent() SELECT MDDOID")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(MDDId) INTO :checkoid INDICATOR :oidind // FROM RAS_MDDOBJECTS; checkoid = 0; TALK( "SELECT MDDId FROM RAS_MDDOBJECTS..." ); EXEC SQL SELECT MDDId INTO :checkoid INDICATOR :oidind FROM RAS_MDDOBJECTS ORDER BY MDDId DESC LIMIT 1; // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(MDDId)"); generateException(); } if ((checkoid > nextoid) && (oidind == 0)) { RMInit::logOut << "The administrative tables for MDD Objects is inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_MDDOBJECTS : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << std::endl; retval=false; } checkoid = 0; nextoid=0; oidind=0; } if(retval) { (void) strncpy( name2, (char*) OId::counterNames[OId::MDDCOLLOID], (size_t) sizeof(name2) ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; if (check("DatabaseIf::isConsistent() SELECT MDDCollOId")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(MDDCollId) INTO :checkoid INDICATOR :oidind // FROM RAS_MDDCOLLNAMES; checkoid = 0; TALK( "SELECT MDDCollId FROM RAS_MDDCOLLNAMES..." ); EXEC SQL SELECT MDDCollId INTO :checkoid INDICATOR :oidind FROM RAS_MDDCOLLNAMES ORDER BY MDDCollId DESC LIMIT 1; // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(MDDCollId)"); generateException(); } if ((checkoid > nextoid) && (oidind == 0)) { RMInit::logOut << "The administrative tables for MDD Collections is inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_MDDCOLLNAMES : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << std::endl; retval=false; } checkoid = 0; nextoid=0; oidind=0; } if(retval) { (void) strncpy( name2, (char*) OId::counterNames[OId::MDDTYPEOID], (size_t) sizeof(name2) ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; if (check("DatabaseIf::isConsistent() SELECT MDDTYPEOID")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(MDDTypeOId) INTO :checkoid INDICATOR :oidind // FROM RAS_MDDTYPES; checkoid = 0; TALK( "SELECT MDDTypeOId FROM RAS_MDDTYPES..." ); EXEC SQL SELECT MDDTypeOId INTO :checkoid INDICATOR :oidind FROM RAS_MDDTYPES ORDER BY MDDTypeOId DESC LIMIT 1; TALK( "SELECT MDDTypeOId FROM RAS_MDDTYPES..." ); // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(MDDTypeOId)"); generateException(); } if (checkoid > nextoid) { RMInit::logOut << "The administrative tables for MDDTypes is inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_MDDTYPES : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << " real " << nextoid << std::endl; retval=false; } checkoid = 0; nextoid=0; oidind=0; } if(retval) { (void) strncpy( name2, (char*) OId::counterNames[OId::MDDBASETYPEOID], (size_t) sizeof(name2) ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; if (check("DatabaseIf::isConsistent() SELECT MDDBASETYPEOID")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(MDDBaseTypeOId) INTO :checkoid INDICATOR :oidind // FROM RAS_MDDBASETYPES; checkoid = 0; TALK( "SELECT MDDBaseTypeOId FROM RAS_MDDBASETYPES..." ); EXEC SQL SELECT MDDBaseTypeOId INTO :checkoid INDICATOR :oidind FROM RAS_MDDBASETYPES ORDER BY MDDBaseTypeOId DESC LIMIT 1; // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(MDDBaseTypeOId)"); generateException(); } if (checkoid > nextoid) { RMInit::logOut << "The administrative tables for MDDBaseTypes is inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_MDDBASETYPES : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << " real " << nextoid << std::endl; retval=false; } checkoid = 0; nextoid=0; oidind=0; } if(retval) { (void) strncpy( name2, (char*) OId::counterNames[OId::MDDDIMTYPEOID], (size_t) sizeof(name2) ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; if (check("DatabaseIf::isConsistent() SELECT MDDDIMTYPEOID")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(MDDDimTypeOId) INTO :checkoid INDICATOR :oidind // FROM RAS_MDDDIMTYPES; checkoid = 0; TALK( "SELECT MDDDimTypeOId FROM RAS_MDDDIMTYPES..." ); EXEC SQL SELECT MDDDimTypeOId INTO :checkoid INDICATOR :oidind FROM RAS_MDDDIMTYPES ORDER BY MDDDimTypeOId DESC LIMIT 1; // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(MDDDimTypeOId)"); generateException(); } if (checkoid > nextoid) { RMInit::logOut << "The administrative tables for MDDDimensionTypes is inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_MDDDIMTYPES : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << " real " << nextoid << std::endl; retval=false; } checkoid = 0; nextoid=0; oidind=0; } if(retval) { (void) strncpy( name2, (char*) OId::counterNames[OId::MDDDOMTYPEOID], (size_t) sizeof(name2) ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; if (check("DatabaseIf::isConsistent() SELECT MDDDOMTYPEOID")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(MDDDomTypeOId) INTO :checkoid INDICATOR :oidind // FROM RAS_MDDDOMTYPES; checkoid = 0; TALK( "SELECT MDDDomTypeOId FROM RAS_MDDDOMTYPES..." ); EXEC SQL SELECT MDDDomTypeOId INTO :checkoid INDICATOR :oidind FROM RAS_MDDDOMTYPES ORDER BY MDDDomTypeOId DESC LIMIT 1; // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(MDDDomTypeId)"); generateException(); } if (checkoid > nextoid) { RMInit::logOut << "The administrative tables for MDDDomainTypes is inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_MDDDOMTYPES : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << " real " << nextoid << std::endl; retval=false; } checkoid = 0; nextoid=0; oidind=0; } if(retval) { (void) strncpy( name2, (char*) OId::counterNames[OId::STRUCTTYPEOID], (size_t) sizeof(name2) ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; if (check("DatabaseIf::isConsistent() SELECT STRUCTTYPEOID")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(BaseTypeId) INTO :checkoid INDICATOR :oidind // FROM RAS_BASETYPENAMES; checkoid = 0; TALK( "SELECT BaseTypeId FROM RAS_BASETYPENAMES..." ); EXEC SQL SELECT BaseTypeId INTO :checkoid INDICATOR :oidind FROM RAS_BASETYPENAMES ORDER BY BaseTypeId DESC LIMIT 1; // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(BaseTypeId)"); generateException(); } if ((checkoid > nextoid) && (oidind == 0)) { RMInit::logOut << "The administrative tables for StructTypes is inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_BASETYPENAMES : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << std::endl; retval=false; } checkoid = 0; nextoid=0; oidind=0; } if(retval) { (void) strncpy( name2, (char*) OId::counterNames[OId::SETTYPEOID], (size_t) sizeof(name2) ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; if (check("DatabaseIf::isConsistent() SELECT SETTYPEOID")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(SetTypeId) INTO :checkoid INDICATOR :oidind // FROM RAS_SETTYPES; checkoid = 0; TALK( "SELECT SetTypeId FROM RAS_SETTYPES..." ); EXEC SQL SELECT SetTypeId INTO :checkoid INDICATOR :oidind FROM RAS_SETTYPES ORDER BY SetTypeId DESC LIMIT 1; // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(SetTypeId)"); generateException(); } if ((checkoid > nextoid) && (oidind == 0)) { RMInit::logOut << "The administrative tables for MDDTypes is inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_SETTYPES : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << std::endl; retval=false; } checkoid = 0; nextoid=0; oidind=0; } if(retval) { (void) strncpy( name2, (char*) OId::counterNames[OId::BLOBOID], (size_t) sizeof(name2) ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; if (check("DatabaseIf::isConsistent() SELECT BLOBOID")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(BlobId) INTO :checkoid INDICATOR :oidind // FROM RAS_TILES; checkoid = 0; TALK( "SELECT BlobId FROM RAS_TILES..." ); EXEC SQL SELECT BlobId INTO :checkoid INDICATOR :oidind FROM RAS_TILES ORDER BY BlobId DESC LIMIT 1; // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(BlobId)"); generateException(); } if ((checkoid > nextoid) && (oidind == 0)) { RMInit::logOut << "The administrative tables for BLOB Data is inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_TILES : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << std::endl; retval=false; } checkoid = 0; nextoid=0; oidind=0; } if(retval) { (void) strncpy( name2, (char*) OId::counterNames[OId::MDDHIERIXOID], (size_t) sizeof(name2) ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; if (check("DatabaseIf::isConsistent() SELECT MDDHIERIXOID")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(MDDObjIxOId) INTO :checkoid INDICATOR :oidind // FROM RAS_HIERIX; checkoid = 0; TALK( "SELECT MDDObjIxOId FROM RAS_HIERIX..." ); EXEC SQL SELECT MDDObjIxOId INTO :checkoid INDICATOR :oidind FROM RAS_HIERIX ORDER BY MDDObjIxOId DESC LIMIT 1; // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(MDDObjIxOId)"); generateException(); } if (checkoid > (nextoid * 512 + OId::MDDHIERIXOID)) { RMInit::logOut << "The administrative tables for hierarchical MDD indexes is inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_HIERIX : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << " real " << (nextoid * 512 + OId::MDDHIERIXOID) << std::endl; retval=false; } checkoid = 0; nextoid=0; oidind=0; } if(retval) { (void) strncpy( name2, (char*) OId::counterNames[OId::STORAGEOID], (size_t) sizeof(name2) ); EXEC SQL SELECT NextValue INTO :nextoid FROM RAS_COUNTERS WHERE CounterName = :name2; if (check("DatabaseIf::isConsistent() SELECT STORAGEOID")) generateException(); // replaced MAX() (which ignores index) by ORDER BY variant -- PB 2005-jul-12 // EXEC SQL SELECT MAX(StorageId) INTO :checkoid INDICATOR :oidind // FROM RAS_STORAGE; checkoid=0; TALK( "SELECT StorageId FROM RAS_STORAGE..." ); EXEC SQL SELECT StorageId INTO :checkoid INDICATOR :oidind FROM RAS_STORAGE ORDER BY StorageId DESC LIMIT 1; // now "no data" means no error, but that we need to initialize the empty table if (SQLCODE < 0) { check("DatabaseIf::isConsistent() SELECT MAX(StorageId)"); generateException(); } if ((checkoid > nextoid) && (oidind == 0)) { RMInit::logOut << "Fatal error: administrative tables for MDD storage structures are inconsistent. Please call support." << std::endl; RMInit::dbgOut << std::endl << "Counter in RAS_STORAGE : " << checkoid << std::endl << "Counter in RAS_COUNTERS : " << nextoid << std::endl; retval=false; } checkoid=0; nextoid=0; oidind=0; } LEAVE( "DatabaseIf::isConsistent, retval=" << retval ); RMDBGEXIT(4, RMDebug::module_adminif, "DatabaseIf", "isConsistent() " << retval); return retval; } void DatabaseIf::createDB(const char* dbName, const char* schemaName, const char* volumeName) throw(r_Error) { RMDBGENTER(4, RMDebug::module_adminif, "DatabaseIf", "create(" << dbName << ", " << schemaName << ", " << volumeName << ")"); ENTER( "DatabaseIf::createDB, dbName=" << dbName << ", schemaName=" << schemaName << ", volumeName=" << volumeName ); int i=0; EXEC SQL BEGIN DECLARE SECTION; long id; long idd; char name[255]; EXEC SQL END DECLARE SECTION; name[0] = '\0'; // initialize to empty string try { if (AdminIf::getCurrentDatabaseIf() != 0) { RMDBGMIDDLE(5, RMDebug::module_adminif, "DatabaseIf", "another database is open"); TALK( "Error: another database is open" ); throw r_Error(r_Error::r_Error_DatabaseOpen); } connect(); TALK( "EXEC SQL BEGIN WORK;"); EXEC SQL BEGIN WORK; if(check("DatabaseIf::create() BEGIN WORK\0")) generateException(); /* not used, see comment with databaseExists() // does database exist already? if (databaseExists(dbName)) { RMDBGMIDDLE(5, RMDebug::module_adminif, "DatabaseIf", "database already exists"); RMInit::logOut << "Database creation failed: database exists already." << std::endl; TALK( "Error: database exists." ); throw r_Error(DATABASE_EXISTS); } */ // --- start table/index creation ------------------------------ // no index here because there is only one entry in the table TALK( "EXEC SQL CREATE TABLE RAS_ADMIN ( IFVersion INTEGER NOT NULL, Architecture VARCHAR(20) NOT NULL, ServerVersion INTEGER NOT NULL) " ); EXEC SQL CREATE TABLE RAS_ADMIN ( IFVersion INTEGER NOT NULL, Architecture VARCHAR(20) NOT NULL, ServerVersion INTEGER NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_ADMIN\0")) generateException(); id = RASSCHEMAVERSION; idd = RMANVERSION; (void) strncpy( name, RASARCHITECTURE, (size_t) sizeof(name) ); TALK( "EXEC SQL INSERT INTO RAS_ADMIN (IFVersion, Architecture, ServerVersion) VALUES (" << id << ", " << name << ", " << idd << ")" ); EXEC SQL INSERT INTO RAS_ADMIN (IFVersion, Architecture, ServerVersion) VALUES (:id, :name, :idd); if(check("DatabaseIf::create() INSERT INTO RAS_ADMIN\0")) generateException(); // no index here because there is only 20 entries in the table TALK( "EXEC SQL CREATE TABLE RAS_COUNTERS ( NextValue INTEGER NOT NULL, CounterName VARCHAR(20) NOT NULL)" ); EXEC SQL CREATE TABLE RAS_COUNTERS ( NextValue INTEGER NOT NULL, CounterName VARCHAR(20) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_COUNTERS\0")) generateException(); // initialising RAS_COUNTERS for(i = 1; i < OId::maxCounter; i++) { (void) strncpy( name, (char*) OId::counterNames[i], (size_t) sizeof(name) ); id = 1; TALK( "EXEC SQL INSERT INTO RAS_COUNTERS (CounterName, NextValue) VALUES (" << name << "," << id << ")" ); EXEC SQL INSERT INTO RAS_COUNTERS (CounterName, NextValue) VALUES (:name, :id); if(check("DatabaseIf::create() INSERT INTO RAS_COUNTERS\0")) generateException(); } TALK( "...and several more tables..." ); // relblobif EXEC SQL CREATE TABLE RAS_TILES ( BlobId INTEGER NOT NULL, DataFormat INTEGER, Tile oid ); if(check("DatabaseIf::create() CREATE TABLE RAS_TILES\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_TILES_IX ON RAS_TILES (BlobId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_TILES_IX\0")) generateException(); //ras_itiles EXEC SQL CREATE TABLE RAS_ITILES ( ITileId INTEGER NOT NULL, ITile oid ); if (check("DatabaseIf::create() CREATE TABLE RAS_ITILES\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_ITILES_IX ON RAS_ITILES (ITileId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_ITILES_IX\0")) generateException(); // relcatalogif EXEC SQL CREATE TABLE RAS_MDDTYPES ( MDDTypeOId DEC(15,0) NOT NULL, MDDTypeName VARCHAR(254) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_MDDTYPES\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_MDDTYPES_IX ON RAS_MDDTYPES (MDDTypeOId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_MDDTYPES_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_ITMAP ( TileId INTEGER NOT NULL, IndexId INTEGER NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_ITMAP\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_ITMAP_IX ON RAS_ITMAP (TileId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_ITMAP_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_MDDBASETYPES ( MDDBaseTypeOId DEC(15,0) NOT NULL, BaseTypeId DEC(15,0) NOT NULL, MDDTypeName VARCHAR(254) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_MDDBASETYPES\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_MDDBASETYPES_IX ON RAS_MDDBASETYPES (MDDBaseTypeOId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_MDDBASETYPES_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_MDDDIMTYPES ( MDDDimTypeOId DEC(15,0) NOT NULL, BaseTypeId DEC(15,0) NOT NULL, Dimension INTEGER NOT NULL, MDDTypeName VARCHAR(254) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_MDDDIMTYPES\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_MDDDIMTYPES_IX ON RAS_MDDDIMTYPES (MDDDimTypeOId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_MDDDIMTYPES_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_MDDDOMTYPES ( MDDDomTypeOId DEC(15,0) NOT NULL, BaseTypeId DEC(15,0) NOT NULL, DomainId INTEGER NOT NULL, MDDTypeName VARCHAR(254) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_MDDDOMAINTYPES\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_MDDDOMTYPES_IX ON RAS_MDDDOMTYPES (MDDDomTypeOId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_MDDDOMTYPES_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_SETTYPES ( SetTypeId INTEGER NOT NULL, MDDTypeOId DEC(15,0) NOT NULL, SetTypeName VARCHAR(254) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_SETTYPES\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_SETTYPES_IX ON RAS_SETTYPES (SetTypeId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_SETTYPES_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_BASETYPENAMES ( BaseTypeId SMALLINT NOT NULL, BaseTypeName VARCHAR (254) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_BASETYPENAMES\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_BASETYPENAMES_IX ON RAS_BASETYPENAMES (BaseTypeId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_BASETYPENAMES_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_BASETYPES ( BaseTypeId INTEGER NOT NULL, Count SMALLINT NOT NULL, ContentType DEC(15,0) NOT NULL, ContentTypeName VARCHAR (254) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_BASETYPES\0")) generateException(); EXEC SQL CREATE INDEX RAS_BASETYPESC_IX ON RAS_BASETYPES (BaseTypeId); if(check("DatabaseIf::create() CREATE INDEX RAS_BASETYPES_IX\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_BASETYPES_IX ON RAS_BASETYPES (BaseTypeId, Count); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_BASETYPES_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_PYRAMIDS ( PyramidName VARCHAR(240) NOT NULL, CollectionName VARCHAR(240) NOT NULL, MDDOId VARCHAR(240) NOT NULL, ScaleFactor DEC NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_PYRAMIDS\0")) generateException(); EXEC SQL CREATE TABLE RAS_DOMAINS ( DomainId INTEGER NOT NULL, Dimension INTEGER NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_DOMAINS\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_DOMAINS_IX ON RAS_DOMAINS (DomainId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_DOMAINS_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_DOMAINVALUES ( DomainId INTEGER NOT NULL, DimensionCount INTEGER NOT NULL, Low INTEGER, High INTEGER ); if(check("DatabaseIf::create() CREATE TABLE RAS_DOMAINVALUES\0")) generateException(); EXEC SQL CREATE INDEX RAS_DOMAINVALUESC_IX ON RAS_DOMAINVALUES (DomainId); if(check("DatabaseIf::create() CREATE INDEX RAS_DOMAINVALUESC_IX\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_DOMAINVALUES_IX ON RAS_DOMAINVALUES (DomainId, DimensionCount); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_DOMAINVALUES_IX\0")) generateException(); // relmddif EXEC SQL CREATE TABLE RAS_MDDCOLLECTIONS ( MDDId INTEGER NOT NULL, MDDCollId INTEGER NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_MDDCOLLECTIONS\0")) generateException(); EXEC SQL CREATE INDEX RAS_COLLECTIONSC_IX ON RAS_MDDCOLLECTIONS (MDDCOllId); if(check("DatabaseIf::create() CREATE INDEX RAS_COLLECTIONSC_IX\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_COLLECTIONS_IX ON RAS_MDDCOLLECTIONS (MDDCOllId, MDDId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_COLLECTIONS_IX\0")) generateException(); // referes to MDDSet EXEC SQL CREATE TABLE RAS_MDDCOLLNAMES ( MDDCollId INTEGER NOT NULL, SetTypeId INTEGER NOT NULL, MDDCollName VARCHAR(254) ); if(check("DatabaseIf::create() CREATE TABLE RAS_MDDCOLLNAMES\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_MDDCOLLNAMES_IX ON RAS_MDDCOLLNAMES (MDDCollId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_MDDCOLLNAMES_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_MDDOBJECTS ( MDDId INTEGER NOT NULL, BaseTypeOId DEC(15,0) NOT NULL, DomainId INTEGER NOT NULL, PersRefCount INTEGER NOT NULL, StorageOId DEC(15,0) NOT NULL, NodeOId DEC(15,0) ); if(check("DatabaseIf::create() CREATE TABLE RAS_MDDOBJECTS\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_MDDOBJECTS_IX ON RAS_MDDOBJECTS (MDDId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_MDDOBJECTS_IX\0")) generateException(); //relstorageif EXEC SQL CREATE TABLE RAS_STORAGE ( StorageId INTEGER NOT NULL, DomainId INTEGER, TileSize INTEGER, PCTMin INTEGER, PCTMax INTEGER, IndexSize INTEGER, IndexType SMALLINT, TilingScheme SMALLINT, DataFormat SMALLINT ); if(check("DatabaseIf::create() CREATE TABLE RAS_MDDOBJECTS\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_STORAGE_IX ON RAS_STORAGE (StorageId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_STORAGE_IX\0")) generateException(); // relindexif // may not be needed EXEC SQL CREATE TABLE RAS_HIERIX ( MDDObjIxOId DEC(15,0) NOT NULL, NumEntries SMALLINT NOT NULL, Dimension SMALLINT NOT NULL, ParentOId DEC(15,0) NOT NULL, IndexSubType SMALLINT NOT NULL, DynData OID ); if(check("DatabaseIf::create() CREATE TABLE RAS_HIERIX\0")) generateException(); // Note: table RAS_HIERIXDYN is not needed, we put each index node into the above DynData blob EXEC SQL CREATE TABLE RAS_UDFBODY ( UOId DEC(15,0) NOT NULL, Name VARCHAR(254) NOT NULL, Body CHAR(3700) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_UDFBODY\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_UDFBODY_IX ON RAS_UDFBODY (UOId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_UDFBODY_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_UDFARGS ( UOId DEC(15,0) NOT NULL, ArgNum SMALLINT NOT NULL, ArgName VARCHAR(254) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_UDFARGS\0")) generateException(); EXEC SQL CREATE INDEX RAS_UDFARGSC_IX ON RAS_UDFARGS(UOId); if(check("DatabaseIf::create() CREATE INDEX RAS_UDFARGSC_IX\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_UDFARGS_IX ON RAS_UDFARGS(UOId, ArgNum); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_UDFARGS_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_UDFPACKAGE ( UOId DEC(15,0) NOT NULL, Name VARCHAR(254) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_UDFPACKAGE\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_UDFPACKAGEN_IX ON RAS_UDFPACKAGE (Name); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_UDFPACKAGEN_IX\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_UDFPACKAGEO_IX ON RAS_UDFPACKAGE (UOId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_UDFPACKAGEO_IX\0")) generateException(); EXEC SQL CREATE TABLE RAS_UDFNSCONTENT ( UOId DEC(15,0) NOT NULL, UDFOId DEC(15,0) NOT NULL ); if(check("DatabaseIf::create() CREATE TABLE RAS_UDFNSCONTENT\0")) generateException(); EXEC SQL CREATE INDEX RAS_UDFNSCONTENTC_IX ON RAS_UDFNSCONTENT(UOId); if(check("DatabaseIf::create() CREATE INDEX RAS_UDFNSCONTENTC_IX\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_UDFNSCONTENT_IX ON RAS_UDFNSCONTENT(UOId, UDFOId); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_UDFNSCONTENT_IX\0")) generateException(); // We need 1 byte more because the first character may not be a \0 -> the first byte is always 13 // note: this does not hold for PG, but we keep it to remain cross-platform consistent in data // note2: we use blob instead of varchar because the latter can hold only ascii data in PG EXEC SQL CREATE TABLE RAS_RCINDEXDYN ( Id DEC(15,0) NOT NULL, Count DEC(3,0) NOT NULL, DynData oid ); if(check("DatabaseIf::create() CREATE TABLE RAS_RCINDEXDYN\0")) generateException(); EXEC SQL CREATE INDEX RAS_RCINDEXDYNC_IX ON RAS_RCINDEXDYN (Id); if(check("DatabaseIf::create() CREATE INDEX RAS_RCINDEXDYNC_IX\0")) generateException(); EXEC SQL CREATE UNIQUE INDEX RAS_RCINDEXDYN_IX ON RAS_RCINDEXDYN (Id, Count); if(check("DatabaseIf::create() CREATE UNIQUE INDEX RAS_RCINDEXDYN_IX\0")) generateException(); EXEC SQL CREATE VIEW RAS_MDDTYPES_VIEW (MDDTypeOId, MDDTypeName) AS SELECT MDDTypeOId * 512 + 3, MDDTypeName FROM RAS_MDDTYPES UNION SELECT MDDBaseTypeOId * 512 + 4, MDDTypeName FROM RAS_MDDBASETYPES UNION SELECT MDDDimTypeOId * 512 + 5, MDDTypeName FROM RAS_MDDDIMTYPES UNION SELECT MDDDomTypeOId * 512 + 6, MDDTypeName FROM RAS_MDDDOMTYPES; if(check("DatabaseIf::create() CREATE VIEW")) generateException(); TALK( "EXEC SQL COMMIT WORK" ); EXEC SQL COMMIT WORK; if(check("DatabaseIf::create() COMMIT WORK")) generateException(); disconnect(); } catch (r_Error& err) { // abort TA, ignore any error there TALK( "EXEC SQL ABORT WORK;"); EXEC SQL ABORT WORK; RMDBGMIDDLE(0, RMDebug::module_adminif, "DatabaseIf", "create(" << dbName << ", " << schemaName << ", " << volumeName << ") error caught " << err.what() << " " << err.get_errorno()); throw; // rethrow exception } LEAVE( "DatabaseIf::createDB, SQLCODE=" << SQLCODE ); RMDBGEXIT(4, RMDebug::module_adminif, "DatabaseIf", "create(" << dbName << ", " << schemaName << ", " << volumeName << ")"); } void DatabaseIf::destroyDB(const char* dbName) throw(r_Error) { RMDBGENTER(4, RMDebug::module_adminif, "DatabaseIf", "destroyDB(" << dbName << ")"); ENTER( "DatabaseIf::destroyDB, dbName=" << dbName ); if (AdminIf::getCurrentDatabaseIf() != 0) { RMDBGMIDDLE(5, RMDebug::module_adminif, "DatabaseIf", "another database is already open"); LEAVE( "Error: another database is already open" ); RMInit::logOut << "Another database is already open." << std::endl << "Cannot destroy database " << dbName << "." << std::endl; throw r_Error(r_Error::r_Error_DatabaseOpen); } connect(); /* this check is omitted, see databaseExists() comment // terminate processing of database was not found -- PB 2003-sep-05 // try // { if (!databaseExists(dbName)) { RMDBGMIDDLE(5, RMDebug::module_adminif, "DatabaseIf", "unknown database"); LEAVE( "Error: Database unknown" ); RMInit::logOut << "Database " << dbName << " not found." << std::endl << "Cannot destroy database " << dbName << "." << std::endl; throw r_Error(r_Error::r_Error_DatabaseUnknown); } // } // catch (r_Error& err) // { // RMInit::logOut << "Caught exception while trying to check for existence of database: " << err.what() << " " << err.get_errorno() << " " << err.get_kind() << endl; // RMInit::logOut << "Continuing with destruction of the database" << endl; // TALK( "Continuing destruction of the database after error " << err.get_errorno() << " " << err.get_kind() ); // } */ EXEC SQL BEGIN WORK; check("DatabaseIf::destroyDB() BEGIN WORK\0"); EXEC SQL DROP VIEW RAS_MDDTYPES_VIEW; check("DatabaseIf::destroyDB() DROP VIEW RAS_MDDTYPES_VIEW\0"); // relblobif EXEC SQL DROP TABLE RAS_TILES; check("DatabaseIf::destroyDB() DROP TABLE RAS_TILES\0"); EXEC SQL DROP TABLE RAS_ITILES; check("DatabaseIf::destroyDB() DROP TABLE RAS_ITILES\0"); // relcatalogif EXEC SQL DROP TABLE RAS_MDDTYPES; check("DatabaseIf::destroyDB() DROP TABLE RAS_MDDTYPES\0"); EXEC SQL DROP TABLE RAS_ITMAP; check("DatabaseIf::destroyDB() DROP TABLE RAS_ITMAP\0"); EXEC SQL DROP TABLE RAS_MDDBASETYPES; check("DatabaseIf::destroyDB() DROP TABLE RAS_MDDBASETYPES\0"); EXEC SQL DROP TABLE RAS_MDDDIMTYPES; check("DatabaseIf::destroyDB() DROP TABLE RAS_MDDDIMENSIONTYPES\0"); EXEC SQL DROP TABLE RAS_MDDDOMTYPES; check("DatabaseIf::destroyDB() DROP TABLE RAS_MDDDOMAINTYPES\0"); EXEC SQL DROP TABLE RAS_SETTYPES; check("DatabaseIf::destroyDB() DROP TABLE RAS_SETTYPES\0"); EXEC SQL DROP TABLE RAS_BASETYPENAMES; check("DatabaseIf::destroyDB() DROP TABLE RAS_BASETYPENAMES\0"); EXEC SQL DROP INDEX RAS_BASETYPES_IX; check("DatabaseIf::destroyDB() DROP INDEX RAS_BASETYPES_IX\0"); EXEC SQL DROP TABLE RAS_BASETYPES; check("DatabaseIf::destroyDB() DROP TABLE RAS_BASETYPES\0"); EXEC SQL DROP TABLE RAS_DOMAINS; check("DatabaseIf::destroyDB() DROP TABLE RAS_DOMAINS\0"); EXEC SQL DROP TABLE RAS_DOMAINVALUES; check("DatabaseIf::destroyDB() DROP TABLE RAS_DOMAINVALUES\0"); // relmddif // referes to DBMDDCollOIdEntry EXEC SQL DROP TABLE RAS_MDDCOLLECTIONS; check("DatabaseIf::destroyDB() DROP TABLE RAS_MDDCOLLECTIONS\0"); // referes to MDDSet EXEC SQL DROP TABLE RAS_MDDCOLLNAMES; check("DatabaseIf::destroyDB() DROP TABLE RAS_MDDCOLLNAMES\0"); EXEC SQL DROP TABLE RAS_MDDOBJECTS; check("DatabaseIf::destroyDB() DROP TABLE RAS_MDDOBJECTS\0"); // relindexif // may not be needed EXEC SQL DROP TABLE RAS_HIERIX; check("DatabaseIf::destroyDB() DROP TABLE RAS_HIERIX\0"); EXEC SQL DROP INDEX RAS_HIERIXDYN_IX; check("DatabaseIf::destroyDB() DROP INDEX RAS_HIERIXDYN_IX\0"); EXEC SQL DROP TABLE RAS_HIERIXDYN; check("DatabaseIf::destroyDB() DROP TABLE RAS_HIERIXDYN\0"); EXEC SQL DROP TABLE RAS_STORAGE; check("DatabaseIf::destroyDB() DROP TABLE RAS_STORAGE\0"); EXEC SQL DROP TABLE RAS_COUNTERS; check("DatabaseIf::destroyDB() DROP TABLE RAS_COUNTERS\0"); EXEC SQL DROP TABLE RAS_PYRAMIDS; check("DatabaseIf::destroyDB() DROP TABLE RAS_PYRAMIDS\0"); EXEC SQL DROP TABLE RAS_UDFBODY; check("DatabaseIf::destroyDB() DROP TABLE RAS_UDFBODY"); EXEC SQL DROP TABLE RAS_UDFARGS; check("DatabaseIf::destroyDB() DROP TABLE RAS_UDFARGS"); EXEC SQL DROP TABLE RAS_UDFPACKAGE; check("DatabaseIf::destroyDB() DROP TABLE RAS_UDFPACKAGE"); EXEC SQL DROP TABLE RAS_UDFNSCONTENT; check("DatabaseIf::destroyDB() DROP TABLE RAS_UDFNSCONTENT"); EXEC SQL DROP INDEX RAS_RCINDEXDYN_IX; check("DatabaseIf::destroyDB() DROP INDEX RAS_RCINDEXDYN_IX\0"); EXEC SQL DROP TABLE RAS_RCINDEXDYN; check("DatabaseIf::destroyDB() DROP TABLE RAS_RCINDEXDYN\0"); EXEC SQL DROP TABLE RAS_ADMIN; check("DatabaseIf::destroyDB() DROP TABLE RAS_ADMIN\0"); EXEC SQL COMMIT WORK; check("DatabaseIf::destroyDB() COMMIT\0"); disconnect(); LEAVE( "DatabaseIf::destroyDB" ); RMDBGEXIT(4, RMDebug::module_adminif, "DatabaseIf", "destroyDB(" << dbName << ")"); }