From: <ibr...@us...> - 2011-12-08 17:03:15
|
Revision: 4179 http://tora.svn.sourceforge.net/tora/?rev=4179&view=rev Author: ibre5041 Date: 2011-12-08 17:03:06 +0000 (Thu, 08 Dec 2011) Log Message: ----------- Modified Paths: -------------- branches/tora-trotl/sandbox/tora3/src/CMakeLists.txt branches/tora-trotl/sandbox/tora3/src/connection/tooracleprovider.cpp branches/tora-trotl/sandbox/tora3/src/core/toconnection.cpp branches/tora-trotl/sandbox/tora3/src/core/toconnection.h branches/tora-trotl/sandbox/tora3/src/core/toconnectionprovider.h branches/tora-trotl/sandbox/tora3/src/core/toglobalsetting.cpp Added Paths: ----------- branches/tora-trotl/sandbox/tora3/src/connection/tooracleconnection.cpp branches/tora-trotl/sandbox/tora3/src/connection/tooracleconnection.h branches/tora-trotl/sandbox/tora3/src/core/tocache.cpp branches/tora-trotl/sandbox/tora3/src/core/tocache.h Removed Paths: ------------- branches/tora-trotl/sandbox/tora3/src/core/tocachenew.cpp branches/tora-trotl/sandbox/tora3/src/core/tocachenew.h Modified: branches/tora-trotl/sandbox/tora3/src/CMakeLists.txt =================================================================== --- branches/tora-trotl/sandbox/tora3/src/CMakeLists.txt 2011-12-06 21:04:13 UTC (rev 4178) +++ branches/tora-trotl/sandbox/tora3/src/CMakeLists.txt 2011-12-08 17:03:06 UTC (rev 4179) @@ -323,7 +323,7 @@ core/toabout.cpp core/tobackground.cpp core/tobackgroundlabel.cpp - core/tocachenew.cpp + core/tocache.cpp core/toconfiguration.cpp core/toconnection.cpp core/toconnectionprovider.cpp @@ -678,7 +678,7 @@ # Oracle connection provider IF(ORACLE_FOUND) SET(PROVIDER_ORACLE "poracle") - ADD_LIBRARY(${PROVIDER_ORACLE} SHARED "connection/tooracleprovider.cpp") + ADD_LIBRARY(${PROVIDER_ORACLE} SHARED "connection/tooracleprovider.cpp" "connection/tooracleconnection.cpp") TARGET_LINK_LIBRARIES(${PROVIDER_ORACLE} ${TROTL_LIB} ${ORACLE_LIBRARIES} ${QT_LIBRARIES} ${TORA_LIB}) ADD_DEPENDENCIES(${PROVIDER_ORACLE} ${EXE_NAME}) ENDIF(ORACLE_FOUND) Added: branches/tora-trotl/sandbox/tora3/src/connection/tooracleconnection.cpp =================================================================== --- branches/tora-trotl/sandbox/tora3/src/connection/tooracleconnection.cpp (rev 0) +++ branches/tora-trotl/sandbox/tora3/src/connection/tooracleconnection.cpp 2011-12-08 17:03:06 UTC (rev 4179) @@ -0,0 +1,11 @@ +#include "connection/tooracleconnection.h" + +toConnectionSub* toOracleConnectionImpl::createConnection(void) +{ + return NULL; +} + +void toOracleConnectionImpl::closeConnection(toConnectionSub *) +{ + +} \ No newline at end of file Added: branches/tora-trotl/sandbox/tora3/src/connection/tooracleconnection.h =================================================================== --- branches/tora-trotl/sandbox/tora3/src/connection/tooracleconnection.h (rev 0) +++ branches/tora-trotl/sandbox/tora3/src/connection/tooracleconnection.h 2011-12-08 17:03:06 UTC (rev 4179) @@ -0,0 +1,30 @@ +#ifndef __ORACLE_CONNECTION__ +#define __ORACLE_CONNECTION__ + +#include "core/toconnection.h" + +class toOracleProvider; + +class toOracleConnectionImpl: public toConnection::connectionImpl +{ + friend class toOracleProvider; + typedef toConnection::connectionImpl super; +protected: + toOracleConnectionImpl(toConnection& con) : super(con) + { + }; +public: + /** Create a new connection to the database. */ + virtual toConnectionSub *createConnection(void); + + /** Close a connection to the database. */ + virtual void closeConnection(toConnectionSub *); +}; + +class toOracleConnectionSub: public toConnectionSub +{ + +}; + + +#endif Modified: branches/tora-trotl/sandbox/tora3/src/connection/tooracleprovider.cpp =================================================================== --- branches/tora-trotl/sandbox/tora3/src/connection/tooracleprovider.cpp 2011-12-06 21:04:13 UTC (rev 4178) +++ branches/tora-trotl/sandbox/tora3/src/connection/tooracleprovider.cpp 2011-12-08 17:03:06 UTC (rev 4179) @@ -42,13 +42,14 @@ #define TORA_DLL #include "core/toconnectionprovider.h" -#include "connection/absfact.h" #include "core/tologger.h" #include "core/utils.h" #include "core/tooracleconst.h" +#include "connection/absfact.h" #include "connection/tooracledatatype.h" #include "connection/tooraclesetting.h" +#include "connection/tooracleconnection.h" #include "trotl.h" #include "trotl_convertor.h" @@ -56,6 +57,9 @@ #include <QSettings> #include <QDir> +class toOracleConnectionImpl; +class toOracleConnectionSub; + class toOracleProvider : public toConnectionProvider { public: @@ -76,6 +80,9 @@ /** see: @ref toConnectionProvider::configurationTab() */ virtual QWidget *configurationTab(QWidget *parent); + /** see: @ref toConnection */ + virtual toConnection::connectionImpl* createConnectionImpl(toConnection&); + private: static QString m_name; }; @@ -249,4 +256,9 @@ return new toOracleSetting(parent); } +toConnection::connectionImpl* toOracleProvider::createConnectionImpl(toConnection &con) +{ + return new toOracleConnectionImpl(con); +} + Util::RegisterInFactory<toOracleProvider, ConnectionProvirerFactory> regToOracleInstantProvider(ORACLE_PROVIDER); Copied: branches/tora-trotl/sandbox/tora3/src/core/tocache.cpp (from rev 4178, branches/tora-trotl/sandbox/tora3/src/core/tocachenew.cpp) =================================================================== --- branches/tora-trotl/sandbox/tora3/src/core/tocache.cpp (rev 0) +++ branches/tora-trotl/sandbox/tora3/src/core/tocache.cpp 2011-12-08 17:03:06 UTC (rev 4179) @@ -0,0 +1,533 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * + * TOra - An Oracle Toolkit for DBA's and developers + * + * Shared/mixed copyright is held throughout files in this product + * + * Portions Copyright (C) 2000-2001 Underscore AB + * Portions Copyright (C) 2003-2005 Quest Software, Inc. + * Portions Copyright (C) 2004-2008 Numerous Other Contributors + * + * This program 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; only version 2 of + * the License is valid for this program. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries. + * + * You may link this product with any GPL'd Qt library. + * + * All trademarks belong to their respective owners. + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include "core/toCache.h" +#include "core/toconfiguration.h" +#include "core/utils.h" + +#include <QtDebug> +#include <QDir> +#include <QDateTime> +#include <QTextStream> +#include <QProgressDialog> +//#include <boost/preprocessor/iteration/detail/local.hpp> + +toCache::toCache( QString const &description) + : ConnectionDescription(description) + , refCount(1) // we assume that we were created from 1s toConnection + , state(NOT_STARTED) + , ownersRead(false) + , usersRead(false) +{ +} + +toCache::~toCache() +{ + /* The parent toConnection is locked by this instance of toCache, + wail till background thread finishes + */ + //if(cacheRefreshRunning()) + // ReadingThread.down(); + { + toExclusiveLocker lock(cacheLock); + clearCache(); + } +} + +void toCache::addEntry(toCache::CacheEntry* e) +{ + toExclusiveLocker lock(cacheLock); + switch(e->type) + { + case SYNONYM: + synonymMap.insert(e->name, e); + case TABLE: + case VIEW: + case PROCEDURE: + case FUNCTION: + case PACKAGE: + case PACKAGE_BODY: + case INDEX: + case SEQUENCE: + case TRIGGER: + case DATABASE: + case TORA_SCHEMA_LIST: + { + QString const& schema = e->name.first; + + CacheEntry const* oldValue = entryMap.value(e->name, NULL); + if( oldValue) + delete oldValue; + entryMap.insert(e->name, e); + + if( !usersMap.contains(schema)) + { + usersMap.insert(schema, new toCacheEntryUser(schema)); + } + + if( !ownersMap.contains(e->name.first)) + { + ownersMap.insert(schema, usersMap.value(schema)); + } + } + break; + case USER: + { + CacheEntry const* oldValue = usersMap.value(e->name.first, NULL); + if( oldValue == NULL) + { + usersMap.insert(e->name.first, e); + } else { + delete e; + } + } + break; + default: + ;; // HERE we ignore directories, dblinks, ... + } +}; + +toCache::CacheEntry const* toCache::findEntry(toCache::ObjectRef const& o) const +{ + toSharedLocker lock(cacheLock); + return entryMap.value(o, NULL); +} + +toCache::ObjectRef toCache::translateName(ObjectRef const& n) const +{ + toSharedLocker lock(cacheLock); + if( synonymMap.contains(n)) + return ObjectRef(synonymMap.value(n)->name); + else + return ObjectRef("", ""); +} + +void toCache::updateSchemaObjects(QString const& schema, QString const& objType, QList<toCache::CacheEntry*> const& rows) +{ + toExclusiveLocker lock(cacheLock); + CacheEntryType type = cacheEntryType(objType); + if( type == OTHER) + throw QString("toCache: Unknown object type %1").arg(objType); + + // Clear whole schema + QList<ObjectRef> objs = entryMap.keys(); // TODO there must be a better way of deleting from QMap + Q_FOREACH(ObjectRef const& o, objs) + { + if( o.first == schema && entryMap.value(o)->type == type) + entryMap.remove(o); + } + + // Add new entries in the schema + Q_FOREACH(CacheEntry* e, rows) + { + entryMap.insert(e->name, e); + } + + // Check if user/owner exists + { + if( !usersMap.contains(schema)) + { + usersMap.insert(schema, new toCacheEntryUser(schema)); + } + + if( !rows.empty() && !ownersMap.contains(schema)) + { + ownersMap.insert(schema, usersMap.value(schema)); + } + } + + if( type == SYNONYM) + { + QList<ObjectRef> objs = synonymMap.keys(); // TODO there must be a better way of deleting from QMap + Q_FOREACH(ObjectRef const& o, objs) + { + if( o.first == schema) + synonymMap.remove(o); + } + + Q_FOREACH(CacheEntry* e, rows) + { + synonymMap.insert(e->name, e); + } + } +}; + +QList<toCache::CacheEntry const*> toCache::getObjectsInSchema(QString const& schema, CacheEntryType type) const +{ + toSharedLocker lock(cacheLock); + QList<toCache::CacheEntry const*> retval; + + QList<ObjectRef> objs = entryMap.keys(); // TODO there must be a better way of searching QMap (do not copy keys) + Q_FOREACH(ObjectRef const& o, objs) + { + if( o.first == schema && (entryMap.value(o)->type == type || type == toCache::ANY)) + retval.append(entryMap.value(o)); + } + + return retval; +}; + +QList<toCache::CacheEntry const*> toCache::getObjectsInSchema(QString const& schema, QString const& type) const +{ + CacheEntryType t = cacheEntryType(type); + if(t != toCache::OTHER) + return getObjectsInSchema(schema, t); + else + return QList<toCache::CacheEntry const*>(); +}; + +/** Clear current list of users and generate a new one */ +void toCache::updateUserList(QList<CacheEntry*> const& r, UserListType listType) +{ + toExclusiveLocker lock(cacheLock); + QString username; + if( listType == USERS) + { + Q_FOREACH(CacheEntry const*e, r) + { + username = e->name.first; + if(usersMap.contains(username)) // Do not replace existing entry + delete e; + else + usersMap.insert(username, e); + } + } else { + Q_FOREACH(CacheEntry const*e, r) + { + username = e->name.first; + if(ownersMap.contains(username)) + { + delete e; + } else { + CacheEntry const* userPointer = usersMap.value(username, NULL); + if( userPointer) + { + ownersMap.insert(username, userPointer); + delete e; + } else + ownersMap.insert(username, e); + } + } + } + + if( listType == USERS) + usersRead = true; + else + ownersRead = true; +}; + +/** List of database users / database onject owners */ +QStringList toCache::userList(UserListType listType) const +{ + toSharedLocker lock(cacheLock); + QStringList retval; + QMap<QString, CacheEntry const*> const& map = (listType == USERS ? usersMap : ownersMap); + unsigned s = map.size(); + Q_FOREACH(CacheEntry const*e, map) + { + retval.append(e->name.first); + } + return retval; +}; + +bool toCache::userListExists(UserListType listType) const +{ + if( listType == USERS) + return usersRead; + else + return ownersRead; +} + +QList<toCache::CacheEntry const*> toCache::objects(bool wait) const +{ + toSharedLocker lock(cacheLock); + return entryMap.values(); +}; + +void toCache::setCacheState(CacheState c) +{ + toExclusiveLocker lock(cacheLock); + state = c; +}; + +toCache::CacheState toCache::cacheState() const +{ + toSharedLocker lock(cacheLock); + return state; +} + +void toCache::readObjects(toTask * t) +{ + if( toConfigurationSingle::Instance().objectCache() == toConfiguration::NEVER) + { + return; + } + + try + { + (new toThread(t))->start(); + ReadingThreadSemaphore.down(); // Wait till child thread starts + /// TODO migrate this too, probably somewhere in toConnection + toMainWidget()->checkCaching(); // notify main window about the change of cache's state + } + catch (...) + { + state = FAILED; + } +} + +void toCache::rereadCache(toTask * t) +{ + if( toConfigurationSingle::Instance().objectCache() == toConfiguration::NEVER) + { + toExclusiveLocker lock(cacheLock); + clearCache(); + return; + } + + if( cacheRefreshRunning()) + { + Utils::toStatusMessage(qApp->translate("toConnection", "Not done caching objects, can not clear unread cache")); + return ; + } + + ///TODO + /** delete cache file to force reload + */ + //QString filename(cacheFile()); + //if (QFile::exists(filename)) + // QFile::remove(filename); + + readObjects(t); +} + +/** + * private functions + */ +void toCache::clearCache() +{ + QList<CacheEntry const*> v = entryMap.values(); + Q_FOREACH(CacheEntry const*e, v) + { + delete e; + } + + entryMap.clear(); + synonymMap.clear(); + columnCache.clear(); + + QList<CacheEntry const*> u = usersMap.values(); + Q_FOREACH(CacheEntry const*e, u) + { + delete e; + } + ownersMap.clear(); + usersMap.clear(); +}; + +QString toCache::cacheDir() +{ + QString home(QDir::homePath()); + QString dirname(toConfigurationSingle::Instance().cacheDir()); + + if (dirname.isEmpty()) + { +#ifdef Q_OS_WIN32 + if (getenv("TEMP")) + dirname = QString(getenv("TEMP")); + else +#endif + dirname = QString(home); + dirname += "/.tora_cache"; + } + return dirname; +} // cacheDir + + +/*static*/ toCache::CacheEntryType toCache::cacheEntryType(QString const& objType) +{ + if( objType == "TABLE") + return TABLE; + else if( objType == "VIEW") + return VIEW; + else if( objType == "SYNONYM") + return SYNONYM; + else if( objType == "PROCEDURE") + return PROCEDURE; + else if( objType == "FUNCTION") + return FUNCTION; + else if( objType == "PACKAGE") + return PACKAGE; + else if( objType == "PACKAGE BODY") + return PACKAGE_BODY; + else if( objType == "INDEX") + return INDEX; + else if( objType == "SEQUENCE") + return SEQUENCE; + else if( objType == "TRIGGER") + return TRIGGER; + else if( objType == "DATABASE") + return DATABASE; + else + return OTHER; +} + +bool toCache::cacheRefreshRunning() const +{ + toSharedLocker lock(cacheLock); + return state != NOT_STARTED && state != DONE && state != FAILED; +} + +toCache::CacheEntry* toCache::createCacheEntry(const QString &objOwner, const QString &objName, const QString &objType, const QString &comment) +{ + switch(cacheEntryType(objType)) + { + case TABLE: + return new toCacheEntryTable(objOwner, objName, objType, comment); + case VIEW: + return new toCacheEntryView(objOwner, objName, objType, comment); + case SYNONYM: + return new toCacheEntrySynonym(objOwner, objName, objType, comment); + case PROCEDURE: + return new toCacheEntryProcedure(objOwner, objName, objType, comment); + case FUNCTION: + return new toCacheEntryFunction(objOwner, objName, objType, comment); + case PACKAGE: + return new toCacheEntryPackage(objOwner, objName, objType, comment); + case PACKAGE_BODY: + return new toCacheEntryPackageBody(objOwner, objName, objType, comment); + case INDEX: + return new toCacheEntryIndex(objOwner, objName, objType, comment); + case SEQUENCE: + return new toCacheEntrySequence(objOwner, objName, objType, comment); + case TRIGGER: + return new toCacheEntryTrigger(objOwner, objName, objType, comment); + case DATABASE: + return new toCacheEntryDatabase(objOwner, objName, objType, comment); + default: + return NULL; + ///throw QString("toCache: Unknown object type %1").arg(objType); + } +}; + +toCache::CacheEntry::CacheEntry(const QString &owner, const QString &objName, const QString &objType, const QString &objComment) + : name(ObjectRef(owner,objName)) + , type(cacheEntryType(objType)) + , comment(objComment) + , timestamp(QDate::currentDate()) + , described(false) +{ + if( type == OTHER) + throw QString("toCache: Unknown object type %1").arg(objType); +}; + +/** TODO delete this - this is courious constructor used to hold TORAs internal cache intries */ +toCache::CacheEntry::CacheEntry(const QString &owner, const QString &objName, toCache::CacheEntryType objType, const QString &objComment) + : name(ObjectRef(owner,objName)) + , type(objType) + , comment(objComment) +{ + if( type == OTHER) + throw QString("toCache: Unknown object type %1").arg(objType); +}; + +bool toCache::CacheEntry::operator < (const toCache::CacheEntry &other) const +{ + if( type < other.type) + return true; + if( type == other.type && name.first < other.name.first) + return true; + if( type == other.type && name.first == other.name.first && name.second < other.name.second) + return true; + return false; +}; + +bool toCache::CacheEntry::operator == (const toCache::CacheEntry &other) const +{ + return type == other.type && name == other.name; +}; + +toCacheEntryTable::toCacheEntryTable(const QString &owner, const QString &name, const QString &type, const QString &comment) + : toCache::CacheEntry(owner, name, type, comment) +{}; + +toCacheEntryView::toCacheEntryView(const QString &owner, const QString &name, const QString &type, const QString &comment) + : toCache::CacheEntry(owner, name, type, comment) +{}; + +toCacheEntrySynonym::toCacheEntrySynonym(const QString &owner, const QString &name, const QString &type, const QString &comment) + : toCache::CacheEntry(owner, name, type, comment) +{}; + +toCacheEntryProcedure::toCacheEntryProcedure(const QString &owner, const QString &name, const QString &type, const QString &comment) + : toCache::CacheEntry(owner, name, type, comment) +{}; + +toCacheEntryFunction::toCacheEntryFunction(const QString &owner, const QString &name, const QString &type, const QString &comment) + : toCache::CacheEntry(owner, name, type, comment) +{}; + +toCacheEntryPackage::toCacheEntryPackage(const QString &owner, const QString &name, const QString &type, const QString &comment) + : toCache::CacheEntry(owner, name, type, comment) +{}; + +toCacheEntryPackageBody::toCacheEntryPackageBody(const QString &owner, const QString &name, const QString &type, const QString &comment) + : toCache::CacheEntry(owner, name, type, comment) +{}; + +toCacheEntryIndex::toCacheEntryIndex(const QString &owner, const QString &name, const QString &type, const QString &comment) + : toCache::CacheEntry(owner, name, type, comment) +{}; + +toCacheEntrySequence::toCacheEntrySequence(const QString &owner, const QString &name, const QString &type, const QString &comment) + : toCache::CacheEntry(owner, name, type, comment) +{}; + +toCacheEntryTrigger::toCacheEntryTrigger(const QString &owner, const QString &name, const QString &type, const QString &comment) + : toCache::CacheEntry(owner, name, type, comment) +{}; + +toCacheEntryDatabase::toCacheEntryDatabase(const QString &owner, const QString &name, const QString &type, const QString &comment) + : toCache::CacheEntry(owner, name, type, comment) +{}; + +toCacheEntryUser::toCacheEntryUser(const QString &schema) + : toCache::CacheEntry(schema, schema, toCache::USER, "") +{}; Copied: branches/tora-trotl/sandbox/tora3/src/core/tocache.h (from rev 4178, branches/tora-trotl/sandbox/tora3/src/core/tocachenew.h) =================================================================== --- branches/tora-trotl/sandbox/tora3/src/core/tocache.h (rev 0) +++ branches/tora-trotl/sandbox/tora3/src/core/tocache.h 2011-12-08 17:03:06 UTC (rev 4179) @@ -0,0 +1,414 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * + * TOra - An Oracle Toolkit for DBA's and developers + * + * Shared/mixed copyright is held throughout files in this product + * + * Portions Copyright (C) 2000-2001 Underscore AB + * Portions Copyright (C) 2003-2005 Quest Software, Inc. + * Portions Copyright (C) 2004-2008 Numerous Other Contributors + * + * This program 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; only version 2 of + * the License is valid for this program. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exception, you have permission to link this program + * with the Oracle Client libraries and distribute executables, as long + * as you follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from Oracle client libraries. + * + * Specifically you are not permitted to link this program with the + * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. + * And you are not permitted to distribute binaries compiled against + * these libraries. + * + * You may link this product with any GPL'd Qt library. + * + * All trademarks belong to their respective owners. + * + * END_COMMON_COPYRIGHT_HEADER */ + +#ifndef TOCACHE_NEW_H +#define TOCACHE_NEW_H + +#include "core/tothread.h" +#include <QMetaType> +#include <QDate> +#include <QList> +#include <QVariant> +//#include <map> +#include <QList> +#include <QPair> +#include <QSet> + +/** Object cache for a connection. This class is accessed only through toConnection +a could be a nested class of toConnection. +*/ +class toConnection; +class toCacheEntryTable; +class toCacheEntryView; +class toCacheEntrySynonym; +class toCacheEntryFunction; +class toCacheEntryPackage; +class toCacheEntryPackageBody; +class toCacheEntryIndex; +class toCacheEntrySequence; +class toCacheEntryTrigger; + +class toGlobalSetting; + +class toCache //: public QObject +{ + friend class toConnection; + friend class toGlobalSetting; +public: + /*** Nested types ***/ + + /** Object reference, used as a lookup key + */ + typedef QPair<QString, QString> ObjectRef; // 1st schema name, 2nd object name + + /** Nested class type + */ + enum CacheEntryType + { + TABLE, + VIEW, + SYNONYM, + PROCEDURE, + FUNCTION, + PACKAGE, + PACKAGE_BODY, + INDEX, + SEQUENCE, + TRIGGER, + DATABASE, // used by MySQL + ANY, // used for querying purposes only + TORA_SCHEMA_LIST, // courious object type - used internaly by TORA, if present browser knows that that schma was read from DB + //TORA_USER_LIST, // courious object type - used internaly by TORA purpose unknown so far. + USER, + OTHER + }; + + /** Contains information about a database object. sub-classed by particular object types + */ + struct CacheEntry + { + ObjectRef name; + /** Object type + */ + CacheEntryType type; + /** Comment about this object + */ + QString comment; + /** synonyms (used for faster disk caching...) + */ + QSet<CacheEntry const*> synonyms; + + /** A date when information about this particular object was last updated + */ + QDate timestamp; + + /** String representation of cache entry details + */ + QString details; + + /** true if additional attributes were fetched from DB + */ + bool described; + + /** Create an object name with filled in values. + */ + CacheEntry(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + + /** TODO delete this - this is courious constructor used to hold TORAs internal cache intries */ + CacheEntry(const QString &owner, const QString &objName, toCache::CacheEntryType objType, const QString &objComment); + + CacheEntry(CacheEntry const& other) + : name(other.name) + , type(other.type) + , comment(other.comment) + { }; + + /** Create an empty object name. + */ + CacheEntry() { }; + + /** This class will be sub-classed by particular object Types + */ + virtual ~CacheEntry() {}; + + bool operator < (const CacheEntry &) const; + bool operator == (const CacheEntry &) const; + }; // struct CacheEntry + + /** This structure is used to describe the resultset of a query. + */ + struct ColumnDescription + { + /** Column name + */ + QString Name; + /** Datatype of string. + */ + QString Datatype; + /** If column can contain null values. + */ + bool Null; + /** Preferred alignment of this kind of value. + */ + bool AlignRight; + /** Comment on column (Only filled out in column cache. + */ + QString Comment; + }; // struct ColumnDescription + + //typedef QList<QVariant> Row; // NOTE: first (0th) value in a row is a row number (see variable currRowKey) + //typedef QList<Row> RowList; + + /** Objects state - updated by background threads + */ + enum CacheState + { + NOT_STARTED = 0, + READING_FROM_DISK, + READING_FROM_DB, + DONE, + FAILED + }; + + enum UserListType + { + USERS, + OWNERS + }; + + /** Constructuctors, destructors + */ + toCache(QString const &description); + + ~toCache(); + + /** simple cacheEntry factory */ + static CacheEntry* createCacheEntry(const QString &owner, const QString &name, const QString &type, const QString &comment); + + /** add/update new entry into cache */ + void addEntry(CacheEntry* e); + + /** Perform direct lookup on object cache - no synonym translation is made */ + CacheEntry const* findEntry(ObjectRef const&) const; + + /** Use synonymMap to resolve object name */ + ObjectRef translateName(ObjectRef const&) const; + + /** add/update a list of objects in cache. + * This should add any new object to the list as well as remove no longer + * existing ones. + */ + void updateSchemaObjects(QString const& schema, QString const& objType, QList<CacheEntry*> const& r); + + QList<CacheEntry const*> getObjectsInSchema(QString const& schema, CacheEntryType type = ANY) const; + QList<CacheEntry const*> getObjectsInSchema(QString const& schema, QString const& type) const; + + bool entryExists(QString const& schema, QString& name, CacheEntryType entryType = ANY) const; + + /** Clear current list of users and generate a new one */ + void updateUserList(QList<CacheEntry*> const&r, UserListType listType = USERS); + + /** List of database users / database onject owners */ + QStringList userList(UserListType listType = USERS) const; + + bool userListExists(UserListType listType = USERS) const; + + + /** get list of the all the objects held in the cache */ + QList<CacheEntry const*> objects(bool wait = false) const; + + /** + * Starts a new thread which will read all objects and synonyms from the database. + */ + void readObjects(toTask * t); + + /** Reread the object and column cache. + */ + void rereadCache(toTask * t); + +private: + + /** setter for cache state */ + void setCacheState(CacheState); + + /** getter for cache state */ + CacheState cacheState() const; + + CacheState state; + + QMap<ObjectRef, CacheEntry const*> entryMap; + QMap<ObjectRef, CacheEntry const*> synonymMap; + QMap<QString, CacheEntry const*> columnCache; + QMap<QString, CacheEntry const*> ownersMap, usersMap; + bool ownersRead, usersRead; + + /** Return the file used to store cache contents for this connection. + * @return A string representing a full path and filename of cache file + */ + QString cacheFile(); + + /** Return the directory storing files (caches) of all connections. + * @return A string representing a full path to cache store directory + */ + static QString cacheDir(); + + /** Load cache information for current connection from a file on disk + * @return True if cache was loaded + */ + bool loadDiskCache(void); + + /** write disk cache + */ + void writeDiskCache(void); + + /** remove all the entries from all the maps, Note: caller should lock instance state first */ + void clearCache(); + + /** translate object type name QString("TABLE") => CacheEntryType::TABLE */ + static CacheEntryType cacheEntryType(QString const& objTypeName); + + /** Non-blocking version of cacheAvailable, used by toMain to update toBackgroundLabel + */ + bool cacheRefreshRunning() const; + + + /** This lock is used by all getters and setters + an Instance of toCache is shared between multiple connections. + */ + mutable toSharedLock cacheLock; + + /* This semaphore is used to synchronize toConnection's constructor/destructor with background thread. + see: toConnection::cacheObjectsNew::run() + */ + toSemaphore ReadingThreadSemaphore; + + /** Description of connection for which this instance of cache is used. + * This name is used as a filename to store cache content between TOra runs. + */ + QString ConnectionDescription; + + /** Multiple connections can point onto same toCache instance, the last connection should delete me. + */ + QAtomicInt refCount; +}; // toCache + +/** A short representation of list<toCache::ColumnDescription> +*/ +typedef QList<toCache::ColumnDescription> toQColumnDescriptionList; +Q_DECLARE_METATYPE(toQColumnDescriptionList); + +class toCacheEntryTable : public toCache::CacheEntry +{ +public: + toCacheEntryTable(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + +private: +}; + +class toCacheEntryView : public toCache::CacheEntry +{ +public: + toCacheEntryView(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + +private: +}; + +class toCacheEntrySynonym : public toCache::CacheEntry +{ +public: + toCacheEntrySynonym(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + +private: +}; + +class toCacheEntryProcedure: public toCache::CacheEntry +{ +public: + toCacheEntryProcedure(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + +private: +}; + +class toCacheEntryFunction: public toCache::CacheEntry +{ +public: + toCacheEntryFunction(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + +private: +}; + +class toCacheEntryPackage: public toCache::CacheEntry +{ +public: + toCacheEntryPackage(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + +private: +}; + +class toCacheEntryPackageBody: public toCache::CacheEntry +{ +public: + toCacheEntryPackageBody(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + +private: +}; + +class toCacheEntryIndex: public toCache::CacheEntry +{ +public: + toCacheEntryIndex(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + +private: +}; + +class toCacheEntrySequence: public toCache::CacheEntry +{ +public: + toCacheEntrySequence(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + +private: +}; + +class toCacheEntryTrigger: public toCache::CacheEntry +{ +public: + toCacheEntryTrigger(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + +private: +}; + +class toCacheEntryDatabase: public toCache::CacheEntry +{ +public: + toCacheEntryDatabase(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + +private: +}; + +// Special "fake" cache entry - not held in entryMap +class toCacheEntryUser: public toCache::CacheEntry +{ +public: + toCacheEntryUser(const QString& user); +private: +}; + + +#endif Deleted: branches/tora-trotl/sandbox/tora3/src/core/tocachenew.cpp =================================================================== --- branches/tora-trotl/sandbox/tora3/src/core/tocachenew.cpp 2011-12-06 21:04:13 UTC (rev 4178) +++ branches/tora-trotl/sandbox/tora3/src/core/tocachenew.cpp 2011-12-08 17:03:06 UTC (rev 4179) @@ -1,492 +0,0 @@ -#include "tocachenew.h" -#include "toconfiguration.h" -#include "utils.h" -#include <QtDebug> -#include <QDir> -#include <QDateTime> -#include <QTextStream> -#include <QProgressDialog> -//#include <boost/preprocessor/iteration/detail/local.hpp> - -toCacheNew::toCacheNew( QString const &description) - : ConnectionDescription(description) - , refCount(1) // we assume that we were created from 1s toConnection - , state(NOT_STARTED) - , ownersRead(false) - , usersRead(false) -{ -} - -toCacheNew::~toCacheNew() -{ - /* The parent toConnection is locked by this instance of toCache, - wail till background thread finishes - */ - //if(cacheRefreshRunning()) - // ReadingThread.down(); - { - toExclusiveLocker lock(cacheLock); - clearCache(); - } -} - -void toCacheNew::addEntry(toCacheNew::CacheEntry* e) -{ - toExclusiveLocker lock(cacheLock); - switch(e->type) - { - case SYNONYM: - synonymMap.insert(e->name, e); - case TABLE: - case VIEW: - case PROCEDURE: - case FUNCTION: - case PACKAGE: - case PACKAGE_BODY: - case INDEX: - case SEQUENCE: - case TRIGGER: - case DATABASE: - case TORA_SCHEMA_LIST: - { - QString const& schema = e->name.first; - - CacheEntry const* oldValue = entryMap.value(e->name, NULL); - if( oldValue) - delete oldValue; - entryMap.insert(e->name, e); - - if( !usersMap.contains(schema)) - { - usersMap.insert(schema, new toCacheEntryUser(schema)); - } - - if( !ownersMap.contains(e->name.first)) - { - ownersMap.insert(schema, usersMap.value(schema)); - } - } - break; - case USER: - { - CacheEntry const* oldValue = usersMap.value(e->name.first, NULL); - if( oldValue == NULL) - { - usersMap.insert(e->name.first, e); - } else { - delete e; - } - } - break; - default: - ;; // HERE we ignore directories, dblinks, ... - } -}; - -toCacheNew::CacheEntry const* toCacheNew::findEntry(toCacheNew::ObjectRef const& o) const -{ - toSharedLocker lock(cacheLock); - return entryMap.value(o, NULL); -} - -toCacheNew::ObjectRef toCacheNew::translateName(ObjectRef const& n) const -{ - toSharedLocker lock(cacheLock); - if( synonymMap.contains(n)) - return ObjectRef(synonymMap.value(n)->name); - else - return ObjectRef("", ""); -} - -void toCacheNew::updateSchemaObjects(QString const& schema, QString const& objType, QList<toCacheNew::CacheEntry*> const& rows) -{ - toExclusiveLocker lock(cacheLock); - CacheEntryType type = cacheEntryType(objType); - if( type == OTHER) - throw QString("toCacheNew: Unknown object type %1").arg(objType); - - // Clear whole schema - QList<ObjectRef> objs = entryMap.keys(); // TODO there must be a better way of deleting from QMap - Q_FOREACH(ObjectRef const& o, objs) - { - if( o.first == schema && entryMap.value(o)->type == type) - entryMap.remove(o); - } - - // Add new entries in the schema - Q_FOREACH(CacheEntry* e, rows) - { - entryMap.insert(e->name, e); - } - - // Check if user/owner exists - { - if( !usersMap.contains(schema)) - { - usersMap.insert(schema, new toCacheEntryUser(schema)); - } - - if( !rows.empty() && !ownersMap.contains(schema)) - { - ownersMap.insert(schema, usersMap.value(schema)); - } - } - - if( type == SYNONYM) - { - QList<ObjectRef> objs = synonymMap.keys(); // TODO there must be a better way of deleting from QMap - Q_FOREACH(ObjectRef const& o, objs) - { - if( o.first == schema) - synonymMap.remove(o); - } - - Q_FOREACH(CacheEntry* e, rows) - { - synonymMap.insert(e->name, e); - } - } -}; - -QList<toCacheNew::CacheEntry const*> toCacheNew::getObjectsInSchema(QString const& schema, CacheEntryType type) const -{ - toSharedLocker lock(cacheLock); - QList<toCacheNew::CacheEntry const*> retval; - - QList<ObjectRef> objs = entryMap.keys(); // TODO there must be a better way of searching QMap (do not copy keys) - Q_FOREACH(ObjectRef const& o, objs) - { - if( o.first == schema && (entryMap.value(o)->type == type || type == toCacheNew::ANY)) - retval.append(entryMap.value(o)); - } - - return retval; -}; - -QList<toCacheNew::CacheEntry const*> toCacheNew::getObjectsInSchema(QString const& schema, QString const& type) const -{ - CacheEntryType t = cacheEntryType(type); - if(t != toCacheNew::OTHER) - return getObjectsInSchema(schema, t); - else - return QList<toCacheNew::CacheEntry const*>(); -}; - -/** Clear current list of users and generate a new one */ -void toCacheNew::updateUserList(QList<CacheEntry*> const& r, UserListType listType) -{ - toExclusiveLocker lock(cacheLock); - QString username; - if( listType == USERS) - { - Q_FOREACH(CacheEntry const*e, r) - { - username = e->name.first; - if(usersMap.contains(username)) // Do not replace existing entry - delete e; - else - usersMap.insert(username, e); - } - } else { - Q_FOREACH(CacheEntry const*e, r) - { - username = e->name.first; - if(ownersMap.contains(username)) - { - delete e; - } else { - CacheEntry const* userPointer = usersMap.value(username, NULL); - if( userPointer) - { - ownersMap.insert(username, userPointer); - delete e; - } else - ownersMap.insert(username, e); - } - } - } - - if( listType == USERS) - usersRead = true; - else - ownersRead = true; -}; - -/** List of database users / database onject owners */ -QStringList toCacheNew::userList(UserListType listType) const -{ - toSharedLocker lock(cacheLock); - QStringList retval; - QMap<QString, CacheEntry const*> const& map = (listType == USERS ? usersMap : ownersMap); - unsigned s = map.size(); - Q_FOREACH(CacheEntry const*e, map) - { - retval.append(e->name.first); - } - return retval; -}; - -bool toCacheNew::userListExists(UserListType listType) const -{ - if( listType == USERS) - return usersRead; - else - return ownersRead; -} - -QList<toCacheNew::CacheEntry const*> toCacheNew::objects(bool wait) const -{ - toSharedLocker lock(cacheLock); - return entryMap.values(); -}; - -void toCacheNew::setCacheState(CacheState c) -{ - toExclusiveLocker lock(cacheLock); - state = c; -}; - -toCacheNew::CacheState toCacheNew::cacheState() const -{ - toSharedLocker lock(cacheLock); - return state; -} - -void toCacheNew::readObjects(toTask * t) -{ - if( toConfigurationSingle::Instance().objectCache() == toConfiguration::NEVER) - { - return; - } - - try - { - (new toThread(t))->start(); - ReadingThreadSemaphore.down(); // Wait till child thread starts - /// TODO migrate this too, probably somewhere in toConnection - toMainWidget()->checkCaching(); // notify main window about the change of cache's state - } - catch (...) - { - state = FAILED; - } -} - -void toCacheNew::rereadCache(toTask * t) -{ - if( toConfigurationSingle::Instance().objectCache() == toConfiguration::NEVER) - { - toExclusiveLocker lock(cacheLock); - clearCache(); - return; - } - - if( cacheRefreshRunning()) - { - Utils::toStatusMessage(qApp->translate("toConnection", "Not done caching objects, can not clear unread cache")); - return ; - } - - ///TODO - /** delete cache file to force reload - */ - //QString filename(cacheFile()); - //if (QFile::exists(filename)) - // QFile::remove(filename); - - readObjects(t); -} - -/** - * private functions - */ -void toCacheNew::clearCache() -{ - QList<CacheEntry const*> v = entryMap.values(); - Q_FOREACH(CacheEntry const*e, v) - { - delete e; - } - - entryMap.clear(); - synonymMap.clear(); - columnCache.clear(); - - QList<CacheEntry const*> u = usersMap.values(); - Q_FOREACH(CacheEntry const*e, u) - { - delete e; - } - ownersMap.clear(); - usersMap.clear(); -}; - -QString toCacheNew::cacheDir() -{ - QString home(QDir::homePath()); - QString dirname(toConfigurationSingle::Instance().cacheDir()); - - if (dirname.isEmpty()) - { -#ifdef Q_OS_WIN32 - if (getenv("TEMP")) - dirname = QString(getenv("TEMP")); - else -#endif - dirname = QString(home); - dirname += "/.tora_cache"; - } - return dirname; -} // cacheDir - - -/*static*/ toCacheNew::CacheEntryType toCacheNew::cacheEntryType(QString const& objType) -{ - if( objType == "TABLE") - return TABLE; - else if( objType == "VIEW") - return VIEW; - else if( objType == "SYNONYM") - return SYNONYM; - else if( objType == "PROCEDURE") - return PROCEDURE; - else if( objType == "FUNCTION") - return FUNCTION; - else if( objType == "PACKAGE") - return PACKAGE; - else if( objType == "PACKAGE BODY") - return PACKAGE_BODY; - else if( objType == "INDEX") - return INDEX; - else if( objType == "SEQUENCE") - return SEQUENCE; - else if( objType == "TRIGGER") - return TRIGGER; - else if( objType == "DATABASE") - return DATABASE; - else - return OTHER; -} - -bool toCacheNew::cacheRefreshRunning() const -{ - toSharedLocker lock(cacheLock); - return state != NOT_STARTED && state != DONE && state != FAILED; -} - -toCacheNew::CacheEntry* toCacheNew::createCacheEntry(const QString &objOwner, const QString &objName, const QString &objType, const QString &comment) -{ - switch(cacheEntryType(objType)) - { - case TABLE: - return new toCacheEntryTable(objOwner, objName, objType, comment); - case VIEW: - return new toCacheEntryView(objOwner, objName, objType, comment); - case SYNONYM: - return new toCacheEntrySynonym(objOwner, objName, objType, comment); - case PROCEDURE: - return new toCacheEntryProcedure(objOwner, objName, objType, comment); - case FUNCTION: - return new toCacheEntryFunction(objOwner, objName, objType, comment); - case PACKAGE: - return new toCacheEntryPackage(objOwner, objName, objType, comment); - case PACKAGE_BODY: - return new toCacheEntryPackageBody(objOwner, objName, objType, comment); - case INDEX: - return new toCacheEntryIndex(objOwner, objName, objType, comment); - case SEQUENCE: - return new toCacheEntrySequence(objOwner, objName, objType, comment); - case TRIGGER: - return new toCacheEntryTrigger(objOwner, objName, objType, comment); - case DATABASE: - return new toCacheEntryDatabase(objOwner, objName, objType, comment); - default: - return NULL; - ///throw QString("toCacheNew: Unknown object type %1").arg(objType); - } -}; - -toCacheNew::CacheEntry::CacheEntry(const QString &owner, const QString &objName, const QString &objType, const QString &objComment) - : name(ObjectRef(owner,objName)) - , type(cacheEntryType(objType)) - , comment(objComment) - , timestamp(QDate::currentDate()) - , described(false) -{ - if( type == OTHER) - throw QString("toCacheNew: Unknown object type %1").arg(objType); -}; - -/** TODO delete this - this is courious constructor used to hold TORAs internal cache intries */ -toCacheNew::CacheEntry::CacheEntry(const QString &owner, const QString &objName, toCacheNew::CacheEntryType objType, const QString &objComment) - : name(ObjectRef(owner,objName)) - , type(objType) - , comment(objComment) -{ - if( type == OTHER) - throw QString("toCacheNew: Unknown object type %1").arg(objType); -}; - -bool toCacheNew::CacheEntry::operator < (const toCacheNew::CacheEntry &other) const -{ - if( type < other.type) - return true; - if( type == other.type && name.first < other.name.first) - return true; - if( type == other.type && name.first == other.name.first && name.second < other.name.second) - return true; - return false; -}; - -bool toCacheNew::CacheEntry::operator == (const toCacheNew::CacheEntry &other) const -{ - return type == other.type && name == other.name; -}; - -toCacheEntryTable::toCacheEntryTable(const QString &owner, const QString &name, const QString &type, const QString &comment) - : toCacheNew::CacheEntry(owner, name, type, comment) -{}; - -toCacheEntryView::toCacheEntryView(const QString &owner, const QString &name, const QString &type, const QString &comment) - : toCacheNew::CacheEntry(owner, name, type, comment) -{}; - -toCacheEntrySynonym::toCacheEntrySynonym(const QString &owner, const QString &name, const QString &type, const QString &comment) - : toCacheNew::CacheEntry(owner, name, type, comment) -{}; - -toCacheEntryProcedure::toCacheEntryProcedure(const QString &owner, const QString &name, const QString &type, const QString &comment) - : toCacheNew::CacheEntry(owner, name, type, comment) -{}; - -toCacheEntryFunction::toCacheEntryFunction(const QString &owner, const QString &name, const QString &type, const QString &comment) - : toCacheNew::CacheEntry(owner, name, type, comment) -{}; - -toCacheEntryPackage::toCacheEntryPackage(const QString &owner, const QString &name, const QString &type, const QString &comment) - : toCacheNew::CacheEntry(owner, name, type, comment) -{}; - -toCacheEntryPackageBody::toCacheEntryPackageBody(const QString &owner, const QString &name, const QString &type, const QString &comment) - : toCacheNew::CacheEntry(owner, name, type, comment) -{}; - -toCacheEntryIndex::toCacheEntryIndex(const QString &owner, const QString &name, const QString &type, const QString &comment) - : toCacheNew::CacheEntry(owner, name, type, comment) -{}; - -toCacheEntrySequence::toCacheEntrySequence(const QString &owner, const QString &name, const QString &type, const QString &comment) - : toCacheNew::CacheEntry(owner, name, type, comment) -{}; - -toCacheEntryTrigger::toCacheEntryTrigger(const QString &owner, const QString &name, const QString &type, const QString &comment) - : toCacheNew::CacheEntry(owner, name, type, comment) -{}; - -toCacheEntryDatabase::toCacheEntryDatabase(const QString &owner, const QString &name, const QString &type, const QString &comment) - : toCacheNew::CacheEntry(owner, name, type, comment) -{}; - -toCacheEntryUser::toCacheEntryUser(const QString &schema) - : toCacheNew::CacheEntry(schema, schema, toCacheNew::USER, "") -{}; Deleted: branches/tora-trotl/sandbox/tora3/src/core/tocachenew.h =================================================================== --- branches/tora-trotl/sandbox/tora3/src/core/tocachenew.h 2011-12-06 21:04:13 UTC (rev 4178) +++ branches/tora-trotl/sandbox/tora3/src/core/tocachenew.h 2011-12-08 17:03:06 UTC (rev 4179) @@ -1,374 +0,0 @@ -#ifndef TOCACHE_NEW_H -#define TOCACHE_NEW_H - -#include "tothread.h" -#include <QMetaType> -#include <QDate> -#include <QList> -#include <QVariant> -//#include <map> -#include <QList> -#include <QPair> -#include <QSet> - -/** Object cache for a connection. This class is accessed only through toConnection -a could be a nested class of toConnection. -*/ -class toConnection; -class toCacheEntryTable; -class toCacheEntryView; -class toCacheEntrySynonym; -class toCacheEntryFunction; -class toCacheEntryPackage; -class toCacheEntryPackageBody; -class toCacheEntryIndex; -class toCacheEntrySequence; -class toCacheEntryTrigger; - -class toGlobalSetting; - -class toCacheNew //: public QObject -{ - friend class toConnection; - friend class toGlobalSetting; -public: - /*** Nested types ***/ - - /** Object reference, used as a lookup key - */ - typedef QPair<QString, QString> ObjectRef; // 1st schema name, 2nd object name - - /** Nested class type - */ - enum CacheEntryType - { - TABLE, - VIEW, - SYNONYM, - PROCEDURE, - FUNCTION, - PACKAGE, - PACKAGE_BODY, - INDEX, - SEQUENCE, - TRIGGER, - DATABASE, // used by MySQL - ANY, // used for querying purposes only - TORA_SCHEMA_LIST, // courious object type - used internaly by TORA, if present browser knows that that schma was read from DB - //TORA_USER_LIST, // courious object type - used internaly by TORA purpose unknown so far. - USER, - OTHER - }; - - /** Contains information about a database object. sub-classed by particular object types - */ - struct CacheEntry - { - ObjectRef name; - /** Object type - */ - CacheEntryType type; - /** Comment about this object - */ - QString comment; - /** synonyms (used for faster disk caching...) - */ - QSet<CacheEntry const*> synonyms; - - /** A date when information about this particular object was last updated - */ - QDate timestamp; - - /** String representation of cache entry details - */ - QString details; - - /** true if additional attributes were fetched from DB - */ - bool described; - - /** Create an object name with filled in values. - */ - CacheEntry(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - - /** TODO delete this - this is courious constructor used to hold TORAs internal cache intries */ - CacheEntry(const QString &owner, const QString &objName, toCacheNew::CacheEntryType objType, const QString &objComment); - - CacheEntry(CacheEntry const& other) - : name(other.name) - , type(other.type) - , comment(other.comment) - { }; - - /** Create an empty object name. - */ - CacheEntry() { }; - - /** This class will be sub-classed by particular object Types - */ - virtual ~CacheEntry() {}; - - bool operator < (const CacheEntry &) const; - bool operator == (const CacheEntry &) const; - }; // struct CacheEntry - - /** This structure is used to describe the resultset of a query. - */ - struct ColumnDescription - { - /** Column name - */ - QString Name; - /** Datatype of string. - */ - QString Datatype; - /** If column can contain null values. - */ - bool Null; - /** Preferred alignment of this kind of value. - */ - bool AlignRight; - /** Comment on column (Only filled out in column cache. - */ - QString Comment; - }; // struct ColumnDescription - - //typedef QList<QVariant> Row; // NOTE: first (0th) value in a row is a row number (see variable currRowKey) - //typedef QList<Row> RowList; - - /** Objects state - updated by background threads - */ - enum CacheState - { - NOT_STARTED = 0, - READING_FROM_DISK, - READING_FROM_DB, - DONE, - FAILED - }; - - enum UserListType - { - USERS, - OWNERS - }; - - /** Constructuctors, destructors - */ - toCacheNew(QString const &description); - - ~toCacheNew(); - - /** simple cacheEntry factory */ - static CacheEntry* createCacheEntry(const QString &owner, const QString &name, const QString &type, const QString &comment); - - /** add/update new entry into cache */ - void addEntry(CacheEntry* e); - - /** Perform direct lookup on object cache - no synonym translation is made */ - CacheEntry const* findEntry(ObjectRef const&) const; - - /** Use synonymMap to resolve object name */ - ObjectRef translateName(ObjectRef const&) const; - - /** add/update a list of objects in cache. - * This should add any new object to the list as well as remove no longer - * existing ones. - */ - void updateSchemaObjects(QString const& schema, QString const& objType, QList<CacheEntry*> const& r); - - QList<CacheEntry const*> getObjectsInSchema(QString const& schema, CacheEntryType type = ANY) const; - QList<CacheEntry const*> getObjectsInSchema(QString const& schema, QString const& type) const; - - bool entryExists(QString const& schema, QString& name, CacheEntryType entryType = ANY) const; - - /** Clear current list of users and generate a new one */ - void updateUserList(QList<CacheEntry*> const&r, UserListType listType = USERS); - - /** List of database users / database onject owners */ - QStringList userList(UserListType listType = USERS) const; - - bool userListExists(UserListType listType = USERS) const; - - - /** get list of the all the objects held in the cache */ - QList<CacheEntry const*> objects(bool wait = false) const; - - /** - * Starts a new thread which will read all objects and synonyms from the database. - */ - void readObjects(toTask * t); - - /** Reread the object and column cache. - */ - void rereadCache(toTask * t); - -private: - - /** setter for cache state */ - void setCacheState(CacheState); - - /** getter for cache state */ - CacheState cacheState() const; - - CacheState state; - - QMap<ObjectRef, CacheEntry const*> entryMap; - QMap<ObjectRef, CacheEntry const*> synonymMap; - QMap<QString, CacheEntry const*> columnCache; - QMap<QString, CacheEntry const*> ownersMap, usersMap; - bool ownersRead, usersRead; - - /** Return the file used to store cache contents for this connection. - * @return A string representing a full path and filename of cache file - */ - QString cacheFile(); - - /** Return the directory storing files (caches) of all connections. - * @return A string representing a full path to cache store directory - */ - static QString cacheDir(); - - /** Load cache information for current connection from a file on disk - * @return True if cache was loaded - */ - bool loadDiskCache(void); - - /** write disk cache - */ - void writeDiskCache(void); - - /** remove all the entries from all the maps, Note: caller should lock instance state first */ - void clearCache(); - - /** translate object type name QString("TABLE") => CacheEntryType::TABLE */ - static CacheEntryType cacheEntryType(QString const& objTypeName); - - /** Non-blocking version of cacheAvailable, used by toMain to update toBackgroundLabel - */ - bool cacheRefreshRunning() const; - - - /** This lock is used by all getters and setters - an Instance of toCacheNew is shared between multiple connections. - */ - mutable toSharedLock cacheLock; - - /* This semaphore is used to synchronize toConnection's constructor/destructor with background thread. - see: toConnection::cacheObjectsNew::run() - */ - toSemaphore ReadingThreadSemaphore; - - /** Description of connection for which this instance of cache is used. - * This name is used as a filename to store cache content between TOra runs. - */ - QString ConnectionDescription; - - /** Multiple connections can point onto same toCache instance, the last connection should delete me. - */ - QAtomicInt refCount; -}; // toCacheNew - -/** A short representation of list<toCacheNew::ColumnDescription> -*/ -typedef QList<toCacheNew::ColumnDescription> toQColumnDescriptionList; -Q_DECLARE_METATYPE(toQColumnDescriptionList); - -class toCacheEntryTable : public toCacheNew::CacheEntry -{ -public: - toCacheEntryTable(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - -private: -}; - -class toCacheEntryView : public toCacheNew::CacheEntry -{ -public: - toCacheEntryView(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - -private: -}; - -class toCacheEntrySynonym : public toCacheNew::CacheEntry -{ -public: - toCacheEntrySynonym(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - -private: -}; - -class toCacheEntryProcedure: public toCacheNew::CacheEntry -{ -public: - toCacheEntryProcedure(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - -private: -}; - -class toCacheEntryFunction: public toCacheNew::CacheEntry -{ -public: - toCacheEntryFunction(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - -private: -}; - -class toCacheEntryPackage: public toCacheNew::CacheEntry -{ -public: - toCacheEntryPackage(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - -private: -}; - -class toCacheEntryPackageBody: public toCacheNew::CacheEntry -{ -public: - toCacheEntryPackageBody(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - -private: -}; - -class toCacheEntryIndex: public toCacheNew::CacheEntry -{ -public: - toCacheEntryIndex(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - -private: -}; - -class toCacheEntrySequence: public toCacheNew::CacheEntry -{ -public: - toCacheEntrySequence(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - -private: -}; - -class toCacheEntryTrigger: public toCacheNew::CacheEntry -{ -public: - toCacheEntryTrigger(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - -private: -}; - -class toCacheEntryDatabase: public toCacheNew::CacheEntry -{ -public: - toCacheEntryDatabase(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); - -private: -}; - -// Special "fake" cache entry - not held in entryMap -class toCacheEntryUser: public toCacheNew::CacheEntry -{ -public: - toCacheEntryUser(const QString& user); -private: -}; - - -#endif Modified: branches/tora-trotl/sandbox/tora3/src/core/toconnection.cpp =================================================================== --- branches/tora-trotl/sandbox/tora3/src/core/toconnection.cpp 2011-12-06 21:04:13 UTC (rev 4178) +++ branches/tora-trotl/sandbox/tora3/src/core/toconnection.cpp 2011-12-08 17:03:06 UTC (rev 4179) @@ -43,38 +43,23 @@ #include "core/utils.h" #include "core/tologger.h" #include "core/toconf.h" -#include "core/tothread.h" +#include "core/tocache.h" #include "core/toqvalue.h" -//#include "tohighlightedtext.h" #include "core/toconfiguration.h" +#include "core/toconnectionprovider.h" -//#include "tomain.h" -//#include "tosql.h" -//#include "totool.h" -//#include "toconnectionpool.h" - -//#include <string> -//#include <time.h> - -//#include <qapplication.h> -#include <QString> -#include <QDateTime> -#include <QPointer> -#include <QList> -#include <QSet> - toConnectionSub* toConnection::addConnection() { Utils::toBusy busy; - toConnectionSub *sub = Connection->createConnection(); + toConnectionSub *sub = pConnectionImpl->createConnection(); toLocker lock(ConnectionLock); toQList params; - foreach (QString const& i, InitStrings) + foreach (QString const& sql, InitStrings) { try { - //tool Connection->execute(su... [truncated message content] |