⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logcache.cpp

📁 LINUX 下以 QT/KDE 写的 SVN 客户端
💻 CPP
字号:
#include "LogCache.hpp"#include <qdir.h>#include <qsql.h>#include <qsqldatabase.h>#if QT_VERSION < 0x040000#include <qthreadstorage.h>#else#include <QMutex>#include <QThreadStorage>#include <QSqlError>#include <QSqlQuery>#include <QVariant>#endif#include <qmap.h>#include "svnqt/path.hpp"#ifndef NO_SQLITE3#include "sqlite3/qsql_sqlite3.h"#define SQLTYPE "QSQLITE3"#else#define SQLTYPE "QSQLITE"#endif#define SQLMAIN "logmain-logcache"#define SQLMAINTABLE "logdb"namespace svn {namespace cache {LogCache* LogCache::mSelf = 0;class ThreadDBStore{public:    ThreadDBStore(){#if QT_VERSION < 0x040000        m_DB=0;#else        m_DB=QSqlDatabase();#endif    }    ~ThreadDBStore(){#if QT_VERSION < 0x040000        m_DB=0;#else        m_DB=QSqlDatabase();#endif        QSqlDatabase::removeDatabase(key);        QMap<QString,QString>::Iterator it;        for (it=reposCacheNames.begin();it!=reposCacheNames.end();++it) {#if QT_VERSION < 0x040000            QSqlDatabase::removeDatabase(it.data());#else            QSqlDatabase::removeDatabase(it.value());#endif        }    }    QDataBase m_DB;    QString key;    QMap<QString,QString> reposCacheNames;};class LogCacheData{protected:    QMutex m_singleDbMutex;public:    LogCacheData(){}    ~LogCacheData(){        if (m_mainDB.hasLocalData()) {            m_mainDB.setLocalData(0L);        }    }    bool checkReposDb(QDataBase aDb)    {#if QT_VERSION < 0x040000        if (!aDb) {            return false;        }        if (!aDb->open()) {            return false;        }#else        if (!aDb.open()) {            return false;        }#endif        QSqlQuery _q(QString::null, aDb);#if QT_VERSION < 0x040000        QStringList list = aDb->tables();#else        QStringList list = aDb.tables();#endif#if QT_VERSION < 0x040000        if (list.find("logentries")==list.end()) {            aDb->transaction();#else        if (list.indexOf("logentries")==-1) {            aDb.transaction();#endif            _q.exec("CREATE TABLE \"logentries\" (\"revision\" INTEGER UNIQUE,\"date\" INTEGER,\"author\" TEXT, \"message\" TEXT)");#if QT_VERSION < 0x040000            aDb->commit();#else            aDb.commit();#endif        }#if QT_VERSION < 0x040000        if (list.find("changeditems")==list.end()) {            aDb->transaction();#else        if (list.indexOf("changeditems")==-1) {            aDb.transaction();#endif            _q.exec("CREATE TABLE \"changeditems\" (\"revision\" INTEGER,\"changeditem\" TEXT,\"action\" TEXT,\"copyfrom\" TEXT,\"copyfromrev\" INTEGER, PRIMARY KEY(revision,changeditem,action))");#if QT_VERSION < 0x040000            aDb->commit();#else            aDb.commit();#endif        }#if QT_VERSION < 0x040000        list = aDb->tables();        if (list.find("logentries")==list.end() || list.find("changeditems")==list.end()) {#else        list = aDb.tables();        if (list.indexOf("logentries")==-1 || list.indexOf("changeditems")==-1) {#endif            return false;        }        return true;    }    QString createReposDB(const svn::Path&reposroot) {        QMutexLocker locker( &m_singleDbMutex );        QDataBase _mdb = getMainDB();        QSqlQuery query1(QString::null,_mdb);        QString q("insert into "+QString(SQLMAINTABLE)+" (reposroot) VALUES('"+reposroot+"')");#if QT_VERSION < 0x040000        _mdb->transaction();#else        _mdb.transaction();#endif        query1.exec(q);#if QT_VERSION < 0x040000        _mdb->commit();#else        _mdb.commit();#endif        QSqlQuery query(QString::null,_mdb);        query.prepare(s_reposSelect);        query.bindValue(0,reposroot.native());        query.exec();        QString db;#if QT_VERSION < 0x040000        if (query.lastError().type()==QSqlError::None && query.next()) {#else        if (query.lastError().type()==QSqlError::NoError && query.next()) {#endif            db = query.value(0).toString();        }        else {            qDebug("Error select_01: %s (%s)",query.lastError().text().TOUTF8().data(),                   query.lastQuery().TOUTF8().data());        }        if (!db.isEmpty()) {            QString fulldb = m_BasePath+"/"+db+".db";            QDataBase _db = QSqlDatabase::addDatabase(SQLTYPE,"tmpdb");#if QT_VERSION < 0x040000            _db->setDatabaseName(fulldb);#else            _db.setDatabaseName(fulldb);#endif            if (!checkReposDb(_db)) {            }            QSqlDatabase::removeDatabase("tmpdb");        }        return db;    }    QDataBase getReposDB(const svn::Path&reposroot) {#if QT_VERSION < 0x040000        if (!getMainDB()) {            return 0;#else        if (!getMainDB().isValid()) {            return QDataBase();#endif        }        bool checkDone = false;        // make sure path is correct eg. without traling slashes.        QString dbFile;        QSqlQuery c(QString::null,getMainDB());        c.prepare(s_reposSelect);        c.bindValue(0,reposroot.native());        c.exec();#if QT_VERSION < 0x040000        qDebug("Check for path: "+reposroot.native());#endif        // only the first one        if ( c.next() ) {#if QT_VERSION < 0x040000            qDebug( c.value(0).toString() + ": " +                    c.value(0).toString() );#endif            dbFile = c.value(0).toString();        }        if (dbFile.isEmpty()) {            dbFile = createReposDB(reposroot);            if (dbFile.isEmpty()) {#if QT_VERSION < 0x040000                return 0;#else                return QSqlDatabase();#endif            }            checkDone=true;        }        if (m_mainDB.localData()->reposCacheNames.find(dbFile)!=m_mainDB.localData()->reposCacheNames.end()) {            return QSqlDatabase::database(m_mainDB.localData()->reposCacheNames[dbFile]);        }        int i = 0;        QString _key = dbFile;        while (QSqlDatabase::contains(_key)) {            _key = QString("%1-%2").arg(dbFile).arg(i++);        }        qDebug("The repository key is now: %s",_key.TOUTF8().data());        QDataBase _db = QSqlDatabase::addDatabase(SQLTYPE,_key);#if QT_VERSION < 0x040000        if (!_db) {            return 0;        }#endif        QString fulldb = m_BasePath+"/"+dbFile+".db";#if QT_VERSION < 0x040000        _db->setDatabaseName(fulldb);#else        _db.setDatabaseName(fulldb);#endif        qDebug("try database open %s",fulldb.TOUTF8().data());        if (!checkReposDb(_db)) {            qDebug("no DB opened");#if QT_VERSION < 0x040000            _db = 0;#else            _db = QSqlDatabase();#endif        } else {            qDebug("Insert into map");            m_mainDB.localData()->reposCacheNames[dbFile]=_key;        }        return _db;    }    QDataBase getMainDB()    {        if (!m_mainDB.hasLocalData()) {            unsigned i=0;            QString _key = SQLMAIN;            while (QSqlDatabase::contains(_key)) {                _key.sprintf("%s-%i",SQLMAIN,i++);            }            qDebug("The key is now: %s",_key.TOUTF8().data());            QDataBase db = QSqlDatabase::addDatabase(SQLTYPE,_key);#if QT_VERSION < 0x040000            db->setDatabaseName(m_BasePath+"/maindb.db");            if (!db->open()) {#else            db.setDatabaseName(m_BasePath+"/maindb.db");            if (!db.open()) {#endif#if QT_VERSION < 0x040000                qWarning("Failed to open main database: " + db->lastError().text());#endif            } else {                m_mainDB.setLocalData(new ThreadDBStore);                m_mainDB.localData()->key = _key;                m_mainDB.localData()->m_DB = db;            }        }        if (m_mainDB.hasLocalData()) {            return m_mainDB.localData()->m_DB;        } else {#if QT_VERSION < 0x040000            return 0;#else            return QSqlDatabase();#endif        }    }    QString m_BasePath;    QThreadStorage<ThreadDBStore*> m_mainDB;    static const QString s_reposSelect;};QString LogCache::s_CACHE_FOLDER="logcache";const QString LogCacheData::s_reposSelect=QString("SELECT id from ")+QString(SQLMAINTABLE)+QString(" where reposroot=? ORDER by id DESC");/*!    \fn svn::cache::LogCache::LogCache() */LogCache::LogCache(){    m_BasePath = QDir::HOMEDIR()+"/.svnqt";    setupCachePath();}LogCache::LogCache(const QString&aBasePath){    if (mSelf) {        delete mSelf;    }    mSelf=this;    if (aBasePath.isEmpty()) {        m_BasePath=QDir::HOMEDIR()+"/.svnqt";    } else {        m_BasePath=aBasePath;    }    setupCachePath();}LogCache::~LogCache(){}/*!    \fn svn::cache::LogCache::setupCachePath() */void LogCache::setupCachePath(){    m_CacheData = new LogCacheData;    m_CacheData->m_BasePath=m_BasePath;    QDir d;    if (!d.exists(m_BasePath)) {        d.mkdir(m_BasePath);    }    m_BasePath=m_BasePath+"/"+s_CACHE_FOLDER;    if (!d.exists(m_BasePath)) {        d.mkdir(m_BasePath);    }    m_CacheData->m_BasePath=m_BasePath;    if (d.exists(m_BasePath)) {        setupMainDb();    }}void LogCache::setupMainDb(){#ifndef NO_SQLITE3    if (!QSqlDatabase::isDriverAvailable(SQLTYPE)) {        QSqlDatabase::registerSqlDriver(SQLTYPE,new QSqlDriverCreator<QSQLite3Driver>);    }#endif    QDataBase mainDB = m_CacheData->getMainDB();#if QT_VERSION < 0x040000    if (!mainDB || !mainDB->open()) {        qWarning("Failed to open main database: " + (mainDB?mainDB->lastError().text():"No database object."));#else    if (!mainDB.isValid()) {        qWarning("Failed to open main database.");#endif    } else {        QSqlQuery q(QString::null, mainDB);#if QT_VERSION < 0x040000        mainDB->transaction();#else        mainDB.transaction();#endif        if (!q.exec("CREATE TABLE IF NOT EXISTS \""+QString(SQLMAINTABLE)+"\" (\"reposroot\" TEXT,\"id\" INTEGER PRIMARY KEY NOT NULL);")) {#if QT_VERSION < 0x040000            qWarning("Failed create main database: " + mainDB->lastError().text());#endif        }#if QT_VERSION < 0x040000        mainDB->commit();#else        mainDB.commit();#endif    }}}}/*!    \fn svn::cache::LogCache::self() */svn::cache::LogCache* svn::cache::LogCache::self(){    if (!mSelf) {        mSelf=new LogCache();    }    return mSelf;}/*!    \fn svn::cache::LogCache::reposDb() */QDataBase  svn::cache::LogCache::reposDb(const QString&aRepository){    qDebug("reposDB");    return m_CacheData->getReposDB(aRepository);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -