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 
0021 #include "SybaseDriver.h"
0022 #include "SybaseConnection.h"
0023 #include "KDbField.h"
0024 #include "KDbDriverBehavior.h"
0025 #include "KDb.h"
0026 
0027 KDB_DRIVER_PLUGIN_FACTORY(SybaseDriver, "kdb_sybasedriver.json")
0028 
0029 SybaseDriver::SybaseDriver(QObject *parent, const QVariantList &args)
0030     : KDbDriver(parent, args)
0031 {
0032     // Sybase supports Nested Transactions. Ignore for now
0033     beh->features = IgnoreTransactions | CursorForward;
0034 
0035     // Last value assigned is stored in variable @@IDENTITY
0036     beh->ROW_ID_FIELD_NAME = "@@IDENTITY";
0037 
0038     beh->ROW_ID_FIELD_RETURNS_LAST_AUTOINCREMENTED_VALUE = true ;
0039 
0040     beh->_1ST_ROW_READ_AHEAD_REQUIRED_TO_KNOW_IF_THE_RESULT_IS_EMPTY = false;
0041     beh->USING_DATABASE_REQUIRED_TO_CONNECT = false;
0042 
0043     // for Sybase ASA this field is "DEFAULT AUTOINCREMENT"
0044     // for MSSQL and Sybase ASE it's IDENTITY
0045     beh->AUTO_INCREMENT_FIELD_OPTION = "IDENTITY";
0046     beh->AUTO_INCREMENT_PK_FIELD_OPTION = beh->AUTO_INCREMENT_FIELD_OPTION + " PRIMARY KEY ";
0047 
0048     // confirm
0049     //beh->SELECT_1_SUBQUERY_SUPPORTED = true;
0050 
0051     beh->OPENING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER = '"';
0052     beh->CLOSING_QUOTATION_MARK_BEGIN_FOR_IDENTIFIER = '"';
0053 
0054     initDriverSpecificKeywords(m_keywords);
0055 
0056     //predefined properties
0057     beh->properties["client_library_version"] = ""; //!< @todo
0058     beh->properties["default_server_encoding"] = ""; //!< @todo
0059 
0060     // datatypes
0061     // integers
0062     beh->typeNames[KDbField::Byte] = "TINYINT";
0063     beh->typeNames[KDbField::ShortInteger] = "SMALLINT";
0064     beh->typeNames[KDbField::Integer] = "INT";
0065     beh->typeNames[KDbField::BigInteger] = "BIGINT";
0066 
0067     // boolean
0068     beh->typeNames[KDbField::Boolean] = "BIT";
0069 
0070     // date and time. There's only one integrated datetime datatype in Sybase
0071     // Though there are smalldatetime (4 bytes) and datetime (8 bytes) data types
0072     beh->typeNames[KDbField::Date] = "DATETIME";
0073     beh->typeNames[KDbField::DateTime] = "DATETIME";
0074     beh->typeNames[KDbField::Time] = "DATETIME"; // or should we use timestamp ?
0075 
0076     // floating point
0077     beh->typeNames[KDbField::Float] = "REAL"; // 4 bytes
0078     beh->typeNames[KDbField::Double] = "DOUBLE PRECISION"; // 8 bytes
0079 
0080     // strings
0081     beh->typeNames[KDbField::Text] = "VARCHAR";
0082     beh->typeNames[KDbField::LongText] = "TEXT";
0083 
0084     // Large Binary Objects
0085     beh->typeNames[KDbField::BLOB] = "IMAGE";
0086 }
0087 
0088 SybaseDriver::~SybaseDriver()
0089 {
0090 }
0091 
0092 KDbConnection* SybaseDriver::drv_createConnection(const KDbConnectionData& connData,
0093                                    const KDbConnectionOptions &options)
0094 {
0095     return new SybaseConnection(this, connData, options);
0096 }
0097 
0098 bool SybaseDriver::isSystemDatabaseName(const QString &n) const
0099 {
0100     if (m_systemDatabases.isEmpty()) {
0101         m_systemDatabases << "master" << "model" << "sybsystemprocs" << "tempdb"
0102                           << "sybsecurity" << "sybsystemdb" << "pubs2" << "pubs3"
0103                           << "dbccdb";
0104     }
0105     return m_systemDatabases.contains(n.toLatin1().toLower());
0106 }
0107 
0108 bool SybaseDriver::drv_isSystemFieldName(const QString&) const
0109 {
0110     return false;
0111 }
0112 
0113 KDbEscapedString SybaseDriver::escapeString(const QString& str) const
0114 {
0115     return KDbEscapedString("'") + KDbEscapedString(str).replace("\'", "\\''") + '\'';
0116 }
0117 
0118 KDbEscapedString SybaseDriver::escapeBLOB(const QByteArray& array) const
0119 {
0120     return KDbEscapedString(KDb::escapeBLOB(array, KDb::BLOBEscapingType::ZeroXHex));
0121 }
0122 
0123 KDbEscapedString SybaseDriver::escapeString(const QByteArray& str) const
0124 {
0125     //! @todo needs any modification ?
0126     return KDbEscapedString("'") + KDbEscapedString(str).replace("\'", "\\''") + '\'';
0127 }
0128 
0129 QByteArray SybaseDriver::drv_escapeIdentifier(const QString& str) const
0130 {
0131     //! @todo verify
0132     return QByteArray("\"") + QByteArray(str.toUtf8()).replace("\\", "\\\\").replace("\"", "\"\"")
0133            + "\"";
0134 }
0135 
0136 QByteArray SybaseDriver::drv_escapeIdentifier(const QByteArray& str) const
0137 {
0138     // verify
0139     return QByteArray("\"") + str
0140            .replace("\\", "\\\\")
0141            .replace("\"", "\"\"")
0142            + "\"";
0143 }
0144 
0145 KDbEscapedString SybaseDriver::addLimitTo1(const QString& sql, bool add)
0146 {
0147     // length of "select" is 6
0148     // eg: before:  select foo from foobar
0149     // after:   select TOP 1 foo from foobar
0150     return add ? KDbEscapedString(sql).trimmed().insert(6, " TOP 1 ") : KDbEscapedString(sql);
0151 }