22#include <kexidb/drivermanager.h>
23#include <kexidb/drivermanager_p.h>
25#include <kexidb/driver.h>
26#include <kexidb/driver_p.h>
27#include <kexidb/error.h>
29#include <klibloader.h>
30#include <tdeparts/componentfactory.h>
38#include <tqapplication.h>
42#define KexiDBDbg if (0) kdDebug()
46DriverManagerInternal* DriverManagerInternal::s_self = 0L;
49DriverManagerInternal::DriverManagerInternal()
50 : TQObject( 0,
"KexiDB::DriverManager" )
52 , m_drivers(17, false)
54 , lookupDriversNeeded(true)
56 m_drivers.setAutoDelete(
true);
61DriverManagerInternal::~DriverManagerInternal()
63 KexiDBDbg <<
"DriverManagerInternal::~DriverManagerInternal()" << endl;
67 KexiDBDbg <<
"DriverManagerInternal::~DriverManagerInternal() ok" << endl;
70void DriverManagerInternal::slotAppQuits()
72 if (tqApp->mainWidget() && tqApp->mainWidget()->isVisible())
74 KexiDBDbg <<
"DriverManagerInternal::slotAppQuits(): let's clear drivers..." << endl;
78DriverManagerInternal *DriverManagerInternal::self()
81 s_self =
new DriverManagerInternal();
86bool DriverManagerInternal::lookupDrivers()
88 if (!lookupDriversNeeded)
92 connect(tqApp,TQ_SIGNAL(aboutToQuit()),
this,TQ_SLOT(slotAppQuits()));
98 lookupDriversNeeded =
false;
100 TDETrader::OfferList tlist = TDETrader::self()->query(
"Kexi/DBDriver");
101 TDETrader::OfferList::ConstIterator it(tlist.constBegin());
102 for(; it != tlist.constEnd(); ++it)
104 KService::Ptr ptr = (*it);
105 if (!ptr->property(
"Library").toString().startsWith(
"kexidb_")) {
106 KexiDBWarn <<
"DriverManagerInternal::lookupDrivers():"
107 " X-TDE-Library == " << ptr->property(
"Library").toString()
108 <<
": no \"kexidb_\" prefix -- skipped to avoid potential conflicts!" << endl;
111 TQString srv_name = ptr->property(
"X-Kexi-DriverName").toString();
112 if (srv_name.isEmpty()) {
113 KexiDBWarn <<
"DriverManagerInternal::lookupDrivers():"
114 " X-Kexi-DriverName must be set for KexiDB driver \""
115 << ptr->property(
"Name").toString() <<
"\" service!\n -- skipped!" << endl;
118 if (m_services_lcase.contains(srv_name.lower())) {
119 KexiDBWarn <<
"DriverManagerInternal::lookupDrivers(): more than one driver named '"
120 << srv_name.lower() <<
"'\n -- skipping this one!" << endl;
124 TQString srv_ver_str = ptr->property(
"X-Kexi-KexiDBVersion").toString();
125 TQStringList lst( TQStringList::split(
".", srv_ver_str) );
126 uint minor_ver, major_ver;
127 bool ok = (lst.count() == 2);
129 major_ver = lst[0].toUInt(&ok);
131 minor_ver = lst[1].toUInt(&ok);
133 KexiDBWarn <<
"DriverManagerInternal::lookupDrivers(): problem with detecting '"
134 << srv_name.lower() <<
"' driver's version -- skipping it!" << endl;
138 KexiDBWarn << TQString(
"DriverManagerInternal::lookupDrivers(): '%1' driver"
139 " has version '%2' but required KexiDB driver version is '%3.%4'\n"
140 " -- skipping this driver!").arg(srv_name.lower()).arg(srv_ver_str)
142 possibleProblems += TQString(
"\"%1\" database driver has version \"%2\" "
143 "but required driver version is \"%3.%4\"")
144 .arg(srv_name.lower()).arg(srv_ver_str)
149 TQString drvType = ptr->property(
"X-Kexi-DriverType").toString().lower();
150 if (drvType==
"file") {
152 TQStringList mimes( ptr->property(
"X-Kexi-FileDBDriverMimeList").toStringList() );
155 TQString mime( ptr->property(
"X-Kexi-FileDBDriverMime").toString().lower() );
157 mimes.append( mime );
161 for (TQStringList::ConstIterator mime_it = mimes.constBegin(); mime_it!=mimes.constEnd(); ++mime_it) {
162 TQString mime( (*mime_it).lower() );
163 if (!m_services_by_mimetype.contains(mime)) {
164 m_services_by_mimetype.insert(mime, ptr);
167 KexiDBWarn <<
"DriverManagerInternal::lookupDrivers(): more than one driver for '"
168 << mime <<
"' mime type!" << endl;
172 m_services.insert(srv_name, ptr);
173 m_services_lcase.insert(srv_name.lower(), ptr);
174 KexiDBDbg <<
"KexiDB::DriverManager::lookupDrivers(): registered driver: " << ptr->name() <<
"(" << ptr->library() <<
")" << endl;
179 setError(ERR_DRIVERMANAGER, i18n(
"Could not find any database drivers.") );
188 if (!error() && i.name.isEmpty())
189 setError(ERR_DRIVERMANAGER, i18n(
"Could not find database driver \"%1\".").arg(name) );
193Driver* DriverManagerInternal::driver(
const TQString& name)
195 if (!lookupDrivers())
199 KexiDBDbg <<
"DriverManager::driver(): loading " << name << endl;
201 Driver *drv = name.isEmpty() ? 0 : m_drivers.find(name.latin1());
205 if (!m_services_lcase.contains(name.lower())) {
206 setError(ERR_DRIVERMANAGER, i18n(
"Could not find database driver \"%1\".").arg(name) );
210 KService::Ptr ptr= *(m_services_lcase.find(name.lower()));
211 TQString srv_name = ptr->property(
"X-Kexi-DriverName").toString();
213 KexiDBDbg <<
"KexiDBInterfaceManager::load(): library: "<<ptr->library()<<endl;
214 drv = KParts::ComponentFactory::createInstanceFromService<KexiDB::Driver>(ptr,
215 this, srv_name.latin1(), TQStringList(),&m_serverResultNum);
218 setError(ERR_DRIVERMANAGER, i18n(
"Could not load database driver \"%1\".")
220 if (m_componentLoadingErrors.isEmpty()) {
221 m_componentLoadingErrors[KParts::ComponentFactory::ErrNoServiceFound]=
"ErrNoServiceFound";
222 m_componentLoadingErrors[KParts::ComponentFactory::ErrServiceProvidesNoLibrary]=
"ErrServiceProvidesNoLibrary";
223 m_componentLoadingErrors[KParts::ComponentFactory::ErrNoLibrary]=
"ErrNoLibrary";
224 m_componentLoadingErrors[KParts::ComponentFactory::ErrNoFactory]=
"ErrNoFactory";
225 m_componentLoadingErrors[KParts::ComponentFactory::ErrNoComponent]=
"ErrNoComponent";
227 m_serverResultName=m_componentLoadingErrors[m_serverResultNum];
230 KexiDBDbg <<
"KexiDBInterfaceManager::load(): loading succeed: " << name <<endl;
234 drv->d->service = ptr.data();
235 drv->d->fileDBDriverMimeType = ptr->property(
"X-Kexi-FileDBDriverMime").toString();
236 drv->d->initInternalProperties();
243 m_drivers.insert(name.latin1(), drv);
247void DriverManagerInternal::incRefCount()
250 KexiDBDbg <<
"DriverManagerInternal::incRefCount(): " << m_refCount << endl;
253void DriverManagerInternal::decRefCount()
256 KexiDBDbg <<
"DriverManagerInternal::decRefCount(): " << m_refCount << endl;
264void DriverManagerInternal::aboutDelete(
Driver* drv )
266 m_drivers.take(drv->name());
275DriverManager::DriverManager()
276 : TQObject( 0,
"KexiDB::DriverManager" )
278 , d_int( DriverManagerInternal::self() )
280 d_int->incRefCount();
286DriverManager::~DriverManager()
288 KexiDBDbg <<
"DriverManager::~DriverManager()" << endl;
297 d_int->decRefCount();
298 if (d_int->m_refCount==0) {
304 KexiDBDbg <<
"DriverManager::~DriverManager() ok" << endl;
309 if (!d_int->lookupDrivers())
310 return KexiDB::Driver::InfoMap();
312 if (!d_int->m_driversInfo.isEmpty())
313 return d_int->m_driversInfo;
314 ServicesMap::ConstIterator it;
315 for ( it=d_int->m_services.constBegin() ; it != d_int->m_services.constEnd(); ++it ) {
317 KService::Ptr ptr = it.data();
318 info.name = ptr->property(
"X-Kexi-DriverName").toString();
319 info.caption = ptr->property(
"Name").toString();
320 info.comment = ptr->property(
"Comment").toString();
321 if (info.caption.isEmpty())
322 info.caption = info.name;
323 info.
fileBased = (ptr->property(
"X-Kexi-DriverType").toString().lower()==
"file");
325 info.fileDBMimeType = ptr->property(
"X-Kexi-FileDBDriverMime").toString().lower();
326 TQVariant v = ptr->property(
"X-Kexi-DoNotAllowProjectImportingTo");
328 d_int->m_driversInfo.insert(info.name.lower(), info);
330 return d_int->m_driversInfo;
335 if (!d_int->lookupDrivers())
336 return TQStringList();
338 if (d_int->m_services.isEmpty() && d_int->error())
339 return TQStringList();
340 return d_int->m_services.keys();
354 if (!d_int->lookupDrivers()) {
356 return KService::Ptr();
360 if (d_int->m_services_lcase.contains(name.lower())) {
361 return *d_int->m_services_lcase.find(name.lower());
363 setError(ERR_DRIVERMANAGER, i18n(
"No such driver service: \"%1\".").arg(name) );
364 return KService::Ptr();
370 d_int->lookupDrivers();
372 return d_int->m_services;
377 if (!d_int->lookupDrivers()) {
382 KService::Ptr ptr = d_int->m_services_by_mimetype[mimeType.lower()];
385 return ptr->property(
"X-Kexi-DriverName").toString();
390 Driver *drv = d_int->driver(name);
398 return d_int->m_serverErrMsg;
403 return d_int->m_serverResultNum;
408 return d_int->m_serverResultName;
413 d_int->m_serverErrMsg=TQString();
414 d_int->m_serverResultNum=0;
415 d_int->m_serverResultName=TQString();
420 if (d_int->possibleProblems.isEmpty())
425 for (TQStringList::ConstIterator it = d_int->possibleProblems.constBegin();
426 it!=d_int->possibleProblems.constEnd(); ++it)
428 str += (TQString::fromLatin1(
"<li>") + *it + TQString::fromLatin1(
"</li>"));
434#include "drivermanager_p.moc"
virtual void drv_clearServerResult()
const KexiDB::Driver::InfoMap driversInfo()
virtual int serverResult()
const TQStringList driverNames()
TQString possibleProblemsInfoMsg() const
Driver * driver(const TQString &name)
KService::Ptr serviceInfo(const TQString &name)
const ServicesMap & services()
KexiDB::Driver::Info driverInfo(const TQString &name)
virtual TQString serverResultName()
TQString lookupByMime(const TQString &mimeType)
virtual TQString serverErrorMsg()
server error is set if there is error at KService level (useful for debugging)
bool fileBased
true is the driver is for file-based database backend
Generic database abstraction.
virtual void clearError()
virtual void setError(int code=ERR_OTHER, const TQString &msg=TQString())
High-level database connectivity library with database backend drivers.
KEXI_DB_EXPORT DatabaseVersionInfo version()