File indexing completed on 2024-06-16 13:25:13

0001 /* This file is part of the KDE project
0002    Copyright (C) 2006 Jarosław Staniek <staniek@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "KDbSimpleCommandLineApp.h"
0021 
0022 #include <QFileInfo>
0023 #include <QTextStream>
0024 
0025 #include <KCmdLineArgs>
0026 #include <KComponentData>
0027 
0028 #include "KDbConnectionData.h"
0029 #include "KDbDriverManager.h"
0030 #include "KDb.h"
0031 
0032 //! @internal used for KDbSimpleCommandLineApp
0033 class Q_DECL_HIDDEN KDbSimpleCommandLineApp::Private
0034 {
0035 public:
0036     Private()
0037             : conn(0) {}
0038     ~Private() {
0039         if (conn) {
0040             conn->disconnect();
0041             delete(KDbConnection*)conn;
0042         }
0043     }
0044 
0045     KDbDriverManager manager;
0046     KComponentData componentData;
0047     KDbConnectionData connData;
0048     QPointer<KDbConnection> conn;
0049 private:
0050     Q_DISABLE_COPY(Private)
0051 };
0052 
0053 //-----------------------------------------
0054 
0055 KDbSimpleCommandLineApp::KDbSimpleCommandLineApp(
0056     int argc, char** argv, const KCmdLineOptions &options,
0057     const char *programName, const char *version,
0058     const char *shortDescription, KAboutData::LicenseKey licenseType,
0059     const char *copyrightStatement, const char *text,
0060     const char *homePageAddress, const char *bugsEmailAddress)
0061         : KDbObject()
0062         , d(new Private())
0063 {
0064     QFileInfo fi(argv[0]);
0065     QByteArray appName(fi.baseName().toLatin1());
0066     KCmdLineArgs::init(argc, argv,
0067                        new KAboutData(appName, 0, tr(programName),
0068                                       version, tr(shortDescription), licenseType, tr(copyrightStatement), tr(text),
0069                                       homePageAddress, bugsEmailAddress));
0070 
0071     d->componentData = KComponentData(appName);
0072 
0073     KCmdLineOptions allOptions;
0074 
0075     // add predefined options
0076     allOptions.add("drv", KLocalizedString(), KDb::defaultFileBasedDriverId().toUtf8());
0077     allOptions.add("driver <id>", tr("Database driver ID"));
0078     allOptions.add("u");
0079     allOptions.add("user <name>", tr("Database user name"));
0080     allOptions.add("p");
0081     allOptions.add("password", tr("Prompt for password"));
0082     allOptions.add("h");
0083     allOptions.add("host <name>", tr("Host (server) name"));
0084     allOptions.add("port <number>", tr("Server's port number"));
0085     allOptions.add("s");
0086     allOptions.add("local-socket <filename>", tr("Server's local socket filename"));
0087 
0088     // add user options
0089     allOptions.add(options);
0090 
0091     KCmdLineArgs::addCmdLineOptions(allOptions);
0092     KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
0093 
0094     d->connData.driverId = args->getOption("driver");
0095     d->connData.userName = args->getOption("user");
0096     d->connData.hostName = args->getOption("host");
0097     d->connData.localSocketFileName = args->getOption("local-socket");
0098     d->connData.port = args->getOption("port").toInt();
0099     d->connData.useLocalSocketFile = args->isSet("local-socket");
0100 
0101     if (args->isSet("password")) {
0102         QString userAtHost = d->connData.userName;
0103         if (!d->connData.userName.isEmpty())
0104             userAtHost += '@';
0105         userAtHost += (d->connData.hostName.isEmpty() ? "localhost" : d->connData.hostName);
0106         QTextStream cout(stdout, IO_WriteOnly);
0107         cout << tr("Enter password for %1: ", "Enter password for <user>").arg(userAtHost);
0108 //! @todo make use of pty/tty here! (and care about portability)
0109         QTextStream cin(stdin, QIODevice::ReadOnly);
0110         cin >> d->connData.password;
0111         kdbDebug() << d->connData.password;
0112     }
0113 }
0114 
0115 KDbSimpleCommandLineApp::~KDbSimpleCommandLineApp()
0116 {
0117     closeDatabase();
0118     delete d;
0119 }
0120 
0121 bool KDbSimpleCommandLineApp::openDatabase(const QString& databaseName)
0122 {
0123     if (!d->conn) {
0124         if (d->manager.error()) {
0125             setError(&d->manager);
0126             return false;
0127         }
0128 
0129         //get the driver
0130         KDbDriver *driver = d->manager.driver(d->connData.driverId);
0131         if (!driver || d->manager.error()) {
0132             setError(&d->manager);
0133             return false;
0134         }
0135 
0136         if (driver->metaData()->isFileBased())
0137             d->connData.setFileName(databaseName);
0138 
0139         d->conn = driver->createConnection(&d->connData);
0140         if (!d->conn || driver->error()) {
0141             setError(driver);
0142             return false;
0143         }
0144     }
0145     if (d->conn->isConnected()) {
0146         // db already opened
0147         if (d->conn->isDatabaseUsed() && d->conn->currentDatabase() == databaseName) //the same: do nothing
0148             return true;
0149         if (!closeDatabase()) // differs: close the first
0150             return false;
0151     }
0152     if (!d->conn->connect()) {
0153         setError(d->conn);
0154         delete d->conn;
0155         d->conn = 0;
0156         return false;
0157     }
0158 
0159     if (!d->conn->useDatabase(databaseName)) {
0160         setError(d->conn);
0161         delete d->conn;
0162         d->conn = 0;
0163         return false;
0164     }
0165     return true;
0166 }
0167 
0168 bool KDbSimpleCommandLineApp::closeDatabase()
0169 {
0170     if (!d->conn)
0171         return true;
0172     if (!d->conn->disconnect()) {
0173         setError(d->conn);
0174         return false;
0175     }
0176     return true;
0177 }
0178 
0179 const KComponentData &KDbSimpleCommandLineApp::componentData() const
0180 {
0181     return d->componentData;
0182 }
0183 
0184 KDbConnectionData* KDbSimpleCommandLineApp::connectionData() const
0185 {
0186     return &d->connData;
0187 }
0188 
0189 KDbConnection* KDbSimpleCommandLineApp::connection() const
0190 {
0191     return d->conn;
0192 }