File indexing completed on 2024-05-05 16:47:17

0001 /* This file is part of the KDE project
0002    Copyright (C) 2007 Sharan Rao <sharanrao@gmail.com>
0003 
0004 This program 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 program 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 program; see the file COPYING. 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 <QRegularExpression>
0021 
0022 #include <kgenericfactory.h>
0023 
0024 #include "SybaseDriver.h"
0025 #include "SybaseConnection.h"
0026 #include "SybaseConnection_p.h"
0027 #include "SybasePreparedStatement.h"
0028 #include "KDbError.h"
0029 
0030 SybaseConnection::SybaseConnection(KDbDriver *driver, const KDbConnectionData& connData)
0031         : KDbConnection(driver, connData)
0032         , d(new SybaseConnectionInternal(this))
0033 {
0034 }
0035 
0036 SybaseConnection::~SybaseConnection()
0037 {
0038     destroy();
0039 }
0040 
0041 bool SybaseConnection::drv_connect(KDbServerVersionInfo* version)
0042 {
0043     const bool ok = d->db_connect(*data());
0044     if (!ok)
0045         return false;
0046 
0047     // we can retrieve the server name and the server version using global variables
0048     // @@servername
0049     // @@version
0050 
0051     QString serverVersionString;
0052 
0053     if (!querySingleString(KDbEscapedString("SELECT @@servername") , &version.string)) {
0054         sybaseWarning() << "Couldn't fetch server name";
0055     }
0056 
0057     if (!querySingleString(KDbEscapedString("SELECT @@version"), &serverVersionString)) {
0058         sybaseWarning() << "Couldn't fetch server version";
0059     }
0060 
0061     QRegularExpression versionRe("^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$");
0062     QRegularExpressionMatch match  = versionRe.match(serverVersionString);
0063     if (match.hasMatch()) {
0064         version.major = match.captured(1).toInt();
0065         version.minor = match.captured(2).toInt();
0066         version.release = match.captured(3).toInt();
0067     }
0068 
0069     return true;
0070 }
0071 
0072 bool SybaseConnection::drv_disconnect()
0073 {
0074     return d->db_disconnect();
0075 }
0076 
0077 KDbCursor* SybaseConnection::prepareQuery(const KDbEscapedString& sql, int cursor_options)
0078 {
0079     return new SybaseCursor(this, sql, cursor_options);
0080 }
0081 
0082 KDbCursor* SybaseConnection::prepareQuery(KDbQuerySchema* query, int cursor_options)
0083 {
0084     return new SybaseCursor(this, query, cursor_options);
0085 }
0086 
0087 bool SybaseConnection::drv_getDatabasesList(QStringList* list)
0088 {
0089     // select * from master..sysdatabases ?
0090     // todo: verify.
0091     return queryStringList(KDbEscapedString("SELECT name FROM master..sysdatabases"), list) ;
0092 }
0093 
0094 bool SybaseConnection::drv_createDatabase(const QString &dbName)
0095 {
0096     //sybaseDebug() << dbName;
0097     // mysql_create_db deprecated, use SQL here.
0098     if (drv_executeSql(KDbEscapedString("CREATE DATABASE ") + dbName)) {
0099         // set allow_nulls_by_default option to true
0100         KDbEscapedString allowNullsQuery = KDbEscapedString("sp_dboption %1, allow_nulls_by_default, true").arg(dbName);
0101         if (drv_executeSql(allowNullsQuery.data()))
0102             return true;
0103     }
0104     d->storeResult();
0105     return false;
0106 }
0107 
0108 bool SybaseConnection::drv_useDatabase(const QString &dbName, bool *cancelled, KDbMessageHandler* msgHandler)
0109 {
0110     Q_UNUSED(cancelled);
0111     Q_UNUSED(msgHandler);
0112 
0113     //! @todo is here escaping needed?
0114     return d->useDatabase(dbName) ;
0115 }
0116 
0117 bool SybaseConnection::drv_closeDatabase()
0118 {
0119 // here we disconnect the connection
0120     return true;
0121 }
0122 
0123 bool SybaseConnection::drv_dropDatabase(const QString &dbName)
0124 {
0125 
0126     return drv_executeSql(KDbEscapedString("DROP DATABASE ") + escapeString(dbName));
0127 }
0128 
0129 bool SybaseConnection::drv_executeSql(const KDbEscapedString& sql)
0130 {
0131     return d->executeSql(sql);
0132 }
0133 
0134 quint64 SybaseConnection::drv_lastInsertRecordId()
0135 {
0136     int rowId = 0;
0137     querySingleNumber(KDbEscapedString("Select @@IDENTITY"), &rowId);
0138     return (qint64)rowId;
0139 }
0140 
0141 int SybaseConnection::serverResult()
0142 {
0143     return d->res;
0144 }
0145 
0146 QString SybaseConnection::serverResultName() const
0147 {
0148     return QString();
0149 }
0150 
0151 /*void SybaseConnection::drv_clearServerResult()
0152 {
0153     if (!d)
0154         return;
0155     d->res = 0;
0156 }*/
0157 
0158 bool SybaseConnection::drv_containsTable(const QString &tableName)
0159 {
0160     return resultExists(KDbEscapedString("SELECT name FROM sysobjects WHERE type='U' AND name=%1")
0161                         .arg(escapeString(tableName)));
0162 }
0163 
0164 bool SybaseConnection::drv_getTablesList(QStringList* list)
0165 {
0166     return queryStringList(KDbEscapedString("SELECT name FROM sysobjects WHERE type='U'"), list);
0167 }
0168 
0169 KDbPreparedStatement SybaseConnection::prepareStatement(KDbPreparedStatement::StatementType type,
0170         KDbFieldList* fields)
0171 {
0172     return SybasePreparedStatement(type, *d, fields);
0173 }
0174 
0175 bool KDbSybaseConnection::drv_beforeInsert(const QString& table, KDbFieldList* fields)
0176 {
0177 
0178     if (fields.autoIncrementFields()->isEmpty())
0179         return true;
0180 
0181     // explicit insertion into IDENTITY fields !!
0182     return drv_executeSql(KDbEscapedString("SET IDENTITY_INSERT %1 ON").arg(escapeIdentifier(table)));
0183 
0184 }
0185 
0186 bool KDbSybaseConnection::drv_afterInsert(const QString& table, KDbFieldList* fields)
0187 {
0188     // should we instead just set a flag when an identity_insert has taken place and only check for that
0189     // flag here ?
0190 
0191     if (fields.autoIncrementFields()->isEmpty())
0192         return true;
0193 
0194     // explicit insertion into IDENTITY fields has taken place. Turn off IDENTITY_INSERT
0195     return drv_executeSql(KDbEscapedString("SET IDENTITY_INSERT %1 OFF").arg(escapeIdentifier(table)));
0196 
0197 }
0198 
0199 bool KDbSybaseConnection::drv_beforeUpdate(const QString& table, KDbFieldList* fields)
0200 {
0201     if (fields->autoIncrementFields()->isEmpty())
0202         return true;
0203 
0204     // explicit update of IDENTITY fields has taken place.
0205     return drv_executeSql(KDbEscapedString("SET IDENTITY_UPDATE %1 ON").arg(escapeIdentifier(table)));
0206 }
0207 
0208 bool KDbSybaseConnection::drv_afterUpdate(const QString& table, KDbFieldList& fields)
0209 {
0210     // should we instead just set a flag when an identity_update has taken place and only check for that
0211     // flag here ?
0212 
0213     if (fields.autoIncrementFields()->isEmpty())
0214         return true;
0215 
0216     // explicit insertion into IDENTITY fields has taken place. Turn off IDENTITY_INSERT
0217     return drv_executeSql(KDbEscapedString("SET IDENTITY_UPDATE %1 OFF").arg(escapeIdentifier(table)));
0218 }