kexi

kexidbshortcutfile.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kexidbshortcutfile.h"
00021 #include <core/kexiprojectdata.h>
00022 #include <kexidb/connectiondata.h>
00023 #include <kexiutils/utils.h>
00024 
00025 #include <kconfig.h>
00026 #include <kdebug.h>
00027 
00028 #include <qstringlist.h>
00029 #include <qdir.h>
00030 
00032 #define KexiDBShortcutFile_version 2
00033 /* CHANGELOG:
00034  v1: initial version
00035  v2: "encryptedPassword" field added. 
00036      For backward compatibility, it is not used if the connection data has been loaded from 
00037      a file saved with version 1. In such cases unencrypted "password" field is used.
00038 */
00039 
00041 class KexiDBShortcutFile::Private
00042 {
00043     public:
00044         Private()
00045          : isDatabaseShortcut(true)
00046         {
00047         }
00048     QString fileName;
00049     bool isDatabaseShortcut : 1;
00050 };
00051 
00052 KexiDBShortcutFile::KexiDBShortcutFile( const QString& fileName )
00053  : d( new KexiDBShortcutFile::Private() )
00054 {
00055     d->fileName = QDir(fileName).absPath();
00056 }
00057 
00058 KexiDBShortcutFile::~KexiDBShortcutFile()
00059 {
00060     delete d;
00061 }
00062 
00063 bool KexiDBShortcutFile::loadProjectData(KexiProjectData& data, QString* _groupKey)
00064 {
00065     KConfig config(d->fileName, true /* readOnly */, false /* local */ );
00066     config.setGroup("File Information");
00067     data.formatVersion = config.readNumEntry("version", KexiDBShortcutFile_version);
00068 
00069     QString groupKey;
00070     if (!_groupKey || _groupKey->isEmpty()) {
00071         QStringList groups(config.groupList());
00072         foreach (QStringList::ConstIterator, it, groups) {
00073             if ((*it).lower()!="file information") {
00074                 groupKey = *it;
00075                 break;
00076             }
00077         }
00078         if (groupKey.isEmpty()) {
00079             //ERR: "File %1 contains no connection information"
00080             return false;
00081         }
00082         if (_groupKey)
00083             *_groupKey = groupKey;
00084     }
00085     else {
00086         if (!config.hasGroup(*_groupKey))
00087             return false;
00088         groupKey = *_groupKey;
00089     }
00090 
00091     config.setGroup(groupKey);
00092     QString type( config.readEntry("type", "database").lower() );
00093 
00094     if (type=="database") {
00095         d->isDatabaseShortcut = true;
00096     } else if (type=="connection") {
00097         d->isDatabaseShortcut = false;
00098     }
00099     else {
00100         //ERR: i18n("No valid "type" field specified for section \"%1\": unknown value \"%2\".").arg(group).arg(type)
00101         return false;
00102     }
00103 
00104 /*  kexidbg << "version=" << version 
00105         << " using group key=" << groupKey 
00106         << " type=" << type
00107         << " caption=" << config.readEntry("caption")
00108         << " name=" << config.readEntry("name")
00109         << " engine=" << config.readEntry("engine")
00110         << " server=" << config.readEntry("server")
00111         << " user=" << config.readEntry("user")
00112         << " password=" << QString().fill('*', config.readEntry("password").length())
00113         << " comment=" << config.readEntry("comment")
00114         << endl;*/
00115 
00116     //no filename by default
00117     data.connectionData()->setFileName(QString::null);
00118 
00119     if (d->isDatabaseShortcut) {
00120         data.setCaption( config.readEntry("caption") );
00121         data.setDescription( config.readEntry("comment") );
00122         data.connectionData()->description = QString::null;
00123         data.connectionData()->caption = QString::null; /* connection name is not specified... */
00124         data.setDatabaseName( config.readEntry("name") );
00125     }
00126     else {
00127         data.setCaption( QString::null );
00128         data.connectionData()->caption = config.readEntry("caption");
00129         data.setDescription( QString::null );
00130         data.connectionData()->description = config.readEntry("comment");
00131         data.setDatabaseName( QString::null ); /* db name is not specified... */
00132     }
00133     data.connectionData()->driverName = config.readEntry("engine");
00134     if (data.connectionData()->driverName.isEmpty()) {
00135         //ERR: "No valid "engine" field specified for %1 section" group
00136         return false;
00137     }
00138     data.connectionData()->hostName = config.readEntry("server"); //empty allowed
00139     data.connectionData()->port = config.readNumEntry("port", 0);
00140     data.connectionData()->useLocalSocketFile = config.readBoolEntry("useLocalSocketFile", false);
00141     data.connectionData()->localSocketFileName = config.readEntry("localSocketFile");
00142     data.connectionData()->savePassword = config.hasKey("password") || config.hasKey("encryptedPassword");
00143     if (data.formatVersion >= 2) {
00144         kdDebug() << config.hasKey("encryptedPassword") << endl;
00145         data.connectionData()->password = config.readEntry("encryptedPassword");
00146         KexiUtils::simpleDecrypt(data.connectionData()->password);
00147     }
00148     if (data.connectionData()->password.isEmpty()) {//no "encryptedPassword", for compatibility
00149         //UNSAFE
00150         data.connectionData()->password = config.readEntry("password");
00151     }
00152 //  data.connectionData()->savePassword = !data.connectionData()->password.isEmpty();
00153     data.connectionData()->userName = config.readEntry("user");
00154 /* @todo add "options=", eg. as string list? */
00155     return true;
00156 }
00157 
00158 bool KexiDBShortcutFile::saveProjectData(const KexiProjectData& data, 
00159     bool savePassword, QString* _groupKey, bool overwriteFirstGroup)
00160 {
00161     KConfig config(d->fileName, false /*rw*/, false /* local */);
00162     config.setGroup("File Information");
00163 
00164     uint realFormatVersion = data.formatVersion;
00165     if (realFormatVersion == 0) /* 0 means "default version"*/
00166         realFormatVersion = KexiDBShortcutFile_version;
00167     config.writeEntry("version", realFormatVersion);
00168 
00169     const bool thisIsConnectionData = data.databaseName().isEmpty();
00170 
00171     //use or find a nonempty group key
00172     QString groupKey;
00173     if (_groupKey && !_groupKey->isEmpty()) {
00174         groupKey = *_groupKey;
00175     }
00176     else {
00177         QString groupPrefix;
00178         const QStringList groups(config.groupList());
00179         if (overwriteFirstGroup && !groups.isEmpty()) {
00180 //          groupKey = groups.first(); //found
00181             foreach (QStringList::ConstIterator, it, groups) {
00182                 if ((*it).lower()!="file information") {
00183                     groupKey = *it;
00184                     break;
00185                 }
00186             }
00187         }
00188 
00189         if (groupKey.isEmpty()) {
00190             //find a new unique name
00191             if (thisIsConnectionData)
00192                 groupPrefix = "Connection%1"; //do not i18n!
00193             else
00194                 groupPrefix = "Database%1"; //do not i18n!
00195 
00196             int number = 1;
00197             while (config.hasGroup(groupPrefix.arg(number))) //a new group key couldn't exist
00198                 number++;
00199             groupKey = groupPrefix.arg(number);
00200         }
00201         if (_groupKey) //return this one (generated or found)
00202             *_groupKey = groupKey;
00203     }
00204 
00205     config.deleteGroup(groupKey);
00206     config.setGroup(groupKey);
00207     if (thisIsConnectionData) {
00208         config.writeEntry("type", "connection");
00209         config.writeEntry("caption", data.constConnectionData()->caption);
00210         if (!data.constConnectionData()->description.isEmpty())
00211             config.writeEntry("comment", data.constConnectionData()->description);
00212     }
00213     else {//database
00214         config.writeEntry("type", "database");
00215         config.writeEntry("caption", data.caption());
00216         config.writeEntry("name", data.databaseName());
00217         if (!data.description().isEmpty())
00218             config.writeEntry("comment", data.description());
00219     }
00220 
00221     config.writeEntry("engine", data.constConnectionData()->driverName);
00222     if (!data.constConnectionData()->hostName.isEmpty())
00223         config.writeEntry("server", data.constConnectionData()->hostName);
00224 
00225     if (data.constConnectionData()->port!=0)
00226         config.writeEntry("port", data.constConnectionData()->port);
00227     config.writeEntry("useLocalSocketFile", data.constConnectionData()->useLocalSocketFile);
00228     if (!data.constConnectionData()->localSocketFileName.isEmpty())
00229         config.writeEntry("localSocketFile", data.constConnectionData()->localSocketFileName);
00230 
00231     if (savePassword || data.constConnectionData()->savePassword) {
00232         if (realFormatVersion < 2) {
00233             config.writeEntry("password", data.constConnectionData()->password);
00234         }
00235         else {
00236             QString encryptedPassword = data.constConnectionData()->password;
00237             KexiUtils::simpleCrypt(encryptedPassword);
00238             config.writeEntry("encryptedPassword", encryptedPassword);
00239             encryptedPassword.fill(' '); //for security
00240         }
00241     }
00242 
00243     if (!data.constConnectionData()->userName.isEmpty())
00244         config.writeEntry("user", data.constConnectionData()->userName);
00245 /* @todo add "options=", eg. as string list? */
00246     config.sync();
00247     return true;
00248 }
00249 
00250 QString KexiDBShortcutFile::fileName() const
00251 {
00252     return d->fileName;
00253 }
00254 
00255 //---------------------------------------------
00256 
00257 KexiDBConnShortcutFile::KexiDBConnShortcutFile( const QString& fileName )
00258  : KexiDBShortcutFile( fileName )
00259 {
00260 }
00261 
00262 KexiDBConnShortcutFile::~KexiDBConnShortcutFile()
00263 {
00264 }
00265 
00266 bool KexiDBConnShortcutFile::loadConnectionData(KexiDB::ConnectionData& data, QString* _groupKey)
00267 {
00268     KexiProjectData pdata(data);
00269     if (!loadProjectData(pdata, _groupKey))
00270         return false;
00271     data = *pdata.connectionData();
00272     return true;
00273 }
00274 
00275 bool KexiDBConnShortcutFile::saveConnectionData(const KexiDB::ConnectionData& data, 
00276     bool savePassword, QString* groupKey, bool overwriteFirstGroup)
00277 {
00278     KexiProjectData pdata(data);
00279     return saveProjectData(pdata, savePassword, groupKey, overwriteFirstGroup);
00280 }
00281 
00282 //---------------------------------------------
00283 
00284 #if 0
00285 
00286 bool KexiDBConnSetShortcutFiles::loadConnectionDataSet(KexiDBConnectionSet& set)
00287 {
00288     set.clear();
00289 //  QStringList dirs( KGlobal::dirs()->findDirs("data", "kexi/connections") );
00290 //  kexidbg << dirs << endl;
00291     QStringList files( KGlobal::dirs()->findAllResources("data", "kexi/connections/*.kexic") );
00292 //  //also try for capital file extension
00293 //  files += KGlobal::dirs()->findAllResources("data", "kexi/connections/*.KEXIC");
00294     kexidbg << files << endl;
00295 
00296     foreach(QStringList::ConstIterator, it, files) {
00297         KexiDB::ConnectionData *data = new KexiDB::ConnectionData();
00298         KexiDBConnShortcutFile shortcutFile( *it );
00299         if (!shortcutFile.loadConnectionData(*data)) {
00300             delete data;
00301             continue;
00302         }
00303         set.addConnectionData(data);
00304     }
00305 }
00306 
00307 
00310 bool KexiDBConnSetShortcutFiles::saveConnectionDataSet(const KexiDBConnectionSet& set)
00311 {
00312 }
00313 
00314 #endif
KDE Home | KDE Accessibility Home | Description of Access Keys