File indexing completed on 2025-02-16 04:21:13
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003-2018 Jarosław Staniek <staniek@kde.org> 0003 0004 Based on nexp.cpp : Parser module of Python-like language 0005 (C) 2001 Jarosław Staniek, MIMUW (www.mimuw.edu.pl) 0006 0007 This library is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 * Boston, MA 02110-1301, USA. 0021 */ 0022 0023 #include "KDbExpression.h" 0024 #include "KDb.h" 0025 #include "KDbQuerySchema.h" 0026 #include "KDbDriver.h" 0027 #include "kdb_debug.h" 0028 #include "generated/sqlparser.h" 0029 0030 #include <QPoint> 0031 0032 KDbConstExpressionData::KDbConstExpressionData(const QVariant& aValue) 0033 : KDbExpressionData() 0034 , value(aValue) 0035 { 0036 ExpressionDebug << "ConstExpressionData" << ref; 0037 } 0038 0039 KDbConstExpressionData::~KDbConstExpressionData() 0040 { 0041 ExpressionDebug << "~ConstExpressionData" << ref; 0042 } 0043 0044 KDbConstExpressionData* KDbConstExpressionData::clone() 0045 { 0046 ExpressionDebug << "ConstExpressionData::clone" << *this; 0047 return new KDbConstExpressionData(*this); 0048 } 0049 0050 KDbField::Type KDbConstExpressionData::typeInternal(KDb::ExpressionCallStack* callStack) const 0051 { 0052 Q_UNUSED(callStack); 0053 switch (token.value()) { 0054 case SQL_NULL: 0055 return KDbField::Null; 0056 case INTEGER_CONST: 0057 //! @todo ok? 0058 //! @todo add sign info? 0059 if (value.type() == QVariant::Int || value.type() == QVariant::UInt) { 0060 qint64 v = value.toInt(); 0061 if (v <= 0xff && v > -0x80) 0062 return KDbField::Byte; 0063 if (v <= 0xffff && v > -0x8000) 0064 return KDbField::ShortInteger; 0065 return KDbField::Integer; 0066 } 0067 return KDbField::BigInteger; 0068 case CHARACTER_STRING_LITERAL: 0069 if (KDbField::defaultMaxLength() > 0 0070 && value.toString().length() > KDbField::defaultMaxLength()) 0071 { 0072 return KDbField::LongText; 0073 } 0074 else { 0075 return KDbField::Text; 0076 } 0077 case SQL_TRUE: 0078 case SQL_FALSE: 0079 return KDbField::Boolean; 0080 case REAL_CONST: 0081 return KDbField::Double; 0082 case DATE_CONST: 0083 if (value.canConvert<KDbDate>() && value.value<KDbDate>().isValid()) { 0084 return KDbField::Date; 0085 } else if (value.canConvert<QDate>() && value.toDate().isValid()) { 0086 return KDbField::Date; 0087 } 0088 break; 0089 case DATETIME_CONST: 0090 if (value.canConvert<KDbDateTime>() && value.value<KDbDateTime>().isValid()) { 0091 return KDbField::DateTime; 0092 } else if (value.canConvert<QDateTime>() && value.toDateTime().isValid()) { 0093 return KDbField::DateTime; 0094 } 0095 break; 0096 case TIME_CONST: 0097 if (value.canConvert<KDbTime>() && value.value<KDbTime>().isValid()) { 0098 return KDbField::Time; 0099 } else if (value.canConvert<QTime>() && value.toTime().isValid()) { 0100 return KDbField::Time; 0101 } 0102 break; 0103 } 0104 return KDbField::InvalidType; 0105 } 0106 0107 void KDbConstExpressionData::debugInternal(QDebug dbg, KDb::ExpressionCallStack* callStack) const 0108 { 0109 Q_UNUSED(callStack); 0110 QString res = QLatin1String("ConstExp(") 0111 + token.name() 0112 + QLatin1String(",") + toString(nullptr).toString() 0113 + QString::fromLatin1(",type=%1").arg(KDbDriver::defaultSqlTypeName(type())); 0114 if (value.type() == QVariant::Point && token.value() == REAL_CONST) { 0115 res += QLatin1String(",DECIMAL"); 0116 } 0117 res += QLatin1String(")"); 0118 dbg.nospace() << qPrintable(res); 0119 } 0120 0121 KDbEscapedString KDbConstExpressionData::toStringInternal( 0122 const KDbDriver *driver, 0123 KDbQuerySchemaParameterValueListIterator* params, 0124 KDb::ExpressionCallStack* callStack) const 0125 { 0126 Q_UNUSED(params); 0127 Q_UNUSED(callStack); 0128 switch (token.value()) { 0129 case SQL_NULL: 0130 return KDb::valueToSql(driver, KDbField::Null, QVariant()); 0131 case CHARACTER_STRING_LITERAL: 0132 //! @todo better escaping! 0133 return KDb::valueToSql(driver, KDbField::Text, value); 0134 case SQL_TRUE: 0135 return KDb::valueToSql(driver, KDbField::Boolean, 1); 0136 case SQL_FALSE: 0137 return KDb::valueToSql(driver, KDbField::Boolean, 0); 0138 case REAL_CONST: 0139 return KDbEscapedString(value.toByteArray()); 0140 case DATE_CONST: 0141 return KDb::valueToSql(driver, KDbField::Date, value); 0142 case DATETIME_CONST: 0143 return KDb::valueToSql(driver, KDbField::Date, value); 0144 case TIME_CONST: 0145 return KDb::valueToSql(driver, KDbField::Time, value); 0146 case INTEGER_CONST: 0147 default: 0148 break; 0149 } 0150 return KDbEscapedString(value.toByteArray()); 0151 } 0152 0153 void KDbConstExpressionData::getQueryParameters(QList<KDbQuerySchemaParameter>* params) 0154 { 0155 Q_UNUSED(params); 0156 } 0157 0158 bool KDbConstExpressionData::validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack* callStack) 0159 { 0160 Q_UNUSED(parseInfo); 0161 return typeInternal(callStack) != KDbField::InvalidType; 0162 } 0163 0164 //========================================= 0165 0166 KDbConstExpression::KDbConstExpression() 0167 : KDbExpression(new KDbConstExpressionData(QVariant())) 0168 { 0169 ExpressionDebug << "KDbConstExpression() ctor" << *this; 0170 } 0171 0172 KDbConstExpression::KDbConstExpression(KDbToken token, const QVariant& value) 0173 : KDbExpression(new KDbConstExpressionData(value), KDb::ConstExpression, token) 0174 { 0175 } 0176 0177 KDbConstExpression::KDbConstExpression(KDbExpressionData* data, KDb::ExpressionClass aClass, 0178 KDbToken token) 0179 : KDbExpression(data, aClass, token) 0180 { 0181 } 0182 0183 KDbConstExpression::KDbConstExpression(KDbExpressionData* data) 0184 : KDbExpression(data) 0185 { 0186 } 0187 0188 KDbConstExpression::KDbConstExpression(const ExplicitlySharedExpressionDataPointer &ptr) 0189 : KDbExpression(ptr) 0190 { 0191 } 0192 0193 KDbConstExpression::KDbConstExpression(const KDbConstExpression& expr) 0194 : KDbExpression(expr) 0195 { 0196 } 0197 0198 KDbConstExpression::~KDbConstExpression() 0199 { 0200 } 0201 0202 QVariant KDbConstExpression::value() const 0203 { 0204 return d->convert<const KDbConstExpressionData>()->value; 0205 } 0206 0207 void KDbConstExpression::setValue(const QVariant& value) 0208 { 0209 d->convert<KDbConstExpressionData>()->value = value; 0210 }