KDb

MysqlConnection.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2002 Lucijan Busch <lucijan@gmx.at>
3 Copyright (C) 2003 Joseph Wenninger<jowenn@kde.org>
4 Copyright (C) 2004-2016 Jarosław Staniek <staniek@kde.org>
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this program; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20*/
21
22#include "MysqlConnection.h"
23#include "MysqlDriver.h"
24#include "MysqlCursor.h"
25#include "MysqlPreparedStatement.h"
26#include "mysql_debug.h"
27#include "KDbConnectionData.h"
28#include "KDbVersionInfo.h"
29
30#include <QRegularExpression>
31
33 const KDbConnectionOptions &options)
34 : KDbConnection(driver, connData, options)
35 , d(new MysqlConnectionInternal(this))
36{
37}
38
39MysqlConnection::~MysqlConnection()
40{
41 destroy();
42 delete d;
43}
44
46{
47 const bool ok = d->db_connect(data());
48 if (!ok) {
49 storeResult(); //store error msg, if any - can be destroyed after disconnect()
50 d->db_disconnect();
51 return false;
52 }
53
54 // Get lower_case_table_name value so we know if there's case sensitivity supported
55 // See https://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html
56 int intLowerCaseTableNames = 0;
57 const tristate res = querySingleNumber(
58 KDbEscapedString("SHOW VARIABLES LIKE 'lower_case_table_name'"), &intLowerCaseTableNames,
59 0 /*col*/,
61 if (res == false) // sanity
62 return false;
63 d->lowerCaseTableNames = intLowerCaseTableNames > 0;
64 return true;
65}
66
68{
69 // https://dev.mysql.com/doc/refman/5.1/en/mysql-get-server-info.html
70 version->setString(QLatin1String(mysql_get_server_info(d->mysql)));
71
72 // get the version info using 'version' built-in variable:
73//! @todo this is hardcoded for now; define api for retrieving variables and use this API...
74 // https://dev.mysql.com/doc/refman/5.1/en/mysql-get-server-version.html
75 QString versionString;
76 tristate res = querySingleString(KDbEscapedString("SELECT @@version"), &versionString,
77 /*column*/ 0,
79
80 static const QRegularExpression versionRe(QLatin1String("^(\\d+)\\.(\\d+)\\.(\\d+)$"));
81 QRegularExpressionMatch match = versionRe.match(versionString);
82 if (res == false) // sanity
83 return false;
84 if (match.hasMatch()) {
85 // (if querySingleString failed, the version will be 0.0.0...
86 version->setMajor(match.captured(1).toInt());
87 version->setMinor(match.captured(2).toInt());
88 version->setRelease(match.captured(3).toInt());
89 }
90 return true;
91}
92
94{
95 return d->db_disconnect();
96}
97
99{
100 return new MysqlCursor(this, sql, options);
101}
102
104{
105 return new MysqlCursor(this, query, options);
106}
107
109{
110 mysqlDebug();
111 list->clear();
112 MYSQL_RES *res = mysql_list_dbs(d->mysql, nullptr);
113 if (res != nullptr) {
114 MYSQL_ROW row;
115 while ((row = mysql_fetch_row(res)) != nullptr) {
116 *list << QString::fromUtf8(row[0]);
117 }
118 mysql_free_result(res);
119 return true;
120 }
121 storeResult();
122 return false;
123}
124
125bool MysqlConnection::drv_databaseExists(const QString &dbName, bool ignoreErrors)
126{
127 /* db names can be lower case in mysql */
128 const QString storedDbName(d->lowerCaseTableNames ? dbName.toLower() : dbName);
129 const tristate result = resultExists(
130 KDbEscapedString("SHOW DATABASES LIKE %1").arg(escapeString(storedDbName)));
131 if (result == true) {
132 return true;
133 }
134 if (!ignoreErrors) {
135 m_result = KDbResult(ERR_OBJECT_NOT_FOUND,
136 tr("The database \"%1\" does not exist.").arg(storedDbName));
137 }
138 return false;
139}
140
142{
143 const QString storedDbName(d->lowerCaseTableNames ? dbName.toLower() : dbName);
144 mysqlDebug() << storedDbName;
145 // mysql_create_db deprecated, use SQL here.
146 // db names are lower case in mysql
147 return drv_executeSql(KDbEscapedString("CREATE DATABASE %1").arg(escapeIdentifier(storedDbName)));
148}
149
150bool MysqlConnection::drv_useDatabase(const QString &dbName, bool *cancelled, KDbMessageHandler* msgHandler)
151{
152 Q_UNUSED(cancelled);
153 Q_UNUSED(msgHandler);
154//! @todo is here escaping needed?
155 const QString storedDbName(d->lowerCaseTableNames ? dbName.toLower() : dbName);
156 if (!d->useDatabase(storedDbName)) {
157 storeResult();
158 return false;
159 }
160 return true;
161}
162
164{
165//! @todo free resources, as far as I know, mysql doesn't support that
166 return true;
167}
168
170{
171//! @todo is here escaping needed?
172 const QString storedDbName(d->lowerCaseTableNames ? dbName.toLower() : dbName);
173 return drv_executeSql(KDbEscapedString("DROP DATABASE %1").arg(escapeIdentifier(storedDbName)));
174}
175
177{
178 if (!drv_executeSql(sql)) {
179 return nullptr;
180 }
181 MYSQL_RES *data = mysql_use_result(d->mysql); // more optimal than mysql_store_result
182 //! @todo use mysql_error()
183 return new MysqlSqlResult(this, data);
184}
185
187{
188 if (!d->executeSql(sql)) {
189 storeResult();
190 return false;
191 }
192 return true;
193}
194
196{
197 return MysqlConnectionInternal::serverResultName(d->mysql);
198}
199
201{
202 return resultExists(KDbEscapedString("SHOW TABLES LIKE %1")
203 .arg(escapeString(tableName)));
204}
205
210
211void MysqlConnection::storeResult()
212{
213 d->storeResult(&m_result);
214}
Database specific connection data, e.g. host, port.
Generic options for a single connection. The options are accessible using key/value pairs....
Provides database connection, allowing queries and data modification.
virtual KDbEscapedString escapeString(const QString &str) const
tristate querySingleString(const KDbEscapedString &sql, QString *value, int column=0, QueryRecordOptions options=QueryRecordOption::Default)
virtual QString escapeIdentifier(const QString &id) const
Identifier escaping function in the associated KDbDriver.
KDbConnectionData data() const
tristate querySingleNumber(const KDbEscapedString &sql, int *number, int column=0, QueryRecordOptions options=QueryRecordOption::Default)
tristate resultExists(const KDbEscapedString &sql, QueryRecordOptions options=QueryRecordOption::Default)
@ AddLimitTo1
Adds a "LIMIT 1" clause to the query for optimization purposes (it should not include one already)
KDbConnectionOptions * options()
Provides database cursor functionality.
Definition KDbCursor.h:69
Database driver's abstraction.
Definition KDbDriver.h:50
Specialized string for escaping.
Prepared statement interface for backend-dependent implementations.
KDbQuerySchema provides information about database query.
The KDbSqlResult class abstracts result of a raw SQL query preparation by KDbConnection::prepareSql()
bool drv_executeSql(const KDbEscapedString &sql) override
Executes query for a raw SQL statement sql without returning resulting records.
KDbSqlResult * drv_prepareSql(const KDbEscapedString &sql) override
Prepares query for a raw SQL statement sql with possibility of returning records.
bool drv_closeDatabase() override
bool drv_useDatabase(const QString &dbName=QString(), bool *cancelled=nullptr, KDbMessageHandler *msgHandler=nullptr) override
QString serverResultName() const override
Implemented for KDbResultable.
bool drv_dropDatabase(const QString &dbName=QString()) override
bool drv_connect() override
bool drv_createDatabase(const QString &dbName=QString()) override
KDbCursor * prepareQuery(const KDbEscapedString &sql, KDbCursor::Options options=KDbCursor::Option::None) override
tristate drv_containsTable(const QString &tableName) override
bool drv_getServerVersion(KDbServerVersionInfo *version) override
bool drv_getDatabasesList(QStringList *list) override
bool drv_disconnect() override
MysqlConnection(KDbDriver *driver, const KDbConnectionData &connData, const KDbConnectionOptions &options)
bool drv_databaseExists(const QString &dbName, bool ignoreErrors=true) override
reimplemented using "SHOW DATABASES LIKE..." because MySQL stores db names in lower case.
KDbPreparedStatementInterface * prepareStatementInternal() override
3-state logical type with three values: true, false and cancelled and convenient operators.
void clear()
QRegularExpressionMatch match(QStringView subjectView, qsizetype offset, MatchType matchType, MatchOptions matchOptions) const const
QString fromUtf8(QByteArrayView str)
QString toLower() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:59 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.