/* This file is part of the KDE project Daniel Molkentin Joseph Wenninger Copyright (C) 2003-2004 Jaroslaw Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "migratemanager.h" #include "migratemanager_p.h" #include "keximigrate.h" #include #include #include #include #include #include #include #include //remove debug #undef KexiDBDbg #define KexiDBDbg if (0) kdDebug() using namespace KexiMigration; MigrateManagerInternal* MigrateManagerInternal::s_self = 0L; /*! @todo Temporary, needed because MigrateManagerInternal::m_drivers is autodeleted drivers currently own KexiMigrate::Data members so these are destroyed when last MigrateManager instance is deleted. Remove this hack when KexiMigrate is splitted into Driver and Connection. */ MigrateManager __manager; MigrateManagerInternal::MigrateManagerInternal() /* protected */ : TQObject( 0, "KexiMigrate::MigrateManagerInternal" ) , Object() , m_drivers(17, false) , m_refCount(0) , lookupDriversNeeded(true) { m_drivers.setAutoDelete(true); m_serverResultNum=0; } MigrateManagerInternal::~MigrateManagerInternal() { KexiDBDbg << "MigrateManagerInternal::~MigrateManagerInternal()" << endl; m_drivers.clear(); if ( s_self == this ) s_self = 0; KexiDBDbg << "MigrateManagerInternal::~MigrateManagerInternal() ok" << endl; } void MigrateManagerInternal::slotAppQuits() { if (tqApp->mainWidget() && tqApp->mainWidget()->isVisible()) return; //what a hack! - we give up when app is still there KexiDBDbg << "MigrateManagerInternal::slotAppQuits(): let's clear drivers..." << endl; m_drivers.clear(); } MigrateManagerInternal *MigrateManagerInternal::self() { if (!s_self) s_self = new MigrateManagerInternal(); return s_self; } bool MigrateManagerInternal::lookupDrivers() { if (!lookupDriversNeeded) return true; if (tqApp) { connect(tqApp,TQT_SIGNAL(aboutToQuit()),this,TQT_SLOT(slotAppQuits())); } //TODO: for QT-only version check for KInstance wrapper // KexiDBWarn << "DriverManagerInternal::lookupDrivers(): cannot work without KInstance (KGlobal::instance()==0)!" << endl; // setError("Driver Manager cannot work without KInstance (KGlobal::instance()==0)!"); lookupDriversNeeded = false; clearError(); KTrader::OfferList tlist = KTrader::self()->query("Kexi/MigrationDriver"); KTrader::OfferList::ConstIterator it(tlist.constBegin()); for(; it != tlist.constEnd(); ++it) { KService::Ptr ptr = (*it); TQString srv_name = ptr->property("X-Kexi-MigrationDriverName").toString(); if (srv_name.isEmpty()) { KexiDBWarn << "MigrateManagerInternal::lookupDrivers(): " "X-Kexi-MigrationDriverName must be set for migration driver \"" << ptr->property("Name").toString() << "\" service!\n -- skipped!" << endl; continue; } if (m_services_lcase.contains(srv_name.lower())) { continue; } //! @todo could be merged. Copied from KexiDB::DriverManager. // TQString srv_ver_str = ptr->property("X-Kexi-KexiMigrationVersion").toString(); TQStringList lst( TQStringList::split(".", srv_ver_str) ); int minor_ver, major_ver; bool ok = (lst.count() == 2); if (ok) major_ver = lst[0].toUInt(&ok); if (ok) minor_ver = lst[1].toUInt(&ok); if (!ok) { KexiDBWarn << "MigrateManagerInternal::lookupDrivers(): problem with detecting '" << srv_name.lower() << "' driver's version -- skipping it!" << endl; possibleProblems += TQString("\"%1\" migration driver has unrecognized version; " "required driver version is \"%2.%3\"") .tqarg(srv_name.lower()) .tqarg(KexiMigration::versionMajor()).tqarg(KexiMigration::versionMinor()); continue; } if (major_ver != KexiMigration::versionMajor() || minor_ver != KexiMigration::versionMinor()) { KexiDBWarn << TQString("MigrateManagerInternal::lookupDrivers(): '%1' driver" " has version '%2' but required migration driver version is '%3.%4'\n" " -- skipping this driver!").tqarg(srv_name.lower()).tqarg(srv_ver_str) .tqarg(KexiMigration::versionMajor()).tqarg(KexiMigration::versionMinor()) << endl; possibleProblems += TQString("\"%1\" migration driver has version \"%2\" " "but required driver version is \"%3.%4\"") .tqarg(srv_name.lower()).tqarg(srv_ver_str) .tqarg(KexiMigration::versionMajor()).tqarg(KexiMigration::versionMinor()); continue; } // TQString mime = ptr->property("X-Kexi-FileDBDriverMime").toString().lower(); TQString drvType = ptr->property("X-Kexi-MigrationDriverType").toString().lower(); if (drvType=="file") { if (!mime.isEmpty()) { if (!m_services_by_mimetype.contains(mime)) { m_services_by_mimetype.insert(mime, ptr); } else { KexiDBWarn << "MigrateManagerInternal::lookupDrivers(): more than one driver for '" << mime << "' mime type!" << endl; } } } m_services.insert(srv_name, ptr); m_services_lcase.insert(srv_name.lower(), ptr); KexiDBDbg << "MigrateManager::lookupDrivers(): registered driver: " << ptr->name() << "(" << ptr->library() << ")" << endl; } if (tlist.isEmpty()) { setError(ERR_DRIVERMANAGER, i18n("Could not find any import/export database drivers.") ); return false; } return true; } KexiMigrate* MigrateManagerInternal::driver(const TQString& name) { if (!lookupDrivers()) return 0; clearError(); KexiDBDbg << "MigrationrManagerInternal::migrationDriver(): loading " << name << endl; KexiMigrate *drv = name.isEmpty() ? 0 : m_drivers.find(name.latin1()); if (drv) return drv; //cached if (!m_services_lcase.contains(name.lower())) { setError(ERR_DRIVERMANAGER, i18n("Could not find import/export database driver \"%1\".").tqarg(name) ); return 0; } KService::Ptr ptr= *(m_services_lcase.find(name.lower())); TQString srv_name = ptr->property("X-Kexi-MigrationDriverName").toString(); KexiDBDbg << "MigrateManagerInternal::driver(): library: "<library()<(ptr, this, srv_name.latin1(), TQStringList(),&m_serverResultNum); if (!drv) { setError(ERR_DRIVERMANAGER, i18n("Could not load import/export database driver \"%1\".") .tqarg(name) ); if (m_componentLoadingErrors.isEmpty()) {//fill errtable on demand m_componentLoadingErrors[KParts::ComponentFactory::ErrNoServiceFound]="ErrNoServiceFound"; m_componentLoadingErrors[KParts::ComponentFactory::ErrServiceProvidesNoLibrary]="ErrServiceProvidesNoLibrary"; m_componentLoadingErrors[KParts::ComponentFactory::ErrNoLibrary]="ErrNoLibrary"; m_componentLoadingErrors[KParts::ComponentFactory::ErrNoFactory]="ErrNoFactory"; m_componentLoadingErrors[KParts::ComponentFactory::ErrNoComponent]="ErrNoComponent"; } m_serverResultName=m_componentLoadingErrors[m_serverResultNum]; return 0; } KexiDBDbg << "MigrateManagerInternal::driver(): loading succeed: " << name <d->initInternalProperties(); if (!drv->isValid()) { setError(drv); delete drv; return 0; } m_drivers.insert(name.latin1(), drv); //cache it return drv; } void MigrateManagerInternal::incRefCount() { m_refCount++; KexiDBDbg << "MigrateManagerInternal::incRefCount(): " << m_refCount << endl; } void MigrateManagerInternal::decRefCount() { m_refCount--; KexiDBDbg << "MigrateManagerInternal::decRefCount(): " << m_refCount << endl; // if (m_refCount<1) { // KexiDBDbg<<"KexiDB::DriverManagerInternal::decRefCount(): reached m_refCount<1 -->deletelater()"<incRefCount(); // if ( !s_self ) // s_self = this; // lookupDrivers(); } MigrateManager::~MigrateManager() { KexiDBDbg << "MigrateManager::~MigrateManager()" << endl; /* Connection *conn; for ( conn = m_connections.first(); conn ; conn = m_connections.next() ) { conn->disconnect(); conn->m_driver = 0; //don't let the connection touch our driver now m_connections.remove(); delete conn; }*/ d_int->decRefCount(); if (d_int->m_refCount==0) { //delete internal drv manager! delete d_int; } // if ( s_self == this ) //s_self = 0; KexiDBDbg << "MigrateManager::~MigrateManager() ok" << endl; } const TQStringList MigrateManager::driverNames() { if (!d_int->lookupDrivers()) { kdDebug() << "MigrateManager::driverNames() lookupDrivers failed" << endl; return TQStringList(); } if (d_int->m_services.isEmpty()) { kdDebug() << "MigrateManager::driverNames() MigrateManager::ServicesMap is empty" << endl; return TQStringList(); } if (d_int->error()) { kdDebug() << "MigrateManager::driverNames() Error: " << d_int->errorMsg() << endl; return TQStringList(); } return d_int->m_services.keys(); } TQString MigrateManager::driverForMimeType(const TQString &mimeType) { if (!d_int->lookupDrivers()) { kdDebug() << "MigrateManager::driverForMimeType() lookupDrivers() failed" << endl; setError(d_int); return 0; } KService::Ptr ptr = d_int->m_services_by_mimetype[mimeType.lower()]; if (!ptr) { kdDebug() << TQString("MigrateManager::driverForMimeType(%1) No such mimetype").tqarg(mimeType) << endl; return TQString(); } return ptr->property("X-Kexi-MigrationDriverName").toString(); } KexiMigrate* MigrateManager::driver(const TQString& name) { KexiMigrate *drv = d_int->driver(name); if (d_int->error()) { kdDebug() << TQString("MigrateManager::driver(%1) Error: %2").tqarg(name).tqarg(d_int->errorMsg()) << endl; setError(d_int); } return drv; } TQString MigrateManager::serverErrorMsg() { return d_int->m_serverErrMsg; } int MigrateManager::serverResult() { return d_int->m_serverResultNum; } TQString MigrateManager::serverResultName() { return d_int->m_serverResultName; } void MigrateManager::drv_clearServerResult() { d_int->m_serverErrMsg=TQString(); d_int->m_serverResultNum=0; d_int->m_serverResultName=TQString(); } TQString MigrateManager::possibleProblemsInfoMsg() const { if (d_int->possibleProblems.isEmpty()) return TQString(); TQString str; str.reserve(1024); str = "
    "; for (TQStringList::ConstIterator it = d_int->possibleProblems.constBegin(); it!=d_int->possibleProblems.constEnd(); ++it) { str += (TQString::fromLatin1("
  • ") + *it + TQString::fromLatin1("
  • ")); } str += "
"; return str; } //------------------------ int KexiMigration::versionMajor() { return KEXI_MIGRATION_VERSION_MAJOR; } int KexiMigration::versionMinor() { return KEXI_MIGRATION_VERSION_MINOR; } #include "migratemanager_p.moc"