diff options
Diffstat (limited to 'kexi/kexidb/drivers/mySQL/mysqldriver.cpp')
| -rw-r--r-- | kexi/kexidb/drivers/mySQL/mysqldriver.cpp | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/kexi/kexidb/drivers/mySQL/mysqldriver.cpp b/kexi/kexidb/drivers/mySQL/mysqldriver.cpp new file mode 100644 index 000000000..c27681c0b --- /dev/null +++ b/kexi/kexidb/drivers/mySQL/mysqldriver.cpp @@ -0,0 +1,212 @@ +/* This file is part of the KDE project +Copyright (C) 2002 Lucijan Busch <lucijan@gmx.at> +Daniel Molkentin <molkentin@kde.org> +Copyright (C) 2003 Joseph Wenninger<jowenn@kde.org> + +This program 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 program 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 program; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifdef Q_WS_WIN +# include <mysql/config-win.h> +#endif +#include <mysql_version.h> +#include <mysql.h> +#define BOOL bool + +#include <qvariant.h> +#include <qfile.h> +#include <qdict.h> + +#include <kgenericfactory.h> +#include <kdebug.h> + +#include "mysqldriver.h" +#include "mysqlconnection.h" +#include <kexidb/field.h> +#include <kexidb/driver_p.h> +#include <kexidb/utils.h> + +using namespace KexiDB; + +KEXIDB_DRIVER_INFO( MySqlDriver, mysql ) + +/* TODO: Implement buffered/unbuffered, rather than buffer everything. + Each MYSQL connection can only handle at most one unbuffered cursor, + so MySqlConnection should keep count? + */ + +/*! + * Constructor sets database features and + * maps the types in KexiDB::Field::Type to the MySQL types. + * + * See: http://dev.mysql.com/doc/mysql/en/Column_types.html + */ +MySqlDriver::MySqlDriver(QObject *parent, const char *name, const QStringList &args) : Driver(parent, name,args) +{ +// KexiDBDrvDbg << "MySqlDriver::MySqlDriver()" << endl; + + d->isFileDriver=false; + d->features=IgnoreTransactions | CursorForward; + + beh->ROW_ID_FIELD_NAME="LAST_INSERT_ID()"; + beh->ROW_ID_FIELD_RETURNS_LAST_AUTOINCREMENTED_VALUE=true; + beh->_1ST_ROW_READ_AHEAD_REQUIRED_TO_KNOW_IF_THE_RESULT_IS_EMPTY=false; + beh->USING_DATABASE_REQUIRED_TO_CONNECT=false; + beh->QUOTATION_MARKS_FOR_IDENTIFIER='`'; + beh->SQL_KEYWORDS = keywords; + initSQLKeywords(331); + + //predefined properties +#if MYSQL_VERSION_ID < 40000 + d->properties["client_library_version"] = MYSQL_SERVER_VERSION; //nothing better + d->properties["default_server_encoding"] = MYSQL_CHARSET; //nothing better +#elif MYSQL_VERSION_ID < 50000 +//OK? d->properties["client_library_version"] = mysql_get_client_version(); +#endif + + d->typeNames[Field::Byte]="TINYINT"; + d->typeNames[Field::ShortInteger]="SMALLINT"; + d->typeNames[Field::Integer]="INT"; + d->typeNames[Field::BigInteger]="BIGINT"; + // Can use BOOLEAN here, but BOOL has been in MySQL longer + d->typeNames[Field::Boolean]="BOOL"; + d->typeNames[Field::Date]="DATE"; + d->typeNames[Field::DateTime]="DATETIME"; + d->typeNames[Field::Time]="TIME"; + d->typeNames[Field::Float]="FLOAT"; + d->typeNames[Field::Double]="DOUBLE"; + d->typeNames[Field::Text]="VARCHAR"; + d->typeNames[Field::LongText]="LONGTEXT"; + d->typeNames[Field::BLOB]="BLOB"; +} + +MySqlDriver::~MySqlDriver() +{ +} + +KexiDB::Connection* +MySqlDriver::drv_createConnection( ConnectionData &conn_data ) +{ + return new MySqlConnection( this, conn_data ); +} + +bool MySqlDriver::isSystemDatabaseName(const QString &n) const +{ + return n.lower()=="mysql" || Driver::isSystemObjectName(n); +} + +bool MySqlDriver::drv_isSystemFieldName(const QString&) const { + return false; +} + +QString MySqlDriver::escapeString(const QString& str) const +{ + //escape as in http://dev.mysql.com/doc/refman/5.0/en/string-syntax.html +//! @todo support more characters, like %, _ + + const int old_length = str.length(); + int i; + for ( i = 0; i < old_length; i++ ) { //anything to escape? + const unsigned int ch = str[i].unicode(); + if (ch == '\\' || ch == '\'' || ch == '"' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\b' || ch == '\0') + break; + } + if (i >= old_length) { //no characters to escape + return QString::fromLatin1("'") + str + QString::fromLatin1("'"); + } + + QChar *new_string = new QChar[ old_length * 3 + 1 ]; // a worst case approximation +//! @todo move new_string to Driver::m_new_string or so... + int new_length = 0; + new_string[new_length++] = '\''; //prepend ' + for ( i = 0; i < old_length; i++, new_length++ ) { + const unsigned int ch = str[i].unicode(); + if (ch == '\\') { + new_string[new_length++] = '\\'; + new_string[new_length] = '\\'; + } + else if (ch <= '\'') {//check for speedup + if (ch == '\'') { + new_string[new_length++] = '\\'; + new_string[new_length] = '\''; + } + else if (ch == '"') { + new_string[new_length++] = '\\'; + new_string[new_length] = '"'; + } + else if (ch == '\n') { + new_string[new_length++] = '\\'; + new_string[new_length] = 'n'; + } + else if (ch == '\r') { + new_string[new_length++] = '\\'; + new_string[new_length] = 'r'; + } + else if (ch == '\t') { + new_string[new_length++] = '\\'; + new_string[new_length] = 't'; + } + else if (ch == '\b') { + new_string[new_length++] = '\\'; + new_string[new_length] = 'b'; + } + else if (ch == '\0') { + new_string[new_length++] = '\\'; + new_string[new_length] = '0'; + } + else + new_string[new_length] = str[i]; + } + else + new_string[new_length] = str[i]; + } + + new_string[new_length++] = '\''; //append ' + QString result(new_string, new_length); + delete [] new_string; + return result; +} + +QString MySqlDriver::escapeBLOB(const QByteArray& array) const +{ + return KexiDB::escapeBLOB(array, KexiDB::BLOBEscape0xHex); +} + +QCString MySqlDriver::escapeString(const QCString& str) const +{ +//! @todo optimize using mysql_real_escape_string()? +//! see http://dev.mysql.com/doc/refman/5.0/en/string-syntax.html + + return QCString("'")+QCString(str) + .replace( '\\', "\\\\" ) + .replace( '\'', "\\''" ) + .replace( '"', "\\\"" ) + + QCString("'"); +} + +/*! Add back-ticks to an identifier, and replace any back-ticks within + * the name with single quotes. + */ +QString MySqlDriver::drv_escapeIdentifier( const QString& str) const { + return QString(str).replace('`', "'"); +} + +QCString MySqlDriver::drv_escapeIdentifier( const QCString& str) const { + return QCString(str).replace('`', "'"); +} + +#include "mysqldriver.moc" + |
