File indexing completed on 2024-12-08 04:17:08
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003 Lucijan Busch <lucijan@kde.org> 0003 Copyright (C) 2004-2018 Jarosław Staniek <staniek@kde.org> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "KDbParser.h" 0022 #include "KDbParser_p.h" 0023 #include "generated/sqlparser.h" 0024 0025 #include "KDbConnection.h" 0026 #include "KDbTableSchema.h" 0027 0028 #include <vector> 0029 0030 bool parseData(); 0031 0032 //! Cache 0033 class ParserStatic 0034 { 0035 public: 0036 ParserStatic() 0037 : statementTypeStrings({ 0038 QLatin1String("None"), 0039 QLatin1String("Select"), 0040 QLatin1String("CreateTable"), 0041 QLatin1String("AlterTable"), 0042 QLatin1String("Insert"), 0043 QLatin1String("Update"), 0044 QLatin1String("Delete")}) 0045 { 0046 } 0047 const std::vector<QString> statementTypeStrings; 0048 private: 0049 Q_DISABLE_COPY(ParserStatic) 0050 }; 0051 0052 Q_GLOBAL_STATIC(ParserStatic, KDb_parserStatic) 0053 0054 KDbParser::KDbParser(KDbConnection *connection) 0055 : d(new KDbParserPrivate) 0056 { 0057 d->connection = connection; 0058 } 0059 0060 KDbParser::~KDbParser() 0061 { 0062 delete d; 0063 } 0064 0065 KDbParser::StatementType KDbParser::statementType() const 0066 { 0067 return d->statementType; 0068 } 0069 0070 QString KDbParser::statementTypeString() const 0071 { 0072 Q_ASSERT(size_t(d->statementType) < sizeof(KDb_parserStatic->statementTypeStrings)); 0073 return KDb_parserStatic->statementTypeStrings[d->statementType]; 0074 } 0075 0076 KDbTableSchema *KDbParser::table() 0077 { 0078 KDbTableSchema *t = d->table; 0079 d->table = nullptr; 0080 return t; 0081 } 0082 0083 KDbQuerySchema *KDbParser::query() 0084 { 0085 KDbQuerySchema *s = d->query; 0086 d->query = nullptr; 0087 return s; 0088 } 0089 0090 KDbConnection *KDbParser::connection() 0091 { 0092 return d->connection; 0093 } 0094 0095 const KDbConnection *KDbParser::connection() const 0096 { 0097 return d->connection; 0098 } 0099 0100 KDbParserError KDbParser::error() const 0101 { 0102 return d->error; 0103 } 0104 0105 KDbEscapedString KDbParser::statement() const 0106 { 0107 return d->sql; 0108 } 0109 0110 void KDbParser::init() 0111 { 0112 if (d->initialized) 0113 return; 0114 // nothing to do 0115 d->initialized = true; 0116 } 0117 0118 bool KDbParser::parse(const KDbEscapedString &sql, KDbQuerySchema *query) 0119 { 0120 init(); 0121 reset(); 0122 d->sql = sql; 0123 d->query = query; 0124 0125 KDbParser *oldParser = globalParser; 0126 KDbField *oldField = globalField; 0127 globalParser = this; 0128 globalField = nullptr; 0129 bool res = parseData(); 0130 globalParser = oldParser; 0131 globalField = oldField; 0132 if (query) { // if existing query was supplied to parse() nullptr should be returned by query() 0133 d->query = nullptr; 0134 } 0135 return res; 0136 } 0137 0138 void KDbParser::reset() 0139 { 0140 d->reset(); 0141 } 0142 0143 //------------------------------------- 0144 0145 class Q_DECL_HIDDEN KDbParserError::Private 0146 { 0147 public: 0148 Private() {} 0149 Private(const Private &other) { 0150 copy(other); 0151 } 0152 #define KDbParserErrorPrivateArgs(o) std::tie(o.type, o.message, o.token, o.position) 0153 void copy(const Private &other) { 0154 KDbParserErrorPrivateArgs((*this)) = KDbParserErrorPrivateArgs(other); 0155 } 0156 bool operator==(const Private &other) const { 0157 return KDbParserErrorPrivateArgs((*this)) == KDbParserErrorPrivateArgs(other); 0158 } 0159 QString type; 0160 QString message; 0161 QByteArray token; 0162 int position = -1; 0163 }; 0164 0165 KDbParserError::KDbParserError() 0166 : d(new Private) 0167 { 0168 } 0169 0170 KDbParserError::KDbParserError(const QString &type, const QString &message, const QByteArray &token, 0171 int position) 0172 : d(new Private) 0173 { 0174 d->type = type; 0175 d->message = message; 0176 d->token = token; 0177 d->position = position; 0178 } 0179 0180 KDbParserError::KDbParserError(const KDbParserError &other) 0181 : d(new Private(*other.d)) 0182 { 0183 *d = *other.d; 0184 } 0185 0186 KDbParserError::~KDbParserError() 0187 { 0188 delete d; 0189 } 0190 0191 KDbParserError& KDbParserError::operator=(const KDbParserError &other) 0192 { 0193 if (this != &other) { 0194 d->copy(*other.d); 0195 } 0196 return *this; 0197 } 0198 0199 bool KDbParserError::operator==(const KDbParserError &other) const 0200 { 0201 return *d == *other.d; 0202 } 0203 0204 QString KDbParserError::type() const 0205 { 0206 return d->type; 0207 } 0208 0209 QString KDbParserError::message() const 0210 { 0211 return d->message; 0212 } 0213 0214 int KDbParserError::position() const 0215 { 0216 return d->position; 0217 } 0218 0219 QDebug operator<<(QDebug dbg, const KDbParserError& error) 0220 { 0221 QDebugStateSaver saver(dbg); 0222 if (error.type().isEmpty() && error.message().isEmpty()) { 0223 dbg.space() << "KDb:KDbParserError: None"; 0224 } else { 0225 dbg.space() << "KDb:KDbParserError: type=" << error.type() << "message=" << error.message() 0226 << "pos=" << error.position() << ")"; 0227 } 0228 return dbg.maybeSpace(); 0229 }