summaryrefslogtreecommitdiffstats
path: root/kexi/core/kexidbshortcutfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kexi/core/kexidbshortcutfile.cpp')
-rw-r--r--kexi/core/kexidbshortcutfile.cpp314
1 files changed, 314 insertions, 0 deletions
diff --git a/kexi/core/kexidbshortcutfile.cpp b/kexi/core/kexidbshortcutfile.cpp
new file mode 100644
index 00000000..4a503d43
--- /dev/null
+++ b/kexi/core/kexidbshortcutfile.cpp
@@ -0,0 +1,314 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
+
+ This library 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 library 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 library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "kexidbshortcutfile.h"
+#include <core/kexiprojectdata.h>
+#include <kexidb/connectiondata.h>
+#include <kexiutils/utils.h>
+
+#include <kconfig.h>
+#include <kdebug.h>
+
+#include <qstringlist.h>
+#include <qdir.h>
+
+//! Version of the KexiDBShortcutFile format.
+#define KexiDBShortcutFile_version 2
+/* CHANGELOG:
+ v1: initial version
+ v2: "encryptedPassword" field added.
+ For backward compatibility, it is not used if the connection data has been loaded from
+ a file saved with version 1. In such cases unencrypted "password" field is used.
+*/
+
+//! @internal
+class KexiDBShortcutFile::Private
+{
+ public:
+ Private()
+ : isDatabaseShortcut(true)
+ {
+ }
+ QString fileName;
+ bool isDatabaseShortcut : 1;
+};
+
+KexiDBShortcutFile::KexiDBShortcutFile( const QString& fileName )
+ : d( new KexiDBShortcutFile::Private() )
+{
+ d->fileName = QDir(fileName).absPath();
+}
+
+KexiDBShortcutFile::~KexiDBShortcutFile()
+{
+ delete d;
+}
+
+bool KexiDBShortcutFile::loadProjectData(KexiProjectData& data, QString* _groupKey)
+{
+ KConfig config(d->fileName, true /* readOnly */, false /* local */ );
+ config.setGroup("File Information");
+ data.formatVersion = config.readNumEntry("version", KexiDBShortcutFile_version);
+
+ QString groupKey;
+ if (!_groupKey || _groupKey->isEmpty()) {
+ QStringList groups(config.groupList());
+ foreach (QStringList::ConstIterator, it, groups) {
+ if ((*it).lower()!="file information") {
+ groupKey = *it;
+ break;
+ }
+ }
+ if (groupKey.isEmpty()) {
+ //ERR: "File %1 contains no connection information"
+ return false;
+ }
+ if (_groupKey)
+ *_groupKey = groupKey;
+ }
+ else {
+ if (!config.hasGroup(*_groupKey))
+ return false;
+ groupKey = *_groupKey;
+ }
+
+ config.setGroup(groupKey);
+ QString type( config.readEntry("type", "database").lower() );
+
+ if (type=="database") {
+ d->isDatabaseShortcut = true;
+ } else if (type=="connection") {
+ d->isDatabaseShortcut = false;
+ }
+ else {
+ //ERR: i18n("No valid "type" field specified for section \"%1\": unknown value \"%2\".").arg(group).arg(type)
+ return false;
+ }
+
+/* kexidbg << "version=" << version
+ << " using group key=" << groupKey
+ << " type=" << type
+ << " caption=" << config.readEntry("caption")
+ << " name=" << config.readEntry("name")
+ << " engine=" << config.readEntry("engine")
+ << " server=" << config.readEntry("server")
+ << " user=" << config.readEntry("user")
+ << " password=" << QString().fill('*', config.readEntry("password").length())
+ << " comment=" << config.readEntry("comment")
+ << endl;*/
+
+ //no filename by default
+ data.connectionData()->setFileName(QString::null);
+
+ if (d->isDatabaseShortcut) {
+ data.setCaption( config.readEntry("caption") );
+ data.setDescription( config.readEntry("comment") );
+ data.connectionData()->description = QString::null;
+ data.connectionData()->caption = QString::null; /* connection name is not specified... */
+ data.setDatabaseName( config.readEntry("name") );
+ }
+ else {
+ data.setCaption( QString::null );
+ data.connectionData()->caption = config.readEntry("caption");
+ data.setDescription( QString::null );
+ data.connectionData()->description = config.readEntry("comment");
+ data.setDatabaseName( QString::null ); /* db name is not specified... */
+ }
+ data.connectionData()->driverName = config.readEntry("engine");
+ if (data.connectionData()->driverName.isEmpty()) {
+ //ERR: "No valid "engine" field specified for %1 section" group
+ return false;
+ }
+ data.connectionData()->hostName = config.readEntry("server"); //empty allowed
+ data.connectionData()->port = config.readNumEntry("port", 0);
+ data.connectionData()->useLocalSocketFile = config.readBoolEntry("useLocalSocketFile", false);
+ data.connectionData()->localSocketFileName = config.readEntry("localSocketFile");
+ data.connectionData()->savePassword = config.hasKey("password") || config.hasKey("encryptedPassword");
+ if (data.formatVersion >= 2) {
+ kdDebug() << config.hasKey("encryptedPassword") << endl;
+ data.connectionData()->password = config.readEntry("encryptedPassword");
+ KexiUtils::simpleDecrypt(data.connectionData()->password);
+ }
+ if (data.connectionData()->password.isEmpty()) {//no "encryptedPassword", for compatibility
+ //UNSAFE
+ data.connectionData()->password = config.readEntry("password");
+ }
+// data.connectionData()->savePassword = !data.connectionData()->password.isEmpty();
+ data.connectionData()->userName = config.readEntry("user");
+/* @todo add "options=", eg. as string list? */
+ return true;
+}
+
+bool KexiDBShortcutFile::saveProjectData(const KexiProjectData& data,
+ bool savePassword, QString* _groupKey, bool overwriteFirstGroup)
+{
+ KConfig config(d->fileName, false /*rw*/, false /* local */);
+ config.setGroup("File Information");
+
+ uint realFormatVersion = data.formatVersion;
+ if (realFormatVersion == 0) /* 0 means "default version"*/
+ realFormatVersion = KexiDBShortcutFile_version;
+ config.writeEntry("version", realFormatVersion);
+
+ const bool thisIsConnectionData = data.databaseName().isEmpty();
+
+ //use or find a nonempty group key
+ QString groupKey;
+ if (_groupKey && !_groupKey->isEmpty()) {
+ groupKey = *_groupKey;
+ }
+ else {
+ QString groupPrefix;
+ const QStringList groups(config.groupList());
+ if (overwriteFirstGroup && !groups.isEmpty()) {
+// groupKey = groups.first(); //found
+ foreach (QStringList::ConstIterator, it, groups) {
+ if ((*it).lower()!="file information") {
+ groupKey = *it;
+ break;
+ }
+ }
+ }
+
+ if (groupKey.isEmpty()) {
+ //find a new unique name
+ if (thisIsConnectionData)
+ groupPrefix = "Connection%1"; //do not i18n!
+ else
+ groupPrefix = "Database%1"; //do not i18n!
+
+ int number = 1;
+ while (config.hasGroup(groupPrefix.arg(number))) //a new group key couldn't exist
+ number++;
+ groupKey = groupPrefix.arg(number);
+ }
+ if (_groupKey) //return this one (generated or found)
+ *_groupKey = groupKey;
+ }
+
+ config.deleteGroup(groupKey);
+ config.setGroup(groupKey);
+ if (thisIsConnectionData) {
+ config.writeEntry("type", "connection");
+ config.writeEntry("caption", data.constConnectionData()->caption);
+ if (!data.constConnectionData()->description.isEmpty())
+ config.writeEntry("comment", data.constConnectionData()->description);
+ }
+ else {//database
+ config.writeEntry("type", "database");
+ config.writeEntry("caption", data.caption());
+ config.writeEntry("name", data.databaseName());
+ if (!data.description().isEmpty())
+ config.writeEntry("comment", data.description());
+ }
+
+ config.writeEntry("engine", data.constConnectionData()->driverName);
+ if (!data.constConnectionData()->hostName.isEmpty())
+ config.writeEntry("server", data.constConnectionData()->hostName);
+
+ if (data.constConnectionData()->port!=0)
+ config.writeEntry("port", data.constConnectionData()->port);
+ config.writeEntry("useLocalSocketFile", data.constConnectionData()->useLocalSocketFile);
+ if (!data.constConnectionData()->localSocketFileName.isEmpty())
+ config.writeEntry("localSocketFile", data.constConnectionData()->localSocketFileName);
+
+ if (savePassword || data.constConnectionData()->savePassword) {
+ if (realFormatVersion < 2) {
+ config.writeEntry("password", data.constConnectionData()->password);
+ }
+ else {
+ QString encryptedPassword = data.constConnectionData()->password;
+ KexiUtils::simpleCrypt(encryptedPassword);
+ config.writeEntry("encryptedPassword", encryptedPassword);
+ encryptedPassword.fill(' '); //for security
+ }
+ }
+
+ if (!data.constConnectionData()->userName.isEmpty())
+ config.writeEntry("user", data.constConnectionData()->userName);
+/* @todo add "options=", eg. as string list? */
+ config.sync();
+ return true;
+}
+
+QString KexiDBShortcutFile::fileName() const
+{
+ return d->fileName;
+}
+
+//---------------------------------------------
+
+KexiDBConnShortcutFile::KexiDBConnShortcutFile( const QString& fileName )
+ : KexiDBShortcutFile( fileName )
+{
+}
+
+KexiDBConnShortcutFile::~KexiDBConnShortcutFile()
+{
+}
+
+bool KexiDBConnShortcutFile::loadConnectionData(KexiDB::ConnectionData& data, QString* _groupKey)
+{
+ KexiProjectData pdata(data);
+ if (!loadProjectData(pdata, _groupKey))
+ return false;
+ data = *pdata.connectionData();
+ return true;
+}
+
+bool KexiDBConnShortcutFile::saveConnectionData(const KexiDB::ConnectionData& data,
+ bool savePassword, QString* groupKey, bool overwriteFirstGroup)
+{
+ KexiProjectData pdata(data);
+ return saveProjectData(pdata, savePassword, groupKey, overwriteFirstGroup);
+}
+
+//---------------------------------------------
+
+#if 0
+/*! Loads connection data into \a data. */
+bool KexiDBConnSetShortcutFiles::loadConnectionDataSet(KexiDBConnectionSet& set)
+{
+ set.clear();
+// QStringList dirs( KGlobal::dirs()->findDirs("data", "kexi/connections") );
+// kexidbg << dirs << endl;
+ QStringList files( KGlobal::dirs()->findAllResources("data", "kexi/connections/*.kexic") );
+// //also try for capital file extension
+// files += KGlobal::dirs()->findAllResources("data", "kexi/connections/*.KEXIC");
+ kexidbg << files << endl;
+
+ foreach(QStringList::ConstIterator, it, files) {
+ KexiDB::ConnectionData *data = new KexiDB::ConnectionData();
+ KexiDBConnShortcutFile shortcutFile( *it );
+ if (!shortcutFile.loadConnectionData(*data)) {
+ delete data;
+ continue;
+ }
+ set.addConnectionData(data);
+ }
+}
+
+
+/*! Saves a set of connection data \a set to a shortcut files.
+ Existing files are overwritten with a new data. */
+bool KexiDBConnSetShortcutFiles::saveConnectionDataSet(const KexiDBConnectionSet& set)
+{
+}
+
+#endif