From: <ibr...@us...> - 2012-06-11 16:29:12
|
Revision: 4348 http://tora.svn.sourceforge.net/tora/?rev=4348&view=rev Author: ibre5041 Date: 2012-06-11 16:28:59 +0000 (Mon, 11 Jun 2012) Log Message: ----------- - sync with trunk - Do use toResultSchema for the user list in all the tools - toCache Modified Paths: -------------- branches/tora3/src/CMakeLists.txt branches/tora3/src/core/tocache.cpp branches/tora3/src/core/tocache.h branches/tora3/src/core/toglobalsetting.cpp branches/tora3/src/core/toresultcombo.cpp branches/tora3/src/core/toresultcombo.h branches/tora3/src/core/toresultplan.cpp branches/tora3/src/core/toresultschema.cpp branches/tora3/src/core/toresultschema.h branches/tora3/src/core/totableselect.cpp branches/tora3/src/core/totableselect.h branches/tora3/src/toawr.cpp branches/tora3/src/todebug.cpp branches/tora3/src/todebug.h branches/tora3/src/tools/toanalyze.cpp branches/tora3/src/tools/toanalyze.h branches/tora3/src/tools/tobrowser.cpp branches/tora3/src/tools/tobrowser.h branches/tora3/src/tools/tobrowsertable.cpp branches/tora3/src/tools/tobrowsertableui.ui branches/tora3/src/tools/tosession.cpp branches/tora3/src/tools/tosession.h branches/tora3/src/tools/tosgatrace.cpp branches/tora3/src/tools/tosgatrace.h branches/tora3/src/tools/toworksheet.cpp branches/tora3/src/toplsqleditor.cpp branches/tora3/src/toplsqleditor.h branches/tora3/src/tounittest.cpp Added Paths: ----------- branches/tora3/src/tocacheold.cpp branches/tora3/src/tocacheold.h Removed Paths: ------------- branches/tora3/src/tocache.cpp branches/tora3/src/tocache.h Modified: branches/tora3/src/CMakeLists.txt =================================================================== --- branches/tora3/src/CMakeLists.txt 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/CMakeLists.txt 2012-06-11 16:28:59 UTC (rev 4348) @@ -203,6 +203,7 @@ core/topiechart.h core/toeditablemenu.h core/tosyntaxsetup.h + core/tocache.h ts_log/toostream.h @@ -249,7 +250,7 @@ # # tobrowserschemabasewidget.h # # toconf.h # # toconfiguration.h - # #tocache.h + # toconnectionpool.h # tocurrent.h Modified: branches/tora3/src/core/tocache.cpp =================================================================== --- branches/tora3/src/core/tocache.cpp 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/core/tocache.cpp 2012-06-11 16:28:59 UTC (rev 4348) @@ -40,6 +40,7 @@ #include "core/tocache.h" #include "core/toconfiguration.h" +#include "core/toraversion.h" #include "core/utils.h" #include <QtDebug> @@ -47,11 +48,18 @@ #include <QDateTime> #include <QTextStream> #include <QProgressDialog> +#include <QDataStream> //#include <boost/preprocessor/iteration/detail/local.hpp> +// Forward declarations +// Allow cache entries to be serialized / de-serialized +QDataStream& operator<< (QDataStream& stream, const toCache::CacheEntry& e); +QDataStream& operator>> (QDataStream& stream, toCache::CacheEntry& e); + toCache::toCache( QString const &description) - : ConnectionDescription(description) - , refCount(1) // we assume that we were created from 1s toConnection + : QObject(NULL) + , ConnectionDescription(description) + , refCount(1) // we assume that we were created from 1st toConnection , state(NOT_STARTED) , ownersRead(false) , usersRead(false) @@ -100,6 +108,7 @@ if( !usersMap.contains(schema)) { usersMap.insert(schema, new toCacheEntryUser(schema)); + emit userListRefreshed(); } if( !ownersMap.contains(e->name.first)) @@ -335,16 +344,206 @@ return ; } - ///TODO /** delete cache file to force reload */ - //QString filename(cacheFile()); - //if (QFile::exists(filename)) - // QFile::remove(filename); + QFileInfo filename(cacheFile()); + if (filename.isFile()) + QFile::remove(filename.absoluteFilePath()); readObjects(t); } +QDir 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 + +QFileInfo toCache::cacheFile() +{ + QString ret (ConnectionDescription.trimmed()); + // using instantclient connectionstrins can result in file name like this: + // isepl_global_stage@//oraclexe11:1521/xe + // which is invalid. Just remove "/" or replace it with something safer. + ret = ret.replace("/", "_"); + ret = ret.replace(":", "~"); + ret += ".bin"; + + return QFileInfo(cacheDir(), ret); +} // cacheFile + +void toCache::writeDiskCache() +{ + QString text; + qint64 objCounter = 0; + qint64 synCounter = 0; + + if (!toConfigurationSingle::Instance().cacheDisk()) + return; + + QFileInfo fileInfo(cacheFile()); + QDir dir(cacheDir()); + + if (!dir.exists()) + dir.mkdir(dir.absolutePath()); + + QString version = QString::fromLatin1(TORAVERSION); + + QFile file(fileInfo.absoluteFilePath()); +//TODO #warn "throw something here" + if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) + return; + + { + toSharedLocker lock(cacheLock); + + QDataStream out(&file); + out << version; // Tora version + out << (quint8)state; // cache state + out << ownersRead; + out << usersRead; + out << ConnectionDescription; + + // TODO Write a gap here. + // then write the whole cache, rewind, + + out << (quint32) entryMap.size(); + out << (quint32) synonymMap.size(); + out << (quint32) columnCache.size(); + out << (quint32) ownersMap.size(); + out << (quint32) usersMap.size(); + + QList<CacheEntry const*> vEntryMap = entryMap.values(); + Q_FOREACH(CacheEntry const*e, vEntryMap) + { + out << (*e); + } + // TODO this can be avoided + QList<CacheEntry const*> vSynonymMap = synonymMap.values(); + Q_FOREACH(CacheEntry const*e, vSynonymMap) + { + out << (*e); + } + + QList<CacheEntry const*> vColumnCache = columnCache.values(); + Q_FOREACH(CacheEntry const*e, vColumnCache) + { + out << (*e); + } + + QList<CacheEntry const*> vOwnersMap = ownersMap.values(); + Q_FOREACH(CacheEntry const*e, vOwnersMap) + { + out << (*e); + } + + QList<CacheEntry const*> vUsersMap = usersMap.values(); + Q_FOREACH(CacheEntry const*e, vUsersMap) + { + out << (*e); + } + + file.flush(); + file.close(); + } +} + +bool toCache::loadDiskCache() +{ + if (!toConfigurationSingle::Instance().cacheDisk()) + return false; + + QFileInfo fileInfo(cacheFile()); + QDir dir(cacheDir()); + + if (!dir.exists()) + dir.mkdir(dir.absolutePath()); + + QString version = QString::fromLatin1(TORAVERSION); + QDateTime today; + + if(!fileInfo.isReadable()) + return false; + + if (fileInfo.lastModified().addDays(toConfigurationSingle::Instance().cacheTimeout()) < today) + return false; + + clearCache(); + +//#warn TODO "throw something here + quint32 entryMapSize, synonymMapSize, columnCacheSize, ownersMapSize, usersMapSize; + QFile file(fileInfo.absoluteFilePath()); + file.open(QIODevice::ReadOnly); + QDataStream in(&file); + { + toExclusiveLocker lock(cacheLock); + quint8 s; + + in >> version; // Tora version + in >> s; state = (CacheState)s; // cache state + in >> ownersRead; + in >> usersRead; + in >> ConnectionDescription; + + in >> entryMapSize; + in >> synonymMapSize; + in >> columnCacheSize; + in >> ownersMapSize; + in >> usersMapSize; + } + for(int i = 0; i < entryMapSize; i++) + { + CacheEntry e, *clone; + in >> e; + clone = cloneCacheEntry(e); + if( clone != NULL) + addEntry(cloneCacheEntry(e)); + } + + // TODO this can be avoided (probably) + for(int i = 0; i < synonymMapSize; i++) + { + CacheEntry e, *clone; + in >> e; + } + for(int i = 0; i < columnCacheSize; i++) + { + CacheEntry e, *clone; + in >> e; + } + for(int i = 0; i < ownersMapSize; i++) + { + CacheEntry e, *clone; + in >> e; + clone = cloneCacheEntry(e); + if( clone != NULL) + addEntry(cloneCacheEntry(e)); + } + for(int i = 0; i < usersMapSize; i++) + { + CacheEntry e, *clone; + in >> e; + clone = cloneCacheEntry(e); + if( clone != NULL) + addEntry(cloneCacheEntry(e)); + } + + file.close(); + return true; +} + /** * private functions */ @@ -369,25 +568,6 @@ 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") @@ -416,44 +596,87 @@ return OTHER; } +/*static*/ QString toCache::cacheEntryTypeToString(toCache::CacheEntryType objType) +{ + switch(objType) + { + case TABLE: + return "TABLE"; + case VIEW: + return "VIEW"; + case SYNONYM: + return "SYNONYM"; + case PROCEDURE: + return "PROCEDURE"; + case FUNCTION: + return "FUNCTION"; + case PACKAGE: + return "PACKAGE"; + case PACKAGE_BODY: + return "PACKAGE BODY"; + case INDEX: + return "INDEX"; + case SEQUENCE: + return "SEQUENCE"; + case TRIGGER: + return "TRIGGER"; + case DATABASE: + return "DATABASE"; + default: + //return NULL; + throw QString("toCacheNew: Unknown object type %1").arg((quint32)objType); + } +} + 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) +toCache::CacheEntry* toCache::createCacheEntry(const QString &objOwner, const QString &objName, CacheEntryType objType, const QString &comment) { - switch(cacheEntryType(objType)) + switch(objType) { case TABLE: - return new toCacheEntryTable(objOwner, objName, objType, comment); + return new toCacheEntryTable(objOwner, objName, comment); case VIEW: - return new toCacheEntryView(objOwner, objName, objType, comment); + return new toCacheEntryView(objOwner, objName, comment); case SYNONYM: - return new toCacheEntrySynonym(objOwner, objName, objType, comment); + return new toCacheEntrySynonym(objOwner, objName, comment); case PROCEDURE: - return new toCacheEntryProcedure(objOwner, objName, objType, comment); + return new toCacheEntryProcedure(objOwner, objName, comment); case FUNCTION: - return new toCacheEntryFunction(objOwner, objName, objType, comment); + return new toCacheEntryFunction(objOwner, objName, comment); case PACKAGE: - return new toCacheEntryPackage(objOwner, objName, objType, comment); + return new toCacheEntryPackage(objOwner, objName, comment); case PACKAGE_BODY: - return new toCacheEntryPackageBody(objOwner, objName, objType, comment); + return new toCacheEntryPackageBody(objOwner, objName, comment); case INDEX: - return new toCacheEntryIndex(objOwner, objName, objType, comment); + return new toCacheEntryIndex(objOwner, objName, comment); case SEQUENCE: - return new toCacheEntrySequence(objOwner, objName, objType, comment); + return new toCacheEntrySequence(objOwner, objName, comment); case TRIGGER: - return new toCacheEntryTrigger(objOwner, objName, objType, comment); + return new toCacheEntryTrigger(objOwner, objName, comment); case DATABASE: - return new toCacheEntryDatabase(objOwner, objName, objType, comment); + return new toCacheEntryDatabase(objOwner, objName, comment); default: - return NULL; + return NULL; // Do ignore some object types, like DBLINK or CLUSTER for example ///throw QString("toCache: Unknown object type %1").arg(objType); } +} + +toCache::CacheEntry* toCache::createCacheEntry(const QString &objOwner, const QString &objName, const QString &objTypeStr, const QString &comment) +{ + CacheEntryType objType = cacheEntryType(objTypeStr); + return createCacheEntry(objOwner, objName, objType, comment); }; +toCache::CacheEntry* toCache::cloneCacheEntry(CacheEntry const& other) +{ + return createCacheEntry(other.name.first, other.name.second, other.type, other.comment); +} + toCache::CacheEntry::CacheEntry(const QString &owner, const QString &objName, const QString &objType, const QString &objComment) : name(ObjectRef(owner, objName)) , type(cacheEntryType(objType)) @@ -470,9 +693,11 @@ : name(ObjectRef(owner, objName)) , type(objType) , comment(objComment) + , timestamp(QDate::currentDate()) + , described(false) { if( type == OTHER) - throw QString("toCache: Unknown object type %1").arg(objType); + throw QString("toCache: Unknown object type %1").arg((quint8)objType); }; bool toCache::CacheEntry::operator < (const toCache::CacheEntry &other) const @@ -491,48 +716,65 @@ 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) +QDataStream& operator<< (QDataStream& stream, const toCache::CacheEntry& e) +{ + stream << e.name << (quint32)e.type << e.comment << e.timestamp << e.details; + return stream; +} + +QDataStream& operator>> (QDataStream& stream, toCache::CacheEntry& e) +{ + quint8 type; + + stream >> e.name >> type >> e.comment >> e.timestamp >> e.details; + + e.type = (toCache::CacheEntryType) type; + e.described = false; + return stream; +} + +toCacheEntryTable::toCacheEntryTable(const QString &owner, const QString &name, const QString &comment) + : toCache::CacheEntry(owner, name, toCache::TABLE, comment) {}; -toCacheEntryView::toCacheEntryView(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 &comment) + : toCache::CacheEntry(owner, name, toCache::VIEW, comment) {}; -toCacheEntrySynonym::toCacheEntrySynonym(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 &comment) + : toCache::CacheEntry(owner, name, toCache::SYNONYM, comment) {}; -toCacheEntryProcedure::toCacheEntryProcedure(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 &comment) + : toCache::CacheEntry(owner, name, toCache::PROCEDURE, comment) {}; -toCacheEntryFunction::toCacheEntryFunction(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 &comment) + : toCache::CacheEntry(owner, name, toCache::FUNCTION, comment) {}; -toCacheEntryPackage::toCacheEntryPackage(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 &comment) + : toCache::CacheEntry(owner, name, toCache::PACKAGE, comment) {}; -toCacheEntryPackageBody::toCacheEntryPackageBody(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 &comment) + : toCache::CacheEntry(owner, name, toCache::PACKAGE_BODY, comment) {}; -toCacheEntryIndex::toCacheEntryIndex(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 &comment) + : toCache::CacheEntry(owner, name, toCache::INDEX, comment) {}; -toCacheEntrySequence::toCacheEntrySequence(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 &comment) + : toCache::CacheEntry(owner, name, toCache::SEQUENCE, comment) {}; -toCacheEntryTrigger::toCacheEntryTrigger(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 &comment) + : toCache::CacheEntry(owner, name, toCache::TRIGGER, comment) {}; -toCacheEntryDatabase::toCacheEntryDatabase(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 &comment) + : toCache::CacheEntry(owner, name, toCache::DATABASE, comment) {}; toCacheEntryUser::toCacheEntryUser(const QString &schema) Modified: branches/tora3/src/core/tocache.h =================================================================== --- branches/tora3/src/core/tocache.h 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/core/tocache.h 2012-06-11 16:28:59 UTC (rev 4348) @@ -67,8 +67,14 @@ class toGlobalSetting; -class toCache //: public QObject +class QDataStream; +class QFileInfo; +class QDir; + +class toCache : public QObject { + Q_OBJECT; + friend class toConnection; friend class toGlobalSetting; public: @@ -80,9 +86,9 @@ /** Nested class type */ - enum CacheEntryType + enum CacheEntryType : quint8 { - TABLE, + TABLE = 1, VIEW, SYNONYM, PROCEDURE, @@ -94,7 +100,7 @@ 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_SCHEMA_LIST, // courious object type - used internaly by TORA, if present browser knows that that schema was read from DB //TORA_USER_LIST, // courious object type - used internaly by TORA purpose unknown so far. USER, OTHER @@ -148,8 +154,12 @@ */ virtual ~CacheEntry() {}; + /** Fetch additional information from the DB */ + virtual void describe() {}; + bool operator < (const CacheEntry &) const; bool operator == (const CacheEntry &) const; + }; // struct CacheEntry /** This structure is used to describe the resultset of a query. @@ -178,7 +188,7 @@ /** Objects state - updated by background threads */ - enum CacheState + enum CacheState : quint8 { NOT_STARTED = 0, READING_FROM_DISK, @@ -201,6 +211,8 @@ /** simple cacheEntry factory */ static CacheEntry* createCacheEntry(const QString &owner, const QString &name, const QString &type, const QString &comment); + static CacheEntry* createCacheEntry(const QString &owner, const QString &name, CacheEntryType type, const QString &comment); + static CacheEntry* cloneCacheEntry(CacheEntry const& other); /** add/update new entry into cache */ void addEntry(CacheEntry* e); @@ -262,12 +274,12 @@ /** 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(); + QFileInfo cacheFile(); /** Return the directory storing files (caches) of all connections. * @return A string representing a full path to cache store directory */ - static QString cacheDir(); + static QDir cacheDir(); /** Load cache information for current connection from a file on disk * @return True if cache was loaded @@ -284,6 +296,9 @@ /** translate object type name QString("TABLE") => CacheEntryType::TABLE */ static CacheEntryType cacheEntryType(QString const& objTypeName); + /** translate object type CacheEntryType::TABLE => QString("TABLE") */ + static QString cacheEntryTypeToString(CacheEntryType objType); + /** Non-blocking version of cacheAvailable, used by toMain to update toBackgroundLabel */ bool cacheRefreshRunning() const; @@ -307,8 +322,11 @@ /** Multiple connections can point onto same toCache instance, the last connection should delete me. */ QAtomicInt refCount; -}; // toCache +signals: + void userListRefreshed(void); +}; // toCacheNew + /** A short representation of list<toCache::ColumnDescription> */ typedef QList<toCache::ColumnDescription> toQColumnDescriptionList; @@ -317,7 +335,7 @@ class toCacheEntryTable : public toCache::CacheEntry { public: - toCacheEntryTable(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + toCacheEntryTable(const QString &owner, const QString &name, const QString &comment = QString::null); private: }; @@ -325,7 +343,7 @@ class toCacheEntryView : public toCache::CacheEntry { public: - toCacheEntryView(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + toCacheEntryView(const QString &owner, const QString &name, const QString &comment = QString::null); private: }; @@ -333,7 +351,7 @@ class toCacheEntrySynonym : public toCache::CacheEntry { public: - toCacheEntrySynonym(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + toCacheEntrySynonym(const QString &owner, const QString &name, const QString &comment = QString::null); private: }; @@ -341,7 +359,7 @@ class toCacheEntryProcedure: public toCache::CacheEntry { public: - toCacheEntryProcedure(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + toCacheEntryProcedure(const QString &owner, const QString &name, const QString &comment = QString::null); private: }; @@ -349,7 +367,7 @@ class toCacheEntryFunction: public toCache::CacheEntry { public: - toCacheEntryFunction(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + toCacheEntryFunction(const QString &owner, const QString &name, const QString &comment = QString::null); private: }; @@ -357,7 +375,7 @@ class toCacheEntryPackage: public toCache::CacheEntry { public: - toCacheEntryPackage(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + toCacheEntryPackage(const QString &owner, const QString &name, const QString &comment = QString::null); private: }; @@ -365,7 +383,7 @@ class toCacheEntryPackageBody: public toCache::CacheEntry { public: - toCacheEntryPackageBody(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + toCacheEntryPackageBody(const QString &owner, const QString &name, const QString &comment = QString::null); private: }; @@ -373,7 +391,7 @@ class toCacheEntryIndex: public toCache::CacheEntry { public: - toCacheEntryIndex(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + toCacheEntryIndex(const QString &owner, const QString &name, const QString &comment = QString::null); private: }; @@ -381,7 +399,7 @@ class toCacheEntrySequence: public toCache::CacheEntry { public: - toCacheEntrySequence(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + toCacheEntrySequence(const QString &owner, const QString &name, const QString &comment = QString::null); private: }; @@ -389,7 +407,7 @@ class toCacheEntryTrigger: public toCache::CacheEntry { public: - toCacheEntryTrigger(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + toCacheEntryTrigger(const QString &owner, const QString &name, const QString &comment = QString::null); private: }; @@ -397,7 +415,7 @@ class toCacheEntryDatabase: public toCache::CacheEntry { public: - toCacheEntryDatabase(const QString &owner, const QString &name, const QString &type, const QString &comment = QString::null); + toCacheEntryDatabase(const QString &owner, const QString &name, const QString &comment = QString::null); private: }; Modified: branches/tora3/src/core/toglobalsetting.cpp =================================================================== --- branches/tora3/src/core/toglobalsetting.cpp 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/core/toglobalsetting.cpp 2012-06-11 16:28:59 UTC (rev 4348) @@ -191,7 +191,7 @@ /** disk caching options */ - CacheDirectory->setText(toCache::cacheDir()); + CacheDirectory->setText(toCache::cacheDir().absolutePath()); DiskCaching->setChecked(toConfigurationSingle::Instance().cacheDisk()); CustomSQL->setText(toConfigurationSingle::Instance().sqlFile()); Modified: branches/tora3/src/core/toresultcombo.cpp =================================================================== --- branches/tora3/src/core/toresultcombo.cpp 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/core/toresultcombo.cpp 2012-06-11 16:28:59 UTC (rev 4348) @@ -40,6 +40,7 @@ * END_COMMON_COPYRIGHT_HEADER */ #include "core/toresultcombo.h" +#include "core/toresultschema.h" #include "core/utils.h" #include "core/toconf.h" #include "core/toconnection.h" @@ -54,7 +55,9 @@ connect(this, SIGNAL(activated(int)), this, SLOT(changeSelected(void))); setSizeAdjustPolicy(QComboBox::AdjustToContents); - queryingUserlist = false; + //queryingUserlist = false; + + connect(&(connection().getCache()), SIGNAL(userListRefreshed()), this, SLOT(usersFromCache())); } toResultCombo::~toResultCombo() @@ -76,10 +79,22 @@ if (Additional[i] == Selected) setCurrentIndex(i); + // NOTE: delete this block. It is just a runtime check. + // It should find all the instances of toResultCombo who use q TOSQL_USERLIST. + // All those should be migrated into toResultSchema + toResultSchema* d = dynamic_cast<toResultSchema*>(this); + if ( d == NULL) + { + if (sql == toSQL::string(toSQL::TOSQL_USERLIST, connection())) + { + throw QString::fromLatin1("Illegal usage"); + } + } + if (sql != toSQL::string(toSQL::TOSQL_USERLIST, connection()) || !connection().getCache().userListExists(toCache::USERS)) { - queryingUserlist = true; + //queryingUserlist = true; userList.clear(); Query = new toEventQuery(connection(), /*toQuery::Background,*/ sql, param); connect(Query, SIGNAL(dataAvailable()), this, SLOT(poll())); @@ -89,20 +104,27 @@ } else { - QStringList users = connection().getCache().userList(toCache::USERS); - for (QStringList::iterator i = users.begin(); i != users.end(); i++) - { - QString t = (*i); - addItem(t); - if (t == Selected) - setCurrentIndex(count() - 1); - } - queryDone(); + usersFromCache(); } } TOCATCH } +// NOTE: this is nonsense too. This should be moved into toResultSchema +void toResultCombo::usersFromCache(void) +{ + QStringList users = connection().getCache().userList(toCache::USERS); + for (QStringList::iterator i = users.begin(); i != users.end(); i++) + { + QString t = (*i); + addItem(t); + if (t == Selected) + setCurrentIndex(count() - 1); + } + queryDone(); +} + + void toResultCombo::changeSelected(void) { Selected = currentText(); @@ -127,10 +149,10 @@ l.append(v); } addItem(t, QVariant(l)); - if (queryingUserlist) - { - userList.append(new toCacheEntryUser(t)); - } +// if (queryingUserlist) +// { +// userList.append(new toCacheEntryUser(t)); +// } if (t == Selected) setCurrentIndex(count() - 1); } @@ -166,11 +188,16 @@ updateGeometry(); // If we were querying user list - save it to cache - if (queryingUserlist) - { - connection().getCache().updateUserList(userList, toCache::USERS); - userList.clear(); - } +// if (queryingUserlist) +// { +// connection().getCache().updateUserList(userList, toCache::USERS); +// userList.clear(); +// } emit done(); } // queryDone + +void toResultCombo::refresh(void) +{ + toResult::refresh(); +} Modified: branches/tora3/src/core/toresultcombo.h =================================================================== --- branches/tora3/src/core/toresultcombo.h 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/core/toresultcombo.h 2012-06-11 16:28:59 UTC (rev 4348) @@ -65,7 +65,7 @@ QString Selected; QStringList Additional; - bool queryingUserlist; + //bool queryingUserlist; QList<toCache::CacheEntry*> userList; public: @@ -85,7 +85,7 @@ toResultCombo(QWidget *parent, const char *name = NULL); /** Destruct object */ - ~toResultCombo(); + virtual ~toResultCombo(); /** Reimplemented for internal reasons. */ @@ -130,7 +130,7 @@ } // Why are these needed? -#if 1 +#if 0 /** Set the SQL statement of this list * @param sql String containing statement. */ @@ -177,10 +177,7 @@ public slots: /** Reimplemented for internal reasons. */ - virtual void refresh(void) - { - toResult::refresh(); - } + virtual void refresh(void); /** Reimplemented for internal reasons. */ virtual void changeParams(const QString &Param1) @@ -199,6 +196,8 @@ { toResult::changeParams(Param1, Param2, Param3); } + + void usersFromCache(void); private slots: void poll(void); void queryDone(void); Modified: branches/tora3/src/core/toresultplan.cpp =================================================================== --- branches/tora3/src/core/toresultplan.cpp 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/core/toresultplan.cpp 2012-06-11 16:28:59 UTC (rev 4348) @@ -365,10 +365,11 @@ TopItem->setToolTip(1, queryText); CursorChildSel = new toResultCombo(this, "toResultPlan"); + CursorChildSel->setSQL(toSQL::string(SQLVSQLChildSel, conn).arg(Ident)); CursorChildSel->setSelectionPolicy(toResultCombo::First); try { - CursorChildSel->query(toSQL::string(SQLVSQLChildSel, conn).arg(Ident)); + CursorChildSel->refresh(); } TOCATCH; setItemWidget(TopItem, 3, CursorChildSel); Modified: branches/tora3/src/core/toresultschema.cpp =================================================================== --- branches/tora3/src/core/toresultschema.cpp 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/core/toresultschema.cpp 2012-06-11 16:28:59 UTC (rev 4348) @@ -46,13 +46,13 @@ #include <QSettings> -toResultSchema::toResultSchema(toConnection &conn, - QWidget *parent, +toResultSchema::toResultSchema(QWidget *parent, const char *name) : toResultCombo(parent, name) { setSQL(toSQL::sql(toSQL::TOSQL_USERLIST)); + toConnection &conn = toConnection::currentConnection(parent); ConnectionKey = conn.provider() + "-" + conn.host() + "-" + @@ -145,3 +145,14 @@ QSettings s; s.setValue("schema/" + ConnectionKey, schema); } + +void toResultSchema::refresh(void) +{ + try { + toResultCombo::refresh(); + } + catch (...) + { + TLOG(1,toDecorator,__HERE__) << " Ignored exception." << std::endl; + } +} Modified: branches/tora3/src/core/toresultschema.h =================================================================== --- branches/tora3/src/core/toresultschema.h 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/core/toresultschema.h 2012-06-11 16:28:59 UTC (rev 4348) @@ -47,7 +47,6 @@ class toConnection; - /** * This widget displays a list of schemas * @@ -65,11 +64,13 @@ * * @param parent Parent widget. * @param name Name of widget. + * + * NOTE: this widget does not eneed any reference to toConnection, + * whenever queriyng it finds toCurrentConnection */ - toResultSchema(toConnection &conn, - QWidget *parent, - const char *name = NULL); + toResultSchema(QWidget *parent, const char *name = NULL); + virtual ~toResultSchema() {}; private slots: // stores last schema selected in qsettings @@ -89,6 +90,11 @@ * */ void update(void); + + virtual void refresh(void); + +private: + void init(toConnection &conn); }; #endif Modified: branches/tora3/src/core/totableselect.cpp =================================================================== --- branches/tora3/src/core/totableselect.cpp 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/core/totableselect.cpp 2012-06-11 16:28:59 UTC (rev 4348) @@ -43,7 +43,7 @@ #include "core/tologger.h" #include "core/toconnection.h" #include "core/toconnectiontraits.h" -#include "core/toresultcombo.h" +#include "core/toresultschema.h" #include <QLabel> #include <QVBoxLayout> @@ -69,7 +69,7 @@ label->show(); vbox->addWidget(label); - Schema = new toResultCombo(this); + Schema = new toResultSchema(this); Schema->show(); Schema->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); vbox->addWidget(Schema); @@ -84,7 +84,7 @@ vbox->addWidget(Table); Schema->additionalItem(mysql ? tr("Select database") : tr("Select schema")); - Schema->query(toSQL::sql(toSQL::TOSQL_USERLIST)); + Schema->refresh(); Table->additionalItem(tr("Select table")); // petr vanek 03/01/07 bug #1180847 Error when creating referential constraint Table->setSQL(toSQL::sql("toBrowser:ListTableNames")); @@ -98,9 +98,10 @@ toTableSelect::toTableSelect(QWidget *parent, const char *name) : QGroupBox(parent) + , Schema(NULL) + , Table(NULL) { setObjectName(name); - Schema = Table = NULL; QTimer::singleShot(0, this, SLOT(setup())); } Modified: branches/tora3/src/core/totableselect.h =================================================================== --- branches/tora3/src/core/totableselect.h 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/core/totableselect.h 2012-06-11 16:28:59 UTC (rev 4348) @@ -7,13 +7,14 @@ #include <QGroupBox> class toConnection; +class toResultSchema; class toResultCombo; class toTableSelect : public QGroupBox { Q_OBJECT - toResultCombo *Schema; + toResultSchema *Schema; toResultCombo *Table; QString SelectedTable; Modified: branches/tora3/src/toawr.cpp =================================================================== --- branches/tora3/src/toawr.cpp 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/toawr.cpp 2012-06-11 16:28:59 UTC (rev 4348) @@ -273,6 +273,7 @@ toolbar->addWidget(new QLabel("Inst:", toolbar)); dbid = new toResultCombo(toolbar, "AWR toolbar"); + dbid->setSQL(toSQL::sql("toAWR:DBInstances", connection())); fsnap = new toResultCombo(toolbar, "AWR toolbar"); fsnap->setSelectionPolicy(toResultCombo::LastButOne); tsnap = new toResultCombo(toolbar, "AWR toolbar"); @@ -296,7 +297,7 @@ try { - dbid->query(toSQL::sql("toAWR:DBInstances", connection())); + dbid->refresh(); } TOCATCH; Deleted: branches/tora3/src/tocache.cpp =================================================================== --- branches/tora3/src/tocache.cpp 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/tocache.cpp 2012-06-11 16:28:59 UTC (rev 4348) @@ -1,594 +0,0 @@ - -#include "tocache.h" -#include "toconfiguration.h" -#include "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) - , state(NOT_STARTED) - , refCount(1) // we assume that we were created from toConnection -{ -} - -toCache::~toCache() -{ - /* toCache locked be parent toConnection */ - if(cacheRefreshRunning()) - ReadingThread.down(); -} - - -bool toCache::cacheAvailable(cacheEntryType type, bool block, toTask * t) -{ - toCacheState waitState = (type == SYNONYMS ? DONE : READING_SYNONYMS); - toCacheState currState = cacheState(); - - switch(toConfigurationSingle::Instance().objectCache()) - { - case toConfiguration::NEVER: - case toConfiguration::UNTIL_MANDATORY: //NOTE: this config option is not handled at all - return currState != FAILED && currState >= waitState; - case toConfiguration::ON_CONNECT: - case toConfiguration::WHEN_NEEDED: //NOTE: this config option is not handled at all - if (!block) - { - return currState != FAILED && currState >= waitState; - } - - if (t) - { - readObjects(t); - } - - if (block) - { - toBusy busy; - if (toThread::mainThread()) - { - QProgressDialog waiting(qApp->translate("toConnection", - "Waiting for object caching to be completed.\n" - "Canceling this dialog will probably leave some list of\n" - "database objects empty."), - qApp->translate("toConnection", "Cancel"), - 0, - 10, - toMainWidget()); - waiting.setWindowTitle(qApp->translate("toConnection", "Waiting for object cache")); - int num = 1; - - do - { - qApp->processEvents(); - toThread::msleep(100); - waiting.setValue((++num) % 10); - if (waiting.wasCanceled()) - return false; - currState = cacheState(); - } - while (currState < waitState); - toMainWidget()->checkCaching(); - } - - return currState != FAILED; - } - else - { - return currState != FAILED && cacheState() >= waitState; - } - default: - assert(0); - return true; // NEVER reached, just prevent MSVC warning - } //switch -} - -bool toCache::cacheRefreshRunning() const -{ - toLocker lock(cacheLock); - return state != NOT_STARTED && state != DONE; -} - -toCache::toCacheState toCache::cacheState() const -{ - toLocker lock(cacheLock); - return state; -} - -void toCache::setCacheState(toCache::toCacheState s) -{ - toLocker lock(cacheLock); - state = s; -} - -bool toCache::addIfNotExists(objectName &obj) -{ - if (!cacheAvailable(SYNONYMS, false)) - { - toStatusMessage(qApp->translate("toConnection", "Not done caching objects"), false, false); - return false; - } - std::list<objectName>::iterator i = ObjectNames.begin(); - while (i != ObjectNames.end() && (*i) < obj) - i++; - if (i != ObjectNames.end() && *i == obj) // Already exists, don't add - return false; - ObjectNames.insert(i, obj); - return true; -} - -void toCache::readObjects(toTask * t) -{ - if (toConfigurationSingle::Instance().objectCache() == toConfiguration::NEVER) - { - return ; - } - - { - try - { - (new toThread(t))->start(); - ReadingThread.down(); // Wait till child thread starts - toMainWidget()->checkCaching(); - } - catch (...) - { - state = FAILED; - } - } -} - -void toCache::rereadCache(toTask * t) -{ - - if (toConfigurationSingle::Instance().objectCache() == toConfiguration::NEVER) - { - ColumnCache.clear(); - return ; - } - - if (cacheRefreshRunning()) - { - toStatusMessage(qApp->translate("toConnection", - "Not done caching objects, can not clear unread cache")); - return ; - } - - ObjectNames.clear(); - ColumnCache.clear(); - SynonymMap.clear(); - - /** delete cache file to force reload - */ - - QString filename(cacheFile()); - - if (QFile::exists(filename)) - QFile::remove(filename); - - readObjects(t); -} - -const toCache::objectName &toCache::realName(const QString &object, - QString &synonym, - bool block, - QString user, - QString database) -{ - if (!cacheAvailable(SYNONYMS, block)) - throw qApp->translate("toConnection", "Not done caching synonyms"); - - QString name; - QString owner; - - QChar q('"'); - QChar c('.'); - - bool quote = false; - for (int pos = 0; pos < object.length(); pos++) - { - if (object.at(pos) == q) - { - quote = !quote; - } - else - { - if (!quote && object.at(pos) == c) - { - owner = name; - name = QString::null; - } - else - name += object.at(pos); - } - } - - QString uo = owner.toUpper(); - QString un = name.toUpper(); - - synonym = QString::null; - for (std::list<objectName>::iterator i = ObjectNames.begin(); i != ObjectNames.end(); i++) - { - if (owner.isEmpty()) - { - if (((*i).Name == un || (*i).Name == name) && - ((*i).Owner == user.toUpper() || (*i).Owner == database)) - return *i; - } - else if (((*i).Name == un || (*i).Name == name) && - ((*i).Owner == uo || (*i).Owner == owner)) - return *i; - } - if (owner.isEmpty()) - { - std::map<QString, objectName>::iterator i = SynonymMap.find(name); - if (i == SynonymMap.end() && un != name) - { - i = SynonymMap.find(un); - synonym = un; - } - else - synonym = name; - if (i != SynonymMap.end()) - { - return (*i).second; - } - } - throw qApp->translate( - "toConnection", - "Object %1 not available for %2").arg(object).arg(user); -} - -std::map<QString, toCache::objectName> &toCache::synonyms(bool block) -{ - if (!cacheAvailable(SYNONYMS, block)) - { - toStatusMessage(qApp->translate("toConnection", "Not done caching synonyms"), false, false); - static std::map<QString, objectName> ret; - return ret; - } - - return SynonymMap; -} - -std::list<toCache::objectName>& toCache::objects(bool block) -{ - if (!cacheAvailable(OBJECTS, block)) - { - toStatusMessage(qApp->translate("toConnection", "Not done caching objects"), false, false); - static std::list<objectName> ret; - return ret; - } - - return ObjectNames; -} - -toQDescList &toCache::columns(const objectName &object) -{ - return ColumnCache[object]; -} - -void toCache::addColumns(objectName object, toQDescList list) -{ - ColumnCache[object] = list; -} // addColumns - -const std::list<toCache::objectName> toCache::tables(const objectName &object, bool nocache) const -{ - std::list<objectName> ret; - - Q_FOREACH(objectName obj, ObjectNames) - { - if(obj.Owner == object.Name) - ret.insert(ret.end(), obj); - } - - return ret; -} - -bool toCache::objectName::operator < (const objectName &nam) const -{ - if (Owner < nam.Owner || (Owner.isNull() && !nam.Owner.isNull())) - return true; - if (Owner > nam.Owner || (!Owner.isNull() && nam.Owner.isNull())) - return false; - if (Name < nam.Name || (Name.isNull() && !nam.Name.isNull())) - return true; - if (Name > nam.Name || (!Name.isNull() && nam.Name.isNull())) - return false; - if (Type < nam.Type) - return true; - return false; -} - -bool toCache::objectName::operator == (const objectName &nam) const -{ - return Owner == nam.Owner && Name == nam.Name && Type == nam.Type; -} - -void toCache::setObjectList(const std::list<objectName> &list) -{ - ObjectNames = list; - // Set the date when information about this object was red. This will later - // be used to clean up an old information. - for (std::list<objectName>::iterator i = ObjectNames.begin(); i != ObjectNames.end(); i++) - (*i).Timestamp = QDate::currentDate(); - ObjectNames.sort(); -} // setObjectList - -void toCache::setSynonymList(const std::map<QString, objectName> &list) -{ - SynonymMap = list; -} // setSynonymList - -bool toCache::objectExists(const QString &owner, const QString &type, const QString &name) -{ - // TODO: ObjectList is sorted therefore going through all of it is not necessary! - for (std::list<objectName>::iterator i = ObjectNames.begin(); i != ObjectNames.end(); i++) - { - if (((*i).Owner == owner || owner == "%") && - (*i).Name == name && - (*i).Type == type) - return true; - } - - return false; -} // objectExists - -toCache::RowList toCache::getObjects(const QString &owner, const QString &type) -{ - Row r; - RowList rl; - for (std::list<objectName>::iterator i = ObjectNames.begin(); i != ObjectNames.end(); i++) - { - if (((*i).Owner == owner || owner == "%") && - (*i).Type == type) - { - r.append((*i).Name); - rl.append(r); - r.clear(); - } - } - - return rl; -} // getObjects - -void toCache::updateObjects(const QString &owner, const QString &type, const QList<objectName> rows) -{ - bool OwnerExists = false; - QList<objectName>::const_iterator newObjects = rows.begin(); - std::list<objectName>::iterator currentObjects = ObjectNames.begin(); - - if (ObjectNames.size() > 0) - { - // Find first object belonging to required owner/schema - while (currentObjects != ObjectNames.end() && - (*currentObjects).Owner < owner) - currentObjects++; - if (currentObjects != ObjectNames.end() && - (*currentObjects).Owner == owner) - OwnerExists = true; - } - - while (newObjects != rows.end()) - { - if (OwnerExists) - { - while (currentObjects != ObjectNames.end() && - (*currentObjects).Type != type) - currentObjects++; // skip cached objects of other types - - if (currentObjects != ObjectNames.end() && - (*currentObjects).Name == (*newObjects).Name) - { - //qDebug() << "Object is already in cache" << (*newObjects).Name; - currentObjects++; - newObjects++; - } - else if (currentObjects != ObjectNames.end() && - (*currentObjects).Name < (*newObjects).Name) - { - //qDebug() << "DELETE:" << (*currentObjects).Name; - currentObjects = ObjectNames.erase(currentObjects); - } - else - { - //qDebug() << "NEW:" << (*newObjects).Name; - ObjectNames.insert(currentObjects, (*newObjects)); - newObjects++; - } - } - else - { - //qDebug() << "NEW2:" << (*newObjects).Name; - ObjectNames.insert(currentObjects, (*newObjects)); - newObjects++; - } - } - // Delete any remaining objects - while (OwnerExists && - currentObjects != ObjectNames.end() && - (*currentObjects).Owner == owner) - { - //qDebug() << "iterating2 through" << (*currentObjects).Name; - if ((*currentObjects).Type == type) - { - //qDebug() << "DELETE2:" << (*currentObjects).Name; - currentObjects = ObjectNames.erase(currentObjects); - } - else - currentObjects++; - } -} // updateObjects - -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 - -QString toCache::cacheFile() -{ - QString ret (ConnectionDescription.trimmed()); - // using instantclient connectionstrins can result in file name like this: - // isepl_global_stage@//oraclexe11:1521/xe - // which is invalid. Just remove "/" or replace it with something safer. - ret = ret.replace("/", "_"); - - return cacheDir() + "/" + ret; -} // cacheFile - -bool toCache::loadDiskCache() -{ - if (!toConfigurationSingle::Instance().cacheDisk()) - return false; - - objectName *cur = 0; - int objCounter = 0; - int synCounter = 0; - - QString filename = cacheFile(); - - QFile file(filename); - - if (!QFile::exists(filename)) - return false; - - QFileInfo fi(file); - QDateTime today; - if (fi.lastModified().addDays(toConfigurationSingle::Instance().cacheTimeout()) < today) - return false; - - /** read in all data - */ - - if (!file.open(QIODevice::ReadOnly)) - return false; - - QString data = file.readAll(); - - /** build cache lists - */ - - if(!data.isEmpty()) - { - QStringList records = data.split("\x1D", QString::KeepEmptyParts); - for (QStringList::Iterator i = records.begin(); i != records.end(); i++) - { - objCounter++; - QStringList record = (*i).split("\x1E", QString::KeepEmptyParts); - QStringList::Iterator rec = record.begin(); - cur = new objectName; - (*cur).Owner = (*rec); - rec++; - (*cur).Name = (*rec); - rec++; - (*cur).Type = (*rec); - rec++; - (*cur).Comment = (*rec); - rec++; - QStringList slist = (*rec).split("\x1F", QString::SkipEmptyParts); - for (QStringList::Iterator s = slist.begin(); s != slist.end(); s++) - { - SynonymMap[(*s)] = (*cur); - (*cur).Synonyms.insert((*cur).Synonyms.end(), (*s)); - synCounter++; - } - /** TODO: This "if" condition is added here for bakwards compatibility as timestamp - * parameter was not saved to disk before 2010-12-12. Therefore this condition can - * be removed after 2011-12-12 (one year for everybody to update). Another way to - * fix this is to delete the cache. - */ - if (record.count() >= 6) - { - rec++; - (*cur).Timestamp = QDate::fromString((*rec), "yyyy-MM-dd"); - } - else - (*cur).Timestamp = QDate::currentDate(); - ObjectNames.insert(ObjectNames.end(), (*cur)); - delete cur; - cur = 0; - } - } - - { - toLocker lock(cacheLock); - ObjectNames.sort(); - } - return true; -} - -void toCache::writeDiskCache() -{ - QString text; - long objCounter = 0; - long synCounter = 0; - - if (!toConfigurationSingle::Instance().cacheDisk()) - return ; - - QString filename(cacheFile()); - - /** check pathnames and create - */ - QString dirname(cacheDir()); - QDir dir; - dir.setPath(dirname); - - if (!dir.exists(dirname)) - dir.mkdir(dirname); - - /** build record to write out - */ - QStringList record; // information about one object - QStringList records; // all objects - QStringList recordSynonym; // all synonyms of one particular object - for (std::list<objectName>::iterator i = ObjectNames.begin(); i != ObjectNames.end(); i++) - { - record.clear(); - record.append((*i).Owner); - record.append((*i).Name); - record.append((*i).Type); - record.append((*i).Comment); - for (std::list<QString>::iterator s = (*i).Synonyms.begin(); s != (*i).Synonyms.end(); s++) - { - recordSynonym.append((*s)); - synCounter++; - } - record.append(recordSynonym.join("\x1F")); - record.append((*i).Timestamp.toString("yyyy-MM-dd")); - recordSynonym.clear(); - objCounter++; - records.append(record.join("\x1E")); - } - - /** Write all records to a file - */ - QFile file(filename); - if (file.open(QIODevice::ReadWrite | QIODevice::Truncate)) - { - QTextStream t(&file); - t << records.join("\x1D"); - file.flush(); - file.close(); - } - else - qDebug() << "Cannot open file" << filename << "!"; -} Deleted: branches/tora3/src/tocache.h =================================================================== --- branches/tora3/src/tocache.h 2012-06-11 13:35:21 UTC (rev 4347) +++ branches/tora3/src/tocache.h 2012-06-11 16:28:59 UTC (rev 4348) @@ -1,253 +0,0 @@ -#ifndef TOCACHE_H -#define TOCACHE_H - -#include "tothread.h" -#include <QMetaType> -#include <QDate> -#include <QList> -#include <QVariant> -#include <map> -#include <list> -#include <set> - -/** Object cache for a connection. This class is accessed only through toConnection - a could be a nested class of toConnection. - */ -class toConnection; - -class toCache : public QObject -{ - friend class toConnection; - /** 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; - unsigned refCount; // Multiple connections can point onto same toCache instance, the last connection should delete me. -public: - mutable toLock cacheLock; - - typedef QList<QVariant> Row; // NOTE: first (0th) value in a row is a row number (see variable currRowKey) - typedef QList<Row> RowList; - - enum toCacheState - { - - NOT_STARTED = 0, - READING_OBJECTS, - READING_SYNONYMS, - DONE, - FAILED - }; - - /* This enum is used to distingish parameter of cacheAvailable */ - enum cacheEntryType - { - SYNONYMS, - OBJECTS - }; - - /* This semaphore is used to synchronize with toConnection::cacheObjects::run() - is initialized in toConnection constructors to 2 - */ - toSemaphore ReadingThread; - - /** Contain information about a tablename. - */ - struct objectName - { - /** The object name - */ - QString Name; - /** The schema that owns it - */ - QString Owner; - /** Object type - */ - QString Type; - /** Comment about this object - */ - QString Comment; - /** synonyms (used for faster disk caching...) - */ - std::list <QString> Synonyms; - - /** A date when information about this particular object was last updated - */ - QDate Timestamp; - - /** Create an object name with filled in values. - */ - objectName(const QString &owner, const QString &name, const QString &type = QString("TABLE"), const QString &comment = QString::null) - : Name(name), Owner(owner), Type(type), Comment(comment) - { } - - /** Create an empty object name. - */ - objectName() - { } - bool operator < (const objectName &) const; - bool operator == (const objectName &) const; - }; - - /** This structure is used to describe the resultset of a query. - */ - struct queryDescribe - { - /** 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; - }; - -private: - std::list<objectName> ObjectNames; - std::map<QString, objectName> SynonymMap; - - toCacheState state; - void setCacheState(toCacheState); -public: - typedef queryDescribe toQDescribe; - typedef std::list<toQDescribe> toQDescList; - - std::map<objectName, toQDescList> ColumnCache; - - toCache(QString const &description); - ~toCache(); - - /** Load cache information for current connection from a file on disk - * @return True if cache was loaded - */ - bool loadDiskCache(void)... [truncated message content] |