File indexing completed on 2024-05-19 08:32: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 }