You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kexi/core/kexidbshortcutfile.cpp

315 lines
10 KiB

/* 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 <tqstringlist.h>
#include <tqdir.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)
{
}
TQString fileName;
bool isDatabaseShortcut : 1;
};
KexiDBShortcutFile::KexiDBShortcutFile( const TQString& fileName )
: d( new KexiDBShortcutFile::Private() )
{
d->fileName = TQDir(fileName).absPath();
}
KexiDBShortcutFile::~KexiDBShortcutFile()
{
delete d;
}
bool KexiDBShortcutFile::loadProjectData(KexiProjectData& data, TQString* _groupKey)
{
KConfig config(d->fileName, true /* readOnly */, false /* local */ );
config.setGroup("File Information");
data.formatVersion = config.readNumEntry("version", KexiDBShortcutFile_version);
TQString groupKey;
if (!_groupKey || _groupKey->isEmpty()) {
TQStringList groups(config.groupList());
foreach (TQStringList::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);
TQString 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=" << TQString().fill('*', config.readEntry("password").length())
<< " comment=" << config.readEntry("comment")
<< endl;*/
//no filename by default
data.connectionData()->setFileName(TQString());
if (d->isDatabaseShortcut) {
data.setCaption( config.readEntry("caption") );
data.setDescription( config.readEntry("comment") );
data.connectionData()->description = TQString();
data.connectionData()->caption = TQString(); /* connection name is not specified... */
data.setDatabaseName( config.readEntry("name") );
}
else {
data.setCaption( TQString() );
data.connectionData()->caption = config.readEntry("caption");
data.setDescription( TQString() );
data.connectionData()->description = config.readEntry("comment");
data.setDatabaseName( TQString() ); /* 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, TQString* _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
TQString groupKey;
if (_groupKey && !_groupKey->isEmpty()) {
groupKey = *_groupKey;
}
else {
TQString groupPrefix;
const TQStringList groups(config.groupList());
if (overwriteFirstGroup && !groups.isEmpty()) {
// groupKey = groups.first(); //found
foreach (TQStringList::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 {
TQString 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;
}
TQString KexiDBShortcutFile::fileName() const
{
return d->fileName;
}
//---------------------------------------------
KexiDBConnShortcutFile::KexiDBConnShortcutFile( const TQString& fileName )
: KexiDBShortcutFile( fileName )
{
}
KexiDBConnShortcutFile::~KexiDBConnShortcutFile()
{
}
bool KexiDBConnShortcutFile::loadConnectionData(KexiDB::ConnectionData& data, TQString* _groupKey)
{
KexiProjectData pdata(data);
if (!loadProjectData(pdata, _groupKey))
return false;
data = *pdata.connectionData();
return true;
}
bool KexiDBConnShortcutFile::saveConnectionData(const KexiDB::ConnectionData& data,
bool savePassword, TQString* 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();
// TQStringList dirs( KGlobal::dirs()->findDirs("data", "kexi/connections") );
// kexidbg << dirs << endl;
TQStringList 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(TQStringList::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