File indexing completed on 2025-01-19 03:53:33
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2007-03-18 0007 * Description : Database Engine storage container for connection parameters. 0008 * 0009 * SPDX-FileCopyrightText: 2007-2008 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * SPDX-FileCopyrightText: 2010 by Holger Foerster <hamsi2k at freenet dot de> 0011 * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0012 * SPDX-FileCopyrightText: 2018 by Mario Frank <mario dot frank at uni minus potsdam dot de> 0013 * 0014 * SPDX-License-Identifier: GPL-2.0-or-later 0015 * 0016 * ============================================================ */ 0017 0018 #include "dbengineparameters.h" 0019 0020 // Qt includes 0021 0022 #include <QDir> 0023 #include <QUrlQuery> 0024 #include <QFile> 0025 #include <QCryptographicHash> 0026 #include <QStandardPaths> 0027 0028 // KDE includes 0029 0030 #include <kconfiggroup.h> 0031 #include <ksharedconfig.h> 0032 0033 // Local includes 0034 0035 #include "digikam_config.h" 0036 #include "digikam_globals.h" 0037 #include "digikam_debug.h" 0038 #include "o0simplecrypt.h" // For password encrypt 0039 0040 namespace 0041 { 0042 0043 static const QLatin1String configGroupDatabase ("Database Settings"); 0044 static const QLatin1String configInternalDatabaseServer ("Internal Database Server"); 0045 static const QLatin1String configInternalDatabaseServerPath ("Internal Database Server Path"); 0046 static const QLatin1String configInternalDatabaseServerUseMariaDB ("Internal Database Server Use MariaDB"); 0047 static const QLatin1String configInternalDatabaseServerMysqlInitCmd ("Internal Database Server Mysql Init Command"); 0048 static const QLatin1String configInternalDatabaseServerMysqlAdminCmd ("Internal Database Server Mysql Admin Command"); 0049 static const QLatin1String configInternalDatabaseServerMysqlServerCmd ("Internal Database Server Mysql Server Command"); 0050 static const QLatin1String configInternalDatabaseServerMysqlUpgradeCmd ("Internal Database Server Mysql Upgrade Command"); 0051 static const QLatin1String configDatabaseType ("Database Type"); 0052 static const QLatin1String configDatabaseName ("Database Name"); ///< For Sqlite the DB file path, for Mysql the DB name 0053 static const QLatin1String configDatabaseNameThumbnails ("Database Name Thumbnails"); ///< For Sqlite the DB file path, for Mysql the DB name 0054 static const QLatin1String configDatabaseNameFace ("Database Name Face"); ///< For Sqlite the DB file path, for Mysql the DB name 0055 static const QLatin1String configDatabaseNameSimilarity ("Database Name Similarity"); ///< For Sqlite the DB file path, for Mysql the DB name 0056 static const QLatin1String configDatabaseHostName ("Database Hostname"); 0057 static const QLatin1String configDatabasePort ("Database Port"); 0058 static const QLatin1String configDatabaseUsername ("Database Username"); 0059 static const QLatin1String configDatabasePassword ("Database Password"); ///< For compatbilitity. Use encrypted version instead. 0060 static const QLatin1String configDatabaseEncryptedPassword ("Database Encrypted Password"); 0061 static const QLatin1String configDatabaseConnectOptions ("Database Connectoptions"); 0062 static const QLatin1String configDatabaseWALMode ("Database WAL Mode"); 0063 0064 /// Legacy for older versions. 0065 static const QLatin1String configDatabaseFilePathEntry ("Database File Path"); 0066 static const QLatin1String configAlbumPathEntry ("Album Path"); 0067 /// Sqlite DB file names 0068 static const QLatin1String digikam4db ("digikam4.db"); 0069 static const QLatin1String thumbnails_digikamdb ("thumbnails-digikam.db"); 0070 static const QLatin1String face_digikamdb ("recognition.db"); 0071 static const QLatin1String similarity_digikamdb ("similarity.db"); 0072 0073 } 0074 0075 namespace Digikam 0076 { 0077 0078 QString DbEngineParameters::serverPrivatePath() 0079 { 0080 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + 0081 QLatin1String("/digikam/"); 0082 } 0083 0084 DbEngineParameters::DbEngineParameters() 0085 : port (-1), 0086 walMode (false), 0087 internalServer(false) 0088 { 0089 } 0090 0091 DbEngineParameters::DbEngineParameters(const QString& _type, 0092 const QString& _databaseNameCore, 0093 const QString& _connectOptions, 0094 const QString& _hostName, 0095 int _port, 0096 bool _walMode, 0097 bool _internalServer, 0098 const QString& _userName, 0099 const QString& _password, 0100 const QString& _databaseNameThumbnails, 0101 const QString& _databaseNameFace, 0102 const QString& _databaseNameSimilarity, 0103 const QString& _internalServerDBPath, 0104 const QString& _internalServerMysqlInitCmd, 0105 const QString& _internalServerMysqlAdminCmd, 0106 const QString& _internalServerMysqlServerCmd, 0107 const QString& _internalServerMysqlUpgradeCmd) 0108 : databaseType (_type), 0109 databaseNameCore (_databaseNameCore), 0110 connectOptions (_connectOptions), 0111 hostName (_hostName), 0112 port (_port), 0113 walMode (_walMode), 0114 internalServer (_internalServer), 0115 userName (_userName), 0116 password (_password), 0117 databaseNameThumbnails (_databaseNameThumbnails), 0118 databaseNameFace (_databaseNameFace), 0119 databaseNameSimilarity (_databaseNameSimilarity), 0120 internalServerDBPath (_internalServerDBPath), 0121 internalServerMysqlInitCmd (_internalServerMysqlInitCmd), 0122 internalServerMysqlAdminCmd (_internalServerMysqlAdminCmd), 0123 internalServerMysqlServerCmd (_internalServerMysqlServerCmd), 0124 internalServerMysqlUpgradeCmd (_internalServerMysqlUpgradeCmd) 0125 { 0126 } 0127 0128 DbEngineParameters::DbEngineParameters(const QUrl& url) 0129 : databaseType (QUrlQuery(url).queryItemValue(QLatin1String("databaseType"))), 0130 databaseNameCore (QUrlQuery(url).queryItemValue(QLatin1String("databaseNameCore"))), 0131 connectOptions (QUrlQuery(url).queryItemValue(QLatin1String("connectOptions"))), 0132 hostName (QUrlQuery(url).queryItemValue(QLatin1String("hostName"))), 0133 port (-1), 0134 walMode (false), 0135 internalServer (false), 0136 databaseNameThumbnails(QUrlQuery(url).queryItemValue(QLatin1String("databaseNameThumbnails"))), 0137 databaseNameFace (QUrlQuery(url).queryItemValue(QLatin1String("databaseNameFace"))), 0138 databaseNameSimilarity(QUrlQuery(url).queryItemValue(QLatin1String("databaseNameSimilarity"))) 0139 { 0140 QString queryPort = QUrlQuery(url).queryItemValue(QLatin1String("port")); 0141 0142 if (!queryPort.isNull()) 0143 { 0144 port = queryPort.toInt(); 0145 } 0146 0147 QString queryWalMode = QUrlQuery(url).queryItemValue(QLatin1String("walMode")); 0148 0149 if (!queryWalMode.isNull()) 0150 { 0151 walMode = (queryWalMode == QLatin1String("true")); 0152 } 0153 0154 #if defined(HAVE_MYSQLSUPPORT) && defined(HAVE_INTERNALMYSQL) 0155 0156 QString queryServer = QUrlQuery(url).queryItemValue(QLatin1String("internalServer")); 0157 0158 if (!queryServer.isNull()) 0159 { 0160 internalServer = (queryServer == QLatin1String("true")); 0161 } 0162 0163 queryServer = QUrlQuery(url).queryItemValue(QLatin1String("internalServerPath")); 0164 0165 if (!queryServer.isNull()) 0166 { 0167 internalServerDBPath = QUrlQuery(url).queryItemValue(QLatin1String("internalServerPath")); 0168 } 0169 else 0170 { 0171 internalServerDBPath = serverPrivatePath(); 0172 } 0173 0174 internalServerMysqlInitCmd = QUrlQuery(url).queryItemValue(QLatin1String("internalServerMysqlInitCmd")); 0175 internalServerMysqlAdminCmd = QUrlQuery(url).queryItemValue(QLatin1String("internalServerMysqlAdminCmd")); 0176 internalServerMysqlServerCmd = QUrlQuery(url).queryItemValue(QLatin1String("internalServerMysqlServerCmd")); 0177 internalServerMysqlUpgradeCmd = QUrlQuery(url).queryItemValue(QLatin1String("internalServerMysqlUpgradeCmd")); 0178 0179 #else 0180 0181 internalServer = false; 0182 0183 #endif 0184 0185 userName = QUrlQuery(url).queryItemValue(QLatin1String("userName")); 0186 password = QUrlQuery(url).queryItemValue(QLatin1String("password")); 0187 } 0188 0189 void DbEngineParameters::insertInUrl(QUrl& url) const 0190 { 0191 removeFromUrl(url); 0192 0193 QUrlQuery q(url); 0194 q.addQueryItem(QLatin1String("databaseType"), databaseType); 0195 q.addQueryItem(QLatin1String("databaseNameCore"), databaseNameCore); 0196 q.addQueryItem(QLatin1String("databaseNameThumbnails"), databaseNameThumbnails); 0197 q.addQueryItem(QLatin1String("databaseNameFace"), databaseNameFace); 0198 q.addQueryItem(QLatin1String("databaseNameSimilarity"), databaseNameSimilarity); 0199 0200 if (!connectOptions.isNull()) 0201 { 0202 q.addQueryItem(QLatin1String("connectOptions"), connectOptions); 0203 } 0204 0205 if (!hostName.isNull()) 0206 { 0207 q.addQueryItem(QLatin1String("hostName"), hostName); 0208 } 0209 0210 if (port != -1) 0211 { 0212 q.addQueryItem(QLatin1String("port"), QString::number(port)); 0213 } 0214 0215 if (walMode) 0216 { 0217 q.addQueryItem(QLatin1String("walMode"), QLatin1String("true")); 0218 } 0219 0220 if (internalServer) 0221 { 0222 q.addQueryItem(QLatin1String("internalServer"), QLatin1String("true")); 0223 q.addQueryItem(QLatin1String("internalServerPath"), internalServerDBPath); 0224 q.addQueryItem(QLatin1String("internalServerMysqlInitCmd"), internalServerMysqlInitCmd); 0225 q.addQueryItem(QLatin1String("internalServerMysqlAdminCmd"), internalServerMysqlAdminCmd); 0226 q.addQueryItem(QLatin1String("internalServerMysqlServerCmd"), internalServerMysqlServerCmd); 0227 q.addQueryItem(QLatin1String("internalServerMysqlUpgradeCmd"), internalServerMysqlUpgradeCmd); 0228 } 0229 0230 if (!userName.isNull()) 0231 { 0232 q.addQueryItem(QLatin1String("userName"), userName); 0233 } 0234 0235 if (!password.isNull()) 0236 { 0237 q.addQueryItem(QLatin1String("password"), password); 0238 } 0239 0240 url.setQuery(q); 0241 } 0242 0243 void DbEngineParameters::removeFromUrl(QUrl& url) 0244 { 0245 QUrlQuery q(url); 0246 0247 q.removeQueryItem(QLatin1String("databaseType")); 0248 q.removeQueryItem(QLatin1String("databaseNameCore")); 0249 q.removeQueryItem(QLatin1String("databaseNameThumbnails")); 0250 q.removeQueryItem(QLatin1String("databaseNameFace")); 0251 q.removeQueryItem(QLatin1String("databaseNameSimilarity")); 0252 q.removeQueryItem(QLatin1String("connectOptions")); 0253 q.removeQueryItem(QLatin1String("hostName")); 0254 q.removeQueryItem(QLatin1String("port")); 0255 q.removeQueryItem(QLatin1String("walMode")); 0256 q.removeQueryItem(QLatin1String("internalServer")); 0257 q.removeQueryItem(QLatin1String("internalServerPath")); 0258 q.removeQueryItem(QLatin1String("internalServerMysqlInitCmd")); 0259 q.removeQueryItem(QLatin1String("internalServerMysqlAdminCmd")); 0260 q.removeQueryItem(QLatin1String("internalServerMysqlServerCmd")); 0261 q.removeQueryItem(QLatin1String("internalServerMysqlUpgradeCmd")); 0262 q.removeQueryItem(QLatin1String("userName")); 0263 q.removeQueryItem(QLatin1String("password")); 0264 0265 url.setQuery(q); 0266 } 0267 0268 bool DbEngineParameters::operator==(const DbEngineParameters& other) const 0269 { 0270 return ( 0271 (databaseType == other.databaseType) && 0272 (databaseNameCore == other.databaseNameCore) && 0273 (databaseNameThumbnails == other.databaseNameThumbnails) && 0274 (databaseNameFace == other.databaseNameFace) && 0275 (databaseNameSimilarity == other.databaseNameSimilarity) && 0276 (connectOptions == other.connectOptions) && 0277 (hostName == other.hostName) && 0278 (port == other.port) && 0279 (walMode == other.walMode) && 0280 (internalServer == other.internalServer) && 0281 (internalServerDBPath == other.internalServerDBPath) && 0282 (internalServerMysqlInitCmd == other.internalServerMysqlInitCmd) && 0283 (internalServerMysqlAdminCmd == other.internalServerMysqlAdminCmd) && 0284 (internalServerMysqlServerCmd == other.internalServerMysqlServerCmd) && 0285 (internalServerMysqlUpgradeCmd == other.internalServerMysqlUpgradeCmd) && 0286 (userName == other.userName) && 0287 (password == other.password) 0288 ); 0289 } 0290 0291 bool DbEngineParameters::operator!=(const DbEngineParameters& other) const 0292 { 0293 return (!operator == (other)); 0294 } 0295 0296 bool DbEngineParameters::isValid() const 0297 { 0298 if (isSQLite()) 0299 { 0300 return !databaseNameCore.isEmpty(); 0301 } 0302 0303 return false; 0304 } 0305 0306 bool DbEngineParameters::isSQLite() const 0307 { 0308 return (databaseType == QLatin1String("QSQLITE")); 0309 } 0310 0311 bool DbEngineParameters::isMySQL() const 0312 { 0313 return (databaseType == QLatin1String("QMYSQL")); 0314 } 0315 0316 QString DbEngineParameters::SQLiteDatabaseType() 0317 { 0318 return QLatin1String("QSQLITE"); 0319 } 0320 0321 QString DbEngineParameters::MySQLDatabaseType() 0322 { 0323 return QLatin1String("QMYSQL"); 0324 } 0325 0326 QString DbEngineParameters::SQLiteDatabaseFile() const 0327 { 0328 if (isSQLite()) 0329 { 0330 return databaseNameCore; 0331 } 0332 0333 return QString(); 0334 } 0335 0336 QByteArray DbEngineParameters::hash() const 0337 { 0338 QCryptographicHash md5(QCryptographicHash::Md5); 0339 0340 md5.addData(databaseType.toUtf8()); 0341 md5.addData(databaseNameCore.toUtf8()); 0342 md5.addData(databaseNameThumbnails.toUtf8()); 0343 md5.addData(databaseNameFace.toUtf8()); 0344 md5.addData(databaseNameSimilarity.toUtf8()); 0345 md5.addData(connectOptions.toUtf8()); 0346 md5.addData(hostName.toUtf8()); 0347 md5.addData((const char*)&port, sizeof(int)); 0348 md5.addData(userName.toUtf8()); 0349 md5.addData(password.toUtf8()); 0350 md5.addData((const char*)&internalServer, sizeof(bool)); 0351 md5.addData(internalServerDBPath.toUtf8()); 0352 0353 return md5.result().toHex(); 0354 } 0355 0356 DbEngineParameters DbEngineParameters::parametersFromConfig(const QString& configGroup) 0357 { 0358 DbEngineParameters parameters; 0359 parameters.readFromConfig(configGroup); 0360 0361 return parameters; 0362 } 0363 0364 void DbEngineParameters::readFromConfig(const QString& configGroup) 0365 { 0366 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0367 KConfigGroup group; 0368 0369 if (configGroup.isNull()) 0370 { 0371 group = config->group(configGroupDatabase); 0372 } 0373 else 0374 { 0375 group = config->group(configGroup); 0376 } 0377 0378 databaseType = group.readEntry(configDatabaseType, QString()); 0379 0380 if (isSQLite()) // see bug #267131 0381 { 0382 databaseNameCore = group.readPathEntry(configDatabaseName, QString()); 0383 databaseNameThumbnails = group.readPathEntry(configDatabaseNameThumbnails, QString()); 0384 databaseNameFace = group.readPathEntry(configDatabaseNameFace, QString()); 0385 databaseNameSimilarity = group.readPathEntry(configDatabaseNameSimilarity, QString()); 0386 walMode = group.readEntry(configDatabaseWALMode, true); 0387 } 0388 else 0389 { 0390 databaseNameCore = group.readEntry(configDatabaseName, QString()); 0391 databaseNameThumbnails = group.readEntry(configDatabaseNameThumbnails, QString()); 0392 databaseNameFace = group.readEntry(configDatabaseNameFace, QString()); 0393 databaseNameSimilarity = group.readEntry(configDatabaseNameSimilarity, QString()); 0394 } 0395 0396 hostName = group.readEntry(configDatabaseHostName, QString()); 0397 port = group.readEntry(configDatabasePort, -1); 0398 userName = group.readEntry(configDatabaseUsername, QString()); 0399 0400 // Non encrypted password for compatibility. 0401 0402 password = group.readEntry(configDatabasePassword, QString()); 0403 0404 if (password.isEmpty()) 0405 { 0406 password = group.readEntry(configDatabaseEncryptedPassword, QString()); 0407 0408 if (!password.isEmpty()) 0409 { 0410 O0SimpleCrypt crypto(QCryptographicHash::hash(configDatabaseEncryptedPassword.latin1(), 0411 QCryptographicHash::Sha1).toULongLong()); 0412 password = crypto.decryptToString(password); 0413 } 0414 } 0415 0416 connectOptions = group.readEntry(configDatabaseConnectOptions, QString()); 0417 0418 #if defined(HAVE_MYSQLSUPPORT) && defined(HAVE_INTERNALMYSQL) 0419 0420 if (isSQLite()) 0421 { 0422 internalServer = group.readEntry(configInternalDatabaseServer, false); 0423 internalServerDBPath = group.readEntry(configInternalDatabaseServerPath, QString()); 0424 internalServerMysqlInitCmd = group.readEntry(configInternalDatabaseServerMysqlInitCmd, QString()); 0425 internalServerMysqlAdminCmd = group.readEntry(configInternalDatabaseServerMysqlAdminCmd, QString()); 0426 internalServerMysqlServerCmd = group.readEntry(configInternalDatabaseServerMysqlServerCmd, QString()); 0427 internalServerMysqlUpgradeCmd = group.readEntry(configInternalDatabaseServerMysqlUpgradeCmd, QString()); 0428 } 0429 else 0430 { 0431 internalServer = group.readEntry(configInternalDatabaseServer, false); 0432 internalServerDBPath = group.readEntry(configInternalDatabaseServerPath, serverPrivatePath()); 0433 internalServerMysqlInitCmd = group.readEntry(configInternalDatabaseServerMysqlInitCmd, defaultMysqlInitCmd()); 0434 internalServerMysqlAdminCmd = group.readEntry(configInternalDatabaseServerMysqlAdminCmd, defaultMysqlAdminCmd()); 0435 internalServerMysqlServerCmd = group.readEntry(configInternalDatabaseServerMysqlServerCmd, defaultMysqlServerCmd()); 0436 internalServerMysqlUpgradeCmd = group.readEntry(configInternalDatabaseServerMysqlUpgradeCmd, defaultMysqlUpgradeCmd()); 0437 } 0438 0439 #else 0440 0441 internalServer = false; 0442 0443 #endif 0444 0445 if (isSQLite() && !databaseNameCore.isNull()) 0446 { 0447 QString orgName = databaseNameCore; 0448 setCoreDatabasePath(orgName); 0449 setThumbsDatabasePath(orgName); 0450 setFaceDatabasePath(orgName); 0451 setSimilarityDatabasePath(orgName); 0452 } 0453 } 0454 0455 void DbEngineParameters::setInternalServerPath(const QString& path) 0456 { 0457 internalServerDBPath = path; 0458 } 0459 0460 QString DbEngineParameters::internalServerPath() const 0461 { 0462 QFileInfo fileInfo(internalServerDBPath); 0463 0464 return QDir::cleanPath(fileInfo.filePath()); 0465 } 0466 0467 void DbEngineParameters::setCoreDatabasePath(const QString& folderOrFileOrName) 0468 { 0469 if (isSQLite()) 0470 { 0471 databaseNameCore = coreDatabaseFileSQLite(folderOrFileOrName); 0472 } 0473 else 0474 { 0475 databaseNameCore = folderOrFileOrName; 0476 } 0477 } 0478 0479 void DbEngineParameters::setThumbsDatabasePath(const QString& folderOrFileOrName) 0480 { 0481 if (isSQLite()) 0482 { 0483 databaseNameThumbnails = thumbnailDatabaseFileSQLite(folderOrFileOrName); 0484 } 0485 else 0486 { 0487 databaseNameThumbnails = folderOrFileOrName; 0488 } 0489 } 0490 0491 void DbEngineParameters::setFaceDatabasePath(const QString& folderOrFileOrName) 0492 { 0493 if (isSQLite()) 0494 { 0495 databaseNameFace = faceDatabaseFileSQLite(folderOrFileOrName); 0496 } 0497 else 0498 { 0499 databaseNameFace = folderOrFileOrName; 0500 } 0501 } 0502 0503 void DbEngineParameters::setSimilarityDatabasePath(const QString& folderOrFileOrName) 0504 { 0505 if (isSQLite()) 0506 { 0507 databaseNameSimilarity = similarityDatabaseFileSQLite(folderOrFileOrName); 0508 } 0509 else 0510 { 0511 databaseNameSimilarity = folderOrFileOrName; 0512 } 0513 } 0514 0515 QString DbEngineParameters::coreDatabaseFileSQLite(const QString& folderOrFile) 0516 { 0517 QFileInfo fileInfo(folderOrFile); 0518 0519 if (fileInfo.isDir()) 0520 { 0521 return (QDir::cleanPath(fileInfo.filePath() + QLatin1Char('/') + QLatin1String(digikam4db))); 0522 } 0523 0524 return QDir::cleanPath(folderOrFile); 0525 } 0526 0527 QString DbEngineParameters::thumbnailDatabaseFileSQLite(const QString& folderOrFile) 0528 { 0529 QFileInfo fileInfo(folderOrFile); 0530 0531 if (fileInfo.isDir()) 0532 { 0533 return (QDir::cleanPath(fileInfo.filePath() + QLatin1Char('/') + QLatin1String(thumbnails_digikamdb))); 0534 } 0535 0536 return QDir::cleanPath(folderOrFile); 0537 } 0538 0539 QString DbEngineParameters::faceDatabaseFileSQLite(const QString& folderOrFile) 0540 { 0541 QFileInfo fileInfo(folderOrFile); 0542 0543 if (fileInfo.isDir()) 0544 { 0545 return (QDir::cleanPath(fileInfo.filePath() + QLatin1Char('/') + QLatin1String(face_digikamdb))); 0546 } 0547 0548 return QDir::cleanPath(folderOrFile); 0549 } 0550 0551 QString DbEngineParameters::similarityDatabaseFileSQLite(const QString& folderOrFile) 0552 { 0553 QFileInfo fileInfo(folderOrFile); 0554 0555 if (fileInfo.isDir()) 0556 { 0557 return (QDir::cleanPath(fileInfo.filePath() + QLatin1Char('/') + QLatin1String(similarity_digikamdb))); 0558 } 0559 0560 return QDir::cleanPath(folderOrFile); 0561 } 0562 0563 void DbEngineParameters::legacyAndDefaultChecks(const QString& suggestedPath) 0564 { 0565 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0566 0567 // Additional semantic checks for the database section. 0568 // If the internal server should be started, then the connection options must be reset 0569 0570 if ((databaseType == QLatin1String("QMYSQL")) && internalServer) 0571 { 0572 const QString miscDir = serverPrivatePath() + QLatin1String("db_misc"); 0573 databaseNameCore = QLatin1String("digikam"); 0574 databaseNameThumbnails = QLatin1String("digikam"); 0575 databaseNameFace = QLatin1String("digikam"); 0576 databaseNameSimilarity = QLatin1String("digikam"); 0577 internalServer = true; 0578 userName = QLatin1String("root"); 0579 password.clear(); 0580 0581 #ifdef Q_OS_WIN 0582 0583 hostName = QLatin1String("localhost"); 0584 port = 3307; 0585 connectOptions.clear(); 0586 0587 #else 0588 0589 hostName.clear(); 0590 port = -1; 0591 connectOptions = QString::fromLatin1("UNIX_SOCKET=%1/mysql.socket").arg(miscDir); 0592 0593 #endif 0594 0595 } 0596 0597 if (databaseType.isEmpty()) 0598 { 0599 // Empty 1.3 config: migration from older versions 0600 0601 KConfigGroup group = config->group(QLatin1String("Album Settings")); 0602 0603 QString databaseFilePath; 0604 0605 if (group.hasKey(configDatabaseFilePathEntry)) 0606 { 0607 // 1.0 - 1.2 style database file path? 0608 0609 databaseFilePath = group.readEntry(configDatabaseFilePathEntry, QString()); 0610 } 0611 else if (group.hasKey(configAlbumPathEntry)) 0612 { 0613 // <= 0.9 style album path entry? 0614 0615 databaseFilePath = group.readEntry(configAlbumPathEntry, QString()); 0616 } 0617 else if (!suggestedPath.isNull()) 0618 { 0619 databaseFilePath = suggestedPath; 0620 } 0621 0622 if (!databaseFilePath.isEmpty()) 0623 { 0624 *this = parametersForSQLite(coreDatabaseFileSQLite(databaseFilePath)); 0625 } 0626 0627 // Be aware that schema updating from version <= 0.9 requires reading the "Album Path", so do not remove it here 0628 } 0629 } 0630 0631 void DbEngineParameters::removeLegacyConfig() 0632 { 0633 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0634 KConfigGroup group = config->group(QLatin1String("Album Settings")); 0635 0636 if (group.hasKey(configDatabaseFilePathEntry)) 0637 { 0638 group.deleteEntry(configDatabaseFilePathEntry); 0639 } 0640 0641 if (group.hasKey(configAlbumPathEntry)) 0642 { 0643 group.deleteEntry(configAlbumPathEntry); 0644 } 0645 } 0646 0647 void DbEngineParameters::writeToConfig(const QString& configGroup) const 0648 { 0649 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0650 KConfigGroup group; 0651 0652 if (configGroup.isNull()) 0653 { 0654 group = config->group(configGroupDatabase); 0655 } 0656 else 0657 { 0658 group = config->group(configGroup); 0659 } 0660 0661 QString dbName = getCoreDatabaseNameOrDir(); 0662 QString dbNameThumbs = getThumbsDatabaseNameOrDir(); 0663 QString dbNameFace = getFaceDatabaseNameOrDir(); 0664 QString dbNameSimilarity = getSimilarityDatabaseNameOrDir(); 0665 0666 group.writeEntry(configDatabaseType, databaseType); 0667 group.writeEntry(configDatabaseName, dbName); 0668 group.writeEntry(configDatabaseNameThumbnails, dbNameThumbs); 0669 group.writeEntry(configDatabaseNameFace, dbNameFace); 0670 group.writeEntry(configDatabaseNameSimilarity, dbNameSimilarity); 0671 group.writeEntry(configDatabaseHostName, hostName); 0672 group.writeEntry(configDatabasePort, port); 0673 group.writeEntry(configDatabaseWALMode, walMode); 0674 group.writeEntry(configDatabaseUsername, userName); 0675 0676 O0SimpleCrypt crypto(QCryptographicHash::hash(configDatabaseEncryptedPassword.latin1(), 0677 QCryptographicHash::Sha1).toULongLong()); 0678 group.writeEntry(configDatabaseEncryptedPassword, crypto.encryptToString(password)); 0679 0680 group.writeEntry(configDatabaseConnectOptions, connectOptions); 0681 group.writeEntry(configInternalDatabaseServer, internalServer); 0682 group.writeEntry(configInternalDatabaseServerPath, internalServerDBPath); 0683 group.writeEntry(configInternalDatabaseServerMysqlInitCmd, internalServerMysqlInitCmd); 0684 group.writeEntry(configInternalDatabaseServerMysqlAdminCmd, internalServerMysqlAdminCmd); 0685 group.writeEntry(configInternalDatabaseServerMysqlServerCmd, internalServerMysqlServerCmd); 0686 group.writeEntry(configInternalDatabaseServerMysqlUpgradeCmd, internalServerMysqlUpgradeCmd); 0687 0688 group.deleteEntry(configDatabasePassword); // Remove non encrypted password 0689 } 0690 0691 QString DbEngineParameters::getCoreDatabaseNameOrDir() const 0692 { 0693 if (isSQLite()) 0694 { 0695 return coreDatabaseDirectorySQLite(databaseNameCore); 0696 } 0697 0698 return databaseNameCore; 0699 } 0700 0701 QString DbEngineParameters::getThumbsDatabaseNameOrDir() const 0702 { 0703 if (isSQLite()) 0704 { 0705 return thumbnailDatabaseDirectorySQLite(databaseNameThumbnails); 0706 } 0707 0708 return databaseNameThumbnails; 0709 } 0710 0711 QString DbEngineParameters::getFaceDatabaseNameOrDir() const 0712 { 0713 if (isSQLite()) 0714 { 0715 return faceDatabaseDirectorySQLite(databaseNameFace); 0716 } 0717 0718 return databaseNameFace; 0719 } 0720 0721 QString DbEngineParameters::getSimilarityDatabaseNameOrDir() const 0722 { 0723 if (isSQLite()) 0724 { 0725 return similarityDatabaseDirectorySQLite(databaseNameSimilarity); 0726 } 0727 0728 return databaseNameSimilarity; 0729 } 0730 0731 QString DbEngineParameters::coreDatabaseDirectorySQLite(const QString& path) 0732 { 0733 if (path.endsWith(QLatin1String(digikam4db))) 0734 { 0735 QString chopped(path); 0736 chopped.chop(QString(QLatin1String(digikam4db)).length()); 0737 0738 return chopped; 0739 } 0740 0741 return path; 0742 } 0743 0744 QString DbEngineParameters::thumbnailDatabaseDirectorySQLite(const QString& path) 0745 { 0746 if (path.endsWith(QLatin1String(thumbnails_digikamdb))) 0747 { 0748 QString chopped(path); 0749 chopped.chop(QString(QLatin1String(thumbnails_digikamdb)).length()); 0750 0751 return chopped; 0752 } 0753 0754 return path; 0755 } 0756 0757 QString DbEngineParameters::faceDatabaseDirectorySQLite(const QString& path) 0758 { 0759 if (path.endsWith(QLatin1String(face_digikamdb))) 0760 { 0761 QString chopped(path); 0762 chopped.chop(QString(QLatin1String(face_digikamdb)).length()); 0763 0764 return chopped; 0765 } 0766 0767 return path; 0768 } 0769 0770 QString DbEngineParameters::similarityDatabaseDirectorySQLite(const QString& path) 0771 { 0772 if (path.endsWith(QLatin1String(similarity_digikamdb))) 0773 { 0774 QString chopped(path); 0775 chopped.chop(QString(QLatin1String(similarity_digikamdb)).length()); 0776 0777 return chopped; 0778 } 0779 0780 return path; 0781 } 0782 0783 DbEngineParameters DbEngineParameters::defaultParameters(const QString& databaseType) 0784 { 0785 DbEngineParameters parameters; 0786 0787 // only the database name is needed 0788 0789 DbEngineConfigSettings config = DbEngineConfig::element(databaseType); 0790 parameters.databaseType = databaseType; 0791 parameters.databaseNameCore = config.databaseName; 0792 parameters.databaseNameThumbnails = config.databaseName; 0793 parameters.databaseNameFace = config.databaseName; 0794 parameters.databaseNameSimilarity = config.databaseName; 0795 parameters.userName = config.userName; 0796 parameters.password = config.password; 0797 parameters.walMode = false; 0798 parameters.internalServer = (databaseType == QLatin1String("QMYSQL")); 0799 parameters.internalServerDBPath = (databaseType == QLatin1String("QMYSQL")) ? serverPrivatePath() : QString(); 0800 parameters.internalServerMysqlInitCmd = (databaseType == QLatin1String("QMYSQL")) ? defaultMysqlInitCmd() : QString(); 0801 parameters.internalServerMysqlAdminCmd = (databaseType == QLatin1String("QMYSQL")) ? defaultMysqlAdminCmd() : QString(); 0802 parameters.internalServerMysqlServerCmd = (databaseType == QLatin1String("QMYSQL")) ? defaultMysqlServerCmd() : QString(); 0803 parameters.internalServerMysqlUpgradeCmd = (databaseType == QLatin1String("QMYSQL")) ? defaultMysqlUpgradeCmd() : QString(); 0804 0805 QString hostName = config.hostName; 0806 QString port = config.port; 0807 QString connectOptions = config.connectOptions; 0808 0809 #ifdef Q_OS_WIN 0810 0811 hostName.replace(QLatin1String("$$DBHOSTNAME$$"), (databaseType == QLatin1String("QMYSQL")) 0812 ? QLatin1String("localhost") 0813 : QString()); 0814 0815 port.replace(QLatin1String("$$DBPORT$$"), (databaseType == QLatin1String("QMYSQL")) 0816 ? QLatin1String("3307") 0817 : QLatin1String("-1")); 0818 0819 connectOptions.replace(QLatin1String("$$DBOPTIONS$$"), QString()); 0820 0821 #else 0822 0823 hostName.replace(QLatin1String("$$DBHOSTNAME$$"), QString()); 0824 0825 port.replace(QLatin1String("$$DBPORT$$"), QLatin1String("-1")); 0826 0827 const QString miscDir = serverPrivatePath() + QLatin1String("db_misc"); 0828 connectOptions.replace(QLatin1String("$$DBOPTIONS$$"), (databaseType == QLatin1String("QMYSQL")) 0829 ? QString::fromLatin1("UNIX_SOCKET=%1/mysql.socket").arg(miscDir) 0830 : QString()); 0831 #endif 0832 0833 parameters.hostName = hostName; 0834 parameters.port = port.toInt(); 0835 parameters.connectOptions = connectOptions; 0836 0837 qCDebug(DIGIKAM_DBENGINE_LOG) << "ConnectOptions " << parameters.connectOptions; 0838 0839 return parameters; 0840 } 0841 0842 DbEngineParameters DbEngineParameters::thumbnailParameters() const 0843 { 0844 DbEngineParameters params = *this; 0845 params.databaseNameCore = databaseNameThumbnails; 0846 0847 return params; 0848 } 0849 0850 DbEngineParameters DbEngineParameters::faceParameters() const 0851 { 0852 DbEngineParameters params = *this; 0853 params.databaseNameCore = databaseNameFace; 0854 0855 return params; 0856 } 0857 0858 DbEngineParameters DbEngineParameters::similarityParameters() const 0859 { 0860 DbEngineParameters params = *this; 0861 params.databaseNameCore = databaseNameSimilarity; 0862 0863 return params; 0864 } 0865 0866 DbEngineParameters DbEngineParameters::parametersForSQLite(const QString& databaseFile) 0867 { 0868 // only the database name is needed 0869 0870 DbEngineParameters params(QLatin1String("QSQLITE"), databaseFile); 0871 params.setCoreDatabasePath(databaseFile); 0872 params.setThumbsDatabasePath(params.getCoreDatabaseNameOrDir()); 0873 params.setFaceDatabasePath(params.getCoreDatabaseNameOrDir()); 0874 params.setSimilarityDatabasePath(params.getCoreDatabaseNameOrDir()); 0875 0876 return params; 0877 } 0878 0879 DbEngineParameters DbEngineParameters::parametersForSQLiteDefaultFile(const QString& directory) 0880 { 0881 return parametersForSQLite(QDir::cleanPath(directory + QLatin1Char('/') + QLatin1String(digikam4db))); 0882 } 0883 0884 QString DbEngineParameters::defaultMysqlInitCmd() // For Linux, Windows and OSX 0885 { 0886 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0887 KConfigGroup group = config->group(configGroupDatabase); 0888 0889 if (group.readEntry(configInternalDatabaseServerUseMariaDB, true)) 0890 { 0891 return QLatin1String("mariadb-install-db"); 0892 } 0893 0894 return QLatin1String("mysql_install_db"); 0895 } 0896 0897 QString DbEngineParameters::defaultMysqlAdminCmd() // For Linux, Windows and OSX 0898 { 0899 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0900 KConfigGroup group = config->group(configGroupDatabase); 0901 0902 if (group.readEntry(configInternalDatabaseServerUseMariaDB, true)) 0903 { 0904 return QLatin1String("mariadb-admin"); 0905 } 0906 0907 return QLatin1String("mysqladmin"); 0908 } 0909 0910 QString DbEngineParameters::defaultMysqlServerCmd() // For Linux, Windows and OSX 0911 { 0912 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0913 KConfigGroup group = config->group(configGroupDatabase); 0914 0915 if (group.readEntry(configInternalDatabaseServerUseMariaDB, true)) 0916 { 0917 return QLatin1String("mariadbd"); 0918 } 0919 0920 return QLatin1String("mysqld"); 0921 } 0922 0923 QString DbEngineParameters::defaultMysqlUpgradeCmd() // For Linux, Windows and OSX 0924 { 0925 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0926 KConfigGroup group = config->group(configGroupDatabase); 0927 0928 if (group.readEntry(configInternalDatabaseServerUseMariaDB, true)) 0929 { 0930 return QLatin1String("mariadb-upgrade"); 0931 } 0932 0933 return QLatin1String("mysql_upgrade"); 0934 } 0935 0936 // -------------------------------- 0937 0938 QDebug operator<<(QDebug dbg, const DbEngineParameters& p) 0939 { 0940 dbg.nospace() << "Database Parameters:" << QT_ENDL; 0941 dbg.nospace() << " Type: " << p.databaseType << QT_ENDL; 0942 dbg.nospace() << " DB Core Name: " << p.databaseNameCore << QT_ENDL; 0943 dbg.nospace() << " DB Thumbs Name: " << p.databaseNameThumbnails << QT_ENDL; 0944 dbg.nospace() << " DB Face Name: " << p.databaseNameFace << QT_ENDL; 0945 dbg.nospace() << " DB Similarity Name: " << p.databaseNameSimilarity << QT_ENDL; 0946 dbg.nospace() << " Connect Options: " << p.connectOptions << QT_ENDL; 0947 dbg.nospace() << " Host Name: " << p.hostName << QT_ENDL; 0948 dbg.nospace() << " Host Port: " << p.port << QT_ENDL; 0949 dbg.nospace() << " WAL Mode: " << p.walMode << QT_ENDL; 0950 dbg.nospace() << " Internal Server: " << p.internalServer << QT_ENDL; 0951 dbg.nospace() << " Internal Server Path: " << p.internalServerDBPath << QT_ENDL; 0952 dbg.nospace() << " Internal Server Init Cmd: " << p.internalServerMysqlInitCmd << QT_ENDL; 0953 dbg.nospace() << " Internal Server Admin Cmd: " << p.internalServerMysqlAdminCmd << QT_ENDL; 0954 dbg.nospace() << " Internal Server Server Cmd: " << p.internalServerMysqlServerCmd << QT_ENDL; 0955 dbg.nospace() << " Internal Server Upgrade Cmd: " << p.internalServerMysqlUpgradeCmd << QT_ENDL; 0956 dbg.nospace() << " Username: " << p.userName << QT_ENDL; 0957 dbg.nospace() << " Password: " << QString().fill(QLatin1Char('X'), p.password.size()) << QT_ENDL; 0958 0959 return dbg.space(); 0960 } 0961 0962 } // namespace Digikam