kexi
drivermanager.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <kexidb/drivermanager.h>
00023 #include <kexidb/drivermanager_p.h>
00024
00025 #include <kexidb/driver.h>
00026 #include <kexidb/driver_p.h>
00027 #include <kexidb/error.h>
00028
00029 #include <klibloader.h>
00030 #include <kparts/componentfactory.h>
00031 #include <ktrader.h>
00032 #include <kdebug.h>
00033 #include <klocale.h>
00034 #include <kservice.h>
00035
00036 #include <assert.h>
00037
00038 #include <qapplication.h>
00039
00040
00041 #undef KexiDBDbg
00042 #define KexiDBDbg if (0) kdDebug()
00043
00044 using namespace KexiDB;
00045
00046 DriverManagerInternal* DriverManagerInternal::s_self = 0L;
00047
00048
00049 DriverManagerInternal::DriverManagerInternal()
00050 : QObject( 0, "KexiDB::DriverManager" )
00051 , Object()
00052 , m_drivers(17, false)
00053 , m_refCount(0)
00054 , lookupDriversNeeded(true)
00055 {
00056 m_drivers.setAutoDelete(true);
00057 m_serverResultNum=0;
00058
00059 }
00060
00061 DriverManagerInternal::~DriverManagerInternal()
00062 {
00063 KexiDBDbg << "DriverManagerInternal::~DriverManagerInternal()" << endl;
00064 m_drivers.clear();
00065 if ( s_self == this )
00066 s_self = 0;
00067 KexiDBDbg << "DriverManagerInternal::~DriverManagerInternal() ok" << endl;
00068 }
00069
00070 void DriverManagerInternal::slotAppQuits()
00071 {
00072 if (qApp->mainWidget() && qApp->mainWidget()->isVisible())
00073 return;
00074 KexiDBDbg << "DriverManagerInternal::slotAppQuits(): let's clear drivers..." << endl;
00075 m_drivers.clear();
00076 }
00077
00078 DriverManagerInternal *DriverManagerInternal::self()
00079 {
00080 if (!s_self)
00081 s_self = new DriverManagerInternal();
00082
00083 return s_self;
00084 }
00085
00086 bool DriverManagerInternal::lookupDrivers()
00087 {
00088 if (!lookupDriversNeeded)
00089 return true;
00090
00091 if (qApp) {
00092 connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(slotAppQuits()));
00093 }
00094
00095
00096
00097
00098 lookupDriversNeeded = false;
00099 clearError();
00100 KTrader::OfferList tlist = KTrader::self()->query("Kexi/DBDriver");
00101 KTrader::OfferList::ConstIterator it(tlist.constBegin());
00102 for(; it != tlist.constEnd(); ++it)
00103 {
00104 KService::Ptr ptr = (*it);
00105 if (!ptr->property("Library").toString().startsWith("kexidb_")) {
00106 KexiDBWarn << "DriverManagerInternal::lookupDrivers():"
00107 " X-KDE-Library == " << ptr->property("Library").toString()
00108 << ": no \"kexidb_\" prefix -- skipped to avoid potential conflicts!" << endl;
00109 continue;
00110 }
00111 QString srv_name = ptr->property("X-Kexi-DriverName").toString();
00112 if (srv_name.isEmpty()) {
00113 KexiDBWarn << "DriverManagerInternal::lookupDrivers():"
00114 " X-Kexi-DriverName must be set for KexiDB driver \""
00115 << ptr->property("Name").toString() << "\" service!\n -- skipped!" << endl;
00116 continue;
00117 }
00118 if (m_services_lcase.contains(srv_name.lower())) {
00119 KexiDBWarn << "DriverManagerInternal::lookupDrivers(): more than one driver named '"
00120 << srv_name.lower() << "'\n -- skipping this one!" << endl;
00121 continue;
00122 }
00123
00124 QString srv_ver_str = ptr->property("X-Kexi-KexiDBVersion").toString();
00125 QStringList lst( QStringList::split(".", srv_ver_str) );
00126 uint minor_ver, major_ver;
00127 bool ok = (lst.count() == 2);
00128 if (ok)
00129 major_ver = lst[0].toUInt(&ok);
00130 if (ok)
00131 minor_ver = lst[1].toUInt(&ok);
00132 if (!ok) {
00133 KexiDBWarn << "DriverManagerInternal::lookupDrivers(): problem with detecting '"
00134 << srv_name.lower() << "' driver's version -- skipping it!" << endl;
00135 continue;
00136 }
00137 if (major_ver != KexiDB::version().major || minor_ver != KexiDB::version().minor) {
00138 KexiDBWarn << QString("DriverManagerInternal::lookupDrivers(): '%1' driver"
00139 " has version '%2' but required KexiDB driver version is '%3.%4'\n"
00140 " -- skipping this driver!").arg(srv_name.lower()).arg(srv_ver_str)
00141 .arg(KexiDB::version().major).arg(KexiDB::version().minor) << endl;
00142 possibleProblems += QString("\"%1\" database driver has version \"%2\" "
00143 "but required driver version is \"%3.%4\"")
00144 .arg(srv_name.lower()).arg(srv_ver_str)
00145 .arg(KexiDB::version().major).arg(KexiDB::version().minor);
00146 continue;
00147 }
00148
00149 QString drvType = ptr->property("X-Kexi-DriverType").toString().lower();
00150 if (drvType=="file") {
00151
00152 QStringList mimes( ptr->property("X-Kexi-FileDBDriverMimeList").toStringList() );
00153
00154 {
00155 QString mime( ptr->property("X-Kexi-FileDBDriverMime").toString().lower() );
00156 if (!mime.isEmpty())
00157 mimes.append( mime );
00158 }
00159
00160
00161 for (QStringList::ConstIterator mime_it = mimes.constBegin(); mime_it!=mimes.constEnd(); ++mime_it) {
00162 QString mime( (*mime_it).lower() );
00163 if (!m_services_by_mimetype.contains(mime)) {
00164 m_services_by_mimetype.insert(mime, ptr);
00165 }
00166 else {
00167 KexiDBWarn << "DriverManagerInternal::lookupDrivers(): more than one driver for '"
00168 << mime << "' mime type!" << endl;
00169 }
00170 }
00171 }
00172 else {
00173 #ifndef KEXI_SERVER_SUPPORT
00174
00175 continue;
00176 #endif
00177 }
00178
00179 m_services.insert(srv_name, ptr);
00180 m_services_lcase.insert(srv_name.lower(), ptr);
00181 KexiDBDbg << "KexiDB::DriverManager::lookupDrivers(): registered driver: " << ptr->name() << "(" << ptr->library() << ")" << endl;
00182 }
00183
00184 if (tlist.isEmpty())
00185 {
00186 setError(ERR_DRIVERMANAGER, i18n("Could not find any database drivers.") );
00187 return false;
00188 }
00189 return true;
00190 }
00191
00192 KexiDB::Driver::Info DriverManagerInternal::driverInfo(const QString &name)
00193 {
00194 KexiDB::Driver::Info i = m_driversInfo[name.lower()];
00195 if (!error() && i.name.isEmpty())
00196 setError(ERR_DRIVERMANAGER, i18n("Could not find database driver \"%1\".").arg(name) );
00197 return i;
00198 }
00199
00200 Driver* DriverManagerInternal::driver(const QString& name)
00201 {
00202 if (!lookupDrivers())
00203 return 0;
00204
00205 clearError();
00206 KexiDBDbg << "DriverManager::driver(): loading " << name << endl;
00207
00208 Driver *drv = name.isEmpty() ? 0 : m_drivers.find(name.latin1());
00209 if (drv)
00210 return drv;
00211
00212 if (!m_services_lcase.contains(name.lower())) {
00213 setError(ERR_DRIVERMANAGER, i18n("Could not find database driver \"%1\".").arg(name) );
00214 return 0;
00215 }
00216
00217 KService::Ptr ptr= *(m_services_lcase.find(name.lower()));
00218 QString srv_name = ptr->property("X-Kexi-DriverName").toString();
00219
00220 KexiDBDbg << "KexiDBInterfaceManager::load(): library: "<<ptr->library()<<endl;
00221 drv = KParts::ComponentFactory::createInstanceFromService<KexiDB::Driver>(ptr,
00222 this, srv_name.latin1(), QStringList(),&m_serverResultNum);
00223
00224 if (!drv) {
00225 setError(ERR_DRIVERMANAGER, i18n("Could not load database driver \"%1\".")
00226 .arg(name) );
00227 if (m_componentLoadingErrors.isEmpty()) {
00228 m_componentLoadingErrors[KParts::ComponentFactory::ErrNoServiceFound]="ErrNoServiceFound";
00229 m_componentLoadingErrors[KParts::ComponentFactory::ErrServiceProvidesNoLibrary]="ErrServiceProvidesNoLibrary";
00230 m_componentLoadingErrors[KParts::ComponentFactory::ErrNoLibrary]="ErrNoLibrary";
00231 m_componentLoadingErrors[KParts::ComponentFactory::ErrNoFactory]="ErrNoFactory";
00232 m_componentLoadingErrors[KParts::ComponentFactory::ErrNoComponent]="ErrNoComponent";
00233 }
00234 m_serverResultName=m_componentLoadingErrors[m_serverResultNum];
00235 return 0;
00236 }
00237 KexiDBDbg << "KexiDBInterfaceManager::load(): loading succeed: " << name <<endl;
00238
00239
00240
00241 drv->d->service = ptr.data();
00242 drv->d->fileDBDriverMimeType = ptr->property("X-Kexi-FileDBDriverMime").toString();
00243 drv->d->initInternalProperties();
00244
00245 if (!drv->isValid()) {
00246 setError(drv);
00247 delete drv;
00248 return 0;
00249 }
00250 m_drivers.insert(name.latin1(), drv);
00251 return drv;
00252 }
00253
00254 void DriverManagerInternal::incRefCount()
00255 {
00256 m_refCount++;
00257 KexiDBDbg << "DriverManagerInternal::incRefCount(): " << m_refCount << endl;
00258 }
00259
00260 void DriverManagerInternal::decRefCount()
00261 {
00262 m_refCount--;
00263 KexiDBDbg << "DriverManagerInternal::decRefCount(): " << m_refCount << endl;
00264
00265
00266
00267
00268
00269 }
00270
00271 void DriverManagerInternal::aboutDelete( Driver* drv )
00272 {
00273 m_drivers.take(drv->name());
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 DriverManager::DriverManager()
00283 : QObject( 0, "KexiDB::DriverManager" )
00284 , Object()
00285 , d_int( DriverManagerInternal::self() )
00286 {
00287 d_int->incRefCount();
00288
00289
00290
00291 }
00292
00293 DriverManager::~DriverManager()
00294 {
00295 KexiDBDbg << "DriverManager::~DriverManager()" << endl;
00296
00297
00298
00299
00300
00301
00302
00303
00304 d_int->decRefCount();
00305 if (d_int->m_refCount==0) {
00306
00307 delete d_int;
00308 }
00309
00310
00311 KexiDBDbg << "DriverManager::~DriverManager() ok" << endl;
00312 }
00313
00314 const KexiDB::Driver::InfoMap DriverManager::driversInfo()
00315 {
00316 if (!d_int->lookupDrivers())
00317 return KexiDB::Driver::InfoMap();
00318
00319 if (!d_int->m_driversInfo.isEmpty())
00320 return d_int->m_driversInfo;
00321 ServicesMap::ConstIterator it;
00322 for ( it=d_int->m_services.constBegin() ; it != d_int->m_services.constEnd(); ++it ) {
00323 Driver::Info info;
00324 KService::Ptr ptr = it.data();
00325 info.name = ptr->property("X-Kexi-DriverName").toString();
00326 info.caption = ptr->property("Name").toString();
00327 info.comment = ptr->property("Comment").toString();
00328 if (info.caption.isEmpty())
00329 info.caption = info.name;
00330 info.fileBased = (ptr->property("X-Kexi-DriverType").toString().lower()=="file");
00331 if (info.fileBased)
00332 info.fileDBMimeType = ptr->property("X-Kexi-FileDBDriverMime").toString().lower();
00333 QVariant v = ptr->property("X-Kexi-DoNotAllowProjectImportingTo");
00334 info.allowImportingTo = v.isNull() ? true : !v.toBool();
00335 d_int->m_driversInfo.insert(info.name.lower(), info);
00336 }
00337 return d_int->m_driversInfo;
00338 }
00339
00340 const QStringList DriverManager::driverNames()
00341 {
00342 if (!d_int->lookupDrivers())
00343 return QStringList();
00344
00345 if (d_int->m_services.isEmpty() && d_int->error())
00346 return QStringList();
00347 return d_int->m_services.keys();
00348 }
00349
00350 KexiDB::Driver::Info DriverManager::driverInfo(const QString &name)
00351 {
00352 driversInfo();
00353 KexiDB::Driver::Info i = d_int->driverInfo(name);
00354 if (d_int->error())
00355 setError(d_int);
00356 return i;
00357 }
00358
00359 KService::Ptr DriverManager::serviceInfo(const QString &name)
00360 {
00361 if (!d_int->lookupDrivers()) {
00362 setError(d_int);
00363 return KService::Ptr();
00364 }
00365
00366 clearError();
00367 if (d_int->m_services_lcase.contains(name.lower())) {
00368 return *d_int->m_services_lcase.find(name.lower());
00369 } else {
00370 setError(ERR_DRIVERMANAGER, i18n("No such driver service: \"%1\".").arg(name) );
00371 return KService::Ptr();
00372 }
00373 }
00374
00375 const DriverManager::ServicesMap& DriverManager::services()
00376 {
00377 d_int->lookupDrivers();
00378
00379 return d_int->m_services;
00380 }
00381
00382 QString DriverManager::lookupByMime(const QString &mimeType)
00383 {
00384 if (!d_int->lookupDrivers()) {
00385 setError(d_int);
00386 return 0;
00387 }
00388
00389 KService::Ptr ptr = d_int->m_services_by_mimetype[mimeType.lower()];
00390 if (!ptr)
00391 return QString::null;
00392 return ptr->property("X-Kexi-DriverName").toString();
00393 }
00394
00395 Driver* DriverManager::driver(const QString& name)
00396 {
00397 Driver *drv = d_int->driver(name);
00398 if (d_int->error())
00399 setError(d_int);
00400 return drv;
00401 }
00402
00403 QString DriverManager::serverErrorMsg()
00404 {
00405 return d_int->m_serverErrMsg;
00406 }
00407
00408 int DriverManager::serverResult()
00409 {
00410 return d_int->m_serverResultNum;
00411 }
00412
00413 QString DriverManager::serverResultName()
00414 {
00415 return d_int->m_serverResultName;
00416 }
00417
00418 void DriverManager::drv_clearServerResult()
00419 {
00420 d_int->m_serverErrMsg=QString::null;
00421 d_int->m_serverResultNum=0;
00422 d_int->m_serverResultName=QString::null;
00423 }
00424
00425 QString DriverManager::possibleProblemsInfoMsg() const
00426 {
00427 if (d_int->possibleProblems.isEmpty())
00428 return QString::null;
00429 QString str;
00430 str.reserve(1024);
00431 str = "<ul>";
00432 for (QStringList::ConstIterator it = d_int->possibleProblems.constBegin();
00433 it!=d_int->possibleProblems.constEnd(); ++it)
00434 {
00435 str += (QString::fromLatin1("<li>") + *it + QString::fromLatin1("</li>"));
00436 }
00437 str += "</ul>";
00438 return str;
00439 }
00440
00441 #include "drivermanager_p.moc"
00442
|